7#ifndef OPENSUBDIV3_SDC_SCHEME_H
8#define OPENSUBDIV3_SDC_SCHEME_H
10#include "../version.h"
21namespace OPENSUBDIV_VERSION {
48template <SchemeType SCHEME_TYPE>
63 template <
typename FACE,
typename MASK>
81 template <
typename EDGE,
typename MASK>
95 template <
typename VERTEX,
typename MASK>
124 template <
typename VERTEX,
typename MASK>
128 template <
typename VERTEX,
typename MASK>
130 MASK& tangent1Mask, MASK& tangent2Mask,
149 template <
typename EDGE,
typename MASK>
151 template <
typename EDGE,
typename MASK>
154 template <
typename VERTEX,
typename MASK>
156 template <
typename VERTEX,
typename MASK>
158 template <
typename VERTEX,
typename MASK>
164 template <
typename VERTEX,
typename MASK>
166 template <
typename VERTEX,
typename MASK>
168 template <
typename VERTEX,
typename MASK>
171 template <
typename VERTEX,
typename MASK>
173 template <
typename VERTEX,
typename MASK>
175 template <
typename VERTEX,
typename MASK>
191 template <
typename WEIGHT>
230 template <
typename USER_MASK>
242 dst.VertexWeight(0) = dstCoeff * dst.VertexWeight(0) + thisCoeff * this->
VertexWeight(0);
245 if (edgeWeightCount) {
246 if (dst.GetNumEdgeWeights() == 0) {
247 dst.SetNumEdgeWeights(edgeWeightCount);
248 for (
int i = 0; i < edgeWeightCount; ++i) {
249 dst.EdgeWeight(i) = thisCoeff * this->
EdgeWeight(i);
252 for (
int i = 0; i < edgeWeightCount; ++i) {
253 dst.EdgeWeight(i) = dstCoeff * dst.EdgeWeight(i) + thisCoeff * this->
EdgeWeight(i);
259 if (faceWeightCount) {
264 if (dst.GetNumFaceWeights() == 0) {
265 dst.SetNumFaceWeights(faceWeightCount);
268 for (
int i = 0; i < faceWeightCount; ++i) {
269 dst.FaceWeight(i) = thisCoeff * this->
FaceWeight(i);
274 for (
int i = 0; i < faceWeightCount; ++i) {
275 dst.FaceWeight(i) = dstCoeff * dst.FaceWeight(i) + thisCoeff * this->
FaceWeight(i);
288 bool _fWeightsForCenters;
297template <SchemeType SCHEME>
298template <
typename EDGE,
typename MASK>
302 mask.SetNumVertexWeights(2);
303 mask.SetNumEdgeWeights(0);
304 mask.SetNumFaceWeights(0);
305 mask.SetFaceWeightsForFaceCenters(
false);
307 mask.VertexWeight(0) = 0.5f;
308 mask.VertexWeight(1) = 0.5f;
311template <SchemeType SCHEME>
312template <
typename VERTEX,
typename MASK>
316 mask.SetNumVertexWeights(1);
317 mask.SetNumEdgeWeights(0);
318 mask.SetNumFaceWeights(0);
319 mask.SetFaceWeightsForFaceCenters(
false);
321 mask.VertexWeight(0) = 1.0f;
328template <SchemeType SCHEME>
329template <
typename FACE,
typename MASK>
333 int vertCount = face.GetNumVertices();
335 mask.SetNumVertexWeights(vertCount);
336 mask.SetNumEdgeWeights(0);
337 mask.SetNumFaceWeights(0);
338 mask.SetFaceWeightsForFaceCenters(
false);
340 typename MASK::Weight vWeight = 1.0f / (
typename MASK::Weight) vertCount;
341 for (
int i = 0; i < vertCount; ++i) {
342 mask.VertexWeight(i) = vWeight;
372template <SchemeType SCHEME>
373template <
typename EDGE,
typename MASK>
387 assignSmoothMaskForEdge(edge, mask);
391 assignCreaseMaskForEdge(edge, mask);
409 bool childIsCrease =
false;
412 childIsCrease =
true;
413 }
else if (edge.GetSharpness() >= 1.0f) {
415 childIsCrease =
true;
418 childIsCrease =
false;
421 float cEdgeSharpness[2];
422 edge.GetChildSharpnesses(crease, cEdgeSharpness);
423 childIsCrease = (cEdgeSharpness[0] > 0.0f) && (cEdgeSharpness[1] > 0.0f);
426 assignCreaseMaskForEdge(edge, mask);
440 assignSmoothMaskForEdge(edge, mask);
442 typedef typename MASK::Weight Weight;
444 Weight pWeight = edge.GetSharpness();
445 Weight cWeight = 1.0f - pWeight;
447 mask.VertexWeight(0) = pWeight * 0.5f + cWeight * mask.VertexWeight(0);
448 mask.VertexWeight(1) = pWeight * 0.5f + cWeight * mask.VertexWeight(1);
450 int faceCount = mask.GetNumFaceWeights();
451 for (
int i = 0; i < faceCount; ++i) {
452 mask.FaceWeight(i) *= cWeight;
492template <SchemeType SCHEME>
493template <
typename VERTEX,
typename MASK>
502 assignSmoothMaskForVertex(vertex, mask);
509 int valence = vertex.GetNumEdges();
515 float * pEdgeSharpnessBuffer = (
float *)alloca(valence*
sizeof(
float)),
516 * pEdgeSharpness = 0,
517 pVertexSharpness = 0.0f;
522 if (requireParentSharpness) {
523 pVertexSharpness = vertex.GetSharpness();
524 pEdgeSharpness = vertex.GetSharpnessPerEdge(pEdgeSharpnessBuffer);
531 assignSmoothMaskForVertex(vertex, mask);
537 assignCreaseMaskForVertex(vertex, mask, creaseEnds);
539 assignCornerMaskForVertex(vertex, mask);
541 if (cRule == pRule)
return;
548 float * cEdgeSharpnessBuffer = (
float *)alloca(valence*
sizeof(
float)),
549 * cEdgeSharpness = vertex.GetChildSharpnessPerEdge(crease, cEdgeSharpnessBuffer),
550 cVertexSharpness = vertex.GetChildSharpness(crease);
554 if (cRule == pRule)
return;
561 typedef typename MASK::Weight Weight;
563 Weight * cMaskWeights = (Weight *)alloca((1 + 2 * valence)*
sizeof(Weight));
564 LocalMask<Weight> cMask(cMaskWeights, cMaskWeights + 1, cMaskWeights + 1 + valence);
567 assignSmoothMaskForVertex(vertex, cMask);
572 assignCreaseMaskForVertex(vertex, cMask, creaseEnds);
574 assignCornerMaskForVertex(vertex, cMask);
578 valence, pEdgeSharpness, cEdgeSharpness);
579 Weight cWeight = 1.0f - pWeight;
587template <SchemeType SCHEME>
588template <
typename VERTEX,
typename MASK>
595 assignSmoothLimitMask(vertex, mask);
597 float * edgeSharpness = (
float *)alloca(vertex.GetNumEdges() *
sizeof(
float));
598 vertex.GetSharpnessPerEdge(edgeSharpness);
603 assignCreaseLimitMask(vertex, mask, creaseEnds);
605 assignCornerLimitMask(vertex, mask);
609template <SchemeType SCHEME>
610template <
typename VERTEX,
typename MASK>
619 assignSmoothLimitMask(vertex, posMask);
620 assignSmoothLimitTangentMasks(vertex, tan1Mask, tan2Mask);
622 float * edgeSharpness = (
float *)alloca(vertex.GetNumEdges() *
sizeof(
float));
623 vertex.GetSharpnessPerEdge(edgeSharpness);
628 assignCreaseLimitMask(vertex, posMask, creaseEnds);
629 assignCreaseLimitTangentMasks(vertex, tan1Mask, tan2Mask, creaseEnds);
631 assignCornerLimitMask(vertex, posMask);
632 assignCornerLimitTangentMasks(vertex, tan1Mask, tan2Mask);
640using namespace OPENSUBDIV_VERSION;
Split
Enumerated type for all face splitting schemes.
Types, constants and utilities related to semi-sharp creasing – whose implementation is independent o...
void GetSharpEdgePairOfCrease(float const *incidentEdgeSharpness, int incidentEdgeCount, int sharpEdgePair[2]) const
Rule DetermineVertexVertexRule(float vertexSharpness, int incidentEdgeCount, float const *incidentEdgeSharpness) const
float ComputeFractionalWeightAtVertex(float vertexSharpness, float childVertexSharpness, int incidentEdgeCount, float const *incidentEdgeSharpness, float const *childEdgesSharpness) const
Transitional weighting: When the rules applicable to a parent vertex and its child differ,...
All supported options applying to subdivision scheme.
Scheme is a class template which provides all implementation for the subdivision schemes supported by...
void assignSmoothMaskForEdge(EDGE const &edge, MASK &mask) const
static Split GetTopologicalSplitType()
void assignCreaseMaskForVertex(VERTEX const &edge, MASK &mask, int const creaseEnds[2]) const
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...
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 for...
void assignCreaseLimitTangentMasks(VERTEX const &vertex, MASK &tan1, MASK &tan2, int const creaseEnds[2]) const
static int GetRegularFaceSize()
void assignCreaseMaskForEdge(EDGE const &edge, MASK &mask) 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...
void assignSmoothLimitMask(VERTEX const &vertex, MASK &pos) const
static int GetLocalNeighborhoodSize()
void assignCornerMaskForVertex(VERTEX const &edge, MASK &mask) const
void assignCreaseLimitMask(VERTEX const &vertex, MASK &pos, int const creaseEnds[2]) const
void assignSmoothMaskForVertex(VERTEX const &edge, MASK &mask) const
static int GetRegularVertexValence()
Options GetOptions() const
void assignSmoothLimitTangentMasks(VERTEX const &vertex, MASK &tan1, MASK &tan2) const
void assignCornerLimitMask(VERTEX const &vertex, MASK &pos) const
Scheme(Options const &options)
void ComputeFaceVertexMask(FACE const &faceNeighborhood, MASK &faceVertexMask) const
Face-vertex masks - trivial for all current schemes.
void assignCornerLimitTangentMasks(VERTEX const &vertex, MASK &tan1, MASK &tan2) const
void SetOptions(const Options &newOptions)
bool AreFaceWeightsForFaceCenters() const
void SetNumEdgeWeights(int count)
Weight const & EdgeWeight(int index) const
Weight & EdgeWeight(int index)
void CombineVertexVertexMasks(Weight thisCoeff, Weight dstCoeff, USER_MASK &dst) const
int GetNumVertexWeights() const
void SetNumFaceWeights(int count)
Weight const & FaceWeight(int index) const
int GetNumEdgeWeights() const
Weight & VertexWeight(int index)
int GetNumFaceWeights() const
void SetFaceWeightsForFaceCenters(bool on)
void SetNumVertexWeights(int count)
LocalMask(Weight *v, Weight *e, Weight *f)
Weight const & VertexWeight(int index) const
Weight & FaceWeight(int index)