29 #include "../hbr/subdivision.h"
31 #include "../version.h"
33 namespace OpenSubdiv {
34 namespace OPENSUBDIV_VERSION {
81 bool extraordinary = (nv != 4);
87 float weight = 1.0f / nv;
101 for (
int j = 0; j < nv; ++j) {
114 bool fv0IsSmooth, fv1IsSmooth, fv3IsSmooth;
116 childVertex = child->
GetVertex(extraordinary ? 0 : (index+0)%4);
119 childVertex->NewFVarData(child);
121 HbrFVarData<T>& fv0 = childVertex->GetFVarData(child);
124 GuaranteeNeighbor(mesh, edge);
126 childVertex = child->
GetVertex(extraordinary ? 1 : (index+1)%4);
129 childVertex->NewFVarData(child);
131 HbrFVarData<T>& fv1 = childVertex->GetFVarData(child);
134 GuaranteeNeighbor(mesh, edge);
135 assert(edge == face->
GetEdge((index + nv - 1) % nv));
137 childVertex = child->
GetVertex(extraordinary ? 3 : (index+3)%4);
140 childVertex->NewFVarData(child);
142 HbrFVarData<T>& fv3 = childVertex->GetFVarData(child);
144 for (
int fvaritem = 0; fvaritem < fvarcount; ++fvaritem) {
158 bool infcorner =
false;
160 const unsigned char fvarmask = v->
GetFVarMask(fvaritem);
161 if (fvarinterp == HbrMesh<T>::k_InterpolateBoundaryEdgeAndCorner) {
162 if (fvarmask >= HbrVertex<T>::k_Corner) {
169 if (face->
GetEdge(index)->GetFVarSharpness(fvaritem,
true) && face->
GetEdge(index)->GetPrev()->GetFVarSharpness(fvaritem,
true)) {
181 if (fvarinterp == HbrMesh<T>::k_InterpolateBoundaryNone ||
182 (fvarinterp == HbrMesh<T>::k_InterpolateBoundaryAlwaysSharp &&
186 fv0.SetWithWeight(face->
GetFVarData(index), fvarindex, fvarwidth, 1.0f);
191 else if (fvarmask == 1) {
195 fv0.SetWithWeight(face->
GetFVarData(index), fvarindex, fvarwidth, 0.75f);
207 if (nextedge == start) {
210 }
else if (!nextedge) {
224 for (j = 0; j < bestface->GetNumVertices(); ++j) {
225 if (bestface->GetVertex(j) == w)
break;
227 assert(j != bestface->GetNumVertices());
228 fv0.AddWithWeight(bestface->GetFVarData(j), fvarindex, fvarwidth, 0.125f);
230 for (j = 0; j < bestface->GetNumVertices(); ++j) {
231 if (bestface->GetVertex(j) == w)
break;
233 assert(j != bestface->GetNumVertices());
234 fv0.AddWithWeight(bestface->GetFVarData(j), fvarindex, fvarwidth, 0.125f);
237 else if (fvarmask != 0) {
240 fv0.SetWithWeight(face->
GetFVarData(index), fvarindex, fvarwidth, 0.75f);
248 HbrFace<T>* bestface = face;
249 HbrHalfedge<T>* bestedge = face->
GetEdge(index)->GetPrev();
250 HbrHalfedge<T>* starte = bestedge->GetOpposite();
253 w = face->
GetEdge(index)->GetPrev()->GetOrgVertex();
255 HbrHalfedge<T>* e = starte, *next;
256 assert(starte->GetOrgVertex() == v);
258 if (e->GetFVarSharpness(fvaritem) || !e->GetLeftFace()) {
259 bestface = e->GetRightFace();
265 bestface = e->GetLeftFace();
266 w = e->GetPrev()->GetOrgVertex();
270 }
while (e && e != starte);
272 if (!w) w = bestedge->GetDestVertex();
274 for (j = 0; j < bestface->GetNumVertices(); ++j) {
275 if (bestface->GetVertex(j) == w)
break;
277 assert(j != bestface->GetNumVertices());
278 fv0.AddWithWeight(bestface->GetFVarData(j), fvarindex, fvarwidth, 0.125f);
282 bestedge = face->
GetEdge(index);
285 if (HbrHalfedge<T>* e = starte) {
286 assert(starte->GetOrgVertex() == v);
288 if (e->GetFVarSharpness(fvaritem) || !e->GetRightFace()) {
289 bestface = e->GetLeftFace();
293 assert(e->GetOpposite());
295 }
while (e && e != starte);
297 if (!w) w = bestedge->GetDestVertex();
298 for (j = 0; j < bestface->GetNumVertices(); ++j) {
299 if (bestface->GetVertex(j) == w)
break;
301 assert(j != bestface->GetNumVertices());
302 fv0.AddWithWeight(bestface->GetFVarData(j), fvarindex, fvarwidth, 0.125f);
308 else if (!fv0IsSmooth || !fv0.IsInitialized()) {
310 float invvalencesquared = 1.0f / (valence * valence);
313 fv0.SetWithWeight(face->
GetFVarData(index), fvarindex, fvarwidth, invvalencesquared * valence * (valence - 2));
321 weight = invvalencesquared / g->GetNumVertices();
327 for (
int j = 0; j < g->GetNumVertices(); ++j) {
328 fv0.AddWithWeight(g->GetFVarData(j), fvarindex, fvarwidth, weight);
329 if (g->GetEdge(j)->GetOrgVertex() == v) {
330 fv0.AddWithWeight(g->GetFVarData((j + 1) % g->GetNumVertices()), fvarindex, fvarwidth, invvalencesquared);
334 if (edge == start)
break;
341 if (fvarinterp == HbrMesh<T>::k_InterpolateBoundaryNone ||
345 fv1.SetWithWeight(face->
GetFVarData(index), fvarindex, fvarwidth, 0.5f);
346 fv1.AddWithWeight(face->
GetFVarData((index + 1) % nv), fvarindex, fvarwidth, 0.5f);
347 }
else if (!fv1IsSmooth || !fv1.IsInitialized()) {
349 fv1.SetWithWeight(face->
GetFVarData(index), fvarindex, fvarwidth, 0.25f);
350 fv1.AddWithWeight(face->
GetFVarData((index + 1) % nv), fvarindex, fvarwidth, 0.25f);
352 fv1.AddWithWeight(fv2, fvarindex, fvarwidth, 0.25f);
355 weight = 0.25f / oppFace->GetNumVertices();
356 for (
int j = 0; j < oppFace->GetNumVertices(); ++j) {
357 fv1.AddWithWeight(oppFace->GetFVarData(j), fvarindex, fvarwidth, weight);
365 if (fvarinterp == HbrMesh<T>::k_InterpolateBoundaryNone ||
369 fv3.SetWithWeight(face->
GetFVarData((index + nv - 1) % nv), fvarindex, fvarwidth, 0.5f);
370 fv3.AddWithWeight(face->
GetFVarData(index), fvarindex, fvarwidth, 0.5f);
371 }
else if (!fv3IsSmooth || !fv3.IsInitialized()) {
373 fv3.SetWithWeight(face->
GetFVarData((index + nv - 1) % nv), fvarindex, fvarwidth, 0.25f);
374 fv3.AddWithWeight(face->
GetFVarData(index), fvarindex, fvarwidth, 0.25f);
376 fv3.AddWithWeight(fv2, fvarindex, fvarwidth, 0.25f);
379 weight = 0.25f / oppFace->GetNumVertices();
380 for (
int j = 0; j < oppFace->GetNumVertices(); ++j) {
381 fv3.AddWithWeight(oppFace->GetFVarData(j), fvarindex, fvarwidth, weight);
385 fvarindex += fvarwidth;
387 fv0.SetInitialized();
388 fv1.SetInitialized();
389 fv3.SetInitialized();
394 HbrBilinearSubdivision<T>::transferEditsToChild(HbrFace<T>* face, HbrFace<T>* child,
int index) {
397 child->SetHole(face->IsHole());
400 if (HbrHierarchicalEdit<T>** edits = face->GetHierarchicalEdits()) {
401 while (HbrHierarchicalEdit<T>* edit = *edits) {
402 if (!edit->IsRelevantToFace(face))
break;
403 if (edit->GetNSubfaces() > face->GetDepth() &&
404 (edit->GetSubface(face->GetDepth()) == index)) {
405 child->SetHierarchicalEdits(edits);
426 bool extraordinary = (nv != 4);
431 for (
int i = 0; i < nv; ++i) {
434 std::cerr <<
"Kid " << i <<
"\n";
446 vertices[(i+3)%4] = prevedge->
Subdivide();
448 child = mesh->
NewFace(4, vertices, face, i);
450 std::cerr <<
"Creating face " << *child <<
" during refine\n";
469 transferFVarToChild(mesh, face, child, i);
479 transferEditsToChild(face, child, i);
491 std::cerr <<
" forcing refine on " << *face <<
" at " << *vertex <<
'\n';
500 bool extraordinary = (nv != 4);
505 for (
int i = 0; i < nv; ++i) {
519 vertices[(i+3)%4] = prevedge->
Subdivide();
522 std::cerr <<
"Kid " << i <<
"\n";
523 std::cerr <<
" subdivision created " << *vertices[0] <<
'\n';
524 std::cerr <<
" subdivision created " << *vertices[1] <<
'\n';
525 std::cerr <<
" subdivision created " << *vertices[2] <<
'\n';
526 std::cerr <<
" subdivision created " << *vertices[3] <<
'\n';
528 child = mesh->
NewFace(4, vertices, face, i);
530 std::cerr <<
"Creating face " << *child <<
" during refine\n";
540 childedge = prevedge->
Subdivide()->GetEdge(vertex->Subdivide());
548 transferFVarToChild(mesh, face, child, i);
558 transferEditsToChild(face, child, i);
582 bool destParentWasEdge =
true;
586 destParentWasEdge =
false;
595 if (parentEdge->
GetFace() != parentFace) {
600 assert(parentEdge && parentEdge->
GetFace() == parentFace);
602 std::cerr <<
"\nparent edge is " << *parentEdge <<
"\n";
608 if (destParentWasEdge) {
609 RefineFaceAtVertex(mesh, parentFace, parentEdge->GetOrgVertex());
611 RefineFaceAtVertex(mesh, parentFace, parentEdge->GetDestVertex());
630 std::cerr <<
"\nparent edge is " << *parentEdge <<
"\n";
635 parentFace = edge->
GetFace()->GetParent();
637 std::cerr <<
"\nparent face is " << *parentFace <<
"\n";
647 if (parentEdge->GetFace() != parentFace)
648 parentEdge = parentEdge->GetOpposite();
649 assert(parentEdge->GetFace() == parentFace);
652 GuaranteeNeighbor(mesh, parentEdge);
655 if (parentEdge->GetRightFace()) {
656 RefineFaceAtVertex(mesh, parentEdge->GetRightFace(), parentVertex);
671 std::cerr <<
"\n\nneighbor guarantee at " << *vertex <<
" invoked\n";
677 HbrFace<T>* parentFace = vertex->GetParentFace();
681 std::cerr <<
" forcing full refine on parent face\n";
683 Refine(mesh, parentFace);
695 std::cerr <<
" forcing full refine on adjacent faces of parent edge\n";
699 GuaranteeNeighbor(mesh, parentEdge);
701 RefineFaceAtVertex(mesh, parentFace, dest);
702 RefineFaceAtVertex(mesh, parentFace, org);
705 std::cerr <<
" on the right face?\n";
711 RefineFaceAtVertex(mesh, parentFace, dest);
712 RefineFaceAtVertex(mesh, parentFace, org);
715 std::cerr <<
" end force\n";
727 std::cerr <<
" recursive parent vertex guarantee call\n";
737 RefineFaceAtVertex(mesh, f, parentVertex);
739 if (edge == start)
break;
748 if (face->
IsHole())
return false;
751 if (!HasLimit(mesh, face->
GetEdge(i))) {
768 switch (vertex->
GetMask(
false)) {
788 float weight = 1.0f / nv;
798 data.AddWithWeight(w->
GetData(), weight);
799 data.AddVaryingWithWeight(w->
GetData(), weight);
803 std::cerr <<
"Subdividing at " << *face <<
"\n";
811 std::cerr <<
" created " << *v <<
"\n";
822 std::cerr <<
"Subdividing at " << *edge <<
" (sharpness = " << esharp <<
")";
843 data.AddWithWeight(edge->
GetOrgVertex()->GetData(), 0.5f);
847 data.AddVaryingWithWeight(edge->
GetOrgVertex()->GetData(), 0.5f);
848 data.AddVaryingWithWeight(edge->
GetDestVertex()->GetData(), 0.5f);
851 std::cerr <<
" created " << *v <<
"\n";
873 data.AddWithWeight(vertex->
GetData(), 1.0f);
876 data.AddVaryingWithWeight(vertex->
GetData(), 1.0f);
884 std::cerr <<
"Subdividing at " << *vertex <<
"\n";
885 std::cerr <<
" created " << *v <<
"\n";
889 float sharp = vertex->GetSharpness();
895 sharp = (float) HbrVertex<T>::k_Smooth;
897 v->SetSharpness(sharp);
905 using namespace OPENSUBDIV_VERSION;
bool HasVertexEdits() const
HbrHalfedge< T > * GetEdge(int index) const
virtual int GetFaceChildrenCount(int nvertices) const
HbrVertex< T > * NewVertex(int id, const T &data)
bool IsFVarInfiniteSharpAnywhere()
virtual void GuaranteeNeighbors(HbrMesh< T > *mesh, HbrVertex< T > *vertex)
HbrFace< T > * GetRightFace() const
float GetSharpness() const
void GuaranteeNeighbors()
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)
virtual HbrSubdivision< T > * Clone() const
bool GetFVarPropagateCorners() const
virtual HbrFace< T > * RefineFaceAtVertex(HbrMesh< T > *mesh, HbrFace< T > *face, HbrVertex< T > *vertex)
float GetSharpness() const
HbrFace< T > * GetChild(int index) const
HbrHalfedge< T > * GetNext() const
HbrVertex< T > * GetDestVertex() const
bool IsFVarCorner(int datum)
HbrHalfedge< T > * GetPreviousEdge(const HbrHalfedge< T > *edge) const
HbrVertex< T > * Subdivide()
HbrFace< T > * GetLeftFace() const
bool HasCreaseEdits() const
float GetFVarSharpness(int datum, bool ignoreGeometry=false)
HbrFace< T > * GetFace() const
HbrVertex< T > * GetParentVertex() const
HbrVertex< T > * Subdivide()
int GetTotalFVarWidth() const
virtual void GuaranteeNeighbor(HbrMesh< T > *mesh, HbrHalfedge< T > *edge)
HbrFVarData< T > & GetFVarData(int index)
int GetNumVertices() const
unsigned char GetFVarMask(int datum)
HbrVertex< T > * Subdivide()
HbrHalfedge< T > * GetIncidentEdge() const
virtual bool FaceIsExtraordinary(HbrMesh< T > const *, HbrFace< T > *face)
HbrHalfedge< T > * GetNextEdge(const HbrHalfedge< T > *edge) const
HbrHalfedge< T > * GetOpposite() const
bool IsInitialized() const
HbrVertex< T > * GetVertex(int index) const
HbrVertex< T > * GetOrgVertex() const
virtual void Refine(HbrMesh< T > *mesh, HbrFace< T > *face)
virtual bool VertexIsExtraordinary(HbrMesh< T > const *, HbrVertex< T > *vertex)
HbrFace< T > * NewFace(int nvertices, const int *vtx, int uindex)
InterpolateBoundaryMethod
virtual bool HasLimit(HbrMesh< T > *mesh, HbrFace< T > *face)
virtual HbrVertex< T > * Subdivide(HbrMesh< T > *mesh, HbrFace< T > *face)
const int * GetFVarWidths() const
HbrHalfedge< T > * GetPrev() const