24 #ifndef OPENSUBDIV3_FAR_PRIMVAR_REFINER_H 25 #define OPENSUBDIV3_FAR_PRIMVAR_REFINER_H 27 #include "../version.h" 29 #include "../sdc/types.h" 30 #include "../sdc/options.h" 31 #include "../sdc/bilinearScheme.h" 32 #include "../sdc/catmarkScheme.h" 33 #include "../sdc/loopScheme.h" 34 #include "../vtr/level.h" 35 #include "../vtr/fvarLevel.h" 36 #include "../vtr/refinement.h" 37 #include "../vtr/fvarRefinement.h" 38 #include "../vtr/stackBuffer.h" 39 #include "../vtr/componentInterfaces.h" 40 #include "../far/types.h" 41 #include "../far/error.h" 42 #include "../far/topologyLevel.h" 43 #include "../far/topologyRefiner.h" 48 namespace OPENSUBDIV_VERSION {
55 template <
typename REAL>
113 template <
class T,
class U>
void Interpolate(
int level, T
const & src, U & dst)
const;
130 template <
class T,
class U>
void InterpolateVarying(
int level, T
const & src, U & dst)
const;
161 template <
class T,
class U>
void InterpolateFaceVarying(
int level, T
const & src, U & dst,
int channel = 0)
const;
175 template <
class T,
class U>
void Limit(T
const & src, U & dstPos)
const;
177 template <
class T,
class U,
class U1,
class U2>
178 void Limit(T
const & src, U & dstPos, U1 & dstTan1, U2 & dstTan2)
const;
180 template <
class T,
class U>
void LimitFaceVarying(T
const & src, U & dst,
int channel = 0)
const;
191 template <Sdc::SchemeType SCHEME,
class T,
class U>
void interpFromFaces(
int, T
const &, U &)
const;
192 template <Sdc::SchemeType SCHEME,
class T,
class U>
void interpFromEdges(
int, T
const &, U &)
const;
193 template <Sdc::SchemeType SCHEME,
class T,
class U>
void interpFromVerts(
int, T
const &, U &)
const;
195 template <Sdc::SchemeType SCHEME,
class T,
class U>
void interpFVarFromFaces(
int, T
const &, U &,
int)
const;
196 template <Sdc::SchemeType SCHEME,
class T,
class U>
void interpFVarFromEdges(
int, T
const &, U &,
int)
const;
197 template <Sdc::SchemeType SCHEME,
class T,
class U>
void interpFVarFromVerts(
int, T
const &, U &,
int)
const;
199 template <Sdc::SchemeType SCHEME,
class T,
class U,
class U1,
class U2>
200 void limit(T
const & src, U & pos, U1 * tan1, U2 * tan2)
const;
202 template <Sdc::SchemeType SCHEME,
class T,
class U>
203 void limitFVar(T
const & src, U & dst,
int channel)
const;
217 Mask(Weight* v, Weight* e, Weight* f) :
218 _vertWeights(v), _edgeWeights(e), _faceWeights(f),
219 _vertCount(0), _edgeCount(0), _faceCount(0),
220 _faceWeightsForFaceCenters(
false)
226 int GetNumVertexWeights()
const {
return _vertCount; }
227 int GetNumEdgeWeights()
const {
return _edgeCount; }
228 int GetNumFaceWeights()
const {
return _faceCount; }
230 void SetNumVertexWeights(
int count) { _vertCount = count; }
231 void SetNumEdgeWeights(
int count) { _edgeCount = count; }
232 void SetNumFaceWeights(
int count) { _faceCount = count; }
234 Weight
const& VertexWeight(
int index)
const {
return _vertWeights[index]; }
235 Weight
const& EdgeWeight(
int index)
const {
return _edgeWeights[index]; }
236 Weight
const& FaceWeight(
int index)
const {
return _faceWeights[index]; }
238 Weight& VertexWeight(
int index) {
return _vertWeights[index]; }
239 Weight& EdgeWeight(
int index) {
return _edgeWeights[index]; }
240 Weight& FaceWeight(
int index) {
return _faceWeights[index]; }
242 bool AreFaceWeightsForFaceCenters()
const {
return _faceWeightsForFaceCenters; }
243 void SetFaceWeightsForFaceCenters(
bool on) { _faceWeightsForFaceCenters = on; }
246 Weight* _vertWeights;
247 Weight* _edgeWeights;
248 Weight* _faceWeights;
254 bool _faceWeightsForFaceCenters;
264 template <
typename REAL>
265 template <
class T,
class U>
269 assert(level>0 && level<=(
int)_refiner._refinements.size());
271 switch (_refiner._subdivType) {
273 interpFromFaces<Sdc::SCHEME_CATMARK>(level, src, dst);
274 interpFromEdges<Sdc::SCHEME_CATMARK>(level, src, dst);
275 interpFromVerts<Sdc::SCHEME_CATMARK>(level, src, dst);
278 interpFromFaces<Sdc::SCHEME_LOOP>(level, src, dst);
279 interpFromEdges<Sdc::SCHEME_LOOP>(level, src, dst);
280 interpFromVerts<Sdc::SCHEME_LOOP>(level, src, dst);
283 interpFromFaces<Sdc::SCHEME_BILINEAR>(level, src, dst);
284 interpFromEdges<Sdc::SCHEME_BILINEAR>(level, src, dst);
285 interpFromVerts<Sdc::SCHEME_BILINEAR>(level, src, dst);
290 template <
typename REAL>
291 template <
class T,
class U>
295 assert(level>0 && level<=(
int)_refiner._refinements.size());
297 switch (_refiner._subdivType) {
299 interpFVarFromFaces<Sdc::SCHEME_CATMARK>(level, src, dst, channel);
300 interpFVarFromEdges<Sdc::SCHEME_CATMARK>(level, src, dst, channel);
301 interpFVarFromVerts<Sdc::SCHEME_CATMARK>(level, src, dst, channel);
304 interpFVarFromFaces<Sdc::SCHEME_LOOP>(level, src, dst, channel);
305 interpFVarFromEdges<Sdc::SCHEME_LOOP>(level, src, dst, channel);
306 interpFVarFromVerts<Sdc::SCHEME_LOOP>(level, src, dst, channel);
309 interpFVarFromFaces<Sdc::SCHEME_BILINEAR>(level, src, dst, channel);
310 interpFVarFromEdges<Sdc::SCHEME_BILINEAR>(level, src, dst, channel);
311 interpFVarFromVerts<Sdc::SCHEME_BILINEAR>(level, src, dst, channel);
316 template <
typename REAL>
317 template <
class T,
class U>
321 if (_refiner.getLevel(_refiner.GetMaxLevel()).getNumVertexEdgesTotal() == 0) {
323 "Failure in PrimvarRefiner::Limit() -- " 324 "last level of refinement does not include full topology.");
328 switch (_refiner._subdivType) {
330 limit<Sdc::SCHEME_CATMARK>(src, dst, (U*)0, (U*)0);
333 limit<Sdc::SCHEME_LOOP>(src, dst, (U*)0, (U*)0);
336 limit<Sdc::SCHEME_BILINEAR>(src, dst, (U*)0, (U*)0);
341 template <
typename REAL>
342 template <
class T,
class U,
class U1,
class U2>
346 if (_refiner.getLevel(_refiner.GetMaxLevel()).getNumVertexEdgesTotal() == 0) {
348 "Failure in PrimvarRefiner::Limit() -- " 349 "last level of refinement does not include full topology.");
353 switch (_refiner._subdivType) {
355 limit<Sdc::SCHEME_CATMARK>(src, dstPos, &dstTan1, &dstTan2);
358 limit<Sdc::SCHEME_LOOP>(src, dstPos, &dstTan1, &dstTan2);
361 limit<Sdc::SCHEME_BILINEAR>(src, dstPos, &dstTan1, &dstTan2);
366 template <
typename REAL>
367 template <
class T,
class U>
371 if (_refiner.getLevel(_refiner.GetMaxLevel()).getNumVertexEdgesTotal() == 0) {
373 "Failure in PrimvarRefiner::LimitFaceVarying() -- " 374 "last level of refinement does not include full topology.");
378 switch (_refiner._subdivType) {
380 limitFVar<Sdc::SCHEME_CATMARK>(src, dst, channel);
383 limitFVar<Sdc::SCHEME_LOOP>(src, dst, channel);
386 limitFVar<Sdc::SCHEME_BILINEAR>(src, dst, channel);
391 template <
typename REAL>
392 template <
class T,
class U>
396 assert(level>0 && level<=(
int)_refiner._refinements.size());
401 for (
int cFace = 0; cFace < child.
getNumFaces(); ++cFace) {
403 Vtr::Index pFace = refinement.getChildFaceParentFace(cFace);
405 dst[cFace] = src[pFace];
409 template <
typename REAL>
410 template <
class T,
class U>
414 assert(level>0 && level<=(
int)_refiner._refinements.size());
423 if (refinement.getNumChildVerticesFromFaces() > 0) {
425 for (
int face = 0; face < parent.
getNumFaces(); ++face) {
427 Vtr::Index cVert = refinement.getFaceChildVertex(face);
433 Weight fVaryingWeight = 1.0f / (Weight) fVerts.
size();
436 for (
int i = 0; i < fVerts.
size(); ++i) {
437 dst[cVert].AddWithWeight(src[fVerts[i]], fVaryingWeight);
442 for (
int edge = 0; edge < parent.
getNumEdges(); ++edge) {
444 Vtr::Index cVert = refinement.getEdgeChildVertex(edge);
451 dst[cVert].AddWithWeight(src[eVerts[0]], 0.5f);
452 dst[cVert].AddWithWeight(src[eVerts[1]], 0.5f);
457 Vtr::Index cVert = refinement.getVertexChildVertex(vert);
462 dst[cVert].AddWithWeight(src[vert], 1.0f);
472 template <
typename REAL>
473 template <Sdc::SchemeType SCHEME,
class T,
class U>
486 for (
int face = 0; face < parent.
getNumFaces(); ++face) {
495 Mask fMask(fVertWeights, 0, 0);
503 for (
int i = 0; i < fVerts.
size(); ++i) {
505 dst[cVert].AddWithWeight(src[fVerts[i]], fVertWeights[i]);
510 template <
typename REAL>
511 template <Sdc::SchemeType SCHEME,
class T,
class U>
523 Weight eVertWeights[2];
526 for (
int edge = 0; edge < parent.
getNumEdges(); ++edge) {
536 Mask eMask(eVertWeights, 0, eFaceWeights);
548 dst[cVert].AddWithWeight(src[eVerts[0]], eVertWeights[0]);
549 dst[cVert].AddWithWeight(src[eVerts[1]], eVertWeights[1]);
551 if (eMask.GetNumFaceWeights() > 0) {
553 for (
int i = 0; i < eFaces.size(); ++i) {
555 if (eMask.AreFaceWeightsForFaceCenters()) {
560 dst[cVert].AddWithWeight(dst[cVertOfFace], eFaceWeights[i]);
567 for ( ; pFaceEdges[eInFace] != edge; ++eInFace ) ;
569 int vInFace = eInFace + 2;
570 if (vInFace >= pFaceVerts.size()) vInFace -= pFaceVerts.
size();
573 dst[cVert].AddWithWeight(src[pVertNext], eFaceWeights[i]);
580 template <
typename REAL>
581 template <Sdc::SchemeType SCHEME,
class T,
class U>
606 * vEdgeWeights = weightBuffer,
607 * vFaceWeights = vEdgeWeights + vEdges.
size();
609 Mask vMask(&vVertWeight, vEdgeWeights, vFaceWeights);
626 if (vMask.GetNumFaceWeights() > 0) {
627 assert(vMask.AreFaceWeightsForFaceCenters());
629 for (
int i = 0; i < vFaces.size(); ++i) {
633 dst[cVert].AddWithWeight(dst[cVertOfFace], vFaceWeights[i]);
636 if (vMask.GetNumEdgeWeights() > 0) {
638 for (
int i = 0; i < vEdges.
size(); ++i) {
641 Vtr::Index pVertOppositeEdge = (eVerts[0] == vert) ? eVerts[1] : eVerts[0];
643 dst[cVert].AddWithWeight(src[pVertOppositeEdge], vEdgeWeights[i]);
646 dst[cVert].AddWithWeight(src[vert], vVertWeight);
654 template <
typename REAL>
655 template <Sdc::SchemeType SCHEME,
class T,
class U>
673 for (
int face = 0; face < parentLevel.
getNumFaces(); ++face) {
689 Mask fMask(fValueWeights, 0, 0);
695 dst[cVertValue].Clear();
697 for (
int i = 0; i < fValues.
size(); ++i) {
698 dst[cVertValue].AddWithWeight(src[fValues[i]], fValueWeights[i]);
703 template <
typename REAL>
704 template <Sdc::SchemeType SCHEME,
class T,
class U>
723 Weight eVertWeights[2];
726 Mask eMask(eVertWeights, 0, eFaceWeights);
730 eMask.SetNumVertexWeights(2);
731 eMask.SetNumEdgeWeights(0);
732 eMask.SetNumFaceWeights(0);
734 eVertWeights[0] = 0.5f;
735 eVertWeights[1] = 0.5f;
740 for (
int edge = 0; edge < parentLevel.
getNumEdges(); ++edge) {
749 if (fvarEdgeVertMatchesVertex) {
787 Index cVertValue = cVertValues[0];
789 dst[cVertValue].Clear();
790 dst[cVertValue].AddWithWeight(src[eVertValues[0]], eVertWeights[0]);
791 dst[cVertValue].AddWithWeight(src[eVertValues[1]], eVertWeights[1]);
793 if (eMask.GetNumFaceWeights() > 0) {
797 for (
int i = 0; i < eFaces.
size(); ++i) {
798 if (eMask.AreFaceWeightsForFaceCenters()) {
804 dst[cVertValue].AddWithWeight(dst[cValueOfFace], eFaceWeights[i]);
811 for ( ; pFaceEdges[eInFace] != edge; ++eInFace ) ;
814 int vInFace = eInFace + 2;
815 if (vInFace >= pFaceVerts.size()) vInFace -= pFaceVerts.
size();
818 dst[cVertValue].AddWithWeight(src[pValueNext], eFaceWeights[i]);
831 for (
int i = 0; i < cVertValues.
size(); ++i) {
834 assert(eFaceIndex == i);
838 Index cVertValue = cVertValues[i];
840 dst[cVertValue].Clear();
841 dst[cVertValue].AddWithWeight(src[eVertValues[0]], 0.5);
842 dst[cVertValue].AddWithWeight(src[eVertValues[1]], 0.5);
848 template <
typename REAL>
849 template <Sdc::SchemeType SCHEME,
class T,
class U>
882 if (isLinearFVar && fvarVertVertMatchesVertex) {
883 dst[cVertValues[0]].Clear();
884 dst[cVertValues[0]].AddWithWeight(src[pVertValues[0]], 1.0f);
888 if (fvarVertVertMatchesVertex) {
898 Weight * vEdgeWeights = weightBuffer;
899 Weight * vFaceWeights = vEdgeWeights + vEdges.
size();
901 Mask vMask(&vVertWeight, vEdgeWeights, vFaceWeights);
903 vHood.SetIndex(vert, cVert);
937 dst[cVertValue].Clear();
938 if (vMask.GetNumFaceWeights() > 0) {
939 assert(vMask.AreFaceWeightsForFaceCenters());
943 for (
int i = 0; i < vFaces.size(); ++i) {
949 dst[cVertValue].AddWithWeight(dst[cValueOfFace], vFaceWeights[i]);
952 if (vMask.GetNumEdgeWeights() > 0) {
956 for (
int i = 0; i < vEdges.
size(); ++i) {
957 dst[cVertValue].AddWithWeight(src[vEdgeValues[i]], vEdgeWeights[i]);
960 dst[cVertValue].AddWithWeight(src[pVertValue], vVertWeight);
972 for (
int cSibling = 0; cSibling < cVertValues.size(); ++cSibling) {
974 assert(pSibling == cSibling);
976 Vtr::Index pVertValue = pVertValues[pSibling];
977 Vtr::Index cVertValue = cVertValues[cSibling];
979 dst[cVertValue].Clear();
980 if (isLinearFVar || cValueTags[cSibling].isCorner()) {
981 dst[cVertValue].AddWithWeight(src[pVertValue], 1.0f);
990 Weight vWeight = 0.75f;
991 Weight eWeight = 0.125f;
998 if (pValueTags[pSibling].isSemiSharp()) {
999 Weight wCorner = pValueTags[pSibling].isDepSharp()
1002 Weight wCrease = 1.0f - wCorner;
1004 vWeight = wCrease * 0.75f + wCorner;
1005 eWeight = wCrease * 0.125f;
1007 dst[cVertValue].AddWithWeight(src[pEndValues[0]], eWeight);
1008 dst[cVertValue].AddWithWeight(src[pEndValues[1]], eWeight);
1009 dst[cVertValue].AddWithWeight(src[pVertValue], vWeight);
1016 template <
typename REAL>
1017 template <Sdc::SchemeType SCHEME,
class T,
class U,
class U1,
class U2>
1026 bool hasTangents = (dstTan1Ptr && dstTan2Ptr);
1027 int numMasks = 1 + (hasTangents ? 2 : 0);
1032 Weight * vPosWeights = weightBuffer,
1033 * ePosWeights = vPosWeights + 1,
1035 Weight * vTan1Weights = vPosWeights + maxWeightsPerMask,
1036 * eTan1Weights = ePosWeights + maxWeightsPerMask,
1037 * fTan1Weights = fPosWeights + maxWeightsPerMask;
1038 Weight * vTan2Weights = vTan1Weights + maxWeightsPerMask,
1039 * eTan2Weights = eTan1Weights + maxWeightsPerMask,
1040 * fTan2Weights = fTan1Weights + maxWeightsPerMask;
1042 Mask posMask( vPosWeights, ePosWeights, fPosWeights);
1043 Mask tan1Mask(vTan1Weights, eTan1Weights, fTan1Weights);
1044 Mask tan2Mask(vTan2Weights, eTan2Weights, fTan2Weights);
1057 dstPos[vert].Clear();
1058 dstPos[vert].AddWithWeight(src[vert], 1.0);
1060 (*dstTan1Ptr)[vert].Clear();
1061 (*dstTan2Ptr)[vert].Clear();
1086 Index * eIndices = indexBuffer;
1087 Index * fIndices = indexBuffer + vEdges.
size();
1089 for (
int i = 0; i < vEdges.
size(); ++i) {
1092 eIndices[i] = (eVerts[0] == vert) ? eVerts[1] : eVerts[0];
1094 if (posMask.GetNumFaceWeights() || (hasTangents && tan1Mask.GetNumFaceWeights())) {
1098 for (
int i = 0; i < vFaces.
size(); ++i) {
1114 dstPos[vert].Clear();
1115 for (
int i = 0; i < posMask.GetNumFaceWeights(); ++i) {
1116 dstPos[vert].AddWithWeight(src[fIndices[i]], fPosWeights[i]);
1118 for (
int i = 0; i < posMask.GetNumEdgeWeights(); ++i) {
1119 dstPos[vert].AddWithWeight(src[eIndices[i]], ePosWeights[i]);
1121 dstPos[vert].AddWithWeight(src[vert], vPosWeights[0]);
1129 assert(tan1Mask.GetNumFaceWeights() == tan2Mask.GetNumFaceWeights());
1130 assert(tan1Mask.GetNumEdgeWeights() == tan2Mask.GetNumEdgeWeights());
1132 U1 & dstTan1 = *dstTan1Ptr;
1133 U2 & dstTan2 = *dstTan2Ptr;
1135 dstTan1[vert].Clear();
1136 dstTan2[vert].Clear();
1137 for (
int i = 0; i < tan1Mask.GetNumFaceWeights(); ++i) {
1138 dstTan1[vert].AddWithWeight(src[fIndices[i]], fTan1Weights[i]);
1139 dstTan2[vert].AddWithWeight(src[fIndices[i]], fTan2Weights[i]);
1141 for (
int i = 0; i < tan1Mask.GetNumEdgeWeights(); ++i) {
1142 dstTan1[vert].AddWithWeight(src[eIndices[i]], eTan1Weights[i]);
1143 dstTan2[vert].AddWithWeight(src[eIndices[i]], eTan2Weights[i]);
1145 dstTan1[vert].AddWithWeight(src[vert], vTan1Weights[0]);
1146 dstTan2[vert].AddWithWeight(src[vert], vTan2Weights[0]);
1151 template <
typename REAL>
1152 template <Sdc::SchemeType SCHEME,
class T,
class U>
1181 if (isIncomplete || fvarChannel.
isLinear()) {
1182 for (
int i = 0; i < vValues.
size(); ++i) {
1185 dst[vValue].Clear();
1186 dst[vValue].AddWithWeight(src[vValue], 1.0f);
1192 if (fvarVertMatchesVertex) {
1196 Weight * vWeights = weightBuffer,
1197 * eWeights = vWeights + 1,
1198 * fWeights = eWeights + vEdges.
size();
1200 Mask vMask(vWeights, eWeights, fWeights);
1202 vHood.SetIndex(vert, vert);
1211 dst[vValue].Clear();
1212 if (vMask.GetNumFaceWeights() > 0) {
1213 assert(!vMask.AreFaceWeightsForFaceCenters());
1218 for (
int i = 0; i < vFaces.size(); ++i) {
1221 if (vOppInFace >= faceValues.
size()) vOppInFace -= faceValues.
size();
1223 Index vValueOppositeFace = faceValues[vOppInFace];
1225 dst[vValue].AddWithWeight(src[vValueOppositeFace], fWeights[i]);
1228 if (vMask.GetNumEdgeWeights() > 0) {
1229 Index * vEdgeValues = vEdgeBuffer;
1232 for (
int i = 0; i < vEdges.
size(); ++i) {
1233 dst[vValue].AddWithWeight(src[vEdgeValues[i]], eWeights[i]);
1236 dst[vValue].AddWithWeight(src[vValue], vWeights[0]);
1241 for (
int i = 0; i < vValues.
size(); ++i) {
1244 dst[vValue].Clear();
1246 dst[vValue].AddWithWeight(src[vValue], 1.0f);
1248 Index vEndValues[2];
1251 dst[vValue].AddWithWeight(src[vEndValues[0]], 1.0f/6.0f);
1252 dst[vValue].AddWithWeight(src[vEndValues[1]], 1.0f/6.0f);
1253 dst[vValue].AddWithWeight(src[vValue], 2.0f/3.0f);
1269 using namespace OPENSUBDIV_VERSION;
Level const & parent() const
ConstIndexArray getVertexFaces(Index vertIndex) const
void ComputeFaceVertexMask(FACE const &faceNeighborhood, MASK &faceVertexMask) const
Face-vertex masks - trivial for all current schemes.
void InterpolateFaceVarying(int level, T const &src, U &dst, int channel=0) const
Apply face-varying interpolation weights to a primvar buffer associated with a particular face-varyin...
float getFractionalWeight(Index pVert, LocalIndex pSibling, Index cVert, LocalIndex cSibling) const
void Limit(T const &src, U &dstPos) const
Apply limit weights to a primvar buffer.
ConstIndexArray getVertexValues(Index vIndex) const
Vtr::LocalIndex LocalIndex
void InterpolateFaceUniform(int level, T const &src, U &dst) const
Refine uniform (per-face) primvar data between levels.
Sdc::Crease::Rule getVertexRule(Index vertIndex) const
float getEdgeSharpness(Index edgeIndex) const
TopologyRefiner const & GetTopologyRefiner() const
int getChildValueParentSource(Index vIndex, int sibling) const
ConstLocalIndexArray getVertexFaceLocalIndices(Index vertIndex) const
ConstIndexArray getFaceValues(Index fIndex) const
FVarRefinement const & getFVarRefinement(int c) const
void ComputeEdgeVertexMask(EDGE const &edgeNeighborhood, MASK &edgeVertexMask, Crease::Rule parentRule=Crease::RULE_UNKNOWN, Crease::Rule childRule=Crease::RULE_UNKNOWN) const
Edge-vertex masks If known, the Rule for the edge and/or the derived vertex can be specified to accel...
FVarLevel & getFVarLevel(int channel)
int getMaxValence() const
void InterpolateVarying(int level, T const &src, U &dst) const
Apply only varying interpolation weights to a primvar buffer for a single level of refinement...
void getVertexEdgeValues(Index vIndex, Index valuesPerEdge[]) const
void Interpolate(int level, T const &src, U &dst) const
Apply vertex interpolation weights to a primvar buffer for a single level of refinement.
void SetIndex(int edgeIndex)
void ComputeVertexVertexMask(VERTEX const &vertexNeighborhood, MASK &vertexVertexMask, Crease::Rule parentRule=Crease::RULE_UNKNOWN, Crease::Rule childRule=Crease::RULE_UNKNOWN) const
Vertex-vertex masks If known, a single Rule or pair of Rules can be specified (indicating a crease tr...
Index getEdgeChildVertex(Index e) const
bool IndexIsValid(Index index)
ConstIndexArray getFaceVertices(Index faceIndex) const
void LimitFaceVarying(T const &src, U &dst, int channel=0) const
int getNumVertices() const
Index getVertexValueOffset(Index v, Sibling i=0) const
ConstValueTagArray getVertexValueTags(Index vIndex) const
void ComputeVertexLimitMask(VERTEX const &vertexNeighborhood, MASK &positionMask, Crease::Rule vertexRule) const
Limit masks for vertices – position and tangents These presume that a vertex is suitably isolated fo...
Stores topology data for a specified set of refinement options.
void Error(ErrorType err, const char *format,...)
Sends an OSD error with a message (internal use only)
ValueTag getValueTag(Index valueIndex) const
Issue a generic runtime error, but continue execution.
int getMaxEdgeFaces() const
Index getFaceChildVertex(Index f) const
int getNumChildVerticesFromFaces() const
Applies refinement operations to generic primvar data.
ConstIndexArray getFaceEdges(Index faceIndex) const
ConstIndexArray getEdgeVertices(Index edgeIndex) const
PrimvarRefiner(TopologyRefiner const &refiner)
ConstIndexArray getEdgeFaces(Index edgeIndex) const
void getEdgeFaceValues(Index eIndex, int fIncToEdge, Index valuesPerVert[2]) const
void getVertexCreaseEndValues(Index vIndex, Sibling sibling, Index endValues[2]) const
PrimvarRefinerReal(TopologyRefiner const &refiner)
Level const & child() const
bool valueTopologyMatches(Index valueIndex) const
void SetIndex(int parentIndex, int childIndex)
Scheme is a class template which provides all implementation for the subdivision schemes supported by...
VTag const & getVertexTag(Index vertIndex) const
Index getVertexChildVertex(Index v) const
ConstIndexArray getVertexEdges(Index vertIndex) const