// ====================================================================== // // 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 : 1999, October 01 // // file : include/CGAL/bops_dcel.C // package : bops (2.2) // source : include/CGAL/bops_dcel.C // revision : $Revision$ // revision_date : $Date$ // author(s) : Wolfgang Freiseisen // // coordinator : RISC Linz // (Wolfgang Freiseisen ) // // // ====================================================================== #ifndef CGAL__DCEL_C #define CGAL__DCEL_C #ifndef CGAL_CFG_NO_AUTOMATIC_TEMPLATE_INCLUSION #include #endif #include #include #include //#define CGAL__DCEL_DEBUG_ON CGAL_BEGIN_NAMESPACE template struct _Dcel_V2E_compare : public I { typedef const _Dcel_vertex_type* vertex; typedef typename I::Point Point; typedef typename I::Direction Direction; Point p0; _Dcel_V2E_compare(vertex v0) : p0((*v0).point()) { } bool operator()(vertex v1, vertex v2 ) const { return compare(v1,v2); } bool compare(vertex v1, vertex v2 ) const { Point p1= (*v1).point(), p2= (*v2).point(); Direction d1= I::direction_of(p0,p1); Direction d2= I::direction_of(p0,p2); return d1 < d2; } }; /* Implementation of the Double Connected Edge List (DCEL) ------------------------------------------------------- template class DCEL__Dcel; */ #ifdef CGAL_CFG_RETURN_TYPE_BUG_2 template void _Dcel :: insert_edges() { const std::list& edges= *__edges; #else template void _Dcel :: insert_edges( const std::list& edges) { #endif // CGAL_CFG_RETURN_TYPE_BUG_2 typedef _V2E_rep_type > V2E_rep_dcel; typedef _V2E_rep_base_type V2E_rep_base; /* insert edges */ _e_list.reserve(edges.size()); std::list< std::pair >::const_iterator ee; for( ee= edges.begin(); ee != edges.end(); ee++ ) _Dcel_base::insert( _Dcel_edge_type(c_it[(*ee).first], c_it[(*ee).second]) ); CGAL__BOPS_DCEL_DEBUG_LN("VERTICES inserted: "); CGAL__BOPS_DCEL_DEBUG_ITERATOR("dcel", this->begin(), this->end() ); CGAL__BOPS_DCEL_DEBUG_ITERATOR("PT", _point_list.begin(), _point_list.end() ); /* template< class T_vertex, class T_edge, class T_compare > */ V2E_rep_dcel v2e_rep( c_it.size(), edges.size() ); /* insertion in vertex-to-edge rep. */ /* const_vertices_iterator v0= _v_list.begin(); */ const_vertices_iterator v1, v2; int iv1, iv2; for( edge_iterator e= _e_list.begin(); e != _e_list.end(); e++ ) { v1= (*e).V1(); v2= (*e).V2(); iv1= (*v1).index(); iv2= (*v2).index(); CGAL__BOPS_DCEL_DEBUG_VAR("insert: ", e); CGAL__BOPS_DCEL_DEBUG_PAIR("", iv1, iv2 ); CGAL__BOPS_DCEL_DEBUG_LN(""); v2e_rep.insert( iv1, (*e).V1(), iv2, (*e).V2(), e); } CGAL__BOPS_DCEL_DEBUG((V2E_rep_base)v2e_rep); v2e_rep.sort_vertices_CCW(); CGAL__BOPS_DCEL_DEBUG((V2E_rep_base)v2e_rep); /* construction of vertex cycles */ construct_vertex_cycles( v2e_rep ); CGAL__BOPS_DCEL_DEBUG_LN("POINTERS inserted: "); CGAL__BOPS_DCEL_DEBUG_ITERATOR("dcel", this->begin(), this->end() ); CGAL__BOPS_DCEL_DEBUG_ITERATOR("V", vertex_begin(), vertex_end() ); /* construction of face cycles */ construct_face_cycles(); CGAL__BOPS_DCEL_DEBUG_LN("FACES inserted: "); CGAL__BOPS_DCEL_DEBUG_ITERATOR("dcel", this->begin(), this->end() ); CGAL__BOPS_DCEL_DEBUG_ITERATOR("F", face_begin(), face_end() ); return; } template #ifdef CGAL_CFG_RETURN_TYPE_BUG_2 bool _Dcel::colorize(const _Dcel_Color& col) { typedef typename I::Point Point; const std::list& pgon= *__point_list; #else bool _Dcel::colorize( const std::list& pgon, const _Dcel_Color& col) { typedef typename I::Point Point; typedef typename I::vertices_iterator vertices_iterator; typedef typename I::edges_iterator edges_iterator; typedef typename I::faces_iterator faces_iterator; typedef typename I::edge_iterator edge_iterator; #endif // CGAL_CFG_RETURN_TYPE_BUG_2 /* This routine colorizes the interior of a simple polygon 'pgon' given by a list of its vertices in counterclockwise order(!). ^^^^^^^^^^^^^^^^^^^^^^^^^ The color is given by the input variable 'col' and will be set using the or operation, i.e. vertex::set_color( vertex::color() | col ); return: true iff everything ok false if e.g. polygon not valid */ if( pgon.size() < 3 ) return false; std::list::const_iterator it_p; /* get last point */ std::list::const_reverse_iterator rit_p= pgon.rbegin(); Point pt= (*rit_p); Point v1_pt; const_vertices_iterator v0, v1; v0= find( pt ); // find first vertex vertices_iterator v= (vertices_iterator)v0; (*v).set_color( (*v0).color() | col); edge_iterator a, e0; edges_iterator e; faces_iterator f; std::list vlist_deg2; // all vertices with degree greater than 2 for(it_p= pgon.begin(); it_p != pgon.end(); it_p++) { /* for all vertices */ v0= v; if( (*v0).degree() > 2 ) vlist_deg2.push_back(v0); /* find second vertex 'v1' and edge [v0,v1] */ a= e0= begin(v0); v1= (*a).opposite_vertex(v0); //if( (*v1).point() != *it_p ) if( !compare_points((*v1).point(), *it_p ) ) { for( a= next(e0,v0); a != e0; a= next(a,v0) ) { v1= (*a).opposite_vertex(v0); //if( (*v1).point() == *it_p ) break; /* found !! */ if( compare_points((*v1).point(), *it_p) ) break; /* found !! */ } if( a==e0) return false; /* ABORT: --> polygon not valid */ } e= (edges_iterator)a; (*e).set_color( (*e).color()|col); v= (vertices_iterator)v1; (*v).set_color( (*v).color()|col); face_iterator face0= (*e).left_face(v0); /* v0 -> v1 ** pgon is CCW */ face_iterator face1= (*e).opposite_face(face0); f= (faces_iterator)face0; (*f).set_color( (*f).color()|col); if( face_inside_in_face(face1, face0) ) { f= (faces_iterator)face1; (*f).set_color( (*f).color()|col); } } std::list::const_iterator vit; face_iterator f1, f2; for( vit= vlist_deg2.begin(); vit != vlist_deg2.end(); vit++) { v0= *vit; a= e0= begin(v0); do { if( !((*a).color() & col ) ) { f1= (*a).F1(); f2= (*a).F2(); if( (*f1).color()&col && (*f2).color()&col ) { e= (edges_iterator)a; (*e).set_color( (*a).color()|col ); v1= (*a).opposite_vertex(v0); v= (vertices_iterator)v1; (*v).set_color( (*v).color()|col); vlist_deg2.push_back(v1); } } a= next(a,v0); } while( a != e0 ); } CGAL__BOPS_DCEL_DEBUG_LN("colorized: "); CGAL__BOPS_DCEL_DEBUG_ITERATOR("E", this->begin(), this->end() ); CGAL__BOPS_DCEL_DEBUG_ITERATOR("V", vertex_begin(), vertex_end() ); CGAL__BOPS_DCEL_DEBUG_ITERATOR("F", face_begin(), face_end() ); return true; } CGAL_END_NAMESPACE #endif /* CGAL__DCEL_C */