⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sm_const_decorator.h

📁 很多二维 三维几何计算算法 C++ 类库
💻 H
字号:
// 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.//// $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.3-branch/Nef_S2/include/CGAL/Nef_S2/SM_const_decorator.h $// $Id: SM_const_decorator.h 28567 2006-02-16 14:30:13Z lsaboret $// //// 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#include <CGAL/basic.h>#include <CGAL/circulator.h>#include <CGAL/Unique_hash_map.h>#include <CGAL/Nef_2/Object_index.h>#include <CGAL/Nef_S2/SM_iteration.h>#include <CGAL/Nef_S2/SM_decorator_traits.h>#include <string>#include <list>#include <sstream>#undef CGAL_NEF_DEBUG#define CGAL_NEF_DEBUG 67#include <CGAL/Nef_2/debug.h>CGAL_BEGIN_NAMESPACEtemplate <typename Map_>class SM_const_decorator {   typedef SM_const_decorator<Map_> Self;public:  typedef Map_                       Map;  typedef const Map_                 Sphere_map;  typedef SM_decorator_const_traits<Map>  Decorator_traits;/*{\Mdefinition ...}*//*{\Mtypes 5}*/typedef typename Map::Sphere_kernel Sphere_kernel;/*{\Mtypemember spherical geometry.}*/typedef typename Map::Sphere_point   Sphere_point;/*{\Mtypemember embedding vertices.}*/typedef typename Map::Sphere_segment Sphere_segment;/*{\Mtypemember embedding edges.}*/typedef typename Map::Sphere_circle  Sphere_circle;/*{\Mtypemember embedding loops.}*/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;/*{\Mtypemember size type.}*/typedef void*  GenPtr;// 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 thefollowing kind: |SVertex_handle|, |SVertex_iterator|, |SHalfedge_handle|,|SHalfedge_iterator|, |SHalfloop_handle|, |SHalfloop_iterator|,|SFace_handle|, |SFace_iterator|.  Additionally the followingcirculators are defined.}*/typedef typename Map::SHalfedge_around_svertex_const_circulator        SHalfedge_around_svertex_const_circulator;/*{\Mtypemember circulating the adjacency list of an vertex |v|.}*/typedef typename Map::SHalfedge_around_sface_const_circulator        SHalfedge_around_sface_const_circulator;/*{\Mtypemember circulating the face cycle of an face |f|.}*/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 correspondinghandles |SVertex_const_handle|, |SHalfedge_const_handle|, or |SHalfloop_const_handle|.}*/protected:   const Map* psm_;  void set_sm(const Map* W) {    psm_ = W;  }public:/*{\Mcreation 3}*/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 Map* M) : psm_(M) {}/*{\Mcreate constructs a plane map decorator exploring |M|.}*//*{\Moperations 4 4}*/const Map* sphere_map() const { return psm_; }bool is_isolated(SVertex_const_handle v) const/*{\Mop returns |true| when |v| is linked to the interior of a face.}*/{ return (SHalfedge_const_handle(v->out_sedge()) == SHalfedge_const_handle()); }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->out_sedge(); }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->out_sedge()); }SHalfedge_const_handle cyclic_adj_succ(SHalfedge_const_handle e) const/*{\Mop returns the edge after |e| in the cyclic ordered adjacency list of  |e->source()|.}*/{ return e->sprev()->twin(); }SHalfedge_const_handle cyclic_adj_pred(SHalfedge_const_handle e) const/*{\Mop returns the edge before |e| in the cyclic ordered adjacency list of  |e->source()|.}*/{ return e->twin()->snext(); }/*{\Mtext \headerline{Iteration} \setopdims{3.3cm}{0cm}}*/  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(); }SHalfloop_const_handle shalfloop() const/*{\Mop returns access to the loop.}*/{ return psm_->shalfloop(); }bool has_shalfloop() const/*{\Mop returns true iff there is a loop.}*/{ return psm_->has_shalfloop(); }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 SHalfedge_around_svertex_const_circulator(first_out_edge(v)); }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 |SVertex_const_handle|, |SHalfloop_const_handle|, or |SHalfedge_const_handle|.}*/{ return f->boundary_entry_objects_.begin(); }SFace_cycle_const_iterator sface_cycles_end(SFace_const_handle f) const/*{\Mop returns the past the end iterator of |f|.}*/{ return f->boundary_entry_objects_.end(); }/*{\Mtext \headerline{Statistics and Integrity}}*/Size_type number_of_svertices() const /*{\Mop returns the number of vertices.}*/{ return psm_->number_of_svertices(); }Size_type number_of_shalfedges() const /*{\Mop returns the number of halfedges.}*/{ return psm_->number_of_shalfedges(); }Size_type number_of_sedges() const /*{\Mop returns the number of edges.}*/{ return number_of_shalfedges()/2; }Size_type number_of_shalfloops() const /*{\Mop returns the number of halfloops.}*/{ return psm_->number_of_shalfloops(); }Size_type number_of_sloops() const /*{\Mop returns the number of loops.}*/{ return psm_->number_of_shalfloops()/2; }Size_type number_of_sfaces() const    /*{\Mop returns the number of faces.}*/{ return psm_->number_of_sfaces(); }Size_type number_of_sface_cycles() const;/*{\Mop returns the number of face cycles.}*/Size_type number_of_connected_components() const;/*{\Mop calculates the number of connected components of |P|.}*/void print_statistics(std::ostream& os = std::cout) const/*{\Mop print the statistics of |P|: the number of vertices, edges, and faces.}*/{  os << "Sphere Map - Statistics\n";  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|.}*/SHalfedge_const_handle cas(SHalfedge_const_handle e) const { return cyclic_adj_succ(e); } SHalfedge_const_handle cap(SHalfedge_const_handle e) const{ return cyclic_adj_pred(e); }template <typename H>bool is_sm_boundary_object(H h) const{ return psm_->is_sm_boundary_object(h); }/*{\Mtext \headerline{Associated Information}\restoreopdims}*//*{\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:\\|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_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_decoratortemplate <typename SM_>void SM_const_decorator<SM_>::check_integrity_and_topological_planarity(bool faces) const{  CGAL_NEF_TRACEN("check_integrity_and_topological_planarity:");  using CGAL::Object_index;  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_svertices(v,*this) {    if ( is_isolated(v) ) {      if ( faces )        CGAL_assertion_msg(v->incident_sface() != SFace_const_handle(), VI(v).c_str());      ++iso_vert_num;    } else {      CGAL_assertion_msg(first_out_edge(v) != SHalfedge_const_handle(),      VI(v).c_str());      CGAL_NEF_TRACEN(v->point()<<" "<<EI(first_out_edge(v)));      CGAL_assertion_msg(first_out_edge(v)->source() == v,			 VI(v).c_str());    }  }  /* check the bidirected links and the face pointer init */  SHalfedge_const_iterator e;  CGAL_forall_shalfedges(e,*this) {    CGAL_assertion( e->twin()->twin() == e );    CGAL_assertion( e->source() != SVertex_const_handle() );    CGAL_assertion( e->snext() != SHalfedge_const_handle() );    CGAL_assertion( e->snext()->sprev() == e );    CGAL_assertion( e->target() == e->snext()->source() );    CGAL_assertion( e->sprev() != SHalfedge_const_handle() );    CGAL_assertion( e->sprev()->snext() == e );    CGAL_assertion( e->sprev()->twin()->source() == e->source() );    if ( !faces ) continue;    CGAL_assertion( e->incident_sface() != SFace_const_handle() );    CGAL_assertion( e->snext()->incident_sface() == e->incident_sface() );    CGAL_assertion( e->sprev()->incident_sface() == e->incident_sface() );  }  int fc_num(0),iv_num(0);  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( SHalfedge_const_handle(fci)->incident_sface() == f ); 	++fc_num;      } else if ( fci.is_svertex() ) {        CGAL_assertion( SVertex_const_handle(fci)->incident_sface() == f ); 	++iv_num;      } else if( fci.is_shalfloop() ) {        CGAL_assertion( SHalfloop_const_handle(fci)->incident_sface() == f );	++fc_num;      } else CGAL_assertion_msg(0,"damn generic handle.");    }  }  CGAL_assertion_code(int v_num = number_of_svertices() - 		      iso_vert_num + 		      number_of_shalfloops());  CGAL_assertion_code(int e_num = number_of_sedges() + 		      number_of_shalfloops());  CGAL_assertion_code(int c_num = number_of_connected_components() - 		      iso_vert_num 		      + number_of_sloops());  CGAL_assertion_code(int f_num = number_of_sface_cycles() - c_num + 1);  CGAL_assertion_code(CGAL_NEF_TRACEV(fc_num));  CGAL_assertion_code(CGAL_NEF_TRACEV(iv_num));  CGAL_assertion_code(CGAL_NEF_TRACEV(iso_vert_num));  CGAL_assertion_code(CGAL_NEF_TRACEV(v_num));  CGAL_assertion_code(CGAL_NEF_TRACEV(e_num));  CGAL_assertion_code(CGAL_NEF_TRACEV(c_num));  CGAL_assertion_code(CGAL_NEF_TRACEV(f_num));  /* this means all face cycles and all isolated vertices are      indeed referenced from a face */  /* every isolated vertex increases the component count       one face cycle per component is redundent except one       finally check the Euler formula: */  CGAL_assertion( v_num - e_num + f_num == 1 + c_num );}template <typename SM_>typename SM_const_decorator<SM_>::Size_typeSM_const_decorator<SM_>::number_of_sface_cycles() const{  unsigned int fc_num=0;  CGAL::Unique_hash_map<SHalfedge_const_handle,bool> visited;   SHalfedge_const_iterator e;  CGAL_forall_shalfedges(e,*this) {    if (visited[e]) continue;    SHalfedge_around_sface_const_circulator hfc(e), hend(hfc);    CGAL_For_all(hfc,hend) visited[hfc]=true;    ++fc_num;  }  if ( has_shalfloop() ) fc_num += 2;  return fc_num;}template <typename SM_>typename SM_const_decorator<SM_>::Size_typeSM_const_decorator<SM_>::number_of_connected_components() const{  int comp_num=0;  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<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()) {      SVertex_const_iterator vc = L.front(); L.pop_front();      if ( is_isolated(vc) ) continue;      SHalfedge_around_svertex_const_circulator 	havc(first_out_edge(vc)), hend(havc);      CGAL_For_all(havc,hend) {        if (!visited[havc->target()]) {          L.push_back(havc->target()); visited[havc->target()]=true;         }      }    }    ++comp_num;  }  return comp_num;   }CGAL_END_NAMESPACE#endif // CGAL_SM_CONST_DECORATOR_H

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -