indexed_attribute.py 3.58 KB
Newer Older
Dario Seyb's avatar
Dario Seyb committed
1 2 3 4 5 6 7 8 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 51 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 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108


def resolve_attributes(face_indices, attribs):
    final_attributes = []

    for attrib in attribs:
        resolved_attrib = attrib.resolve(face_indices)
        final_attributes.append(stretch_attribute(face_indices, resolved_attrib))
          
    return final_attributes

def stretch_attribute(face_indices, resolved_attrib):
    vs_per_face = len(face_indices[0])
    stretched_attrib = [None] * (len(face_indices) * vs_per_face)
    
    for val in resolved_attrib:
        stretched_attrib[val[0] * vs_per_face + val[1]] = val[2]

    return stretched_attrib

def find(element, list_element):
    try:
        index_element = list_element.index(element)
        return index_element
    except ValueError:
        return None

class UniformAttribute(object):
    def __init__(self, value):
        self.value = value
    
    def resolve(self, face_indices):
        result = []
        for f_idx, face in enumerate(face_indices):
            for idx_in_face, _ in enumerate(face):
                result.append((f_idx, idx_in_face, self.value))

        return result

class IndexedAttribute(object):
    def __init__(self, values, indices):
        assert(len(values) is len(indices))
        self.values = values
        self.indices = indices

class PointAttribute(IndexedAttribute):
    def __init__(self, values, indices = None):
        if indices is None: 
            indices = range(0, len(values))
        super(PointAttribute, self).__init__(values, indices)
    
    def resolve(self, face_indices):
        result = []
        for i, val in enumerate(self.values):
            idx = self.indices[i]
            # find all faces that contain the vertex
            for f_idx, face in enumerate(face_indices):
                # check if vertex is in face
                idx_in_face = find(idx, face)
                # if yes, add value for vertex in that face
                if idx_in_face is not None: 
                    result.append((f_idx, idx_in_face, val))

        return result

class FaceAttribute(IndexedAttribute):
    def __init__(self, values, indices = None):
        if indices is None: 
            indices = range(0, len(values))
        super(FaceAttribute, self).__init__(values, indices)
    
    def resolve(self, face_indices):
        result = []
        for i, val in enumerate(self.values):
            idx = self.indices[i]
            # Add value for all vertices in the face
            for f_vidx in range(0, len(face_indices[idx])):
                result.append((idx, f_vidx, val))

        return result

class HalfEdgeAttribute(IndexedAttribute):
    def __init__(self, values, indices):
        super(HalfEdgeAttribute, self).__init__(values, indices)
    
    def resolve(self, face_indices):
        result = []
        for i, val in enumerate(self.values):
            idx = self.indices[i]
            
            # find all faces that contain the vertex
            for f_idx, face in enumerate(face_indices):
                # check if edge is in face
                start_idx_in_face = find(idx[0], face)
                end_idx_in_face = find(idx[1], face)
                
                # both ends need to be in the face
                if start_idx_in_face is None or end_idx_in_face is None: 
                    continue
                
                # and the edge needs to point in the right direction
                if (start_idx_in_face + 1) % len(face) is not end_idx_in_face:
                    continue

                # value of half edge counts as value of the vertex that's pointed towards
                result.append((f_idx, end_idx_in_face, val))

        return result