From dc21f0d895e71133ab22d1773b80b94858c79bfb Mon Sep 17 00:00:00 2001 From: Ester Ezra Date: Tue, 21 May 2002 13:40:46 +0000 Subject: [PATCH] The demo for Boolean operations using subdivisions defined on line segments. In these two demos, the input subdivisions are scanned from a text file. --- .../Segment_incremental_bops_from_file.C | 283 +++++++++++++++ .../Segment_sweep_bops_from_file.C | 338 ++++++++++++++++++ 2 files changed, 621 insertions(+) create mode 100644 Packages/Map_overlay_2/demo/Boolean_operations/Segment_incremental_bops_from_file.C create mode 100644 Packages/Map_overlay_2/demo/Boolean_operations/Segment_sweep_bops_from_file.C diff --git a/Packages/Map_overlay_2/demo/Boolean_operations/Segment_incremental_bops_from_file.C b/Packages/Map_overlay_2/demo/Boolean_operations/Segment_incremental_bops_from_file.C new file mode 100644 index 00000000000..e6ee3e742f2 --- /dev/null +++ b/Packages/Map_overlay_2/demo/Boolean_operations/Segment_incremental_bops_from_file.C @@ -0,0 +1,283 @@ +// demo/Map_overlay_2/Segment_bops_from_mouse.C +// +// constructs an overlay of two segment planar maps from CGAL window. +// We use the leda traits (therefore we are using leda functions). + +#include // needed for the LONGNAME flag + +#ifdef CGAL_CFG_NO_LONGNAME_PROBLEM +// Define shorter names to please linker (g++/egcs) +#define Planar_map_with_intersections Pmwx +#define Arr_leda_segment_exact_traits Alset +#define Bop_default_dcel Bdd +#define Boolean_operation Bo +#define In_place_list_iterator IPLI +#define Arr_2_vertex_base Avb +#define Arr_2_halfedge_base Ahb +#define Arr_2_face_base Afb +#define Point_2 pT +#define Segment_2 sT +#define Topological_map TpM +#define _List_iterator Lit +#define Halfedge hE +#define Forward_circulator_tag Fct +#endif + +#include + +#ifndef CGAL_USE_LEDA +int main() +{ + + std::cout << "Sorry, this demo needs LEDA for visualisation."; + std::cout << std::endl; + + return 0; +} + +#else + +#include +#include +#include + + +#include +#include +#include +#include + +#include +#include +#include +#include + +#if defined(LEDA_NAMESPACE) +using namespace leda; +#endif + +typedef leda_rational NT; +typedef CGAL::Arr_leda_segment_exact_traits Traits; + +typedef Traits::Point Point; +typedef Traits::X_curve X_curve; + +typedef CGAL::Bop_default_dcel Dcel; +typedef CGAL::Planar_map_2 PM; +typedef CGAL::Planar_map_with_intersections_2 Pmwx; + +typedef CGAL::Map_overlay_default_notifier MapOverlay_change_notification; +typedef CGAL::Map_overlay_incremental + MapOverlay_incremental; +typedef CGAL::Map_overlay MapOverlay; +typedef CGAL::Boolean_operations Bops; + +typedef CGAL::Pm_walk_along_line_point_location PmWalkPL; + +//typedef Bops::Faces_container Faces_container; +//typedef Bops::Halfedges_container Halfedges_container; +//typedef Bops::Vertices_container Vertices_container; + +// global variables are used so that the redraw function for the LEDA window +// can be defined to draw information found in these variables. +//static PmWalkPL pm_walk1, pm_walk2; +static Pmwx pmwx1; +static Pmwx pmwx2; +static CGAL::Window_stream W(700, 700, "CGAL - Segment Boolean-Operations Demo"); + +// redraw function for the LEDA window. +// used automatically when window reappears. +void redraw(CGAL::Window_stream * wp) +{ wp->start_buffering(); + wp->clear(); + // draw planar map. + *wp << CGAL::BLUE; + *wp << pmwx1; + *wp << CGAL::RED; + *wp << pmwx2; + wp->flush_buffer(); + wp->stop_buffering(); +} + +/* +void draw_and_locate_maps (Bops& bops , + const Pmwx& arr1, + const Pmwx& arr2, + CGAL::Window_stream& W) +{ + MapOverlay_change_notification tmp_notf; + + W<::iterator f_iter = faces_result.begin(); + f_iter != faces_result.end(); f_iter++){ + Pmwx::Face_const_handle fh = *f_iter; + if (fh->is_unbounded()) + continue; + + W.set_color(fg_col); + W.set_fill_color(fg_col); + + Pmwx::Ccb_halfedge_const_circulator cc = fh->outer_ccb(); + leda_list points_list; + do { + leda_point p = cc->source()->point().to_point(); + + points_list.push_back(p); + } while (++cc != fh->outer_ccb()); + W.draw_filled_polygon(points_list); + + for (Pmwx::Holes_const_iterator hit = fh->holes_begin(); hit != fh->holes_end(); ++hit) { + leda_list holes_points_list; + Pmwx::Ccb_halfedge_const_circulator cc(*hit); + W.set_fill_color(leda_black); + W << CGAL::WHITE; + do{ + W << cc->curve(); + + leda_point p = cc->source()->point().to_point(); + points_list.push_back(p); + } while (++cc != *hit); + W.draw_filled_polygon(holes_points_list); + } + + do { + W <curve()<outer_ccb()); + } + + for (list::iterator h_iter = halfedges_result.begin(); + h_iter != halfedges_result.end(); h_iter++){ + Pmwx::Halfedge_const_handle h = *h_iter; + + W.set_color(fg_col); + W.set_node_width(4); + W << h->curve(); + } + + for (list::iterator v_iter = vertices_result.begin(); + v_iter != vertices_result.end(); v_iter++){ + W.set_node_width(4); + //for (Vertex_const_iterator v_iter = bop.get_map_overlay().get_arr().vertices_begin(); + //v_iter != bop.get_map_overlay().get_arr().vertices_end(); v_iter++){ + + Pmwx::Vertex_const_handle vh = *v_iter; + //Vertex_const_iterator vh = v_iter; + + W.set_color(leda_violet); + W << vh->point(); + } + } + } +}*/ + +int main(int argc, char* argv[]) +{ + double x0=-700,x1=700,y0=-700; + + if (argc != 3) { + std::cout << "usage: Segment_sweep_ovl_from_file filename\n"; + exit(1); + } + + CGAL::Bops_utility utility; + + utility.scan_segment_pmwx(argv[1],pmwx1); + utility.scan_segment_pmwx(argv[2],pmwx2); + + pmwx1.unbounded_face()->set_ignore_bop(false); + pmwx2.unbounded_face()->set_ignore_bop(false); + + MapOverlay_incremental ovl_incremental, pmwx_incremental1, pmwx_incremental2; + MapOverlay map1(pmwx1, &pmwx_incremental1); + MapOverlay map2(pmwx2, &pmwx_incremental2); + Bops bops(MapOverlay(map1, map2, &ovl_incremental)); + + utility.calc_window_size(pmwx1, x0, x1, y0); + utility.calc_window_size(pmwx2, x0, x1, y0); + + W.init(x0,x1,y0); + W.set_redraw(redraw); + W.set_mode(leda_src_mode); + W.set_node_width(3); + W.open_status_window(); + W.button("Intersection",4); + W.button("Union",5); + W.button("Symmetric Difference",6); + W.button("Exit",7); + W.display(); + + W << CGAL::RED; + W << pmwx1; + W << CGAL::BLUE; + W << pmwx2; + + // Point Location Queries + W.set_status_string("Boolean Operations. " + "Finish button - Exit." ); + + // if first map is empty + if (pmwx1.halfedges_begin() == pmwx1.halfedges_end()) + { + std::cout << std::endl; + std::cout << "No edges were inserted to the first planar map. First Planar map is empty. Exiting."; + std::cout << std::endl; + } + + // if second map is empty + if (pmwx2.halfedges_begin() == pmwx2.halfedges_end()) + { + std::cout << std::endl; + std::cout << "No edges were inserted to the first planar map. First Planar map is empty. Exiting."; + std::cout << std::endl; + } + + if (pmwx1.halfedges_begin() != pmwx1.halfedges_end() && + pmwx2.halfedges_begin() != pmwx2.halfedges_end() ) + utility.draw_and_locate_maps(bops,pmwx1,pmwx2,W); + + return 0; +} + +#endif // CGAL_USE_LEDA diff --git a/Packages/Map_overlay_2/demo/Boolean_operations/Segment_sweep_bops_from_file.C b/Packages/Map_overlay_2/demo/Boolean_operations/Segment_sweep_bops_from_file.C new file mode 100644 index 00000000000..5d23900450d --- /dev/null +++ b/Packages/Map_overlay_2/demo/Boolean_operations/Segment_sweep_bops_from_file.C @@ -0,0 +1,338 @@ +// demo/Map_overlay_2/Segment_bops_from_mouse.C +// +// constructs an overlay of two segment planar maps from CGAL window. +// We use the leda traits (therefore we are using leda functions). + +#include // needed for the LONGNAME flag + +#ifdef CGAL_CFG_NO_LONGNAME_PROBLEM +// Define shorter names to please linker (g++/egcs) +#define Planar_map Pm +#define Arr_leda_segment_exact_traits Alset +#define Bop_default_dcel Bdd +#define Boolean_operation Bo +#define In_place_list_iterator IPLI +#define Arr_2_vertex_base Avb +#define Arr_2_halfedge_base Ahb +#define Arr_2_face_base Afb +#define Point_2 pT +#define Segment_2 sT +#define Topological_map TpM +#define _List_iterator Lit +#define Halfedge hE +#define Forward_circulator_tag Fct +#endif + +#include + +#ifndef CGAL_USE_LEDA +int main() +{ + + std::cout << "Sorry, this demo needs LEDA for visualisation."; + std::cout << std::endl; + + return 0; +} + +#else + +#include +#include +#include + +#include + +#ifndef CGAL_ARR_2_BOP_DCEL_H +#include +#endif + +#ifndef CGAL_MAP_OVERLAY_NAIVE_H +#include +#endif + +#ifndef CGAL_MAP_OVERLAY_NAIVE_H +#include +#endif + +#ifndef BOOLEAN_OPERATIONS_H +#include +#endif + +#include +#include +#include +#include + +#if defined(LEDA_NAMESPACE) +using namespace leda; +#endif + +typedef leda_rational NT; +typedef CGAL::Arr_leda_segment_exact_traits Traits; + +typedef Traits::Point_2 Point; +typedef Traits::Curve_2 Curve; +typedef Traits::X_curve X_curve; + +typedef CGAL::Bop_default_dcel Dcel; +typedef CGAL::Planar_map_2 PM; + +typedef CGAL::Map_overlay_default_notifier Ovl_change_notification; +typedef CGAL::Map_overlay MapOverlay; +typedef CGAL::Boolean_operations Bops; + +typedef CGAL::Pm_walk_along_line_point_location PmWalkPL; + +// global variables are used so that the redraw function for the LEDA window +// can be defined to draw information found in these variables. +static PmWalkPL pm_walk1, pm_walk2; +static PM pm1(&pm_walk1); +static PM pm2(&pm_walk2); +static CGAL::Window_stream W(700, 700, "CGAL - Segment Boolean-Operations Demo"); + +// redraw function for the LEDA window. +// used automatically when window reappears. +void redraw(CGAL::Window_stream * wp) +{ wp->start_buffering(); + wp->clear(); + // draw planar map. + W << CGAL::BLUE; + *wp << pm1; + W << CGAL::RED; + *wp << pm2; + + wp->flush_buffer(); + wp->stop_buffering(); +} + +/*void draw_and_locate_maps (Bops& bops , + const PM& pm1, + const PM& pm2, + CGAL::Window_stream& W) +{ + W<::iterator f_iter = faces_result.begin(); + f_iter != faces_result.end(); ++f_iter){ + PM::Face_const_handle fh = *f_iter; + if (fh->is_unbounded()) + continue; + + W.set_color(fg_col); + W.set_fill_color(fg_col); + + PM::Ccb_halfedge_const_circulator cc = fh->outer_ccb(); + leda_list points_list; + do { + leda_point p = cc->source()->point().to_point(); + + points_list.push_back(p); + } while (++cc != fh->outer_ccb()); + W.draw_filled_polygon(points_list); + + for (PM::Holes_const_iterator hit = fh->holes_begin(); hit != fh->holes_end(); ++hit) { + leda_list holes_points_list; + PM::Ccb_halfedge_const_circulator cc(*hit); + W.set_fill_color(leda_black); + W << CGAL::WHITE; + do{ + W << cc->curve(); + + leda_point p = cc->source()->point().to_point(); + + points_list.push_back(p); + } while (++cc != *hit); + W.draw_filled_polygon(holes_points_list); + } + + do { + W <outer_ccb()); + } + + for (list::iterator h_iter = halfedges_result.begin(); + h_iter != halfedges_result.end(); ++h_iter, ++h_iter){ + PM::Halfedge_const_handle h = *h_iter; + + W.set_color(fg_col); + W.set_node_width(4); + W << h->curve(); + } + + for (list::iterator v_iter = vertices_result.begin(); + v_iter != vertices_result.end(); v_iter++){ + W.set_node_width(4); + + PM::Vertex_const_handle vh = *v_iter; + //Vertex_const_iterator vh = v_iter; + + W.set_color(leda_violet); + W << vh->point(); + } + } + } +} + +void scan_planar_map(const char* filename, PM& pm) +{ + std::vector curves; + + std::ifstream file(filename); + int num_curves; + file >> num_curves; + while (num_curves--) { + //NT x,y; + double x,y; //(actually int) + file >> x >> y; + NT nx(x),ny(y); + Point s(nx,ny); + file >> x >> y; + NT mx(x),my(y); + Point t(mx,my); + + curves.push_back(Curve(s,t)); + } + + file.close(); + + Traits traits; + CGAL::sweep_to_construct_planar_map_2(curves.begin(), + curves.end(), + traits, pm); + W << pm; +} + +template +void calc_window_size(const Arrangement &arr, double &min_x, double &max_x, double &min_y) +{ + Vertex_const_iterator v_iter = arr.vertices_begin(); + + max_x = min_x = CGAL::to_double(v_iter->point().xcoordD()); + min_y = CGAL::to_double(v_iter->point().ycoordD()); + + for (v_iter = arr.vertices_begin(); v_iter != arr.vertices_end(); v_iter++){ + NT x = v_iter->point().xcoordD(), y = v_iter->point().ycoordD(); + + double dx, dy; + dx = CGAL::to_double(x); + dy = CGAL::to_double(y); + if (dx > max_x) max_x = dx; + if (dx < min_x) min_x = dx; + if (dy < min_y) min_y = dy; + } +}*/ + +int main(int argc, char* argv[]) +{ + double x0=-700,x1=700,y0=-700; + + if (argc != 3) { + std::cout << "usage: Segment_sweep_ovl_from_file filename\n"; + exit(1); + } + + CGAL::Bops_utility utility; + + utility.scan_segment_planar_map(argv[1],pm1); + utility.scan_segment_planar_map(argv[2],pm2); + + pm1.unbounded_face()->set_ignore_bop(false); + pm2.unbounded_face()->set_ignore_bop(false); + + PmWalkPL ovl_walk; + MapOverlay map1(pm1); + MapOverlay map2(pm2); + Bops bops(MapOverlay(map1, map2, &ovl_walk)); + //Bops bops(pm1, pm2); + + utility.calc_window_size(pm1, x0, x1, y0); + utility.calc_window_size(pm2, x0, x1, y0); + + W.init(x0,x1,y0); + W.set_redraw(redraw); + W.set_mode(leda_src_mode); + W.set_node_width(3); + W.open_status_window(); + W.button("Intersection",4); + W.button("Union",5); + W.button("Symmetric Difference",6); + W.button("Exit",7); + W.display(); + + W << CGAL::RED; + W << pm1; + W << CGAL::BLUE; + W << pm2; + + // Point Location Queries + W.set_status_string("Boolean Operations. " + "Finish button - Exit." ); + + // if first map is empty + if (pm1.halfedges_begin() == pm1.halfedges_end()) + { + std::cout << std::endl; + std::cout << "No edges were inserted to the first planar map. First Planar map is empty. Exiting."; + std::cout << std::endl; + } + + // if second map is empty + if (pm2.halfedges_begin() == pm2.halfedges_end()) + { + std::cout << std::endl; + std::cout << "No edges were inserted to the first planar map. First Planar map is empty. Exiting."; + std::cout << std::endl; + } + + if (pm1.halfedges_begin() != pm1.halfedges_end() && + pm2.halfedges_begin() != pm2.halfedges_end() ) + utility.draw_and_locate_maps(bops,pm1,pm2,W); + + return 0; +} + +#endif // CGAL_USE_LEDA +