161 void Limit(T
const & src, U & dstPos, U1 & dstTan1, U2 & dstTan2)
const;
163 template <
class T,
class U>
void LimitFaceVarying(T
const & src, U & dst,
int channel = 0)
const;
174 template <Sdc::SchemeType SCHEME,
class T,
class U>
void interpFromFaces(
int, T
const &, U &)
const;
175 template <Sdc::SchemeType SCHEME,
class T,
class U>
void interpFromEdges(
int, T
const &, U &)
const;
176 template <Sdc::SchemeType SCHEME,
class T,
class U>
void interpFromVerts(
int, T
const &, U &)
const;
178 template <Sdc::SchemeType SCHEME,
class T,
class U>
void interpFVarFromFaces(
int, T
const &, U &,
int)
const;
179 template <Sdc::SchemeType SCHEME,
class T,
class U>
void interpFVarFromEdges(
int, T
const &, U &,
int)
const;
180 template <Sdc::SchemeType SCHEME,
class T,
class U>
void interpFVarFromVerts(
int, T
const &, U &,
int)
const;
182 template <Sdc::SchemeType SCHEME,
class T,
class U,
class U1,
class U2>
183 void limit(T
const & src, U & pos, U1 * tan1, U2 * tan2)
const;
185 template <Sdc::SchemeType SCHEME,
class T,
class U>
186 void limitFVar(T
const & src, U & dst,
int channel)
const;
189 TopologyRefiner
const & _refiner;
200 Mask(Weight* v, Weight* e, Weight* f) :
201 _vertWeights(v), _edgeWeights(e), _faceWeights(f),
202 _vertCount(0), _edgeCount(0), _faceCount(0),
203 _faceWeightsForFaceCenters(false)
209 int GetNumVertexWeights()
const {
return _vertCount; }
210 int GetNumEdgeWeights()
const {
return _edgeCount; }
211 int GetNumFaceWeights()
const {
return _faceCount; }
213 void SetNumVertexWeights(
int count) { _vertCount = count; }
214 void SetNumEdgeWeights(
int count) { _edgeCount = count; }
215 void SetNumFaceWeights(
int count) { _faceCount = count; }
217 Weight
const& VertexWeight(
int index)
const {
return _vertWeights[index]; }
218 Weight
const& EdgeWeight(
int index)
const {
return _edgeWeights[index]; }
219 Weight
const& FaceWeight(
int index)
const {
return _faceWeights[index]; }
221 Weight& VertexWeight(
int index) {
return _vertWeights[index]; }
222 Weight& EdgeWeight(
int index) {
return _edgeWeights[index]; }
223 Weight& FaceWeight(
int index) {
return _faceWeights[index]; }
225 bool AreFaceWeightsForFaceCenters()
const {
return _faceWeightsForFaceCenters; }
226 void SetFaceWeightsForFaceCenters(
bool on) { _faceWeightsForFaceCenters = on; }
229 Weight* _vertWeights;
230 Weight* _edgeWeights;
231 Weight* _faceWeights;
237 bool _faceWeightsForFaceCenters;
247template <
typename REAL>
248template <
class T,
class U>
252 assert(level>0 && level<=(
int)_refiner._refinements.size());
254 switch (_refiner._subdivType) {
256 interpFromFaces<Sdc::SCHEME_CATMARK>(level, src, dst);
257 interpFromEdges<Sdc::SCHEME_CATMARK>(level, src, dst);
258 interpFromVerts<Sdc::SCHEME_CATMARK>(level, src, dst);
261 interpFromFaces<Sdc::SCHEME_LOOP>(level, src, dst);
262 interpFromEdges<Sdc::SCHEME_LOOP>(level, src, dst);
263 interpFromVerts<Sdc::SCHEME_LOOP>(level, src, dst);
266 interpFromFaces<Sdc::SCHEME_BILINEAR>(level, src, dst);
267 interpFromEdges<Sdc::SCHEME_BILINEAR>(level, src, dst);
268 interpFromVerts<Sdc::SCHEME_BILINEAR>(level, src, dst);
273template <
typename REAL>
274template <
class T,
class U>
278 assert(level>0 && level<=(
int)_refiner._refinements.size());
280 switch (_refiner._subdivType) {
282 interpFVarFromFaces<Sdc::SCHEME_CATMARK>(level, src, dst, channel);
283 interpFVarFromEdges<Sdc::SCHEME_CATMARK>(level, src, dst, channel);
284 interpFVarFromVerts<Sdc::SCHEME_CATMARK>(level, src, dst, channel);
287 interpFVarFromFaces<Sdc::SCHEME_LOOP>(level, src, dst, channel);
288 interpFVarFromEdges<Sdc::SCHEME_LOOP>(level, src, dst, channel);
289 interpFVarFromVerts<Sdc::SCHEME_LOOP>(level, src, dst, channel);
292 interpFVarFromFaces<Sdc::SCHEME_BILINEAR>(level, src, dst, channel);
293 interpFVarFromEdges<Sdc::SCHEME_BILINEAR>(level, src, dst, channel);
294 interpFVarFromVerts<Sdc::SCHEME_BILINEAR>(level, src, dst, channel);
299template <
typename REAL>
300template <
class T,
class U>
304 if (_refiner.getLevel(_refiner.GetMaxLevel()).getNumVertexEdgesTotal() == 0) {
306 "Failure in PrimvarRefiner::Limit() -- "
307 "last level of refinement does not include full topology.");
311 switch (_refiner._subdivType) {
313 limit<Sdc::SCHEME_CATMARK>(src, dst, (U*)0, (U*)0);
316 limit<Sdc::SCHEME_LOOP>(src, dst, (U*)0, (U*)0);
319 limit<Sdc::SCHEME_BILINEAR>(src, dst, (U*)0, (U*)0);
324template <
typename REAL>
325template <
class T,
class U,
class U1,
class U2>
329 if (_refiner.getLevel(_refiner.GetMaxLevel()).getNumVertexEdgesTotal() == 0) {
331 "Failure in PrimvarRefiner::Limit() -- "
332 "last level of refinement does not include full topology.");
336 switch (_refiner._subdivType) {
338 limit<Sdc::SCHEME_CATMARK>(src, dstPos, &dstTan1, &dstTan2);
341 limit<Sdc::SCHEME_LOOP>(src, dstPos, &dstTan1, &dstTan2);
344 limit<Sdc::SCHEME_BILINEAR>(src, dstPos, &dstTan1, &dstTan2);
349template <
typename REAL>
350template <
class T,
class U>
354 if (_refiner.getLevel(_refiner.GetMaxLevel()).getNumVertexEdgesTotal() == 0) {
356 "Failure in PrimvarRefiner::LimitFaceVarying() -- "
357 "last level of refinement does not include full topology.");
361 switch (_refiner._subdivType) {
363 limitFVar<Sdc::SCHEME_CATMARK>(src, dst, channel);
366 limitFVar<Sdc::SCHEME_LOOP>(src, dst, channel);
369 limitFVar<Sdc::SCHEME_BILINEAR>(src, dst, channel);
374template <
typename REAL>
375template <
class T,
class U>
379 assert(level>0 && level<=(
int)_refiner._refinements.size());
381 Vtr::internal::Refinement
const & refinement = _refiner.getRefinement(level-1);
382 Vtr::internal::Level
const & child = refinement.child();
384 for (
int cFace = 0; cFace < child.getNumFaces(); ++cFace) {
386 Vtr::Index pFace = refinement.getChildFaceParentFace(cFace);
388 dst[cFace] = src[pFace];
392template <
typename REAL>
393template <
class T,
class U>
397 assert(level>0 && level<=(
int)_refiner._refinements.size());
399 Vtr::internal::Refinement
const & refinement = _refiner.getRefinement(level-1);
400 Vtr::internal::Level
const & parent = refinement.parent();
406 if (refinement.getNumChildVerticesFromFaces() > 0) {
408 for (
int face = 0; face < parent.getNumFaces(); ++face) {
410 Vtr::Index cVert = refinement.getFaceChildVertex(face);
416 Weight fVaryingWeight = 1.0f / (Weight) fVerts.
size();
419 for (
int i = 0; i < fVerts.
size(); ++i) {
420 dst[cVert].AddWithWeight(src[fVerts[i]], fVaryingWeight);
425 for (
int edge = 0; edge < parent.getNumEdges(); ++edge) {
427 Vtr::Index cVert = refinement.getEdgeChildVertex(edge);
434 dst[cVert].AddWithWeight(src[eVerts[0]], 0.5f);
435 dst[cVert].AddWithWeight(src[eVerts[1]], 0.5f);
438 for (
int vert = 0; vert < parent.getNumVertices(); ++vert) {
440 Vtr::Index cVert = refinement.getVertexChildVertex(vert);
445 dst[cVert].AddWithWeight(src[vert], 1.0f);
455template <
typename REAL>
456template <Sdc::SchemeType SCHEME,
class T,
class U>
460 Vtr::internal::Refinement
const & refinement = _refiner.getRefinement(level-1);
461 Vtr::internal::Level
const & parent = refinement.parent();
463 if (refinement.getNumChildVerticesFromFaces() == 0)
return;
467 Vtr::internal::StackBuffer<Weight,16> fVertWeights(parent.getMaxValence());
469 for (
int face = 0; face < parent.getNumFaces(); ++face) {
471 Vtr::Index cVert = refinement.getFaceChildVertex(face);
478 Mask fMask(fVertWeights, 0, 0);
479 Vtr::internal::FaceInterface fHood(fVerts.
size());
481 scheme.ComputeFaceVertexMask(fHood, fMask);
486 for (
int i = 0; i < fVerts.
size(); ++i) {
488 dst[cVert].AddWithWeight(src[fVerts[i]], fVertWeights[i]);
493template <
typename REAL>
494template <Sdc::SchemeType SCHEME,
class T,
class U>
496PrimvarRefinerReal<REAL>::interpFromEdges(
int level, T
const & src, U & dst)
const {
498 Vtr::internal::Refinement
const & refinement = _refiner.getRefinement(level-1);
499 Vtr::internal::Level
const & parent = refinement.parent();
500 Vtr::internal::Level
const & child = refinement.child();
502 Sdc::Scheme<SCHEME> scheme(_refiner._subdivOptions);
504 Vtr::internal::EdgeInterface eHood(parent);
506 Weight eVertWeights[2];
507 Vtr::internal::StackBuffer<Weight,8> eFaceWeights(parent.getMaxEdgeFaces());
509 for (
int edge = 0; edge < parent.getNumEdges(); ++edge) {
511 Vtr::Index cVert = refinement.getEdgeChildVertex(edge);
517 eFaces = parent.getEdgeFaces(edge);
519 Mask eMask(eVertWeights, 0, eFaceWeights);
521 eHood.SetIndex(edge);
526 scheme.ComputeEdgeVertexMask(eHood, eMask, pRule, cRule);
531 dst[cVert].AddWithWeight(src[eVerts[0]], eVertWeights[0]);
532 dst[cVert].AddWithWeight(src[eVerts[1]], eVertWeights[1]);
534 if (eMask.GetNumFaceWeights() > 0) {
536 for (
int i = 0; i < eFaces.size(); ++i) {
538 if (eMask.AreFaceWeightsForFaceCenters()) {
539 assert(refinement.getNumChildVerticesFromFaces() > 0);
540 Vtr::Index cVertOfFace = refinement.getFaceChildVertex(eFaces[i]);
543 dst[cVert].AddWithWeight(dst[cVertOfFace], eFaceWeights[i]);
547 pFaceVerts = parent.getFaceVertices(pFace);
550 for ( ; pFaceEdges[eInFace] != edge; ++eInFace ) ;
552 int vInFace = eInFace + 2;
553 if (vInFace >= pFaceVerts.size()) vInFace -= pFaceVerts.
size();
556 dst[cVert].AddWithWeight(src[pVertNext], eFaceWeights[i]);
563template <
typename REAL>
564template <Sdc::SchemeType SCHEME,
class T,
class U>
566PrimvarRefinerReal<REAL>::interpFromVerts(
int level, T
const & src, U & dst)
const {
568 Vtr::internal::Refinement
const & refinement = _refiner.getRefinement(level-1);
569 Vtr::internal::Level
const & parent = refinement.parent();
570 Vtr::internal::Level
const & child = refinement.child();
572 Sdc::Scheme<SCHEME> scheme(_refiner._subdivOptions);
574 Vtr::internal::VertexInterface vHood(parent, child);
576 Vtr::internal::StackBuffer<Weight,32> weightBuffer(2*parent.getMaxValence());
578 for (
int vert = 0; vert < parent.getNumVertices(); ++vert) {
580 Vtr::Index cVert = refinement.getVertexChildVertex(vert);
586 vFaces = parent.getVertexFaces(vert);
589 * vEdgeWeights = weightBuffer,
590 * vFaceWeights = vEdgeWeights + vEdges.
size();
592 Mask vMask(&vVertWeight, vEdgeWeights, vFaceWeights);
594 vHood.SetIndex(vert, cVert);
599 scheme.ComputeVertexVertexMask(vHood, vMask, pRule, cRule);
609 if (vMask.GetNumFaceWeights() > 0) {
610 assert(vMask.AreFaceWeightsForFaceCenters());
612 for (
int i = 0; i < vFaces.size(); ++i) {
614 Vtr::Index cVertOfFace = refinement.getFaceChildVertex(vFaces[i]);
616 dst[cVert].AddWithWeight(dst[cVertOfFace], vFaceWeights[i]);
619 if (vMask.GetNumEdgeWeights() > 0) {
621 for (
int i = 0; i < vEdges.size(); ++i) {
624 Vtr::Index pVertOppositeEdge = (eVerts[0] == vert) ? eVerts[1] : eVerts[0];
626 dst[cVert].AddWithWeight(src[pVertOppositeEdge], vEdgeWeights[i]);
629 dst[cVert].AddWithWeight(src[vert], vVertWeight);
637template <
typename REAL>
638template <Sdc::SchemeType SCHEME,
class T,
class U>
640PrimvarRefinerReal<REAL>::interpFVarFromFaces(
int level, T
const & src, U & dst,
int channel)
const {
642 Vtr::internal::Refinement
const & refinement = _refiner.getRefinement(level-1);
644 if (refinement.getNumChildVerticesFromFaces() == 0)
return;
646 Sdc::Scheme<SCHEME> scheme(_refiner._subdivOptions);
648 Vtr::internal::Level
const & parentLevel = refinement.parent();
649 Vtr::internal::Level
const & childLevel = refinement.child();
651 Vtr::internal::FVarLevel
const & parentFVar = parentLevel.getFVarLevel(channel);
652 Vtr::internal::FVarLevel
const & childFVar = childLevel.getFVarLevel(channel);
654 Vtr::internal::StackBuffer<Weight,16> fValueWeights(parentLevel.getMaxValence());
656 for (
int face = 0; face < parentLevel.getNumFaces(); ++face) {
658 Vtr::Index cVert = refinement.getFaceChildVertex(face);
662 Vtr::Index cVertValue = childFVar.getVertexValueOffset(cVert);
672 Mask fMask(fValueWeights, 0, 0);
673 Vtr::internal::FaceInterface fHood(fValues.size());
675 scheme.ComputeFaceVertexMask(fHood, fMask);
678 dst[cVertValue].Clear();
680 for (
int i = 0; i < fValues.size(); ++i) {
681 dst[cVertValue].AddWithWeight(src[fValues[i]], fValueWeights[i]);
686template <
typename REAL>
687template <Sdc::SchemeType SCHEME,
class T,
class U>
689PrimvarRefinerReal<REAL>::interpFVarFromEdges(
int level, T
const & src, U & dst,
int channel)
const {
691 Vtr::internal::Refinement
const & refinement = _refiner.getRefinement(level-1);
693 Sdc::Scheme<SCHEME> scheme(_refiner._subdivOptions);
695 Vtr::internal::Level
const & parentLevel = refinement.parent();
696 Vtr::internal::Level
const & childLevel = refinement.child();
698 Vtr::internal::FVarRefinement
const & refineFVar = refinement.getFVarRefinement(channel);
699 Vtr::internal::FVarLevel
const & parentFVar = parentLevel.getFVarLevel(channel);
700 Vtr::internal::FVarLevel
const & childFVar = childLevel.getFVarLevel(channel);
706 Weight eVertWeights[2];
707 Vtr::internal::StackBuffer<Weight,8> eFaceWeights(parentLevel.getMaxEdgeFaces());
709 Mask eMask(eVertWeights, 0, eFaceWeights);
713 eMask.SetNumVertexWeights(2);
714 eMask.SetNumEdgeWeights(0);
715 eMask.SetNumFaceWeights(0);
717 eVertWeights[0] = 0.5f;
718 eVertWeights[1] = 0.5f;
721 Vtr::internal::EdgeInterface eHood(parentLevel);
723 for (
int edge = 0; edge < parentLevel.getNumEdges(); ++edge) {
725 Vtr::Index cVert = refinement.getEdgeChildVertex(edge);
731 bool fvarEdgeVertMatchesVertex = childFVar.valueTopologyMatches(cVertValues[0]);
732 if (fvarEdgeVertMatchesVertex) {
737 eHood.SetIndex(edge);
743 scheme.ComputeEdgeVertexMask(eHood, eMask, pRule, cRule);
768 parentFVar.getEdgeFaceValues(edge, 0, eVertValues);
770 Index cVertValue = cVertValues[0];
772 dst[cVertValue].Clear();
773 dst[cVertValue].AddWithWeight(src[eVertValues[0]], eVertWeights[0]);
774 dst[cVertValue].AddWithWeight(src[eVertValues[1]], eVertWeights[1]);
776 if (eMask.GetNumFaceWeights() > 0) {
780 for (
int i = 0; i < eFaces.size(); ++i) {
781 if (eMask.AreFaceWeightsForFaceCenters()) {
783 Vtr::Index cVertOfFace = refinement.getFaceChildVertex(eFaces[i]);
786 Vtr::Index cValueOfFace = childFVar.getVertexValueOffset(cVertOfFace);
787 dst[cVertValue].AddWithWeight(dst[cValueOfFace], eFaceWeights[i]);
791 pFaceVerts = parentLevel.getFaceVertices(pFace);
794 for ( ; pFaceEdges[eInFace] != edge; ++eInFace ) ;
797 int vInFace = eInFace + 2;
798 if (vInFace >= pFaceVerts.size()) vInFace -= pFaceVerts.
size();
800 Vtr::Index pValueNext = parentFVar.getFaceValues(pFace)[vInFace];
801 dst[cVertValue].AddWithWeight(src[pValueNext], eFaceWeights[i]);
814 for (
int i = 0; i < cVertValues.size(); ++i) {
816 int eFaceIndex = refineFVar.getChildValueParentSource(cVert, i);
817 assert(eFaceIndex == i);
819 parentFVar.getEdgeFaceValues(edge, eFaceIndex, eVertValues);
821 Index cVertValue = cVertValues[i];
823 dst[cVertValue].Clear();
824 dst[cVertValue].AddWithWeight(src[eVertValues[0]], 0.5);
825 dst[cVertValue].AddWithWeight(src[eVertValues[1]], 0.5);
831template <
typename REAL>
832template <Sdc::SchemeType SCHEME,
class T,
class U>
834PrimvarRefinerReal<REAL>::interpFVarFromVerts(
int level, T
const & src, U & dst,
int channel)
const {
836 Vtr::internal::Refinement
const & refinement = _refiner.getRefinement(level-1);
838 Sdc::Scheme<SCHEME> scheme(_refiner._subdivOptions);
840 Vtr::internal::Level
const & parentLevel = refinement.parent();
841 Vtr::internal::Level
const & childLevel = refinement.child();
843 Vtr::internal::FVarRefinement
const & refineFVar = refinement.getFVarRefinement(channel);
844 Vtr::internal::FVarLevel
const & parentFVar = parentLevel.getFVarLevel(channel);
845 Vtr::internal::FVarLevel
const & childFVar = childLevel.getFVarLevel(channel);
849 Vtr::internal::StackBuffer<Weight,32> weightBuffer(2*parentLevel.getMaxValence());
851 Vtr::internal::StackBuffer<Vtr::Index,16> vEdgeValues(parentLevel.getMaxValence());
853 Vtr::internal::VertexInterface vHood(parentLevel, childLevel);
855 for (
int vert = 0; vert < parentLevel.getNumVertices(); ++vert) {
857 Vtr::Index cVert = refinement.getVertexChildVertex(vert);
862 cVertValues = childFVar.getVertexValues(cVert);
864 bool fvarVertVertMatchesVertex = childFVar.valueTopologyMatches(cVertValues[0]);
865 if (isLinearFVar && fvarVertVertMatchesVertex) {
866 dst[cVertValues[0]].Clear();
867 dst[cVertValues[0]].AddWithWeight(src[pVertValues[0]], 1.0f);
871 if (fvarVertVertMatchesVertex) {
881 Weight * vEdgeWeights = weightBuffer;
882 Weight * vFaceWeights = vEdgeWeights + vEdges.
size();
884 Mask vMask(&vVertWeight, vEdgeWeights, vFaceWeights);
886 vHood.SetIndex(vert, cVert);
891 scheme.ComputeVertexVertexMask(vHood, vMask, pRule, cRule);
920 dst[cVertValue].Clear();
921 if (vMask.GetNumFaceWeights() > 0) {
922 assert(vMask.AreFaceWeightsForFaceCenters());
926 for (
int i = 0; i < vFaces.size(); ++i) {
928 Vtr::Index cVertOfFace = refinement.getFaceChildVertex(vFaces[i]);
931 Vtr::Index cValueOfFace = childFVar.getVertexValueOffset(cVertOfFace);
932 dst[cVertValue].AddWithWeight(dst[cValueOfFace], vFaceWeights[i]);
935 if (vMask.GetNumEdgeWeights() > 0) {
937 parentFVar.getVertexEdgeValues(vert, vEdgeValues);
939 for (
int i = 0; i < vEdges.size(); ++i) {
940 dst[cVertValue].AddWithWeight(src[vEdgeValues[i]], vEdgeWeights[i]);
943 dst[cVertValue].AddWithWeight(src[pVertValue], vVertWeight);
952 Vtr::internal::FVarLevel::ConstValueTagArray pValueTags = parentFVar.getVertexValueTags(vert);
953 Vtr::internal::FVarLevel::ConstValueTagArray cValueTags = childFVar.getVertexValueTags(cVert);
955 for (
int cSiblingIndex = 0; cSiblingIndex < cVertValues.size(); ++cSiblingIndex) {
956 int pSiblingIndex = refineFVar.getChildValueParentSource(cVert, cSiblingIndex);
957 assert(pSiblingIndex == cSiblingIndex);
959 typedef Vtr::internal::FVarLevel::Sibling SiblingIntType;
961 SiblingIntType cSibling = (SiblingIntType) cSiblingIndex;
962 SiblingIntType pSibling = (SiblingIntType) pSiblingIndex;
964 Vtr::Index pVertValue = pVertValues[pSibling];
965 Vtr::Index cVertValue = cVertValues[cSibling];
967 dst[cVertValue].Clear();
968 if (isLinearFVar || cValueTags[cSibling].isCorner()) {
969 dst[cVertValue].AddWithWeight(src[pVertValue], 1.0f);
976 parentFVar.getVertexCreaseEndValues(vert, pSibling, pEndValues);
978 Weight vWeight = 0.75f;
979 Weight eWeight = 0.125f;
986 if (pValueTags[pSibling].isSemiSharp()) {
987 Weight wCorner = pValueTags[pSibling].isDepSharp()
988 ? refineFVar.getFractionalWeight(vert, !pSibling, cVert, !cSibling)
989 : refineFVar.getFractionalWeight(vert, pSibling, cVert, cSibling);
990 Weight wCrease = 1.0f - wCorner;
992 vWeight = wCrease * 0.75f + wCorner;
993 eWeight = wCrease * 0.125f;
995 dst[cVertValue].AddWithWeight(src[pEndValues[0]], eWeight);
996 dst[cVertValue].AddWithWeight(src[pEndValues[1]], eWeight);
997 dst[cVertValue].AddWithWeight(src[pVertValue], vWeight);
1004template <
typename REAL>
1005template <Sdc::SchemeType SCHEME,
class T,
class U,
class U1,
class U2>
1007PrimvarRefinerReal<REAL>::limit(T
const & src, U & dstPos, U1 * dstTan1Ptr, U2 * dstTan2Ptr)
const {
1009 Sdc::Scheme<SCHEME> scheme(_refiner._subdivOptions);
1011 Vtr::internal::Level
const & level = _refiner.getLevel(_refiner.GetMaxLevel());
1013 int maxWeightsPerMask = 1 + 2 * level.getMaxValence();
1014 bool hasTangents = (dstTan1Ptr && dstTan2Ptr);
1015 int numMasks = 1 + (hasTangents ? 2 : 0);
1017 Vtr::internal::StackBuffer<Index,33> indexBuffer(maxWeightsPerMask);
1018 Vtr::internal::StackBuffer<Weight,99> weightBuffer(numMasks * maxWeightsPerMask);
1020 Weight * vPosWeights = weightBuffer,
1021 * ePosWeights = vPosWeights + 1,
1022 * fPosWeights = ePosWeights + level.getMaxValence();
1023 Weight * vTan1Weights = vPosWeights + maxWeightsPerMask,
1024 * eTan1Weights = ePosWeights + maxWeightsPerMask,
1025 * fTan1Weights = fPosWeights + maxWeightsPerMask;
1026 Weight * vTan2Weights = vTan1Weights + maxWeightsPerMask,
1027 * eTan2Weights = eTan1Weights + maxWeightsPerMask,
1028 * fTan2Weights = fTan1Weights + maxWeightsPerMask;
1030 Mask posMask( vPosWeights, ePosWeights, fPosWeights);
1031 Mask tan1Mask(vTan1Weights, eTan1Weights, fTan1Weights);
1032 Mask tan2Mask(vTan2Weights, eTan2Weights, fTan2Weights);
1036 Vtr::internal::VertexInterface vHood(level, level);
1038 for (
int vert = 0; vert < level.getNumVertices(); ++vert) {
1044 if (level.getVertexTag(vert)._incomplete || (vEdges.size() == 0)) {
1045 dstPos[vert].Clear();
1046 dstPos[vert].AddWithWeight(src[vert], 1.0);
1048 (*dstTan1Ptr)[vert].Clear();
1049 (*dstTan2Ptr)[vert].Clear();
1062 vHood.SetIndex(vert, vert);
1065 scheme.ComputeVertexLimitMask(vHood, posMask, tan1Mask, tan2Mask, vRule);
1067 scheme.ComputeVertexLimitMask(vHood, posMask, vRule);
1074 Index * eIndices = indexBuffer;
1075 Index * fIndices = indexBuffer + vEdges.
size();
1077 for (
int i = 0; i < vEdges.size(); ++i) {
1080 eIndices[i] = (eVerts[0] == vert) ? eVerts[1] : eVerts[0];
1082 if (posMask.GetNumFaceWeights() || (hasTangents && tan1Mask.GetNumFaceWeights())) {
1086 for (
int i = 0; i < vFaces.size(); ++i) {
1090 if (vOppInFace >= fVerts.size()) vOppInFace -= (
LocalIndex)fVerts.
size();
1092 fIndices[i] = level.getFaceVertices(vFaces[i])[vOppInFace];
1102 dstPos[vert].Clear();
1103 for (
int i = 0; i < posMask.GetNumFaceWeights(); ++i) {
1104 dstPos[vert].AddWithWeight(src[fIndices[i]], fPosWeights[i]);
1106 for (
int i = 0; i < posMask.GetNumEdgeWeights(); ++i) {
1107 dstPos[vert].AddWithWeight(src[eIndices[i]], ePosWeights[i]);
1109 dstPos[vert].AddWithWeight(src[vert], vPosWeights[0]);
1117 assert(tan1Mask.GetNumFaceWeights() == tan2Mask.GetNumFaceWeights());
1118 assert(tan1Mask.GetNumEdgeWeights() == tan2Mask.GetNumEdgeWeights());
1120 U1 & dstTan1 = *dstTan1Ptr;
1121 U2 & dstTan2 = *dstTan2Ptr;
1123 dstTan1[vert].Clear();
1124 dstTan2[vert].Clear();
1125 for (
int i = 0; i < tan1Mask.GetNumFaceWeights(); ++i) {
1126 dstTan1[vert].AddWithWeight(src[fIndices[i]], fTan1Weights[i]);
1127 dstTan2[vert].AddWithWeight(src[fIndices[i]], fTan2Weights[i]);
1129 for (
int i = 0; i < tan1Mask.GetNumEdgeWeights(); ++i) {
1130 dstTan1[vert].AddWithWeight(src[eIndices[i]], eTan1Weights[i]);
1131 dstTan2[vert].AddWithWeight(src[eIndices[i]], eTan2Weights[i]);
1133 dstTan1[vert].AddWithWeight(src[vert], vTan1Weights[0]);
1134 dstTan2[vert].AddWithWeight(src[vert], vTan2Weights[0]);
1139template <
typename REAL>
1140template <Sdc::SchemeType SCHEME,
class T,
class U>
1142PrimvarRefinerReal<REAL>::limitFVar(T
const & src, U & dst,
int channel)
const {
1144 Sdc::Scheme<SCHEME> scheme(_refiner._subdivOptions);
1146 Vtr::internal::Level
const & level = _refiner.getLevel(_refiner.GetMaxLevel());
1147 Vtr::internal::FVarLevel
const & fvarChannel = level.getFVarLevel(channel);
1149 int maxWeightsPerMask = 1 + 2 * level.getMaxValence();
1151 Vtr::internal::StackBuffer<Weight,33> weightBuffer(maxWeightsPerMask);
1152 Vtr::internal::StackBuffer<Index,16> vEdgeBuffer(level.getMaxValence());
1155 Vtr::internal::VertexInterface vHood(level, level);
1157 for (
int vert = 0; vert < level.getNumVertices(); ++vert) {
1168 bool isIncomplete = (level.getVertexTag(vert)._incomplete || (vEdges.size() == 0));
1169 if (isIncomplete || fvarChannel.isLinear()) {
1170 for (
int i = 0; i < vValues.size(); ++i) {
1173 dst[vValue].Clear();
1174 dst[vValue].AddWithWeight(src[vValue], 1.0f);
1179 bool fvarVertMatchesVertex = fvarChannel.valueTopologyMatches(vValues[0]);
1180 if (fvarVertMatchesVertex) {
1184 Weight * vWeights = weightBuffer,
1185 * eWeights = vWeights + 1,
1186 * fWeights = eWeights + vEdges.size();
1188 Mask vMask(vWeights, eWeights, fWeights);
1190 vHood.SetIndex(vert, vert);
1192 scheme.ComputeVertexLimitMask(vHood, vMask, level.getVertexRule(vert));
1199 dst[vValue].Clear();
1200 if (vMask.GetNumFaceWeights() > 0) {
1201 assert(!vMask.AreFaceWeightsForFaceCenters());
1206 for (
int i = 0; i < vFaces.size(); ++i) {
1209 if (vOppInFace >= faceValues.size()) vOppInFace -= faceValues.
size();
1211 Index vValueOppositeFace = faceValues[vOppInFace];
1213 dst[vValue].AddWithWeight(src[vValueOppositeFace], fWeights[i]);
1216 if (vMask.GetNumEdgeWeights() > 0) {
1217 Index * vEdgeValues = vEdgeBuffer;
1218 fvarChannel.getVertexEdgeValues(vert, vEdgeValues);
1220 for (
int i = 0; i < vEdges.size(); ++i) {
1221 dst[vValue].AddWithWeight(src[vEdgeValues[i]], eWeights[i]);
1224 dst[vValue].AddWithWeight(src[vValue], vWeights[0]);
1229 for (
int i = 0; i < vValues.size(); ++i) {
1232 dst[vValue].Clear();
1233 if (fvarChannel.getValueTag(vValue).isCorner()) {
1234 dst[vValue].AddWithWeight(src[vValue], 1.0f);
1236 Index vEndValues[2];
1237 fvarChannel.getVertexCreaseEndValues(vert, i, vEndValues);
1239 dst[vValue].AddWithWeight(src[vEndValues[0]], 1.0f/6.0f);
1240 dst[vValue].AddWithWeight(src[vEndValues[1]], 1.0f/6.0f);
1241 dst[vValue].AddWithWeight(src[vValue], 2.0f/3.0f);
1257using namespace OPENSUBDIV_VERSION;