예제 #1
0
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
예제 #2
0
def subdivide_face_extrude_tapered(face, height=0.0, fraction=0.5,doCap=True):
    """
    Extrudes the face tapered like a window by creating an
    offset face and quads between every original edge and the
    corresponding new edge.

    Arguments:
    ----------
    face : mola.core.Face
        The face to be extruded
    height : float
        The distance of the new face to the original face, default 0
    fraction : float
        The relative offset distance, 0: original vertex, 1: center point
        default 0.5 (halfway)
    """
    center_vertex = utils_face.face_center(face)
    normal = utils_face.face_normal(face)
    scaled_normal = utils_vertex.vertex_scale(normal, height)

    # calculate new vertex positions
    new_vertices = []
    for i in range(len(face.vertices)):
        n1 = face.vertices[i]
        betw = utils_vertex.vertex_subtract(center_vertex, n1)
        betw = utils_vertex.vertex_scale(betw, fraction)
        nn = utils_vertex.vertex_add(n1, betw)
        nn = utils_vertex.vertex_add(nn, scaled_normal)
        new_vertices.append(nn)

    new_faces = []
    # create the quads along the edges
    num = len(face.vertices)
    for i in range(num):
        n1 = face.vertices[i]
        n2 = face.vertices[(i + 1) % num]
        n3 = new_vertices[(i + 1) % num]
        n4 = new_vertices[i]
        new_face = Face([n1,n2,n3,n4])
        new_faces.append(new_face)

    # create the closing cap face
    if doCap:
        cap_face = Face(new_vertices)
        new_faces.append(cap_face)

    for new_face in new_faces:
        utils_face.face_copy_properties(face,new_face)
    return new_faces
예제 #3
0
def subdivide_face_extrude_to_point_center(face, height=0.0):
    """
    Extrudes the face to the center point moved by height
    normal to the face and creating a triangular face from
    each edge to the point.

    Arguments:
    ----------
    face : mola.core.Face
        The face to be extruded
    height : float
        The distance of the new point to the face center, default 0
    """
    normal = utils_face.face_normal(face)
    normal = utils_vertex.vertex_scale(normal,height)
    center = utils_face.face_center(face)
    center = utils_vertex.vertex_add(center,normal)
    return subdivide_face_extrude_to_point(face,center)
예제 #4
0
def subdivide_face_split_roof(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 = utils_face.face_normal(face)
    normal = utils_vertex.vertex_scale(normal,height)
    if len(face.vertices) == 4:
        ev1 = utils_vertex.vertex_center(face.vertices[0], face.vertices[1])
        ev1 = utils_vertex.vertex_add(ev1, normal)
        ev2 = utils_vertex.vertex_center(face.vertices[2], face.vertices[3])
        ev2 = utils_vertex.vertex_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:
            utils_face.face_copy_properties(face,f)
        return faces

    elif len(face.vertices) == 3:
        ev1 = utils_vertex.vertex_center(face.vertices[0], face.vertices[1])
        ev1 = utils_vertex.vertex_add(ev1, normal)
        ev2 = utils_vertex.vertex_center(face.vertices[1], face.vertices[2])
        ev2 = utils_vertex.vertex_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:
            utils_face.face_copy_properties(face, f)
        return faces
    return [face]
예제 #5
0
 def curvature(self):
     """
     Returns the local curvature of a mesh face, by measuring the angle to the neighbour faces.
     """
     facenormal = self.normal()
     sumD = 0
     vPrev = self.vertices[-1]
     num_faces = 1
     for v in self.vertices:
         edge = v.edge_adjacent_to_vertex(vPrev)
         if edge != None:
             nbFace = edge.face1
             if edge.face1 == self:
                 nbFace = edge.face2
             if nbFace != None:
                 num_faces += 1
                 nbNormal = utils_face.face_normal(nbFace)
                 sumD += utils_vertex.vertex_distance(nbNormal,facenormal)
         vPrev = v
     return sumD / num_faces
예제 #6
0
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
예제 #7
0
def subdivide_face_extrude(face, height=0.0, capBottom=False, capTop=True):
    """
    Extrudes the face straight by distance height.

    Arguments:
    ----------
    face : mola.core.Face
        The face to be extruded
    height : float
        The extrusion distance, default 0
    capBottom : bool
        Toggle if bottom face (original face) should be created, default False
    capTop : bool
        Toggle if top face (extrusion face) should be created, default True
    """
    normal=utils_face.face_normal(face)
    normal=utils_vertex.vertex_scale(normal,height)
    # calculate vertices
    new_vertices=[]
    for i in range(len(face.vertices)):
        new_vertices.append(utils_vertex.vertex_add(face.vertices[i], normal))
    # faces
    new_faces=[]
    if capBottom:
        new_faces.append(face)
    for i in range(len(face.vertices)):
        i2=i+1
        if i2>=len(face.vertices):
            i2=0
        v0=face.vertices[i]
        v1=face.vertices[i2]
        v2=new_vertices[i2]
        v3=new_vertices[i]
        new_faces.append(Face([v0,v1,v2,v3]))
    if capTop:
        new_faces.append(Face(new_vertices))
    for new_face in new_faces:
        utils_face.face_copy_properties(face,new_face)
    return new_faces
예제 #8
0
def _translate_face_vertices(mesh,values):
    for face,value in zip(mesh.faces, values):
        normal=utils_face.face_normal(face)
        normal.scale(value)
        face.vertex.add(normal)
예제 #9
0
def subdivide_custom_triface_extrude_tapered_nonU(face,
                                                  height=0.0,
                                                  fraction=0.5,
                                                  doCap=True):
    """
    Extrudes a triangular face tapered like a window by creating an
    offset face and quads between every original edge and the
    corresponding new edge. The vertices of the new edge which corresponds 
    to the shortest edge of the triangle are moved closer to the later,
    while preserving the offset from its other edges 

    Arguments:
    ----------
    face : mola.core.Face
        The face to be extruded
    height : float
        The distance of the new face to the original face, default 0
    fraction : float
        The relative offset distance, 0: original vertex, 1: center point
        default 0.5 (halfway)
    """

    center_vertex = utils_face.face_center(face)
    normal = utils_face.face_normal(face)
    scaled_normal = utils_vertex.vertex_scale(normal, height)

    minD = 9999999999999999
    for i in range(len(face.vertices) - 1):
        n1 = face.vertices[i]
        for j in range(i + 1, len(face.vertices)):

            n2 = face.vertices[j]
            d = (n2.x - n1.x)**2.0 + (n2.y - n1.y)**2.0 + (n2.z - n1.z)**2.0
            if d < minD:
                minD = d
                shortF_st = i
                shortF_end = j

    other = 3 - shortF_st - shortF_end
    n_other = face.vertices[other]
    betw_other = utils_vertex.vertex_subtract(center_vertex, n_other)
    betw_other = utils_vertex.vertex_scale(betw_other, fraction)
    nn_other = utils_vertex.vertex_add(n_other, betw_other)
    nn_other = utils_vertex.vertex_add(nn_other, scaled_normal)

    # calculate new vertex positions
    new_vertices = []
    for i in range(len(face.vertices)):
        n1 = face.vertices[i]
        betw = utils_vertex.vertex_subtract(center_vertex, n1)
        betw = utils_vertex.vertex_scale(betw, fraction)
        nn = utils_vertex.vertex_add(n1, betw)
        nn = utils_vertex.vertex_add(nn, scaled_normal)

        if i == shortF_st or i == shortF_end:
            vec = utils_vertex.vertex_subtract(n1, nn_other)
            vec = utils_vertex.vertex_scale(vec, 0.25)
            nn = utils_vertex.vertex_add(nn, vec)

        new_vertices.append(nn)

    new_faces = []
    # create the quads along the edges
    num = len(face.vertices)
    for i in range(num):
        n1 = face.vertices[i]
        n2 = face.vertices[(i + 1) % num]
        n3 = new_vertices[(i + 1) % num]
        n4 = new_vertices[i]
        new_face = Face([n1, n2, n3, n4])
        new_faces.append(new_face)

    # create the closing cap face
    if doCap:
        cap_face = Face(new_vertices)
        new_faces.append(cap_face)

    for new_face in new_faces:
        utils_face.face_copy_properties(face, new_face)

    return new_faces