Example #1
0
void
OsdPtexMeshData::rebuildHbrMeshIfNeeded(OpenSubdivPtexShader *shader)
{
    MStatus status;

    if (!_meshTopoDirty && !shader->getHbrMeshDirty())
        return;

    MFnMesh meshFn(_meshDagPath, &status);
    if (status != MS::kSuccess) return;

    int level = shader->getLevel();
    if (level < 1) level =1;

    SchemeType scheme = shader->getScheme();
    if (scheme == kLoop) scheme = kCatmark;  // XXX: avoid loop for now

    // Get Maya vertex topology and crease data
    MIntArray vertexCount;
    MIntArray vertexList;
    meshFn.getVertices(vertexCount, vertexList);

    MUintArray edgeIds;
    MDoubleArray edgeCreaseData;
    meshFn.getCreaseEdges(edgeIds, edgeCreaseData);

    MUintArray vtxIds;
    MDoubleArray vtxCreaseData;
    meshFn.getCreaseVertices(vtxIds, vtxCreaseData);

    if (vertexCount.length() == 0) return;

    // Cache attribute values
    _level              = shader->getLevel();
    _scheme             = shader->getScheme();
    _kernel             = shader->getKernel();
    _adaptive           = shader->isAdaptive();
    _interpBoundary     = shader->getInterpolateBoundary();

    // Copy Maya vectors into std::vectors
    std::vector<int> numIndices(&vertexCount[0], &vertexCount[vertexCount.length()]);
    std::vector<int> faceIndices(&vertexList[0], &vertexList[vertexList.length()]);
    std::vector<int> vtxCreaseIndices(&vtxIds[0], &vtxIds[vtxIds.length()]);
    std::vector<double> vtxCreases(&vtxCreaseData[0], &vtxCreaseData[vtxCreaseData.length()]);
    std::vector<double> edgeCreases(&edgeCreaseData[0], &edgeCreaseData[edgeCreaseData.length()]);

    // Edge crease index is stored as pairs of vertex ids
    int nEdgeIds = edgeIds.length();
    std::vector<int> edgeCreaseIndices;
    edgeCreaseIndices.resize(nEdgeIds*2);
    for (int i = 0; i < nEdgeIds; ++i) {
        int2 vertices;
        status = meshFn.getEdgeVertices(edgeIds[i], vertices);
        if (status.error()) {
            status.perror("ERROR can't get creased edge vertices");
            continue;
        }
        edgeCreaseIndices[i*2] = vertices[0];
        edgeCreaseIndices[i*2+1] = vertices[1];
    }

    // Convert attribute enums to HBR enums (this is why the enums need to match)
    // XXX use some sort of built-in transmorgification avoid assumption?
    HbrMeshUtil::SchemeType hbrScheme = (HbrMeshUtil::SchemeType) _scheme;
    OsdHbrMesh::InterpolateBoundaryMethod hbrInterpBoundary = 
            (OsdHbrMesh::InterpolateBoundaryMethod) _interpBoundary;

    // Convert Maya mesh to internal HBR representation
    _hbrmesh = ConvertToHBR(meshFn.numVertices(), numIndices, faceIndices,
                            vtxCreaseIndices, vtxCreases,
                            std::vector<int>(), std::vector<float>(),
                            edgeCreaseIndices, edgeCreases,
                            hbrInterpBoundary, 
                            hbrScheme,
                            true );                     // add ptex indices to HBR

    // note: GL function can't be used in prepareForDraw API.
    _needsInitializeMesh = true;

    // Mesh topology data is up to date
    _meshTopoDirty = false;
    shader->setHbrMeshDirty(false);
}
Example #2
0
// #### rebuildHbrMeshIfNeeded
//
//      If the topology of the mesh changes, or any attributes that affect
//      how the mesh is computed the original HBR needs to be rebuilt
//      which will trigger a rebuild of the FAR mesh and subsequent buffers.
//
void
OsdMeshData::rebuildHbrMeshIfNeeded(OpenSubdivShader *shader)
{
    MStatus status = MS::kSuccess;

    if (!_meshTopoDirty && !shader->getHbrMeshDirty())
        return;

    MFnMesh meshFn(_meshDagPath);

    // Cache attribute values
    _level      = shader->getLevel();
    _kernel     = shader->getKernel();
    _adaptive   = shader->isAdaptive();
    _uvSet      = shader->getUVSet();

    // Get Maya vertex topology and crease data
    MIntArray vertexCount;
    MIntArray vertexList;
    meshFn.getVertices(vertexCount, vertexList);

    MUintArray edgeIds;
    MDoubleArray edgeCreaseData;
    meshFn.getCreaseEdges(edgeIds, edgeCreaseData);

    MUintArray vtxIds;
    MDoubleArray vtxCreaseData;
    meshFn.getCreaseVertices(vtxIds, vtxCreaseData);

    if (vertexCount.length() == 0) return;

    // Copy Maya vectors into std::vectors
    std::vector<int> numIndices(&vertexCount[0], &vertexCount[vertexCount.length()]);
    std::vector<int> faceIndices(&vertexList[0], &vertexList[vertexList.length()]);
    std::vector<int> vtxCreaseIndices(&vtxIds[0], &vtxIds[vtxIds.length()]);
    std::vector<double> vtxCreases(&vtxCreaseData[0], &vtxCreaseData[vtxCreaseData.length()]);
    std::vector<double> edgeCreases(&edgeCreaseData[0], &edgeCreaseData[edgeCreaseData.length()]);

    // Edge crease index is stored as pairs of vertex ids
    int nEdgeIds = edgeIds.length();
    std::vector<int> edgeCreaseIndices;
    edgeCreaseIndices.resize(nEdgeIds*2);
    for (int i = 0; i < nEdgeIds; ++i) {
        int2 vertices;
        status = meshFn.getEdgeVertices(edgeIds[i], vertices);
        if (status.error()) {
            MERROR(status, "OpenSubdivShader: Can't get edge vertices");
            continue;
        }
        edgeCreaseIndices[i*2] = vertices[0];
        edgeCreaseIndices[i*2+1] = vertices[1];
    }

    // Convert attribute enums to HBR enums (this is why the enums need to match)
    HbrMeshUtil::SchemeType hbrScheme = (HbrMeshUtil::SchemeType) shader->getScheme();
    OsdHbrMesh::InterpolateBoundaryMethod hbrInterpBoundary = 
            (OsdHbrMesh::InterpolateBoundaryMethod) shader->getInterpolateBoundary();
    OsdHbrMesh::InterpolateBoundaryMethod hbrInterpUVBoundary = 
            (OsdHbrMesh::InterpolateBoundaryMethod) shader->getInterpolateUVBoundary();


    // clear any existing face-varying descriptor
    if (_fvarDesc) {
        delete _fvarDesc;
        _fvarDesc = NULL;
    }

    // read UV data from maya and build per-face per-vert list of UVs for HBR face-varying data
    std::vector< float > uvList;
    status = buildUVList( meshFn, uvList );
    if (! status.error()) {
        // Create face-varying data descriptor.  The memory required for indices
        // and widths needs to stay alive as the HBR library only takes in the
        // pointers and assumes the client will maintain the memory so keep _fvarDesc
        // around as long as _hbrmesh is around.
        int fvarIndices[] = { 0, 1 };
        int fvarWidths[] = { 1, 1 };
        _fvarDesc = new FVarDataDesc( 2, fvarIndices, fvarWidths, 2, hbrInterpUVBoundary );
    }

    if (_fvarDesc && hbrScheme != HbrMeshUtil::kCatmark) {
        MGlobal::displayWarning("Face-varying not yet supported for Loop/Bilinear, using Catmull-Clark");
        hbrScheme = HbrMeshUtil::kCatmark;
    }

    // Convert Maya mesh to internal HBR representation
    _hbrmesh = ConvertToHBR(meshFn.numVertices(), numIndices, faceIndices,
                            vtxCreaseIndices, vtxCreases,
                            std::vector<int>(), std::vector<float>(),
                            edgeCreaseIndices, edgeCreases,
                            hbrInterpBoundary, 
                            hbrScheme,
                            false,                      // no ptex
                            _fvarDesc, 
                            _fvarDesc?&uvList:NULL);    // yes fvar (if have UVs)

    // note: GL function can't be used in prepareForDraw API.
    _needsInitializeMesh = true;

    // Mesh topology data is up to date
    _meshTopoDirty = false;
    shader->setHbrMeshDirty(false);
}