diff --git a/examples/farViewer/farViewer.cpp b/examples/farViewer/farViewer.cpp index ea22f888..542e2a8e 100644 --- a/examples/farViewer/farViewer.cpp +++ b/examples/farViewer/farViewer.cpp @@ -48,8 +48,6 @@ GLFWmonitor* g_primary=0; #include -#include -#include #include #include #include @@ -623,9 +621,9 @@ createFarGLMesh(Shape * shape, int maxlevel) { patchTable = Far::PatchTableFactory::Create(*refiner, options); - // increase vertex buffer for the additional endcap verts - if (patchTable->GetEndCapVertexStencilTable()) { - numTotalVerts += patchTable->GetEndCapVertexStencilTable()->GetNumStencils(); + // increase vertex buffer for the additional local points + if (patchTable->GetLocalPointStencilTable()) { + numTotalVerts += patchTable->GetLocalPointStencilTable()->GetNumStencils(); } g_numPatches = patchTable->GetNumPatchesTotal(); @@ -681,14 +679,14 @@ createFarGLMesh(Shape * shape, int maxlevel) { options.generateIntermediateLevels=true; stencilTable = Far::StencilTableFactory::Create(*refiner, options); - // append endpatch stencils if needed - if (patchTable and patchTable->GetEndCapVertexStencilTable()) { - if (Far::StencilTable const * stencilTableWithEndCap = - Far::StencilTableFactory::AppendEndCapStencilTable( + // append local point stencils if needed + if (patchTable and patchTable->GetLocalPointStencilTable()) { + if (Far::StencilTable const * stencilTableWithLocalPoints = + Far::StencilTableFactory::AppendLocalPointStencilTable( *refiner, stencilTable, - patchTable->GetEndCapVertexStencilTable())) { + patchTable->GetLocalPointStencilTable())) { delete stencilTable; - stencilTable = stencilTableWithEndCap; + stencilTable = stencilTableWithLocalPoints; } } diff --git a/examples/glEvalLimit/glEvalLimit.cpp b/examples/glEvalLimit/glEvalLimit.cpp index 87962c8a..5ab76c0c 100644 --- a/examples/glEvalLimit/glEvalLimit.cpp +++ b/examples/glEvalLimit/glEvalLimit.cpp @@ -87,8 +87,6 @@ GLFWmonitor* g_primary=0; #include #endif -#include -#include #include #include #include @@ -571,22 +569,21 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level) { Far::PatchTable const * patchTable = Far::PatchTableFactory::Create(*topologyRefiner, poptions); - // append endcap stencils - if (Far::StencilTable const *endCapVertexStencilTable = - patchTable->GetEndCapVertexStencilTable()) { + // append local points stencils + if (Far::StencilTable const *localPointStencilTable = + patchTable->GetLocalPointStencilTable()) { Far::StencilTable const *table = - Far::StencilTableFactory::AppendEndCapStencilTable( - *topologyRefiner, - vertexStencils, endCapVertexStencilTable); + Far::StencilTableFactory::AppendLocalPointStencilTable( + *topologyRefiner, vertexStencils, localPointStencilTable); delete vertexStencils; vertexStencils = table; } - if (Far::StencilTable const *endCapVaryingStencilTable = - patchTable->GetEndCapVaryingStencilTable()) { + if (Far::StencilTable const *localPointVaryingStencilTable = + patchTable->GetLocalPointVaryingStencilTable()) { Far::StencilTable const *table = - Far::StencilTableFactory::AppendEndCapStencilTable( + Far::StencilTableFactory::AppendLocalPointStencilTable( *topologyRefiner, - varyingStencils, endCapVaryingStencilTable); + varyingStencils, localPointVaryingStencilTable); delete varyingStencils; varyingStencils = table; } diff --git a/examples/glShareTopology/sceneBase.cpp b/examples/glShareTopology/sceneBase.cpp index 12d5678b..af1bebcf 100644 --- a/examples/glShareTopology/sceneBase.cpp +++ b/examples/glShareTopology/sceneBase.cpp @@ -144,24 +144,24 @@ SceneBase::createStencilTable(Shape const *shape, int level, bool varying, } *patchTableOut = patchTable; - // append gregory vertices into stencils + // append local points to stencils { - if (Far::StencilTable const *vertexStencilsWithEndCap = - Far::StencilTableFactory::AppendEndCapStencilTable( + if (Far::StencilTable const *vertexStencilsWithLocalPoints = + Far::StencilTableFactory::AppendLocalPointStencilTable( *refiner, vertexStencils, - patchTable->GetEndCapVertexStencilTable())) { + patchTable->GetLocalPointStencilTable())) { delete vertexStencils; - vertexStencils = vertexStencilsWithEndCap; + vertexStencils = vertexStencilsWithLocalPoints; } if (varyingStencils) { - if (Far::StencilTable const *varyingStencilsWithEndCap = - Far::StencilTableFactory::AppendEndCapStencilTable( + if (Far::StencilTable const *varyingStencilsWithLocalPoints = + Far::StencilTableFactory::AppendLocalPointStencilTable( *refiner, varyingStencils, - patchTable->GetEndCapVaryingStencilTable())) { + patchTable->GetLocalPointVaryingStencilTable())) { delete varyingStencils; - varyingStencils = varyingStencilsWithEndCap; + varyingStencils = varyingStencilsWithLocalPoints; } } } diff --git a/opensubdiv/far/CMakeLists.txt b/opensubdiv/far/CMakeLists.txt index 18604d0f..b1770e1e 100644 --- a/opensubdiv/far/CMakeLists.txt +++ b/opensubdiv/far/CMakeLists.txt @@ -44,16 +44,16 @@ set(SOURCE_FILES ) set(PRIVATE_HEADER_FILES + gregoryBasis.h + endCapBSplineBasisPatchFactory.h + endCapGregoryBasisPatchFactory.h + endCapLegacyGregoryPatchFactory.h + patchBasis.h stencilBuilder.h ) set(PUBLIC_HEADER_FILES error.h - endCapBSplineBasisPatchFactory.h - endCapGregoryBasisPatchFactory.h - endCapLegacyGregoryPatchFactory.h - gregoryBasis.h - patchBasis.h patchDescriptor.h patchParam.h patchMap.h @@ -69,8 +69,6 @@ set(PUBLIC_HEADER_FILES types.h ) -set(PRIVATE_HEADER_FILES ) - set(DOXY_HEADER_FILES ${PUBLIC_HEADER_FILES}) #------------------------------------------------------------------------------- diff --git a/opensubdiv/far/endCapBSplineBasisPatchFactory.cpp b/opensubdiv/far/endCapBSplineBasisPatchFactory.cpp index 060bbb06..e90414c3 100644 --- a/opensubdiv/far/endCapBSplineBasisPatchFactory.cpp +++ b/opensubdiv/far/endCapBSplineBasisPatchFactory.cpp @@ -44,7 +44,9 @@ EndCapBSplineBasisPatchFactory::EndCapBSplineBasisPatchFactory( ConstIndexArray EndCapBSplineBasisPatchFactory::GetPatchPoints( - Vtr::internal::Level const * level, Index faceIndex) { + Vtr::internal::Level const * level, Index faceIndex, + PatchTableFactory::PatchFaceTag const * /*levelPatchTags*/, + int levelVertOffset) { // XXX: For now, always create new 16 indices for each patch. // we'll optimize later to share all regular control points with @@ -60,7 +62,7 @@ EndCapBSplineBasisPatchFactory::GetPatchPoints( // vertices if available // // Reorder gregory basis stencils into regular bezier - GregoryBasis::ProtoBasis basis(*level, faceIndex); + GregoryBasis::ProtoBasis basis(*level, faceIndex, levelVertOffset, -1); std::vector bezierCP; bezierCP.reserve(16); diff --git a/opensubdiv/far/endCapBSplineBasisPatchFactory.h b/opensubdiv/far/endCapBSplineBasisPatchFactory.h index 2c67dad1..9f54a190 100644 --- a/opensubdiv/far/endCapBSplineBasisPatchFactory.h +++ b/opensubdiv/far/endCapBSplineBasisPatchFactory.h @@ -66,8 +66,14 @@ public: /// /// @param faceIndex vtr faceIndex at the level /// + /// @param levelPatchTags Array of patchTags for all faces in the level + /// + /// @param levelVertOffset relative offset of patch vertex indices + /// ConstIndexArray GetPatchPoints( - Vtr::internal::Level const * level, Index faceIndex); + Vtr::internal::Level const * level, Index faceIndex, + PatchTableFactory::PatchFaceTag const * levelPatchTags, + int levelVertOffset); /// \brief Create a StencilTable for end patch points, relative to the max /// subdivision level. diff --git a/opensubdiv/far/endCapGregoryBasisPatchFactory.cpp b/opensubdiv/far/endCapGregoryBasisPatchFactory.cpp index 93a6c9c0..dab51902 100644 --- a/opensubdiv/far/endCapGregoryBasisPatchFactory.cpp +++ b/opensubdiv/far/endCapGregoryBasisPatchFactory.cpp @@ -59,7 +59,7 @@ EndCapGregoryBasisPatchFactory::Create(TopologyRefiner const & refiner, // Gregory patches are end-caps: they only exist on max-level Vtr::internal::Level const & level = refiner.getLevel(refiner.GetMaxLevel()); - GregoryBasis::ProtoBasis basis(level, faceIndex, fvarChannel); + GregoryBasis::ProtoBasis basis(level, faceIndex, 0, fvarChannel); GregoryBasis * result = new GregoryBasis; basis.Copy(result); @@ -69,14 +69,15 @@ EndCapGregoryBasisPatchFactory::Create(TopologyRefiner const & refiner, bool EndCapGregoryBasisPatchFactory::addPatchBasis(Index faceIndex, - bool verticesMask[4][5]) { + bool verticesMask[4][5], + int levelVertOffset) { // Gregory patches only exist on the hight Vtr::internal::Level const & level = _refiner->getLevel(_refiner->GetMaxLevel()); // Gather the CVs that influence the Gregory patch and their relative // weights in a basis - GregoryBasis::ProtoBasis basis(level, faceIndex); + GregoryBasis::ProtoBasis basis(level, faceIndex, levelVertOffset, -1); for (int i = 0; i < 4; ++i) { if (verticesMask[i][0]) { @@ -112,8 +113,8 @@ EndCapGregoryBasisPatchFactory::addPatchBasis(Index faceIndex, ConstIndexArray EndCapGregoryBasisPatchFactory::GetPatchPoints( Vtr::internal::Level const * level, Index faceIndex, - PatchTableFactory::PatchFaceTag const * levelPatchTags) -{ + PatchTableFactory::PatchFaceTag const * levelPatchTags, + int levelVertOffset) { // allocate indices (awkward) // assert(Vtr::INDEX_INVALID==0xFFFFFFFF); for (int i = 0; i < 20; ++i) { @@ -208,7 +209,7 @@ EndCapGregoryBasisPatchFactory::GetPatchPoints( _faceIndices.push_back(faceIndex); // add basis - addPatchBasis(faceIndex, newVerticesMask); + addPatchBasis(faceIndex, newVerticesMask, levelVertOffset); ++_numGregoryBasisPatches; diff --git a/opensubdiv/far/endCapGregoryBasisPatchFactory.h b/opensubdiv/far/endCapGregoryBasisPatchFactory.h index f204fd3e..6fd87679 100644 --- a/opensubdiv/far/endCapGregoryBasisPatchFactory.h +++ b/opensubdiv/far/endCapGregoryBasisPatchFactory.h @@ -92,9 +92,12 @@ public: /// /// @param levelPatchTags Array of patchTags for all faces in the level /// + /// @param levelVertOffset relative offset of patch vertex indices + /// ConstIndexArray GetPatchPoints( Vtr::internal::Level const * level, Index faceIndex, - PatchTableFactory::PatchFaceTag const * levelPatchTags); + PatchTableFactory::PatchFaceTag const * levelPatchTags, + int levelVertOffset); /// \brief Create a StencilTable for end patch points, relative to the max /// subdivision level. @@ -115,7 +118,8 @@ private: /// Creates a basis for the vertices specified in mask on the face and /// accumates it - bool addPatchBasis(Index faceIndex, bool newVerticesMask[4][5]); + bool addPatchBasis(Index faceIndex, bool newVerticesMask[4][5], + int levelVertOffset); GregoryBasis::PointsVector _vertexStencils; GregoryBasis::PointsVector _varyingStencils; diff --git a/opensubdiv/far/gregoryBasis.cpp b/opensubdiv/far/gregoryBasis.cpp index 69727bbb..1484909d 100644 --- a/opensubdiv/far/gregoryBasis.cpp +++ b/opensubdiv/far/gregoryBasis.cpp @@ -150,7 +150,8 @@ inline float computeCoefficient(int valence) { } GregoryBasis::ProtoBasis::ProtoBasis( - Vtr::internal::Level const & level, Index faceIndex, int fvarChannel) { + Vtr::internal::Level const & level, Index faceIndex, + int levelVertOffset, int fvarChannel) { Vtr::ConstIndexArray facePoints = (fvarChannel<0) ? level.getFaceVertices(faceIndex) : @@ -389,6 +390,19 @@ GregoryBasis::ProtoBasis::ProtoBasis( Fp[vid] = Fm[vid] = (org[vid]*4.0f + org[((vid+2)%n)] + org[ip]*2.0f + org[im]*2.0f)/9.0f; } } + + // offset stencil indices. + // These stencils are created relative to the level. Adding levelVertOffset, + // we get stencils with absolute indices + // (starts from the coarse level if the leveVertOffset includes level 0) + for (int i = 0; i < 4; ++i) { + P[i].OffsetIndices(levelVertOffset); + Ep[i].OffsetIndices(levelVertOffset); + Em[i].OffsetIndices(levelVertOffset); + Fp[i].OffsetIndices(levelVertOffset); + Fm[i].OffsetIndices(levelVertOffset); + V[i].OffsetIndices(levelVertOffset); + } } /*static*/ diff --git a/opensubdiv/far/gregoryBasis.h b/opensubdiv/far/gregoryBasis.h index 6e90fa3e..deff764c 100644 --- a/opensubdiv/far/gregoryBasis.h +++ b/opensubdiv/far/gregoryBasis.h @@ -202,7 +202,10 @@ public: // struct ProtoBasis { - ProtoBasis(Vtr::internal::Level const & level, Vtr::Index faceIndex, int fvarChannel=-1); + ProtoBasis(Vtr::internal::Level const & level, + Vtr::Index faceIndex, + int levelVertOffset, + int fvarChannel); int GetNumElements() const; diff --git a/opensubdiv/far/patchTable.cpp b/opensubdiv/far/patchTable.cpp index 84f13f80..31e40e21 100644 --- a/opensubdiv/far/patchTable.cpp +++ b/opensubdiv/far/patchTable.cpp @@ -35,8 +35,8 @@ namespace Far { PatchTable::PatchTable(int maxvalence) : _maxValence(maxvalence), - _vertexStencilTable(NULL), - _varyingStencilTable(NULL) { + _localPointStencils(NULL), + _localPointVaryingStencils(NULL) { } // Copy constructor @@ -49,23 +49,25 @@ PatchTable::PatchTable(PatchTable const & src) : _paramTable(src._paramTable), _quadOffsetsTable(src._quadOffsetsTable), _vertexValenceTable(src._vertexValenceTable), - _vertexStencilTable(NULL), - _varyingStencilTable(NULL), + _localPointStencils(NULL), + _localPointVaryingStencils(NULL), _fvarChannels(src._fvarChannels), _sharpnessIndices(src._sharpnessIndices), _sharpnessValues(src._sharpnessValues) { - if (src._vertexStencilTable) { - _vertexStencilTable = new StencilTable(*src._vertexStencilTable); + if (src._localPointStencils) { + _localPointStencils = + new StencilTable(*src._localPointStencils); } - if (src._varyingStencilTable) { - _varyingStencilTable = new StencilTable(*src._varyingStencilTable); + if (src._localPointVaryingStencils) { + _localPointVaryingStencils = + new StencilTable(*src._localPointVaryingStencils); } } PatchTable::~PatchTable() { - delete _vertexStencilTable; - delete _varyingStencilTable; + delete _localPointStencils; + delete _localPointVaryingStencils; } // @@ -396,6 +398,11 @@ PatchTable::GetSingleCreasePatchSharpnessValue(int arrayIndex, int patchIndex) c return _sharpnessValues[index]; } +int +PatchTable::GetNumLocalPoints() const { + return _localPointStencils ? _localPointStencils->GetNumStencils() : 0; +} + PatchTable::ConstQuadOffsetsArray PatchTable::GetPatchQuadOffsets(PatchHandle const & handle) const { PatchArray const & pa = getPatchArray(handle.arrayIndex); @@ -529,6 +536,7 @@ PatchTable::EvaluateBasis(PatchHandle const & handle, float s, float t, } } + } // end namespace Far } // end namespace OPENSUBDIV_VERSION diff --git a/opensubdiv/far/patchTable.h b/opensubdiv/far/patchTable.h index b153767f..eadef275 100644 --- a/opensubdiv/far/patchTable.h +++ b/opensubdiv/far/patchTable.h @@ -153,13 +153,47 @@ public: //@{ - /// @name End-Cap patches + /// @name change of basis patches /// - /// \anchor end_cap_patches + /// \anchor change_of_basis_patches + /// + /// \brief Accessors for change of basis patch points /// - /// \brief Accessors for end-cap patch additional data /// + /// \brief Returns the number of points of the change of basis patches. + int GetNumLocalPoints() const; + + /// \brief Updates local point values based on the refined values + /// + /// @param src Buffer with primvar data for the control vertices + /// and refined vertices + /// + /// @param dst Destination buffer for the computed local points + /// + /// + template void + ComputeLocalPointValues(T const *src, T *dst) const; + + /// \brief Returns the stencil table to get change of basis patch points. + StencilTable const *GetLocalPointStencilTable() const { + return _localPointStencils; + } + + /// \brief Returns the varying stencil table for the change of basis patch + /// points. + StencilTable const *GetLocalPointVaryingStencilTable() const { + return _localPointVaryingStencils; + } + //@} + + + //@{ + /// @name Legacy gregory patch evaluation buffers + + /// \brief Accessors for the gregory patch evaluation buffers. + /// These methods will be deprecated. + /// typedef Vtr::ConstArray ConstQuadOffsetsArray; /// \brief Returns the 'QuadOffsets' for the Gregory patch identified by 'handle' @@ -171,19 +205,6 @@ public: VertexValenceTable const & GetVertexValenceTable() const { return _vertexValenceTable; } - - /// \brief Returns the basis conversion stencil table to get endcap patch points. - /// This stencil is relative to the max level refined vertices. - StencilTable const *GetEndCapVertexStencilTable() const { - return _vertexStencilTable; - } - - /// \brief Returns the varying stencil table for the endcap patches - /// which has same ordering as the endcap vertex stencil table. - StencilTable const *GetEndCapVaryingStencilTable() const { - return _varyingStencilTable; - } - //@} @@ -386,8 +407,8 @@ private: // QuadOffsetsTable _quadOffsetsTable; // Quad offsets (for Gregory patches) VertexValenceTable _vertexValenceTable; // Vertex valence table (for Gregory patches) - StencilTable const * _vertexStencilTable; // endcap basis conversion stencils - StencilTable const * _varyingStencilTable; // endcap varying stencils (for convenience) + StencilTable const * _localPointStencils; // endcap basis conversion stencils + StencilTable const * _localPointVaryingStencils; // endcap varying stencils (for convenience) // // Face-varying data @@ -403,6 +424,15 @@ private: std::vector _sharpnessValues; // Sharpness values. }; +template +inline void +PatchTable::ComputeLocalPointValues(T const *src, T *dst) const { + if (_localPointStencils) { + _localPointStencils->UpdateValues(src, dst); + } +}; + + } // end namespace Far } // end namespace OPENSUBDIV_VERSION diff --git a/opensubdiv/far/patchTableFactory.cpp b/opensubdiv/far/patchTableFactory.cpp index 87f49238..f758dd74 100644 --- a/opensubdiv/far/patchTableFactory.cpp +++ b/opensubdiv/far/patchTableFactory.cpp @@ -1410,7 +1410,7 @@ PatchTableFactory::populateAdaptivePatches( { // note: this call will be moved into vtr::level. ConstIndexArray cvs = endCapGregoryBasis->GetPatchPoints( - level, faceIndex, levelPatchTags); + level, faceIndex, levelPatchTags, levelVertOffset); for (int j = 0; j < cvs.size(); ++j) iptrs.GP[j] = cvs[j]; iptrs.GP += cvs.size(); @@ -1425,7 +1425,7 @@ PatchTableFactory::populateAdaptivePatches( case Options::ENDCAP_BSPLINE_BASIS: { ConstIndexArray cvs = endCapBSpline->GetPatchPoints( - level, faceIndex); + level, faceIndex, levelPatchTags, levelVertOffset); for (int j = 0; j < cvs.size(); ++j) iptrs.R[j] = cvs[j]; iptrs.R += cvs.size(); @@ -1486,16 +1486,16 @@ PatchTableFactory::populateAdaptivePatches( // finalize end patches switch(context.options.GetEndCapType()) { case Options::ENDCAP_GREGORY_BASIS: - table->_vertexStencilTable = + table->_localPointStencils = endCapGregoryBasis->CreateVertexStencilTable(); - table->_varyingStencilTable = + table->_localPointVaryingStencils = endCapGregoryBasis->CreateVaryingStencilTable(); delete endCapGregoryBasis; break; case Options::ENDCAP_BSPLINE_BASIS: - table->_vertexStencilTable = + table->_localPointStencils = endCapBSpline->CreateVertexStencilTable(); - table->_varyingStencilTable = + table->_localPointVaryingStencils = endCapBSpline->CreateVaryingStencilTable(); delete endCapBSpline; break; diff --git a/opensubdiv/far/stencilTableFactory.cpp b/opensubdiv/far/stencilTableFactory.cpp index 919f9d3d..8d5a532f 100644 --- a/opensubdiv/far/stencilTableFactory.cpp +++ b/opensubdiv/far/stencilTableFactory.cpp @@ -181,29 +181,23 @@ StencilTableFactory::Create(int numTables, StencilTable const ** tables) { //------------------------------------------------------------------------------ StencilTable const * -StencilTableFactory::AppendEndCapStencilTable( +StencilTableFactory::AppendLocalPointStencilTable( TopologyRefiner const &refiner, StencilTable const * baseStencilTable, - StencilTable const * endCapStencilTable, + StencilTable const * localPointStencilTable, bool factorize) { // factorize and append. if (baseStencilTable == NULL or - endCapStencilTable == NULL) return NULL; + localPointStencilTable == NULL) return NULL; - // endcap stencils have indices that are relative to the level - // (maxlevel) of subdivision. These indices need to be offset to match - // the indices from the multi-level adaptive stencil table. - // In addition: stencil table can be built with singular stencils - // (single weight of 1.0f) as place-holders for coarse mesh vertices, - // which also needs to be accounted for. + // baseStencilTable can be built with or without singular stencils + // (single weight of 1.0f) as place-holders for coarse mesh vertices. - int stencilsIndexOffset = 0; int controlVertsIndexOffset = 0; int nBaseStencils = baseStencilTable->GetNumStencils(); int nBaseStencilsElements = (int)baseStencilTable->_indices.size(); { - int maxlevel = refiner.GetMaxLevel(); int nverts = refiner.GetNumVerticesTotal(); if (nBaseStencils == nverts) { @@ -212,18 +206,15 @@ StencilTableFactory::AppendEndCapStencilTable( // <----------------- nverts ------------------> // // +---------------+----------------------------+-----------------+ - // | control verts | refined verts : (max lv) | endcap points | + // | control verts | refined verts : (max lv) | local points | // +---------------+----------------------------+-----------------+ - // | base stencil table | endcap stencils | + // | base stencil table | LP stencils | // +--------------------------------------------+-----------------+ - // : ^ / - // : \_________/ - // <--------------------------------> - // stencilsIndexOffset + // ^ / + // \_________________________/ // // - stencilsIndexOffset = nverts - refiner.GetLevel(maxlevel).GetNumVertices(); - controlVertsIndexOffset = stencilsIndexOffset; + controlVertsIndexOffset = 0; } else if (nBaseStencils == (nverts -refiner.GetLevel(0).GetNumVertices())) { @@ -232,19 +223,16 @@ StencilTableFactory::AppendEndCapStencilTable( // <----------------- nverts ------------------> // <------ nBaseStencils -------> // +---------------+----------------------------+-----------------+ - // | control verts | refined verts : (max lv) | endcap points | + // | control verts | refined verts : (max lv) | local points | // +---------------+----------------------------+-----------------+ - // | base stencil table | endcap stencils | + // | base stencil table | LP stencils | // +----------------------------+-----------------+ - // : ^ / - // : \_________/ - // <----------------> - // stencilsIndexOffset - // <--------------------------------> - // controlVertsIndexOffset + // ^ / + // \_________________/ + // <--------------> + // controlVertsIndexOffset // - stencilsIndexOffset = nBaseStencils - refiner.GetLevel(maxlevel).GetNumVertices(); - controlVertsIndexOffset = nverts - refiner.GetLevel(maxlevel).GetNumVertices(); + controlVertsIndexOffset = refiner.GetLevel(0).GetNumVertices(); } else { // these are not the stencils you are looking for. @@ -252,10 +240,10 @@ StencilTableFactory::AppendEndCapStencilTable( return NULL; } } - - // copy all endcap stencils to proto stencils, and factorize if needed. - int nEndCapStencils = endCapStencilTable->GetNumStencils(); - int nEndCapStencilsElements = 0; + + // copy all local points stencils to proto stencils, and factoriz if needed. + int nLocalPointStencils = localPointStencilTable->GetNumStencils(); + int nLocalPointStencilsElements = 0; internal::StencilBuilder builder(refiner.GetLevel(0).GetNumVertices(), /*genControlVerts*/ false, @@ -264,8 +252,8 @@ StencilTableFactory::AppendEndCapStencilTable( internal::StencilBuilder::Index dst = origin; internal::StencilBuilder::Index srcIdx = origin; - for (int i = 0 ; i < nEndCapStencils; ++i) { - Stencil src = endCapStencilTable->GetStencil(i); + for (int i = 0 ; i < nLocalPointStencils; ++i) { + Stencil src = localPointStencilTable->GetStencil(i); dst = origin[i]; for (int j = 0; j < src.GetSize(); ++j) { Index index = src.GetVertexIndices()[j]; @@ -274,21 +262,25 @@ StencilTableFactory::AppendEndCapStencilTable( if (factorize) { dst.AddWithWeight( - baseStencilTable->GetStencil(index+stencilsIndexOffset), + // subtracting controlVertsIndex if the baseStencil doesn't + // include control vertices (see above diagram) + // since currently local point stencils are created with + // absolute indices including control (level=0) vertices. + baseStencilTable->GetStencil(index - controlVertsIndexOffset), weight); } else { srcIdx = origin[index + controlVertsIndexOffset]; dst.AddWithWeight(srcIdx, weight); } } - nEndCapStencilsElements += builder.GetNumVertsInStencil(i); + nLocalPointStencilsElements += builder.GetNumVertsInStencil(i); } // create new stencil table StencilTable * result = new StencilTable; result->_numControlVertices = refiner.GetLevel(0).GetNumVertices(); - result->resize(nBaseStencils + nEndCapStencils, - nBaseStencilsElements + nEndCapStencilsElements); + result->resize(nBaseStencils + nLocalPointStencils, + nBaseStencilsElements + nLocalPointStencilsElements); int* sizes = &result->_sizes[0]; Index * indices = &result->_indices[0]; @@ -307,7 +299,7 @@ StencilTableFactory::AppendEndCapStencilTable( weights += nBaseStencilsElements; // endcap stencils second - for (int i = 0 ; i < nEndCapStencils; ++i) { + for (int i = 0 ; i < nLocalPointStencils; ++i) { int size = builder.GetNumVertsInStencil(i); int idx = builder.GetStencilOffsets()[i]; for (int j = 0; j < size; ++j) { @@ -385,11 +377,11 @@ LimitStencilTableFactory::Create(TopologyRefiner const & refiner, if (not cvStencilsIn) { // if cvstencils is just created above, append endcap stencils - if (StencilTable const *endCapStencilTable = - patchtable->GetEndCapVertexStencilTable()) { + if (StencilTable const *localPointStencilTable = + patchtable->GetLocalPointStencilTable()) { StencilTable const *table = - StencilTableFactory::AppendEndCapStencilTable( - refiner, cvstencils, endCapStencilTable); + StencilTableFactory::AppendLocalPointStencilTable( + refiner, cvstencils, localPointStencilTable); delete cvstencils; cvstencils = table; } diff --git a/opensubdiv/far/stencilTableFactory.h b/opensubdiv/far/stencilTableFactory.h index d7544c58..98dedcfc 100644 --- a/opensubdiv/far/stencilTableFactory.h +++ b/opensubdiv/far/stencilTableFactory.h @@ -103,24 +103,24 @@ public: static StencilTable const * Create(int numTables, StencilTable const ** tables); - /// \brief Utility function for stencil splicing for endcap stencils. + /// \brief Utility function for stencil splicing for local point stencils. /// /// @param refiner The TopologyRefiner containing the topology /// /// @param baseStencilTable Input StencilTable for refined vertices /// - /// @param endCapStencilTable EndCap basis conversion stencils. This stenciltable - /// has to be relative to the max level of subdivision. + /// @param localPointStencilTable + /// StencilTable for the change of basis patch points. /// /// @param factorize If factorize sets to true, endcap stencils will be /// factorized with supporting vertices from baseStencil /// table so that the endcap points can be computed /// directly from control vertices. /// - static StencilTable const * AppendEndCapStencilTable( + static StencilTable const * AppendLocalPointStencilTable( TopologyRefiner const &refiner, StencilTable const *baseStencilTable, - StencilTable const *endCapStencilTable, + StencilTable const *localPointStencilTable, bool factorize = true); private: diff --git a/opensubdiv/osd/mesh.h b/opensubdiv/osd/mesh.h index 8a36a073..671b67e8 100644 --- a/opensubdiv/osd/mesh.h +++ b/opensubdiv/osd/mesh.h @@ -527,24 +527,24 @@ private: _farPatchTable = Far::PatchTableFactory::Create(*_refiner, poptions); // if there's endcap stencils, merge it into regular stencils. - if (_farPatchTable->GetEndCapVertexStencilTable()) { + if (_farPatchTable->GetLocalPointStencilTable()) { // append stencils - if (Far::StencilTable const *vertexStencilsWithEndCap = - Far::StencilTableFactory::AppendEndCapStencilTable( + if (Far::StencilTable const *vertexStencilsWithLocalPoints = + Far::StencilTableFactory::AppendLocalPointStencilTable( *_refiner, vertexStencils, - _farPatchTable->GetEndCapVertexStencilTable())) { + _farPatchTable->GetLocalPointStencilTable())) { delete vertexStencils; - vertexStencils = vertexStencilsWithEndCap; + vertexStencils = vertexStencilsWithLocalPoints; } if (varyingStencils) { - if (Far::StencilTable const *varyingStencilsWithEndCap = - Far::StencilTableFactory::AppendEndCapStencilTable( + if (Far::StencilTable const *varyingStencilsWithLocalPoints = + Far::StencilTableFactory::AppendLocalPointStencilTable( *_refiner, varyingStencils, - _farPatchTable->GetEndCapVaryingStencilTable())) { + _farPatchTable->GetLocalPointVaryingStencilTable())) { delete varyingStencils; - varyingStencils = varyingStencilsWithEndCap; + varyingStencils = varyingStencilsWithLocalPoints; } } } diff --git a/tutorials/far/tutorial_6/far_tutorial_6.cpp b/tutorials/far/tutorial_6/far_tutorial_6.cpp index a5cbfd01..9e018f93 100644 --- a/tutorials/far/tutorial_6/far_tutorial_6.cpp +++ b/tutorials/far/tutorial_6/far_tutorial_6.cpp @@ -155,29 +155,22 @@ int main(int, char **) { Far::PatchTable const * patchTable = Far::PatchTableFactory::Create(*refiner, patchOptions); - // In this example, we use Gregory basis patch for endcaps. - Far::StencilTable const *endCapStencils = - patchTable->GetEndCapVertexStencilTable(); - int nEndCapPoints = endCapStencils ? endCapStencils->GetNumStencils() : 0; + // Compute the total number of points we need to evaluate patchtable. + // we use local points around extraordinary features. int nRefinerVertices = refiner->GetNumVerticesTotal(); + int nLocalPoints = patchTable->GetNumLocalPoints(); // Create a buffer to hold the position of the refined verts and - // endcap points, and copy the coarse positions. - std::vector verts(nRefinerVertices + nEndCapPoints); + // local points, then copy the coarse positions at the beginning. + std::vector verts(nRefinerVertices + nLocalPoints); memcpy(&verts[0], g_verts, g_nverts*3*sizeof(float)); // Interpolate vertex primvar data : they are the control vertices // of the limit patches (see far_tutorial_0 for details) Far::PrimvarRefiner(*refiner).Interpolate(&verts[0], &verts[g_nverts]); - // Evaluate endcaps from interpolated vertex primvars. - if (endCapStencils) { - int maxLevelVertsIndex = nRefinerVertices - - refiner->GetLevel(refiner->GetMaxLevel()).GetNumVertices(); - - endCapStencils->UpdateValues(&verts[maxLevelVertsIndex], - &verts[nRefinerVertices]); - } + // Evaluate local points from interpolated vertex primvars. + patchTable->ComputeLocalPointValues(&verts[0], &verts[nRefinerVertices]); // Create a Far::PatchMap to help locating patches in the table Far::PatchMap patchmap(*patchTable);