29 #include "../hbr/subdivision.h"
31 #include "../version.h"
33 namespace OpenSubdiv {
34 namespace OPENSUBDIV_VERSION {
103 bool extraordinary = (nv != 4);
109 float weight = 1.0f / nv;
122 for (
int j = 0; j < nv; ++j) {
135 bool fv0IsSmooth, fv1IsSmooth, fv3IsSmooth;
137 childVertex = child->
GetVertex(extraordinary ? 0 : (index+0)%4);
140 childVertex->NewFVarData(child);
142 HbrFVarData<T>& fv0 = childVertex->GetFVarData(child);
145 GuaranteeNeighbor(mesh, edge);
147 childVertex = child->
GetVertex(extraordinary ? 1 : (index+1)%4);
150 childVertex->NewFVarData(child);
152 HbrFVarData<T>& fv1 = childVertex->GetFVarData(child);
155 GuaranteeNeighbor(mesh, edge);
156 assert(edge == face->
GetEdge((index + nv - 1) % nv));
158 childVertex = child->
GetVertex(extraordinary ? 3 : (index+3)%4);
161 childVertex->NewFVarData(child);
163 HbrFVarData<T>& fv3 = childVertex->GetFVarData(child);
165 for (
int fvaritem = 0; fvaritem < fvarcount; ++fvaritem) {
179 bool infcorner =
false;
181 const unsigned char fvarmask = v->
GetFVarMask(fvaritem);
182 if (fvarinterp == HbrMesh<T>::k_InterpolateBoundaryEdgeAndCorner) {
183 if (fvarmask >= HbrVertex<T>::k_Corner) {
190 if (face->
GetEdge(index)->GetFVarSharpness(fvaritem,
true) && face->
GetEdge(index)->GetPrev()->GetFVarSharpness(fvaritem,
true)) {
202 if (fvarinterp == HbrMesh<T>::k_InterpolateBoundaryNone ||
203 (fvarinterp == HbrMesh<T>::k_InterpolateBoundaryAlwaysSharp &&
207 fv0.SetWithWeight(face->
GetFVarData(index), fvarindex, fvarwidth, 1.0f);
212 else if (fvarmask == 1) {
216 fv0.SetWithWeight(face->
GetFVarData(index), fvarindex, fvarwidth, 0.75f);
228 if (nextedge == start) {
231 }
else if (!nextedge) {
245 for (j = 0; j < bestface->GetNumVertices(); ++j) {
246 if (bestface->GetVertex(j) == w)
break;
248 assert(j != bestface->GetNumVertices());
249 fv0.AddWithWeight(bestface->GetFVarData(j), fvarindex, fvarwidth, 0.125f);
251 for (j = 0; j < bestface->GetNumVertices(); ++j) {
252 if (bestface->GetVertex(j) == w)
break;
254 assert(j != bestface->GetNumVertices());
255 fv0.AddWithWeight(bestface->GetFVarData(j), fvarindex, fvarwidth, 0.125f);
258 else if (fvarmask != 0) {
261 fv0.SetWithWeight(face->
GetFVarData(index), fvarindex, fvarwidth, 0.75f);
269 HbrFace<T>* bestface = face;
270 HbrHalfedge<T>* bestedge = face->
GetEdge(index)->GetPrev();
271 HbrHalfedge<T>* starte = bestedge->GetOpposite();
274 w = face->
GetEdge(index)->GetPrev()->GetOrgVertex();
276 HbrHalfedge<T>* e = starte, *next;
277 assert(starte->GetOrgVertex() == v);
279 if (e->GetFVarSharpness(fvaritem) || !e->GetLeftFace()) {
280 bestface = e->GetRightFace();
286 bestface = e->GetLeftFace();
287 w = e->GetPrev()->GetOrgVertex();
291 }
while (e && e != starte);
293 if (!w) w = bestedge->GetDestVertex();
295 for (j = 0; j < bestface->GetNumVertices(); ++j) {
296 if (bestface->GetVertex(j) == w)
break;
298 assert(j != bestface->GetNumVertices());
299 fv0.AddWithWeight(bestface->GetFVarData(j), fvarindex, fvarwidth, 0.125f);
303 bestedge = face->
GetEdge(index);
306 if (HbrHalfedge<T>* e = starte) {
307 assert(starte->GetOrgVertex() == v);
309 if (e->GetFVarSharpness(fvaritem) || !e->GetRightFace()) {
310 bestface = e->GetLeftFace();
314 assert(e->GetOpposite());
316 }
while (e && e != starte);
318 if (!w) w = bestedge->GetDestVertex();
319 for (j = 0; j < bestface->GetNumVertices(); ++j) {
320 if (bestface->GetVertex(j) == w)
break;
322 assert(j != bestface->GetNumVertices());
323 fv0.AddWithWeight(bestface->GetFVarData(j), fvarindex, fvarwidth, 0.125f);
329 else if (!fv0IsSmooth || !fv0.IsInitialized()) {
331 float invvalencesquared = 1.0f / (valence * valence);
334 fv0.SetWithWeight(face->
GetFVarData(index), fvarindex, fvarwidth, invvalencesquared * valence * (valence - 2));
342 weight = invvalencesquared / g->GetNumVertices();
348 for (
int j = 0; j < g->GetNumVertices(); ++j) {
349 fv0.AddWithWeight(g->GetFVarData(j), fvarindex, fvarwidth, weight);
350 if (g->GetEdge(j)->GetOrgVertex() == v) {
351 fv0.AddWithWeight(g->GetFVarData((j + 1) % g->GetNumVertices()), fvarindex, fvarwidth, invvalencesquared);
355 if (edge == start)
break;
362 if (fvarinterp == HbrMesh<T>::k_InterpolateBoundaryNone ||
366 fv1.SetWithWeight(face->
GetFVarData(index), fvarindex, fvarwidth, 0.5f);
367 fv1.AddWithWeight(face->
GetFVarData((index + 1) % nv), fvarindex, fvarwidth, 0.5f);
368 }
else if (!fv1IsSmooth || !fv1.IsInitialized()) {
370 fv1.SetWithWeight(face->
GetFVarData(index), fvarindex, fvarwidth, 0.25f);
371 fv1.AddWithWeight(face->
GetFVarData((index + 1) % nv), fvarindex, fvarwidth, 0.25f);
373 fv1.AddWithWeight(fv2, fvarindex, fvarwidth, 0.25f);
376 weight = 0.25f / oppFace->GetNumVertices();
377 for (
int j = 0; j < oppFace->GetNumVertices(); ++j) {
378 fv1.AddWithWeight(oppFace->GetFVarData(j), fvarindex, fvarwidth, weight);
386 if (fvarinterp == HbrMesh<T>::k_InterpolateBoundaryNone ||
390 fv3.SetWithWeight(face->
GetFVarData((index + nv - 1) % nv), fvarindex, fvarwidth, 0.5f);
391 fv3.AddWithWeight(face->
GetFVarData(index), fvarindex, fvarwidth, 0.5f);
392 }
else if (!fv3IsSmooth || !fv3.IsInitialized()) {
394 fv3.SetWithWeight(face->
GetFVarData((index + nv - 1) % nv), fvarindex, fvarwidth, 0.25f);
395 fv3.AddWithWeight(face->
GetFVarData(index), fvarindex, fvarwidth, 0.25f);
397 fv3.AddWithWeight(fv2, fvarindex, fvarwidth, 0.25f);
400 weight = 0.25f / oppFace->GetNumVertices();
401 for (
int j = 0; j < oppFace->GetNumVertices(); ++j) {
402 fv3.AddWithWeight(oppFace->GetFVarData(j), fvarindex, fvarwidth, weight);
406 fvarindex += fvarwidth;
408 fv0.SetInitialized();
409 fv1.SetInitialized();
410 fv3.SetInitialized();
416 HbrCatmarkSubdivision<T>::transferEditsToChild(HbrFace<T>* face, HbrFace<T>* child,
int index) {
419 child->SetHole(face->IsHole());
422 if (HbrHierarchicalEdit<T>** edits = face->GetHierarchicalEdits()) {
423 while (HbrHierarchicalEdit<T>* edit = *edits) {
424 if (!edit->IsRelevantToFace(face))
break;
425 if (edit->GetNSubfaces() > face->GetDepth() &&
426 (edit->GetSubface(face->GetDepth()) == index)) {
427 child->SetHierarchicalEdits(edits);
448 bool extraordinary = (nv != 4);
453 for (
int i = 0; i < nv; ++i) {
456 std::cerr <<
"Kid " << i <<
"\n";
468 vertices[(i+3)%4] = prevedge->
Subdivide();
470 child = mesh->
NewFace(4, vertices, face, i);
472 std::cerr <<
"Creating face " << *child <<
" during refine\n";
493 transferFVarToChild(mesh, face, child, i);
503 transferEditsToChild(face, child, i);
515 std::cerr <<
" forcing refine on " << *face <<
" at " << *vertex <<
'\n';
524 bool extraordinary = (nv != 4);
529 for (
int i = 0; i < nv; ++i) {
543 vertices[(i+3)%4] = prevedge->
Subdivide();
546 std::cerr <<
"Kid " << i <<
"\n";
547 std::cerr <<
" subdivision created " << *vertices[0] <<
'\n';
548 std::cerr <<
" subdivision created " << *vertices[1] <<
'\n';
549 std::cerr <<
" subdivision created " << *vertices[2] <<
'\n';
550 std::cerr <<
" subdivision created " << *vertices[3] <<
'\n';
552 child = mesh->
NewFace(4, vertices, face, i);
554 std::cerr <<
"Creating face " << *child <<
" during refine\n";
565 childedge = prevedge->
Subdivide()->GetEdge(vertex->Subdivide());
574 transferFVarToChild(mesh, face, child, i);
584 transferEditsToChild(face, child, i);
608 bool destParentWasEdge =
true;
612 destParentWasEdge =
false;
621 if (parentEdge->
GetFace() != parentFace) {
626 assert(parentEdge && parentEdge->
GetFace() == parentFace);
628 std::cerr <<
"\nparent edge is " << *parentEdge <<
"\n";
634 if (destParentWasEdge) {
635 RefineFaceAtVertex(mesh, parentFace, parentEdge->GetOrgVertex());
637 RefineFaceAtVertex(mesh, parentFace, parentEdge->GetDestVertex());
656 std::cerr <<
"\nparent edge is " << *parentEdge <<
"\n";
661 parentFace = edge->
GetFace()->GetParent();
663 std::cerr <<
"\nparent face is " << *parentFace <<
"\n";
673 if (parentEdge->GetFace() != parentFace)
674 parentEdge = parentEdge->GetOpposite();
675 assert(parentEdge->GetFace() == parentFace);
678 GuaranteeNeighbor(mesh, parentEdge);
681 if (parentEdge->GetRightFace()) {
682 RefineFaceAtVertex(mesh, parentEdge->GetRightFace(), parentVertex);
697 std::cerr <<
"\n\nneighbor guarantee at " << *vertex <<
" invoked\n";
703 HbrFace<T>* parentFace = vertex->GetParentFace();
707 std::cerr <<
" forcing full refine on parent face\n";
709 Refine(mesh, parentFace);
721 std::cerr <<
" forcing full refine on adjacent faces of parent edge\n";
725 GuaranteeNeighbor(mesh, parentEdge);
727 RefineFaceAtVertex(mesh, parentFace, dest);
728 RefineFaceAtVertex(mesh, parentFace, org);
731 std::cerr <<
" on the right face?\n";
737 RefineFaceAtVertex(mesh, parentFace, dest);
738 RefineFaceAtVertex(mesh, parentFace, org);
741 std::cerr <<
" end force\n";
753 std::cerr <<
" recursive parent vertex guarantee call\n";
763 RefineFaceAtVertex(mesh, f, parentVertex);
765 if (edge == start)
break;
774 if (face->
IsHole())
return false;
777 if (!HasLimit(mesh, face->
GetEdge(i))) {
802 switch (vertex->
GetMask(
false)) {
844 float weight = 1.0f / nv;
854 data.AddWithWeight(w->
GetData(), weight);
855 data.AddVaryingWithWeight(w->
GetData(), weight);
859 std::cerr <<
"Subdividing at " << *face <<
"\n";
867 std::cerr <<
" created " << *v <<
"\n";
884 assert(face->
GetNumVertices() == 3 && triangleSubdivision == k_Old);
886 NgpVVectorItem& data = w->GetData();
889 float weight = 1.0f / 6.0f;
891 for (
int i = 0; i < 3; ++i) {
894 data.AddWithWeight(w->
Subdivide()->GetData(), weight);
895 data.AddWithWeight(e->
Subdivide()->GetData(), weight);
941 #define HBR_SMOOTH_TRI_EDGE_WEIGHT 0.470f
948 GuaranteeNeighbor(mesh, edge);
953 std::cerr <<
"Subdividing at " << *edge <<
" (sharpness = " << esharp <<
")";
985 float leftWeight, rightWeight, faceWeight, vertWeight;
995 faceWeight = 0.5f * (leftWeight + rightWeight);
996 vertWeight = 0.5f * (1.0f - 2.0f * faceWeight);
1000 faceWeight *= (1.0f - esharp);
1004 vertWeight = 0.5f * esharp + (1.0f - esharp) * vertWeight;
1006 data.AddWithWeight(edge->
GetOrgVertex()->GetData(), vertWeight);
1007 data.AddWithWeight(edge->
GetDestVertex()->GetData(), vertWeight);
1009 data.AddWithWeight(lf->
Subdivide()->GetData(), faceWeight);
1010 data.AddWithWeight(rf->
Subdivide()->GetData(), faceWeight);
1013 data.AddWithWeight(edge->
GetOrgVertex()->GetData(), 0.5f);
1018 data.AddVaryingWithWeight(edge->
GetOrgVertex()->GetData(), 0.5f);
1019 data.AddVaryingWithWeight(edge->
GetDestVertex()->GetData(), 0.5f);
1022 std::cerr <<
" created " << *v <<
"\n";
1035 float valence =
static_cast<float>(vertex->
GetValence());
1036 float invvalencesquared = 1.0f / (valence * valence);
1047 masks[0] = vertex->
GetMask(
false);
1048 masks[1] = vertex->
GetMask(
true);
1053 if (masks[0] != masks[1]) {
1055 weights[0] = 1.0f - weights[1];
1062 for (
int i = 0; i < passes; ++i) {
1067 data.AddWithWeight(vertex->
GetData(), weights[i] * invvalencesquared * valence * (valence - 2));
1071 mesh, vertex, weights[i] * invvalencesquared, &data);
1077 data.AddWithWeight(f->
Subdivide()->GetData(), weights[i] * invvalencesquared);
1079 if (edge == start)
break;
1085 data.AddWithWeight(vertex->
GetData(), weights[i] * 0.75f);
1090 mesh, vertex, i == 1, weights[i] * 0.125f, &data);
1096 data.AddWithWeight(vertex->
GetData(), weights[i]);
1103 data.AddVaryingWithWeight(vertex->
GetData(), 1.0f);
1106 std::cerr <<
"Subdividing at " << *vertex <<
"\n";
1107 std::cerr <<
" created " << *v <<
"\n";
1111 float sharp = vertex->GetSharpness();
1117 sharp = (float) HbrVertex<T>::k_Smooth;
1119 v->SetSharpness(sharp);
1127 using namespace OPENSUBDIV_VERSION;
bool HasVertexEdits() const
HbrHalfedge< T > * GetEdge(int index) const
#define HBR_SMOOTH_TRI_EDGE_WEIGHT
HbrVertex< T > * NewVertex(int id, const T &data)
bool IsFVarInfiniteSharpAnywhere()
void SetTriangleSubdivisionMethod(TriangleSubdivision method)
HbrFace< T > * GetRightFace() const
float GetSharpness() const
void GuaranteeNeighbors()
virtual bool HasLimit(HbrMesh< T > *mesh, HbrFace< T > *face)
void AddWithWeightAll(const HbrFVarData &fvvi, int width, float weight)
InterpolateBoundaryMethod GetFVarInterpolateBoundaryMethod() const
void CopyFVarInfiniteSharpness(HbrHalfedge< T > *edge)
unsigned char GetMask(bool next)
HbrHalfedge< T > * GetFirstEdge() const
void SubdivideCreaseWeight(HbrHalfedge< T > *edge, HbrVertex< T > *vertex, HbrHalfedge< T > *subedge)
bool GetFVarPropagateCorners() const
float GetSharpness() const
HbrFace< T > * GetChild(int index) const
virtual HbrSubdivision< T > * Clone() const
HbrHalfedge< T > * GetNext() const
HbrVertex< T > * GetDestVertex() const
bool IsFVarCorner(int datum)
virtual void GuaranteeNeighbors(HbrMesh< T > *mesh, HbrVertex< T > *vertex)
HbrHalfedge< T > * GetPreviousEdge(const HbrHalfedge< T > *edge) const
HbrVertex< T > * Subdivide()
HbrFace< T > * GetLeftFace() const
float GetFVarSharpness(int datum, bool ignoreGeometry=false)
HbrFace< T > * GetFace() const
HbrVertex< T > * GetParentVertex() const
virtual HbrFace< T > * RefineFaceAtVertex(HbrMesh< T > *mesh, HbrFace< T > *face, HbrVertex< T > *vertex)
HbrVertex< T > * Subdivide()
int GetTotalFVarWidth() const
HbrFVarData< T > & GetFVarData(int index)
int GetNumVertices() const
unsigned char GetFVarMask(int datum)
virtual void GuaranteeNeighbor(HbrMesh< T > *mesh, HbrHalfedge< T > *edge)
HbrVertex< T > * Subdivide()
HbrHalfedge< T > * GetIncidentEdge() const
HbrHalfedge< T > * GetNextEdge(const HbrHalfedge< T > *edge) const
virtual void Refine(HbrMesh< T > *mesh, HbrFace< T > *face)
void AddCreaseEdgesWithWeight(HbrMesh< T > *mesh, HbrVertex< T > *vertex, bool next, float weight, T *data)
HbrHalfedge< T > * GetOpposite() const
bool IsInitialized() const
virtual bool FaceIsExtraordinary(HbrMesh< T > const *, HbrFace< T > *face)
HbrVertex< T > * GetVertex(int index) const
HbrVertex< T > * GetOrgVertex() const
HbrFace< T > * NewFace(int nvertices, const int *vtx, int uindex)
InterpolateBoundaryMethod
void AddSurroundingVerticesWithWeight(HbrMesh< T > *mesh, HbrVertex< T > *vertex, float weight, T *data)
float GetFractionalMask() const
TriangleSubdivision GetTriangleSubdivisionMethod() const
virtual bool VertexIsExtraordinary(HbrMesh< T > const *, HbrVertex< T > *vertex)
const int * GetFVarWidths() const
HbrHalfedge< T > * GetPrev() const
virtual HbrVertex< T > * Subdivide(HbrMesh< T > *mesh, HbrFace< T > *face)
virtual int GetFaceChildrenCount(int nvertices) const