Fix VtrViewer to display Gregory patch basis (debugging)

This commit is contained in:
manuelk 2014-11-11 11:28:39 -08:00
parent abae4459e6
commit 15725d28e8
3 changed files with 53 additions and 37 deletions

View File

@ -404,6 +404,7 @@ getNumEdges(int numCVs) {
case 12: return 4; case 12: return 4;
// case 16: return 24; // case 16: return 24;
case 16: return 4; case 16: return 4;
case 20: return 4;
default: default:
assert(0); assert(0);
} }
@ -451,6 +452,7 @@ getEdgeList(int numCVs) {
case 9: return edgeList9; break; case 9: return edgeList9; break;
case 12: return edgeList12; break; case 12: return edgeList12; break;
case 16: return edgeList16; break; case 16: return edgeList16; break;
case 20: return edgeList4; break;
default: default:
assert(0); assert(0);
} }

View File

@ -458,7 +458,8 @@ private:
B[NUM_TRANSITIONS][NUM_ROTATIONS], // boundary patch (4 rotations) B[NUM_TRANSITIONS][NUM_ROTATIONS], // boundary patch (4 rotations)
C[NUM_TRANSITIONS][NUM_ROTATIONS], // corner patch (4 rotations) C[NUM_TRANSITIONS][NUM_ROTATIONS], // corner patch (4 rotations)
G, // gregory patch G, // gregory patch
GB; // gregory boundary patch GB, // gregory boundary patch
GP; // gregory basis
PatchTypes() { memset(this, 0, sizeof(PatchTypes<TYPE>)); } PatchTypes() { memset(this, 0, sizeof(PatchTypes<TYPE>)); }
@ -494,6 +495,7 @@ Far::PatchTablesFactory::PatchTypes<TYPE>::getValue( Far::PatchTables::Descripto
case Far::PatchTables::CORNER : return C[desc.GetPattern()][desc.GetRotation()]; case Far::PatchTables::CORNER : return C[desc.GetPattern()][desc.GetRotation()];
case Far::PatchTables::GREGORY : return G; case Far::PatchTables::GREGORY : return G;
case Far::PatchTables::GREGORY_BOUNDARY : return GB; case Far::PatchTables::GREGORY_BOUNDARY : return GB;
case Far::PatchTables::GREGORY_BASIS : return GP;
default : assert(0); default : assert(0);
} }
// can't be reached (suppress compiler warning) // can't be reached (suppress compiler warning)

View File

@ -546,36 +546,31 @@ createPatchNumbers(OpenSubdiv::Far::PatchTables const & patchTables,
static GLMesh gregoryWire; static GLMesh gregoryWire;
static void static void
createGregoryBasis(OpenSubdiv::Far::TopologyRefiner const & refiner, createGregoryBasis(OpenSubdiv::Far::PatchTables const & patchTables,
OpenSubdiv::Far::StencilTables const & stencils, int maxvalence,
std::vector<Vertex> const & vertexBuffer) { std::vector<Vertex> const & vertexBuffer) {
int level = refiner.GetMaxLevel(), typedef OpenSubdiv::Far::PatchTables FPatchTables;
nfaces = refiner.GetNumFaces(level);
std::vector<OpenSubdiv::Far::Index> gpatches(nfaces); FPatchTables::PatchArrayVector const & parrays =
for (int face=0; face<nfaces; ++face) { patchTables.GetPatchArrayVector();
if (not refiner.FaceIsRegular(level, face)) {
gpatches.push_back(face); int npatches = 0;
for (int i=0; i<(int)parrays.size(); ++i) {
FPatchTables::PatchArray const & pa = parrays[i];
if (pa.GetDescriptor().GetType()==FPatchTables::GREGORY_BASIS) {
npatches = pa.GetNumPatches();
break;
} }
} }
int npatches = (int)gpatches.size();
OpenSubdiv::Far::GregoryBasisFactory factory(
refiner, stencils, npatches, maxvalence);
for (int i=0; i<npatches; ++i) {
factory.AddPatchBasis(gpatches[i]);
}
OpenSubdiv::Far::StencilTables const * gstencils =
factory.CreateStencilTables();
int nedges = npatches * 20; int nedges = npatches * 20;
std::vector<int> vertsperedge(nedges), edgeindices(nedges*2); std::vector<int> vertsperedge(nedges), edgeindices(nedges*2);
std::vector<Vertex> edgeverts(npatches*20); std::vector<Vertex> edgeverts(npatches*20);
OpenSubdiv::Far::StencilTables const * gstencils =
patchTables.GetEndCapStencilTables();
assert(gstencils);
gstencils->UpdateValues(&vertexBuffer[0], &edgeverts[0]); gstencils->UpdateValues(&vertexBuffer[0], &edgeverts[0]);
for (int patch=0; patch<npatches; ++patch) { for (int patch=0; patch<npatches; ++patch) {
@ -592,7 +587,7 @@ createGregoryBasis(OpenSubdiv::Far::TopologyRefiner const & refiner,
for (int i=0; i<20; ++i) { for (int i=0; i<20; ++i) {
vpe[i] = 2; vpe[i] = 2;
indices[i*2] = basisedges[i*2] + offset; indices[i*2] = basisedges[i*2] + offset;
indices[i*2+1] =basisedges[i*2+1] + offset; indices[i*2+1] = basisedges[i*2+1] + offset;
} }
Vertex const * verts = &edgeverts[offset]; Vertex const * verts = &edgeverts[offset];
@ -615,6 +610,7 @@ createGregoryBasis(OpenSubdiv::Far::TopologyRefiner const & refiner,
GLMesh::Options options; GLMesh::Options options;
gregoryWire.Initialize(options, (int)edgeverts.size(), (int)vertsperedge.size(), gregoryWire.Initialize(options, (int)edgeverts.size(), (int)vertsperedge.size(),
&vertsperedge[0], &edgeindices[0], (float const * )&edgeverts[0]); &vertsperedge[0], &edgeindices[0], (float const * )&edgeverts[0]);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -689,27 +685,20 @@ createVtrMesh(Shape * shape, int maxlevel) {
OpenSubdiv::Far::TopologyRefiner * refiner = OpenSubdiv::Far::TopologyRefiner * refiner =
OpenSubdiv::Far::TopologyRefinerFactory<Shape>::Create(sdctype, sdcoptions, *shape); OpenSubdiv::Far::TopologyRefinerFactory<Shape>::Create(sdctype, sdcoptions, *shape);
OpenSubdiv::Far::PatchTables * patchTables = 0;
if (g_Adaptive) { if (g_Adaptive) {
refiner->RefineAdaptive(maxlevel, /*fullTopology*/true); refiner->RefineAdaptive(maxlevel, /*fullTopology*/true);
patchTables = OpenSubdiv::Far::PatchTablesFactory::Create(*refiner);
g_numPatches = patchTables->GetNumPatchesTotal();
g_maxValence = patchTables->GetMaxValence();
} else { } else {
refiner->RefineUniform(maxlevel, /*fullTopology*/true); refiner->RefineUniform(maxlevel, /*fullTopology*/true);
} }
s.Stop();
//
// Stencils
//
// create vertex primvar data buffer // create vertex primvar data buffer
std::vector<Vertex> vertexBuffer(refiner->GetNumVerticesTotal()); std::vector<Vertex> vertexBuffer(refiner->GetNumVerticesTotal());
Vertex * verts = &vertexBuffer[0]; Vertex * verts = &vertexBuffer[0];
//printf("Vtr time: %f ms (topology)\n", float(s.GetElapsed())*1000.0f);
// copy coarse vertices positions // copy coarse vertices positions
int ncoarseverts = shape->GetNumVertices(); int ncoarseverts = shape->GetNumVertices();
for (int i=0; i<ncoarseverts; ++i) { for (int i=0; i<ncoarseverts; ++i) {
@ -741,6 +730,29 @@ createVtrMesh(Shape * shape, int maxlevel) {
} }
#endif #endif
//
// Patch tables
//
OpenSubdiv::Far::PatchTables * patchTables = 0;
if (g_Adaptive) {
assert(stencilTables);
OpenSubdiv::Far::PatchTablesFactory::Options options;
options.adaptiveStencilTables = stencilTables;
patchTables = OpenSubdiv::Far::PatchTablesFactory::Create(*refiner, options);
g_numPatches = patchTables->GetNumPatchesTotal();
g_maxValence = patchTables->GetMaxValence();
}
s.Stop();
//
// Misc display
//
//printf("Vtr time: %f ms (topology)\n", float(s.GetElapsed())*1000.0f);
if (g_VtrDrawVertIDs) { if (g_VtrDrawVertIDs) {
createVertNumbers(*refiner, vertexBuffer); createVertNumbers(*refiner, vertexBuffer);
} }
@ -758,7 +770,7 @@ createVtrMesh(Shape * shape, int maxlevel) {
} }
if (g_Adaptive and g_drawGregoryBasis) { if (g_Adaptive and g_drawGregoryBasis) {
createGregoryBasis(*refiner, *stencilTables, g_maxValence, vertexBuffer); createGregoryBasis(*patchTables, vertexBuffer);
} }
createEdgeNumbers(*refiner, vertexBuffer, g_VtrDrawEdgeIDs!=0, g_VtrDrawEdgeSharpness!=0); createEdgeNumbers(*refiner, vertexBuffer, g_VtrDrawEdgeIDs!=0, g_VtrDrawEdgeSharpness!=0);