BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Arr_spherical_gaussian_map_3/Arr_polyhedral_sgm.h
Go to the documentation of this file.
00001 // Copyright (c) 2006 Tel-Aviv University (Israel).
00002 // All rights reserved.
00003 //
00004 // This file is part of CGAL (www.cgal.org); you may redistribute it under
00005 // the terms of the Q Public License version 1.0.
00006 // See the file LICENSE.QPL distributed with CGAL.
00007 //
00008 // Licensees holding a valid commercial license may use this file in
00009 // accordance with the commercial license agreement provided with the software.
00010 //
00011 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00012 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00013 //
00014 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Arrangement_on_surface_2/include/CGAL/Arr_spherical_gaussian_map_3/Arr_polyhedral_sgm.h $
00015 // $Id: Arr_polyhedral_sgm.h 50610 2009-07-15 15:21:14Z efif $
00016 // 
00017 // Author(s)     : Efi Fogel         <efif@post.tau.ac.il>
00018 
00019 #ifndef CGAL_ARR_POLYHEDRAL_SGM_H
00020 #define CGAL_ARR_POLYHEDRAL_SGM_H
00021 
00027 #include <string>
00028 #include <vector>
00029 #include <list>
00030 #include <iostream>
00031 
00032 #include <boost/type_traits.hpp>
00033 
00034 #include <CGAL/basic.h>
00035 #include <CGAL/Polyhedron_incremental_builder_3.h>
00036 #include <CGAL/Polyhedron_traits_with_normals_3.h>
00037 #include <CGAL/Polyhedron_3.h>
00038 #include <CGAL/HalfedgeDS_vector.h>
00039 #include <CGAL/IO/Polyhedron_iostream.h>
00040 #include <CGAL/Aff_transformation_3.h>
00041 #include <CGAL/aff_transformation_tags.h>
00042 #include <CGAL/intersections.h>
00043 #include <CGAL/Polygon_2_algorithms.h>
00044 
00045 #include <CGAL/Arr_overlay_2.h>
00046 #include <CGAL/Arr_spherical_gaussian_map_3/Arr_spherical_gaussian_map_3.h>
00047 #include <CGAL/Arr_spherical_gaussian_map_3/Arr_polyhedral_sgm_traits.h>
00048 #include <CGAL/Arr_spherical_gaussian_map_3/Arr_polyhedral_sgm_arr_dcel.h>
00049 #include <CGAL/Arr_spherical_gaussian_map_3/Arr_polyhedral_sgm_overlay.h>
00050 #include <CGAL/Arr_spherical_gaussian_map_3/Arr_polyhedral_sgm_initializer_visitor.h>
00051 
00052 CGAL_BEGIN_NAMESPACE
00053 
00056 template <typename PolyhedralSgm,
00057           typename Polyhedron,
00058           typename Visitor =
00059             Arr_polyhedral_sgm_initializer_visitor<PolyhedralSgm, Polyhedron> >
00060 class Arr_polyhedral_sgm_initializer :
00061   public Arr_sgm_initializer<typename PolyhedralSgm::Base>
00062 {
00063 private:
00064   // Base type:
00065   typedef Arr_sgm_initializer<typename PolyhedralSgm::Base> Base;
00066   typedef typename PolyhedralSgm::Geometry_traits_2         Geometry_traits_2;
00067   typedef typename Geometry_traits_2::Point_2               Point_2;
00068   typedef typename Geometry_traits_2::X_monotone_curve_2    X_monotone_curve_2;
00069   typedef typename Geometry_traits_2::Curve_2               Curve_2;  
00070 
00071   typedef typename Geometry_traits_2::Point_3               Point_3;
00072   typedef typename Geometry_traits_2::Vector_3              Vector_3;
00073   
00075   typedef unsigned int *                                    Coord_index_iter;
00076   
00077   // Polyhedron types:
00078   typedef typename Polyhedron::Vertex_const_handle
00079     Polyhedron_vertex_const_handle;
00080   typedef typename Polyhedron::Halfedge_const_handle
00081     Polyhedron_halfedge_const_handle;
00082 
00083   typedef typename Polyhedron::Vertex_iterator
00084     Polyhedron_vertex_iterator;
00085   typedef typename Polyhedron::Halfedge_iterator
00086     Polyhedron_halfedge_iterator;
00087   typedef typename Polyhedron::Facet_iterator
00088     Polyhedron_facet_iterator;
00089 
00090   typedef typename Polyhedron::Halfedge_around_vertex_circulator
00091     Polyhedron_halfedge_around_vertex_circulator;
00092   typedef boost::is_same<typename Polyhedron::Plane_3, Vector_3>
00093     Polyhedron_has_normal;
00094 
00096   struct Normal_equation {
00097     template <class Facet>
00098     typename Facet::Plane_3 operator()(Facet & f) {
00099       typename Facet::Halfedge_handle h = f.halfedge();
00100       return CGAL::cross_product(h->next()->vertex()->point() -
00101                                  h->vertex()->point(),
00102                                  h->next()->next()->vertex()->point() -
00103                                  h->next()->vertex()->point());
00104     }
00105   };
00106 
00107   void compute_planes(Polyhedron & polyhedron, boost::true_type)
00108   {
00109     std::transform(polyhedron.facets_begin(), polyhedron.facets_end(),
00110                    polyhedron.planes_begin(), Normal_equation());
00111   }
00112   
00114   struct Plane_equation {
00115     template <typename Facet>
00116     typename Facet::Plane_3 operator()(Facet & f) {
00117       typename Facet::Halfedge_handle h = f.halfedge();
00118       return typename Facet::Plane_3(h->vertex()->point(),
00119                                      h->next()->vertex()->point(),
00120                                      h->next()->next()->vertex()->point());
00121     }
00122   };
00123 
00124   void compute_planes(Polyhedron & polyhedron, boost::false_type)
00125   {
00126     std::transform(polyhedron.facets_begin(), polyhedron.facets_end(),
00127                    polyhedron.planes_begin(), Plane_equation());
00128   }
00129   
00131   template <class HDS, class PointIterator_3>
00132   class Point_adder {
00133   private:
00134     typedef Polyhedron_incremental_builder_3<HDS>               Builder;
00135     Builder & m_B;
00136 
00137   public:
00138     typedef typename Polyhedron::Vertex_handle
00139       Polyhedron_vertex_handle;
00140 
00142     Point_adder(Builder & B) : m_B(B) {}
00143       
00144     Polyhedron_vertex_handle operator()(PointIterator_3 pi)
00145     {
00146       typedef typename HDS::Vertex      Vertex;
00147       typedef typename Vertex::Point    Point;
00148       return m_B.add_vertex(Point((*pi)[0], (*pi)[1], (*pi)[2]));
00149     }
00150   };
00151 
00153   template <class HDS> class Point_adder<HDS, Point_3 *> {
00154   private:
00155     typedef Polyhedron_incremental_builder_3<HDS>               Builder;
00156     Builder & m_B;
00157 
00158   public:
00159     typedef typename Polyhedron::Vertex_handle
00160       Polyhedron_vertex_handle;
00161 
00163     Point_adder(Builder & B) : m_B(B) {}
00164       
00165     Polyhedron_vertex_handle operator()(Point_3 * pi)
00166     { return m_B.add_vertex(*pi); }
00167   };
00168   
00170   template <class PointIterator_3>
00171   class Build_surface : public Modifier_base<typename Polyhedron::HalfedgeDS>
00172   {
00173   private:
00174     typedef typename Polyhedron::Vertex_handle
00175       Polyhedron_vertex_handle;
00176     typedef typename Polyhedron::Facet_handle
00177       Polyhedron_facet_handle;
00178     typedef typename Polyhedron::HalfedgeDS             HDS;
00179     typedef Polyhedron_incremental_builder_3<HDS>       Builder;
00180     typedef typename Builder::size_type                 size_type;
00181     typedef unsigned int *                              Coord_index_iter;
00182 
00184     const PointIterator_3 & m_points_begin;
00185 
00187     const PointIterator_3 & m_points_end;
00188     
00190     size_type m_num_points;
00191 
00193     const Coord_index_iter & m_indices_begin;
00194 
00196     const Coord_index_iter & m_indices_end;
00197     
00199     size_type m_num_facets;
00200 
00202     unsigned int m_marked_vertex_index;
00203 
00205     unsigned int m_marked_edge_index;
00206 
00208     unsigned int m_marked_facet_index;
00209     
00210   public:
00212     Build_surface(const PointIterator_3 & points_begin,
00213                   const PointIterator_3 & points_end,
00214                   unsigned int num_points,
00215                   const Coord_index_iter & indices_begin,
00216                   const Coord_index_iter & indices_end,
00217                   unsigned int num_facets) :
00218       m_points_begin(points_begin), m_points_end(points_end),
00219       m_num_points(num_points),
00220       m_indices_begin(indices_begin), m_indices_end(indices_end),
00221       m_num_facets(num_facets),
00222       m_marked_vertex_index(0),
00223       m_marked_edge_index(0),
00224       m_marked_facet_index(0)      
00225     {}
00226 
00228     virtual ~Build_surface() {}
00229 
00231     void set_marked_vertex_index(unsigned int id) {m_marked_vertex_index = id;}
00232 
00234     void set_marked_edge_index(unsigned int id) {m_marked_edge_index = id;}
00235 
00237     void set_marked_facet_index(unsigned int id) {m_marked_facet_index = id;}
00238 
00240     void operator()(HDS & hds)
00241     {
00242       // Postcondition: `hds' is a valid polyhedral surface.
00243       Builder B(hds, true);
00244       B.begin_surface(m_num_points, m_num_facets);
00245       // Add the points:
00246       unsigned int counter = 0;
00247       Point_adder<HDS, PointIterator_3> add(B);
00248       for (PointIterator_3 pi = m_points_begin; pi != m_points_end; ++pi) {
00249         Polyhedron_vertex_handle vh = add(pi);
00250         if (counter == m_marked_vertex_index) vh->set_marked(true);
00251         ++counter;
00252       }
00253       
00254       // Add the facets:
00255       bool facet_ended = true;
00256       counter = 0;
00257       for (Coord_index_iter ii = m_indices_begin; ii != m_indices_end; ++ii) {
00258         int index = *ii;
00259         if (facet_ended) {
00260           Polyhedron_facet_handle fh = B.begin_facet();
00261           if (counter == m_marked_facet_index) fh->set_marked(true);
00262           B.add_vertex_to_facet(index);
00263           facet_ended = false;
00264           continue;
00265         }
00266         if (index != -1) {
00267           B.add_vertex_to_facet(index);
00268           continue;
00269         }
00270         B.end_facet();
00271         facet_ended = true;
00272         ++counter;
00273       }
00274       B.end_surface();
00275     }
00276   };
00277 
00279   Visitor * m_visitor;
00280   
00282   unsigned int m_marked_vertex_index;
00283 
00285   unsigned int m_marked_edge_index;
00286 
00288   unsigned int m_marked_facet_index;
00289 
00291   Polyhedron_vertex_const_handle m_src_vertex;
00292 
00294   Polyhedron_vertex_const_handle m_trg_vertex;
00295 
00297   Polyhedron_halfedge_const_handle m_halfedge;
00298 
00300   virtual void handle_new_edge(typename Base::Halfedge_handle edge)
00301   {
00302     typedef typename Base::Face_handle          Arr_face_handle;
00303     typedef typename Base::Vertex_handle        Arr_vertex_handle;
00304     
00305     Arr_face_handle src_face = edge->twin()->face();
00306     Arr_face_handle trg_face = edge->face();
00307     src_face->set_point(m_src_vertex->point());
00308     trg_face->set_point(m_trg_vertex->point());
00309 
00310     if (m_visitor) {
00311       m_visitor->update_dual_vertex(m_src_vertex, src_face);
00312       m_visitor->update_dual_vertex(m_trg_vertex, trg_face);
00313 
00314       m_visitor->update_dual_halfedge(m_halfedge, edge);
00315       m_visitor->update_dual_halfedge(m_halfedge, edge->twin());
00316 
00317 //       m_visitor->update_dual_face(m_halfedge->opposite()->facet(),
00318 //                                   edge->source());
00319 //       m_visitor->update_dual_face(m_halfedge->facet(), edge->target());
00320     }
00321   }
00322   
00324   template <class PointIterator_3>  
00325   void update_polyhedron(Polyhedron & polyhedron,
00326                          const PointIterator_3 & points_begin,
00327                          const PointIterator_3 & points_end,
00328                          unsigned int num_points,
00329                          const Coord_index_iter indices_begin,
00330                          Coord_index_iter indices_end,
00331                          unsigned int num_facets)
00332   {
00334     Build_surface<PointIterator_3>
00335       surface(points_begin, points_end, num_points,
00336               indices_begin, indices_end, num_facets);
00337     surface.set_marked_vertex_index(m_marked_vertex_index);
00338     surface.set_marked_edge_index(m_marked_edge_index);
00339     surface.set_marked_facet_index(m_marked_facet_index);
00340     polyhedron.delegate(surface);
00341 
00342     // Mark the marked (half) edges:
00343     unsigned int counter = 0;
00344     typedef typename Polyhedron::Edge_iterator Polyhedron_edge_iterator;
00345     Polyhedron_edge_iterator ei;
00346     for (ei = polyhedron.edges_begin(); ei != polyhedron.edges_end(); ++ei) {
00347       if (counter == m_marked_edge_index) {
00348         // Mark both halfedges:
00349         ei->set_marked(true);
00350         ei->opposite()->set_marked(true);
00351       }
00352       ++counter;
00353     }
00354   }
00355 
00357   template <typename Facet>
00358   const Vector_3 & get_normal(const Facet & facet, boost::true_type) const
00359   { return facet->plane(); }
00360   
00362   template <typename Facet>
00363   Vector_3 get_normal(const Facet & facet, boost::false_type) const
00364   { return facet->plane().orthogonal_vector(); }
00365 
00372   void process_vertex(Polyhedron_vertex_iterator src, bool first_time)
00373   {
00374     m_src_vertex = src;
00375 
00376     typedef typename Base::Vertex_handle                Vertex_handle;
00377     typedef typename Base::Halfedge_handle              Halfedge_handle;
00378 
00379     Vertex_handle invalid_vertex;
00380     
00381     // For each vertex, traverse incident faces:
00382     Polyhedron_halfedge_around_vertex_circulator hec = src->vertex_begin();
00383 
00384     // If the vertex is not a real vertex of the polyhedron, advance to the
00385     // next one:
00386     if (circulator_size(hec) == 0) {
00387       process_vertex(++src, first_time);
00388       return;
00389     }
00390 
00391     CGAL_assertion(circulator_size(hec) >= 3);
00392     Polyhedron_halfedge_around_vertex_circulator begin_hec = hec;
00393     Polyhedron_halfedge_around_vertex_circulator next_hec = hec;
00394     ++next_hec;
00395 
00396     /* If this is not the first invocation, advance the halfedge iterator
00397      * until its source vertex is processed. It is guaranteed to reach such
00398      * a halfedge on consecutive invocations.
00399      */
00400     if (!first_time) {
00401       while (!hec->opposite()->vertex()->processed()) {
00402         hec = next_hec;
00403         begin_hec = hec;
00404         ++next_hec;
00405       }
00406     }
00407 
00408     // Traverse the incident halfedges:
00409     do {
00410       if (!next_hec->processed()) {
00411 
00412         Vector_3 normal1 =
00413           get_normal(hec->facet(), Polyhedron_has_normal());
00414         Vector_3 normal2 =
00415           get_normal(next_hec->facet(), Polyhedron_has_normal());
00416 
00417         m_trg_vertex = next_hec->opposite()->vertex();
00418 
00419 #if 0
00420         std::cout << "process_vertex trg: "
00421                   << static_cast<float>(todouble(m_trg_vertex->point().x()))
00422                   << ","
00423                   << static_cast<float>(todouble(m_trg_vertex->point().y()))
00424                   << ","
00425                   << static_cast<float>(todouble(m_trg_vertex->point().z()))
00426                   << std::endl;
00427 #endif
00428         
00429         m_halfedge = next_hec;
00430 #if 0
00431         Halfedge_handle he = this->insert(normal1, normal2);
00432 #else
00433         Vertex_handle v1 = hec->facet()->vertex();
00434         Vertex_handle v2 = next_hec->facet()->vertex();
00435         /* The arc might be non-x-monotone. In this case, it is broken into 2
00436          * x-monotone curves. The halfedges of both are obtained.
00437          */
00438         typedef typename std::list<Halfedge_handle>     Halfedge_list;
00439         typedef typename Halfedge_list::iterator        Halfedge_list_iter;
00440         Halfedge_list hes;
00441         if (first_time) {
00442           this->insert(normal1, normal2, std::back_inserter(hes));
00443           Halfedge_list_iter first = hes.begin();
00444           Halfedge_list_iter last = hes.end();
00445           --last;
00446           hec->facet()->set_vertex((*first)->source());
00447           next_hec->facet()->set_vertex((*last)->target());
00448           first_time = false;
00449         } else {
00450           if (v1 != invalid_vertex && v2 != invalid_vertex) {
00451             this->insert(normal1, v1, normal2, v2, std::back_inserter(hes));
00452           } else if (v1 != invalid_vertex) {
00453             this->insert(normal1, v1, normal2, std::back_inserter(hes));
00454             Halfedge_list_iter last = hes.end();
00455             --last;
00456             next_hec->facet()->set_vertex((*last)->target());
00457           } else if (v2 != invalid_vertex) {
00458             this->insert(normal1, normal2, v2, std::back_inserter(hes));
00459             Halfedge_list_iter first = hes.begin();
00460             hec->facet()->set_vertex((*first)->source());
00461           } else CGAL_error();
00462         }
00463 #endif
00464         next_hec->set_processed(true);
00465         next_hec->opposite()->set_processed(true);
00466         Halfedge_list_iter first = hes.begin();
00467         if (v1 != invalid_vertex && v2 != invalid_vertex)
00468           handle_new_edge(*first);
00469 
00473         if (m_visitor) {
00474           m_visitor->update_dual_face(m_halfedge->opposite()->facet(),
00475                                       (*first)->source());
00476           // m_visitor->update_dual_face(m_halfedge->facet(), (*first)->target());
00477         }
00478       }
00479       hec = next_hec;
00480       ++next_hec;
00481     } while (hec != begin_hec);
00482     src->set_processed(true);
00483 
00484     // Traverse recursively:
00485     hec = src->vertex_begin();
00486     begin_hec = hec;
00487     do {
00488       if (!(hec->opposite()->vertex()->processed()))
00489         process_vertex(hec->opposite()->vertex(), false);
00490       ++hec;
00491     } while (hec != begin_hec);
00492   }
00493   
00497   void compute_sgm(Polyhedron & polyhedron)
00498   {
00499     typedef typename Base::Vertex_handle                Vertex_handle;
00500 
00501     // Clear the polyhedron:
00502     Polyhedron_facet_iterator fi;
00503     for (fi = polyhedron.facets_begin(); fi != polyhedron.facets_end(); ++fi)
00504       fi->set_vertex(Vertex_handle());
00505 
00506     Polyhedron_halfedge_iterator hei;
00507     for (hei = polyhedron.halfedges_begin(); hei != polyhedron.halfedges_end();
00508          ++hei)
00509       hei->set_processed(false);
00510 
00511     Polyhedron_vertex_iterator vi;
00512     for (vi = polyhedron.vertices_begin(); vi != polyhedron.vertices_end();
00513          ++vi)
00514       vi->set_processed(false);
00515 
00516     // Traverse all verticess recursively:
00517     process_vertex(polyhedron.vertices_begin(), true);
00518   }
00519   
00520 public:
00522   Arr_polyhedral_sgm_initializer(PolyhedralSgm & sgm) :
00523     Base(sgm),
00524     m_visitor(NULL),
00525     m_marked_vertex_index(0),
00526     m_marked_edge_index(0),
00527     m_marked_facet_index(0)
00528   {}
00529     
00531   virtual ~Arr_polyhedral_sgm_initializer() {}
00532 
00538   void operator()(Polyhedron & polyhedron, Visitor * visitor = NULL)
00539   {
00540 #if 0
00541     std::copy(polyhedron.points_begin(), polyhedron.points_end(),
00542               std::ostream_iterator<Point_3>(std::cout, "\n"));
00543 #endif
00544 
00545     m_visitor = visitor;
00546 
00547 #if 0
00548     if (!polyhedron.normalized_border_is_valid())
00549       polyhedron.normalize_border();
00550 #else
00551     polyhedron.normalize_border();
00552 #endif
00553 #if 1
00554     compute_planes(polyhedron, Polyhedron_has_normal());
00555 #endif
00556 
00557     compute_sgm(polyhedron);
00558   }
00559   
00561   template <class PointIterator_3>
00562   void operator()(const PointIterator_3 & points_begin,
00563                   const PointIterator_3 & points_end,
00564                   unsigned int num_points,
00565                   const Coord_index_iter indices_begin,
00566                   Coord_index_iter indices_end,
00567                   unsigned int num_facets,
00568                   Visitor * visitor = NULL)
00569   {
00570     m_visitor = visitor;
00571  
00572     Polyhedron polyhedron;
00573     update_polyhedron(polyhedron, points_begin, points_end, num_points,
00574                       indices_begin, indices_end, num_facets);
00575 
00576 #if 0
00577     std::copy(polyhedron.points_begin(), polyhedron.points_end(),
00578               std::ostream_iterator<Point_3>(std::cout, "\n"));
00579 #endif
00580 
00581 #if 0
00582     if (!polyhedron.normalized_border_is_valid())
00583       polyhedron.normalize_border();
00584 #else
00585     polyhedron.normalize_border();
00586 #endif
00587 #if 1
00588     compute_planes(polyhedron, Polyhedron_has_normal());
00589 #endif
00590 
00591     compute_sgm(polyhedron);
00592     polyhedron.clear();
00593   }
00594 
00596   void set_marked_vertex_index(unsigned int id) {m_marked_vertex_index = id;}
00597 
00599   void set_marked_edge_index(unsigned int id) {m_marked_edge_index = id;}
00600 
00602   void set_marked_facet_index(unsigned int id) {m_marked_facet_index = id;}
00603 };
00604 
00607 template <class Geometry_traits_2,
00608 #ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
00609           template <class T>
00610 #endif
00611           class T_Dcel = Arr_polyhedral_sgm_arr_dcel>
00612 class Arr_polyhedral_sgm :
00613   public Arr_spherical_gaussian_map_3<Geometry_traits_2, T_Dcel>
00614 {
00615 private:
00616   typedef Arr_polyhedral_sgm<Geometry_traits_2, T_Dcel>     Self;
00617   
00618 public:
00619   typedef typename Geometry_traits_2::Point_3               Point_3;
00620   typedef typename Geometry_traits_2::Vector_3              Vector_3;
00621 
00622 #ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
00623   typedef T_Dcel<Geometry_traits_2>                         Dcel;
00624 #else
00625   typedef typename T_Dcel::template Dcel<Geometry_traits_2> Dcel;
00626 #endif
00627   
00628   // For some reason MSVC barfs on the friend statement below. Therefore,
00629   // we declare the Base to be public to overcome the problem.
00630   typedef Arr_spherical_gaussian_map_3<Geometry_traits_2, T_Dcel>   Base;
00631 
00632   typedef Arr_polyhedral_sgm_overlay<Self>
00633     Arr_polyhedral_sgm_overlay;
00634 
00635 #if 0
00636 
00637   template <class Polyhedron, class Visitor>
00638   friend class Arr_polyhedral_sgm_initializer<Self, Polyhedron, Visitor>;
00639 #endif
00640   
00641 private:
00643   Point_3 m_center;
00644   
00646   bool m_dirty_center;
00647   
00649   void calculate_center()
00650   {
00651     // Count them:
00652     typename Base::Face_handle fi;
00653     for (fi = this->faces_begin(); fi != this->faces_end(); fi++) {
00654       const Point_3 & p = fi->point();
00655       Vector_3 v = p - CGAL::ORIGIN;
00656       m_center = m_center + v;
00657     }
00658 
00659     typename Base::Size num = this->number_of_faces();
00660     m_center =
00661       Point_3(m_center.x() / num, m_center.y() / num, m_center.z() / num);
00662 
00663     m_dirty_center = false;
00664   }
00665   
00666 public:
00668   Arr_polyhedral_sgm() : m_dirty_center(true) {}
00669   
00671   Arr_polyhedral_sgm(const Self & sgm)
00672   {
00673     assign(sgm);
00674   }
00675 
00677   void assign(const Self & sgm)
00678   {
00679     // Call the assign of the base class.
00680     Base::assign(sgm);
00681 
00682     typename Dcel::Face_iterator fit;
00683     typename Base::Face_const_iterator fit1 = sgm.faces_begin();
00684           
00685     // Set the points of the faces.
00686     for (fit = this->_dcel().faces_begin(); fit != this->_dcel().faces_end();
00687          ++fit)
00688     {
00689       fit->set_point (fit1->point());
00690       ++fit1;
00691     }
00692                   
00693     typename Dcel::Edge_iterator eit;
00694     typename Base::Edge_const_iterator eit1 = sgm.edges_begin();
00695 
00696     // Set the arr_mask of the edges
00697     for (eit = this->_dcel().edges_begin(); eit != this->_dcel().edges_end();
00698          ++eit)
00699     {
00700       eit->set_arr(eit1->arr_mask());
00701       eit->opposite()->set_arr(eit1->arr_mask());
00702       ++eit1;
00703     }
00704   }
00705   
00707   virtual ~Arr_polyhedral_sgm() { clear(); }
00708 
00711   void clear()
00712   {
00713     m_dirty_center = true;
00714     Base::clear();
00715   }
00716   
00717  // /*! Compute the minkowski sum of a range of objects of type
00718  //  * Arr_polyhedral_sgm
00719  //  */
00720  // template <class SgmIterator>  
00721  // void minkowski_sum(SgmIterator begin, SgmIterator end)
00722  // {
00723         //typename SgmIterator::value_type * sgm1 = *begin++;
00724  //   typename SgmIterator::value_type * sgm2 = *begin;
00725  //   minkowski_sum(sgm1, sgm2);
00726  // }
00727 
00728  // /*! Compute the minkowski sum of a range of objects of type
00729  //  * Arr_polyhedral_sgm
00730  //  */
00731  // template <typename SgmIterator, typename OverlayTraits>  
00732  // void minkowski_sum(SgmIterator begin, SgmIterator end,
00733  //                    OverlayTraits & overlay_traits)
00734  // {
00735  //   typename SgmIterator::value_type * sgm1 = *begin++;
00736  //   typename SgmIterator::value_type * sgm2 = *begin;
00737  //   minkowski_sum(sgm1, sgm2, overlay_traits);
00738  // }
00739  
00744   template <class Arr_polyhedral_sgm>
00745   void minkowski_sum(const Arr_polyhedral_sgm & sgm1,
00746                      const Arr_polyhedral_sgm & sgm2)
00747   {
00748     // Compute the overlays:
00749     Arr_polyhedral_sgm_overlay sgm_overlay;
00750     CGAL::overlay(sgm1, sgm2, *this, sgm_overlay);
00751     // print_stat();
00752   }
00753 
00758   template <class Arr_polyhedral_sgm, typename OverlayTraits>
00759   void minkowski_sum(const Arr_polyhedral_sgm & sgm1,
00760                      const Arr_polyhedral_sgm & sgm2,
00761                      OverlayTraits & overlay_traits)
00762   { CGAL::overlay(sgm1, sgm2, *this, overlay_traits); }
00763   
00765   unsigned int number_of_vertices() const
00766   { return (static_cast<const Base*>(this))->number_of_faces(); }
00767   
00774   unsigned int number_of_edges() const
00775   {
00776     unsigned int size = 0;
00777     typename Base::Vertex_const_iterator vit;
00778     for (vit = this->vertices_begin(); vit != this->vertices_end(); ++vit)
00779       if (vit->degree() == 2) size++;
00780     return (static_cast<const Base*>(this))->number_of_edges() - size;
00781   }
00782 
00788   unsigned int number_of_facets() const
00789   {
00790     unsigned int size = 0;
00791     typename Base::Vertex_const_iterator vit;
00792     for (vit = this->vertices_begin(); vit != this->vertices_end(); ++vit)
00793       if (vit->degree() > 2) size++;
00794     return size;
00795   }
00796   
00798   void print_stat()
00799   {
00800     Base::print_stat();
00801     
00802     std::cout << "Polyhedron"
00803               << ", no. facets: " << number_of_facets()
00804               << ", no. edges: " << number_of_edges()
00805               << ", no. vertices: " << number_of_vertices()
00806               << std::endl;
00807   }
00808 };
00809 
00810 CGAL_END_NAMESPACE
00811 
00812 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines