Adaptation such that Nef_S2 can be reused in Nef_3

This commit is contained in:
Peter Hachenberger 2004-03-05 15:47:07 +00:00
parent f47aa33548
commit 7e32f78e1b
19 changed files with 2758 additions and 2328 deletions

View File

@ -110,7 +110,7 @@ check_order_preserving_embedding(Vertex_const_handle v) const
!K.strictly_ordered_ccw(direction(e),direction(en),
direction(ef)) ) {
error_status << "ccw order violate!" << endl << '\0';
CGAL_nef_assertion_msg(0,error_status.str());
CGAL_assertion_msg(0,error_status.str());
}
e = en;
}
@ -129,7 +129,7 @@ check_forward_prefix_condition(Vertex_const_handle v) const
point(target(el)));
bool el_forward = is_forward(el);
bool ef_forward = is_forward(ef);
CGAL_nef_assertion_msg( (ef == el ||
CGAL_assertion_msg( (ef == el ||
ef_forward && !el_forward ||
ef_forward && el_forward && is_left_turn ||
!ef_forward && !el_forward && is_left_turn) ,
@ -156,7 +156,7 @@ check_boundary_is_clockwise_weakly_polygon() const
Vertex_const_iterator vit, v_min;
for (vit = v_min = vertices_begin() ; vit != vertices_end(); ++vit)
if ( K.compare_xy(point(vit), point(v_min))<0 ) v_min = vit;
CGAL_nef_assertion_msg(!is_isolated(v_min),"Minimal vertex not connected.");
CGAL_assertion_msg(!is_isolated(v_min),"Minimal vertex not connected.");
Sphere_point p_min = point(v_min);
// determine boundary edge incident to v_min:
@ -187,7 +187,7 @@ check_boundary_is_clockwise_weakly_polygon() const
if ( d_curr < d_prev ) ++winding_around_globally;
d_prev = d_curr;
}
CGAL_nef_assertion(winding_around_globally == 1);
CGAL_assertion(winding_around_globally == 1);
return e_boundary_at_v_min;
}
@ -197,7 +197,7 @@ check_is_triangulation() const
{
Halfedge_const_iterator eb;
check_integrity_and_topological_planarity(false);
CGAL_nef_assertion(number_of_connected_components() == 1);
CGAL_assertion(number_of_connected_components() == 1);
check_order_preserving_embedding();
eb = check_boundary_is_clockwise_weakly_polygon();
@ -220,7 +220,7 @@ check_is_triangulation() const
error_status << PE(hit);
++edges_in_face_cycle;
}
CGAL_nef_assertion_msg(edges_in_face_cycle==3,error_status.str());
CGAL_assertion_msg(edges_in_face_cycle==3,error_status.str());
}
error_status.freeze(0);
}

View File

@ -1,3 +1,25 @@
// Copyright (c) 1997-2002 Max-Planck-Institute Saarbruecken (Germany).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $Source$
// $Revision$ $Date$
// $Name$
//
// Author(s) : Michael Seel <seel@mpi-sb.mpg.de>
// Miguel Granados <granados@mpi-sb.mpg.de>
// Susan Hert <hert@mpi-sb.mpg.de>
// Lutz Kettner <kettner@mpi-sb.mpg.de>
// Peter Hachenberger <hachenberger@mpi-sb.mpg.de>
#ifndef CGAL_SM_CONST_DECORATOR_H
#define CGAL_SM_CONST_DECORATOR_H
@ -5,60 +27,44 @@
#include <CGAL/circulator.h>
#include <CGAL/Unique_hash_map.h>
#include <CGAL/Nef_2/Object_index.h>
#include <CGAL/Nef_2/iterator_tools.h>
#include <CGAL/Nef_S2/SM_iteration.h>
#include <CGAL/Nef_S2/SM_decorator_traits.h>
#include <string>
#include <list>
#include <strstream>
#include <sstream>
#undef _DEBUG
#define _DEBUG 127
#define _DEBUG 67
#include <CGAL/Nef_S2/debug.h>
CGAL_BEGIN_NAMESPACE
template <typename HE>
class move_edge_around_vertex {
public:
void forward(HE& e) const { e = (e->prev_->twin_); }
void backward(HE& e) const { e = (e->twin_->next_); }
};
template <typename HE>
struct move_edge_around_face {
void forward(HE& e) const { e = (e->next_); }
void backward(HE& e) const { e = (e->prev_); }
};
template <typename Sphere_map_, typename Kernel_>
class SM_decorator;
/*{\Moptions print_title=yes }*/
/*{\Moptions outfile=SM_const_decorator.man }*/
/*{\Manpage {SM_const_decorator}{Sphere_map,Kernel}
{Topological sphere map decorator}{D}}*/
template <typename Sphere_map_, typename Kernel_>
class SM_const_decorator
{ typedef SM_const_decorator<Sphere_map_,Kernel_> Self;
template <typename Map>
class SM_const_decorator {
typedef SM_const_decorator<Map> Self;
public:
typedef SM_decorator_const_traits<Map> Decorator_traits;
/*{\Mdefinition ...}*/
/*{\Mtypes 5}*/
typedef Kernel_ Kernel;
typedef typename Map::Sphere_kernel Sphere_kernel;
/*{\Mtypemember spherical geometry.}*/
typedef typename Kernel_::Sphere_point Sphere_point;
typedef typename Map::Sphere_point Sphere_point;
/*{\Mtypemember embedding vertices.}*/
typedef typename Kernel_::Sphere_segment Sphere_segment;
typedef typename Map::Sphere_segment Sphere_segment;
/*{\Mtypemember embedding edges.}*/
typedef typename Kernel_::Sphere_circle Sphere_circle;
typedef typename Map::Sphere_circle Sphere_circle;
/*{\Mtypemember embedding loops.}*/
typedef typename Sphere_map_::Mark Mark;
typedef typename Map::Sphere_direction Sphere_direction;
/*{\Mtypemember embedding directions.}*/
typedef typename Map::Mark Mark;
/*{\Mtypemember attributes of objects (vertices, edges, faces).}*/
typedef size_t Size_type;
@ -66,50 +72,45 @@ typedef size_t Size_type;
typedef void* GenPtr;
#define CGAL_USING(t) typedef typename Sphere_map_::t t
CGAL_USING(Vertex_const_handle);
CGAL_USING(Vertex_const_iterator);
CGAL_USING(Vertex);
CGAL_USING(Halfedge);
CGAL_USING(Halfedge_const_handle);
CGAL_USING(Halfedge_const_iterator);
CGAL_USING(Face);
CGAL_USING(Face_const_handle);
CGAL_USING(Face_const_iterator);
CGAL_USING(Halfloop);
CGAL_USING(Halfloop_const_handle);
CGAL_USING(Halfloop_const_iterator);
#undef CGAL_USING
typedef typename Map::Constructor_const_parameter Constructor_parameter;
typedef typename Map::SVertex_const_handle SVertex_const_handle;
typedef typename Map::SVertex_const_iterator SVertex_const_iterator;
typedef typename Map::SHalfedge_const_handle SHalfedge_const_handle;
typedef typename Map::SHalfedge_const_iterator SHalfedge_const_iterator;
typedef typename Map::SHalfloop_const_handle SHalfloop_const_handle;
typedef typename Map::SHalfloop_const_iterator SHalfloop_const_iterator;
typedef typename Map::SFace_const_handle SFace_const_handle;
typedef typename Map::SFace_const_iterator SFace_const_iterator;
/*{\Mtext Local types are handles, iterators and circulators of the
following kind: |Vertex_handle|, |Vertex_iterator|, |Halfedge_handle|,
|Halfedge_iterator|, |Halfloop_handle|, |Halfloop_iterator|,
|Face_handle|, |Face_iterator|. Additionally the following
following kind: |SVertex_handle|, |SVertex_iterator|, |SHalfedge_handle|,
|SHalfedge_iterator|, |SHalfloop_handle|, |SHalfloop_iterator|,
|SFace_handle|, |SFace_iterator|. Additionally the following
circulators are defined.}*/
typedef CircFromIt<
Halfedge_const_iterator,
move_edge_around_vertex<Halfedge_const_iterator> >
Halfedge_around_vertex_const_circulator;
typedef typename Map::SHalfedge_around_svertex_const_circulator
SHalfedge_around_svertex_const_circulator;
/*{\Mtypemember circulating the adjacency list of an vertex |v|.}*/
typedef CircFromIt<
Halfedge_const_iterator,
move_edge_around_face<Halfedge_const_iterator> >
Halfedge_around_face_const_circulator;
typedef typename Map::SHalfedge_around_sface_const_circulator
SHalfedge_around_sface_const_circulator;
/*{\Mtypemember circulating the face cycle of an face |f|.}*/
typedef typename Sphere_map_::Face_cycle_const_iterator
Face_cycle_const_iterator;
/*{\Mtypemember iterating all face cycles of an face |f|.
The iterator has method |bool is_vertex()|, |bool is_halfedge()|,
|bool is_halfloop()|, and can be converted to the corresponding
handles |Vertex_const_handle|, |Halfedge_const_handle|, or
|Halfloop_const_handle|.}*/
typedef typename Map::SFace_cycle_const_iterator
SFace_cycle_const_iterator;
/*{\Mtypemember iterating all sface cycles of an sface |f|.
The iterator has method |bool is_svertex()|, |bool is_shalfedge()|,
|bool is_shalfloop()|, and can be converted to the corresponding
handles |SVertex_const_handle|, |SHalfedge_const_handle|, or
|SHalfloop_const_handle|.}*/
protected:
Sphere_map_* psm_;
friend class SM_decorator<Sphere_map_,Kernel_>;
Constructor_parameter psm_;
void set_sm(Constructor_parameter W) {
psm_ = W;
}
public:
/*{\Mcreation 3}*/
@ -117,144 +118,145 @@ SM_const_decorator() : psm_(0) {}
SM_const_decorator(const Self& D) : psm_(D.psm_) {}
Self& operator=(const Self& D) { psm_=D.psm_; return *this; }
SM_const_decorator(const Sphere_map_& M) :
psm_(const_cast<Sphere_map_*>(&M)) {}
SM_const_decorator(Constructor_parameter M) : psm_(M) {}
/*{\Mcreate constructs a plane map decorator exploring |M|.}*/
/*{\Moperations 4 4}*/
Vertex_const_handle source(Halfedge_const_handle e) const
Constructor_parameter center_vertex() const { return psm_; }
SVertex_const_handle source(SHalfedge_const_handle e) const
/*{\Mop returns the source of |e|.}*/
{ return e->source_; }
Vertex_const_handle target(Halfedge_const_handle e) const
SVertex_const_handle target(SHalfedge_const_handle e) const
/*{\Mop returns the target of |e|.}*/
{ return e->twin_->source_; }
Halfedge_const_handle twin(Halfedge_const_handle e) const
SHalfedge_const_handle twin(SHalfedge_const_handle e) const
/*{\Mop returns the twin of |e|.}*/
{ return e->twin_; }
Halfloop_const_handle twin(Halfloop_const_handle l) const
SHalfloop_const_handle twin(SHalfloop_const_handle l) const
/*{\Mop returns the twin of |l|.}*/
{ return l->twin_; }
bool is_isolated(Vertex_const_handle v) const
bool is_isolated(SVertex_const_handle v) const
/*{\Mop returns |true| when |v| is linked to the interior of a face.}*/
{ return (Halfedge_const_handle(v->edge_) == Halfedge_const_handle()); }
{ return (SHalfedge_const_handle(v->out_sedge_) == SHalfedge_const_handle()); }
Halfedge_const_handle first_out_edge(Vertex_const_handle v) const
SHalfedge_const_handle first_out_edge(SVertex_const_handle v) const
/*{\Mop returns one edge with source |v|. It's the starting point for
the circular iteration over the edges with source |v|.
\precond |!is_isolated(v)|.}*/
{ return v->edge_; }
{ return v->out_sedge_; }
Halfedge_const_handle last_out_edge(Vertex_const_handle v) const
SHalfedge_const_handle last_out_edge(SVertex_const_handle v) const
/*{\Mop returns one edge with source |v|. \precond |!is_isolated(v)|.}*/
{ return cap(v->edge_); }
{ return cap(v->out_sedge_); }
Halfedge_const_handle cyclic_adj_succ(Halfedge_const_handle e) const
SHalfedge_const_handle cyclic_adj_succ(SHalfedge_const_handle e) const
/*{\Mop returns the edge after |e| in the cyclic ordered adjacency list of
|source(e)|.}*/
{ return e->prev_->twin_; }
{ return e->sprev_->twin_; }
Halfedge_const_handle cyclic_adj_pred(Halfedge_const_handle e) const
SHalfedge_const_handle cyclic_adj_pred(SHalfedge_const_handle e) const
/*{\Mop returns the edge before |e| in the cyclic ordered adjacency list of
|source(e)|.}*/
{ return e->twin_->next_; }
{ return e->twin_->snext_; }
Halfedge_const_handle next(Halfedge_const_handle e) const
SHalfedge_const_handle next(SHalfedge_const_handle e) const
/*{\Mop returns the next edge in the face cycle containing |e|.}*/
{ return e->next_; }
{ return e->snext_; }
Halfedge_const_handle previous(Halfedge_const_handle e) const
SHalfedge_const_handle previous(SHalfedge_const_handle e) const
/*{\Mop returns the previous edge in the face cycle containing |e|.}*/
{ return e->prev_; }
{ return e->sprev_; }
Face_const_handle face(Halfedge_const_handle e) const
SFace_const_handle face(SHalfedge_const_handle e) const
/*{\Mop returns the face incident to |e|.}*/
{ return e->face_; }
{ return e->incident_sface_; }
Face_const_handle face(Halfloop_const_handle l) const
SFace_const_handle face(SHalfloop_const_handle l) const
/*{\Mop returns the face incident to |l|.}*/
{ return l->face_; }
{ return l->incident_sface_; }
Face_const_handle face(Vertex_const_handle v) const
SFace_const_handle face(SVertex_const_handle v) const
/*{\Mop returns the face incident to |v|.
\precond |is_isolated(v)|.}*/
{ return v->face_; }
{ return v->incident_sface_; }
/*{\Mtext \headerline{Iteration} \setopdims{3.3cm}{0cm}}*/
Vertex_const_iterator vertices_begin() const
{ return psm_->vertices_begin(); }
Vertex_const_iterator vertices_end() const
{ return psm_->vertices_end(); }
Halfedge_const_iterator halfedges_begin() const
{ return psm_->halfedges_begin(); }
Halfedge_const_iterator halfedges_end() const
{ return psm_->halfedges_end(); }
Face_const_iterator faces_begin() const
{ return psm_->faces_begin(); }
Face_const_iterator faces_end() const
{ return psm_->faces_end(); }
Halfloop_const_iterator halfloops_begin() const
{ return psm_->halfloops_begin(); }
Halfloop_const_iterator halfloops_end() const
{ return psm_->halfloops_end(); }
SVertex_const_iterator svertices_begin() const
{ return psm_->svertices_begin(); }
SVertex_const_iterator svertices_end() const
{ return psm_->svertices_end(); }
SHalfedge_const_iterator shalfedges_begin() const
{ return psm_->shalfedges_begin(); }
SHalfedge_const_iterator shalfedges_end() const
{ return psm_->shalfedges_end(); }
SFace_const_iterator sfaces_begin() const
{ return psm_->sfaces_begin(); }
SFace_const_iterator sfaces_end() const
{ return psm_->sfaces_end(); }
SHalfloop_const_iterator shalfloops_begin() const
{ return psm_->shalfloops_begin(); }
SHalfloop_const_iterator shalfloops_end() const
{ return psm_->shalfloops_end(); }
Halfloop_const_handle halfloop() const
SHalfloop_const_handle shalfloop() const
/*{\Mop returns access to the loop.}*/
{ return psm_->loops_; }
{ return psm_->shalfloop_; }
bool has_loop() const
bool has_sloop() const
/*{\Mop returns true iff there is a loop.}*/
{ return halfloop() != 0; }
{ return psm_->has_sloop(); }
Halfedge_around_vertex_const_circulator
out_edges(Vertex_const_handle v) const
SHalfedge_around_svertex_const_circulator
out_edges(SVertex_const_handle v) const
/*{\Mop returns a circulator for the cyclic adjacency list of |v|.
\precond the adjacency list is not empty.}*/
{ return Halfedge_around_vertex_const_circulator(first_out_edge(v)); }
{ return SHalfedge_around_svertex_const_circulator(first_out_edge(v)); }
Face_cycle_const_iterator face_cycles_begin(Face_const_handle f) const
SFace_cycle_const_iterator sface_cycles_begin(SFace_const_handle f) const
/*{\Mop returns an iterator for all bounding face cycles of |f|.
The iterator is is convertable to |Vertex_const_handle|,
|Halfloop_const_handle|, or |Halfedge_const_handle|.}*/
{ return f->bounday_.begin(); }
The iterator is is convertable to |SVertex_const_handle|,
|SHalfloop_const_handle|, or |SHalfedge_const_handle|.}*/
{ return f->boundary_entry_objects_.begin(); }
Face_cycle_const_iterator face_cycles_end(Face_const_handle f) const
SFace_cycle_const_iterator sface_cycles_end(SFace_const_handle f) const
/*{\Mop returns the past the end iterator of |f|.}*/
{ return f->boundary_.end(); }
{ return f->boundary_entry_objects_.end(); }
/*{\Mtext \headerline{Statistics and Integrity}}*/
Size_type number_of_vertices() const
Size_type number_of_svertices() const
/*{\Mop returns the number of vertices.}*/
{ return psm_->number_of_vertices(); }
{ return psm_->number_of_svertices(); }
Size_type number_of_halfedges() const
Size_type number_of_shalfedges() const
/*{\Mop returns the number of halfedges.}*/
{ return psm_->number_of_halfedges(); }
{ return psm_->number_of_shalfedges(); }
Size_type number_of_edges() const
Size_type number_of_sedges() const
/*{\Mop returns the number of edges.}*/
{ return number_of_halfedges()/2; }
{ return number_of_shalfedges()/2; }
Size_type number_of_halfloops() const
Size_type number_of_shalfloops() const
/*{\Mop returns the number of halfloops.}*/
{ return psm_->number_of_halfloops(); }
{ return psm_->number_of_shalfloops(); }
Size_type number_of_loops() const
Size_type number_of_sloops() const
/*{\Mop returns the number of loops.}*/
{ return psm_->number_of_halfloops()/2; }
{ return psm_->number_of_shalfloops()/2; }
Size_type number_of_faces() const
Size_type number_of_sfaces() const
/*{\Mop returns the number of faces.}*/
{ return psm_->number_of_faces(); }
{ return psm_->number_of_sfaces(); }
Size_type number_of_face_cycles() const;
Size_type number_of_sface_cycles() const;
/*{\Mop returns the number of face cycles.}*/
Size_type number_of_connected_components() const;
@ -265,20 +267,20 @@ void print_statistics(std::ostream& os = std::cout) const
and faces.}*/
{
os << "Sphere Map - Statistics\n";
os << "|V| = " << number_of_vertices() << std::endl;
os << "|E| = " << number_of_edges() << std::endl;
os << "|L| = " << number_of_halfloops()/2 << std::endl;
os << "|F| = " << number_of_faces() << std::endl;
os << "|Fcs| = " << number_of_face_cycles() << std::endl << std::endl;
os << "|V| = " << number_of_svertices() << std::endl;
os << "|E| = " << number_of_shalfedges() << std::endl;
os << "|L| = " << number_of_shalfloops() << std::endl;
os << "|F| = " << number_of_sfaces() << std::endl;
os << "|Fcs| = " << number_of_sface_cycles() << std::endl << std::endl;
}
void check_integrity_and_topological_planarity(bool faces=true) const;
/*{\Mop checks the link structure and the genus of |P|.}*/
Halfedge_const_handle cas(Halfedge_const_handle e) const
SHalfedge_const_handle cas(SHalfedge_const_handle e) const
{ return cyclic_adj_succ(e); }
Halfedge_const_handle cap(Halfedge_const_handle e) const
SHalfedge_const_handle cap(SHalfedge_const_handle e) const
{ return cyclic_adj_pred(e); }
template <typename H>
@ -287,122 +289,123 @@ bool is_boundary_object(H h) const
/*{\Mtext \headerline{Associated Information}\restoreopdims}*/
const Sphere_point& point(Vertex_const_handle v) const
const Sphere_point& point(SVertex_const_handle v) const
/*{\Mop returns the embedding of |v|.}*/
{ return v->point_; }
const Sphere_circle& circle(Halfedge_const_handle e) const
const Sphere_circle& circle(SHalfedge_const_handle e) const
/*{\Mop returns the circle supporting |e|.}*/
{ return e->circle_; }
const Sphere_circle& circle(Halfloop_const_handle l) const
const Sphere_circle& circle(SHalfloop_const_handle l) const
/*{\Mop returns the circle supporting |l|.}*/
{ return l->circle_; }
Mark mark(Vertex_const_handle v) const
const Mark& mark(SVertex_const_handle v) const
/*{\Mop returns the mark of |v|.}*/
{ return v->mark_; }
Mark mark(Halfedge_const_handle e) const
const Mark& mark(SHalfedge_const_handle e) const
/*{\Mop returns the mark of |e|.}*/
{ return ( &*e < &*twin(e) ) ? e->mark_ : twin(e)->mark_; }
Mark mark(Halfloop_const_handle l) const
const Mark& mark(SHalfloop_const_handle l) const
/*{\Mop returns the mark of |l|.}*/
{ return ( &*l < &*twin(l) ) ? l->mark_ : twin(l)->mark_; }
Mark mark(Face_const_handle f) const
const Mark& mark(SFace_const_handle f) const
/*{\Mop returns the mark of |f|.}*/
{ return f->mark_; }
Mark mark_of_halfsphere(int i) const
{ CGAL_nef_assertion(i);
if (i<0) return psm_->m_neg_;
return psm_->m_pos_; }
/*{\Mtext \headerline{Iteration}}*/
/*{\Mtext The list of all objects can be accessed via iterator ranges.
For comfortable iteration we also provide iterations macros.
The iterator range access operations are of the following kind:\\
|Vertex_iterator vertices_begin()/vertices_end()|\\
|Halfedge_iterator halfedges_begin()/halfedges_end()|\\
|Halfloop_iterator halfloops_begin()/halfloops_end()|\\
|Face_iterator faces_begin()/faces_end()|
|SVertex_iterator svertices_begin()/svertices_end()|\\
|SHalfedge_iterator shalfedges_begin()/shalfedges_end()|\\
|SHalfloop_iterator shalfloops_begin()/shalfloops_end()|\\
|SFace_iterator sfaces_begin()/sfaces_end()|
The macros are then |CGAL_forall_vertices(v,M)|,
|CGAL_forall_halfedges(e,M)|, |CGAL_forall_edges(e,M)|,
|CGAL_forall_faces(f,M)|, |CGAL_forall_face_cycles_of(fc,F)| where |M|
is a sphere map and |F| is a face.}*/
The macros are then |CGAL_forall_svertices(v,M)|,
|CGAL_forall_shalfedges(e,M)|, |CGAL_forall_sedges(e,M)|,
|CGAL_forall_sfaces(f,M)|, |CGAL_forall_sface_cycles_of(fc,F)|
where |M| is a sphere map and |F| is a sface.}*/
}; // SM_const_decorator
template <typename SM_, typename K_>
void SM_const_decorator<SM_,K_>::
template <typename SM_>
void SM_const_decorator<SM_>::
check_integrity_and_topological_planarity(bool faces) const
{
TRACEN("check_integrity_and_topological_planarity:");
using CGAL::Object_index;
Object_index<Vertex_const_iterator>
VI(vertices_begin(),vertices_end(),'v');
Object_index<Halfedge_const_iterator>
EI(halfedges_begin(),halfedges_end(),'e');
Object_index<Face_const_iterator>
FI(faces_begin(),faces_end(),'f');
typedef Halfedge_around_vertex_const_circulator hvc_circulator;
typedef Halfedge_around_face_const_circulator hfc_circulator;
Vertex_const_handle v;
Object_index<SVertex_const_iterator>
VI(svertices_begin(),svertices_end(),'v');
Object_index<SHalfedge_const_iterator>
EI(shalfedges_begin(),shalfedges_end(),'e');
Object_index<SFace_const_iterator>
FI(sfaces_begin(),sfaces_end(),'f');
typedef SHalfedge_around_svertex_const_circulator hvc_circulator;
typedef SHalfedge_around_sface_const_circulator hfc_circulator;
SVertex_const_handle v;
int iso_vert_num=0;
/* check the source links of out edges and count isolated vertices */
CGAL_forall_vertices(v,*this) {
CGAL_forall_svertices(v,*this) {
if ( is_isolated(v) ) {
if ( faces )
CGAL_nef_assertion_msg( face(v) != Face_const_handle(), VI(v).c_str());
CGAL_assertion_msg(face(v) != SFace_const_handle(), VI(v).c_str());
++iso_vert_num;
} else {
CGAL_nef_assertion_msg( first_out_edge(v) != Halfedge_const_handle(),
CGAL_assertion_msg(first_out_edge(v) != SHalfedge_const_handle(),
VI(v).c_str());
TRACEN(point(v)<<" "<<EI(first_out_edge(v)));
CGAL_nef_assertion_msg( source(first_out_edge(v)) == v ,
VI(v).c_str());
CGAL_assertion_msg(source(first_out_edge(v)) == v,
VI(v).c_str());
}
}
/* check the bidirected links and the face pointer init */
Halfedge_const_iterator e;
CGAL_forall_halfedges(e,*this) {
CGAL_nef_assertion( twin(twin(e)) == e );
CGAL_nef_assertion( source(e) != Vertex_const_handle() );
CGAL_nef_assertion( next(e) != Halfedge_const_handle() );
CGAL_nef_assertion( previous(next(e)) == e );
CGAL_nef_assertion( target(e) == source(next(e)) );
CGAL_nef_assertion( previous(e) != Halfedge_const_handle() );
CGAL_nef_assertion( next(previous(e)) == e );
CGAL_nef_assertion( target(previous(e)) == source(e) );
SHalfedge_const_iterator e;
CGAL_forall_shalfedges(e,*this) {
CGAL_assertion( twin(twin(e)) == e );
CGAL_assertion( source(e) != SVertex_const_handle() );
CGAL_assertion( next(e) != SHalfedge_const_handle() );
CGAL_assertion( previous(next(e)) == e );
CGAL_assertion( target(e) == source(next(e)) );
CGAL_assertion( previous(e) != SHalfedge_const_handle() );
CGAL_assertion( next(previous(e)) == e );
CGAL_assertion( target(previous(e)) == source(e) );
if ( !faces ) continue;
CGAL_nef_assertion( face(e) != Face_const_handle() );
CGAL_nef_assertion( face(next(e)) == face(e) );
CGAL_nef_assertion( face(previous(e)) == face(e) );
CGAL_assertion( face(e) != SFace_const_handle() );
CGAL_assertion( face(next(e)) == face(e) );
CGAL_assertion( face(previous(e)) == face(e) );
}
int fc_num(0),iv_num(0);
Face_const_iterator f;
Face_cycle_const_iterator fci;
CGAL_forall_faces(f,*this) {
CGAL_forall_face_cycles_of(fci,f) {
if ( fci.is_halfedge() ) {
CGAL_nef_assertion( face(Halfedge_const_handle(fci)) == f ); ++fc_num;
} else if ( fci.is_vertex() ) {
CGAL_nef_assertion( face(Vertex_const_handle(fci)) == f ); ++iv_num;
} else CGAL_nef_assertion_msg(0,"damn generic handle.");
SFace_const_iterator f;
SFace_cycle_const_iterator fci;
CGAL_forall_sfaces(f,*this) {
CGAL_forall_sface_cycles_of(fci,f) {
if ( fci.is_shalfedge() ) {
CGAL_assertion( face(SHalfedge_const_handle(fci)) == f );
++fc_num;
} else if ( fci.is_svertex() ) {
CGAL_assertion( face(SVertex_const_handle(fci)) == f );
++iv_num;
} else if( fci.is_shalfloop() ) {
CGAL_assertion( face(SHalfloop_const_handle(fci)) == f );
++fc_num;
} else CGAL_assertion_msg(0,"damn generic handle.");
}
}
int v_num = number_of_vertices() - iso_vert_num;
int e_num = number_of_edges();
int c_num = number_of_connected_components() - iso_vert_num;
int f_num = number_of_face_cycles() - c_num + 1;
int v_num = number_of_svertices() - iso_vert_num + number_of_shalfloops();
int e_num = number_of_sedges() + number_of_shalfloops();
int c_num = number_of_connected_components() - iso_vert_num
+ number_of_sloops();
int f_num = number_of_sface_cycles() - c_num + 1;
TRACEV(fc_num);TRACEV(iv_num);TRACEV(iso_vert_num);
TRACEV(v_num);TRACEV(e_num);TRACEV(c_num);TRACEV(f_num);
/* this means all face cycles and all isolated vertices are
@ -410,46 +413,45 @@ check_integrity_and_topological_planarity(bool faces) const
/* every isolated vertex increases the component count
one face cycle per component is redundent except one
finally check the Euler formula: */
CGAL_nef_assertion( v_num - e_num + f_num == 1 + c_num );
CGAL_assertion( v_num - e_num + f_num == 1 + c_num );
}
template <typename SM_, typename K_>
typename SM_const_decorator<SM_,K_>::Size_type
SM_const_decorator<SM_,K_>::
number_of_face_cycles() const
template <typename SM_>
typename SM_const_decorator<SM_>::Size_type
SM_const_decorator<SM_>::
number_of_sface_cycles() const
{
unsigned int fc_num=0;
CGAL::Unique_hash_map<Halfedge_const_handle,bool> visited;
// init with bool() == false
Halfedge_const_iterator e;
CGAL_forall_halfedges(e,*this) {
CGAL::Unique_hash_map<SHalfedge_const_handle,bool> visited;
SHalfedge_const_iterator e;
CGAL_forall_shalfedges(e,*this) {
if (visited[e]) continue;
Halfedge_around_face_const_circulator hfc(e), hend(hfc);
SHalfedge_around_sface_const_circulator hfc(e), hend(hfc);
CGAL_For_all(hfc,hend) visited[hfc]=true;
++fc_num;
}
if ( has_loop() ) fc_num += 2;
if ( has_sloop() ) fc_num += 2;
return fc_num;
}
template <typename SM_, typename K_>
typename SM_const_decorator<SM_,K_>::Size_type
SM_const_decorator<SM_,K_>::
template <typename SM_>
typename SM_const_decorator<SM_>::Size_type
SM_const_decorator<SM_>::
number_of_connected_components() const
{
int comp_num=0;
CGAL::Unique_hash_map<Vertex_const_iterator,bool> visited(false);
Vertex_const_iterator v;
CGAL_forall_vertices(v,*this) {
CGAL::Unique_hash_map<SVertex_const_iterator,bool> visited(false);
SVertex_const_iterator v;
CGAL_forall_svertices(v,*this) {
if (visited[v]) continue;
std::list<Vertex_const_iterator> L;
std::list<SVertex_const_iterator> L;
L.push_back(v); visited[v]=true;
/* we keep the invariant that all nodes which have been stacked
are marked visited */
while (!L.empty()) {
Vertex_const_iterator vc = L.front(); L.pop_front();
SVertex_const_iterator vc = L.front(); L.pop_front();
if ( is_isolated(vc) ) continue;
Halfedge_around_vertex_const_circulator
SHalfedge_around_svertex_const_circulator
havc(first_out_edge(vc)), hend(havc);
CGAL_For_all(havc,hend) {
if (!visited[target(havc)]) {

View File

@ -46,29 +46,29 @@ public:
typedef typename Kernel_::Point_2 Point;
typedef typename Kernel_::Segment_2 Segment;
typedef typename Base::Halfedge_handle Halfedge_handle;
typedef typename Base::Vertex_handle Vertex_handle;
typedef typename Base::Face_handle Face_handle;
typedef typename Base::Halfedge_iterator Halfedge_iterator;
typedef typename Base::Vertex_iterator Vertex_iterator;
typedef typename Base::Face_iterator Face_iterator;
typedef typename Base::Halfedge_around_vertex_circulator
Halfedge_around_vertex_circulator;
typedef typename Base::SHalfedge_handle SHalfedge_handle;
typedef typename Base::SVertex_handle SVertex_handle;
typedef typename Base::SFace_handle SFace_handle;
typedef typename Base::SHalfedge_iterator SHalfedge_iterator;
typedef typename Base::SVertex_iterator SVertex_iterator;
typedef typename Base::SFace_iterator SFace_iterator;
typedef typename Base::SHalfedge_around_svertex_circulator
SHalfedge_around_svertex_circulator;
// the types interfacing the sweep:
typedef std::pair<Vertex_iterator,Vertex_iterator> INPUT;
typedef std::pair<SVertex_iterator,SVertex_iterator> INPUT;
typedef Decorator_ OUTPUT;
typedef Kernel_ GEOMETRY;
class lt_edges_in_sweepline : public Decorator_
{ const Point& p;
const Halfedge_handle& e_bottom;
const Halfedge_handle& e_top;
const SHalfedge_handle& e_bottom;
const SHalfedge_handle& e_top;
const Kernel_& K;
public:
lt_edges_in_sweepline(const Point& pi,
const Halfedge_handle& e1, const Halfedge_handle& e2,
const SHalfedge_handle& e1, const SHalfedge_handle& e2,
const Decorator_& D, const Kernel_& k) :
Decorator_(D), p(pi), e_bottom(e1), e_top(e2), K(k) {}
@ -76,13 +76,13 @@ public:
Decorator_(lt), p(lt.p),
e_bottom(lt.e_bottom), e_top(lt.e_top), K(lt.K) {}
Segment seg(const Halfedge_handle& e) const
Segment seg(const SHalfedge_handle& e) const
{ return K.construct_segment(point(source(e)),point(target(e))); }
int orientation(Halfedge_handle e, const Point& p) const
int orientation(SHalfedge_handle e, const Point& p) const
{ return K.orientation(point(source(e)),point(target(e)),p); }
bool operator()(const Halfedge_handle& e1, const Halfedge_handle& e2) const
bool operator()(const SHalfedge_handle& e1, const SHalfedge_handle& e2) const
{ // Precondition:
// [[p]] is identical to the source of either [[e1]] or [[e2]].
if (e1 == e_bottom || e2 == e_top) return true;
@ -91,11 +91,11 @@ public:
int s = 0;
if ( p == point(source(e1)) ) s = orientation(e2,p);
else if ( p == point(source(e2)) ) s = - orientation(e1,p);
else CGAL_nef_assertion_msg(0,"compare error in sweep.");
else CGAL_assertion_msg(0,"compare error in sweep.");
if ( s || source(e1) == target(e1) || source(e2) == target(e2) )
return ( s < 0 );
s = orientation(e2,point(target(e1)));
if (s==0) CGAL_nef_assertion_msg(0,"parallel edges not allowed.");
if (s==0) CGAL_assertion_msg(0,"parallel edges not allowed.");
return ( s < 0 );
}
@ -107,28 +107,28 @@ public:
public:
lt_pnts_xy(const Decorator_& D, const Kernel_& k) : Decorator_(D), K(k) {}
lt_pnts_xy(const lt_pnts_xy& lt) : Decorator_(lt), K(lt.K) {}
int operator()(const Vertex_handle& v1, const Vertex_handle& v2) const
int operator()(const SVertex_handle& v1, const SVertex_handle& v2) const
{ return K.compare_xy(point(v1),point(v2)) < 0; }
}; // lt_pnts_xy
typedef std::map<Halfedge_handle, Halfedge_handle, lt_edges_in_sweepline>
typedef std::map<SHalfedge_handle, SHalfedge_handle, lt_edges_in_sweepline>
Sweep_status_structure;
typedef typename Sweep_status_structure::iterator ss_iterator;
typedef typename Sweep_status_structure::value_type ss_pair;
typedef std::set<Vertex_iterator,lt_pnts_xy> Event_Q;
typedef std::set<SVertex_iterator,lt_pnts_xy> Event_Q;
typedef typename Event_Q::const_iterator event_iterator;
const GEOMETRY& K;
Event_Q event_Q;
event_iterator event_it;
Vertex_handle event;
SVertex_handle event;
Point p_sweep;
Sweep_status_structure SL;
CGAL::Unique_hash_map<Halfedge_handle,ss_iterator> SLItem;
Halfedge_handle e_low,e_high; // framing edges !
Halfedge_handle e_search;
Vertex_iterator v_first, v_beyond;
CGAL::Unique_hash_map<SHalfedge_handle,ss_iterator> SLItem;
SHalfedge_handle e_low,e_high; // framing edges !
SHalfedge_handle e_search;
SVertex_iterator v_first, v_beyond;
SM_constrained_triang_traits(const INPUT& in, OUTPUT& out,
const GEOMETRY& k)
@ -137,47 +137,47 @@ public:
SLItem(SL.end()), v_first(in.first), v_beyond(in.second)
{ TRACEN("Constrained Triangulation Sweep"); }
/* |treat_new_edge| is used to forward information that exists
/* |treat_new_sedge| is used to forward information that exists
at input edges of the triangulation as such it spreads input
information to the newly created edges of the triangulation;
the used operation incident_mark refers to the base class of
|*this| */
void treat_new_edge(Halfedge_handle e)
void treat_new_edge(SHalfedge_handle e)
{ assoc_info(e);
mark(e) = incident_mark(e) = incident_mark(twin(e)) =
incident_mark(next(e));
TRACEN(" treat_new_edge "<<PH(e));
}
Halfedge_handle new_bi_edge(Vertex_handle v1, Vertex_handle v2)
SHalfedge_handle new_bi_edge(SVertex_handle v1, SVertex_handle v2)
{ // appended at v1 and v2 adj list
Halfedge_handle e = Base::new_edge_pair(v1,v2);
SHalfedge_handle e = Base::new_shalfedge_pair(v1,v2);
treat_new_edge(e);
return e;
}
Halfedge_handle new_bi_edge(Halfedge_handle e_bf, Halfedge_handle e_af)
SHalfedge_handle new_bi_edge(SHalfedge_handle e_bf, SHalfedge_handle e_af)
{ // ccw before e_bf and after e_af
Halfedge_handle e =
Base::new_edge_pair(e_bf,e_af,Base::BEFORE, Base::AFTER);
SHalfedge_handle e =
Base::new_shalfedge_pair(e_bf,e_af,Base::BEFORE, Base::AFTER);
treat_new_edge(e);
return e;
}
Halfedge_handle new_bi_edge(Vertex_handle v, Halfedge_handle e_bf)
SHalfedge_handle new_bi_edge(SVertex_handle v, SHalfedge_handle e_bf)
{ // appended at v's adj list and before e_bf
Halfedge_handle e = Base::new_edge_pair(v,e_bf,Base::BEFORE);
SHalfedge_handle e = Base::new_shalfedge_pair(v,e_bf,Base::BEFORE);
treat_new_edge(e);
return e;
}
Segment segment(Halfedge_handle e) const
Segment segment(SHalfedge_handle e) const
{ return K.construct_segment(point(source(e)),point(target(e))); }
bool is_forward(Halfedge_handle e) const
bool is_forward(SHalfedge_handle e) const
{ return K.compare_xy(point(source(e)),point(target(e))) < 0; }
bool edge_is_visible_from(Vertex_handle v, Halfedge_handle e)
bool edge_is_visible_from(SVertex_handle v, SHalfedge_handle e)
{
Point p = point(v);
Point p1 = point(source(e));
@ -185,54 +185,54 @@ public:
return ( K.orientation(p1,p2,p) > 0 ); // left_turn
}
void triangulate_up(Halfedge_handle& e_apex)
void triangulate_up(SHalfedge_handle& e_apex)
{
TRACEN("triangulate_up "<<segment(e_apex));
Vertex_handle v_apex = source(e_apex);
SVertex_handle v_apex = source(e_apex);
while (true) {
Halfedge_handle e_vis = previous(twin(e_apex));
SHalfedge_handle e_vis = previous(twin(e_apex));
bool in_sweep_line = (SLItem[e_vis] != SL.end());
bool not_visible = !edge_is_visible_from(v_apex,e_vis);
TRACEN(" checking "<<in_sweep_line<<not_visible<<" "<<segment(e_vis));
if ( in_sweep_line || not_visible) {
TRACEN(" STOP"); return;
}
Halfedge_handle e_back = new_bi_edge(e_apex,e_vis);
SHalfedge_handle e_back = new_bi_edge(e_apex,e_vis);
e_apex = e_back;
TRACEN(" produced " << segment(e_apex));
}
}
void triangulate_down(Halfedge_handle& e_apex)
void triangulate_down(SHalfedge_handle& e_apex)
{
TRACEN("triangulate_down "<<segment(e_apex));
Vertex_handle v_apex = source(e_apex);
SVertex_handle v_apex = source(e_apex);
while (true) {
Halfedge_handle e_vis = next(e_apex);
SHalfedge_handle e_vis = next(e_apex);
bool in_sweep_line = (SLItem[e_vis] != SL.end());
bool not_visible = !edge_is_visible_from(v_apex,e_vis);
TRACEN(" checking "<<in_sweep_line<<not_visible<<" "<<segment(e_vis));
if ( in_sweep_line || not_visible) {
TRACEN(" STOP"); return;
}
Halfedge_handle e_vis_rev = twin(e_vis);
Halfedge_handle e_forw = new_bi_edge(e_vis_rev,e_apex);
SHalfedge_handle e_vis_rev = twin(e_vis);
SHalfedge_handle e_forw = new_bi_edge(e_vis_rev,e_apex);
e_apex = twin(e_forw);
TRACEN(" produced " << segment(e_apex));
}
}
void triangulate_between(Halfedge_handle e_upper, Halfedge_handle e_lower)
void triangulate_between(SHalfedge_handle e_upper, SHalfedge_handle e_lower)
{
// we triangulate the interior of the whole chain between
// target(e_upper) and target(e_lower)
assert(source(e_upper)==source(e_lower));
TRACE("triangulate_between\n "<<segment(e_upper));
TRACEN("\n "<<segment(e_lower));
Halfedge_handle e_end = twin(e_lower);
SHalfedge_handle e_end = twin(e_lower);
while (true) {
Halfedge_handle e_vis = next(e_upper);
Halfedge_handle en_vis = next(e_vis);
SHalfedge_handle e_vis = next(e_upper);
SHalfedge_handle en_vis = next(e_vis);
TRACEN(" working on base e_vis " << segment(e_vis));
TRACEN(" next is " << segment(en_vis));
if (en_vis == e_end) return;
@ -244,7 +244,7 @@ public:
void process_event()
{
TRACEN("\nPROCESS_EVENT " << p_sweep);
Halfedge_handle e, ep, eb_low, eb_high, e_end;
SHalfedge_handle e, ep, eb_low, eb_high, e_end;
if ( !is_isolated(event) ) {
e = last_out_edge(event);
ep = first_out_edge(event);
@ -257,7 +257,7 @@ public:
eb_high = e_end = ep;
eb_low = e;
TRACEN("determining handle in SL");
if ( e != Halfedge_handle() ) {
if ( e != SHalfedge_handle() ) {
point(target(e_search)) = p_sweep; // degenerate loop edge
sit_pred = SLItem[e];
if ( sit_pred != SL.end()) sit = --sit_pred;
@ -268,7 +268,7 @@ public:
}
bool ending_edges(0), starting_edges(0);
while ( e != Halfedge_handle() ) { // walk adjacency list clockwise
while ( e != SHalfedge_handle() ) { // walk adjacency list clockwise
if ( SLItem[e] != SL.end() )
{
TRACEN("ending " << segment(e));
@ -292,8 +292,8 @@ public:
}
if (!ending_edges)
{
Halfedge_handle e_vis = sit_pred->second;
Halfedge_handle e_vis_n = cyclic_adj_succ(e_vis);
SHalfedge_handle e_vis = sit_pred->second;
SHalfedge_handle e_vis_n = cyclic_adj_succ(e_vis);
eb_low = eb_high = new_bi_edge(event,e_vis_n);
TRACEN(" producing link "<<segment(eb_low)<<
"\n before "<<segment(e_vis_n));
@ -317,7 +317,7 @@ public:
void procede_to_next_event()
{ ++event_it; }
void link_bi_edge_to(Halfedge_handle e, ss_iterator sit) {
void link_bi_edge_to(SHalfedge_handle e, ss_iterator sit) {
SLItem[e] = SLItem[twin(e)] = sit;
}
@ -333,7 +333,7 @@ public:
event = *event_it;
p_sweep = point(event);
if ( !is_isolated(event) ) {
Halfedge_around_vertex_circulator
SHalfedge_around_svertex_circulator
e(first_out_edge(event)), eend(e);
CGAL_For_all(e,eend) {
TRACEN("init with "<<PH(e));
@ -343,12 +343,12 @@ public:
}
Vertex_handle v_tmp = new_vertex(Point());
e_high = Base::new_edge_pair(event,v_tmp);
e_low = Base::new_edge_pair(event,v_tmp);
SVertex_handle v_tmp = new_svertex(Point());
e_high = Base::new_shalfedge_pair(event,v_tmp);
e_low = Base::new_shalfedge_pair(event,v_tmp);
// this are two symbolic edges just accessed as sentinels
// they carry no geometric information
e_search = Base::new_edge_pair(v_tmp,v_tmp);
e_search = Base::new_shalfedge_pair(v_tmp,v_tmp);
// this is just a loop used for searches in SL
ss_iterator sit_high = SL.insert(ss_pair(e_high,e_high)).first;
@ -367,7 +367,7 @@ public:
void complete_structures()
{
if (e_low != Halfedge_handle()) {
if (e_low != SHalfedge_handle()) {
delete_vertex(target(e_search));
} // removing sentinels and e_search
}

File diff suppressed because it is too large Load Diff

View File

@ -3,6 +3,7 @@
#include <CGAL/Nef_S2/SM_decorator.h>
#include <CGAL/Nef_2/Object_index.h>
#include <CGAL/Nef_S2/SM_decorator_traits.h>
#include <vector>
#include <iostream>
@ -26,44 +27,48 @@ class SM_io_parser : public Decorator_
typedef typename Decorator_::Sphere_circle Sphere_circle;
typedef typename Decorator_::Mark Mark;
typedef typename Decorator_::Vertex_iterator Vertex_iterator;
typedef typename Decorator_::Halfedge_iterator Halfedge_iterator;
typedef typename Decorator_::Face_iterator Face_iterator;
typedef typename Decorator_::Vertex_handle Vertex_handle;
typedef typename Decorator_::Halfedge_handle Halfedge_handle;
typedef typename Decorator_::Face_handle Face_handle;
typedef typename Decorator_::Halfloop_handle Halfloop_handle;
typedef typename Decorator_::Face_cycle_iterator Face_cycle_iterator;
typedef typename Decorator_::Decorator_traits Decorator_traits;
typedef typename Decorator_traits::SVertex_iterator SVertex_iterator;
typedef typename Decorator_traits::SHalfedge_iterator SHalfedge_iterator;
typedef typename Decorator_traits::SFace_iterator SFace_iterator;
typedef typename Decorator_traits::SVertex_handle SVertex_handle;
typedef typename Decorator_traits::SHalfedge_handle SHalfedge_handle;
typedef typename Decorator_traits::SFace_handle SFace_handle;
typedef typename Decorator_traits::SHalfloop_handle SHalfloop_handle;
typedef typename Decorator_traits::SFace_cycle_iterator SFace_cycle_iterator;
typedef typename Decorator_traits::SHalfedge_around_svertex_circulator
SHalfedge_around_svertex_circulator;
std::istream& in; std::ostream& out;
bool verbose;
// a reference to the IO object
CGAL::Object_index<Vertex_handle> VI;
CGAL::Object_index<Halfedge_handle> EI;
CGAL::Object_index<Face_handle> FI;
std::vector<Vertex_handle> Vertex_of;
std::vector<Halfedge_handle> Edge_of;
std::vector<Face_handle> Face_of;
Halfloop_handle Loop_of[2];
CGAL::Object_index<SVertex_handle> VI;
CGAL::Object_index<SHalfedge_handle> EI;
CGAL::Object_index<SFace_handle> FI;
std::vector<SVertex_handle> SVertex_of;
std::vector<SHalfedge_handle> Edge_of;
std::vector<SFace_handle> SFace_of;
SHalfloop_handle Loop_of[2];
// object mapping for input
int vn,en,ln,fn,i;
// the number of objects
bool check_sep(char* sep);
void print_vertex(Vertex_handle) const;
void print_edge(Halfedge_handle) const;
void print_loop(Halfloop_handle) const;
void print_face(Face_handle) const;
void print_init_points() const;
void print_vertex(SVertex_handle) const;
void print_edge(SHalfedge_handle) const;
void print_loop(SHalfloop_handle) const;
void print_face(SFace_handle) const;
bool read_vertex(Vertex_handle);
bool read_edge(Halfedge_handle);
bool read_loop(Halfloop_handle);
bool read_face(Face_handle);
bool read_vertex(SVertex_handle);
bool read_edge(SHalfedge_handle);
bool read_loop(SHalfloop_handle);
bool read_face(SFace_handle);
bool read_init_points() const;
void debug_vertex(Vertex_handle) const;
void debug_edge(Halfedge_handle) const;
void debug_loop(Halfloop_handle) const;
void debug_vertex(SVertex_handle) const;
void debug_edge(SHalfedge_handle) const;
void debug_loop(SHalfloop_handle) const;
public:
/*{\Mcreation 3}*/
@ -83,15 +88,15 @@ void read();
void debug() const;
void print_faces() const;
std::string index(Vertex_handle v) const
std::string index(SVertex_handle v) const
{ return VI(v,verbose); }
std::string index(Halfedge_handle e) const
std::string index(SHalfedge_handle e) const
{ return EI(e,verbose); }
std::string index(Halfloop_handle l) const
{ if (verbose) return (l==halfloop()? "l0" : "l1");
else return (l==halfloop()? "0" : "1");
std::string index(SHalfloop_handle l) const
{ if (verbose) return (l==shalfloop()? "l0" : "l1");
else return (l==shalfloop()? "0" : "1");
}
std::string index(Face_handle f) const
std::string index(SFace_handle f) const
{ return FI(f,verbose); }
static void dump(const Decorator_& D, std::ostream& os = cerr);
@ -111,13 +116,13 @@ template <typename Decorator_>
SM_io_parser<Decorator_>::
SM_io_parser(std::ostream& iout, const Decorator_& D)
: Base(D), in(std::cin), out(iout),
VI(vertices_begin(),vertices_end(),'v'),
EI(halfedges_begin(),halfedges_end(),'e'),
FI(faces_begin(),faces_end(),'f'),
vn(number_of_vertices()),
en(number_of_halfedges()),
ln(number_of_halfloops()),
fn(number_of_faces())
VI(svertices_begin(),svertices_end(),'v'),
EI(shalfedges_begin(),shalfedges_end(),'e'),
FI(sfaces_begin(),sfaces_end(),'f'),
vn(number_of_svertices()),
en(number_of_shalfedges()),
ln(number_of_shalfloops()),
fn(number_of_sfaces())
{ verbose = (out.iword(CGAL::IO::mode) != CGAL::IO::ASCII &&
out.iword(CGAL::IO::mode) != CGAL::IO::BINARY);
}
@ -144,7 +149,7 @@ bool SM_io_parser<Decorator_>::check_sep(char* sep)
}
template <typename Decorator_>
void SM_io_parser<Decorator_>::print_vertex(Vertex_handle v) const
void SM_io_parser<Decorator_>::print_vertex(SVertex_handle v) const
{
// syntax: index { isolated incident_object, mark, point }
out << index(v) << " { ";
@ -154,7 +159,7 @@ void SM_io_parser<Decorator_>::print_vertex(Vertex_handle v) const
}
template <typename Decorator_>
bool SM_io_parser<Decorator_>::read_vertex(Vertex_handle v)
bool SM_io_parser<Decorator_>::read_vertex(SVertex_handle v)
{
// precondition: nodes exist
// syntax: index { isolated incident_object, mark, point}
@ -169,14 +174,14 @@ bool SM_io_parser<Decorator_>::read_vertex(Vertex_handle v)
!(in >> p) ||
!check_sep("}") ) return false;
if (iso) set_face(v,Face_of[f]);
if (iso) set_face(v,SFace_of[f]);
else set_first_out_edge(v,Edge_of[f]);
mark(v) = m; point(v) = p;
return true;
}
template <typename Decorator_>
void SM_io_parser<Decorator_>::print_edge(Halfedge_handle e) const
void SM_io_parser<Decorator_>::print_edge(SHalfedge_handle e) const
{ // syntax: index { twin, prev, next, source, face, mark, circle }
out << index(e) << " { "
<< index(twin(e)) << ", "
@ -186,7 +191,7 @@ void SM_io_parser<Decorator_>::print_edge(Halfedge_handle e) const
}
template <typename Decorator_>
bool SM_io_parser<Decorator_>::read_edge(Halfedge_handle e)
bool SM_io_parser<Decorator_>::read_edge(SHalfedge_handle e)
{ // syntax: index { twin, prev, next, source, face, mark, circle }
int n, eo, epr, ene, v, f; bool m; Sphere_circle k;
if ( !(in >> n) ||
@ -199,24 +204,24 @@ bool SM_io_parser<Decorator_>::read_edge(Halfedge_handle e)
!(in >> m) || !check_sep(",") ||
!(in >> k) || !check_sep("}") )
return false;
CGAL_nef_assertion_msg
CGAL_assertion_msg
(eo >= 0 && eo < en && epr >= 0 && epr < en && ene >= 0 && ene < en &&
v >= 0 && v < vn && f >= 0 && f < fn ,
"wrong index in read_edge");
// precond: features exist!
CGAL_nef_assertion(EI[twin(e)]);
CGAL_assertion(EI[twin(e)]);
set_prev(e,Edge_of[epr]);
set_next(e,Edge_of[ene]);
set_source(e,Vertex_of[v]);
set_face(e,Face_of[f]);
set_source(e,SVertex_of[v]);
set_face(e,SFace_of[f]);
mark(e) = m;
circle(e) = k;
return true;
}
template <typename Decorator_>
void SM_io_parser<Decorator_>::print_loop(Halfloop_handle l) const
void SM_io_parser<Decorator_>::print_loop(SHalfloop_handle l) const
{ // syntax: index { twin, face, mark, circle }
out << index(l) << " { "
<< index(twin(l)) << ", "
@ -225,7 +230,7 @@ void SM_io_parser<Decorator_>::print_loop(Halfloop_handle l) const
}
template <typename Decorator_>
bool SM_io_parser<Decorator_>::read_loop(Halfloop_handle l)
bool SM_io_parser<Decorator_>::read_loop(SHalfloop_handle l)
{ // syntax: index { twin, face, mark, circle }
int n, lo, f; bool m; Sphere_circle k;
if ( !(in >> n) ||
@ -235,10 +240,10 @@ bool SM_io_parser<Decorator_>::read_loop(Halfloop_handle l)
!(in >> m) || !check_sep(",") ||
!(in >> k) || !check_sep("}") )
return false;
CGAL_nef_assertion_msg(
CGAL_assertion_msg(
(lo >= 0 && lo < 2 && f >= 0 && f < fn),"wrong index in read_edge");
set_face(l,Face_of[f]);
set_face(l,SFace_of[f]);
mark(l) = m;
circle(l) = k;
return true;
@ -246,49 +251,40 @@ bool SM_io_parser<Decorator_>::read_loop(Halfloop_handle l)
template <typename Decorator_>
void SM_io_parser<Decorator_>::print_face(Face_handle f) const
void SM_io_parser<Decorator_>::print_face(SFace_handle f) const
{ // syntax: index { fclist, ivlist, loop, mark }
out << index(f) << " { ";
Face_cycle_iterator it;
CGAL_forall_face_cycles_of(it,f)
if ( it.is_halfedge() ) out << index(Halfedge_handle(it)) << ' ';
SFace_cycle_iterator it;
CGAL_forall_sface_cycles_of(it,f)
if ( it.is_shalfedge() ) out << index(SHalfedge_handle(it)) << ' ';
out << ", ";
CGAL_forall_face_cycles_of(it,f)
if ( it.is_vertex() ) out << index(Vertex_handle(it)) << ' ';
CGAL_forall_sface_cycles_of(it,f)
if ( it.is_svertex() ) out << index(SVertex_handle(it)) << ' ';
out << ", ";
CGAL_forall_face_cycles_of(it,f)
if ( it.is_halfloop() ) out << index(Halfloop_handle(it));
CGAL_forall_sface_cycles_of(it,f)
if ( it.is_shalfloop() ) out << index(SHalfloop_handle(it));
out << ", " << mark(f) << " }\n";
}
template <typename Decorator_>
void SM_io_parser<Decorator_>::print_init_points() const
{
out << mark_of_halfsphere(-1) << " "
<< mark_of_halfsphere(+1) << "\n";
}
template <typename Decorator_>
bool SM_io_parser<Decorator_>::read_face(Face_handle f)
bool SM_io_parser<Decorator_>::read_face(SFace_handle f)
{ // syntax: index { fclist, ivlist, loop, mark }
int n, ei, vi, li; Mark m;
if ( !(in >> n) || !check_sep("{") ) return false;
while (in >> ei) {
CGAL_nef_assertion_msg(ei >= 0 && ei < en,
CGAL_assertion_msg(ei >= 0 && ei < en,
"wrong index in face cycle list.");
store_boundary_object(Edge_of[ei],f);
} in.clear();
if (!check_sep(",")) { return false; }
while (in >> vi) {
CGAL_nef_assertion_msg(vi >= 0 && vi < vn,
CGAL_assertion_msg(vi >= 0 && vi < vn,
"wrong index in iso vertex list.");
store_boundary_object(Vertex_of[vi],f);
store_boundary_object(SVertex_of[vi],f);
} in.clear();
if (!check_sep(",")) { return false; }
while (in >> li) {
CGAL_nef_assertion_msg(li >= 0 && li < 2,
CGAL_assertion_msg(li >= 0 && li < 2,
"wrong index in iso vertex list.");
store_boundary_object(Loop_of[li],f);
} in.clear();
@ -319,24 +315,21 @@ void SM_io_parser<Decorator_>::print() const
out << "faces " << fn << std::endl;
if (verbose)
out << "/* index { isolated ? face : edge, mark, point } */" << std::endl;
Vertex_iterator vit;
CGAL_forall_vertices(vit,*this) print_vertex(vit);
SVertex_iterator vit;
CGAL_forall_svertices(vit,*this) print_vertex(vit);
if (verbose)
out << "/* index { twin, prev, next, source, face, mark, circle } */"
<< std::endl;
Halfedge_iterator eit;
CGAL_forall_halfedges(eit,*this) print_edge(eit);
SHalfedge_iterator eit;
CGAL_forall_shalfedges(eit,*this) print_edge(eit);
if (verbose)
out << "/* index { twin, face, mark, circle } */" << std::endl;
if ( has_loop() )
{ print_loop(halfloop()); print_loop(twin(halfloop())); }
if ( has_sloop() )
{ print_loop(shalfloop()); print_loop(twin(shalfloop())); }
if (verbose)
out << "/* index { fclist, ivlist, loop, mark } */" << std::endl;
Face_iterator fit;
CGAL_forall_faces(fit,*this) print_face(fit);
if (verbose)
out << "/* mark at y-/y+ */" << std::endl;
print_init_points();
SFace_iterator fit;
CGAL_forall_sfaces(fit,*this) print_face(fit);
out.flush();
if (verbose) debug();
}
@ -345,44 +338,44 @@ template <typename Decorator_>
void SM_io_parser<Decorator_>::read()
{
if ( !check_sep("Plane_map_2") )
CGAL_nef_assertion_msg(0,"SM_io_parser::read: no embedded_PM header.");
CGAL_assertion_msg(0,"SM_io_parser::read: no embedded_PM header.");
if ( !(check_sep("vertices") && (in >> vn)) )
CGAL_nef_assertion_msg(0,"SM_io_parser::read: wrong vertex line.");
CGAL_assertion_msg(0,"SM_io_parser::read: wrong vertex line.");
if ( !(check_sep("edges") && (in >> en) && (en%2==0)) )
CGAL_nef_assertion_msg(0,"SM_io_parser::read: wrong edge line.");
CGAL_assertion_msg(0,"SM_io_parser::read: wrong edge line.");
if ( !(check_sep("loops") && (in >> ln)) )
CGAL_nef_assertion_msg(0,"SM_io_parser::read: wrong loop line.");
CGAL_assertion_msg(0,"SM_io_parser::read: wrong loop line.");
if ( !(check_sep("faces") && (in >> fn)) )
CGAL_nef_assertion_msg(0,"SM_io_parser::read: wrong face line.");
CGAL_assertion_msg(0,"SM_io_parser::read: wrong face line.");
Vertex_of.reserve(vn);
SVertex_of.reserve(vn);
Edge_of.reserve(en);
Face_of.reserve(fn);
for(i=0; i<vn; i++) Vertex_of[i] = new_vertex();
SFace_of.reserve(fn);
for(i=0; i<vn; i++) SVertex_of[i] = new_vertex();
for(i=0; i<en; i++)
if (i%2==0) Edge_of[i] = new_edge_pair_without_vertices();
else Edge_of[i] = twin(Edge_of[i-1]);
for(i=0; i<fn; i++) Face_of[i] = new_face();
for(i=0; i<fn; i++) SFace_of[i] = new_face();
if ( ln == 2 )
{ Loop_of[0] = new_loop(); Loop_of[1] = twin(loop()); }
for(i=0; i<vn; i++) {
if (!read_vertex(Vertex_of[i]))
CGAL_nef_assertion_msg(0,"SM_io_parser::read: error in node line");
if (!read_vertex(SVertex_of[i]))
CGAL_assertion_msg(0,"SM_io_parser::read: error in node line");
}
for(i=0; i<en; i++) {
if (!read_edge(Edge_of[i]))
CGAL_nef_assertion_msg(0,"SM_io_parser::read: error in edge line");
CGAL_assertion_msg(0,"SM_io_parser::read: error in edge line");
}
if ( ln == 2 ) {
read_loop(Loop_of[0]); read_loop(Loop_of[1]);
}
for(i=0; i<fn; i++) {
if (!read_face(Face_of[i]))
CGAL_nef_assertion_msg(0,"SM_io_parser::read: error in face line");
if (!read_face(SFace_of[i]))
CGAL_assertion_msg(0,"SM_io_parser::read: error in face line");
}
if (!read_init_points())
CGAL_nef_assertion_msg(0,"SM_io_parser::read: error in init point line");
CGAL_assertion_msg(0,"SM_io_parser::read: error in init point line");
}
//-----------------------------------------------------------------------------
@ -392,13 +385,13 @@ void SM_io_parser<Decorator_>::read()
//-----------------------------------------------------------------------------
template <typename Decorator_>
void SM_io_parser<Decorator_>::debug_vertex(Vertex_handle v) const
void SM_io_parser<Decorator_>::debug_vertex(SVertex_handle v) const
{
out << index(v) << "[" << mark(v) << "," << point(v) << "]" << std::endl;
}
template <typename Decorator_>
void SM_io_parser<Decorator_>::debug_edge(Halfedge_handle e) const
void SM_io_parser<Decorator_>::debug_edge(SHalfedge_handle e) const
{
out << index(e)
<< "(" << index(source(e)) << "," << index(target(e)) << ") "
@ -407,7 +400,7 @@ void SM_io_parser<Decorator_>::debug_edge(Halfedge_handle e) const
}
template <typename Decorator_>
void SM_io_parser<Decorator_>::debug_loop(Halfloop_handle l) const
void SM_io_parser<Decorator_>::debug_loop(SHalfloop_handle l) const
{
out << index(l) << " "
<< index(twin(l)) << " " << index(face(l))
@ -419,19 +412,18 @@ template <typename Decorator_>
void SM_io_parser<Decorator_>::debug() const
{
out << "\nDEBUG Plane_map\n";
out << "Vertices: " << number_of_vertices() << "\n";
out << "Halfedges: " << number_of_halfedges() << "\n";
out << "Loop: " << number_of_halfloops() << "\n";
Vertex_iterator vit;
CGAL_forall_vertices(vit,*this) {
out << "Vertices: " << number_of_svertices() << "\n";
out << "SHalfedges: " << number_of_shalfedges() << "\n";
out << "Loop: " << number_of_shalfloops() << "\n";
SVertex_iterator vit;
CGAL_forall_svertices(vit,*this) {
if ( is_isolated(vit) ) continue;
typename Base::Halfedge_around_vertex_circulator
hcirc = out_edges(vit), hend = hcirc;
SHalfedge_around_svertex_circulator hcirc(out_edges(vit)), hend(hcirc);
debug_vertex(vit);
CGAL_For_all(hcirc,hend) { out << " "; debug_edge(hcirc); }
}
if ( has_loop() )
{ debug_loop(halfloop()); debug_loop(twin(halfloop())); }
if ( has_sloop() )
{ debug_loop(shalfloop()); debug_loop(twin(shalfloop())); }
out << std::endl;
}
@ -439,20 +431,20 @@ template <typename Decorator_>
void SM_io_parser<Decorator_>::print_faces() const
{
out << "\nFACES\n";
out << "Vertices: " << number_of_vertices() << "\n";
out << "Halfedges: " << number_of_halfedges() << "\n";
out << "Loop: " << number_of_halfloops() << "\n";
Halfedge_iterator e;
Unique_hash_map<Halfedge_iterator,bool> Done(false);
CGAL_forall_halfedges(e,*this) {
out << "Vertices: " << number_of_svertices() << "\n";
out << "SHalfedges: " << number_of_shalfedges() << "\n";
out << "Loop: " << number_of_shalfloops() << "\n";
SHalfedge_iterator e;
Unique_hash_map<SHalfedge_iterator,bool> Done(false);
CGAL_forall_shalfedges(e,*this) {
if ( Done[e] ) continue;
typename Base::Halfedge_around_face_circulator c(e), ce = c;
typename Base::SHalfedge_around_sface_circulator c(e), ce = c;
out << "face cycle\n";
CGAL_For_all(c,ce)
{ Done[c]=true; out << " "; debug_vertex(source(c)); }
}
if ( has_loop() )
{ debug_loop(halfloop()); debug_loop(twin(halfloop())); }
if ( has_sloop() )
{ debug_loop(shalfloop()); debug_loop(twin(shalfloop())); }
out << std::endl;
}

View File

@ -10,11 +10,11 @@
CGAL_BEGIN_NAMESPACE
template <typename K, typename M> class SM_items;
template <typename K> class Sphere_map;
template <typename SM, typename K> class SM_const_decorator;
template <typename SM, typename K> class SM_decorator;
template <typename EH> struct move_edge_around_vertex;
template <typename EH> struct move_edge_around_face;
template <typename K, typename I> class Sphere_map;
template <typename SM> class SM_const_decorator;
template <typename SM> class SM_decorator;
template <typename EH> struct move_edge_around_svertex;
template <typename EH> struct move_edge_around_sface;
template <typename Kernel_, typename Mark_>
struct SM_items {
@ -28,47 +28,47 @@ public:
typedef void* GenPtr;
template <typename Refs>
class Vertex : public CGAL::In_place_list_base< Vertex<Refs> >
class SVertex : public CGAL::In_place_list_base< SVertex<Refs> >
{
typedef typename Refs::Items Items;
friend class Sphere_map<Kernel_>;
friend class SM_const_decorator<Refs,Kernel_>;
friend class SM_decorator<Refs,Kernel_>;
friend class Sphere_map<Kernel_, Items>;
friend class SM_const_decorator<Refs>;
friend class SM_decorator<Refs>;
typedef typename Refs::Vertex_handle Vertex_handle;
typedef typename Refs::Halfedge_handle Halfedge_handle;
typedef typename Refs::Face_handle Face_handle;
typedef typename Refs::SVertex_handle SVertex_handle;
typedef typename Refs::SHalfedge_handle SHalfedge_handle;
typedef typename Refs::SFace_handle SFace_handle;
Sphere_point point_;
Mark mark_;
Halfedge_handle edge_;
Face_handle face_;
SHalfedge_handle out_sedge_;
SFace_handle incident_sface_;
GenPtr info_;
// temporary information:
public:
Vertex() :
point_(), mark_(), edge_(), face_(), info_() {}
Vertex(const Mark& m) :
point_(), mark_(m), edge_(), face_(), info_() {}
Vertex(const Sphere_point& p) :
point_(p), mark_(), edge_(), face_(), info_() {}
SVertex() :
point_(), mark_(), out_sedge_(), incident_sface_(), info_() {}
SVertex(const Mark& m) :
point_(), mark_(m), out_sedge_(), incident_sface_(), info_() {}
SVertex(const Sphere_point& p) :
point_(p), mark_(), out_sedge_(), incident_sface_(), info_() {}
~Vertex() {}
~SVertex() {}
Vertex(const Vertex<Refs>& v)
SVertex(const SVertex<Refs>& v)
{ point_ = v.point_;
mark_ = v.mark_;
edge_ = v.edge_;
face_ = v.face_;
out_sedge_ = v.out_sedge_;
incident_sface_ = v.incident_sface_;
info_ = 0;
}
Vertex<Refs>& operator=(const Vertex<Refs>& v)
SVertex<Refs>& operator=(const SVertex<Refs>& v)
{ point_ = v.point_;
mark_ = v.mark_;
edge_ = v.edge_;
face_ = v.face_;
out_sedge_ = v.out_sedge_;
incident_sface_ = v.incident_sface_;
info_ = 0;
return *this;
}
@ -80,64 +80,66 @@ public:
std::string res(os.str()); os.freeze(0); return res;
}
}; // Vertex
}; // SVertex
template <typename Refs>
class Halfedge : public CGAL::In_place_list_base< Halfedge<Refs> >
class SHalfedge : public CGAL::In_place_list_base< SHalfedge<Refs> >
{
typedef typename Refs::Items Items;
typedef typename Refs::Vertex_handle Vertex_handle;
typedef typename Refs::Halfedge_handle Halfedge_handle;
typedef typename Refs::Halfedge_const_handle Halfedge_const_handle;
typedef typename Refs::Face_handle Face_handle;
typedef typename Refs::SVertex_handle SVertex_handle;
typedef typename Refs::SHalfedge_handle SHalfedge_handle;
typedef typename Refs::SHalfedge_const_handle SHalfedge_const_handle;
typedef typename Refs::SFace_handle SFace_handle;
friend class Sphere_map<Kernel_>;
friend class SM_const_decorator<Refs,Kernel_>;
friend class SM_decorator<Refs,Kernel_>;
friend class move_edge_around_vertex<Halfedge_handle>;
friend class move_edge_around_face<Halfedge_handle>;
friend class move_edge_around_vertex<Halfedge_const_handle>;
friend class move_edge_around_face<Halfedge_const_handle>;
friend class Sphere_map<Kernel_, Items>;
friend class SM_const_decorator<Refs>;
friend class SM_decorator<Refs>;
friend class move_edge_around_svertex<SHalfedge_handle>;
friend class move_edge_around_sface<SHalfedge_handle>;
friend class move_edge_around_svertex<SHalfedge_const_handle>;
friend class move_edge_around_sface<SHalfedge_const_handle>;
// Role within local graph:
Sphere_circle circle_;
Mark mark_;
Halfedge_handle twin_, prev_, next_;
Vertex_handle source_;
Face_handle face_;
SHalfedge_handle twin_, sprev_, snext_;
SVertex_handle source_;
SFace_handle incident_sface_;
GenPtr info_;
public:
Halfedge() : circle_(), mark_(), twin_(), prev_(), next_(),
source_(), face_(), info_() {}
SHalfedge() : circle_(), mark_(), twin_(), sprev_(), snext_(),
source_(), incident_sface_(), info_() {}
~Halfedge() {}
~SHalfedge() {}
Halfedge(const Halfedge<Refs>& e)
SHalfedge(const SHalfedge<Refs>& e)
{
circle_ = e.circle_;
mark_ = e.mark_;
twin_ = e.twin_;
prev_ = e.prev_;
next_ = e.next_;
sprev_ = e.sprev_;
snext_ = e.snext_;
source_ = e.source_;
face_ = e.face_;
incident_sface_ = e.incident_sface_;
info_ = 0;
}
Halfedge<Refs>& operator=(const Halfedge<Refs>& e)
SHalfedge<Refs>& operator=(const SHalfedge<Refs>& e)
{
circle_ = e.circle_;
mark_ = e.mark_;
twin_ = e.twin_;
prev_ = e.prev_;
next_ = e.next_;
sprev_ = e.sprev_;
snext_ = e.snext_;
source_ = e.source_;
face_ = e.face_;
incident_sface_ = e.incident_sface_;
info_ = 0;
return *this;
}
bool is_twin() const { return (&*twin_ < this); }
std::string debug() const
{ std::ostrstream os; set_pretty_mode(os);
os <<"e["<<source_->debug()<<", "
@ -145,102 +147,105 @@ public:
std::string res(os.str()); os.freeze(0); return res;
}
}; // Halfedge
}; // SHalfedge
template <typename Refs>
class Halfloop : public CGAL::In_place_list_base< Halfloop<Refs> >
class SHalfloop : public CGAL::In_place_list_base< SHalfloop<Refs> >
{
typedef typename Refs::Halfloop_handle Halfloop_handle;
typedef typename Refs::Face_handle Face_handle;
typedef typename Refs::SHalfloop_handle SHalfloop_handle;
typedef typename Refs::SFace_handle SFace_handle;
typedef typename Refs::Items Items;
friend class Sphere_map<Kernel_>;
friend class SM_const_decorator<Refs,Kernel_>;
friend class SM_decorator<Refs,Kernel_>;
friend class Self::Vertex<Refs>;
friend class Sphere_map<Kernel_, Items>;
friend class SM_const_decorator<Refs>;
friend class SM_decorator<Refs>;
friend class Self::SVertex<Refs>;
Sphere_circle circle_;
Mark mark_;
Halfloop_handle twin_;
Face_handle face_;
SHalfloop_handle twin_;
SFace_handle incident_sface_;
GenPtr info_;
// temporary needed:
public:
Halfloop() : circle_(), mark_(), twin_(), face_(), info_() {}
~Halfloop() {}
Halfloop(const Halfloop<Refs>& l)
SHalfloop() : circle_(), mark_(), twin_(), incident_sface_(), info_() {}
~SHalfloop() {}
SHalfloop(const SHalfloop<Refs>& l)
{
circle_ = l.circle_;
mark_ = l.mark_;
twin_ = l.twin_;
face_ = l.face_;
incident_sface_ = l.incident_sface_;
info_ = 0;
}
Halfloop<Refs>& operator=(const Halfloop<Refs>& l)
SHalfloop<Refs>& operator=(const SHalfloop<Refs>& l)
{
circle_ = l.circle_;
mark_ = l.mark_;
twin_ = l.twin_;
face_ = l.face_;
incident_sface_ = l.incident_sface_;
info_ = 0;
return *this;
}
bool is_twin() const { return (&*twin_ < this); }
std::string debug() const
{ std::ostrstream os; set_pretty_mode(os);
os<<"l"<<circle_<<' '<<info_<<'\0';
std::string res(os.str()); os.freeze(0); return res;
}
}; // Halfloop
}; // SHalfloop
template <typename Refs>
class Face : public CGAL::In_place_list_base< Face<Refs> >
class SFace : public CGAL::In_place_list_base< SFace<Refs> >
{
typedef typename Refs::Items Items;
friend class Sphere_map<Kernel_>;
friend class SM_const_decorator<Refs,Kernel_>;
friend class SM_decorator<Refs,Kernel_>;
friend class Sphere_map<Kernel_, Items>;
friend class SM_const_decorator<Refs>;
friend class SM_decorator<Refs>;
typedef typename Refs::Object_handle Object_handle;
typedef typename Refs::Object_list Object_list;
typedef typename Refs::Face_cycle_iterator Face_cycle_iterator;
typedef typename Refs::Face_cycle_const_iterator
Face_cycle_const_iterator;
typedef typename Refs::SFace_cycle_iterator SFace_cycle_iterator;
typedef typename Refs::SFace_cycle_const_iterator
SFace_cycle_const_iterator;
Mark mark_;
Object_list boundary_; // Halfedges, Halfloops, Vertices
Object_list boundary_entry_objects_;
// SHalfedges, SHalfloops, Vertices
GenPtr info_;
// temporary needed:
public:
Face() : mark_(), info_() {}
~Face() {}
SFace() : mark_(), info_() {}
~SFace() {}
Face(const Face<Refs>& f)
SFace(const SFace<Refs>& f)
{ mark_ = f.mark_;
boundary_ = f.boundary_;
boundary_entry_objects_ = f.boundary_entry_objects_;
info_ = 0;
}
Face<Refs>& operator=(const Face<Refs>& f)
SFace<Refs>& operator=(const SFace<Refs>& f)
{ if (this == &f) return *this;
mark_ = f.mark_;
boundary_ = f.boundary_;
boundary_entry_objects_ = f.boundary_entry_objects_;
info_ = 0;
return *this;
}
Face_cycle_iterator face_cycles_begin()
{ return boundary_.begin(); }
Face_cycle_iterator face_cycles_end()
{ return boundary_.end(); }
SFace_cycle_iterator sface_cycles_begin()
{ return boundary_entry_objects_.begin(); }
SFace_cycle_iterator sface_cycles_end()
{ return boundary_entry_objects_.end(); }
Face_cycle_const_iterator face_cycles_begin() const
{ return boundary_.begin(); }
Face_cycle_const_iterator face_cycles_end() const
{ return boundary_.end(); }
SFace_cycle_const_iterator sface_cycles_begin() const
{ return boundary_entry_objects_.begin(); }
SFace_cycle_const_iterator sface_cycles_end() const
{ return boundary_entry_objects_.end(); }
}; // Face
}; // SFace
}; // SM_items

View File

@ -3,31 +3,31 @@
#undef CGAL_forall_iterators
#define CGAL_forall_iterators(x,S)\
for(x = S.begin(); x != S.end(); ++x)
for(x = (S).begin(); x != (S).end(); ++x)
#undef CGAL_forall_vertices
#define CGAL_forall_vertices(x,SM)\
for(x = (SM).vertices_begin(); x != (SM).vertices_end(); ++x)
#undef CGAL_forall_svertices
#define CGAL_forall_svertices(x,SM)\
for(x = (SM).svertices_begin(); x != (SM).svertices_end(); ++x)
#undef CGAL_forall_halfedges
#define CGAL_forall_halfedges(x,SM)\
for(x = (SM).halfedges_begin(); x != (SM).halfedges_end(); ++x)
#undef CGAL_forall_shalfedges
#define CGAL_forall_shalfedges(x,SM)\
for(x = (SM).shalfedges_begin(); x != (SM).shalfedges_end(); ++x)
#undef CGAL_forall_edges
#define CGAL_forall_edges(x,SM)\
for(x = (SM).halfedges_begin(); x != (SM).halfedges_end(); ++(++x))
#undef CGAL_forall_sedges
#define CGAL_forall_sedges(x,SM)\
for(x = (SM).shalfedges_begin(); x != (SM).shalfedges_end(); ++(++x))
#undef CGAL_forall_halfloops
#define CGAL_forall_halfloops(x,SM)\
for(x = (SM).halfloops_begin(); x != (SM).halfloops_end(); ++x)
#undef CGAL_forall_shalfloops
#define CGAL_forall_shalfloops(x,SM)\
for(x = (SM).shalfloops_begin(); x != (SM).shalfloops_end(); ++x)
#undef CGAL_forall_faces
#define CGAL_forall_faces(x,SM)\
for(x = (SM).faces_begin(); x != (SM).faces_end(); ++x)
#undef CGAL_forall_sfaces
#define CGAL_forall_sfaces(x,SM)\
for(x = (SM).sfaces_begin(); x != (SM).sfaces_end(); ++x)
#undef CGAL_forall_face_cycles_of
#define CGAL_forall_face_cycles_of(x,F)\
for(x = (F)->face_cycles_begin(); x != (F)->face_cycles_end(); ++x)
#undef CGAL_forall_sface_cycles_of
#define CGAL_forall_sface_cycles_of(x,F)\
for(x = (F)->sface_cycles_begin(); x != (F)->sface_cycles_end(); ++x)
#endif //CGAL_SM_ITERATION_H

File diff suppressed because it is too large Load Diff

View File

@ -19,12 +19,14 @@
#ifndef CGAL_SM_POINT_LOCATOR_H
#define CGAL_SM_POINT_LOCATOR_H
#include <vector>
#include <CGAL/basic.h>
#include <CGAL/Unique_hash_map.h>
#include <CGAL/Nef_2/geninfo.h>
#include <CGAL/Nef_2/Object_handle.h>
#include <CGAL/Nef_S2/SM_decorator_traits.h>
#undef _DEBUG
#define _DEBUG 143
#define _DEBUG 47
#include <CGAL/Nef_S2/debug.h>
@ -36,201 +38,235 @@ CGAL_BEGIN_NAMESPACE
{Naive point location in plane maps}{PL}}*/
/*{\Mdefinition An instance |\Mvar| of data type |\Mname|
encapsulates naive point location queries within a sphere map |M|. The
two template parameters are specified via concepts. |PM_decorator_|
must be a model of the concept |PMDecorator| as described in the
two template parameters are specified via concepts. |SM_decorator_|
must be a model of the concept |SMDecorator| as described in the
appendix. |Geometry_| must be a model of the concept
|AffineGeometryTraits_2| as described in the appendix. For a
specification of plane maps see also the concept of
|PMConstDecorator|.}*/
|SMConstDecorator|.}*/
/*{\Mgeneralization Decorator}*/
template <typename Decorator_>
class SM_point_locator : public Decorator_ {
template <class SM_decorator>
class SM_point_locator : public SM_decorator {
protected:
typedef Decorator_ Base;
typedef SM_point_locator<Decorator_> Self;
typedef SM_decorator Base;
typedef SM_point_locator<SM_decorator> Self;
typedef typename SM_decorator::Constructor_parameter Constructor_parameter;
public:
/*{\Mtypes 5}*/
typedef Decorator_ Decorator;
/*{\Mtypemember equals |Decorator_|.}*/
typedef typename Decorator::Sphere_map Sphere_map;
/*{\Mtypemember the sphere map type decorated by |Decorator|.}*/
typedef typename Decorator::Mark Mark;
typedef typename SM_decorator::Decorator_traits Decorator_traits;
typedef typename Base::Mark Mark;
/*{\Mtypemember the attribute of all objects (vertices, edges, loops,
faces).}*/
typedef typename Decorator::Kernel Kernel;
typedef typename SM_decorator::Sphere_kernel Sphere_kernel;
/*{\Mtypemember the sphere kernel.}*/
typedef typename Kernel::Sphere_point Sphere_point;
typedef typename Sphere_kernel::Sphere_point Sphere_point;
/*{\Mtypemember points.}*/
typedef typename Kernel::Sphere_segment Sphere_segment;
typedef typename Sphere_kernel::Sphere_segment Sphere_segment;
/*{\Mtypemember segments.}*/
typedef typename Kernel::Sphere_circle Sphere_circle;
typedef typename Sphere_kernel::Sphere_circle Sphere_circle;
/*{\Mtypemember circles.}*/
typedef typename Kernel::Sphere_direction Sphere_direction;
typedef typename Sphere_kernel::Sphere_direction Sphere_direction;
/*{\Mtypemember directions.}*/
/*{\Mtext Local types are handles, iterators and circulators of the
following kind: |Vertex_const_handle|, |Vertex_const_iterator|,
|Halfedge_const_handle|, |Halfedge_const_iterator|,
|Halfloop_const_handle|, |Halfloop_const_iterator|,
|Face_const_handle|, |Face_const_iterator|.}*/
following kind: |SVertex_const_handle|, |SVertex_const_iterator|,
|SHalfedge_const_handle|, |SHalfedge_const_iterator|,
|SHalfloop_const_handle|, |SHalfloop_const_iterator|,
|SFace_const_handle|, |SFace_const_iterator|.}*/
typedef typename Sphere_map::Object_handle Object_handle;
typedef CGAL::Object_handle Object_handle;
/*{\Mtypemember a generic handle to an object of the underlying plane
map. The kind of the object |(vertex, halfedge,face)| can be determined and
the object assigned by the three functions:\\
|bool assign(Vertex_const_handle& h, Object_handle o)|\\
|bool assign(Halfedge_const_handle& h, Object_handle o)|\\
|bool assign(Face_const_handle& h, Object_handle o)|\\ where each
|bool assign(SVertex_const_handle& h, Object_handle o)|\\
|bool assign(SHalfedge_const_handle& h, Object_handle o)|\\
|bool assign(SFace_const_handle& h, Object_handle o)|\\ where each
function returns |true| iff the assignment of |o| to |h| was valid.}*/
#define CGAL_USING(t) typedef typename Decorator_::t t
CGAL_USING(Vertex_handle);
CGAL_USING(Halfedge_handle);
CGAL_USING(Halfloop_handle);
CGAL_USING(Face_handle);
CGAL_USING(Vertex_const_handle);
CGAL_USING(Halfedge_const_handle);
CGAL_USING(Halfloop_const_handle);
CGAL_USING(Face_const_handle);
CGAL_USING(Vertex_iterator);
CGAL_USING(Halfedge_iterator);
CGAL_USING(Halfloop_iterator);
CGAL_USING(Face_iterator);
CGAL_USING(Vertex_const_iterator);
CGAL_USING(Halfedge_const_iterator);
CGAL_USING(Halfloop_const_iterator);
CGAL_USING(Face_const_iterator);
CGAL_USING(Halfedge_around_vertex_circulator);
CGAL_USING(Halfedge_around_vertex_const_circulator);
CGAL_USING(Halfedge_around_face_circulator);
CGAL_USING(Halfedge_around_face_const_circulator);
#undef CGAL_USING
typedef typename Decorator_traits::SVertex_handle SVertex_handle;
typedef typename Decorator_traits::SHalfedge_handle SHalfedge_handle;
typedef typename Decorator_traits::SHalfloop_handle SHalfloop_handle;
typedef typename Decorator_traits::SFace_handle SFace_handle;
Sphere_segment segment(Halfedge_const_handle e) const
typedef typename Decorator_traits::SVertex_iterator SVertex_iterator;
typedef typename Decorator_traits::SHalfedge_iterator SHalfedge_iterator;
typedef typename Decorator_traits::SHalfloop_iterator SHalfloop_iterator;
typedef typename Decorator_traits::SFace_iterator SFace_iterator;
typedef typename Decorator_traits::SHalfedge_around_svertex_circulator
SHalfedge_around_svertex_circulator;
typedef typename Decorator_traits::SHalfedge_around_sface_circulator
SHalfedge_around_sface_circulator;
Sphere_segment segment(SHalfedge_handle e) const
{ return Sphere_segment(point(source(e)), point(target(e)), circle(e)); }
Sphere_direction direction(Halfedge_const_handle e) const
Sphere_direction direction(SHalfedge_handle e) const
{ return Sphere_direction(circle(e)); }
Halfedge_const_handle out_wedge(Vertex_const_handle v,
const Sphere_direction& d, bool& collinear) const
SHalfedge_handle out_wedge(SVertex_handle v, const Sphere_direction& d,
bool& collinear) const
/*{\Xop returns a halfedge |e| bounding a wedge in between two
neighbored edges in the adjacency list of |v| which contains |d|.
If |d| extends along a edge then |e| is this edge. If |d| extends
into the interior of such a wedge then |e| is the first edge hit
when |d| is rotated clockwise. \precond |v| is not isolated.}*/
{ TRACEN("out_wedge "<<PH(v));
assert(!is_isolated(v));
CGAL_assertion(!is_isolated(v));
collinear=false;
Sphere_point p = point(v);
Halfedge_const_handle e_res = first_out_edge(v);
SHalfedge_handle e_res = first_out_edge(v);
Sphere_direction d_res = direction(e_res);
Halfedge_around_vertex_const_circulator el(e_res),ee(el);
CGAL_For_all(el,ee) {
if ( strictly_ordered_ccw_at(p,d_res, direction(el), d) )
e_res = el; d_res = direction(e_res);
SHalfedge_around_svertex_circulator el(e_res),ee(el);
if(direction(el) == d) {
collinear = true;
TRACEN(" determined "<<PH(el) << circle(el));
return el;
}
TRACEN(" determined "<<PH(e_res)<<" "<<d_res);
if ( direction(cyclic_adj_succ(e_res)) == d ) {
CGAL_For_all(el,ee) {
if(direction(cyclic_adj_succ(el)) == d) {
collinear = true;
TRACEN(" equal "<<PH(cyclic_adj_succ(el)) << circle(cyclic_adj_succ(el)));
return cyclic_adj_succ(el);
}
else {
TRACEN("strictly_ordered_ccw " << direction(el) << " ? " << d << " ? " << direction(cyclic_adj_succ(el)));
// if ( strictly_ordered_ccw_at(p,d_res, direction(el), d) ) {
if ( strictly_ordered_ccw_at(p,direction(el), d, direction(cyclic_adj_succ(el))) ) {
TRACEN("strictly_ordered_ccw " << direction(el) << " - " << d << " - " << direction(cyclic_adj_succ(el)));
e_res = el; d_res = direction(e_res); break;
}
}
}
TRACEN(" finally determined "<<PH(e_res) << circle(e_res));
/*
Sphere_direction d2 = direction(cyclic_adj_succ(e_res));
d2 = normalized(d2);
TRACEN(d2 << " =?= " << d);
if (d2 == d ) {
e_res = cyclic_adj_succ(e_res);
collinear=true;
}
TRACEN(" wedge = "<<PH(e_res)<<" "<<collinear);
*/
return e_res;
}
/*{\Mcreation 3}*/
SM_point_locator() : Base() {}
/*{\Moptions constref=yes}*/
SM_point_locator(const Sphere_map& M) :
Base(const_cast<Sphere_map&>(M)) {}
SM_point_locator(Constructor_parameter cp) : Base(cp) {}
/*{\Mcreate constructs a point locator working on |P|.}*/
/*{\Moptions constref=no}*/
/*{\Moperations 2.5 0.5}*/
const Mark& mark(Object_handle h) const
/*{\Mop returns the mark associated to the object |h|.}*/
{ Vertex_const_handle v;
Halfedge_const_handle e;
Face_const_handle f;
if ( assign(v,h) ) return mark(v);
if ( assign(e,h) ) return mark(e);
if ( assign(f,h) ) return mark(f);
CGAL_nef_assertion_msg(0,
"PM_point_locator::mark: Object_handle holds no object.");
{ SVertex_handle v;
SHalfedge_handle e;
SHalfloop_handle l;
SFace_handle f;
if ( assign(v,h) ) return Base::mark(v);
if ( assign(e,h) ) return Base::mark(e);
if ( assign(l,h) ) return Base::mark(l);
CGAL_assertion_msg(assign(f,h),
"PM_point_locator::mark: Object_handle holds no object.");
assign(f,h);
return Base::mark(f);
}
enum SOLUTION { is_vertex_, is_edge_, is_loop_ };
// enumeration for internal use
Object_handle locate(const Sphere_point& p) const
/*{\Mop returns a generic handle |h| to an object (vertex, halfedge,
face) of the underlying plane map |P| which contains the point |p =
s.source()| in its relative interior. |s.target()| must be a point
such that |s| intersects the $1$-skeleton of |P|.}*/
{ TRACEN("locate naivly "<<p);
Vertex_const_iterator v;
CGAL_forall_vertices(v,*this) {
if ( p == point(v) ) return Object_handle(v);
SVertex_iterator v;
CGAL_forall_svertices(v,*this) {
if ( p == point(v) ) {
TRACEN( " on point");
return Object_handle(v);
}
}
Halfedge_const_iterator e;
CGAL_forall_edges(e,*this) {
if ( segment(e).has_on(p) ) return Object_handle(e);
SHalfedge_iterator e;
CGAL_forall_sedges(e,*this) {
if ( segment(e).has_on(p) ) {
TRACEN( " on segment " << segment(e));
return Object_handle(e);
}
}
if ( has_sloop() && circle(shalfloop()).has_on(p) ) {
TRACEN( " on loop");
return Object_handle(SHalfloop_handle(shalfloop()));
}
if ( has_loop() && circle(halfloop()).has_on(p) )
return Object_handle(Halfloop_const_handle(halfloop()));
// now in face:
if ( number_of_vertices() == 0 && ! has_loop() )
return Object_handle(faces_begin());
if(number_of_sfaces() == 1) {
TRACEN(" on unique face");
SFace_handle f = sfaces_begin();
return Object_handle(f);
}
Vertex_const_handle v_res;
Halfedge_const_handle e_res;
Halfloop_const_handle l_res;
SVertex_handle v_res;
SHalfedge_handle e_res;
SHalfloop_handle l_res;
SOLUTION solution;
TRACEN(" on face...");
Sphere_segment s; // we shorten the segment iteratively
if ( has_loop() ) {
Sphere_circle c(circle(halfloop()),p); // orthogonal through p
s = Sphere_segment(p,intersection(c,circle(halfloop())));
l_res = circle(halfloop()).has_on_positive_side(p) ?
halfloop() : twin(halfloop());
if ( has_sloop() ) {
Sphere_circle c(circle(shalfloop()),p); // orthogonal through p
s = Sphere_segment(p,intersection(c,circle(shalfloop())));
l_res = circle(shalfloop()).has_on_positive_side(p) ?
shalfloop() : twin(shalfloop());
solution = is_loop_;
TRACEN("has loop, initial ray "<<s);
TRACEN(circle(l_res));
} else { // has vertices !
CGAL_nef_assertion( number_of_vertices()!=0 );
Vertex_const_handle vt = vertices_begin();
Sphere_point pvt = point(vt);
if ( p != pvt.antipode() ) s = Sphere_segment(p,pvt);
else s = Sphere_segment(p,pvt,Sphere_circle(p,pvt));
v_res = vt;
CGAL_assertion( number_of_svertices()!=0 );
SVertex_iterator vi = svertices_begin();
if( p == point(vi).antipode()) {
++vi;
CGAL_assertion( vi != svertices_end());
}
TRACEN("initial segment: "<<p<<","<<point(vi));
CGAL_assertion( p != point(vi).antipode());
s = Sphere_segment( p, point(vi));
v_res = vi;
solution = is_vertex_;
TRACEN("has vertices, initial ray "<<s);
}
// s now initialized
Sphere_direction dso(s.sphere_circle().opposite()), d_res;
Unique_hash_map<Halfedge_const_handle,bool> visited(false);
CGAL_forall_vertices(v,*this) {
Sphere_point p_res, vp = point(v);
Sphere_direction dso(s.sphere_circle().opposite());
Unique_hash_map<SHalfedge_handle,bool> visited(false);
CGAL_forall_svertices(v,*this) {
Sphere_point vp = point(v);
if ( s.has_on(vp) ) {
TRACEN(" location via vertex at "<<vp);
s = Sphere_segment(p,vp,s.sphere_circle()); // we shrink the segment
if ( is_isolated(v) ) {
TRACEN("is_vertex_");
v_res = v; solution = is_vertex_;
} else { // not isolated
bool dummy;
e_res = out_wedge(v,dso,dummy);
Halfedge_around_vertex_const_circulator el(e_res),ee(el);
SHalfedge_around_svertex_circulator el(e_res),ee(el);
CGAL_For_all(el,ee)
visited[el] = visited[twin(el)] = true;
/* e_res is now the counterclockwise maximal halfedge out
@ -244,7 +280,7 @@ public:
}
}
CGAL_forall_halfedges(e,*this) {
CGAL_forall_sedges(e,*this) {
if ( visited[e] ) continue;
Sphere_segment se = segment(e);
Sphere_point p_res;
@ -260,26 +296,25 @@ public:
switch ( solution ) {
case is_edge_:
return Object_handle((Face_const_handle)(face(e_res)));
return Object_handle(SFace_handle(face(e_res)));
case is_loop_:
return Object_handle((Face_const_handle)(face(l_res)));
return Object_handle(SFace_handle(face(l_res)));
case is_vertex_:
return Object_handle((Face_const_handle)(face(v_res)));
default: CGAL_nef_assertion_msg(0,"missing solution.");
return Object_handle(SFace_handle(face(v_res)));
default: CGAL_assertion_msg(0,"missing solution.");
}
return Object_handle(); // never reached!
}
template <typename Object_predicate>
Object_handle ray_shoot(const Sphere_point& p,
const Sphere_direction& d,
const Object_predicate& M) const
/*{\Mop returns an |Object_handle o| which can be converted to a
|Vertex_const_handle|, |Halfedge_const_handle|, |Face_const_handle|
|SVertex_handle|, |SHalfedge_handle|, |SFace_handle|
|h| as described above. The object predicate |M| has to have
function operators \\ |bool operator() (const
Vertex_/Halfedge_/Halfloop_/Face_const_handle&)|.\\ The object
SVertex_/SHalfedge_/SHalfloop_/SFace_handle&)|.\\ The object
returned is intersected by |d.circle()|, has minimal distance to
|p|, and |M(h)| holds on the converted object. The operation returns
the null handle |NULL| if the ray shoot along |s| does not hit any
@ -289,10 +324,10 @@ public:
Sphere_segment s;
bool s_init(false);
Object_handle h = locate(p);
Vertex_const_handle v;
Halfedge_const_handle e;
Halfloop_const_handle l;
Face_const_handle f;
SVertex_handle v;
SHalfedge_handle e;
SHalfloop_handle l;
SFace_handle f;
if ( assign(v,h) && M(v) ||
assign(e,h) && M(e) ||
assign(l,h) && M(l) ||
@ -303,7 +338,7 @@ public:
HASEN: s am anfang circle, ab wann segment ?
wo loop ?
CGAL_forall_vertices (v,*this) {
CGAL_forall_svertices (v,*this) {
Point pv = point(v);
if ( !(s_init && s.has_on(pv) ||
!s_init && c.has_on(pv)) ) continue;
@ -315,7 +350,7 @@ public:
}
// now we know that v is not marked but on s
bool collinear;
Halfedge_const_handle e = out_wedge(v,d,collinear);
SHalfedge_handle e = out_wedge(v,d,collinear);
if ( collinear ) {
if ( M(e) ) {
h = Object_handle(e);
@ -329,9 +364,9 @@ public:
}
} // all vertices
CGAL::Unique_hash_map<Halfedge_const_handle,bool> visited(false);
Halfedge_const_iterator e_res;
CGAL_forall_halfedges(e,*this) {
CGAL::Unique_hash_map<SHalfedge_handle,bool> visited(false);
SHalfedge_iterator e_res;
CGAL_forall_sedges(e,*this) {
Sphere_segment se = segment(e);
Sphere_point p_res;
if ( do_intersect_internally(se,s,p_res) ) {
@ -353,79 +388,96 @@ public:
}
}
#endif
CGAL_nef_assertion_msg(0,"not yet correct");
CGAL_assertion_msg(0,"not yet correct");
return h;
}
void init_marks_of_halfspheres();
void marks_of_halfspheres(std::vector<Mark>& mohs, int offset,
int axis=2);
void marks_of_halfspheres(Mark& unten, Mark& oben, int axis=2);
// C++ is really friendly:
#define USECMARK(t) const Mark& mark(t h) const { return Base::mark(h); }
#define USEMARK(t) Mark& mark(t h) const { return Base::mark(h); }
USEMARK(Vertex_handle)
USEMARK(Halfedge_handle)
USEMARK(Face_handle)
USECMARK(Vertex_const_handle)
USECMARK(Halfedge_const_handle)
USECMARK(Face_const_handle)
#undef USEMARK
#undef USECMARK
/*{\Mimplementation Naive query operations are realized by checking
the intersection points of the $1$-skeleton of the plane map |P| with
the query segments $s$. This method takes time linear in the size $n$
of the underlying plane map without any preprocessing.}*/
}; // SM_point_locator<Decorator_>
}; // SM_point_locator<SM_decorator>
template <typename D>
void SM_point_locator<D>::init_marks_of_halfspheres()
{ TRACEN("init_marks_of_halfspheres");
Sphere_point y_minus(0,-1,0);
void SM_point_locator<D>::
marks_of_halfspheres(std::vector<Mark>& mohs, int offset, int axis) {
Mark lower, upper;
marks_of_halfspheres(lower, upper, axis);
mohs[offset] = lower;
mohs[offset+1] = upper;
}
template <typename D>
void SM_point_locator<D>::
marks_of_halfspheres(Mark& lower, Mark& upper, int axis) {
TRACEN("marks_of_halfspheres ");
Sphere_point y_minus;
if(axis!=1)
y_minus = Sphere_point(0,-1,0);
else
y_minus = Sphere_point(0,0,1);
Object_handle h = locate(y_minus);
Face_const_handle f;
if ( CGAL::assign(f,h) ) {
mark_of_halfsphere(-1) = mark_of_halfsphere(+1) = mark(f);
SFace_handle f;
if ( assign(f,h) ) {
TRACEN("on face " << mark(f));
lower = upper = mark(f);
return;
}
Halfedge_const_handle e;
if ( CGAL::assign(e,h) ) {
CGAL_nef_assertion(circle(e).has_on(y_minus));
SHalfedge_handle e;
if ( assign(e,h) ) {
CGAL_assertion(circle(e).has_on(y_minus));
Sphere_point op(CGAL::ORIGIN+circle(e).orthogonal_vector());
TRACEN("on edge "<<op);
if ( (op.x() > 0) || (op.x() == 0) && (op.z() < 0) ) e = twin(e);
// if ( (op.z() < 0) || (op.z() == 0) && (op.x() > 0) ) e = twin(e);
mark_of_halfsphere(+1) = mark(face(e));
mark_of_halfsphere(-1) = mark(face(twin(e)));
if (axis==0 && ((op.z() < 0) || (op.z() == 0) && (op.x() < 0))) e = twin(e);
if (axis==1 && ((op.x() > 0) || (op.x() == 0) && (op.y() < 0))) e = twin(e);
if (axis==2 && ((op.x() > 0) || (op.x() == 0) && (op.z() < 0))) e = twin(e);
upper = mark(face(e));
lower = mark(face(twin(e)));
return;
}
Halfloop_const_handle l;
if ( CGAL::assign(l,h) ) {
CGAL_nef_assertion(circle(l).has_on(y_minus));
SHalfloop_handle l;
if ( assign(l,h) ) {
CGAL_assertion(circle(l).has_on(y_minus));
Sphere_point op(CGAL::ORIGIN+circle(l).orthogonal_vector());
TRACEN("on loop "<<op);
if ( (op.x() > 0) || (op.x() == 0) && (op.z() < 0) ) l = twin(l);
// if ( (op.z() < 0) || (op.z() == 0) && (op.x() > 0) ) l = twin(l);
mark_of_halfsphere(+1) = mark(face(l));
mark_of_halfsphere(-1) = mark(face(twin(l)));
if (axis==0 && ((op.z() < 0) || (op.z() == 0) && (op.x() < 0))) l = twin(l);
if (axis==1 && ((op.x() > 0) || (op.x() == 0) && (op.y() < 0))) l = twin(l);
if (axis==2 && ((op.x() > 0) || (op.x() == 0) && (op.z() < 0))) l = twin(l);
upper = mark(face(l));
lower = mark(face(twin(l)));
return;
}
Sphere_circle c(0,0,1);
Sphere_circle c;
switch(axis) {
case 0: c = Sphere_circle(1,0,0); break;
case 1: c = Sphere_circle(0,1,0); break;
case 2: c = Sphere_circle(0,0,1); break;
}
Sphere_direction right(c),left(c.opposite());
bool collinear(false);
Vertex_const_handle v;
if ( CGAL::assign(v,h) ) {
CGAL_nef_assertion(point(v)==y_minus);
e = out_wedge(v,left,collinear);
if ( collinear ) mark_of_halfsphere(+1) = mark(face(twin(e)));
else mark_of_halfsphere(+1) = mark(face(e));
e = out_wedge(v,right,collinear);
if ( collinear ) mark_of_halfsphere(-1) = mark(face(twin(e)));
else mark_of_halfsphere(-1) = mark(face(e));
return;
SVertex_handle v;
if ( assign(v,h) ) {
CGAL_assertion(point(v)==y_minus);
if(is_isolated(v))
upper = lower = mark(face(v));
else {
e = out_wedge(v,left,collinear);
if ( collinear ) upper = mark(face(twin(e)));
else upper = mark(face(e));
e = out_wedge(v,right,collinear);
if ( collinear ) lower = mark(face(twin(e)));
else lower = mark(face(e));
}
}
CGAL_nef_assertion_msg(0,"damn wrong type.");
}
CGAL_END_NAMESPACE

View File

@ -25,6 +25,8 @@
#include <CGAL/Nef_2/Segment_overlay_traits.h>
#include <CGAL/Nef_2/geninfo.h>
#include <CGAL/Nef_S2/SM_decorator.h>
#include <CGAL/Nef_S2/SM_const_decorator.h>
#include <CGAL/Nef_S2/SM_point_locator.h>
#include <CGAL/Nef_S2/SM_io_parser.h>
#include <CGAL/Nef_S2/SM_constrained_triang_traits.h>
@ -41,8 +43,8 @@ CGAL_BEGIN_NAMESPACE
template <typename Decorator_, typename IT, typename INFO>
struct SM_subdivision {
typedef Decorator_ Triangulator;
typedef typename Decorator_::Vertex_handle Vertex_handle;
typedef typename Decorator_::Halfedge_handle Halfedge_handle;
typedef typename Decorator_::SVertex_handle Vertex_handle;
typedef typename Decorator_::SHalfedge_handle Halfedge_handle;
typedef typename Decorator_::Sphere_point Point;
typedef typename Decorator_::Sphere_segment Segment;
Triangulator T;
@ -54,7 +56,7 @@ struct SM_subdivision {
CGAL::Unique_hash_map<IT,INFO>& Mi) : T(Ti), M(Mi) {}
Vertex_handle new_vertex(const Point& p) const
{ Vertex_handle v = T.new_vertex(p); T.assoc_info(v);
{ Vertex_handle v = T.new_svertex(p); T.assoc_info(v);
return v;
}
@ -63,7 +65,7 @@ void link_as_target_and_append(Vertex_handle v, Halfedge_handle e) const
Halfedge_handle new_halfedge_pair_at_source(Vertex_handle v) const
{ Halfedge_handle e =
T.new_edge_pair_at_source(v,Decorator_::BEFORE);
T.new_shalfedge_pair_at_source(v,Decorator_::BEFORE);
T.assoc_info(e);
return e;
}
@ -110,41 +112,45 @@ public:
/*{\Mdefinition An instance |\Mvar| of data type |\Mname| is a
decorator object offering sphere map triangulation calculation.}*/
typedef Decorator_ Base;
typedef typename Decorator_::Base Explorer;
typedef Decorator_ Decorator;
typedef SM_triangulator<Decorator_> Self;
CGAL_USING(Vertex_handle);
CGAL_USING(Halfedge_handle);
CGAL_USING(Halfloop_handle);
CGAL_USING(Face_handle);
CGAL_USING(Vertex_iterator);
CGAL_USING(Halfedge_iterator);
CGAL_USING(Face_iterator);
CGAL_USING(Vertex_const_handle);
CGAL_USING(Halfedge_const_handle);
CGAL_USING(Halfloop_const_handle);
CGAL_USING(Face_const_handle);
CGAL_USING(Vertex_const_iterator);
CGAL_USING(Halfedge_const_iterator);
CGAL_USING(Face_const_iterator);
typedef Decorator_ Base;
typedef typename Decorator_::Map Map;
typedef SM_const_decorator<Map> Explorer;
typedef Decorator_ Decorator;
typedef SM_triangulator<Decorator_> Self;
typedef CGAL::SM_const_decorator<Map> SM_const_decorator;
typedef SM_point_locator<SM_const_decorator> SM_point_locator;
CGAL_USING(SVertex_handle);
CGAL_USING(SHalfedge_handle);
CGAL_USING(SHalfloop_handle);
CGAL_USING(SFace_handle);
CGAL_USING(SVertex_iterator);
CGAL_USING(SHalfedge_iterator);
CGAL_USING(SFace_iterator);
CGAL_USING(SVertex_const_handle);
CGAL_USING(SHalfedge_const_handle);
CGAL_USING(SHalfloop_const_handle);
CGAL_USING(SFace_const_handle);
CGAL_USING(SVertex_const_iterator);
CGAL_USING(SHalfedge_const_iterator);
CGAL_USING(SFace_const_iterator);
CGAL_USING(Object_handle);
CGAL_USING(Halfedge_around_vertex_circulator);
CGAL_USING(Halfedge_around_face_circulator);
CGAL_USING(Sphere_map);
typedef std::pair<Halfedge_handle,Halfedge_handle> Halfedge_pair;
CGAL_USING(SHalfedge_around_svertex_circulator);
CGAL_USING(SHalfedge_around_sface_circulator);
CGAL_USING(Map);
typedef std::pair<SHalfedge_handle,SHalfedge_handle> SHalfedge_pair;
/*{\Mtypes 3}*/
typedef typename Base::Kernel Kernel;
typedef typename Base::Sphere_kernel Sphere_kernel;
typedef typename Kernel::Sphere_point Sphere_point;
typedef typename Sphere_kernel::Sphere_point Sphere_point;
/*{\Mtypemember the point type of the sphere geometry.}*/
typedef typename Kernel::Sphere_segment Sphere_segment;
typedef typename Sphere_kernel::Sphere_segment Sphere_segment;
/*{\Mtypemember the segment type of the sphere geometry.}*/
typedef typename Kernel::Sphere_circle Sphere_circle;
typedef typename Sphere_kernel::Sphere_circle Sphere_circle;
/*{\Mtypemember the circle type of the sphere geometry.}*/
typedef typename Kernel::Sphere_triangle Sphere_triangle;
typedef typename Sphere_kernel::Sphere_triangle Sphere_triangle;
/*{\Mtypemember the triangle type of the sphere geometry.}*/
typedef typename Decorator::Mark Mark;
@ -154,7 +160,7 @@ public:
protected:
Explorer E_;
const Kernel& K;
const Sphere_kernel& K;
public:
@ -167,24 +173,24 @@ public:
// vertex_info stores the origin of vertices
struct vertex_info {
Object_handle o_;
Halfedge_handle e_;
SHalfedge_handle e_;
vertex_info() : o_(),e_() {}
LEDA_MEMORY(vertex_info)
};
void assoc_info(Vertex_handle v) const
void assoc_info(SVertex_handle v) const
{ geninfo<vertex_info>::create(info(v)); }
void discard_info(Vertex_handle v) const
void discard_info(SVertex_handle v) const
{ geninfo<vertex_info>::clear(info(v)); }
vertex_info& ginfo(Vertex_handle v) const
vertex_info& ginfo(SVertex_handle v) const
{ return geninfo<vertex_info>::access(info(v)); }
Object_handle& support(Vertex_handle v) const
Object_handle& support(SVertex_handle v) const
{ return ginfo(v).o_; }
Halfedge_handle& halfedge_below(Vertex_handle v) const
SHalfedge_handle& halfedge_below(SVertex_handle v) const
{ return ginfo(v).e_; }
// edge_info stores the origin of edges
@ -195,82 +201,82 @@ public:
LEDA_MEMORY(edge_info)
};
void assoc_info(Halfedge_handle e) const
void assoc_info(SHalfedge_handle e) const
{ geninfo<edge_info>::create(info(e));
geninfo<edge_info>::create(info(twin(e))); }
void discard_info(Halfedge_handle e) const
void discard_info(SHalfedge_handle e) const
{ geninfo<edge_info>::clear(info(e));
geninfo<edge_info>::clear(info(twin(e))); }
edge_info& ginfo(Halfedge_handle e) const
edge_info& ginfo(SHalfedge_handle e) const
{ return geninfo<edge_info>::access(info(e)); }
Object_handle& support(Halfedge_handle e) const
Object_handle& support(SHalfedge_handle e) const
// uedge information we store in the smaller one
{ if (&*e < &*(twin(e))) return ginfo(e).o_;
else return ginfo(twin(e)).o_; }
Mark& incident_mark(Halfedge_handle e) const
Mark& incident_mark(SHalfedge_handle e) const
// biedge information we store in the edge
{ return ginfo(e).m_left_; }
const edge_info& ginfo(Halfedge_const_handle e) const
const edge_info& ginfo(SHalfedge_const_handle e) const
{ return geninfo<edge_info>::const_access(info(e)); }
const Mark& incident_mark(Halfedge_const_handle e) const
const Mark& incident_mark(SHalfedge_const_handle e) const
{ return ginfo(e).m_left_; }
bool& is_forward(Halfedge_handle e) const
bool& is_forward(SHalfedge_handle e) const
// biedge information we store in the edge
{ return ginfo(e).forw_; }
void assert_equal_marks(Vertex_handle v1, Vertex_handle v2) const
{ CGAL_nef_assertion(mark(v1)==mark(v2)); }
void assert_equal_marks(SVertex_handle v1, SVertex_handle v2) const
{ CGAL_assertion(mark(v1)==mark(v2)); }
void assert_equal_marks(Halfedge_handle e1, Halfedge_handle e2) const
{ CGAL_nef_assertion(mark(e1)==mark(e2)); }
void assert_equal_marks(SHalfedge_handle e1, SHalfedge_handle e2) const
{ CGAL_assertion(mark(e1)==mark(e2)); }
Sphere_segment segment(Explorer N,
Halfedge_const_handle e) const
SHalfedge_const_handle e) const
{ return Sphere_segment(
N.point(N.source(e)),N.point(N.target(e)),N.circle(e)); }
Sphere_segment trivial_segment(Explorer N,
Vertex_const_handle v) const
SVertex_const_handle v) const
{ Sphere_point p = N.point(v);
return Sphere_segment(p,p); }
Seg_pair two_segments(Explorer N,
Halfedge_const_handle e) const
SHalfedge_const_handle e) const
// we know that source(e)==target(e)
{ return N.circle(e).split_at(N.point(N.source(e))); }
Seg_pair two_segments(Explorer N,
Halfloop_const_handle l) const
SHalfloop_const_handle l) const
{ return N.circle(l).split_at_xy_plane(); }
Mark& mark(Vertex_handle h) const
Mark& mark(SVertex_handle h) const
{ return Base::mark(h); }
Mark& mark(Halfedge_handle h) const
Mark& mark(SHalfedge_handle h) const
{ return Base::mark(h); }
Mark& mark(Halfloop_handle h) const
Mark& mark(SHalfloop_handle h) const
{ return Base::mark(h); }
Mark& mark(Face_handle h) const
Mark& mark(SFace_handle h) const
{ return Base::mark(h); }
const Mark& mark(Vertex_const_handle h) const
const Mark& mark(SVertex_const_handle h) const
{ return Base::mark(h); }
const Mark& mark(Halfedge_const_handle h) const
const Mark& mark(SHalfedge_const_handle h) const
{ return Base::mark(h); }
const Mark& mark(Halfloop_const_handle h) const
const Mark& mark(SHalfloop_const_handle h) const
{ return Base::mark(h); }
const Mark& mark(Face_const_handle h) const
const Mark& mark(SFace_const_handle h) const
{ return Base::mark(h); }
/*{\Mcreation 6}*/
SM_triangulator(const Sphere_map& M, Sphere_map& MT,
const Kernel& Kr = Kernel()) :
Base(MT), E_(const_cast<Sphere_map&>(M)), K(Kr) {}
SM_triangulator(const Map& M, Map& MT,
const Sphere_kernel& Kr = Sphere_kernel()) :
Base(&MT), E_(const_cast<Map*>(&M)), K(Kr) {}
/*{\Mcreate |\Mvar| is a triangulator object for the map |M|,
stores the triangulation in |MT|.}*/
@ -279,22 +285,22 @@ public:
void triangulate();
/*{\Mop produces a triangulated sphere map.}*/
void triangulate_per_hemisphere(Vertex_iterator start, Vertex_iterator end);
void triangulate_per_hemisphere(SVertex_iterator start, SVertex_iterator end);
template <typename Iterator, typename T>
void partition_to_halfsphere(Iterator start, Iterator end,
Seg_list& L, CGAL::Unique_hash_map<Iterator,T>& M, int pos) const;
void merge_halfsphere_maps(Vertex_handle v1, Vertex_handle v2) const;
void merge_nodes(Halfedge_handle e1, Halfedge_handle e2) const;
void complete_support(Vertex_iterator v_start, Vertex_iterator v_end,
int pos) const;
void merge_halfsphere_maps(SVertex_handle v1, SVertex_handle v2) const;
void merge_nodes(SHalfedge_handle e1, SHalfedge_handle e2) const;
void complete_support(SVertex_iterator v_start, SVertex_iterator v_end,
Mark mohs) const;
void correct_triangle_at(Vertex_handle v)
void correct_triangle_at(SVertex_handle v)
{ TRACEN("correct_triangle_at "<<PH(v));
if ( !has_outdeg_two(v) ) return;
Halfedge_handle e = first_out_edge(v);
CGAL_nef_assertion(next(next(next(e)))==e);
SHalfedge_handle e = first_out_edge(v);
CGAL_assertion(next(next(next(e)))==e);
flip_diagonal(next(e));
}
@ -302,17 +308,17 @@ public:
{ SM_io_parser<Explorer>::dump(E_,os);
SM_io_parser<Base>::dump(*this,os); }
Sphere_triangle incident_triangle(Halfedge_handle e) const
{ Halfedge_handle en(next(e)), enn(next(en));
CGAL_nef_assertion(next(enn)==e);
Sphere_triangle incident_triangle(SHalfedge_handle e) const
{ SHalfedge_handle en(next(e)), enn(next(en));
CGAL_assertion(next(enn)==e);
return Sphere_triangle(
point(source(e)),point(source(en)),point(source(enn)),
circle(e),circle(en),circle(enn));
}
Sphere_triangle incident_triangle(Halfedge_const_handle e) const
{ Halfedge_const_handle en(next(e)), enn(next(en));
CGAL_nef_assertion(next(enn)==e);
Sphere_triangle incident_triangle(SHalfedge_const_handle e) const
{ SHalfedge_const_handle en(next(e)), enn(next(en));
CGAL_assertion(next(enn)==e);
return Sphere_triangle(
point(source(e)),point(source(en)),point(source(enn)),
circle(e),circle(en),circle(enn));
@ -320,10 +326,10 @@ public:
void discard_info()
{
Vertex_iterator v;
Halfedge_iterator e;
CGAL_forall_vertices(v,*this) discard_info(v);
CGAL_forall_halfedges(e,*this) discard_info(e);
SVertex_iterator v;
SHalfedge_iterator e;
CGAL_forall_svertices(v,*this) discard_info(v);
CGAL_forall_shalfedges(e,*this) discard_info(e);
}
@ -336,14 +342,14 @@ void SM_triangulator<Decorator_>::triangulate()
// first create sphere segments from isoverts, edges, loops
Seg_list L;
Seg_map From;
Vertex_const_iterator v;
CGAL_forall_vertices(v,E_) {
SVertex_const_iterator v;
CGAL_forall_svertices(v,E_) {
if ( !E_.is_isolated(v) ) continue;
L.push_back(trivial_segment(E_,v));
From[--L.end()] = Object_handle(v);
}
Halfedge_const_iterator e;
CGAL_forall_edges(e,E_) {
SHalfedge_const_iterator e;
CGAL_forall_sedges(e,E_) {
if ( E_.source(e) == E_.target(e) ) {
Seg_pair p = two_segments(E_,e);
L.push_back(p.first); L.push_back(p.second);
@ -353,10 +359,10 @@ void SM_triangulator<Decorator_>::triangulate()
From[--L.end()] = Object_handle(e);
}
}
if ( E_.has_loop() ) {
Seg_pair p = two_segments(E_,E_.halfloop());
if ( E_.has_sloop() ) {
Seg_pair p = two_segments(E_,E_.shalfloop());
L.push_back(p.first); L.push_back(p.second);
From[--L.end()] = From[--(--L.end())] = Object_handle(E_.halfloop());
From[--L.end()] = From[--(--L.end())] = Object_handle(E_.shalfloop());
}
// partition segments from L to positive and negative hemisphere
@ -366,30 +372,30 @@ void SM_triangulator<Decorator_>::triangulate()
// sweep the hemispheres to create two half sphere maps
typedef SM_subdivision<Self,Seg_iterator,Object_handle> SM_output;
typedef typename Kernel::Positive_halfsphere_geometry PH_geometry;
typedef typename Sphere_kernel::Positive_halfsphere_geometry PH_geometry;
typedef CGAL::Segment_overlay_traits<
Seg_iterator, SM_output, PH_geometry> PHS_traits;
typedef CGAL::generic_sweep<PHS_traits> Positive_halfsphere_sweep;
typedef typename Kernel::Negative_halfsphere_geometry NH_geometry;
typedef typename Sphere_kernel::Negative_halfsphere_geometry NH_geometry;
typedef CGAL::Segment_overlay_traits<
Seg_iterator, SM_output, NH_geometry> NHS_traits;
typedef CGAL::generic_sweep<NHS_traits> Negative_halfsphere_sweep;
Vertex_handle v_sep;
Halfedge_handle e_sep;
SVertex_handle v_sep;
SHalfedge_handle e_sep;
SM_output O(*this,From);
typedef typename PHS_traits::INPUT Input_range;
Positive_halfsphere_sweep SP(
Input_range(L_pos.begin(),L_pos.end()),O,
K.get_positive_halfsphere_geometry());
PH_geometry());
SP.sweep();
v_sep=--vertices_end(); e_sep=--halfedges_end();
v_sep=--svertices_end(); e_sep=--shalfedges_end();
Negative_halfsphere_sweep SM(
Input_range(L_neg.begin(),L_neg.end()),O,
K.get_negative_halfsphere_geometry());
NH_geometry());
SM.sweep();
++v_sep; ++e_sep;
// now two CCs of sphere graph are calculated
@ -397,31 +403,33 @@ void SM_triangulator<Decorator_>::triangulate()
// e_sep = first edge of CC in negative x-sphere
// enrich the edges by circle information
Halfedge_iterator u;
CGAL_forall_edges(u,*this) {
SHalfedge_iterator u;
CGAL_forall_sedges(u,*this) {
Sphere_segment s(point(source(u)),point(target(u)));
circle(u) = s.sphere_circle();
circle(twin(u)) = s.sphere_circle().opposite();
}
// complete the support of per hemisphere
complete_support(vertices_begin(), v_sep, +1);
complete_support(v_sep, vertices_end(), -1);
Mark lower, upper;
SM_point_locator PL(E_.center_vertex());
PL.marks_of_halfspheres(lower,upper);
complete_support(svertices_begin(), v_sep, lower);
complete_support(v_sep, svertices_end(), upper);
// triangulate per hemisphere
typedef SM_constrained_triang_traits<Self,PH_geometry> PCT_traits;
typedef CGAL::generic_sweep<PCT_traits> Positive_halfsphere_ct_sweep;
typedef SM_constrained_triang_traits<Self,NH_geometry> NCT_traits;
typedef CGAL::generic_sweep<NCT_traits> Negative_halfsphere_ct_sweep;
typedef std::pair<Vertex_iterator,Vertex_iterator> Vertex_pair;
typedef std::pair<SVertex_iterator,SVertex_iterator> SVertex_pair;
Vertex_pair vpp(vertices_begin(),v_sep);
SVertex_pair vpp(svertices_begin(),v_sep);
Positive_halfsphere_ct_sweep PCTS(vpp, *this,
K.get_positive_halfsphere_geometry());
PH_geometry());
PCTS.sweep();
Vertex_pair vpn(v_sep,vertices_end());
SVertex_pair vpn(v_sep,svertices_end());
Negative_halfsphere_ct_sweep NCTS(vpn, *this,
K.get_negative_halfsphere_geometry());
NH_geometry());
NCTS.sweep();
/* Note the we divide the world along the xy equator and
@ -431,20 +439,20 @@ void SM_triangulator<Decorator_>::triangulate()
appear we repair it by flipping the edge opposite to the
vertex y-(y+).
*/
correct_triangle_at(vertices_begin());
correct_triangle_at(--Vertex_iterator(v_sep));
correct_triangle_at(svertices_begin());
correct_triangle_at(--SVertex_iterator(v_sep));
correct_triangle_at(v_sep);
correct_triangle_at(--vertices_end());
correct_triangle_at(--svertices_end());
// enrigh triangulation edges by circle information
CGAL_forall_edges(u,*this) {
CGAL_forall_sedges(u,*this) {
Sphere_segment s(point(source(u)),point(target(u)));
circle(u) = s.sphere_circle();
circle(twin(u)) = s.sphere_circle().opposite();
}
// merge the hemisphere maps into one sphere map
merge_halfsphere_maps(vertices_begin(),v_sep);
merge_halfsphere_maps(svertices_begin(),v_sep);
check_integrity_and_topological_planarity(false);
}
@ -455,7 +463,7 @@ void SM_triangulator<Decorator_>::
partition_to_halfsphere(Iterator start, Iterator beyond, Seg_list& L,
CGAL::Unique_hash_map<Iterator,T>& M, int pos) const
{ TRACEN("partition_to_halfsphere ");
CGAL_nef_assertion(pos!=0);
CGAL_assertion(pos!=0);
Sphere_segment s1,s2;
Sphere_circle xycircle(0,0,pos);
while ( start != beyond ) {
@ -521,13 +529,13 @@ partition_to_halfsphere(Iterator start, Iterator beyond, Seg_list& L,
template <typename Decorator_>
void SM_triangulator<Decorator_>::
merge_nodes(Halfedge_handle e1, Halfedge_handle e2) const
merge_nodes(SHalfedge_handle e1, SHalfedge_handle e2) const
{
Vertex_handle v1 = source(e1), v2 = target(e2);
SVertex_handle v1 = source(e1), v2 = target(e2);
TRACEN("merge_nodes "<<PH(v1)<<PH(v2));
CGAL_nef_assertion(point(v1)==point(v2));
Halfedge_handle ep1 = previous(e1), en2 = next(e2);
Halfedge_around_vertex_circulator eav(out_edges(v2)),ee(eav);
CGAL_assertion(point(v1)==point(v2));
SHalfedge_handle ep1 = previous(e1), en2 = next(e2);
SHalfedge_around_svertex_circulator eav(out_edges(v2)),ee(eav);
CGAL_For_all(eav,ee) { set_source(eav,v1); }
link_as_prev_next_pair(e2,e1);
link_as_prev_next_pair(ep1,en2);
@ -539,27 +547,27 @@ merge_nodes(Halfedge_handle e1, Halfedge_handle e2) const
template <typename Decorator_>
void SM_triangulator<Decorator_>::
merge_halfsphere_maps(Vertex_handle v1, Vertex_handle v2) const
merge_halfsphere_maps(SVertex_handle v1, SVertex_handle v2) const
{ TRACEN("merging halfspheres "<<PH(v1)<<PH(v2));
CGAL_nef_assertion(point(v1)==point(v2));
std::list<Halfedge_pair> L_equator;
Halfedge_around_face_circulator
CGAL_assertion(point(v1)==point(v2));
std::list<SHalfedge_pair> L_equator;
SHalfedge_around_sface_circulator
ep(last_out_edge(v1)), en(twin(first_out_edge(v2)));
do {
L_equator.push_back(Halfedge_pair(ep,en));
L_equator.push_back(SHalfedge_pair(ep,en));
merge_nodes(ep,en); ++ep; --en;
} while ( source(ep) != v1 );
typename std::list<Halfedge_pair>::iterator it;
typename std::list<SHalfedge_pair>::iterator it;
CGAL_forall_iterators(it,L_equator) {
Halfedge_handle e1 = it->first, e2 = it->second;
Halfedge_handle e1t = twin(e1), e2t = twin(e2);
SHalfedge_handle e1 = it->first, e2 = it->second;
SHalfedge_handle e1t = twin(e1), e2t = twin(e2);
TRACEV(PH(e1));TRACEV(PH(e2));
Halfedge_handle e2tp = previous(e2t);
Halfedge_handle e2tn = next(e2t);
SHalfedge_handle e2tp = previous(e2t);
SHalfedge_handle e2tn = next(e2t);
link_as_prev_next_pair(e2tp,e1);
link_as_prev_next_pair(e1,e2tn);
Face_handle f = face(e2t);
SFace_handle f = face(e2t);
if ( is_boundary_object(e2t) )
{ undo_boundary_object(e2t,f); store_boundary_object(e1,f); }
set_face(e1,f);
@ -572,30 +580,29 @@ merge_halfsphere_maps(Vertex_handle v1, Vertex_handle v2) const
template <typename Decorator_>
void SM_triangulator<Decorator_>::
complete_support(Vertex_iterator v_start, Vertex_iterator v_end, int pos) const
{
TRACEN("complete_support");
for (Vertex_iterator v = v_start; v != v_end; ++v) {
complete_support(SVertex_iterator v_start, SVertex_iterator v_end,
Mark mohs) const
{ TRACEN("complete_support");
Mark m_buffer(mohs);
for (SVertex_iterator v = v_start; v != v_end; ++v) {
TRACEN(" vertex = "<<PH(v));
Mark m_buffer;
Halfedge_handle e_below = halfedge_below(v);
if ( v == v_start ) {
m_buffer = E_.mark_of_halfsphere(-pos);
} else if ( e_below != Halfedge_handle() ) {
m_buffer = incident_mark(e_below);
} else { // e_below does not exist
/* this is only the case for a vertex v on the final equatorial
halfcircle; there we take the mark from an inedge edge into v */
CGAL_nef_assertion( point(v).z() == 0 &&
( pos > 0 ? (point(v).x() >= 0) : (point(v).x()<=0)) );
m_buffer = incident_mark(previous(first_out_edge(v)));
}
SHalfedge_handle e_below = halfedge_below(v);
if ( v != v_start )
if ( e_below != SHalfedge_handle() ) {
m_buffer = incident_mark(e_below);
} else { // e_below does not exist
/* this is only the case for a vertex v on the final equatorial
halfcircle; there we take the mark from an inedge edge into v */
// CGAL_assertion( point(v).z() == 0 &&
// ( pos > 0 ? (point(v).x() >= 0) : (point(v).x()<=0)) );
m_buffer = incident_mark(previous(first_out_edge(v)));
}
TRACEN(" face mark below "<<m_buffer);
Object_handle o = support(v);
Vertex_const_handle vs;
Halfedge_const_handle es;
Halfloop_const_handle ls;
SVertex_const_handle vs;
SHalfedge_const_handle es;
SHalfloop_const_handle ls;
if ( o == NULL ) { mark(v) = m_buffer; }
else if ( assign(vs,o) ) { mark(v) = E_.mark(vs); }
else if ( assign(es,o) ) {
@ -606,29 +613,29 @@ complete_support(Vertex_iterator v_start, Vertex_iterator v_end, int pos) const
else { mark(v) = E_.mark(es); }
}
else if ( assign(ls,o) ) { mark(v) = E_.mark(ls); }
else CGAL_nef_assertion_msg(0,"damn wrong support.");
else CGAL_assertion_msg(0,"damn wrong support.");
TRACEN(" face mark at "<<mark(v));
if ( is_isolated(v) ) continue;
Halfedge_around_vertex_circulator e(first_out_edge(v)), hend(e);
SHalfedge_around_svertex_circulator e(first_out_edge(v)), hend(e);
CGAL_For_all(e,hend) {
TRACEN(" edge "<<PH(e));
if ( !is_forward(e) ) break;
if ( support(e) != NULL ) {
Halfedge_const_handle ei;
SHalfedge_const_handle ei;
if ( assign(ei,support(e)) ) {
if ( E_.circle(ei) != circle(e) ) { ei = E_.twin(ei); }
CGAL_nef_assertion( E_.circle(ei) == circle(e) );
CGAL_assertion( E_.circle(ei) == circle(e) );
TRACEN(" supporting edge "<<PH(ei));
incident_mark(twin(e)) = E_.mark(E_.face(E_.twin(ei)));
mark(e) = E_.mark(ei);
incident_mark(e) = m_buffer = E_.mark(E_.face(ei));
}
Halfloop_const_handle li;
SHalfloop_const_handle li;
if ( assign(li,support(e)) ) {
if ( E_.circle(li) != circle(e) ) { li = E_.twin(li); }
CGAL_nef_assertion( E_.circle(li) == circle(e) );
CGAL_assertion( E_.circle(li) == circle(e) );
TRACEN(" supporting loop "<<PH(li));
incident_mark(twin(e)) = E_.mark(E_.face(E_.twin(li)));
mark(e) = E_.mark(li);

View File

@ -6,41 +6,38 @@
#include <CGAL/Nef_S2/SM_triangulator.h>
#include <CGAL/Nef_S2/Sphere_geometry_OGL.h>
#define CGAL_USING(t) typedef typename Sphere_map_::t t
//#define LGREY CGAL::Color(170,170,170)
//#define DGREY CGAL::Color(30,30,30)
#define LGREY CGAL::Color(170,170,200)
#define DGREY CGAL::Color(30,30,50)
CGAL_BEGIN_NAMESPACE
template <typename Sphere_map_>
template <typename Map_>
class SM_BooleColor
{
typedef typename Sphere_map_::Vertex_const_handle Vertex_const_handle;
typedef typename Sphere_map_::Halfedge_const_handle Halfedge_const_handle;
typedef typename Sphere_map_::Halfloop_const_handle Halfloop_const_handle;
typedef typename Sphere_map_::Face_const_handle Face_const_handle;
typedef typename Sphere_map_::Mark Mark;
typedef typename Map_::SVertex_const_handle SVertex_const_handle;
typedef typename Map_::SHalfedge_const_handle SHalfedge_const_handle;
typedef typename Map_::SHalfloop_const_handle SHalfloop_const_handle;
typedef typename Map_::SFace_const_handle SFace_const_handle;
typedef typename Map_::Mark Mark;
public:
Color color(Vertex_const_handle, Mark m) const
Color color(SVertex_const_handle, Mark m) const
{ return ( m ? CGAL::BLACK : CGAL::WHITE ); }
Color color(Halfedge_const_handle, Mark m) const
Color color(SHalfedge_const_handle, Mark m) const
{ return ( m ? CGAL::BLACK : CGAL::WHITE ); }
Color color(Halfloop_const_handle, Mark m) const
Color color(SHalfloop_const_handle, Mark m) const
{ return ( m ? CGAL::BLACK : CGAL::WHITE ); }
Color color(Face_const_handle, Mark m) const
Color color(SFace_const_handle, Mark m) const
{ return ( m ? DGREY : LGREY ); }
};
/*{\Moptions outfile=SM_visualizor.man }*/
/*{\Manpage {SM_visualizor}{Sphere_map_,Sphere_kernel_}
/*{\Manpage {SM_visualizor}{Map_,Sphere_kernel_}
{Drawing plane maps}{V}}*/
template <typename Sphere_map_, typename Sphere_kernel_,
typename Color_ = SM_BooleColor<Sphere_map_> >
template <typename Map_, typename Sphere_kernel_,
typename Color_ = SM_BooleColor<Map_> >
class SM_visualizor : public
SM_triangulator< SM_decorator<Sphere_map_,Sphere_kernel_> >
SM_triangulator< SM_decorator<Map_> >
{
/*{\Mdefinition An instance |\Mvar| of the data type |\Mname| is a
decorator to draw the structure of a sphere map into the surface
@ -50,42 +47,41 @@ concept.}*/
/*{\Mgeneralization SM_decorator}*/
/*{\Mtypes 3}*/
public:
typedef Sphere_map_ Sphere_map;
typedef Map_ Map;
typedef Sphere_kernel_ Sphere_kernel;
typedef SM_visualizor<Sphere_map_,Sphere_kernel_,Color_> Self;
typedef SM_const_decorator<Sphere_map_,Sphere_kernel_> Explorer;
typedef SM_decorator<Sphere_map_,Sphere_kernel_> Decorator;
typedef SM_triangulator<Decorator> Base;
typedef SM_visualizor<Map_,Sphere_kernel_,Color_> Self;
typedef SM_const_decorator<Map_> Explorer;
typedef SM_decorator<Map_> Decorator;
typedef SM_triangulator<Decorator> Base;
CGAL_USING(Vertex_const_handle);
CGAL_USING(Halfedge_const_handle);
CGAL_USING(Face_const_handle);
CGAL_USING(Vertex_const_iterator);
CGAL_USING(Halfedge_const_iterator);
CGAL_USING(Face_const_iterator);
CGAL_USING(Mark);
typedef typename Map_::SVertex_const_handle SVertex_const_handle;
typedef typename Map_::SHalfedge_const_handle SHalfedge_const_handle;
typedef typename Map_::SFace_const_handle SFace_const_handle;
typedef typename Map_::SVertex_const_iterator SVertex_const_iterator;
typedef typename Map_::SHalfedge_const_iterator SHalfedge_const_iterator;
typedef typename Map_::SFace_const_iterator SFace_const_iterator;
typedef typename Map_::Mark Mark;
typedef typename Sphere_kernel::Sphere_point Sphere_point;
typedef typename Sphere_kernel::Sphere_segment Sphere_segment;
typedef typename Sphere_kernel::Sphere_circle Sphere_circle;
typedef typename Sphere_kernel::Sphere_triangle Sphere_triangle;
typedef Color_ Color_objects;
/*{\Mtypemember The color data accessor.}*/
typedef Color_ Color_objects;
protected:
Explorer E_;
const Color_objects& CO_;
Sphere_map MT_;
Map MT_;
CGAL::OGL::Unit_sphere& S_;
public:
/*{\Mcreation 4}*/
SM_visualizor(const Sphere_map& M, CGAL::OGL::Unit_sphere& S,
SM_visualizor(const Map& M, CGAL::OGL::Unit_sphere& S,
const Color_objects& C = Color_objects())
/*{\Mcreate creates an instance |\Mvar| of type |\Mname| to visualize
the vertices, edges, and faces of |D| in an open GL window.}*/
: Base(M,MT_), E_(M), CO_(C), MT_(), S_(S)
: Base(M,MT_), E_(&M), CO_(C), MT_(), S_(S)
{ triangulate(); }
/*{\Moperations 2 1}*/
@ -98,8 +94,8 @@ void draw_map() const
/*{\Mop draw the whole plane map.}*/
{
// draw sphere segments underlying edges of E_:
Halfedge_const_iterator e;
CGAL_forall_edges(e,E_) {
SHalfedge_const_iterator e;
CGAL_forall_sedges(e,E_) {
if ( source(e) == target(e) ) {
S_.push_back(E_.circle(e), CO_.color(e,E_.mark(e)));
} else {
@ -110,23 +106,23 @@ void draw_map() const
}
// draw sphere circles underlying loops of E_:
if ( E_.has_loop() )
if ( E_.has_sloop() )
S_.push_back(
Sphere_circle(E_.circle(E_.halfloop())),
CO_.color(E_.halfloop(),E_.mark(E_.halfloop())));
Sphere_circle(E_.circle(E_.shalfloop())),
CO_.color(E_.shalfloop(),E_.mark(E_.shalfloop())));
// draw points underlying vertices of E_:
Vertex_const_iterator v;
CGAL_forall_vertices(v,E_)
SVertex_const_iterator v;
CGAL_forall_svertices(v,E_)
S_.push_back(E_.point(v),CO_.color(v,E_.mark(v)));
Unique_hash_map<Halfedge_const_iterator,bool> Done(false);
CGAL_forall_halfedges(e,*this) {
Unique_hash_map<SHalfedge_const_iterator,bool> Done(false);
CGAL_forall_shalfedges(e,*this) {
if ( Done[e] ) continue;
Halfedge_const_handle en(next(e)),enn(next(en));
SHalfedge_const_handle en(next(e)),enn(next(en));
TRACEV(Base::incident_triangle(e));
TRACEN(incident_mark(e)<<incident_mark(en)<<incident_mark(enn));
CGAL_nef_assertion(Base::incident_mark(e)==Base::incident_mark(en) &&
CGAL_assertion(Base::incident_mark(e)==Base::incident_mark(en) &&
Base::incident_mark(en)==Base::incident_mark(enn));
Mark m = Base::incident_mark(e);
Sphere_triangle t = Base::incident_triangle(e);
@ -135,7 +131,7 @@ void draw_map() const
}
Done.clear(false);
CGAL_forall_halfedges(e,*this) {
CGAL_forall_shalfedges(e,*this) {
if ( Done[e] ) continue;
S_.push_back_triangle_edge(Sphere_segment(E_.point(E_.source(e)),
E_.point(E_.target(e)),
@ -152,22 +148,22 @@ void draw_map() const
void draw_triangulation() const
{
// draw sphere segments underlying edges of triangulation:
Halfedge_const_iterator e;
CGAL_forall_edges(e,*this) {
SHalfedge_const_iterator e;
CGAL_forall_sedges(e,*this) {
S_.push_back(Sphere_segment(point(source(e)),point(target(e)),
circle(e)),CO_.color(e,mark(e)));
}
// draw points underlying vertices of triangulation:
Vertex_const_iterator v;
CGAL_forall_vertices(v,*this)
SVertex_const_iterator v;
CGAL_forall_svertices(v,*this)
S_.push_back(point(v),CO_.color(v,mark(v)));
Done.clear(false);
CGAL_forall_halfedges(e,*this) {
Unique_hash_map<SHalfedge_const_iterator,bool> Done(false);
CGAL_forall_shalfedges(e,*this) {
if ( Done[e] ) continue;
Halfedge_const_handle en(next(e)),enn(next(en));
CGAL_nef_assertion(incident_mark(e)==incident_mark(en)&&
SHalfedge_const_handle en(next(e)),enn(next(en));
CGAL_assertion(incident_mark(e)==incident_mark(en)&&
incident_mark(en)==incident_mark(enn));
Mark m = incident_mark(e);
Sphere_triangle t = incident_triangle(e);

View File

@ -2,7 +2,7 @@
#define CGAL_SPHERE_CIRCLE_H
#include <CGAL/basic.h>
#include <CGAL/Nef_3/Infimaximal_box.h>
#include <CGAL/Nef_3/Normalizing.h>
CGAL_BEGIN_NAMESPACE
@ -34,8 +34,6 @@ typedef typename R_::Point_3 Point_3;
typedef Sphere_circle<R_> Self;
typedef typename R_::Plane_3 Base;
typedef Infimaximal_box<typename Is_extended_kernel<R_>::value_type, R_> Infi_box;
/*{\Mcreation 5}*/
Sphere_circle() : Base() {}
/*{\Mcreate creates some great circle.}*/
@ -69,8 +67,6 @@ create any great circle that contains $p$ and $q$.}*/
circle parallel to |h| containing the origin.}*/
{
if(h.d() != 0) *this = Plane_3(h.a(),h.b(),h.c(),RT(0));
// if(h.a().degree() != 0 || h.b().degree() != 0 || h.c().degree() != 0) *this = normalized(*this);
if(Infi_box::degree(h.a()) != 0 || Infi_box::degree(h.b()) != 0 || Infi_box::degree(h.c()) != 0) *this = normalized(*this);
}
Sphere_circle(const RT& x, const RT& y, const RT& z): Base(x,y,z,0) {}

View File

@ -37,7 +37,8 @@ typedef CGAL::Sphere_segment<R> Segment_2;
int axis;
Positive_halfsphere_geometry(int check_sphere=2) : axis(check_sphere) {}
Positive_halfsphere_geometry() : axis(2) {}
Positive_halfsphere_geometry(int check_sphere) : axis(check_sphere) {}
Point_2 source(const Segment_2& s) const
{ return s.source(); }
@ -96,7 +97,8 @@ int orientation(const Segment_2& s, const Point_2& p) const
bool is_degenerate(const Segment_2& s) const
{ return s.is_degenerate(); }
int compare_xy(const Point_2& p1, const Point_2& p2) const {
int compare_xy(const Point_2& p1, const Point_2& p2) const {
TRACEN("compare_xy " << axis << ":" << p1 << " / " << p2);
return CGAL::spherical_compare(p1,p2,axis,+1);
}
@ -117,6 +119,7 @@ typedef Positive_halfsphere_geometry<R> Base;
typedef typename Base::Point_2 Point_2;
typedef typename Base::Segment_2 Segment_2;
Negative_halfsphere_geometry() : Base() {}
Negative_halfsphere_geometry(int check_sphere) : Base(check_sphere) {}
int orientation(const Point_2& p1, const Point_2& p2,
@ -293,16 +296,17 @@ Point_2 intersection(const Segment_2& s1, const Segment_2& s2) const
template <typename R_>
struct Sphere_geometry {
typedef R_ R;
typedef typename R_::RT RT;
typedef typename R_::FT FT;
typedef CGAL::Sphere_point<R> Sphere_point;
typedef CGAL::Sphere_segment<R> Sphere_segment;
typedef CGAL::Sphere_circle<R> Sphere_circle;
typedef CGAL::Sphere_direction<R> Sphere_direction;
typedef CGAL::Sphere_triangle<R> Sphere_triangle;
typedef CGAL::Point_3<R> Point_3;
typedef CGAL::Plane_3<R> Plane_3;
typedef R_ R;
typedef typename R_::RT RT;
typedef typename R_::FT FT;
typedef CGAL::Sphere_point<R> Sphere_point;
typedef CGAL::Sphere_segment<R> Sphere_segment;
typedef CGAL::Sphere_circle<R> Sphere_circle;
typedef CGAL::Sphere_direction<R> Sphere_direction;
typedef CGAL::Sphere_triangle<R> Sphere_triangle;
typedef CGAL::Point_3<R> Point_3;
typedef CGAL::Plane_3<R> Plane_3;
typedef CGAL::Aff_transformation_3<R> Aff_transformation_3;
typedef Positive_halfsphere_geometry<R> Positive_halfsphere_geometry;
typedef Negative_halfsphere_geometry<R> Negative_halfsphere_geometry;
typedef Fullsphere_geometry<R> Fullsphere_geometry;

View File

@ -23,10 +23,10 @@
#include <CGAL/basic.h>
#include <CGAL/Unique_hash_map.h>
#include <CGAL/Nef_2/Object_handle.h>
#include <CGAL/Nef_S2/nef_assertions.h>
#include <CGAL/Nef_S2/SM_items.h>
#include <CGAL/Nef_S2/SM_iteration.h>
#include <CGAL/Nef_S2/Generic_handle_map.h>
#include <CGAL/Nef_2/iterator_tools.h>
#include <list>
#undef _DEBUG
#define _DEBUG 109
@ -34,9 +34,22 @@
CGAL_BEGIN_NAMESPACE
template <typename HE>
class move_edge_around_svertex {
public:
void forward(HE& e) const { e = (e->sprev_->twin_); }
void backward(HE& e) const { e = (e->twin_->snext_); }
};
template <typename HE>
struct move_edge_around_sface {
void forward(HE& e) const { e = (e->snext_); }
void backward(HE& e) const { e = (e->sprev_); }
};
/*{\Manpage {Sphere_map}{Kernel}{Sphere Maps}{M}}*/
template <typename Kernel_>
template <typename Kernel_, typename Items_>
class Sphere_map {
/*{\Mdefinition selective sphere map container based on
@ -44,18 +57,23 @@ the HDS design of Kettner.}*/
public:
/*{\Mtypes 7}*/
typedef Kernel_ Kernel;
typedef Sphere_map<Kernel_> Self;
typedef SM_items<Kernel_,bool> Items;
typedef Kernel_ Sphere_kernel;
typedef Items_ Items;
typedef Sphere_map<Kernel_, Items_> Self;
// typedef SM_items<Kernel_,bool> Items;
friend class SM_const_decorator<Self>;
friend class SM_decorator<Self>;
friend class SM_const_decorator<Self,Kernel>;
friend class SM_decorator<Self,Kernel>;
typedef typename Kernel::Sphere_point Sphere_point;
/*{\Mtypemember embedding vertices.}*/
typedef typename Kernel::Sphere_circle Sphere_circle;
/*{\Mtypemember embedding edges.}*/
typedef bool Mark;
typedef typename Sphere_kernel::Sphere_point Sphere_point;
/*{\Mtypemember points on the unit sphere.}*/
typedef typename Sphere_kernel::Sphere_segment Sphere_segment;
/*{\Mtypemember segments on the unit sphere.}*/
typedef typename Sphere_kernel::Sphere_circle Sphere_circle;
/*{\Mtypemember segments on the unit sphere.}*/
typedef typename Sphere_kernel::Sphere_direction Sphere_direction;
/*{\Mtypemember directions on the unit sphere.}*/
typedef typename Items::Mark Mark;
/*{\Mtypemember selective attributes of all objects.}*/
typedef size_t Size_type;
/*{\Mtypemember size type.}*/
@ -65,32 +83,35 @@ public:
There's no type |SLoop_iterator|, as there is
at most one |SLoop| pair per sphere map.}*/
typedef typename Items::template Vertex<Self> Vertex;
typedef CGAL::In_place_list<Vertex,false> Vertex_list;
typedef typename Vertex_list::iterator Vertex_handle;
typedef typename Vertex_list::const_iterator Vertex_const_handle;
typedef typename Vertex_list::iterator Vertex_iterator;
typedef typename Vertex_list::const_iterator Vertex_const_iterator;
typedef typename Items::template SVertex<Self> SVertex;
typedef CGAL::In_place_list<SVertex,false> SVertex_list;
typedef CGAL_ALLOCATOR(SVertex) SVertex_alloc;
typedef typename SVertex_list::iterator SVertex_handle;
typedef typename SVertex_list::const_iterator SVertex_const_handle;
typedef typename SVertex_list::iterator SVertex_iterator;
typedef typename SVertex_list::const_iterator SVertex_const_iterator;
typedef typename Items::template Halfedge<Self> Halfedge;
typedef CGAL::In_place_list<Halfedge,false> Halfedge_list;
typedef typename Halfedge_list::iterator Halfedge_handle;
typedef typename Halfedge_list::const_iterator Halfedge_const_handle;
typedef typename Halfedge_list::iterator Halfedge_iterator;
typedef typename Halfedge_list::const_iterator Halfedge_const_iterator;
typedef typename Items::template SHalfedge<Self> SHalfedge;
typedef CGAL::In_place_list<SHalfedge,false> SHalfedge_list;
typedef CGAL_ALLOCATOR(SHalfedge) SHalfedge_alloc;
typedef typename SHalfedge_list::iterator SHalfedge_handle;
typedef typename SHalfedge_list::const_iterator SHalfedge_const_handle;
typedef typename SHalfedge_list::iterator SHalfedge_iterator;
typedef typename SHalfedge_list::const_iterator SHalfedge_const_iterator;
typedef typename Items::template Face<Self> Face;
typedef CGAL::In_place_list<Face,false> Face_list;
typedef typename Face_list::iterator Face_handle;
typedef typename Face_list::const_iterator Face_const_handle;
typedef typename Face_list::iterator Face_iterator;
typedef typename Face_list::const_iterator Face_const_iterator;
typedef typename Items::template SFace<Self> SFace;
typedef CGAL::In_place_list<SFace,false> SFace_list;
typedef CGAL_ALLOCATOR(SFace) SFace_alloc;
typedef typename SFace_list::iterator SFace_handle;
typedef typename SFace_list::const_iterator SFace_const_handle;
typedef typename SFace_list::iterator SFace_iterator;
typedef typename SFace_list::const_iterator SFace_const_iterator;
typedef typename Items::template Halfloop<Self> Halfloop;
typedef Halfloop* Halfloop_handle;
typedef const Halfloop* Halfloop_const_handle;
typedef Halfloop* Halfloop_iterator;
typedef const Halfloop* Halfloop_const_iterator;
typedef typename Items::template SHalfloop<Self> SHalfloop;
typedef SHalfloop* SHalfloop_handle;
typedef const SHalfloop* SHalfloop_const_handle;
typedef SHalfloop* SHalfloop_iterator;
typedef const SHalfloop* SHalfloop_const_iterator;
typedef CGAL::Object_handle Object_handle;
/*{\Mtypemember a generic handle to an object of |\Mvar|.
@ -100,113 +121,142 @@ public:
where the function returns |true| iff the assignment of |o| to
|h| was valid.}*/
typedef std::list<Object_handle> Object_list;
typedef std::list<Object_handle> Object_list;
typedef typename Object_list::iterator Object_iterator;
typedef typename Object_list::const_iterator Object_const_iterator;
typedef Generic_handle_map<Object_iterator> Handle_to_iterator_map;
typedef Generic_handle_map<Object_iterator> Handle_to_iterator_map;
class Face_cycle_iterator : public Object_iterator
typedef Sphere_map* Constructor_parameter;
typedef const Sphere_map* Constructor_const_parameter;
Sphere_map* map() { return this; }
class SFace_cycle_iterator : public Object_iterator
/*{\Mtypemember a generic iterator to an object in the boundary
of a facet. Convertible to |Object_handle|.}*/
{ typedef Object_iterator Ibase;
public:
Face_cycle_iterator() : Ibase() {}
Face_cycle_iterator(const Ibase& b) : Ibase(b) {}
Face_cycle_iterator(const Face_cycle_iterator& i) : Ibase(i) {}
bool is_vertex() const
{ Vertex_handle v; return CGAL::assign(v,Ibase::operator*()); }
bool is_halfedge() const
{ Halfedge_handle e; return CGAL::assign(e,Ibase::operator*()); }
bool is_halfloop() const
{ Halfloop_handle l; return CGAL::assign(l,Ibase::operator*()); }
operator Vertex_handle() const
{ Vertex_handle v; CGAL::assign(v,Ibase::operator*()); return v; }
operator Halfedge_handle() const
{ Halfedge_handle e; CGAL::assign(e,Ibase::operator*()); return e; }
operator Halfloop_handle() const
{ Halfloop_handle l; CGAL::assign(l,Ibase::operator*()); return l; }
SFace_cycle_iterator() : Ibase() {}
SFace_cycle_iterator(const Ibase& b) : Ibase(b) {}
SFace_cycle_iterator(const SFace_cycle_iterator& i) : Ibase(i) {}
bool is_svertex() const
{ SVertex_handle v; return CGAL::assign(v,Ibase::operator*()); }
bool is_shalfedge() const
{ SHalfedge_handle e; return CGAL::assign(e,Ibase::operator*()); }
bool is_shalfloop() const
{ SHalfloop_handle l; return CGAL::assign(l,Ibase::operator*()); }
operator SVertex_handle() const
{ SVertex_handle v; CGAL::assign(v,Ibase::operator*()); return v; }
operator SHalfedge_handle() const
{ SHalfedge_handle e; CGAL::assign(e,Ibase::operator*()); return e; }
operator SHalfloop_handle() const
{ SHalfloop_handle l; CGAL::assign(l,Ibase::operator*()); return l; }
operator Object_handle() const { return Ibase::operator*(); }
Object_handle& operator*() const { return Ibase::operator*(); }
Object_handle operator->() const
{ CGAL_nef_assertion_msg(0,"not impl."); }
{ CGAL_assertion_msg(0,"not impl."); }
};
class Face_cycle_const_iterator : public Object_const_iterator
class SFace_cycle_const_iterator : public Object_const_iterator
/*{\Mtypemember a generic iterator to an object in the boundary
of a facet. Convertible to |Object_handle|.}*/
{ typedef Object_const_iterator Ibase;
public:
Face_cycle_const_iterator() : Ibase() {}
Face_cycle_const_iterator(const Ibase& b) : Ibase(b) {}
Face_cycle_const_iterator(const Face_cycle_const_iterator& i)
SFace_cycle_const_iterator() : Ibase() {}
SFace_cycle_const_iterator(const Ibase& b) : Ibase(b) {}
SFace_cycle_const_iterator(const SFace_cycle_const_iterator& i)
: Ibase(i) {}
bool is_vertex() const
{ Vertex_handle v; return CGAL::assign(v,Ibase::operator*()); }
bool is_halfedge() const
{ Halfedge_handle e; return CGAL::assign(e,Ibase::operator*()); }
bool is_halfloop() const
{ Halfloop_handle l; return CGAL::assign(l,Ibase::operator*()); }
operator Vertex_const_handle() const
{ Vertex_handle v; CGAL::assign(v,Ibase::operator*());
return Vertex_const_handle(v); }
operator Halfedge_const_handle() const
{ Halfedge_handle e; CGAL::assign(e,Ibase::operator*());
return Halfedge_const_handle(e); }
operator Halfloop_const_handle() const
{ Halfloop_handle l; CGAL::assign(l,Ibase::operator*());
return Halfloop_const_handle(l); }
bool is_svertex() const
{ SVertex_handle v; return CGAL::assign(v,Ibase::operator*()); }
bool is_shalfedge() const
{ SHalfedge_handle e; return CGAL::assign(e,Ibase::operator*()); }
bool is_shalfloop() const
{ SHalfloop_handle l; return CGAL::assign(l,Ibase::operator*()); }
operator SVertex_const_handle() const
{ SVertex_handle v; CGAL::assign(v,Ibase::operator*());
return SVertex_const_handle(v); }
operator SHalfedge_const_handle() const
{ SHalfedge_handle e; CGAL::assign(e,Ibase::operator*());
return SHalfedge_const_handle(e); }
operator SHalfloop_const_handle() const
{ SHalfloop_handle l; CGAL::assign(l,Ibase::operator*());
return SHalfloop_const_handle(l); }
operator Object_handle() const { return Ibase::operator*(); }
const Object_handle& operator*() const { return Ibase::operator*(); }
Object_handle operator->() const
{ CGAL_nef_assertion_msg(0,"not impl."); }
{ CGAL_assertion_msg(0,"not impl."); }
};
/*{\Mtext Local types are handles, iterators and circulators of the
following kind: |SVertex_handle|, |SVertex_iterator|, |SHalfedge_handle|,
|SHalfedge_iterator|, |SHalfloop_handle|, |SHalfloop_iterator|,
|SFace_handle|, |SFace_iterator|. Additionally the following
circulators are defined.}*/
typedef CircFromIt<
SHalfedge_const_iterator,
move_edge_around_svertex<SHalfedge_const_iterator> >
SHalfedge_around_svertex_const_circulator;
/*{\Mtypemember circulating the adjacency list of an vertex |v|.}*/
typedef CircFromIt<
SHalfedge_const_iterator,
move_edge_around_sface<SHalfedge_const_iterator> >
SHalfedge_around_sface_const_circulator;
/*{\Mtypemember circulating the face cycle of an face |f|.}*/
typedef CircFromIt<
SHalfedge_iterator,
move_edge_around_svertex<SHalfedge_iterator> >
SHalfedge_around_svertex_circulator;
/*{\Mtypemember circulating the adjacency list of an vertex |v|.}*/
typedef CircFromIt<
SHalfedge_iterator,
move_edge_around_sface<SHalfedge_iterator> >
SHalfedge_around_sface_circulator;
/*{\Mtypemember circulating the face cycle of an face |f|.}*/
/*{\Mcreation 3}*/
/*{\Mtext |\Mname| is default and copy constructible. Note that copy
construction means cloning an isomorphic structure and is thus an
expensive operation.}*/
Sphere_map() : boundary_item_(undef_),
vertices_(), edges_(), faces_(), loops_(0)
{ m_pos_ = m_neg_ = Mark(); }
svertices_(), sedges_(), sfaces_(), shalfloop_(0) {}
~Sphere_map() { clear(); }
Sphere_map(const Self& D) : boundary_item_(undef_),
vertices_(D.vertices_),
// edges_(D.edges_),
faces_(D.faces_),
loops_(0)
{ if ( D.loops_ != 0 ) new_halfloop_pair(*(D.loops_));
Halfedge_const_iterator e;
CGAL_forall_edges(e,D) new_halfedge_pair(*e);
svertices_(D.svertices_),
sedges_(D.sedges_),
sfaces_(D.sfaces_),
shalfloop_(0)
{ if ( D.shalfloop_ != 0 ) new_shalfloop_pair(*(D.shalfloop_));
pointer_update(D);
m_pos_ = D.m_pos_; m_neg_ = D.m_neg_; }
}
Self& operator=(const Self& D)
{ if ( this == &D ) return *this;
clear();
vertices_ = D.vertices_;
faces_ = D.faces_;
Halfedge_const_iterator e;
CGAL_forall_edges(e,D) new_halfedge_pair(*e);
if ( D.loops_ != 0 ) new_halfloop_pair(*D.loops_);
svertices_ = D.svertices_;
sfaces_ = D.sfaces_;
sedges_ = D.sedges_;
if ( D.shalfloop_ != 0 ) new_shalfloop_pair(*D.shalfloop_);
pointer_update(D);
m_pos_ = D.m_pos_; m_neg_ = D.m_neg_;
return *this;
}
void clear()
{
boundary_item_.clear(undef_);
vertices_.destroy();
faces_.destroy();
while ( halfedges_begin() != halfedges_end() )
delete_halfedge_pair( halfedges_begin() );
if ( loops_ != 0 ) { delete_halfloop_pair(loops_); loops_=0; }
m_pos_ = m_neg_ = Mark();
svertices_.destroy();
sfaces_.destroy();
while ( shalfedges_begin() != shalfedges_end() )
delete_halfedge_pair( shalfedges_begin() );
if ( shalfloop_ != 0 ) { delete_halfloop_pair(shalfloop_); shalfloop_=0; }
}
template <typename H>
@ -223,13 +273,13 @@ public:
template <typename H>
void undef_boundary_item(H h)
{ CGAL_nef_assertion(boundary_item_[h]!=undef_);
{ CGAL_assertion(boundary_item_[h]!=undef_);
boundary_item_[h] = undef_; }
void reset_iterator_hash(Object_iterator it)
{ Vertex_handle sv;
Halfedge_handle se;
Halfloop_handle sl;
{ SVertex_handle sv;
SHalfedge_handle se;
SHalfloop_handle sl;
if ( assign(se,*it) ) { undef_boundary_item(se); return; }
if ( assign(sl,*it) ) { undef_boundary_item(sl); return; }
if ( assign(sv,*it) ) { undef_boundary_item(sv); return; }
@ -244,134 +294,177 @@ public:
/*{\Moperations 2.5 3}*/
// The constant iterators and circulators.
Vertex_const_iterator vertices_begin() const { return vertices_.begin();}
Vertex_const_iterator vertices_end() const { return vertices_.end();}
Halfedge_const_iterator halfedges_begin() const { return edges_.begin();}
Halfedge_const_iterator halfedges_end() const { return edges_.end();}
Halfloop_const_iterator halfloops_begin() const { return loops_; }
Halfloop_const_iterator halfloops_end() const
{ return loops_ != 0 ? loops_+2 : loops_; }
Face_const_iterator faces_begin() const { return faces_.begin();}
Face_const_iterator faces_end() const { return faces_.end();}
SVertex_const_iterator svertices_begin() const { return svertices_.begin();}
SVertex_const_iterator svertices_end() const { return svertices_.end();}
SHalfedge_const_iterator shalfedges_begin() const { return sedges_.begin();}
SHalfedge_const_iterator shalfedges_end() const { return sedges_.end();}
SHalfloop_const_iterator shalfloops_begin() const { return shalfloop_; }
SHalfloop_const_iterator shalfloops_end() const
{ return shalfloop_ != 0 ? shalfloop_+2 : shalfloop_; }
SFace_const_iterator sfaces_begin() const { return sfaces_.begin();}
SFace_const_iterator sfaces_end() const { return sfaces_.end();}
Vertex_iterator vertices_begin() { return vertices_.begin();}
Vertex_iterator vertices_end() { return vertices_.end();}
Halfedge_iterator halfedges_begin() { return edges_.begin();}
Halfedge_iterator halfedges_end() { return edges_.end();}
Halfloop_iterator halfloops_begin() { return loops_; }
Halfloop_iterator halfloops_end()
{ return loops_ != 0 ? loops_+2 : loops_; }
Face_iterator faces_begin() { return faces_.begin();}
Face_iterator faces_end() { return faces_.end();}
SVertex_iterator svertices_begin() { return svertices_.begin();}
SVertex_iterator svertices_end() { return svertices_.end();}
SHalfedge_iterator shalfedges_begin() { return sedges_.begin();}
SHalfedge_iterator shalfedges_end() { return sedges_.end();}
SHalfloop_iterator shalfloops_begin() { return shalfloop_; }
SHalfloop_iterator shalfloops_end()
{ return shalfloop_ != 0 ? shalfloop_+2 : shalfloop_; }
SFace_iterator sfaces_begin() { return sfaces_.begin();}
SFace_iterator sfaces_end() { return sfaces_.end();}
Face_cycle_const_iterator face_cycles_begin(Face_const_handle f) const
{ return f->face_cycles_begin(); }
Face_cycle_const_iterator face_cycles_end(Face_const_handle f) const
{ return f->face_cycles_end(); }
Face_cycle_iterator face_cycles_begin(Face_handle f) const
{ return f->face_cycles_begin(); }
Face_cycle_iterator face_cycles_end(Face_handle f) const
{ return f->face_cycles_end(); }
SFace_cycle_const_iterator sface_cycles_begin(SFace_const_handle f) const
{ return f->sface_cycles_begin(); }
SFace_cycle_const_iterator sface_cycles_end(SFace_const_handle f) const
{ return f->sface_cycles_end(); }
SFace_cycle_iterator sface_cycles_begin(SFace_handle f) const
{ return f->sface_cycles_begin(); }
SFace_cycle_iterator sface_cycles_end(SFace_handle f) const
{ return f->sface_cycles_end(); }
/*{\Mtext The list of all objects can be accessed via iterator ranges.
For comfortable iteration we also provide iterations macros.
The iterator range access operations are of the following kind:\\
|Vertex_iterator vertices_begin()/vertices_end()|\\
|Halfedge_iterator halfedges_begin()/halfedges_end()|\\
|Halfloop_iterator halfloops_begin()/halfloops_end()|\\
|Face_iterator faces_begin()/faces_end()|
|SVertex_iterator vertices_begin()/vertices_end()|\\
|SHalfedge_iterator halfedges_begin()/halfedges_end()|\\
|SHalfloop_iterator halfloops_begin()/halfloops_end()|\\
|SFace_iterator faces_begin()/faces_end()| */
The macros are then |CGAL_forall_vertices(v,\Mvar)|,
|CGAL_forall_halfedges(e,\Mvar)|,
|CGAL_forall_halfloops(l,\Mvar)|,
|CGAL_forall_faces(f,\Mvar)|.}*/
Size_type number_of_vertices() const { return vertices_.size();}
Size_type number_of_svertices() const { return svertices_.size();}
/*{\Mop returns the number of vertices.}*/
Size_type number_of_halfedges() const { return edges_.size();}
Size_type number_of_shalfedges() const { return sedges_.size();}
/*{\Mop returns the number of (directed edges).}*/
Size_type number_of_faces() const { return faces_.size();}
Size_type number_of_sfaces() const { return sfaces_.size();}
/*{\Mop returns the number of facets.}*/
Size_type number_of_halfloops() const
{ return loops_!=Halfloop_handle() ? 2 : 0; }
/*{\Mop returns the number of sloops.}*/
Size_type number_of_shalfloops() const
{ return shalfloop_!=SHalfloop_handle() ? 2 : 0; }
/*{\Mop returns the number of shalfloop.}*/
bool empty() const
{ return number_of_vertices() == 0 &&
number_of_halfedges() == 0 &&
number_of_halfloops() == 0 &&
number_of_faces() == 0;
{ return number_of_svertices() == 0 &&
number_of_shalfedges() == 0 &&
number_of_shalfloops() == 0 &&
number_of_sfaces() == 0;
}
Vertex_handle new_vertex(const Sphere_point& p,
bool has_sloop() const {
return shalfloop_ != 0;
}
SHalfloop_handle shalfloop() const {
return shalfloop_;
}
SVertex_alloc vertex_allocator;
SVertex* get_vertex_node( const SVertex& t) {
SVertex* p = vertex_allocator.allocate(1);
vertex_allocator.construct( p, SVertex());
return p;
}
void put_vertex_node( SVertex* p) {
vertex_allocator.destroy(p);
vertex_allocator.deallocate( p, 1);
}
SHalfedge_alloc halfedge_allocator;
SHalfedge* get_halfedge_node( const SHalfedge& t) {
SHalfedge* p = halfedge_allocator.allocate(1);
halfedge_allocator.construct( p, SHalfedge());
return p;
}
void put_halfedge_node( SHalfedge* p) {
halfedge_allocator.destroy(p);
halfedge_allocator.deallocate( p, 1);
}
SFace_alloc face_allocator;
SFace* get_face_node( const SFace& t) {
SFace* p = face_allocator.allocate(1);
face_allocator.construct( p, SFace());
return p;
}
void put_face_node( SFace* p) {
face_allocator.destroy(p);
face_allocator.deallocate( p, 1);
}
SVertex_handle new_svertex(const Sphere_point& p,
Mark m = Mark())
/*{\Mop returns a new vertex at point |p| marked by |m|.}*/
{ Vertex_handle vh = new_vertex(); vh->point_ = p; vh->mark_ = m;
TRACEN("new_vertex "<<&*vh);
{ SVertex_handle vh = new_svertex(); vh->point_ = p; vh->mark_ = m;
TRACEN("new_svertex "<<&*vh);
return vh;
}
template <typename H>
void make_twins(H h1, H h2) { h1->twin_ = h2; h2->twin_ = h1; }
Vertex_handle new_vertex()
{ vertices_.push_back( * new Vertex); return --vertices_end(); }
SVertex_handle new_svertex() {
svertices_.push_back( * get_vertex_node(SVertex()));
return --svertices_end();
}
Face_handle new_face()
{ faces_.push_back( * new Face ); return --faces_end(); }
SFace_handle new_sface() {
sfaces_.push_back( * get_face_node(SFace()));
return --sfaces_end();
}
Halfedge_handle new_halfedge_pair()
{ Halfedge* ep2 = new Halfedge[2];
Halfedge* ep1 = ep2++;
edges_.push_back( *ep1 );
Halfedge_handle e1 = --halfedges_end();
edges_.push_back( *ep2 );
Halfedge_handle e2 = --halfedges_end();
SHalfedge_handle new_shalfedge_pair() {
SHalfedge* ep2 = get_halfedge_node(SHalfedge());
SHalfedge* ep1 = get_halfedge_node(SHalfedge());
sedges_.push_back( *ep1 );
SHalfedge_handle e1 = --shalfedges_end();
sedges_.push_back( *ep2 );
SHalfedge_handle e2 = --shalfedges_end();
make_twins(e1,e2); return e1; }
Halfloop_handle new_halfloop_pair()
{ Halfloop_handle ph = new Halfloop[2];
Halfloop* pt(ph); ++pt;
SHalfloop_handle new_shalfloop_pair()
{ SHalfloop_handle ph = new SHalfloop[2];
SHalfloop* pt(ph); ++pt;
make_twins(ph,pt);
loops_=ph; return ph; }
shalfloop_=ph; return ph; }
Halfedge_handle new_halfedge_pair(const Halfedge& e1)
{ const Halfedge& e2 = *(e1.twin_);
Halfedge* ep2 = new Halfedge[2];
Halfedge* ep1 = ep2++;
SHalfedge_handle new_shalfedge_pair(const SHalfedge& e1)
{ const SHalfedge& e2 = *(e1.twin_);
SHalfedge* ep2 = new SHalfedge[2];
SHalfedge* ep1 = ep2++;
*ep1=e1; *ep2=e2;
edges_.push_back( *ep1 );
Halfedge_handle eh1 = --halfedges_end();
edges_.push_back( *ep2 );
Halfedge_handle eh2 = --halfedges_end();
sedges_.push_back( *ep1 );
SHalfedge_handle eh1 = --shalfedges_end();
sedges_.push_back( *ep2 );
SHalfedge_handle eh2 = --shalfedges_end();
make_twins(eh1,eh2); return eh1; }
Halfloop_handle new_halfloop_pair(const Halfloop& l1)
{ const Halfloop& l2 = *(l1.twin_);
Halfloop* ph = new Halfloop[2];
Halfloop* pt(ph); ++pt;
SHalfloop_handle new_shalfloop_pair(const SHalfloop& l1)
{ const SHalfloop& l2 = *(l1.twin_);
SHalfloop* ph = new SHalfloop[2];
SHalfloop* pt(ph); ++pt;
*ph=l1; *pt=l2; make_twins(ph,pt);
loops_=ph; return ph; }
shalfloop_=ph; return ph; }
void delete_vertex(Vertex_handle h)
{ vertices_.erase(h); delete &* h; }
void delete_vertex(SVertex_handle h) {
svertices_.erase(h);
put_vertex_node(&*h);
}
void delete_face(Face_handle h)
{ faces_.erase(h); delete &* h; }
void delete_face(SFace_handle h) {
sfaces_.erase(h);
put_face_node(&*h);
}
void delete_halfedge_pair(Halfedge_handle h)
{ Halfedge_handle t = h->twin_;
edges_.erase(h); edges_.erase(t);
Halfedge* ph = &*h;
Halfedge* pt = &*t;
void delete_halfedge_pair(SHalfedge_handle h) {
SHalfedge_handle t = h->twin_;
sedges_.erase(h); sedges_.erase(t);
put_halfedge_node(&*h);
put_halfedge_node(&*t);
}
void delete_halfloop_pair(SHalfloop_handle h)
{ SHalfloop* ph = &*h;
SHalfloop* pt = &*(h->twin_);
if ( ph > pt ) std::swap(ph,pt);
delete [] ph; }
void delete_halfloop_pair(Halfloop_handle h)
{ Halfloop* ph = &*h;
Halfloop* pt = &*(h->twin_);
if ( ph > pt ) std::swap(ph,pt);
loops_ = Halfloop_handle();
shalfloop_ = SHalfloop_handle();
delete [] ph; }
protected:
@ -379,87 +472,97 @@ protected:
Handle_to_iterator_map boundary_item_;
static Object_iterator undef_;
Vertex_list vertices_;
Halfedge_list edges_;
Face_list faces_;
Halfloop_iterator loops_;
Mark m_pos_, m_neg_;
/* two default marks at y-
m_neg_ just below the pos-xy-equator
m_pos_ just above the neg-xy-equator */
SVertex_list svertices_;
SHalfedge_list sedges_;
SFace_list sfaces_;
SHalfloop_iterator shalfloop_;
}; // Sphere_map
template <typename K>
void Sphere_map<K>::
pointer_update(const Sphere_map<K>& D)
template <typename K, typename I>
void Sphere_map<K, I>::
pointer_update(const Sphere_map<K, I>& D)
{
CGAL::Unique_hash_map<Vertex_const_handle,Vertex_handle> VM;
CGAL::Unique_hash_map<Halfedge_const_handle,Halfedge_handle> EM;
CGAL::Unique_hash_map<Halfloop_const_handle,Halfloop_handle> LM;
CGAL::Unique_hash_map<Face_const_handle,Face_handle> FM;
CGAL::Unique_hash_map<SVertex_const_handle,SVertex_handle> VM;
CGAL::Unique_hash_map<SHalfedge_const_handle,SHalfedge_handle> EM;
CGAL::Unique_hash_map<SHalfloop_const_handle,SHalfloop_handle> LM;
CGAL::Unique_hash_map<SFace_const_handle,SFace_handle> FM;
Vertex_const_iterator vc = D.vertices_begin();
Vertex_iterator v = vertices_begin();
for ( ; vc != D.vertices_end(); ++vc,++v) VM[vc] = v;
VM[D.vertices_end()] = vertices_end();
SVertex_const_iterator vc = D.svertices_begin();
SVertex_iterator v = svertices_begin();
for ( ; vc != D.svertices_end(); ++vc,++v) VM[vc] = v;
VM[D.svertices_end()] = svertices_end();
Halfedge_const_iterator ec = D.halfedges_begin();
Halfedge_iterator e = halfedges_begin();
for ( ; ec != D.halfedges_end(); ++ec,++e) EM[ec] = e;
EM[D.halfedges_end()] = halfedges_end();
SHalfedge_const_iterator ec = D.shalfedges_begin();
SHalfedge_iterator e = shalfedges_begin();
for ( ; ec != D.shalfedges_end(); ++ec,++e) {
EM[ec] = e;
e->mark_ = ec->mark_;
}
EM[D.shalfedges_end()] = shalfedges_end();
Face_const_iterator fc = D.faces_begin();
Face_iterator f = faces_begin();
for ( ; fc != D.faces_end(); ++fc,++f) FM[fc] = f;
FM[D.faces_end()] = faces_end();
SFace_const_iterator fc = D.sfaces_begin();
SFace_iterator f = sfaces_begin();
for ( ; fc != D.sfaces_end(); ++fc,++f) FM[fc] = f;
FM[D.sfaces_end()] = sfaces_end();
Halfloop_iterator l;
if ( D.loops_ != 0 ) {
LM[D.loops_] = loops_;
LM[D.loops_->twin_] = loops_->twin_;
SHalfloop_iterator l, lc;
if ( D.shalfloop_ != 0 ) {
LM[D.shalfloop_] = shalfloop_;
LM[D.shalfloop_->twin_] = shalfloop_->twin_;
l = shalfloop();
lc = D.shalfloop();
shalfloop_->mark_ = D.shalfloop()->mark_;
shalfloop_->twin_->mark_ = D.shalfloop()->twin_->mark_;
if( !l->is_twin() && D.shalfloop()->is_twin()) l->mark_ = l->twin_->mark_;
}
for (v = vertices_begin(); v != vertices_end(); ++v) {
for (v = svertices_begin(); v != svertices_end(); ++v) {
// Local Graph update: (SVertices are postponed/updated as Edges)
v->edge_ = EM[v->edge_];
v->face_ = FM[v->face_];
v->out_sedge_ = EM[v->out_sedge_];
v->incident_sface_ = FM[v->incident_sface_];
}
// Edge update:
for (e = halfedges_begin(); e != halfedges_end(); ++e) {
// e->twin_ = EM[e->twin_]; twin is set on construction
e->prev_ = EM[e->prev_];
e->next_ = EM[e->next_];
for (e = shalfedges_begin(); e != shalfedges_end(); ++e) {
e->twin_ = EM[e->twin_];
e->sprev_ = EM[e->sprev_];
e->snext_ = EM[e->snext_];
e->source_ = VM[e->source_];
e->face_ = FM[e->face_];
e->incident_sface_ = FM[e->incident_sface_];
}
for ( ec = D.shalfedges_begin(), e = shalfedges_begin();
ec != D.shalfedges_end(); ++ec, ++e) {
if( !e->is_twin() && ec->is_twin()) e->mark_ = e->twin_->mark_;
}
for (l = halfloops_begin(); l != halfloops_end(); ++l) {
// l->twin_ = LM[l->twin_]; twin is set on construction
l->face_ = FM[l->face_];
for (l = shalfloops_begin(); l != shalfloops_end(); ++l) {
// l->twin_ = LM[l->twin_];
l->incident_sface_ = FM[l->incident_sface_];
}
for (f = faces_begin(); f != faces_end(); ++f) {
Face_cycle_iterator fci;
for(fci = f->boundary_.begin(); fci != f->boundary_.end(); ++fci) {
if ( fci.is_vertex() )
{ v = Vertex_handle(fci);
for (f = sfaces_begin(); f != sfaces_end(); ++f) {
SFace_cycle_iterator fci;
for(fci = f->boundary_entry_objects_.begin();
fci != f->boundary_entry_objects_.end(); ++fci) {
if ( fci.is_svertex() )
{ v = SVertex_handle(fci);
*fci = Object_handle(VM[v]); store_boundary_item(v,fci); }
else if ( fci.is_halfedge() )
{ e = Halfedge_handle(fci);
else if ( fci.is_shalfedge() )
{ e = SHalfedge_handle(fci);
*fci = Object_handle(EM[e]); store_boundary_item(e,fci); }
else if ( fci.is_halfloop() )
{ l = Halfloop_handle(fci);
else if ( fci.is_shalfloop() )
{ l = SHalfloop_handle(fci);
*fci = Object_handle(LM[l]); store_boundary_item(l,fci); }
else CGAL_nef_assertion_msg(0,"damn wrong boundary item in face.");
else CGAL_assertion_msg(0,"damn wrong boundary item in face.");
}
}
}
template <typename Kernel_>
typename Sphere_map<Kernel_>::Object_iterator
Sphere_map<Kernel_>::undef_;
template <typename Kernel_, typename Items_>
typename Sphere_map<Kernel_, Items_>::Object_iterator
Sphere_map<Kernel_, Items_>::undef_;
CGAL_END_NAMESPACE

View File

@ -3,6 +3,7 @@
#include <CGAL/basic.h>
#include <CGAL/Handle_for.h>
#include <vector>
CGAL_BEGIN_NAMESPACE
@ -139,6 +140,9 @@ Sphere_segment<R> complement() const
{ return Sphere_segment<R>(target(),source(),sphere_circle()); }
int intersection(const Sphere_circle<R>& c,
std::vector<Sphere_segment<R> >& s) const;
int intersection(const Sphere_circle<R>& c,
Sphere_segment<R>& s1, Sphere_segment<R>& s2) const;
/*{\Mop returns the number of non-trivial connected components

View File

@ -129,7 +129,7 @@ typedef CGAL::generic_sweep<NHS_traits> Negative_halfsphere_sweep;
// v2 = first node of CC in negative xy-sphere
merging_halfspheres(v1,v2);
clean_trivial_face_cycles();
clean_trivial_sface_cycles();
if (!Is_Plane_Map(G)) error_handler(1,"Sphere map: embedding wrong.");
compute_faces();
}
@ -166,9 +166,9 @@ void merging_halfspheres(leda_node v1, leda_node v2)
{
TRACEN("Merging Halfspheres");
leda_edge e1,e2,e3,e4,e1n,e2n;
forall_adj_edges(e1,v1)
forall_sadj_edges(e1,v1)
if ( G[target(e1)].hz()==0 && G[target(e1)].hx()<0 ) break;
forall_adj_edges(e2,v2)
forall_sadj_edges(e2,v2)
if ( G[target(e2)].hz()==0 && G[target(e2)].hx()>0 ) break;
e3 = G.face_cycle_pred(e1);
e4 = e2; e2 = G.face_cycle_pred(e2);
@ -181,7 +181,7 @@ void merging_halfspheres(leda_node v1, leda_node v2)
}
void clean_trivial_face_cycles()
void clean_trivial_sface_cycles()
// removes trivial face cycles at equator
// removes isolated vertices stemming from
// equator unification
@ -190,7 +190,7 @@ void clean_trivial_face_cycles()
leda_list<leda_edge> L;
leda_list<edge_pair> Lr;
leda_edge e;
forall_edges(e,G) {
forall_sedges(e,G) {
if (known[e]) continue;
leda_edge en = G.face_cycle_succ(e);
if ( G.face_cycle_succ(en) != e )
@ -207,7 +207,7 @@ void clean_trivial_face_cycles()
forall(ep,Lr) G.set_reversal(ep.first,ep.second);
G.del_edges(L);
leda_node v;
forall_nodes(v,G) if ( G.outdeg(v)==0 ) G.del_node(v);
forall_snodes(v,G) if ( G.outdeg(v)==0 ) G.del_node(v);
}
void compute_faces()
@ -215,9 +215,9 @@ void compute_faces()
G.compute_faces();
leda_face f;
leda_edge e;
forall_faces(f,G) {
forall_sfaces(f,G) {
TRACEN("FACE:");
forall_face_edges(e,f)
forall_sface_edges(e,f)
TRACEN(" "<<SSegment_2(G[source(e)],G[target(e)]));
}
}
@ -230,9 +230,9 @@ void dump(std::ostream& os) const
{
leda_node v;
leda_edge e;
forall_nodes(v,G) {
forall_snodes(v,G) {
dump(os,v);
forall_adj_edges(e,v) {
forall_sadj_edges(e,v) {
os << " ->";
dump(os,target(e),false);
os <<" ["<<G[e]<<" ]\n";

View File

@ -1,267 +0,0 @@
// Copyright (c) 1997 Max-Planck-Institute Saarbruecken (Germany).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $Source$
// $Revision$ $Date$
// $Name$
//
// Author(s) : script by Geert-Jan Giezeman and Sven Schönherr
// macro definitions
// =================
// assertions
// ----------
#if defined(CGAL_NEF_NO_ASSERTIONS) || defined(CGAL_NO_ASSERTIONS) \
|| defined(NDEBUG)
# define CGAL_nef_assertion(EX) ((void)0)
# define CGAL_nef_assertion_msg(EX,MSG) ((void)0)
# define CGAL_nef_assertion_code(CODE)
#else
# define CGAL_nef_assertion(EX) \
((EX)?((void)0): ::CGAL::assertion_fail( # EX , __FILE__, __LINE__, 0))
# define CGAL_nef_assertion_msg(EX,MSG) \
((EX)?((void)0): ::CGAL::assertion_fail( # EX , __FILE__, __LINE__, MSG))
# define CGAL_nef_assertion_code(CODE) CODE
#endif // CGAL_NEF_NO_ASSERTIONS
#if defined(CGAL_NEF_NO_ASSERTIONS) || defined(CGAL_NO_ASSERTIONS) \
|| (!defined(CGAL_NEF_CHECK_EXACTNESS) && !defined(CGAL_CHECK_EXACTNESS))\
|| defined(NDEBUG)
# define CGAL_nef_exactness_assertion(EX) ((void)0)
# define CGAL_nef_exactness_assertion_msg(EX,MSG) ((void)0)
# define CGAL_nef_exactness_assertion_code(CODE)
#else
# define CGAL_nef_exactness_assertion(EX) \
((EX)?((void)0): ::CGAL::assertion_fail( # EX , __FILE__, __LINE__, 0))
# define CGAL_nef_exactness_assertion_msg(EX,MSG) \
((EX)?((void)0): ::CGAL::assertion_fail( # EX , __FILE__, __LINE__, MSG))
# define CGAL_nef_exactness_assertion_code(CODE) CODE
#endif // CGAL_NEF_NO_ASSERTIONS
#if defined(CGAL_NEF_NO_ASSERTIONS) \
|| defined(CGAL_NO_ASSERTIONS) \
|| (!defined(CGAL_NEF_CHECK_EXPENSIVE) && !defined(CGAL_CHECK_EXPENSIVE)) \
|| defined(NDEBUG)
# define CGAL_nef_expensive_assertion(EX) ((void)0)
# define CGAL_nef_expensive_assertion_msg(EX,MSG) ((void)0)
# define CGAL_nef_expensive_assertion_code(CODE)
#else
# define CGAL_nef_expensive_assertion(EX) \
((EX)?((void)0): ::CGAL::assertion_fail( # EX , __FILE__, __LINE__, 0))
# define CGAL_nef_expensive_assertion_msg(EX,MSG) \
((EX)?((void)0): ::CGAL::assertion_fail( # EX , __FILE__, __LINE__, MSG))
# define CGAL_nef_expensive_assertion_code(CODE) CODE
#endif // CGAL_NEF_NO_ASSERTIONS
#if defined(CGAL_NEF_NO_ASSERTIONS) || defined(CGAL_NO_ASSERTIONS) \
|| (!defined(CGAL_NEF_CHECK_EXACTNESS) && !defined(CGAL_CHECK_EXACTNESS))\
|| (!defined(CGAL_NEF_CHECK_EXPENSIVE) && !defined(CGAL_CHECK_EXPENSIVE)) \
|| defined(NDEBUG)
# define CGAL_nef_expensive_exactness_assertion(EX) ((void)0)
# define CGAL_nef_expensive_exactness_assertion_msg(EX,MSG) ((void)0)
# define CGAL_nef_expensive_exactness_assertion_code(CODE)
#else
# define CGAL_nef_expensive_exactness_assertion(EX) \
((EX)?((void)0): ::CGAL::assertion_fail( # EX , __FILE__, __LINE__, 0))
# define CGAL_nef_expensive_exactness_assertion_msg(EX,MSG) \
((EX)?((void)0): ::CGAL::assertion_fail( # EX , __FILE__, __LINE__, MSG))
# define CGAL_nef_expensive_exactness_assertion_code(CODE) CODE
#endif // CGAL_NEF_NO_ASSERTIONS
// preconditions
// -------------
#if defined(CGAL_NEF_NO_PRECONDITIONS) || defined(CGAL_NO_PRECONDITIONS) \
|| defined(NDEBUG)
# define CGAL_nef_precondition(EX) ((void)0)
# define CGAL_nef_precondition_msg(EX,MSG) ((void)0)
# define CGAL_nef_precondition_code(CODE)
#else
# define CGAL_nef_precondition(EX) \
((EX)?((void)0): ::CGAL::precondition_fail( # EX , __FILE__, __LINE__, 0))
# define CGAL_nef_precondition_msg(EX,MSG) \
((EX)?((void)0): ::CGAL::precondition_fail( # EX , __FILE__, __LINE__, MSG))
# define CGAL_nef_precondition_code(CODE) CODE
#endif // CGAL_NEF_NO_PRECONDITIONS
#if defined(CGAL_NEF_NO_PRECONDITIONS) || defined(CGAL_NO_PRECONDITIONS) \
|| (!defined(CGAL_NEF_CHECK_EXACTNESS) && !defined(CGAL_CHECK_EXACTNESS))\
|| defined(NDEBUG)
# define CGAL_nef_exactness_precondition(EX) ((void)0)
# define CGAL_nef_exactness_precondition_msg(EX,MSG) ((void)0)
# define CGAL_nef_exactness_precondition_code(CODE)
#else
# define CGAL_nef_exactness_precondition(EX) \
((EX)?((void)0): ::CGAL::precondition_fail( # EX , __FILE__, __LINE__, 0))
# define CGAL_nef_exactness_precondition_msg(EX,MSG) \
((EX)?((void)0): ::CGAL::precondition_fail( # EX , __FILE__, __LINE__, MSG))
# define CGAL_nef_exactness_precondition_code(CODE) CODE
#endif // CGAL_NEF_NO_PRECONDITIONS
#if defined(CGAL_NEF_NO_PRECONDITIONS) || defined(CGAL_NO_PRECONDITIONS) \
|| (!defined(CGAL_NEF_CHECK_EXPENSIVE) && !defined(CGAL_CHECK_EXPENSIVE)) \
|| defined(NDEBUG)
# define CGAL_nef_expensive_precondition(EX) ((void)0)
# define CGAL_nef_expensive_precondition_msg(EX,MSG) ((void)0)
# define CGAL_nef_expensive_precondition_code(CODE)
#else
# define CGAL_nef_expensive_precondition(EX) \
((EX)?((void)0): ::CGAL::precondition_fail( # EX , __FILE__, __LINE__, 0))
# define CGAL_nef_expensive_precondition_msg(EX,MSG) \
((EX)?((void)0): ::CGAL::precondition_fail( # EX , __FILE__, __LINE__, MSG))
# define CGAL_nef_expensive_precondition_code(CODE) CODE
#endif // CGAL_NEF_NO_PRECONDITIONS
#if defined(CGAL_NEF_NO_PRECONDITIONS) || defined(CGAL_NO_PRECONDITIONS) \
|| (!defined(CGAL_NEF_CHECK_EXACTNESS) && !defined(CGAL_CHECK_EXACTNESS))\
|| (!defined(CGAL_NEF_CHECK_EXPENSIVE) && !defined(CGAL_CHECK_EXPENSIVE)) \
|| defined(NDEBUG)
# define CGAL_nef_expensive_exactness_precondition(EX) ((void)0)
# define CGAL_nef_expensive_exactness_precondition_msg(EX,MSG) ((void)0)
# define CGAL_nef_expensive_exactness_precondition_code(CODE)
#else
# define CGAL_nef_expensive_exactness_precondition(EX) \
((EX)?((void)0): ::CGAL::precondition_fail( # EX , __FILE__, __LINE__, 0))
# define CGAL_nef_expensive_exactness_precondition_msg(EX,MSG) \
((EX)?((void)0): ::CGAL::precondition_fail( # EX , __FILE__, __LINE__, MSG))
# define CGAL_nef_expensive_exactness_precondition_code(CODE) CODE
#endif // CGAL_NEF_NO_PRECONDITIONS
// postconditions
// --------------
#if defined(CGAL_NEF_NO_POSTCONDITIONS) || defined(CGAL_NO_POSTCONDITIONS) \
|| defined(NDEBUG)
# define CGAL_nef_postcondition(EX) ((void)0)
# define CGAL_nef_postcondition_msg(EX,MSG) ((void)0)
# define CGAL_nef_postcondition_code(CODE)
#else
# define CGAL_nef_postcondition(EX) \
((EX)?((void)0): ::CGAL::postcondition_fail( # EX , __FILE__, __LINE__, 0))
# define CGAL_nef_postcondition_msg(EX,MSG) \
((EX)?((void)0): ::CGAL::postcondition_fail( # EX , __FILE__, __LINE__, MSG))
# define CGAL_nef_postcondition_code(CODE) CODE
#endif // CGAL_NEF_NO_POSTCONDITIONS
#if defined(CGAL_NEF_NO_POSTCONDITIONS) || defined(CGAL_NO_POSTCONDITIONS) \
|| (!defined(CGAL_NEF_CHECK_EXACTNESS) && !defined(CGAL_CHECK_EXACTNESS))\
|| defined(NDEBUG)
# define CGAL_nef_exactness_postcondition(EX) ((void)0)
# define CGAL_nef_exactness_postcondition_msg(EX,MSG) ((void)0)
# define CGAL_nef_exactness_postcondition_code(CODE)
#else
# define CGAL_nef_exactness_postcondition(EX) \
((EX)?((void)0): ::CGAL::postcondition_fail( # EX , __FILE__, __LINE__, 0))
# define CGAL_nef_exactness_postcondition_msg(EX,MSG) \
((EX)?((void)0): ::CGAL::postcondition_fail( # EX , __FILE__, __LINE__, MSG))
# define CGAL_nef_exactness_postcondition_code(CODE) CODE
#endif // CGAL_NEF_NO_POSTCONDITIONS
#if defined(CGAL_NEF_NO_POSTCONDITIONS) || defined(CGAL_NO_POSTCONDITIONS) \
|| (!defined(CGAL_NEF_CHECK_EXPENSIVE) && !defined(CGAL_CHECK_EXPENSIVE)) \
|| defined(NDEBUG)
# define CGAL_nef_expensive_postcondition(EX) ((void)0)
# define CGAL_nef_expensive_postcondition_msg(EX,MSG) ((void)0)
# define CGAL_nef_expensive_postcondition_code(CODE)
#else
# define CGAL_nef_expensive_postcondition(EX) \
((EX)?((void)0): ::CGAL::postcondition_fail( # EX , __FILE__, __LINE__, 0))
# define CGAL_nef_expensive_postcondition_msg(EX,MSG) \
((EX)?((void)0): ::CGAL::postcondition_fail( # EX , __FILE__, __LINE__, MSG))
# define CGAL_nef_expensive_postcondition_code(CODE) CODE
#endif // CGAL_NEF_NO_POSTCONDITIONS
#if defined(CGAL_NEF_NO_POSTCONDITIONS) || defined(CGAL_NO_POSTCONDITIONS) \
|| (!defined(CGAL_NEF_CHECK_EXACTNESS) && !defined(CGAL_CHECK_EXACTNESS))\
|| (!defined(CGAL_NEF_CHECK_EXPENSIVE) && !defined(CGAL_CHECK_EXPENSIVE)) \
|| defined(NDEBUG)
# define CGAL_nef_expensive_exactness_postcondition(EX) ((void)0)
# define CGAL_nef_expensive_exactness_postcondition_msg(EX,MSG) ((void)0)
# define CGAL_nef_expensive_exactness_postcondition_code(CODE)
#else
# define CGAL_nef_expensive_exactness_postcondition(EX) \
((EX)?((void)0): ::CGAL::postcondition_fail( # EX , __FILE__, __LINE__, 0))
# define CGAL_nef_expensive_exactness_postcondition_msg(EX,MSG) \
((EX)?((void)0): ::CGAL::postcondition_fail( # EX , __FILE__, __LINE__, MSG))
# define CGAL_nef_expensive_exactness_postcondition_code(CODE) CODE
#endif // CGAL_NEF_NO_POSTCONDITIONS
// warnings
// --------
#if defined(CGAL_NEF_NO_WARNINGS) || defined(CGAL_NO_WARNINGS) \
|| defined(NDEBUG)
# define CGAL_nef_warning(EX) ((void)0)
# define CGAL_nef_warning_msg(EX,MSG) ((void)0)
# define CGAL_nef_warning_code(CODE)
#else
# define CGAL_nef_warning(EX) \
((EX)?((void)0): ::CGAL::warning_fail( # EX , __FILE__, __LINE__, 0))
# define CGAL_nef_warning_msg(EX,MSG) \
((EX)?((void)0): ::CGAL::warning_fail( # EX , __FILE__, __LINE__, MSG))
# define CGAL_nef_warning_code(CODE) CODE
#endif // CGAL_NEF_NO_WARNINGS
#if defined(CGAL_NEF_NO_WARNINGS) || defined(CGAL_NO_WARNINGS) \
|| (!defined(CGAL_NEF_CHECK_EXACTNESS) && !defined(CGAL_CHECK_EXACTNESS))\
|| defined(NDEBUG)
# define CGAL_nef_exactness_warning(EX) ((void)0)
# define CGAL_nef_exactness_warning_msg(EX,MSG) ((void)0)
# define CGAL_nef_exactness_warning_code(CODE)
#else
# define CGAL_nef_exactness_warning(EX) \
((EX)?((void)0): ::CGAL::warning_fail( # EX , __FILE__, __LINE__, 0))
# define CGAL_nef_exactness_warning_msg(EX,MSG) \
((EX)?((void)0): ::CGAL::warning_fail( # EX , __FILE__, __LINE__, MSG))
# define CGAL_nef_exactness_warning_code(CODE) CODE
#endif // CGAL_NEF_NO_WARNINGS
#if defined(CGAL_NEF_NO_WARNINGS) || defined(CGAL_NO_WARNINGS) \
|| (!defined(CGAL_NEF_CHECK_EXPENSIVE) && !defined(CGAL_CHECK_EXPENSIVE)) \
|| defined(NDEBUG)
# define CGAL_nef_expensive_warning(EX) ((void)0)
# define CGAL_nef_expensive_warning_msg(EX,MSG) ((void)0)
# define CGAL_nef_expensive_warning_code(CODE)
#else
# define CGAL_nef_expensive_warning(EX) \
((EX)?((void)0): ::CGAL::warning_fail( # EX , __FILE__, __LINE__, 0))
# define CGAL_nef_expensive_warning_msg(EX,MSG) \
((EX)?((void)0): ::CGAL::warning_fail( # EX , __FILE__, __LINE__, MSG))
# define CGAL_nef_expensive_warning_code(CODE) CODE
#endif // CGAL_NEF_NO_WARNINGS
#if defined(CGAL_NEF_NO_WARNINGS) || defined(CGAL_NO_WARNINGS) \
|| (!defined(CGAL_NEF_CHECK_EXACTNESS) && !defined(CGAL_CHECK_EXACTNESS))\
|| (!defined(CGAL_NEF_CHECK_EXPENSIVE) && !defined(CGAL_CHECK_EXPENSIVE)) \
|| defined(NDEBUG)
# define CGAL_nef_expensive_exactness_warning(EX) ((void)0)
# define CGAL_nef_expensive_exactness_warning_msg(EX,MSG) ((void)0)
# define CGAL_nef_expensive_exactness_warning_code(CODE)
#else
# define CGAL_nef_expensive_exactness_warning(EX) \
((EX)?((void)0): ::CGAL::warning_fail( # EX , __FILE__, __LINE__, 0))
# define CGAL_nef_expensive_exactness_warning_msg(EX,MSG) \
((EX)?((void)0): ::CGAL::warning_fail( # EX , __FILE__, __LINE__, MSG))
# define CGAL_nef_expensive_exactness_warning_code(CODE) CODE
#endif // CGAL_NEF_NO_WARNINGS

View File

@ -5,7 +5,6 @@
#undef _DEBUG
#define _DEBUG 23
#include <CGAL/Nef_2/debug.h>
#include <vector>
#undef CGAL_forall_iterators
@ -44,6 +43,7 @@ int spherical_compare(const Sphere_point<R>& p1,
int axis, int pos) {
Sphere_point<R> pS, pN;
CGAL_assertion(axis>=0 && axis<=2);
switch(axis) {
case 0:
pS=Sphere_point<R>(0,-1,0);

View File

@ -51,14 +51,15 @@ class Nef_polyhedron_S2_rep
{ typedef Nef_polyhedron_S2_rep<K> Self;
friend class Nef_polyhedron_S2<K>;
typedef K Kernel;
typedef CGAL::Sphere_geometry<Kernel> Sphere_kernel;
typedef CGAL::Sphere_map<Sphere_kernel> Sphere_map;
typedef CGAL::SM_const_decorator<Sphere_map,Sphere_kernel>
Const_decorator;
typedef CGAL::SM_decorator<Sphere_map,Sphere_kernel> Decorator;
typedef K Kernel;
typedef CGAL::Sphere_geometry<Kernel> Sphere_kernel;
typedef bool Mark;
typedef CGAL::SM_items<Sphere_kernel, Mark> Items;
typedef CGAL::Sphere_map<Sphere_kernel,Items> Sphere_map;
typedef CGAL::SM_const_decorator<Sphere_map> Const_decorator;
typedef CGAL::SM_decorator<Sphere_map> Decorator;
typedef CGAL::SM_overlayer<Decorator> Overlayer;
typedef CGAL::SM_point_locator<Decorator> Locator;
typedef CGAL::SM_point_locator<Const_decorator> Locator;
Sphere_map sm_;
@ -84,7 +85,8 @@ The template parameter |Kernel| is specified via a kernel concept.
}*/
template <typename K>
class Nef_polyhedron_S2 : public Handle_for< Nef_polyhedron_S2_rep<K> >
class Nef_polyhedron_S2 : public Handle_for< Nef_polyhedron_S2_rep<K> >,
public Nef_polyhedron_S2_rep<K>::Const_decorator
{
public:
typedef K Kernel;
@ -107,7 +109,7 @@ public:
typedef typename Sphere_kernel::Sphere_direction Sphere_direction;
typedef typename Sphere_map::Mark Mark;
typedef typename Rep::Mark Mark;
/*{\Xtypemember marking set membership or exclusion.}*/
enum Boundary { EXCLUDED=0, INCLUDED=1 };
@ -137,28 +139,30 @@ protected:
friend std::istream& operator>> <>
(std::istream& is, Nef_polyhedron_S2<K>& NP);
typedef typename Decorator::Vertex_handle Vertex_handle;
typedef typename Decorator::Halfedge_handle Halfedge_handle;
typedef typename Decorator::Halfloop_handle Halfloop_handle;
typedef typename Decorator::Face_handle Face_handle;
typedef typename Decorator::SVertex_handle SVertex_handle;
typedef typename Decorator::SHalfedge_handle SHalfedge_handle;
typedef typename Decorator::SHalfloop_handle SHalfloop_handle;
typedef typename Decorator::SFace_handle SFace_handle;
typedef typename Decorator::Vertex_const_handle Vertex_const_handle;
typedef typename Decorator::Halfedge_const_handle Halfedge_const_handle;
typedef typename Decorator::Halfloop_const_handle Halfloop_const_handle;
typedef typename Decorator::Face_const_handle Face_const_handle;
typedef typename Decorator::SVertex_const_handle SVertex_const_handle;
typedef typename Decorator::SHalfedge_const_handle SHalfedge_const_handle;
typedef typename Decorator::SHalfloop_const_handle SHalfloop_const_handle;
typedef typename Decorator::SFace_const_handle SFace_const_handle;
typedef typename Decorator::Vertex_iterator Vertex_iterator;
typedef typename Decorator::Halfedge_iterator Halfedge_iterator;
typedef typename Decorator::Halfloop_iterator Halfloop_iterator;
typedef typename Decorator::Face_iterator Face_iterator;
typedef typename Const_decorator::Vertex_const_iterator
Vertex_const_iterator;
typedef typename Const_decorator::Halfedge_const_iterator
Halfedge_const_iterator;
typedef typename Const_decorator::Halfloop_const_iterator
Halfloop_const_iterator;
typedef typename Const_decorator::Face_const_iterator
Face_const_iterator;
typedef typename Decorator::SVertex_iterator SVertex_iterator;
typedef typename Decorator::SHalfedge_iterator SHalfedge_iterator;
typedef typename Decorator::SHalfloop_iterator SHalfloop_iterator;
typedef typename Decorator::SFace_iterator SFace_iterator;
typedef typename Const_decorator::SVertex_const_iterator
SVertex_const_iterator;
typedef typename Const_decorator::SHalfedge_const_iterator
SHalfedge_const_iterator;
typedef typename Const_decorator::SHalfloop_const_iterator
SHalfloop_const_iterator;
typedef typename Const_decorator::SFace_const_iterator
SFace_const_iterator;
typedef typename Const_decorator::Constructor_parameter Constructor_parameter;
typedef std::list<Sphere_segment> SS_list;
typedef typename SS_list::const_iterator SS_iterator;
@ -171,24 +175,28 @@ public:
and initializes it to the empty set if |sphere == EMPTY|
and to the whole sphere if |sphere == COMPLETE|.}*/
{
SS_list L;
Decorator D(sphere_map());
D.mark_of_halfsphere(-1) = D.mark_of_halfsphere(+1) = bool(sphere);
set_sm(&sphere_map());
Decorator D(&sphere_map());
SFace_handle sf=D.new_sface();
D.mark(sf) = bool(sphere);
}
Nef_polyhedron_S2(const Sphere_circle& c,
Boundary circle = INCLUDED) : Base(Nef_rep())
Boundary circle = INCLUDED) : Base(Nef_rep()) {
/*{\Mcreate creates a Nef polyhedron |\Mvar| containing the half-sphere
left of |c| including |c| if |circle==INCLUDED|, excluding |c| if
|circle==EXCLUDED|.}*/
{ TRACEN("Nef_polyhedron_S2(): construction from circle "<<c);
Overlayer D(sphere_map()); D.create(c);
Halfloop_handle h = D.halfloop();
set_sm(&sphere_map());
TRACEN("Nef_polyhedron_S2(): construction from circle "<<c);
Decorator D(&sphere_map());
Overlayer O(&sphere_map());
O.create(c);
SHalfloop_handle h = D.shalfloop();
if ( D.circle(h) != c ) h = D.twin(h);
D.mark(D.face(h)) = true;
D.mark(h) = bool(circle);
Locator L(sphere_map()); L.init_marks_of_halfspheres();
}
@ -204,30 +212,32 @@ public:
otherwise. |Forward_iterator| has to be an iterator with value
type |Sphere_segment|.}*/
{ TRACEN("Nef_polyhedron_S2(): creation from segment range");
CGAL_nef_assertion(first!=beyond);
Overlayer D(sphere_map());
CGAL_assertion(first!=beyond);
set_sm(&sphere_map());
Overlayer D(&sphere_map());
Sphere_segment s = *first;
D.create_from_segments(first,beyond);
Halfedge_iterator e;
CGAL_forall_halfedges(e,D) {
SHalfedge_iterator e;
CGAL_forall_shalfedges(e,D) {
Sphere_circle c(D.circle(e));
if ( c == s.sphere_circle() ) break;
}
if ( e != Halfedge_iterator() ) {
if ( e != SHalfedge_iterator() ) {
if ( D.circle(e) != s.sphere_circle() ) e = D.twin(e);
CGAL_nef_assertion( D.circle(e) == s.sphere_circle() );
CGAL_assertion( D.circle(e) == s.sphere_circle() );
D.set_marks_in_face_cycle(e,bool(b));
if ( D.number_of_faces() > 2 ) D.mark(D.face(e)) = true;
else D.mark(D.face(e)) = !bool(b);
if ( D.number_of_sfaces() > 2 ) D.mark(D.face(e)) = true;
else D.mark(D.face(e)) = !bool(b);
return;
}
D.simplify();
Locator L(sphere_map()); L.init_marks_of_halfspheres();
}
Nef_polyhedron_S2(const Nef_polyhedron_S2<K>& N1) : Base(N1) {}
Nef_polyhedron_S2(const Nef_polyhedron_S2<K>& N1) : Base(N1) {
set_sm(&sphere_map());
}
Nef_polyhedron_S2& operator=(const Nef_polyhedron_S2<K>& N1)
{ Base::operator=(N1); return (*this); }
{ Base::operator=(N1); set_sm(&sphere_map()); return (*this); }
~Nef_polyhedron_S2() {}
template <class Forward_iterator>
@ -237,27 +247,31 @@ public:
the set of circles |S = set[first,beyond)|. The cells of the arrangement
are selected uniformly at random with probability $p$. \precond $0 < p
< 1$.}*/
{ CGAL_nef_assertion(0<=p && p<=1);
CGAL_nef_assertion(first!=beyond);
Overlayer D(sphere_map());
{ CGAL_assertion(0<=p && p<=1);
CGAL_assertion(first!=beyond);
set_sm(&sphere_map());
Overlayer D(&sphere_map());
D.create_from_circles(first, beyond); D.simplify();
Vertex_iterator v; Halfedge_iterator e; Face_iterator f;
CGAL_forall_vertices(v,D)
SVertex_iterator v; SHalfedge_iterator e; SFace_iterator f;
CGAL_forall_svertices(v,D)
D.mark(v) = ( default_random.get_double() < p ? true : false );
CGAL_forall_halfedges(e,D)
CGAL_forall_shalfedges(e,D)
D.mark(e) = ( default_random.get_double() < p ? true : false );
CGAL_forall_faces(f,D)
CGAL_forall_sfaces(f,D)
D.mark(f) = ( default_random.get_double() < p ? true : false );
D.simplify();
Locator L(sphere_map()); L.init_marks_of_halfspheres();
}
protected:
Nef_polyhedron_S2(const Sphere_map& H, bool clone=true) : Base(Nef_rep())
/*{\Xcreate makes |\Mvar| a new object. If |clone==true| then the
underlying structure of |H| is copied into |\Mvar|.}*/
{ if (clone) ptr()->sm_ = H; }
{
if (!clone) return;
ptr()->sm_ = H;
set_sm(&sphere_map());
}
void clone_rep() { *this = Nef_polyhedron_S2<K>(sphere_map()); }
/*{\Moperations 4 3 }*/
@ -270,53 +284,51 @@ protected:
bool is_empty() const
/*{\Mop returns true if |\Mvar| is empty, false otherwise.}*/
{ Const_decorator D(sphere_map());
{ Const_decorator D(&sphere_map());
TRACEN("is_empty()"<<*this);
Face_const_iterator f = D.faces_begin();
return (D.number_of_vertices()==0 &&
D.number_of_edges()==0 &&
D.number_of_loops()==0 &&
D.number_of_faces()==1 &&
SFace_const_iterator f = D.sfaces_begin();
return (D.number_of_svertices()==0 &&
D.number_of_sedges()==0 &&
D.number_of_sloops()==0 &&
D.number_of_sfaces()==1 &&
D.mark(f) == false);
}
bool is_plane() const
/*{\Mop returns true if |\Mvar| is the whole plane, false otherwise.}*/
{ Const_decorator D(sphere_map());
Face_const_iterator f = D.faces_begin();
return (D.number_of_vertices()==0 &&
D.number_of_edges()==0 &&
D.number_of_loops()==0 &&
D.number_of_faces()==1 &&
{ Const_decorator D(&sphere_map());
SFace_const_iterator f = D.sfaces_begin();
return (D.number_of_svertices()==0 &&
D.number_of_sedges()==0 &&
D.number_of_sloops()==0 &&
D.number_of_sfaces()==1 &&
D.mark(f) == true);
}
void extract_complement()
{ TRACEN("extract complement");
if ( is_shared() ) clone_rep();
Overlayer D(sphere_map());
Vertex_iterator v;
Halfedge_iterator e;
Face_iterator f;
CGAL_forall_vertices(v,D) D.mark(v) = !D.mark(v);
CGAL_forall_edges(e,D) D.mark(e) = !D.mark(e);
CGAL_forall_faces(f,D) D.mark(f) = !D.mark(f);
Overlayer D(&sphere_map());
SVertex_iterator v;
SHalfedge_iterator e;
SFace_iterator f;
CGAL_forall_svertices(v,D) D.mark(v) = !D.mark(v);
CGAL_forall_sedges(e,D) D.mark(e) = !D.mark(e);
CGAL_forall_sfaces(f,D) D.mark(f) = !D.mark(f);
if ( D.has_loop() )
D.mark(D.halfloop()) = !D.mark(D.halfloop());
D.mark_of_halfsphere(-1) = !D.mark_of_halfsphere(-1);
D.mark_of_halfsphere(+1) = !D.mark_of_halfsphere(+1);
if ( D.has_sloop() )
D.mark(D.shalfloop()) = !D.mark(D.shalfloop());
}
void extract_interior()
{ TRACEN("extract interior");
if ( is_shared() ) clone_rep();
Overlayer D(sphere_map());
Vertex_iterator v;
Halfedge_iterator e;
CGAL_forall_vertices(v,D) D.mark(v) = false;
CGAL_forall_edges(e,D) D.mark(e) = false;
if ( D.has_loop() ) D.mark(D.halfloop()) = false;
Overlayer D(&sphere_map());
SVertex_iterator v;
SHalfedge_iterator e;
CGAL_forall_svertices(v,D) D.mark(v) = false;
CGAL_forall_sedges(e,D) D.mark(e) = false;
if ( D.has_sloop() ) D.mark(D.shalfloop()) = false;
D.simplify();
}
@ -324,15 +336,14 @@ protected:
void extract_boundary()
{ TRACEN("extract boundary");
if ( is_shared() ) clone_rep();
Overlayer D(sphere_map());
Vertex_iterator v;
Halfedge_iterator e;
Face_iterator f;
CGAL_forall_vertices(v,D) D.mark(v) = true;
CGAL_forall_edges(e,D) D.mark(e) = true;
CGAL_forall_faces(f,D) D.mark(f) = false;
if ( D.has_loop() ) D.mark(D.halfloop()) = true;
D.mark_of_halfsphere(-1) = D.mark_of_halfsphere(+1) = false;
Overlayer D(&sphere_map());
SVertex_iterator v;
SHalfedge_iterator e;
SFace_iterator f;
CGAL_forall_svertices(v,D) D.mark(v) = true;
CGAL_forall_sedges(e,D) D.mark(e) = true;
CGAL_forall_sfaces(f,D) D.mark(f) = false;
if ( D.has_sloop() ) D.mark(D.shalfloop()) = true;
D.simplify();
}
@ -393,8 +404,8 @@ protected:
Nef_polyhedron_S2<K> intersection(const Nef_polyhedron_S2<K>& N1) const
/*{\Mop returns |\Mvar| $\cap$ |N1|. }*/
{ Nef_polyhedron_S2<K> res(sphere_map(),false); // empty
Overlayer D(res.sphere_map());
D.subdivide(sphere_map(),N1.sphere_map());
Overlayer D(&res.sphere_map());
D.subdivide(&sphere_map(),&N1.sphere_map());
AND _and; D.select(_and); D.simplify();
return res;
}
@ -403,8 +414,8 @@ protected:
Nef_polyhedron_S2<K> join(const Nef_polyhedron_S2<K>& N1) const
/*{\Mop returns |\Mvar| $\cup$ |N1|. }*/
{ Nef_polyhedron_S2<K> res(sphere_map(),false); // empty
Overlayer D(res.sphere_map());
D.subdivide(sphere_map(),N1.sphere_map());
Overlayer D(&res.sphere_map());
D.subdivide(&sphere_map(),&N1.sphere_map());
OR _or; D.select(_or); D.simplify();
return res;
}
@ -412,8 +423,8 @@ protected:
Nef_polyhedron_S2<K> difference(const Nef_polyhedron_S2<K>& N1) const
/*{\Mop returns |\Mvar| $-$ |N1|. }*/
{ Nef_polyhedron_S2<K> res(sphere_map(),false); // empty
Overlayer D(res.sphere_map());
D.subdivide(sphere_map(),N1.sphere_map());
Overlayer D(&res.sphere_map());
D.subdivide(&sphere_map(),&N1.sphere_map());
DIFF _diff; D.select(_diff); D.simplify();
return res;
}
@ -423,8 +434,8 @@ protected:
/*{\Mop returns the symmectric difference |\Mvar - T| $\cup$
|T - \Mvar|. }*/
{ Nef_polyhedron_S2<K> res(sphere_map(),false); // empty
Overlayer D(res.sphere_map());
D.subdivide(sphere_map(),N1.sphere_map());
Overlayer D(&res.sphere_map());
D.subdivide(&sphere_map(),&N1.sphere_map());
XOR _xor; D.select(_xor); D.simplify();
return res;
}
@ -507,9 +518,9 @@ protected:
plane map. The kind of object |(vertex, halfedge, face)| can
be determined and the object can be assigned to a corresponding
handle by the three functions:\\
|bool assign(Vertex_const_handle& h, Object_handle)|\\
|bool assign(Halfedge_const_handle& h, Object_handle)|\\
|bool assign(Face_const_handle& h, Object_handle)|\\
|bool assign(SVertex_const_handle& h, Object_handle)|\\
|bool assign(SHalfedge_const_handle& h, Object_handle)|\\
|bool assign(SFace_const_handle& h, Object_handle)|\\
where each function returns |true| iff the assignment to
|h| was done.}*/
@ -519,13 +530,13 @@ protected:
bool contains(Object_handle h) const
/*{\Mop returns true iff the object |h| is contained in the set
represented by |\Mvar|.}*/
{ Locator PL(sphere_map()); return PL.mark(h); }
{ Locator PL(&sphere_map()); return PL.mark(h); }
bool contained_in_boundary(Object_handle h) const
/*{\Mop returns true iff the object |h| is contained in the $1$-skeleton
of |\Mvar|.}*/
{ Vertex_const_handle v;
Halfedge_const_handle e;
{ SVertex_const_handle v;
SHalfedge_const_handle e;
return ( CGAL::assign(v,h) || CGAL::assign(e,h) );
}
@ -537,43 +548,43 @@ protected:
|\Mvar.contains(h)| is true. The location mode flag |m| allows one to choose
between different point location strategies.}*/
{
Locator PL(sphere_map());
Locator PL(&sphere_map());
return PL.locate(p);
}
struct INSET {
const Const_decorator& D;
INSET(const Const_decorator& Di) : D(Di) {}
bool operator()(Vertex_const_handle v) const { return D.mark(v); }
bool operator()(Halfedge_const_handle e) const { return D.mark(e); }
bool operator()(Halfloop_const_handle l) const { return D.mark(l); }
bool operator()(Face_const_handle f) const { return D.mark(f); }
bool operator()(SVertex_const_handle v) const { return D.mark(v); }
bool operator()(SHalfedge_const_handle e) const { return D.mark(e); }
bool operator()(SHalfloop_const_handle l) const { return D.mark(l); }
bool operator()(SFace_const_handle f) const { return D.mark(f); }
};
Object_handle ray_shoot(const Sphere_point& p,
const Sphere_direction& d) const
/*{\Mop returns a handle |h| with |\Mvar.contains(h)| that can be
converted to a |Vertex_/Halfedge_/Face_const_handle| as described
converted to a |SVertex_/SHalfedge_/SFace_const_handle| as described
above. The object returned is intersected by the ray starting in |p|
with direction |d| and has minimal distance to |p|. The operation
returns the null handle |NULL| if the ray shoot along |d| does not hit
any object |h| of |\Mvar| with |\Mvar.contains(h)|.}*/
{
Locator PL(sphere_map());
Locator PL(&sphere_map());
return PL.ray_shoot(p,d,INSET(PL));
}
struct INSKEL {
bool operator()(Vertex_const_handle) const { return true; }
bool operator()(Halfedge_const_handle) const { return true; }
bool operator()(Halfloop_const_handle) const { return true; }
bool operator()(Face_const_handle) const { return false; }
bool operator()(SVertex_const_handle) const { return true; }
bool operator()(SHalfedge_const_handle) const { return true; }
bool operator()(SHalfloop_const_handle) const { return true; }
bool operator()(SFace_const_handle) const { return false; }
};
Object_handle ray_shoot_to_boundary(const Sphere_point& p,
const Sphere_direction& d) const
/*{\Mop returns a handle |h| that can be converted to a
|Vertex_/Halfedge_const_handle| as described above. The object
|SVertex_/SHalfedge_const_handle| as described above. The object
returned is part of the $1$-skeleton of |\Mvar|, intersected by the
ray starting in |p| with direction |d| and has minimal distance to
|p|. The operation returns the null handle |NULL| if the ray shoot
@ -581,7 +592,7 @@ protected:
location mode flag |m| allows one to choose between different point
location strategies.}*/
{
Locator PL(sphere_map());
Locator PL(&sphere_map());
return PL.ray_shoot(p,d,INSKEL());
}
@ -590,7 +601,7 @@ protected:
/*{\Mop returns a decorator object which allows read-only access of
the underlying plane map. See the manual page |Explorer| for its
usage.}*/
{ return Explorer(const_cast<Sphere_map&>(sphere_map())); }
{ return Explorer(const_cast<Sphere_map*>(&sphere_map())); }
/*{\Mtext\headerline{Input and Output}
A Nef polyhedron |\Mvar| can be visualized in an open GL window. The
@ -636,16 +647,14 @@ protected:
}; // end of Nef_polyhedron_S2
template <typename K>
std::ostream& operator<<
(std::ostream& os, const Nef_polyhedron_S2<K>& NP)
{
os << "Nef_polyhedron_S2\n";
typedef typename Nef_polyhedron_S2<K>::Decorator Decorator;
typedef typename Nef_polyhedron_S2<K>::Explorer Decorator;
typedef typename Nef_polyhedron_S2<K>::Sphere_map Sphere_map;
CGAL::SM_io_parser<Decorator> O(os,
const_cast<Sphere_map&>(NP.sphere_map()));
CGAL::SM_io_parser<Decorator> O(os, NP.explorer());
O.print();
return os;
}
@ -655,7 +664,7 @@ std::istream& operator>>
(std::istream& is, Nef_polyhedron_S2<K>& NP)
{
typedef typename Nef_polyhedron_S2<K>::Decorator Decorator;
CGAL::SM_io_parser<Decorator> I(is, NP.sphere_map());
CGAL::SM_io_parser<Decorator> I(is, Decorator(NP.sphere_map()));
if ( I.check_sep("Nef_polyhedron_S2") ) I.read();
else {
std::cerr << "Nef_polyhedron_S2 input corrupted." << std::endl;