示例#1
0
//! Caller is expected to delete the returned value
static OpenSubdiv::Far::TopologyRefiner *
gatherTopology( MFnMesh & inMeshFn,
                MItMeshPolygon & inMeshItPolygon,
                OpenSubdiv::Sdc::SchemeType type,
                OpenSubdiv::Sdc::Options options,
                bool * hasUVs, bool * hasColors,
                std::vector<MFloatArray> & uvSet_uCoords,
                std::vector<MFloatArray> & uvSet_vCoords,
                std::vector<MColorArray> & colorSet_colors,
                float * maxCreaseSharpness=0 ) {

    MStatus returnStatus;

    // Gather FVarData
    MStringArray uvSetNames;
    MStringArray colorSetNames;
    std::vector<int> colorSetChannels;
    std::vector<MFnMesh::MColorRepresentation> colorSetReps;
    int totalColorSetChannels = 0;
    returnStatus = getMayaFvarFieldParams(inMeshFn, uvSetNames, colorSetNames, 
                        colorSetChannels, colorSetReps, totalColorSetChannels);
    MWARNERR(returnStatus, "Failed to retrieve Maya face-varying parameters");

    // Storage for UVs and ColorSets for face-vertex
    MIntArray fvArray; // face vertex array
    uvSet_uCoords.clear();  uvSet_uCoords.resize(uvSetNames.length());
    uvSet_vCoords.clear();  uvSet_vCoords.resize(uvSetNames.length());
    colorSet_colors.clear();colorSet_colors.resize(colorSetNames.length());

    // Put the data in the format needed for OSD
    Descriptor desc;
    
    int numFaceVertices = inMeshFn.numFaceVertices();

    desc.numVertices = inMeshFn.numVertices();
    desc.numFaces = inMeshItPolygon.count();

    int * vertsPerFace = new int[desc.numFaces],
        * vertIndices = new int[numFaceVertices];

    desc.numVertsPerFace = vertsPerFace;
    desc.vertIndicesPerFace = vertIndices;

    // Create Topology
    for (inMeshItPolygon.reset(); !inMeshItPolygon.isDone(); inMeshItPolygon.next()) {

        inMeshItPolygon.getVertices(fvArray);
        int nverts = fvArray.length();

        vertsPerFace[inMeshItPolygon.index()] = nverts;

        for (int i=0; i<nverts; ++i) {
            *vertIndices++ = fvArray[i];
        }
    }

    // Add Face-Varying data to the descriptor
    Descriptor::FVarChannel * channels = NULL;
    *hasUVs = uvSet_uCoords.size() > 0 && uvSet_vCoords.size() > 0;
    *hasColors = colorSet_colors.size() > 0;

    // Note : Only supports 1 channel of UVs and 1 channel of color
    if (*hasUVs || *hasColors) {

        // Create 2 face-varying channel descriptor that will hold UVs and color
        desc.numFVarChannels = 2;
        channels = new Descriptor::FVarChannel[desc.numFVarChannels];
        desc.fvarChannels = channels;

        int * uvIndices = new int[numFaceVertices];
        channels[CHANNELUV].valueIndices = uvIndices;
        channels[CHANNELUV].numValues = 0;

        int * colorIndices = new int[numFaceVertices];
        channels[CHANNELCOLOR].valueIndices = colorIndices;
        channels[CHANNELCOLOR].numValues = 0;

        // Obtain UV information
        if (*hasUVs) {
            inMeshFn.getUVs(uvSet_uCoords[0], uvSet_vCoords[0], &uvSetNames[0]);
            assert( uvSet_uCoords[0].length() == uvSet_vCoords[0].length() );

            int uvId = 0, nUVs = 0;
            for (int faceIndex = 0; faceIndex < inMeshFn.numPolygons(); ++faceIndex)
            {
                int numVertices = inMeshFn.polygonVertexCount(faceIndex);
                for (int v = 0; v < numVertices; v++)
                {
                    inMeshFn.getPolygonUVid(faceIndex, v, uvId, &uvSetNames[0]);
                    uvIndices[nUVs++] = uvId;
                }
            }

            channels[CHANNELUV].numValues = uvSet_uCoords[0].length();
        }

        // Obtain color information
        if (*hasColors) {  
            inMeshFn.getColors(colorSet_colors[0], &colorSetNames[0]);

            int colorId = 0, nColors = 0;
            bool addDefaultColor = true;
            for (int faceIndex = 0; faceIndex < inMeshFn.numPolygons(); ++faceIndex)
            {
                int numVertices = inMeshFn.polygonVertexCount(faceIndex);
                for ( int v = 0 ; v < numVertices; v++ )
                {
                    inMeshFn.getColorIndex(faceIndex, v, colorId, &colorSetNames[0]);
                    if (colorId == -1)
                    {
                        if (addDefaultColor)
                        {
                            addDefaultColor = false;
                            colorSet_colors[0].append(MColor(1.0, 1.0, 1.0, 1.0));
                        }
                        colorId = colorSet_colors[0].length() - 1;
                    }
                    colorIndices[nColors ++] = colorId;
                }
            }
            
            channels[CHANNELCOLOR].numValues = colorSet_colors[0].length();
        }
    }

    // Apply Creases
    float maxEdgeCrease = getCreaseEdges( inMeshFn, desc );
    float maxVertexCrease = getCreaseVertices( inMeshFn, desc );

    OpenSubdiv::Far::TopologyRefiner * refiner =
        OpenSubdiv::Far::TopologyRefinerFactory<Descriptor>::Create(desc,
            OpenSubdiv::Far::TopologyRefinerFactory<Descriptor>::Options(type, options));

    delete [] desc.numVertsPerFace;
    delete [] desc.vertIndicesPerFace;
    delete [] desc.creaseVertexIndexPairs;
    delete [] desc.creaseWeights;
    delete [] desc.cornerVertexIndices;
    delete [] desc.cornerWeights;

    if (*hasUVs || *hasColors) {
        for(int i = 0 ; i < desc.numFVarChannels ; i ++) {
            delete [] channels[i].valueIndices;
        }
        delete [] channels;
    }

    if (maxCreaseSharpness) {
        *maxCreaseSharpness = std::max(maxEdgeCrease, maxVertexCrease);
    }

    return refiner;
}
示例#2
0
//! Caller is expected to delete the returned value
static OpenSubdiv::Far::TopologyRefiner *
gatherTopology( MFnMesh const & inMeshFn,
                MItMeshPolygon & inMeshItPolygon,
                OpenSubdiv::Sdc::SchemeType type,
                OpenSubdiv::Sdc::Options options,
                float * maxCreaseSharpness=0 ) {

    MStatus returnStatus;

    // Gather FVarData
    MStringArray uvSetNames;
    MStringArray colorSetNames;
    std::vector<int> colorSetChannels;
    std::vector<MFnMesh::MColorRepresentation> colorSetReps;
    int totalColorSetChannels = 0;
    returnStatus = getMayaFvarFieldParams(inMeshFn, uvSetNames, colorSetNames, colorSetChannels, colorSetReps, totalColorSetChannels);
    MWARNERR(returnStatus, "Failed to retrieve Maya face-varying parameters");

    // Create face-varying data with independent float channels of dimension 1
    // Note: This FVarData needs to be kept around for the duration of the HBR mesh
    int totalFvarWidth = 2*uvSetNames.length() + totalColorSetChannels;

    // temp storage for UVs and ColorSets for a face
    MIntArray fvArray; // face vertex array
    std::vector<MFloatArray> uvSet_uCoords(uvSetNames.length());
    std::vector<MFloatArray> uvSet_vCoords(uvSetNames.length());
    std::vector<MColorArray> colorSet_colors(colorSetNames.length());

    Descriptor desc;

    desc.numVertices = inMeshFn.numVertices();
    desc.numFaces = inMeshItPolygon.count();

    int * vertsPerFace = new int[desc.numFaces],
        * vertIndices = new int[inMeshFn.numFaceVertices()];

    desc.numVertsPerFace = vertsPerFace;
    desc.vertIndicesPerFace = vertIndices;

    // Create Topology

    for( inMeshItPolygon.reset(); !inMeshItPolygon.isDone(); inMeshItPolygon.next() ) {

        inMeshItPolygon.getVertices(fvArray);
        int nverts = fvArray.length();

        vertsPerFace[inMeshItPolygon.index()] = nverts;

        for (int i=0; i<nverts; ++i) {
            *vertIndices++ = fvArray[i];
        }

        // Add FaceVaryingData (UVSets, ...)
        if (totalFvarWidth > 0) {
// XXXX
            // Retrieve all UV and ColorSet topology
            for (unsigned int i=0; i < uvSetNames.length(); ++i) {
                inMeshItPolygon.getUVs(uvSet_uCoords[i], uvSet_vCoords[i], &uvSetNames[i] );
            }
            for (unsigned int i=0; i < colorSetNames.length(); ++i) {
                inMeshItPolygon.getColors(colorSet_colors[i], &colorSetNames[i]);
            }

            // Handle uvSets
            for (unsigned int fvid=0; fvid < fvArray.length(); ++fvid) {
            }
            // Handle colorSets
            for( unsigned int colorSetIt=0; colorSetIt < colorSetNames.length(); ++colorSetIt ) {
            }
        }
    }

    // Apply Creases
    float maxEdgeCrease = getCreaseEdges( inMeshFn, desc );

    float maxVertexCrease = getCreaseVertices( inMeshFn, desc );

    OpenSubdiv::Far::TopologyRefiner * refiner =
        OpenSubdiv::Far::TopologyRefinerFactory<Descriptor>::Create(desc,
            OpenSubdiv::Far::TopologyRefinerFactory<Descriptor>::Options(type, options));

    delete [] desc.numVertsPerFace;
    delete [] desc.vertIndicesPerFace;

    delete [] desc.creaseVertexIndexPairs;
    delete [] desc.creaseWeights;
    delete [] desc.cornerVertexIndices;
    delete [] desc.cornerWeights;

    if (maxCreaseSharpness) {
        *maxCreaseSharpness = std::max(maxEdgeCrease, maxVertexCrease);
    }

    return refiner;
}