Exemplo n.º 1
0
bool
PxOsdUniformEvaluator::Initialize(
    PxOsdTopologyRefinerSharedPtr refiner,
    const PxOsdMeshTopology &topology,
    int level,
    string *errorMessage)    
{    
    TRACE_FUNCTION();

    _topology = topology;

    refiner->RefineUniform(level);
    
    Far::StencilTableFactory::Options options;
    options.generateOffsets = true;
    options.generateIntermediateLevels = false;
    _vertexStencils =
        Far::StencilTableFactory::Create(*refiner, options);

    Far::PatchTable const *patchTable  =
        Far::PatchTableFactory::Create(*refiner);

    if (not (TF_VERIFY(_vertexStencils) and TF_VERIFY(patchTable))) {
        return false;
    }
    
    // populate refined quad indices, note that four indices are packed
    // for each quad.
    int numRefinedQuadIndices = refiner->GetLevel(level).GetNumFaceVertices();
    
    _refinedQuadIndices.resize(numRefinedQuadIndices);
    for (int i=0; i<numRefinedQuadIndices/4; ++i) {
        OpenSubdiv::Far::ConstIndexArray faceVertices =
            refiner->GetLevel(level).GetFaceVertices(i);
        int baseIndex = i*4;
        if (faceVertices.size() != 4) {
            TF_WARN("Non-quad found after subdivision, bailing");
            delete patchTable;            
            return false;
        }
        for (int j=0; j<4; ++j) {
            _refinedQuadIndices[baseIndex+j] = faceVertices[j];
        }
    }
    

    int numRefinedQuads = _refinedQuadIndices.size()/4;
    _subfaceUvs.resize(_refinedQuadIndices.size());
    vector<float>::iterator uvIt = _subfaceUvs.begin();

    _ptexIndices.resize(numRefinedQuads);
    vector<int>::iterator idIt = _ptexIndices.begin();

    const Far::PatchParamTable &patchParamTable =
        patchTable->GetPatchParamTable();
    
    for (int refinedIndex = 0; refinedIndex < numRefinedQuads; ++refinedIndex) {
        
        const Far::PatchParam& param =
            patchParamTable[refinedIndex];
        
        float u0 = 0;
        float v0 = 0;
        _InverseNormalize(param, u0, v0);
        
        float u1 = 1;
        float v1 = 1;
        _InverseNormalize(param, u1, v1);
        
        *idIt++ = param.GetFaceId();
        *uvIt++ = u0;
        *uvIt++ = v0;
        *uvIt++ = u1;
        *uvIt++ = v1;
    }
    
    delete patchTable;

    return true;
}
Exemplo n.º 2
0
bool
HdSt_Osd3TopologyComputation::Resolve()
{
    using namespace OpenSubdiv;

    if (!_TryLock()) return false;

    HD_TRACE_FUNCTION();
    HF_MALLOC_TAG_FUNCTION();

    // do far analysis and set stencils and patch table into HdSt_Subdivision.

    // create topology refiner
    PxOsdTopologyRefinerSharedPtr refiner;

    if (!TF_VERIFY(_topology)) {
        _SetResolved();
        return true;
    }

    // for empty topology, we don't need to refine anything.
    // but still need to return the typed buffer for codegen
    if (_topology->GetFaceVertexCounts().size() == 0) {
        // leave refiner empty
    } else {
        refiner = PxOsdRefinerFactory::Create(_topology->GetPxOsdMeshTopology(),
                                              TfToken(_id.GetText()));
    }

    if (!TF_VERIFY(_subdivision)) {
        _SetResolved();
        return true;
    }

    // refine
    //  and
    // create stencil/patch table
    Far::StencilTable const *vertexStencils = NULL;
    Far::StencilTable const *varyingStencils = NULL;
    Far::PatchTable const *patchTable = NULL;

    if (refiner) {
        // split trace scopes.
        {
            HD_TRACE_SCOPE("refine");
            if (_adaptive) {
                refiner->RefineAdaptive(_level);
            } else {
                refiner->RefineUniform(_level);
            }
        }
        {
            HD_TRACE_SCOPE("stencil factory");
            Far::StencilTableFactory::Options options;
            options.generateOffsets = true;
            options.generateIntermediateLevels = _adaptive;
            options.interpolationMode =
                Far::StencilTableFactory::INTERPOLATE_VERTEX;
            vertexStencils = Far::StencilTableFactory::Create(*refiner, options);

            options.interpolationMode =
                Far::StencilTableFactory::INTERPOLATE_VARYING;
            varyingStencils = Far::StencilTableFactory::Create(*refiner, options);
        }
        {
            HD_TRACE_SCOPE("patch factory");
            Far::PatchTableFactory::Options options;
            if (_adaptive) {
                options.endCapType =
                    Far::PatchTableFactory::Options::ENDCAP_BSPLINE_BASIS;
            }

            patchTable = Far::PatchTableFactory::Create(*refiner, options);
        }
    }

    // merge endcap
    if (patchTable && patchTable->GetLocalPointStencilTable()) {
        // append stencils
        if (Far::StencilTable const *vertexStencilsWithLocalPoints =
            Far::StencilTableFactory::AppendLocalPointStencilTable(
                *refiner,
                vertexStencils,
                patchTable->GetLocalPointStencilTable())) {
            delete vertexStencils;
            vertexStencils = vertexStencilsWithLocalPoints;
        }
        if (Far::StencilTable const *varyingStencilsWithLocalPoints =
            Far::StencilTableFactory::AppendLocalPointStencilTable(
                *refiner,
                varyingStencils,
                patchTable->GetLocalPointStencilTable())) {
            delete varyingStencils;
            varyingStencils = varyingStencilsWithLocalPoints;
        }
    }

    // set tables to topology
    // HdSt_Subdivision takes an ownership of stencilTable and patchTable.
    _subdivision->SetRefinementTables(vertexStencils, varyingStencils,
                                      patchTable, _adaptive);

    _SetResolved();
    return true;
}