//------------------------------------------------------------------------------ // 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(); } } }
//------------------------------------------------------------------------------ // generate display vert IDs for the selected Far patch static void createPatchNumbers(OpenSubdiv::Far::PatchTable const & patchTable, std::vector<Vertex> const & vertexBuffer) { if (not g_currentPatch) return; int patchID = g_currentPatch-1, patchArray = -1; // Find PatchArray containing our patch for (int array=0; array<(int)patchTable.GetNumPatchArrays(); ++array) { int npatches = patchTable.GetNumPatches(array); if (patchID >= npatches) { patchID -= npatches; } else { patchArray = array; break; } } if (patchArray==-1) { return; } g_currentPatchDesc = patchTable.GetPatchArrayDescriptor(patchArray); OpenSubdiv::Far::ConstIndexArray const cvs = patchTable.GetPatchVertices(patchArray, patchID); static char buf[16]; for (int i=0; i<cvs.size(); ++i) { snprintf(buf, 16, "%d", i); g_font->Print3D(vertexBuffer[cvs[i]].GetPos(), buf, 1); } }
//------------------------------------------------------------------------------ // 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)); } } } } }
//------------------------------------------------------------------------------ // generate display vert IDs for the selected Far FVar patch static void createFVarPatchNumbers(OpenSubdiv::Far::PatchTable const & patchTable, std::vector<Vertex> const & fvarBuffer) { static int channel = 0; int patch = g_currentPatch-1; static char buf[16]; if (patch>=0 and patch<patchTable.GetNumPatchesTotal()) { OpenSubdiv::Far::PatchTable::PatchHandle handle; handle.patchIndex = patch; OpenSubdiv::Far::ConstIndexArray const cvs = patchTable.GetPatchFVarValues(handle, channel); for (int i=0; i<cvs.size(); ++i) { snprintf(buf, 16, "%d", i); g_font->Print3D(fvarBuffer[cvs[i]].GetPos(), buf, 2); } } }
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; }