PageRenderTime 63ms CodeModel.GetById 35ms RepoModel.GetById 1ms app.codeStats 0ms

/include/CGAL/Nef_S2/SM_const_decorator.h

https://bitbucket.org/jtotz/cgal
C Header | 415 lines | 249 code | 66 blank | 100 comment | 35 complexity | 1c205b3932795a36dcbba95a238dcd59 MD5 | raw file
Possible License(s): LGPL-2.1, LGPL-2.0
  1. // Copyright (c) 1997-2002 Max-Planck-Institute Saarbruecken (Germany).
  2. // All rights reserved.
  3. //
  4. // This file is part of CGAL (www.cgal.org); you may redistribute it under
  5. // the terms of the Q Public License version 1.0.
  6. // See the file LICENSE.QPL distributed with CGAL.
  7. //
  8. // Licensees holding a valid commercial license may use this file in
  9. // accordance with the commercial license agreement provided with the software.
  10. //
  11. // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
  12. // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  13. //
  14. // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.7-branch/Nef_S2/include/CGAL/Nef_S2/SM_const_decorator.h $
  15. // $Id: SM_const_decorator.h 57092 2010-06-25 08:27:45Z afabri $
  16. //
  17. //
  18. // Author(s) : Michael Seel <seel@mpi-sb.mpg.de>
  19. // Miguel Granados <granados@mpi-sb.mpg.de>
  20. // Susan Hert <hert@mpi-sb.mpg.de>
  21. // Lutz Kettner <kettner@mpi-sb.mpg.de>
  22. // Peter Hachenberger <hachenberger@mpi-sb.mpg.de>
  23. #ifndef CGAL_SM_CONST_DECORATOR_H
  24. #define CGAL_SM_CONST_DECORATOR_H
  25. #include <CGAL/basic.h>
  26. #include <CGAL/circulator.h>
  27. #include <CGAL/Unique_hash_map.h>
  28. #include <CGAL/Nef_2/Object_index.h>
  29. #include <CGAL/Nef_S2/SM_iteration.h>
  30. #include <CGAL/Nef_S2/SM_decorator_traits.h>
  31. #include <string>
  32. #include <list>
  33. #include <sstream>
  34. #undef CGAL_NEF_DEBUG
  35. #define CGAL_NEF_DEBUG 67
  36. #include <CGAL/Nef_2/debug.h>
  37. namespace CGAL {
  38. template <typename Map_>
  39. class SM_const_decorator {
  40. typedef SM_const_decorator<Map_> Self;
  41. public:
  42. typedef Map_ Map;
  43. typedef const Map_ Sphere_map;
  44. typedef SM_decorator_const_traits<Map> Decorator_traits;
  45. /*{\Mdefinition ...}*/
  46. /*{\Mtypes 5}*/
  47. typedef typename Map::Sphere_kernel Sphere_kernel;
  48. /*{\Mtypemember spherical geometry.}*/
  49. typedef typename Map::Sphere_point Sphere_point;
  50. /*{\Mtypemember embedding vertices.}*/
  51. typedef typename Map::Sphere_segment Sphere_segment;
  52. /*{\Mtypemember embedding edges.}*/
  53. typedef typename Map::Sphere_circle Sphere_circle;
  54. /*{\Mtypemember embedding loops.}*/
  55. typedef typename Map::Sphere_direction Sphere_direction;
  56. /*{\Mtypemember embedding directions.}*/
  57. typedef typename Map::Mark Mark;
  58. /*{\Mtypemember attributes of objects (vertices, edges, faces).}*/
  59. typedef size_t Size_type;
  60. /*{\Mtypemember size type.}*/
  61. typedef void* GenPtr;
  62. // typedef typename Map::Constructor_const_parameter Constructor_parameter;
  63. typedef typename Map::SVertex_const_handle SVertex_const_handle;
  64. typedef typename Map::SVertex_const_iterator SVertex_const_iterator;
  65. typedef typename Map::SHalfedge_const_handle SHalfedge_const_handle;
  66. typedef typename Map::SHalfedge_const_iterator SHalfedge_const_iterator;
  67. typedef typename Map::SHalfloop_const_handle SHalfloop_const_handle;
  68. typedef typename Map::SHalfloop_const_iterator SHalfloop_const_iterator;
  69. typedef typename Map::SFace_const_handle SFace_const_handle;
  70. typedef typename Map::SFace_const_iterator SFace_const_iterator;
  71. /*{\Mtext Local types are handles, iterators and circulators of the
  72. following kind: |SVertex_handle|, |SVertex_iterator|, |SHalfedge_handle|,
  73. |SHalfedge_iterator|, |SHalfloop_handle|, |SHalfloop_iterator|,
  74. |SFace_handle|, |SFace_iterator|. Additionally the following
  75. circulators are defined.}*/
  76. typedef typename Map::SHalfedge_around_svertex_const_circulator
  77. SHalfedge_around_svertex_const_circulator;
  78. /*{\Mtypemember circulating the adjacency list of an vertex |v|.}*/
  79. typedef typename Map::SHalfedge_around_sface_const_circulator
  80. SHalfedge_around_sface_const_circulator;
  81. /*{\Mtypemember circulating the face cycle of an face |f|.}*/
  82. typedef typename Map::SFace_cycle_const_iterator
  83. SFace_cycle_const_iterator;
  84. /*{\Mtypemember iterating all sface cycles of an sface |f|.
  85. The iterator has method |bool is_svertex()|, |bool is_shalfedge()|,
  86. |bool is_shalfloop()|, and can be converted to the corresponding
  87. handles |SVertex_const_handle|, |SHalfedge_const_handle|, or
  88. |SHalfloop_const_handle|.}*/
  89. protected:
  90. const Map* psm_;
  91. void set_sm(const Map* W) {
  92. psm_ = W;
  93. }
  94. public:
  95. /*{\Mcreation 3}*/
  96. SM_const_decorator() : psm_(0) {}
  97. SM_const_decorator(const Self& D) : psm_(D.psm_) {}
  98. Self& operator=(const Self& D) { psm_=D.psm_; return *this; }
  99. SM_const_decorator(const Map* M) : psm_(M) {}
  100. /*{\Mcreate constructs a plane map decorator exploring |M|.}*/
  101. /*{\Moperations 4 4}*/
  102. const Map* sphere_map() const { return psm_; }
  103. bool is_isolated(SVertex_const_handle v) const
  104. /*{\Mop returns |true| when |v| is linked to the interior of a face.}*/
  105. { return (SHalfedge_const_handle(v->out_sedge()) == SHalfedge_const_handle()); }
  106. SHalfedge_const_handle first_out_edge(SVertex_const_handle v) const
  107. /*{\Mop returns one edge with source |v|. It's the starting point for
  108. the circular iteration over the edges with source |v|.
  109. \precond |!is_isolated(v)|.}*/
  110. { return v->out_sedge(); }
  111. SHalfedge_const_handle last_out_edge(SVertex_const_handle v) const
  112. /*{\Mop returns one edge with source |v|. \precond |!is_isolated(v)|.}*/
  113. { return cap(v->out_sedge()); }
  114. SHalfedge_const_handle cyclic_adj_succ(SHalfedge_const_handle e) const
  115. /*{\Mop returns the edge after |e| in the cyclic ordered adjacency list of
  116. |e->source()|.}*/
  117. { return e->sprev()->twin(); }
  118. SHalfedge_const_handle cyclic_adj_pred(SHalfedge_const_handle e) const
  119. /*{\Mop returns the edge before |e| in the cyclic ordered adjacency list of
  120. |e->source()|.}*/
  121. { return e->twin()->snext(); }
  122. /*{\Mtext \headerline{Iteration} \setopdims{3.3cm}{0cm}}*/
  123. SVertex_const_iterator svertices_begin() const
  124. { return psm_->svertices_begin(); }
  125. SVertex_const_iterator svertices_end() const
  126. { return psm_->svertices_end(); }
  127. SHalfedge_const_iterator shalfedges_begin() const
  128. { return psm_->shalfedges_begin(); }
  129. SHalfedge_const_iterator shalfedges_end() const
  130. { return psm_->shalfedges_end(); }
  131. SFace_const_iterator sfaces_begin() const
  132. { return psm_->sfaces_begin(); }
  133. SFace_const_iterator sfaces_end() const
  134. { return psm_->sfaces_end(); }
  135. SHalfloop_const_iterator shalfloops_begin() const
  136. { return psm_->shalfloops_begin(); }
  137. SHalfloop_const_iterator shalfloops_end() const
  138. { return psm_->shalfloops_end(); }
  139. SHalfloop_const_handle shalfloop() const
  140. /*{\Mop returns access to the loop.}*/
  141. { return psm_->shalfloop(); }
  142. bool has_shalfloop() const
  143. /*{\Mop returns true iff there is a loop.}*/
  144. { return psm_->has_shalfloop(); }
  145. SHalfedge_around_svertex_const_circulator
  146. out_edges(SVertex_const_handle v) const
  147. /*{\Mop returns a circulator for the cyclic adjacency list of |v|.
  148. \precond the adjacency list is not empty.}*/
  149. { return SHalfedge_around_svertex_const_circulator(first_out_edge(v)); }
  150. SFace_cycle_const_iterator sface_cycles_begin(SFace_const_handle f) const
  151. /*{\Mop returns an iterator for all bounding face cycles of |f|.
  152. The iterator is is convertable to |SVertex_const_handle|,
  153. |SHalfloop_const_handle|, or |SHalfedge_const_handle|.}*/
  154. { return f->boundary_entry_objects_.begin(); }
  155. SFace_cycle_const_iterator sface_cycles_end(SFace_const_handle f) const
  156. /*{\Mop returns the past the end iterator of |f|.}*/
  157. { return f->boundary_entry_objects_.end(); }
  158. /*{\Mtext \headerline{Statistics and Integrity}}*/
  159. Size_type number_of_svertices() const
  160. /*{\Mop returns the number of vertices.}*/
  161. { return psm_->number_of_svertices(); }
  162. Size_type number_of_shalfedges() const
  163. /*{\Mop returns the number of halfedges.}*/
  164. { return psm_->number_of_shalfedges(); }
  165. Size_type number_of_sedges() const
  166. /*{\Mop returns the number of edges.}*/
  167. { return number_of_shalfedges()/2; }
  168. Size_type number_of_shalfloops() const
  169. /*{\Mop returns the number of halfloops.}*/
  170. { return psm_->number_of_shalfloops(); }
  171. Size_type number_of_sloops() const
  172. /*{\Mop returns the number of loops.}*/
  173. { return psm_->number_of_shalfloops()/2; }
  174. Size_type number_of_sfaces() const
  175. /*{\Mop returns the number of faces.}*/
  176. { return psm_->number_of_sfaces(); }
  177. Size_type number_of_sface_cycles() const;
  178. /*{\Mop returns the number of face cycles.}*/
  179. Size_type number_of_connected_components() const;
  180. /*{\Mop calculates the number of connected components of |P|.}*/
  181. void print_statistics(std::ostream& os = std::cout) const
  182. /*{\Mop print the statistics of |P|: the number of vertices, edges,
  183. and faces.}*/
  184. {
  185. os << "Sphere Map - Statistics\n";
  186. os << "|V| = " << number_of_svertices() << std::endl;
  187. os << "|E| = " << number_of_shalfedges() << std::endl;
  188. os << "|L| = " << number_of_shalfloops() << std::endl;
  189. os << "|F| = " << number_of_sfaces() << std::endl;
  190. os << "|Fcs| = " << number_of_sface_cycles() << std::endl << std::endl;
  191. }
  192. void check_integrity_and_topological_planarity(bool faces=true) const;
  193. /*{\Mop checks the link structure and the genus of |P|.}*/
  194. SHalfedge_const_handle cas(SHalfedge_const_handle e) const
  195. { return cyclic_adj_succ(e); }
  196. SHalfedge_const_handle cap(SHalfedge_const_handle e) const
  197. { return cyclic_adj_pred(e); }
  198. template <typename H>
  199. bool is_sm_boundary_object(H h) const
  200. { return psm_->is_sm_boundary_object(h); }
  201. /*{\Mtext \headerline{Associated Information}\restoreopdims}*/
  202. /*{\Mtext \headerline{Iteration}}*/
  203. /*{\Mtext The list of all objects can be accessed via iterator ranges.
  204. For comfortable iteration we also provide iterations macros.
  205. The iterator range access operations are of the following kind:\\
  206. |SVertex_iterator svertices_begin()/svertices_end()|\\
  207. |SHalfedge_iterator shalfedges_begin()/shalfedges_end()|\\
  208. |SHalfloop_iterator shalfloops_begin()/shalfloops_end()|\\
  209. |SFace_iterator sfaces_begin()/sfaces_end()|
  210. The macros are then |CGAL_forall_svertices(v,M)|,
  211. |CGAL_forall_shalfedges(e,M)|, |CGAL_forall_sedges(e,M)|,
  212. |CGAL_forall_sfaces(f,M)|, |CGAL_forall_sface_cycles_of(fc,F)|
  213. where |M| is a sphere map and |F| is a sface.}*/
  214. }; // SM_const_decorator
  215. template <typename SM_>
  216. void SM_const_decorator<SM_>::
  217. check_integrity_and_topological_planarity(bool faces) const
  218. {
  219. CGAL_NEF_TRACEN("check_integrity_and_topological_planarity:");
  220. using CGAL::Object_index;
  221. Object_index<SVertex_const_iterator>
  222. VI(svertices_begin(),svertices_end(),'v');
  223. Object_index<SHalfedge_const_iterator>
  224. EI(shalfedges_begin(),shalfedges_end(),'e');
  225. Object_index<SFace_const_iterator>
  226. FI(sfaces_begin(),sfaces_end(),'f');
  227. typedef SHalfedge_around_svertex_const_circulator hvc_circulator;
  228. typedef SHalfedge_around_sface_const_circulator hfc_circulator;
  229. SVertex_const_handle v;
  230. int iso_vert_num=0;
  231. /* check the source links of out edges and count isolated vertices */
  232. CGAL_forall_svertices(v,*this) {
  233. if ( is_isolated(v) ) {
  234. if ( faces )
  235. CGAL_assertion_msg(v->incident_sface() != SFace_const_handle(), VI(v).c_str());
  236. ++iso_vert_num;
  237. } else {
  238. CGAL_assertion_msg(first_out_edge(v) != SHalfedge_const_handle(),
  239. VI(v).c_str());
  240. CGAL_NEF_TRACEN(v->point()<<" "<<EI(first_out_edge(v)));
  241. CGAL_assertion_msg(first_out_edge(v)->source() == v,
  242. VI(v).c_str());
  243. }
  244. }
  245. /* check the bidirected links and the face pointer init */
  246. SHalfedge_const_iterator e;
  247. CGAL_forall_shalfedges(e,*this) {
  248. CGAL_assertion( e->twin()->twin() == e );
  249. CGAL_assertion( e->source() != SVertex_const_handle() );
  250. CGAL_assertion( e->snext() != SHalfedge_const_handle() );
  251. CGAL_assertion( e->snext()->sprev() == e );
  252. CGAL_assertion( e->target() == e->snext()->source() );
  253. CGAL_assertion( e->sprev() != SHalfedge_const_handle() );
  254. CGAL_assertion( e->sprev()->snext() == e );
  255. CGAL_assertion( e->sprev()->twin()->source() == e->source() );
  256. if ( !faces ) continue;
  257. CGAL_assertion( e->incident_sface() != SFace_const_handle() );
  258. CGAL_assertion( e->snext()->incident_sface() == e->incident_sface() );
  259. CGAL_assertion( e->sprev()->incident_sface() == e->incident_sface() );
  260. }
  261. int fc_num(0),iv_num(0);
  262. SFace_const_iterator f;
  263. SFace_cycle_const_iterator fci;
  264. CGAL_forall_sfaces(f,*this) {
  265. CGAL_forall_sface_cycles_of(fci,f) {
  266. if ( fci.is_shalfedge() ) {
  267. CGAL_assertion( SHalfedge_const_handle(fci)->incident_sface() == f );
  268. ++fc_num;
  269. } else if ( fci.is_svertex() ) {
  270. CGAL_assertion( SVertex_const_handle(fci)->incident_sface() == f );
  271. ++iv_num;
  272. } else if( fci.is_shalfloop() ) {
  273. CGAL_assertion( SHalfloop_const_handle(fci)->incident_sface() == f );
  274. ++fc_num;
  275. } else CGAL_error_msg("damn generic handle.");
  276. }
  277. }
  278. CGAL_assertion_code(std::size_t v_num = number_of_svertices() -
  279. iso_vert_num +
  280. number_of_shalfloops());
  281. CGAL_assertion_code(std::size_t e_num = number_of_sedges() +
  282. number_of_shalfloops());
  283. CGAL_assertion_code(std::size_t c_num = number_of_connected_components() -
  284. iso_vert_num
  285. + number_of_sloops());
  286. CGAL_assertion_code(std::size_t f_num = number_of_sface_cycles() - c_num + 1);
  287. CGAL_assertion_code(CGAL_NEF_TRACEV(fc_num));
  288. CGAL_assertion_code(CGAL_NEF_TRACEV(iv_num));
  289. CGAL_assertion_code(CGAL_NEF_TRACEV(iso_vert_num));
  290. CGAL_assertion_code(CGAL_NEF_TRACEV(v_num));
  291. CGAL_assertion_code(CGAL_NEF_TRACEV(e_num));
  292. CGAL_assertion_code(CGAL_NEF_TRACEV(c_num));
  293. CGAL_assertion_code(CGAL_NEF_TRACEV(f_num));
  294. /* this means all face cycles and all isolated vertices are
  295. indeed referenced from a face */
  296. /* every isolated vertex increases the component count
  297. one face cycle per component is redundent except one
  298. finally check the Euler formula: */
  299. CGAL_assertion( v_num - e_num + f_num == 1 + c_num );
  300. }
  301. template <typename SM_>
  302. typename SM_const_decorator<SM_>::Size_type
  303. SM_const_decorator<SM_>::
  304. number_of_sface_cycles() const
  305. {
  306. unsigned int fc_num=0;
  307. CGAL::Unique_hash_map<SHalfedge_const_handle,bool> visited;
  308. SHalfedge_const_iterator e;
  309. CGAL_forall_shalfedges(e,*this) {
  310. if (visited[e]) continue;
  311. SHalfedge_around_sface_const_circulator hfc(e), hend(hfc);
  312. CGAL_For_all(hfc,hend) visited[hfc]=true;
  313. ++fc_num;
  314. }
  315. if ( has_shalfloop() ) fc_num += 2;
  316. return fc_num;
  317. }
  318. template <typename SM_>
  319. typename SM_const_decorator<SM_>::Size_type
  320. SM_const_decorator<SM_>::
  321. number_of_connected_components() const
  322. {
  323. int comp_num=0;
  324. CGAL::Unique_hash_map<SVertex_const_iterator,bool> visited(false);
  325. SVertex_const_iterator v;
  326. CGAL_forall_svertices(v,*this) {
  327. if (visited[v]) continue;
  328. std::list<SVertex_const_iterator> L;
  329. L.push_back(v); visited[v]=true;
  330. /* we keep the invariant that all nodes which have been stacked
  331. are marked visited */
  332. while (!L.empty()) {
  333. SVertex_const_iterator vc = L.front(); L.pop_front();
  334. if ( is_isolated(vc) ) continue;
  335. SHalfedge_around_svertex_const_circulator
  336. havc(first_out_edge(vc)), hend(havc);
  337. CGAL_For_all(havc,hend) {
  338. if (!visited[havc->target()]) {
  339. L.push_back(havc->target()); visited[havc->target()]=true;
  340. }
  341. }
  342. }
  343. ++comp_num;
  344. }
  345. return comp_num;
  346. }
  347. } //namespace CGAL
  348. #endif // CGAL_SM_CONST_DECORATOR_H