def offset(mesh,offset=1,doclose=True): newMesh=Mesh() # calculate vertex normals for vertex in mesh.vertices: vertex.vertex = Vertex(0,0,0) vertex.nfaces = 0 for face in mesh.faces: normal = utils_face.face_normal(face) for vertex in face.vertices: vertex.vertex.add(normal) vertex.nfaces += 1 for vertex in mesh.vertices: vertex.vertex.scale(offset / vertex.nfaces) vertex.vertex.add(vertex) # create faces for face in mesh.faces: offsetVertices = [] for vertex in face.vertices: offsetVertices.append(vertex.vertex) offsetVertices.reverse() newFace = Face(offsetVertices) newMesh.faces.append(newFace) newMesh.faces.append(face) # create sides if doclose: for edge in mesh.edges: if edge.face1 == None or edge.face2 == None: offsetVertices = [edge.v1, edge.v2, edge.v2.vertex, edge.v1.vertex] if edge.face2 == None: offsetVertices.reverse() newFace = Face(offsetVertices) newMesh.faces.append(newFace) newMesh.update_topology() return newMesh
def construct_cone(z1, z2, radius1, radius2, nSegments, capBottom=True, capTop=True): """ Creates and returns a conic cylinder. Arguments: ---------- z1, z2 : float<br> The bottom and top z-level.<br> radius1, radius2 : float<br> The radii at the bottom and at the top respectively<br> nSegments : int<br> The number of segments along the circumference<br> capBottom, capTop : bool<br> Toggle whether or not to close the cylinder at the bottom and the top """ delaAngle = math.radians(360.0 / nSegments) angle = 0 verticesBottom = [] verticesTop = [] for i in range(nSegments): x1 = radius1 * math.cos(angle) y1 = radius1 * math.sin(angle) verticesBottom.append(Vertex(x1, y1, z1)) x2 = radius2 * math.cos(angle) y2 = radius2 * math.sin(angle) verticesTop.append(Vertex(x2, y2, z2)) angle += delaAngle mesh = Mesh() mesh.vertices.extend(verticesBottom) mesh.vertices.extend(verticesTop) for i in range(nSegments): i2 = (i + 1) % nSegments mesh.faces.append( Face([ verticesBottom[i], verticesBottom[i2], verticesTop[i2], verticesTop[i] ])) if capBottom: # centerBottom = Vertex(0, 0, z1) # mesh.vertices.append(centerBottom) # for i in range(nSegments): # i2=(i+1)%nSegments # mesh.faces.append(Face([verticesBottom[i2],verticesBottom[i],centerBottom])) mesh.faces.append(Face(list(reversed(verticesBottom)))) if capTop: # centerTop=Vertex(0,0,z2) # mesh.vertices.append(centerTop) # for i in range(nSegments): # i2=(i+1)%nSegments # mesh.faces.append(Face([verticesTop[i],verticesTop[i2],centerTop])) mesh.faces.append(Face(verticesTop)) mesh.update_topology() return mesh
def subdivide_mesh_extrude_tapered(mesh, heights, fractions, doCaps): new_mesh = Mesh() for face, height, fraction, doCap in zip(mesh.faces, heights, fractions, doCaps): new_mesh.faces.extend( subdivide_face_extrude_tapered(face, height, fraction, doCap)) new_mesh.update_topology() return new_mesh
def subdivide_mesh_extrude_to_point_center(mesh,heights,doExtrudes): new_mesh = Mesh() for face,height,doExtrude in zip(mesh.faces,heights,doExtrudes): if doExtrude: new_mesh.faces.extend(subdivide_face_extrude_to_point_center(face,height)) else: new_mesh.faces.append(face) new_mesh.update_topology() return new_mesh
def quad_mesh(self, functionIn, functionOut): faces = [] for x in range(self.nx): for y in range(self.ny): for z in range(self.nz): index = self.get_index(x, y, z) if functionIn(self.values[index]): # (x,y) (x1,y) (x1,y1) (x,y1) if x == self.nx - 1 or functionOut( self.get_value_at_xyz(x + 1, y, z)): v1 = Vertex(x + 1, y, z) v2 = Vertex(x + 1, y + 1, z) v3 = Vertex(x + 1, y + 1, z + 1) v4 = Vertex(x + 1, y, z + 1) faces.append(Face([v1, v2, v3, v4])) if x == 0 or functionOut( self.get_value_at_xyz(x - 1, y, z)): v1 = Vertex(x, y + 1, z) v2 = Vertex(x, y, z) v3 = Vertex(x, y, z + 1) v4 = Vertex(x, y + 1, z + 1) faces.append(Face([v1, v2, v3, v4])) if y == self.ny - 1 or functionOut( self.get_value_at_xyz(x, y + 1, z)): v1 = Vertex(x + 1, y + 1, z) v2 = Vertex(x, y + 1, z) v3 = Vertex(x, y + 1, z + 1) v4 = Vertex(x + 1, y + 1, z + 1) faces.append(Face([v1, v2, v3, v4])) if y == 0 or functionOut( self.get_value_at_xyz(x, y - 1, z)): v1 = Vertex(x, y, z) v2 = Vertex(x + 1, y, z) v3 = Vertex(x + 1, y, z + 1) v4 = Vertex(x, y, z + 1) faces.append(Face([v1, v2, v3, v4])) if z == self.nz - 1 or functionOut( self.get_value_at_xyz(x, y, z + 1)): v1 = Vertex(x, y, z + 1) v2 = Vertex(x + 1, y, z + 1) v3 = Vertex(x + 1, y + 1, z + 1) v4 = Vertex(x, y + 1, z + 1) faces.append(Face([v1, v2, v3, v4])) if z == 0 or functionOut( self.get_value_at_xyz(x, y, z - 1)): v1 = Vertex(x, y + 1, z) v2 = Vertex(x + 1, y + 1, z) v3 = Vertex(x + 1, y, z) v4 = Vertex(x, y, z) faces.append(Face([v1, v2, v3, v4])) mesh = Mesh() mesh.faces = faces mesh.update_topology() if (self.scale_to_canvas): mesh.translate(-self.nx / 2.0, -self.ny / 2.0, -self.nz / 2.0) sc = 20.0 / max(self.nx, self.ny) mesh.scale(sc, sc, sc) return mesh
def mesh_marching_cubes(nX, nY, nZ, values, iso): mesh = Mesh() nYZ = nY * nZ index = 0 n = [0] * 8 switcher = { 0: lambda: Vertex(x + _v(n[0], n[1], iso), y + 1, z), 1: lambda: Vertex(x + 1, y + _v(n[2], n[1], iso), z), 2: lambda: Vertex(x + _v(n[3], n[2], iso), y, z), 3: lambda: Vertex(x, y + _v(n[3], n[0], iso), z), 4: lambda: Vertex(x + _v(n[4], n[5], iso), y + 1, z + 1), 5: lambda: Vertex(x + 1, y + _v(n[6], n[5], iso), z + 1), 6: lambda: Vertex(x + _v(n[7], n[6], iso), y, z + 1), 7: lambda: Vertex(x, y + _v(n[7], n[4], iso), z + 1), 8: lambda: Vertex(x, y + 1, z + _v(n[0], n[4], iso)), 9: lambda: Vertex(x + 1, y + 1, z + _v(n[1], n[5], iso)), 10: lambda: Vertex(x, y, z + _v(n[3], n[7], iso)), 11: lambda: Vertex(x + 1, y, z + _v(n[2], n[6], iso)) } for x in range(nX - 1): for y in range(nY - 1): for z in range(nZ - 1): caseNumber = 0 index = z + y * nZ + x * nYZ # collecting the values n[0] = values[index + nZ] # 0,1,0 n[1] = values[index + nYZ + nZ] #1,1,0 n[2] = values[index + nYZ] # 1,0,0 n[3] = values[index] # 0,0,0 n[4] = values[index + nZ + 1] # 0,1,1 n[5] = values[index + nYZ + nZ + 1] # 1,1,1 n[6] = values[index + nYZ + 1] # 1,0,1 n[7] = values[index + 1] # 0,0,1 for i in range(7, -1, -1): if n[i] > iso: caseNumber += 1 if i > 0: caseNumber = caseNumber << 1 # collecting the faces offset = caseNumber * 15 for i in range(offset, offset + 15, 3): if _faces[i] > -1: vs = [] for j in range(i, i + 3): v = switcher[_faces[j]]() mesh.vertices.append(v) vs.append(v) if len(vs) == 3: mesh.faces.append(Face(vs)) mesh.update_topology() return mesh
def construct_tetrahedron(size=1, cx=0, cy=0, cz=0): """ Constructs a tetrahedron mesh. Optional Arguments: ---------- side : float<br> The edge length of the tetrahedron<br> cx,cy,cz : float<br> The coordinates of the center point. """ mesh = Mesh() coord = 1 / math.sqrt(2) mesh.vertices = [ Vertex(+1, 0, -coord), Vertex(-1, 0, -coord), Vertex(0, +1, +coord), Vertex(0, -1, +coord) ] for i in range(len(mesh.vertices)): mesh.vertices[i] = utils_vertex.vertex_scale(mesh.vertices[i], size / 2) mesh.vertices[i] = utils_vertex.vertex_add(mesh.vertices[i], Vertex(cx, cy, cz)) f1 = Face([mesh.vertices[0], mesh.vertices[1], mesh.vertices[2]]) f2 = Face([mesh.vertices[1], mesh.vertices[0], mesh.vertices[3]]) f3 = Face([mesh.vertices[2], mesh.vertices[3], mesh.vertices[0]]) f4 = Face([mesh.vertices[3], mesh.vertices[2], mesh.vertices[1]]) mesh.faces = [f1, f2, f3, f4] mesh.update_topology() return mesh
def quad_mesh(self, functionIn, functionOut): faces = [] for x in range(self.nx): for y in range(self.ny): for z in range(self.nz): index=self.get_index(x,y,z) if functionIn(self.values[index]): # (x,y) (x1,y) (x1,y1) (x,y1) if x == self.nx - 1 or functionOut(self.get_value_at_xyz(x + 1, y, z)): v1 = Vertex(x + 1, y, z) v2 = Vertex(x + 1, y + 1, z) v3 = Vertex(x + 1, y + 1, z + 1) v4 = Vertex(x + 1, y, z + 1) faces.append(Face([v1, v2, v3, v4])) if x == 0 or functionOut(self.get_value_at_xyz(x-1,y,z)): v1 = Vertex(x, y + 1, z) v2 = Vertex(x, y, z) v3 = Vertex(x, y, z + 1) v4 = Vertex(x, y + 1, z + 1) faces.append(Face([v1, v2, v3, v4])) if y == self.ny - 1 or functionOut(self.get_value_at_xyz(x, y + 1, z)): v1 = Vertex(x + 1, y + 1, z) v2 = Vertex(x, y + 1, z) v3 = Vertex(x, y + 1, z + 1) v4 = Vertex(x + 1, y + 1, z + 1) faces.append(Face([v1, v2, v3, v4])) if y == 0 or functionOut(self.get_value_at_xyz(x, y - 1, z)): v1 = Vertex(x, y, z) v2 = Vertex(x + 1, y, z) v3 = Vertex(x + 1, y, z + 1) v4 = Vertex(x, y, z + 1) faces.append(Face([v1, v2, v3, v4])) if z==self.nz-1 or functionOut(self.get_value_at_xyz(x, y, z + 1)): v1 = Vertex(x, y, z + 1) v2 = Vertex(x + 1, y, z + 1) v3 = Vertex(x + 1, y + 1, z + 1) v4 = Vertex(x, y + 1, z + 1) faces.append(Face([v1, v2, v3, v4])) if z == 0 or functionOut(self.get_value_at_xyz(x, y, z - 1)): v1 = Vertex(x, y + 1, z) v2 = Vertex(x + 1, y + 1, z) v3 = Vertex(x + 1, y, z) v4 = Vertex(x, y, z) faces.append(Face([v1, v2, v3, v4])) mesh = Mesh() mesh.faces = faces mesh.update_topology() return mesh
def _collect_new_faces(mesh): newMesh=Mesh() for face in mesh.faces: v1 = face.vertices[-2] v2 = face.vertices[-1] for v3 in face.vertices: edge1 = mesh.edge_adjacent_to_vertices(v1,v2) edge2 = mesh.edge_adjacent_to_vertices(v2,v3) if (edge1 != None) and (edge2!= None): newFace = Face([edge1.vertex, v2.vertex, edge2.vertex, face.vertex]) newFace.color = face.color newFace.group = face.group newMesh.faces.append(newFace) v1 = v2 v2 = v3 newMesh.update_topology() return newMesh
def construct_icosahedron(radius=1, cx=0, cy=0, cz=0): """ Creates and returns a mesh in the form of an icosahedron. Optional Arguments: ---------- radius : float<br> The radius of the containing sphere.<br> cx,cy,cz : float<br> The coordinates of the center point. """ mesh = Mesh() phi = (1 + 5**0.5) / 2 coordA = 1 / (2 * math.sin(2 * math.pi / 5)) coordB = phi / (2 * math.sin(2 * math.pi / 5)) mesh.vertices = [ Vertex(0, -coordA, coordB), Vertex(coordB, 0, coordA), Vertex(coordB, 0, -coordA), Vertex(-coordB, 0, -coordA), Vertex(-coordB, 0, coordA), Vertex(-coordA, coordB, 0), Vertex(coordA, coordB, 0), Vertex(coordA, -coordB, 0), Vertex(-coordA, -coordB, 0), Vertex(0, -coordA, -coordB), Vertex(0, coordA, -coordB), Vertex(0, coordA, coordB) ] for i in range(len(mesh.vertices)): mesh.vertices[i] = utils_vertex.vertex_scale(mesh.vertices[i], radius) mesh.vertices[i] = utils_vertex.vertex_add(mesh.vertices[i], Vertex(cx, cy, cz)) indices = [ 1, 2, 6, 1, 7, 2, 3, 4, 5, 4, 3, 8, 6, 5, 11, 5, 6, 10, 9, 10, 2, 10, 9, 3, 7, 8, 9, 8, 7, 0, 11, 0, 1, 0, 11, 4, 6, 2, 10, 1, 6, 11, 3, 5, 10, 5, 4, 11, 2, 7, 9, 7, 1, 0, 3, 9, 8, 4, 8, 0 ] faces = [] for i in range(0, len(indices), 3): f = Face([ mesh.vertices[indices[i]], mesh.vertices[indices[i + 1]], mesh.vertices[indices[i + 2]] ]) faces.append(f) mesh.faces = faces mesh.update_topology() return mesh
def mesh_offset(mesh, offset=1, doclose=True): """ Creates an offset of a mesh. If `doclose` is `True`, it will create quad faces along the naked edges of an open input mesh. """ newMesh = Mesh() # calculate vertex normals for vertex in mesh.vertices: vertex.vertex = Vertex(0, 0, 0) vertex.nfaces = 0 for face in mesh.faces: normal = utils_face.face_normal(face) for vertex in face.vertices: vertex.vertex.add(normal) vertex.nfaces += 1 for vertex in mesh.vertices: vertex.vertex.scale(offset / vertex.nfaces) vertex.vertex.add(vertex) # create faces for face in mesh.faces: offsetVertices = [] for vertex in face.vertices: offsetVertices.append(vertex.vertex) offsetVertices.reverse() newFace = Face(offsetVertices) newMesh.faces.append(newFace) newMesh.faces.append(face) # create sides if doclose: for edge in mesh.edges: if edge.face1 == None or edge.face2 == None: offsetVertices = [ edge.v1, edge.v2, edge.v2.vertex, edge.v1.vertex ] if edge.face2 == None: offsetVertices.reverse() newFace = Face(offsetVertices) newMesh.faces.append(newFace) newMesh.update_topology() return newMesh
def construct_dodecahedron(radius=1, cx=0, cy=0, cz=0): """ Constructs a dodecaheron mesh. Optional Arguments: ---------- radius : float<br> The radius of the containing sphere<br> cx,cy,cz : float<br> The coordinates of the center point. """ mesh = Mesh() phi = (1 + 5**0.5) / 2 mesh.vertices = [ Vertex(1, 1, 1), Vertex(1, 1, -1), Vertex(1, -1, 1), Vertex(1, -1, -1), Vertex(-1, 1, 1), Vertex(-1, 1, -1), Vertex(-1, -1, 1), Vertex(-1, -1, -1), Vertex(0, -phi, -1 / phi), Vertex(0, -phi, 1 / phi), Vertex(0, phi, -1 / phi), Vertex(0, phi, 1 / phi), Vertex(-phi, -1 / phi, 0), Vertex(-phi, 1 / phi, 0), Vertex(phi, -1 / phi, 0), Vertex(phi, 1 / phi, 0), Vertex(-1 / phi, 0, -phi), Vertex(1 / phi, 0, -phi), Vertex(-1 / phi, 0, phi), Vertex(1 / phi, 0, phi) ] for i in range(len(mesh.vertices)): mesh.vertices[i] = utils_vertex.vertex_scale(mesh.vertices[i], radius) mesh.vertices[i] = utils_vertex.vertex_add(mesh.vertices[i], Vertex(cx, cy, cz)) indices = [ 2, 9, 6, 18, 19, 4, 11, 0, 19, 18, 18, 6, 12, 13, 4, 19, 0, 15, 14, 2, 4, 13, 5, 10, 11, 14, 15, 1, 17, 3, 1, 15, 0, 11, 10, 3, 17, 16, 7, 8, 2, 14, 3, 8, 9, 6, 9, 8, 7, 12, 1, 10, 5, 16, 17, 12, 7, 16, 5, 13 ] for i in range(0, len(indices), 5): f = Face([ mesh.vertices[indices[i]], mesh.vertices[indices[i + 1]], mesh.vertices[indices[i + 2]], mesh.vertices[indices[i + 3]], mesh.vertices[indices[i + 4]] ]) mesh.faces.append(f) mesh.update_topology() return mesh
def construct_box(x1, y1, z1, x2, y2, z2): """ Creates and returns a mesh box with six quad faces. Arguments: ---------- x1,y1,z1 : float<br> The coordinates of the bottom left front corner<br> x2,y2,z2 : float<br> The coordinates of the top right back corner """ mesh = Mesh() v1 = Vertex(x1, y1, z1) v2 = Vertex(x1, y2, z1) v3 = Vertex(x2, y2, z1) v4 = Vertex(x2, y1, z1) v5 = Vertex(x1, y1, z2) v6 = Vertex(x1, y2, z2) v7 = Vertex(x2, y2, z2) v8 = Vertex(x2, y1, z2) mesh.vertices = [v1, v2, v3, v4, v5, v6, v7, v8] f1 = Face([v1, v2, v3, v4]) f2 = Face([v8, v7, v6, v5]) f3 = Face([v4, v3, v7, v8]) f4 = Face([v3, v2, v6, v7]) f5 = Face([v2, v1, v5, v6]) f6 = Face([v1, v4, v8, v5]) mesh.faces = [f1, f2, f3, f4, f5, f6] mesh.update_topology() return mesh
def construct_octahedron(edgeLen=1, cx=0, cy=0, cz=0): mesh = Mesh() #make vertices mesh.vertices = [ Vertex(0, 0, edgeLen / 2), Vertex(-edgeLen / 2, 0, 0), Vertex(0, -edgeLen / 2, 0), Vertex(edgeLen / 2, 0, 0), Vertex(0, edgeLen / 2, 0), Vertex(0, 0, -edgeLen / 2) ] #move center to desired coordinates center = Vertex(cx, cy, cz) for v in mesh.vertices: v.add(center) #construct triangular faces f1 = Face([mesh.vertices[0], mesh.vertices[1], mesh.vertices[2]]) f2 = Face([mesh.vertices[0], mesh.vertices[2], mesh.vertices[3]]) f3 = Face([mesh.vertices[0], mesh.vertices[3], mesh.vertices[4]]) f4 = Face([mesh.vertices[0], mesh.vertices[4], mesh.vertices[1]]) f5 = Face([mesh.vertices[5], mesh.vertices[2], mesh.vertices[1]]) f6 = Face([mesh.vertices[5], mesh.vertices[3], mesh.vertices[2]]) f7 = Face([mesh.vertices[5], mesh.vertices[4], mesh.vertices[3]]) f8 = Face([mesh.vertices[5], mesh.vertices[1], mesh.vertices[4]]) mesh.faces = [f1, f2, f3, f4, f5, f6, f7, f8] mesh.update_topology() return mesh
def construct_torus(ringRadius, tubeRadius, ringN=16, tubeN=16): """ Constructs a torus mesh. Arguments: ---------- ringRadius : float<br> the big radius of the axis<br> tubeRadius : float<br> radius of the the tube along the axis<br> Optional Arguments: ---------- ringN : int<br> resolution along the ring<br> tubeN : int<br> resolution along the tube """ mesh = Mesh() theta = 2 * math.pi / ringN phi = 2 * math.pi / tubeN for i in range(ringN): for j in range(tubeN): mesh.vertices.append( _torus_vertex(ringRadius, tubeRadius, phi * j, theta * i)) for i in range(ringN): ii = (i + 1) % ringN for j in range(tubeN): jj = (j + 1) % tubeN a = i * tubeN + j b = ii * tubeN + j c = ii * tubeN + jj d = i * tubeN + jj f = Face([mesh.vertices[k] for k in [a, b, c, d]]) mesh.faces.append(f) mesh.update_topology() return mesh
def construct_single_face(vertices): """ Creates and returns a single face mesh from the vertices. Arguments: ---------- vertices : list of mola.core.Vertex<br> The vertices describing the face """ mesh = Mesh() mesh.vertices = vertices mesh.faces = [Face(vertices)] mesh.update_topology() return mesh
def mesh_from_rhino_mesh(obj): mesh = Mesh() vertices = rs.MeshVertices(obj) for v in vertices: mesh.vertices.append(Vertex(v[0], v[1], v[2])) faceVerts = rs.MeshFaceVertices(obj) for face in faceVerts: if face[2] == face[3]: mesh.faces.append( Face([ mesh.vertices[face[0]], mesh.vertices[face[1]], mesh.vertices[face[2]] ])) else: mesh.faces.append( Face([ mesh.vertices[face[0]], mesh.vertices[face[1]], mesh.vertices[face[2]], mesh.vertices[face[3]] ])) return mesh
def import_obj(filename): """Loads a Wavefront OBJ file. """ mesh = Mesh() group = "" for line in open(filename, "r"): if line.startswith('#'): continue values = line.split() if not values: continue if values[0] == 'g': group=values[1] elif values[0] == 'v': v = [float(c) for c in values[1 : 4]] #v = map(float, values[1:4]) mesh.vertices.append(Vertex(v[0],v[1],v[2])) elif values[0] == 'f': face = Face([]) face.group = group for v in values[1:]: w = v.split('/') vertex = mesh.vertices[int(w[0]) - 1] face.vertices.append(vertex) mesh.faces.append(face) return mesh
def numpy_to_voxel_mesh(voxel_bools, voxel_colors): """Returns the Mesh of a voxel geometry that is described by Numpy Arrays. Arguments ---------- voxel_bools : numpy.ndarray Numpy Array of shape (nX,nY,nZ) and dtype=bool where True corresponds to a Solid voxel and False corresponds to a Void voxel. voxel_colors : numpy.ndarray Numpy Array of shape (nX,nY,nZ,3) containing r,g,b values for each voxel. """ #add one dimension if input is 2d if voxel_bools.ndim == 2 and voxel_colors.ndim == 3: voxel_bools = voxel_bools[:,:,np.newaxis] voxel_colors = np.expand_dims(voxel_colors, axis=2) shape = voxel_bools.shape nx, ny, nz = shape[0], shape[1], shape[2] mesh = Mesh() for index in np.ndindex(shape): x = index[0] y = index[1] z = index[2] if voxel_bools[x, y, z]: # (x,y) (x1,y) (x1,y1) (x,y1) r = voxel_colors[x, y, z, 0] g = voxel_colors[x, y, z, 1] b = voxel_colors[x, y, z, 2] # rgb=voxel_colors[x,y,z] rgb = (r, g, b, 1) if x == nx - 1 or not voxel_bools[x+1, y, z]: v1 = mesh.add_vertex(x + 1, y, z) v2 = mesh.add_vertex(x + 1, y + 1, z) v3 = mesh.add_vertex(x + 1, y + 1, z + 1) v4 = mesh.add_vertex(x + 1, y, z + 1) new_face = mesh.add_face([v1, v2, v3, v4]) new_face.color = rgb if x == 0 or not voxel_bools[x-1, y, z]: v1 = mesh.add_vertex(x, y + 1, z) v2 = mesh.add_vertex(x, y, z) v3 = mesh.add_vertex(x, y, z + 1) v4 = mesh.add_vertex(x, y + 1, z + 1) new_face = mesh.add_face([v1, v2, v3, v4]) new_face.color = rgb if y == ny - 1 or not voxel_bools[x, y+1, z]: v1 = mesh.add_vertex(x + 1, y + 1, z) v2 = mesh.add_vertex(x, y + 1, z) v3 = mesh.add_vertex(x, y + 1, z + 1) v4 = mesh.add_vertex(x + 1, y + 1, z + 1) new_face = mesh.add_face([v1, v2, v3, v4]) new_face.color = rgb if y == 0 or not voxel_bools[x, y-1, z]: v1 = mesh.add_vertex(x, y, z) v2 = mesh.add_vertex(x + 1, y, z) v3 = mesh.add_vertex(x + 1, y, z + 1) v4 = mesh.add_vertex(x, y, z + 1) new_face = mesh.add_face([v1, v2, v3, v4]) new_face.color = rgb if z == nz-1 or not voxel_bools[x, y, z+1]: v1 = mesh.add_vertex(x, y, z + 1) v2 = mesh.add_vertex(x + 1, y, z + 1) v3 = mesh.add_vertex(x + 1, y + 1, z + 1) v4 = mesh.add_vertex(x, y + 1, z + 1) new_face = mesh.add_face([v1, v2, v3, v4]) new_face.color = rgb if z == 0 or not voxel_bools[x, y, z-1]: v1 = mesh.add_vertex(x, y + 1, z) v2 = mesh.add_vertex(x + 1, y + 1, z) v3 = mesh.add_vertex(x + 1, y, z) v4 = mesh.add_vertex(x, y, z) new_face = mesh.add_face([v1, v2, v3, v4]) new_face.color = rgb mesh.update_topology() return mesh
def construct_sphere(radius=1, cx=0, cy=0, cz=0, u_res=10, v_res=10): """ Constructs a uv sphere mesh. Optional Arguments: ---------- radius : float<br> The radius of the sphere.<br> cx,cy,cz : float<br> The coordinates of the center point.<br> u_res : float<br> The u resolution of the sphere.<br> y_res : float<br> The v resolution of the sphere. """ mesh = Mesh() for v in range(v_res + 1): theta = math.pi * (float(v) / v_res) for u in range(u_res): phi = 2.0 * math.pi * (float(u) / u_res) cartesian = _polar_to_cartesian(radius, theta, phi) mesh.add_vertex(cartesian[0] + cx, cartesian[1] + cy, cartesian[2] + cz) #work around weld_vertices problem v_top = mesh.vertices[0] v_bottom = mesh.vertices[v_res * u_res + u_res - 1] for v in range(v_res): for u in range(u_res): v0 = mesh.vertices[v * u_res + u] v1 = mesh.vertices[(v + 1) * u_res + u] v2 = mesh.vertices[(v + 1) * u_res + (u + 1) % u_res] v3 = mesh.vertices[v * u_res + (u + 1) % u_res] if (v == 0): mesh.add_face([v_top, v1, v2]) elif (v == v_res - 1): mesh.add_face([v0, v_bottom, v3]) else: mesh.add_face([v0, v1, v2, v3]) mesh.update_topology() return mesh
def construct_rhombic_dodecahedron(edge_length=1, cx=0, cy=0, cz=0): mesh = Mesh() #make vertices mesh.vertices = [ Vertex(0, 0, 2 * edge_length), Vertex(-edge_length, edge_length, edge_length), Vertex(-edge_length, -edge_length, edge_length), Vertex(edge_length, -edge_length, edge_length), Vertex(edge_length, edge_length, edge_length), Vertex(-2 * edge_length, 0, 0), Vertex(0, -2 * edge_length, 0), Vertex(2 * edge_length, 0, 0), Vertex(0, 2 * edge_length, 0), Vertex(-edge_length, edge_length, -edge_length), Vertex(-edge_length, -edge_length, -edge_length), Vertex(edge_length, -edge_length, -edge_length), Vertex(edge_length, edge_length, -edge_length), Vertex(0, 0, -2 * edge_length) ] #move center to desired coordinates center = Vertex(cx, cy, cz) for v in mesh.vertices: v.add(center) #construct quad faces f1 = Face([ mesh.vertices[0], mesh.vertices[2], mesh.vertices[5], mesh.vertices[1] ]) f2 = Face([ mesh.vertices[0], mesh.vertices[3], mesh.vertices[6], mesh.vertices[2] ]) f3 = Face([ mesh.vertices[0], mesh.vertices[4], mesh.vertices[7], mesh.vertices[3] ]) f4 = Face([ mesh.vertices[0], mesh.vertices[1], mesh.vertices[8], mesh.vertices[4] ]) f5 = Face([ mesh.vertices[2], mesh.vertices[6], mesh.vertices[10], mesh.vertices[5] ]) f6 = Face([ mesh.vertices[3], mesh.vertices[7], mesh.vertices[11], mesh.vertices[6] ]) f7 = Face([ mesh.vertices[4], mesh.vertices[8], mesh.vertices[12], mesh.vertices[7] ]) f8 = Face([ mesh.vertices[1], mesh.vertices[5], mesh.vertices[9], mesh.vertices[8] ]) f9 = Face([ mesh.vertices[10], mesh.vertices[13], mesh.vertices[9], mesh.vertices[5] ]) f10 = Face([ mesh.vertices[11], mesh.vertices[13], mesh.vertices[10], mesh.vertices[6] ]) f11 = Face([ mesh.vertices[12], mesh.vertices[13], mesh.vertices[11], mesh.vertices[7] ]) f12 = Face([ mesh.vertices[9], mesh.vertices[13], mesh.vertices[12], mesh.vertices[8] ]) mesh.faces = [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12] mesh.update_topology() return mesh