def readMeshes(file, xpsHeader, hasBones): meshes = [] meshCount = bin_ops.readUInt32(file) hasHeader = bool(xpsHeader) hasTangent = False if hasHeader: hasTangent = hasTangentHeader(xpsHeader) for meshId in range(meshCount): # Name meshName = readFilesString(file) if not meshName: meshName = 'unnamed' # print('Mesh Name:', meshName) # uv Count uvLayerCount = bin_ops.readUInt32(file) # Textures textures = [] textureCount = bin_ops.readUInt32(file) for texId in range(textureCount): textureFile = ntpath.basename(readFilesString(file)) # print('Texture file', textureFile) uvLayerId = bin_ops.readUInt32(file) xpsTexture = xps_types.XpsTexture(texId, textureFile, uvLayerId) textures.append(xpsTexture) # Vertices vertex = [] vertexCount = bin_ops.readUInt32(file) for vertexId in range(vertexCount): coord = readXYZ(file) normal = readXYZ(file) vertexColor = readVertexColor(file) uvs = [] for uvLayerId in range(uvLayerCount): uvVert = readUvVert(file) uvs.append(uvVert) if not hasHeader or hasTangent: tangent = read4Float(file) boneWeights = [] if hasBones: # if cero bones dont have weights to read boneIdx = read4Int16(file) boneWeight = read4Float(file) for idx in range(len(boneIdx)): boneWeights.append( xps_types.BoneWeight(boneIdx[idx], boneWeight[idx])) xpsVertex = xps_types.XpsVertex(vertexId, coord, normal, vertexColor, uvs, boneWeights) vertex.append(xpsVertex) # Faces faces = [] triCount = bin_ops.readUInt32(file) for i in range(triCount): triIdxs = readTriIdxs(file) faces.append(triIdxs) xpsMesh = xps_types.XpsMesh(meshName, textures, vertex, faces, uvLayerCount) meshes.append(xpsMesh) return meshes
def readMeshes(file, hasBones): meshes = [] meshCount = ascii_ops.readInt(file) for meshId in range(meshCount): # Name meshName = ascii_ops.readString(file) if not meshName: meshName = 'xxx' # print('Mesh Name:', meshName) # uv Count uvLayerCount = ascii_ops.readInt(file) # Textures textures = [] textureCount = ascii_ops.readInt(file) for texId in range(textureCount): textureFile = ntpath.basename(ascii_ops.readString(file)) # print('Texture file', textureFile) uvLayerId = ascii_ops.readInt(file) xpsTexture = xps_types.XpsTexture(texId, textureFile, uvLayerId) textures.append(xpsTexture) # Vertices vertex = [] vertexCount = ascii_ops.readInt(file) for vertexId in range(vertexCount): coord = readXYZ(file) normal = readXYZ(file) vertexColor = read4Int(file) uvs = [] for uvLayerId in range(uvLayerCount): uvVert = readUvVert(file) uvs.append(uvVert) # if ???? # tangent???? # tangent = read4float(file) boneWeights = [] if hasBones: # if cero bones dont have weights to read boneIdx = readBoneId(file) boneWeight = readBoneWeight(file) for idx in range(len(boneIdx)): boneWeights.append( xps_types.BoneWeight(boneIdx[idx], boneWeight[idx])) xpsVertex = xps_types.XpsVertex(vertexId, coord, normal, vertexColor, uvs, boneWeights) vertex.append(xpsVertex) # Faces faces = [] triCount = ascii_ops.readInt(file) for i in range(triCount): triIdxs = readTriIdxs(file) faces.append(triIdxs) xpsMesh = xps_types.XpsMesh(meshName, textures, vertex, faces, uvLayerCount) meshes.append(xpsMesh) return meshes
def getXpsVertices(selectedArmature, mesh): mapMatVertexKeys = [] # remap vertex index xpsMatVertices = [] # Vertices separated by material xpsMatFaces = [] # Faces separated by material # xpsVertices = [] # list of vertices for a single material # xpsFaces = [] # list of faces for a single material uvIndexs = makeSimpleUvVert(mesh) vColors = makeSimpleVertColor(mesh) armature = getMeshArmature(selectedArmature, mesh) objectMatrix = mesh.matrix_world rotQuaternion = mesh.matrix_world.to_quaternion() #Calculates tesselated faces and normal split to make them available for export mesh.data.calc_normals_split() mesh.data.update(calc_edges=True, calc_tessface=True) vertices = mesh.data.vertices matCount = len(mesh.data.materials) for idx in range(matCount): xpsMatVertices.append([]) # Vertices separated by material xpsMatFaces.append([]) # Faces separated by material mapMatVertexKeys.append({}) for faceIdx, face in enumerate(mesh.data.tessfaces): material_index = face.material_index xpsVertices = xpsMatVertices[material_index] xpsFaces = xpsMatFaces[material_index] mapVertexKeys = mapMatVertexKeys[material_index] faceVerts = [] for vertNum, vertIndex in enumerate(face.vertices): vertex = vertices[vertIndex] co = coordTransform(objectMatrix * vertex.co) split_normal = Vector(face.split_normals[vertNum]) norm = coordTransform(rotQuaternion * split_normal) vColor = getVertexColor() uv = getUvs(mesh, faceIdx, vertNum) boneId = getBonesId(mesh, vertex, armature) boneWeight = getBonesWeight(vertex) boneWeights = [] for idx in range(len(boneId)): boneWeights.append( xps_types.BoneWeight(boneId[idx], boneWeight[idx])) vertexKey = generateVertexKey(vertex, uv) if vertexKey in mapVertexKeys: vertexID = mapVertexKeys[vertexKey] else: vertexID = len(xpsVertices) mapVertexKeys[vertexKey] = vertexID xpsVertex = xps_types.XpsVertex(vertexID, co, norm, vColor, uv, boneWeights) xpsVertices.append(xpsVertex) faceVerts.append(vertexID) meshFaces = getXpsFace(faceVerts) xpsFaces.extend(meshFaces) return xpsMatVertices, xpsMatFaces
def buildMeshes(): meshes = [] meshName = 'Mesh1' uvLayerCount = 1 # Textures textures = [] texId = 0 textureFile = 'textutefile1.png' uvLayerId = 0 xpsTexture = xps_types.XpsTexture(texId, textureFile, uvLayerId) textures.append(xpsTexture) texId = 1 textureFile = 'textutefile2.png' uvLayerId = 0 xpsTexture = xps_types.XpsTexture(texId, textureFile, uvLayerId) textures.append(xpsTexture) # Vertices vertex = [] # Vertex1 vertexId = 0 coord = (1, 0, 0) normal = (0, 0, 1) vertexColor = (255, 255, 255, 0) uvs = [] uvs.append((.2, .4)) boneWeights = (xps_types.BoneWeight(0, 0), xps_types.BoneWeight(0, 0), xps_types.BoneWeight(0, 0), xps_types.BoneWeight(0, 0)) xpsVertex = xps_types.XpsVertex(vertexId, coord, normal, vertexColor, uvs, boneWeights) # Vertex2 vertexId = 1 coord = (0, 1, 0) normal = (0, 1, 0) vertexColor = (255, 255, 255, 0) uvs = [] uvs.append((.3, .5)) boneWeights = (xps_types.BoneWeight(0, 0), xps_types.BoneWeight(0, 0), xps_types.BoneWeight(0, 0), xps_types.BoneWeight(0, 0)) xpsVertex = xps_types.XpsVertex(vertexId, coord, normal, vertexColor, uvs, boneWeights) vertex.append(xpsVertex) # Vertex3 vertexId = 2 coord = (0, 0, 1) normal = (1, 0, 0) vertexColor = (255, 255, 255, 0) uvs = [] uvs.append((.3, .9)) boneWeights = (xps_types.BoneWeight(0, 0), xps_types.BoneWeight(0, 0), xps_types.BoneWeight(0, 0), xps_types.BoneWeight(0, 0)) xpsVertex = xps_types.XpsVertex(vertexId, coord, normal, vertexColor, uvs, boneWeights) vertex.append(xpsVertex) faces = [] face = (0, 1, 2) faces.append(face) xpsMesh = xps_types.XpsMesh(meshName, textures, vertex, faces, uvLayerCount) meshes.append(xpsMesh) return meshes
def getXpsVertices(selectedArmature, mesh): mapMatVertexKeys = [] # remap vertex index xpsMatVertices = [] # Vertices separated by material xpsMatFaces = [] # Faces separated by material # xpsVertices = [] # list of vertices for a single material # xpsFaces = [] # list of faces for a single material exportVertColors = xpsSettings.vColors armature = mesh.find_armature() objectMatrix = mesh.matrix_world rotQuaternion = mesh.matrix_world.to_quaternion() verts_nor = xpsSettings.exportNormals # Calculates tesselated faces and normal split to make them available for export mesh.data.calc_normals_split() mesh.data.update(calc_edges=True, calc_tessface=True) vertices = mesh.data.vertices matCount = len(mesh.data.materials) if (matCount > 0): for idx in range(matCount): xpsMatVertices.append([]) # Vertices separated by material xpsMatFaces.append([]) # Faces separated by material mapMatVertexKeys.append({}) else: xpsMatVertices.append([]) # Vertices separated by material xpsMatFaces.append([]) # Faces separated by material mapMatVertexKeys.append({}) meshVerts = mesh.data.vertices meshEdges = mesh.data.edges # tessface accelerator hasSeams = any(edge.use_seam for edge in meshEdges) tessFaces = [tessface for tessface in mesh.data.tessfaces] #tessFaces = mesh.data.tessfaces tessface_uv_tex = mesh.data.tessface_uv_textures tessface_vert_color = mesh.data.tessface_vertex_colors vertexColors = mesh.data.vertex_colors meshEdgeKeys = mesh.data.edge_keys vertEdges = [[] for x in range(len(meshVerts))] tessEdgeFaces = {} preserveSeams = xpsSettings.preserveSeams if (preserveSeams and hasSeams): # Count edges for faces tessEdgeCount = Counter(tessEdgeKey for tessFace in tessFaces for tessEdgeKey in tessFace.edge_keys) # create dictionary. faces for each edge for tessface in tessFaces: for tessEdgeKey in tessface.edge_keys: if tessEdgeFaces.get(tessEdgeKey) is None: tessEdgeFaces[tessEdgeKey] = [] tessEdgeFaces[tessEdgeKey].append(tessface.index) # use Dict to speedup search edgeKeyIndex = {val: index for index, val in enumerate(meshEdgeKeys)} # create dictionary. Edges connected to each Vert for key in meshEdgeKeys: meshEdge = meshEdges[edgeKeyIndex[key]] vert1, vert2 = key vertEdges[vert1].append(meshEdge) vertEdges[vert2].append(meshEdge) faceEdges = [] faceSeams = [] for face in tessFaces: faceIdx = face.index material_index = face.material_index xpsVertices = xpsMatVertices[material_index] xpsFaces = xpsMatFaces[material_index] mapVertexKeys = mapMatVertexKeys[material_index] faceVerts = [] seamSideId = '' faces = [face for face in face.vertices] for vertNum, vertIndex in enumerate(faces): vertex = meshVerts[vertIndex] if (preserveSeams and hasSeams): connectedFaces = set() faceEdges = vertEdges[vertIndex] faceSeams = [edge for edge in faceEdges if edge.use_seam] if (len(faceSeams) >= 1): vertIsBorder = any(tessEdgeCount[edge.index] != 2 for edge in faceEdges) if (len(faceSeams) > 1) or (len(faceSeams) == 1 and vertIsBorder): oldFacesList = set() connectedFaces = set([face]) while oldFacesList != connectedFaces: oldFacesList = connectedFaces allEdgeKeys = set(connEdgeKey for connface in connectedFaces for connEdgeKey in connface.edge_keys) connEdgesKeys = [edge.key for edge in faceEdges] connEdgesNotSeamsKeys = [seam.key for seam in faceSeams] connectedEdges = allEdgeKeys.intersection(connEdgesKeys).difference(connEdgesNotSeamsKeys) connectedFaces = set(tessFaces[connFace] for connEdge in connectedEdges for connFace in tessEdgeFaces[connEdge]) connectedFaces.add(face) faceIndices = [face.index for face in connectedFaces] seamSideId = '|'.join(str(faceIdx) for faceIdx in sorted(faceIndices)) uv = getUvs(tessface_uv_tex, mesh, faceIdx, vertNum) vertexKey = generateVertexKey(vertex, uv, seamSideId) if vertexKey in mapVertexKeys: vertexID = mapVertexKeys[vertexKey] else: vCoord = coordTransform(objectMatrix * vertex.co) if verts_nor: normal = Vector(face.split_normals[vertNum]) else: normal = vertex.normal norm = coordTransform(rotQuaternion * normal) vColor = getVertexColor(exportVertColors, tessface_vert_color, faceIdx, vertNum) boneId, boneWeight = getBoneWeights(mesh, vertex, armature) boneWeights = [] for idx in range(len(boneId)): boneWeights.append(xps_types.BoneWeight(boneId[idx], boneWeight[idx])) vertexID = len(xpsVertices) mapVertexKeys[vertexKey] = vertexID xpsVertex = xps_types.XpsVertex(vertexID, vCoord, norm, vColor, uv, boneWeights) xpsVertices.append(xpsVertex) faceVerts.append(vertexID) meshFaces = getXpsFace(faceVerts) xpsFaces.extend(meshFaces) return xpsMatVertices, xpsMatFaces