Revisit singular vertex fix for FarSubdivisionTables

The previous fix pointed far indexing tables to the origin vertex
of duped singular verts.

This fix goes one step further and actually shifts all vertex indexing
to start at the end of the coarse mesh vertices, using the space for
data that was previously occupied by duplicated singular verts.

The consequence is that client code no longer needs to duplicate vertex
data in vertex buffers (huzzah !).

- fix FarSubdivisionTablesFactory to shift factory vertex table offsets using Hbr's
  singular verts map
- fix schema table factories (Catmark, Loop...) to correctly use these offsets
- remove vertex data duplication code from osdPolySmooth example
- remove some (unrelated) cruft from glViewer example
- shape_utils unfortunately still needs to dubplicate the singular verts to
  allow the coarse edge drawing in our example viewers to work correctly
  (although it could be fixed to avoid data duplication too...)

fixes #241
This commit is contained in:
manuelk 2013-11-22 11:27:01 -08:00
parent 575d931f2d
commit 000cb400ca
7 changed files with 9 additions and 18 deletions

View File

@ -215,8 +215,7 @@ Stopwatch g_fpsTimer;
// geometry
std::vector<float> g_orgPositions,
g_positions,
g_normals;
g_positions;
Scheme g_scheme;
@ -620,9 +619,7 @@ createOsdMesh( const std::string &shape, int level, int kernel, Scheme scheme=kC
OsdHbrMesh * hmesh = simpleHbr<OpenSubdiv::OsdVertex>(shape.c_str(), scheme, g_orgPositions,
g_displayStyle == kFaceVaryingColor);
g_normals.resize(g_orgPositions.size(),0.0f);
g_positions.resize(g_orgPositions.size(),0.0f);
calcNormals( hmesh, g_orgPositions, g_normals );
// save coarse topology (used for coarse mesh drawing)
g_coarseEdges.clear();

View File

@ -813,13 +813,6 @@ MStatus OsdPolySmooth::compute( const MPlug& plug, MDataBlock& data ) {
float const * vertex3fArray = inMeshFn.getRawPoints(&returnStatus);
vertexBuffer->UpdateData(vertex3fArray, 0, numVertices );
// Hbr dupes singular vertices during Mesh::Finish() - we need
// to duplicate their positions in the vertex buffer.
std::vector<std::pair<int, int> > const splits = hbrMesh->GetSplitVertices();
for (int i=0; i<(int)splits.size(); ++i) {
vertexBuffer->UpdateData(&vertex3fArray[0]+splits[i].second*numVertexElements, splits[i].first, 1);
}
// == Delete HBR
// Can now delete the hbrMesh as we will only be referencing the farMesh from this point on
delete hbrMesh;

View File

@ -101,8 +101,7 @@ FarBilinearSubdivisionTablesFactory<T,U>::Create( FarMeshFactory<T,U> * meshFact
for (int level=1; level<=maxlevel; ++level) {
// pointer to the first vertex corresponding to this level
vertexOffset = tablesFactory._vertVertIdx[level-1] +
(int)tablesFactory._vertVertsList[level-1].size();
vertexOffset = tablesFactory._faceVertIdx[level];
result->_vertsOffsets[level] = vertexOffset;
// Face vertices

View File

@ -110,8 +110,7 @@ FarCatmarkSubdivisionTablesFactory<T,U>::Create( FarMeshFactory<T,U> * meshFacto
for (int level=1; level<=maxlevel; ++level) {
// pointer to the first vertex corresponding to this level
vertexOffset = tablesFactory._vertVertIdx[level-1] +
(int)tablesFactory._vertVertsList[level-1].size();
vertexOffset = tablesFactory._faceVertIdx[level];
result->_vertsOffsets[level] = vertexOffset;
// Face vertices

View File

@ -103,8 +103,7 @@ FarLoopSubdivisionTablesFactory<T,U>::Create( FarMeshFactory<T,U> * meshFactory,
for (int level=1; level<=maxlevel; ++level) {
// pointer to the first vertex corresponding to this level
vertexOffset = tablesFactory._vertVertIdx[level-1] +
(int)tablesFactory._vertVertsList[level-1].size();
vertexOffset = tablesFactory._edgeVertIdx[level];
result->_vertsOffsets[level] = vertexOffset;
// Edge vertices

View File

@ -171,6 +171,9 @@ FarSubdivisionTablesFactory<T,U>::FarSubdivisionTablesFactory( HbrMesh<T> const
}
}
int nsingulars = (int)mesh->GetSplitVertices().size();
vertCounts[0] -= nsingulars;
// Per-level offset to the first vertex of each type in the global vertex map
_vertVertsList[0].reserve( vertCounts[0] );
for (int l=1; l<(maxlevel+1); ++l) {

View File

@ -778,7 +778,8 @@ copyVertexPositions( shape const * sh, OpenSubdiv::HbrMesh<T> * mesh, std::vecto
std::copy(sh->verts.begin(), sh->verts.end(), verts.begin());
// Sometimes Hbr dupes some vertices during Mesh::Finish()
// Sometimes Hbr dupes some vertices during Mesh::Finish() and our example
// code uses those vertices to draw coarse control cages and such
std::vector<std::pair<int, int> > const splits = mesh->GetSplitVertices();
for (int i=0; i<(int)splits.size(); ++i) {
memcpy(&verts[splits[i].first*3], &sh->verts[splits[i].second*3], 3*sizeof(float));