24 #ifndef OPENSUBDIV3_SDC_LOOP_SCHEME_H
25 #define OPENSUBDIV3_SDC_LOOP_SCHEME_H
27 #include "../version.h"
29 #include "../sdc/scheme.h"
34 namespace OPENSUBDIV_VERSION {
67 template <
typename EDGE,
typename MASK>
71 mask.SetNumVertexWeights(2);
72 mask.SetNumEdgeWeights(0);
73 mask.SetNumFaceWeights(0);
74 mask.SetFaceWeightsForFaceCenters(
false);
76 mask.VertexWeight(0) = 0.5f;
77 mask.VertexWeight(1) = 0.5f;
81 template <
typename EDGE,
typename MASK>
85 int faceCount = edge.GetNumFaces();
87 mask.SetNumVertexWeights(2);
88 mask.SetNumEdgeWeights(0);
89 mask.SetNumFaceWeights(faceCount);
90 mask.SetFaceWeightsForFaceCenters(
false);
109 typedef typename MASK::Weight Weight;
111 Weight vWeight = mask.AreFaceWeightsForFaceCenters() ? 0.125f : 0.375f;
112 Weight fWeight = mask.AreFaceWeightsForFaceCenters() ? 0.375f : 0.125f;
114 mask.VertexWeight(0) = vWeight;
115 mask.VertexWeight(1) = vWeight;
117 if (faceCount == 2) {
118 mask.FaceWeight(0) = fWeight;
119 mask.FaceWeight(1) = fWeight;
123 fWeight *= 2.0f / (Weight) faceCount;
124 for (
int i = 0; i < faceCount; ++i) {
125 mask.FaceWeight(i) = fWeight;
139 template <
typename VERTEX,
typename MASK>
143 mask.SetNumVertexWeights(1);
144 mask.SetNumEdgeWeights(0);
145 mask.SetNumFaceWeights(0);
146 mask.SetFaceWeightsForFaceCenters(
false);
148 mask.VertexWeight(0) = 1.0f;
152 template <
typename VERTEX,
typename MASK>
155 int const creaseEnds[2])
const {
156 typedef typename MASK::Weight Weight;
158 int valence = vertex.GetNumEdges();
160 mask.SetNumVertexWeights(1);
161 mask.SetNumEdgeWeights(valence);
162 mask.SetNumFaceWeights(0);
163 mask.SetFaceWeightsForFaceCenters(
false);
165 Weight vWeight = 0.75f;
166 Weight eWeight = 0.125f;
168 mask.VertexWeight(0) = vWeight;
169 for (
int i = 0; i < valence; ++i) {
170 mask.EdgeWeight(i) = 0.0f;
172 mask.EdgeWeight(creaseEnds[0]) = eWeight;
173 mask.EdgeWeight(creaseEnds[1]) = eWeight;
177 template <
typename VERTEX,
typename MASK>
181 typedef typename MASK::Weight Weight;
183 int valence = vertex.GetNumFaces();
185 mask.SetNumVertexWeights(1);
186 mask.SetNumEdgeWeights(valence);
187 mask.SetNumFaceWeights(0);
188 mask.SetFaceWeightsForFaceCenters(
false);
191 Weight eWeight = (Weight) 0.0625f;
192 Weight vWeight = (Weight) 0.625f;
199 Weight invValence = 1.0f / (Weight) valence;
200 Weight beta = 0.25f * cosf((Weight)M_PI * 2.0f * invValence) + 0.375f;
202 eWeight = (0.625f - (beta * beta)) * invValence;;
203 vWeight = 1.0f - (eWeight * (Weight)valence);
206 mask.VertexWeight(0) = vWeight;
207 for (
int i = 0; i < valence; ++i) {
208 mask.EdgeWeight(i) = eWeight;
217 template <
typename VERTEX,
typename MASK>
221 posMask.SetNumVertexWeights(1);
222 posMask.SetNumEdgeWeights(0);
223 posMask.SetNumFaceWeights(0);
224 posMask.SetFaceWeightsForFaceCenters(
false);
226 posMask.VertexWeight(0) = 1.0f;
230 template <
typename VERTEX,
typename MASK>
233 int const creaseEnds[2])
const {
235 typedef typename MASK::Weight Weight;
237 int valence = vertex.GetNumEdges();
239 posMask.SetNumVertexWeights(1);
240 posMask.SetNumEdgeWeights(valence);
241 posMask.SetNumFaceWeights(0);
242 posMask.SetFaceWeightsForFaceCenters(
false);
255 Weight vWeight = 4.0f / 6.0f;
256 Weight eWeight = 1.0f / 6.0f;
258 posMask.VertexWeight(0) = vWeight;
259 for (
int i = 0; i < valence; ++i) {
260 posMask.EdgeWeight(i) = 0.0f;
262 posMask.EdgeWeight(creaseEnds[0]) = eWeight;
263 posMask.EdgeWeight(creaseEnds[1]) = eWeight;
267 template <
typename VERTEX,
typename MASK>
271 typedef typename MASK::Weight Weight;
273 int valence = vertex.GetNumFaces();
274 assert(valence != 2);
276 posMask.SetNumVertexWeights(1);
277 posMask.SetNumEdgeWeights(valence);
278 posMask.SetNumFaceWeights(0);
279 posMask.SetFaceWeightsForFaceCenters(
false);
283 Weight eWeight = 1.0f / 12.0f;
284 Weight vWeight = 0.5f;
286 posMask.VertexWeight(0) = vWeight;
288 posMask.EdgeWeight(0) = eWeight;
289 posMask.EdgeWeight(1) = eWeight;
290 posMask.EdgeWeight(2) = eWeight;
291 posMask.EdgeWeight(3) = eWeight;
292 posMask.EdgeWeight(4) = eWeight;
293 posMask.EdgeWeight(5) = eWeight;
296 Weight invValence = 1.0f / valence;
298 Weight beta = 0.25f * cosf((Weight)M_PI * 2.0f * invValence) + 0.375f;
299 beta = (0.625f - (beta * beta)) * invValence;;
301 Weight eWeight = 1.0f / (valence + 3.0f / (8.0f * beta));
302 Weight vWeight = (Weight)(1.0f - (eWeight * valence));
304 posMask.VertexWeight(0) = vWeight;
305 for (
int i = 0; i < valence; ++i) {
306 posMask.EdgeWeight(i) = eWeight;
379 template <
typename VERTEX,
typename MASK>
382 MASK& tan1Mask, MASK& tan2Mask)
const {
384 int valence = vertex.GetNumEdges();
386 tan1Mask.SetNumVertexWeights(1);
387 tan1Mask.SetNumEdgeWeights(valence);
388 tan1Mask.SetNumFaceWeights(0);
389 tan1Mask.SetFaceWeightsForFaceCenters(
false);
391 tan2Mask.SetNumVertexWeights(1);
392 tan2Mask.SetNumEdgeWeights(valence);
393 tan2Mask.SetNumFaceWeights(0);
394 tan2Mask.SetFaceWeightsForFaceCenters(
false);
397 tan1Mask.VertexWeight(0) = -3.0f;
398 tan1Mask.EdgeWeight(0) = 3.0f;
399 tan1Mask.EdgeWeight(1) = 0.0f;
401 tan2Mask.VertexWeight(0) = -3.0f;
402 tan2Mask.EdgeWeight(0) = 0.0f;
403 tan2Mask.EdgeWeight(1) = 3.0f;
406 for (
int i = 2; i < valence; ++i) {
407 tan1Mask.EdgeWeight(i) = 0.0f;
408 tan2Mask.EdgeWeight(i) = 0.0f;
413 template <
typename VERTEX,
typename MASK>
416 MASK& tan1Mask, MASK& tan2Mask,
int const creaseEnds[2])
const {
418 typedef typename MASK::Weight Weight;
427 int valence = vertex.GetNumEdges();
429 tan1Mask.SetNumVertexWeights(1);
430 tan1Mask.SetNumEdgeWeights(valence);
431 tan1Mask.SetNumFaceWeights(0);
432 tan1Mask.SetFaceWeightsForFaceCenters(
false);
434 tan1Mask.VertexWeight(0) = 0.0f;
435 for (
int i = 0; i < valence; ++i) {
436 tan1Mask.EdgeWeight(i) = 0.0f;
440 tan1Mask.EdgeWeight(creaseEnds[0]) = 1.5f;
441 tan1Mask.EdgeWeight(creaseEnds[1]) = -1.5f;
463 tan2Mask.SetNumVertexWeights(1);
464 tan2Mask.SetNumEdgeWeights(valence);
465 tan2Mask.SetNumFaceWeights(0);
466 tan2Mask.SetFaceWeightsForFaceCenters(
false);
468 for (
int i = 0; i < creaseEnds[0]; ++i) {
469 tan2Mask.EdgeWeight(i) = 0.0f;
471 int interiorEdgeCount = creaseEnds[1] - creaseEnds[0] - 1;
472 if (interiorEdgeCount == 2) {
475 static Weight
const Root3 = (Weight) 1.73205080756887729352f;
476 static Weight
const Root3by2 = (Weight) (Root3 * 0.5);
478 tan2Mask.VertexWeight(0) = -Root3;
480 tan2Mask.EdgeWeight(creaseEnds[0]) = -Root3by2;
481 tan2Mask.EdgeWeight(creaseEnds[1]) = -Root3by2;
483 tan2Mask.EdgeWeight(creaseEnds[0] + 1) = Root3;
484 tan2Mask.EdgeWeight(creaseEnds[0] + 2) = Root3;
485 }
else if (interiorEdgeCount > 2) {
490 double theta = M_PI / (interiorEdgeCount + 1);
492 Weight cWeight = -3.0f * std::sin(theta);
493 Weight eWeightCoeff = -3.0f * (2.0f * std::cos(theta) - 2.0f);
495 tan2Mask.VertexWeight(0) = 0.0f;
497 tan2Mask.EdgeWeight(creaseEnds[0]) = cWeight;
498 tan2Mask.EdgeWeight(creaseEnds[1]) = cWeight;
500 for (
int i = 1; i <= interiorEdgeCount; ++i) {
501 tan2Mask.EdgeWeight(creaseEnds[0] + i) = eWeightCoeff * std::sin(i * theta);
503 }
else if (interiorEdgeCount == 1) {
506 tan2Mask.VertexWeight(0) = -3.0f;
508 tan2Mask.EdgeWeight(creaseEnds[0]) = 0.0f;
509 tan2Mask.EdgeWeight(creaseEnds[1]) = 0.0f;
511 tan2Mask.EdgeWeight(creaseEnds[0] + 1) = 3.0f;
515 tan2Mask.VertexWeight(0) = -6.0f;
517 tan2Mask.EdgeWeight(creaseEnds[0]) = 3.0f;
518 tan2Mask.EdgeWeight(creaseEnds[1]) = 3.0f;
520 for (
int i = creaseEnds[1] + 1; i < valence; ++i) {
521 tan2Mask.EdgeWeight(i) = 0.0f;
526 template <
typename VERTEX,
typename MASK>
529 MASK& tan1Mask, MASK& tan2Mask)
const {
531 typedef typename MASK::Weight Weight;
533 int valence = vertex.GetNumFaces();
534 assert(valence != 2);
536 tan1Mask.SetNumVertexWeights(1);
537 tan1Mask.SetNumEdgeWeights(valence);
538 tan1Mask.SetNumFaceWeights(0);
539 tan1Mask.SetFaceWeightsForFaceCenters(
false);
541 tan2Mask.SetNumVertexWeights(1);
542 tan2Mask.SetNumEdgeWeights(valence);
543 tan2Mask.SetNumFaceWeights(0);
544 tan2Mask.SetFaceWeightsForFaceCenters(
false);
546 tan1Mask.VertexWeight(0) = 0.0f;
547 tan2Mask.VertexWeight(0) = 0.0f;
550 static Weight
const Root3by2 = (Weight)(0.5f * 1.73205080756887729352f);
552 tan1Mask.EdgeWeight(0) = 1.0f;
553 tan1Mask.EdgeWeight(1) = 0.5f;
554 tan1Mask.EdgeWeight(2) = -0.5f;
555 tan1Mask.EdgeWeight(3) = -1.0f;
556 tan1Mask.EdgeWeight(4) = -0.5f;
557 tan1Mask.EdgeWeight(5) = 0.5f;
559 tan2Mask.EdgeWeight(0) = 0.0f;
560 tan2Mask.EdgeWeight(1) = Root3by2;
561 tan2Mask.EdgeWeight(2) = Root3by2;
562 tan2Mask.EdgeWeight(3) = 0.0f;
563 tan2Mask.EdgeWeight(4) = -Root3by2;
564 tan2Mask.EdgeWeight(5) = -Root3by2;
566 Weight alpha = (Weight) (2.0f * M_PI / valence);
567 for (
int i = 0; i < valence; ++i) {
568 double alphaI = alpha * i;
569 tan1Mask.EdgeWeight(i) = std::cos(alphaI);
570 tan2Mask.EdgeWeight(i) = std::sin(alphaI);
577 using namespace OPENSUBDIV_VERSION;
Split
Enumerated type for all face splitting scheme.
static int GetRegularFaceSize()
static Split GetTopologicalSplitType()
void assignCornerLimitMask(VERTEX const &vertex, MASK &pos) const
void assignSmoothMaskForVertex(VERTEX const &edge, MASK &mask) const
void assignCreaseMaskForEdge(EDGE const &edge, MASK &mask) const
static int GetLocalNeighborhoodSize()
void assignCornerMaskForVertex(VERTEX const &edge, MASK &mask) const
void assignCreaseMaskForVertex(VERTEX const &edge, MASK &mask, int const creaseEnds[2]) const
void assignSmoothMaskForEdge(EDGE const &edge, MASK &mask) const
void assignSmoothLimitMask(VERTEX const &vertex, MASK &pos) const
void assignCreaseLimitMask(VERTEX const &vertex, MASK &pos, int const creaseEnds[2]) const
static int GetRegularVertexValence()
void assignCreaseLimitTangentMasks(VERTEX const &vertex, MASK &tan1, MASK &tan2, int const creaseEnds[2]) const
void assignCornerLimitTangentMasks(VERTEX const &vertex, MASK &tan1, MASK &tan2) const
void assignSmoothLimitTangentMasks(VERTEX const &vertex, MASK &tan1, MASK &tan2) const