VoxyPy

VoxyPy is a data structure for operations on Voxel models and .vox files.

It uses NumPy for data storage and transformation.

Reading and writing .vox files is achieved using a heavily modified version of numpy-vox-io for IO operations.

You can view the code, submit bugs/issues, and leave comments at the VoxyPy GitLab repo.

Note

This project is under active development.

Quickstart

from voxypy.models import Entity, Voxel
dense = np.zeros((10, 10, 10), dtype=int)
entity = Entity(data=dense)

entity.set(x=1, y=2, z=3, 42)
voxel = entity.get(1, 2, 3) # Voxel object with value 42

voxel.add(1) # Voxel object with value 43
new_voxel = Voxel(255)
new_voxel.add(1) # Returns Voxel object with value 1
entity.set(5, 5, 5, new_voxel)
entity.set(5, 5, 5, 69)

entity = Entity().from_file('old_entity.vox')
# optional
entity.set_palette_from_file('palette.png')
entity.save('new_entity.vox')

For complete documentation, see Voxel and Entity.

Voxel

Voxel is a small class representing one cell in an Entity.

Voxel colors are represented as indices from 0 to 255, where 0 means blank. These indices refer to actual RGB colors in a 1x255 .png file. So, for example, if the 10th pixel in the texture is red, then a voxel with value 10 will render as red.

The Voxel equality operator works with ints and Voxels. Voxels can also be cast to ints.

Methods

  • _init__(color=0) - Voxel object with color color. 0 is blank.
    • color - 0-255

  • get() - int value of voxel’s color.

  • set(color=0) - Voxel object with color color. 0 is blank.
    • color - 0-255

  • add(amount=1) - Adds amount to voxel’s color.
    • Adding 1 to 255 causes the color to wrap to 1 instead of 0. See Voxel for info about voxel colors.

  • subtract(amount=1) - Subtracts amount from voxel’s color.
    • Just a wrapper for add.

from voxypy.models import Voxel
v1 = Voxel(1)
v2 = Voxel(1)

v1 == v2      # True
v1 == 1       # True
int(v1) == 1  # True
v1 != 0       # True

Entity

An Entity is (conceptually) a 3d array of Voxels.

Under the hood, an Entity is actually a wrapper for a 3d NumPy ndarray of ints. Values are converted to Voxels during get and set methods. Voxels and ints can be used interchangeably in almost every case.

Initialization

import numpy as np
from voxypy.models import Entity

# Empty model with shape (1, 2, 3)
entity = Entity(1, 2, 3)

# Entity from numpy array
data = np.array([1, 2, 3, 4]).reshape((2, 2, 1))
entity = Entity(data=data) # Shape is automatically set from array

# or with color palette
palette = [(255, 0, 0, 255), (0, 255, 0, 255), (0, 0, 255, 255)]
entity = Entity(data=data, palette=palette)

# or from an existing .vox file
entity = Entity().from_file('entity.vox')

Providing mismatched dimensions for x, y, z and data will throw an error.

Tricks

The methods get_dense and from_dense can be combined to allow invocation of any NumPy ndarray method

entity = (x=10, y=10, z=10) # 10x10x10 Entity full of zeros.
ones = entity.get_dense().fill(1)  # 10x10x10 ndarray full of ones.
entity.from_dense(ones)  # 10x10x10 Entity full of ones.
# one liner
entity.from_dense(entity.get_dense().fill(1))

Methods

  • get(x, y, z) - A Voxel object from Entity at [x, y, z]
    • x, y, z - Coordinates.

  • set(x, y, z, color) - Sets Entity at [x, y, z] to color and returns self.
    • x, y, z - Coordinates.

    • color - Either int(0-255) or a Voxel.

  • get_dense() - Returns a NumPy ndarray of dtype=int, where each int is a voxel color index.

  • from_dense(dense) - Overwrites Entity voxels with new data. Does not overwrite palette.
    • dense - 3d NumPy ndarray with dtype=int

  • write(filename) - Writes entity to a .vox file.
    • filename - String name of a file.

  • save(filename) - Wrapper for write()
    • filename - String name of a file.

  • from_file(filename) - Reads .vox file into an Entity, replacing existing data.
    • If the .vox file includes a color palette, it will also be read.

    • filename - String name of a file.

  • layers() - Generator for list of z-layers.

  • get_layer(z) - Returns layer at height z.

  • set_layer(z, layer) - Sets layer z of Entity to the contents of layer. Dimensions must match.
    • z - Z level at which to insert layer.

    • layer - 2d NumPy ndarray with dtype=int

  • flip() - Flips the entity along the Z (gravity) axis.

  • set_palette_from_file(filename) - Overwrites the entity’s color palette with a new one from a png file.
    • filename - String name of a file.

  • set_palette(palette) - Overwrites the entity’s color palette with one that you pass in.
    • Palettes are validated and padded to fill missing color indices.

    • palette - List of 4-tuples (R, G, B, A=255)

  • get_palette(padded=True) - Returns the entity’s color palette in a list of tuples.
    • padded - If True, color at index 0 will be blank. This is handy because index 0 is interpreted as blank in voxel editors.

  • nonzero() - Returns a list of tuples of the coordinates of the Entity which are not blank.
    • For example, [(0, 0, 0), (0, 0, 1) ... ]

Change Log

0.2.3

  • Added nonzero() to Entity

0.2.2

  • Fixed bad structure

0.2.1

  • Fixed missing imageio and Pillow requirements

0.2.0