//------------------------------------------------------------------------------
// generate display IDs for Vtr verts
static void
createVertNumbers(OpenSubdiv::Far::TopologyRefiner const & refiner,
    std::vector<Vertex> const & vertexBuffer) {

    int maxlevel = refiner.GetMaxLevel(),
        firstvert = 0;

    if (refiner.IsUniform()) {
        for (int i=0; i<maxlevel; ++i) {
            firstvert += refiner.GetNumVertices(i);
        }
    }

    static char buf[16];
    if (refiner.IsUniform()) {
        for (int i=firstvert; i<(int)vertexBuffer.size(); ++i) {
            snprintf(buf, 16, "%d", i);
            g_font->Print3D(vertexBuffer[i].GetPos(), buf, 1);
        }
    } else {

        for (int level=0, vert=0; level<=refiner.GetMaxLevel(); ++level) {
            for (int i=0; i<refiner.GetNumVertices(level); ++i, ++vert) {
                snprintf(buf, 16, "%d", i);
                g_font->Print3D(vertexBuffer[vert].GetPos(), buf, 1);
            }
        }
    }
}
Beispiel #2
0
//------------------------------------------------------------------------------
// generate display IDs for Far faces
static void
createFaceNumbers(OpenSubdiv::Far::TopologyRefiner const & refiner,
    std::vector<Vertex> const & vertexBuffer) {

    static char buf[16];

    if (refiner.IsUniform()) {
        int maxlevel = refiner.GetMaxLevel(),
            firstvert = 0;

        for (int i=0; i<maxlevel; ++i) {
            firstvert += refiner.GetLevel(i).GetNumVertices();
        }

        OpenSubdiv::Far::TopologyLevel const & refLastLevel = refiner.GetLevel(maxlevel);

        for (int face=0; face<refLastLevel.GetNumFaces(); ++face) {

            Vertex center(0.0f, 0.0f, 0.0f);

            OpenSubdiv::Far::ConstIndexArray const verts = refLastLevel.GetFaceVertices(face);

            float weight = 1.0f / (float)verts.size();

            for (int vert=0; vert<verts.size(); ++vert) {
                center.AddWithWeight(vertexBuffer[firstvert+verts[vert]], weight);
            }

            snprintf(buf, 16, "%d", face);
            g_font->Print3D(center.GetPos(), buf, 2);
        }
    } else {
        int maxlevel = refiner.GetMaxLevel(),
//            patch = refiner.GetLevel(0).GetNumFaces(),
            firstvert = refiner.GetLevel(0).GetNumVertices();

        for (int level=1; level<=maxlevel; ++level) {

            OpenSubdiv::Far::TopologyLevel const & refLevel = refiner.GetLevel(level);

            int nfaces = refLevel.GetNumFaces();

            for (int face=0; face<nfaces; ++face /*, ++patch */) {

                Vertex center(0.0f, 0.0f, 0.0f);

                OpenSubdiv::Far::ConstIndexArray const verts = refLevel.GetFaceVertices(face);

                float weight = 1.0f / (float)verts.size();

                for (int vert=0; vert<verts.size(); ++vert) {
                    center.AddWithWeight(vertexBuffer[firstvert+verts[vert]], weight);
                }
                snprintf(buf, 16, "%d", face);
                g_font->Print3D(center.GetPos(), buf, 2);
            }
            firstvert+=refLevel.GetNumVertices();
        }
    }
}
Beispiel #3
0
void
InterpolateFVarData(OpenSubdiv::Far::TopologyRefiner & refiner,
    Shape const & shape, std::vector<float> & fvarData) {

    int channel = 0,    // shapes only have 1 UV channel
        fvarWidth = 2;

    int maxlevel = refiner.GetMaxLevel(),
        numValuesM = refiner.GetLevel(maxlevel).GetNumFVarValues(channel),
        numValuesTotal = refiner.GetNumFVarValuesTotal(channel);

    if (shape.uvs.empty() || numValuesTotal<=0) {
        return;
    }

    OpenSubdiv::Far::PrimvarRefiner primvarRefiner(refiner);

    if (refiner.IsUniform()) {

        // For uniform we only keep the highest level of refinement:
        fvarData.resize(numValuesM * fvarWidth);

        std::vector<FVarVertex> buffer(numValuesTotal - numValuesM);

        FVarVertex * src = &buffer[0];
        memcpy(src, &shape.uvs[0], shape.uvs.size()*sizeof(float));

        //  Defer the last level to treat separately with its alternate destination:
        for (int level = 1; level < maxlevel; ++level) {
            FVarVertex * dst = src + refiner.GetLevel(level-1).GetNumFVarValues(channel);

            primvarRefiner.InterpolateFaceVarying(level, src, dst, channel);

            src = dst;
        }

        FVarVertex * dst = reinterpret_cast<FVarVertex *>(&fvarData[0]);
        primvarRefiner.InterpolateFaceVarying(maxlevel, src, dst, channel);

    } else {

        // For adaptive we keep all levels:
        fvarData.resize(numValuesTotal * fvarWidth);

        FVarVertex * src = reinterpret_cast<FVarVertex *>(&fvarData[0]);
        memcpy(src, &shape.uvs[0], shape.uvs.size()*sizeof(float));

        for (int level = 1; level <= maxlevel; ++level) {
            FVarVertex * dst = src + refiner.GetLevel(level-1).GetNumFVarValues(channel);

            primvarRefiner.InterpolateFaceVarying(level, src, dst, channel);

            src = dst;
        }
    }
}
Beispiel #4
0
//------------------------------------------------------------------------------
// generate display IDs for Far edges
static void
createEdgeNumbers(OpenSubdiv::Far::TopologyRefiner const & refiner,
    std::vector<Vertex> const & vertexBuffer, bool ids=false, bool sharpness=false) {

    if (ids or sharpness) {

        int maxlevel = refiner.GetMaxLevel(),
            firstvert = 0;

        for (int i=0; i<maxlevel; ++i) {
            firstvert += refiner.GetLevel(i).GetNumVertices();
        }

        OpenSubdiv::Far::TopologyLevel const & refLastLevel = refiner.GetLevel(maxlevel);

        static char buf[16];
        for (int i=0; i<refLastLevel.GetNumEdges(); ++i) {

            Vertex center(0.0f, 0.0f, 0.0f);

            OpenSubdiv::Far::ConstIndexArray const verts = refLastLevel.GetEdgeVertices(i);
            assert(verts.size()==2);

            center.AddWithWeight(vertexBuffer[firstvert+verts[0]], 0.5f);
            center.AddWithWeight(vertexBuffer[firstvert+verts[1]], 0.5f);

            if (ids) {
                snprintf(buf, 16, "%d", i);
                g_font->Print3D(center.GetPos(), buf, 3);
            }

            if (sharpness) {
                float sharpness = refLastLevel.GetEdgeSharpness(i);
                if (sharpness>0.0f) {
                    snprintf(buf, 16, "%g", sharpness);
                    g_font->Print3D(center.GetPos(), buf, std::min(8,(int)sharpness+4));
                }
            }
        }
    }
}
Beispiel #5
0
static MStatus
convertToMayaMeshData(OpenSubdiv::Far::TopologyRefiner const & refiner,
    std::vector<Vertex> const & refinedVerts,
    bool hasUVs, std::vector<FVarVertexUV> const & refinedUVs,
    bool hasColors, std::vector<FVarVertexColor> const & refinedColors,
    MFnMesh & inMeshFn, MObject newMeshDataObj) {

    MStatus status;

    typedef OpenSubdiv::Far::ConstIndexArray IndexArray;

    int maxlevel = refiner.GetMaxLevel();

    OpenSubdiv::Far::TopologyLevel const & refLastLevel 
                                                = refiner.GetLevel(maxlevel);

    int nfaces = refLastLevel.GetNumFaces();

    // Init Maya Data

    // Face Counts
    MIntArray faceCounts(nfaces);
    for (int face=0; face < nfaces; ++face) {
        faceCounts[face] = 4;
    }

    // Face Connects
    MIntArray faceConnects(nfaces*4);
    for (int face=0, idx=0; face < nfaces; ++face) {
        IndexArray fverts = refLastLevel.GetFaceVertices(face);
        for (int vert=0; vert < fverts.size(); ++vert) {
            faceConnects[idx++] = fverts[vert];
        }
    }

    // Points
    int nverts = refLastLevel.GetNumVertices();
    int firstOfLastVert = refiner.GetNumVerticesTotal() 
                        - nverts 
                        - refiner.GetLevel(0).GetNumVertices();

    MFloatPointArray points(nverts);
    for (int vIt = 0; vIt < nverts; ++vIt) {
        Vertex const & v = refinedVerts[firstOfLastVert + vIt];
        points.set(vIt, v.position[0], v.position[1], v.position[2]);
    }

    // Create New Mesh from MFnMesh
    MFnMesh newMeshFn;
    MObject newMeshObj = newMeshFn.create(points.length(), faceCounts.length(),
        points, faceCounts, faceConnects, newMeshDataObj, &status);
    MCHECKERR(status, "Cannot create new mesh");

    // Get face-varying set names and other info from the inMesh
    MStringArray uvSetNames;
    MStringArray colorSetNames;
    std::vector<int> colorSetChannels;
    std::vector<MFnMesh::MColorRepresentation> colorSetReps;
    int totalColorSetChannels = 0;
    status = getMayaFvarFieldParams(inMeshFn, uvSetNames, colorSetNames,
        colorSetChannels, colorSetReps, totalColorSetChannels);

    // Add new UVs back to the mesh if needed
    if (hasUVs) {

        MIntArray fvarConnects(faceConnects.length());
        int count = 0;
        for (int f = 0; f < refLastLevel.GetNumFaces(); ++f) {
            IndexArray faceIndices = refLastLevel.GetFaceFVarValues(f, CHANNELUV);
            for (int index = 0 ; index < faceIndices.size() ; ++index) {
                fvarConnects[count++] = faceIndices[index];
            }
        }

        int nuvs = refLastLevel.GetNumFVarValues(CHANNELUV);
        int firstOfLastUvs = refiner.GetNumFVarValuesTotal(CHANNELUV) 
                             - nuvs
                             - refiner.GetLevel(0).GetNumFVarValues(CHANNELUV);

        MFloatArray uCoord(nuvs), vCoord(nuvs);
        for (int uvIt = 0; uvIt < nuvs; ++uvIt) {
            FVarVertexUV const & uv = refinedUVs[firstOfLastUvs + uvIt];
            uCoord[uvIt] = uv.u;
            vCoord[uvIt] = uv.v;
        }

        // Currently, the plugin only supports one UV set
        int uvSetIndex = 0;
        if (uvSetIndex > 0) {
            status = newMeshFn.createUVSetDataMesh( uvSetNames[uvSetIndex] );
            MCHECKERR(status, "Cannot create UVSet");
        }
        static MString defaultUVName("map1");
        MString const * uvname = uvSetIndex==0 ? 
            &defaultUVName : &uvSetNames[uvSetIndex];
        status = newMeshFn.setUVs(uCoord, vCoord, uvname);                  
        MCHECKERR(status, "Cannot set UVs for set : "+*uvname);

        status = newMeshFn.assignUVs(faceCounts, fvarConnects, uvname);     
        MCHECKERR(status, "Cannot assign UVs");
    }

    // Add new colors back to the mesh if needed
    if (hasColors) {

        int count = 0;
        MIntArray fvarConnects2(faceConnects.length());
        for (int f = 0 ; f < refLastLevel.GetNumFaces(); ++f) {
            IndexArray faceIndices = refLastLevel.GetFaceFVarValues(f, CHANNELCOLOR);
            for (int index = 0 ; index < faceIndices.size() ; ++index) {
                fvarConnects2[count++] = faceIndices[index];
            }
        }
  
        int ncols = refLastLevel.GetNumFVarValues(CHANNELCOLOR);
        int firstOfLastCols = refiner.GetNumFVarValuesTotal(CHANNELCOLOR) 
                              - ncols
                              - refiner.GetLevel(0).GetNumFVarValues(CHANNELCOLOR);

        MColorArray colorArray(ncols);
        for (int colIt = 0; colIt < ncols; ++colIt) {
            FVarVertexColor const & c = refinedColors[firstOfLastCols + colIt];
            colorArray.set(colIt, c.r, c.g, c.b, c.a);
        }

        // Currently, the plugin only supports one color sets
        int colorSetIndex = 0;

        // Assign color buffer and map the ids for each face-vertex
        // API Limitation: Cannot set MColorRepresentation here
        status = newMeshFn.createColorSetDataMesh(
            colorSetNames[colorSetIndex]);                                
        MCHECKERR(status, "Cannot create ColorSet");

        bool isColorClamped = inMeshFn.isColorClamped(
            colorSetNames[colorSetIndex], &status);                   
        MCHECKERR(status, "Can not get Color Clamped ");

        status = newMeshFn.setIsColorClamped(
            colorSetNames[colorSetIndex], isColorClamped);                     
        MCHECKERR(status, "Can not set Color Clamped : " + isColorClamped);

        status = newMeshFn.setColors(
            colorArray, &colorSetNames[colorSetIndex], 
            colorSetReps[colorSetIndex]);   
        MCHECKERR(status, "Can not set Colors");

        status = newMeshFn.assignColors(
            fvarConnects2, &colorSetNames[colorSetIndex]);                          
        MCHECKERR(status, "Can not assign Colors");
    }

    return MS::kSuccess;
}
Beispiel #6
0
static MStatus
convertToMayaMeshData(OpenSubdiv::Far::TopologyRefiner const & refiner,
    std::vector<Vertex> const & vertexBuffer, MFnMesh const & inMeshFn,
        MObject newMeshDataObj) {

    MStatus status;

    typedef OpenSubdiv::Far::ConstIndexArray IndexArray;

    int maxlevel = refiner.GetMaxLevel();

    OpenSubdiv::Far::TopologyLevel const & refLastLevel 
                                                = refiner.GetLevel(maxlevel);

    int nfaces = refLastLevel.GetNumFaces();
        
    // Init Maya Data

    // -- Face Counts
    MIntArray faceCounts(nfaces);
    for (int face=0; face < nfaces; ++face) {
        faceCounts[face] = 4;
    }

    // -- Face Connects
    MIntArray faceConnects(nfaces*4);
    for (int face=0, idx=0; face < nfaces; ++face) {
        IndexArray fverts = refLastLevel.GetFaceVertices(face);
        for (int vert=0; vert < fverts.size(); ++vert) {
            faceConnects[idx++] = fverts[vert];
        }
    }

    // -- Points
    MFloatPointArray points(refLastLevel.GetNumVertices());
    Vertex const * v = &vertexBuffer.at(0);

    for (int level=1; level<=maxlevel; ++level) {
        int nverts = refiner.GetLevel(level).GetNumVertices();
        if (level==maxlevel) {
            for (int vert=0; vert < nverts; ++vert, ++v) {
                points.set(vert, v->position[0], v->position[1], v->position[2]);
            }
        } else {
            v += nverts;
        }
    }

    // Create New Mesh from MFnMesh
    MFnMesh newMeshFn;
    MObject newMeshObj = newMeshFn.create(points.length(), faceCounts.length(),
        points, faceCounts, faceConnects, newMeshDataObj, &status);
    MCHECKERR(status, "Cannot create new mesh");

    int fvarTotalWidth = 0;

    if (fvarTotalWidth > 0) {

        // Get face-varying set names and other info from the inMesh
        MStringArray uvSetNames;
        MStringArray colorSetNames;
        std::vector<int> colorSetChannels;
        std::vector<MFnMesh::MColorRepresentation> colorSetReps;
        int totalColorSetChannels = 0;
        status = getMayaFvarFieldParams(inMeshFn, uvSetNames, colorSetNames,
            colorSetChannels, colorSetReps, totalColorSetChannels);

#if defined(DEBUG) or defined(_DEBUG)
        int numUVSets = uvSetNames.length();
        int expectedFvarTotalWidth = numUVSets*2 + totalColorSetChannels;
        assert(fvarTotalWidth == expectedFvarTotalWidth);
#endif

// XXXX fvar stuff here

    }

    return MS::kSuccess;
}