From 3afc54895a913b46185850adc156ab7c8d145f01 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 29 Mar 2022 14:18:07 +0100 Subject: [PATCH] Box_intersection_d-progress_tracking-GF --- .../doc/Box_intersection_d/examples.txt | 1 + .../examples/Box_intersection_d/progress.cpp | 101 ++++++++++++++++++ .../CGAL/Box_intersection_d/segment_tree.h | 71 +++++++++++- 3 files changed, 170 insertions(+), 3 deletions(-) create mode 100644 Box_intersection_d/examples/Box_intersection_d/progress.cpp diff --git a/Box_intersection_d/doc/Box_intersection_d/examples.txt b/Box_intersection_d/doc/Box_intersection_d/examples.txt index 7a4c4169913..39cee00a522 100644 --- a/Box_intersection_d/doc/Box_intersection_d/examples.txt +++ b/Box_intersection_d/doc/Box_intersection_d/examples.txt @@ -2,6 +2,7 @@ \example Box_intersection_d/box_grid.cpp \example Box_intersection_d/custom_box_grid.cpp \example Box_intersection_d/minimal.cpp +\example Box_intersection_d/progress.cpp \example Box_intersection_d/minimal_self.cpp \example Box_intersection_d/proximity_custom_box_traits.cpp \example Box_intersection_d/triangle_self_intersect.cpp diff --git a/Box_intersection_d/examples/Box_intersection_d/progress.cpp b/Box_intersection_d/examples/Box_intersection_d/progress.cpp new file mode 100644 index 00000000000..bea94294a74 --- /dev/null +++ b/Box_intersection_d/examples/Box_intersection_d/progress.cpp @@ -0,0 +1,101 @@ +#include +#include +#include +#include +#include + +typedef CGAL::Box_intersection_d::Box_d Box; +typedef CGAL::Bbox_2 Bbox; + + +void fill(std::vector& b, int xbl, int ybl, int n) +{ + b.reserve(n * n); + n = 2 * n; + for(int i = 0; i < n; i += 2){ + for(int j = 0; j < n; j += 2){ + b.push_back(Bbox(xbl + i, ybl + j, + xbl + i + 2, ybl + j + 2)); + } + } +} + + +struct Callback_rep{ + + Callback_rep(double normalize) + : normalize(normalize) + { + t.start(); + } + + void progress(double d) + { + d /= normalize; + total += d; + if(total > bound){ + std::cout << std::setprecision(3) << total*100 << " % in " << std::setprecision(5) << t.time() << " sec." << std::endl; + bound += 0.1; + } + } + + double normalize; + double bound = 0.1; + double total = 0; + int count = 0; + CGAL::Timer t; +}; + +struct Callback { + + std::shared_ptr sptr; + + Callback(double normalize = 1.0) + : sptr(std::make_shared(normalize)) + {} + + + void operator()( const Box& a, const Box& b ) { + ++(sptr->count); + // std::cout << "box " << a.id() << " intersects box " << b.id() << std::endl; + } + + + bool report(int dim) + { + return (dim == Box::dimension() - 1); + } + + + void progress(double d) + { + sptr->progress(d); + } + + int count() const + { + return sptr->count; + } + +}; + +int main(int argc, char* argv[]) { + + int n = (argc>1)?std::atoi(argv[1]): 100; + int blx = (argc>2)?std::atoi(argv[2]): 1; + int bly = (argc>2)?std::atoi(argv[3]): 1; + + std::vector boxes, queries; + fill(boxes, 0, 0, n); + fill(queries, blx, bly, n); + + std::ptrdiff_t cutoff = 1; + + Callback callback(2.); // because we call segment_tree twice + + CGAL::box_intersection_d( boxes.begin(), boxes.end(), queries.begin(), queries.end(), callback); + + std::cout << callback.count() << " callback" << std::endl; + + return 0; +} diff --git a/Box_intersection_d/include/CGAL/Box_intersection_d/segment_tree.h b/Box_intersection_d/include/CGAL/Box_intersection_d/segment_tree.h index c810c98b3af..9a70fd5b3cd 100644 --- a/Box_intersection_d/include/CGAL/Box_intersection_d/segment_tree.h +++ b/Box_intersection_d/include/CGAL/Box_intersection_d/segment_tree.h @@ -308,6 +308,56 @@ void dump_box_numbers( ForwardIter begin, ForwardIter end, Traits /* traits */ ) std::cout << std::endl; } + +template +class Has_member_report +{ +private: + template + class check {}; + + template + static char f(check*); + + template + static int f(...); +public: + static const bool value = (sizeof(f(0)) == sizeof(char)); +}; + +template +inline +std::enable_if_t::value, bool> +report_impl(Callback callback, int dim) +{ + return callback.report(dim); +} + +template +inline +std::enable_if_t::value, bool> +report_impl(const Callback&, int) +{ + return false; +} + +template +inline +std::enable_if_t::value, void> +progress_impl(Callback callback, double d) +{ + callback.progress(d); +} + +template +inline +std::enable_if_t::value, void> +progress_impl(const Callback&, double) +{} + + + + template< class T > struct Counter { T& value; @@ -330,9 +380,11 @@ void segment_tree( RandomAccessIter1 p_begin, RandomAccessIter1 p_end, const T inf = box_limits< T >::inf(); const T sup = box_limits< T >::sup(); -#if CGAL_BOX_INTERSECTION_DEBUG - CGAL_STATIC_THREAD_LOCAL_VARIABLE(int, level, -1); + + CGAL_STATIC_THREAD_LOCAL_VARIABLE(int, level, -1); Counter bla( level ); + + #if CGAL_BOX_INTERSECTION_DEBUG CGAL_BOX_INTERSECTION_DUMP("range: [" << lo << "," << hi << ") dim " << dim << std::endl ) CGAL_BOX_INTERSECTION_DUMP("intervals: " ) @@ -356,13 +408,20 @@ void segment_tree( RandomAccessIter1 p_begin, RandomAccessIter1 p_end, } #endif - if( p_begin == p_end || i_begin == i_end || lo >= hi ) + if( p_begin == p_end || i_begin == i_end || lo >= hi ){ + if(report_impl(callback, dim)){ + progress_impl(callback, 1.0 / (1 << level)); + } return; + } if( dim == 0 ) { CGAL_BOX_INTERSECTION_DUMP( "dim = 0. scanning ... " << std::endl ) one_way_scan( p_begin, p_end, i_begin, i_end, callback, traits, dim, in_order ); + if(report_impl(callback,dim)){ + progress_impl(callback, 1.0 / (1 << level)); + } return; } @@ -372,6 +431,9 @@ void segment_tree( RandomAccessIter1 p_begin, RandomAccessIter1 p_end, CGAL_BOX_INTERSECTION_DUMP( "scanning ... " << std::endl ) modified_two_way_scan( p_begin, p_end, i_begin, i_end, callback, traits, dim, in_order ); + if(report_impl(callback,dim)){ + progress_impl(callback, 1.0 / (1 << level)); + } return; } @@ -398,6 +460,9 @@ void segment_tree( RandomAccessIter1 p_begin, RandomAccessIter1 p_end, << std::endl ) modified_two_way_scan( p_begin, p_end, i_span_end, i_end, callback, traits, dim, in_order ); + if(report_impl(callback,dim)){ + progress_impl(callback, 1.0 / (1 << level)); + } return; }