// compute_arrangement: a new method to compute arrangement of segments. // Copyright (C) 2020 CNRS and LIRIS' Establishments (France). // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see <https://www.gnu.org/licenses/>. // // Author(s) : Guillaume Damiand <guillaume.damiand@liris.cnrs.fr> // #include <cassert> #include <cstdlib> #include <iostream> #include <fstream> #include <string> #include <vector> #include <stack> #include <tuple> #include <thread> #include <boost/filesystem.hpp> #include <CGAL/Memory_sizer.h> #include <CGAL/assertions.h> #include <CGAL/Surface_sweep_2.h> #include <CGAL/Surface_sweep_2_algorithms.h> #include <CGAL/Arr_segment_traits_2.h> #include <CGAL/Arrangement_2.h> #include <CGAL/Arr_consolidated_curve_data_traits_2.h> #include <CGAL/Arr_non_caching_segment_basic_traits_2.h> #include "CGAL_typedefs.h" #include "Segment_readers.h" #include "My_visitor.h" #include "SHds.h" //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////// [[ noreturn ]] void usage(int /*argc*/, char** argv) { // Name std::cout<<"Name"<<std::endl; std::cout<<" "<<argv[0]<<" - a new method to compute arrangement of segments"; std::cout<<std::endl<<std::endl; // Synopsis std::cout<<"SYNOPSIS"<<std::endl; std::cout<<" "<<argv[0]<<" [--help|-h|-?] " <<"[-t1 filename] [-nbs S] [-nbt N] [-crop] [-optimized-strips] [-cgal]" <<std::endl<<std::endl; // Description std::cout<<"DESCRIPTION"<<std::endl; std::cout<<" "<<"Compute the arrangement of segments given in the filename." <<std::endl<<std::endl; // Options std::cout<<" --help, -h, -?"<<std::endl <<" display this help and exit." <<std::endl<<std::endl; std::cout<<" -t1 filename" <<std::endl <<" load the text segment file, and creates the arrangement: required." <<std::endl<<std::endl; std::cout<<" -nbs S" <<std::endl <<" number of strips (1 by default)." <<std::endl<<std::endl; std::cout<<" -nbt N" <<std::endl <<" number of threads (1 by default)." <<std::endl<<std::endl; std::cout<<" -crop" <<std::endl <<" crop the segments to fit in its strip." <<std::endl<<std::endl; std::cout<<" -repeat R" <<std::endl <<" repeat each test R times (1 by default)." <<std::endl<<std::endl; std::cout<<" -optimized-strips" <<std::endl <<" compute the length of each strips dynamically (by default each strip has the same size) (used only if the number of threads is > 1)." <<std::endl<<std::endl; std::cout<<" -cgal" <<std::endl <<" run cgal arrangement (and not our new method)." <<std::endl<<std::endl; // Author std::cout<<"AUTHOR"<<std::endl; std::cout<<" "<<"Written by Guillaume Damiand." <<std::endl<<std::endl; // Copyright std::cout<<"COPYRIGHT"<<std::endl; std::cout<<" "<<"Copyright (C) 2020 CNRS and LIRIS' Establishments (France). " <<"License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>" <<std::endl <<" This is free software: you are free to change and redistribute it under certain conditions. " <<"There is NO WARRANTY, to the extent permitted by law." <<std::endl<<std::endl; // Reporting bugs std::cout<<"REPORTING BUGS"<<std::endl; std::cout<<" "<<"Email bug reports to Guillaume Damiand ⟨guillaume.damiand@liris.cnrs.fr⟩." <<std::endl<<std::endl; exit(EXIT_FAILURE); } //////////////////////////////////////////////////////////////////////////////// [[ noreturn ]] void error_command_line(int argc, char** argv, const char* msg) { std::cout<<"ERROR: "<<msg<<std::endl; usage(argc, argv); } //////////////////////////////////////////////////////////////////////////////// void process_command_line(int argc, char** argv, bool& t1, std::string& filename, std::size_t& nbstrips, std::size_t& nbthreads, std::size_t& repeat, bool &optimized_strips, bool &cgal, bool &crop) { t1=false; filename=""; nbstrips=1; nbthreads=1; optimized_strips=false; cgal=false; repeat=1; crop=false; bool helprequired=false; std::string arg; for (int i=1; i<argc; ++i) { arg=std::string(argv[i]); if (arg==std::string("-h") || arg==std::string("--help") || arg==std::string("-?")) { helprequired=true; } else if (arg==std::string("-t1")) { t1=true; if (argc-1-i<1) { error_command_line(argc, argv, "Error: no filename after -t1 option."); } filename=std::string(argv[++i]); } else if (arg==std::string("-nbs")) { if (argc-1-i<1) { error_command_line(argc, argv, "Error: no number after -nbs option."); } nbstrips=std::stoi(std::string(argv[++i])); } else if (arg==std::string("-nbt")) { if (argc-1-i<1) { error_command_line(argc, argv, "Error: no number after -nbt option."); } nbthreads=std::stoi(std::string(argv[++i])); } else if (arg==std::string("-repeat")) { if (argc-1-i<1) { error_command_line(argc, argv, "Error: no number after -repeat option."); } repeat=std::stoi(std::string(argv[++i])); } else if (arg==std::string("-optimized-strips")) { optimized_strips=true; } else if (arg==std::string("-cgal")) { cgal=true; } else if (arg==std::string("-crop")) { crop=true; } else if (arg[0]=='-') { std::cout<<"Unknown option "<<arg<<std::endl; helprequired=true; } } if (nbthreads==0) { nbthreads=1; } if (repeat==0) { repeat=1; } if (!t1) { std::cout<<"ERROR: missing txt file name."<<std::endl; } if (helprequired || !t1) { usage(argc, argv); } } /////////////////////////////////////////////////////////////////////////////// int main(int argc, char** argv) { std::string filename; bool t1; std::size_t nbstrips, nbthreads, repeat; bool optimized_strips; bool cgal; bool crop; process_command_line(argc, argv, t1, filename, nbstrips, nbthreads, repeat, optimized_strips, cgal, crop); std::ofstream ftimes("times.dat", std::ios_base::app); std::ofstream fdetailedtimes("detailed-times.dat", std::ios_base::app); std::ofstream fcells("nbcells.dat", std::ios_base::app); ftimes.setf( std::ios::fixed, std:: ios::floatfield ); ftimes.precision(2); fdetailedtimes.setf( std::ios::fixed, std:: ios::floatfield ); fdetailedtimes.precision(2); boost::filesystem::path p(filename); if (cgal) { ftimes<<p.stem()<<'\t'; fdetailedtimes<<p.stem()<<'\t'; fcells<<"####################"<<p.stem()<<std::endl; } if (cgal) { typedef CGAL::Arr_segment_traits_2<EPECK> Traits_2; typedef CGAL::Arrangement_2<Traits_2> Arrangement_2; std::vector<ESegment> all_segments; all_segments.reserve(number_of_lines(filename)); Read_from_file<EPECK> reader(filename); fill_segment_array<EPECK>(reader, all_segments); My_timer timer; for (std::size_t i=0; i<repeat; ++i) { timer.start(); Arrangement_2 arr; CGAL::insert(arr, all_segments.begin(), all_segments.end()); timer.stop(); if (i==0) { fcells<<arr.number_of_halfedges()<<'\t' <<arr.number_of_vertices()<<'\t' <<arr.number_of_edges()<<'\t' <<arr.number_of_faces()-arr.number_of_unbounded_faces()<<'\t' <<arr.number_of_faces()<<std::endl; } } ftimes<<timer.time()/repeat<<'\t'; } else { std::vector<double> times; // times[0] : global time // times[1] : load and dispatch // times[2] : compute all local arrangements // times[3] : compute faces for (std::size_t i=0; i<repeat; ++i) { SHds shds(filename, nbstrips, nbthreads, optimized_strips, times, crop); if (i==0) { fcells<<shds.number_of_halfedges()<<'\t' <<shds.number_of_vertices()<<'\t' <<shds.number_of_edges()<<'\t' <<shds.number_of_finite_faces()<<'\t' <<shds.number_of_faces()<<'\t' <<shds.number_of_external_halfedges()<<std::endl; } } ftimes<<(times[0]-times[1])/repeat<<'\t'; fdetailedtimes<<times[1]/repeat<<'\t' <<times[2]/repeat<<'\t' <<times[3]/repeat<<'\t'; } return EXIT_SUCCESS; } ///////////////////////////////////////////////////////////////////////////////