Example #1
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
Example #2
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()
Example #3
0
    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))
    a[0, 0] = 0
    library_materials = np.hstack((a, library_materials))

    # Initialize object to hold inserted components
    insertedComponents = VoxelModel.emptyLike(modelResult)

    # Find inserted components
    for m in range(len(modelIn.materials)):
        i = np.where(np.equal(library_materials,
                              modelIn.materials[m]).all(1))[0]
Example #4
0
        tab_template = VoxelModel.fromVoxFile('tab_' + tabDesign + '.vox')

        # Set tab locations
        xVals = [79, 46]
        yVals = [9, 9]
        rVals = [0, 2]

        # Generate tabs
        coupon = coupon.insertTabs(tab_template, xVals, yVals, rVals)

    if blur:  # Blur materials
        coupon = coupon.blur(blurRadius)
        coupon = coupon.scaleValues()

    # Add support features
    coupon_supported = VoxelModel.copy(coupon)

    if mold:  # Generate mold feature around material 2
        # Find all voxels containing <50% material 2
        material_vector = np.zeros(len(material_properties) + 1)
        material_vector[0] = 1
        material_vector[3] = 0.5
        printed_components = coupon - coupon.setMaterialVector(material_vector)
        printed_components.materials = np.around(printed_components.materials,
                                                 0)
        printed_components = printed_components.scaleValues()

        # Find voxels containing >50% material 2
        cast_components = coupon.difference(printed_components)

        # Generate mold body
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
        # Combine components
        coupon = end1 | center | end2
        coupon = coupon.setMaterial(1)

        # Scaled center
        newCenterLength = round(centerLength * centerLengthScale)
        centerCoordsOffset = (center.coords[0] + round(
            (centerLength - newCenterLength) / 2), center.coords[1],
                              center.coords[2])
        center = cuboid((newCenterLength, centerWidth, centerHeight),
                        centerCoordsOffset)
        center = center.setMaterial(2)
        coupon = center | coupon

        coupon_input = VoxelModel.copy(coupon)

        start = time.time()

        # Generate transition regions
        transition_1 = cuboid((blurRadius * res * 2, coupon.voxels.shape[1],
                               coupon.voxels.shape[2]),
                              (center.coords[0] - (blurRadius * res), 0, 0), 3)
        transition_2 = cuboid(
            (blurRadius * res * 2, coupon.voxels.shape[1],
             coupon.voxels.shape[2]),
            (center.coords[0] - (blurRadius * res) + newCenterLength, 0, 0), 3)
        transition_regions = transition_1 | transition_2
        transition_regions = transition_regions.getComponents()

        # Generate lattice elements
# 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)
    mesh2 = Mesh.fromVoxelModel(modelResult2)

    # Create Plot
    plot1 = Plot(mesh1)
    plot1.show()
Example #8
0
    def __init__(self, voxel_model):
        """
        Initialize a Simulation object with default settings.

        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
        """
        # 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()

        # Simulator ##############
        # Integration
        self.__integrator = 0
        self.__dtFraction = 1.0

        # Damping
        self.__dampingBond = 1.0  # (0-1) Bulk material damping
        self.__dampingEnvironment = 0.0001  # (0-0.1) Damping caused by fluid environment

        # Collisions
        self.__collisionEnable = False
        self.__collisionDamping = 1.0  # (0-2) Elastic vs inelastic conditions
        self.__collisionSystem = 3
        self.__collisionHorizon = 3

        # Features
        self.__blendingEnable = False
        self.__xMixRadius = 0
        self.__yMixRadius = 0
        self.__zMixRadius = 0
        self.__blendingModel = 0
        self.__polyExp = 1
        self.__volumeEffectsEnable = False

        # Stop conditions
        self.__stopConditionType = StopCondition.NONE
        self.__stopConditionValue = 0.0

        # Equilibrium mode
        self.__equilibriumModeEnable = False

        # Environment ############
        # Boundary conditions
        self.__bcRegions = []
        self.__bcVoxels = []

        # Gravity
        self.__gravityEnable = True
        self.__gravityValue = -9.81
        self.__floorEnable = True

        # Thermal
        self.__temperatureEnable = False
        self.__temperatureBaseValue = 25.0
        self.__temperatureVaryEnable = False
        self.__temperatureVaryAmplitude = 0.0
        self.__temperatureVaryPeriod = 0.0

        # Sensors #######
        self.__sensors = []

        # Temperature Controls #######
        self.__tempControls = []

        # Results ################
        self.results = []
        self.valueMap = np.zeros_like(voxel_model.voxels, dtype=np.float32)