Add Far::PatchTable::ComputeLocalPointValues() to compute endcap patch points.

To encapsulate endcap functions from public API, add methods to
tell the number of patch points needed (GetNumLocalPoints()) and
to compute those patch points as a result of change of basis from
the refined vertices (ComputeLocalPointValues()).

ComputeLocalPointValues takes contiguous source data of all levels
including level0 control vertices.
This commit is contained in:
Takahito Tejima 2015-05-29 12:41:11 -07:00
parent 7e82df37b2
commit 4e807a776d
16 changed files with 199 additions and 147 deletions

View File

@ -621,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();
@ -679,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;
}
}

View File

@ -569,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;
}

View File

@ -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;
}
}
}

View File

@ -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<GregoryBasis::Point> bezierCP;
bezierCP.reserve(16);

View File

@ -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.

View File

@ -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;

View File

@ -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;

View File

@ -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*/

View File

@ -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;

View File

@ -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

View File

@ -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 <class T> 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<unsigned int> 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<float> _sharpnessValues; // Sharpness values.
};
template <class T>
inline void
PatchTable::ComputeLocalPointValues(T const *src, T *dst) const {
if (_localPointStencils) {
_localPointStencils->UpdateValues(src, dst);
}
};
} // end namespace Far
} // end namespace OPENSUBDIV_VERSION

View File

@ -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;

View File

@ -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.
@ -253,9 +241,9 @@ StencilTableFactory::AppendEndCapStencilTable(
}
}
// 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;
}

View File

@ -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:

View File

@ -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;
}
}
}

View File

@ -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<Vertex> verts(nRefinerVertices + nEndCapPoints);
// local points, then copy the coarse positions at the beginning.
std::vector<Vertex> 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);