def splitRelFreeQuad(face, indexEdge, split1, split2): """ Splits a quad in two new quads through the points specified by relative position along the edge. Arguments: ---------- face : mola.core.Face The face to be extruded indexEdge : int direction of split, 0: 0->2, 1: 1->3 split1, split2 : float relative position of split on each edge (0..1) """ # only works with quads, therefore return original face if triangular if len(face.vertices) != 4: return face # constrain indexEdge to be either 0 or 1 indexEdge = indexEdge % 2 indexEdge1 = (indexEdge + 1) % len(face.vertices) indexEdge2 = (indexEdge + 2) % len(face.vertices) indexEdge3 = (indexEdge + 3) % len(face.vertices) p1 = _vec.betweenRel(face.vertices[indexEdge], face.vertices[indexEdge1], split1) p2 = _vec.betweenRel(face.vertices[indexEdge2], face.vertices[indexEdge3], split2) faces = [] if indexEdge == 0: faces.append(_Face([face.vertices[0], p1, p2, face.vertices[3]])) faces.append(_Face([p1, face.vertices[1], face.vertices[2], p2])) elif indexEdge == 1: faces.append(_Face([face.vertices[0], face.vertices[1], p1, p2])) faces.append(_Face([p2, p1, face.vertices[2], face.vertices[3]])) return faces
def _collectNewFaces(_mesh): newMesh=_Mesh() for face in _mesh.faces: v1=face.vertices[-2] v2=face.vertices[-1] for v3 in face.vertices: edge1=_mesh.getEdgeAdjacentToVertices(v1,v2) edge2=_mesh.getEdgeAdjacentToVertices(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.updateAdjacencies() return newMesh
def splitRoof(face, height): """ Extrudes a pitched roof Arguments: ---------- face : mola.core.Face The face to be extruded height : mola.core.Vertex Th height of the roof """ faces = [] normal = faceUtils.normal(face) normal = _vec.scale(normal,height) if len(face.vertices)==4: ev1=_vec.center(face.vertices[0],face.vertices[1]) ev1=_vec.add(ev1,normal) ev2=_vec.center(face.vertices[2],face.vertices[3]) ev2=_vec.add(ev2,normal) faces.append(_Face([face.vertices[0],face.vertices[1],ev1])) faces.append(_Face([face.vertices[1],face.vertices[2],ev2,ev1])) faces.append(_Face([face.vertices[2],face.vertices[3],ev2])) faces.append(_Face([face.vertices[3],face.vertices[0],ev1,ev2])) for f in faces: faceUtils.copyProperties(face,f) return faces elif len(face.vertices)==3: ev1=_vec.center(face.vertices[0],face.vertices[1]) ev1=_vec.add(ev1,normal) ev2=_vec.center(face.vertices[1],face.vertices[2]) ev2=_vec.add(ev2,normal) faces.append(_Face([face.vertices[0],face.vertices[1],ev1])) faces.append(_Face([face.vertices[1],ev2,ev1])) faces.append(_Face([face.vertices[1],face.vertices[2],ev2])) faces.append(_Face([face.vertices[2],face.vertices[0],ev1,ev2])) for f in faces: faceUtils.copyProperties(face,f) return faces return [face]
def splitOffsets(face,offsets): offsetFace = offsetPlanar(face,offsets) nOffsetFaces = 0 for o in offsets: if(abs(o)>0): nOffsetFaces+=1 faces = [] for i in range(len(face.vertices)): if(abs(offsets[i])>0): i2 = (i+1)%len(face.vertices) f = _Face([face.vertices[i],face.vertices[i2],offsetFace.vertices[i2],offsetFace.vertices[i]]) faceUtils.copyProperties(face,f) faces.append(f) faces.append(offsetFace) for f in faces: if(faceUtils.area(f)<0): f.vertices.reverse() return faces
def constructTorus(ringRadius, tubeRadius, ringN=16, tubeN=16): mesh = _Mesh() phi = 2 * _math.pi / ringN theta = 2 * _math.pi / tubeN for i in range(ringN): for j in range(tubeN): v0 = _getTorusVertex(ringRadius, tubeRadius, phi * ((i + 1) % ringN), theta * j) v1 = _getTorusVertex(ringRadius, tubeRadius, phi * ((i + 1) % ringN), theta * ((j + 1) % tubeN)) v2 = _getTorusVertex(ringRadius, tubeRadius, phi * i, theta * ((j + 1) % tubeN)) v3 = _getTorusVertex(ringRadius, tubeRadius, phi * i, theta * j) f = _Face([v0, v1, v2, v3]) mesh.faces.append(f) return mesh
def extrudeToPoint(face, point): """ Extrudes the face to a point by creating a triangular face from each edge to the point. Arguments: ---------- face : mola.core.Face The face to be extruded point : mola.core.Vertex The point to extrude to """ numV = len(face.vertices) faces = [] for i in range(numV): v1 = face.vertices[i] v2 = face.vertices[(i + 1) % numV] faces.append(_Face([v1, v2, point])) return faces
def constructIcosahedron(cx,cy,cz,radius): """ Creates and returns a mesh in the form of an icosahedron. Arguments: ---------- cx,cy,cz : float The coordinates of the center point radius : float The radius of the containing sphere """ 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] = _vec.scale(mesh.vertices[i],radius) mesh.vertices[i] = _vec.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 return mesh
def importOBJ(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 = 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