def createResourcesPost(self): """ face array creates per vertex data. some vertices may occur multiple times in the resulting array, depending on the per face data. """ VBOSegment.createResourcesPost(self) faceCol = self.hasFaceCol() faceUV = self.hasFaceUV() faceNor = self.hasFaceNor() groupIndexes = [] if faceNor: groupNormals = [None]*self.numVertices if faceUV: groupUV = [None]*self.numVertices if faceCol: groupColors = [None]*self.numVertices # remember processed vertices and per face data processedVertices = {} for f in self.faces: for i in range(len(f.indexes)): # get the index to per vertex lists j = f.indexes[i] # vertex index processed before? data = processedVertices.get(j) if data==None: # if not set the data processedVertices[j] = [(listGet(f.normals, i), listGet(f.uv, i), listGet(f.colors, i))] if faceNor: groupNormals[j] = f.normals[i] if faceUV: groupUV[j] = f.uv[i] if faceCol: groupColors[j] = f.colors[i] else: # if this vertex index was processed before, # check if per face data equals, # else we need to add this vertex to the list. # the vertex data will then be multiple times in the list. (n0,u0,c0) = (listGet(f.normals, i), listGet(f.uv, i), listGet(f.colors, i)) # check if face vertex equals saved vertex isEqualVertex = True for d in data: (n1,u1,c1) = d if almostEqual(n0,n1) and almostEqual(u0,u1) and almostEqual(c0,c1): # if per face data is equal, do nothing pass else: isEqualVertex = False break if not isEqualVertex: # let the class hierarchy push back one vertex attribute. # for example a class may want to add a tangent now to the end of # its tangent list. self.duplicatePerVertexAttribute(j) # face vertex index changed. f.indexes[i] = self.numVertices-1 # remember this vertex. processedVertices[j].append( (n0,u0,c0) ) if faceNor: groupNormals.append( f.normals[i] ) if faceUV: groupUV.append( f.uv[i] ) if faceCol: groupColors.append( f.colors[i] ) groupIndexes += list(f.indexes) self.indexes = groupIndexes if faceNor: self.normals.data = groupNormals if faceUV: self.uvs = uvAttribute(groupUV) if faceCol: self.colors = colorAttribute(groupColors)
def getPlaneFaces(self, segment): """ create multiple plane faces for this face. """ # successive vertices with same normal normalGroups = [] # normal of last processed vertex lastNormal = None currentGroup = None # create face groups, with vertices sharing a plane. vertices = map(lambda i: segment.vertices.data[i], self.indexes) for i in range(len(vertices)): # lookup indexes of neighbor vertices in segment i0 = self.indexes[i-2] i1 = self.indexes[i-1] i2 = self.indexes[i] v0 = segment.vertices.data[i0] v1 = segment.vertices.data[i1] v2 = segment.vertices.data[i2] # Calculate vertex normal. edge1 = v2 - v1 edge2 = v0 - v1 normal = crossVec3Float32( edge1, edge2 ) if lastNormal!=None and almostEqual(normal, lastNormal): currentGroup[0].append(i1) else: if currentGroup!=None: currentGroup[0].append(i1) normalGroups.append(currentGroup) currentGroup = ([i0, i1], normal) else: currentGroup = ([i1], normal) lastNormal = normal if currentGroup!=None: normalGroups.append(currentGroup) # all vertex in plane if len(normalGroups)==1: return [self] # first and last group may get joined if almostEqual( normalGroups[0][1], normalGroups[-1][1] ): indexes = normalGroups[0][0] + normalGroups[-1][0] normalGroups = normalGroups[:-1] normalGroups[0] = (indexes, normalGroups[0][1]) # groups must have at least three member, # this way we can remove groups of # vertices acting as bridge between planes. normalGroups = filter(lambda x: len(x)>2, normalGroups) # create VArrayFace instances for each group groupFaces = [] for (indexes, _) in normalGroups: params = { 'i': indexes } uv = None; col = None; nor = None numIndexes = len(indexes) for i in range(len(indexes)): j = indexes[i] for k in self.indexes: if k==j: break # set params if bool(self.uv): if not bool(uv): uv = [None]*numIndexes uv[i] = self.uv[j] if bool(self.col): if not bool(col): col = [None]*numIndexes col[i] = self.col[j] if bool(self.nor): if not bool(nor): nor = [None]*numIndexes nor[i] = self.nor[j] face = VArrayFace(params) groupFaces.append(face) return groupFaces