3 #ifndef VSR_GRAPH_H_INCLUDED
4 #define VSR_GRAPH_H_INCLUDED
43 Node&
data( T& v ) { ptr = &v;
return *
this; }
46 vector<HalfEdge*>
valence()
const;
60 vector<HalfEdge*>
nulls();
63 vector<Face*>
faces();
68 void visited(
bool t) { bVisited=t; }
70 void reset() { bVisited=
false; }
84 HalfEdge() : node(NULL), face(NULL), opp(NULL), next(NULL), bVisited(
false)
95 HalfEdge& prev() {
return *(next -> next); }
97 T& a() {
return node -> data(); }
98 T& b() {
return prev().node -> data(); }
100 bool isBorder() {
return opp == NULL; }
119 e = e -> next -> opp;
126 t = e -> next -> next;
127 e = e -> next -> next -> opp;
136 if ( node == eb.prev().node )
return true;
140 if ( prev().node == eb.node )
return true;
146 if ( ( node == eb.prev().node ) && ( prev().node == eb.node ) )
return true;
152 opp = &eb; eb.opp =
this;
187 Face() : edge(NULL) {}
192 HalfEdge& eb() {
return *(edge->next); }
193 HalfEdge& ec() {
return *(edge->next->next); }
199 Node& na() {
return * ( ea().node ); }
200 Node& nb() {
return * ( eb().node ); }
201 Node& nc() {
return * ( ec().node ); }
208 T& a() {
return na().
data() ; }
209 T& b() {
return nb().
data() ; }
210 T& c() {
return nc().
data() ; }
216 vector<Face*> edgeNeighbors(){
219 if ( ea().opp != NULL ) vp.push_back( ea().opp -> face );
220 if ( eb().opp != NULL ) vp.push_back( eb().opp -> face );
221 if ( ec().opp != NULL ) vp.push_back( ec().opp -> face );
241 na = &(*(mNode[0])); nb = &(*( mNode[1] )); nc = &(*(mNode[2]));
261 ea -> next = eb; ea -> face = f;
262 eb -> next = ec; eb -> face = f;
263 ec -> next = ea; ec -> face = f;
266 mHalfEdge.push_back(ea);
267 mHalfEdge.push_back(eb);
268 mHalfEdge.push_back(ec);
275 void facet( HalfEdge * ea, HalfEdge * eb, HalfEdge * ec, Face * f){
277 ea -> next = eb; eb -> next = ec; ec -> next = ea;
278 ea -> face = f; eb -> face = f; ec -> face = f;
285 Node& addNode( T& v ){
288 mNode.push_back( n );
293 HEGraph& fillFace(
int a,
int b,
int c ){
296 HalfEdge *ea, *eb, *ec;
318 mHalfEdge.push_back(ea);
319 mHalfEdge.push_back(eb);
320 mHalfEdge.push_back(ec);
332 HEGraph& add( T& v ) {
333 int num = mNode.size();
334 if (num < 3 ) addNode( v );
335 if (num == 2 ) seedNodes();
336 if (num >= 3 ) addAt ( v, lastEdge() );
343 HEGraph& addAt( T& v, HalfEdge& e ){
347 HalfEdge * ea =
new HalfEdge;
348 HalfEdge * eb =
new HalfEdge;
349 HalfEdge * ec =
new HalfEdge;
357 ea -> next = eb; eb -> next = ec; ec -> next = ea;
358 ea -> face = f; eb -> face = f; ec -> face = f;
365 e.opp = eb; eb -> opp = &e;
368 eb -> node = e.next -> next -> node;
373 mHalfEdge.push_back(ea);
374 mHalfEdge.push_back(eb);
375 mHalfEdge.push_back(ec);
382 HEGraph& addAt( T& v,
int x ){
383 return addAt(v, edge(x));
387 void seed( T& a, T& b, T& c, T& d){
388 seed(a,b,c); add(d, lastEdge() );
392 void insert( T& pa, HalfEdge& e){
395 HalfEdge * ea, *eb, *ec;
399 ea =
new HalfEdge; eb =
new HalfEdge; ec =
new HalfEdge;
403 ea -> face = f; f -> edge = ea;
405 ec->opp = eb; eb->opp = ec;
410 eb->node = &(*(e.next -> node));
411 eb->next = &(*(e.next -> next));
412 eb->face = &(*(e.face));
414 n -> ptr = &pa; n -> edge = ea;
419 e.node = n; e.next = eb;
425 mHalfEdge.push_back( eb );
426 mHalfEdge.push_back( ec );
427 mHalfEdge.push_back( ea );
429 mFace.push_back( f );
434 void close( HalfEdge& ha, HalfEdge& hb){
439 HalfEdge *ea, *eb, *ec;
440 ea =
new HalfEdge; eb =
new HalfEdge; ec =
new HalfEdge;
445 ea -> node = hb.prev().node;
446 ec -> node = hb.node;
447 eb -> node = ha.prev().node;
449 ha.opp = eb; eb -> opp = &ha;
450 hb.opp = ea; ea -> opp = &hb;
452 mHalfEdge.push_back( ea );
453 mHalfEdge.push_back( eb );
454 mHalfEdge.push_back( ec );
456 mFace.push_back( f );
460 void close( HalfEdge& e, Node& n){
466 HalfEdge *ea, *eb, *ec;
467 ea =
new HalfEdge; eb =
new HalfEdge; ec =
new HalfEdge;
473 eb -> node = e.prev().node;
476 e.opp = eb; eb -> opp = &e;
478 mHalfEdge.push_back( ea );
479 mHalfEdge.push_back( eb );
480 mHalfEdge.push_back( ec );
482 mFace.push_back( f );
488 void close( HalfEdge& e ){
492 HalfEdge *ea, *eb, *ec;
493 ea =
new HalfEdge; eb =
new HalfEdge; ec =
new HalfEdge;
498 auto& tb = e.nextNull(
false);
499 auto& tc = e.nextNull(
true);
501 ea -> node = tb.node;
502 eb -> node = tc.node;
505 ea -> opp = &e; e.opp = ea;
506 eb -> opp = &tb; tb.opp = eb;
507 ec -> opp = &tc; tc.opp = ec;
509 mHalfEdge.push_back( ea );
510 mHalfEdge.push_back( eb );
511 mHalfEdge.push_back( ec );
513 mFace.push_back( f );
518 void removeFacet(
int idx ) {
523 void removeEdge(
int idx ) {
528 vector<HalfEdge*> edgeLoop0( vector<HalfEdge*> loop ){
530 vector<HalfEdge*> result;
534 auto v = loop[0]->node->valence();
536 HalfEdge * first = NULL;
539 for (
auto& j : loop){
540 if (j->node==i->node){
554 HalfEdge * tmp = first;
555 while (tmp!=NULL && (tmp->node != first->node) ){
559 for (
auto& j : loop){
560 if (j->node==tmp->node){
565 if (bExists) tmp = tmp->opp;
567 result.push_back(tmp);
576 vector<HalfEdge*> emanatingEdges( vector<HalfEdge*> loop ){
578 HalfEdge * first = NULL;
580 vector<HalfEdge*> result;
584 result.push_back(i->opp->next);
590 vector<HalfEdge*> edgeLoop( vector<HalfEdge*> loop ){
594 vector<HalfEdge*> result;
595 HalfEdge * tmp = NULL;
600 bool bClosed = loop.back()->node == loop[0]->prev().node;
603 auto edges = emanatingEdges(loop);
610 if (!tmp->isBorder()){
612 while (!tmp->isBorder() && iter<maxNum){
616 result.push_back(tmp);
618 result.push_back(tmp);
621 while(tmp->node != edges[0]->node && iter<maxNum){
622 tmp = tmp->next->opp->next;
623 result.push_back(tmp);
626 }
else if (edges.size()>2) {
627 result.push_back(tmp);
634 for (
int i=0; i<edges.size();++i){
636 int nxt = i<edges.size()-1 ? i+1 : 0;
638 while ( tmp!=NULL && tmp->node != edges[nxt]->node && iter < maxNum){
643 for (
auto& j : loop){
644 if ( (j->node==tmp->node) || (j->next->next->node==tmp->node) ){
652 result.push_back(tmp);
656 result.push_back(tmp);
675 vector<HalfEdge*> tmp;
676 for (
auto& i : mHalfEdge){
677 if ( i -> isBorder() ) tmp.push_back(i);
684 for (
auto& i : mHalfEdge){
685 if ( i -> isBorder() )
return true;
692 for (
auto& i : mHalfEdge){
693 if ( i -> isBorder() )
return *i;
700 vector<HalfEdge*> tmp;
703 for (
int it = 0; it < mHalfEdge.size(); ++it){
705 if ( mHalfEdge[it] -> opp != NULL )
continue;
709 HalfEdge * he = mHalfEdge[it];
713 he = &(he -> nextNull() );
714 }
while ( he != mHalfEdge[it] );
724 for (
auto& i : mHalfEdge){
725 i -> bVisited =
false;
727 for (
auto& i : mNode){
739 HalfEdge& lastEdge() {
return *mHalfEdge.back(); }
740 Face& lastFace() {
return *mFace.back(); }
741 Node& lastNode() {
return *(mHalfEdge.back() -> node); }
743 Face& face(
int idx ) {
return *mFace[idx]; }
745 HalfEdge& edge(
int idx ) {
return idx < 0 ? *mHalfEdge[ mHalfEdge.size() + idx ] : *mHalfEdge[idx]; }
747 Node& node(
int idx ) {
return *mNode[idx]; }
750 vector<HalfEdge*>& edge() {
return mHalfEdge; }
751 vector<Face*>& face() {
return mFace; }
752 vector<Node*>& node() {
return mNode; }
754 vector<HalfEdge*> edge()
const {
return mHalfEdge; }
755 vector<Face*> face()
const {
return mFace; }
756 vector<Node*> node()
const {
return mNode; }
760 HEGraph& UV(
int w,
int h, S& p,
bool bCloseU=
false,
bool bCloseV=
false);
764 vector<HalfEdge*> mHalfEdge;
778 while ( e != NULL && e !=
edge -> next -> next ){
779 e = e -> next -> opp;
787 if (e == NULL)
return false;
788 while ( e != edge -> next -> next ){
789 e = e -> next -> opp;
790 if (e == NULL)
return false;
797 vector<HEGraph<T>::HalfEdge*> tmp;
799 while ( e != NULL && e != edge -> next -> next ){
800 e = e -> next -> opp;
804 e = edge -> next -> next -> opp;
806 e = e -> next -> next -> opp;
817 vector<HEGraph<T>::HalfEdge*> tmp;
824 e = e -> next -> next -> opp;
825 }
while( e != edge );
840 e = e -> next -> next -> opp;
848 vector<HEGraph<T>::HalfEdge*> tmp;
851 tmp.push_back(i->next);
861 vector<HEGraph<T>::Face*> tmp;
862 for (
auto& i : valence() ){
863 tmp.push_back( i -> face );
869 vector<typename HEGraph<T>::Node*> tmp;
870 auto res = valence();
872 tmp.push_back( i->node );
874 if( !closed() ) tmp.push_back( res.back()->next->node );
899 template<
class T>
template<
class S>
903 for (
int j = 0; j < h; ++j){
907 if (j<2) graph.add( p[idx] );
908 else graph.addAt( p[idx], graph.edge(-3) );
910 if (j==0) graph.add( p[idxB] );
912 else graph.addAt( p[idxB], graph.edge(-1) );
915 for (
int i = 2; i < w; ++i){
916 int idx = ((i-2) * (h-1) + 1)*6 -1;
918 int pidxB = pidx + 1;
919 graph.addAt( p[pidx], graph.edge( idx ) );
920 graph.addAt( p[pidxB], graph.edge(-3) );
921 for (
int j = 2; j < h; ++j){
922 int pidxC = i * h + j;
923 graph.
close( graph.edge(-3), graph.edge( idx + (j-1) * 6 ) );
924 graph.add( p[pidxC] );
929 for (
int j=0;j<h-1;++j){
930 int idxR = ((w-2)*(h-1)+j+1)*6;
932 graph.
close( graph.edge(idxR), *graph.edge(idxL).node);
937 graph.
close( graph.edge(6*(h-1)-3), graph.node(0) );
938 graph.
close( graph.lastEdge(), *graph.node(0).
edge );
939 for (
int i=1;i<w-1;++i){
940 int idxB = (i*(h-1))*6+2;
941 int idxT = ((i+1)*(h-1)*6)-3;
942 graph.
close( graph.edge(idxT), *graph.edge(idxB).prev().node);
943 graph.
close( graph.lastEdge(), graph.edge(idxB) );
HalfEdge & null()
Find any null edge of a node.
Definition: vsr_graph.h:776
Definition: vsr_graph.h:185
HalfEdge * edge
An emanating half-edge.
Definition: vsr_graph.h:35
vector< HalfEdge * > edgeLoop() const
Find edge loop (next of edges)
Definition: vsr_graph.h:847
bool ccwFrom(HalfEdge &eb)
Check for shared Node with another HalfEdge.
Definition: vsr_graph.h:135
vector< HalfEdge * > nullEdges()
Get null edges of graph.
Definition: vsr_graph.h:674
bool bVisited
Flag for keeping track of visitation.
Definition: vsr_graph.h:37
Templated half edge structure (pointers to any type) Navigates references to surface topology of data...
Definition: vsr_graph.h:18
HalfEdge & firstNull()
Find first null edge.
Definition: vsr_graph.h:691
bool triangle()
Check for simple Loop (triangle)
Definition: vsr_graph.h:160
A Node stores address of value of type T and pointer to an emanating edge.
Definition: vsr_graph.h:30
vector< HalfEdge * > valence() const
Find all outgoing Edges.
Definition: vsr_graph.h:816
HalfEdge & nextNull(bool clockwise)
Find next null edge (assumes this edge is null) Could be on same face .
Definition: vsr_graph.h:112
vector< Face * > faces()
Find all faces.
Definition: vsr_graph.h:860
bool isOpp(HalfEdge &eb)
Test for partnership.
Definition: vsr_graph.h:145
vector< Node * > neighbors()
Find all Neighboring nodes.
Definition: vsr_graph.h:868
bool closed() const
Test for node closure (no null Edges in loop)
Definition: vsr_graph.h:785
the versor library namespace
Definition: vsr_algebra.h:29
vector< HalfEdge * > nullEdgeLoop()
Get null edge path (boundary) of graph.
Definition: vsr_graph.h:698
T & data()
Get reference to data;.
Definition: vsr_graph.h:40
void seal(HalfEdge &eb)
Seal together two halfedges.
Definition: vsr_graph.h:151
T * ptr
Pointer to type T.
Definition: vsr_graph.h:34
vector< HalfEdge * > nulls()
Find both null edges around a node.
Definition: vsr_graph.h:796
HALF EDGE Data structure
Definition: vsr_graph.h:80
bool hasBorder()
Any Null Edges?
Definition: vsr_graph.h:683
void close(HalfEdge &ha, HalfEdge &hb)
eb /ea counter clockwise
Definition: vsr_graph.h:434