Ejemplo n.º 1
0
def sphere(radius: int = 1,
           coords: Tuple[int, int, int] = (0, 0, 0),
           material: int = 1,
           resolution: float = 1):
    """
    Create a VoxelModel containing a sphere.

    :param radius: Radius of sphere in voxels
    :param coords: Model origin coordinates
    :param material: Material index corresponding to materials.py
    :param resolution: Number of voxels per mm
    :return: VoxelModel
    """
    diameter = (radius * 2) + 1
    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
Ejemplo n.º 2
0
def dither(model,
           radius=1,
           use_full=True,
           x_error=0.0,
           y_error=0.0,
           z_error=0.0,
           error_spread_threshold=0.8,
           blur=True,
           mem_use_log=[]):
    if radius == 0:
        return VoxelModel.copy(model)

    if blur:
        new_model = model.blur(radius)
        mem_use_log.append(memory_usage_psutil())
        new_model = new_model.scaleValues()
        mem_use_log.append(memory_usage_psutil())
    else:
        new_model = model.scaleValues()
        mem_use_log.append(memory_usage_psutil())

    full_model = toFullMaterials(new_model.voxels, new_model.materials,
                                 len(material_properties) + 1)
    mem_use_log.append(memory_usage_psutil())
    full_model = ditherOptimized(full_model, use_full, x_error, y_error,
                                 z_error, error_spread_threshold)
    mem_use_log.append(memory_usage_psutil())

    return toIndexedMaterials(full_model, model), mem_use_log
Ejemplo n.º 3
0
def pyramid(min_radius: int = 0,
            max_radius: int = 4,
            height: int = 5,
            coords: Tuple[int, int, int] = (0, 0, 0),
            material: int = 1,
            resolution: float = 1):
    """
    Create a VoxelModel containing a cylinder.

    :param min_radius: Point radius of pyramid in voxels
    :param max_radius: Base radius of pyramid in voxels
    :param height: Height of pyramid in voxels
    :param coords: Model origin coordinates
    :param material: Material index corresponding to materials.py
    :param resolution: Number of voxels per mm
    :return: 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
Ejemplo n.º 4
0
    def setModel(self, voxel_model):
        """
        Set the model for a simulation.

        Models located at positive coordinate values will have their workspace
        size adjusted to maintain their position in the exported simulation.
        Models located at negative coordinate values will be shifted to the origin.

        :param voxel_model: VoxelModel
        :return: None
        """
        # Fit workspace and union with an empty object at the origin to clear offsets if object is raised
        self.__model = (VoxelModel.copy(voxel_model).fitWorkspace()) | empty()
Ejemplo n.º 5
0
def empty(coords: Tuple[int, int, int] = (0, 0, 0), resolution: float = 1):
    """
    Create a VoxelModel containing a single empty voxel at the specified coordinates.

    :param coords: Model origin coordinates
    :param resolution: Number of voxels per mm
    :return: VoxelModel
    """
    model_data = np.zeros((1, 1, 1), dtype=np.uint16)
    materials = np.zeros((1, len(material_properties) + 1), dtype=np.float)
    model = VoxelModel(model_data,
                       materials,
                       coords=coords,
                       resolution=resolution)
    return model
Ejemplo n.º 6
0
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)
Ejemplo n.º 7
0
def schwarzD(size: Tuple[int, int, int] = (15, 15, 15),
             scale: int = 15,
             coords: Tuple[int, int, int] = (0, 0, 0),
             material1: int = 1,
             material2: int = 2,
             resolution: float = 1):
    """
    Generate a Schwarz D-surface over a rectangular region.

    This function will generate two models representing the "positive" and
    "negative" halves of the pattern. If a thin surface is desired,
    these two models can be dilated and the intersection of the results found.
    However, due to the voxel-based representation, this "surface" will have
    a non-zero thickness.

    Args:
        size: Size of rectangular region
        scale: Period of the surface function in voxels
        coords: Model origin coordinates
        material1: Material index for negative model, corresponds to materials.py
        material2: Material index for positive model, corresponds to materials.py
        resolution: Number of voxels per mm
    
    Returns:
        Negative model, Positive model
    """
    s = (2 * math.pi) / scale  # scaling multipler

    modelData = np.zeros((size[0], size[1], size[2]), dtype=np.uint16)
    surface_model_inner = VoxelModel(modelData,
                                     generateMaterials(material1),
                                     coords=coords,
                                     resolution=resolution)
    surface_model_outer = VoxelModel(modelData,
                                     generateMaterials(material2),
                                     coords=coords,
                                     resolution=resolution)

    for x in tqdm(range(size[0]), desc='Generating Gyroid'):
        for y in range(size[1]):
            for z in range(size[2]):
                t_calc = math.sin(x * s) * math.sin(y * s) * math.sin(z * s)
                t_calc = math.sin(x * s) * math.cos(y * s) * math.cos(
                    z * s) + t_calc
                t_calc = math.cos(x * s) * math.sin(y * s) * math.cos(
                    z * s) + t_calc
                t_calc = math.cos(x * s) * math.cos(y * s) * math.sin(
                    z * s) + t_calc

                if t_calc < 0:
                    surface_model_inner.voxels[x, y, z] = 1
                else:
                    surface_model_outer.voxels[x, y, z] = 1

    return surface_model_inner, surface_model_outer
Ejemplo n.º 8
0
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
Ejemplo n.º 9
0
    def marchingCubes(cls,
                      voxel_model: VoxelModel,
                      smooth: bool = False,
                      color: Tuple[float, float, float,
                                   float] = (0.8, 0.8, 0.8, 1)):
        """
        Generate a mesh object from a VoxelModel object using a marching cubes algorithm.

        This meshing approach is best suited to high resolution models where some smoothing is acceptable.

        Args:
            voxel_model: VoxelModel object to be converted to a mesh
            smooth: Enable smoothing
            color: Mesh color in the format (r, g, b, a)
        
        Returns:
            None
        """
        voxel_model_fit = voxel_model.fitWorkspace().getOccupied()
        voxels = voxel_model_fit.voxels.astype(np.uint16)
        x, y, z = voxels.shape
        model_offsets = voxel_model_fit.coords

        voxels_padded = np.zeros((x + 2, y + 2, z + 2))
        voxels_padded[1:-1, 1:-1, 1:-1] = voxels

        if smooth:
            voxels_padded = mcubes.smooth(voxels_padded)
            levelset = 0
        else:
            levelset = 0.5

        verts, tris = mcubes.marching_cubes(voxels_padded, levelset)

        # Shift model to align with origin
        verts = np.subtract(verts, 0.5)
        verts[:, 0] = np.add(verts[:, 0], model_offsets[0])
        verts[:, 1] = np.add(verts[:, 1], model_offsets[1])
        verts[:, 2] = np.add(verts[:, 2], model_offsets[2])

        verts_colors = generateColors(len(verts), color)

        return cls(voxels_padded, verts, verts_colors, tris,
                   voxel_model.resolution)
Ejemplo n.º 10
0
def cuboid(size: Tuple[int, int, int] = (1, 1, 1),
           coords: Tuple[int, int, int] = (0, 0, 0),
           material: int = 1,
           resolution: float = 1):
    """
    Create a VoxelModel containing a cuboid.

    :param size: Lengths of cuboid sides in voxels
    :param coords: Model origin coordinates
    :param material: Material index corresponding to materials.py
    :param resolution: Number of voxels per mm
    :return: 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
Ejemplo n.º 11
0
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
Ejemplo n.º 12
0
def toIndexedMaterials(voxels, model):
    x_len = model.voxels.shape[0]
    y_len = model.voxels.shape[1]
    z_len = model.voxels.shape[2]

    new_voxels = np.zeros((x_len, y_len, z_len), dtype=np.int32)
    new_materials = np.zeros((1, len(material_properties) + 1),
                             dtype=np.float32)

    for x in range(x_len):
        for y in range(y_len):
            for z in range(z_len):
                m = voxels[x, y, z, :]
                i = np.where(np.equal(new_materials, m).all(1))[0]

                if len(i) > 0:
                    new_voxels[x, y, z] = i[0]
                else:
                    new_materials = np.vstack((new_materials, m))
                    new_voxels[x, y, z] = len(new_materials) - 1

    return VoxelModel(new_voxels, new_materials, model.coords)
Ejemplo n.º 13
0
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
Ejemplo n.º 14
0
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
Ejemplo n.º 15
0
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
    app1 = qg.QApplication(sys.argv)

    # Settings
    # scaleFactor = 1 # Scale the model to increase/decrease resolution
    trim = True # Remove end bumps
    cleanup = False # Remove duplicate materials and save file
    export = True # STL file for slicing
    display = False # Display output

    # Open File
    location = 'stl_files_v3_combined/output-'
    variations = ['A', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K']

    for var in variations:
        file = location + var + '.vf'
        model = VoxelModel.openVF(file)

        # Remove end bumps
        if trim:
            modelCutTool1 = cuboid((model.voxels.shape[0], model.voxels.shape[1], 12), (0, 0, model.voxels.shape[2] - 12), 3)
            modelCutTool2 = cuboid((1, model.voxels.shape[1], model.voxels.shape[2]), (0, 0, 0), 3)
            modelCutTool3 = cuboid((1, model.voxels.shape[1], model.voxels.shape[2]), (model.voxels.shape[0] - 1, 0, 0), 3)
            model = model.difference(modelCutTool1 | modelCutTool2 | modelCutTool3)
            model = model.fitWorkspace()
            model.coords = (0, 0, 0)

        # Apply scale factor
        # model = model.scale(scaleFactor)

        # Apply rubber material
        # modelRubber = model.isolateMaterial(1)
# Start Application
if __name__=='__main__':
    app1 = qg.QApplication(sys.argv)

    transitionWidth = 12
    transitionCenter = 71.1
    materialToMeasure = 1

    largestOnly = True # Only look at the largest component of each material
    cleanup = False # Remove duplicate materials
    display = False # Display output

    # Open File
    # file = 'stl_files_v4.2_combined/output_K'
    file = 'stl_files_fdm_v1/output_J'
    model = VoxelModel.openVF(file)
    model.resolution = 5 # Manually set resolution if not set in file
    res = model.resolution

    # Define a region in which to calculate the contact area
    testRegionSize = (round(transitionWidth*res*1.75), model.voxels.shape[1], model.voxels.shape[2])
    testRegionLocation = (model.coords[0] + round(transitionCenter*res) - round(testRegionSize[0]*.5), model.coords[1], model.coords[2])
    test_region = cuboid(testRegionSize, testRegionLocation, material=3, resolution=res)

    # Cleanup operations
    if cleanup:
        model.materials = np.round(model.materials, 3)
        model = model.removeDuplicateMaterials()

    # Crop the model to the region of interest
    model_cropped = VoxelModel.emptyLike(model)
Ejemplo n.º 18
0
    fixture = True
    fixtureWallThickness = 5
    fixtureGap = 1

    mold = True
    moldWallThickness = 2
    moldGap = 1

    export = False

    app1 = qg.QApplication(sys.argv)

    # Import coupon components
    if stl:
        # TODO: Improve dimensional accuracy of stl model import and use these files instead of vox file
        end1 = VoxelModel.fromMeshFile('end1.stl', (0, 0, 0))
        center = VoxelModel.fromMeshFile('center.stl', (67, 3, 0))
        end2 = VoxelModel.fromMeshFile('end2.stl', (98, 0, 0))

        # Set materials
        end1 = end1.setMaterial(1)
        end2 = end2.setMaterial(1)
        center = center.setMaterial(2)

        # Combine components
        coupon = Linkage.copy(end1.union(center.union(end2)))
    else:  # use vox file
        coupon = Linkage.fromVoxFile(
            'coupon.vox')  # Should use materials 1 and 2 (red and green)

    # Apply effects to material interface
def thin(model, max_iter):
    x_len = model.voxels.shape[0] + 4
    y_len = model.voxels.shape[1] + 4
    z_len = model.voxels.shape[2] + 4

    struct = ndimage.generate_binary_structure(3, 3)

    sphere = np.zeros((5, 5, 5), dtype=np.int32)
    for x in range(5):
        for y in range(5):
            for z in range(5):
                xd = (x - 2)
                yd = (y - 2)
                zd = (z - 2)
                r = np.sqrt(xd ** 2 + yd ** 2 + zd ** 2)

                if r < 2.5:
                    sphere[x, y, z] = 1

    input_model = VoxelModel(np.zeros((x_len, y_len, z_len), dtype=np.int32), model.materials, model.coords)
    input_model.voxels[2:-2, 2:-2, 2:-2] = model.voxels
    new_model = VoxelModel.emptyLike(input_model)

    for i in tqdm(range(max_iter), desc='Thinning'):
        # Find exterior voxels
        interior_voxels = input_model.erode(radius=1, plane=Axes.XYZ, structType=Struct.STANDARD, connectivity=1)
        exterior_voxels = input_model.difference(interior_voxels)

        x_len = len(exterior_voxels.voxels[:, 0, 0])
        y_len = len(exterior_voxels.voxels[0, :, 0])
        z_len = len(exterior_voxels.voxels[0, 0, :])

        # Create list of exterior voxel coordinates
        exterior_coords = []
        for x in range(x_len):
            for y in range(y_len):
                for z in range(z_len):
                    if exterior_voxels.voxels[x, y, z] != 0:
                        exterior_coords.append([x, y, z])

        # Store voxels that must be part of the center line
        for coords in exterior_coords:
            x = coords[0]
            y = coords[1]
            z = coords[2]

            if input_model.voxels[x,y,z] != 0:
                # Get matrix of neighbors
                n = np.copy(input_model.voxels[x - 2:x + 3, y - 2:y + 3, z - 2:z + 3])
                n[n != 0] = 1

                # Find V - number of voxels near current along xyz axes
                Vx = np.sum(n[:, 2, 2])
                Vy = np.sum(n[2, :, 2])
                Vz = np.sum(n[2, 2, :])

                # Subtract sphere
                n = n - sphere
                n[n < 1] = 0

                # Check if subtraction split model
                C = ndimage.label(n, structure=struct)[1]

                # Apply conditions
                if (C > 1) or (Vx <= 2) or (Vy <= 2) or (Vz <= 2):
                    new_model.voxels[x, y, z] = input_model.voxels[x, y, z]

        if np.sum(interior_voxels.voxels) < 1:
            break
        else:
            input_model = VoxelModel.copy(interior_voxels)

    new_model = new_model.union(input_model)

    return new_model
Ejemplo n.º 20
0
from voxelfuse.voxel_model import VoxelModel
from voxelfuse.mesh import Mesh
from voxelfuse.plot import Plot

if __name__ == '__main__':
    app1 = qg.QApplication(sys.argv)

    # User preferences
    modelName = 'boxes.vox'
    #modelName = 'joint2.1.vox'
    blur = [1, 2]  # materials to blur
    blurRadius = 3

    # Import model
    modelIn = VoxelModel.fromVoxFile(modelName)

    # Isolate materials with blurring requested
    modelBlur = VoxelModel.emptyLike(modelIn)
    for i in blur:
        modelBlur = modelBlur + modelIn.isolateMaterial(i)

    # Blur compatible materials
    # modelBlur = modelBlur.dither(blurRadius)
    modelBlur = modelBlur.blur(blurRadius)

    # Add unmodified voxels to result
    modelResult = modelBlur.union(modelIn)

    # Clean up result
    modelResult = modelResult.scaleValues()
            )  # 0/1 min radius that results in a printable structure
            maxRadius = config.get(
                'maxRadius'
            )  # 3/5 max radius that results in a viable lattice element

        if gyroidEnable:
            gyroidType = config.get('gyroidType')
            gyroidMaxDilate = config.get('gyroidMaxDilate')
            gyroidMaxErode = config.get('gyroidMaxErode')

        app1 = qg.QApplication(sys.argv)

        # Import coupon components
        print('Importing Files')
        end1 = VoxelModel.fromMeshFile('coupon_templates/' + couponStandard +
                                       '-End.stl', (0, 0, 0),
                                       resolution=res).fitWorkspace()
        center = VoxelModel.fromMeshFile('coupon_templates/' + couponStandard +
                                         '-Center-2.stl', (0, 0, 0),
                                         resolution=res).fitWorkspace()
        end2 = end1.rotate90(2, axis=Axes.Z)
        center.coords = (end1.voxels.shape[0],
                         round(
                             (end1.voxels.shape[1] - center.voxels.shape[1]) /
                             2), 0)
        end2.coords = (end1.voxels.shape[0] + center.voxels.shape[0], 0, 0)

        # Trim center
        center_cross_section = VoxelModel(center.voxels[0:2, :, :],
                                          3).fitWorkspace()
        centerLength = center.voxels.shape[0]
Ejemplo n.º 22
0
from voxelfuse.mesh import Mesh
from voxelfuse.plot import Plot
from voxelfuse.primitives import *

# Start Application
if __name__=='__main__':
    app1 = qg.QApplication(sys.argv)

    res = 5 # voxels per mm
    clearance = 50
    defaultModelName = 'stl_files_v5_combined/output_B1_default'
    normalizedModelName = 'stl_files_v5_combined/output_B2_normalized'

    # Open Files
    outputFolder = 'stl_files_v5_combined/'
    dModel = VoxelModel.openVF(defaultModelName)
    nModel = VoxelModel.openVF(normalizedModelName)

    # Markers
    size = dModel.voxels.shape
    markerSize = int((size[2] * 0.7)/2) * 2
    marker1 = cylinder(int(markerSize/2), size[2], (0, 0, 0), resolution=res)
    marker2 = marker1 | cylinder(int(markerSize/2), size[2], (0, markerSize*2, 0), resolution=res)
    marker3 = marker2 | cylinder(int(markerSize/2), size[2], (0, markerSize*4, 0), resolution=res)

    # Init result model
    resultModel = VoxelModel.emptyLike(dModel)

    # Add vertical coupons
    resultModel = resultModel | dModel.setCoords((0, 0, 0))
    resultModel = resultModel | nModel.setCoords((350, 100 + clearance, 0))
Ejemplo n.º 23
0
Used by the Mesh class to improve meshing speed.

----

Copyright 2019 - Cole Brauer, Dan Aukes
"""

from voxelfuse.voxel_model import VoxelModel

if __name__=='__main__':
    # User preferences
    modelName = 'cylinder-blue.vox'

    # Import model
    model1 = VoxelModel.fromVoxFile(modelName, (0, 0, 0))

    # Find exterior voxels
    interiorVoxels = model1.erode(radius=1, connectivity=1)
    exteriorVoxels = model1.difference(interiorVoxels)

    x_len = len(exteriorVoxels.voxels[:, 0, 0])
    y_len = len(exteriorVoxels.voxels[0, :, 0])
    z_len = len(exteriorVoxels.voxels[0, 0, :])

    # Create list of exterior voxel coordinates
    exterior_voxels = []
    for x in range(x_len):
        for y in range(y_len):
            for z in range(z_len):
                if exteriorVoxels.voxels[x, y, z] != 0:
Ejemplo n.º 24
0
import numpy as np
import time

from voxelfuse.voxel_model import VoxelModel, Axes, Process
from voxelfuse.mesh import Mesh
from voxelfuse.materials import material_properties

if __name__ == '__main__':
    # User preferences
    modelName = 'joint-2.vox'
    # modelName = 'tail-holder-1r.vox'

    # Import model
    start = time.time()
    modelIn = VoxelModel.fromVoxFile(modelName)
    end = time.time()
    importTime = (end - start)

    start = time.time()

    # Rotate to best orientation for printing
    modelIn = modelIn.rotate90(axis=Axes.Y)

    # Initialize object to hold result
    modelResult = VoxelModel.copy(modelIn)

    # Initialize array for identifying library materials
    library_materials = np.identity(len(material_properties))
    library_materials[0, 0] = 0
    a = np.ones((len(material_properties), 1))
Ejemplo n.º 25
0
Import a mesh file and convert it to voxels.

----

Copyright 2019 - Cole Brauer, Dan Aukes
"""

import PyQt5.QtGui as qg
import sys
from voxelfuse.voxel_model import VoxelModel
from voxelfuse.mesh import Mesh
from voxelfuse.plot import Plot

if __name__ == '__main__':
    app1 = qg.QApplication(sys.argv)

    # Import model file
    model = VoxelModel.fromMeshFile('axes.stl', (0, 0, 0))

    # To use a copy of gmsh on the system path, replace line 21 with the following:
    # model = VoxelModel.fromMeshFile('axes.stl', (0, 0, 0), gmsh_on_path=True)

    # Create new mesh data for plotting
    mesh1 = Mesh.fromVoxelModel(model)

    # Create plot
    plot1 = Plot(mesh1, grids=True)
    plot1.show()

    app1.processEvents()
    app1.exec_()
    app1 = qg.QApplication(sys.argv)

    cleanup = False  # Remove duplicate materials

    # Open File
    couponsIDs = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K']
    #folder = 'stl_files_v3_combined/output-'
    folder = 'stl_files_v4.2_combined/output_'

    rigidMaterial = 2
    flexibleMaterial = 1
    rigidPercentages = np.zeros(len(couponsIDs))
    flexiblePercentages = np.zeros(len(couponsIDs))

    for pattern in range(len(couponsIDs)):
        model = VoxelModel.openVF(folder + couponsIDs[pattern])
        model.resolution = 5  # Manually set resolution if not set in file
        res = model.resolution

        # Cleanup operations
        if cleanup:
            model.materials = np.round(model.materials, 3)
            model = model.removeDuplicateMaterials()

        _, totalVolume = model.getVolume()
        _, rigidVolume = model.getVolume(material=rigidMaterial)
        _, flexibleVolume = model.getVolume(material=flexibleMaterial)

        rigidPercentages[pattern] = rigidVolume / totalVolume
        flexiblePercentages[pattern] = flexibleVolume / totalVolume
Ejemplo n.º 27
0
    moldWallThickness = 2
    moldGap = 1

    fixture = True
    fixtureWallThickness = 5
    fixtureGap = 1

    export = False

    app1 = qg.QApplication(sys.argv)

    # Import coupon components
    print('Importing Files')
    if stl:
        if highRes:
            end1 = VoxelModel.fromMeshFile('end1x10.stl', (0, 0, 0), 1)
            center = VoxelModel.fromMeshFile('centerx10.stl', (670, 30, 0), 2)
            end2 = VoxelModel.fromMeshFile('end2x10.stl', (980, 0, 0), 1)
        else:
            end1 = VoxelModel.fromMeshFile('end1.stl', (0, 0, 0), 1)
            center = VoxelModel.fromMeshFile('center.stl', (66, 4, 0), 2)
            end2 = VoxelModel.fromMeshFile('end2.stl', (98, 0, 0), 1)

        # Combine components
        coupon = end1 | center | end2
    else: # use vox file
        coupon = VoxelModel.fromVoxFile('coupon.vox') # Should use materials 1 and 2 (red and green)

    start = time.time()

    if blur: # Blur materials
Ejemplo n.º 28
0
    display = False  # Display output
    cleanup = True  # Remove duplicate materials and save file
    export = True  # STL file for slicing

    # Open Files
    outputFolder = 'stl_files_fdm_v1/'
    outputFile = 'output_combined'
    files = [
        'output_A', 'output_D', 'output_E', 'output_F', 'output_G', 'output_H',
        'output_I', 'output_J', 'output_K'
    ]
    # files = ['output_J', 'output_K']

    model = empty(resolution=res)
    for i in range(len(files)):
        new_model = VoxelModel.openVF(outputFolder + files[i])
        new_model = new_model.setCoords((0, i * 110, 0))
        model = model | new_model

    # Cleanup operations
    if cleanup:
        model.materials = np.round(model.materials, 1)
        model = model.removeDuplicateMaterials()
        model.saveVF(outputFolder + outputFile)

    # Create stl files
    if export:
        for m in range(1, len(model.materials)):
            mesh = Mesh.fromVoxelModel(model.isolateMaterial(m),
                                       resolution=res)
            mesh.export(
Ejemplo n.º 29
0
Copyright 2020 - Cole Brauer, Dan Aukes
"""

# Import Libraries
import numpy as np
from voxelfuse.voxel_model import VoxelModel
from voxelfuse.mesh import Mesh
from voxelfuse.primitives import cylinder

# Start Application
if __name__ == '__main__':
    dilate_radius = 2

    # Import element template
    T = VoxelModel.fromVoxFile('lattice_element_1m.vox')
    T = T.dilateBounded(dilate_radius)

    # Create target volume model
    M = cylinder(30, 60).translate((30, 30, 0))
    M = M.setCoords((0, 0, 0))

    t = T.voxels.shape[0]
    size = M.voxels.shape

    # Create empty model to hold result
    V = VoxelModel.empty(size)

    # Add tiled lattice elements
    for x in range(int(np.ceil(size[0] / t))):
        for y in range(int(np.ceil(size[1] / t))):
import PyQt5.QtGui as qg
import sys
import time
from voxelfuse.voxel_model import VoxelModel
from voxelfuse.mesh import Mesh
from voxelfuse.plot import Plot

# Start Application
if __name__ == '__main__':
    app1 = qg.QApplication(sys.argv)

    min_radius = 3  # min radius that results in a printable structure
    max_radius = 6  # max radius that results in a viable lattice element

    # Import Models
    latticeModel = VoxelModel.fromVoxFile(
        'lattice_elements/lattice_element_1_30x30.vox')
    lattice_size = latticeModel.voxels.shape[0]

    start = time.time()

    # Process Model
    modelResult = VoxelModel.copy(latticeModel)
    modelResult1 = modelResult.dilateBounded(min_radius)
    modelResult2 = modelResult.dilateBounded(max_radius)

    end = time.time()
    m1Time = (end - start)
    print(m1Time)

    # Create Mesh
    mesh1 = Mesh.fromVoxelModel(modelResult1)