xc
enriched_polyhedron.h
1 // -*-c++-*-
2 //----------------------------------------------------------------------------
3 // xc utils library; general purpose classes and functions.
4 //
5 // Copyright (C) Luis C. Pérez Tato
6 //
7 // XC utils is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation, either version 3 of the License, or
10 // (at your option) any later version.
11 //
12 // This software is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program.
19 // If not, see <http://www.gnu.org/licenses/>.
20 //----------------------------------------------------------------------------
22 // //
23 // Class: Enriched_polyhedron //
24 // //
26 
27 #ifndef _POLYGON_MESH_
28 #define _POLYGON_MESH_
29 
30 // CGAL stuff
31 #include <CGAL/Cartesian.h>
32 #include <CGAL/Polyhedron_3.h>
33 #include <list>
34 #include "utility/geom/cgal_types.h"
35 #include "PolygonMap.h"
36 #include <cassert>
37 #include <GL/gl.h>
38 #include <GL/glu.h>
39 #include <fstream>
40 
41 // a refined facet with a normal and a tag
42 template <class Refs, class T, class P, class Norm>
43 class Enriched_facet : public CGAL::HalfedgeDS_face_base<Refs, T>
44  {
45  // tag
46  int m_tag;
47 
48  // normal
49  Norm m_normal;
50  public:
51  // life cycle
52  // no constructors to repeat, since only
53  // default constructor mandatory
54 
55  Enriched_facet(void) {}
56 
57  // tag
58  const int& tag(void) { return m_tag; }
59  void tag(const int& t) { m_tag = t; }
60 
61  // normal
62  typedef Norm Normal_3; //glVertex3f
63  Normal_3& normal(void) { return m_normal; }
64  const Normal_3& normal(void) const { return m_normal; }
65  };
66 
67 // a refined halfedge with a general tag and
68 // a binary tag to indicate wether it belongs
69 // to the control mesh or not
70 template <class Refs, class Tprev, class Tvertex, class Tface, class Norm>
71 class Enriched_halfedge : public CGAL::HalfedgeDS_halfedge_base<Refs,Tprev,Tvertex,Tface>
72  {
73  private:
74 
75  // tag
76  int m_tag;
77  // option for edge superimposing
78  bool m_control_edge;
79 
80  public:
81  // life cycle
82  Enriched_halfedge(void)
83  { m_control_edge = true; }
84 
85  // tag
86  const int& tag(void) const { return m_tag; }
87  int& tag(void) { return m_tag; }
88  void tag(const int& t) { m_tag = t; }
89 
90  // control edge
91  bool& control_edge(void) { return m_control_edge; }
92  const bool& control_edge(void) const { return m_control_edge; }
93  void control_edge(const bool& flag) { m_control_edge = flag; }
94  };
95 
96 // a refined vertex with a normal and a tag
97 template <class Refs, class T, class P, class Norm>
98 class Enriched_vertex : public CGAL::HalfedgeDS_vertex_base<Refs, T, P>
99  {
100  // tag
101  int m_tag;
102 
103  // normal
104  Norm m_normal;
105 
106  public:
107  // life cycle
108  Enriched_vertex(void){}
109  // repeat mandatory constructors
110  Enriched_vertex(const P& pt)
111  :CGAL::HalfedgeDS_vertex_base<Refs, T, P>(pt)
112  {}
113 
114  // normal
115  typedef Norm Normal_3;
116  Normal_3& normal(void) { return m_normal; }
117  const Normal_3& normal(void) const { return m_normal; }
118 
119  // tag
120  int& tag(void) { return m_tag; }
121  const int& tag(void) const { return m_tag; }
122  void tag(const int& t) { m_tag = t; }
123  };
124 
125 // A redefined items class for the Polyhedron_3
126 // with a refined vertex class that contains a
127 // member for the normal vector and a refined
128 // facet with a normal vector instead of the
129 // plane equation (this is an alternative
130 // solution instead of using
131 // Polyhedron_traits_with_normals_3).
132 
133 struct Enriched_items : public CGAL::Polyhedron_items_3
134  {
135  // wrap vertex
136  template <class Refs, class Traits>
138  {
139  typedef typename Traits::Point_3 Point;
140  typedef typename Traits::Vector_3 Normal;
141  typedef Enriched_vertex<Refs,
142  CGAL::Tag_true,
143  Point,
144  Normal> Vertex;
145  };
146 
147  // wrap face
148  template <class Refs, class Traits>
150  {
151  typedef typename Traits::Point_3 Point;
152  typedef typename Traits::Vector_3 Normal;
153  typedef Enriched_facet<Refs,
154  CGAL::Tag_true,
155  Point,
156  Normal> Face;
157  };
158 
159  // wrap halfedge
160  template <class Refs, class Traits>
162  {
163  typedef typename Traits::Vector_3 Normal;
164  typedef Enriched_halfedge<Refs,
165  CGAL::Tag_true,
166  CGAL::Tag_true,
167  CGAL::Tag_true,
168  Normal> Halfedge;
169  };
170  };
171 
172 //*********************************************************
173 template <class kernel, class items>
174 class Enriched_polyhedron : public CGAL::Polyhedron_3<kernel,items>
175  {
176  public :
177  typedef typename kernel::FT FT;
178  typedef typename kernel::Point_3 Point;
179  typedef typename kernel::Vector_3 Vector;
180  typedef typename kernel::Iso_cuboid_3 Iso_cuboid;
181  //Empieza modificación LCPT
182  typedef typename CGAL::Polyhedron_3<kernel,items>::Point_iterator Point_iterator;
183  typedef typename CGAL::Polyhedron_3<kernel,items>::Vertex_iterator Vertex_iterator;
184  typedef typename CGAL::Polyhedron_3<kernel,items>::Facet_iterator Facet_iterator;
185  typedef typename CGAL::Polyhedron_3<kernel,items>::Edge_iterator Edge_iterator;
186  typedef typename CGAL::Polyhedron_3<kernel,items>::Halfedge_iterator Halfedge_iterator;
187  typedef typename CGAL::Polyhedron_3<kernel,items>::Halfedge_around_facet_circulator Halfedge_around_facet_circulator;
188  typedef typename CGAL::Polyhedron_3<kernel,items>::Halfedge_around_vertex_circulator Halfedge_around_vertex_circulator;
189  typedef typename CGAL::Polyhedron_3<kernel,items>::Vertex_handle Vertex_handle;
190  typedef typename CGAL::Polyhedron_3<kernel,items>::Facet_handle Facet_handle;
191  typedef typename CGAL::Polyhedron_3<kernel,items>::Halfedge_handle Halfedge_handle;
192  //Termina modificación LCPT
193 
194  private :
195  // bounding box
196  Iso_cuboid m_bbox;
197 
198  // type
199  bool m_pure_quad;
200  bool m_pure_triangle;
201 
202  public :
203  // life cycle
204  Enriched_polyhedron(void)
205  : CGAL::Polyhedron_3<kernel,items>()
206  {
207  m_pure_quad = false;
208  m_pure_triangle = false;
209  }
210  virtual ~Enriched_polyhedron(void) {}
211 
212  // type
213  bool is_pure_triangle(void) { return m_pure_triangle; }
214  bool is_pure_quad(void) { return m_pure_quad; }
215 
216  // normals (per facet, then per vertex)
217  void compute_normals_per_facet(void)
218  { std::for_each(this->facets_begin(),this->facets_end(),this->Facet_normal()); }
219  void compute_normals_per_vertex(void)
220  { std::for_each(this->vertices_begin(),this->vertices_end(),this->Vertex_normal()); }
221  void compute_normals(void)
222  {
223  compute_normals_per_facet();
224  compute_normals_per_vertex();
225  }
226 
227  // bounding box
228  Iso_cuboid& bbox(void) { return m_bbox; }
229  const Iso_cuboid bbox(void) const { return m_bbox; }
230 
231  // compute bounding box
232  void compute_bounding_box(void);
233 
234  // bounding box
235  FT xmin(void) { return m_bbox.xmin(); }
236  FT xmax(void) { return m_bbox.xmax(); }
237  FT ymin(void) { return m_bbox.ymin(); }
238  FT ymax(void) { return m_bbox.ymax(); }
239  FT zmin(void) { return m_bbox.zmin(); }
240  FT zmax(void) { return m_bbox.zmax(); }
241 
242  // copy bounding box
243  void copy_bounding_box(Enriched_polyhedron<kernel,items> *pMesh)
244  { m_bbox = pMesh->bbox(); }
245 
246  // degree of a face
247  static unsigned int degree(Facet_handle pFace)
248  { return CGAL::circulator_size(pFace->facet_begin()); }
249 
250  // valence of a vertex
251  static unsigned int valence(Vertex_handle pVertex)
252  { return CGAL::circulator_size(pVertex->vertex_begin()); }
253 
254  // check wether a vertex is on a boundary or not
255  static bool is_border(Vertex_handle pVertex);
256 
257  // get any border halfedge attached to a vertex
258  Halfedge_handle get_border_halfedge(Vertex_handle pVertex);
259 
260  // tag all halfedges
261  void tag_halfedges(const int tag);
262  // tag all facets
263  void tag_facets(const int tag);
264 
265  // set index for all vertices
266  void set_index_vertices(void);
267 
268  // is pure degree ?
269  bool is_pure_degree(unsigned int d);
270 
271  // compute type
272  void compute_type(void)
273  {
274  m_pure_quad = is_pure_degree(4);
275  m_pure_triangle = is_pure_degree(3);
276  }
277 
278  // compute facet center
279  void compute_facet_center(Facet_handle pFace,Point &center);
280 
281  // compute average edge length around a vertex
282  FT average_edge_length_around(Vertex_handle pVertex);
283 
284  // draw using OpenGL commands (display lists)
285  void gl_draw(bool smooth_shading,bool use_normals);
286 
287  void gl_draw_facet(Facet_handle pFacet,bool smooth_shading,bool use_normals);
288 
289  // superimpose edges
290  void superimpose_edges(bool skip_ordinary_edges = true,bool skip_control_edges = false,bool voronoi_edge = false);
291  // superimpose vertices
292  void superimpose_vertices(void);
293  // superimpose vertices
294  void superimpose_spheres(GEOM_FT scale);
295 
296  // write in obj file format (OBJ).
297  void write_obj(char *pFilename,int incr = 1); // 1-based by default
298 
299  // draw bounding box
300  void gl_draw_bounding_box(void);
301 
302  // count #boundaries
303  unsigned int nb_boundaries(void);
304 
305  // tag component
306  void tag_component(Facet_handle pSeedFacet,const int tag_free, const int tag_done);
307 
308  // count #components
309  unsigned int nb_components(void);
310 
311  // compute the genus
312  // V - E + F + B = 2 (C - G)
313  // C -> #connected components
314  // G : genus
315  // B : #boundaries
316  int genus(void);
317  int genus(int c,int v,int f,int e,int b);
318  };
319 
320 template <class kernel, class items>
322  {
323  if(this->size_of_vertices() == 0)
324  {
325  assert(false);
326  return;
327  }
328 
329  FT xmin,xmax,ymin,ymax,zmin,zmax;
330  Vertex_iterator pVertex = this->vertices_begin();
331  xmin = xmax = pVertex->point().x();
332  ymin = ymax = pVertex->point().y();
333  zmin = zmax = pVertex->point().z();
334  for(;pVertex != this->vertices_end();pVertex++)
335  {
336  const Point& p = pVertex->point();
337 
338  xmin = std::min(xmin,p.x());
339  ymin = std::min(ymin,p.y());
340  zmin = std::min(zmin,p.z());
341 
342  xmax = std::max(xmax,p.x());
343  ymax = std::max(ymax,p.y());
344  zmax = std::max(zmax,p.z());
345  }
346  m_bbox= Iso_cuboid(xmin,ymin,zmin,xmax,ymax,zmax);
347  }
348 
349 //check wether a vertex is on a boundary or not
350 template <class kernel, class items>
351 bool Enriched_polyhedron<kernel,items>::is_border(Vertex_handle pVertex)
352  {
353  Halfedge_around_vertex_circulator pHalfEdge = pVertex->vertex_begin();
354  if(pHalfEdge == nullptr) // isolated vertex
355  return true;
356  Halfedge_around_vertex_circulator d = pHalfEdge;
357  CGAL_For_all(pHalfEdge,d)
358  if(pHalfEdge->is_border())
359  return true;
360  return false;
361  }
362 
363 // get any border halfedge attached to a vertex
364 template <class kernel, class items>
365 typename Enriched_polyhedron<kernel,items>::Halfedge_handle Enriched_polyhedron<kernel,items>::get_border_halfedge(Vertex_handle pVertex)
366  {
367  Halfedge_around_vertex_circulator pHalfEdge = pVertex->vertex_begin();
368  Halfedge_around_vertex_circulator d = pHalfEdge;
369  CGAL_For_all(pHalfEdge,d)
370  if(pHalfEdge->is_border())
371  return pHalfEdge;
372  return nullptr;
373  }
374 
375 // tag all halfedges
376 template <class kernel, class items>
378  {
379  for(Halfedge_iterator pHalfedge = this->halfedges_begin();
380  pHalfedge != this->halfedges_end();
381  pHalfedge++)
382  pHalfedge->tag(tag);
383  }
384 
385 // tag all facets
386 template <class kernel, class items>
388  {
389  for(Facet_iterator pFacet = this->facets_begin();
390  pFacet != this->facets_end();
391  pFacet++)
392  pFacet->tag(tag);
393  }
394 
395 // set index for all vertices
396 template <class kernel, class items>
398  {
399  int index = 0;
400  for(Vertex_iterator pVertex = this->vertices_begin();
401  pVertex != this->vertices_end();
402  pVertex++)
403  pVertex->tag(index++);
404  }
405 
406 // is pure degree ?
407 template <class kernel, class items>
409  {
410  for(Facet_iterator pFace = this->facets_begin();
411  pFace != this->facets_end();
412  pFace++)
413  if(degree(pFace) != d)
414  return false;
415  return true;
416  }
417 
418 // compute facet center
419 template <class kernel, class items>
420 void Enriched_polyhedron<kernel,items>::compute_facet_center(Facet_handle pFace,Point &center)
421  {
422  Halfedge_around_facet_circulator pHalfEdge = pFace->facet_begin();
423  Halfedge_around_facet_circulator end = pHalfEdge;
424  Vector vec(0.0,0.0,0.0);
425  int degree = 0;
426  CGAL_For_all(pHalfEdge,end)
427  {
428  vec = vec + (pHalfEdge->vertex()->point()-CGAL::ORIGIN);
429  degree++;
430  }
431  center = CGAL::ORIGIN + (vec/(typename kernel::FT)degree);
432  }
433 
434 // compute average edge length around a vertex
435 template <class kernel, class items>
436 typename Enriched_polyhedron<kernel,items>::FT Enriched_polyhedron<kernel,items>::average_edge_length_around(Vertex_handle pVertex)
437  {
438  FT sum = 0.0;
439  Halfedge_around_vertex_circulator pHalfEdge = pVertex->vertex_begin();
440  Halfedge_around_vertex_circulator end = pHalfEdge;
441  Vector vec(0.0,0.0,0.0);
442  int degree = 0;
443  CGAL_For_all(pHalfEdge,end)
444  {
445  Vector vec = pHalfEdge->vertex()->point()-
446  pHalfEdge->opposite()->vertex()->point();
447  sum += sqrt_FT(vec*vec);
448  degree++;
449  }
450  return sum / (FT) degree;
451  }
452 
453 // draw using OpenGL commands (display lists)
454 template <class kernel, class items>
455 void Enriched_polyhedron<kernel,items>::gl_draw(bool smooth_shading,bool use_normals)
456  {
457  // draw polygons
458  Facet_iterator pFacet= this->facets_begin();
459  for(;pFacet != this->facets_end();pFacet++)
460  {
461  // begin polygon assembly
462  glBegin(GL_POLYGON);
463  gl_draw_facet(pFacet,smooth_shading,use_normals);
464  glEnd(); // end polygon assembly
465  }
466  glFlush();
467  }
468 
469 template <class kernel, class items>
470 void Enriched_polyhedron<kernel,items>::gl_draw_facet(Facet_handle pFacet,bool smooth_shading,bool use_normals)
471  {
472  // one normal per face
473  if(use_normals && !smooth_shading)
474  {
475  const typename Enriched_polyhedron<kernel,items>::Facet::Normal_3 &normal= pFacet->normal();
476  ::glNormal3f(this->normal[0],this->normal[1],this->normal[2]);
477  }
478 
479  // revolve around current face to get vertices
480  Halfedge_around_facet_circulator pHalfedge = pFacet->facet_begin();
481  do
482  {
483  // one normal per vertex
484  if(use_normals && smooth_shading)
485  {
486  const typename Enriched_polyhedron<kernel,items>::Facet::Normal_3& normal = pHalfedge->vertex()->normal();
487  ::glNormal3f(normal[0],normal[1],normal[2]);
488  }
489 
490  // polygon assembly is performed per vertex
491  const Point& point = pHalfedge->vertex()->point();
492  ::glVertex3d(point[0],point[1],point[2]);
493  }
494  while(++pHalfedge != pFacet->facet_begin());
495  }
496 
497 // superimpose edges
498 template <class kernel, class items>
499 void Enriched_polyhedron<kernel,items>::superimpose_edges(bool skip_ordinary_edges,bool skip_control_edges, bool voronoi_edge)
500  {
501  glBegin(GL_LINES);
502  for(Edge_iterator h = this->edges_begin();h != this->edges_end(); h++)
503  {
504  // ignore this edges
505  if(skip_ordinary_edges && !h->control_edge()) continue;
506 
507  // ignore control edges
508  if(skip_control_edges && h->control_edge()) continue;
509 
510  if(voronoi_edge)
511  {
512  Facet_handle pFace1 = h->facet();
513  Facet_handle pFace2 = h->opposite()->facet();
514  if(pFace1 == nullptr || pFace2 == nullptr) continue;
515 
516  const Point &p1 = h->vertex()->point();
517  const Point &p2 = h->next()->vertex()->point();
518  const Point &p3 = h->next()->next()->vertex()->point();
519 
520  kernel k;
521  Point d1 = k.construct_circumcenter_3_object()(p1,p2,p3);
522  glVertex3f(d1[0],d1[1],d1[2]);
523 
524  const Point &pp1 = h->opposite()->vertex()->point();
525  const Point &pp2 = h->opposite()->next()->vertex()->point();
526  const Point &pp3 = h->opposite()->next()->next()->vertex()->point();
527  Point d2 = k.construct_circumcenter_3_object()(pp1,pp2,pp3);
528  glVertex3f(d2[0],d2[1],d2[2]);
529  }
530  else
531  {
532  // assembly and draw line segment
533  const Point& p1 = h->prev()->vertex()->point();
534  const Point& p2 = h->vertex()->point();
535  glVertex3f(p1[0],p1[1],p1[2]);
536  glVertex3f(p2[0],p2[1],p2[2]);
537  }
538  }
539  ::glEnd();
540  }
541 
542 // superimpose vertices
543 template <class kernel, class items>
545  {
546  glBegin(GL_POINTS);
547  for(Point_iterator pPoint = this->points_begin();pPoint != this->points_end();pPoint++)
548  glVertex3f(pPoint->x(),pPoint->y(),pPoint->z());
549  ::glEnd(); // // end point assembly
550  }
551 
552 // superimpose vertices
553 template <class kernel, class items>
555  {
556  GLUquadricObj* pQuadric = gluNewQuadric();
557  ::glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
558 
559  for(Vertex_iterator pVertex = this->vertices_begin();pVertex != this->vertices_end(); pVertex++)
560  {
561  glPushMatrix();
562  GEOM_FT radius = average_edge_length_around(pVertex);
563  glTranslatef(pVertex->point().x(),
564  pVertex->point().y(),
565  pVertex->point().z());
566  gluSphere(pQuadric,scale*radius,24,24);
567  glPopMatrix();
568  }
569  gluDeleteQuadric(pQuadric);
570  }
571 
572 // write in obj file format (OBJ).
573 template <class kernel, class items>
574 void Enriched_polyhedron<kernel,items>::write_obj(char *pFilename,int incr)
575  {
576  std::ofstream stream(pFilename);
577 
578  // output vertices
579  for(Point_iterator pPoint = this->points_begin();pPoint != this->points_end();pPoint++)
580  stream << 'v' << ' ' << pPoint->x() << ' ' <<
581  pPoint->y() << ' ' <<
582  pPoint->z() << std::endl;
583 
584  // precompute vertex indices
585  this->set_index_vertices();
586 
587  // output facets
588  for(Facet_iterator pFacet = this->facets_begin();pFacet != this->facets_end(); pFacet++)
589  {
590  stream << 'f';
591  Halfedge_around_facet_circulator pHalfedge = pFacet->facet_begin();
592  do
593  stream << ' ' << pHalfedge->vertex()->tag()+incr;
594  while(++pHalfedge != pFacet->facet_begin());
595  stream << std::endl;
596  }
597  }
598 
599  // draw bounding box
600 template <class kernel, class items>
602  {
603  glBegin(GL_LINES);
604 
605  // along x axis
606  glVertex3f(m_bbox.xmin(),m_bbox.ymin(),m_bbox.zmin());
607  glVertex3f(m_bbox.xmax(),m_bbox.ymin(),m_bbox.zmin());
608  glVertex3f(m_bbox.xmin(),m_bbox.ymin(),m_bbox.zmax());
609  glVertex3f(m_bbox.xmax(),m_bbox.ymin(),m_bbox.zmax());
610  glVertex3f(m_bbox.xmin(),m_bbox.ymax(),m_bbox.zmin());
611  glVertex3f(m_bbox.xmax(),m_bbox.ymax(),m_bbox.zmin());
612  glVertex3f(m_bbox.xmin(),m_bbox.ymax(),m_bbox.zmax());
613  glVertex3f(m_bbox.xmax(),m_bbox.ymax(),m_bbox.zmax());
614 
615  // along y axis
616  glVertex3f(m_bbox.xmin(),m_bbox.ymin(),m_bbox.zmin());
617  glVertex3f(m_bbox.xmin(),m_bbox.ymax(),m_bbox.zmin());
618  glVertex3f(m_bbox.xmin(),m_bbox.ymin(),m_bbox.zmax());
619  glVertex3f(m_bbox.xmin(),m_bbox.ymax(),m_bbox.zmax());
620  glVertex3f(m_bbox.xmax(),m_bbox.ymin(),m_bbox.zmin());
621  glVertex3f(m_bbox.xmax(),m_bbox.ymax(),m_bbox.zmin());
622  glVertex3f(m_bbox.xmax(),m_bbox.ymin(),m_bbox.zmax());
623  glVertex3f(m_bbox.xmax(),m_bbox.ymax(),m_bbox.zmax());
624 
625  // along z axis
626  glVertex3f(m_bbox.xmin(),m_bbox.ymin(),m_bbox.zmin());
627  glVertex3f(m_bbox.xmin(),m_bbox.ymin(),m_bbox.zmax());
628  glVertex3f(m_bbox.xmin(),m_bbox.ymax(),m_bbox.zmin());
629  glVertex3f(m_bbox.xmin(),m_bbox.ymax(),m_bbox.zmax());
630  glVertex3f(m_bbox.xmax(),m_bbox.ymin(),m_bbox.zmin());
631  glVertex3f(m_bbox.xmax(),m_bbox.ymin(),m_bbox.zmax());
632  glVertex3f(m_bbox.xmax(),m_bbox.ymax(),m_bbox.zmin());
633  glVertex3f(m_bbox.xmax(),m_bbox.ymax(),m_bbox.zmax());
634 
635  ::glEnd();
636  }
637 
638 // count #boundaries
639 template <class kernel, class items>
641  {
642  unsigned int nb = 0;
643  tag_halfedges(0);
644  for(Halfedge_iterator he = this->halfedges_begin();
645  he != this->halfedges_end();
646  he++)
647  {
648  if(he->is_border() && he->tag() == 0)
649  {
650  nb++;
651  Halfedge_handle curr = he;
652  do
653  {
654  curr = curr->next();
655  curr->tag(1);
656  }
657  while(curr != he);
658  }
659  }
660  return nb;
661  }
662 
663 template <class kernel, class items>
664 void Enriched_polyhedron<kernel,items>::tag_component(Facet_handle pSeedFacet,
665  const int tag_free,
666  const int tag_done)
667  {
668  pSeedFacet->tag(tag_done);
669  std::list<Facet_handle> facets;
670  facets.push_front(pSeedFacet);
671  while(!facets.empty())
672  {
673  Facet_handle pFacet = facets.front();
674  facets.pop_front();
675  pFacet->tag(tag_done);
676  Halfedge_around_facet_circulator pHalfedge = pFacet->facet_begin();
677  Halfedge_around_facet_circulator end = pHalfedge;
678  CGAL_For_all(pHalfedge,end)
679  {
680  Facet_handle pNFacet = pHalfedge->opposite()->facet();
681  if(pNFacet != nullptr && pNFacet->tag() == tag_free)
682  {
683  facets.push_front(pNFacet);
684  pNFacet->tag(tag_done);
685  }
686  }
687  }
688  }
689 
690 // count #components
691 template <class kernel, class items>
693  {
694  unsigned int nb = 0;
695  tag_facets(0);
696  for(Facet_iterator pFacet = this->facets_begin(); pFacet != this->facets_end(); pFacet++)
697  {
698  if(pFacet->tag() == 0)
699  {
700  nb++;
701  tag_component(pFacet,0,1);
702  }
703  }
704  return nb;
705  }
706  // compute the genus
707  // V - E + F + B = 2 (C - G)
708  // C -> #connected components
709  // G : genus
710  // B : #boundaries
711 template <class kernel, class items>
713  {
714  const int c = this->nb_components();
715  const int b = this->nb_boundaries();
716  const int v = this->size_of_vertices();
717  const int e = this->size_of_halfedges()/2;
718  const int f = this->size_of_facets();
719  return genus(c,v,f,e,b);
720  }
721 template <class kernel, class items>
722 int Enriched_polyhedron<kernel,items>::genus(int c,int v,int f,int e,int b)
723  { return (2*c+e-b-f-v)/2; }
724 
725 // compute facet normal
726 struct Facet_normal // (functor)
727  {
728  template <class Facet>
729  void operator()(Facet& f);
730  };
731 
732 template <class Facet>
733 void Facet_normal::operator()(Facet& f)
734  {
735  typename Facet::Normal_3 sum = CGAL::NULL_VECTOR;
736  typename Facet::Halfedge_around_facet_circulator h = f.facet_begin();
737  do
738  {
739  typename Facet::Normal_3 normal = CGAL::cross_product(
740  h->next()->vertex()->point() - h->vertex()->point(),
741  h->next()->next()->vertex()->point() - h->next()->vertex()->point());
742  GEOM_FT sqnorm = normal * normal;
743  if(sqnorm != 0) normal = normal / sqrt_FT(sqnorm);
744  sum = sum + normal;
745  }
746  while(++h != f.facet_begin());
747  float sqnorm = sum * sum;
748  if(sqnorm != 0.0)
749  f.normal() = sum / sqrt_FT(sqnorm);
750  else
751  {
752  f.normal() = CGAL::NULL_VECTOR;
753  std::cerr << "degenerate face\n";
754  }
755  }
756 
757 
758 // compute vertex normal
759 struct Vertex_normal // (functor)
760  {
761  template <class Vertex>
762  void operator()(Vertex& v);
763  };
764 
765 template <class Vertex>
766 void Vertex_normal::operator()(Vertex& v)
767  {
768  typename Vertex::Normal_3 normal = CGAL::NULL_VECTOR;
769  typename Vertex::Halfedge_around_vertex_const_circulator pHalfedge = v.vertex_begin();
770  typename Vertex::Halfedge_around_vertex_const_circulator begin = pHalfedge;
771  CGAL_For_all(pHalfedge,begin)
772  if(!pHalfedge->is_border()) normal = normal + pHalfedge->facet()->normal();
773  float sqnorm = normal * normal;
774  if(sqnorm != 0.0f)
775  v.normal() = normal / sqrt_FT(sqnorm);
776  else
777  v.normal() = CGAL::NULL_VECTOR;
778  }
779 
781 
782 EPolyhedron enriquece(const CGPolyhedron_3 &pol);
783 CGPolyhedron_3 empobrece(const EPolyhedron &pol);
784 
785 #endif // _POLYGON_MESH_
Definition: enriched_polyhedron.h:174
Definition: enriched_polyhedron.h:133
Definition: enriched_polyhedron.h:137
Definition: enriched_polyhedron.h:726
Definition: enriched_polyhedron.h:161
Definition: enriched_polyhedron.h:43
Definition: enriched_polyhedron.h:759
Definition: enriched_polyhedron.h:98
Definition: enriched_polyhedron.h:71
Definition: enriched_polyhedron.h:149