cgal/Packages/Triangulation_2/include/CGAL/Triangulation_ds_face_2.h

376 lines
9.6 KiB
C++

#ifndef CGAL_TRIANGULATION_DS_FACE_2_H
#define CGAL_TRIANGULATION_DS_FACE_2_H
#include <CGAL/Triangulation_short_names_2.h>
template <class Vb, class Fb >
class CGAL_Triangulation_ds_vertex_2 ;
template < class Vb, class Fb >
class CGAL_Triangulation_ds_face_2
: public Fb
{
public:
//typedef typename Fb::Triangle Triangle;
typedef CGAL_Triangulation_ds_vertex_2<Vb,Fb> Vertex;
typedef CGAL_Triangulation_ds_face_2<Vb,Fb> Face;
// creators
CGAL_Triangulation_ds_face_2()
: Fb()
{}
CGAL_Triangulation_ds_face_2(Vertex* v0, Vertex* v1, Vertex* v2)
: Fb(v0,v1,v2)
{}
CGAL_Triangulation_ds_face_2(Vertex* v0, Vertex* v1, Vertex* v2,
Face* n0, Face* n1, Face* n2)
: Fb(v0,v1,v2,n0,n1,n2)
{}
//setting
inline
void set_vertex(int i, Vertex* v)
{
Fb::set_vertex(i,v);
}
inline
void set_neighbor(int i, Face* n)
{
Fb::set_neighbor(i,n);
}
// void set_vertices() inherited
inline
void set_vertices(Vertex* v0,
Vertex* v1,
Vertex* v2)
{
Fb::set_vertices(v0,v1,v2);
}
// void set_neighbors() inherited
inline
void set_neighbors(Face* n0,
Face* n1,
Face* n2)
{
Fb::set_neighbors(n0,n1,n2);
}
//Vertex Access Member Functions
Vertex* vertex(int i) const
{
return( (Vertex*) (Fb::vertex(i)));
}
inline
bool has_vertex(const Vertex* v) const
{
return (Fb::has_vertex(v));
}
inline
bool has_vertex(const Vertex* v, int& i) const
{
return (Fb::has_vertex(v,i));
}
inline
int index(const Vertex* v) const
{
return(Fb::vertex_index(v));
}
// Neighbors Access Functions
inline
Face* neighbor(int i) const
{
return ((Face*) Fb::neighbor(i));
}
inline
bool has_neighbor(const Face* n) const
{
return (Fb::has_neighbor(n));
}
inline
bool has_neighbor(const Face* n, int& i) const
{
return (Fb::has_neighbor(n,i));
}
inline
int index(const Face* n) const
{
return(Fb::face_index(n));
}
//Miscelleanous
// inline int ccw(int i) const
// {
// return (i+1) % 3;
// }
//
// inline int cw(int i) const
// {
// return (i+2) % 3;
// }
//
//Additionnal Operations
//the following function has been moved to the tds class
// void insert_in_face(Vertex*& v)
// {
// CGAL_triangulation_precondition(v != NULL);
// Vertex* v0 = vertex(0);
// Vertex* v2 = vertex(2);
// Vertex* v1 = vertex(1);
//
// Face* f1 = neighbor(1);
// Face* f2 = neighbor(2);
// int i1,i2 ;
// if (f1 != NULL) {i1= cw(f1->index(vertex(cw(1))));}
// if (f2 != NULL) {i2 = cw(f2->index(vertex(cw(2))));}
//
// Face* n1ptr = new Face(v0, v, v2,
// this, f1, NULL);
//
// Face* n2ptr = new Face(v0, v1, v,
// this, NULL, f2);
//
// n1ptr->set_neighbor(2, n2ptr);
// n2ptr->set_neighbor(1, n1ptr);
// if (f1 != NULL) {f1->set_neighbor(i1,n1ptr);}
// if (f2 != NULL) {f2->set_neighbor(i2,n2ptr);}
//
// set_vertex(0, v);
// set_neighbor(1, n1ptr);
// set_neighbor(2, n2ptr);
//
// if( v0->face() == this ) { v0->set_face(n2ptr); }
// v->set_face(this);
// }
//the following function has been moved to the tds class
// void insert_on_edge(const Vertex* v, int i)
// {
//
// CGAL_triangulation_precondition(v != NULL);
// Face* n = neighbor(i);
//
// // The following seems natural, but it may fail if the faces
// // this and n are neighbors on two edges (1-dim triangulation,
// // with infinite faces
// // int in = n->index(this);
//
// int in;
// CGAL_triangulation_assertion( n->has_vertex(vertex(cw(i),in)));
// in = cw(in);
// insert_in_face(v);
// n->flip(in);
// }
//
//no longer necessary
// bool insert_outside(const Vertex* v, int i)
// {
// CGAL_triangulation_precondition(v != NULL);
// if(neighbor(i) != NULL) {
// cerr << "Insert_outside impossible as neighbor face already exists" << endl;
// return false;
// }
// Face* f = new Face(v, vertex(cw(i)), vertex(ccw(i)),
// this, NULL, NULL);
// set_neighbor(i, f);
// v->set_face(f);
// Vertex* w = vertex(ccw(i));
// if(w != NULL){
// w->set_face(f);
// }
//
// return true;
// }
// this function has been moved to the Tds class
// bool remove(Vertex* v)
// {
// CGAL_triangulation_precondition(v != NULL);
// CGAL_triangulation_precondition( has_vertex(v));
// int i = index(v);
//
// Face* left, *right, *ll, *rr;
//
// left = neighbor(cw(i));
// right = neighbor(ccw(i));
//
// // if(left == NULL || right == NULL) {
// // if(left == NULL && right == NULL) {
// // Face* n = neighbor(i);
// // if(n != NULL) {
// // int ni = n->index(this);
// // n->set_neighbor(ni, NULL);
// // Vertex* q = vertex(cw(i));
// // if(q != NULL){
// // q->set_face(n);
// // }
// // } else {
// // cerr << "removal of boundary vertex failed as face has"
// // << "no neighbors" << endl;
// // }
// // handle().Delete();
// // v.Delete();
// // return true;
// // } else {
// // cerr << "removal of boundary vertex with degree != 2 failed";
// // cerr << endl;
// // return false;
// // }
// // }
// //
// if(v->degree() != 3){
// cerr << "removal of internal vertex with degree != 3 failed";
// cerr << endl;
// return false;
// }
//
// int li = left->index(this);
// int ri = right->index(this);
// Vertex* q = left->vertex(li);
// CGAL_triangulation_assertion( left->vertex(li) == right->vertex(ri));
//
// ll = left->neighbor(cw(li));
// if(ll != NULL) {
// int lli = ll->index(left);
// ll->set_neighbor(lli, this);
// }
// set_neighbor(cw(i), ll);
// if (vertex(ccw(i))->face() == left) vertex(ccw(i))->set_face(this);
//
//
//
// rr = right->neighbor(ccw(ri));
// if(rr != NULL) {
// int rri = rr->index(right);
// rr->set_neighbor(rri, this);
// }
// set_neighbor(ccw(i), rr);
// if (vertex(cw(i))->face() == right) vertex(cw(i))->set_face(this);
//
// set_vertex(i, q);
// if (q->face() == right || q->face() == left) {
// q->set_face(this);
// }
//
// delete right;
// delete left;
//
// delete v;
// return true;
// }
//
// void flip(int i)
// {
// Face* n = neighbor(i);
//
// Vertex* v_cw = vertex(cw(i));
// Vertex* v_ccw = vertex(ccw(i));
//
// // we should not attempt to flip two faces which are adjacent on two edges
// // This configuration happens in 1-dim triangulation
//
// int ni;
// CGAL_triangulation_assertion( n->has_vertex(v_cw,ni));
// ni = cw(ni);
// CGAL_triangulation_assertion( vertex(i) != n->vertex(ni));
// CGAL_triangulation_assertion( this == n->neighbor(ni) );
//
// // Old stuff
// // The following seems natural, but it may fail if the faces
// // this and n are neighbors on two edges (1-dim triangulation,
// // with infinite faces
// // int ni = n->index(this);
// //
// // int ni = cw(n->index(v_cw));
// // CGAL_triangulation_assertion( this == n->neighbor(ni) );
//
// // bl == bottom left, tr == top right
// Face* tr = neighbor(ccw(i));
// Face* bl = n->neighbor(ccw(ni));
// int bli, tri;
//
// // Old stuff which seems natural
// // but makes problem if f and tr or n and bl are incident through two edges
// // bli = bl->index(n);
// // tri = tr->index(f);
// bli = 3 - ( bl->index(n->vertex(ni)) + bl->index(n->vertex(cw(ni))) );
// tri = 3 - (tr->index(vertex(i)) + tr->index(vertex(cw(i))));
//
// set_vertex(cw(i), n->vertex(ni));
// n->set_vertex(cw(ni), vertex(i));
//
// // update the neighborhood relations
// set_neighbor(i, bl);
// bl->set_neighbor(bli, this);
//
// set_neighbor(ccw(i), n);
// n->set_neighbor(ccw(ni), this);
//
// n->set_neighbor(ni, tr);
// tr->set_neighbor(tri,n);
//
// if(v_cw->face() == this) {
// v_cw->set_face(n);
// }
//
// if(v_ccw->face() == n) {
// v_ccw->set_face(this);
// }
// }
bool is_valid(bool verbose = false, int level = 0) const
{
bool result = Fb::is_valid();
for(int i = 0; i < 3; i++) {
Face* n = neighbor(i);
// The following seems natural, but it may fail if the faces
// this and n are neighbors on two edges (1-dim triangulation,
// with infinite faces
// int ni = n->index(this);
// int ni = cw(n->index(vertex(cw(i))));
// CGAL_triangulation_assertion( this == n->neighbor(ni) );
// result = result && (vertex(cw(i)) == n->vertex(ccw(ni)));
// result = result && (vertex(ccw(i)) == n->vertex(cw(ni)));
int in;
if (! n->has_vertex(vertex(cw(i)),in )) return false;
in = cw(in);
result = result && ( this == n->neighbor(in) );
result = result && (vertex(ccw(i)) == n->vertex(cw(in)));
}
return result;
}
};
#endif CGAL_TRIANGULATION_DS_FACE_2_H