mesh.py 2.77 KB
Newer Older
1 2 3 4
import numpy as np
from .mesh_helper import calculateFaceNormals, calculatePointNormals

class Mesh():
5 6 7 8
    """
    A polygonal mesh. Faces can have varying valence.
    """
    
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
    def __init__(self, vertices, face_indices, normals=None, colors=None, uvs=None):
        self.normals = normals
        self.colors = colors
        self.uvs = uvs
        
        self.face_valence = (face_indices != -1).sum(1)

        minValence = self.face_valence.min(axis = 0)
        maxValuence = self.face_valence.max(axis = 0)
        self.uniform_valence = minValence == maxValuence
        
        self.is_triangulated = self.uniform_valence and self.face_valence[0] == 3

        self.vertices = vertices
        self.face_indices = face_indices

    def prepare_render(self):
        if not self.normals:
            self.calculateNormals()

        self.triangulate()

        if self.normals: 
            self.normals.face_remap = self.triangulate_face_to_attribute_face
        
        if self.colors:
            self.colors.face_remap = self.triangulate_face_to_attribute_face
        
        if self.uvs:
            self.uvs.face_remap = self.triangulate_face_to_attribute_face

    def calculateNormals(self, normal_element = 'face'):
        assert(normal_element is 'face' or normal_element is 'point')
        
        if normal_element is 'face':
            self.normals = calculateFaceNormals(self.vertices, self.face_indices)
        else:
            self.normals = calculatePointNormals(self.vertices, self.face_indices)

    def triangulate(self):
        if self.is_triangulated:
            self.tri_face_indices = self.face_indices
51
            self.triangulate_face_to_attribute_face = np.arange(len(self.face_indices))
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
            return
        
        new_faces = []

        triangulate_face_to_attribute_face = []

        for fid, face in enumerate(self.face_indices):
            originVertex = face[0]
            for in_face_idx in range(2, self.face_valence[fid]):
                triangulate_face_to_attribute_face.append(fid)
                new_faces.append([originVertex, face[in_face_idx-1], face[in_face_idx]])

        self.triangulate_face_to_attribute_face = np.array(triangulate_face_to_attribute_face)
        self.tri_face_indices = np.array(new_faces)
        
        self.is_triangulated = True
        
        

class PointList():
    def __init__(self, vertices, colors = None, uvs = None):
        self.vertices = vertices
        self.colors = colors
        self.uvs = uvs

    def prepare_render(self):
        pass


class EdgeList():

    def __init__(self, vertices, edge_indices, colors=None, uvs=None):
        self.vertices = vertices
        self.edge_indices = edge_indices
        self.colors = colors
        self.uvs = uvs

    def prepare_render(self):
        pass