Beispiel #1
0
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
Beispiel #2
0
	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)
Beispiel #3
0
def vertices_triangles_to_openctm( vertices, triangles ):
  import ctypes 
  import openctm 


  if not vertices or not triangles:
    return ''

  pVertices = make_blob(vertices, ctypes.c_float)
  pTriangles = make_blob(triangles, ctypes.c_uint)
  pNormals = ctypesPOINTER(ctypes.c_float)()
  openctm.ctm = ctmNewContext(openctm.CTM_EXPORT)
  openctm.ctmDefineMesh(ctm, pVertices, len(vertices), pTriangles, len(triangles), pNormals)

  #Having to use a tmp file, because StringIO can't be easly pass
  #Because the biding is expecting an string
  #It is also possible to pass a c++ stream, but I don't know
  #how to interface that with python
  tf = tempfile.NamedTemporaryFile()
  openctm/ctmSave(ctm, tf.name)
  openctm.ctmFreeContext(ctm)
  s = tf.read()
  tf.close()
  return s
Beispiel #4
0
    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)
Beispiel #5
0
    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)
Beispiel #6
0
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
Beispiel #7
0
    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)
Beispiel #8
0
    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)
Beispiel #9
0
    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
Beispiel #10
0
        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