32 #include "../hbr/fvarData.h"
33 #include "../hbr/face.h"
35 #include "../version.h"
37 namespace OpenSubdiv {
38 namespace OPENSUBDIV_VERSION {
40 template <
class T>
class HbrHalfedge;
41 template <
class T>
class HbrHalfedgeCompare;
42 template <
class T>
class HbrVertex;
54 void Initialize(
int vid,
const T &data,
int fvarwidth);
79 int GetID()
const {
return id; }
167 bool IsSharp(
bool next)
const {
return (next ? (sharpness > 0.0f) : (sharpness >= 1.0f)); }
172 mask0 = mask1 = 0; validmask = 0; volatil = 0;
178 unsigned char GetMask(
bool next);
198 template <
typename OutputIterator>
209 template <
typename OutputIterator>
241 neighborsguaranteed = 0;
286 if (nIncidentEdges > 1) {
287 return incident.edges[0];
288 }
else if (nIncidentEdges == 1) {
289 return incident.edge;
311 bool IsUsed()
const {
return used || (vchild != -1); }
332 void splitSingular();
339 struct morefvardata {
361 unsigned short nIncidentEdges;
365 unsigned short mask0:3;
366 unsigned short mask1:3;
369 unsigned short extraordinary:1;
371 unsigned short validmask:1;
374 unsigned short volatil:1;
377 unsigned short neighborsguaranteed:1;
379 unsigned short collected:1;
384 unsigned short hasvertexedit:1;
386 unsigned short editsapplied:1;
388 unsigned short destroyed:1;
391 unsigned short parentType:2;
414 struct adaptiveFlags {
416 unsigned wasTagged:1;
418 adaptiveFlags() : isTagged(0), wasTagged(0) { }
421 adaptiveFlags _adaptiveFlags;
427 morefvar(0), id(-1), references(0), used(0),
428 sharpness(0.0f), vchild(-1), nIncidentEdges(0), extraordinary(0), validmask(0),
429 volatil(0), neighborsguaranteed(0), collected(0), hasvertexedit(0),
430 editsapplied(0), destroyed(0), parentType(k_ParentNone) {
446 neighborsguaranteed = 0;
454 assert(!parent.vertex);
455 parentType = k_ParentVertex;
463 char *buffer = ((
char*)
this +
sizeof(*
this));
479 assert(references == 0);
482 if (parentType == k_ParentEdge && parent.edge) {
483 parent.edge->RemoveChild();
485 }
else if (parentType == k_ParentFace && parent.face) {
486 parent.face->RemoveChild();
488 }
else if (parentType == k_ParentVertex && parent.vertex) {
489 parent.vertex->RemoveChild();
497 vchildVert->
SetParent(static_cast<HbrVertex*>(0));
521 unsigned short newEdgeCount = 0;
522 bool edgeFound =
false;
524 (nIncidentEdges > 1) ? incident.edges : &incident.edge;
526 for (i = 0; i < nIncidentEdges; ++i) {
527 if (incidentEdges[i] == edge) {
530 if (incidentEdges[i]->IsBoundary()) {
531 incidentEdges[newEdgeCount++] = incidentEdges[i];
540 bool prevmatch =
false;
542 edge = GetNextEdge(edge);
546 for (
int j = 0; j < i; ++j) {
547 if (incidentEdges[j] == edge) {
552 }
while (!prevmatch && edge && edge != start);
553 if (!prevmatch && edge && edge == start) {
555 incidentEdges[newEdgeCount++] = incidentEdges[i];
565 if (newEdgeCount == 0) {
566 if (!(edgeFound && nIncidentEdges == 1)) {
567 if (nIncidentEdges > 1) {
568 delete [] incidentEdges;
570 incidentEdges = &incident.edge;
571 incidentEdges[0] = edge;
582 if (newEdgeCount + 1 != nIncidentEdges) {
584 if (newEdgeCount + 1 > 1) {
587 newIncidentEdges = &incident.edge;
589 for (i = 0; i < newEdgeCount; ++i) {
590 newIncidentEdges[i] = incidentEdges[i];
592 if (nIncidentEdges > 1) {
593 delete[] incidentEdges;
595 nIncidentEdges = newEdgeCount + 1;
596 incidentEdges = newIncidentEdges;
597 if (nIncidentEdges > 1) {
598 incident.edges = newIncidentEdges;
601 incidentEdges[newEdgeCount] = edge;
606 if (newEdgeCount != nIncidentEdges) {
608 if (newEdgeCount > 1) {
611 newIncidentEdges = &incident.edge;
613 for (i = 0; i < newEdgeCount; ++i) {
614 newIncidentEdges[i] = incidentEdges[i];
616 if (nIncidentEdges > 1) {
617 delete[] incidentEdges;
619 nIncidentEdges = newEdgeCount;
620 incidentEdges = newIncidentEdges;
621 if (nIncidentEdges > 1) {
622 incident.edges = newIncidentEdges;
630 if (newEdgeCount != nIncidentEdges) {
632 if (newEdgeCount > 1) {
635 newIncidentEdges = &incident.edge;
637 for (i = 0; i < newEdgeCount; ++i) {
638 newIncidentEdges[i] = incidentEdges[i];
640 if (nIncidentEdges > 1) {
641 delete[] incidentEdges;
643 nIncidentEdges = newEdgeCount;
644 incidentEdges = newIncidentEdges;
645 if (nIncidentEdges > 1) {
646 incident.edges = newIncidentEdges;
655 if (!incidentEdges[0]->IsBoundary()) {
657 incidentEdges[0] = start;
661 if (e == start)
break;
663 if (ePath < incidentEdgePath) {
664 incidentEdges[0] = e;
665 incidentEdgePath = ePath;
670 if (e->
GetFace()->GetPath() < incidentEdges[0]->
GetFace()->GetPath()) {
671 incidentEdges[0] = e;
689 (nIncidentEdges > 1) ? incident.edges : &incident.edge;
698 bool edgeFound =
false;
699 next = GetNextEdge(edge);
701 for (i = 0; i < nIncidentEdges; ++i) {
702 if (incidentEdges[i] == edge) {
707 incidentEdges[i] = next;
721 assert(nIncidentEdges > 1);
724 if (nIncidentEdges - 1 > 1) {
727 newIncidentEdges = &incident.edge;
730 for (i = 0; i < nIncidentEdges; ++i) {
731 if (incidentEdges[i] != edge) {
732 newIncidentEdges[j++] = incidentEdges[i];
735 assert(j == nIncidentEdges - 1);
736 if (nIncidentEdges > 1) {
737 delete[] incidentEdges;
740 if (nIncidentEdges > 1) {
741 incident.edges = newIncidentEdges;
750 else if (nIncidentEdges == 1 && !incidentEdges[0]->IsBoundary()) {
752 incidentEdges[0] = next;
756 std::cout <<
"Could not split cycle!\n";
772 if (nIncidentEdges + 1 > 1) {
775 newIncidentEdges = &incident.edge;
777 for (i = 0; i < nIncidentEdges; ++i) {
778 newIncidentEdges[i] = incidentEdges[i];
780 newIncidentEdges[nIncidentEdges] = next;
781 if (nIncidentEdges > 1) {
782 delete[] incidentEdges;
785 if (nIncidentEdges > 1) {
786 incident.edges = newIncidentEdges;
791 if (nIncidentEdges > 1) {
792 delete[] incidentEdges;
802 if (references <= 1 || nIncidentEdges <= 0) {
809 else if (nIncidentEdges > 1) {
815 else if (nIncidentEdges == 1 && incident.edge == edge) {
824 else if (!GetIncidentEdge()->IsBoundary()) {
826 }
else if (GetNextEdge(edge)) {
836 extraordinary =
false;
838 if (IsSingular()) splitSingular();
839 assert(!IsSingular());
840 if (mesh->GetSubdivision()) {
841 extraordinary = mesh->GetSubdivision()->VertexIsExtraordinary(mesh,
this);
850 assert(!IsSingular());
852 (nIncidentEdges > 1) ? incident.edges[0] : incident.edge;
856 edge = GetNextEdge(edge);
857 }
while (edge && edge != start);
860 if (!edge) valence++;
868 assert(!IsSingular());
870 (nIncidentEdges > 1) ? incident.edges[0] : incident.edge;
873 if (edge->IsCoarse()) {
876 edge = GetNextEdge(edge);
877 }
while (edge && edge != start);
881 if (!edge) valence++;
891 size_t fvtsize =
sizeof(
HbrFVarData<T>) +
sizeof(
float) * (GetMesh()->GetTotalFVarWidth() - 1);
893 for (
int i = 0; i < morefvar->count; ++i) {
908 const int fvarwidth = GetMesh()->GetTotalFVarWidth();
909 size_t fvtsize =
sizeof(
HbrFVarData<T>) + (fvarwidth - 1) *
sizeof(float);
911 struct morefvardata *newmorefvar =
912 (
struct morefvardata *) malloc(
sizeof(
int) + (morefvar->count + 1) * fvtsize);
915 for (
int i = 0; i < morefvar->count; ++i) {
924 newmorefvar->count = morefvar->count + 1;
926 morefvar = newmorefvar;
929 morefvar = (
struct morefvardata *) malloc(
sizeof(
int) + fvtsize);
943 return GetIncidentEdge()->GetFace();
949 return GetFace()->GetMesh();
956 for (
int i = 0; i < nIncidentEdges; ++i) {
958 (nIncidentEdges > 1) ? incident.edges[i] : incident.edge;
961 if (edge->GetDestVertex() == dest) {
964 edge = GetNextEdge(edge);
965 }
while (edge && edge != cycle);
974 for (
int i = 0; i < nIncidentEdges; ++i) {
976 (nIncidentEdges > 1) ? incident.edges[i] : incident.edge;
979 if (edge->GetDestVertexID() == dest) {
982 edge = GetNextEdge(edge);
983 }
while (edge && edge != cycle);
993 return edge->
GetPrev()->GetOpposite();
1009 return edge->
GetPrev()->GetOrgVertex();
1014 next = GetNextEdge(edge);
1017 return edge->
GetPrev()->GetOrgVertex();
1019 return next->GetDestVertex();
1022 if (next == start) {
1025 if (edge->
GetPrev()->GetOrgVertex() == dest) {
1042 return edge->
GetPrev()->GetOrgVertex();
1051 return edge->
GetOpposite()->GetNext()->GetDestVertex();
1056 next = GetNextEdge(edge);
1057 if (next == start) {
1058 if (next->GetDestVertex() == dest) {
1064 if (edge->
GetPrev()->GetOrgVertex() == dest) {
1067 return edge->
GetPrev()->GetOrgVertex();
1071 }
else if (next->GetDestVertex() == dest) {
1082 return edge->
GetNext()->GetDestVertex();
1092 return edge->
GetOpposite()->GetNext()->GetDestVertex();
1103 return edge->
GetNext()->GetDestVertex();
1107 return edge->
GetPrev()->GetOrgVertex();
1117 return GetIncidentEdge()->IsBoundary();
1123 return (GetFVarMask(datum) == k_Smooth);
1129 for (
int i = 0; i < GetMesh()->GetFVarCount(); ++i) {
1130 if (!IsFVarSmooth(i))
return false;
1138 return (GetFVarMask(datum) == k_Dart);
1146 if (IsFVarDart(datum))
return true;
1152 bool lastedgewassharp =
false;
1154 if (edge->GetFVarSharpness(datum)) {
1155 if (lastedgewassharp) {
1158 lastedgewassharp =
true;
1161 lastedgewassharp =
false;
1163 nextedge = GetNextEdge(edge);
1164 if (nextedge == start) {
1166 }
else if (!nextedge) {
1168 edge = edge->GetPrev();
1169 return edge->GetFVarSharpness(datum) && lastedgewassharp;
1182 return (
unsigned char)(next ? mask1 : mask0);
1188 if (sharpness > k_Smooth && sharpness < k_InfinitelySharp)
1193 if (IsSharp(
false)) {
1196 if (IsSharp(
true)) {
1206 if (edge->IsSharp(
false)) {
1207 if (mask0 < k_Corner) {
1211 if (edge->IsSharp(
true)) {
1212 if (mask1 < k_Corner) {
1220 nextedge = GetNextEdge(edge);
1221 if (nextedge == start) {
1223 }
else if (!nextedge) {
1225 edge = edge->GetPrev();
1226 esharp = edge->GetSharpness();
1227 if (edge->IsSharp(
false)) {
1228 if (mask0 < k_Corner) {
1232 if (edge->IsSharp(
true)) {
1233 if (mask1 < k_Corner) {
1246 return (
unsigned char)(next ? mask1 : mask0);
1253 unsigned char mask = 0;
1257 if (IsSharp(
false)) {
1265 if (edge->GetFVarSharpness(datum)) {
1266 if (mask < k_Corner) {
1273 nextedge = GetNextEdge(edge);
1274 if (nextedge == start) {
1276 }
else if (!nextedge) {
1278 edge = edge->GetPrev();
1279 if (edge->GetFVarSharpness(datum)) {
1280 if (mask < k_Corner) {
1298 if (sharpness > k_Smooth && sharpness < k_Dart) {
1299 mask += sharpness; ++n;
1308 mask += esharp; ++n;
1310 next = GetNextEdge(edge);
1311 if (next == start) {
1315 esharp = edge->GetPrev()->GetSharpness();
1317 mask += esharp; ++n;
1324 assert (n > 0.0f && mask < n);
1329 template <
typename OutputIterator>
1336 next = GetNextEdge(edge);
1337 if (next == start) {
1341 *edges++ = edge->GetPrev();
1356 next = GetNextEdge(edge);
1357 if (next == start) {
1360 op(*edge->GetPrev());
1369 template <
typename OutputIterator>
1377 next = GetNextEdge(edge);
1378 if (next == start) {
1384 *vertices++ = edge->GetPrev()->GetOrgVertex(mesh);
1399 op(*edge->GetDestVertex(mesh));
1400 next = GetNextEdge(edge);
1401 if (next == start)
return;
1403 op(*edge->GetPrev()->GetOrgVertex(mesh));
1417 op(*edge->GetLeftFace());
1418 edge = GetNextEdge(edge);
1419 if (edge == start)
break;
1427 if (vchild != -1)
return mesh->
GetVertex(vchild);
1429 vchild = vchildVert->
GetID();
1444 if (!neighborsguaranteed) {
1447 neighborsguaranteed = 1;
1453 if (hasvertexedit && !editsapplied) {
1460 if (!edit->IsRelevantToFace(face))
break;
1461 edit->ApplyEditToVertex(face,
this);
1465 edge = GetNextEdge(edge);
1466 if (edge == start)
break;
1486 (nIncidentEdges > 1) ? incident.edges : &incident.edge;
1490 for (
int i = 1; i < nIncidentEdges; ++i) {
1494 w->
GetData().AddWithWeight(GetData(), 1.0);
1505 }
while (e && e != start);
1507 for (
typename std::vector<
HbrHalfedge<T>*>::iterator ei = edges.begin(); ei != edges.end(); ++ei) {
1527 mesh->addSplitVertex(w->
GetID(), this->GetID());
1531 e = incidentEdges[0];
1532 if (nIncidentEdges > 1) {
1533 delete[] incidentEdges;
1541 operator<<(std::ostream& out, const HbrVertex<T>& vertex) {
1542 return out <<
"vertex " << vertex.GetID();
1553 using namespace OPENSUBDIV_VERSION;
void RemoveIncidentEdge(HbrHalfedge< T > *edge)
HbrFVarData< T > & NewFVarData(const HbrFace< T > *face)
void SetVertexClientData(int id, void *data)
HbrVertex< T > * NewVertex(int id, const T &data)
bool HasVertexEdit() const
void SetParent(HbrFace< T > *face)
float GetSharpness() const
void GuaranteeNeighbors()
HbrVertex< T > * GetVertex(int id) const
void ApplyOperatorSurroundingVertices(HbrVertexOperator< T > &op) const
bool EdgeRemovalWillMakeSingular(HbrHalfedge< T > *edge) const
bool IsReferenced() const
unsigned char GetMask(bool next)
HbrHalfedge< T > * GetEdge(const HbrVertex< T > *dest) const
float GetSharpness() const
void GetSurroundingEdges(OutputIterator edges) const
void * GetVertexClientData(int id) const
HbrHalfedge< T > * GetNext() const
HbrVertex< T > * GetDestVertex() const
bool IsFVarCorner(int datum)
float * GetData(int item)
HbrHalfedge< T > * GetPreviousEdge(const HbrHalfedge< T > *edge) const
HbrFace< T > * GetParentFace() const
HbrVertex< T > * Subdivide()
HbrVertex< T > *& GetNext()
virtual void operator()(HbrVertex< T > &vertex)=0
HbrSubdivision< T > * GetSubdivision() const
float GetFVarSharpness(int datum, bool ignoreGeometry=false)
HbrHierarchicalEdit< T > ** GetHierarchicalEdits() const
HbrFace< T > * GetFace() const
HbrMesh< T > * GetMesh() const
HbrVertex< T > * GetParentVertex() const
HbrHalfedge< T > ** edges
unsigned char GetFVarMask(int datum)
HbrHalfedge< T > * GetIncidentEdge() const
HbrVertex< T > * GetQEOPrev(const HbrHalfedge< T > *edge) const
void SetSharpness(float sharp)
HbrFace< T > * GetFace() const
HbrHalfedge< T > * GetNextEdge(const HbrHalfedge< T > *edge) const
bool IsExtraordinary() const
HbrHalfedge< T > * GetOpposite() const
int GetCoarseValence() const
bool IsFVarDart(int datum)
void GetSurroundingVertices(OutputIterator vertices) const
HbrVertex< T > * GetOrgVertex() const
bool IsSharp(bool next) const
const T & GetData() const
void SetParent(HbrHalfedge< T > *edge)
void ApplyOperatorSurroundingFaces(HbrFaceOperator< T > &op) const
HbrVertex(int vid, const T &data, int fvarwidth)
void SetParent(HbrVertex< T > *vertex)
void Destroy(HbrMesh< T > *mesh=0)
void * GetClientData(HbrMesh< T > *mesh) const
void Initialize(int vid, const T &data, int fvarwidth)
HbrHalfedge< T > * GetParentEdge() const
void SetClientData(HbrMesh< T > *mesh, void *data)
bool IsFVarSmooth(int datum)
void ApplyOperatorSurroundingEdges(HbrHalfedgeOperator< T > &op) const
unsigned long GetMemStats() const
float GetFractionalMask() const
void SetAllData(int width, const float *values)
void SetOrgVertex(HbrVertex< T > *v)
void UnGuaranteeNeighbors()
virtual ~HbrVertexOperator()
HbrVertex< T > * GetQEONext(const HbrVertex< T > *dest) const
HbrVertex< T > * GetQELNext(const HbrVertex< T > *dest) const
HbrHalfedge< T > * GetPrev() const
HbrFVarData< T > & GetFVarData(const HbrFace< T > *face)
void AddIncidentEdge(HbrHalfedge< T > *edge)