예제 #1
0
파일: factory.py 프로젝트: wenqian157/mola
def constructTetrahedron(cx,cy,cz,side):
    """
    Constructs a tetrahedron mesh.

    Arguments:
    ----------
    cx, cy, cz : float
        The center point of the tetrahedron
    side : float
        The edge length of the tetrahedron
    """
    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] = vec.scale(mesh.vertices[i], side / 2)
        mesh.vertices[i] = vec.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]
    return mesh
예제 #2
0
파일: slicer.py 프로젝트: wenqian157/mola
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)
예제 #3
0
파일: factory.py 프로젝트: wenqian157/mola
def constructBox(x1,y1,z1,x2,y2,z2):
    """
    Creates and returns a mesh box with six quad faces.

    Arguments:
    ----------
    x1,y1,z1 : float
        The coordinates of the bottom left front corner
    x2,y2,z2 : float
        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]
    return mesh
예제 #4
0
def _catmullVertices(mesh):
    for face in mesh.faces:
        face.vertex = faceUtils.center(face)

    for edge in mesh.edges:
        if edge.face1 == None or edge.face2 == None:
            edge.v1.fix = True
            edge.v2.fix = True
            edge.vertex = edge.getCenter()
        else:
            vsum = Vertex()
            nElements = 2
            vsum = vec.add(vsum, edge.v1)
            vsum = vec.add(vsum, edge.v2)
            if edge.face1 != None:
                vsum = vec.add(vsum, edge.face1.vertex)
                nElements += 1
            if edge.face2 != None:
                vsum = vec.add(vsum, edge.face2.vertex)
                nElements += 1
            vsum = vec.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 = vec.add(averageFaces, face.vertex)
                averageEdges=vec.add(averageEdges,edge.getCenter())
            averageEdges = vec.scale(averageEdges, 2.0/nEdges)
            averageFaces = vec.scale(averageFaces, 1.0/nEdges)

            v = Vertex(vertex.x, vertex.y, vertex.z)
            v = vec.scale(v,nEdges-3)
            v = vec.add(v,averageFaces)
            v = vec.add(v,averageEdges)
            v = vec.scale(v,1.0/nEdges)
            vertex.vertex = v
예제 #5
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 = faceUtils.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.updateAdjacencies()
    return newMesh
예제 #6
0
def subdivide(mesh):
    for face in mesh.faces:
        face.vertex=faceUtils.center(face)
    for edge in mesh.edges:
        edge.vertex = edge.getCenter()
    for vertex in mesh.vertices:
        vertex.vertex = Vertex(vertex.x,vertex.y,vertex.z)
    return _collectNewFaces(mesh)
예제 #7
0
def subdivide_translate_facevertices(mesh,values):
    for face in mesh.faces:
        face.vertex=faceUtils.center(face)
    for edge in mesh.edges:
        edge.vertex = edge.getCenter()
    for vertex in mesh.vertices:
        vertex.vertex = Vertex(vertex.x,vertex.y,vertex.z)
    _translateFaceVertices(mesh,values)
    return _collectNewFaces(mesh)
예제 #8
0
파일: vec.py 프로젝트: wenqian157/mola
def offsetLine(v1, v2, offset):
    v = subtract(v2, v1)
    v = unitize(v)
    v = scale(v, offset)
    t = v.x
    v.x = -v.y
    v.y = t
    v.z = 0
    return Vertex(add(v1, v), add(v2, v))
예제 #9
0
파일: vec.py 프로젝트: wenqian157/mola
def lineLineIntersection(a, b, c, d):
    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)
예제 #10
0
파일: factory.py 프로젝트: wenqian157/mola
def constructCone(z1, z2, radius1, radius2, nSegments, capBottom=True, capTop=True):
    """
    Creates and returns a conic cylinder.
    """
    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))
    return mesh
예제 #11
0
def centerFromVertices(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.core.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)
예제 #12
0
def centerFromLine(v1,v2):
    """
    Returns the center of a line defined by two vertices.

    Arguments:
    ----------
    v1, v2 : mola.core.Vertex
        start and end points of the line

    Returns:
    --------
    mola.core.Vertex
        the center point of the line
    """
    return Vertex((v1.x + v2.x) / 2, (v1.y + v2.y) / 2, (v1.z + v2.z) / 2)
예제 #13
0
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 = [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
예제 #14
0
파일: factory.py 프로젝트: wenqian157/mola
def _getTorusVertex(ringRadius, tubeRadius, ph,th):
    x = math.cos(th) * (ringRadius + tubeRadius * math.cos(ph))
    y = math.sin(th) * (ringRadius + tubeRadius * math.cos(ph))
    z = tubeRadius * math.sin(ph)
    return Vertex(x, y, z)
예제 #15
0
 def getQuadMesh(self, functionIn, functionOut):
     faces = []
     for x in range(self.nX):
         for y in range(self.nY):
             for z in range(self.nZ):
                 index = self.getIndex(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_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_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_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_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_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_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
     return mesh
예제 #16
0
파일: vec.py 프로젝트: wenqian157/mola
def center(v1, v2):
    return Vertex((v1.x + v2.x) / 2, (v1.y + v2.y) / 2, (v1.z + v2.z) / 2)
예제 #17
0
파일: vec.py 프로젝트: wenqian157/mola
def betweenRel(v1, v2, f):
    return Vertex((v2.x - v1.x) * f + v1.x, (v2.y - v1.y) * f + v1.y,
                  (v2.z - v1.z) * f + v1.z)
예제 #18
0
파일: vec.py 프로젝트: wenqian157/mola
def divide(v, factor):
    return Vertex(v.x / factor, v.y / factor, v.z / factor)
예제 #19
0
파일: vec.py 프로젝트: wenqian157/mola
def cross(v1, v2):
    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)
예제 #20
0
파일: vec.py 프로젝트: wenqian157/mola
def subtract(v1, v2):
    return Vertex(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z)
예제 #21
0
파일: vec.py 프로젝트: wenqian157/mola
def scale(v, factor):
    return Vertex(v.x * factor, v.y * factor, v.z * factor)
예제 #22
0
파일: vec.py 프로젝트: wenqian157/mola
def add(v1, v2):
    return Vertex(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z)
예제 #23
0
파일: vec.py 프로젝트: wenqian157/mola
def rot2D90(vertex):
    return Vertex(-vertex.y, vertex.x, vertex.z)
예제 #24
0
파일: factory.py 프로젝트: wenqian157/mola
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
예제 #25
0
def marchingCubes(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))
    return mesh
예제 #26
0
파일: factory.py 프로젝트: wenqian157/mola
def constructDodecahedron(cx,cy,cz,radius):
    """
    Constructs a dodecaheron mesh.

    Arguments:
    ----------
    cx, cy, cz : float
        The center point of the dodecaheron
    radius : float
        The radius of the containing sphere
    """
    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] = vec.scale(mesh.vertices[i], radius)
        mesh.vertices[i] = vec.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)

    return mesh