56 typedef typename MASK::Weight Weight;
58 int faceCount = edge.GetNumFaces();
60 mask.SetNumVertexWeights(2);
61 mask.SetNumEdgeWeights(0);
62 mask.SetNumFaceWeights(faceCount);
63 mask.SetFaceWeightsForFaceCenters(
true);
69 bool face0IsTri =
false;
70 bool face1IsTri =
false;
72 if (useTriangleOption) {
80 edge.GetNumVerticesPerFace(vertsPerFace);
82 face0IsTri = (vertsPerFace[0] == 3);
83 face1IsTri = (vertsPerFace[1] == 3);
84 useTriangleOption = face0IsTri || face1IsTri;
86 useTriangleOption =
false;
90 if (! useTriangleOption) {
91 mask.VertexWeight(0) = 0.25f;
92 mask.VertexWeight(1) = 0.25f;
95 mask.FaceWeight(0) = 0.25f;
96 mask.FaceWeight(1) = 0.25f;
98 Weight fWeight = 0.5f / (Weight)faceCount;
99 for (
int i = 0; i < faceCount; ++i) {
100 mask.FaceWeight(i) = fWeight;
107 const Weight CATMARK_SMOOTH_TRI_EDGE_WEIGHT = (Weight) 0.470;
109 Weight f0Weight = face0IsTri ? CATMARK_SMOOTH_TRI_EDGE_WEIGHT : 0.25f;
110 Weight f1Weight = face1IsTri ? CATMARK_SMOOTH_TRI_EDGE_WEIGHT : 0.25f;
112 Weight fWeight = 0.5f * (f0Weight + f1Weight);
113 Weight vWeight = 0.5f * (1.0f - 2.0f * fWeight);
115 mask.VertexWeight(0) = vWeight;
116 mask.VertexWeight(1) = vWeight;
118 mask.FaceWeight(0) = fWeight;
119 mask.FaceWeight(1) = fWeight;
132 int const creaseEnds[2])
const {
133 typedef typename MASK::Weight Weight;
135 int valence = vertex.GetNumEdges();
137 mask.SetNumVertexWeights(1);
138 mask.SetNumEdgeWeights(valence);
139 mask.SetNumFaceWeights(0);
140 mask.SetFaceWeightsForFaceCenters(
false);
142 Weight vWeight = 0.75f;
143 Weight eWeight = 0.125f;
145 mask.VertexWeight(0) = vWeight;
146 for (
int i = 0; i < valence; ++i) {
147 mask.EdgeWeight(i) = 0.0f;
149 mask.EdgeWeight(creaseEnds[0]) = eWeight;
150 mask.EdgeWeight(creaseEnds[1]) = eWeight;
158 typedef typename MASK::Weight Weight;
165 assert(vertex.GetNumFaces() == vertex.GetNumEdges());
167 int valence = vertex.GetNumFaces();
169 mask.SetNumVertexWeights(1);
170 mask.SetNumEdgeWeights(valence);
171 mask.SetNumFaceWeights(valence);
172 mask.SetFaceWeightsForFaceCenters(
true);
174 Weight vWeight = (Weight)(valence - 2) / (Weight)valence;
175 Weight fWeight = 1.0f / (Weight)(valence * valence);
176 Weight eWeight = fWeight;
178 mask.VertexWeight(0) = vWeight;
179 for (
int i = 0; i < valence; ++i) {
180 mask.EdgeWeight(i) = eWeight;
181 mask.FaceWeight(i) = fWeight;
205 int const creaseEnds[2])
const {
207 typedef typename MASK::Weight Weight;
209 int valence = vertex.GetNumEdges();
211 posMask.SetNumVertexWeights(1);
212 posMask.SetNumEdgeWeights(valence);
213 posMask.SetNumFaceWeights(0);
214 posMask.SetFaceWeightsForFaceCenters(
false);
216 Weight vWeight = (Weight)(2.0 / 3.0);
217 Weight eWeight = (Weight)(1.0 / 6.0);
219 posMask.VertexWeight(0) = vWeight;
220 for (
int i = 0; i < valence; ++i) {
221 posMask.EdgeWeight(i) = 0.0f;
223 posMask.EdgeWeight(creaseEnds[0]) = eWeight;
224 posMask.EdgeWeight(creaseEnds[1]) = eWeight;
232 typedef typename MASK::Weight Weight;
234 int valence = vertex.GetNumFaces();
236 assignCornerLimitMask(vertex, posMask);
240 posMask.SetNumVertexWeights(1);
241 posMask.SetNumEdgeWeights(valence);
242 posMask.SetNumFaceWeights(valence);
243 posMask.SetFaceWeightsForFaceCenters(
false);
247 Weight fWeight = (Weight)(1.0 / 36.0);
248 Weight eWeight = (Weight)(1.0 / 9.0);
249 Weight vWeight = (Weight)(4.0 / 9.0);
251 posMask.VertexWeight(0) = vWeight;
253 posMask.EdgeWeight(0) = eWeight;
254 posMask.EdgeWeight(1) = eWeight;
255 posMask.EdgeWeight(2) = eWeight;
256 posMask.EdgeWeight(3) = eWeight;
258 posMask.FaceWeight(0) = fWeight;
259 posMask.FaceWeight(1) = fWeight;
260 posMask.FaceWeight(2) = fWeight;
261 posMask.FaceWeight(3) = fWeight;
263 Weight Valence = (Weight) valence;
265 Weight fWeight = 1.0f / (Valence * (Valence + 5.0f));
266 Weight eWeight = 4.0f * fWeight;
267 Weight vWeight = 1.0f - Valence * (eWeight + fWeight);
269 posMask.VertexWeight(0) = vWeight;
270 for (
int i = 0; i < valence; ++i) {
271 posMask.EdgeWeight(i) = eWeight;
272 posMask.FaceWeight(i) = fWeight;
285 MASK& tan1Mask, MASK& tan2Mask)
const {
287 int valence = vertex.GetNumEdges();
289 tan1Mask.SetNumVertexWeights(1);
290 tan1Mask.SetNumEdgeWeights(valence);
291 tan1Mask.SetNumFaceWeights(0);
292 tan1Mask.SetFaceWeightsForFaceCenters(
false);
294 tan2Mask.SetNumVertexWeights(1);
295 tan2Mask.SetNumEdgeWeights(valence);
296 tan2Mask.SetNumFaceWeights(0);
297 tan2Mask.SetFaceWeightsForFaceCenters(
false);
300 tan1Mask.VertexWeight(0) = -1.0f;
301 tan1Mask.EdgeWeight(0) = 1.0f;
302 tan1Mask.EdgeWeight(1) = 0.0f;
304 tan2Mask.VertexWeight(0) = -1.0f;
305 tan2Mask.EdgeWeight(0) = 0.0f;
306 tan2Mask.EdgeWeight(1) = 1.0f;
308 for (
int i = 2; i < valence; ++i) {
309 tan1Mask.EdgeWeight(i) = 0.0f;
310 tan2Mask.EdgeWeight(i) = 0.0f;
318 MASK& tan1Mask, MASK& tan2Mask,
int const creaseEnds[2])
const {
320 typedef typename MASK::Weight Weight;
329 int numEdges = vertex.GetNumEdges();
330 int numFaces = vertex.GetNumFaces();
332 tan1Mask.SetNumVertexWeights(1);
333 tan1Mask.SetNumEdgeWeights(numEdges);
334 tan1Mask.SetNumFaceWeights(numFaces);
335 tan1Mask.SetFaceWeightsForFaceCenters(
false);
337 tan1Mask.VertexWeight(0) = 0.0f;
338 for (
int i = 0; i < numEdges; ++i) {
339 tan1Mask.EdgeWeight(i) = 0.0f;
341 for (
int i = 0; i < numFaces; ++i) {
342 tan1Mask.FaceWeight(i) = 0.0f;
345 tan1Mask.EdgeWeight(creaseEnds[0]) = 0.5f;
346 tan1Mask.EdgeWeight(creaseEnds[1]) = -0.5f;
357 tan2Mask.SetNumVertexWeights(1);
358 tan2Mask.SetNumEdgeWeights(numEdges);
359 tan2Mask.SetNumFaceWeights(numFaces);
360 tan2Mask.SetFaceWeightsForFaceCenters(
false);
363 for (
int i = 0; i < creaseEnds[0]; ++i) {
364 tan2Mask.EdgeWeight(i) = 0.0f;
365 tan2Mask.FaceWeight(i) = 0.0f;
369 int interiorEdgeCount = creaseEnds[1] - creaseEnds[0] - 1;
370 if (interiorEdgeCount == 1) {
373 tan2Mask.VertexWeight(0) = (Weight)(-4.0 / 6.0);
375 tan2Mask.EdgeWeight(creaseEnds[0]) = (Weight)(-1.0 / 6.0);
376 tan2Mask.EdgeWeight(creaseEnds[0] + 1) = (Weight)( 4.0 / 6.0);
377 tan2Mask.EdgeWeight(creaseEnds[1]) = (Weight)(-1.0 / 6.0);
379 tan2Mask.FaceWeight(creaseEnds[0]) = (Weight)(1.0 / 6.0);
380 tan2Mask.FaceWeight(creaseEnds[0] + 1) = (Weight)(1.0 / 6.0);
381 }
else if (interiorEdgeCount > 1) {
384 double k = (double) (interiorEdgeCount + 1);
385 double theta = M_PI / k;
387 double cosTheta = std::cos(theta);
388 double sinTheta = std::sin(theta);
391 double commonDenom = 1.0f / (k * (3.0f + cosTheta));
392 double R = (cosTheta + 1.0f) / sinTheta;
394 double vertexWeight = 4.0f * R * (cosTheta - 1.0f);
395 double creaseWeight = -R * (1.0f + 2.0f * cosTheta);
397 tan2Mask.VertexWeight(0) = (Weight) (vertexWeight * commonDenom);
399 tan2Mask.EdgeWeight(creaseEnds[0]) = (Weight) (creaseWeight * commonDenom);
400 tan2Mask.EdgeWeight(creaseEnds[1]) = (Weight) (creaseWeight * commonDenom);
402 tan2Mask.FaceWeight(creaseEnds[0]) = (Weight) (sinTheta * commonDenom);
404 double sinThetaI = 0.0f;
405 double sinThetaIplus1 = sinTheta;
406 for (
int i = 1; i < k; ++i) {
407 sinThetaI = sinThetaIplus1;
408 sinThetaIplus1 = std::sin((i+1)*theta);
410 tan2Mask.EdgeWeight(creaseEnds[0] + i) = (Weight) ((4.0f * sinThetaI) * commonDenom);
411 tan2Mask.FaceWeight(creaseEnds[0] + i) = (Weight) ((sinThetaI + sinThetaIplus1) * commonDenom);
416 tan2Mask.VertexWeight(0) = -6.0f;
418 tan2Mask.EdgeWeight(creaseEnds[0]) = 3.0f;
419 tan2Mask.EdgeWeight(creaseEnds[1]) = 3.0f;
421 tan2Mask.FaceWeight(creaseEnds[0]) = 0.0f;
425 for (
int i = creaseEnds[1]; i < numFaces; ++i) {
426 tan2Mask.FaceWeight(i) = 0.0f;
428 for (
int i = creaseEnds[1] + 1; i < numEdges; ++i) {
429 tan2Mask.EdgeWeight(i) = 0.0f;
437 MASK& tan1Mask, MASK& tan2Mask)
const {
439 typedef typename MASK::Weight Weight;
441 int valence = vertex.GetNumFaces();
443 assignCornerLimitTangentMasks(vertex, tan1Mask, tan2Mask);
448 tan1Mask.SetNumVertexWeights(1);
449 tan1Mask.SetNumEdgeWeights(valence);
450 tan1Mask.SetNumFaceWeights(valence);
451 tan1Mask.SetFaceWeightsForFaceCenters(
false);
453 tan1Mask.VertexWeight(0) = 0.0f;
456 tan1Mask.EdgeWeight(0) = 4.0f;
457 tan1Mask.EdgeWeight(1) = 0.0f;
458 tan1Mask.EdgeWeight(2) = -4.0f;
459 tan1Mask.EdgeWeight(3) = 0.0f;
461 tan1Mask.FaceWeight(0) = 1.0f;
462 tan1Mask.FaceWeight(1) = -1.0f;
463 tan1Mask.FaceWeight(2) = -1.0f;
464 tan1Mask.FaceWeight(3) = 1.0f;
466 double theta = 2.0f * M_PI / (double)valence;
468 double cosTheta = std::cos(theta);
469 double cosHalfTheta = std::cos(theta * 0.5f);
471 double lambda = (5.0 / 16.0) + (1.0 / 16.0) *
472 (cosTheta + cosHalfTheta * std::sqrt(2.0f * (9.0f + cosTheta)));
474 double edgeWeightScale = 4.0f;
475 double faceWeightScale = 1.0f / (4.0f * lambda - 1.0f);
477 for (
int i = 0; i < valence; ++i) {
478 double cosThetaI = std::cos( i * theta);
479 double cosThetaIplus1 = std::cos((i+1)* theta);
481 tan1Mask.EdgeWeight(i) = (Weight) (edgeWeightScale * cosThetaI);
482 tan1Mask.FaceWeight(i) = (Weight) (faceWeightScale * (cosThetaI + cosThetaIplus1));
487 tan2Mask.SetNumVertexWeights(1);
488 tan2Mask.SetNumEdgeWeights(valence);
489 tan2Mask.SetNumFaceWeights(valence);
490 tan2Mask.SetFaceWeightsForFaceCenters(
false);
492 tan2Mask.VertexWeight(0) = 0.0f;
494 tan2Mask.EdgeWeight(0) = 0.0f;
495 tan2Mask.EdgeWeight(1) = 4.0f;
496 tan2Mask.EdgeWeight(2) = 0.0f;
497 tan2Mask.EdgeWeight(3) = -4.0f;
499 tan2Mask.FaceWeight(0) = 1.0f;
500 tan2Mask.FaceWeight(1) = 1.0f;
501 tan2Mask.FaceWeight(2) = -1.0f;
502 tan2Mask.FaceWeight(3) = -1.0f;
504 tan2Mask.EdgeWeight(0) = tan1Mask.EdgeWeight(valence-1);
505 tan2Mask.FaceWeight(0) = tan1Mask.FaceWeight(valence-1);
506 for (
int i = 1; i < valence; ++i) {
507 tan2Mask.EdgeWeight(i) = tan1Mask.EdgeWeight(i-1);
508 tan2Mask.FaceWeight(i) = tan1Mask.FaceWeight(i-1);