mirror of
https://github.com/PixarAnimationStudios/OpenSubdiv
synced 2024-12-23 08:20:06 +00:00
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:
parent
7e82df37b2
commit
4e807a776d
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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*/
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user