Module voxelfuse.primitives
Functions for generating primitive solids.
Copyright 2020 - Cole Brauer, Dan Aukes
Expand source code
"""
Functions for generating primitive solids.
----
Copyright 2020 - Cole Brauer, Dan Aukes
"""
import numpy as np
from typing import Tuple
from voxelfuse.voxel_model import VoxelModel, generateMaterials
from voxelfuse.materials import material_properties
# Basic primitives
def empty(coords: Tuple[int, int, int] = (0, 0, 0), resolution: float = 1, num_materials: int = len(material_properties)):
"""
Create a VoxelModel containing a single empty voxel at the specified coordinates.
Args:
coords: Model origin coordinates
resolution: Number of voxels per mm
num_materials: Number of material types in materials vector
Returns:
VoxelModel
"""
return VoxelModel.empty((1, 1, 1), coords, resolution, num_materials)
def cube(size: int, coords: Tuple[int, int, int] = (0, 0, 0), material: int = 1, resolution: float = 1):
"""
Create a VoxelModel containing a cube.
Args:
size: Length of cube side in voxels
coords: Model origin coordinates
material: Material index corresponding to materials.py
resolution: Number of voxels per mm
Returns:
VoxelModel
"""
model_data = np.ones((size, size, size), dtype=np.uint16)
model = VoxelModel(model_data, generateMaterials(material), coords=coords, resolution=resolution)
return model
def cuboid(size: Tuple[int, int, int], coords: Tuple[int, int, int] = (0, 0, 0), material: int = 1, resolution: float = 1):
"""
Create a VoxelModel containing a cuboid.
Args:
size: Lengths of cuboid sides in voxels
coords: Model origin coordinates
material: Material index corresponding to materials.py
resolution: Number of voxels per mm
Returns:
VoxelModel
"""
model_data = np.ones((size[0], size[1], size[2]), dtype=np.uint16)
model = VoxelModel(model_data, generateMaterials(material), coords=coords, resolution=resolution)
return model
def sphere(radius: int, coords: Tuple[int, int, int] = (0, 0, 0), material: int = 1, resolution: float = 1):
"""
Create a VoxelModel containing a sphere.
Args:
radius: Radius of sphere in voxels
coords: Model origin coordinates
material: Material index corresponding to materials.py
resolution: Number of voxels per mm
Returns:
VoxelModel
"""
diameter = (radius*2) + 1 # +1 ensures there is a voxel centered on the origin
model_data = np.zeros((diameter, diameter, diameter), dtype=np.uint16)
for x in range(diameter):
for y in range(diameter):
for z in range(diameter):
xd = (x - radius)
yd = (y - radius)
zd = (z - radius)
r = np.sqrt(xd**2 + yd**2 + zd**2)
if r < (radius + .5):
model_data[x, y, z] = 1
model = VoxelModel(model_data, generateMaterials(material), coords=(coords[0]-radius, coords[1]-radius, coords[2]-radius), resolution=resolution)
return model
def ellipsoid(size: Tuple[int, int, int], coords: Tuple[int, int, int] = (0, 0, 0), material: int = 1, resolution: float = 1):
"""
Create a VoxelModel containing an ellipsoid.
Args:
size: Lengths of ellipsoid principal semi-axes in voxels
coords: Model origin coordinates
material: Material index corresponding to materials.py
resolution: Number of voxels per mm
Returns:
VoxelModel
"""
# lengths of principal semi-axes
a, b, c = size
# bounding box size (+1 ensures there is a voxel centered on the origin)
dx = (a*2) + 1
dy = (b*2) + 1
dz = (c*2) + 1
model_data = np.zeros((dx, dy, dz), dtype=np.uint16)
# check each voxel in the bounding box and determine if it falls inside the ellipsoid
for x in range(dx):
for y in range(dy):
for z in range(dz):
# get coords relative to origin
xx = (x - a)
yy = (y - b)
zz = (z - c)
# apply ellipsoid formula
f = np.sqrt(((xx ** 2) / (a **2)) +
((yy ** 2) / (b **2)) +
((zz ** 2) / (c **2)))
if f < 1:
model_data[x, y, z] = 1
model = VoxelModel(model_data, generateMaterials(material), coords=(coords[0] - a, coords[1] - b, coords[2] - c), resolution=resolution)
return model
def cylinder(radius: int, height: int, coords: Tuple[int, int, int] = (0, 0, 0), material: int = 1, resolution: float = 1):
"""
Create a VoxelModel containing a cylinder.
Args:
radius: Radius of cylinder in voxels
height: Height of cylinder in voxels
coords: Model origin coordinates
material: Material index corresponding to materials.py
resolution: Number of voxels per mm
Returns:
VoxelModel
"""
diameter = (radius * 2) + 1
model_data = np.zeros((diameter, diameter, 1), dtype=np.uint16)
for x in range(diameter):
for y in range(diameter):
xd = (x - radius)
yd = (y - radius)
r = np.sqrt(xd ** 2 + yd ** 2)
if r < (radius + .5):
model_data[x, y, 0] = 1
model_data = np.repeat(model_data, height, 2)
model = VoxelModel(model_data, generateMaterials(material), coords=(coords[0]-radius, coords[1]-radius, coords[2]), resolution=resolution)
return model
def cone(min_radius: int, max_radius: int, height: int, coords: Tuple[int, int, int] = (0, 0, 0), material: int = 1, resolution: float = 1):
"""
Create a VoxelModel containing a cylinder.
Args:
min_radius: Point radius of cone in voxels
max_radius: Base radius of cone in voxels
height: Height of cone in voxels
coords: Model origin coordinates
material: Material index corresponding to materials.py
resolution: Number of voxels per mm
Returns:
VoxelModel
"""
max_diameter = (max_radius*2)+1
model_data = np.zeros((max_diameter, max_diameter, height), dtype=np.uint16)
for z in range(height):
radius = (abs(max_radius - min_radius) * (((height-1) - z)/(height-1))) + min_radius
for x in range(max_diameter):
for y in range(max_diameter):
xd = (x - max_radius)
yd = (y - max_radius)
r = np.sqrt(xd ** 2 + yd ** 2)
if r < (radius + .5):
model_data[x, y, z] = 1
model = VoxelModel(model_data, generateMaterials(material), coords=(coords[0]-max_radius, coords[1]-max_radius, coords[2]), resolution=resolution)
return model
def pyramid(min_radius: int, max_radius: int, height: int, coords: Tuple[int, int, int] = (0, 0, 0), material: int = 1, resolution: float = 1):
"""
Create a VoxelModel containing a cylinder.
Args:
min_radius: Point radius of pyramid in voxels
max_radius: Base radius of pyramid in voxels
height: Height of pyramid in voxels
coords: Model origin coordinates
material: Material index corresponding to materials.py
resolution: Number of voxels per mm
Returns:
VoxelModel
"""
max_diameter = (max_radius * 2) + 1
model_data = np.zeros((max_diameter, max_diameter, height), dtype=np.uint16)
for z in range(height):
radius = round((abs(max_radius - min_radius) * (z / (height - 1))))
if radius == 0:
model_data[:, :, z].fill(1)
else:
model_data[radius:-radius, radius:-radius, z].fill(1)
model = VoxelModel(model_data, generateMaterials(material), coords=(coords[0]-max_radius, coords[1]-max_radius, coords[2]), resolution=resolution)
return model
def prism(size: Tuple[int, int, int], point_offset: int = 0, coords: Tuple[int, int, int] = (0, 0, 0), material: int = 1, resolution: float = 1):
"""
Create a VoxelModel containing a prism.
Args:
size: Size of prism in voxels (base,
point_offset: Distance that prism point is offset from model center in voxels
coords: Model origin coordinates
material: Material index corresponding to materials.py
resolution: Number of voxels per mm
Returns:
VoxelModel
"""
point_pos = (size[0]/2) + point_offset
min_x = min(0, round(point_pos))
max_x = max(size[0], round(point_pos))
dx = max_x - min_x
model_data = np.zeros((dx, size[1], size[2]), dtype=np.uint16)
for z in range(size[2]):
width = (size[0]/size[2])*(size[2] - z)
side_1_index = round((point_pos/size[2])*z) - min_x
side_2_index = round((point_pos/size[2])*z + width) - min_x
model_data[side_1_index:side_2_index, :, z].fill(1)
model = VoxelModel(model_data, generateMaterials(material), coords=(coords[0] + min_x, coords[1], coords[2]), resolution=resolution)
return model
Functions
def cone(min_radius: int, max_radius: int, height: int, coords: Tuple[int, int, int] = (0, 0, 0), material: int = 1, resolution: float = 1)
-
Create a VoxelModel containing a cylinder.
Args
min_radius
- Point radius of cone in voxels
max_radius
- Base radius of cone in voxels
height
- Height of cone in voxels
coords
- Model origin coordinates
material
- Material index corresponding to materials.py
resolution
- Number of voxels per mm
Returns
VoxelModel
Expand source code
def cone(min_radius: int, max_radius: int, height: int, coords: Tuple[int, int, int] = (0, 0, 0), material: int = 1, resolution: float = 1): """ Create a VoxelModel containing a cylinder. Args: min_radius: Point radius of cone in voxels max_radius: Base radius of cone in voxels height: Height of cone in voxels coords: Model origin coordinates material: Material index corresponding to materials.py resolution: Number of voxels per mm Returns: VoxelModel """ max_diameter = (max_radius*2)+1 model_data = np.zeros((max_diameter, max_diameter, height), dtype=np.uint16) for z in range(height): radius = (abs(max_radius - min_radius) * (((height-1) - z)/(height-1))) + min_radius for x in range(max_diameter): for y in range(max_diameter): xd = (x - max_radius) yd = (y - max_radius) r = np.sqrt(xd ** 2 + yd ** 2) if r < (radius + .5): model_data[x, y, z] = 1 model = VoxelModel(model_data, generateMaterials(material), coords=(coords[0]-max_radius, coords[1]-max_radius, coords[2]), resolution=resolution) return model
def cube(size: int, coords: Tuple[int, int, int] = (0, 0, 0), material: int = 1, resolution: float = 1)
-
Create a VoxelModel containing a cube.
Args
size
- Length of cube side in voxels
coords
- Model origin coordinates
material
- Material index corresponding to materials.py
resolution
- Number of voxels per mm
Returns
VoxelModel
Expand source code
def cube(size: int, coords: Tuple[int, int, int] = (0, 0, 0), material: int = 1, resolution: float = 1): """ Create a VoxelModel containing a cube. Args: size: Length of cube side in voxels coords: Model origin coordinates material: Material index corresponding to materials.py resolution: Number of voxels per mm Returns: VoxelModel """ model_data = np.ones((size, size, size), dtype=np.uint16) model = VoxelModel(model_data, generateMaterials(material), coords=coords, resolution=resolution) return model
def cuboid(size: Tuple[int, int, int], coords: Tuple[int, int, int] = (0, 0, 0), material: int = 1, resolution: float = 1)
-
Create a VoxelModel containing a cuboid.
Args
size
- Lengths of cuboid sides in voxels
coords
- Model origin coordinates
material
- Material index corresponding to materials.py
resolution
- Number of voxels per mm
Returns
VoxelModel
Expand source code
def cuboid(size: Tuple[int, int, int], coords: Tuple[int, int, int] = (0, 0, 0), material: int = 1, resolution: float = 1): """ Create a VoxelModel containing a cuboid. Args: size: Lengths of cuboid sides in voxels coords: Model origin coordinates material: Material index corresponding to materials.py resolution: Number of voxels per mm Returns: VoxelModel """ model_data = np.ones((size[0], size[1], size[2]), dtype=np.uint16) model = VoxelModel(model_data, generateMaterials(material), coords=coords, resolution=resolution) return model
def cylinder(radius: int, height: int, coords: Tuple[int, int, int] = (0, 0, 0), material: int = 1, resolution: float = 1)
-
Create a VoxelModel containing a cylinder.
Args
radius
- Radius of cylinder in voxels
height
- Height of cylinder in voxels
coords
- Model origin coordinates
material
- Material index corresponding to materials.py
resolution
- Number of voxels per mm
Returns
VoxelModel
Expand source code
def cylinder(radius: int, height: int, coords: Tuple[int, int, int] = (0, 0, 0), material: int = 1, resolution: float = 1): """ Create a VoxelModel containing a cylinder. Args: radius: Radius of cylinder in voxels height: Height of cylinder in voxels coords: Model origin coordinates material: Material index corresponding to materials.py resolution: Number of voxels per mm Returns: VoxelModel """ diameter = (radius * 2) + 1 model_data = np.zeros((diameter, diameter, 1), dtype=np.uint16) for x in range(diameter): for y in range(diameter): xd = (x - radius) yd = (y - radius) r = np.sqrt(xd ** 2 + yd ** 2) if r < (radius + .5): model_data[x, y, 0] = 1 model_data = np.repeat(model_data, height, 2) model = VoxelModel(model_data, generateMaterials(material), coords=(coords[0]-radius, coords[1]-radius, coords[2]), resolution=resolution) return model
def ellipsoid(size: Tuple[int, int, int], coords: Tuple[int, int, int] = (0, 0, 0), material: int = 1, resolution: float = 1)
-
Create a VoxelModel containing an ellipsoid.
Args
size
- Lengths of ellipsoid principal semi-axes in voxels
coords
- Model origin coordinates
material
- Material index corresponding to materials.py
resolution
- Number of voxels per mm
Returns
VoxelModel
Expand source code
def ellipsoid(size: Tuple[int, int, int], coords: Tuple[int, int, int] = (0, 0, 0), material: int = 1, resolution: float = 1): """ Create a VoxelModel containing an ellipsoid. Args: size: Lengths of ellipsoid principal semi-axes in voxels coords: Model origin coordinates material: Material index corresponding to materials.py resolution: Number of voxels per mm Returns: VoxelModel """ # lengths of principal semi-axes a, b, c = size # bounding box size (+1 ensures there is a voxel centered on the origin) dx = (a*2) + 1 dy = (b*2) + 1 dz = (c*2) + 1 model_data = np.zeros((dx, dy, dz), dtype=np.uint16) # check each voxel in the bounding box and determine if it falls inside the ellipsoid for x in range(dx): for y in range(dy): for z in range(dz): # get coords relative to origin xx = (x - a) yy = (y - b) zz = (z - c) # apply ellipsoid formula f = np.sqrt(((xx ** 2) / (a **2)) + ((yy ** 2) / (b **2)) + ((zz ** 2) / (c **2))) if f < 1: model_data[x, y, z] = 1 model = VoxelModel(model_data, generateMaterials(material), coords=(coords[0] - a, coords[1] - b, coords[2] - c), resolution=resolution) return model
def empty(coords: Tuple[int, int, int] = (0, 0, 0), resolution: float = 1, num_materials: int = 15)
-
Create a VoxelModel containing a single empty voxel at the specified coordinates.
Args
coords
- Model origin coordinates
resolution
- Number of voxels per mm
num_materials
- Number of material types in materials vector
Returns
VoxelModel
Expand source code
def empty(coords: Tuple[int, int, int] = (0, 0, 0), resolution: float = 1, num_materials: int = len(material_properties)): """ Create a VoxelModel containing a single empty voxel at the specified coordinates. Args: coords: Model origin coordinates resolution: Number of voxels per mm num_materials: Number of material types in materials vector Returns: VoxelModel """ return VoxelModel.empty((1, 1, 1), coords, resolution, num_materials)
def prism(size: Tuple[int, int, int], point_offset: int = 0, coords: Tuple[int, int, int] = (0, 0, 0), material: int = 1, resolution: float = 1)
-
Create a VoxelModel containing a prism.
Args
size
- Size of prism in voxels (base,
point_offset
- Distance that prism point is offset from model center in voxels
coords
- Model origin coordinates
material
- Material index corresponding to materials.py
resolution
- Number of voxels per mm
Returns
VoxelModel
Expand source code
def prism(size: Tuple[int, int, int], point_offset: int = 0, coords: Tuple[int, int, int] = (0, 0, 0), material: int = 1, resolution: float = 1): """ Create a VoxelModel containing a prism. Args: size: Size of prism in voxels (base, point_offset: Distance that prism point is offset from model center in voxels coords: Model origin coordinates material: Material index corresponding to materials.py resolution: Number of voxels per mm Returns: VoxelModel """ point_pos = (size[0]/2) + point_offset min_x = min(0, round(point_pos)) max_x = max(size[0], round(point_pos)) dx = max_x - min_x model_data = np.zeros((dx, size[1], size[2]), dtype=np.uint16) for z in range(size[2]): width = (size[0]/size[2])*(size[2] - z) side_1_index = round((point_pos/size[2])*z) - min_x side_2_index = round((point_pos/size[2])*z + width) - min_x model_data[side_1_index:side_2_index, :, z].fill(1) model = VoxelModel(model_data, generateMaterials(material), coords=(coords[0] + min_x, coords[1], coords[2]), resolution=resolution) return model
def pyramid(min_radius: int, max_radius: int, height: int, coords: Tuple[int, int, int] = (0, 0, 0), material: int = 1, resolution: float = 1)
-
Create a VoxelModel containing a cylinder.
Args
min_radius
- Point radius of pyramid in voxels
max_radius
- Base radius of pyramid in voxels
height
- Height of pyramid in voxels
coords
- Model origin coordinates
material
- Material index corresponding to materials.py
resolution
- Number of voxels per mm
Returns
VoxelModel
Expand source code
def pyramid(min_radius: int, max_radius: int, height: int, coords: Tuple[int, int, int] = (0, 0, 0), material: int = 1, resolution: float = 1): """ Create a VoxelModel containing a cylinder. Args: min_radius: Point radius of pyramid in voxels max_radius: Base radius of pyramid in voxels height: Height of pyramid in voxels coords: Model origin coordinates material: Material index corresponding to materials.py resolution: Number of voxels per mm Returns: VoxelModel """ max_diameter = (max_radius * 2) + 1 model_data = np.zeros((max_diameter, max_diameter, height), dtype=np.uint16) for z in range(height): radius = round((abs(max_radius - min_radius) * (z / (height - 1)))) if radius == 0: model_data[:, :, z].fill(1) else: model_data[radius:-radius, radius:-radius, z].fill(1) model = VoxelModel(model_data, generateMaterials(material), coords=(coords[0]-max_radius, coords[1]-max_radius, coords[2]), resolution=resolution) return model
def sphere(radius: int, coords: Tuple[int, int, int] = (0, 0, 0), material: int = 1, resolution: float = 1)
-
Create a VoxelModel containing a sphere.
Args
radius
- Radius of sphere in voxels
coords
- Model origin coordinates
material
- Material index corresponding to materials.py
resolution
- Number of voxels per mm
Returns
VoxelModel
Expand source code
def sphere(radius: int, coords: Tuple[int, int, int] = (0, 0, 0), material: int = 1, resolution: float = 1): """ Create a VoxelModel containing a sphere. Args: radius: Radius of sphere in voxels coords: Model origin coordinates material: Material index corresponding to materials.py resolution: Number of voxels per mm Returns: VoxelModel """ diameter = (radius*2) + 1 # +1 ensures there is a voxel centered on the origin model_data = np.zeros((diameter, diameter, diameter), dtype=np.uint16) for x in range(diameter): for y in range(diameter): for z in range(diameter): xd = (x - radius) yd = (y - radius) zd = (z - radius) r = np.sqrt(xd**2 + yd**2 + zd**2) if r < (radius + .5): model_data[x, y, z] = 1 model = VoxelModel(model_data, generateMaterials(material), coords=(coords[0]-radius, coords[1]-radius, coords[2]-radius), resolution=resolution) return model