32 #include "../hbr/subdivision.h"
34 #include "../version.h"
36 namespace OpenSubdiv {
37 namespace OPENSUBDIV_VERSION {
93 for (
int i = 0; i < 3; ++i) {
95 GuaranteeNeighbor(mesh, edge);
96 childVertex = child->
GetVertex((i + 2) % 3);
101 HbrFVarData<T>& fv = childVertex->
GetFVarData(child);
103 for (
int fvaritem = 0; fvaritem < fvarcount; ++fvaritem) {
106 if (fvarinterp == HbrMesh<T>::k_InterpolateBoundaryNone ||
107 face->
GetEdge(i)->GetFVarSharpness(fvaritem) || face->
GetEdge(i)->IsBoundary()) {
110 fv.SetWithWeight(face->
GetFVarData(i), fvarindex, fvarwidth, 0.5f);
111 fv.AddWithWeight(face->
GetFVarData((i + 1) % 3), fvarindex, fvarwidth, 0.5f);
112 }
else if (!fvIsSmooth || !fv.IsInitialized()) {
114 fv.SetWithWeight(face->
GetFVarData(i), fvarindex, fvarwidth, 0.375f);
115 fv.AddWithWeight(face->
GetFVarData((i + 1) % 3), fvarindex, fvarwidth, 0.375f);
117 fv.AddWithWeight(face->
GetFVarData((i + 2) % 3), fvarindex, fvarwidth, 0.125f);
118 HbrFace<T>* oppFace = face->
GetEdge(i)->GetRightFace();
119 for (
int j = 0; j < oppFace->GetNumVertices(); ++j) {
120 if (oppFace->GetVertex(j) == face->
GetVertex(i)) {
121 fv.AddWithWeight(oppFace->GetFVarData((j+1)%oppFace->GetNumVertices()), fvarindex, fvarwidth, 0.125f);
126 fvarindex += fvarwidth;
133 HbrHalfedge<T>* edge;
134 HbrVertex<T>* v = face->
GetVertex(index);
157 v->GuaranteeNeighbors();
160 bool fv0IsSmooth, fv1IsSmooth, fv2IsSmooth;
163 fv0IsSmooth = v->IsFVarAllSmooth();
167 HbrFVarData<T>& fv0 = childVertex->
GetFVarData(child);
170 GuaranteeNeighbor(mesh, edge);
171 assert(edge->GetOrgVertex() == v);
172 childVertex = child->
GetVertex((index + 1) % 3);
173 fv1IsSmooth = !edge->IsFVarInfiniteSharpAnywhere();
175 childVertex->NewFVarData(child);
177 HbrFVarData<T>& fv1 = childVertex->GetFVarData(child);
179 edge = edge->GetPrev();
180 GuaranteeNeighbor(mesh, edge);
181 assert(edge == face->
GetEdge((index + 2) % 3));
182 assert(edge->GetDestVertex() == v);
183 childVertex = child->
GetVertex((index + 2) % 3);
184 fv2IsSmooth = !edge->IsFVarInfiniteSharpAnywhere();
186 childVertex->NewFVarData(child);
188 HbrFVarData<T>& fv2 = childVertex->GetFVarData(child);
192 for (
int fvaritem = 0; fvaritem < fvarcount; ++fvaritem) {
193 bool infcorner =
false;
195 const char fvarmask = v->GetFVarMask(fvaritem);
196 if (fvarinterp == HbrMesh<T>::k_InterpolateBoundaryEdgeAndCorner) {
197 if (fvarmask >= HbrVertex<T>::k_Corner) {
200 if (v->IsFVarCorner(fvaritem)) {
204 if (face->
GetEdge(index)->GetFVarSharpness(fvaritem,
true) && face->
GetEdge(index)->GetPrev()->GetFVarSharpness(fvaritem,
true)) {
216 if (fvarinterp == HbrMesh<T>::k_InterpolateBoundaryNone ||
217 (fvarinterp == HbrMesh<T>::k_InterpolateBoundaryAlwaysSharp &&
219 v->GetSharpness() > HbrVertex<T>::k_Smooth ||
221 fv0.SetWithWeight(face->
GetFVarData(index), fvarindex, fvarwidth, 1.0f);
226 else if (fvarmask == 1) {
228 fv0.SetWithWeight(face->
GetFVarData(index), fvarindex, fvarwidth, 0.75f);
233 HbrHalfedge<T>* start = v->GetIncidentEdge(), *edge, *nextedge;
236 if (edge->GetFVarSharpness(fvaritem)) {
239 nextedge = v->GetNextEdge(edge);
240 if (nextedge == start) {
243 }
else if (!nextedge) {
248 edge = edge->GetPrev();
254 HbrVertex<T>* w = edge->GetDestVertex();
255 HbrFace<T>* bestface = edge->GetLeftFace();
257 for (j = 0; j < bestface->GetNumVertices(); ++j) {
258 if (bestface->GetVertex(j) == w)
break;
260 assert(j != bestface->GetNumVertices());
261 fv0.AddWithWeight(bestface->GetFVarData(j), fvarindex, fvarwidth, 0.125f);
262 bestface = edge->GetRightFace();
263 for (j = 0; j < bestface->GetNumVertices(); ++j) {
264 if (bestface->GetVertex(j) == w)
break;
266 assert(j != bestface->GetNumVertices());
267 fv0.AddWithWeight(bestface->GetFVarData(j), fvarindex, fvarwidth, 0.125f);
271 else if (fvarmask != 0) {
274 fv0.SetWithWeight(face->
GetFVarData(index), fvarindex, fvarwidth, 0.75f);
282 HbrFace<T>* bestface = face;
283 HbrHalfedge<T>* bestedge = face->
GetEdge(index)->GetPrev();
284 HbrHalfedge<T>* starte = bestedge->GetOpposite();
287 w = face->
GetEdge(index)->GetPrev()->GetOrgVertex();
289 HbrHalfedge<T>* e = starte, *next;
290 assert(starte->GetOrgVertex() == v);
292 if (e->GetFVarSharpness(fvaritem) || !e->GetLeftFace()) {
293 bestface = e->GetRightFace();
297 next = v->GetNextEdge(e);
299 bestface = e->GetLeftFace();
300 w = e->GetPrev()->GetOrgVertex();
304 }
while (e && e != starte);
306 if (!w) w = bestedge->GetDestVertex();
308 for (j = 0; j < bestface->GetNumVertices(); ++j) {
309 if (bestface->GetVertex(j) == w)
break;
311 assert(j != bestface->GetNumVertices());
312 fv0.AddWithWeight(bestface->GetFVarData(j), fvarindex, fvarwidth, 0.125f);
316 bestedge = face->
GetEdge(index);
319 if (HbrHalfedge<T>* e = starte) {
320 assert(starte->GetOrgVertex() == v);
322 if (e->GetFVarSharpness(fvaritem) || !e->GetRightFace()) {
323 bestface = e->GetLeftFace();
327 assert(e->GetOpposite());
328 e = v->GetPreviousEdge(e);
329 }
while (e && e != starte);
331 if (!w) w = bestedge->GetDestVertex();
332 for (j = 0; j < bestface->GetNumVertices(); ++j) {
333 if (bestface->GetVertex(j) == w)
break;
335 assert(j != bestface->GetNumVertices());
336 fv0.AddWithWeight(bestface->GetFVarData(j), fvarindex, fvarwidth, 0.125f);
340 else if (!fv0IsSmooth || !fv0.IsInitialized()) {
341 int valence = v->GetValence();
342 float invvalence = 1.0f / valence;
343 float beta = 0.25f * cosf((
float)M_PI * 2.0f * invvalence) + 0.375f;
345 beta = (0.625f - beta) * invvalence;
348 fv0.SetWithWeight(face->
GetFVarData(index), fvarindex, fvarwidth, 1 - (beta * valence));
352 HbrHalfedge<T>* start = v->GetIncidentEdge(), *edge;
355 HbrFace<T>* g = edge->GetLeftFace();
361 for (
int j = 0; j < g->GetNumVertices(); ++j) {
362 if (g->GetEdge(j)->GetOrgVertex() == v) {
363 fv0.AddWithWeight(g->GetFVarData((j + 1) % g->GetNumVertices()), fvarindex, fvarwidth, beta);
367 edge = v->GetNextEdge(edge);
368 if (edge == start)
break;
373 HbrHalfedge<T>* edge = face->
GetEdge(index);
375 if (fvarinterp == HbrMesh<T>::k_InterpolateBoundaryNone ||
376 edge->GetFVarSharpness(fvaritem) || edge->IsBoundary()) {
379 fv1.SetWithWeight(face->
GetFVarData(index), fvarindex, fvarwidth, 0.5f);
380 fv1.AddWithWeight(face->
GetFVarData((index + 1) % 3), fvarindex, fvarwidth, 0.5f);
381 }
else if (!fv1IsSmooth || !fv1.IsInitialized()) {
383 fv1.SetWithWeight(face->
GetFVarData(index), fvarindex, fvarwidth, 0.375f);
384 fv1.AddWithWeight(face->
GetFVarData((index + 1) % 3), fvarindex, fvarwidth, 0.375f);
386 fv1.AddWithWeight(face->
GetFVarData((index + 2) % 3), fvarindex, fvarwidth, 0.125f);
387 HbrFace<T>* oppFace = edge->GetRightFace();
388 for (
int j = 0; j < oppFace->GetNumVertices(); ++j) {
389 if (oppFace->GetVertex(j) == v) {
390 fv1.AddWithWeight(oppFace->GetFVarData((j+1)%oppFace->GetNumVertices()), fvarindex, fvarwidth, 0.125f);
398 edge = edge->GetPrev();
400 if (fvarinterp == HbrMesh<T>::k_InterpolateBoundaryNone ||
401 edge->GetFVarSharpness(fvaritem) || edge->IsBoundary()) {
404 fv2.SetWithWeight(face->
GetFVarData((index + 2) % 3), fvarindex, fvarwidth, 0.5f);
405 fv2.AddWithWeight(face->
GetFVarData(index), fvarindex, fvarwidth, 0.5f);
406 }
else if (!fv2IsSmooth || !fv2.IsInitialized()) {
408 fv2.SetWithWeight(face->
GetFVarData((index + 2) % 3), fvarindex, fvarwidth, 0.375f);
409 fv2.AddWithWeight(face->
GetFVarData(index), fvarindex, fvarwidth, 0.375f);
411 fv2.AddWithWeight(face->
GetFVarData((index + 1) % 3), fvarindex, fvarwidth, 0.125f);
413 HbrFace<T>* oppFace = edge->GetRightFace();
414 for (
int j = 0; j < oppFace->GetNumVertices(); ++j) {
415 if (oppFace->GetVertex(j) == v) {
416 fv2.AddWithWeight(oppFace->GetFVarData((j+2)%oppFace->GetNumVertices()), fvarindex, fvarwidth, 0.125f);
422 fvarindex += fvarwidth;
424 fv0.SetInitialized();
425 fv1.SetInitialized();
426 fv2.SetInitialized();
431 HbrLoopSubdivision<T>::transferEditsToChild(HbrFace<T>* face, HbrFace<T>* child,
int index) {
434 child->SetHole(face->IsHole());
437 if (HbrHierarchicalEdit<T>** edits = face->GetHierarchicalEdits()) {
438 while (HbrHierarchicalEdit<T>* edit = *edits) {
439 if (!edit->IsRelevantToFace(face))
break;
440 if (edit->GetNSubfaces() > face->GetDepth() &&
441 (edit->GetSubface(face->GetDepth()) == index)) {
442 child->SetHierarchicalEdits(edits);
455 std::cerr <<
"\n\nRefining face " << *face <<
"\n";
458 assert(face->GetNumVertices() == 3);
462 for (
int i = 0; i < 3; ++i) {
464 if (!face->GetChild(i)) {
466 std::cerr <<
"Kid " << i <<
"\n";
472 vertices[(i + 1) % 3] = edge->
Subdivide();
473 vertices[(i + 2) % 3] = prevedge->
Subdivide();
474 child = mesh->
NewFace(3, vertices, face, i);
476 std::cerr <<
"Creating face " << *child <<
" during refine\n";
483 childedge = child->GetEdge(i);
486 edge, edge->GetOrgVertex(), childedge);
490 childedge = child->GetEdge((i+2)%3);
498 transferFVarToChild(mesh, face, child, i);
501 transferEditsToChild(face, child, i);
508 refineFaceAtMiddle(mesh, face);
516 std::cerr <<
" forcing refine on " << *face <<
" at " << *vertex <<
'\n';
521 for (
int i = 0; i < 3; ++i) {
525 std::cerr <<
"Kid " << i <<
"\n";
531 vertices[(i + 1) % 3] = edge->
Subdivide();
532 vertices[(i + 2) % 3] = prevedge->
Subdivide();
533 child = mesh->
NewFace(3, vertices, face, i);
535 std::cerr <<
"Creating face " << *child <<
" during refine\n";
542 childedge = child->GetEdge(i);
549 childedge = child->GetEdge((i+2)%3);
557 transferFVarToChild(mesh, face, child, i);
560 transferEditsToChild(face, child, i);
581 std::cerr <<
"\n\nneighbor guarantee at " << *edge <<
" invoked\n";
606 if (parentEdge1 && parentEdge2) {
608 std::cerr <<
"two parent edge situation\n";
611 assert(parentFace == parentEdge2->
GetFace());
613 refineFaceAtMiddle(mesh, parentFace);
615 RefineFaceAtVertex(mesh, parentFace, parentEdge1->
GetOrgVertex());
617 assert(edge->GetOpposite());
625 std::cerr <<
"parent edge 1 " << *parentEdge1 <<
"\n";
628 assert(parentVertex2);
629 RefineFaceAtVertex(mesh, parentEdge1->GetLeftFace(), parentVertex2);
630 if (parentEdge1->GetRightFace()) {
631 RefineFaceAtVertex(mesh, parentEdge1->GetRightFace(), parentVertex2);
633 }
else if (parentEdge2) {
635 std::cerr <<
"parent edge 2 " << *parentEdge2 <<
"\n";
638 assert(parentVertex1);
639 RefineFaceAtVertex(mesh, parentEdge2->GetLeftFace(), parentVertex1);
640 if (parentEdge2->GetRightFace()) {
641 RefineFaceAtVertex(mesh, parentEdge2->GetRightFace(), parentVertex1);
651 std::cerr <<
"\n\nneighbor guarantee at " << *vertex <<
" invoked\n";
654 assert(vertex->GetParentFace() == 0);
665 std::cerr <<
"parent edge situation " << *parentEdge <<
"\n";
669 GuaranteeNeighbor(mesh, parentEdge);
670 HbrFace<T>* parentFace = parentEdge->GetLeftFace();
671 RefineFaceAtVertex(mesh, parentFace, dest);
672 RefineFaceAtVertex(mesh, parentFace, org);
673 refineFaceAtMiddle(mesh, parentFace);
674 parentFace = parentEdge->GetRightFace();
678 RefineFaceAtVertex(mesh, parentFace, dest);
679 RefineFaceAtVertex(mesh, parentFace, org);
680 refineFaceAtMiddle(mesh, parentFace);
691 std::cerr <<
"parent vertex situation " << *parentVertex <<
"\n";
701 RefineFaceAtVertex(mesh, f, parentVertex);
702 edge = parentVertex->GetNextEdge(edge);
703 if (edge == start)
break;
712 if (face->
IsHole())
return false;
715 if (!HasLimit(mesh, face->
GetEdge(i))) {
740 switch (vertex->
GetMask(
false)) {
760 edge = edge->GetPrev();
787 std::cerr <<
"Subdividing at " << *edge <<
"\n";
790 GuaranteeNeighbor(mesh, edge);
792 float esharp = edge->GetSharpness();
799 edge->GetOrgVertex()->GuaranteeNeighbors();
800 edge->GetDestVertex()->GuaranteeNeighbors();
803 if (!edge->IsBoundary() && esharp <= 1.0f) {
813 if (edge->GetOpposite() && edge->GetOpposite()->GetFace()->GetPath() < edge->GetFace()->GetPath()) {
814 edge = edge->GetOpposite();
824 float endPtWeight = 0.375f + esharp * (0.5f - 0.375f);
825 data.AddWithWeight(edge->GetOrgVertex()->GetData(), endPtWeight);
826 data.AddWithWeight(edge->GetDestVertex()->GetData(), endPtWeight);
830 float oppPtWeight = 0.125f * (1 - esharp);
832 data.AddWithWeight(ee->
GetDestVertex()->GetData(), oppPtWeight);
834 data.AddWithWeight(ee->
GetDestVertex()->GetData(), oppPtWeight);
837 data.AddWithWeight(edge->GetOrgVertex()->GetData(), 0.5f);
838 data.AddWithWeight(edge->GetDestVertex()->GetData(), 0.5f);
842 data.AddVaryingWithWeight(edge->GetOrgVertex()->GetData(), 0.5f);
843 data.AddVaryingWithWeight(edge->GetDestVertex()->GetData(), 0.5f);
846 std::cerr <<
" created " << *v <<
"\n";
850 if (edge->IsBoundary()) {
864 float valence =
static_cast<float>(vertex->
GetValence());
865 float invvalence = 1.0f / valence;
875 masks[0] = vertex->
GetMask(
false);
876 masks[1] = vertex->
GetMask(
true);
881 if (masks[0] != masks[1]) {
883 weights[0] = 1.0f - weights[1];
890 for (
int i = 0; i < passes; ++i) {
894 float beta = 0.25f * cosf((
float)M_PI * 2.0f * invvalence) + 0.375f;
896 beta = (0.625f - beta) * invvalence;
898 data.AddWithWeight(vertex->
GetData(), weights[i] * (1 - (beta * valence)));
901 mesh, vertex, weights[i] * beta, &data);
906 data.AddWithWeight(vertex->
GetData(), weights[i] * 0.75f);
911 mesh, vertex, i == 1, weights[i] * 0.125f, &data);
917 data.AddWithWeight(vertex->
GetData(), weights[i]);
924 data.AddVaryingWithWeight(vertex->
GetData(), 1.0f);
927 std::cerr <<
"Subdividing at " << *vertex <<
"\n";
928 std::cerr <<
" created " << *v <<
"\n";
932 float sharp = vertex->GetSharpness();
948 std::cerr <<
"Refining middle face of " << *face <<
"\n";
951 if (!face->GetChild(3)) {
959 vertices[0] = face->
GetEdge(1)->Subdivide();
960 vertices[1] = face->
GetEdge(2)->Subdivide();
961 vertices[2] = face->
GetEdge(0)->Subdivide();
962 child = mesh->
NewFace(3, vertices, face, 3);
964 std::cerr <<
"Creating face " << *child <<
"\n";
967 transferFVarToChild(mesh, face, child, 3);
970 transferEditsToChild(face, child, 3);
975 using namespace OPENSUBDIV_VERSION;
bool HasVertexEdits() const
HbrFVarData< T > & NewFVarData(const HbrFace< T > *face)
HbrHalfedge< T > * GetEdge(int index) const
HbrVertex< T > * NewVertex(int id, const T &data)
bool IsFVarInfiniteSharpAnywhere()
void GuaranteeNeighbors()
virtual bool FaceIsExtraordinary(HbrMesh< T > const *, HbrFace< T > *face)
InterpolateBoundaryMethod GetFVarInterpolateBoundaryMethod() const
void CopyFVarInfiniteSharpness(HbrHalfedge< T > *edge)
unsigned char GetMask(bool next)
HbrHalfedge< T > * GetFirstEdge() const
HbrHalfedge< T > * GetEdge(const HbrVertex< T > *dest) const
void SubdivideCreaseWeight(HbrHalfedge< T > *edge, HbrVertex< T > *vertex, HbrHalfedge< T > *subedge)
bool GetFVarPropagateCorners() const
float GetSharpness() const
virtual HbrVertex< T > * Subdivide(HbrMesh< T > *mesh, HbrFace< T > *face)
HbrFace< T > * GetChild(int index) const
HbrHalfedge< T > * GetNext() const
HbrVertex< T > * GetDestVertex() const
HbrVertex< T > * Subdivide()
virtual void Refine(HbrMesh< T > *mesh, HbrFace< T > *face)
virtual bool HasLimit(HbrMesh< T > *mesh, HbrFace< T > *face)
virtual bool VertexIsExtraordinary(HbrMesh< T > const *, HbrVertex< T > *vertex)
HbrFace< T > * GetFace() const
HbrVertex< T > * GetParentVertex() const
int GetTotalFVarWidth() const
HbrFVarData< T > & GetFVarData(int index)
virtual int GetFaceChildrenCount(int) const
int GetNumVertices() const
virtual void GuaranteeNeighbors(HbrMesh< T > *mesh, HbrVertex< T > *vertex)
HbrVertex< T > * Subdivide()
HbrHalfedge< T > * GetIncidentEdge() const
HbrHalfedge< T > * GetNextEdge(const HbrHalfedge< T > *edge) const
void AddCreaseEdgesWithWeight(HbrMesh< T > *mesh, HbrVertex< T > *vertex, bool next, float weight, T *data)
HbrHalfedge< T > * GetOpposite() const
HbrVertex< T > * GetVertex(int index) const
HbrVertex< T > * GetOrgVertex() const
virtual HbrFace< T > * RefineFaceAtVertex(HbrMesh< T > *mesh, HbrFace< T > *face, HbrVertex< T > *vertex)
virtual HbrSubdivision< T > * Clone() const
HbrFace< T > * NewFace(int nvertices, const int *vtx, int uindex)
InterpolateBoundaryMethod
void AddSurroundingVerticesWithWeight(HbrMesh< T > *mesh, HbrVertex< T > *vertex, float weight, T *data)
virtual void GuaranteeNeighbor(HbrMesh< T > *mesh, HbrHalfedge< T > *edge)
float GetFractionalMask() const
HbrHalfedge< T > * GetPrev() const
const int * GetFVarWidths() const
HbrFVarData< T > & GetFVarData(const HbrFace< T > *face)