Merge pull request #830 from davidgyu/patch_table_fvarendcaps

Updated Far::EndCap*PatchFactory for fvar patches
This commit is contained in:
barfowl 2016-08-05 19:21:09 -07:00 committed by GitHub
commit 421afbc6e8
7 changed files with 117 additions and 99 deletions

View File

@ -70,15 +70,17 @@ EndCapBSplineBasisPatchFactory::EndCapBSplineBasisPatchFactory(
int numStencilsExpected = std::min(numPatchPointsExpected * 16, int numStencilsExpected = std::min(numPatchPointsExpected * 16,
100*1024*1024); 100*1024*1024);
_vertexStencils->reserve(numPatchPointsExpected, numStencilsExpected); _vertexStencils->reserve(numPatchPointsExpected, numStencilsExpected);
// varying stencils use only 1 index with weight=1.0 if (_varyingStencils) {
_varyingStencils->reserve(numPatchPointsExpected, numPatchPointsExpected); // varying stencils use only 1 index with weight=1.0
_varyingStencils->reserve(numPatchPointsExpected, numPatchPointsExpected);
}
} }
ConstIndexArray ConstIndexArray
EndCapBSplineBasisPatchFactory::GetPatchPoints( EndCapBSplineBasisPatchFactory::GetPatchPoints(
Vtr::internal::Level const * level, Index thisFace, Vtr::internal::Level const * level, Index thisFace,
Vtr::internal::Level::VSpan const cornerSpans[], Vtr::internal::Level::VSpan const cornerSpans[],
int levelVertOffset) { int levelVertOffset, int fvarChannel) {
// //
// We can only use a faster method directly with B-Splines when we have a // We can only use a faster method directly with B-Splines when we have a
@ -113,10 +115,12 @@ EndCapBSplineBasisPatchFactory::GetPatchPoints(
if (useGregoryPatch) { if (useGregoryPatch) {
return getPatchPointsFromGregoryBasis( return getPatchPointsFromGregoryBasis(
level, thisFace, cornerSpans, facePoints, levelVertOffset); level, thisFace, cornerSpans, facePoints,
levelVertOffset, fvarChannel);
} else { } else {
return getPatchPoints( return getPatchPoints(
level, thisFace, irregCornerIndex, facePoints, levelVertOffset); level, thisFace, irregCornerIndex, facePoints,
levelVertOffset, fvarChannel);
} }
} }
@ -124,18 +128,20 @@ ConstIndexArray
EndCapBSplineBasisPatchFactory::getPatchPointsFromGregoryBasis( EndCapBSplineBasisPatchFactory::getPatchPointsFromGregoryBasis(
Vtr::internal::Level const * level, Index thisFace, Vtr::internal::Level const * level, Index thisFace,
Vtr::internal::Level::VSpan const cornerSpans[], Vtr::internal::Level::VSpan const cornerSpans[],
ConstIndexArray facePoints, int levelVertOffset) { ConstIndexArray facePoints, int levelVertOffset, int fvarChannel) {
// XXX: For now, always create new 16 indices for each patch. // XXX: For now, always create new 16 indices for each patch.
// we'll optimize later to share all regular control points with // we'll optimize later to share all regular control points with
// other patches as well as to try to make extra ordinary verts watertight. // other patches as well as to try to make extra ordinary verts watertight.
int offset = _refiner->GetNumVerticesTotal(); int offset = (fvarChannel < 0)
? _refiner->GetNumVerticesTotal()
: _refiner->GetNumFVarValuesTotal(fvarChannel);
for (int i = 0; i < 16; ++i) { for (int i = 0; i < 16; ++i) {
_patchPoints.push_back(_numVertices + offset); _patchPoints.push_back(_numVertices + offset);
++_numVertices; ++_numVertices;
} }
GregoryBasis::ProtoBasis basis(*level, thisFace, cornerSpans, levelVertOffset, -1); GregoryBasis::ProtoBasis basis(*level, thisFace, cornerSpans, levelVertOffset, fvarChannel);
// XXX: temporary hack. we should traverse topology and find existing // XXX: temporary hack. we should traverse topology and find existing
// vertices if available // vertices if available
// //
@ -192,15 +198,17 @@ EndCapBSplineBasisPatchFactory::getPatchPointsFromGregoryBasis(
GregoryBasis::AppendToStencilTable(p, _vertexStencils); GregoryBasis::AppendToStencilTable(p, _vertexStencils);
} }
} }
int varyingIndices[] = { 0, 0, 1, 1, if (_varyingStencils) {
0, 0, 1, 1, int varyingIndices[] = { 0, 0, 1, 1,
3, 3, 2, 2, 0, 0, 1, 1,
3, 3, 2, 2,}; 3, 3, 2, 2,
for (int i = 0; i < 16; ++i) { 3, 3, 2, 2,};
int varyingIndex = facePoints[varyingIndices[i]] + levelVertOffset; for (int i = 0; i < 16; ++i) {
_varyingStencils->_sizes.push_back(1); int varyingIndex = facePoints[varyingIndices[i]] + levelVertOffset;
_varyingStencils->_indices.push_back(varyingIndex); _varyingStencils->_sizes.push_back(1);
_varyingStencils->_weights.push_back(1.0f); _varyingStencils->_indices.push_back(varyingIndex);
_varyingStencils->_weights.push_back(1.0f);
}
} }
++_numPatches; ++_numPatches;
@ -210,7 +218,7 @@ EndCapBSplineBasisPatchFactory::getPatchPointsFromGregoryBasis(
void void
EndCapBSplineBasisPatchFactory::computeLimitStencils( EndCapBSplineBasisPatchFactory::computeLimitStencils(
Vtr::internal::Level const *level, Vtr::internal::Level const *level,
ConstIndexArray facePoints, int vid, ConstIndexArray facePoints, int vid, int fvarChannel,
GregoryBasis::Point *P, GregoryBasis::Point *Ep, GregoryBasis::Point *Em) GregoryBasis::Point *P, GregoryBasis::Point *Ep, GregoryBasis::Point *Em)
{ {
int maxvalence = level->getMaxValence(); int maxvalence = level->getMaxValence();
@ -220,7 +228,7 @@ EndCapBSplineBasisPatchFactory::computeLimitStencils(
int ringSize = int ringSize =
level->gatherQuadRegularRingAroundVertex( level->gatherQuadRegularRingAroundVertex(
facePoints[vid], manifoldRing, /*fvarChannel*/-1); facePoints[vid], manifoldRing, fvarChannel);
// note: this function has not yet supported boundary. // note: this function has not yet supported boundary.
assert((ringSize & 1) == 0); assert((ringSize & 1) == 0);
@ -284,7 +292,7 @@ ConstIndexArray
EndCapBSplineBasisPatchFactory::getPatchPoints( EndCapBSplineBasisPatchFactory::getPatchPoints(
Vtr::internal::Level const *level, Index thisFace, Vtr::internal::Level const *level, Index thisFace,
Index extraOrdinaryIndex, ConstIndexArray facePoints, Index extraOrdinaryIndex, ConstIndexArray facePoints,
int levelVertOffset) { int levelVertOffset, int fvarChannel) {
// Fast B-spline endcap construction. // Fast B-spline endcap construction.
// //
@ -319,7 +327,7 @@ EndCapBSplineBasisPatchFactory::getPatchPoints(
int stencilCapacity = 2*maxvalence + 16; int stencilCapacity = 2*maxvalence + 16;
GregoryBasis::Point P(stencilCapacity), Em(stencilCapacity), Ep(stencilCapacity); GregoryBasis::Point P(stencilCapacity), Em(stencilCapacity), Ep(stencilCapacity);
computeLimitStencils(level, facePoints, extraOrdinaryIndex, &P, &Em, &Ep); computeLimitStencils(level, facePoints, extraOrdinaryIndex, fvarChannel, &P, &Em, &Ep);
P.OffsetIndices(levelVertOffset); P.OffsetIndices(levelVertOffset);
Em.OffsetIndices(levelVertOffset); Em.OffsetIndices(levelVertOffset);
Ep.OffsetIndices(levelVertOffset); Ep.OffsetIndices(levelVertOffset);
@ -473,7 +481,9 @@ EndCapBSplineBasisPatchFactory::getPatchPoints(
// patch point stencils will be stored in this order // patch point stencils will be stored in this order
// (Em) 6, 7, 8, (Ep) 4, 15, 14, (P) 5 // (Em) 6, 7, 8, (Ep) 4, 15, 14, (P) 5
int offset = _refiner->GetNumVerticesTotal(); int offset = (fvarChannel < 0)
? _refiner->GetNumVerticesTotal()
: _refiner->GetNumFVarValuesTotal(fvarChannel);
int varyingIndex0 = facePoints[vid] + levelVertOffset; int varyingIndex0 = facePoints[vid] + levelVertOffset;
int varyingIndex1 = facePoints[(vid+1)&3] + levelVertOffset; int varyingIndex1 = facePoints[(vid+1)&3] + levelVertOffset;
@ -482,31 +492,45 @@ EndCapBSplineBasisPatchFactory::getPatchPoints(
// push back to stencils; // push back to stencils;
patchPoints[3* vid + 6] = (_numVertices++) + offset; patchPoints[3* vid + 6] = (_numVertices++) + offset;
GregoryBasis::AppendToStencilTable(X6, _vertexStencils); GregoryBasis::AppendToStencilTable(X6, _vertexStencils);
GregoryBasis::AppendToStencilTable(varyingIndex0, _varyingStencils); if (_varyingStencils) {
GregoryBasis::AppendToStencilTable(varyingIndex0, _varyingStencils);
}
patchPoints[3*((vid+1)%4) + 4] = (_numVertices++) + offset; patchPoints[3*((vid+1)%4) + 4] = (_numVertices++) + offset;
GregoryBasis::AppendToStencilTable(X7, _vertexStencils); GregoryBasis::AppendToStencilTable(X7, _vertexStencils);
GregoryBasis::AppendToStencilTable(varyingIndex1, _varyingStencils); if (_varyingStencils) {
GregoryBasis::AppendToStencilTable(varyingIndex1, _varyingStencils);
}
patchPoints[3*((vid+1)%4) + 5] = (_numVertices++) + offset; patchPoints[3*((vid+1)%4) + 5] = (_numVertices++) + offset;
GregoryBasis::AppendToStencilTable(X8, _vertexStencils); GregoryBasis::AppendToStencilTable(X8, _vertexStencils);
GregoryBasis::AppendToStencilTable(varyingIndex1, _varyingStencils); if (_varyingStencils) {
GregoryBasis::AppendToStencilTable(varyingIndex1, _varyingStencils);
}
patchPoints[3* vid + 4] = (_numVertices++) + offset; patchPoints[3* vid + 4] = (_numVertices++) + offset;
GregoryBasis::AppendToStencilTable(X4, _vertexStencils); GregoryBasis::AppendToStencilTable(X4, _vertexStencils);
GregoryBasis::AppendToStencilTable(varyingIndex0, _varyingStencils); if (_varyingStencils) {
GregoryBasis::AppendToStencilTable(varyingIndex0, _varyingStencils);
}
patchPoints[3*((vid+3)%4) + 6] = (_numVertices++) + offset; patchPoints[3*((vid+3)%4) + 6] = (_numVertices++) + offset;
GregoryBasis::AppendToStencilTable(X15, _vertexStencils); GregoryBasis::AppendToStencilTable(X15, _vertexStencils);
GregoryBasis::AppendToStencilTable(varyingIndex3, _varyingStencils); if (_varyingStencils) {
GregoryBasis::AppendToStencilTable(varyingIndex3, _varyingStencils);
}
patchPoints[3*((vid+3)%4) + 5] = (_numVertices++) + offset; patchPoints[3*((vid+3)%4) + 5] = (_numVertices++) + offset;
GregoryBasis::AppendToStencilTable(X14, _vertexStencils); GregoryBasis::AppendToStencilTable(X14, _vertexStencils);
GregoryBasis::AppendToStencilTable(varyingIndex3, _varyingStencils); if (_varyingStencils) {
GregoryBasis::AppendToStencilTable(varyingIndex3, _varyingStencils);
}
patchPoints[3*vid + 5] = (_numVertices++) + offset; patchPoints[3*vid + 5] = (_numVertices++) + offset;
GregoryBasis::AppendToStencilTable(X5, _vertexStencils); GregoryBasis::AppendToStencilTable(X5, _vertexStencils);
GregoryBasis::AppendToStencilTable(varyingIndex0, _varyingStencils); if (_varyingStencils) {
GregoryBasis::AppendToStencilTable(varyingIndex0, _varyingStencils);
}
// reorder into UV row-column // reorder into UV row-column
static int const permuteRegular[16] = static int const permuteRegular[16] =

View File

@ -45,8 +45,6 @@ class TopologyRefiner;
class EndCapBSplineBasisPatchFactory { class EndCapBSplineBasisPatchFactory {
public: public:
// XXXX need to add support for face-varying channel stencils
/// \brief This factory accumulates vertex for bspline basis end cap /// \brief This factory accumulates vertex for bspline basis end cap
/// ///
/// @param refiner TopologyRefiner from which to generate patches /// @param refiner TopologyRefiner from which to generate patches
@ -76,26 +74,28 @@ public:
/// ///
/// @param levelVertOffset relative offset of patch vertex indices /// @param levelVertOffset relative offset of patch vertex indices
/// ///
/// @param fvarChannel face-varying channel index
///
ConstIndexArray GetPatchPoints( ConstIndexArray GetPatchPoints(
Vtr::internal::Level const * level, Index faceIndex, Vtr::internal::Level const * level, Index faceIndex,
Vtr::internal::Level::VSpan const cornerSpans[], Vtr::internal::Level::VSpan const cornerSpans[],
int levelVertOffset); int levelVertOffset, int fvarChannel = -1);
private: private:
ConstIndexArray getPatchPointsFromGregoryBasis( ConstIndexArray getPatchPointsFromGregoryBasis(
Vtr::internal::Level const * level, Index thisFace, Vtr::internal::Level const * level, Index thisFace,
Vtr::internal::Level::VSpan const cornerSpans[], Vtr::internal::Level::VSpan const cornerSpans[],
ConstIndexArray facePoints, ConstIndexArray facePoints,
int levelVertOffset); int levelVertOffset, int fvarChannel);
ConstIndexArray getPatchPoints( ConstIndexArray getPatchPoints(
Vtr::internal::Level const *level, Index thisFace, Vtr::internal::Level const *level, Index thisFace,
Index extraOrdinaryIndex, ConstIndexArray facePoints, Index extraOrdinaryIndex, ConstIndexArray facePoints,
int levelVertOffset); int levelVertOffset, int fvarChannel);
void computeLimitStencils( void computeLimitStencils(
Vtr::internal::Level const *level, Vtr::internal::Level const *level,
ConstIndexArray facePoints, int vid, ConstIndexArray facePoints, int vid, int fvarChannel,
GregoryBasis::Point *P, GregoryBasis::Point *Ep, GregoryBasis::Point *Em); GregoryBasis::Point *P, GregoryBasis::Point *Ep, GregoryBasis::Point *Em);
StencilTable * _vertexStencils; StencilTable * _vertexStencils;

View File

@ -63,59 +63,53 @@ EndCapGregoryBasisPatchFactory::EndCapGregoryBasisPatchFactory(
int numStencilsExpected = std::min(numPatchPointsExpected * 16, int numStencilsExpected = std::min(numPatchPointsExpected * 16,
100*1024*1024); 100*1024*1024);
_vertexStencils->reserve(numPatchPointsExpected, numStencilsExpected); _vertexStencils->reserve(numPatchPointsExpected, numStencilsExpected);
// varying stencils use only 1 index with weight=1.0 if (_varyingStencils) {
_varyingStencils->reserve(numPatchPointsExpected, numPatchPointsExpected); // varying stencils use only 1 index with weight=1.0
} _varyingStencils->reserve(numPatchPointsExpected, numPatchPointsExpected);
}
//
// Stateless EndCapGregoryBasisPatchFactory
//
GregoryBasis const *
EndCapGregoryBasisPatchFactory::Create(TopologyRefiner const & refiner,
Index faceIndex, int fvarChannel) {
// Gregory patches are end-caps: they only exist on max-level
Vtr::internal::Level const & level = refiner.getLevel(refiner.GetMaxLevel());
// Is this method used/supported? If so, needs corner spans (and vert offset?)...
GregoryBasis::ProtoBasis basis(level, faceIndex, 0, 0, fvarChannel);
GregoryBasis * result = new GregoryBasis;
basis.Copy(result);
// note: this function doesn't create varying stencils.
return result;
} }
bool bool
EndCapGregoryBasisPatchFactory::addPatchBasis(Vtr::internal::Level const & level, Index faceIndex, EndCapGregoryBasisPatchFactory::addPatchBasis(Vtr::internal::Level const & level, Index faceIndex,
Vtr::internal::Level::VSpan const cornerSpans[], Vtr::internal::Level::VSpan const cornerSpans[],
bool verticesMask[4][5], bool verticesMask[4][5],
int levelVertOffset) { int levelVertOffset,
int fvarChannel) {
// Gather the CVs that influence the Gregory patch and their relative // Gather the CVs that influence the Gregory patch and their relative
// weights in a basis // weights in a basis
GregoryBasis::ProtoBasis basis(level, faceIndex, cornerSpans, levelVertOffset, -1); GregoryBasis::ProtoBasis basis(level, faceIndex, cornerSpans, levelVertOffset, fvarChannel);
for (int i = 0; i < 4; ++i) { for (int i = 0; i < 4; ++i) {
if (verticesMask[i][0]) { if (verticesMask[i][0]) {
GregoryBasis::AppendToStencilTable(basis.P[i], _vertexStencils); GregoryBasis::AppendToStencilTable(basis.P[i], _vertexStencils);
GregoryBasis::AppendToStencilTable(basis.varyingIndex[i], _varyingStencils); if (_varyingStencils) {
GregoryBasis::AppendToStencilTable(basis.varyingIndex[i], _varyingStencils);
}
} }
if (verticesMask[i][1]) { if (verticesMask[i][1]) {
GregoryBasis::AppendToStencilTable(basis.Ep[i], _vertexStencils); GregoryBasis::AppendToStencilTable(basis.Ep[i], _vertexStencils);
GregoryBasis::AppendToStencilTable(basis.varyingIndex[i], _varyingStencils); if (_varyingStencils) {
GregoryBasis::AppendToStencilTable(basis.varyingIndex[i], _varyingStencils);
}
} }
if (verticesMask[i][2]) { if (verticesMask[i][2]) {
GregoryBasis::AppendToStencilTable(basis.Em[i], _vertexStencils); GregoryBasis::AppendToStencilTable(basis.Em[i], _vertexStencils);
GregoryBasis::AppendToStencilTable(basis.varyingIndex[i], _varyingStencils); if (_varyingStencils) {
GregoryBasis::AppendToStencilTable(basis.varyingIndex[i], _varyingStencils);
}
} }
if (verticesMask[i][3]) { if (verticesMask[i][3]) {
GregoryBasis::AppendToStencilTable(basis.Fp[i], _vertexStencils); GregoryBasis::AppendToStencilTable(basis.Fp[i], _vertexStencils);
GregoryBasis::AppendToStencilTable(basis.varyingIndex[i], _varyingStencils); if (_varyingStencils) {
GregoryBasis::AppendToStencilTable(basis.varyingIndex[i], _varyingStencils);
}
} }
if (verticesMask[i][4]) { if (verticesMask[i][4]) {
GregoryBasis::AppendToStencilTable(basis.Fm[i], _vertexStencils); GregoryBasis::AppendToStencilTable(basis.Fm[i], _vertexStencils);
GregoryBasis::AppendToStencilTable(basis.varyingIndex[i], _varyingStencils); if (_varyingStencils) {
GregoryBasis::AppendToStencilTable(basis.varyingIndex[i], _varyingStencils);
}
} }
} }
return true; return true;
@ -131,7 +125,7 @@ ConstIndexArray
EndCapGregoryBasisPatchFactory::GetPatchPoints( EndCapGregoryBasisPatchFactory::GetPatchPoints(
Vtr::internal::Level const * level, Index faceIndex, Vtr::internal::Level const * level, Index faceIndex,
Vtr::internal::Level::VSpan const cornerSpans[], Vtr::internal::Level::VSpan const cornerSpans[],
int levelVertOffset) { int levelVertOffset, int fvarChannel) {
// allocate indices (awkward) // allocate indices (awkward)
// assert(Vtr::INDEX_INVALID==0xFFFFFFFF); // assert(Vtr::INDEX_INVALID==0xFFFFFFFF);
@ -140,7 +134,9 @@ EndCapGregoryBasisPatchFactory::GetPatchPoints(
} }
Index * dest = &_patchPoints[_numGregoryBasisPatches * 20]; Index * dest = &_patchPoints[_numGregoryBasisPatches * 20];
int gregoryVertexOffset = _refiner->GetNumVerticesTotal(); int gregoryVertexOffset = (fvarChannel < 0)
? _refiner->GetNumVerticesTotal()
: _refiner->GetNumFVarValuesTotal(fvarChannel);
if (_shareBoundaryVertices) { if (_shareBoundaryVertices) {
int levelIndex = level->getDepth(); int levelIndex = level->getDepth();
@ -180,6 +176,10 @@ EndCapGregoryBasisPatchFactory::GetPatchPoints(
// - are also Gregory basis patches // - are also Gregory basis patches
if ((adjFaceIndex != Vtr::INDEX_INVALID) && (adjFaceIndex < faceIndex)) { if ((adjFaceIndex != Vtr::INDEX_INVALID) && (adjFaceIndex < faceIndex)) {
if (_levelAndFaceIndices.empty()) {
break;
}
ConstIndexArray aedges = level->getFaceEdges(adjFaceIndex); ConstIndexArray aedges = level->getFaceEdges(adjFaceIndex);
int aedge = aedges.FindIndexIn4Tuple(edge); int aedge = aedges.FindIndexIn4Tuple(edge);
assert(aedge!=Vtr::INDEX_INVALID); assert(aedge!=Vtr::INDEX_INVALID);
@ -231,7 +231,7 @@ EndCapGregoryBasisPatchFactory::GetPatchPoints(
} }
// add basis // add basis
addPatchBasis(*level, faceIndex, cornerSpans, newVerticesMask, levelVertOffset); addPatchBasis(*level, faceIndex, cornerSpans, newVerticesMask, levelVertOffset, fvarChannel);
++_numGregoryBasisPatches; ++_numGregoryBasisPatches;

View File

@ -44,32 +44,12 @@ class TopologyRefiner;
/// ///
class EndCapGregoryBasisPatchFactory { class EndCapGregoryBasisPatchFactory {
public:
//
// Single patch GregoryBasis basis factory
//
/// \brief Instantiates a GregoryBasis from a TopologyRefiner that has been
/// refined adaptively for a given face.
///
/// @param refiner The TopologyRefiner containing the topology
///
/// @param faceIndex The index of the face (level is assumed to be MaxLevel)
///
/// @param fvarChannel Index of face-varying channel topology (default -1)
///
static GregoryBasis const * Create(TopologyRefiner const & refiner,
Index faceIndex, int fvarChannel=-1);
public: public:
/// ///
/// Multi-patch Gregory stencils factory /// Multi-patch Gregory stencils factory
/// ///
// XXXX need to add support for face-varying channel stencils
/// \brief This factory accumulates vertex for Gregory basis patch /// \brief This factory accumulates vertex for Gregory basis patch
/// ///
/// @param refiner TopologyRefiner from which to generate patches /// @param refiner TopologyRefiner from which to generate patches
@ -101,10 +81,12 @@ public:
/// @param cornerSpans information about topology for each corner of patch /// @param cornerSpans information about topology for each corner of patch
/// @param levelVertOffset relative offset of patch vertex indices /// @param levelVertOffset relative offset of patch vertex indices
/// ///
/// @param fvarChannel face-varying channel index
///
ConstIndexArray GetPatchPoints( ConstIndexArray GetPatchPoints(
Vtr::internal::Level const * level, Index faceIndex, Vtr::internal::Level const * level, Index faceIndex,
Vtr::internal::Level::VSpan const cornerSpans[], Vtr::internal::Level::VSpan const cornerSpans[],
int levelVertOffset); int levelVertOffset, int fvarChannel = -1);
private: private:
@ -112,7 +94,8 @@ private:
/// accumates it /// accumates it
bool addPatchBasis(Vtr::internal::Level const & level, Index faceIndex, bool addPatchBasis(Vtr::internal::Level const & level, Index faceIndex,
Vtr::internal::Level::VSpan const cornerSpans[], Vtr::internal::Level::VSpan const cornerSpans[],
bool newVerticesMask[4][5], int levelVertOffset); bool newVerticesMask[4][5],
int levelVertOffset, int fvarChannel);
StencilTable *_vertexStencils; StencilTable *_vertexStencils;
StencilTable *_varyingStencils; StencilTable *_varyingStencils;

View File

@ -41,11 +41,13 @@ EndCapLegacyGregoryPatchFactory::EndCapLegacyGregoryPatchFactory(
ConstIndexArray ConstIndexArray
EndCapLegacyGregoryPatchFactory::GetPatchPoints( EndCapLegacyGregoryPatchFactory::GetPatchPoints(
Vtr::internal::Level const * level, Index faceIndex, Vtr::internal::Level const * level, Index faceIndex,
Vtr::internal::Level::VSpan const cornerSpans[], Vtr::internal::Level::VSpan const /*cornerSpans*/[],
int levelVertOffset) { int levelVertOffset, int fvarChannel) {
// Gregory Regular Patch (4 CVs + quad-offsets / valence tables) // Gregory Regular Patch (4 CVs + quad-offsets / valence tables)
Vtr::ConstIndexArray faceVerts = level->getFaceVertices(faceIndex); Vtr::ConstIndexArray faceVerts = (fvarChannel < 0)
? level->getFaceVertices(faceIndex)
: level->getFaceFVarValues(faceIndex, fvarChannel);
if (level->getFaceCompositeVTag(faceVerts)._boundary) { if (level->getFaceCompositeVTag(faceVerts)._boundary) {
for (int j = 0; j < 4; ++j) { for (int j = 0; j < 4; ++j) {
@ -68,9 +70,11 @@ EndCapLegacyGregoryPatchFactory::GetPatchPoints(
// Populate the quad-offsets table used by Gregory patches // Populate the quad-offsets table used by Gregory patches
// //
static void getQuadOffsets( static void getQuadOffsets(
Vtr::internal::Level const& level, Index faceIndex, unsigned int offsets[]) { Vtr::internal::Level const& level, Index faceIndex, unsigned int offsets[], int fvarChannel) {
Vtr::ConstIndexArray fVerts = level.getFaceVertices(faceIndex); Vtr::ConstIndexArray fVerts = (fvarChannel < 0)
? level.getFaceVertices(faceIndex)
: level.getFaceFVarValues(faceIndex, fvarChannel);
for (int i = 0; i < 4; ++i) { for (int i = 0; i < 4; ++i) {
@ -101,7 +105,8 @@ void
EndCapLegacyGregoryPatchFactory::Finalize( EndCapLegacyGregoryPatchFactory::Finalize(
int maxValence, int maxValence,
PatchTable::QuadOffsetsTable *quadOffsetsTable, PatchTable::QuadOffsetsTable *quadOffsetsTable,
PatchTable::VertexValenceTable *vertexValenceTable) PatchTable::VertexValenceTable *vertexValenceTable,
int fvarChannel)
{ {
// populate quad offsets // populate quad offsets
@ -118,11 +123,11 @@ EndCapLegacyGregoryPatchFactory::Finalize(
PatchTable::QuadOffsetsTable::value_type *p = PatchTable::QuadOffsetsTable::value_type *p =
&((*quadOffsetsTable)[0]); &((*quadOffsetsTable)[0]);
for (size_t i = 0; i < numGregoryPatches; ++i) { for (size_t i = 0; i < numGregoryPatches; ++i) {
getQuadOffsets(maxLevel, _gregoryFaceIndices[i], p); getQuadOffsets(maxLevel, _gregoryFaceIndices[i], p, fvarChannel);
p += 4; p += 4;
} }
for (size_t i = 0; i < numGregoryBoundaryPatches; ++i) { for (size_t i = 0; i < numGregoryBoundaryPatches; ++i) {
getQuadOffsets(maxLevel, _gregoryBoundaryFaceIndices[i], p); getQuadOffsets(maxLevel, _gregoryBoundaryFaceIndices[i], p, fvarChannel);
p += 4; p += 4;
} }
} }

View File

@ -58,14 +58,17 @@ public:
/// ///
/// @param levelVertOffset relative offset of patch vertex indices /// @param levelVertOffset relative offset of patch vertex indices
/// ///
/// @param fvarChannel face-varying channel index
///
ConstIndexArray GetPatchPoints( ConstIndexArray GetPatchPoints(
Vtr::internal::Level const * level, Index faceIndex, Vtr::internal::Level const * level, Index faceIndex,
Vtr::internal::Level::VSpan const cornerSpans[], Vtr::internal::Level::VSpan const cornerSpans[],
int levelVertOffset); int levelVertOffset, int fvarChannel = -1);
void Finalize(int maxValence, void Finalize(int maxValence,
PatchTable::QuadOffsetsTable *quadOffsetsTable, PatchTable::QuadOffsetsTable *quadOffsetsTable,
PatchTable::VertexValenceTable *vertexValenceTable); PatchTable::VertexValenceTable *vertexValenceTable,
int fvarChannel = -1);
private: private:

View File

@ -347,6 +347,9 @@ gatherEndCapPatchPoints(
int levelVertOffset = (fvarChannel < 0) int levelVertOffset = (fvarChannel < 0)
? levelVertOffsets[patch.levelIndex] ? levelVertOffsets[patch.levelIndex]
: levelFVarValueOffsets[fvarChannel][patch.levelIndex]; : levelFVarValueOffsets[fvarChannel][patch.levelIndex];
int refinerChannel = (fvarChannel < 0)
? fvarChannel
: fvarChannelIndices[fvarChannel];
// identify relevant spans around the corner vertices for the irregular patches // identify relevant spans around the corner vertices for the irregular patches
// (this is just a stub for now -- leaving the span "size" to zero, as constructed, // (this is just a stub for now -- leaving the span "size" to zero, as constructed,
@ -354,7 +357,7 @@ gatherEndCapPatchPoints(
Vtr::internal::Level::VSpan cornerSpans[4]; Vtr::internal::Level::VSpan cornerSpans[4];
ConstIndexArray cvs = endCapFactory->GetPatchPoints( ConstIndexArray cvs = endCapFactory->GetPatchPoints(
level, patch.faceIndex, cornerSpans, levelVertOffset); level, patch.faceIndex, cornerSpans, levelVertOffset, refinerChannel);
for (int i = 0; i < cvs.size(); ++i) iptrs[i] = cvs[i]; for (int i = 0; i < cvs.size(); ++i) iptrs[i] = cvs[i];
return cvs.size(); return cvs.size();