# 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] if len(i) > 0: if material_properties[i[0]]['process'] == 'ins': insertedComponents = insertedComponents.union( modelIn.isolateMaterial(m).dilate()) # Find clearance for inserted components insertedComponentsClearance = insertedComponents.clearance(Process.INSERT) pauseLayers = []
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) if largestOnly: # Isolate the region of the model that intersects with the test region model_cropped_all_components = model & test_region # Loop through each material in model for m in range(1, len(model_cropped.materials)): model_current_material = model_cropped_all_components.isolateMaterial(m) model_current_material = model_current_material.getComponents() # Find the volume of each component made of this material componentVolumes = np.zeros(model_current_material.numComponents+1) for c in range(1, model_current_material.numComponents+1): componentVolumes[c], _ = model_current_material.getVolume(component=c) # Identify the largest component and add to cropped model
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
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() # Create mesh data mesh1 = Mesh.fromVoxelModel(modelIn)
(center.coords[0] - (blurRadius * res) + newCenterLength, 0, 0), 3) transition_regions = transition_1 | transition_2 transition_regions = transition_regions.getComponents() # Generate lattice elements latticeSize = None lattice_elements = None if latticeEnable: # Import Models lattice_model = VoxelModel.fromVoxFile("lattice_elements/" + latticeElementFile + '.vox') latticeSize = lattice_model.voxels.shape[0] print('Lattice Element Imported') # Generate Dilated Lattice Elements lattice_elements = [VoxelModel.emptyLike(lattice_model)] for r in range(minRadius, maxRadius + 1): lattice_elements.append(lattice_model.dilate(r)) lattice_elements.append(cuboid(lattice_model.voxels.shape)) print('Lattice Elements Generated') elif gyroidEnable: # Import Models s = center.voxels.shape[2] if gyroidType == 2: lattice_model_1, lattice_model_2 = schwarzP((s, s, s), s) elif gyroidType == 3: lattice_model_1, lattice_model_2 = schwarzD((s, s, s), s) elif gyroidType == 4: lattice_model_1, lattice_model_2 = FRD((s, s, s), s)
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)) resultModel = resultModel | dModel.setCoords((750, 200 + 2 * clearance, 0)) resultModel = resultModel | nModel.setCoords((0, 1300 - 2 * clearance, 0)) resultModel = resultModel | dModel.setCoords((350, 1400 - clearance, 0)) resultModel = resultModel | nModel.setCoords((750, 1500, 0)) resultModel = resultModel.difference(marker1.setCoords((0 + markerSize, 0 + markerSize, 0))) resultModel = resultModel.difference(marker2.setCoords((350 + markerSize, 100 + clearance + markerSize, 0))) resultModel = resultModel.difference(marker3.setCoords((750 + markerSize, 200 + 2 * clearance + markerSize, 0))) resultModel = resultModel.difference(marker1.setCoords((0 + markerSize, 1300 - 2 * clearance + markerSize, 0))) resultModel = resultModel.difference(marker2.setCoords((350 + markerSize, 1400 - clearance + markerSize, 0))) resultModel = resultModel.difference(marker3.setCoords((750 + markerSize, 1500 + markerSize, 0)))