35 #include "../hbr/fvarData.h"
36 #include "../hbr/allocator.h"
38 #include "libgprims/stitch.h"
39 #include "libgprims/stitchInternal.h"
42 #include "../version.h"
44 namespace OpenSubdiv {
45 namespace OPENSUBDIV_VERSION {
53 template <
class T> std::ostream& operator<<(std::ostream& out, const HbrFace<T>& face);
59 for (std::vector<int>::const_reverse_iterator i =
remainder.rbegin(); i !=
remainder.rend(); ++i) {
77 std::vector<int>::const_reverse_iterator i = x.
remainder.rbegin();
78 std::vector<int>::const_reverse_iterator j = y.
remainder.rbegin();
79 for ( ; i != x.
remainder.rend(); ++i, ++j) {
80 if (*i != *j)
return (*i < *j);
92 return children[index];
96 return children[index];
110 HbrFace<T> *children[4];
113 template <
class T>
class HbrFace {
156 if (parent == -1)
return NULL;
157 return mesh->GetFace(parent);
165 int nchildren = mesh->GetSubdivision()->GetFaceChildrenCount(nvertices);
166 if (!
children.children || index < 0 || index >= nchildren)
return 0;
168 return children.extrachildren[index];
222 return GetVertex(index)->GetFVarData(
this);
245 if (editOffset == -1) {
248 return mesh->GetHierarchicalEditsAtOffset(editOffset);
257 int GetDepth()
const {
return static_cast<int>(depth); }
280 int nchildren = mesh->GetSubdivision()->GetFaceChildrenCount(p->nvertices);
282 for (
int i = 0; i < nchildren; ++i) {
283 if (p->children.extrachildren[i] == f) {
289 for (
int i = 0; i < nchildren; ++i) {
290 if ((*p->children.children)[i] == f) {
310 return mesh->GetFaceClientData(
id);
315 mesh->SetFaceClientData(
id, data);
353 unsigned int *fvarbits;
357 StitchEdge **stitchEdges;
374 unsigned short hole:1;
375 unsigned short coarse:1;
376 unsigned short protect:1;
377 unsigned short collected:1;
378 unsigned short hasVertexEdits:1;
379 unsigned short initialized:1;
380 unsigned short destroyed:1;
384 enum PatchType { kUnknown=0,
389 enum TransitionType { kTransition0=0,
396 struct AdaptiveFlags {
397 unsigned patchType:2;
398 unsigned transitionType:3;
402 unsigned isCritical:1;
403 unsigned isExtraordinary:1;
406 AdaptiveFlags() : patchType(0), transitionType(5), rots(0), brots(0), bverts(0), isCritical(0), isExtraordinary(0), isTagged(0) { }
409 AdaptiveFlags _adaptiveFlags;
411 bool isTransitionPatch()
const {
412 return (_adaptiveFlags.transitionType!=kNone);
415 bool hasTaggedVertices() {
417 for (
int i=0; i<nv; ++i) {
418 if (
GetVertex(i)->_adaptiveFlags.wasTagged)
427 using namespace OPENSUBDIV_VERSION;
431 #include "../hbr/mesh.h"
433 namespace OpenSubdiv {
434 namespace OPENSUBDIV_VERSION {
437 HbrFace<T>::HbrFace()
438 : mesh(0), id(-1), uindex(-1), ptexindex(-1), nvertices(0), extraedges(0), fvarbits(0), parent(-1), vchild(-1),
442 editOffset(-1), depth(0), hole(0), coarse(0), protect(0), collected(0), hasVertexEdits(0), initialized(0), destroyed(0) {
455 children.children = 0;
462 depth =
static_cast<unsigned char>(_depth);
473 int fvarbitsSizePerEdge = ((fvarcount + 15) / 16);
481 if (mesh->GetStitchCount()) {
482 const size_t buffersize = nv * (mesh->GetStitchCount() *
sizeof(StitchEdge*));
483 char *buffer = (
char *) malloc(buffersize);
484 memset(buffer, 0, buffersize);
485 stitchEdges = (StitchEdge**) buffer;
492 const size_t fvarbitsSize = nv * (fvarbitsSizePerEdge *
sizeof(
unsigned int));
493 char *buffer = (
char*) malloc(fvarbitsSize);
494 fvarbits = (
unsigned int*) buffer;
500 extraedges = (
char *) malloc(nv * edgesize);
501 for (i = 0; i < nv; ++i) {
510 char *buffer = ((
char *)
this +
sizeof(*
this));
512 if (mesh->GetStitchCount()) {
513 const size_t buffersize = 4 * (mesh->GetStitchCount() *
sizeof(StitchEdge*));
514 memset(buffer, 0, buffersize);
515 stitchEdges = (StitchEdge**) buffer;
516 buffer += buffersize;
520 fvarbits = (
unsigned int*) buffer;
526 _parent->SetChild(childindex,
this);
534 unsigned int *curfvarbits = fvarbits;
544 for (i = 0, next = 1; i < nv; ++i, ++next) {
545 if (next == nv) next = 0;
547 edge->Initialize(opposite, i, vertices[i], curfvarbits,
this);
550 curfvarbits = curfvarbits + fvarbitsSizePerEdge;
559 for (i = 0; i < nv; ++i) {
573 if (initialized && !destroyed) {
576 const int stitchCount = mesh->GetStitchCount();
580 if (children.children) {
581 int nchildren = mesh->GetSubdivision()->GetFaceChildrenCount(nvertices);
583 for (i = 0; i < nchildren; ++i) {
584 if (children.extrachildren[i]) {
585 children.extrachildren[i]->parent = -1;
586 children.extrachildren[i] = 0;
589 delete[] children.extrachildren;
590 children.extrachildren = 0;
592 for (i = 0; i < nchildren; ++i) {
593 if ((*children.children)[i]) {
594 (*children.children)[i]->parent = -1;
595 (*children.children)[i] = 0;
598 mesh->DeleteFaceChildren(children.children);
599 children.children = 0;
618 for (i = 0; i < nvertices; ++i) {
620 edge->DestroyStitchEdges(stitchCount);
635 for (i = 0; i < nvertices; ++i) {
636 edge->~HbrHalfedge<T>();
646 bool parentHasOtherKids =
false;
647 int nchildren = mesh->GetSubdivision()->GetFaceChildrenCount(parentFace->nvertices);
649 for (i = 0; i < nchildren; ++i) {
650 if (parentFace->children.extrachildren[i] ==
this) {
651 parentFace->children.extrachildren[i] = 0;
652 }
else if (parentFace->children.extrachildren[i]) parentHasOtherKids =
true;
656 if (!parentHasOtherKids) {
657 delete[] parentFace->children.extrachildren;
658 parentFace->children.extrachildren = 0;
659 if (parentFace->GarbageCollectable()) {
660 mesh->DeleteFace(parentFace);
664 for (i = 0; i < nchildren; ++i) {
665 if ((*parentFace->children.children)[i] ==
this) {
666 (*parentFace->children.children)[i] = 0;
667 }
else if ((*parentFace->children.children)[i]) parentHasOtherKids =
true;
671 if (!parentHasOtherKids) {
672 mesh->DeleteFaceChildren(parentFace->children.children);
673 parentFace->children.children = 0;
674 if (parentFace->GarbageCollectable()) {
675 mesh->DeleteFace(parentFace);
685 vchildVert->
SetParent(static_cast<HbrFace*>(0));
689 if (nvertices > 4 && fvarbits) {
704 if (nvertices <= 4) {
705 for (i = 0; i < nvertices; ++i) {
719 assert(index >= 0 && index < nvertices);
731 assert(index >= 0 && index < nvertices);
738 return mesh->GetVertex(edges[index].GetOrgVertexID());
745 assert(index >= 0 && index < nvertices);
752 return edges[index].GetOrgVertexID();
760 int nchildren = mesh->GetSubdivision()->GetFaceChildrenCount(nvertices);
762 if (!children.children) {
765 children.extrachildren =
new HbrFace<T>*[nchildren];
766 for (i = 0; i < nchildren; ++i) {
770 children.children = mesh->NewFaceChildren();
771 for (i = 0; i < nchildren; ++i) {
772 (*children.children)[i] = 0;
777 children.extrachildren[index] = face;
779 (*children.children)[index] = face;
781 face->parent = this->id;
787 if (vchild != -1)
return mesh->GetVertex(vchild);
789 vchild = vchildVert->
GetID();
797 mesh->GetSubdivision()->Refine(mesh,
this);
805 if (children.children) {
806 int nchildren = mesh->GetSubdivision()->GetFaceChildrenCount(nvertices);
808 for (
int i = 0; i < nchildren; ++i) {
809 if (children.extrachildren[i]) mesh->DeleteFace(children.extrachildren[i]);
811 delete[] children.extrachildren;
812 children.extrachildren = 0;
814 for (
int i = 0; i < nchildren; ++i) {
815 if ((*children.children)[i]) mesh->DeleteFace((*children.children)[i]);
817 mesh->DeleteFaceChildren(children.children);
818 children.children = 0;
826 return mesh->GetSubdivision()->HasLimit(mesh,
this);
846 size_t edgesize, eedgesize;
854 for (
int i = 0; i < nvertices; ++i) {
861 int nv = f->GetNumVertices();
869 for (
int j = 0; j < nv; ++j) {
874 if (ee == start)
break;
887 size_t edgesize, eedgesize;
895 for (
int i = 0; i < nvertices; ++i) {
901 int nv = f->GetNumVertices();
909 for (
int j = 0; j < nv; ++j) {
913 mesh->AddGarbageCollectableVertex(vert);
919 if (ee == start)
break;
923 if (gc) mesh->GarbageCollect();
929 if (children.children || protect)
return false;
930 for (
int i = 0; i < nvertices; ++i) {
933 if (vertex->
IsUsed())
return false;
946 editOffset = int(faceedits - baseedit);
950 if (!edit->IsRelevantToFace(
this))
break;
951 edit->ApplyEditToFace(
this);
962 size_t edgesize, eedgesize;
970 for (
int i = 0; i < nvertices; ++i) {
977 int nv = f->GetNumVertices();
985 for (
int j = 0; j < nv; ++j) {
987 std::vector<int>::iterator vi =
988 std::lower_bound(support.begin(), support.end(), id);
989 if (vi == support.end() || *vi != id) {
990 support.insert(vi,
id);
995 if (ee == start)
break;
1002 std::ostream& operator<<(std::ostream& out, const HbrFace<T>& face) {
1003 out <<
"face " << face.GetID() <<
", " << face.GetNumVertices() <<
" vertices (";
1004 for (
int i = 0; i < face.GetNumVertices(); ++i) {
1025 using namespace OPENSUBDIV_VERSION;
void RemoveIncidentEdge(HbrHalfedge< T > *edge)
void SetChild(int index, HbrFace< T > *face)
HbrHalfedge< T > * GetEdge(int index) const
void GuaranteeNeighbors()
HbrFacePath GetPath() const
HbrFaceChildren< T > * children
bool EdgeRemovalWillMakeSingular(HbrHalfedge< T > *edge) const
HbrHalfedge< T > * GetFirstEdge() const
HbrHalfedge< T > * GetEdge(const HbrVertex< T > *dest) const
void SetUniformIndex(int i)
HbrFace< T > * GetChild(int index) const
int GetVertexID(int index) const
HbrVertex< T > * GetVertex() const
int GetOrgVertexID() const
HbrVertex< T > * Subdivide()
HbrFace< T > ** extrachildren
HbrFace< T > * GetLeftFace() const
const HbrFace< T > *& operator[](const int index) const
HbrHierarchicalEdit< T > ** GetHierarchicalEdits() const
HbrFace< T > *& GetNext()
bool HasChildVertex() const
HbrVertex< T > * Subdivide()
HbrFace< T > * GetParent() const
HbrFace< T > *& operator[](const int index)
friend bool operator<(const HbrFacePath &x, const HbrFacePath &y)
void SetClientData(void *data)
HbrFVarData< T > & GetFVarData(int index)
int GetNumVertices() const
HbrMesh< T > * GetMesh() const
bool HasVertexEdits() const
bool operator<(const HbrFacePath &x, const HbrFacePath &y)
HbrHalfedge< T > * GetIncidentEdge() const
void Initialize(HbrMesh< T > *mesh, HbrFace< T > *parent, int childindex, int id, int uindex, int nvertices, HbrVertex< T > **vertices, int fvarwidth=0, int depth=0)
HbrHalfedge< T > * GetNextEdge(const HbrHalfedge< T > *edge) const
HbrVertex< T > * GetVertex(int index) const
HbrVertex< T > * GetOrgVertex() const
void SetParent(HbrHalfedge< T > *edge)
virtual void operator()(HbrFace< T > &face)=0
virtual ~HbrFaceOperator()
bool GarbageCollectable() const
int GetUniformIndex() const
unsigned long GetMemStats() const
void SetHierarchicalEdits(HbrHierarchicalEdit< T > **edits)
void * GetClientData() const
void SetOpposite(HbrHalfedge< T > *opposite)
void UnGuaranteeNeighbors()
std::vector< int > remainder
void GetSupportingVertices(std::vector< int > &support)
HbrFVarData< T > & GetFVarData(const HbrFace< T > *face)
void AddIncidentEdge(HbrHalfedge< T > *edge)