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