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 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 subdivide_catmull_2d(vertices): newNodes = [] for i in range(len(vertices)): a = vertices[i] newNodes.append(Vertex(a.x,a.y,a.z)) b = vertices[(i + 1) % len(vertices)] center = utils_vertex.vertex_add(a, b) newNodes.append(utils_vertex.vertex_scale(center,0.5)) newNodes2 = [] for i in range(len(newNodes)): iPrev = i - 1 if iPrev < 0: iPrev = len(newNodes) - 1 iNext = i + 1 if iNext >= len(newNodes): iNext = 0 a = newNodes[iPrev] b = newNodes[i] c = newNodes[iNext] average = Vertex() # [average.add(v) for v in [a,b,b,c]] average.add(a) average.add(b) average.add(b) average.add(c) average.divide(4.0) # average = utils_vertex.vertex_add(average,a) # average = utils_vertex.vertex_add(average,b) # average = utils_vertex.vertex_add(average,b) # average = utils_vertex.vertex_add(average,c) # average /= 4 # average = utils_vertex.vertex_divide(average,4.0) newNodes2.append(average) return newNodes2
def sliceWithZ(v1, v2, z): if v1.z == z: return Vertex(v1.x, v1.y, z) if v1.z <= z and v2.z <= z: return None if v1.z >= z and v2.z >= z: return None dX = v2.x - v1.x dY = v2.y - v1.y dZ = v2.z - v1.z if dZ == 0: return None f = (z - v1.z) / dZ return Vertex(f * dX + v1.x, f * dY + v1.y, z)
def _catmullVertices(mesh): for face in mesh.faces: face.vertex = face.center() for edge in mesh.edges: if edge.face1 == None or edge.face2 == None: edge.v1.fix = True edge.v2.fix = True edge.vertex = edge.center() else: vsum = Vertex() nElements = 2 vsum = utils_vertex.vertex_add(vsum, edge.v1) vsum = utils_vertex.vertex_add(vsum, edge.v2) if edge.face1 != None: vsum = utils_vertex.vertex_add(vsum, edge.face1.vertex) nElements += 1 if edge.face2 != None: vsum = utils_vertex.vertex_add(vsum, edge.face2.vertex) nElements += 1 vsum = utils_vertex.vertex_divide(vsum, nElements) edge.vertex = vsum if edge.v1.fix and edge.v2.fix: edge.vertex.fix = True for vertex in mesh.vertices: if vertex.fix: vertex.vertex = copy.copy(vertex) else: averageFaces = Vertex() averageEdges = Vertex() nEdges = len(vertex.edges) for edge in vertex.edges: face = edge.face1 if edge.v2 is vertex: face = edge.face2 if face != None: averageFaces = utils_vertex.vertex_add( averageFaces, face.vertex) averageEdges = utils_vertex.vertex_add(averageEdges, edge.center()) averageEdges = utils_vertex.vertex_scale(averageEdges, 2.0 / nEdges) averageFaces = utils_vertex.vertex_scale(averageFaces, 1.0 / nEdges) v = Vertex(vertex.x, vertex.y, vertex.z) v = utils_vertex.vertex_scale(v, nEdges - 3) v = utils_vertex.vertex_add(v, averageFaces) v = utils_vertex.vertex_add(v, averageEdges) v = utils_vertex.vertex_scale(v, 1.0 / nEdges) vertex.vertex = v
def mesh_smooth_laplacian(mesh, factor=0.3): smoothed = mesh.copy() #smoothed.update_topology() for i, v in enumerate(mesh.vertices): adjacent_vertices = [e.other_vertex(v) for e in v.edges] v_sum = Vertex() [v_sum.add(av) for av in adjacent_vertices] v_sum.divide(len(adjacent_vertices)) delta = v_sum - v sv = smoothed.vertices[i] delta.scale(factor) sv.add(delta) return smoothed
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 center(self): """ returns the midpoint on an edge as a Vertex() object """ return Vertex((self.v2.x + self.v1.x) / 2.0, (self.v2.y + self.v1.y) / 2.0, (self.v2.z + self.v1.z) / 2.0)
def construct_circle(radius, segments, z=0): vertices = [] deltaAngle = math.pi * 2.0 / segments for i in range(segments): cAngle = i * deltaAngle vertices.append(Vertex(math.cos(cAngle) * radius, math.sin(cAngle) * radius, z)) return vertices
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 translate(self, tx, ty, tz): """ translates a mesh by adding tx,ty and tz to the position of the vertices. """ vt = Vertex(tx, ty, tz) for v in self.vertices: v.add(vt)
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 mesh_smooth_laplacian(mesh, factor=0.3): """ Applies Laplacian smoothing to a mesh. It works by moving each vertex in the direction of the average position of its neighbors. Note: this does not increase the face count. """ smoothed = mesh.copy() #smoothed.update_topology() for i, v in enumerate(mesh.vertices): adjacent_vertices = [e.other_vertex(v) for e in v.edges] v_sum = Vertex() [v_sum.add(av) for av in adjacent_vertices] v_sum.divide(len(adjacent_vertices)) delta = v_sum - v sv = smoothed.vertices[i] delta.scale(factor) sv.add(delta) return smoothed
def vertex_offset_line(v1, v2, offset): v = vertex_subtract(v2, v1) v = vertex_unitize(v) v = vertex_scale(v,offset) t = v.x v.x = -v.y v.y = t v.z = 0 return Vertex(vertex_add(v1, v), vertex_add(v2, v))
def subdivide_mesh(mesh,values=[]): for face in mesh.faces: face.vertex=utils_face.center(face) for edge in mesh.edges: edge.vertex = edge.center() for vertex in mesh.vertices: vertex.vertex = Vertex(vertex.x,vertex.y,vertex.z) if len(values)>0: _translate_face_vertices(mesh,values) return _collect_new_faces(mesh)
def copy(self): meshcopy = Mesh() # if mesh has no topolgy constructed if len(self.edges) == 0: for f in self.faces: vs = [Vertex(v.x,v.y,v.z) for v in f.vertices] for nv,ov in zip(vs, f.vertices): nv.fix = ov.fix nv.generation = ov.generation nf = meshcopy.add_face(vs) utils_face.face_copy_properties(f,nf) else: meshcopy.vertices = [Vertex(v.x,v.y,v.z) for v in self.vertices] for nv,ov in zip(meshcopy.vertices, self.vertices): nv.fix = ov.fix nv.generation = ov.generation for f in self.faces: vs = [meshcopy.vertices[self.vertices.index(v)] for v in f.vertices] nf = meshcopy.add_face(vs) utils_face.face_copy_properties(f,nf) for e in self.edges: iv1 = self.vertices.index(e.v1) iv2 = self.vertices.index(e.v1) ie1 = self.faces.index(e.face1) ie2 = self.faces.index(e.face2) v1c = meshcopy.vertices[iv1] v2c = meshcopy.vertices[iv2] edge = Edge(v1c,v2c) v1c.edges.append(edge) v2c.edges.append(edge) meshcopy.edges.append(edge) edge.face1 = meshcopy.faces[ie1] edge.face2 = meshcopy.faces[ie2] return meshcopy
def vertices_list_center(vertices): """ Returns the center point (type Vertex) of a list of vertices. Note: not the center of gravity, just the average of the vertices. Arguments: ---------- vertices : list of mola.Vertex The list of vertices to be measured """ n = len(vertices) cx = sum([v.x for v in vertices]) / n cy = sum([v.y for v in vertices]) / n cz = sum([v.z for v in vertices]) / n return Vertex(cx,cy,cz)
def vertex_center(v1,v2): """ Returns the center of a line defined by two vertices. Arguments: ---------- v1, v2 : mola.Vertex start and end points of the line Returns: -------- mola.Vertex the center point of the line """ return Vertex((v1.x+v2.x)/2,(v1.y+v2.y)/2,(v1.z+v2.z)/2)
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 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 vertex_line_line_intersection(a,b,c,d): """ Returns the intersection of two lines in 2D as a new Vertex. Arguments: ---------- a,b,c,d: mola.Vertex a,b are the endpoints of line1 c,d are the endpoints of line2 """ deltaABX = b.x - a.x deltaABY = b.y - a.y deltaDCX = d.x - c.x deltaDCY = d.y - c.y denominator = deltaABX * deltaDCY - deltaABY * deltaDCX if denominator == 0: return None numerator = (a.y - c.y) * deltaDCX - (a.x - c.x) * deltaDCY r = numerator / denominator x = a.x + r * deltaABX y = a.y + r * deltaABY return Vertex(x,y,0)
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 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 marching_cubes(nX,nY,nZ,values,iso, scale_to_canvas=False): 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() if(scale_to_canvas): mesh.translate(-nX/2.0,-nY/2.0,-nZ/2.0) sc = 20.0/max(nX,nY) mesh.scale(sc,sc,sc) return mesh
def vertex_scale(v,factor): """ scales the position vector of a Vertex by a factor (multiplication) and returns the result as a new Vertex. """ return Vertex(v.x * factor, v.y * factor, v.z * factor)
def vertex_divide(v,factor): """ scales the position vector of a Vertex by a factor (division) and returns the result as a new Vertex. """ return Vertex(v.x / factor, v.y / factor, v.z / factor)
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 vertex_cross(v1,v2): """ returns the cross product of v1 and v2 as a new Vertex. """ return Vertex(v1.y * v2.z - v2.y * v1.z, v1.z * v2.x - v2.z * v1.x, v1.x * v2.y - v2.x * v1.y)
def add_vertex(self, x, y, z=0): v = Vertex(x,y,z) self.vertices.append(v) return v
def center(self): """ returns the Box's center as a Vertex() object """ return Vertex((self.x2 + self.x1) / 2.0, (self.y2 + self.y1) / 2.0, (self.z2 + self.z1) / 2.0)