-
Notifications
You must be signed in to change notification settings - Fork 581
Open
Description
Hi there!
I am trying to create uniform b-spline patches with adaptive refinement. As an example, I took the catmark_torus an set a crease value to one of the inner circle edges.
Refiner:
Sdc::SchemeType type = OpenSubdiv::Sdc::SCHEME_CATMARK;
Sdc::Options options;
options.SetVtxBoundaryInterpolation(Sdc::Options::VTX_BOUNDARY_EDGE_ONLY);
Descriptor desc;
desc.numVertices = quadMesh.Vertices.size();
desc.numFaces = quadMesh.Faces.size();
desc.numVertsPerFace = quadMesh.VerticesPerFace.data();
const auto* vec = static_cast<void*>(quadMesh.Faces.data());
desc.vertIndicesPerFace = static_cast<const Far::Index*>(vec);
desc.numCreases = 8;
std::vector<int> crease_verts{1, 29, 29, 25, 25, 21, 21, 17, 17, 13, 13, 9, 9, 5, 5, 1};
std::vector<float> crease_weights{3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f};
desc.creaseVertexIndexPairs = crease_verts.data();
desc.creaseWeights = crease_weights.data();
// Instantiate a Far::TopologyRefiner from the descriptor.
Far::TopologyRefiner* refiner = Far::TopologyRefinerFactory<Descriptor>::Create(
desc, Far::TopologyRefinerFactory<Descriptor>::Options(type, options));
Code to create b-splines:
int maxPatchLevel = 3;
Far::PatchTableFactory::Options patchOptions(maxPatchLevel);
patchOptions.SetPatchPrecision<Real>();
patchOptions.useInfSharpPatch = true;
patchOptions.generateVaryingTables = false;
patchOptions.endCapType = Far::PatchTableFactory::Options::ENDCAP_BSPLINE_BASIS;
// Initialize corresonding options for adaptive refinement:
Far::TopologyRefiner::AdaptiveOptions adaptiveOptions = patchOptions.GetRefineAdaptiveOptions();
// Apply adaptive refinement and construct the associated PatchTable to
// evaluate the limit surface:
refiner->RefineAdaptive(adaptiveOptions);
Far::PatchTable const* patchTable = Far::PatchTableFactory::Create(*refiner, patchOptions);
// Compute the total number of points we need to evaluate the PatchTable.
// Approximations at irregular or extraordinary features require the use
// of additional points associated with the patches that are referred to
// as "local points" (i.e. local to the PatchTable).
int nRefinerVertices = refiner->GetNumVerticesTotal();
int nLocalPoints = patchTable->GetNumLocalPoints();
// Create a buffer to hold the position of the refined verts and
// local points, then copy the coarse positions at the beginning.
std::vector<Vertex> verts(nRefinerVertices + nLocalPoints);
auto index = 0;
for(auto& vertex : quadMesh.Vertices)
{
verts[index].point[0] = vertex[0];
verts[index].point[1] = vertex[1];
verts[index].point[2] = vertex[2];
++index;
}
//std::memcpy(&verts[0], quadMesh.Vertices.data(), quadMesh.Vertices.size() * 3 * sizeof(float));
// Adaptive refinement may result in fewer levels than the max specified.
int nRefinedLevels = refiner->GetNumLevels();
// Interpolate vertex primvar data : they are the control vertices
// of the limit patches (see tutorial_1_1 for details)
Far::PrimvarRefinerReal<Real> primvarRefiner(*refiner);
Vertex* src = &verts[0];
for (int level = 1; level < nRefinedLevels; ++level)
{
Vertex* dst = src + refiner->GetLevel(level - 1).GetNumVertices();
primvarRefiner.Interpolate(level, src, dst);
src = dst;
}
// Evaluate local points from interpolated vertex primvars.
if (nLocalPoints)
{
patchTable->GetLocalPointStencilTable<Real>()->UpdateValues(&verts[0], &verts[nRefinerVertices]);
}
// Create a Far::PatchMap to help locating patches in the table
Far::PatchMap patchmap(*patchTable);
// Create a Far::PtexIndices to help find indices of ptex faces.
Far::PtexIndices ptexIndices(*refiner);
int face = 0;
for (auto& handle : patchmap._handles)
{
Far::ConstIndexArray cvs = patchTable->GetPatchVertices(handle);
// tessellate b-spline
// done with other library
}
Then this is my result, I did draw in the actual borders for better visibility:

So the inner circle of the torus has got the crease as expected and the patches are getting smaller and are adaptively refined
What I need now is that the smallest adaptive refinement is globally uniformly applied. So at one border of a b-spline patch is also only one other patch. I tried to draw what I mean from the example above:

Is something like that possible with OpenSubdiv?
Metadata
Metadata
Assignees
Labels
No labels