def combinePrimatives(self, shapeList): """ combines the stl of two primitives :param shapeList: a list of primitives to merge with the first :return: the axes of the new stl """ # Create a new plot figure = plt.figure() axes = mplot3d.Axes3D(figure) # Combine shape primitives shape1Mesh = self.generateMesh() combined = mesh.Mesh(shape1Mesh.data) for shape in shapeList: shapeMesh = shape.generateMesh() combined = mesh.Mesh( numpy.concatenate([combined.data, shapeMesh.data])) # Load the STL files and add the vectors to the plot axes.add_collection3d( mplot3d.art3d.Poly3DCollection(combined.vectors, edgecolor='k')) scale = combined.points.flatten() axes.auto_scale_xyz(scale, scale, scale) axes.set_xlabel('X (mm)') axes.set_ylabel('Y (mm)') axes.set_zlabel('Z (mm)') return axes
def extrude(img, depth, blur=None): img = np.array(img) gray_img = preprocess(img, blur) # creates vertices from image with the height of the cube being based off of the pixels height vertices_array = [] min = np.amin(gray_img) max = np.amax(gray_img) for y, column in enumerate(gray_img): for x, pixel in enumerate(column): pixel = ((pixel - min) / (max - min)) * depth if pixel > 0.1 * depth: pixel = pixel - 0.1 * depth + 1 else: pixel = 1 vertices = np.array([ \ [x, y, 0], [x + 1, y, 0], [x + 1, y + 1, 0], [x, y + 1, 0], [x, y, pixel], [x + 1, y, pixel], [x + 1, y + 1, pixel], [x, y + 1, pixel], ]) vertices_array.append(vertices) faces = np.array([[0, 3, 1], [1, 3, 2], [0, 4, 7], [0, 7, 3], [4, 5, 6], [4, 6, 7], [5, 1, 2], [5, 2, 6], [2, 3, 6], [3, 7, 6], [0, 1, 5], [0, 5, 4]]) # creates meshes from vertices meshes = [] for vertice in vertices_array: cube = mesh.Mesh(np.zeros(faces.shape[0], dtype=mesh.Mesh.dtype)) for i, f in enumerate(faces): for j in range(3): cube.vectors[i][j] = vertice[f[j], :] meshes.append(cube) # combines all meshes together total_length_data = 0 for i in range(len(meshes)): total_length_data += len(meshes[i].data) data = np.zeros(total_length_data, dtype=mesh.Mesh.dtype) data['vectors'] = np.array(meshes).reshape((-1, 9)).reshape((-1, 3, 3)) mesh_final = mesh.Mesh(data.copy()) return mesh_final
def strut(strut_width, lattice_pitch, cham_factor): data = np.zeros(2, dtype=mesh.Mesh.dtype) #Top of the strut data['vectors'][0] = np.array([[0.5, 0, 0.5], [-0.696872, 1.0, 0.11987], [0.11987, 1.0, 0.696872]]) data['vectors'][1] = np.array([[0.5, 0, 0.5], [-0.5, 0, 0.5], [-0.696872, 1.0, 0.11987]]) strut = mesh.Mesh(data.copy()) for i in range(3): tmpside = mesh.Mesh(data.copy()) tmpside.rotate([0.0, 1.0, 0.0], math.radians(90 * (i + 1))) strut = mesh.Mesh(np.concatenate([strut.data, tmpside.data.copy()])) hex_node_width = (0.5 * math.sqrt(3) + cham_factor) * strut_width square_node_width = (0.5 + cham_factor / math.sqrt(2)) * strut_width scale(strut, [ strut_width, lattice_pitch - hex_node_width - square_node_width, strut_width ]) translate(strut, (0, square_node_width, 0)) strut.rotate([0.0, 0.0, 1.0], math.radians(45)) return strut
def cube_generation_by_extending_objects(): # Create 3 faces of a cube data = numpy.zeros(6, dtype=mesh.Mesh.dtype) # Top of the cube data['vectors'][0] = numpy.array([[0, 1, 1], [1, 0, 1], [0, 0, 1]]) data['vectors'][1] = numpy.array([[1, 0, 1], [0, 1, 1], [1, 1, 1]]) # Right face data['vectors'][2] = numpy.array([[1, 0, 0], [1, 0, 1], [1, 1, 0]]) data['vectors'][3] = numpy.array([[1, 1, 1], [1, 0, 1], [1, 1, 0]]) # Left face data['vectors'][4] = numpy.array([[0, 0, 0], [1, 0, 0], [1, 0, 1]]) data['vectors'][5] = numpy.array([[0, 0, 0], [0, 0, 1], [1, 0, 1]]) # Since the cube faces are from 0 to 1 we can move it to the middle by # substracting .5 data['vectors'] -= .5 cube_back = mesh.Mesh(data.copy()) cube_front = mesh.Mesh(data.copy()) # Rotate 90 degrees over the X axis followed by the Y axis followed by the # X axis cube_back.rotate([0.5, 0.0, 0.0], math.radians(90)) cube_back.rotate([0.0, 0.5, 0.0], math.radians(90)) cube_back.rotate([0.5, 0.0, 0.0], math.radians(90)) cube = mesh.Mesh( numpy.concatenate([ cube_back.data.copy(), cube_front.data.copy(), ])) # Write the mesh to file "cube.stl" cube.save('cube.stl')
def generate_stl(pixel_map, color_map, pixel_size): """ Generate the 3D model according to the specified pixel heights. :param pixel_heights: array of pixel height. Might be the same size as the original picture. :param pixel_size: Size of each pixel in the STL file. :return: Generated mesh. """ data = numpy.zeros(0, dtype=mesh.Mesh.dtype) pixel_art_model = mesh.Mesh(data, remove_empty_areas=False) for row_index, row in pixel_map.items(): for pixel_index, pixel in row.items(): pixel_height = 0 height_found = False i = 0 while i < len(color_map) and not height_found: if (color_map[i]["r"], color_map[i]["g"], color_map[i]["b"]) == (pixel["r"], pixel["g"], pixel["b"]): height_found = True pixel_height = color_map[i]["h"] i+=1 new_pixel = cube(1, pixel_height, pixel_size) # generate the pixel at origin new_pixel.translate([row_index * pixel_size, pixel_index * pixel_size, 0.0]) # translate to the position in x an y pixel_art_model = mesh.Mesh(numpy.concatenate([ pixel_art_model.data, new_pixel.data, ])) return pixel_art_model
def cap(strut_width, chamfer_factor, pitch): """ Creates a mesh of the face capping geometry for the octet voxel. :param strut_width: float :param chamfer_factor: float :param pitch: float :return: numpy stl mesh object of cap geometry """ # Calculate commonly used values for geometry definition chamheight = float(strut_width) / chamfer_factor halfw = strut_width / 2.0 l_2 = strut_width / 2.0 + chamheight l_3 = l_2 + strut_width * np.cos(np.pi / 4.0) # horizontal position of points l_4 = np.sqrt(2) * (l_3 - halfw) # Is this square root going to be a problem for error prop? # Define points for node cap face_strut_pos = l_3 - np.sqrt(2) * strut_width / 2.0 point_A_prime_bottom = [face_strut_pos, l_3, 0] point_B_prime_bottom = [l_3, face_strut_pos, 0] point_C_prime_bottom = [l_3, -face_strut_pos, 0] point_D_prime_bottom = [face_strut_pos, -l_3, 0] point_E_prime_bottom = [-face_strut_pos, -l_3, 0] point_F_prime_bottom = [-l_3, -face_strut_pos, 0] point_G_prime_bottom = [-l_3, face_strut_pos, 0] point_H_prime_bottom = [-face_strut_pos, l_3, 0] # Use these points to cap area over the node node_cap_geo = np.zeros(6, dtype=mesh.Mesh.dtype) node_cap_geo['vectors'][0] = np.array([point_H_prime_bottom, point_A_prime_bottom, point_G_prime_bottom]) node_cap_geo['vectors'][1] = np.array([point_A_prime_bottom, point_B_prime_bottom, point_G_prime_bottom]) node_cap_geo['vectors'][2] = np.array([point_G_prime_bottom, point_B_prime_bottom, point_F_prime_bottom]) node_cap_geo['vectors'][3] = np.array([point_B_prime_bottom, point_C_prime_bottom, point_F_prime_bottom]) node_cap_geo['vectors'][4] = np.array([point_C_prime_bottom, point_E_prime_bottom, point_F_prime_bottom]) node_cap_geo['vectors'][5] = np.array([point_C_prime_bottom, point_D_prime_bottom, point_E_prime_bottom]) node_cap = mesh.Mesh(node_cap_geo) # Define corner node cap corner_cap_geo = np.zeros(3, dtype=mesh.Mesh.dtype) corner_cap_geo['vectors'][0] = np.array([[0,0,0], [0, l_3, 0], [l_3, 0, 0]]) corner_cap_geo['vectors'][1] = np.array([[0, l_3, 0], point_B_prime_bottom, [l_3, 0, 0]]) corner_cap_geo['vectors'][2] = np.array([[0, l_3, 0], point_A_prime_bottom, point_B_prime_bottom]) corner_cap = mesh.Mesh(corner_cap_geo) # Define strut cap point_corner_A_prime_bottom = [-pitch/2.0 + point_A_prime_bottom[0], -pitch/2.0 + point_A_prime_bottom[1], 0] point_corner_B_prime_bottom = [-pitch/2.0 + point_B_prime_bottom[0], -pitch/2.0 + point_B_prime_bottom[1], 0] strut_cap_geo = np.zeros(2, dtype=mesh.Mesh.dtype) strut_cap_geo['vectors'][0] = np.array([point_corner_A_prime_bottom, point_F_prime_bottom, point_E_prime_bottom]) strut_cap_geo['vectors'][1] = np.array([point_corner_A_prime_bottom, point_E_prime_bottom, point_corner_B_prime_bottom]) strut_cap = mesh.Mesh(strut_cap_geo) translate(corner_cap, np.array([-1, -1, 0])* pitch/2.0) corners = arraypolar(corner_cap, [0, 0, 1], 4) struts = arraypolar(strut_cap, [0, 0, 1], 4) combined_geometry = corners + struts + [node_cap] return combine_meshes(*combined_geometry)
def hexnode(beam_width, chamfer_factor, side_code): topcap = np.zeros(12, dtype=mesh.Mesh.dtype) side = np.zeros(12, dtype=mesh.Mesh.dtype) chamside = np.zeros(12, dtype=mesh.Mesh.dtype) center = np.array([0.0, 0.0, beam_width / 2.0]) topbound = np.array([[ 0.5 * chamfer_factor * beam_width, beam_width + 0.5 * math.sqrt(3) * chamfer_factor * beam_width, beam_width / 2.0 ], [ -0.5 * chamfer_factor * beam_width, beam_width + 0.5 * math.sqrt(3) * chamfer_factor * beam_width, beam_width / 2.0 ]]) for i in range(10): vec = topbound[-2] topbound = np.vstack((topbound, np.dot(rot_60_tform, vec))) botbound = np.copy(topbound) botbound.T[2] = -botbound.T[2] for i in range(12): topcap['vectors'][i] = np.vstack( (topbound[i], center, topbound[i - 1])) botcap = mesh.Mesh(topcap.copy()) botcap.rotate([0.0, 1.0, 0.0], math.radians(180)) for i in range(0, 12, 2): if side_code[i / 2] == 1: side['vectors'][i] = np.vstack( (botbound[i - 1], botbound[i], topbound[i])) side['vectors'][i + 1] = np.vstack( (topbound[i], topbound[i - 1], botbound[i - 1])) for i in range(-1, 11, 2): chamside['vectors'][i] = np.vstack( (botbound[i - 1], botbound[i], topbound[i])) chamside['vectors'][i + 1] = np.vstack( (topbound[i], topbound[i - 1], botbound[i - 1])) nodedata = [ topcap.copy(), botcap.data.copy(), side.copy(), chamside.copy() ] nodecapbase = mesh.Mesh(np.concatenate(nodedata)) #nodecapbase.rotate([0.0,0.0,1.0],math.radians(45)) return nodecapbase
def corner(strut_width, chamfer_factor, pitch): """ :param strut_width: :param chamfer_factor: :param pitch: :return: """ # Make a base node for the corner cnode = corner_node(strut_width, chamfer_factor) # Geometry Parameters # Calculate commonly used values for geometry definition chamheight = float(strut_width) / chamfer_factor halfw = strut_width / 2.0 halfp = pitch / 2.0 h = chamheight + (strut_width * np.sin(np.pi / 4.0) + halfw) # height of top cap l_2 = halfw + chamheight # horizontal position of points on topcap hs = l_2 # height of side points of node l_3 = l_2 + strut_width * np.cos(np.pi / 4.0) # horizontal position of points # re-use points from strut code, with alteration to create half-struts point2 = [l_2, halfw, h] point3 = [l_2, 0, h] point2s = [l_3, halfw, hs] point3s = [l_3, 0, hs] # new points to attach to on side node point2n = [halfp - h, halfw, halfp - l_2] point3n = [halfp - h, 0, halfp - l_2] point2sn = [halfp - hs, halfw, halfp - l_3] point3sn = [halfp - hs, 0, halfp - l_3] face_halfstrut_geo = np.zeros(6, dtype=mesh.Mesh.dtype) face_halfstrut_geo['vectors'][0] = np.array([point3, point3n, point2n]) face_halfstrut_geo['vectors'][1] = np.array([point3, point2n, point2]) face_halfstrut_geo['vectors'][2] = np.array([point2, point2n, point2sn]) face_halfstrut_geo['vectors'][3] = np.array([point2, point2sn, point2s]) face_halfstrut_geo['vectors'][4] = np.array([point2s, point2sn, point3s]) face_halfstrut_geo['vectors'][5] = np.array([point3s, point2sn, point3sn]) face_halfstrut = mesh.Mesh(face_halfstrut_geo) face_halfstrut2 = mesh.Mesh(face_halfstrut.data.copy()) face_halfstrut2.rotate([1, 0, 1], math.radians(180)) face_halfstrut2.rotate([0,0,1], math.radians(270)) face_halfstrut3 = mesh.Mesh(face_halfstrut.data.copy()) face_halfstrut3.rotate([1, 0, 1], math.radians(270)) face_halfstrut3.rotate([0, 1, 0], math.radians(-45)) face_halfstrut3.rotate([0, 0, 1], math.radians(-45)) combined_geometry = [cnode] + [face_halfstrut] + [face_halfstrut2] + [face_halfstrut3] return combine_meshes(*combined_geometry)
def box_array(voxel_mesh, pitch, x, y, z): """ This function cubically arrays a mesh object :param voxel_mesh: :param pitch: :param x: integer number of items in the lattice in x direction :param y: integer number of items in the lattice in y direction :param z: integer number of items in the lattice in z direction :return: numpy stl mesh object of arrayed geometry """ lattice = [voxel_mesh] # Assume want list structure # array in x direction if x == 1: # Don't need to do anything if x dimension is 1 x = 1 else: for i in range(x): if i == 0: # Don't need to make a copy of the original voxel i = 0 else: new_obj = mesh.Mesh(voxel_mesh.data.copy()) # Make a copy of the voxel translate(new_obj, np.array([1, 0, 0]) * pitch * i) lattice += [new_obj] # array in y direction if y == 1: # Don't need to do anything if y dimension is 1 y = 1 else: xline = lattice for j in range(y): if j == 0: # Don't need to make a copy of the original voxel line j = 0 else: for thing in xline: new_obj = mesh.Mesh(thing.data.copy()) # Make a copy of the voxel translate(new_obj, np.array([0, 1, 0]) * pitch * j) lattice = lattice + [new_obj] # Can't use += because modifies copy too and creates an infinite loop # array in z direction if z == 1: # Don't need to do anything if the z dimension is 1 z = 1 else: xyplane = lattice for k in range(z): if k == 0: # Don't need to make a copy of the original voxel plane k == 0 else: for thing in xyplane: new_obj = mesh.Mesh(thing.data.copy()) # Make a copy of the voxel translate(new_obj, np.array([0, 0, 1]) * pitch * k) lattice = lattice + [new_obj] # Can't use += because modifies copy too and creates an infinite loop open_lattice = combine_meshes(*lattice) return open_lattice
def base_cylinder(self, center, r, h): ox, oy, oz = center theta = np.linspace(0, 2 * np.pi, 100) x_list = r * np.cos(theta) y_list = r * np.sin(theta) z = -h / 100 ox = ox oy = oy oz = oz - z # Create 6 faces of a cube, 2 triagles per face data = np.zeros(400, dtype=mesh.Mesh.dtype) for i in range(100): x1 = x_list[i] y1 = y_list[i] if i == 99: i = -1 x2 = x_list[i + 1] y2 = y_list[i + 1] # Bottem face data['vectors'][4 * i + 0] = np.array([[ox + x2, oy + y2, oz + 0], [ox + x1, oy + y1, oz + 0], [ox + 0, oy + 0, oz + 0]]) # Top face data['vectors'][4 * i + 1] = np.array([[ox + x2, oy + y2, oz + z], [ox + x1, oy + y1, oz + z], [ox + 0, oy + 0, oz + z]]) # outside face data['vectors'][4 * i + 2] = np.array([[ox + x2, oy + y2, oz + 0], [ox + x1, oy + y1, oz + 0], [ox + x1, oy + y1, oz + z]]) data['vectors'][4 * i + 3] = np.array([[ox + x2, oy + y2, oz + z], [ox + x1, oy + y1, oz + z], [ox + x2, oy + y2, oz + 0]]) _mesh = [mesh.Mesh(data.copy()) for _ in range(1)] for m in _mesh: self.axes.add_collection3d( mplot3d.art3d.Poly3DCollection(m.vectors)) #save total_length_data = 0 for i in range(len(_mesh)): total_length_data += len(_mesh[i].data) data = np.zeros(total_length_data, dtype=mesh.Mesh.dtype) data['vectors'] = np.array(_mesh).reshape((-1, 9)).reshape((-1, 3, 3)) mesh_final = mesh.Mesh(data.copy()) mesh_final.save('cylinder_buttom.stl')
def createMeshCube(corner, dx, dy, dz): """ Returns a mesh cube object with the above diameters for x, y, z axis with respect to an axial slice orientation - corner is the posterior, inferior, left corner - I think """ # vertices of square vertices = np.array([ corner, corner + np.array([dx, 0, 0]), corner + np.array([dx, dy, 0]), corner + np.array([0, dy, 0]), corner + np.array([0, 0, dz]), corner + np.array([dx, 0, dz]), corner + np.array([dx, dy, dz]), corner + np.array([0, dy, dz]), ]) # Define the 12 triangles composing the cube faces = np.array([[0, 3, 1], [1, 3, 2], [0, 4, 7], [0, 7, 3], [4, 5, 6], [4, 6, 7], [5, 1, 2], [5, 2, 6], [2, 3, 6], [3, 7, 6], [0, 1, 5], [0, 5, 4]]) # Create the mesh cube = mesh.Mesh(np.zeros(faces.shape[0], dtype=mesh.Mesh.dtype)) for i, f in enumerate(faces): for j in range(3): cube.vectors[i][j] = vertices[f[j], :] return cube
def __init__(self, filename, min_z_val=0.1, req_rotation=None): ''' Initialise class Inputs: - filename path to STL file - min_z_val will only use facets above this z height - req_rotation XYZ rotation for mesh. Applied before min_z_val truncation ''' self._raw_data = mesh.Mesh.from_file(filename) data = np.zeros(len(self._raw_data), dtype=mesh.Mesh.dtype) idx = 0 if np.sum(req_rotation) is not None: self.rotateMesh(req_rotation) self._max_z = -9999999999 for val in self._raw_data.points: np_val = np.array(val) if all(np_val[[2, 5, 8]] > min_z_val): # select z values data['vectors'][idx] = np_val.reshape(3, 3) idx += 1 # update max if required if max(np_val[[2, 5, 8]]) > self._max_z: self._max_z = max(np_val[[2, 5, 8]]) self._mesh_data = mesh.Mesh(data)
def generateSTL(data, name="key.stl"): if data is None: print("No Mesh, can't save STL") return key = mesh.Mesh(np.zeros(data.shape[0], dtype=mesh.Mesh.dtype)) key.vectors = data key.save(name)
def main(): #Full read and import print("loading image data") totalimage = np.zeros((len(file_names), xresolution, yresolution)) for i, slice_object in enumerate(file_list): a = pydicom.dcmread(slice_object.getName()).pixel_array a -= midpoint a[a > 0] = -a[a > 0] totalimage[i] = a #Pass to SCIKITfor marching cubes print("marching cubes") #Use second thread to prevent windows timing us out verts, faces, normals, values = ski.marching_cubes( totalimage, level=-threshold_width, step_size=stepsize, spacing=(sliceThickness, pixelSpacing[0], pixelSpacing[1])) #Convert Vertices to STL print("converting to stl") output_mesh = mesh.Mesh(np.zeros(faces.shape[0], dtype=mesh.Mesh.dtype)) for i, f in enumerate(faces): for j in range(3): output_mesh.vectors[i][j] = verts[f[j], :] print("saving") output_mesh.save(outfilename + '.stl') print("finished")
def diagramToSTLMesh(diagram): # Flip any faces facing inwards to now face outwards. fixOrdering(diagram) vertices = diagram.vertices # Collect the facets of bounded regions. bounded_region_facets = [ y for x in [region.facets for region in diagram.bounded_regions] for y in x ] # Collect the vertices of triangulated facets. tri_facets_i = [] for facet in bounded_region_facets: for tri in facet.triangles(): tri_facets_i.append(tri.vertices_i) tri_facets_i = np.array(tri_facets_i) # Generate the Mesh object. m = mesh.Mesh(np.zeros(tri_facets_i.shape[0], dtype=mesh.Mesh.dtype)) for i, facet_i in enumerate(tri_facets_i): for j in range(len(facet_i)): m.vectors[i][j] = vertices[facet_i[j], :] return m
def STL_Gen(x,y,g,s): res = len(x) # x=[x[i]/1000 for i in range(len(x))] #y=[y[i]/1000 for i in range(len(x))] z=0.1 i = 0; v=[] while (i <res): # +ve z axis points v.append([x[i],y[i],z]) i += 1 i=0 while (i <res): # -ve z axis points v.append([x[i],y[i],-z]) i += 1 vertices=np.array(v) i=0; f=[] while (i<res-1): # generating faces f.append([i,i+1,res+i+1]) f.append([i,res+i+1,res+i]) i +=1 faces= np.array(f) suf=mesh.Mesh(np.zeros(faces.shape[0], dtype=mesh.Mesh.dtype)) for i, f in enumerate(faces): for j in range(3): suf.vectors[i][j]= vertices[f[j],:] suf.save('Airfoil_%i-%i.stl'%(g,s), mode=stl.Mode.ASCII) shutil.copyfile('Airfoil_%i-%i.stl'%(g,s), 'constant/triSurface/Airfoil1.stl')
def plotMesh(mesh, points=None): # Create a new plot figure = pyplot.figure() axes = mplot3d.Axes3D(figure) toPlot = stlmesh.Mesh( np.zeros(mesh.faces.shape[0], dtype=stlmesh.Mesh.dtype)) for i, f in enumerate(mesh.faces): for j in range(3): toPlot.vectors[i][j] = mesh.vertices[f[j], :] axes.add_collection3d(mplot3d.art3d.Poly3DCollection(toPlot.vectors)) if not (points is None) and points.any(): axes.scatter3D(points[:, 0], points[:, 1], zs=points[:, 2], c='r', s=20) # Auto scale to the mesh size scale = toPlot.points.flatten(-1) axes.auto_scale_xyz(scale, scale, scale) # Show the plot to the screen pyplot.show()
def generate_stl(array, geometry): """ Make a mesh from a volume. """ from stl import mesh # Segment the volume: threshold = array > analyze.binary_threshold(array, mode='otsu') # Close small holes: print('Filling small holes...') threshold = ndimage.morphology.binary_fill_holes(threshold, structure=numpy.ones( (3, 3, 3))) print('Generating mesh...') # Use marching cubes to obtain the surface mesh of these ellipsoids verts, faces, normals, values = measure.marching_cubes_lewiner( threshold, 0) print('Mesh with %1.1e vertices generated.' % verts.shape[0]) # Create stl: stl_mesh = mesh.Mesh(numpy.zeros(faces.shape[0], dtype=mesh.Mesh.dtype)) stl_mesh.vectors = verts[faces] * geometry.voxel return stl_mesh
def _populate_atoms(system, sphere): # Initialise the 3d space all_atoms = [] # Loop over all the molecules for mol_ID in tqdm(system.molecules.keys()): # Get the current atom and positions crt_positions = system.molecules[mol_ID].positions crt_radii = system.molecules[mol_ID].radii # Loop over all the atoms for atom_ID in range(crt_positions.shape[0]): # Get the new object new_atom = _add_atom(sphere, crt_positions[atom_ID], crt_radii[atom_ID]) # Append the new object all_atoms.append(new_atom.data.copy()) # Merge the meshes together all_atoms = mesh.Mesh(np.concatenate(all_atoms)) return all_atoms
def GenerateRidgeTerrian(y, ridge_min=7, ridge_max=10, ridge_length=35): zero = ridge_min index = 0 step = ridge_length / len(y) if step > 1: step = 1 data = np.zeros(len(y) * 6, dtype=mesh.Mesh.dtype) y += [zero] # TODO: Remove List Function Call x = 1 for i in range(0, len(data['vectors']), 6): # The Roof data['vectors'][i] = np.array([[index, y[x - 1], 1], [index, y[x - 1], 0], [index + step, y[x], 0]]) data['vectors'][i + 1] = np.array([[index + step, y[x], 1], [index + step, y[x], 0], [index, y[x - 1], 1]]) #The Walls data['vectors'][i + 2] = np.array([[index, y[x - 1], 1], [index, zero, 1], [index + step, zero, 1]]) data['vectors'][i + 3] = np.array([[index, y[x - 1], 1], [index + step, y[x], 1], [index + step, zero, 1]]) data['vectors'][i + 4] = np.array([[index, y[x - 1], 0], [index, zero, 0], [index + step, zero, 0]]) data['vectors'][i + 5] = np.array([[index, y[x - 1], 0], [index + step, y[x], 0], [index + step, zero, 0]]) x += 1 index += step return mesh.Mesh(data)
def write(self, mesh_points, filename, write_bin=False): """ Writes a stl file, called filename, copying all the lines from self.filename but the coordinates. mesh_points is a matrix that contains the new coordinates to write in the stl file. :param numpy.ndarray mesh_points: it is a `n_points`-by-3 matrix containing the coordinates of the points of the mesh. :param string filename: name of the output file. :param boolean write_bin: flag to write in the binary format. Default is False. """ self._check_filename_type(filename) self._check_extension(filename) self._check_infile_instantiation() self.outfile = filename n_vertices = mesh_points.shape[0] # number of triplets of vertices n_triplets = n_vertices / 3 data = np.zeros(n_triplets, dtype=mesh.Mesh.dtype) stl_mesh = mesh.Mesh(data, remove_empty_areas=False) for i in range(0, n_triplets): for j in range(0, 3): data['vectors'][i][j] = mesh_points[3 * i + j] if not write_bin: stl_mesh.save(self.outfile, mode=Mode.ASCII, update_normals=True) else: stl_mesh.save(self.outfile, update_normals=True)
def voxelizeLocationsMesh(locations): """receives a list of tuples [(x1,y1,z1),...] where to build voxels, and creates a mesh containing those relevant cubes""" listOfVoxels = [] for (a,b,c) in locations: listOfVoxels.append(cubeData(trans = (a,b,c))) outputMesh = mesh.Mesh(np.concatenate(listOfVoxels)) return outputMesh
def save_mesh_to_stl(mesh_object, filename): mesh_object = list( map(lambda x: (0, x.tolist(), 0), mesh_object.verts[mesh_object.faces])) mesh_object = np.array(mesh_object, dtype=mesh.Mesh.dtype) mesh_object = mesh.Mesh(mesh_object, remove_empty_areas=True) mesh_object.save(filename)
def STL_Gen(x,y,filename): res = len(x) #x=[x[i]/1000 for i in range(len(x))] #y=[y[i]/1000 for i in range(len(x))] z=0.25 i = 0; v=[] while (i <res): # +ve z axis points v.append([x[i],y[i],z]) i += 1 i=0 while (i <res): # -ve z axis points v.append([x[i],y[i],-z]) i += 1 vertices=np.array(v) i=0; f=[] while (i<res-1): # generating faces f.append([i,i+1,res+i+1]) f.append([i,res+i+1,res+i]) i +=1 faces= np.array(f) suf=mesh.Mesh(np.zeros(faces.shape[0], dtype=mesh.Mesh.dtype)) for i, f in enumerate(faces): for j in range(3): suf.vectors[i][j]= vertices[f[j],:] suf.save(filename, mode=stl.Mode.ASCII)
def _sludge_pattern(resolution=128): """Random sludge pattern at bottom of tank.""" x_pos = np.linspace(1, 25, num=resolution) y_pos = .0625 * x_pos - 6.0625 y_pos[1:-1] += np.random.normal(loc=.25, scale=.1, size=resolution - 2) vertices = np.zeros((2 * resolution, 3)) vertices[:, 0] = np.concatenate((x_pos, x_pos[::-1])) vertices[:, 1] = np.concatenate((y_pos, y_pos[::-1])) vertices[resolution:, 2] = resolution * [-.5] vert_id = np.array(range(2 * resolution)) triags = tr.triangulate( dict(vertices=vertices[:, [0, 2]], segments=np.stack((vert_id, (vert_id + 1) % len(vert_id))).T), 'pq') faces = triags['triangles'] sludge = mesh.Mesh(np.zeros(faces.shape[0], dtype=mesh.Mesh.dtype)) for i, face in enumerate(faces): for j in range(3): sludge.vectors[i][j] = vertices[face[j], :] sludge.save('../foam/sim/constant/triSurface/sludge.stl') return True
def create_diffuser(design_frequency, N, M, c): wavelength = c / design_frequency w = wavelength / 2.0 cavity_height = wavelength / 20.0 base_height = 1.0 top_height = 1.0 unit_width = w wall_width = 1.0 qrs = QRS2D(N, M, w) # unit 2D list units = [[0 for x in range(M)] for y in range(N)] for i in range(N): for j in range(M): resonator_width = np.random.randint(0, unit_width/2) base = create_base(i, j, w, base_height) perimeter = create_perimeter(i, j, unit_width, wall_width, base_height, cavity_height) h = (w * qrs[i][j]) / (2 * N) top = create_top(i, j, unit_width, h, cavity_height + base_height, top_height) units[i][j] = np.concatenate([base.data, perimeter.data, top.data]).data unit_list = [] for i in range(N): for j in range(M): unit_list.append(units[i][j]) stl = mesh.Mesh(np.concatenate(unit_list)) stl.save("test.stl")
def lineToSTL(pts, name, z=19): pts_base = [[ax, ay, 0] for (ax, ay) in pts] pts_top = [[ax, ay, z] for (ax, ay) in pts] #points to triangles triangles_indices = earcut.triangulate_float32( np.array(pts).reshape(-1, 2), np.array([len(pts)])).reshape(-1, 3) #2d triangles to 3d triangles base = [[pts_base[a], pts_base[b], pts_base[c]] for (a, b, c) in triangles_indices] top = [[pts_top[a], pts_top[b], pts_top[c]] for (a, b, c) in triangles_indices] n_facets = 2 * len(pts) + 2 * triangles_indices.shape[0] data = np.zeros(n_facets, dtype=mesh.Mesh.dtype) for i in range(len(base)): data['vectors'][2 * i] = np.array([base[i][0], base[i][1], base[i][2]]) data['vectors'][2 * i + 1] = np.array( [top[i][0], top[i][1], top[i][2]]) for i in range(len(pts)): data['vectors'][2 * len(base) + 2 * i] = np.array( [pts_base[i], pts_top[i - 1], pts_base[i - 1]]) data['vectors'][2 * len(base) + 2 * i + 1] = np.array( [pts_base[i], pts_top[i], pts_top[i - 1]]) new_mesh = mesh.Mesh(data) new_mesh.save(name)
def create_perimeter(x_index, y_index, unit_width, wall_width, z_offset, height): left = left_perimeter(x_index, y_index, unit_width, wall_width, z_offset, height) top = top_perimeter(x_index, y_index, unit_width, wall_width, z_offset, height) right = right_perimeter(x_index, y_index, unit_width, wall_width, z_offset, height) bottom = bottom_perimeter(x_index, y_index, unit_width, wall_width, z_offset, height) return mesh.Mesh(np.concatenate([left.data, top.data, right.data, bottom.data])).data
def lineToSTL(pts, name, z = 1): # 3D vertices of the base and top faces. pts_base = [ [ax,ay,0] for (ax,ay) in pts] pts_top = [ [ax,ay,z] for (ax,ay) in pts] # Triangulate the 2D curve triangles_indices = earcut.triangulate_float32(np.array(pts).reshape(-1,2), np.array([len(pts)])).reshape(-1,3) # 2d triangles to 3d triangles base = [ [pts_base[a], pts_base[b], pts_base[c]] for (a,b,c) in triangles_indices] top = [ [pts_top[a], pts_top[b], pts_top[c]] for (a,b,c) in triangles_indices] # Need to get the number of triangles: 2 per segment plus twice the number given by our triangulization n_facets = 2 * len(pts) + 2 * triangles_indices.shape[0] data = np.zeros(n_facets, dtype=mesh.Mesh.dtype) #Add base and top triangles for i in range(len(base)): data['vectors'][2*i] = np.array([base[i][0], base[i][1], base[i][2]]) data['vectors'][2*i + 1] = np.array([top[i][0], top[i][1], top[i][2]]) #Add side triangles. for i in range(len(pts)): data['vectors'][2*len(base) + 2*i] = np.array([pts_base[i], pts_top[i-1], pts_base[i-1]]) data['vectors'][2*len(base) + 2*i + 1] = np.array([pts_base[i], pts_top[i], pts_top[i-1]]) new_mesh = mesh.Mesh(data) new_mesh.save(name)
def convert_verts(self, conversion): """ converion -> conversion factor for measurement Creates new STL file based on conversion parameter """ conversion_factor = 1.0 if conversion == "in2cm": conversion_factor = 2.54 elif conversion == "in2mm": conversion_factor = 25.4 elif conversion == "cm2in": conversion_factor = 0.393701 elif conversion == "cm2mm": conversion_factor = 10 else: return list = self.stl_mesh.data.copy() for i in range(len(list)): list[i][1][0][0:3] *= conversion_factor list[i][1][1][0:3] *= conversion_factor list[i][1][2][0:3] *= conversion_factor data = np.asarray(list, dtype=mesh.Mesh.dtype) new_mesh = mesh.Mesh(data) new_mesh.save(f'new_stl.stl')