From 6cd5535d24f8e30e32ea969b2c183f28c8c6315d Mon Sep 17 00:00:00 2001 From: Peter Hachenberger Date: Wed, 1 Aug 2007 12:54:10 +0000 Subject: [PATCH] new classes that efficiently handle the union or intersection of multiple polyhedra OFF_to_nef_3 benefits from the new union --- Nef_3/include/CGAL/Nef_3/Nary_intersection.h | 47 ++++++++++++++++++++ Nef_3/include/CGAL/Nef_3/Nary_union.h | 47 ++++++++++++++++++++ Nef_3/include/CGAL/OFF_to_nef_3.h | 45 +++++++------------ 3 files changed, 111 insertions(+), 28 deletions(-) create mode 100644 Nef_3/include/CGAL/Nef_3/Nary_intersection.h create mode 100644 Nef_3/include/CGAL/Nef_3/Nary_union.h diff --git a/Nef_3/include/CGAL/Nef_3/Nary_intersection.h b/Nef_3/include/CGAL/Nef_3/Nary_intersection.h new file mode 100644 index 00000000000..2ba3bf13168 --- /dev/null +++ b/Nef_3/include/CGAL/Nef_3/Nary_intersection.h @@ -0,0 +1,47 @@ +#ifndef CGAL_NEF_NARY_INTERSECTION_H +#define CGAL_NEF_NARY_INTERSECTION_H + +#include + +CGAL_BEGIN_NAMESPACE + +template +class Nary_intersection { + + int inserted; + std::list queue; + typedef typename std::list::iterator pit; + Polyhedron empty; + + public: + Nary_intersection() : inserted(0) {} + + void unite() { + pit i1(queue.begin()), i2(i1); + ++i2; + + Polyhedron tmp(*i1 * *i2); + + queue.pop_front(); + queue.pop_front(); + queue.push_front(tmp); + } + + void add_polyhedron(const Polyhedron& P) { + queue.push_front(P); + ++inserted; + for(int i=2;(inserted%i) == 0; i*=2) { + unite(); + } + } + + Polyhedron get_intersection() { + + while(queue.size() > 1) + unite(); + return queue.front(); + } +}; + +CGAL_END_NAMESPACE +#endif // CGAL_NEF_NARY_INTERSECTION_H diff --git a/Nef_3/include/CGAL/Nef_3/Nary_union.h b/Nef_3/include/CGAL/Nef_3/Nary_union.h new file mode 100644 index 00000000000..f0e7c1d86e8 --- /dev/null +++ b/Nef_3/include/CGAL/Nef_3/Nary_union.h @@ -0,0 +1,47 @@ +#ifndef CGAL_NEF_NARY_UNION_H +#define CGAL_NEF_NARY_UNION_H + +#include + +CGAL_BEGIN_NAMESPACE + +template +class Nary_union { + + int inserted; + std::list queue; + typedef typename std::list::iterator pit; + Polyhedron empty; + + public: + Nary_union() : inserted(0) {} + + void unite() { + pit i1(queue.begin()), i2(i1); + ++i2; + + Polyhedron tmp(*i1 + *i2); + + queue.pop_front(); + queue.pop_front(); + queue.push_front(tmp); + } + + void add_polyhedron(const Polyhedron& P) { + queue.push_front(P); + ++inserted; + for(int i=2;(inserted%i) == 0; i*=2) { + unite(); + } + } + + Polyhedron get_union() { + + while(queue.size() > 1) + unite(); + return queue.front(); + } +}; + +CGAL_END_NAMESPACE +#endif // CGAL_NEF_NARY_UNION_H diff --git a/Nef_3/include/CGAL/OFF_to_nef_3.h b/Nef_3/include/CGAL/OFF_to_nef_3.h index 05b9f3b2fda..51505e1a6a6 100644 --- a/Nef_3/include/CGAL/OFF_to_nef_3.h +++ b/Nef_3/include/CGAL/OFF_to_nef_3.h @@ -29,6 +29,7 @@ #include #include #include +#include #ifdef CGAL_USE_LEDA #include @@ -108,22 +109,20 @@ OFF_to_nef_3 (std::istream &i_st, Nef_3 &nef_union, bool verb=false) { // Nef typedef typename Nef_3::Kernel Kernel; - typedef typename Nef_3::Point_3 Point_3; - typedef typename std::vector Point_set; - typedef std::multimap Nef_map; - typedef typename Nef_map::iterator Nef_map_iter; - + typedef typename Nef_3::Point_3 Point_3; + typedef typename std::vector Point_set; + CGAL::Nary_union nary_union; // input data structure typedef double Scan_NT; typedef CGAL::Cartesian Scan_kernel; - typedef Scan_kernel::Point_3 Scan_point; - typedef std::vector Scan_point_set; - typedef Scan_kernel::Vector_3 Scan_vector; + typedef Scan_kernel::Point_3 Scan_point; + typedef std::vector Scan_point_set; + typedef Scan_kernel::Vector_3 Scan_vector; typedef CGAL::Scanner_OFF Scan_OFF; - typedef Scan_OFF::Vertex_iterator Scan_vertex_it; - typedef Scan_OFF::Facet_iterator Scan_facet_it; - typedef Scan_OFF::Index_iterator Scan_index_it; + typedef Scan_OFF::Vertex_iterator Scan_vertex_it; + typedef Scan_OFF::Facet_iterator Scan_facet_it; + typedef Scan_OFF::Index_iterator Scan_index_it; typedef typename Kernel::Kernel_tag Kernel_tag; typedef typename CGAL::number_type_converter_nef_3 ntc; @@ -131,7 +130,6 @@ OFF_to_nef_3 (std::istream &i_st, Nef_3 &nef_union, bool verb=false) // declarations and defaults std::size_t discarded_facets=0; long idx; - Nef_map nef_map; // priority queue #ifdef CGAL_NEF_OFF_TO_NEF_TIMER CGAL::Timer t_convert, t_union; @@ -190,7 +188,7 @@ OFF_to_nef_3 (std::istream &i_st, Nef_3 &nef_union, bool verb=false) // construct and enqueue Nef_polyhedron_3 Nef_3 nef (V_f.begin(), V_f.end(), normal, verb); if ( !nef.is_empty() ) - { nef_map.insert (std::make_pair(nef.number_of_vertices(),nef)); + {nary_union.add_polyhedron(nef); is_nef = true; } } @@ -216,27 +214,18 @@ OFF_to_nef_3 (std::istream &i_st, Nef_3 &nef_union, bool verb=false) t_union.start(); #endif - while ( nef_map.size() > 1 ) - { Nef_map_iter nm=nef_map.begin(), nm2=nef_map.begin(); - ++nm2; - Nef_3 nef_tmp ((nm->second)+(nm2->second)); - nef_map.insert ( std::make_pair(nef_tmp.number_of_vertices(),nef_tmp)); - nef_map.erase(nm); - nef_map.erase(nm2); - } - #ifdef CGAL_NEF_OFF_TO_NEF_TIMER t_union.stop(); std::cout << "time (union): " << t_union.time() << "\n" << std::endl; #endif // return values - if ( nef_map.size() == 0 ) nef_union = Nef_3 (); - else - { nef_union = nef_map.begin()->second; - CGAL::Mark_bounded_volumes mbv (true); - nef_union.delegate (mbv); - } + // if ( nef_map.size() == 0 ) nef_union = Nef_3 (); + // else + nef_union = nary_union.get_union(); + CGAL::Mark_bounded_volumes mbv (true); + nef_union.delegate (mbv); + return discarded_facets; }