BWAPI
|
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