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; }
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; }