def surf2ctm(fsdir, outdir): """ Convert a FreeSurfer surface to a compressed CTM surface. Treat both hemishperes: 'lh' and 'rh'. Parameters ---------- fsdir: str (mandatory) the subject FreeSurfer home directory where the '*.white', '*.pial' sufraces and the '*.aparc.annot' files can be found. outdir: str directory where a '*.ctm' file will be saved. The output file base name will be the same as the input 'path_mesh' file. Returns ------- paths_ctm: list of str the converted surfaces. """ # Treat both hemishperes for hemi in ["lh", "rh"]: # Guess file locations fom the FreeSurfer standard organization path_white = os.path.join(fsdir, "surf", "{0}.white".format(hemi)) path_pial = os.path.join(fsdir, "surf", "{0}.pial".format(hemi)) path_annot = os.path.join(fsdir, "label", "{0}.aparc.annot".format(hemi)) for path in (path_white, path_pial, path_annot): if not os.path.isfile(path): raise ValueError("'{0}' FreeSurfer standard file cannot be " "found.".format(path)) # Load the surfaces paths_ctm = [] for path_surf in (path_white, path_pial): surface = TriSurface.load(path_surf, annotfile=path_annot) # Convert the loaded surface in compressed CTM format path_ctm = os.path.join(outdir, os.path.basename(path_surf) + ".ctm") paths_ctm.append(path_ctm) colors = [] for label in surface.labels: if label < 0: label = 0 color = numpy.asarray(surface.metadata[label]["color"], dtype=float) color /= 255. colors.append(tuple(color)) pVerts = make_blob(surface.vertices, ctypes.c_float) pFaces = make_blob(surface.triangles, ctypes.c_uint) pNormals = ctypes.POINTER(ctypes.c_float)() pColors = make_blob(colors, ctypes.c_float) ctm = openctm.ctmNewContext(openctm.CTM_EXPORT) openctm.ctmDefineMesh(ctm, pVerts, len(surface.vertices), pFaces, len(surface.triangles), pNormals) openctm.ctmAddAttribMap(ctm, pColors, "Color") openctm.ctmSave(ctm, path_ctm) openctm.ctmFreeContext(ctm) return paths_ctm
def dump(self, filename = "mesh.ctm"): pVertex = blob.make_blob(self.vertex, ctypes.c_float) pTriangles = blob.make_blob(self.triangles, ctypes.c_uint) pNormals = ctypes.POINTER(ctypes.c_float)() ctm = openctm.ctmNewContext(openctm.CTM_EXPORT) openctm.ctmDefineMesh(ctm, pVertex, len(self.vertex), pTriangles, len(self.triangles), pNormals) openctm.ctmSave(ctm, filename) openctm.ctmFreeContext(ctm)
def _exportCtm(self, fileName, exportOptions, exportAll): exportNormals = exportOptions.get('normals', False) exportUVs = exportOptions.get('uvs', False) # TODO: implement colors export exportColors = exportOptions.get('colors', False) if exportAll: dagIterator = OpenMaya.MItDag(OpenMaya.MItDag.kBreadthFirst, OpenMaya.MFn.kGeometric) else: selection = OpenMaya.MGlobal.getActiveSelectionList() dagIterator = OpenMaya.MItSelectionList(selection, OpenMaya.MFn.kGeometric) ctmindices = [] ctmvertices = [] ctmnormals = [] ctmtexcoords = [] indicesOffset = 0 while not dagIterator.isDone(): if exportAll: dagPath = dagIterator.getPath() else: dagPath = dagIterator.getDagPath() fnMesh = None try: fnMesh = OpenMaya.MFnMesh(dagPath) except Exception as e: dagIterator.next() continue meshPoints = fnMesh.getPoints(OpenMaya.MSpace.kWorld) meshNormals = normals = None if exportNormals: meshNormals = fnMesh.getNormals() normals = {} UVSets = u = v = uvs = None if exportUVs: UVSets = fnMesh.getUVSetNames() u, v = fnMesh.getUVs(UVSets[0]) uvs = {} iterPolys = OpenMaya.MItMeshPolygon(dagPath) offset = 0 maxPoints = 0 while not iterPolys.isDone(): if not iterPolys.hasValidTriangulation(): raise ValueError("The mesh has not valid triangulation") # Not used # uvSet = iterPolys.getUVSetNames() polygonVertices = iterPolys.getVertices() numTriangles = iterPolys.numTriangles() offset = len(ctmvertices) localindices = [] for i in range(numTriangles): points, indices = iterPolys.getTriangle(i) ctmindices.append(indicesOffset) indicesOffset += 1 ctmindices.append(indicesOffset) indicesOffset += 1 ctmindices.append(indicesOffset) indicesOffset += 1 localindices.append(indices[0]) localindices.append(indices[1]) localindices.append(indices[2]) localIndex = [] for gt in range(len(indices)): for gv in range(len(polygonVertices)): if indices[gt] == polygonVertices[gv]: localIndex.append(gv) break if exportNormals: normals[indices[0]] = meshNormals[ iterPolys.normalIndex(localIndex[0])] normals[indices[1]] = meshNormals[ iterPolys.normalIndex(localIndex[1])] normals[indices[2]] = meshNormals[ iterPolys.normalIndex(localIndex[2])] if exportUVs and iterPolys.hasUVs(): uvID = [0, 0, 0] for vtxInPolygon in range(3): uvID[vtxInPolygon] = iterPolys.getUVIndex( localIndex[vtxInPolygon], UVSets[0]) uvs[indices[0]] = (u[uvID[0]], v[uvID[0]]) uvs[indices[1]] = (u[uvID[1]], v[uvID[1]]) uvs[indices[2]] = (u[uvID[2]], v[uvID[2]]) for i in localindices: ctmvertices.append(meshPoints[i].x) ctmvertices.append(meshPoints[i].y) ctmvertices.append(meshPoints[i].z) if exportNormals: ctmnormals.append(normals[i][0]) ctmnormals.append(normals[i][1]) ctmnormals.append(normals[i][2]) if exportUVs and iterPolys.hasUVs(): ctmtexcoords.append(uvs[i][0]) ctmtexcoords.append(uvs[i][1]) iterPolys.next(None) dagIterator.next() pindices = cast((openctm.CTMuint * len(ctmindices))(), POINTER(openctm.CTMuint)) pvertices = cast((openctm.CTMfloat * len(ctmvertices))(), POINTER(openctm.CTMfloat)) if exportNormals: pnormals = cast((openctm.CTMfloat * len(ctmnormals))(), POINTER(openctm.CTMfloat)) else: pnormals = None if exportUVs and ctmtexcoords: ptexcoords = cast((openctm.CTMfloat * len(ctmtexcoords))(), POINTER(openctm.CTMfloat)) for i in range(len(ctmindices)): pindices[i] = openctm.CTMuint(ctmindices[i]) for i in range(len(ctmvertices)): pvertices[i] = openctm.CTMfloat(ctmvertices[i]) if exportNormals: pnormals[i] = openctm.CTMfloat(ctmnormals[i]) if exportUVs and ctmtexcoords: for i in range(len(ctmtexcoords)): ptexcoords[i] = openctm.CTMfloat(ctmtexcoords[i]) context = openctm.ctmNewContext(openctm.CTM_EXPORT) # openctm.ctmCompressionMethod(context, openctm.CTM_METHOD_MG2) # Select compression level (0-9) - default 1 openctm.ctmCompressionLevel(context, exportOptions.get("compressionLevel", 1)) comment = "Exported with OpenCTM exporter using Maya" openctm.ctmFileComment(context, c_char_p(comment)) openctm.ctmDefineMesh(context, pvertices, openctm.CTMuint(len(ctmvertices) / 3), pindices, openctm.CTMuint(len(ctmindices) / 3), pnormals) if exportUVs: if ctmtexcoords: openctm.ctmAddUVMap(context, ptexcoords, c_char_p("map1"), c_char_p()) else: print("[Warning] Export UVs selected but " "there are no available UVs to export") openctm.ctmSave(context, c_char_p(fileName)) openctm.ctmFreeContext(context) e = openctm.ctmGetError(context) if e != 0: s = openctm.ctmErrorString(e) print(s) raise Exception(s)
def _importCtm(self, fileName, importOptions): verbose = importOptions.get('verbose', False) context = openctm.ctmNewContext(openctm.CTM_IMPORT) # Extract file openctm.ctmLoad(context, fileName) e = openctm.ctmGetError(context) if e != 0: s = openctm.ctmErrorString(e) print(s) openctm.ctmFreeContext(context) raise Exception(s) # Extract indices triCount = openctm.ctmGetInteger(context, openctm.CTM_TRIANGLE_COUNT) ctmIndices = openctm.ctmGetIntegerArray(context, openctm.CTM_INDICES) polyCount = [3] * triCount # Extract vertices vertCount = openctm.ctmGetInteger(context, openctm.CTM_VERTEX_COUNT) ctmVertices = openctm.ctmGetFloatArray(context, openctm.CTM_VERTICES) vertices = OpenMaya.MFloatPointArray() vertices.setLength(vertCount) # Extract Normals ctmVertNormals = None vertNormals = OpenMaya.MFloatPointArray() hasNormals = openctm.ctmGetInteger( context, openctm.CTM_HAS_NORMALS) == openctm.CTM_TRUE if hasNormals: ctmVertNormals = openctm.ctmGetFloatArray(context, openctm.CTM_NORMALS) vertNormals.setLength(vertCount) # Extract UVs hasUVs = openctm.ctmGetInteger(context, openctm.CTM_UV_MAP_COUNT) > 0 ctmTexCoords = None uCoords = OpenMaya.MFloatArray() vCoords = OpenMaya.MFloatArray() if hasUVs: ctmTexCoords = openctm.ctmGetFloatArray(context, openctm.CTM_UV_MAP_1) uCoords.setLength(vertCount) vCoords.setLength(vertCount) textureFilename = openctm.ctmGetUVMapString( context, openctm.CTM_UV_MAP_1, openctm.CTM_FILE_NAME) # TODO: Load texture file if textureFilename: pass # Extract colors colorAttrib = openctm.ctmGetNamedAttribMap(context, "Color") hasVertexColors = colorAttrib != openctm.CTM_NONE ctmColors = None vertexColors = OpenMaya.MColorArray() if hasVertexColors: ctmColors = openctm.ctmGetFloatArray(context, colorAttrib) vertexColors.setLength(vertCount) pointToIndex = {} ctmVertIndexToUniqueIndex = {} nrSkippedVertices = 0 for i in range(vertCount): ctmVertIndex = i * 3 p = (float(ctmVertices[ctmVertIndex]), float(ctmVertices[ctmVertIndex + 1]), float(ctmVertices[ctmVertIndex + 2])) if p not in pointToIndex: index = i - nrSkippedVertices pointToIndex[p] = index ctmVertIndexToUniqueIndex[i] = index vertices[index].x = p[0] vertices[index].y = p[1] vertices[index].z = p[2] if hasNormals: vertNormals[index].x = float(ctmVertNormals[ctmVertIndex]) vertNormals[index].y = float(ctmVertNormals[ctmVertIndex + 1]) vertNormals[index].z = float(ctmVertNormals[ctmVertIndex + 2]) if hasUVs: ctmUVIndex = i * 2 uCoords[index] = float(ctmTexCoords[ctmUVIndex]) vCoords[index] = float(ctmTexCoords[ctmUVIndex + 1]) if hasVertexColors: ctmColIndex = i * 4 vertexColors[index].r = float(ctmColors[ctmColIndex]) vertexColors[index].g = float(ctmColors[ctmColIndex + 1]) vertexColors[index].b = float(ctmColors[ctmColIndex + 2]) vertexColors[index].a = float(ctmColors[ctmColIndex + 3]) else: ctmVertIndexToUniqueIndex[i] = pointToIndex[p] nrSkippedVertices += 1 uniqVertCount = len(pointToIndex) vertices.setLength(uniqVertCount) vertNormals.setLength(uniqVertCount) indices = [ ctmVertIndexToUniqueIndex[ctmIndices[i]] for i in range(3 * triCount) ] if hasUVs: uCoords.setLength(uniqVertCount) vCoords.setLength(uniqVertCount) if hasVertexColors: vertexColors.setLength(uniqVertCount) if verbose: method = openctm.ctmGetInteger(context, openctm.CTM_COMPRESSION_METHOD) if method == openctm.CTM_METHOD_RAW: methodStr = "RAW" elif method == openctm.CTM_METHOD_MG1: methodStr = "MG1" elif method == openctm.CTM_METHOD_MG2: methodStr = "MG2" else: methodStr = "Unknown" print("File: %s" % fileName) print("Comment: %s" % str(openctm.ctmGetString(context, openctm.CTM_FILE_COMMENT))) print("Compression Method: %s" % methodStr) print("Vertices Count : %d" % vertCount) print("Unique Vertices Count : %d" % uniqVertCount) print("Triangles Count: %d" % triCount) print("Has normals: %r" % hasNormals) print("Has UVs: %r" % hasUVs) print("Has Vertex Colors: %r" % hasVertexColors) fnMesh = OpenMaya.MFnMesh() newMesh = fnMesh.create(vertices, polyCount, indices, uCoords, vCoords) if hasNormals: fnMesh.setVertexNormals(vertNormals, range(len(vertices))) if hasVertexColors: fnMesh.setVertexColors(vertexColors, range(len(vertices))) fnMesh.updateSurface() # Assign initial shading group slist = OpenMaya.MGlobal.getSelectionListByName("initialShadingGroup") initialSG = slist.getDependNode(0) fnSG = OpenMaya.MFnSet(initialSG) if fnSG.restriction() == OpenMaya.MFnSet.kRenderableOnly: fnSG.addMember(newMesh)
def _exportCtm(self, fileName, exportOptions, exportAll): exportNormals = exportOptions.get('normals', False) exportUVs = exportOptions.get('uvs', False) # TODO: implement colors export exportColors = exportOptions.get('colors', False) if exportAll: dagIterator = OpenMaya.MItDag( OpenMaya.MItDag.kBreadthFirst, OpenMaya.MFn.kGeometric) else: selection = OpenMaya.MGlobal.getActiveSelectionList() dagIterator = OpenMaya.MItSelectionList( selection, OpenMaya.MFn.kGeometric) ctmindices = [] ctmvertices = [] ctmnormals = [] ctmtexcoords = [] indicesOffset = 0 while not dagIterator.isDone(): if exportAll: dagPath = dagIterator.getPath() else: dagPath = dagIterator.getDagPath() fnMesh = None try: fnMesh = OpenMaya.MFnMesh(dagPath) except Exception as e: dagIterator.next() continue meshPoints = fnMesh.getPoints(OpenMaya.MSpace.kWorld) meshNormals = normals = None if exportNormals: meshNormals = fnMesh.getNormals() normals = {} UVSets = u = v = uvs = None if exportUVs: UVSets = fnMesh.getUVSetNames() u, v = fnMesh.getUVs(UVSets[0]) uvs = {} iterPolys = OpenMaya.MItMeshPolygon(dagPath) offset = 0 maxPoints = 0 while not iterPolys.isDone(): if not iterPolys.hasValidTriangulation(): raise ValueError("The mesh has not valid triangulation") # Not used # uvSet = iterPolys.getUVSetNames() polygonVertices = iterPolys.getVertices() numTriangles = iterPolys.numTriangles() offset = len(ctmvertices) localindices = [] for i in range(numTriangles): points, indices = iterPolys.getTriangle(i) ctmindices.append(indicesOffset) indicesOffset += 1 ctmindices.append(indicesOffset) indicesOffset += 1 ctmindices.append(indicesOffset) indicesOffset += 1 localindices.append(indices[0]) localindices.append(indices[1]) localindices.append(indices[2]) localIndex = [] for gt in range(len(indices)): for gv in range(len(polygonVertices)): if indices[gt] == polygonVertices[gv]: localIndex.append(gv) break if exportNormals: normals[indices[0]] = meshNormals[ iterPolys.normalIndex(localIndex[0])] normals[indices[1]] = meshNormals[ iterPolys.normalIndex(localIndex[1])] normals[indices[2]] = meshNormals[ iterPolys.normalIndex(localIndex[2])] if exportUVs and iterPolys.hasUVs(): uvID = [0, 0, 0] for vtxInPolygon in range(3): uvID[vtxInPolygon] = iterPolys.getUVIndex( localIndex[vtxInPolygon], UVSets[0]) uvs[indices[0]] = (u[uvID[0]], v[uvID[0]]) uvs[indices[1]] = (u[uvID[1]], v[uvID[1]]) uvs[indices[2]] = (u[uvID[2]], v[uvID[2]]) for i in localindices: ctmvertices.append(meshPoints[i].x) ctmvertices.append(meshPoints[i].y) ctmvertices.append(meshPoints[i].z) if exportNormals: ctmnormals.append(normals[i][0]) ctmnormals.append(normals[i][1]) ctmnormals.append(normals[i][2]) if exportUVs and iterPolys.hasUVs(): ctmtexcoords.append(uvs[i][0]) ctmtexcoords.append(uvs[i][1]) iterPolys.next(None) dagIterator.next() pindices = cast((openctm.CTMuint * len(ctmindices)) (), POINTER(openctm.CTMuint)) pvertices = cast((openctm.CTMfloat * len(ctmvertices)) (), POINTER(openctm.CTMfloat)) if exportNormals: pnormals = cast((openctm.CTMfloat * len(ctmnormals)) (), POINTER(openctm.CTMfloat)) else: pnormals = None if exportUVs and ctmtexcoords: ptexcoords = cast((openctm.CTMfloat * len(ctmtexcoords)) (), POINTER(openctm.CTMfloat)) for i in range(len(ctmindices)): pindices[i] = openctm.CTMuint(ctmindices[i]) for i in range(len(ctmvertices)): pvertices[i] = openctm.CTMfloat(ctmvertices[i]) if exportNormals: pnormals[i] = openctm.CTMfloat(ctmnormals[i]) if exportUVs and ctmtexcoords: for i in range(len(ctmtexcoords)): ptexcoords[i] = openctm.CTMfloat(ctmtexcoords[i]) context = openctm.ctmNewContext(openctm.CTM_EXPORT) # openctm.ctmCompressionMethod(context, openctm.CTM_METHOD_MG2) # Select compression level (0-9) - default 1 openctm.ctmCompressionLevel( context, exportOptions.get("compressionLevel", 1)) comment = "Exported with OpenCTM exporter using Maya" openctm.ctmFileComment(context, c_char_p(comment)) openctm.ctmDefineMesh(context, pvertices, openctm.CTMuint( len(ctmvertices) / 3), pindices, openctm.CTMuint(len(ctmindices) / 3), pnormals) if exportUVs: if ctmtexcoords: openctm.ctmAddUVMap(context, ptexcoords, c_char_p("map1"), c_char_p()) else: print("[Warning] Export UVs selected but " "there are no available UVs to export") openctm.ctmSave(context, c_char_p(fileName)) openctm.ctmFreeContext(context) e = openctm.ctmGetError(context) if e != 0: s = openctm.ctmErrorString(e) print(s) raise Exception(s)
def _importCtm(self, fileName, importOptions): verbose = importOptions.get('verbose', False) context = openctm.ctmNewContext(openctm.CTM_IMPORT) # Extract file openctm.ctmLoad(context, fileName) e = openctm.ctmGetError(context) if e != 0: s = openctm.ctmErrorString(e) print(s) openctm.ctmFreeContext(context) raise Exception(s) # Extract indices triCount = openctm.ctmGetInteger(context, openctm.CTM_TRIANGLE_COUNT) ctmIndices = openctm.ctmGetIntegerArray(context, openctm.CTM_INDICES) polyCount = [3] * triCount # Extract vertices vertCount = openctm.ctmGetInteger(context, openctm.CTM_VERTEX_COUNT) ctmVertices = openctm.ctmGetFloatArray(context, openctm.CTM_VERTICES) vertices = OpenMaya.MFloatPointArray() vertices.setLength(vertCount) # Extract Normals ctmVertNormals = None vertNormals = OpenMaya.MFloatPointArray() hasNormals = openctm.ctmGetInteger( context, openctm.CTM_HAS_NORMALS) == openctm.CTM_TRUE if hasNormals: ctmVertNormals = openctm.ctmGetFloatArray( context, openctm.CTM_NORMALS) vertNormals.setLength(vertCount) # Extract UVs hasUVs = openctm.ctmGetInteger(context, openctm.CTM_UV_MAP_COUNT) > 0 ctmTexCoords = None uCoords = OpenMaya.MFloatArray() vCoords = OpenMaya.MFloatArray() if hasUVs: ctmTexCoords = openctm.ctmGetFloatArray( context, openctm.CTM_UV_MAP_1) uCoords.setLength(vertCount) vCoords.setLength(vertCount) textureFilename = openctm.ctmGetUVMapString( context, openctm.CTM_UV_MAP_1, openctm.CTM_FILE_NAME) # TODO: Load texture file if textureFilename: pass # Extract colors colorAttrib = openctm.ctmGetNamedAttribMap(context, "Color") hasVertexColors = colorAttrib != openctm.CTM_NONE ctmColors = None vertexColors = OpenMaya.MColorArray() if hasVertexColors: ctmColors = openctm.ctmGetFloatArray(context, colorAttrib) vertexColors.setLength(vertCount) pointToIndex = {} ctmVertIndexToUniqueIndex = {} nrSkippedVertices = 0 for i in range(vertCount): ctmVertIndex = i * 3 p = ( float(ctmVertices[ctmVertIndex]), float(ctmVertices[ctmVertIndex + 1]), float(ctmVertices[ctmVertIndex + 2]) ) if p not in pointToIndex: index = i - nrSkippedVertices pointToIndex[p] = index ctmVertIndexToUniqueIndex[i] = index vertices[index].x = p[0] vertices[index].y = p[1] vertices[index].z = p[2] if hasNormals: vertNormals[index].x = float(ctmVertNormals[ctmVertIndex]) vertNormals[index].y = float( ctmVertNormals[ctmVertIndex + 1]) vertNormals[index].z = float( ctmVertNormals[ctmVertIndex + 2]) if hasUVs: ctmUVIndex = i * 2 uCoords[index] = float(ctmTexCoords[ctmUVIndex]) vCoords[index] = float(ctmTexCoords[ctmUVIndex + 1]) if hasVertexColors: ctmColIndex = i * 4 vertexColors[index].r = float(ctmColors[ctmColIndex]) vertexColors[index].g = float(ctmColors[ctmColIndex + 1]) vertexColors[index].b = float(ctmColors[ctmColIndex + 2]) vertexColors[index].a = float(ctmColors[ctmColIndex + 3]) else: ctmVertIndexToUniqueIndex[i] = pointToIndex[p] nrSkippedVertices += 1 uniqVertCount = len(pointToIndex) vertices.setLength(uniqVertCount) vertNormals.setLength(uniqVertCount) indices = [ctmVertIndexToUniqueIndex[ ctmIndices[i]] for i in range(3 * triCount)] if hasUVs: uCoords.setLength(uniqVertCount) vCoords.setLength(uniqVertCount) if hasVertexColors: vertexColors.setLength(uniqVertCount) if verbose: method = openctm.ctmGetInteger( context, openctm.CTM_COMPRESSION_METHOD) if method == openctm.CTM_METHOD_RAW: methodStr = "RAW" elif method == openctm.CTM_METHOD_MG1: methodStr = "MG1" elif method == openctm.CTM_METHOD_MG2: methodStr = "MG2" else: methodStr = "Unknown" print("File: %s" % fileName) print("Comment: %s" % str(openctm.ctmGetString( context, openctm.CTM_FILE_COMMENT))) print("Compression Method: %s" % methodStr) print("Vertices Count : %d" % vertCount) print("Unique Vertices Count : %d" % uniqVertCount) print("Triangles Count: %d" % triCount) print("Has normals: %r" % hasNormals) print("Has UVs: %r" % hasUVs) print("Has Vertex Colors: %r" % hasVertexColors) fnMesh = OpenMaya.MFnMesh() newMesh = fnMesh.create( vertices, polyCount, indices, uCoords, vCoords) if hasNormals: fnMesh.setVertexNormals(vertNormals, range(len(vertices))) if hasVertexColors: fnMesh.setVertexColors(vertexColors, range(len(vertices))) fnMesh.updateSurface() # Assign initial shading group slist = OpenMaya.MGlobal.getSelectionListByName("initialShadingGroup") initialSG = slist.getDependNode(0) fnSG = OpenMaya.MFnSet(initialSG) if fnSG.restriction() == OpenMaya.MFnSet.kRenderableOnly: fnSG.addMember(newMesh)
def writer(self, fileObject, optionString, accessMode): fileName = fileObject.fullName() selection = OpenMaya.MSelectionList() all = (accessMode == self.kExportAccessMode or accessMode == self.kSaveAccessMode) dagIterator = None if (all): dagIterator = OpenMaya.MItDag(OpenMaya.MItDag.kBreadthFirst, OpenMaya.MFn.kGeometric) else: OpenMaya.MGlobal.getActiveSelectionList(selection) dagIterator = OpenMaya.MItSelectionList(selection, OpenMaya.MFn.kGeometric) ctmindices = [] ctmvertices = [] ctmnormals = [] ctmtexcoords = [] indicesOffset = 0 while not dagIterator.isDone(): dagPath = OpenMaya.MDagPath() if (all): dagIterator.getPath(dagPath) else: dagIterator.getDagPath(dagPath) fnMesh = None try: fnMesh = OpenMaya.MFnMesh(dagPath) except: dagIterator.next() continue meshPoints = OpenMaya.MPointArray() fnMesh.getPoints(meshPoints, OpenMaya.MSpace.kWorld) meshNormals = OpenMaya.MFloatVectorArray() fnMesh.getNormals(meshNormals) UVSets = [] fnMesh.getUVSetNames(UVSets) u = OpenMaya.MFloatArray() v = OpenMaya.MFloatArray() fnMesh.getUVs(u, v, UVSets[0]) iterPolys = OpenMaya.MItMeshPolygon(dagPath) offset = 0 maxPoints = 0 normals = {} uvs = {} while not iterPolys.isDone(): if not iterPolys.hasValidTriangulation(): return OpenMaya.MStatus.kFailiure uvSet = [] iterPolys.getUVSetNames(uvSet) polygonVertices = OpenMaya.MIntArray() iterPolys.getVertices(polygonVertices) numTrianglesPx = OpenMaya.MScriptUtil() numTrianglesPx.createFromInt(0) numTrianglesPtr = numTrianglesPx.asIntPtr() iterPolys.numTriangles(numTrianglesPtr) numTriangles = OpenMaya.MScriptUtil(numTrianglesPtr).asInt() offset = len(ctmvertices) localindices = [] for i in range(numTriangles): points = OpenMaya.MPointArray() indices = OpenMaya.MIntArray() iterPolys.getTriangle(i, points, indices) ctmindices.append(indicesOffset) indicesOffset += 1 ctmindices.append(indicesOffset) indicesOffset += 1 ctmindices.append(indicesOffset) indicesOffset += 1 localindices.append(int(indices[0])) localindices.append(int(indices[1])) localindices.append(int(indices[2])) localIndex = [] for gt in range(indices.length()): for gv in range(polygonVertices.length()): if indices[gt] == polygonVertices[gv]: localIndex.append(gv) break normals[int( indices[0])] = (float( meshNormals[iterPolys.normalIndex( localIndex[0])].x), float( meshNormals[iterPolys.normalIndex( localIndex[0])].y), float( meshNormals[iterPolys.normalIndex( localIndex[0])].z)) normals[int( indices[1])] = (float( meshNormals[iterPolys.normalIndex( localIndex[1])].x), float( meshNormals[iterPolys.normalIndex( localIndex[1])].y), float( meshNormals[iterPolys.normalIndex( localIndex[1])].z)) normals[int( indices[2])] = (float( meshNormals[iterPolys.normalIndex( localIndex[2])].x), float( meshNormals[iterPolys.normalIndex( localIndex[2])].y), float( meshNormals[iterPolys.normalIndex( localIndex[2])].z)) uvID = [0, 0, 0] for vtxInPolygon in range(3): uvIDPx = OpenMaya.MScriptUtil() uvIDPx.createFromInt(0) uvIDPtr = numTrianglesPx.asIntPtr() iterPolys.getUVIndex(localIndex[vtxInPolygon], uvIDPtr, UVSets[0]) uvID[vtxInPolygon] = OpenMaya.MScriptUtil( uvIDPtr).asInt() if (iterPolys.hasUVs()): uvs[int(indices[0])] = (u[uvID[0]], v[uvID[0]]) uvs[int(indices[1])] = (u[uvID[1]], v[uvID[1]]) uvs[int(indices[2])] = (u[uvID[2]], v[uvID[2]]) for i in localindices: ctmvertices.append(float(meshPoints[i].x)) ctmvertices.append(float(meshPoints[i].y)) ctmvertices.append(float(meshPoints[i].z)) ctmnormals.append(normals[i][0]) ctmnormals.append(normals[i][1]) ctmnormals.append(normals[i][2]) if (iterPolys.hasUVs()): ctmtexcoords.append(uvs[i][0]) ctmtexcoords.append(uvs[i][1]) iterPolys.next() dagIterator.next() pindices = cast((openctm.CTMuint * len(ctmindices))(), POINTER(openctm.CTMuint)) pvertices = cast((openctm.CTMfloat * len(ctmvertices))(), POINTER(openctm.CTMfloat)) pnormals = cast((openctm.CTMfloat * len(ctmnormals))(), POINTER(openctm.CTMfloat)) ptexcoords = cast((openctm.CTMfloat * len(ctmtexcoords))(), POINTER(openctm.CTMfloat)) for i in range(len(ctmindices)): pindices[i] = openctm.CTMuint(ctmindices[i]) for i in range(len(ctmvertices)): pvertices[i] = openctm.CTMfloat(ctmvertices[i]) pnormals[i] = openctm.CTMfloat(ctmnormals[i]) for i in range(len(ctmtexcoords)): ptexcoords[i] = openctm.CTMfloat(ctmtexcoords[i]) context = openctm.ctmNewContext(openctm.CTM_EXPORT) comment = "Exported with OpenCTM exporter using Maya " + OpenMaya.MGlobal.mayaVersion( ) openctm.ctmFileComment(context, c_char_p(comment)) openctm.ctmDefineMesh(context, pvertices, openctm.CTMuint(len(ctmvertices) / 3), pindices, openctm.CTMuint(len(ctmindices) / 3), pnormals) openctm.ctmAddUVMap(context, ptexcoords, c_char_p(), c_char_p()) openctm.ctmSave(context, c_char_p(fileName)) openctm.ctmFreeContext(context) e = openctm.ctmGetError(context) if e != 0: s = openctm.ctmErrorString(e) print s return OpenMaya.MStatus.kFailiure else: return OpenMaya.MStatus.kSuccess
def writer( self, fileObject, optionString, accessMode ): fileName = fileObject.fullName() selection = OpenMaya.MSelectionList() all = (accessMode == self.kExportAccessMode or accessMode == self.kSaveAccessMode) dagIterator = None if(all): dagIterator = OpenMaya.MItDag(OpenMaya.MItDag.kBreadthFirst, OpenMaya.MFn.kGeometric) else: OpenMaya.MGlobal.getActiveSelectionList( selection ) dagIterator = OpenMaya.MItSelectionList ( selection, OpenMaya.MFn.kGeometric ) ctmindices = [] ctmvertices = [] ctmnormals = [] ctmtexcoords = [] indicesOffset = 0 while not dagIterator.isDone(): dagPath = OpenMaya.MDagPath() if (all): dagIterator.getPath(dagPath) else: dagIterator.getDagPath(dagPath) fnMesh = None try: fnMesh = OpenMaya.MFnMesh( dagPath ) except: dagIterator.next() continue meshPoints = OpenMaya.MPointArray() fnMesh.getPoints( meshPoints,OpenMaya.MSpace.kWorld ) meshNormals = OpenMaya.MFloatVectorArray() fnMesh.getNormals(meshNormals) UVSets = [] fnMesh.getUVSetNames( UVSets ) u = OpenMaya.MFloatArray() v = OpenMaya.MFloatArray() fnMesh.getUVs( u, v, UVSets[0] ) iterPolys = OpenMaya.MItMeshPolygon( dagPath ) offset = 0 maxPoints = 0 normals = {} uvs = {} while not iterPolys.isDone(): if not iterPolys.hasValidTriangulation(): return OpenMaya.MStatus.kFailiure uvSet = [] iterPolys.getUVSetNames(uvSet) polygonVertices = OpenMaya.MIntArray() iterPolys.getVertices( polygonVertices ) numTrianglesPx = OpenMaya.MScriptUtil() numTrianglesPx.createFromInt(0) numTrianglesPtr = numTrianglesPx.asIntPtr() iterPolys.numTriangles(numTrianglesPtr) numTriangles = OpenMaya.MScriptUtil(numTrianglesPtr).asInt() offset = len(ctmvertices) localindices = [] for i in range( numTriangles ): points = OpenMaya.MPointArray() indices = OpenMaya.MIntArray() iterPolys.getTriangle( i, points,indices) ctmindices.append (indicesOffset) indicesOffset += 1 ctmindices.append (indicesOffset) indicesOffset += 1 ctmindices.append (indicesOffset) indicesOffset += 1 localindices.append(int(indices[0])) localindices.append(int(indices[1])) localindices.append(int(indices[2])) localIndex = [] for gt in range(indices.length()) : for gv in range( polygonVertices.length() ): if indices[gt] == polygonVertices[gv]: localIndex.append( gv ) break normals[int(indices[0])] = (float(meshNormals[iterPolys.normalIndex(localIndex[0])].x),float(meshNormals[iterPolys.normalIndex(localIndex[0])].y),float(meshNormals[iterPolys.normalIndex(localIndex[0])].z)) normals[int(indices[1])] = (float(meshNormals[iterPolys.normalIndex(localIndex[1])].x),float(meshNormals[iterPolys.normalIndex(localIndex[1])].y),float(meshNormals[iterPolys.normalIndex(localIndex[1])].z)) normals[int(indices[2])] = (float(meshNormals[iterPolys.normalIndex(localIndex[2])].x),float(meshNormals[iterPolys.normalIndex(localIndex[2])].y),float(meshNormals[iterPolys.normalIndex(localIndex[2])].z)) uvID = [0,0,0] for vtxInPolygon in range(3): uvIDPx = OpenMaya.MScriptUtil() uvIDPx.createFromInt(0) uvIDPtr = numTrianglesPx.asIntPtr() iterPolys.getUVIndex( localIndex[vtxInPolygon], uvIDPtr, UVSets[0] ) uvID[vtxInPolygon] = OpenMaya.MScriptUtil(uvIDPtr).asInt() if (iterPolys.hasUVs()): uvs[int(indices[0])] = (u[uvID[0]], v[uvID[0]]) uvs[int(indices[1])] = (u[uvID[1]], v[uvID[1]]) uvs[int(indices[2])] = (u[uvID[2]], v[uvID[2]]) for i in localindices: ctmvertices.append (float(meshPoints[i].x)) ctmvertices.append (float(meshPoints[i].y)) ctmvertices.append (float(meshPoints[i].z)) ctmnormals.append(normals[i][0]) ctmnormals.append(normals[i][1]) ctmnormals.append(normals[i][2]) if (iterPolys.hasUVs()): ctmtexcoords.append(uvs[i][0]) ctmtexcoords.append(uvs[i][1]) iterPolys.next() dagIterator.next() pindices = cast((openctm.CTMuint * len(ctmindices))(), POINTER(openctm.CTMuint)) pvertices = cast((openctm.CTMfloat * len(ctmvertices))(), POINTER(openctm.CTMfloat)) pnormals = cast((openctm.CTMfloat * len(ctmnormals))(), POINTER(openctm.CTMfloat)) ptexcoords = cast((openctm.CTMfloat * len(ctmtexcoords))(), POINTER(openctm.CTMfloat)) for i in range(len(ctmindices)): pindices[i] = openctm.CTMuint(ctmindices[i]) for i in range(len(ctmvertices)): pvertices[i] = openctm.CTMfloat(ctmvertices[i]) pnormals[i] = openctm.CTMfloat(ctmnormals[i]) for i in range(len(ctmtexcoords)): ptexcoords[i] = openctm.CTMfloat(ctmtexcoords[i]) context = openctm.ctmNewContext(openctm.CTM_EXPORT) comment = "Exported with OpenCTM exporter using Maya " + OpenMaya.MGlobal.mayaVersion() openctm.ctmFileComment(context, c_char_p(comment)) openctm.ctmDefineMesh(context, pvertices, openctm.CTMuint(len(ctmvertices)/3), pindices, openctm.CTMuint(len(ctmindices)/3), pnormals) openctm.ctmAddUVMap (context, ptexcoords,c_char_p() , c_char_p()) openctm.ctmSave(context, c_char_p(fileName)) openctm.ctmFreeContext(context) e = openctm.ctmGetError(context) if e != 0: s = openctm.ctmErrorString(e) print s return OpenMaya.MStatus.kFailiure else: return OpenMaya.MStatus.kSuccess