diff --git a/.travis/test_package.sh b/.travis/test_package.sh index c1c7ba238cc..f91f9982916 100644 --- a/.travis/test_package.sh +++ b/.travis/test_package.sh @@ -7,6 +7,9 @@ DO_IGNORE=FALSE cd $1 if [ ! -f "$2/package_info/$2/dependencies" ];then echo "No dependencies found for $2" + bash Scripts/developer_scripts/cgal_check_dependencies.sh --check_headers /usr/bin/doxygen + + exit 1 fi LIST_OF_FILES=$(git diff --name-only origin/master... |cut -d/ -f1 |uniq |sort) diff --git a/AABB_tree/include/CGAL/AABB_tree.h b/AABB_tree/include/CGAL/AABB_tree.h index 9a05e1068a4..42c732f7ca4 100644 --- a/AABB_tree/include/CGAL/AABB_tree.h +++ b/AABB_tree/include/CGAL/AABB_tree.h @@ -195,8 +195,8 @@ namespace CGAL { if(size() > 1) return root_node()->bbox(); else - return AABB_traits().compute_bbox_object()(m_primitives.begin(), - m_primitives.end()); + return traits().compute_bbox_object()(m_primitives.begin(), + m_primitives.end()); } /// Returns the number of primitives in the tree. diff --git a/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Algebraic_curve_kernel_2.h b/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Algebraic_curve_kernel_2.h index bcc17651c39..8f2e79215d3 100644 --- a/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Algebraic_curve_kernel_2.h +++ b/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Algebraic_curve_kernel_2.h @@ -408,7 +408,19 @@ public: } public: + static auto initialize_poly_0() { + Polynomial_2 poly_0; + return poly_0; + } static Algebraic_curve_kernel_2& get_static_instance(){ + // Useless reference to a `Polynomial_2` to force the creation + // of `CORE::MemoryPool` (and related type) + // before the static thread-local instance `ack_2_instance`. + // The issue is otherwise that the memory pool is created during + // the filling of the curves cache, and then destroyed too soon, + // before the destruction of `ack_2_instance`. + CGAL_STATIC_THREAD_LOCAL_VARIABLE(Polynomial_2, poly_0, initialize_poly_0()); + CGAL_USE(poly_0); // a default constructed ack_2 instance CGAL_STATIC_THREAD_LOCAL_VARIABLE_0(Algebraic_curve_kernel_2, ack_2_instance); return ack_2_instance; diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_polycurve_basic_traits_2.h b/Arrangement_on_surface_2/include/CGAL/Arr_polycurve_basic_traits_2.h index 5fc50e0c5fb..da39fc3a02c 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_polycurve_basic_traits_2.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_polycurve_basic_traits_2.h @@ -2534,7 +2534,7 @@ protected: Polycurve_basic_traits_2; /*! The polycurve traits (in case it has state). */ - const Polycurve_basic_traits_2& m_poly_traits; + const Polycurve_basic_traits_2 m_poly_traits; const Point_2& m_point; diff --git a/BGL/include/CGAL/boost/graph/helpers.h b/BGL/include/CGAL/boost/graph/helpers.h index 065c37448a3..c6b49fd4157 100644 --- a/BGL/include/CGAL/boost/graph/helpers.h +++ b/BGL/include/CGAL/boost/graph/helpers.h @@ -385,84 +385,93 @@ bool is_valid_halfedge_graph(const Graph& g, bool verb = false) bool valid = (1 != (num_h&1) && (2*num_e == num_h)); if(!valid) + { verr << "number of halfedges is odd." << std::endl; + verr << "Halfedge Graph Structure is NOT VALID." << std::endl; + return false; + } // All halfedges. halfedges_size_type n = 0; for(halfedge_descriptor begin : halfedges(g)) { - if(!valid) - break; - // Pointer integrity. - valid = valid && (next(begin, g) != boost::graph_traits::null_halfedge()); + valid = (next(begin, g) != boost::graph_traits::null_halfedge()); valid = valid && (opposite(begin, g) != boost::graph_traits::null_halfedge()); if(!valid) { - verr << "halfedge " << n << " next / opposite halfedges are null." << std::endl; - break; + verr << "halfedge " << n << " next / opposite halfedges are null." << std::endl; + verr << "Halfedge Graph Structure is NOT VALID." << std::endl; + return false; } // edge integrity - valid = valid && (halfedge(edge(begin, g), g) == begin); + valid = (halfedge(edge(begin, g), g) == begin); // opposite integrity. valid = valid && (opposite(begin, g) != begin); valid = valid && (opposite(opposite(begin, g), g) == begin); if(!valid) { - verr << "halfedge " << n << " invalid halfedge opposite()." << std::endl; - break; + verr << "halfedge " << n << " invalid halfedge opposite()." << std::endl; + verr << "Halfedge Graph Structure is NOT VALID." << std::endl; + return false; } // previous integrity. - valid = valid && (prev(next(begin, g), g) == begin); + valid = (prev(next(begin, g), g) == begin); valid = valid && (next(prev(begin, g), g) == begin); if(!valid) { - verr << "halfedge " << n << " prev(next(hd)) != hd OR next(prev(hd)) != hd" << std::endl; - break; + verr << "halfedge " << n << " prev(next(hd)) != hd OR next(prev(hd)) != hd" << std::endl; + verr << "Halfedge Graph Structure is NOT VALID." << std::endl; + return false; } // vertex integrity. - valid = valid && (target(begin, g) != boost::graph_traits::null_vertex()); + valid = (target(begin, g) != boost::graph_traits::null_vertex()); if(!valid) { - verr << "halfedge " << n << " target of halfedge is the null vertex." << std::endl; - break; + verr << "halfedge " << n << " target of halfedge is the null vertex." << std::endl; + verr << "Halfedge Graph Structure is NOT VALID." << std::endl; + return false; } - valid = valid && (target(begin, g) == target(opposite(next(begin, g), g), g)); + valid = (target(begin, g) == target(opposite(next(begin, g), g), g)); if(!valid) { - verr << "halfedge " << n << " target(hd) != source(next(hd))." << std::endl; - break; + verr << "halfedge " << n << " target(hd) != source(next(hd))." << std::endl; + verr << "Halfedge Graph Structure is NOT VALID." << std::endl; + return false; } ++n; } - if(valid && n != num_h) + valid = (n == num_h); + if(!valid) + { verr << "counting halfedges failed." << std::endl; + verr << "Halfedge Graph Structure is NOT VALID." << std::endl; + return false; + } // All vertices. vertex_size_type v = 0; n = 0; for(vertex_descriptor vbegin : vertices(g)) { - if(!valid) - break; - // Pointer integrity. if(halfedge(vbegin, g) != boost::graph_traits::null_halfedge()) - valid = valid && (target(halfedge(vbegin, g), g) == vbegin); + valid = (target(halfedge(vbegin, g), g) == vbegin); else valid = false; if(!valid) { - verr << "vertex " << v << " halfedge incident to vertex is the null halfedge." << std::endl; - break; + verr << "vertex " << v << " halfedge incident to vertex is the null halfedge." << std::endl; + verr << "Halfedge Graph Structure is NOT VALID." << std::endl; + return false; } // cycle-around-vertex test. @@ -474,49 +483,56 @@ bool is_valid_halfedge_graph(const Graph& g, bool verb = false) { ++n; h = opposite(next(h, g), g); - valid = valid && (n <= num_h && n!=0); + valid = (n <= num_h && n != 0); if(!valid) { - verr << "vertex " << v << " too many halfedges around vertex." << std::endl; - break; + verr << "vertex " << v << " too many halfedges around vertex." << std::endl; + verr << "Halfedge Graph Structure is NOT VALID." << std::endl; + return false; } } - while (valid && (h != ge)); + while(h != ge); } - if(!valid) - break; - ++v; } - if(valid && v != num_v) + valid = (v == num_v); + if(!valid) + { verr << "counting vertices failed." << std::endl; + verr << "Halfedge Graph Structure is NOT VALID." << std::endl; + return false; + } - if(valid && (n != num_h)) + valid = (n == num_h); + if(!valid) + { verr << "counting halfedges via vertices failed." << std::endl; - - valid = valid && (v == num_v); + verr << "Halfedge Graph Structure is NOT VALID." << std::endl; + return false; + } // All halfedges. n = 0; for(halfedge_descriptor i : halfedges(g)) { // At least triangular facets and distinct geometry. - valid = valid && (next(i, g) != i); - valid = valid && (target(i, g) != target(opposite(i, g), g)); + valid = (next(i, g) != i) && (target(i, g) != target(opposite(i, g), g)); if(!valid) { - verr << "halfedge " << n << " pointer validity corrupted." << std::endl; - break; + verr << "halfedge " << n << " pointer validity corrupted." << std::endl; + verr << "Halfedge Graph Structure is NOT VALID." << std::endl; + return false; } ++n; } - valid = valid && (n == num_h); - if(n != num_h) + valid = (n == num_h); + if(!valid) verr << "counting halfedges failed." << std::endl; + verr << "Halfedge Graph Structure is " << (valid ? "valid." : "NOT VALID.") << std::endl; return valid; @@ -546,36 +562,35 @@ bool is_valid_face_graph(const Graph& g, bool verb = false) typedef typename boost::graph_traits::face_descriptor face_descriptor; typedef typename boost::graph_traits::faces_size_type faces_size_type; + Verbose_ostream verr(verb); + std::size_t num_f(std::distance(boost::begin(faces(g)), boost::end(faces(g)))), num_h(std::distance(boost::begin(halfedges(g)), boost::end(halfedges(g)))); + faces_size_type f = 0; + std::size_t n = 0; + std::size_t hn = 0; + halfedges_size_type nb = 0; + //is valid halfedge_graph ? bool valid = is_valid_halfedge_graph(g, verb); if(!valid) return false; - Verbose_ostream verr(verb); - // All faces. - faces_size_type f = 0; - std::size_t n = 0; - halfedges_size_type nb = 0; - for(face_descriptor fbegin : faces(g)) { - if(!valid) - break; - // Pointer integrity. if(halfedge(fbegin, g) != boost::graph_traits::null_halfedge()) - valid = valid && (face(halfedge(fbegin, g), g) == fbegin); + valid = (face(halfedge(fbegin, g), g) == fbegin); else valid = false; - if(! valid) + if(!valid) { - verr << "face " << f << " halfedge incident to face is the null halfedge." << std::endl; - break; + verr << "face " << f << " halfedge incident to face is the null halfedge." << std::endl; + verr << "Face Graph Structure is NOT VALID." << std::endl; + return false; } // cycle-around-face test. @@ -587,26 +602,28 @@ bool is_valid_face_graph(const Graph& g, bool verb = false) { ++n; h = next(h, g); - valid = valid && (n <= num_h && n != 0); + valid = (n <= num_h && n != 0); if(!valid) { - verr << "face " << f << " too many halfedges around face." << std::endl; - break; + verr << "face " << f << " too many halfedges around face." << std::endl; + verr << "Face Graph Structure is NOT VALID." << std::endl; + return false; } } - while(valid && (h != ge)); + while(h != ge); } - if(! valid) - break; - ++f; } - if(valid && f != num_f) + valid = (f == num_f); + if(!valid) + { verr << "counting faces failed." << std::endl; + verr << "Face Graph Structure is NOT VALID." << std::endl; + return false; + } - std::size_t hn = 0; for(halfedge_descriptor i : halfedges(g)) { ++hn; @@ -616,20 +633,28 @@ bool is_valid_face_graph(const Graph& g, bool verb = false) ++nb; // face integrity. - valid = valid && (face(i, g) == face(next(i, g), g)); + valid = (face(i, g) == face(next(i, g), g)); if(!valid) { - verr << "halfedge " << hn << " face(hd) != face(next(hd))." << std::endl; - break; + verr << "halfedge " << hn << " face(hd) != face(next(hd))." << std::endl; + verr << "Face Graph Structure is NOT VALID." << std::endl; + return false; } } - verr << "sum border halfedges (2*nb) = " << 2 * nb << std::endl; - if(valid && n + nb != num_h) + valid = (n + nb == num_h); + if(!valid) + { + verr << "sum border halfedges (2*nb) = " << 2 * nb << std::endl; verr << "counting halfedges via faces failed." << std::endl; + verr << "Face Graph Structure is NOT VALID." << std::endl; + return false; + } + + valid = (f == num_f); + if(!valid) + verr << "counting faces failed." << std::endl; - valid = valid && (f == num_f); - valid = valid && (n + nb == num_h); verr << "Face Graph Structure is " << (valid ? "valid." : "NOT VALID.") << std::endl; return valid; @@ -667,26 +692,27 @@ bool is_valid_polygon_mesh(const Mesh& g, bool verb = false) // Distinct facets on each side of an halfedge. for(halfedge_descriptor i : halfedges(g)) { - valid = valid && (face(i, g) != face(opposite(i, g), g)); + valid = (face(i, g) != face(opposite(i, g), g)); if(!valid) { - verr << " both incident facets are equal." << std::endl; - break; + verr << "both incident facets are equal." << std::endl; + verr << "Polygon Mesh Structure is NOT VALID." << std::endl; + return false; } - valid = valid && (next(next(i, g), g) != i); + valid = (next(next(i, g), g) != i); valid = valid && (target(i, g) != target(next(i, g), g)); valid = valid && (target(i, g) != target(next(next(i, g), g), g)); if(!valid) { - verr << " incident facet is not at least a triangle." << std::endl; - break; + verr << "incident facet is not at least a triangle." << std::endl; + verr << "Polygon Mesh Structure is NOT VALID." << std::endl; + return false; } } - verr << "Polygon Mesh Structure is " << (valid ? "valid." : "NOT VALID.") << std::endl; - - return valid; + verr << "Polygon Mesh Structure is valid." << std::endl; + return true; } /*! diff --git a/CGAL_Core/include/CGAL/CORE/Gmp_impl.h b/CGAL_Core/include/CGAL/CORE/Gmp_impl.h index e12f7f1c81e..324746d69dc 100644 --- a/CGAL_Core/include/CGAL/CORE/Gmp_impl.h +++ b/CGAL_Core/include/CGAL/CORE/Gmp_impl.h @@ -46,15 +46,14 @@ MA 02110-1301, USA. */ #include #include -using namespace std; - namespace CORE { CGAL_INLINE_FUNCTION int -__gmp_istream_set_base (istream &i, char &c, bool &zero, bool &showbase) +__gmp_istream_set_base (std::istream &i, char &c, bool &zero, bool &showbase) { int base; + using std::ios; zero = showbase = false; switch (i.flags() & ios::basefield) @@ -96,7 +95,7 @@ __gmp_istream_set_base (istream &i, char &c, bool &zero, bool &showbase) CGAL_INLINE_FUNCTION void -__gmp_istream_set_digits (string &s, istream &i, char &c, bool &ok, int base) +__gmp_istream_set_digits (std::string &s, std::istream &i, char &c, bool &ok, int base) { switch (base) { @@ -131,13 +130,14 @@ __gmp_istream_set_digits (string &s, istream &i, char &c, bool &ok, int base) } CGAL_INLINE_FUNCTION -istream & -//operator>> (istream &i, mpz_ptr z) -io_read (istream &i, mpz_ptr z) +std::istream & +//operator>> (std::istream &i, mpz_ptr z) +io_read (std::istream &i, mpz_ptr z) { + using namespace std; int base; char c = 0; - string s; + std::string s; bool ok = false, zero, showbase; i.get(c); // start reading @@ -175,13 +175,14 @@ io_read (istream &i, mpz_ptr z) } CGAL_INLINE_FUNCTION -istream & -//operator>> (istream &i, mpq_ptr q) -io_read (istream &i, mpq_ptr q) +std::istream & +//operator>> (std::istream &i, mpq_ptr q) +io_read (std::istream &i, mpq_ptr q) { + using namespace std; int base; char c = 0; - string s; + std::string s; bool ok = false, zero, showbase; i.get(c); // start reading @@ -253,9 +254,9 @@ io_read (istream &i, mpq_ptr q) } CGAL_INLINE_FUNCTION -ostream& -//operator<< (ostream &o, mpz_srcptr z) -io_write (ostream &o, mpz_srcptr z) +std::ostream& +//operator<< (std::ostream &o, mpz_srcptr z) +io_write (std::ostream &o, mpz_srcptr z) { char *str = new char [mpz_sizeinbase(z,10) + 2]; str = mpz_get_str(str, 10, z); @@ -265,9 +266,9 @@ io_write (ostream &o, mpz_srcptr z) } CGAL_INLINE_FUNCTION -ostream& -//operator<< (ostream &o, mpq_srcptr q) -io_write (ostream &o, mpq_srcptr q) +std::ostream& +//operator<< (std::ostream &o, mpq_srcptr q) +io_write (std::ostream &o, mpq_srcptr q) { // size according to GMP documentation char *str = new char [mpz_sizeinbase(mpq_numref(q), 10) + diff --git a/CGAL_Core/include/CGAL/CORE/MemoryPool.h b/CGAL_Core/include/CGAL/CORE/MemoryPool.h index 0f015768f99..b033bc5ecfd 100644 --- a/CGAL_Core/include/CGAL/CORE/MemoryPool.h +++ b/CGAL_Core/include/CGAL/CORE/MemoryPool.h @@ -38,7 +38,7 @@ #include #include #include -#if CGAL_STATIC_THREAD_LOCAL_USE_BOOST || (defined(CGAL_HAS_THREADS) && BOOST_GCC) +#if defined(CGAL_HAS_THREADS) && defined(BOOST_GCC) && BOOST_GCC < 90100 // Force the use of Boost.Thread with g++ and C++11, because of the PR66944 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66944 // See also CGAL PR #1888 @@ -84,6 +84,10 @@ public: ::operator delete(blocks[i]); } } + // un-commenting the following line can help reproduce on Linux the + // assertion !blocks.empty() that is sometimes triggered with MSVC + // or AppleClang + // blocks.clear(); } @@ -92,10 +96,14 @@ public: // Access the corresponding static global allocator. static MemoryPool& global_allocator() { -#if CGAL_STATIC_THREAD_LOCAL_USE_BOOST || (defined(CGAL_HAS_THREADS) && BOOST_GCC) +#if defined(CGAL_HAS_THREADS) && defined(BOOST_GCC) && BOOST_GCC < 90100 if(memPool_ptr.get() == nullptr) {memPool_ptr.reset(new Self());} Self& memPool = * memPool_ptr.get(); -#endif +#elif defined(CGAL_HAS_THREADS) // use the C++11 implementation + static thread_local Self memPool; +#else // not CGAL_HAS_THREADS + static Self memPool; +#endif // not CGAL_HAS_THREADS return memPool; } @@ -103,25 +111,15 @@ private: Thunk* head; // next available block in the pool std::vector blocks; -#if CGAL_STATIC_THREAD_LOCAL_USE_BOOST || (defined(CGAL_HAS_THREADS) && BOOST_GCC) +#if defined(CGAL_HAS_THREADS) && defined(BOOST_GCC) && BOOST_GCC < 90100 static boost::thread_specific_ptr memPool_ptr; -#elif defined(CGAL_HAS_THREADS) // use the C++11 implementation - static thread_local Self memPool; -#else // not CGAL_HAS_THREADS - static Self memPool; #endif // not CGAL_HAS_THREADS }; -#if CGAL_STATIC_THREAD_LOCAL_USE_BOOST || (defined(CGAL_HAS_THREADS) && BOOST_GCC) +#if defined(CGAL_HAS_THREADS) && defined(BOOST_GCC) && BOOST_GCC < 90100 template boost::thread_specific_ptr > MemoryPool::memPool_ptr; -#else // use C++11 or without CGAL_HAS_THREADS -template -# ifdef CGAL_HAS_THREADS -thread_local -# endif -MemoryPool MemoryPool::memPool; #endif template< class T, int nObjects > diff --git a/CGAL_Core/include/CGAL/CORE/poly/Poly.h b/CGAL_Core/include/CGAL/CORE/poly/Poly.h index 29a11e6ef82..a16c37fbbbc 100644 --- a/CGAL_Core/include/CGAL/CORE/poly/Poly.h +++ b/CGAL_Core/include/CGAL/CORE/poly/Poly.h @@ -65,7 +65,6 @@ #include namespace CORE { -using namespace std; class Expr; // ================================================== // Typedefs @@ -117,25 +116,25 @@ public: Polynomial(const Polynomial &); Polynomial(const VecNT &); Polynomial(int n, const char* s[]); - Polynomial(const string & s, char myX='x'); + Polynomial(const std::string & s, char myX='x'); Polynomial(const char* s, char myX='x'); ~Polynomial(); private: void constructX(int n, Polynomial& P); - void constructFromString(string & s, char myX='x'); + void constructFromString(std::string & s, char myX='x'); int getnumber(const char* c, int i, unsigned int len, Polynomial & P); bool isint(char c); int getint(const char* c, int i, unsigned int len, int & n); int matchparen(const char* cstr, int start); - int getbasicterm(string & s, Polynomial & P); - int getterm(string & s, Polynomial & P); + int getbasicterm(std::string & s, Polynomial & P); + int getterm(std::string & s, Polynomial & P); public: //Returns a Polynomial corresponding to s, which is supposed to //contain as place-holders the chars 'x' and 'y'. - Polynomial getpoly(string & s); + Polynomial getpoly(std::string & s); // Assignment: Polynomial & operator=(const Polynomial&); diff --git a/CGAL_Core/include/CGAL/CORE/poly/Poly.tcc b/CGAL_Core/include/CGAL/CORE/poly/Poly.tcc index a4af8cd1825..8455a22c52f 100644 --- a/CGAL_Core/include/CGAL/CORE/poly/Poly.tcc +++ b/CGAL_Core/include/CGAL/CORE/poly/Poly.tcc @@ -131,21 +131,21 @@ Polynomial::Polynomial(int n, const char * s[]) { // want to generalize this to BigFloat, etc. // template -Polynomial::Polynomial(const string & s, char myX) { - string ss(s); +Polynomial::Polynomial(const std::string & s, char myX) { + std::string ss(s); constructFromString(ss, myX); } template Polynomial::Polynomial(const char * s, char myX) { - string ss(s); + std::string ss(s); constructFromString(ss, myX); } template -void Polynomial::constructFromString(string & s, char myX) { +void Polynomial::constructFromString(std::string & s, char myX) { if(myX != 'x' || myX != 'X'){ //Replace myX with 'x'. - string::size_type loc = s.find(myX, 0); - while(loc != string::npos){ + std::string::size_type loc = s.find(myX, 0); + while(loc != std::string::npos){ s.replace(loc,1,1,'x'); loc = s.find(myX, loc+1); } @@ -241,7 +241,7 @@ int Polynomial::matchparen(const char* cstr, int start){ template -int Polynomial::getbasicterm(string & s, Polynomial & P){ +int Polynomial::getbasicterm(std::string & s, Polynomial & P){ const char * cstr = s.c_str(); unsigned int len = s.length(); int i=0; @@ -254,7 +254,7 @@ int Polynomial::getbasicterm(string & s, Polynomial & P){ }else if(cstr[i] =='('){ int oldi = i; i = matchparen(cstr, i); - string t = s.substr(oldi+1, i -oldi -1); + std::string t = s.substr(oldi+1, i -oldi -1); P = getpoly(t); }else{ #ifdef CGAL_CORE_TRACE @@ -272,7 +272,7 @@ int Polynomial::getbasicterm(string & s, Polynomial & P){ template -int Polynomial::getterm(string & s, Polynomial & P){ +int Polynomial::getterm(std::string & s, Polynomial & P){ unsigned int len = s.length(); if(len == 0){// Zero Polynomial P=Polynomial(); @@ -280,7 +280,7 @@ int Polynomial::getterm(string & s, Polynomial & P){ } unsigned int ind, oind; const char* cstr =s.c_str(); - string t; + std::string t; //P will be used to accumulate the product of basic terms. ind = getbasicterm(s, P); while(ind != len-1 && cstr[ind + 1]!='+' && cstr[ind + 1]!='-' ){ @@ -304,11 +304,11 @@ int Polynomial::getterm(string & s, Polynomial & P){ } template -Polynomial Polynomial::getpoly(string & s){ +Polynomial Polynomial::getpoly(std::string & s){ //Remove white spaces from the string - string::size_type cnt=s.find(' ',0); - while(cnt != string::npos){ + std::string::size_type cnt=s.find(' ',0); + while(cnt != std::string::npos){ s.erase(cnt, 1); cnt = s.find(' ', cnt); } @@ -321,10 +321,10 @@ Polynomial Polynomial::getpoly(string & s){ //To handle the case when there is one '=' sign //Suppose s is of the form s1 = s2. Then we assign s to //s1 + (-1)(s2) and reset len - string::size_type loc; - if((loc=s.find('=',0)) != string::npos){ + std::string::size_type loc; + if((loc=s.find('=',0)) != std::string::npos){ s.replace(loc,1,1,'+'); - string s3 = "(-1)("; + std::string s3 = "(-1)("; s.insert(loc+1, s3); len = s.length(); s.insert(len, 1, ')'); @@ -332,7 +332,7 @@ Polynomial Polynomial::getpoly(string & s){ len = s.length(); const char *cstr = s.c_str(); - string t; + std::string t; Polynomial P; // P will be the polynomial in which we accumulate the //sum and difference of the different terms. @@ -966,7 +966,7 @@ BigInt Polynomial::UpperBound() const { lhsNeg.makeCeilExact(); /* compute B^{deg} */ - if (rhs <= max(lhsPos,lhsNeg)) { + if (rhs <= (std::max)(lhsPos,lhsNeg)) { B <<= 1; rhs *= (BigInt(1)<vy; } double vz() const { return image_ptr->vz; } + double tx() const { return image_ptr->tx; } + double ty() const { return image_ptr->ty; } + double tz() const { return image_ptr->tz; } + float value(const std::size_t i, const std::size_t j, const std::size_t k) const diff --git a/Classification/include/CGAL/Classification/Cluster.h b/Classification/include/CGAL/Classification/Cluster.h index 46d0d49857b..85ce5a9893f 100644 --- a/Classification/include/CGAL/Classification/Cluster.h +++ b/Classification/include/CGAL/Classification/Cluster.h @@ -69,6 +69,28 @@ public: std::shared_ptr > neighbors; /// \endcond + /// \cond SKIP_IN_MANUAL + class Point_idx_to_point_unary_function + { + public: + typedef std::size_t argument_type; + typedef typename ItemMap::reference result_type; + typedef boost::readable_property_map_tag category; + + const ItemRange* m_range; + ItemMap m_item_map; + + Point_idx_to_point_unary_function (const ItemRange* range, ItemMap item_map) + : m_range (range), m_item_map (item_map) + { } + + result_type operator() (const argument_type& arg) const + { + return get (m_item_map, *(m_range->begin() + arg)); + } + }; + /// \endcond + private: const ItemRange* m_range; ItemMap m_item_map; @@ -139,14 +161,12 @@ public: */ const CGAL::Bbox_3& bbox() const { - auto transform = [&](const std::size_t& idx) -> typename ItemMap::reference - { - return get (m_item_map, *(m_range->begin() + idx)); - }; - if (m_bounding_box == CGAL::Bbox_3()) + { + Point_idx_to_point_unary_function transform (m_range, m_item_map); m_bounding_box = CGAL::bbox_3 (boost::make_transform_iterator (m_inliers->begin(), transform), boost::make_transform_iterator (m_inliers->end(), transform)); + } return m_bounding_box; } diff --git a/Documentation/doc/Documentation/Installation.txt b/Documentation/doc/Documentation/Installation.txt index a9a81b1219d..5637d22c869 100644 --- a/Documentation/doc/Documentation/Installation.txt +++ b/Documentation/doc/Documentation/Installation.txt @@ -295,7 +295,7 @@ We next list the libraries and essential 3rd party software | Library | CMake Variable | Functionality | Dependencies | | :-------- | :------------- | :------------ | :----------- | -| `%CGAL` | none | Main library | \sc{Gmp}, \sc{Mpfr}, \sc{Boost} (headers), Boost.Thread and Boost.System (library) for compilers not supporting the keywords `thread_local` and the class `std::mutex` | +| `%CGAL` | none | Main library | \sc{Gmp}, \sc{Mpfr}, \sc{Boost} (headers) | | `CGAL_Core` | `WITH_CGAL_Core` | The CORE library for algebraic numbers.\cgalFootnote{CGAL_Core is not part of \cgal, but a custom version of the \sc{Core} library distributed by \cgal for the user convenience and it has it's own license.} | \sc{Gmp} and \sc{Mpfr} | | `CGAL_ImageIO` | `WITH_CGAL_ImageIO` | Utilities to read and write image files | \sc{zlib}, \sc{Vtk}(optional) | | `CGAL_Qt5` | `WITH_CGAL_Qt5` | `QGraphicsView` support for \sc{Qt}5-based demos | \sc{Qt}5 | @@ -388,27 +388,16 @@ The \sc{Boost} libraries are a set of portable C++ source libraries. Most of \sc{Boost} libraries are header-only, but a few of them need to be compiled or installed as binaries. -\cgal requires the \sc{Boost} libraries. In particular the header files -and the threading library (`Boost.Thread` and -`Boost.System` binaries). Version 1.48 (or higher) are needed -for compilers not supporting the keyword `thread_local` and the class `std::mutex` (This is supported for \gcc 4.8 and later when using the \cpp 11 standard, and for Visual C++ starting with 2015, that is VC14). +\cgal only requires the headers of the \sc{Boost} libraries, but some demos and examples depend on the binary library `Boost.Program_options`. As an exception, because of a bug in the \gcc compiler about the \cpp 11 keyword `thread_local`, the `CGAL_Core` library always requires -`Boost.Thread` if the \gcc compiler is used. - -On Windows, as auto-linking is used, you also need the binaries of -`Boost.Serialization` and `Boost.DateTime`, but the -dependency is artificial and used only at link-time: the \cgal libraries do -not depend on the DLL's of those two libraries. - -In \cgal some demos and examples depend on `Boost.Program_options`. +the binary library `Boost.Thread` if the \gcc compiler version 9.0 or +earlier is used. In case the \sc{Boost} libraries are not installed on your system already, you can obtain them from `https://www.boost.org/`. For Visual C++ you can download precompiled libraries from `https://sourceforge.net/projects/boost/files/boost-binaries/`. -For Visual C++ versions prior to 2015 `Boost.Thread` is required, so make sure to either install the precompiled -libraries for your compiler or build `libboost-thread` and `libboost-system`. As on Windows there is no canonical directory for where to find \sc{Boost}, we recommend that you define the environment variable diff --git a/GraphicsView/include/CGAL/Buffer_for_vao.h b/GraphicsView/include/CGAL/Buffer_for_vao.h index c6790f79c9f..dbb440a9496 100644 --- a/GraphicsView/include/CGAL/Buffer_for_vao.h +++ b/GraphicsView/include/CGAL/Buffer_for_vao.h @@ -35,7 +35,7 @@ #include #include #include -#include +#include namespace CGAL { @@ -161,6 +161,9 @@ public: m_flat_normal_buffer(flat_normal), m_gouraud_normal_buffer(gouraud_normal), m_bb(bbox), + m_zero_x(true), + m_zero_y(true), + m_zero_z(true), m_face_started(false) {} @@ -171,6 +174,10 @@ public: if (m_index_buffer!=nullptr) { m_index_buffer->clear(); } if (m_flat_normal_buffer!=nullptr) { m_flat_normal_buffer->clear(); } if (m_gouraud_normal_buffer!=nullptr) { m_gouraud_normal_buffer->clear(); } + + m_zero_x=true; + m_zero_y=true; + m_zero_z=true; } bool is_empty() const @@ -198,6 +205,15 @@ public: bool has_gouraud_normal() const { return m_gouraud_normal_buffer!=nullptr; } + bool has_zero_x() const + { return m_zero_x; } + + bool has_zero_y() const + { return m_zero_y; } + + bool has_zero_z() const + { return m_zero_z; } + // 1.1) Add a point, without color. Return the index of the added point. template std::size_t add_point(const KPoint& kp) @@ -209,6 +225,10 @@ public: if (m_bb!=nullptr) { (*m_bb)=(*m_bb)+p.bbox(); } + + if (m_zero_x && p.x()!=0) { m_zero_x=false; } + if (m_zero_y && p.y()!=0) { m_zero_y=false; } + if (m_zero_z && p.z()!=0) { m_zero_z=false; } return m_pos_buffer->size()-3; } @@ -605,8 +625,23 @@ protected: { P_traits cdt_traits(normal); CDT cdt(cdt_traits); - bool with_vertex_normal=(m_vertex_normals_for_face.size()==m_points_of_face.size()); + Local_point p1, p2; + + // For each point of the face, store the list of adjacent points and the number of time + // the edge is found in the face. For an edge p1, p2, store edge min(p1,p2)->max(p1,p2) + std::map > edges; + for (unsigned int i=0; i m; m[p2]=1; edges[p1]=m; } + else if (edges[p1].count(p2)==0) { edges[p1][p2]=1; } + else { ++(edges[p1][p2]); } + } // (1) We insert all the edges as contraint in the CDT. typename CDT::Vertex_handle previous=nullptr, first=nullptr; @@ -625,12 +660,22 @@ protected: { vh->info().index=m_indices_of_points_of_face[i]; } if(previous!=nullptr && previous!=vh) - { cdt.insert_constraint(previous, vh); } + { + p1=m_points_of_face[i]; p2=m_points_of_face[i-1]; + if (p2 constraint + { cdt.insert_constraint(previous, vh); } + } previous=vh; } if (previous!=nullptr && previous!=first) - { cdt.insert_constraint(previous, first); } + { + p1=m_points_of_face[m_points_of_face.size()-1]; p2=m_points_of_face[0]; + if (p2 constraint + { cdt.insert_constraint(previous, first); } + } // (2) We mark all external triangles // (2.1) We initialize is_external and is_process values @@ -782,6 +827,10 @@ protected: std::vector* m_gouraud_normal_buffer; CGAL::Bbox_3* m_bb; + + bool m_zero_x; /// True iff all points have x==0 + bool m_zero_y; /// True iff all points have y==0 + bool m_zero_z; /// True iff all points have z==0 // Local variables, used when we started a new face. bool m_face_started; diff --git a/GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h b/GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h index e4ae0184c19..1d2fbd751e9 100644 --- a/GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h +++ b/GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h @@ -55,6 +55,7 @@ #include #include +#include #include namespace CGAL @@ -253,6 +254,39 @@ public: const CGAL::Bbox_3& bounding_box() const { return m_bounding_box; } + bool has_zero_x() const + { + return + m_buffer_for_mono_points.has_zero_x() && + m_buffer_for_colored_points.has_zero_x() && + m_buffer_for_mono_segments.has_zero_x() && + m_buffer_for_colored_segments.has_zero_x() && + m_buffer_for_mono_faces.has_zero_x() && + m_buffer_for_colored_faces.has_zero_x(); + } + + bool has_zero_y() const + { + return + m_buffer_for_mono_points.has_zero_y() && + m_buffer_for_colored_points.has_zero_y() && + m_buffer_for_mono_segments.has_zero_y() && + m_buffer_for_colored_segments.has_zero_y() && + m_buffer_for_mono_faces.has_zero_y() && + m_buffer_for_colored_faces.has_zero_y(); + } + + bool has_zero_z() const + { + return + m_buffer_for_mono_points.has_zero_z() && + m_buffer_for_colored_points.has_zero_z() && + m_buffer_for_mono_segments.has_zero_z() && + m_buffer_for_colored_segments.has_zero_z() && + m_buffer_for_mono_faces.has_zero_z() && + m_buffer_for_colored_faces.has_zero_z(); + } + template void add_point(const KPoint& p) { m_buffer_for_mono_points.add_point(p); } @@ -732,6 +766,23 @@ protected: rendering_program_face.release(); } + + if (!is_empty() && (has_zero_x() || has_zero_y() || has_zero_z())) + { + camera()->setType(CGAL::qglviewer::Camera::ORTHOGRAPHIC); + // Camera Constraint: + constraint.setRotationConstraintType(CGAL::qglviewer::AxisPlaneConstraint::AXIS); + constraint.setTranslationConstraintType(CGAL::qglviewer::AxisPlaneConstraint::FREE); + + double cx=0., cy=0., cz=0.; + if (has_zero_x()) { cx=1.; } + else if (has_zero_y()) { cy=1.; } + else { cz=1.; } + + camera()->setViewDirection(CGAL::qglviewer::Vec(-cx,-cy,-cz)); + constraint.setRotationConstraintDirection(CGAL::qglviewer::Vec(cx, cy, cz)); + camera()->frame()->setConstraint(&constraint); + } } virtual void redraw() @@ -775,7 +826,7 @@ protected: glHint(GL_LINE_SMOOTH_HINT, GL_FASTEST); compile_shaders(); - + CGAL::Bbox_3 bb; if (bb==bounding_box()) // Case of "empty" bounding box { @@ -1000,7 +1051,10 @@ protected: bool m_are_buffers_initialized; CGAL::Bbox_3 m_bounding_box; - + + // CGAL::qglviewer::LocalConstraint constraint; + CGAL::qglviewer::WorldConstraint constraint; + // The following enum gives the indices of different elements of arrays vectors. enum { @@ -1059,36 +1113,14 @@ protected: #else // CGAL_USE_BASIC_VIEWER -namespace CGAL +namespace CGAL { -template -void draw(const T&, const char*, bool, const ColorFunctor&) -{ - std::cerr<<"Impossible to draw because CGAL_USE_BASIC_VIEWER is not defined." - < -void draw(const T&, const char*, bool) -{ - std::cerr<<"Impossible to draw because CGAL_USE_BASIC_VIEWER is not defined." - < -void draw(const T&, const char*) -{ - std::cerr<<"Impossible to draw because CGAL_USE_BASIC_VIEWER is not defined." - < -void draw(const T&) -{ - std::cerr<<"Impossible to draw because CGAL_USE_BASIC_VIEWER is not defined." - < + void draw(const T&, const char* ="", bool=false) + { + std::cerr<<"Impossible to draw, CGAL_USE_BASIC_VIEWER is not defined."<= 1.48) Required for building CGAL and for applications using CGAL - Required compiled Boost library: Boost.Thread, Boost.System Optional compiled Boost library: Boost.Program_options http://www.boost.org/ or http://www.boostpro.com/products/free/ You need the former if you plan to compile the boost libraries yourself, diff --git a/Installation/cmake/modules/CGALConfig_binary.cmake.in b/Installation/cmake/modules/CGALConfig_binary.cmake.in index 23a6399923e..e22b4141f3a 100644 --- a/Installation/cmake/modules/CGALConfig_binary.cmake.in +++ b/Installation/cmake/modules/CGALConfig_binary.cmake.in @@ -12,6 +12,9 @@ get_filename_component(CGAL_CONFIG_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) set(CGAL_HEADER_ONLY "@CGAL_HEADER_ONLY@" ) +include(CMakeFindDependencyMacro) +find_dependency(Boost REQUIRED) + # The code for including exported targets is different from # CGAL_Config_install.cmake. We do not have separate export files in # an installed version and we need to make sure that we are not @@ -114,15 +117,6 @@ macro(check_cgal_component COMPONENT) if ( "${CGAL_LIB}" STREQUAL "CGAL" ) set( CGAL_FOUND TRUE ) set( CHECK_CGAL_ERROR_TAIL "" ) - get_property(CGAL_CGAL_is_imported TARGET CGAL::CGAL PROPERTY IMPORTED) - if(CGAL_CGAL_is_imported) - include("${CGAL_MODULES_DIR}/CGAL_SetupBoost.cmake") - get_property(CGAL_requires_Boost_libs - GLOBAL PROPERTY CGAL_requires_Boost_Thread) - if(CGAL_requires_Boost_libs AND TARGET Boost::thread) - set_property(TARGET CGAL::CGAL APPEND PROPERTY INTERFACE_LINK_LIBRARIES Boost::thread) - endif() - endif() else( "${CGAL_LIB}" STREQUAL "CGAL" ) if ( WITH_${CGAL_LIB} ) if(TARGET CGAL::${CGAL_LIB}) diff --git a/Installation/cmake/modules/CGALConfig_install.cmake.in b/Installation/cmake/modules/CGALConfig_install.cmake.in index a97e23a1a8b..91f7a645385 100644 --- a/Installation/cmake/modules/CGALConfig_install.cmake.in +++ b/Installation/cmake/modules/CGALConfig_install.cmake.in @@ -12,6 +12,9 @@ get_filename_component(CGAL_CONFIG_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) set(CGAL_HEADER_ONLY "@CGAL_HEADER_ONLY@" ) +include(CMakeFindDependencyMacro) +find_dependency(Boost REQUIRED) + # CGAL_DIR is the directory where this CGALConfig.cmake is installed string(REPLACE "/@CGAL_INSTALL_CMAKE_DIR@" "" CGAL_INSTALL_PREFIX "${CGAL_CONFIG_DIR}") diff --git a/Installation/cmake/modules/CGAL_Macros.cmake b/Installation/cmake/modules/CGAL_Macros.cmake index 23049fbb26e..4d501fa5ce5 100644 --- a/Installation/cmake/modules/CGAL_Macros.cmake +++ b/Installation/cmake/modules/CGAL_Macros.cmake @@ -290,13 +290,6 @@ if( NOT CGAL_MACROS_FILE_INCLUDED ) # To deal with imported targets of Qt5 and Boost, when CGAL # targets are themselves imported by another project. if(NOT CGAL_BUILDING_LIBS) - if (NOT MSVC AND "${component}" STREQUAL "Core") - # See the release notes of CGAL-4.10: CGAL_Core now requires - # Boost.Thread, with all compilers but MSVC. - find_package( Boost 1.48 REQUIRED thread system ) - add_to_list( CGAL_3RD_PARTY_LIBRARIES ${Boost_LIBRARIES} ) - endif() - if (${component} STREQUAL "Qt5") find_package(Qt5 COMPONENTS OpenGL Gui Core Script ScriptTools QUIET) endif() diff --git a/Installation/cmake/modules/CGAL_SetupBoost.cmake b/Installation/cmake/modules/CGAL_SetupBoost.cmake index 758736e3dd0..a1b57c24423 100644 --- a/Installation/cmake/modules/CGAL_SetupBoost.cmake +++ b/Installation/cmake/modules/CGAL_SetupBoost.cmake @@ -17,38 +17,7 @@ set ( CGAL_Boost_Setup TRUE ) include(${CMAKE_CURRENT_LIST_DIR}/CGAL_TweakFindBoost.cmake) -function(CGAL_detect_if_Boost_Thread_is_required) - get_property(PROPERTY_CGAL_requires_Boost_Thread_IS_SET - GLOBAL PROPERTY CGAL_requires_Boost_Thread SET) - if(PROPERTY_CGAL_requires_Boost_Thread_IS_SET) - get_property(CGAL_requires_Boost_libs - GLOBAL PROPERTY CGAL_requires_Boost_Thread) - else() - set ( CGAL_requires_Boost_libs TRUE ) - if ( DEFINED MSVC_VERSION AND "${MSVC_VERSION}" GREATER 1800) - set ( CGAL_requires_Boost_libs FALSE ) - else() - try_run( CGAL_test_cpp_version_RUN_RES CGAL_test_cpp_version_COMPILE_RES - "${CMAKE_BINARY_DIR}" - "${CGAL_MODULES_DIR}/config/support/CGAL_test_cpp_version.cpp" - RUN_OUTPUT_VARIABLE CGAL_cplusplus) - message(STATUS "__cplusplus is ${CGAL_cplusplus}") - if(NOT CGAL_test_cpp_version_RUN_RES) - set ( CGAL_requires_Boost_libs FALSE ) - message(STATUS " --> Do not link with Boost.Thread") - endif() - endif() - endif() - set_property(GLOBAL PROPERTY CGAL_requires_Boost_Thread ${CGAL_requires_Boost_libs}) - set(CGAL_requires_Boost_libs ${CGAL_requires_Boost_libs} PARENT_SCOPE) -endfunction(CGAL_detect_if_Boost_Thread_is_required) - -CGAL_detect_if_Boost_Thread_is_required() -if (CGAL_requires_Boost_libs) - find_package( Boost 1.48 REQUIRED thread system ) -else() - find_package( Boost 1.48 REQUIRED ) -endif() +find_package( Boost 1.48 REQUIRED ) if(Boost_FOUND AND Boost_VERSION VERSION_LESS 1.70) if(DEFINED Boost_DIR AND NOT Boost_DIR) @@ -94,9 +63,6 @@ function(use_CGAL_Boost_support target) endif() if(TARGET Boost::boost) target_link_libraries(${target} ${keyword} Boost::boost) - if (CGAL_requires_Boost_libs) - target_link_libraries(${target} ${keyword} Boost::thread) - endif() else() target_include_directories(${target} SYSTEM ${keyword} ${Boost_INCLUDE_DIRS}) target_link_libraries(${target} ${keyword} ${Boost_LIBRARIES}) diff --git a/Installation/cmake/modules/CGAL_SetupCGAL_CoreDependencies.cmake b/Installation/cmake/modules/CGAL_SetupCGAL_CoreDependencies.cmake index 6c0f2ad214d..053c4f6ab67 100644 --- a/Installation/cmake/modules/CGAL_SetupCGAL_CoreDependencies.cmake +++ b/Installation/cmake/modules/CGAL_SetupCGAL_CoreDependencies.cmake @@ -54,8 +54,8 @@ endif() # # See the release notes of CGAL-4.10: CGAL_Core now requires -# Boost.Thread, with GNU G++. -if (CMAKE_CXX_COMPILER_ID STREQUAL GNU) +# Boost.Thread, with GNU G++ < 9.1. +if (CMAKE_CXX_COMPILER_ID STREQUAL GNU AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.1) include(${CMAKE_CURRENT_LIST_DIR}/CGAL_TweakFindBoost.cmake) find_package( Boost 1.48 REQUIRED COMPONENTS thread system ) endif() @@ -73,7 +73,7 @@ function(CGAL_setup_CGAL_Core_dependencies target) # See the release notes of CGAL-4.10: CGAL_Core now requires # Boost.Thread, with GNU G++. - if (CMAKE_CXX_COMPILER_ID STREQUAL GNU) + if (CMAKE_CXX_COMPILER_ID STREQUAL GNU AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.1) if(TARGET Boost::thread) target_link_libraries( CGAL_Core ${keyword} Boost::thread) else() diff --git a/Installation/cmake/modules/CGAL_add_test.cmake b/Installation/cmake/modules/CGAL_add_test.cmake index 926b8bb9948..5d839f9907c 100644 --- a/Installation/cmake/modules/CGAL_add_test.cmake +++ b/Installation/cmake/modules/CGAL_add_test.cmake @@ -98,8 +98,25 @@ function(cgal_add_compilation_test exe_name) COMMAND ${TIME_COMMAND} "${CMAKE_COMMAND}" --build "${CMAKE_BINARY_DIR}" --target "${exe_name}") set_property(TEST "compilation_of__${exe_name}" APPEND PROPERTY LABELS "${PROJECT_NAME}") + if(NOT TARGET cgal_check_build_system) + add_custom_target(cgal_check_build_system) + endif() + if(NOT TEST check_build_system) + add_test(NAME "check_build_system" + COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_BINARY_DIR}" --target "cgal_check_build_system") + if(POLICY CMP0066) # cmake 3.7 or later + set_property(TEST "check_build_system" + PROPERTY FIXTURES_SETUP "check_build_system_SetupFixture") + endif() + endif() + if(POLICY CMP0066) # cmake 3.7 or later + set_property(TEST "compilation_of__${exe_name}" + APPEND PROPERTY FIXTURES_REQUIRED "check_build_system_SetupFixture") + endif() endfunction(cgal_add_compilation_test) +option(CGAL_TEST_DRAW_FUNCTIONS "If set, the ctest command will not skip the tests of the draw functions.") + function(cgal_setup_test_properties test_name) if(ARGC GREATER 1) set(exe_name ${ARGV1}) @@ -109,6 +126,11 @@ function(cgal_setup_test_properties test_name) # message(STATUS " working dir: ${CMAKE_CURRENT_SOURCE_DIR}") set_property(TEST "${test_name}" PROPERTY WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + if(NOT CGAL_TEST_DRAW_FUNCTIONS) + set_property(TEST "${test_name}" + APPEND PROPERTY ENVIRONMENT CGAL_TEST_SUITE=1) + endif() + if(exe_name) set_property(TEST "${test_name}" APPEND PROPERTY DEPENDS "compilation_of__${exe_name}") diff --git a/Installation/include/CGAL/tss.h b/Installation/include/CGAL/tss.h index 7096b1612e8..22f47a46632 100644 --- a/Installation/include/CGAL/tss.h +++ b/Installation/include/CGAL/tss.h @@ -22,64 +22,22 @@ #include #if defined( CGAL_HAS_THREADS ) -# ifdef CGAL_CAN_USE_CXX11_THREAD_LOCAL -//# pragma message ( "Use keyword thread_local" ) -# else -//# pragma message ("Use thread_local from boost") -# define CGAL_USE_BOOST_THREAD -# include -# endif +# define CGAL_STATIC_THREAD_LOCAL_VARIABLE_0(TYPE, VAR) \ + static thread_local TYPE VAR -# ifdef CGAL_USE_BOOST_THREAD -# define CGAL_STATIC_THREAD_LOCAL_USE_BOOST 1 +# define CGAL_STATIC_THREAD_LOCAL_VARIABLE(TYPE, VAR, ARG1) \ + static thread_local TYPE VAR(ARG1) -# define CGAL_STATIC_THREAD_LOCAL_VARIABLE_0(TYPE, VAR) \ - static boost::thread_specific_ptr VAR##_ptr; \ - if(VAR##_ptr.get() == nullptr) {VAR##_ptr.reset(new TYPE());} \ - TYPE& VAR = * VAR##_ptr.get() - -# define CGAL_STATIC_THREAD_LOCAL_VARIABLE(TYPE, VAR, ARG1) \ - static boost::thread_specific_ptr VAR##_ptr; \ - if(VAR##_ptr.get() == nullptr) {VAR##_ptr.reset(new TYPE(ARG1));} \ - TYPE& VAR = * VAR##_ptr.get() - -# define CGAL_STATIC_THREAD_LOCAL_VARIABLE_2(TYPE, VAR, ARG1, ARG2) \ - static boost::thread_specific_ptr VAR##_ptr; \ - if(VAR##_ptr.get() == nullptr) {VAR##_ptr.reset(new TYPE(ARG1,ARG2));} \ - TYPE& VAR = * VAR##_ptr.get() - -# define CGAL_STATIC_THREAD_LOCAL_VARIABLE_3(TYPE, VAR, ARG1, ARG2, ARG3) \ - static boost::thread_specific_ptr VAR##_ptr; \ - if(VAR##_ptr.get() == nullptr) {VAR##_ptr.reset(new TYPE(ARG1,ARG2,ARG3));} \ - TYPE& VAR = * VAR##_ptr.get() - -# define CGAL_STATIC_THREAD_LOCAL_VARIABLE_4(TYPE, VAR, ARG1, ARG2, ARG3, ARG4) \ - static boost::thread_specific_ptr VAR##_ptr; \ - if(VAR##_ptr.get() == nullptr) {VAR##_ptr.reset(new TYPE(ARG1,ARG2,ARG3,ARG4));} \ - TYPE& VAR = * VAR##_ptr.get() - - - -# else // not CGAL_USE_BOOST_THREAD, -> use C++11 thread_local - -# define CGAL_STATIC_THREAD_LOCAL_VARIABLE_0(TYPE, VAR) \ - static thread_local TYPE VAR - -# define CGAL_STATIC_THREAD_LOCAL_VARIABLE(TYPE, VAR, ARG1) \ - static thread_local TYPE VAR(ARG1) - -# define CGAL_STATIC_THREAD_LOCAL_VARIABLE_2(TYPE, VAR, ARG1, ARG2) \ +# define CGAL_STATIC_THREAD_LOCAL_VARIABLE_2(TYPE, VAR, ARG1, ARG2) \ static thread_local TYPE VAR(ARG1,ARG2) -# define CGAL_STATIC_THREAD_LOCAL_VARIABLE_3(TYPE, VAR, ARG1, ARG2, ARG3) \ +# define CGAL_STATIC_THREAD_LOCAL_VARIABLE_3(TYPE, VAR, ARG1, ARG2, ARG3) \ static thread_local TYPE VAR(ARG1,ARG2,ARG3) -# define CGAL_STATIC_THREAD_LOCAL_VARIABLE_4(TYPE, VAR, ARG1, ARG2, ARG3, ARG4) \ +# define CGAL_STATIC_THREAD_LOCAL_VARIABLE_4(TYPE, VAR, ARG1, ARG2, ARG3, ARG4) \ static thread_local TYPE VAR(ARG1,ARG2,ARG3,ARG4) -# endif // not CGAL_USE_BOOST_THREAD - #else // not CGAL_HAS_THREADS # define CGAL_STATIC_THREAD_LOCAL_VARIABLE_0(TYPE, VAR) static TYPE VAR diff --git a/Kernel_23/test/Kernel_23/Filtered_cartesian.cpp b/Kernel_23/test/Kernel_23/Filtered_cartesian.cpp index 25a57e1965e..ee48df866ac 100644 --- a/Kernel_23/test/Kernel_23/Filtered_cartesian.cpp +++ b/Kernel_23/test/Kernel_23/Filtered_cartesian.cpp @@ -58,7 +58,7 @@ void test(); int main() { - CGAL::force_ieee_double_precision(); + CGAL::Set_ieee_double_precision double_precision_guard; typedef CGAL::Cartesian Clsdb; typedef CGAL::Filtered_kernel Clsd; diff --git a/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_tetrahedron_3.h b/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_tetrahedron_3.h index 3d54525e066..0b12bcfd8eb 100644 --- a/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_tetrahedron_3.h +++ b/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_tetrahedron_3.h @@ -36,9 +36,6 @@ _test_cls_tetrahedron_3(const R& ) typedef typename R::RT RT; typedef typename R::FT FT; - typename R::Tetrahedron_3 it; - CGAL::Tetrahedron_3 t0(it); - RT n0 = 0; RT n1 = 12; RT n2 = 16; @@ -60,6 +57,10 @@ _test_cls_tetrahedron_3(const R& ) CGAL::Point_3 ps1( n7, n0, n0, n5); // (3, 0, 0) CGAL::Point_3 ps0( CGAL::ORIGIN ); // (0, 0, 0) + typename R::Tetrahedron_3 it0; // check the default-constructor + typename R::Tetrahedron_3 it(p1,p2,p3,p4); + CGAL::Tetrahedron_3 t0(it); + const CGAL::Tetrahedron_3 t1(p1,p2,p3,p4); CGAL::Tetrahedron_3 t2(p2,p1,p3,p4); CGAL::Tetrahedron_3 t3(ps0,ps1,ps2,ps3); // positive oriented diff --git a/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_triangle_3.h b/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_triangle_3.h index 0b85fc87108..fbb1a21ef7a 100644 --- a/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_triangle_3.h +++ b/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_triangle_3.h @@ -36,9 +36,6 @@ _test_cls_triangle_3(const R& ) typedef typename R::RT RT; typedef typename R::FT FT; - typename R::Triangle_3 it; - CGAL::Triangle_3 t0(it); - RT n0 = 0; RT n1 = 12; RT n2 = 16; @@ -61,7 +58,10 @@ _test_cls_triangle_3(const R& ) CGAL::Point_3 ps2( n0, n7, n0, n5); // (0, 3, 0) CGAL::Point_3 ps1( n7, n0, n0, n5); // (3, 0, 0) + typename R::Triangle_3 it; // test default-constructor + const CGAL::Triangle_3 t1(p1,p2,p3); + CGAL::Triangle_3 t0(t1); CGAL::Triangle_3 t2(p4,p2,p3); CGAL::Triangle_3 t3(ps1,ps2,ps3); CGAL::Triangle_3 t4(ps2,ps1,ps3); diff --git a/Kernel_23/test/Kernel_23/include/CGAL/_test_new_3.h b/Kernel_23/test/Kernel_23/include/CGAL/_test_new_3.h index 6b5939a9afa..c96987f970f 100644 --- a/Kernel_23/test/Kernel_23/include/CGAL/_test_new_3.h +++ b/Kernel_23/test/Kernel_23/include/CGAL/_test_new_3.h @@ -221,8 +221,8 @@ test_new_3(const R& rep) typename R::Construct_tetrahedron_3 construct_tetrahedron = rep.construct_tetrahedron_3_object(); - Tetrahedron_3 th1; - Tetrahedron_3 th2 = construct_tetrahedron(p2,p3,p4,p5); + Tetrahedron_3 th0; // test default-constructor + Tetrahedron_3 th2 = construct_tetrahedron(p2,p3,p4,p5), th1 = th2; typename R::Construct_iso_cuboid_3 construct_iso_cuboid = rep.construct_iso_cuboid_3_object(); diff --git a/Linear_cell_complex/doc/Linear_cell_complex/CGAL/draw_linear_cell_complex.h b/Linear_cell_complex/doc/Linear_cell_complex/CGAL/draw_linear_cell_complex.h index 7fd78b6695f..79cbda10f2f 100644 --- a/Linear_cell_complex/doc/Linear_cell_complex/CGAL/draw_linear_cell_complex.h +++ b/Linear_cell_complex/doc/Linear_cell_complex/CGAL/draw_linear_cell_complex.h @@ -3,7 +3,7 @@ namespace CGAL { /*! \ingroup PkgDrawLinearCellComplex -Open a new window and draw `alcc`, a model of the `LinearCellComplex` concept. The function is blocking, that is the program continues as soon as the user closes the window. This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time. +opens a new window and draws `alcc`, a model of the `LinearCellComplex` concept. A call to this function is blocking, that is the program continues as soon as the user closes the window. This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time. \tparam LCC a model of the `LinearCellComplex` concept. \param alcc the linear cell complex to draw. diff --git a/Linear_cell_complex/doc/Linear_cell_complex/Linear_cell_complex.txt b/Linear_cell_complex/doc/Linear_cell_complex/Linear_cell_complex.txt index 30e3be293e6..fba0ac158e8 100644 --- a/Linear_cell_complex/doc/Linear_cell_complex/Linear_cell_complex.txt +++ b/Linear_cell_complex/doc/Linear_cell_complex/Linear_cell_complex.txt @@ -253,7 +253,7 @@ We can observe that the second run is faster than the first one. Indeed, updatin \subsection Linear_cell_complexDraw Draw a Linear Cell Complex \anchor ssecDrawLCC -A linear cell complex can be visualized by calling the `CGAL::draw()` function as shown in the following example. This function opens a new window showing the given linear cell complex. The function is blocking, that is the program continues as soon as the user closes the window. +A linear cell complex can be visualized by calling the \link PkgDrawLinearCellComplex CGAL::draw() \endlink function as shown in the following example. This function opens a new window showing the given linear cell complex. A call to this function is blocking, that is the program continues as soon as the user closes the window. \cgalExample{Linear_cell_complex/draw_linear_cell_complex.cpp} diff --git a/Linear_cell_complex/doc/Linear_cell_complex/PackageDescription.txt b/Linear_cell_complex/doc/Linear_cell_complex/PackageDescription.txt index c57f67ee8ec..42da9fd9276 100644 --- a/Linear_cell_complex/doc/Linear_cell_complex/PackageDescription.txt +++ b/Linear_cell_complex/doc/Linear_cell_complex/PackageDescription.txt @@ -19,7 +19,7 @@ /// \defgroup PkgLinearCellComplexOperations Operations for Linear Cell Complex /// \ingroup PkgLinearCellComplexRef -/*! Draw. +/*! \code #include \endcode @@ -75,7 +75,7 @@ - `CGAL::compute_normal_of_cell_2` \cgalCRPSubsection{Draw a Linear Cell Complex} -- `CGAL::draw` +- \link PkgDrawLinearCellComplex CGAL::draw() \endlink */ diff --git a/Linear_cell_complex/examples/Linear_cell_complex/CMakeLists.txt b/Linear_cell_complex/examples/Linear_cell_complex/CMakeLists.txt index 270c76321d8..b9b86d10fc5 100644 --- a/Linear_cell_complex/examples/Linear_cell_complex/CMakeLists.txt +++ b/Linear_cell_complex/examples/Linear_cell_complex/CMakeLists.txt @@ -16,7 +16,7 @@ endif() find_package(CGAL COMPONENTS Qt5) if(CGAL_Qt5_FOUND) - add_definitions(-DCGAL_USE_BASIC_VIEWER -DQT_NO_KEYWORDS) + add_definitions(-DCGAL_USE_BASIC_VIEWER -DQT_NO_KEYWORDS) endif() # For Gprof. diff --git a/Linear_cell_complex/include/CGAL/draw_linear_cell_complex.h b/Linear_cell_complex/include/CGAL/draw_linear_cell_complex.h index 2e2c09cc36a..1b750f2dc0b 100644 --- a/Linear_cell_complex/include/CGAL/draw_linear_cell_complex.h +++ b/Linear_cell_complex/include/CGAL/draw_linear_cell_complex.h @@ -25,6 +25,7 @@ #ifdef CGAL_USE_BASIC_VIEWER +#include #include namespace CGAL @@ -371,49 +372,45 @@ protected: bool m_random_face_color; const DrawingFunctorLCC& m_drawing_functor; }; - -template -void draw(const LCC& alcc, - const char* title, - bool nofill, - const DrawingFunctorLCC& drawing_functor) + +// Specialization of draw function. +#define CGAL_LCC_TYPE CGAL::Linear_cell_complex_base \ + + +template < unsigned int d_, unsigned int ambient_dim, + class Traits_, + class Items_, + class Alloc_, + template + class Map, + class Refs, + class Storage_> +void draw(const CGAL_LCC_TYPE& alcc, + const char* title="LCC for CMap Basic Viewer", + bool nofill=false) { #if defined(CGAL_TEST_SUITE) bool cgal_test_suite=true; #else - bool cgal_test_suite=false; + bool cgal_test_suite=qEnvironmentVariableIsSet("CGAL_TEST_SUITE"); #endif - + if (!cgal_test_suite) { int argc=1; const char* argv[2]={"lccviewer","\0"}; QApplication app(argc,const_cast(argv)); - SimpleLCCViewerQt mainwindow(app.activeWindow(), - &alcc, - title, - nofill, - drawing_functor); + DefaultDrawingFunctorLCC fcolor; + SimpleLCCViewerQt + mainwindow(app.activeWindow(), &alcc, title, nofill, fcolor); mainwindow.show(); app.exec(); } } -template -void draw(const LCC& alcc, const char* title, bool nofill) -{ - DefaultDrawingFunctorLCC f; - draw(alcc, title, nofill, f); -} - -template -void draw(const LCC& alcc, const char* title) -{ draw(alcc, title, false); } - -template -void draw(const LCC& alcc) -{ draw(alcc, "Basic LCC Viewer"); } - +// Todo a function taking a const DrawingFunctorLCC& drawing_functor as parameter +#undef CGAL_LCC_TYPE + } // End namespace CGAL #endif // CGAL_USE_BASIC_VIEWER diff --git a/Mesh_3/examples/Mesh_3/CMakeLists.txt b/Mesh_3/examples/Mesh_3/CMakeLists.txt index 363821b8f97..aa7231d42fb 100644 --- a/Mesh_3/examples/Mesh_3/CMakeLists.txt +++ b/Mesh_3/examples/Mesh_3/CMakeLists.txt @@ -52,19 +52,22 @@ if ( CGAL_FOUND ) include( ${EIGEN3_USE_FILE} ) endif() - set(VTK_LIBS "") - find_package(VTK QUIET COMPONENTS vtkImagingGeneral vtkIOImage NO_MODULE) - if(VTK_FOUND) - include(${VTK_USE_FILE}) - if ("${VTK_VERSION_MAJOR}" GREATER "5") - message(STATUS "VTK found") - set( VTK_LIBS vtkImagingGeneral vtkIOImage ) - else() - message(STATUS "VTK version 6.0 or greater is required") - endif() - else() - message(STATUS "VTK was not found") + find_package(VTK QUIET COMPONENTS vtkImagingGeneral vtkIOImage NO_MODULE) + if(VTK_FOUND) + if(VTK_USE_FILE) + include(${VTK_USE_FILE}) + endif() + if ("${VTK_VERSION_MAJOR}" GREATER "5" OR VTK_VERSION VERSION_GREATER 5) + message(STATUS "VTK found") + if(TARGET VTK::IOImage) + set(VTK_LIBRARIES VTK::ImagingGeneral VTK::IOImage) endif() + else() + message(STATUS "VTK version 6.0 or greater is required") + endif() + else() + message(STATUS "VTK was not found") + endif() # Compilable examples @@ -87,9 +90,10 @@ if ( CGAL_FOUND ) create_single_source_cgal_program( "mesh_polyhedral_complex.cpp" ) create_single_source_cgal_program( "mesh_polyhedral_complex_sm.cpp" ) if( WITH_CGAL_ImageIO ) - if( VTK_FOUND AND "${VTK_VERSION_MAJOR}" GREATER "5" ) + if( VTK_FOUND AND ("${VTK_VERSION_MAJOR}" GREATER "5" OR VTK_VERSION VERSION_GREATER 5) ) add_executable ( mesh_3D_gray_vtk_image mesh_3D_gray_vtk_image.cpp ) - target_link_libraries( mesh_3D_gray_vtk_image ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES} ${VTK_LIBS}) + target_link_libraries( mesh_3D_gray_vtk_image ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES} ${VTK_LIBRARIES}) + cgal_add_test( mesh_3D_gray_vtk_image ) endif() create_single_source_cgal_program( "mesh_3D_gray_image.cpp" ) diff --git a/Mesh_3/include/CGAL/IO/output_to_vtu.h b/Mesh_3/include/CGAL/IO/output_to_vtu.h index 4f8643825c1..96d048d97e8 100644 --- a/Mesh_3/include/CGAL/IO/output_to_vtu.h +++ b/Mesh_3/include/CGAL/IO/output_to_vtu.h @@ -283,7 +283,7 @@ typedef boost::variant*, const std::vector*, template void output_to_vtu_with_attributes(std::ostream& os, const C3T3& c3t3, - std::vector >&attributes, + std::vector >&attributes, IO::Mode mode = IO::BINARY) { //CGAL_assertion(attributes.size() == attribute_types.size()); @@ -372,7 +372,7 @@ void output_to_vtu(std::ostream& os, mids.push_back(v); } - std::vector > atts; + std::vector > atts; Vtu_attributes v = &mids; atts.push_back(std::make_pair("MeshDomain", v)); output_to_vtu_with_attributes(os, c3t3, atts, mode); diff --git a/Mesh_3/include/CGAL/Labeled_image_mesh_domain_3.h b/Mesh_3/include/CGAL/Labeled_image_mesh_domain_3.h index b2430d810ea..fe7e3b4147a 100644 --- a/Mesh_3/include/CGAL/Labeled_image_mesh_domain_3.h +++ b/Mesh_3/include/CGAL/Labeled_image_mesh_domain_3.h @@ -109,12 +109,12 @@ private: /// Returns a box enclosing image \c im Bbox_3 compute_bounding_box(const Image& im) const { - return Bbox_3(-im.vx(), - -im.vy(), - -im.vz(), - double(im.xdim()+1)*im.vx(), - double(im.ydim()+1)*im.vy(), - double(im.zdim()+1)*im.vz()); + return Bbox_3(-im.vx()+im.tx(), + -im.vy()+im.ty(), + -im.vz()+im.tz(), + double(im.xdim()+1)*im.vx()+im.tx(), + double(im.ydim()+1)*im.vy()+im.ty(), + double(im.zdim()+1)*im.vz()+im.tz()); } }; // end class Labeled_image_mesh_domain_3 diff --git a/Mesh_3/include/CGAL/Labeled_mesh_domain_3.h b/Mesh_3/include/CGAL/Labeled_mesh_domain_3.h index 782e62b648b..a61e84411c9 100644 --- a/Mesh_3/include/CGAL/Labeled_mesh_domain_3.h +++ b/Mesh_3/include/CGAL/Labeled_mesh_domain_3.h @@ -88,10 +88,10 @@ namespace internal { /// Returns a box enclosing image \c im inline Bbox_3 compute_bounding_box(const Image_3& im) { - return Bbox_3(-1,-1,-1, - double(im.xdim())*im.vx()+1, - double(im.ydim())*im.vy()+1, - double(im.zdim())*im.vz()+1); + return Bbox_3(-1+im.tx(),-1+im.ty(),-1+im.tz(), + double(im.xdim())*im.vx()+im.tx()+1, + double(im.ydim())*im.vy()+im.ty()+1, + double(im.zdim())*im.vz()+im.tz()+1); } template diff --git a/Mesh_3/include/CGAL/internal/Mesh_3/Handle_IO_for_pair_of_int.h b/Mesh_3/include/CGAL/internal/Mesh_3/Handle_IO_for_pair_of_int.h index 8eee712d970..604039ce667 100644 --- a/Mesh_3/include/CGAL/internal/Mesh_3/Handle_IO_for_pair_of_int.h +++ b/Mesh_3/include/CGAL/internal/Mesh_3/Handle_IO_for_pair_of_int.h @@ -41,13 +41,6 @@ struct Get_io_signature > { } }; // end Get_io_signature > -inline std::ostream& operator<<(std::ostream& out, const std::pair& id) { - return out << id.first << " " << id.second; -} -inline std::istream& operator>>(std::istream& in, std::pair& id) { - return in >> id.first >> id.second; -} - template <> class Output_rep > : public IO_rep_is_specialized { typedef std::pair T; diff --git a/Periodic_4_hyperbolic_triangulation_2/include/CGAL/Hyperbolic_octagon_translation.h b/Periodic_4_hyperbolic_triangulation_2/include/CGAL/Hyperbolic_octagon_translation.h index 36dde2fe321..c324efa94e5 100644 --- a/Periodic_4_hyperbolic_triangulation_2/include/CGAL/Hyperbolic_octagon_translation.h +++ b/Periodic_4_hyperbolic_triangulation_2/include/CGAL/Hyperbolic_octagon_translation.h @@ -59,15 +59,8 @@ private: Word _wrd; - - - static const Matrix& gmap(const std::string& s) - { - typedef std::map M; - CGAL_STATIC_THREAD_LOCAL_VARIABLE_0(M, m); - - if(m.empty()){ - + static auto initialize_gmap() { + std::map m; std::vector g; Matrix::generators(g); @@ -128,7 +121,30 @@ private: m["7"] = g[D]; m["72"] = g[D]*g[C]; m["725"] = g[D]*g[C]*g[B]; + + { // This block abuses `operator<<` of numbers, to a null stream. + // That ensures that the following memory pool are correctly + // initialized: + // - `CORE::MemoryPool` + // - `CORE::MemoryPool` + // - `CORE::MemoryPool` + // - `CORE::MemoryPool` + // otherwise, there is an assertion during the destruction of + // static (or `thread_local`) objects + struct NullBuffer : public std::streambuf { + int overflow(int c) { return c; } + }; + NullBuffer null_buffer; + std::ostream null_stream(&null_buffer); + for(auto& pair: m) null_stream << pair.second; } + return m; + } + + static const Matrix& gmap(const std::string& s) + { + typedef std::map M; + CGAL_STATIC_THREAD_LOCAL_VARIABLE(M, m, initialize_gmap()); return m[s]; } diff --git a/Point_set_3/doc/Point_set_3/PackageDescription.txt b/Point_set_3/doc/Point_set_3/PackageDescription.txt index 0ce7749a122..83cbc94046a 100644 --- a/Point_set_3/doc/Point_set_3/PackageDescription.txt +++ b/Point_set_3/doc/Point_set_3/PackageDescription.txt @@ -1,6 +1,16 @@ /// \defgroup PkgPointSet3Ref 3D Point Set Reference /*! + \code + #include + \endcode +*/ +/// \defgroup PkgDrawPointSet3D Draw a 3D Point Set +/// \ingroup PkgPointSet3Ref + +/*! +\addtogroup PkgPointSet3Ref + \cgalPkgDescriptionBegin{3D Point Set, PkgPointSet3} \cgalPkgPicture{point_set_3.png} \cgalPkgSummaryBegin @@ -21,6 +31,9 @@ \cgalCRPSection{Class} - `CGAL::Point_set_3` +\cgalCRPSection{Draw a 3D Point Set} +- \link PkgDrawPointSet3D CGAL::draw() \endlink + \defgroup PkgPointSet3IO Input/Output \ingroup PkgPointSet3Ref diff --git a/Point_set_3/doc/Point_set_3/Point_set_3.txt b/Point_set_3/doc/Point_set_3/Point_set_3.txt index 288d44d4911..2a765f352bf 100644 --- a/Point_set_3/doc/Point_set_3/Point_set_3.txt +++ b/Point_set_3/doc/Point_set_3/Point_set_3.txt @@ -163,6 +163,18 @@ overload provided for `CGAL::Point_set_3`: \cgalExample{Point_set_3/point_set_advanced.cpp} +\subsection Point_set_3_Draw Draw a Point Set + +A 3D point set can be visualized by calling the \link PkgDrawPointSet3D CGAL::draw() \endlink function as shown in the following example. This function opens a new window showing the given point set. A call to this function is blocking, that is the program continues as soon as the user closes the window. + +\cgalExample{Point_set_3/draw_point_set_3.cpp} + +This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time. + +\cgalFigureBegin{fig_draw_point_set,draw_point_set.png} +Result of the run of the draw_point_set_3 program. A window shows the 3D points and allows to navigate through the 3D scene. +\cgalFigureEnd + \section Point_set_3_History History This package has been created to fill the need for a practical data diff --git a/Point_set_3/doc/Point_set_3/examples.txt b/Point_set_3/doc/Point_set_3/examples.txt index 269700c266a..d8711deceed 100644 --- a/Point_set_3/doc/Point_set_3/examples.txt +++ b/Point_set_3/doc/Point_set_3/examples.txt @@ -5,4 +5,5 @@ \example Point_set_3/point_set_read_xyz.cpp \example Point_set_3/point_set_read_ply.cpp \example Point_set_3/point_set_advanced.cpp +\example Point_set_3/draw_point_set_3.cpp */ diff --git a/Point_set_3/doc/Point_set_3/fig/draw_point_set.png b/Point_set_3/doc/Point_set_3/fig/draw_point_set.png new file mode 100644 index 00000000000..21cec33e55d Binary files /dev/null and b/Point_set_3/doc/Point_set_3/fig/draw_point_set.png differ diff --git a/Point_set_3/examples/Point_set_3/CMakeLists.txt b/Point_set_3/examples/Point_set_3/CMakeLists.txt index 100e1919211..45172ef603d 100644 --- a/Point_set_3/examples/Point_set_3/CMakeLists.txt +++ b/Point_set_3/examples/Point_set_3/CMakeLists.txt @@ -7,7 +7,7 @@ project( Point_set_3_Examples ) # CGAL and its components -find_package( CGAL QUIET COMPONENTS ) +find_package( CGAL QUIET COMPONENTS Qt5 ) if ( NOT CGAL_FOUND ) @@ -16,6 +16,10 @@ if ( NOT CGAL_FOUND ) endif() +if(CGAL_Qt5_FOUND) + add_definitions(-DCGAL_USE_BASIC_VIEWER -DQT_NO_KEYWORDS) +endif() + # Boost and its components find_package( Boost REQUIRED ) @@ -50,5 +54,7 @@ else() create_single_source_cgal_program( "point_set_algo.cpp" ) endif() - - +create_single_source_cgal_program("draw_point_set_3.cpp" ) +if(CGAL_Qt5_FOUND) + target_link_libraries(draw_point_set_3 PUBLIC CGAL::CGAL_Qt5) +endif() diff --git a/Point_set_3/examples/Point_set_3/draw_point_set_3.cpp b/Point_set_3/examples/Point_set_3/draw_point_set_3.cpp new file mode 100644 index 00000000000..3e9cfae71b7 --- /dev/null +++ b/Point_set_3/examples/Point_set_3/draw_point_set_3.cpp @@ -0,0 +1,29 @@ +#include +#include +#include +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; +typedef Kernel::FT FT; +typedef Kernel::Point_3 Point; +typedef Kernel::Vector_3 Vector; +typedef CGAL::Point_set_3 Point_set; + +int main (int argc, char** argv) +{ + std::ifstream f (argc > 1 ? argv[1] : "data/oni.xyz"); + Point_set point_set; + + // Reading input in XYZ format + if (!f || !CGAL::read_xyz_point_set (f, point_set)) + { + std::cerr<<"Can't read input file " + <<(argc > 1 ? argv[1] : "data/oni.xyz")<< std::endl; + return EXIT_FAILURE; + } + + CGAL::draw(point_set); + + return EXIT_SUCCESS; +} diff --git a/Point_set_3/include/CGAL/draw_point_set_3.h b/Point_set_3/include/CGAL/draw_point_set_3.h new file mode 100644 index 00000000000..ca5d094b3a5 --- /dev/null +++ b/Point_set_3/include/CGAL/draw_point_set_3.h @@ -0,0 +1,127 @@ +// Copyright (c) 2016 GeometryFactory Sarl (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// 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. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0+ +// +// +// Author(s) : Guillaume Damiand + +#ifndef CGAL_DRAW_POINT_SET_3_H +#define CGAL_DRAW_POINT_SET_3_H + +#include +#include + +#ifdef DOXYGEN_RUNNING +namespace CGAL { + +/*! +\ingroup PkgDrawPointSet3D + +opens a new window and draws `aps`, an instance of the `CGAL::Point_set_3` class. A call to this function is blocking, that is the program continues as soon as the user closes the window. This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time. +\tparam PS an instance of the `CGAL::Point_set_3` class. +\param aps the point set to draw. + +*/ +template +void draw(const PS& aps); + +} /* namespace CGAL */ +#endif + +#ifdef CGAL_USE_BASIC_VIEWER + +#include +#include + +namespace CGAL +{ + +// Viewer class for Point_set +template +class SimplePointSetViewerQt : public Basic_viewer_qt +{ + typedef Basic_viewer_qt Base; + typedef typename PointSet::Point_map::value_type Point; + +public: + /// Construct the viewer. + /// @param apointset the point set to view + /// @param title the title of the window + SimplePointSetViewerQt(QWidget* parent, + const PointSet& apointset, const char* title="") : + // First draw: vertices; no-edge, no-face; mono-color; no inverse normal + Base(parent, title, true, false, false, true, false), + pointset(apointset) + { + compute_elements(); + } + +protected: + void compute_vertex(const Point& p) + { + add_point(p); + // We can use add_point(p, c) with c a CGAL::Color to add a colored point + } + + void compute_elements() + { + clear(); + + for (typename PointSet::const_iterator it=pointset.begin(); + it!=pointset.end(); ++it) + { compute_vertex(pointset.point(*it)); } + } + + virtual void keyPressEvent(QKeyEvent *e) + { + // const ::Qt::KeyboardModifiers modifiers = e->modifiers(); + Base::keyPressEvent(e); + } + +protected: + const PointSet& pointset; +}; + +// Specialization of draw function. +template +void draw(const Point_set_3& apointset, + const char* title="Point_set_3 Basic Viewer") +{ +#if defined(CGAL_TEST_SUITE) + bool cgal_test_suite=true; +#else + bool cgal_test_suite=qEnvironmentVariableIsSet("CGAL_TEST_SUITE"); +#endif + + if (!cgal_test_suite) + { + int argc=1; + const char* argv[2]={"point_set_viewer","\0"}; + QApplication app(argc,const_cast(argv)); + SimplePointSetViewerQt > mainwindow(app.activeWindow(), + apointset, + title); + mainwindow.show(); + app.exec(); + } +} + +} // End namespace CGAL + +#endif // CGAL_USE_BASIC_VIEWER + +#endif // CGAL_DRAW_POINT_SET_3_H diff --git a/Point_set_3/package_info/Point_set_3/dependencies b/Point_set_3/package_info/Point_set_3/dependencies index d5ec00a4fea..cab851ef527 100644 --- a/Point_set_3/package_info/Point_set_3/dependencies +++ b/Point_set_3/package_info/Point_set_3/dependencies @@ -1,5 +1,6 @@ Algebraic_foundations BGL +GraphicsView Installation Interval_support Kernel_23 diff --git a/Polygon/doc/Polygon/Doxyfile.in b/Polygon/doc/Polygon/Doxyfile.in index f4a3edd012e..8cfb32b528f 100644 --- a/Polygon/doc/Polygon/Doxyfile.in +++ b/Polygon/doc/Polygon/Doxyfile.in @@ -4,7 +4,6 @@ PROJECT_NAME = "CGAL ${CGAL_DOC_VERSION} - 2D Polygons" EXAMPLE_PATH = ${CGAL_PACKAGE_DIR}/examples \ ${CGAL_Stream_support_EXAMPLE_DIR} - EXTRACT_ALL = false HIDE_UNDOC_MEMBERS = true HIDE_UNDOC_CLASSES = true diff --git a/Polygon/doc/Polygon/PackageDescription.txt b/Polygon/doc/Polygon/PackageDescription.txt index e9867f1bb65..b5057669497 100644 --- a/Polygon/doc/Polygon/PackageDescription.txt +++ b/Polygon/doc/Polygon/PackageDescription.txt @@ -6,6 +6,22 @@ /// \defgroup PkgPolygon2Functions Global Functions /// \ingroup PkgPolygon2Ref +/*! + \code + #include + \endcode +*/ +/// \defgroup PkgDrawPolygon2 Draw a 2D Polygon +/// \ingroup PkgPolygon2Ref + +/*! + \code + #include + \endcode +*/ +/// \defgroup PkgDrawPolygonWithHoles2 Draw a 2D Polygon with Holes +/// \ingroup PkgPolygon2Ref + /*! \addtogroup PkgPolygon2Ref @@ -53,5 +69,11 @@ The assertion flags for the polygons and polygon operations use - `CGAL::right_vertex_2()` - `CGAL::top_vertex_2()` +\cgalCRPSection{Draw a Polygon_2} +- \link PkgDrawPolygon2 CGAL::draw

() \endlink + +\cgalCRPSection{Draw a Polygon_with_holes_2} +- \link PkgDrawPolygonWithHoles2 CGAL::draw() \endlink + */ diff --git a/Polygon/doc/Polygon/Polygon.txt b/Polygon/doc/Polygon/Polygon.txt index 279d24c457f..9b34746cee1 100644 --- a/Polygon/doc/Polygon/Polygon.txt +++ b/Polygon/doc/Polygon/Polygon.txt @@ -70,6 +70,18 @@ and 3D Linear Geometric %Kernel. \cgalExample{Polygon/projected_polygon.cpp} +\subsection subsecPolygonDraw Draw a Polygon + +A polygon can be visualized by calling the \link PkgDrawPolygon2 CGAL::draw

() \endlink function as shown in the following example. This function opens a new window showing the given polygon. A call to this function is blocking, that is the program continues as soon as the user closes the window (a version exists for polygon with holes, cf. \link PkgDrawPolygonWithHoles2 CGAL::draw() \endlink). + +\cgalExample{Polygon/draw_polygon.cpp} + +This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time. + +\cgalFigureBegin{fig_draw_polygon,draw_polygon.png} +Result of the run of the draw_polygon program. A window shows the polygon and allows to navigate through the scene. +\cgalFigureEnd + */ \section secPolygonWithHole Polygons with Holes diff --git a/Polygon/doc/Polygon/examples.txt b/Polygon/doc/Polygon/examples.txt index 0e102b3f83e..d176af36d0a 100644 --- a/Polygon/doc/Polygon/examples.txt +++ b/Polygon/doc/Polygon/examples.txt @@ -4,4 +4,6 @@ \example Polygon/Polygon.cpp \example Polygon/projected_polygon.cpp \example Stream_support/Polygon_WKT.cpp +\example Polygon/draw_polygon.cpp +\example Polygon/draw_polygon_with_holes.cpp */ diff --git a/Polygon/doc/Polygon/fig/draw_polygon.png b/Polygon/doc/Polygon/fig/draw_polygon.png new file mode 100644 index 00000000000..6da8e0ae0c9 Binary files /dev/null and b/Polygon/doc/Polygon/fig/draw_polygon.png differ diff --git a/Polygon/examples/Polygon/CMakeLists.txt b/Polygon/examples/Polygon/CMakeLists.txt index fbd4cbe65e2..eebdf3979e0 100644 --- a/Polygon/examples/Polygon/CMakeLists.txt +++ b/Polygon/examples/Polygon/CMakeLists.txt @@ -6,7 +6,11 @@ cmake_minimum_required(VERSION 3.1...3.15) project( Polygon_Examples ) -find_package(CGAL QUIET) +find_package(CGAL QUIET COMPONENTS Qt5) + +if(CGAL_Qt5_FOUND) + add_definitions(-DCGAL_USE_BASIC_VIEWER -DQT_NO_KEYWORDS) +endif() if ( CGAL_FOUND ) @@ -16,6 +20,11 @@ if ( CGAL_FOUND ) create_single_source_cgal_program( "${cppfile}" ) endforeach() + if(CGAL_Qt5_FOUND) + target_link_libraries(draw_polygon PUBLIC CGAL::CGAL_Qt5) + target_link_libraries(draw_polygon_with_holes PUBLIC CGAL::CGAL_Qt5) + endif() + else() message(STATUS "This program requires the CGAL library, and will not be compiled.") diff --git a/Polygon/examples/Polygon/draw_polygon.cpp b/Polygon/examples/Polygon/draw_polygon.cpp new file mode 100644 index 00000000000..072e41387e3 --- /dev/null +++ b/Polygon/examples/Polygon/draw_polygon.cpp @@ -0,0 +1,22 @@ +#include +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef CGAL::Polygon_2 Polygon_2; +typedef CGAL::Point_2 Point; + +int main() +{ + // create a polygon and put some points in it + Polygon_2 p; + p.push_back(Point(0,0)); + p.push_back(Point(4,0)); + p.push_back(Point(4,4)); + p.push_back(Point(2,2)); + p.push_back(Point(0,4)); + + CGAL::draw(p); + + return EXIT_SUCCESS; +} diff --git a/Polygon/examples/Polygon/draw_polygon_with_holes.cpp b/Polygon/examples/Polygon/draw_polygon_with_holes.cpp new file mode 100644 index 00000000000..b2a551b7f12 --- /dev/null +++ b/Polygon/examples/Polygon/draw_polygon_with_holes.cpp @@ -0,0 +1,37 @@ +#include +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef CGAL::Polygon_with_holes_2 Polygon_with_holes_2; +typedef CGAL::Polygon_2 Polygon_2; +typedef CGAL::Point_2 Point; + +int main() +{ + // create a polygon with three holes + Polygon_2 outer_polygon; + outer_polygon.push_back(Point(0,0)); outer_polygon.push_back(Point(9,0)); + outer_polygon.push_back(Point(6,8)); outer_polygon.push_back(Point(5,3)); + outer_polygon.push_back(Point(2,8)); outer_polygon.push_back(Point(0,8)); + + std::vector holes(3); + holes[0].push_back(Point(6,2)); holes[0].push_back(Point(7,1)); + holes[0].push_back(Point(7,3)); holes[0].push_back(Point(6,3)); + holes[0].push_back(Point(5,2)); + + holes[1].push_back(Point(2,1)); holes[1].push_back(Point(3,1)); + holes[1].push_back(Point(3,3)); holes[1].push_back(Point(2,2)); + holes[1].push_back(Point(1,2)); + + holes[2].push_back(Point(1,4)); holes[2].push_back(Point(2,4)); + holes[2].push_back(Point(2,5)); holes[2].push_back(Point(3,5)); + holes[2].push_back(Point(3,6)); holes[2].push_back(Point(1,6)); + + Polygon_with_holes_2 p(outer_polygon, holes.begin(), holes.end()); + + // And draw it. + CGAL::draw(p); + + return EXIT_SUCCESS; +} diff --git a/Polygon/include/CGAL/draw_polygon_2.h b/Polygon/include/CGAL/draw_polygon_2.h new file mode 100644 index 00000000000..8b7bdd296a6 --- /dev/null +++ b/Polygon/include/CGAL/draw_polygon_2.h @@ -0,0 +1,148 @@ +// Copyright (c) 1997 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0+ +// +// +// Author(s) : Guillaume Damiand + +#ifndef CGAL_DRAW_POLYGON_2_H +#define CGAL_DRAW_POLYGON_2_H + +#include + +#ifdef DOXYGEN_RUNNING +namespace CGAL { + +/*! +\ingroup PkgDrawPolygon2 + +opens a new window and draws `ap`, an instance of the `CGAL::Polygon_2` class. A call to this function is blocking, that is the program continues as soon as the user closes the window. This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time. +\tparam P an instance of the `CGAL::Polygon_2` class. +\param ap the polygon to draw. + +*/ +template +void draw(const P& ap); + +} /* namespace CGAL */ + +#endif + +#ifdef CGAL_USE_BASIC_VIEWER + +#include +#include + +namespace CGAL +{ + +// Viewer class for Polygon_2 +template +class SimplePolygon2ViewerQt : public Basic_viewer_qt +{ + typedef Basic_viewer_qt Base; + typedef typename P2::Point_2 Point; + +public: + /// Construct the viewer. + /// @param ap2 the polygon to view + /// @param title the title of the window + SimplePolygon2ViewerQt(QWidget* parent, const P2& ap2, + const char* title="Basic Polygon_2 Viewer") : + // First draw: vertices; edges, faces; multi-color; no inverse normal + Base(parent, title, true, true, true, false, false), + p2(ap2) + { + compute_elements(); + } + +protected: + void compute_elements() + { + clear(); + + if (p2.is_empty()) return; + + Point prev=p2.vertex(p2.size()-1); + + CGAL::Color c(75,160,255); + face_begin(c); + + for (typename P2::Vertex_const_iterator i=p2.vertices_begin(); + i!=p2.vertices_end(); ++i) + { + add_point(*i); // Add vertex + add_segment(prev, *i); // Add segment with previous point + add_point_in_face(*i); // Add point in face + prev=*i; + } + + face_end(); + } + + virtual void keyPressEvent(QKeyEvent *e) + { + // Test key pressed: + // const ::Qt::KeyboardModifiers modifiers = e->modifiers(); + // if ((e->key()==Qt::Key_PageUp) && (modifiers==Qt::NoButton)) { ... } + + // Call: * compute_elements() if the model changed, followed by + // * redraw() if some viewing parameters changed that implies some + // modifications of the buffers + // (eg. type of normal, color/mono) + // * update() just to update the drawing + + // Call the base method to process others/classicals key + Base::keyPressEvent(e); + } + +protected: + const P2& p2; +}; + +// Specialization of draw function. +template +void draw(const CGAL::Polygon_2& ap2, + const char* title="Polygon_2 Basic Viewer") +{ +#if defined(CGAL_TEST_SUITE) + bool cgal_test_suite=true; +#else + bool cgal_test_suite=qEnvironmentVariableIsSet("CGAL_TEST_SUITE"); +#endif + + if (!cgal_test_suite) + { + int argc=1; + const char* argv[2]={"t2_viewer","\0"}; + QApplication app(argc,const_cast(argv)); + SimplePolygon2ViewerQt > + mainwindow(app.activeWindow(), ap2, title); + mainwindow.show(); + app.exec(); + } +} + +} // End namespace CGAL + +#endif // CGAL_USE_BASIC_VIEWER + +#endif // CGAL_DRAW_POLYGON_2_H diff --git a/Polygon/include/CGAL/draw_polygon_with_holes_2.h b/Polygon/include/CGAL/draw_polygon_with_holes_2.h new file mode 100644 index 00000000000..33806eb1b38 --- /dev/null +++ b/Polygon/include/CGAL/draw_polygon_with_holes_2.h @@ -0,0 +1,164 @@ +// Copyright (c) 1997 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0+ +// +// +// Author(s) : Guillaume Damiand + +#ifndef CGAL_DRAW_POLYGON_WITH_HOLES_2_H +#define CGAL_DRAW_POLYGON_WITH_HOLES_2_H + +#include + +#ifdef DOXYGEN_RUNNING +namespace CGAL { + +/*! +\ingroup PkgDrawPolygonWithHoles2 + +opens a new window and draws `aph`, an instance of the `CGAL::Polygon_with_holes_2` class. A call to this function is blocking, that is the program continues as soon as the user closes the window. This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time. +\tparam PH an instance of the `CGAL::Polygon_with_holes_2` class. +\param aph the polygon with holes to draw. + +*/ +template +void draw(const PH& aph); + +} /* namespace CGAL */ +#endif + +#ifdef CGAL_USE_BASIC_VIEWER + +#include +#include + +namespace CGAL +{ + +// Viewer class for Polygon_2 +template +class SimplePolygonWithHoles2ViewerQt : public Basic_viewer_qt +{ + typedef Basic_viewer_qt Base; + typedef typename P2::General_polygon_2::Point_2 Point; + +public: + /// Construct the viewer. + /// @param ap2 the polygon to view + /// @param title the title of the window + SimplePolygonWithHoles2ViewerQt(QWidget* parent, const P2& ap2, + const char* title="Basic Polygon_with_holes_2 Viewer") : + // First draw: vertices; edges, faces; multi-color; no inverse normal + Base(parent, title, true, true, true, false, false), + p2(ap2) + { + compute_elements(); + } + +protected: + void compute_one_loop_elements(const typename P2::General_polygon_2& p, bool hole) + { + if (hole) + { add_point_in_face(p.vertex(p.size()-1)); } + + typename P2::General_polygon_2::Vertex_const_iterator prev; + for (typename P2::General_polygon_2::Vertex_const_iterator i=p.vertices_begin(); + i!=p.vertices_end(); ++i) + { + add_point(*i); // Add vertex + if (i!=p.vertices_begin()) + { add_segment(*prev, *i); } // Add segment with previous point + add_point_in_face(*i); // Add point in face + prev=i; + } + + // Add the last segment between the last point and the first one + add_segment(*prev, *(p.vertices_begin())); + } + + void compute_elements() + { + clear(); + + if (p2.outer_boundary().is_empty()) return; + + CGAL::Color c(75,160,255); + face_begin(c); + + compute_one_loop_elements(p2.outer_boundary(), false); + + for (typename P2::Hole_const_iterator it=p2.holes_begin(); it!=p2.holes_end(); ++it) + { + compute_one_loop_elements(*it, true); + add_point_in_face(p2.outer_boundary().vertex(p2.outer_boundary().size()-1)); + } + + face_end(); + } + + virtual void keyPressEvent(QKeyEvent *e) + { + // Test key pressed: + // const ::Qt::KeyboardModifiers modifiers = e->modifiers(); + // if ((e->key()==Qt::Key_PageUp) && (modifiers==Qt::NoButton)) { ... } + + // Call: * compute_elements() if the model changed, followed by + // * redraw() if some viewing parameters changed that implies some + // modifications of the buffers + // (eg. type of normal, color/mono) + // * update() just to update the drawing + + // Call the base method to process others/classicals key + Base::keyPressEvent(e); + } + +protected: + const P2& p2; +}; + +// Specialization of draw function. +template +void draw(const CGAL::Polygon_with_holes_2& ap2, + const char* title="Polygon_with_holes_2 Basic Viewer") +{ +#if defined(CGAL_TEST_SUITE) + bool cgal_test_suite=true; +#else + bool cgal_test_suite=qEnvironmentVariableIsSet("CGAL_TEST_SUITE"); +#endif + + if (!cgal_test_suite) + { + int argc=1; + const char* argv[2]={"t2_viewer","\0"}; + QApplication app(argc,const_cast(argv)); + SimplePolygonWithHoles2ViewerQt > + mainwindow(app.activeWindow(), ap2, title); + mainwindow.show(); + app.exec(); + } +} + +} // End namespace CGAL + +#endif // CGAL_USE_BASIC_VIEWER + +#endif // CGAL_DRAW_POLYGON_WITH_HOLES_2_H diff --git a/Polygon/package_info/Polygon/dependencies b/Polygon/package_info/Polygon/dependencies index ad435cca369..3312eb37e46 100644 --- a/Polygon/package_info/Polygon/dependencies +++ b/Polygon/package_info/Polygon/dependencies @@ -1,5 +1,6 @@ Algebraic_foundations Circulator +GraphicsView Installation Kernel_23 Number_types diff --git a/Polyhedron/demo/Polyhedron/CMakeLists.txt b/Polyhedron/demo/Polyhedron/CMakeLists.txt index d1c810bba9c..313305843f9 100644 --- a/Polyhedron/demo/Polyhedron/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/CMakeLists.txt @@ -362,6 +362,11 @@ add_executable ( CGAL_Classification Classification.cpp ) add_dependencies(CGAL_Classification Classification) target_link_libraries( CGAL_Classification PRIVATE polyhedron_demo ) add_to_cached_list( CGAL_EXECUTABLE_TARGETS CGAL_Classification ) + +add_executable ( CGAL_PMP PMP.cpp ) +add_dependencies(CGAL_PMP PMP) +target_link_libraries( CGAL_PMP PRIVATE polyhedron_demo ) +add_to_cached_list( CGAL_EXECUTABLE_TARGETS CGAL_PMP ) # # Exporting # diff --git a/Polyhedron/demo/Polyhedron/Classification.cpp b/Polyhedron/demo/Polyhedron/Classification.cpp index acbb39eb536..aaa7d30116d 100644 --- a/Polyhedron/demo/Polyhedron/Classification.cpp +++ b/Polyhedron/demo/Polyhedron/Classification.cpp @@ -10,20 +10,9 @@ */ int main(int argc, char **argv) { - QSurfaceFormat fmt; - - fmt.setVersion(4, 3); - fmt.setRenderableType(QSurfaceFormat::OpenGL); - fmt.setProfile(QSurfaceFormat::CoreProfile); - fmt.setOption(QSurfaceFormat::DebugContext); - QSurfaceFormat::setDefaultFormat(fmt); - QStringList keywords; - keywords << "Classification"; - Polyhedron_demo app(argc, argv, + Polyhedron_demo app(argc, argv, "Classification demo", "CGAL Classification Demo", - keywords); - //We set the locale to avoid any trouble with VTK - std::setlocale(LC_ALL, "C"); + QStringList() << "Classification"); return app.try_exec(); } diff --git a/Polyhedron/demo/Polyhedron/MainWindow.cpp b/Polyhedron/demo/Polyhedron/MainWindow.cpp index 4fa880e9043..7df998e4964 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.cpp +++ b/Polyhedron/demo/Polyhedron/MainWindow.cpp @@ -383,14 +383,38 @@ MainWindow::MainWindow(const QStringList &keywords, bool verbose, QWidget* paren connect(ui->menuOperations, SIGNAL(aboutToShow()), this, SLOT(filterOperations())); } +void addActionToMenu(QAction* action, QMenu* menu) +{ + bool added = false; + for(QAction* it : menu->actions()) + { + QString atxt = action->text().remove("&"), + btxt = it->text().remove("&"); + int i = 0; + while(atxt[i] == btxt[i] + && i < atxt.size() + && i < btxt.size()) + ++i; + bool res = (atxt[i] < btxt[i]); + if (res) + { + menu->insertAction(it, action); + added = true; + break; + } + } + if(!added) + menu->addAction(action); +} + //Recursive function that do a pass over a menu and its sub-menus(etc.) and hide them when they are empty void filterMenuOperations(QMenu* menu, QString filter, bool keep_from_here) { QList buffer; Q_FOREACH(QAction* action, menu->actions()) buffer.append(action); + while(!buffer.isEmpty()){ - Q_FOREACH(QAction* action, buffer) { if(QMenu* submenu = action->menu()) { @@ -407,14 +431,17 @@ void filterMenuOperations(QMenu* menu, QString filter, bool keep_from_here) } else { - menu->addAction(submenu->menuAction()); + //menu->addAction(submenu->menuAction()); + addActionToMenu(submenu->menuAction(), menu); } } filterMenuOperations(submenu, filter, keep); action->setVisible(!(submenu->isEmpty())); + } else if(action->text().contains(filter, Qt::CaseInsensitive)){ - menu->addAction(action); + //menu->addAction(action); + addActionToMenu(action, menu); } buffer.removeAll(action); } @@ -432,14 +459,17 @@ void MainWindow::filterOperations() menu->removeAction(action); } } + Q_FOREACH(QAction* action, action_menu_map.keys()) { - action_menu_map[action]->addAction(action); + QMenu* menu = action_menu_map[action]; + addActionToMenu(action, menu); } + QString filter=operationSearchBar.text(); Q_FOREACH(const PluginNamePair& p, plugins) { Q_FOREACH(QAction* action, p.first->actions()) { - action->setVisible( p.first->applicable(action) + action->setVisible( p.first->applicable(action) && (action->text().contains(filter, Qt::CaseInsensitive) || action->property("subMenuName") .toString().contains(filter, Qt::CaseInsensitive))); @@ -447,6 +477,7 @@ void MainWindow::filterOperations() } // do a pass over all menus in Operations and their sub-menus(etc.) and hide them when they are empty filterMenuOperations(ui->menuOperations, filter, false); + operationSearchBar.setFocus(); } diff --git a/Polyhedron/demo/Polyhedron/Mesh_3.cpp b/Polyhedron/demo/Polyhedron/Mesh_3.cpp index 10070f21a59..e29026b1ade 100644 --- a/Polyhedron/demo/Polyhedron/Mesh_3.cpp +++ b/Polyhedron/demo/Polyhedron/Mesh_3.cpp @@ -10,20 +10,9 @@ */ int main(int argc, char **argv) { - QSurfaceFormat fmt; - - fmt.setVersion(4, 3); - fmt.setRenderableType(QSurfaceFormat::OpenGL); - fmt.setProfile(QSurfaceFormat::CoreProfile); - fmt.setOption(QSurfaceFormat::DebugContext); - QSurfaceFormat::setDefaultFormat(fmt); - QStringList keywords; - keywords << "Mesh_3"; - Polyhedron_demo app(argc, argv, + Polyhedron_demo app(argc, argv, "Mesh_3 demo", "CGAL Mesh_3 Demo", - keywords); - //We set the locale to avoid any trouble with VTK - std::setlocale(LC_ALL, "C"); + QStringList() << "Mesh_3"); return app.try_exec(); } diff --git a/Polyhedron/demo/Polyhedron/PMP.cpp b/Polyhedron/demo/Polyhedron/PMP.cpp new file mode 100644 index 00000000000..469ff93b27d --- /dev/null +++ b/Polyhedron/demo/Polyhedron/PMP.cpp @@ -0,0 +1,29 @@ +#include "Polyhedron_demo.h" +#include +#include +#include + + +/*! + * \brief Defines the entry point of the demo. + * Creates the application and sets a main window. + */ +int main(int argc, char **argv) +{ + QSurfaceFormat fmt; + + fmt.setVersion(4, 3); + fmt.setRenderableType(QSurfaceFormat::OpenGL); + fmt.setProfile(QSurfaceFormat::CoreProfile); + fmt.setOption(QSurfaceFormat::DebugContext); + QSurfaceFormat::setDefaultFormat(fmt); + QStringList keywords; + keywords << "PMP"; + Polyhedron_demo app(argc, argv, + "PMP demo", + "CGAL Polygon Mesh Processing Demo", + keywords); + //We set the locale to avoid any trouble with VTK + std::setlocale(LC_ALL, "C"); + return app.try_exec(); +} diff --git a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp index 2619db2aca5..ca66b7ce18a 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp @@ -1073,7 +1073,7 @@ void Polyhedron_demo_cut_plugin::apply(Item* item, QMap< QObject*, Facets_tree*> traits.set_shared_data(mesh, pmap); //Mandatory for SMesh. If not provided, mesh and PPmap are taken default, saying NULL in tree.traversal(). connect(item, SIGNAL(item_is_about_to_be_changed()), this, SLOT(deleteTree())); - f_trees[item] = new Facets_tree(traits); + Facets_tree* new_tree = new Facets_tree(traits); //filter facets to ignore degenerated ones for(typename boost::graph_traits::face_iterator fit = faces(mesh).first, @@ -1085,10 +1085,10 @@ void Polyhedron_demo_cut_plugin::apply(Item* item, QMap< QObject*, Facets_tree*> c(get(pmap, target(prev(halfedge(*fit, mesh), mesh), mesh))); if(!CGAL::collinear(a,b,c)) - f_trees[item]->insert(typename Facets_tree::Primitive(fit, mesh, pmap)); + new_tree->insert(typename Facets_tree::Primitive(fit, mesh, pmap)); } - - Scene_aabb_item* aabb_item = new Scene_aabb_item(*f_trees[item]); + Scene_aabb_item* aabb_item = new Scene_aabb_item(*new_tree); + f_trees[item] = new_tree; aabb_item->setName(tr("AABB tree of %1").arg(item->name())); aabb_item->setRenderingMode(Wireframe); aabb_item->setColor(Qt::black); diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt b/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt index 809ff9f9ada..616414c3f4d 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt @@ -10,7 +10,7 @@ target_link_libraries(io_implicit_function_plugin PUBLIC scene_implicit_function polyhedron_demo_plugin(nef_io_plugin Nef_io_plugin KEYWORDS IO) target_link_libraries(nef_io_plugin PUBLIC scene_nef_polyhedron_item) -polyhedron_demo_plugin(off_plugin OFF_io_plugin KEYWORDS IO Mesh_3 PointSetProcessing Classification) +polyhedron_demo_plugin(off_plugin OFF_io_plugin KEYWORDS IO Mesh_3 PointSetProcessing Classification PMP) target_link_libraries(off_plugin PUBLIC scene_polygon_soup_item scene_points_with_normal_item scene_surface_mesh_item) polyhedron_demo_plugin(off_to_nef_plugin OFF_to_nef_io_plugin KEYWORDS IO) @@ -19,11 +19,11 @@ target_link_libraries(off_to_nef_plugin PUBLIC scene_nef_polyhedron_item) polyhedron_demo_plugin(polylines_io_plugin Polylines_io_plugin KEYWORDS IO Mesh_3) target_link_libraries(polylines_io_plugin PUBLIC scene_polylines_item) -polyhedron_demo_plugin(stl_plugin STL_io_plugin KEYWORDS IO) +polyhedron_demo_plugin(stl_plugin STL_io_plugin KEYWORDS IO PMP) target_link_libraries(stl_plugin PUBLIC scene_surface_mesh_item scene_polygon_soup_item) -polyhedron_demo_plugin(surf_io_plugin Surf_io_plugin KEYWORDS IO) +polyhedron_demo_plugin(surf_io_plugin Surf_io_plugin KEYWORDS IO PMP) target_link_libraries(surf_io_plugin PUBLIC scene_surface_mesh_item) polyhedron_demo_plugin(lcc_io_plugin lcc_io_plugin KEYWORDS IO) @@ -33,13 +33,17 @@ target_link_libraries(lcc_io_plugin PUBLIC scene_lcc_item) find_package(VTK QUIET COMPONENTS vtkCommonCore vtkIOCore vtkIOLegacy vtkIOXML vtkFiltersCore vtkFiltersSources) if (VTK_FOUND) - include(${VTK_USE_FILE}) - if ("${VTK_VERSION_MAJOR}" GREATER "5") + if(VTK_USE_FILE) + include(${VTK_USE_FILE}) + endif() + if ("${VTK_VERSION_MAJOR}" GREATER "5" OR VTK_VERSION VERSION_GREATER 5) + if(TARGET VTK::CommonCore) + set(VTK_LIBRARIES VTK::CommonCore VTK::IOCore VTK::IOLegacy VTK::IOXML VTK::FiltersCore VTK::FiltersSources) + endif() if(VTK_LIBRARIES) polyhedron_demo_plugin(vtk_plugin VTK_io_plugin KEYWORDS IO Mesh_3) target_link_libraries(vtk_plugin PUBLIC scene_surface_mesh_item scene_polylines_item scene_c3t3_item scene_points_with_normal_item - vtkCommonCore vtkIOCore vtkIOLegacy vtkIOXML - vtkFiltersCore vtkFiltersSources) + ${VTK_LIBRARIES}) else() message(STATUS "NOTICE : the vtk IO plugin needs VTK libraries and will not be compiled.") @@ -61,7 +65,7 @@ if(has_cxx_rvalues LESS 0 OR has_cxx_variadic LESS 0) else() set(needed_cxx_features cxx_rvalue_references cxx_variadic_templates) - polyhedron_demo_plugin(ply_plugin PLY_io_plugin KEYWORDS IO PointSetProcessing Classification) + polyhedron_demo_plugin(ply_plugin PLY_io_plugin KEYWORDS IO PointSetProcessing Classification PMP) target_link_libraries(ply_plugin PUBLIC scene_points_with_normal_item scene_polygon_soup_item scene_surface_mesh_item scene_textured_item) target_compile_features(ply_plugin PRIVATE ${needed_cxx_features}) @@ -82,7 +86,7 @@ find_library(3MF_LIBRARIES NAMES 3MF DOC "Path to the lib3MF library") if(3MF_LIBRARIES AND 3MF_INCLUDE_DIR) include_directories(${3MF_INCLUDE_DIR}) - polyhedron_demo_plugin(3mf_io_plugin 3mf_io_plugin KEYWORDS IO) + polyhedron_demo_plugin(3mf_io_plugin 3mf_io_plugin KEYWORDS IO PMP) target_link_libraries(3mf_io_plugin PRIVATE scene_surface_mesh_item scene_points_with_normal_item scene_polylines_item ${3MF_LIBRARIES}) else() message(STATUS "NOTICE : The 3mf_io_plugin requires the lib3MF library, and will not be compiled.") diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/CMakeLists.txt b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/CMakeLists.txt index 96575090599..9db4d61b2e1 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/CMakeLists.txt @@ -11,15 +11,18 @@ polyhedron_demo_plugin(mesh_3_plugin Mesh_3_plugin target_link_libraries(mesh_3_plugin PUBLIC scene_polygon_soup_item scene_polylines_item scene_implicit_function_item scene_image_item scene_surface_mesh_item scene_c3t3_item ${OPENGL_gl_LIBRARY} ) -set(VTK_LIBS "") find_package(VTK QUIET COMPONENTS vtkImagingGeneral vtkIOImage NO_MODULE) if (VTK_FOUND) - include(${VTK_USE_FILE}) - if ("${VTK_VERSION_MAJOR}" GREATER "5") + if(VTK_USE_FILE) + include(${VTK_USE_FILE}) + endif() + if ("${VTK_VERSION_MAJOR}" GREATER "5" OR VTK_VERSION VERSION_GREATER 5) + if(TARGET VTK::IOImage) + set(VTK_LIBRARIES VTK::IOImage) + endif() if(VTK_LIBRARIES) add_definitions(-DCGAL_USE_VTK) - set(VTK_LIBS vtkImagingGeneral vtkIOImage) else() message(STATUS "NOTICE : the DICOM files (.dcm) need VTK libraries to be open and will not be able to.") endif() @@ -34,7 +37,7 @@ find_package(Boost QUIET OPTIONAL_COMPONENTS filesystem) if(Boost_FILESYSTEM_FOUND) qt5_wrap_ui( imgUI_FILES Image_res_dialog.ui raw_image.ui) polyhedron_demo_plugin(io_image_plugin Io_image_plugin Volume_plane_intersection.cpp Raw_image_dialog.cpp ${imgUI_FILES} ${VOLUME_MOC_OUTFILES} KEYWORDS IO Mesh_3) - target_link_libraries(io_image_plugin PUBLIC scene_image_item ${VTK_LIBS} CGAL::CGAL_ImageIO) + target_link_libraries(io_image_plugin PUBLIC scene_image_item ${VTK_LIBRARIES} CGAL::CGAL_ImageIO) if(TARGET Boost::filesystem) target_link_libraries(io_image_plugin PUBLIC Boost::filesystem) else() diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp index 804beed5389..7b3324cc49d 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp @@ -462,7 +462,9 @@ void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults) if (!sm_items.empty()) { QList polyhedrons; - sm_items.removeAll(bounding_sm_item); + if(!surface_only) { + sm_items.removeAll(bounding_sm_item); + } std::transform(sm_items.begin(), sm_items.end(), std::back_inserter(polyhedrons), [](Scene_surface_mesh_item* item) { diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Basic_generator_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PCA/Basic_generator_plugin.cpp index 9cbb92e4c73..269eb121ae4 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/Basic_generator_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Basic_generator_plugin.cpp @@ -113,7 +113,7 @@ public : { menu->addAction(action); } - dock_widget = new GeneratorWidget("Basic Objets", mw); + dock_widget = new GeneratorWidget("Basic Objects", mw); dock_widget->setVisible(false); // do not show at the beginning addDockWidget(dock_widget); connect(dock_widget->generateButton, &QAbstractButton::clicked, diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/CMakeLists.txt b/Polyhedron/demo/Polyhedron/Plugins/PMP/CMakeLists.txt index b210579ec7c..669b8e85ce1 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/CMakeLists.txt @@ -12,14 +12,14 @@ if(EIGEN3_FOUND) if("${EIGEN3_VERSION}" VERSION_GREATER "3.1.90") qt5_wrap_ui( hole_fillingUI_FILES Hole_filling_widget.ui) - polyhedron_demo_plugin(hole_filling_plugin Hole_filling_plugin ${hole_fillingUI_FILES}) + polyhedron_demo_plugin(hole_filling_plugin Hole_filling_plugin ${hole_fillingUI_FILES} KEYWORDS PMP) target_link_libraries(hole_filling_plugin PUBLIC scene_surface_mesh_item scene_polylines_item scene_selection_item) qt5_wrap_ui( fairingUI_FILES Fairing_widget.ui) - polyhedron_demo_plugin(fairing_plugin Fairing_plugin ${fairingUI_FILES}) + polyhedron_demo_plugin(fairing_plugin Fairing_plugin ${fairingUI_FILES} KEYWORDS PMP) target_link_libraries(fairing_plugin PUBLIC scene_selection_item) - polyhedron_demo_plugin(hole_filling_polyline_plugin Hole_filling_polyline_plugin) + polyhedron_demo_plugin(hole_filling_polyline_plugin Hole_filling_polyline_plugin ) target_link_libraries(hole_filling_polyline_plugin PUBLIC scene_surface_mesh_item scene_polylines_item) qt5_wrap_ui( Mean_curvature_flow_skeleton_pluginUI_FILES Mean_curvature_flow_skeleton_plugin.ui) @@ -40,13 +40,14 @@ else(EIGEN3_FOUND) endif() qt5_wrap_ui( soupUI_FILES Repair_soup.ui ) -polyhedron_demo_plugin(orient_soup_plugin Orient_soup_plugin ${soupUI_FILES} KEYWORDS Classification ) +polyhedron_demo_plugin(orient_soup_plugin Orient_soup_plugin ${soupUI_FILES} KEYWORDS Classification PMP) target_link_libraries(orient_soup_plugin PUBLIC scene_polygon_soup_item scene_surface_mesh_item scene_polylines_item scene_points_with_normal_item) -polyhedron_demo_plugin(inside_out_plugin Inside_out_plugin) + +polyhedron_demo_plugin(inside_out_plugin Inside_out_plugin KEYWORDS PMP) target_link_libraries(inside_out_plugin PUBLIC scene_surface_mesh_item scene_polygon_soup_item) -polyhedron_demo_plugin(join_and_split_plugin Join_and_split_polyhedra_plugin) +polyhedron_demo_plugin(join_and_split_plugin Join_and_split_polyhedra_plugin KEYWORDS PMP) target_link_libraries(join_and_split_plugin PUBLIC scene_surface_mesh_item scene_selection_item) qt5_wrap_ui( point_inside_polyhedronUI_FILES Point_inside_polyhedron_widget.ui) @@ -57,57 +58,59 @@ qt5_wrap_ui( polyhedron_slicerUI_FILES Polyhedron_slicer_widget.ui) polyhedron_demo_plugin(polyhedron_slicer_plugin Polyhedron_slicer_plugin ${polyhedron_slicerUI_FILES}) target_link_libraries(polyhedron_slicer_plugin PUBLIC scene_surface_mesh_item scene_basic_objects scene_polylines_item) -polyhedron_demo_plugin(polyhedron_stitching_plugin Polyhedron_stitching_plugin) +polyhedron_demo_plugin(polyhedron_stitching_plugin Polyhedron_stitching_plugin KEYWORDS PMP) target_link_libraries(polyhedron_stitching_plugin PUBLIC scene_surface_mesh_item scene_polylines_item) qt5_wrap_ui( selectionUI_FILES Selection_widget.ui) -polyhedron_demo_plugin(selection_plugin Selection_plugin ${selectionUI_FILES} KEYWORDS PolygonMesh IO Classification Mesh_3) +polyhedron_demo_plugin(selection_plugin Selection_plugin ${selectionUI_FILES} KEYWORDS PMP IO Classification Mesh_3) target_link_libraries(selection_plugin PUBLIC scene_selection_item scene_points_with_normal_item scene_polylines_item) -polyhedron_demo_plugin(self_intersection_plugin Self_intersection_plugin) -target_link_libraries(self_intersection_plugin PUBLIC scene_selection_item scene_surface_mesh_item) +#to keep it simple to compile +add_custom_target(self_intersection_plugin ) +add_dependencies(self_intersection_plugin selection_plugin) -polyhedron_demo_plugin(triangulate_facets_plugin Triangulate_facets_plugin) +polyhedron_demo_plugin(triangulate_facets_plugin Triangulate_facets_plugin KEYWORDS PMP) target_link_libraries(triangulate_facets_plugin PUBLIC scene_surface_mesh_item) -polyhedron_demo_plugin(corefinement_plugin Corefinement_plugin) +polyhedron_demo_plugin(corefinement_plugin Corefinement_plugin KEYWORDS PMP) target_link_libraries(corefinement_plugin PUBLIC scene_surface_mesh_item) -polyhedron_demo_plugin(surface_intersection_plugin Surface_intersection_plugin) +polyhedron_demo_plugin(surface_intersection_plugin Surface_intersection_plugin KEYWORDS PMP) target_link_libraries(surface_intersection_plugin PUBLIC scene_surface_mesh_item scene_polylines_item scene_points_with_normal_item) -polyhedron_demo_plugin(repair_polyhedron_plugin Repair_polyhedron_plugin) +polyhedron_demo_plugin(repair_polyhedron_plugin Repair_polyhedron_plugin KEYWORDS PMP) target_link_libraries(repair_polyhedron_plugin PUBLIC scene_surface_mesh_item) qt5_wrap_ui( isotropicRemeshingUI_FILES Isotropic_remeshing_dialog.ui) -polyhedron_demo_plugin(isotropic_remeshing_plugin Isotropic_remeshing_plugin ${isotropicRemeshingUI_FILES}) +polyhedron_demo_plugin(isotropic_remeshing_plugin Isotropic_remeshing_plugin ${isotropicRemeshingUI_FILES} KEYWORDS PMP) target_link_libraries(isotropic_remeshing_plugin PUBLIC scene_surface_mesh_item scene_selection_item) if(TBB_FOUND) CGAL_target_use_TBB(isotropic_remeshing_plugin) endif() -polyhedron_demo_plugin(distance_plugin Distance_plugin) +polyhedron_demo_plugin(distance_plugin Distance_plugin KEYWORDS PMP) target_link_libraries(distance_plugin PUBLIC scene_surface_mesh_item scene_color_ramp) if(TBB_FOUND) CGAL_target_use_TBB(distance_plugin) endif() -polyhedron_demo_plugin(detect_sharp_edges_plugin Detect_sharp_edges_plugin KEYWORDS IO Mesh_3) + +polyhedron_demo_plugin(detect_sharp_edges_plugin Detect_sharp_edges_plugin KEYWORDS IO Mesh_3 PMP) target_link_libraries(detect_sharp_edges_plugin PUBLIC scene_surface_mesh_item) qt5_wrap_ui( randomPerturbationUI_FILES Random_perturbation_dialog.ui) -polyhedron_demo_plugin(random_perturbation_plugin Random_perturbation_plugin ${randomPerturbationUI_FILES}) +polyhedron_demo_plugin(random_perturbation_plugin Random_perturbation_plugin ${randomPerturbationUI_FILES} KEYWORDS PMP) target_link_libraries(random_perturbation_plugin PUBLIC scene_surface_mesh_item scene_selection_item) -polyhedron_demo_plugin(degenerated_faces_plugin Degenerated_faces_plugin) +polyhedron_demo_plugin(degenerated_faces_plugin Degenerated_faces_plugin KEYWORDS PMP) target_link_libraries(degenerated_faces_plugin PUBLIC scene_surface_mesh_item scene_selection_item) qt5_wrap_ui( engravUI_FILES Engrave_dock_widget.ui ) polyhedron_demo_plugin(engrave_text_plugin Engrave_text_plugin ${engravUI_FILES}) target_link_libraries(engrave_text_plugin PUBLIC scene_surface_mesh_item scene_selection_item scene_polylines_item) -polyhedron_demo_plugin(extrude_plugin Extrude_plugin) +polyhedron_demo_plugin(extrude_plugin Extrude_plugin KEYWORDS PMP) target_link_libraries(extrude_plugin PUBLIC scene_surface_mesh_item scene_selection_item) # The smoothing plugin can still do some things, even if Ceres is not found diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Corefinement_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Corefinement_plugin.cpp index bb6c5ece3fd..b3084533368 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Corefinement_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Corefinement_plugin.cpp @@ -19,7 +19,7 @@ class Polyhedron_demo_corefinement_sm_plugin : { Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "corefinement_plugin.json") enum bool_op {CRF_UNION, CRF_INTER, CRF_MINUS, CRF_MINUS_OP}; diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Degenerated_faces_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Degenerated_faces_plugin.cpp index 43d4f2fe3f8..b3fa95830f3 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Degenerated_faces_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Degenerated_faces_plugin.cpp @@ -25,7 +25,7 @@ class Degenerated_faces_plugin : { Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "degenerated_faces_plugin.json") public: diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Detect_sharp_edges_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Detect_sharp_edges_plugin.cpp index 357f34c8eca..b3fa6da7e8f 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Detect_sharp_edges_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Detect_sharp_edges_plugin.cpp @@ -26,7 +26,7 @@ class Polyhedron_demo_detect_sharp_edges_plugin : { Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "detect_sharp_edges_plugin.json") public: void init(QMainWindow* mainWindow, Scene_interface* scene_interface, Messages_interface*) { diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Distance_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Distance_plugin.cpp index 7e89598303c..1a7b64458dd 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Distance_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Distance_plugin.cpp @@ -345,7 +345,7 @@ class DistancePlugin : { Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "distance_plugin.json") typedef Kernel::Point_3 Point_3; public: diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Extrude_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Extrude_plugin.cpp index 1b2526922d8..d5688c3b011 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Extrude_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Extrude_plugin.cpp @@ -316,7 +316,7 @@ class ExtrudePlugin : { Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "extrude_plugin.json") public: bool applicable(QAction* action) const Q_DECL_OVERRIDE diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Fairing_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Fairing_plugin.cpp index d54a23fb011..e35106929a4 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Fairing_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Fairing_plugin.cpp @@ -37,7 +37,7 @@ class Polyhedron_demo_fairing_plugin : { Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "fairing_plugin.json") public: bool applicable(QAction*) const { return qobject_cast(scene->item(scene->mainSelectionIndex())) diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Hole_filling_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Hole_filling_plugin.cpp index 391e6e312c4..ca87a529133 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Hole_filling_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Hole_filling_plugin.cpp @@ -164,9 +164,9 @@ void removeViewer(Viewer_interface *viewer) Scene_item_rendering_helper::removeViewer(viewer); } // filter events for selecting / activating holes with mouse input - bool eventFilter(QObject* target, QEvent *event) + bool eventFilter(QObject* , QEvent *event) { - Viewer_interface* viewer = qobject_cast(target); + Viewer_interface* viewer = CGAL::Three::Three::activeViewer(); // This filter is both filtering events from 'viewer' and 'main window' Mouse_keyboard_state old_state = state; // key events @@ -262,7 +262,7 @@ private: Face_graph& poly = *poly_item->polyhedron(); - CGAL::QGLViewer* viewer = Three::mainViewer(); + CGAL::QGLViewer* viewer = Three::currentViewer(); CGAL::qglviewer::Camera* camera = viewer->camera(); Polyline_data_list::const_iterator min_it; @@ -270,15 +270,6 @@ private: Kernel::Point_2 xy(x,y); for(Polyline_data_list::const_iterator it = polyline_data_list.begin(); it != polyline_data_list.end(); ++it) { -#if 0 - /* use center of polyline to measure distance - performance wise */ - const CGAL::qglviewer::Vec& pos_it = camera->projectedCoordinatesOf(it->position); - float dist = std::pow(pos_it.x - x, 2) + std::pow(pos_it.y - y, 2); - if(dist < min_dist) { - min_dist = dist; - min_it = it; - } -#else boost::property_map::type vpm = get(CGAL::vertex_point,poly); /* use polyline points to measure distance - might hurt performance for large holes */ for(fg_halfedge_descriptor hf_around_facet : halfedges_around_face(it->halfedge,poly)){ @@ -287,14 +278,12 @@ private: const Point_3& p_2 = get(vpm,target(opposite(hf_around_facet,poly),poly)); const CGAL::qglviewer::Vec& pos_it_2 = camera->projectedCoordinatesOf(CGAL::qglviewer::Vec(p_2.x(), p_2.y(), p_2.z())); Kernel::Segment_2 s(Kernel::Point_2(pos_it_1.x, pos_it_1.y), Kernel::Point_2(pos_it_2.x, pos_it_2.y)); - double dist = CGAL::squared_distance(s, xy); if(dist < min_dist) { min_dist = dist; min_it = it; } } -#endif } if(min_it == active_hole) { @@ -337,7 +326,7 @@ class Polyhedron_demo_hole_filling_plugin : { Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "hole_filling_plugin.json") public: bool applicable(QAction*) const { return qobject_cast(scene->item(scene->mainSelectionIndex())) || qobject_cast(scene->item(scene->mainSelectionIndex())); } diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Inside_out_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Inside_out_plugin.cpp index b1941923dff..bab53f34637 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Inside_out_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Inside_out_plugin.cpp @@ -15,7 +15,7 @@ class Polyhedron_demo_inside_out_plugin : { Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "inside_out_plugin.json") public: diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Isotropic_remeshing_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Isotropic_remeshing_plugin.cpp index 6cd5fe1b928..8f1ec8d723e 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Isotropic_remeshing_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Isotropic_remeshing_plugin.cpp @@ -170,7 +170,7 @@ class Polyhedron_demo_isotropic_remeshing_plugin : { Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "isotropic_remeshing_plugin.json") typedef boost::graph_traits::edge_descriptor edge_descriptor; typedef boost::graph_traits::halfedge_descriptor halfedge_descriptor; diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Join_and_split_polyhedra_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Join_and_split_polyhedra_plugin.cpp index a1f1ccdcac3..f63a100eb8c 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Join_and_split_polyhedra_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Join_and_split_polyhedra_plugin.cpp @@ -33,7 +33,7 @@ class Polyhedron_demo_join_and_split_polyhedra_plugin: public Polyhedron_demo_plugin_helper { Q_OBJECT - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "join_and_split_polyhedra_plugin.json") Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface) QAction* actionJoinPolyhedra, *actionSplitPolyhedra, *actionColorConnectedComponents; Messages_interface* msg_interface; diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Orient_soup_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Orient_soup_plugin.cpp index ab41a5aea46..265507b8a9c 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Orient_soup_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Orient_soup_plugin.cpp @@ -25,7 +25,7 @@ class Polyhedron_demo_orient_soup_plugin : { Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "orient_soup_plugin.json") public: void init(QMainWindow* mainWindow, diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Polyhedron_stitching_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Polyhedron_stitching_plugin.cpp index 6be59b73e9e..011d5e9dc79 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Polyhedron_stitching_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Polyhedron_stitching_plugin.cpp @@ -40,7 +40,7 @@ class Polyhedron_demo_polyhedron_stitching_plugin : { Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "polyhedron_stitching_plugin.json") QAction* actionDetectBorders; QAction* actionStitchBorders; diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Random_perturbation_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Random_perturbation_plugin.cpp index 7a12447e978..c7f58900e67 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Random_perturbation_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Random_perturbation_plugin.cpp @@ -34,7 +34,7 @@ class Polyhedron_demo_random_perturbation_plugin : { Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "random_perturbation_plugin.json") public: void init(QMainWindow* mainWindow, diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Repair_polyhedron_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Repair_polyhedron_plugin.cpp index eeb65880b6d..a02cae1f847 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Repair_polyhedron_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Repair_polyhedron_plugin.cpp @@ -24,7 +24,7 @@ class Polyhedron_demo_repair_polyhedron_plugin : { Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "repair_polyhedron_plugin.json") public: diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Selection_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Selection_plugin.cpp index 7169c7efd4f..f820aa70419 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Selection_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Selection_plugin.cpp @@ -25,6 +25,8 @@ #include #include #include +#include + #include typedef Scene_surface_mesh_item Scene_face_graph_item; @@ -125,17 +127,32 @@ public: return res; } - bool applicable(QAction*) const override { - return qobject_cast(scene->item(scene->mainSelectionIndex())) - || qobject_cast(scene->item(scene->mainSelectionIndex())); + bool applicable(QAction* action) const override { + if(action == actionSelfIntersection) + return qobject_cast(scene->item(scene->mainSelectionIndex())); + else if(action == actionSelection) + return qobject_cast(scene->item(scene->mainSelectionIndex())) + || qobject_cast(scene->item(scene->mainSelectionIndex())); + return false; } void print_message(QString message) { CGAL::Three::Three::information(message); } - QList actions() const override { return QList() << actionSelection; } + + QList actions() const override { + return QList() << actionSelection + << actionSelfIntersection; + } + using Polyhedron_demo_io_plugin_interface::init; virtual void init(QMainWindow* mainWindow, CGAL::Three::Scene_interface* scene_interface, Messages_interface* m) override{ mw = mainWindow; scene = scene_interface; messages = m; + + actionSelfIntersection = new QAction(tr("Self-&Intersection Test"), mw); + actionSelfIntersection->setObjectName("actionSelfIntersection"); + actionSelfIntersection->setProperty("subMenuName", "Polygon Mesh Processing"); + connect(actionSelfIntersection, SIGNAL(triggered()), this, SLOT(on_actionSelfIntersection_triggered())); + actionSelection = new QAction( QString("Surface Mesh Selection") , mw); @@ -224,8 +241,10 @@ Q_SIGNALS: void save_handleType(); void set_operation_mode(int); void set_highlighting(bool); + public Q_SLOTS: + void on_actionSelfIntersection_triggered(); void connectItem(Scene_polyhedron_selection_item* new_item) { @@ -1057,6 +1076,7 @@ void filter_operations() private: Messages_interface* messages; QAction* actionSelection; + QAction *actionSelfIntersection; QDockWidget* dock_widget; Ui::Selection ui_widget; @@ -1068,6 +1088,102 @@ typedef boost::unordered_map +bool selfIntersect(Mesh* mesh, std::vector::face_descriptor,typename boost::graph_traits::face_descriptor> > &faces) +{ + if(!CGAL::is_triangle_mesh(*mesh)) + { + CGAL::Three::Three::warning("%1 skipped because not triangulated."); + return false; + } + // compute self-intersections + CGAL::Polygon_mesh_processing::self_intersections + (*mesh, std::back_inserter(faces), + CGAL::Polygon_mesh_processing::parameters::vertex_point_map(get(CGAL::vertex_point, *mesh))); + + std::cout << "ok (" << faces.size() << " triangle pair(s))" << std::endl; + return !faces.empty(); +} + +void Polyhedron_demo_selection_plugin::on_actionSelfIntersection_triggered() +{ + typedef boost::graph_traits::face_descriptor Face_descriptor; + typedef boost::graph_traits::halfedge_descriptor halfedge_descriptor; + QApplication::setOverrideCursor(Qt::WaitCursor); + bool found = false; + std::vector selected_polys; + Q_FOREACH(Scene_interface::Item_id index, scene->selectionIndices()) + { + Scene_face_graph_item* poly_item = + qobject_cast(scene->item(index)); + if(poly_item) + { + selected_polys.push_back(poly_item); + } + } + Q_FOREACH(Scene_face_graph_item* poly_item, selected_polys) + { + Face_graph* mesh = poly_item->face_graph(); + std::vector > faces; + // add intersecting triangles to a new Surface_mesh. + if(selfIntersect(mesh, faces)) + { + Scene_polyhedron_selection_item* selection_item = nullptr; + bool should_add = true; + if(selection_item_map.find(poly_item) != selection_item_map.end()) + { + QApplication::restoreOverrideCursor(); + if(QMessageBox::question(mw, "Question", "Only one Selection Item can be associated to an item at once, " + "and one already exists. Would you like to replace it ? (If not, this item will be skipped.)") + == QMessageBox::Yes) + { + selection_item = selection_item_map.find(poly_item)->second; + selection_item->clear(); + should_add = false; + } + else + continue; + } + else + { + selection_item = new Scene_polyhedron_selection_item(poly_item, mw); + } + QApplication::setOverrideCursor(Qt::WaitCursor); + //add the faces + for(std::vector >::iterator fb = faces.begin(); + fb != faces.end(); ++fb) { + selection_item->selected_facets.insert(fb->first); + selection_item->selected_facets.insert(fb->second); + + //add the edges + for(halfedge_descriptor he_circ : halfedges_around_face( halfedge(fb->first, *mesh), *mesh)) + { + selection_item->selected_edges.insert(edge(he_circ, *mesh)); + } + for(halfedge_descriptor he_circ : halfedges_around_face( halfedge(fb->second, *mesh), *mesh)) + { + selection_item->selected_edges.insert(edge(he_circ, *mesh)); + } + } + + selection_item->invalidateOpenGLBuffers(); + selection_item->setName(tr("%1 (selection) (intersecting triangles)").arg(poly_item->name())); + if(should_add) + connectItem(selection_item); + poly_item->setRenderingMode(Wireframe); + + scene->itemChanged(poly_item); + + selection_item->set_highlighting(false); + found = true; + } + } + QApplication::restoreOverrideCursor(); + if(!found) + QMessageBox::information(mw, tr("No self intersection"), + tr("None of the selected surfaces self-intersect.")); +} //Q_EXPORT_PLUGIN2(Polyhedron_demo_selection_plugin, Polyhedron_demo_selection_plugin) #include "Selection_plugin.moc" diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Self_intersection_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Self_intersection_plugin.cpp deleted file mode 100644 index b4735e94b7f..00000000000 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Self_intersection_plugin.cpp +++ /dev/null @@ -1,138 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - - -#include "Kernel_type.h" -#include "Scene_polyhedron_selection_item.h" - -#include "Scene_surface_mesh_item.h" -typedef Scene_surface_mesh_item Scene_face_graph_item; - -typedef Scene_face_graph_item::Face_graph Face_graph; -typedef Kernel::Triangle_3 Triangle; -using namespace CGAL::Three; -class Polyhedron_demo_self_intersection_plugin : - public QObject, - public Polyhedron_demo_plugin_interface -{ - Q_OBJECT - Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") - -public: - - QList actions() const { - return _actions; - } - - void init(QMainWindow* mainWindow, - Scene_interface* scene_interface, - Messages_interface*) - { - mw = mainWindow; - scene = scene_interface; - QAction *actionSelfIntersection = new QAction(tr("Self-&Intersection Test"), mw); - actionSelfIntersection->setProperty("subMenuName", "Polygon Mesh Processing"); - connect(actionSelfIntersection, SIGNAL(triggered()), this, SLOT(on_actionSelfIntersection_triggered())); - _actions <(scene->item(scene->mainSelectionIndex())); - } - -public Q_SLOTS: - void on_actionSelfIntersection_triggered(); -private: - QList _actions; - Scene_interface *scene; - QMainWindow *mw; - -}; // end Polyhedron_demo_self_intersection_plugin - -//pretty useless for now but could allow a huge factorization when a selection_item is -// available for SM_items -template -bool selfIntersect(Mesh* mesh, std::vector::face_descriptor,typename boost::graph_traits::face_descriptor> > &faces) -{ - if(!CGAL::is_triangle_mesh(*mesh)) - { - CGAL::Three::Three::warning("%1 skipped because not triangulated."); - return false; - } - // compute self-intersections - CGAL::Polygon_mesh_processing::self_intersections - (*mesh, std::back_inserter(faces), - CGAL::Polygon_mesh_processing::parameters::vertex_point_map(get(CGAL::vertex_point, *mesh))); - - std::cout << "ok (" << faces.size() << " triangle pair(s))" << std::endl; - return !faces.empty(); -} - -void Polyhedron_demo_self_intersection_plugin::on_actionSelfIntersection_triggered() -{ - typedef boost::graph_traits::face_descriptor Face_descriptor; - typedef boost::graph_traits::halfedge_descriptor halfedge_descriptor; - QApplication::setOverrideCursor(Qt::WaitCursor); - bool found = false; - std::vector selected_polys; - Q_FOREACH(Scene_interface::Item_id index, scene->selectionIndices()) - { - Scene_face_graph_item* poly_item = - qobject_cast(scene->item(index)); - if(poly_item) - { - selected_polys.push_back(poly_item); - } - } - Q_FOREACH(Scene_face_graph_item* poly_item, selected_polys) - { - Face_graph* mesh = poly_item->face_graph(); - std::vector > faces; - // add intersecting triangles to a new Surface_mesh. - if(selfIntersect(mesh, faces)) - { - //add the faces - Scene_polyhedron_selection_item* selection_item = new Scene_polyhedron_selection_item(poly_item, mw); - for(std::vector >::iterator fb = faces.begin(); - fb != faces.end(); ++fb) { - selection_item->selected_facets.insert(fb->first); - selection_item->selected_facets.insert(fb->second); - - //add the edges - for(halfedge_descriptor he_circ : halfedges_around_face( halfedge(fb->first, *mesh), *mesh)) - { - selection_item->selected_edges.insert(edge(he_circ, *mesh)); - } - for(halfedge_descriptor he_circ : halfedges_around_face( halfedge(fb->second, *mesh), *mesh)) - { - selection_item->selected_edges.insert(edge(he_circ, *mesh)); - } - } - selection_item->invalidateOpenGLBuffers(); - selection_item->setName(tr("%1 (selection) (intersecting triangles)").arg(poly_item->name())); - poly_item->setRenderingMode(Wireframe); - scene->addItem(selection_item); - scene->itemChanged(poly_item); - scene->itemChanged(selection_item); - found = true; - } - } - QApplication::restoreOverrideCursor(); - if(!found) - QMessageBox::information(mw, tr("No self intersection"), - tr("None of the selected surfaces self-intersect.")); -} - -#include "Self_intersection_plugin.moc" diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Surface_intersection_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Surface_intersection_plugin.cpp index 42897e71660..7095bc1bc26 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Surface_intersection_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Surface_intersection_plugin.cpp @@ -32,7 +32,7 @@ class Polyhedron_demo_intersection_plugin : { Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "surface_intersection_plugin.json") public: diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Triangulate_facets_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Triangulate_facets_plugin.cpp index 2afeaeb5b85..a607a011945 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Triangulate_facets_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Triangulate_facets_plugin.cpp @@ -14,7 +14,7 @@ class Polyhedron_demo_triangulate_facets_plugin : { Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "triangulate_facets_plugin.json") public: diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_3.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_3.cpp index dec2e51de7a..f15675749d7 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_3.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_3.cpp @@ -1,8 +1,4 @@ #include "Polyhedron_demo.h" -#include -#include -#include - /*! * \brief Defines the entry point of the demo. @@ -10,17 +6,8 @@ */ int main(int argc, char **argv) { - QSurfaceFormat fmt; - - fmt.setVersion(4, 3); - fmt.setRenderableType(QSurfaceFormat::OpenGL); - fmt.setProfile(QSurfaceFormat::CoreProfile); - fmt.setOption(QSurfaceFormat::DebugContext); - QSurfaceFormat::setDefaultFormat(fmt); - Polyhedron_demo app(argc, argv, + Polyhedron_demo app(argc, argv, "Polyhedron_3 demo", "CGAL Polyhedron Demo"); - //We set the locale to avoid any trouble with VTK - std::setlocale(LC_ALL, "C"); return app.try_exec(); } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo.cpp index c0e957bd645..6fd6bb4865a 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo.cpp @@ -8,6 +8,7 @@ #include #include #include +#include struct Polyhedron_demo_impl { @@ -17,11 +18,34 @@ struct Polyhedron_demo_impl { Polyhedron_demo_impl() : catch_exceptions(true) {} }; // end struct Polyhedron_demo_impl +int& code_to_call_before_creation_of_QCoreApplication(int& i) { + QSurfaceFormat fmt; + + fmt.setVersion(4, 3); + fmt.setRenderableType(QSurfaceFormat::OpenGL); + fmt.setProfile(QSurfaceFormat::CoreProfile); + fmt.setOption(QSurfaceFormat::DebugContext); + QSurfaceFormat::setDefaultFormat(fmt); + + //for windows +#if (QT_VERSION >= QT_VERSION_CHECK(5, 3, 0)) + QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL); +#endif + + //We set the locale to avoid any trouble with VTK + std::setlocale(LC_ALL, "C"); + return i; +} + Polyhedron_demo::Polyhedron_demo(int& argc, char **argv, QString application_name, QString main_window_title, QStringList input_keywords) - : QApplication(argc, argv) + : QApplication(code_to_call_before_creation_of_QCoreApplication(argc), + // This trick in the previous line ensure that code + // is called before the creation of the QApplication + // object. + argv) , d_ptr_is_initialized(false) , d_ptr(new Polyhedron_demo_impl) { @@ -30,11 +54,6 @@ Polyhedron_demo::Polyhedron_demo(int& argc, char **argv, std::cout.precision(17); std::clog.precision(17); - //for windows -#if (QT_VERSION >= QT_VERSION_CHECK(5, 3, 0)) - this->setAttribute(Qt::AA_UseDesktopOpenGL); -#endif - // Import resources from libCGAL (Qt5). CGAL_QT_INIT_RESOURCES; diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp index 8df409d7547..7a84ee2d911 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -25,6 +26,8 @@ #include #include #include + +#define CGAL_PMP_REPAIR_POLYGON_SOUP_VERBOSE 1 #include #include @@ -41,11 +44,14 @@ #include #include +#include + using namespace CGAL::Three; typedef Viewer_interface Vi; typedef Triangle_container Tc; typedef Edge_container Ec; typedef Point_container Pc; + struct Scene_polygon_soup_item_priv{ typedef Polygon_soup::Polygons::const_iterator Polygons_iterator; @@ -858,6 +864,8 @@ void Scene_polygon_soup_item::repair(bool erase_dup, bool req_same_orientation) erase_all_duplicates(erase_dup) .require_same_orientation(req_same_orientation)); QApplication::restoreOverrideCursor(); + + // CGAL::Three::Three::information( } CGAL::Three::Scene_item::Header_data Scene_polygon_soup_item::header() const diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp index 987c0c99994..371f2dee09c 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp @@ -198,6 +198,10 @@ struct Scene_polyhedron_selection_item_priv{ }; QUndoStack stack; CGAL::Face_filtered_graph *filtered_graph; + + std::size_t num_faces; + std::size_t num_vertices; + std::size_t num_edges; }; typedef Scene_polyhedron_selection_item_priv Priv; @@ -1121,6 +1125,7 @@ bool Scene_polyhedron_selection_item:: treat_selection(const std::setinvalidateOpenGLBuffers(); } @@ -2121,6 +2126,9 @@ void Scene_polyhedron_selection_item::init(Scene_face_graph_item* poly_item, QMa { this->poly_item = poly_item; d->poly =poly_item->polyhedron(); + d->num_faces = num_faces(*poly_item->polyhedron()); + d->num_vertices = num_vertices(*poly_item->polyhedron()); + d->num_edges = num_edges(*poly_item->polyhedron()); connect(poly_item, SIGNAL(item_is_about_to_be_changed()), this, SLOT(poly_item_changed())); //parameters type must be of the same name here and there, so they must be hardcoded. connect(&k_ring_selector, SIGNAL(selected(const std::set&)), this, @@ -2148,6 +2156,29 @@ void Scene_polyhedron_selection_item::init(Scene_face_graph_item* poly_item, QMa connect(&k_ring_selector,SIGNAL(isCurrentlySelected(Scene_facegraph_item_k_ring_selection*)), this, SIGNAL(isCurrentlySelected(Scene_facegraph_item_k_ring_selection*))); k_ring_selector.init(poly_item, mw, Active_handle::VERTEX, -1); connect(&k_ring_selector, SIGNAL(resetIsTreated()), this, SLOT(resetIsTreated())); + connect(poly_item, &Scene_surface_mesh_item::itemChanged, this, [this](){ + std::size_t new_num_faces = num_faces(*this->poly_item->face_graph()); + std::size_t new_num_vertices = num_vertices(*this->poly_item->face_graph()); + std::size_t new_num_edges = num_edges(*this->poly_item->face_graph()); + + if(new_num_faces != d->num_faces) + { + selected_facets.clear(); + d->num_faces = new_num_faces ; + } + if(new_num_vertices!= d->num_vertices) + { + selected_vertices.clear(); + d->num_vertices = new_num_vertices ; + } + if(new_num_edges!= d->num_edges) + { + selected_edges.clear(); + d->num_edges = new_num_edges ; + } + invalidateOpenGLBuffers(); + redraw(); + }); d->manipulated_frame = new ManipulatedFrame(); Q_FOREACH(CGAL::QGLViewer* v, CGAL::QGLViewer::QGLViewerPool()) v->installEventFilter(this); diff --git a/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp b/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp index 7793692024d..660be318dc1 100644 --- a/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp @@ -2259,6 +2259,7 @@ void Scene_surface_mesh_item::computeElements()const { d->compute_elements(ALL); setBuffersFilled(true); + const_cast(this)->itemChanged(); } void diff --git a/Polyhedron/doc/Polyhedron/CGAL/draw_polyhedron.h b/Polyhedron/doc/Polyhedron/CGAL/draw_polyhedron.h index 8ac1c401b79..5e8a22595c7 100644 --- a/Polyhedron/doc/Polyhedron/CGAL/draw_polyhedron.h +++ b/Polyhedron/doc/Polyhedron/CGAL/draw_polyhedron.h @@ -3,7 +3,7 @@ namespace CGAL { /*! \ingroup PkgDrawPolyhedron -Open a new window and draw `apoly`, an instance of the `CGAL::Polyhedron_3` class. The function is blocking, that is the program continues as soon as the user closes the window. This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time. +opens a new window and draws `apoly`, an instance of the `CGAL::Polyhedron_3` class. A call to this function is blocking, that is the program continues as soon as the user closes the window. This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time. \tparam POLY an instance of the `CGAL::Polyhedron_3` class. \param apoly the polyhedron to draw. diff --git a/Polyhedron/doc/Polyhedron/PackageDescription.txt b/Polyhedron/doc/Polyhedron/PackageDescription.txt index 9cc3663b547..67f938ec4b7 100644 --- a/Polyhedron/doc/Polyhedron/PackageDescription.txt +++ b/Polyhedron/doc/Polyhedron/PackageDescription.txt @@ -5,7 +5,7 @@ /// \defgroup PkgPolyhedronIOFunc I/O Functions /// \ingroup PkgPolyhedronRef -/*! Draw. +/*! \code #include \endcode @@ -73,7 +73,7 @@ surface can be used without knowing the halfedge data structure. - \link PkgPolyhedronIOFunc `read_off()` \endlink \cgalCRPSection{Draw a Polyhedron 3} -- `CGAL::draw` +- \link PkgDrawPolyhedron CGAL::draw() \endlink */ diff --git a/Polyhedron/doc/Polyhedron/Polyhedron.txt b/Polyhedron/doc/Polyhedron/Polyhedron.txt index b960089fa00..c5ba15dd26b 100644 --- a/Polyhedron/doc/Polyhedron/Polyhedron.txt +++ b/Polyhedron/doc/Polyhedron/Polyhedron.txt @@ -278,7 +278,7 @@ are also marked in the program code. \subsection PolyhedronDraw Draw a Polyhedron \anchor ssecDrawPolyhedron -A polyhedron can be visualized by calling the `CGAL::draw()` function as shown in the following example. This function opens a new window showing the given polyhedron. The function is blocking, that is the program continues as soon as the user closes the window. +A polyhedron can be visualized by calling the \link PkgDrawPolyhedron CGAL::draw() \endlink function as shown in the following example. This function opens a new window showing the given polyhedron. A call to this function is blocking, that is the program continues as soon as the user closes the window. \cgalExample{Polyhedron/draw_polyhedron.cpp} diff --git a/Polyhedron/include/CGAL/draw_polyhedron.h b/Polyhedron/include/CGAL/draw_polyhedron.h index 52dc930075d..66cf3a7f3bd 100644 --- a/Polyhedron/include/CGAL/draw_polyhedron.h +++ b/Polyhedron/include/CGAL/draw_polyhedron.h @@ -26,6 +26,7 @@ #ifdef CGAL_USE_BASIC_VIEWER +#include #include namespace CGAL @@ -194,45 +195,40 @@ protected: bool m_nofaces; const ColorFunctor& m_fcolor; }; - -template -void draw(const Polyhedron& apoly, - const char* title, - bool nofill, - const ColorFunctor& fcolor) -{ + +// Specialization of draw function. +#define CGAL_POLY_TYPE CGAL::Polyhedron_3 \ + + +template + class T_HDS, + class Alloc> +void draw(const CGAL_POLY_TYPE& apoly, + const char* title="Polyhedron Basic Viewer", + bool nofill=false) +{ #if defined(CGAL_TEST_SUITE) bool cgal_test_suite=true; #else - bool cgal_test_suite=false; + bool cgal_test_suite=qEnvironmentVariableIsSet("CGAL_TEST_SUITE"); #endif - + if (!cgal_test_suite) { int argc=1; const char* argv[2]={"polyhedron_viewer","\0"}; QApplication app(argc,const_cast(argv)); - SimplePolyhedronViewerQt + DefaultColorFunctorPolyhedron fcolor; + SimplePolyhedronViewerQt mainwindow(app.activeWindow(), apoly, title, nofill, fcolor); mainwindow.show(); app.exec(); } } -template -void draw(const Polyhedron& apoly, const char* title, bool nofill) -{ - DefaultColorFunctorPolyhedron c; - draw(apoly, title, nofill, c); -} - -template -void draw(const Polyhedron& apoly, const char* title) -{ draw(apoly, title, false); } - -template -void draw(const Polyhedron& apoly) -{ draw(apoly, "Basic Polyhedron Viewer"); } +#undef CGAL_POLY_TYPE } // End namespace CGAL diff --git a/Polynomial/include/CGAL/Test/_test_polynomial_traits_d.h b/Polynomial/include/CGAL/Test/_test_polynomial_traits_d.h index 1496e42abf5..342bfe5763c 100644 --- a/Polynomial/include/CGAL/Test/_test_polynomial_traits_d.h +++ b/Polynomial/include/CGAL/Test/_test_polynomial_traits_d.h @@ -1857,9 +1857,11 @@ void test_rebind(const PT& /*traits*/){ typedef CGAL::LEDA_arithmetic_kernel AT; typedef typename AT::Integer Integer; typedef typename AT::Rational Rational; - const int dimension = 4; + const int dimension = 4; CGAL_USE(dimension); typedef typename PT:: template Rebind::Other PT_Integer_4; + CGAL_USE_TYPE(PT_Integer_4); typedef typename PT:: template Rebind::Other PT_Rational_4; + CGAL_USE_TYPE(PT_Rational_4); CGAL_static_assertion((boost::is_same< typename PT_Integer_4::Innermost_coefficient_type, Integer>::value)); CGAL_static_assertion((boost::is_same< typename PT_Rational_4::Innermost_coefficient_type, diff --git a/Surface_mesh/doc/Surface_mesh/PackageDescription.txt b/Surface_mesh/doc/Surface_mesh/PackageDescription.txt index 6d8ed2ad4a7..5d00ad2253f 100644 --- a/Surface_mesh/doc/Surface_mesh/PackageDescription.txt +++ b/Surface_mesh/doc/Surface_mesh/PackageDescription.txt @@ -1,6 +1,6 @@ /// \defgroup PkgSurface_mesh Surface Mesh Reference -/*! Draw. +/*! \code #include \endcode @@ -39,7 +39,8 @@ and faces is much simpler and can be used at runtime and not at compile time.} - `CGAL::Surface_mesh

` \cgalCRPSection{Draw a Surface Mesh} -- `CGAL::draw` + +- \link PkgDrawSurfaceMesh CGAL::draw() \endlink */ diff --git a/Surface_mesh/doc/Surface_mesh/Surface_mesh.txt b/Surface_mesh/doc/Surface_mesh/Surface_mesh.txt index 9856b42bccc..754f49ac762 100644 --- a/Surface_mesh/doc/Surface_mesh/Surface_mesh.txt +++ b/Surface_mesh/doc/Surface_mesh/Surface_mesh.txt @@ -347,7 +347,7 @@ refering to the right vertices. \section SurfaceMeshDraw Draw a Surface Mesh \anchor ssecDrawSurfaceMesh -A surface mesh can be visualized by calling the `CGAL::draw()` function as shown in the following example. This function opens a new window showing the given surface mesh. The function is blocking, that is the program continues as soon as the user closes the window. +A surface mesh can be visualized by calling the \link PkgDrawSurfaceMesh CGAL::draw() \endlink as shown in the following example. This function opens a new window showing the given surface mesh. A call to this function is blocking, that is the program continues as soon as the user closes the window. \cgalExample{Surface_mesh/draw_surface_mesh.cpp} diff --git a/Surface_mesh/examples/Surface_mesh/CMakeLists.txt b/Surface_mesh/examples/Surface_mesh/CMakeLists.txt index 6f5b413973d..7ce13885fc5 100644 --- a/Surface_mesh/examples/Surface_mesh/CMakeLists.txt +++ b/Surface_mesh/examples/Surface_mesh/CMakeLists.txt @@ -38,10 +38,12 @@ if ( CGAL_FOUND ) create_single_source_cgal_program( "sm_properties.cpp" ) create_single_source_cgal_program("draw_surface_mesh.cpp") + create_single_source_cgal_program("sm_draw_small_faces.cpp") if(CGAL_Qt5_FOUND ) target_link_libraries(draw_surface_mesh PUBLIC CGAL::CGAL_Qt5) + target_link_libraries(sm_draw_small_faces PUBLIC CGAL::CGAL_Qt5) endif() - + else() message(STATUS "This program requires the CGAL library, and will not be compiled.") diff --git a/Surface_mesh/examples/Surface_mesh/draw_surface_mesh.cpp b/Surface_mesh/examples/Surface_mesh/draw_surface_mesh.cpp index 4735193c89f..a04a092fc5c 100644 --- a/Surface_mesh/examples/Surface_mesh/draw_surface_mesh.cpp +++ b/Surface_mesh/examples/Surface_mesh/draw_surface_mesh.cpp @@ -10,7 +10,7 @@ typedef CGAL::Surface_mesh Mesh; int main(int argc, char* argv[]) { Mesh sm1; - std::ifstream in1((argc>1)?argv[1]:"data/triangle.off"); + std::ifstream in1((argc>1)?argv[1]:"data/elephant.off"); in1 >> sm1; CGAL::draw(sm1); diff --git a/Surface_mesh/examples/Surface_mesh/draw_surface_mesh_small_faces.h b/Surface_mesh/examples/Surface_mesh/draw_surface_mesh_small_faces.h new file mode 100644 index 00000000000..b50c3a36a27 --- /dev/null +++ b/Surface_mesh/examples/Surface_mesh/draw_surface_mesh_small_faces.h @@ -0,0 +1,294 @@ +// Copyright (c) 2018 GeometryFactory (France) +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// 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. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0+ +// +// Author(s) : Guillaume Damiand + +#ifndef CGAL_DRAW_SURFACE_MESH_SMALL_FACES_H +#define CGAL_DRAW_SURFACE_MESH_SMALL_FACES_H + +#include +#include + +#ifdef CGAL_USE_BASIC_VIEWER + +#include +#include + +template +class SimpleSurfaceMeshWithSmallFacesViewerQt : public CGAL::Basic_viewer_qt +{ + typedef CGAL::Basic_viewer_qt Base; + typedef typename SM::Point Point; + typedef typename CGAL::Kernel_traits::Kernel Kernel; + typedef typename SM::Vertex_index vertex_descriptor; + typedef typename SM::Face_index face_descriptor; + typedef typename SM::Edge_index edge_descriptor; + typedef typename SM::Halfedge_index halfedge_descriptor; + typedef typename Kernel::FT FT; + +public: + /// Construct the viewer. + /// @param amesh the surface mesh to view + SimpleSurfaceMeshWithSmallFacesViewerQt(QWidget* parent, + SM& amesh) : + // First draw: no vertex; no edge, faces; multi-color; inverse normal + Base(parent, "Surface mesh viewer with small faces", false, false, true, false, false), + sm(amesh), + m_threshold(85), + m_draw_small_faces(true), + m_draw_big_faces(true) + { + // Add custom key description (see keyPressEvent). + setKeyDescription(Qt::Key_I, "Increment threshold for small faces"); + setKeyDescription(Qt::Key_D, "Decrement threshold for small faces"); + setKeyDescription(Qt::Key_S, "Draw small faces only , big faces only, both"); + + if (sm.faces().begin()!=sm.faces().end()) + { + bool exist; + typename SM::template Property_map faces_size; + boost::tie(faces_size, exist)=sm.template property_map("f:size"); + CGAL_assertion(exist); + + m_min_size=faces_size[*(sm.faces().begin())]; + m_max_size=m_min_size; + FT cur_size; + + for (typename SM::Face_range::iterator f=sm.faces().begin(); f!=sm.faces().end(); ++f) + { + cur_size=faces_size[*f]; + if (cur_sizem_max_size) m_max_size=cur_size; + } + } + + compute_elements(); + } + +protected: + void compute_face(face_descriptor fh) + { + // [Face creation] + bool issmall=false; + + // Default color of faces + CGAL::Color c(75,160,255); + + // Compare the size of the face with the % m_threshold + bool exist; + typename SM::template Property_map faces_size; + boost::tie(faces_size, exist)=sm.template property_map("f:size"); + CGAL_assertion(exist); + + // It it is smaller, color the face in red. + if (get(faces_size, fh)::null_face()) + { compute_face(*f); } + } + + for (typename SM::Edge_range::iterator e=sm.edges().begin(); + e!=sm.edges().end(); ++e) + { compute_edge(*e); } + + for (typename SM::Vertex_range::iterator v=sm.vertices().begin(); + v!=sm.vertices().end(); ++v) + { compute_vertex(*v); } + } + + // Call: * compute_elements() if the model changed, followed by + // * redraw() if some viewing parameters changed that implies some + // modifications of the buffers + // (eg. type of normal, color/mono) + // * update() just to update the drawing + virtual void keyPressEvent(QKeyEvent *e) + { + /// [Keypress] + const ::Qt::KeyboardModifiers modifiers = e->modifiers(); + if ((e->key()==Qt::Key_I) && (modifiers==Qt::NoButton)) + { + if (m_threshold<100) { ++m_threshold; } + displayMessage(QString("Threshold percent=%1%.").arg(m_threshold)); + compute_elements(); + redraw(); + } + else if ((e->key()==Qt::Key_D) && (modifiers==Qt::NoButton)) + { + if (m_threshold>0) { --m_threshold; } + displayMessage(QString("Threshold percent=%1%.").arg(m_threshold)); + compute_elements(); + redraw(); + } + else if ((e->key()==Qt::Key_S) && (modifiers==Qt::NoButton)) + { + QString msg; + if (m_draw_small_faces) + { + if (m_draw_big_faces) + { + m_draw_big_faces=false; + msg=QString("Draw small faces only."); + } + else + { + m_draw_big_faces=true; m_draw_small_faces=false; + msg=QString("Draw big faces only."); + } + } + else + { + assert(m_draw_big_faces); + m_draw_small_faces=true; + msg=QString("Draw small and big faces."); + } + + displayMessage(msg); + compute_elements(); + redraw(); + } + else + { + // Call the base method to process others/classicals key + Base::keyPressEvent(e); + } + /// [Keypress] + } + +protected: + typename Kernel::Vector_3 get_face_normal(halfedge_descriptor he) + { + typename Kernel::Vector_3 normal=CGAL::NULL_VECTOR; + halfedge_descriptor end=he; + unsigned int nb=0; + do + { + CGAL::internal::newell_single_step_3(sm.point(sm.source(he)), + sm.point(sm.target(he)), normal); + ++nb; + he=sm.next(he); + } + while (he!=end); + assert(nb>0); + return (typename Kernel::Construct_scaled_vector_3()(normal, 1.0/nb)); + } + + typename Kernel::Vector_3 get_vertex_normal(halfedge_descriptor he) + { + typename Kernel::Vector_3 normal=CGAL::NULL_VECTOR; + halfedge_descriptor end=he; + do + { + if (!sm.is_border(he)) + { + typename Kernel::Vector_3 n=get_face_normal(he); + normal=typename Kernel::Construct_sum_of_vectors_3()(normal, n); + } + he=sm.next(sm.opposite(he)); + } + while (he!=end); + + if (!typename Kernel::Equal_3()(normal, CGAL::NULL_VECTOR)) + { normal=(typename Kernel::Construct_scaled_vector_3() + (normal, 1.0/CGAL::sqrt(normal.squared_length()))); } + + return normal; + } + +protected: + SM& sm; + unsigned int m_threshold; + FT m_min_size, m_max_size; + bool m_draw_small_faces; + bool m_draw_big_faces; +}; + +template +void draw_surface_mesh_with_small_faces(CGAL::Surface_mesh& amesh) +{ +#if defined(CGAL_TEST_SUITE) + bool cgal_test_suite=true; +#else + bool cgal_test_suite=qEnvironmentVariableIsSet("CGAL_TEST_SUITE"); +#endif + + if (!cgal_test_suite) + { + int argc=1; + const char* argv[2]={"surface_mesh_viewer","\0"}; + QApplication app(argc,const_cast(argv)); + SimpleSurfaceMeshWithSmallFacesViewerQt> + mainwindow(app.activeWindow(), amesh); + mainwindow.show(); + app.exec(); + } +} + +#else // CGAL_USE_BASIC_VIEWER + +template +void draw_surface_mesh_with_small_faces(CGAL::Surface_mesh&) +{ + std::cerr<<"Impossible to draw, CGAL_USE_BASIC_VIEWER is not defined."< +#include +#include +#include +#include +#include +#include +#include "draw_surface_mesh_small_faces.h" + +typedef CGAL::Simple_cartesian K; +typedef CGAL::Surface_mesh Mesh; +typedef Mesh::Vertex_index vertex_descriptor; +typedef Mesh::Face_index face_descriptor; +typedef K::FT FT; + +int main(int argc, char* argv[]) +{ + Mesh sm; + std::ifstream input((argc>1)?argv[1]:"data/elephant.off"); + input>>sm; + + CGAL::Polygon_mesh_processing::triangulate_faces(sm); + + Mesh::Property_map faces_size; + bool created; + boost::tie(faces_size, created)=sm.add_property_map("f:size",0.); + CGAL_assertion(created); + + BOOST_FOREACH(face_descriptor fd, sm.faces()) + { faces_size[fd]=CGAL::Polygon_mesh_processing::face_area(fd, sm); } + + draw_surface_mesh_with_small_faces(sm); + + sm.remove_property_map(faces_size); + + return EXIT_SUCCESS; +} + diff --git a/Surface_mesh/include/CGAL/draw_surface_mesh.h b/Surface_mesh/include/CGAL/draw_surface_mesh.h index 6d34dd96f90..bfd76350505 100644 --- a/Surface_mesh/include/CGAL/draw_surface_mesh.h +++ b/Surface_mesh/include/CGAL/draw_surface_mesh.h @@ -41,6 +41,7 @@ void draw(const SM& asm); #ifdef CGAL_USE_BASIC_VIEWER +#include #include namespace CGAL @@ -202,16 +203,16 @@ protected: const ColorFunctor& m_fcolor; }; -template -void draw(const SM& amesh, - const char* title, - bool nofill, - const ColorFunctor& fcolor) +// Specialization of draw function. +template +void draw(const Surface_mesh& amesh, + const char* title="Surface_mesh Basic Viewer", + bool nofill=false) { #if defined(CGAL_TEST_SUITE) bool cgal_test_suite=true; #else - bool cgal_test_suite=false; + bool cgal_test_suite=qEnvironmentVariableIsSet("CGAL_TEST_SUITE"); #endif if (!cgal_test_suite) @@ -219,31 +220,14 @@ void draw(const SM& amesh, int argc=1; const char* argv[2]={"surface_mesh_viewer","\0"}; QApplication app(argc,const_cast(argv)); - SimpleSurfaceMeshViewerQt mainwindow(app.activeWindow(), - amesh, - title, - nofill, - fcolor); + DefaultColorFunctorSM fcolor; + SimpleSurfaceMeshViewerQt, DefaultColorFunctorSM> + mainwindow(app.activeWindow(), amesh, title, nofill, fcolor); mainwindow.show(); app.exec(); } } -template -void draw(const SM& amesh, const char* title, bool nofill) -{ - DefaultColorFunctorSM c; - draw(amesh, title, nofill, c); -} - -template -void draw(const SM& amesh, const char* title) -{ draw(amesh, title, false); } - -template -void draw(const SM& amesh) -{ draw(amesh, "Basic Surface_mesh Viewer"); } - } // End namespace CGAL #endif // CGAL_USE_BASIC_VIEWER diff --git a/Surface_mesher/demo/Surface_mesher/CMakeLists.txt b/Surface_mesher/demo/Surface_mesher/CMakeLists.txt index c1e5b5a4a5f..a3026736db0 100644 --- a/Surface_mesher/demo/Surface_mesher/CMakeLists.txt +++ b/Surface_mesher/demo/Surface_mesher/CMakeLists.txt @@ -93,14 +93,17 @@ if ( CGAL_FOUND AND CGAL_Qt5_FOUND AND CGAL_ImageIO_FOUND) add_to_cached_list( CGAL_EXECUTABLE_TARGETS ${prj} ) - set(VTK_LIBS "") find_package(VTK QUIET COMPONENTS vtkImagingGeneral vtkIOImage NO_MODULE) if(VTK_FOUND) - include(${VTK_USE_FILE}) - if ("${VTK_VERSION_MAJOR}" GREATER "5") + if(VTK_USE_FILE) + include(${VTK_USE_FILE}) + endif() + if ("${VTK_VERSION_MAJOR}" GREATER "5" OR VTK_VERSION VERSION_GREATER 5) message(STATUS "VTK found") add_definitions(-DCGAL_USE_VTK) - set(VTK_LIBS vtkImagingGeneral vtkIOImage) + if(TARGET VTK::IOImage) + set(VTK_LIBRARIES VTK::IOImage VTK::ImagingGeneral) + endif() else() message(STATUS "Vtk must be at least Rel 6") endif() @@ -111,7 +114,7 @@ if ( CGAL_FOUND AND CGAL_Qt5_FOUND AND CGAL_ImageIO_FOUND) target_link_libraries( ${prj} PRIVATE CGAL::CGAL CGAL::CGAL_Qt5 CGAL::CGAL_ImageIO ${OPENGL_LIBRARIES} - ${VTK_LIBS} ) + ${VTK_LIBRARIES} ) include(${CGAL_MODULES_DIR}/CGAL_add_test.cmake) cgal_add_compilation_test(${prj}) diff --git a/Triangulation_2/doc/Triangulation_2/CGAL/draw_triangulation_2.h b/Triangulation_2/doc/Triangulation_2/CGAL/draw_triangulation_2.h index 11d13a005a1..88c9644d30a 100644 --- a/Triangulation_2/doc/Triangulation_2/CGAL/draw_triangulation_2.h +++ b/Triangulation_2/doc/Triangulation_2/CGAL/draw_triangulation_2.h @@ -3,7 +3,7 @@ namespace CGAL { /*! \ingroup PkgDrawTriangulation2 -Open a new window and draw `at2`, a model of the `TriangulationDataStructure_2` concept. The function is blocking, that is the program continues as soon as the user closes the window. This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time. +opens a new window and draws `at2`, a model of the `TriangulationDataStructure_2` concept. A call to this function is blocking, that is the program continues as soon as the user closes the window. This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time. \tparam T2 a model of the `TriangulationDataStructure_2` concept. \param at2 the triangulation to draw. diff --git a/Triangulation_2/doc/Triangulation_2/PackageDescription.txt b/Triangulation_2/doc/Triangulation_2/PackageDescription.txt index d199da9f5a3..5cb5b93e1b2 100644 --- a/Triangulation_2/doc/Triangulation_2/PackageDescription.txt +++ b/Triangulation_2/doc/Triangulation_2/PackageDescription.txt @@ -13,7 +13,7 @@ /// \defgroup PkgTriangulation2Miscellaneous Miscellaneous /// \ingroup PkgTriangulation2Ref -/*! Draw. +/*! \code #include \endcode @@ -107,7 +107,7 @@ are described in Chapter \ref PkgTDS2Ref "2D Triangulation Data Structure". - \link CGAL::Triangulation_2::Locate_type `CGAL::Triangulation_2::Locate_type` \endlink \cgalCRPSection{Draw a Triangulation 2} -- `CGAL::draw` +- \link PkgDrawTriangulation2 CGAL::draw() \endlink */ diff --git a/Triangulation_2/doc/Triangulation_2/Triangulation_2.txt b/Triangulation_2/doc/Triangulation_2/Triangulation_2.txt index 6bee3b8a77f..742ea922347 100644 --- a/Triangulation_2/doc/Triangulation_2/Triangulation_2.txt +++ b/Triangulation_2/doc/Triangulation_2/Triangulation_2.txt @@ -493,7 +493,7 @@ Finally points on the convex hull are written to cout. \subsection Triangulation2Draw Draw a 2D Triangulation \anchor ssecDrawT2 -A 2D triangulation can be visualized by calling the `CGAL::draw()` function as shown in the following example. This function opens a new window showing the given 2D triangulation. The function is blocking, that is the program continues as soon as the user closes the window. +A 2D triangulation can be visualized by calling the \link PkgDrawTriangulation2 CGAL::draw() \endlink function as shown in the following example. This function opens a new window showing the given 2D triangulation. A call to this function is blocking, that is the program continues as soon as the user closes the window. \cgalExample{Triangulation_2/draw_triangulation_2.cpp} diff --git a/Triangulation_2/include/CGAL/Triangulation_2/internal/Polyline_constraint_hierarchy_2.h b/Triangulation_2/include/CGAL/Triangulation_2/internal/Polyline_constraint_hierarchy_2.h index 8d7cf7e38d3..e468fa4d9de 100644 --- a/Triangulation_2/include/CGAL/Triangulation_2/internal/Polyline_constraint_hierarchy_2.h +++ b/Triangulation_2/include/CGAL/Triangulation_2/internal/Polyline_constraint_hierarchy_2.h @@ -742,13 +742,13 @@ Polyline_constraint_hierarchy_2::concatenate2(Constraint_id firs // now we really concatenate the vertex lists // Note that all iterators pointing into second remain valid. first.vl_ptr()->pop_back(); // because it is the same as second.front() - Vertex_it back_it = first.vl_ptr()->skip_end(); - --back_it; + Vertex_it back_it = second.vl_ptr()->skip_begin(); + second.vl_ptr()->splice(second.vl_ptr()->skip_begin(), *(first.vl_ptr()), first.vl_ptr()->skip_begin(), first.vl_ptr()->skip_end()); // Note that for VC8 with iterator debugging the iterators pointing into second // are NOT valid So we have to update them - for(Vertex_it it = back_it, succ = it, end = first.vl_ptr()->skip_end(); + for(Vertex_it it = second.vl_ptr()->skip_begin(), succ = it, end = back_it; ++succ != end; ++it){ typename Sc_to_c_map::iterator scit = sc_to_c_map.find(make_edge(*it,*succ)); diff --git a/Triangulation_2/include/CGAL/draw_triangulation_2.h b/Triangulation_2/include/CGAL/draw_triangulation_2.h index 193e12e20ea..bfa1fbaa04c 100644 --- a/Triangulation_2/include/CGAL/draw_triangulation_2.h +++ b/Triangulation_2/include/CGAL/draw_triangulation_2.h @@ -26,6 +26,7 @@ #ifdef CGAL_USE_BASIC_VIEWER +#include #include namespace CGAL @@ -135,48 +136,35 @@ protected: bool m_nofaces; const ColorFunctor& m_fcolor; }; + +// Specialization of draw function. +#define CGAL_T2_TYPE CGAL::Triangulation_2 -template -void draw(const T2& at2, - const char* title, - bool nofill, - const ColorFunctor& fcolor) +template +void draw(const CGAL_T2_TYPE& at2, + const char* title="Triangulation_2 Basic Viewer", + bool nofill=false) { #if defined(CGAL_TEST_SUITE) bool cgal_test_suite=true; #else - bool cgal_test_suite=false; + bool cgal_test_suite=qEnvironmentVariableIsSet("CGAL_TEST_SUITE"); #endif - + if (!cgal_test_suite) { int argc=1; const char* argv[2]={"t2_viewer","\0"}; - QApplication app(argc,const_cast(argv)); - SimpleTriangulation2ViewerQt mainwindow(app.activeWindow(), - at2, - title, - nofill, - fcolor); + QApplication app(argc,const_cast(argv)); + DefaultColorFunctorT2 fcolor; + SimpleTriangulation2ViewerQt + mainwindow(app.activeWindow(), at2, title, nofill, fcolor); mainwindow.show(); app.exec(); } } -template -void draw(const T2& at2, const char* title, bool nofill) -{ - DefaultColorFunctorT2 c; - draw(at2, title, nofill, c); -} - -template -void draw(const T2& at2, const char* title) -{ draw(at2, title, false); } - -template -void draw(const T2& at2) -{ draw(at2, "Basic T2 Viewer"); } +#undef CGAL_T2_TYPE } // End namespace CGAL diff --git a/Triangulation_2/test/Triangulation_2/issue_4025.cpp b/Triangulation_2/test/Triangulation_2/issue_4025.cpp new file mode 100644 index 00000000000..af37b05ac06 --- /dev/null +++ b/Triangulation_2/test/Triangulation_2/issue_4025.cpp @@ -0,0 +1,89 @@ +#include +#include +#include +#include + + +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef CGAL::Polygon_2 Polygon_2; +typedef CGAL::Exact_intersections_tag Itag_; +typedef CGAL::Constrained_Delaunay_triangulation_2 CDT; +typedef CGAL::Constrained_triangulation_plus_2 CDTP; + +typedef CDTP::Point Point; +typedef CDTP::Constraint_id Cid; +typedef CDTP::Vertex_handle Vertex_handle; +typedef CDTP::Constraint_id Constraint_id; +typedef CDTP::Vertices_in_constraint_iterator Vertices_in_constraint_iterator; + +int countVertex(CDTP &cdtp, CDTP::Constraint_id id) +{ + Vertices_in_constraint_iterator v=cdtp.vertices_in_constraint_begin(id); + + int count=0; + while(v!=cdtp.vertices_in_constraint_end(id)) + { + count++; + v++; + } + + return count; +} + + +int main() +{ + CDTP cdtp; + + std::list pointsListCollinear; + + pointsListCollinear.push_back(Point(0,0)); + pointsListCollinear.push_back(Point(0,1)); + pointsListCollinear.push_back(Point(0,2)); + pointsListCollinear.push_back(Point(0,3)); + pointsListCollinear.push_back(Point(0,4)); + pointsListCollinear.push_back(Point(0,5)); + + std::list pointsListNoCollinear; + + pointsListNoCollinear.push_back(Point(1,0)); + pointsListNoCollinear.push_back(Point(2,1)); + pointsListNoCollinear.push_back(Point(4,2)); + pointsListNoCollinear.push_back(Point(2,3)); + pointsListNoCollinear.push_back(Point(4,4)); + pointsListNoCollinear.push_back(Point(1,5)); + + + Constraint_id ctIdCollinear=cdtp.insert_constraint(pointsListCollinear.begin(),pointsListCollinear.end()); + Constraint_id ctIdNoCollinear=cdtp.insert_constraint(pointsListNoCollinear.begin(),pointsListNoCollinear.end()); + + + //******************************* attempt with the collinear constraint + Vertices_in_constraint_iterator vertexToRemoveCollinear=cdtp.vertices_in_constraint_begin(ctIdCollinear); + vertexToRemoveCollinear++; + vertexToRemoveCollinear++; + + + std::cout<<"attempt to remove vertex "<<(*vertexToRemoveCollinear)->point().x()<<" , "<<(*vertexToRemoveCollinear)->point().y() < 5, expected 4 + std::cout<<"number of constraints "< 1 + std::cout<<"number of vertex in constraint "< 6, expected 5 + + + //******************************* attempt with the collinear constraint + Vertices_in_constraint_iterator vertexToRemoveNoCollinear=cdtp.vertices_in_constraint_begin(ctIdNoCollinear); + vertexToRemoveNoCollinear++; + vertexToRemoveNoCollinear++; + + std::cout<<"attempt to remove vertex "<<(*vertexToRemoveNoCollinear)->point().x()<<" , "<<(*vertexToRemoveNoCollinear)->point().y() << std::endl; + cdtp.remove_vertex_from_constraint(ctIdNoCollinear,vertexToRemoveNoCollinear); + + std::cout<<"number of subconstraints "< 4, ok + std::cout<<"number of constraints "< 1 + std::cout<<"number of vertex in constraint "< 5, ok + + return 0; + +} diff --git a/Triangulation_3/doc/Triangulation_3/CGAL/draw_triangulation_3.h b/Triangulation_3/doc/Triangulation_3/CGAL/draw_triangulation_3.h index b7704903210..4b33db6062f 100644 --- a/Triangulation_3/doc/Triangulation_3/CGAL/draw_triangulation_3.h +++ b/Triangulation_3/doc/Triangulation_3/CGAL/draw_triangulation_3.h @@ -3,7 +3,7 @@ namespace CGAL { /*! \ingroup PkgDrawTriangulation3 -Open a new window and draw `at3`, a model of the `TriangulationDataStructure_3` concept. The function is blocking, that is the program continues as soon as the user closes the window. This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time. +opens a new window and draws `at3`, a model of the `TriangulationDataStructure_3` concept. A call to this function is blocking, that is the program continues as soon as the user closes the window. This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time. \tparam T3 a model of the `TriangulationDataStructure_3` concept. \param at3 the triangulation to draw. diff --git a/Triangulation_3/doc/Triangulation_3/PackageDescription.txt b/Triangulation_3/doc/Triangulation_3/PackageDescription.txt index a7b80f3c621..1804cdccaf7 100644 --- a/Triangulation_3/doc/Triangulation_3/PackageDescription.txt +++ b/Triangulation_3/doc/Triangulation_3/PackageDescription.txt @@ -13,7 +13,7 @@ /// \defgroup PkgTriangulation3VertexCellClasses Vertex and Cell Classes /// \ingroup PkgTriangulation3Ref -/*! Draw. +/*! \code #include \endcode @@ -118,7 +118,8 @@ is opposite to the vertex with the same index. See - `CGAL::Triangulation_3::Locate_type` \cgalCRPSection{Draw a Triangulation 3} -- `CGAL::draw` + +- \link PkgDrawTriangulation3 CGAL::draw() \endlink */ diff --git a/Triangulation_3/doc/Triangulation_3/Triangulation_3.txt b/Triangulation_3/doc/Triangulation_3/Triangulation_3.txt index 4284b30705b..66fdb0cdee7 100644 --- a/Triangulation_3/doc/Triangulation_3/Triangulation_3.txt +++ b/Triangulation_3/doc/Triangulation_3/Triangulation_3.txt @@ -557,7 +557,7 @@ removal of the first 100,000 vertices. \subsection Triangulation3Draw Draw a 3D Triangulation \anchor ssecDrawT3 -A 3D triangulation can be visualized by calling the `CGAL::draw()` function as shown in the following example. This function opens a new window showing the given 3D triangulation. The function is blocking, that is the program continues as soon as the user closes the window. +A 3D triangulation can be visualized by calling the \link PkgDrawTriangulation3 CGAL::draw() \endlink function as shown in the following example. This function opens a new window showing the given 3D triangulation. A call to this function is blocking, that is the program continues as soon as the user closes the window. \cgalExample{Triangulation_3/draw_triangulation_3.cpp} diff --git a/Triangulation_3/include/CGAL/draw_triangulation_3.h b/Triangulation_3/include/CGAL/draw_triangulation_3.h index 065eba016a3..ea9520ae0cb 100644 --- a/Triangulation_3/include/CGAL/draw_triangulation_3.h +++ b/Triangulation_3/include/CGAL/draw_triangulation_3.h @@ -26,6 +26,7 @@ #ifdef CGAL_USE_BASIC_VIEWER +#include #include namespace CGAL @@ -141,49 +142,35 @@ protected: bool m_nofaces; const ColorFunctor& m_fcolor; }; - -template -void draw(const T3& at3, - const char* title, - bool nofill, - const ColorFunctor& fcolor) -{ +// Specialization of draw function. +#define CGAL_T3_TYPE CGAL::Triangulation_3 + +template +void draw(const CGAL_T3_TYPE& at3, + const char* title="T3 Basic Viewer", + bool nofill=false) +{ #if defined(CGAL_TEST_SUITE) bool cgal_test_suite=true; #else - bool cgal_test_suite=false; + bool cgal_test_suite=qEnvironmentVariableIsSet("CGAL_TEST_SUITE"); #endif - + if (!cgal_test_suite) { int argc=1; const char* argv[2]={"t3_viewer","\0"}; QApplication app(argc,const_cast(argv)); - SimpleTriangulation3ViewerQt mainwindow(app.activeWindow(), - at3, - title, - nofill, - fcolor); + DefaultColorFunctorT3 fcolor; + SimpleTriangulation3ViewerQt + mainwindow(app.activeWindow(), at3, title, nofill, fcolor); mainwindow.show(); app.exec(); } } -template -void draw(const T3& at3, const char* title, bool nofill) -{ - DefaultColorFunctorT3 c; - draw(at3, title, nofill, c); -} - -template -void draw(const T3& at3, const char* title) -{ draw(at3, title, false); } - -template -void draw(const T3& at3) -{ draw(at3, "Basic T3 Viewer"); } +#undef CGAL_T3_TYPE } // End namespace CGAL