Esempio n. 1
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
Esempio n. 2
0
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
Esempio n. 3
0
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
Esempio n. 4
0
def _vertices_between(v1,v2,n):
    row = []
    deltaV = utils_vertex.vertex_subtract(v2, v1)
    deltaV = utils_vertex.vertex_divide(deltaV, n)
    for i in range(n):
        addV = utils_vertex.vertex_scale(deltaV, i)
        row.append(utils_vertex.vertex_add(addV, v1))
    row.append(v2)
    return row
Esempio n. 5
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]
Esempio n. 6
0
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
Esempio n. 7
0
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
Esempio n. 8
0
def normal_vertex_2d(vprev, v, vnext):
    vec1 = utils_vertex.vertex_subtract(v, vprev)
    vec1 = utils_vertex.vertex_unitize(vec1)
    vec2 = utils_vertex.vertex_subtract(vnext, v)
    vec2 = utils_vertex.vertex_unitize(vec2)
    n = utils_vertex.vertex_add(vec1, vec2)
    n = utils_vertex.vertex_scale(n, 0.5)
    n = utils_vertex.vertex_rotate_2D_90(n)
    #t=n.x
    #n.x=-n.y
    #n.y=t
    return n
Esempio n. 9
0
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
Esempio n. 10
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)
Esempio n. 11
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
Esempio n. 12
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