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

1036 lines
27 KiB
C++

// ============================================================================
//
// Copyright (c) 1997 The CGAL Consortium
//
// This software and related documentation is part of an INTERNAL release
// of the Computational Geometry Algorithms Library (CGAL). It is not
// intended for general use.
//
// ----------------------------------------------------------------------------
//
// release :
// release_date :
//
// file : Triangulation/include/CGAL/Regular_triangulation_2.h
// source : $RCSfile$
// revision : $Revision$
// revision_date : $Date$
// author(s) : Frederic Fichel, Mariette Yvinec
//
// coordinator : Mariette Yvinec <Mariette Yvinec@sophia.inria.fr>
//
// ============================================================================
#ifndef CGAL_REGULAR_TRIANGULATION_2_H
#define CGAL_REGULAR_TRIANGULATION_2_H
#include <pair.h>
#include <list.h>
#include <map.h>
#include <assert.h>
#include <stack.h>
#include <CGAL/Triangulation_short_names_2.h>
#include <CGAL/triangulation_assertions.h>
#include <CGAL/Triangulation_2.h>
#include <CGAL/Weighted_point_2.h>
#include <CGAL/Regular_triangulation_face_base_2.h>
template < class Gt, class Tds >
class CGAL_Regular_triangulation_2
: public CGAL_Triangulation_2<Gt,Tds>
{
public:
typedef CGAL_Triangulation_2<Gt,Tds> Triangulation;
typedef typename Gt::Bare_point Point;
typedef typename Gt::Weighted_point Weighted_point;
typedef typename Gt::Weight Weight;
// a list to memorise temporary the faces around a point
typedef list<Face_handle > Faces_around_stack;
// point list
typedef list<Weighted_point> Weighted_point_list;
public:
CGAL_Regular_triangulation_2()
: Triangulation( )
{}
CGAL_Regular_triangulation_2(const Gt& gt) : Triangulation(gt) { }
CGAL_Regular_triangulation_2(const CGAL_Regular_triangulation_2 &rt )
: Triangulation( rt )
{ CGAL_triangulation_postcondition( is_valid() ); }
CGAL_Regular_triangulation_2(const Vertex_handle& v, const Gt& gt)
: Triangulation(v,gt)
{ CGAL_triangulation_postcondition( is_valid() ); }
// Insertion and Deletion
Vertex_handle push_back(const Weighted_point &p)
{
Locate_type lt;
return insert(p, lt, NULL);
}
#ifndef CGAL_CFG_NO_MEMBER_TEMPLATES
template < class InputIterator >
int
insert(InputIterator first, InputIterator last)
{ int n = number_of_vertices();
while(first != last)
{ insert(*first);
++first;
}
return number_of_vertices() - n;
}
#else
#if defined(LIST_H) || defined(__SGI_STL_LIST_H)
int
insert(list<Weighted_point>::const_iterator first,
list<Weighted_point>::const_iterator last)
{ int n = number_of_vertices();
while(first != last)
{ insert(*first);
++first;
}
return number_of_vertices() - n;
}
#endif // LIST_H
#if defined(VECTOR_H) || defined(__SGI_STL_VECTOR_H)
int
insert(vector<Weighted_point>::const_iterator first,
vector<Weighted_point>::const_iterator last)
{ int n = number_of_vertices();
while(first != last)
{ insert(*first);
++first;
}
return number_of_vertices() - n;
}
#endif // VECTOR_H
#ifdef ITERATOR_H
int
insert(istream_iterator<Weighted_point, ptrdiff_t> first,
istream_iterator<Weighted_point, ptrdiff_t> last)
{ int n = number_of_vertices();
while(first != last)
{ insert(*first);
++first;
}
return number_of_vertices() - n;
}
#endif // ITERATOR_H
int
insert(Weighted_point* first, Weighted_point* last)
{ int n = number_of_vertices();
while(first != last)
{ insert(*first);
++first;
}
return number_of_vertices() - n;
}
#endif // CGAL_TEMPLATE_MEMBER_FUNCTIONS
public:
CGAL_Oriented_side
power_test(const Face_handle& f, const Weighted_point & p) const
{
//p is assume to be a finite point
CGAL_Orientation o;
if ( ! is_infinite(f) )
{
return geom_traits().power_test(f->vertex(0)->point(),
f->vertex(1)->point(),
f->vertex(2)->point(),p);
}
else if ( f->vertex(0) == infinite_vertex() )
{ o = geom_traits().orientation(f->vertex(1)->point(),
f->vertex(2)->point(),p);
if (o==CGAL_COLLINEAR)
{ return geom_traits().power_test(f->vertex(1)->point(),
f->vertex(2)->point(),p);
}
}
else if ( f->vertex(1) == infinite_vertex() )
{ o = geom_traits().orientation(f->vertex(2)->point(),
f->vertex(0)->point(),p);
if (o==CGAL_COLLINEAR)
{ return geom_traits().power_test(f->vertex(2)->point(),
f->vertex(0)->point(),p);
}
}
else if ( f->vertex(2) == infinite_vertex() )
{ o = geom_traits().orientation(f->vertex(0)->point(),
f->vertex(1)->point(),p);
if (o==CGAL_COLLINEAR)
{
return geom_traits().power_test(f->vertex(0)->point(),
f->vertex(1)->point(),p);
}
}
return (o == CGAL_NEGATIVE) ? CGAL_ON_NEGATIVE_SIDE :
(o == CGAL_POSITIVE) ? CGAL_ON_POSITIVE_SIDE : CGAL_ON_ORIENTED_BOUNDARY;
}
private :
// add the point_list of f2 and f3 to the point list of f1
// for the 3-1 flip
void update_hidden_points_3_1(const Face_handle& f1,
const Face_handle& f2,
const Face_handle& f3 )
{
(f1->point_list()).splice(f1->point_list().begin(),f2->point_list());
(f1->point_list()).splice(f1->point_list().begin(),f3->point_list());
}
// the points of the lists of 2 faces are sorted
// because of a 2-2 flip
void update_hidden_points_2_2(const Face_handle& f1, const Face_handle& f2)
{
CGAL_triangulation_assertion(f1->has_neighbor(f2));
Weighted_point_list p_list;
p_list.splice(p_list.begin(),f1->point_list());
p_list.splice(p_list.begin(),f2->point_list());
// if both faces are infinite faces
//if they share the finite edge, any one hide all points
//if they share an infinite edge : their finite edges
//should be collinear
//split hidden points along the midpoint
if ( is_infinite(f1) && is_infinite(f2) ) {
int i1 = f1->index(infinite_vertex());
if (f2 == f1->neighbor(i1)) {
(f1->point_list()).splice(f1->point_list().begin(),p_list);
return;
}
// else split the hidden points according to finite edges
// because f2 != f1->neighbor(i1)
// the following vertices are finite vertices
Weighted_point a1 = f1->vertex(f1->index(f2))->point();
Weighted_point a2 = f2->vertex(f2->index(f1))->point();
Weighted_point a = f1->vertex(3-(i1+f1->index(f2)))->point();
while ( ! p_list.empty() ){
if ( geom_traits().compare_x(a, p_list.front()) ==
geom_traits().compare_x(a, a1) &&
geom_traits().compare_y(a, p_list.front()) ==
geom_traits().compare_y(a, a1)) {
(f1->point_list()).push_back(p_list.front());
}
else {
(f2->point_list()).push_back(p_list.front());
}
p_list.pop_front();
}
return;
}
//otherwise at least one of the face is finite
// if one is infinite, the finite face hide all the points
if ( is_infinite(f1)) {
(f2->point_list()).splice(f2->point_list().begin(),p_list);
return;
}
if ( is_infinite(f2)) {
(f1->point_list()).splice(f1->point_list().begin(),p_list);
return;
}
// from here f1 and f2 are finite faces
int idx2;
idx2=f1->index(f2);
Vertex_handle v2=f1->vertex(idx2),
v0=f1->vertex(ccw(idx2)),
v1=f1->vertex(cw(idx2));
CGAL_triangulation_assertion((!is_infinite(v0)) && (!is_infinite(v1)));
while ( ! p_list.empty() ){
if (CGAL_orientation(v0->point(), v1->point(), p_list.front()) ==
CGAL_COUNTERCLOCKWISE) {
(f1->point_list()).push_back(p_list.front());
}
else{(f2->point_list()).push_back(p_list.front()) ;}
p_list.pop_front();
}
}
// The point list of f1 is separated into 3 lists
// for a 1-3 flip
void update_hidden_points_1_3(const Face_handle& f1, const Face_handle& f2,
const Face_handle& f3)
{
CGAL_triangulation_assertion(f1->has_neighbor(f2) &&
f2->has_neighbor(f3) &&
f3->has_neighbor(f1));
Weighted_point_list p_list;
p_list.splice(p_list.begin(),f1->point_list());
p_list.splice(p_list.begin(),f1->point_list());
p_list.splice(p_list.begin(),f1->point_list());
if(p_list.empty()) return;
// the following does not work if
// two of f1,f2 and f3 are twice neighbors
// but this cannot appear taking the assertion into account;
int idx2,idx3;
idx2=f1->index(f2);
idx3=f1->index(f3);
Vertex_handle v2=f1->vertex(idx2),
v3=f1->vertex(idx3),
v0=f1->vertex(3-(idx2+idx3)),
v1=f2->vertex(f2->index(f1));
CGAL_triangulation_assertion(f2->has_vertex(v0) && f1->has_vertex(v0));
CGAL_triangulation_assertion(f3->has_vertex(v1));
CGAL_triangulation_assertion( ! is_infinite(v0));
// if two of f1, f2,and f3 are infinite
// the list goes entirely to the third finite face
// no orientation test necessary
// because the point list of an infinite face
// is only made of point projecting on its finite edge
if ( is_infinite(f1 ) && is_infinite(f2)) {
f3->point_list().splice(f3->point_list().begin(), p_list);
return;
}
if ( is_infinite(f1) && is_infinite(f3)) {
f2->point_list().splice(f2->point_list().begin(), p_list);
return;
}
if ( is_infinite(f2) && is_infinite(f3)){
f1->point_list().splice(f1->point_list().begin(), p_list);
return;
}
// if here, v1,v2,v3 and v0 are finite vertices
while(! p_list.empty()) {
if(CGAL_orientation(v2->point(),v0->point(),p_list.front()) !=
CGAL_orientation(v2->point(),v0->point(),v3->point()) )
{ // not in f1
if (CGAL_orientation(v1->point(), v0->point(), p_list.front() ) !=
CGAL_orientation(v1->point(), v0->point(), v3->point() ) )
{// not in f2
f3->point_list().push_back(p_list.front());
}
else{
f2->point_list().push_back(p_list.front());
}
}
else { f1->point_list().push_back(p_list.front());
}
p_list.pop_front();
}
}
protected:
bool is_degree(Vertex_handle v, int i) const
{
Face_circulator fic = v->incident_faces(), done(fic);
fic++;
int count=1;
while ( fic != done && count <= i) {
fic ++; count++;
}
return (count==i ? true :false );
}
bool degree_equal_3(Vertex_handle v) const
{
Face_handle f = v->face();
if (f == NULL)
{ return false;
}
int i = f->index(v);
Face_handle ptr1 = f->neighbor(ccw(i));
Face_handle ptr2 = f;
f = f->neighbor(cw(i));
int count = 2;
while(ptr1 != f)
{ count++;
i = ptr1->index(ptr2);
ptr2 = ptr1;
ptr1 = ptr1->neighbor(cw(i));
if (count>3)
break;
}
return (count==3 ? true :false );
}
bool degree_equal_4(Vertex_handle v) const
{
return ( v->degree() == 4);
}
void hide_vertex(const Face_handle& f,const Weighted_point& p)
// insert the point among the hidden points list
{
f->point_list().push_back(p);
}
public:
void
regularize(Vertex_handle v)
{
CGAL_triangulation_precondition( v != infinite_vertex());
Faces_around_stack faces_around;
//initialise faces_around
Face_circulator fit = v->incident_faces(), done(fit);
do {
faces_around.push_back(fit++);
} while(fit != done);
while( ! faces_around.empty() ){
stack_flip(v, faces_around);
}
return;
}
private :
void stack_flip(Vertex_handle v, Faces_around_stack &faces_around)
{
Face_handle f=faces_around.front();
int i = i=f->index(v);
faces_around.pop_front();
//test the regularity of edge (f,i)
Face_handle n = f->neighbor(i);
if( power_test(n, v->point()) == CGAL_ON_NEGATIVE_SIDE){
return;
}
if(is_infinite(f,i)) {
int j = 3 - ( i + f->index(infinite_vertex()));
if ( is_degree(f->vertex(j),4)) {
stack_flip_4_2(f,i,j,faces_around);
}
return;
}
// now f and n are both finite faces
int ni= n->index(f);
CGAL_Orientation occw = geom_traits().orientation(f->vertex(i)->point(),
f->vertex(ccw(i))->point(),
n->vertex(ni)->point());
CGAL_Orientation ocw = geom_traits().orientation(f->vertex(i)->point(),
f->vertex(cw(i))->point(),
n->vertex(ni)->point());
if(occw == CGAL_LEFTTURN && ocw == CGAL_RIGHTTURN){
// quadrilater (f,n) is convex
stack_flip_2_2(f,i, faces_around);
return;
}
else if (occw == CGAL_RIGHTTURN && is_degree(f->vertex(ccw(i)), 3) ){
stack_flip_3_1(f,i,ccw(i),faces_around);
return;
}
else if (ocw == CGAL_LEFTTURN && is_degree(f->vertex(cw(i)), 3) ){
stack_flip_3_1(f,i,cw(i),faces_around);
return;
}
else if (occw == CGAL_COLLINEAR && is_degree(f->vertex(ccw(i)), 4) ){
stack_flip_4_2(f,i,ccw(i),faces_around);
return;
}
else if (ocw == CGAL_COLLINEAR && is_degree(f->vertex(cw(i)), 4) ){
stack_flip_4_2(f,i,cw(i),faces_around);
return;
}
return;
}
void stack_flip_4_2(Face_handle f, int i, int j,
Faces_around_stack & faces_around)
{
int k = 3-(i+j);
Face_handle g=f->neighbor(k);
if (!faces_around.empty()){
if (faces_around.front()== g){ faces_around.pop_front();}
else if ( faces_around.back() == g) { faces_around.pop_back();}
}
//union f with g and f->neihgbor(i) with g->f->neihgbor(i)
Face_handle fn = f->neighbor(i);
Face_handle gn = g->neighbor(g->index(f->vertex(i)));
Vertex_handle vq = f->vertex(j);
_tds.flip( &(*f), i); //not using flip because the vertex j is flat.
update_hidden_points_2_2(f,fn);
Face_handle h1 = ( f->has_vertex(vq) ? fn : f);
remove_degree_3(vq,g);
hide_vertex(h1, vq->point());
faces_around.push_front(g);
faces_around.push_front(h1);
}
void stack_flip_3_1(Face_handle f, int i, int j,
Faces_around_stack & faces_around)
{
int k = 3-(i+j);
Face_handle g=f->neighbor(k);
if (!faces_around.empty()){
if (faces_around.front()== g){ faces_around.pop_front();}
else if ( faces_around.back() == g) { faces_around.pop_back();}
}
Vertex_handle vq= f->vertex(j);
remove_degree_3(vq,f);
hide_vertex(f,vq->point());
faces_around.push_front(f);
}
void stack_flip_2_2(Face_handle f, int i, Faces_around_stack & faces_around)
{
Vertex_handle vq = f->vertex(ccw(i));
flip(f,i);
if(f->has_vertex(vq)) {
faces_around.push_front(f->neighbor(ccw(i)));
faces_around.push_front(f);
}
else {
faces_around.push_front(f);
faces_around.push_front(f->neighbor(cw(i)));
}
}
public:
// INSERTION / DELETION
Vertex_handle
insert(const Weighted_point &p,
CGAL_Triangulation_2<Gt,Tds>::Locate_type& lt,
Face_handle f = Face_handle() )
{
Vertex_handle v;
if(number_of_vertices() == 0) {
v = new Vertex(p);
lt = OUTSIDE;
insert_first(v);
return v;
}
if(number_of_vertices() == 1) {
if (geom_traits().compare(p,finite_vertex()->point())) {
remove_first(finite_vertex());
v= new Vertex(p);
insert_first(v);
return v;
}
else{
v = new Vertex(p);
lt = OUTSIDE;
insert_second(v);
return v;
}
}
int li;
Face_handle loc = locate(p, lt, li, f);
switch(lt){
case VERTEX:
remove(loc->vertex(li));
v = insert(p,lt,f);
return v;
case OUTSIDE:
v = new Vertex(p);
insert_outside(v,loc);
break;
case FACE:
if (power_test( loc ,p)==CGAL_ON_NEGATIVE_SIDE) {
hide_vertex(loc, p );
return v;
}
v = new Vertex(p);
insert_in_face(v,loc);
break;
case EDGE:
if (power_test( loc ,p)==CGAL_ON_NEGATIVE_SIDE){
hide_vertex(loc, p);
return v;
}
v = new Vertex(p);
insert_in_edge(v,loc,li);
break;
case COLLINEAR_OUTSIDE:
v = new Vertex(p);
insert_collinear_outside( v, loc,li);
break;
default:
CGAL_triangulation_assertion(false); // locate step failed
}
regularize(v);
return v;
}
public:
Vertex_handle insert(const Weighted_point &p,
Face_handle f = Face_handle() )
{
//cerr<<endl<<"INSERT : "<<p<<endl;
Locate_type lt;
return insert(p, lt, f);
}
void insert_in_face(Vertex_handle v, Face_handle f)
{
CGAL_Triangulation_2<Gt,Tds>::insert_in_face(v,f);
update_hidden_points_1_3(f, f->neighbor(ccw(f->index(v))),
f->neighbor(cw(f->index(v))) );
return;
}
void insert_in_edge(Vertex_handle v, Face_handle f, int i)
{
CGAL_Triangulation_2<Gt,Tds>::insert_in_edge(v,f,i);
Face_handle g =
(v==f->vertex(cw(i)) ? f->neighbor(ccw(i)) : f->neighbor(cw(i)) );
update_hidden_points_2_2(f,g);
update_hidden_points_2_2(f->neighbor(i), g->neighbor(i));
}
void flip(Face_handle f,int i)
{
Face_handle n = f->neighbor(i);
CGAL_Triangulation_2<Gt,Tds>::flip(f,i);
update_hidden_points_2_2(f,n);
return;
}
void remove_degree_3(Vertex_handle v,Face_handle f = Face_handle())
{
if (f == Face_handle()) f=v->face();
update_hidden_points_3_1(f, f->neighbor(cw(f->index(v))),
f->neighbor(ccw(f->index(v))));
CGAL_Triangulation_2<Gt,Tds>::remove_degree_3(v,f);
}
protected :
void remove_2D(Vertex_handle v)
{
// General case
// remove incident faces
// set up list of faces neighboring the hole
// in ccw order around the hole
// should be face_handle instead of void*
// but it doesn't link (maybe because of too long names
// generated by template classes imbrication)
typedef pair<void* , int> Hole_neighbor;
typedef list<Hole_neighbor> Hole;
typedef list<Hole> Hole_list;
Hole hole;
Hole_list hole_list;
list<Face_handle> to_delete;
Face_handle f, ff, fn;
int i =0,ii =0, in =0;
Vertex_handle vv;
Face_circulator fc = v->incident_faces();
Face_circulator done(fc);
do
{
f = (*fc).handle(); fc++;
i = f->index(v);
fn = f->neighbor(i);
vv = f->vertex(f->cw(i));
if( vv->face()== f) vv->set_face(fn);
vv = f->vertex(f->ccw(i));
if( vv->face()== f) vv->set_face(fn);
in = fn->index( f );
fn->set_neighbor(in, NULL);
hole.push_back(Hole_neighbor(&(*fn),in));
to_delete.push_back(f);
}
while(fc != done);
while (! to_delete.empty()){
to_delete.front().Delete();
to_delete.pop_front();
}
hole_list.push_front(hole);
while( ! hole_list.empty())
{
hole = hole_list.front();
hole_list.pop_front();
Hole::iterator hit = hole.begin();
// if the hole has only three edges, create the triangle
if (hole.size() == 3)
{
Face_handle newf = new Face();
hit = hole.begin();
for(int j = 0;j<3;j++)
{
ff = (Face*)(*hit).first;
ii = (*hit).second;
hit++;
ff->set_neighbor(ii,newf);
newf->set_neighbor(j,ff);
newf->set_vertex(newf->ccw(j),ff->vertex(ff->cw(ii)));
}
continue;
}
// else find an edge with two finite vertices
// on the hole boundary
// and the new triangle adjacent to that edge
// cut the hole and push it back
// first, ensure that a neighboring face
// whose vertices on the hole boundary are finite
// is the first of the hole
bool finite= false;
while (!finite)
{
ff = (Face*)(hole.front()).first;
ii = (hole.front()).second;
if ( is_infinite(ff->vertex(cw(ii))) ||
is_infinite(ff->vertex(ccw(ii))))
{
hole.push_back(hole.front());
hole.pop_front();
}
else
finite=true;
}
// take the first neighboring face and pop it;
ff = (Face*)(hole.front()).first;
ii =(hole.front()).second;
hole.pop_front();
Vertex_handle v0 = ff->vertex(ff->cw(ii)); Weighted_point p0 =v0->point();
Vertex_handle v1 = ff->vertex(ff->ccw(ii)); Weighted_point p1 =v1->point();
Vertex_handle v2 = infinite_vertex(); Weighted_point p2;
Vertex_handle vv; Weighted_point p;
Hole::iterator hdone = hole.end();
hit = hole.begin();
Hole::iterator cut_after(hit);
// if tested vertex is c with respect to the vertex opposite
// to NULL neighbor,
// stop at the before last face;
hdone--;
while( hit != hdone)
{
fn = (Face*)(*hit).first;
in = (*hit).second;
vv = fn->vertex(ccw(in));
if (is_infinite(vv))
{
if(is_infinite(v2))
cut_after = hit;
}else
{ // vv is a finite vertex
p = vv->point();
if ( geom_traits().orientation(p0,p1,p) == CGAL_COUNTERCLOCKWISE)
{ if(is_infinite(v2))
{ v2=vv; p2=p;
cut_after=hit;
}else
{ if( geom_traits().power_test (p0,p1,p2,p) == CGAL_ON_POSITIVE_SIDE)
{ v2=vv; p2=p; cut_after=hit;
}
}
}
}
++hit;
}
// create new triangle and update adjacency relations
Face_handle newf = new Face(v0,v1,v2);
newf->set_neighbor(2,ff);
ff->set_neighbor(ii, newf);
//update the hole and push back in the Hole_List stack
// if v2 belongs to the neighbor following or preceding *f
// the hole remain a single hole
// otherwise it is split in two holes
fn = (Face*)(hole.front()).first;
in = (hole.front()).second;
if (fn->has_vertex(v2, i) && i == fn->ccw(in))
{
newf->set_neighbor(0,fn);
fn->set_neighbor(in,newf);
hole.pop_front();
hole.push_front(Hole_neighbor(&(*newf),1));
hole_list.push_front(hole);
}else
{
fn = (Face*)(hole.back()).first;
in = (hole.back()).second;
if (fn->has_vertex(v2, i) && i== fn->cw(in))
{
newf->set_neighbor(1,fn);
fn->set_neighbor(in,newf);
hole.pop_back();
hole.push_back(Hole_neighbor(&(*newf),0));
hole_list.push_front(hole);
}else
{
// split the hole in two holes
Hole new_hole;
++cut_after;
while( hole.begin() != cut_after )
{
new_hole.push_back(hole.front());
hole.pop_front();
}
hole.push_front(Hole_neighbor(&(*newf),1));
new_hole.push_front(Hole_neighbor(&(*newf),0));
hole_list.push_front(hole);
hole_list.push_front(new_hole);
}
}
}
}
public:
void remove(Vertex_handle v )
{
CGAL_triangulation_precondition(! v.is_null());
CGAL_triangulation_precondition( !is_infinite(v));
Weighted_point_list p_list;
if (number_of_vertices() == 1){
_tds.remove_first(& (*v));
v.clear();
return;
}
// take care of finite_vertex data member
if (finite_vertex() == v){
Face_handle f = v->face();
int i=f->index(v);
Vertex_handle vv= is_infinite(f->vertex(cw(i))) ?
f->vertex(ccw(i)) : f->vertex(cw(i));
set_finite_vertex( vv);
}
// Collect in p_list
// the points hidden by the face to be deleted
Face_circulator fc = v->incident_faces(),done(fc);
do {
p_list.splice(p_list.begin(), fc->point_list());
fc++;
}
while( fc != done);
if (number_of_vertices() == 2) {
Face_handle f = v->face();
Face_handle ff =f->neighbor(0);
ff.Delete();
f.Delete();
}
else{
if ( dimension() == 1) remove_1D(v);
else remove_2D(v);
}
v.Delete();
set_number_of_vertices(number_of_vertices()-1);
Weighted_point p;
while ( ! p_list.empty() )
{ p=p_list.front();
p_list.pop_front();
//cerr<<endl<<"re-insertion : "<<p<<endl;
insert(p);
}
return;
//cerr<<"etat APRES remove"<<endl;
//affiche_tout();
}
bool is_valid(bool verbose = false, int level = 0) const
{
if(number_of_vertices() <= 1) {
return true;
}
bool result = CGAL_Triangulation_2<Gt,Tds>::is_valid();
for( Face_iterator it = faces_begin(); it != faces_end() ; it++) {
for(int i=0; i<3; i++) {
if ( ! is_infinite( it->vertex(i))) {
result = result &&
CGAL_ON_POSITIVE_SIDE !=
power_test( it->neighbor(i), it->vertex(i)->point());
}
if ( !result) {
cerr << "face : " << (void*)&(*it)<< " "
<<"["<< it->vertex(0)->point()
<<"/"<< it->vertex(1)->point()
<<"/"<< it->vertex(2)->point()<<"]" <<endl;
cerr << "voisin : " << (void*)&(*(it->neighbor(i)))<< " "
<<"["<<(it->neighbor(i))->vertex(0)->point()
<<"/"<<(it->neighbor(i))->vertex(1)->point()
<<"/"<<(it->neighbor(i))->vertex(2)->point()<<"]" <<endl;
}
CGAL_triangulation_assertion( result );
}
Weighted_point_list::iterator plit= it->point_list().begin(),
pldone= it->point_list().end();
for( ; plit != pldone ; plit++) {
result = result &&
power_test( it, *plit) == CGAL_ON_NEGATIVE_SIDE ;
if ( !result) {
cerr << "face : " << (void*)&(*it)<< " "
<<"["<< it->vertex(0)->point()
<<"/"<< it->vertex(1)->point()
<<"/"<< it->vertex(2)->point()<<"]" <<endl;
cerr << "hidden point : " << *plit <<endl;
}
CGAL_triangulation_assertion( result );
}
return result;
}
}
void affiche_tout()
{
cerr<< "AFFICHE TOUTE LA TRIANGULATION :"<<endl;
Face_iterator fi , fi_end=faces_end();
cerr << endl<<"====> "<<this<<endl;
fi=faces_begin();
cerr<<"***"<<endl;
while(fi != fi_end)
{
cerr << "face : "<<(void*)&(*fi)<<" => "<<endl;
cerr <<"point :"<<(fi->vertex(0)->point())
<<" / voisin "<<&(*(fi->neighbor(0)))
<<"["<<(fi->neighbor(0))->vertex(0)->point()
<<"/"<<(fi->neighbor(0))->vertex(1)->point()
<<"/"<<(fi->neighbor(0))->vertex(2)->point()<<"]"
<<endl;
cerr <<"point :"<<(fi->vertex(1)->point())
<<" / voisin "<<&(*(fi->neighbor(1)))
<<"["<<(fi->neighbor(1))->vertex(0)->point()
<<"/"<<(fi->neighbor(1))->vertex(1)->point()
<<"/"<<(fi->neighbor(1))->vertex(2)->point()<<"]"
<<endl;
cerr <<"point :"<<(fi->vertex(2)->point())
<<" / voisin "<<&(*(fi->neighbor(2)))
<<"["<<(fi->neighbor(2))->vertex(0)->point()
<<"/"<<(fi->neighbor(2))->vertex(1)->point()
<<"/"<<(fi->neighbor(2))->vertex(2)->point()<<"]"
<<endl;
Weighted_point_list::iterator current;
cerr << " +++++>>> ";
for (current= fi->point_list().begin() ;
current!= fi->point_list().end() ; current++ )
{
cerr <<"[ "<< (*current) << " ] , ";
}
cerr <<endl;
++fi;
}
cerr <<"faces infinies "<<endl;
if ( number_of_vertices() <= 2) {return;}
Face_circulator fc = infinite_vertex()->incident_faces(),fcdone(fc);
do {
cerr<<(void*)&(*fc) <<" = "<< fc->vertex(0)->point()<<" / "
<< fc->vertex(1)->point()<<" / "<< fc->vertex(2)->point()
<<" / ";
Weighted_point_list::iterator current;
cerr << " +++++>>> ";
for (current= fc->point_list().begin() ;
current!= fc->point_list().end() ; current++ )
{
cerr <<"[ "<< (*current) << " ] , ";
}
cerr <<endl;
}while(++fc != fcdone);
cerr <<endl;
if (number_of_vertices()>1) {
cerr << "affichage des sommets de la triangulation reguliere"<<endl;
Vertex_iterator vi;
vi=vertices_begin();
if (number_of_vertices()>1) {
while ( vi!=vertices_end() ) {
//cerr << "* "<< &(*vi) <<" / ";
cerr << "* "<< vi->point() <<" / face associee : "
<< (void*)(&(*(vi->face())))<<endl;;
++vi;
}
cerr<<endl;
}
}
}
};
#endif