From 9651cadd1db3b2b3cb1eb1067c22ec820a54e247 Mon Sep 17 00:00:00 2001 From: Youmu Date: Wed, 3 Jun 2020 11:15:59 -0400 Subject: [PATCH 001/248] Basic call interface. Special case for torus and cylinder. --- .../include/CGAL/Curves_on_surface_topology.h | 10 ++ .../internal/Minimal_quadrangulation.h | 97 +++++++++++++++++++ 2 files changed, 107 insertions(+) diff --git a/Surface_mesh_topology/include/CGAL/Curves_on_surface_topology.h b/Surface_mesh_topology/include/CGAL/Curves_on_surface_topology.h index 02e040de132..0671c2a36e5 100644 --- a/Surface_mesh_topology/include/CGAL/Curves_on_surface_topology.h +++ b/Surface_mesh_topology/include/CGAL/Curves_on_surface_topology.h @@ -166,6 +166,16 @@ public: return m_facewidth->compute_face_width(display_time); } +//================================================================================ +// Test whether a path is homotopic to a simple cycle + + bool is_simple_cycle(const Path_on_surface& p, + bool display_time=false) const + { + compute_minimal_quadrangulation(display_time); + return m_minimal_quadrangulation->is_simple_cycle(p, display_time); + } + protected: const Mesh& m_original_mesh; mutable std::unique_ptr m_minimal_quadrangulation; diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h index 1506ec864e9..03a2de5abc6 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h @@ -475,6 +475,67 @@ public: #endif // defined(CGAL_PWRLE_TURN_V2) || defined(CGAL_PWRLE_TURN_V3) } + /// @return true iff 'p' is a simple curve. + bool is_simple_cycle(const Path_on_surface& p, + bool display_time=false) const + { + if (p.is_empty()) + { return true; } + + if (!p.is_closed()) + { + std::cerr<<"Error: is_contractible requires a closed path."< + pt=transform_original_path_into_quad_surface_for_torus(p); + + int a, b; + count_edges_of_path_on_torus(pt, a, b); + a = std::abs(a); + b = std::abs(b); + res=(a == 0 || b == 0 || CGAL::gcd(a, b) - 1 == 0); + } + else if (local_map_is_a_cylinder()) + { + internal::Path_on_surface_with_rle + pt=transform_original_path_into_quad_surface_with_rle(p); + + int p = count_edges_of_path_on_cylinder(pt); + res=(std::abs(p) <= 1); + } + else if (is_contractible()) + { + // genus > 1 and contractible + res=true; + } + else + { + // TODO: genus > 1 and not contractible, perform unzip algorithm + } + + if (display_time) + { + t.stop(); + std::cout<<"[TIME] is_simple_cycle: "<& path) const + { + CGAL_assertion(local_map_is_a_cylinder()); + int p = 0; + + Dart_const_handle dhp=get_local_map().darts().begin(); + Dart_const_handle dhn=get_local_map().template beta<2>(dhp); + for (std::size_t i = 0; i < path.length(); ++i) + { + if(path.get_ith_flip(i)) + { + if (path[i]==dhp || path[i]==get_local_map().template beta<1>(dhp)) + { --p; } + else if (path[i]==dhn || path[i]==get_local_map().template beta<1>(dhn)) + { ++p; } + } + else + { + if (path[i]==dhp || path[i]==get_local_map().template beta<1>(dhp)) + { ++p; } + else if (path[i]==dhn || path[i]==get_local_map().template beta<1>(dhn)) + { --p; } + } + } + + return p/2; + } + Path_on_surface transform_original_path_into_quad_surface_for_torus (const Path_on_surface& path) const @@ -1405,6 +1495,13 @@ protected: return (get_local_map().number_of_marked_darts(m_mark_perforated)==0); } + bool local_map_is_a_cylinder() const + { + if (get_local_map().number_of_darts()!=4) + { return false; } + return (get_local_map().number_of_marked_darts(m_mark_perforated)==4); + } + /// @return true iff the perforated faces are correctly marked /// (i.e. either fully marked or fully unmarked). bool perforated_faces_correctly_marked() const From e29896a13513f63e1bdce27ba0ee2b0c420739c8 Mon Sep 17 00:00:00 2001 From: Youmu Date: Sat, 6 Jun 2020 19:49:32 -0400 Subject: [PATCH 002/248] Add path factorization --- .../include/CGAL/Path_on_surface.h | 35 +++++++++++++++++++ .../internal/Path_on_surface_with_rle.h | 6 ++++ 2 files changed, 41 insertions(+) diff --git a/Surface_mesh_topology/include/CGAL/Path_on_surface.h b/Surface_mesh_topology/include/CGAL/Path_on_surface.h index 96a0c56a029..5dd53b8605d 100644 --- a/Surface_mesh_topology/include/CGAL/Path_on_surface.h +++ b/Surface_mesh_topology/include/CGAL/Path_on_surface.h @@ -1095,6 +1095,41 @@ public: } } + /// @return the primitive root and the power of the path in the sense of string. + /// use the linear Knuth-Morris-Pratt search + Self factorize(int& power) { + CGAL_assertion(is_valid()); + if (!is_closed()) { + // if a path is not closed, it is already primitive + power = 1; + return Path_on_surface(*this); + } + + Self pp1(*this); + pp1.simplify_flips(); + Self pp2(pp1); + /// create a path of (*this)->(*this) + pp2 += pp1; + + /// Match (*this) to (*this)->(*this) with the first dart removed + auto itMatch = boost::algorithm::knuth_morris_pratt_search(pp2.m_path.begin() + 1, + pp2.m_path.end(), + pp1.m_path.begin(), + pp1.m_path.end()) +#if BOOST_VERSION>=106200 + .first +#endif + ; + /// It can be proved that the first match location is the length of match + auto primitiveSize = itMatch - pp2.m_path.begin(); + std::cout << pp1.length() << ' ' << primitiveSize << std::endl; + CGAL_assertion(pp1.length() % primitiveSize == 0); + power = pp1.length() / primitiveSize; + pp1.cut(primitiveSize); + CGAL_assertion(pp1.is_closed()); + return pp1; + } + /// @return the turn between dart number i and dart number i+1. /// (turn is position of the second edge in the cyclic ordering of /// edges starting from the first edge around the second extremity diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Path_on_surface_with_rle.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Path_on_surface_with_rle.h index 64438208dd6..82dcda953f1 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Path_on_surface_with_rle.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Path_on_surface_with_rle.h @@ -1499,6 +1499,12 @@ public: CGAL_assertion(is_valid()); } + /// Factorize the path into primitive + Self factorize(int& power) { + Path_on_surface p(*this); + return Self(m_MQ, p.factorize(power), m_use_only_positive, m_use_only_negative); + } + void display_positive_turns() { std::cout<<"+("; From 59d4428fffac9f9fb7f2e639d6022d7d8f83da05 Mon Sep 17 00:00:00 2001 From: Youmu Date: Wed, 10 Jun 2020 01:50:26 -0400 Subject: [PATCH 003/248] Change interface for factorize to avoid output argument --- Surface_mesh_topology/include/CGAL/Path_on_surface.h | 8 +++----- .../internal/Path_on_surface_with_rle.h | 5 +++-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/Surface_mesh_topology/include/CGAL/Path_on_surface.h b/Surface_mesh_topology/include/CGAL/Path_on_surface.h index 5dd53b8605d..40932947472 100644 --- a/Surface_mesh_topology/include/CGAL/Path_on_surface.h +++ b/Surface_mesh_topology/include/CGAL/Path_on_surface.h @@ -1097,12 +1097,11 @@ public: /// @return the primitive root and the power of the path in the sense of string. /// use the linear Knuth-Morris-Pratt search - Self factorize(int& power) { + std::pair factorize() { CGAL_assertion(is_valid()); if (!is_closed()) { // if a path is not closed, it is already primitive - power = 1; - return Path_on_surface(*this); + return std::make_pair(Path_on_surface(*this), 1); } Self pp1(*this); @@ -1124,10 +1123,9 @@ public: auto primitiveSize = itMatch - pp2.m_path.begin(); std::cout << pp1.length() << ' ' << primitiveSize << std::endl; CGAL_assertion(pp1.length() % primitiveSize == 0); - power = pp1.length() / primitiveSize; pp1.cut(primitiveSize); CGAL_assertion(pp1.is_closed()); - return pp1; + return std::make_pair(pp1, pp1.length() / primitiveSize); } /// @return the turn between dart number i and dart number i+1. diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Path_on_surface_with_rle.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Path_on_surface_with_rle.h index 82dcda953f1..ac9aa06af8b 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Path_on_surface_with_rle.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Path_on_surface_with_rle.h @@ -1500,9 +1500,10 @@ public: } /// Factorize the path into primitive - Self factorize(int& power) { + std::pair factorize() { Path_on_surface p(*this); - return Self(m_MQ, p.factorize(power), m_use_only_positive, m_use_only_negative); + auto result = p.factorize(); + return std::make_pair(Self(m_MQ, result.first, m_use_only_positive, m_use_only_negative), result.second); } void display_positive_turns() From 41183a08aa9e691153638e752e278ab1c0bfc269 Mon Sep 17 00:00:00 2001 From: Youmu Date: Wed, 10 Jun 2020 01:50:52 -0400 Subject: [PATCH 004/248] Compute switchable darts and match longest common suffix for the path --- .../internal/Minimal_quadrangulation.h | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h index 03a2de5abc6..8b03d493ae3 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h @@ -523,6 +523,22 @@ public: else { // TODO: genus > 1 and not contractible, perform unzip algorithm + internal::Path_on_surface_with_rle + pt=transform_original_path_into_quad_surface_with_rle(p); + pt.canonize(); + // Use non-rle path from now on + Path_on_surface ps(pt); + auto factorization=ps.factorize(); + if (factorization.first > 1) { + // If the curve is not primitive, there must be at least + // one self intersection + res=false; + } + // Label the switchable arcs + std::vector switchables = compute_switchable(ps); + // Compute the backward cyclic KMP failure table for the curve + std::vector suffix_len = compute_common_circular_suffix(ps); + } if (display_time) @@ -1672,6 +1688,61 @@ protected: return res; } + /// Compute whether each darts is switchable in the path + std::vector compute_switchable(const Path_on_surface& p) { + std::vector switchables(p.length(), false); + std::vector turns = p.compute_positive_turns(); + /// Skip the last dart since it can never be switched, nor can it + /// be the second last dart of a switch + std::size_t i = p.length() - 2; + while (i >= 0) { + if (turns[i] == 1) { + /// This is the end of a possible switchbale subpath + --i; + while (i >= 0 && turns[i] == 2) { + switchables[i].flip(); + --i; + } + } + else { + --i; + } + } + return switchables; + } + + /// Compute the longest common suffix of a path against all of it circular shifts + /// Based on a modification of Knuth-Morris-Pratt algorithm + std::vector compute_common_circular_suffix(const Path_on_surface& p) { + Path_on_surface q(p); + q += p; + std::vector suffix_len(q.length()); + std::size_t match_begin = q.length() - 1, + match_end = q.length() - 1; + suffix_len.back() = q.length(); + for (std::size_t i = q.length() - 2; i >= 0; --i) { + if (i <= match_end || i - suffix_len[i + q.length() - match_begin - 1] <= match_end) { + match_begin = i; + if (i <= match_end) { + match_end = i; + } + while (match_end >= 0 && q[match_end] == q[match_end + q.elngth() - i - 1]) { + --match_end; + } + suffix_len[i] = match_begin - match_end; + } + else { + suffix_len[i] = suffix_len[i + q.length() - match_begin - 1]; + } + } + + std::vector result(suffix_len.begin() + p.length(), suffix_len.end()); + for (std::size_t i = 0; i < result.size(); ++i) { + result[i] = std::min(result[i], p.length()); + } + return result; + } + protected: /// The original map (the mesh seen as a 2-map) const typename Get_map::storage_type m_original_map; From 274542fa9f1fbf564b658fe9fc137198d34f8da8 Mon Sep 17 00:00:00 2001 From: Youmu Date: Wed, 10 Jun 2020 16:53:53 -0400 Subject: [PATCH 005/248] Prepare boost intrusive rbtree. Fix indexing error in KMP and switchable finding --- .../internal/Minimal_quadrangulation.h | 140 ++++++++++++++---- 1 file changed, 113 insertions(+), 27 deletions(-) diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h index 8b03d493ae3..4e9267635db 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h @@ -31,6 +31,8 @@ #include #include #include +#include +#include namespace CGAL { namespace Surface_mesh_topology { @@ -49,6 +51,52 @@ struct Minimal_quadrangulation_local_map_items }; }; +struct Minimal_quadrangulation_simplicity_testing_rbtree_node +{ + Minimal_quadrangulation_simplicity_testing_rbtree_node(std::size_t i) + : m_idx(i) {} + + Minimal_quadrangulation_simplicity_testing_rbtree_node *m_parent, *m_left, *m_right; + int m_color; + std::size_t m_idx; +}; + +struct Minimal_quadrangulation_simplicity_testing_rbtree_node_traits +{ + typedef Minimal_quadrangulation_simplicity_testing_rbtree_node node; + typedef Minimal_quadrangulation_simplicity_testing_rbtree_node* node_ptr; + typedef const Minimal_quadrangulation_simplicity_testing_rbtree_node* const_node_ptr; + typedef int color; + + static node_ptr get_parent(const_node_ptr n) { return n->m_parent; } + static void set_parent(node_ptr n, node_ptr parent) { n->m_parent = parent; } + static node_ptr get_left(const_node_ptr n) { return n->m_left; } + static void set_left(node_ptr n, node_ptr left) { n->m_left = left; } + static node_ptr get_right(const_node_ptr n) { return n->m_right; } + static void set_right(node_ptr n, node_ptr right) { n->m_right = right; } + static color get_color(const_node_ptr n) { return n->m_color; } + static void set_color(node_ptr n, color color) { n->m_color = color; } + static color black() { return color(0); } + static color red() { return color(1); } +}; + +struct Minimal_quadrangulation_simplicity_testing_rbtree_value_traits +{ + typedef Minimal_quadrangulation_simplicity_testing_rbtree_node_traits node_traits; + typedef node_traits::node value_type; + typedef node_traits::node_ptr node_ptr; + typedef node_traits::const_node_ptr const_node_ptr; + typedef value_type* pointer; + typedef value_type const* const_pointer; + + static const boost::intrusive::link_mode_type link_mode = boost::intrusive::link_mode_type::normal_link; + + static node_ptr to_nodeptr(value_type &value) { return &value; } + static const_node_ptr to_nodeptr(const value_type &value) { return &value; } + static pointer to_value_ptr(node_ptr n) { return n; } + static const_pointer to_value_ptr(const_node_ptr n) { return n; } +}; + template class Minimal_quadrangulation { @@ -515,7 +563,7 @@ public: int p = count_edges_of_path_on_cylinder(pt); res=(std::abs(p) <= 1); } - else if (is_contractible()) + else if (is_contractible(p)) { // genus > 1 and contractible res=true; @@ -527,18 +575,52 @@ public: pt=transform_original_path_into_quad_surface_with_rle(p); pt.canonize(); // Use non-rle path from now on - Path_on_surface ps(pt); + Path_on_surface ps(pt); auto factorization=ps.factorize(); - if (factorization.first > 1) { + Path_on_surface& pr = factorization.first; + if (factorization.second > 1) { // If the curve is not primitive, there must be at least // one self intersection res=false; } - // Label the switchable arcs - std::vector switchables = compute_switchable(ps); - // Compute the backward cyclic KMP failure table for the curve - std::vector suffix_len = compute_common_circular_suffix(ps); + /// TODO: remove debug output + pr.display(); + std::cout << std::endl; + pr.display_pos_and_neg_turns(); + std::cout << std::endl; + + + // Label the switchable arcs + std::vector switchables = compute_switchable(pr); + // Compute the backward cyclic KMP failure table for the curve + std::vector suffix_len = compute_common_circular_suffix(pr); + + std::size_t num_sides = degree(get_local_map(), get_local_map().darts().begin()); + + // Mark outoging darts to represent an edge of both directions + auto markoutgoing=get_local_map().get_new_mark(); + auto it = get_local_map().darts().begin(); + Dart_const_handle dh = it; + do { + get_local_map().mark(dh, markoutgoing); + dh=get_local_map().template beta<0,2>(dh); + } while(dh != it); + + typedef boost::intrusive::rbtree> rbtree; + std::vector rb_nodes; + rb_nodes.reserve(pr.length()); + + for (std::size_t i = 0; i < pr.length(); ++i) { + auto dart_order = get_local_map().is_marked(pr[i], markoutgoing) ? + get_local_map().info(pr[i]) : + get_local_map().info(get_local_map().template beta<2>(pr[1])); + std::cout << dart_order << ' '; + rb_nodes.emplace_back(i); + } + + get_local_map().free_mark(markoutgoing); } if (display_time) @@ -1689,23 +1771,26 @@ protected: } /// Compute whether each darts is switchable in the path - std::vector compute_switchable(const Path_on_surface& p) { + std::vector compute_switchable(const Path_on_surface& p) const { std::vector switchables(p.length(), false); std::vector turns = p.compute_positive_turns(); /// Skip the last dart since it can never be switched, nor can it /// be the second last dart of a switch - std::size_t i = p.length() - 2; - while (i >= 0) { - if (turns[i] == 1) { + std::size_t i = 1; + while (i < p.length()) { + std::size_t idx = p.length() - 1 - i; + if (turns[idx] == 1) { /// This is the end of a possible switchbale subpath - --i; - while (i >= 0 && turns[i] == 2) { - switchables[i].flip(); - --i; + ++i; + idx = p.length() - 1 - i; + while (i < p.length() && turns[idx] == 2) { + switchables[idx].flip(); + ++i; + idx = p.length() - 1 - i; } } else { - --i; + ++i; } } return switchables; @@ -1713,26 +1798,27 @@ protected: /// Compute the longest common suffix of a path against all of it circular shifts /// Based on a modification of Knuth-Morris-Pratt algorithm - std::vector compute_common_circular_suffix(const Path_on_surface& p) { - Path_on_surface q(p); + std::vector compute_common_circular_suffix(const Path_on_surface& p) const { + Path_on_surface q(p); q += p; std::vector suffix_len(q.length()); - std::size_t match_begin = q.length() - 1, - match_end = q.length() - 1; + std::size_t match_begin = 0, + match_end = 0; suffix_len.back() = q.length(); - for (std::size_t i = q.length() - 2; i >= 0; --i) { - if (i <= match_end || i - suffix_len[i + q.length() - match_begin - 1] <= match_end) { + for (std::size_t i = 1; i < q.length(); ++i) { + std::size_t match_idx = q.length() - 1 - i; + if (i >= match_end || i + suffix_len[match_idx + match_begin] >= match_end) { match_begin = i; - if (i <= match_end) { + if (i >= match_end) { match_end = i; } - while (match_end >= 0 && q[match_end] == q[match_end + q.elngth() - i - 1]) { - --match_end; + while (match_end < q.length() && q[q.length() - 1 - match_end] == q[q.length() - 1 - (match_end - i)]) { + ++match_end; } - suffix_len[i] = match_begin - match_end; + suffix_len[match_idx] = match_end - match_begin; } else { - suffix_len[i] = suffix_len[i + q.length() - match_begin - 1]; + suffix_len[match_idx] = suffix_len[match_idx + match_begin]; } } From c23b921fe9d437f8b2c98cbf9ef9c46ce2890373 Mon Sep 17 00:00:00 2001 From: Youmu Date: Fri, 12 Jun 2020 19:33:47 -0400 Subject: [PATCH 006/248] detect switch and perform switch in RLE path --- .../internal/Path_on_surface_with_rle.h | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Path_on_surface_with_rle.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Path_on_surface_with_rle.h index ac9aa06af8b..160cc1584e2 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Path_on_surface_with_rle.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Path_on_surface_with_rle.h @@ -1214,6 +1214,15 @@ public: return is_next_flat_can_be_extended_at_beginning(it, dh, dummy1, dummy2); } + /// @return true iff the flat 'it' forms a switchable subpath (aka left-L-shape) + bool is_switchable(const List_iterator& it) + { + CGAL_assertion(is_valid_iterator(it)); + if (it == m_path.begin() || std::next(it) == m_path.end()) { return false; } + std::size_t t=next_positive_turn(it); + return (t==1 && flat_length(it) >= 0); + } + /// Add the given dart 'dh' before the flat 'it'. void add_dart_before(const List_iterator& it, Dart_const_handle dh, Set_of_it& modified_flats) @@ -1452,6 +1461,27 @@ public: it1=merge_modified_flats_when_possible(modified_flats); } + /// Switch the left-L-shape of the subpath starting at 'it' + void switch_flat(List_iterator& it) + { + CGAL_assertion(is_switchable(it)); + Set_of_it modified_flats; + /// Need to switch to t1-1 turn + List_iterator it_next = next_iterator(it); + Dart_const_handle d_new_first_dart = get_map().template beta<0, 2>(begin_of_flat(it)); + Dart_const_handle d_new_flat_begin = get_map().template beta<2, 0>(d_new_first_dart); + Dart_const_handle d_new_flat_end = get_map().template beta<1, 2>(begin_of_flat(it_next)); + + add_dart_before(it, d_new_first_dart, modified_flats); + set_begin_of_flat(it, d_new_flat_begin, modified_flats); + set_end_of_flat(it, d_new_flat_end, modified_flats); + flat_modified(it, modified_flats); + reduce_flat_from_beginning(it_next, modified_flats); + flat_modified(it_next, modified_flats); + + it=merge_modified_flats_when_possible(modified_flats); + } + /// Right push the path, if all all l-shape are pushed, otherwise only one. /// @return true iff the path was pushed bool right_push(bool all=true) From 70f16ca80094f3777b108803a7977ba24a5c0a0b Mon Sep 17 00:00:00 2001 From: Youmu Date: Fri, 12 Jun 2020 19:44:03 -0400 Subject: [PATCH 007/248] Detect trigger of switch in unzip algorithm --- .../internal/Minimal_quadrangulation.h | 85 +++++++++++++++---- 1 file changed, 70 insertions(+), 15 deletions(-) diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h index 4e9267635db..54451850b71 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h @@ -53,7 +53,7 @@ struct Minimal_quadrangulation_local_map_items struct Minimal_quadrangulation_simplicity_testing_rbtree_node { - Minimal_quadrangulation_simplicity_testing_rbtree_node(std::size_t i) + Minimal_quadrangulation_simplicity_testing_rbtree_node(std::size_t i=0) : m_idx(i) {} Minimal_quadrangulation_simplicity_testing_rbtree_node *m_parent, *m_left, *m_right; @@ -91,8 +91,8 @@ struct Minimal_quadrangulation_simplicity_testing_rbtree_value_traits static const boost::intrusive::link_mode_type link_mode = boost::intrusive::link_mode_type::normal_link; - static node_ptr to_nodeptr(value_type &value) { return &value; } - static const_node_ptr to_nodeptr(const value_type &value) { return &value; } + static node_ptr to_node_ptr(value_type &value) { return &value; } + static const_node_ptr to_node_ptr(const value_type &value) { return &value; } static pointer to_value_ptr(node_ptr n) { return n; } static const_pointer to_value_ptr(const_node_ptr n) { return n; } }; @@ -583,6 +583,8 @@ public: // one self intersection res=false; } + /// TODO: very messy if not using RLE. Need to redo and make + // use of RLE /// TODO: remove debug output pr.display(); @@ -600,24 +602,75 @@ public: // Mark outoging darts to represent an edge of both directions auto markoutgoing=get_local_map().get_new_mark(); - auto it = get_local_map().darts().begin(); - Dart_const_handle dh = it; - do { - get_local_map().mark(dh, markoutgoing); - dh=get_local_map().template beta<0,2>(dh); - } while(dh != it); + { + auto it = get_local_map().darts().begin(); + Dart_const_handle dh = it; + do { + std::cout << get_local_map().info(dh) << ' '; + get_local_map().mark(dh, markoutgoing); + dh=get_local_map().template beta<0,2>(dh); + } while(dh != it); + //TODO: remove debug output + std::cout << std::endl; + } - typedef boost::intrusive::rbtree> rbtree; + typedef typename boost::intrusive::rbtree> rbtree; std::vector rb_nodes; rb_nodes.reserve(pr.length()); + std::vector trees(num_sides); + std::size_t outoging_parity = get_local_map().is_marked(pr[0], markoutgoing) ? 0 : 1; for (std::size_t i = 0; i < pr.length(); ++i) { - auto dart_order = get_local_map().is_marked(pr[i], markoutgoing) ? - get_local_map().info(pr[i]) : - get_local_map().info(get_local_map().template beta<2>(pr[1])); - std::cout << dart_order << ' '; + Dart_const_handle dh = pr[i]; + auto is_outgoing = i % 2 == outoging_parity; + auto dart_id = is_outgoing ? + get_local_map().info(dh) : + get_local_map().info(get_local_map().opposite2(dh)); + //TODO: remove debug output + std::cout << dart_id << ' '; rb_nodes.emplace_back(i); + auto& node = rb_nodes.back(); + + // Check whether current darts needs to be switched + if (bool(switchables[i])) { + // Look at the t-1 turn of [i-1, i, i + 1] + Dart_const_handle dleft = get_local_map().template beta<0, 2>(dh); + auto left_order = is_outgoing ? + get_local_map().info(dleft) : + get_local_map().info(get_local_map().opposite2(dh)); + // Binary search within potential switch trigger + // TODO: apply the optimization Francis mentioned by only look at the largest one + auto orientation_start = get_local_map().info(dh); + auto to_order = [i, &pr, this] (const std::size_t& j) -> decltype(get_local_map().info(dh)) { + auto is_outgoing_wrt_cur_dart = (j % 2) == (i % 2); + /// Choose the correct predecessor/successor and make sure they are pointing the same direction as [i, i+1] + if (j == 0 && is_outgoing_wrt_cur_dart) { + return this->get_local_map().info(pr[0]); + } + Dart_const_handle dneighbor = is_outgoing_wrt_cur_dart ? this->get_local_map().template beta<0, 2>(pr[j - 1]) : pr[j + 1]; + return this->get_local_map().info(dneighbor); + }; + auto comparator = [to_order, orientation_start, num_sides] (const std::size_t& key, const rbtree::value_type& b) -> bool { + std::size_t order_b = to_order(b.m_idx); + order_b += (order_b > orientation_start) ? num_sides : 2 * num_sides; + return key > order_b; + }; + auto comparator_wrapper = [&comparator] () -> decltype(comparator) { + return comparator; + }; + std::size_t target_order = to_order(i); + target_order += (target_order > orientation_start) ? num_sides : 2 * num_sides; + auto it_trigger = trees[left_order].upper_bound(target_order, comparator); + if (it_trigger != trees[left_order].end()) { + // Switch the edge + + } + } + // Insert current darts + if (trees[dart_id].empty()) { + trees[dart_id].push_back(node); + } } get_local_map().free_mark(markoutgoing); @@ -1781,6 +1834,7 @@ protected: std::size_t idx = p.length() - 1 - i; if (turns[idx] == 1) { /// This is the end of a possible switchbale subpath + switchables[idx].flip(); ++i; idx = p.length() - 1 - i; while (i < p.length() && turns[idx] == 2) { @@ -1793,6 +1847,7 @@ protected: ++i; } } + switchables[0] = false; return switchables; } From 5d1a7bd65023540f344c58066d9acd36d0642a58 Mon Sep 17 00:00:00 2001 From: Youmu Date: Mon, 15 Jun 2020 16:28:47 -0400 Subject: [PATCH 008/248] Add a per-dart iterator to Path_on_surface_with_rle. Allow to switch subpath of Path_on_surface_with_rle at a dart_iterator. --- .../internal/Path_on_surface_with_rle.h | 160 +++++++++++++++++- 1 file changed, 153 insertions(+), 7 deletions(-) diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Path_on_surface_with_rle.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Path_on_surface_with_rle.h index 160cc1584e2..aa8dd8a2336 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Path_on_surface_with_rle.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Path_on_surface_with_rle.h @@ -95,6 +95,119 @@ protected: const Local_map& m_map; }; +// Small wrapper to provide per dart iterator on a Path_on_surface_with_rle +template +class Dart_iterator +{ +public: + typedef Dart_iterator Self; + typedef Path_ Path; + typedef typename Path::Map Map; + typedef typename Map::Dart_handle Dart_handle; + typedef typename Map::Dart_const_handle Dart_const_handle; + typedef CFlat Flat; + typedef typename Path::List_iterator List_iterator; + typedef std::ptrdiff_t difference_type; + typedef Dart_const_handle value_type; + typedef Dart_const_handle* pointer; + typedef Dart_const_handle& reference; + typedef std::bidirectional_iterator_tag iterator_category; + + Dart_iterator(const Path_& path, const List_iterator& it_flat, bool is_end = false) + : m_path(path), + m_it_flat(it_flat), + m_curr_idx_in_flat(0), + m_curr_dart(is_end ? nullptr : it_flat->begin) + {} + + Dart_const_handle operator*() const { + CGAL_assertion(m_it_flat != m_path.m_path.end()); + return m_curr_dart; + } + + Self& operator++() { + CGAL_assertion(m_it_flat != m_path.m_path.end()); + increment(); + return *this; + } + + Self operator++(int) { + CGAL_assertion(m_it_flat != m_path.m_path.end()); + Self pre_increment(*this); + increment(); + return pre_increment; + } + + Self& operator--() { + CGAL_assertion(m_it_flat != m_path.m_path.begin()); + decrement(); + return *this; + } + + Self operator--(int) { + CGAL_assertion(m_it_flat != m_path.m_path.begin()); + Self pre_decrement(*this); + decrement(); + return pre_decrement; + } + + void increment() { + if (m_curr_idx_in_flat == std::abs(m_it_flat->length)) { + m_it_flat = std::next(m_it_flat); + m_curr_idx_in_flat = 0; + if (m_it_flat != m_path.m_path.end()) { + m_curr_dart = m_it_flat->begin; + } + } + else { + ++m_curr_idx_in_flat; + if (m_it_flat->length > 0) { + m_curr_dart = m_path.get_map().template beta<1, 2, 1>(m_curr_dart); + } + else { + m_curr_dart = m_path.get_map().template beta<2, 0, 2, 0, 2>(m_curr_dart); + } + } + } + + void decrement() { + if (m_curr_idx_in_flat == 0) { + m_it_flat = std::prev(m_it_flat); + m_curr_idx_in_flat = std::abs(m_it_flat->length); + m_curr_dart = m_it_flat->end; + } + else { + --m_curr_idx_in_flat; + if (m_it_flat->length > 0) { + m_curr_dart = m_path.get_map().template beta<0, 2, 0>(m_curr_dart); + } + else { + m_curr_dart = m_path.get_map().template beta<2, 1, 2, 1, 2>(m_curr_dart); + } + } + } + + bool operator==(const Self& other) const { + return m_it_flat == other.m_it_flat && m_curr_idx_in_flat == other.m_curr_idx_in_flat; + } + + bool operator!=(const Self& other) const { + return !(*this == other); + } + + Self& operator=(const Self& other) { + m_it_flat = other.m_it_flat; + m_curr_idx_in_flat = other.m_curr_idx_in_flat; + m_curr_dart = other.m_curr_dart; + return *this; + } + + const Path_& m_path; + List_iterator m_it_flat; + std::size_t m_curr_idx_in_flat; + Dart_const_handle m_curr_dart; +}; + template // MQ for minimal quadrangulation class Path_on_surface_with_rle { @@ -107,9 +220,11 @@ public: typedef CFlat Flat; typedef std::list List_of_flats; typedef typename List_of_flats::iterator List_iterator; + typedef Dart_iterator Dart_iterator; // TODO typedef typename List_of_dart_length::const_iterator List_const_iterator; friend class Path_on_surface; + friend Dart_iterator; struct List_iterator_hash { @@ -433,6 +548,18 @@ public: return end_of_flat(std::prev(m_path.end())); } + /// @return the beginning of an iterator through all the darts + Dart_iterator begin() + { + return Dart_iterator(*this, m_path.begin(), is_empty()); + } + + /// @return the end of the iterator through all the darts + Dart_iterator end() + { + return Dart_iterator(*this, m_path.end(), true); + } + /// @return true iff df can be added at the end of the path. bool can_be_pushed(Dart_const_handle dh) { @@ -1223,6 +1350,12 @@ public: return (t==1 && flat_length(it) >= 0); } + /// @return true iff the dart 'it_dart' forms a switchable subpath (aka left-L-shape) + bool is_switchable(const Dart_iterator& it_dart) { + CGAL_assertion(it_dart != end()); + return is_switchable(it_dart.m_it_flat); + } + /// Add the given dart 'dh' before the flat 'it'. void add_dart_before(const List_iterator& it, Dart_const_handle dh, Set_of_it& modified_flats) @@ -1462,24 +1595,37 @@ public: } /// Switch the left-L-shape of the subpath starting at 'it' - void switch_flat(List_iterator& it) + void switch_dart(Dart_iterator& it_dart) { - CGAL_assertion(is_switchable(it)); + CGAL_assertion(is_switchable(it_dart)); + List_iterator it = it_dart.m_it_flat; Set_of_it modified_flats; + /// Break current flat into 3 pieces: + /// previous unswitched flat, current dart, next switched flat + if (it_dart.m_curr_idx_in_flat > 0) { + add_dart_before(it, it->begin, modified_flats); + List_iterator it_prev = std::prev(it); + set_end_of_flat(it_prev, get_map().template beta<0, 2, 0>(*it_dart)); + set_flat_length(it_prev, it_dart.m_curr_idx_in_flat - 1); + flat_modified(it_prev, modified_flats); + } /// Need to switch to t1-1 turn List_iterator it_next = next_iterator(it); - Dart_const_handle d_new_first_dart = get_map().template beta<0, 2>(begin_of_flat(it)); - Dart_const_handle d_new_flat_begin = get_map().template beta<2, 0>(d_new_first_dart); + Dart_const_handle d_new_first_dart = get_map().template beta<0, 2>(*it_dart); + Dart_const_handle d_new_flat_begin = get_map().template beta<2, 0, 2>(d_new_first_dart); Dart_const_handle d_new_flat_end = get_map().template beta<1, 2>(begin_of_flat(it_next)); add_dart_before(it, d_new_first_dart, modified_flats); - set_begin_of_flat(it, d_new_flat_begin, modified_flats); - set_end_of_flat(it, d_new_flat_end, modified_flats); + set_begin_of_flat(it, d_new_flat_begin); + set_end_of_flat(it, d_new_flat_end); + set_flat_length(it, -(it->length - it_dart.m_curr_idx_in_flat)); flat_modified(it, modified_flats); reduce_flat_from_beginning(it_next, modified_flats); flat_modified(it_next, modified_flats); - it=merge_modified_flats_when_possible(modified_flats); + merge_modified_flats_when_possible(modified_flats); + it_dart = Dart_iterator(*this, it); + --it_dart; } /// Right push the path, if all all l-shape are pushed, otherwise only one. From e383bc7d6b559d19190b89b0e5f528c1eb643676 Mon Sep 17 00:00:00 2001 From: Youmu Date: Mon, 15 Jun 2020 16:32:54 -0400 Subject: [PATCH 009/248] Set up switching edge check for rle-version of path --- .../internal/Minimal_quadrangulation.h | 32 ++++++++++++------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h index 54451850b71..453198d2231 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h @@ -575,9 +575,11 @@ public: pt=transform_original_path_into_quad_surface_with_rle(p); pt.canonize(); // Use non-rle path from now on - Path_on_surface ps(pt); - auto factorization=ps.factorize(); - Path_on_surface& pr = factorization.first; + auto factorization=pt.factorize(); + internal::Path_on_surface_with_rle& pr_rle = factorization.first; + Path_on_surface pr(pr_rle); + std::vector p_visited; + pr.simplify_flips(); if (factorization.second > 1) { // If the curve is not primitive, there must be at least // one self intersection @@ -585,16 +587,16 @@ public: } /// TODO: very messy if not using RLE. Need to redo and make // use of RLE - /// TODO: remove debug output pr.display(); std::cout << std::endl; pr.display_pos_and_neg_turns(); std::cout << std::endl; + pr_rle.display(); + std::cout << std::endl; + pr_rle.display_pos_and_neg_turns(); + std::cout << std::endl; - - // Label the switchable arcs - std::vector switchables = compute_switchable(pr); // Compute the backward cyclic KMP failure table for the curve std::vector suffix_len = compute_common_circular_suffix(pr); @@ -621,8 +623,9 @@ public: std::vector trees(num_sides); std::size_t outoging_parity = get_local_map().is_marked(pr[0], markoutgoing) ? 0 : 1; - for (std::size_t i = 0; i < pr.length(); ++i) { - Dart_const_handle dh = pr[i]; + std::size_t i = 0; + for (auto it_dart = pr_rle.begin(); it_dart != pr_rle.end(); ++it_dart, ++i) { + Dart_const_handle dh = *it_dart; auto is_outgoing = i % 2 == outoging_parity; auto dart_id = is_outgoing ? get_local_map().info(dh) : @@ -633,7 +636,7 @@ public: auto& node = rb_nodes.back(); // Check whether current darts needs to be switched - if (bool(switchables[i])) { + if (pr_rle.is_switchable(it_dart)) { // Look at the t-1 turn of [i-1, i, i + 1] Dart_const_handle dleft = get_local_map().template beta<0, 2>(dh); auto left_order = is_outgoing ? @@ -642,6 +645,7 @@ public: // Binary search within potential switch trigger // TODO: apply the optimization Francis mentioned by only look at the largest one auto orientation_start = get_local_map().info(dh); + // Convert a dart to a circular ordering index auto to_order = [i, &pr, this] (const std::size_t& j) -> decltype(get_local_map().info(dh)) { auto is_outgoing_wrt_cur_dart = (j % 2) == (i % 2); /// Choose the correct predecessor/successor and make sure they are pointing the same direction as [i, i+1] @@ -664,13 +668,19 @@ public: auto it_trigger = trees[left_order].upper_bound(target_order, comparator); if (it_trigger != trees[left_order].end()) { // Switch the edge - + pr_rle.switch_dart(it_dart); + dh = *it_dart; } } // Insert current darts if (trees[dart_id].empty()) { trees[dart_id].push_back(node); } + else { + /// TODO: first check overlap of prceeding edge + } + + p_visited.push_back(dh); } get_local_map().free_mark(markoutgoing); From b28b5c0d1ca0cba894374c05e219370c8ad3fd63 Mon Sep 17 00:00:00 2001 From: Youmu Date: Wed, 17 Jun 2020 17:00:09 -0400 Subject: [PATCH 010/248] Provide an implementation of switching for Path_on_surface --- .../include/CGAL/Path_on_surface.h | 70 +++++++++++++++++++ .../internal/Minimal_quadrangulation.h | 31 +------- 2 files changed, 72 insertions(+), 29 deletions(-) diff --git a/Surface_mesh_topology/include/CGAL/Path_on_surface.h b/Surface_mesh_topology/include/CGAL/Path_on_surface.h index 40932947472..41c1b295a4f 100644 --- a/Surface_mesh_topology/include/CGAL/Path_on_surface.h +++ b/Surface_mesh_topology/include/CGAL/Path_on_surface.h @@ -1224,6 +1224,68 @@ public: return true; } + /// Compute whether each dart is switchable + void compute_switchable() + { + m_switchable.clear(); + m_switchable.resize(length(), false); + std::vector turns = compute_positive_turns(); + /// Skip the last dart since it can never be switched, nor can it + /// be the second last dart of a switch + std::size_t i = 1; + while (i < length()) + { + std::size_t idx = length() - 1 - i; + if (turns[idx] == 1) + { + /// This is the end of a possible switchbale subpath + m_switchable[idx].flip(); + ++i; + idx = length() - 1 - i; + while (i < length() && turns[idx] == 2) + { + m_switchable[idx].flip(); + ++i; + idx = length() - 1 - i; + } + } else + { + ++i; + } + } + m_switchable[0] = false; + } + + /// Report whether 'i'-th dart is switchable, needs to compute switchable first + bool is_switchable(std::size_t i) const + { + CGAL_assertion(m_switchable.size() == length()); + return i < length() && m_switchable[i]; + } + + /// Perform a switch starting at 'i'-th dart + void switch_dart(std::size_t i) + { + CGAL_assertion(is_switchable(i)); + m_path[i] = get_map().template beta<0, 2>(m_path[i]); + m_path[i + 1] = get_map().template beta<2, 0, 2>(m_path[i]); + m_switchable[i] = false; + /// It is guarantee that the last dart is not switchable + std::size_t j = i + 2; + for(; is_switchable(j - 1); ++j) + { + m_path[j] = get_map().template beta<2, 0, 2, 0, 2>(m_path[j - 1]); + m_switchable[j - 1] = false; + } + /// Last dart may become switchable + if ((is_switchable(j) && next_positive_turn(j - 1) == 2) || + next_positive_turn(j - 1) == 1) + { + m_switchable[j - 1] = true; + } + CGAL_assertion(is_valid()); + } + bool same_turns(const char* turns) const { std::vector resplus=compute_positive_turns(); @@ -1279,6 +1341,13 @@ public: { std::cout<<" c "; } //< m_path; /// The sequence of darts bool m_is_closed; /// True iff the path is a cycle std::vector m_flip; /// The sequence of flips + std::vector m_switchable; /// True iff the correspondent dart is switchable }; } // namespace Surface_mesh_topology diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h index 453198d2231..10ee59b8d90 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h @@ -1833,37 +1833,10 @@ protected: return res; } - /// Compute whether each darts is switchable in the path - std::vector compute_switchable(const Path_on_surface& p) const { - std::vector switchables(p.length(), false); - std::vector turns = p.compute_positive_turns(); - /// Skip the last dart since it can never be switched, nor can it - /// be the second last dart of a switch - std::size_t i = 1; - while (i < p.length()) { - std::size_t idx = p.length() - 1 - i; - if (turns[idx] == 1) { - /// This is the end of a possible switchbale subpath - switchables[idx].flip(); - ++i; - idx = p.length() - 1 - i; - while (i < p.length() && turns[idx] == 2) { - switchables[idx].flip(); - ++i; - idx = p.length() - 1 - i; - } - } - else { - ++i; - } - } - switchables[0] = false; - return switchables; - } - /// Compute the longest common suffix of a path against all of it circular shifts /// Based on a modification of Knuth-Morris-Pratt algorithm - std::vector compute_common_circular_suffix(const Path_on_surface& p) const { + std::vector compute_common_circular_suffix(const Path_on_surface& p) const + { Path_on_surface q(p); q += p; std::vector suffix_len(q.length()); From 9dfec6f0d4a083d08e6edcd62d1a0216fb7ffb72 Mon Sep 17 00:00:00 2001 From: Youmu Date: Wed, 17 Jun 2020 17:01:27 -0400 Subject: [PATCH 011/248] Add helper functions to navigate in the path based on dart direction --- .../internal/Minimal_quadrangulation.h | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h index 10ee59b8d90..acd961d68b6 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h @@ -1867,6 +1867,63 @@ protected: return result; } + size_type get_order_relative_to(Dart_const_handle x, Dart_const_handle ref, size_type num_sides) + { + size_type ref_order = get_dart_id(ref, ref), + x_order = get_dart_id(x, ref); + return x_order <= ref_order ? (x_order + num_sides - ref_order - 1) : (x_order - ref_order - 1); + } + + int get_previous_idx_relative_to(const Path_on_surface&p, std::size_t i, Dart_const_handle ref) const + { + return get_local_map().template belong_to_same_cell<0>(p[i], ref) ? static_cast(i) - 1, static_cast(i) + 1; + } + + bool has_previous_relative_to(const Path_on_surface& p, std::size_t i, Dart_const_handle ref) const + { + CGAL_assertion(get_local_map().template belong_to_same_cell<1>(p[i], ref)); + int j = get_previous_idx_relative_to(p, i, ref); + return j >= 0 && j < p.length(); + } + + Dart_const_handle get_previous_relative_to(const Path_on_surface& p, std::size_t i, Dart_const_handle ref) const + { + CGAL_assertion(get_local_map().template belong_to_same_cell<1>(p[i], ref)); + int j = get_previous_idx_relative_to(p, i, ref); + if (j < 0) { j += p.length(); } + else if (j >= p.length()) { j -= p.length(); } + return p[j]; + } + + int get_next_idx_relative_to(const Path_on_surface&p, std::size_t i, Dart_const_handle ref) const + { + return get_local_map().template belong_to_same_cell<0>(p[i], ref) ? static_cast(i) + 1, static_cast(i) - 1; + } + + bool has_next_relative_to(const Path_on_surface& p, std::size_t i, Dart_const_handle ref) const + { + CGAL_assertion(get_local_map().template belong_to_same_cell<1>(p[i], ref)); + int j = get_next_idx_relative_to(p, i, ref); + return j >= 0 && j < p.length(); + } + + Dart_const_handle get_next_relative_to(const Path_on_surface& p, std::size_t i, Dart_const_handle ref) const + { + CGAL_assertion(get_local_map().template belong_to_same_cell<1>(p[i], ref)); + int j = get_next_idx_relative_to(p, i, ref); + if (j < 0) { j += p.length(); } + else if (j >= p.length()) { j -= p.length(); } + return p[j]; + } + + size_type get_dart_id(Dart_const_handle x, Dart_const_handle ref) + { + return get_local_map().template belong_to_same_cell<0>(x, ref) ? + get_local_map().info(x) : + get_local_map().info(get_local_map().opposite2(x)); + } + } + protected: /// The original map (the mesh seen as a 2-map) const typename Get_map::storage_type m_original_map; From 4b17d38b85e5f67debc2572bbb9eca70631a9f62 Mon Sep 17 00:00:00 2001 From: Youmu Date: Wed, 17 Jun 2020 17:14:41 -0400 Subject: [PATCH 012/248] Slightly tweak helper functions --- .../internal/Minimal_quadrangulation.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h index acd961d68b6..ec3de37af81 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h @@ -1867,16 +1867,16 @@ protected: return result; } - size_type get_order_relative_to(Dart_const_handle x, Dart_const_handle ref, size_type num_sides) + size_type get_order_relative_to(Dart_const_handle x, Dart_const_handle ref, size_type num_sides) const { - size_type ref_order = get_dart_id(ref, ref), - x_order = get_dart_id(x, ref); + size_type ref_order = get_dart_id_relative_to(ref, ref), + x_order = get_dart_id_relative_to(x, ref); return x_order <= ref_order ? (x_order + num_sides - ref_order - 1) : (x_order - ref_order - 1); } int get_previous_idx_relative_to(const Path_on_surface&p, std::size_t i, Dart_const_handle ref) const { - return get_local_map().template belong_to_same_cell<0>(p[i], ref) ? static_cast(i) - 1, static_cast(i) + 1; + return get_local_map().template belong_to_same_cell<0>(p[i], ref) ? (static_cast(i) - 1) : (static_cast(i) + 1); } bool has_previous_relative_to(const Path_on_surface& p, std::size_t i, Dart_const_handle ref) const @@ -1897,7 +1897,7 @@ protected: int get_next_idx_relative_to(const Path_on_surface&p, std::size_t i, Dart_const_handle ref) const { - return get_local_map().template belong_to_same_cell<0>(p[i], ref) ? static_cast(i) + 1, static_cast(i) - 1; + return get_local_map().template belong_to_same_cell<0>(p[i], ref) ? (static_cast(i) + 1) : (static_cast(i) - 1); } bool has_next_relative_to(const Path_on_surface& p, std::size_t i, Dart_const_handle ref) const @@ -1916,7 +1916,7 @@ protected: return p[j]; } - size_type get_dart_id(Dart_const_handle x, Dart_const_handle ref) + size_type get_dart_id_relative_to(Dart_const_handle x, Dart_const_handle ref) const { return get_local_map().template belong_to_same_cell<0>(x, ref) ? get_local_map().info(x) : From 21ec3ab3e153847ddf562e999e77def074399f6c Mon Sep 17 00:00:00 2001 From: Youmu Date: Wed, 17 Jun 2020 17:16:09 -0400 Subject: [PATCH 013/248] Correctly handle switch case by also looking at the direction of darts --- .../internal/Minimal_quadrangulation.h | 102 +++++++----------- 1 file changed, 37 insertions(+), 65 deletions(-) diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h index ec3de37af81..c57ec0fc714 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h @@ -576,100 +576,76 @@ public: pt.canonize(); // Use non-rle path from now on auto factorization=pt.factorize(); - internal::Path_on_surface_with_rle& pr_rle = factorization.first; - Path_on_surface pr(pr_rle); - std::vector p_visited; + Path_on_surface pr(factorization.first); pr.simplify_flips(); + Path_on_surface p_original(pr); if (factorization.second > 1) { // If the curve is not primitive, there must be at least // one self intersection - res=false; + return false; } - /// TODO: very messy if not using RLE. Need to redo and make - // use of RLE + /// TODO: remove debug output pr.display(); std::cout << std::endl; pr.display_pos_and_neg_turns(); std::cout << std::endl; - pr_rle.display(); - std::cout << std::endl; - pr_rle.display_pos_and_neg_turns(); - std::cout << std::endl; // Compute the backward cyclic KMP failure table for the curve std::vector suffix_len = compute_common_circular_suffix(pr); - std::size_t num_sides = degree(get_local_map(), get_local_map().darts().begin()); - // Mark outoging darts to represent an edge of both directions - auto markoutgoing=get_local_map().get_new_mark(); - { - auto it = get_local_map().darts().begin(); - Dart_const_handle dh = it; - do { - std::cout << get_local_map().info(dh) << ' '; - get_local_map().mark(dh, markoutgoing); - dh=get_local_map().template beta<0,2>(dh); - } while(dh != it); - //TODO: remove debug output - std::cout << std::endl; - } - typedef typename boost::intrusive::rbtree> rbtree; std::vector rb_nodes; rb_nodes.reserve(pr.length()); std::vector trees(num_sides); - std::size_t outoging_parity = get_local_map().is_marked(pr[0], markoutgoing) ? 0 : 1; - std::size_t i = 0; - for (auto it_dart = pr_rle.begin(); it_dart != pr_rle.end(); ++it_dart, ++i) { - Dart_const_handle dh = *it_dart; - auto is_outgoing = i % 2 == outoging_parity; - auto dart_id = is_outgoing ? - get_local_map().info(dh) : - get_local_map().info(get_local_map().opposite2(dh)); + for (std::size_t i = 0; i < pr.length(); ++i) + { + Dart_const_handle dh = pr[i]; + auto dart_id = get_dart_id_relative_to(pr[i], pr[0]); //TODO: remove debug output std::cout << dart_id << ' '; rb_nodes.emplace_back(i); auto& node = rb_nodes.back(); // Check whether current darts needs to be switched - if (pr_rle.is_switchable(it_dart)) { + if (pr.is_switchable(i)) + { // Look at the t-1 turn of [i-1, i, i + 1] Dart_const_handle dleft = get_local_map().template beta<0, 2>(dh); - auto left_order = is_outgoing ? - get_local_map().info(dleft) : - get_local_map().info(get_local_map().opposite2(dh)); + auto dleft_id = get_dart_id_relative_to(dleft, pr[0]); // Binary search within potential switch trigger // TODO: apply the optimization Francis mentioned by only look at the largest one - auto orientation_start = get_local_map().info(dh); // Convert a dart to a circular ordering index - auto to_order = [i, &pr, this] (const std::size_t& j) -> decltype(get_local_map().info(dh)) { - auto is_outgoing_wrt_cur_dart = (j % 2) == (i % 2); - /// Choose the correct predecessor/successor and make sure they are pointing the same direction as [i, i+1] - if (j == 0 && is_outgoing_wrt_cur_dart) { - return this->get_local_map().info(pr[0]); + auto to_order = [this, &pr, &dleft, num_sides] (const std::size_t& j) -> size_type + { + Dart_const_handle dprev = this->get_previous_relative_to(pr, j, dleft); + return this->get_order_relative_to(dprev, dleft, num_sides); + }; + size_type key_val = get_order_relative_to(pr[i - 1], dleft, num_sides); + if (get_local_map().template belong_to_same_cell<0>(dh, pr[0])) + { + auto comparator = [&to_order, num_sides] (const std::size_t& key, const rbtree::value_type& b) -> bool { + return key > to_order(b.m_idx); + }; + auto it_trigger = trees[dleft_id].upper_bound(key_val, comparator); + if (it_trigger != trees[dleft_id].end() && !get_local_map().template belong_to_same_cell<1>(pr[it_trigger->m_idx], dh)) + { + pr.switch_dart(i); + } + } + else + { + auto comparator = [&to_order, num_sides] (const std::size_t& key, const rbtree::value_type& b) -> bool { + return key < to_order(b.m_idx); + }; + auto it_trigger = trees[dleft_id].upper_bound(0, comparator); + if (it_trigger != trees[dleft_id].end() && to_order(it_trigger->m_idx) < key_val) + { + pr.switch_dart(i); } - Dart_const_handle dneighbor = is_outgoing_wrt_cur_dart ? this->get_local_map().template beta<0, 2>(pr[j - 1]) : pr[j + 1]; - return this->get_local_map().info(dneighbor); - }; - auto comparator = [to_order, orientation_start, num_sides] (const std::size_t& key, const rbtree::value_type& b) -> bool { - std::size_t order_b = to_order(b.m_idx); - order_b += (order_b > orientation_start) ? num_sides : 2 * num_sides; - return key > order_b; - }; - auto comparator_wrapper = [&comparator] () -> decltype(comparator) { - return comparator; - }; - std::size_t target_order = to_order(i); - target_order += (target_order > orientation_start) ? num_sides : 2 * num_sides; - auto it_trigger = trees[left_order].upper_bound(target_order, comparator); - if (it_trigger != trees[left_order].end()) { - // Switch the edge - pr_rle.switch_dart(it_dart); - dh = *it_dart; } } // Insert current darts @@ -679,11 +655,7 @@ public: else { /// TODO: first check overlap of prceeding edge } - - p_visited.push_back(dh); } - - get_local_map().free_mark(markoutgoing); } if (display_time) From 0b8ad2ea932dc63b2dc762f36cc1741db6a9b604 Mon Sep 17 00:00:00 2001 From: Youmu Date: Wed, 17 Jun 2020 17:17:02 -0400 Subject: [PATCH 014/248] Handle case where current dart is adjacent to another exactly the same turn --- .../internal/Minimal_quadrangulation.h | 31 +++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h index c57ec0fc714..bc61e9ece6a 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h @@ -649,11 +649,28 @@ public: } } // Insert current darts - if (trees[dart_id].empty()) { + if (trees[dart_id].empty()) + { trees[dart_id].push_back(node); } - else { - /// TODO: first check overlap of prceeding edge + else + { + size_type prev_dart_id = get_dart_id_relative_to(pr[i - 1], pr[0]); + auto it_prev = trees[prev_dart_id].iterator_to(rb_nodes[i - 1]); + if (it_prev != trees[prev_dart_id].begin() && is_same_corner(pr, std::prev(it_prev)->m_idx, i - 1)) + { + auto it_after = trees[dart_id].iterator_to(rb_nodes[get_next_idx_relative_to(pr, std::prev(it_prev)->m_idx, pr[i - 1])]); + trees[dart_id].insert_before(it_after, node); + } + else if (std::next(it_prev) != trees[prev_dart_id].end() && is_same_corner(pr, std::next(it_prev)->m_idx, i - 1)) + { + auto it_before = trees[dart_id].iterator_to(rb_nodes[get_next_idx_relative_to(pr, std::next(it_prev)->m_idx, pr[i-1])]); + trees[dart_id].insert_before(std::next(it_before), node); + } + else + { + // TODO: insert into the tree guaranteed no same corner instance + } } } } @@ -1894,6 +1911,14 @@ protected: get_local_map().info(x) : get_local_map().info(get_local_map().opposite2(x)); } + + bool is_same_corner(const Path_on_surface& p, std::size_t j, std::size_t ref) const + { + if (!has_next_relative_to(p, j, p[ref])) + { + return false; + } + return get_local_map().template belong_to_same_cell<1>(get_next_relative_to(p, j, p[ref]), p[ref + 1]); } protected: From a40c79037fcf7d9e9419919716d9a3b4692b4c83 Mon Sep 17 00:00:00 2001 From: Youmu Date: Mon, 22 Jun 2020 21:20:03 -0400 Subject: [PATCH 015/248] Insertion of dart into correspondent tree --- .../internal/Minimal_quadrangulation.h | 228 ++++++++++++------ 1 file changed, 155 insertions(+), 73 deletions(-) diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h index bc61e9ece6a..0f88da95af5 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h @@ -563,7 +563,7 @@ public: int p = count_edges_of_path_on_cylinder(pt); res=(std::abs(p) <= 1); } - else if (is_contractible(p)) + else if (is_contractible(p)) { // genus > 1 and contractible res=true; @@ -579,99 +579,181 @@ public: Path_on_surface pr(factorization.first); pr.simplify_flips(); Path_on_surface p_original(pr); - if (factorization.second > 1) { + if (factorization.second <= 1) { // If the curve is not primitive, there must be at least // one self intersection - return false; - } - /// TODO: remove debug output - pr.display(); - std::cout << std::endl; - pr.display_pos_and_neg_turns(); - std::cout << std::endl; + /// TODO: remove debug output + pr.display(); + std::cout << std::endl; + pr.display_pos_and_neg_turns(); + std::cout << std::endl; - // Compute the backward cyclic KMP failure table for the curve - std::vector suffix_len = compute_common_circular_suffix(pr); - std::size_t num_sides = degree(get_local_map(), get_local_map().darts().begin()); + // Compute the backward cyclic KMP failure table for the curve + std::vector suffix_len = compute_common_circular_suffix(pr); + std::size_t num_sides = degree(get_local_map(), get_local_map().darts().begin()); - typedef typename boost::intrusive::rbtree> rbtree; - std::vector rb_nodes; - rb_nodes.reserve(pr.length()); - std::vector trees(num_sides); + typedef typename boost::intrusive::rbtree> rbtree; + std::vector rb_nodes; + rb_nodes.reserve(pr.length()); + std::vector trees(num_sides); - for (std::size_t i = 0; i < pr.length(); ++i) - { - Dart_const_handle dh = pr[i]; - auto dart_id = get_dart_id_relative_to(pr[i], pr[0]); - //TODO: remove debug output - std::cout << dart_id << ' '; - rb_nodes.emplace_back(i); - auto& node = rb_nodes.back(); - - // Check whether current darts needs to be switched - if (pr.is_switchable(i)) + for (std::size_t i = 0; i < pr.length(); ++i) { - // Look at the t-1 turn of [i-1, i, i + 1] - Dart_const_handle dleft = get_local_map().template beta<0, 2>(dh); - auto dleft_id = get_dart_id_relative_to(dleft, pr[0]); - // Binary search within potential switch trigger - // TODO: apply the optimization Francis mentioned by only look at the largest one - // Convert a dart to a circular ordering index - auto to_order = [this, &pr, &dleft, num_sides] (const std::size_t& j) -> size_type + Dart_const_handle dh = pr[i]; + auto dart_id = get_dart_id_relative_to(pr[i], pr[0]); + //TODO: remove debug output + std::cout << dart_id << ' '; + rb_nodes.emplace_back(i); + auto& node = rb_nodes.back(); + + // Check whether current darts needs to be switched + if (pr.is_switchable(i)) { - Dart_const_handle dprev = this->get_previous_relative_to(pr, j, dleft); - return this->get_order_relative_to(dprev, dleft, num_sides); - }; - size_type key_val = get_order_relative_to(pr[i - 1], dleft, num_sides); - if (get_local_map().template belong_to_same_cell<0>(dh, pr[0])) - { - auto comparator = [&to_order, num_sides] (const std::size_t& key, const rbtree::value_type& b) -> bool { - return key > to_order(b.m_idx); - }; - auto it_trigger = trees[dleft_id].upper_bound(key_val, comparator); - if (it_trigger != trees[dleft_id].end() && !get_local_map().template belong_to_same_cell<1>(pr[it_trigger->m_idx], dh)) + // Look at the t-1 turn of [i-1, i, i + 1] + Dart_const_handle dleft = get_local_map().template beta<0, 2>(dh); + auto dleft_id = get_dart_id_relative_to(dleft, pr[0]); + // Binary search within potential switch trigger + // TODO: apply the optimization Francis mentioned by only look at the largest one + // Convert a dart to a circular ordering index + auto to_order = [this, &pr, &dleft, num_sides] (const std::size_t& j) -> size_type { - pr.switch_dart(i); + Dart_const_handle dprev = this->get_previous_relative_to(pr, j, dleft); + return this->get_order_relative_to(dprev, dleft, num_sides); + }; + size_type key_val = get_order_relative_to(pr[i - 1], dleft, num_sides); + if (get_local_map().template belong_to_same_cell<0>(dh, pr[0])) + { + auto comparator = [&to_order, num_sides] (const std::size_t& key, const rbtree::value_type& b) -> bool { + return key > to_order(b.m_idx); + }; + auto it_trigger = trees[dleft_id].upper_bound(key_val, comparator); + if (it_trigger != trees[dleft_id].end() && !get_local_map().template belong_to_same_cell<1>(pr[it_trigger->m_idx], dh)) + { + pr.switch_dart(i); + } } + else + { + auto comparator = [&to_order, num_sides] (const std::size_t& key, const rbtree::value_type& b) -> bool { + return key < to_order(b.m_idx); + }; + auto it_trigger = trees[dleft_id].upper_bound(0, comparator); + if (it_trigger != trees[dleft_id].end() && to_order(it_trigger->m_idx) < key_val) + { + pr.switch_dart(i); + } + } + } + // Insert current darts + if (trees[dart_id].empty()) + { + trees[dart_id].push_back(node); } else { - auto comparator = [&to_order, num_sides] (const std::size_t& key, const rbtree::value_type& b) -> bool { - return key < to_order(b.m_idx); - }; - auto it_trigger = trees[dleft_id].upper_bound(0, comparator); - if (it_trigger != trees[dleft_id].end() && to_order(it_trigger->m_idx) < key_val) + size_type prev_dart_id = get_dart_id_relative_to(pr[i - 1], pr[0]); + auto it_prev = trees[prev_dart_id].iterator_to(rb_nodes[i - 1]); + if (it_prev != trees[prev_dart_id].begin() && is_same_corner(pr, std::prev(it_prev)->m_idx, i - 1)) { - pr.switch_dart(i); + auto it_after = trees[dart_id].iterator_to(rb_nodes[get_next_idx_relative_to(pr, std::prev(it_prev)->m_idx, pr[i - 1])]); + trees[dart_id].insert_before(it_after, node); + } + else if (std::next(it_prev) != trees[prev_dart_id].end() && is_same_corner(pr, std::next(it_prev)->m_idx, i - 1)) + { + auto it_before = trees[dart_id].iterator_to(rb_nodes[get_next_idx_relative_to(pr, std::next(it_prev)->m_idx, pr[i-1])]); + trees[dart_id].insert_before(std::next(it_before), node); + } + else + { + // TODO: insert into the tree guaranteed no same corner instance + if (get_local_map().template belong_to_same_cell<0>(dh, pr[0])) + { + auto comparator = [this, &pr, &p_original, &suffix_len, num_sides] (const std::size_t& key, const rbtee:value_type& b) -> bool { + if (b.m_idx == 0 && pr[key] == pr[0]) + { + std::size_t current_dividing_idx = key + p_original.length() - 1 - suffix_len[key - 1]; + std::size_t path_end_dividing_idx = p_original.length() - 1 - suffix_len[key - 1]; + std::size_t last_same_idx = (path_end_dividing_idx == p_original.length() - 1) ? 0 : path_end_dividing_idx + 1; + if (current_dividing_idx >= p_original.length()) + { + current_dividing_idx -= p_original.length(); + } + Dart_const_handle dbase = p_original[last_same_idx], + dcur = p_original[current_dividing_idx], + d0 = p_original[path_end_dividing_idx]; + + std::size_t key_prev_order = this->get_order_relative_to(dcur, dbase, num_sides); + std::size_t b_prev_order = this->get_order_relative_to(d0, dbase, num_sides); + return b_prev_order < key_prev_order; + } + else + { + std::size_t key_prev_order = this->get_order_relative_to(pr[key - 1], pr[key], num_sides); + Dart_const_handle bprev = this->get_previous_relative_to(pr, b.m_idx, pr[key]); + std::size_t b_prev_order = this->get_order_relative_to(bprev, pr[key], num_sides); + return b_prev_order < key_prev_order; + } + }; + auto it_after = trees[dart_id].upper_bound(i, comparator); + trees[dart_id].insert_before(it_after, node): + } + else + { + auto comparator = [this, &pr, &p_original, num_sides] (const std::size_t& key, const rbtee:value_type& b) -> bool { + /// It is impossible that pr[key] == pr[b.m_idx] == pr[0] + std::size_t key_prev_order = this->get_order_relative_to(pr[key - 1], pr[key], num_sides); + Dart_const_handle bprev = this->get_previous_relative_to(pr, b.m_idx, pr[key]); + std::size_t b_prev_order = this->get_order_relative_to(bprev, pr[key], num_sides); + return b_prev_order > key_prev_order; + }; + auto it_after = trees[dart_id].upper_bound(i, comparator); + trees[dart_id].insert_before(it_after, node): + } } } } - // Insert current darts - if (trees[dart_id].empty()) + // Check whether orders form a valid parenthesis expression + // First for the same direction of pr[0] + res = true; + std::stack parenthesis_pairing; + for (std::size_t i = 0; res && i < num_sides; ++i) { - trees[dart_id].push_back(node); - } - else - { - size_type prev_dart_id = get_dart_id_relative_to(pr[i - 1], pr[0]); - auto it_prev = trees[prev_dart_id].iterator_to(rb_nodes[i - 1]); - if (it_prev != trees[prev_dart_id].begin() && is_same_corner(pr, std::prev(it_prev)->m_idx, i - 1)) + for (auto it = trees[i].begin(); res && it != trees[i].end(); ++it) { - auto it_after = trees[dart_id].iterator_to(rb_nodes[get_next_idx_relative_to(pr, std::prev(it_prev)->m_idx, pr[i - 1])]); - trees[dart_id].insert_before(it_after, node); - } - else if (std::next(it_prev) != trees[prev_dart_id].end() && is_same_corner(pr, std::next(it_prev)->m_idx, i - 1)) - { - auto it_before = trees[dart_id].iterator_to(rb_nodes[get_next_idx_relative_to(pr, std::next(it_prev)->m_idx, pr[i-1])]); - trees[dart_id].insert_before(std::next(it_before), node); - } - else - { - // TODO: insert into the tree guaranteed no same corner instance + if (parenthesis_pairing.empty()) + { + parenthesis_pairing.push(it->m_idx); + } + else + { + std::size_t prev = parenthesis_pairing.top(); + std::size_t next = it->m_idx; + if(prev > next) + { + std::swap(prev, next); + } + if(next == prev + 1 && get_local_map().template belong_to_same_cell<0>(pr[next], pr[0])) + { + parenthesis_pairing.pop(); + } + else if(next == pr.length() - 1 && prev == 0) + { + parenthesis_pairing.pop(); + } + else + { + parenthesis_pairing.push(it->m_idx); + } + } } } + res = parenthesis_pairing.empty(); + while (!parenthesis_pairing.empty()) + { parenthesis_pairing.pop(); } + // Next check for the opposite direction of pr[0] + // TODO } } From 67fb806d63d486696416e5a14aa81bd312a9c905 Mon Sep 17 00:00:00 2001 From: Youmu Date: Wed, 24 Jun 2020 16:37:56 -0400 Subject: [PATCH 016/248] Preliminary finished version of is_simple_cycle() --- .../internal/Minimal_quadrangulation.h | 71 ++++++++++++++----- 1 file changed, 53 insertions(+), 18 deletions(-) diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h index 0f88da95af5..42938c98db8 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h @@ -583,14 +583,9 @@ public: // If the curve is not primitive, there must be at least // one self intersection - /// TODO: remove debug output - pr.display(); - std::cout << std::endl; - pr.display_pos_and_neg_turns(); - std::cout << std::endl; - // Compute the backward cyclic KMP failure table for the curve std::vector suffix_len = compute_common_circular_suffix(pr); + pr.compute_switchable(); std::size_t num_sides = degree(get_local_map(), get_local_map().darts().begin()); typedef typename boost::intrusive::rbtree(dh, pr[0])) { - auto comparator = [this, &pr, &p_original, &suffix_len, num_sides] (const std::size_t& key, const rbtee:value_type& b) -> bool { + auto comparator = [this, &pr, &p_original, &suffix_len, num_sides] (const std::size_t& key, const rbtree::value_type& b) -> bool { if (b.m_idx == 0 && pr[key] == pr[0]) { + if(pr[key] != p_original[key]) { + // current edge was switched + return false; + } std::size_t current_dividing_idx = key + p_original.length() - 1 - suffix_len[key - 1]; std::size_t path_end_dividing_idx = p_original.length() - 1 - suffix_len[key - 1]; std::size_t last_same_idx = (path_end_dividing_idx == p_original.length() - 1) ? 0 : path_end_dividing_idx + 1; @@ -697,11 +696,11 @@ public: } }; auto it_after = trees[dart_id].upper_bound(i, comparator); - trees[dart_id].insert_before(it_after, node): + trees[dart_id].insert_before(it_after, node); } else { - auto comparator = [this, &pr, &p_original, num_sides] (const std::size_t& key, const rbtee:value_type& b) -> bool { + auto comparator = [this, &pr, &p_original, num_sides] (const std::size_t& key, const rbtree::value_type& b) -> bool { /// It is impossible that pr[key] == pr[b.m_idx] == pr[0] std::size_t key_prev_order = this->get_order_relative_to(pr[key - 1], pr[key], num_sides); Dart_const_handle bprev = this->get_previous_relative_to(pr, b.m_idx, pr[key]); @@ -709,7 +708,7 @@ public: return b_prev_order > key_prev_order; }; auto it_after = trees[dart_id].upper_bound(i, comparator); - trees[dart_id].insert_before(it_after, node): + trees[dart_id].insert_before(it_after, node); } } } @@ -717,10 +716,11 @@ public: // Check whether orders form a valid parenthesis expression // First for the same direction of pr[0] res = true; + Dart_const_handle dcur = pr[0], dstart = pr[0]; std::stack parenthesis_pairing; - for (std::size_t i = 0; res && i < num_sides; ++i) - { - for (auto it = trees[i].begin(); res && it != trees[i].end(); ++it) + do { + auto dart_id = get_dart_id_relative_to(dcur, pr[0]); + for (auto it = trees[dart_id].begin(); it != trees[dart_id].end(); ++it) { if (parenthesis_pairing.empty()) { @@ -734,7 +734,7 @@ public: { std::swap(prev, next); } - if(next == prev + 1 && get_local_map().template belong_to_same_cell<0>(pr[next], pr[0])) + if(next == prev + 1 && get_local_map().template belong_to_same_cell<0>(pr[next], dstart)) { parenthesis_pairing.pop(); } @@ -748,12 +748,47 @@ public: } } } - } + dcur = get_local_map().template beta<2, 1>(dcur); + } while (dcur != dstart); res = parenthesis_pairing.empty(); while (!parenthesis_pairing.empty()) { parenthesis_pairing.pop(); } // Next check for the opposite direction of pr[0] - // TODO + dcur = get_local_map().opposite2(pr[0]); + dstart = get_local_map().opposite2(pr[0]); + do { + auto dart_id = get_dart_id_relative_to(dcur, pr[0]); + for (auto it = trees[dart_id].rbegin(); it != trees[dart_id].rend(); ++it) + { + if (parenthesis_pairing.empty()) + { + parenthesis_pairing.push(it->m_idx); + } + else + { + std::size_t prev = parenthesis_pairing.top(); + std::size_t next = it->m_idx; + if(prev > next) + { + std::swap(prev, next); + } + if(next == prev + 1 && get_local_map().template belong_to_same_cell<0>(pr[next], dstart)) + { + parenthesis_pairing.pop(); + } + else if(next == pr.length() - 1 && prev == 0) + { + parenthesis_pairing.pop(); + } + else + { + parenthesis_pairing.push(it->m_idx); + } + } + } + dcur = get_local_map().template beta<2, 1>(dcur); + } while (dcur != dstart); + res = res && parenthesis_pairing.empty(); } } From 47702769b99cb96049d7c59460a9755fb7b576b5 Mon Sep 17 00:00:00 2001 From: Youmu Date: Thu, 25 Jun 2020 21:42:59 -0400 Subject: [PATCH 017/248] Provide an example of simplicity testing on a double-torus --- .../Surface_mesh_topology/CMakeLists.txt | 2 + .../path_simplicity_double_torus.cpp | 115 ++++++++++++++++++ .../include/CGAL/Path_on_surface.h | 1 - .../internal/Minimal_quadrangulation.h | 5 +- 4 files changed, 119 insertions(+), 4 deletions(-) create mode 100644 Surface_mesh_topology/examples/Surface_mesh_topology/path_simplicity_double_torus.cpp diff --git a/Surface_mesh_topology/examples/Surface_mesh_topology/CMakeLists.txt b/Surface_mesh_topology/examples/Surface_mesh_topology/CMakeLists.txt index ba810895f23..ac49937cab1 100644 --- a/Surface_mesh_topology/examples/Surface_mesh_topology/CMakeLists.txt +++ b/Surface_mesh_topology/examples/Surface_mesh_topology/CMakeLists.txt @@ -36,6 +36,7 @@ set(SOURCE_FILES path_homotopy_with_sm_and_polyhedron.cpp path_homotopy_with_symbols_2.cpp path_homotopy_with_symbols.cpp + path_simplicity_double_torus.cpp shortest_noncontractible_cycle_2.cpp shortest_noncontractible_cycle.cpp unsew_edgewidth_repeatedly.cpp @@ -54,6 +55,7 @@ if(CGAL_Qt5_FOUND) target_link_libraries(path_homotopy_double_torus PUBLIC CGAL::CGAL_Qt5) target_link_libraries(path_homotopy_torus PUBLIC CGAL::CGAL_Qt5) target_link_libraries(path_homotopy_with_sm_and_polyhedron PUBLIC CGAL::CGAL_Qt5) + target_link_libraries(path_simplicity_double_torus PUBLIC CGAL::CGAL_Qt5) target_link_libraries(shortest_noncontractible_cycle_2 PUBLIC CGAL::CGAL_Qt5) target_link_libraries(shortest_noncontractible_cycle PUBLIC CGAL::CGAL_Qt5) target_link_libraries(unsew_edgewidth_repeatedly PUBLIC CGAL::CGAL_Qt5) diff --git a/Surface_mesh_topology/examples/Surface_mesh_topology/path_simplicity_double_torus.cpp b/Surface_mesh_topology/examples/Surface_mesh_topology/path_simplicity_double_torus.cpp new file mode 100644 index 00000000000..e708fb6478c --- /dev/null +++ b/Surface_mesh_topology/examples/Surface_mesh_topology/path_simplicity_double_torus.cpp @@ -0,0 +1,115 @@ +#include +#include +#include +#include +#include + +typedef CGAL::Linear_cell_complex_for_combinatorial_map<2,3> LCC_3_cmap; +using namespace CGAL::Surface_mesh_topology; + +/////////////////////////////////////////////////////////////////////////////// +void create_path_1(Path_on_surface& p) +{ + p.push_back_by_index(438); // Its starting dart + for (int i=0; i<5; ++i) + { p.extend_positive_turn(2); } // Extend the path + p.extend_positive_turn(1); + for (int i=0; i<7; ++i) + { p.extend_positive_turn(2); } +} + +/////////////////////////////////////////////////////////////////////////////// +void create_path_2(Path_on_surface& p) +{ + p.push_back_by_index({14, 15, 391, 392, 395, 227, 223, 313, 318, 326, 82, + 87, 431, 160, 435, 753, 754, 756, 757, 674, 678, 850, + 483, 480, 475, 470, 893, 618, 622, 548, 551, 795, + 797, 806, 637, 634, 638, 872, 521, 376, 180, 424, + 88, 95, 440, 152, 149, 21}); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_path_3(Path_on_surface& p) +{ + p.push_back_by_index(473); // Its starting dart + p.extend_positive_turn(1); // Extend the path + p.extend_positive_turn(3); + for (int i=0; i<7; ++i) + { p.extend_positive_turn(2); } + p.extend_positive_turn(3); + p.extend_positive_turn(1); + for (int i=0; i<3; ++i) + { p.extend_positive_turn(2); } + p.extend_positive_turn(3); + p.extend_positive_turn(1); + for (int i=0; i<2; ++i) + { p.extend_positive_turn(2); } + p.extend_positive_turn(1); + for (int i=0; i<3; ++i) + { p.extend_positive_turn(2); } + p.extend_positive_turn(3); + p.extend_positive_turn(2); + p.extend_positive_turn(1); + for (int i=0; i<2; ++i) + { p.extend_positive_turn(2); } + p.extend_positive_turn(3); + for (int i=0; i<3; ++i) + { p.extend_positive_turn(2); } + p.extend_positive_turn(1); + p.extend_positive_turn(1); + for (int i=0; i<2; ++i) + { p.extend_positive_turn(2); } + p.extend_positive_turn(1); + for (int i=0; i<2; ++i) + { p.extend_positive_turn(2); } + p.extend_positive_turn(3); + for (int i=0; i<3; ++i) + { p.extend_positive_turn(2); } + p.extend_positive_turn(3); + for (int i=0; i<3; ++i) + { p.extend_positive_turn(2); } + p.extend_positive_turn(1); + p.extend_positive_turn(3); + for (int i=0; i<2; ++i) + { p.extend_positive_turn(2); } + p.extend_positive_turn(3); + p.extend_positive_turn(2); +} + +/////////////////////////////////////////////////////////////////////////////// +int main(int argc, char** argv) +{ + bool draw=(argc>1?std::string(argv[1])=="-draw":false); + LCC_3_cmap lcc; + if (!CGAL::load_off(lcc, "data/double-torus.off")) + { + std::cout<<"ERROR reading file data/double-torus.off"< cst(lcc); + Path_on_surface p1(lcc), p2(lcc), p3(lcc); + create_path_1(p1); + create_path_2(p2); + create_path_3(p3); + + + bool res1=cst.is_simple_cycle(p1); + std::cout<<"Path p1 (pink) "<<(res1?"IS":"IS NOT") + <<" simple."< Date: Fri, 26 Jun 2020 17:35:30 -0400 Subject: [PATCH 018/248] Fix a bug when checking parenthesis pairing for the opposite direction of the first dart --- .../Surface_mesh_topology/internal/Minimal_quadrangulation.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h index a2a2149ffaf..33f852f9a67 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h @@ -775,10 +775,6 @@ public: { parenthesis_pairing.pop(); } - else if(next == pr.length() - 1 && prev == 0) - { - parenthesis_pairing.pop(); - } else { parenthesis_pairing.push(it->m_idx); From 8fdddd49e23047da13724f8691dd195dafa84d4c Mon Sep 17 00:00:00 2001 From: Youmu Date: Fri, 26 Jun 2020 17:36:41 -0400 Subject: [PATCH 019/248] Add a slightly more compicated example on double torus --- .../path_simplicity_double_torus_2.cpp | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 Surface_mesh_topology/examples/Surface_mesh_topology/path_simplicity_double_torus_2.cpp diff --git a/Surface_mesh_topology/examples/Surface_mesh_topology/path_simplicity_double_torus_2.cpp b/Surface_mesh_topology/examples/Surface_mesh_topology/path_simplicity_double_torus_2.cpp new file mode 100644 index 00000000000..340ab74486c --- /dev/null +++ b/Surface_mesh_topology/examples/Surface_mesh_topology/path_simplicity_double_torus_2.cpp @@ -0,0 +1,82 @@ +#include +#include +#include +#include +#include + +typedef CGAL::Linear_cell_complex_for_combinatorial_map<2,3> LCC_3_cmap; +using namespace CGAL::Surface_mesh_topology; + +/////////////////////////////////////////////////////////////////////////////// +void create_path(Path_on_surface& p) +{ + p.push_back_by_index(682); // Its starting dart + for (int i=0; i<11; ++i) + { p.extend_positive_turn(2); } // Extend the path + p.extend_positive_turn(3); + for (int i=0; i<5; ++i) + { p.extend_positive_turn(2); } + p.extend_positive_turn(1); + p.extend_positive_turn(2); + p.extend_positive_turn(3); + for (int i=0; i<2; ++i) + { p.extend_positive_turn(2); } + p.extend_positive_turn(3); + for (int i=0; i<5; ++i) + { p.extend_positive_turn(2); } + p.extend_positive_turn(1); + for (int i=0; i<2; ++i) + { p.extend_positive_turn(2); } + p.extend_positive_turn(1); + for (int i=0; i<2; ++i) + { p.extend_positive_turn(2); } + p.extend_positive_turn(3); + p.extend_positive_turn(2); + p.extend_positive_turn(1); + for (int i=0; i<8; ++i) + { p.extend_positive_turn(2); } + p.extend_positive_turn(1); + for (int i=0; i<4; ++i) + { p.extend_positive_turn(2); } + p.extend_positive_turn(3); + for (int i=0; i<5; ++i) + { p.extend_positive_turn(2); } + p.extend_positive_turn(3); + for (int i=0; i<5; ++i) + { p.extend_positive_turn(2); } + p.extend_positive_turn(1); + for (int i=0; i<3; ++i) + { p.extend_positive_turn(2); } + p.extend_positive_turn(1); + p.extend_positive_turn(1); + for (int i=0; i<11; ++i) + { p.extend_positive_turn(2); } + p.extend_positive_turn(1); +} + +/////////////////////////////////////////////////////////////////////////////// +int main(int argc, char** argv) +{ + bool draw=(argc>1?std::string(argv[1])=="-draw":false); + LCC_3_cmap lcc; + if (!CGAL::load_off(lcc, "data/double-torus.off")) + { + std::cout<<"ERROR reading file data/double-torus.off"< cst(lcc); + Path_on_surface p(lcc); + create_path(p); + + bool res=cst.is_simple_cycle(p); + std::cout<<"Path p (pink) "<<(res?"IS":"IS NOT") + <<" simple."< Date: Thu, 2 Jul 2020 00:35:13 -0400 Subject: [PATCH 020/248] Change the function name to is_homotopic_to_simple_cycle() Correctly handle the order of darts when the surface has holes --- .../Surface_mesh_topology/CMakeLists.txt | 2 + .../path_simplicity_double_torus.cpp | 6 +- .../path_simplicity_double_torus_2.cpp | 2 +- .../include/CGAL/Curves_on_surface_topology.h | 4 +- .../internal/Minimal_quadrangulation.h | 68 ++++++++++--------- 5 files changed, 43 insertions(+), 39 deletions(-) diff --git a/Surface_mesh_topology/examples/Surface_mesh_topology/CMakeLists.txt b/Surface_mesh_topology/examples/Surface_mesh_topology/CMakeLists.txt index ac49937cab1..39fc5fb842a 100644 --- a/Surface_mesh_topology/examples/Surface_mesh_topology/CMakeLists.txt +++ b/Surface_mesh_topology/examples/Surface_mesh_topology/CMakeLists.txt @@ -37,6 +37,7 @@ set(SOURCE_FILES path_homotopy_with_symbols_2.cpp path_homotopy_with_symbols.cpp path_simplicity_double_torus.cpp + path_simplicity_double_torus_2.cpp shortest_noncontractible_cycle_2.cpp shortest_noncontractible_cycle.cpp unsew_edgewidth_repeatedly.cpp @@ -56,6 +57,7 @@ if(CGAL_Qt5_FOUND) target_link_libraries(path_homotopy_torus PUBLIC CGAL::CGAL_Qt5) target_link_libraries(path_homotopy_with_sm_and_polyhedron PUBLIC CGAL::CGAL_Qt5) target_link_libraries(path_simplicity_double_torus PUBLIC CGAL::CGAL_Qt5) + target_link_libraries(path_simplicity_double_torus_2 PUBLIC CGAL::CGAL_Qt5) target_link_libraries(shortest_noncontractible_cycle_2 PUBLIC CGAL::CGAL_Qt5) target_link_libraries(shortest_noncontractible_cycle PUBLIC CGAL::CGAL_Qt5) target_link_libraries(unsew_edgewidth_repeatedly PUBLIC CGAL::CGAL_Qt5) diff --git a/Surface_mesh_topology/examples/Surface_mesh_topology/path_simplicity_double_torus.cpp b/Surface_mesh_topology/examples/Surface_mesh_topology/path_simplicity_double_torus.cpp index e708fb6478c..762c9f986d9 100644 --- a/Surface_mesh_topology/examples/Surface_mesh_topology/path_simplicity_double_torus.cpp +++ b/Surface_mesh_topology/examples/Surface_mesh_topology/path_simplicity_double_torus.cpp @@ -94,15 +94,15 @@ int main(int argc, char** argv) create_path_3(p3); - bool res1=cst.is_simple_cycle(p1); + bool res1=cst.is_homotopic_to_simple_cycle(p1); std::cout<<"Path p1 (pink) "<<(res1?"IS":"IS NOT") <<" simple."< p(lcc); create_path(p); - bool res=cst.is_simple_cycle(p); + bool res=cst.is_homotopic_to_simple_cycle(p); std::cout<<"Path p (pink) "<<(res?"IS":"IS NOT") <<" simple."<& p, + bool is_homotopic_to_simple_cycle(const Path_on_surface& p, bool display_time=false) const { compute_minimal_quadrangulation(display_time); - return m_minimal_quadrangulation->is_simple_cycle(p, display_time); + return m_minimal_quadrangulation->is_homotopic_to_simple_cycle(p, display_time); } protected: diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h index 33f852f9a67..17c1fb07db5 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h @@ -524,7 +524,7 @@ public: } /// @return true iff 'p' is a simple curve. - bool is_simple_cycle(const Path_on_surface& p, + bool is_homotopic_to_simple_cycle(const Path_on_surface& p, bool display_time=false) const { if (p.is_empty()) @@ -532,7 +532,7 @@ public: if (!p.is_closed()) { - std::cerr<<"Error: is_simple_cycle requires a closed path."< suffix_len = compute_common_circular_suffix(pr); pr.compute_switchable(); - std::size_t num_sides = degree(get_local_map(), get_local_map().darts().begin()); + size_type degree = get_local_map().template info<0>(get_local_map().darts().begin()); typedef typename boost::intrusive::rbtree> rbtree; std::vector rb_nodes; rb_nodes.reserve(pr.length()); - std::vector trees(num_sides); + std::vector trees(degree); for (std::size_t i = 0; i < pr.length(); ++i) { Dart_const_handle dh = pr[i]; - auto dart_id = get_dart_id_relative_to(pr[i], pr[0]); + auto dart_id = get_dart_absolute_order_relative_to(pr[i], pr[0]); rb_nodes.emplace_back(i); auto& node = rb_nodes.back(); // Check whether current darts needs to be switched - if (pr.is_switchable(i)) + if (i > 0 && pr.is_switchable(i)) { // Look at the t-1 turn of [i-1, i, i + 1] Dart_const_handle dleft = get_local_map().template beta<0, 2>(dh); - auto dleft_id = get_dart_id_relative_to(dleft, pr[0]); + auto dleft_id = get_dart_absolute_order_relative_to(dleft, pr[0]); // Binary search within potential switch trigger // TODO: apply the optimization Francis mentioned by only look at the largest one // Convert a dart to a circular ordering index - auto to_order = [this, &pr, &dleft, num_sides] (const std::size_t& j) -> size_type + auto to_order = [this, &pr, &dleft] (const std::size_t& j) -> size_type { Dart_const_handle dprev = this->get_previous_relative_to(pr, j, dleft); - return this->get_order_relative_to(dprev, dleft, num_sides); + return this->get_order_relative_to(dprev, dleft); }; - size_type key_val = get_order_relative_to(pr[i - 1], dleft, num_sides); + size_type key_val = get_order_relative_to(pr[i - 1], dleft); if (get_local_map().template belong_to_same_cell<0>(dh, pr[0])) { - auto comparator = [&to_order, num_sides] (const std::size_t& key, const rbtree::value_type& b) -> bool { + auto comparator = [&to_order] (const std::size_t& key, const rbtree::value_type& b) -> bool { return key > to_order(b.m_idx); }; auto it_trigger = trees[dleft_id].upper_bound(key_val, comparator); @@ -629,7 +629,7 @@ public: } else { - auto comparator = [&to_order, num_sides] (const std::size_t& key, const rbtree::value_type& b) -> bool { + auto comparator = [&to_order] (const std::size_t& key, const rbtree::value_type& b) -> bool { return key < to_order(b.m_idx); }; auto it_trigger = trees[dleft_id].upper_bound(0, comparator); @@ -639,7 +639,7 @@ public: } } dh = pr[i]; - dart_id = get_dart_id_relative_to(pr[i], pr[0]); + dart_id = get_dart_absolute_order_relative_to(pr[i], pr[0]); } // Insert current darts if (trees[dart_id].empty()) @@ -648,7 +648,7 @@ public: } else { - size_type prev_dart_id = get_dart_id_relative_to(pr[i - 1], pr[0]); + size_type prev_dart_id = get_dart_absolute_order_relative_to(pr[i - 1], pr[0]); auto it_prev = trees[prev_dart_id].iterator_to(rb_nodes[i - 1]); if (it_prev != trees[prev_dart_id].begin() && is_same_corner(pr, std::prev(it_prev)->m_idx, i - 1)) { @@ -664,11 +664,11 @@ public: { if (get_local_map().template belong_to_same_cell<0>(dh, pr[0])) { - auto comparator = [this, &pr, &p_original, &suffix_len, num_sides] (const std::size_t& key, const rbtree::value_type& b) -> bool { + auto comparator = [this, &pr, &p_original, &suffix_len] (const std::size_t& key, const rbtree::value_type& b) -> bool { if (b.m_idx == 0 && pr[key] == pr[0]) { if(pr[key] != p_original[key]) { - // current edge was switched + // current edge was switched so it should always be on the right side (more counter-clockwise) return false; } std::size_t current_dividing_idx = key + p_original.length() - 1 - suffix_len[key - 1]; @@ -682,15 +682,15 @@ public: dcur = p_original[current_dividing_idx], d0 = p_original[path_end_dividing_idx]; - std::size_t key_prev_order = this->get_order_relative_to(dcur, dbase, num_sides); - std::size_t b_prev_order = this->get_order_relative_to(d0, dbase, num_sides); + std::size_t key_prev_order = this->get_order_relative_to(dcur, dbase); + std::size_t b_prev_order = this->get_order_relative_to(d0, dbase); return b_prev_order < key_prev_order; } else { - std::size_t key_prev_order = this->get_order_relative_to(pr[key - 1], pr[key], num_sides); + std::size_t key_prev_order = this->get_order_relative_to(pr[key - 1], pr[key]); Dart_const_handle bprev = this->get_previous_relative_to(pr, b.m_idx, pr[key]); - std::size_t b_prev_order = this->get_order_relative_to(bprev, pr[key], num_sides); + std::size_t b_prev_order = this->get_order_relative_to(bprev, pr[key]); return b_prev_order < key_prev_order; } }; @@ -699,11 +699,11 @@ public: } else { - auto comparator = [this, &pr, &p_original, num_sides] (const std::size_t& key, const rbtree::value_type& b) -> bool { + auto comparator = [this, &pr, &p_original] (const std::size_t& key, const rbtree::value_type& b) -> bool { /// It is impossible that pr[key] == pr[b.m_idx] == pr[0] - std::size_t key_prev_order = this->get_order_relative_to(pr[key - 1], pr[key], num_sides); + std::size_t key_prev_order = this->get_order_relative_to(pr[key - 1], pr[key]); Dart_const_handle bprev = this->get_previous_relative_to(pr, b.m_idx, pr[key]); - std::size_t b_prev_order = this->get_order_relative_to(bprev, pr[key], num_sides); + std::size_t b_prev_order = this->get_order_relative_to(bprev, pr[key]); return b_prev_order > key_prev_order; }; auto it_after = trees[dart_id].upper_bound(i, comparator); @@ -718,7 +718,7 @@ public: Dart_const_handle dcur = pr[0], dstart = pr[0]; std::stack parenthesis_pairing; do { - auto dart_id = get_dart_id_relative_to(dcur, pr[0]); + auto dart_id = get_dart_absolute_order_relative_to(dcur, pr[0]); for (auto it = trees[dart_id].begin(); it != trees[dart_id].end(); ++it) { if (parenthesis_pairing.empty()) @@ -756,7 +756,7 @@ public: dcur = get_local_map().opposite2(pr[0]); dstart = get_local_map().opposite2(pr[0]); do { - auto dart_id = get_dart_id_relative_to(dcur, pr[0]); + auto dart_id = get_dart_absolute_order_relative_to(dcur, pr[0]); for (auto it = trees[dart_id].rbegin(); it != trees[dart_id].rend(); ++it) { if (parenthesis_pairing.empty()) @@ -790,7 +790,7 @@ public: if (display_time) { t.stop(); - std::cout<<"[TIME] is_simple_cycle: "<(ref); + size_type ref_order = get_dart_absolute_order_relative_to(ref, ref), + x_order = get_dart_absolute_order_relative_to(x, ref); + return x_order <= ref_order ? (x_order + degree - ref_order - 1) : (x_order - ref_order - 1); } int get_previous_idx_relative_to(const Path_on_surface&p, std::size_t i, Dart_const_handle ref) const @@ -2017,11 +2018,12 @@ protected: return p[j]; } - size_type get_dart_id_relative_to(Dart_const_handle x, Dart_const_handle ref) const + size_type get_dart_absolute_order_relative_to(Dart_const_handle x, Dart_const_handle ref) const { + size_type degree = get_local_map().template info<0>(ref); return get_local_map().template belong_to_same_cell<0>(x, ref) ? - get_local_map().info(x) : - get_local_map().info(get_local_map().opposite2(x)); + get_dart_id(x) % degree : + get_dart_id(get_local_map().opposite2(x)) % degree; } bool is_same_corner(const Path_on_surface& p, std::size_t j, std::size_t ref) const From f4110ca5c50c9b35c5c0a640f50611e2210e950b Mon Sep 17 00:00:00 2001 From: Guillaume Damiand Date: Tue, 7 Jul 2020 09:57:09 +0200 Subject: [PATCH 021/248] Bugfix when creating a path on surface with rle from a path having a flat starting from its last dart. --- .../include/CGAL/Path_on_surface.h | 17 ++++++++++++++ .../internal/Path_on_surface_with_rle.h | 23 +++++++++---------- .../test/Surface_mesh_topology/path_tests.cpp | 2 +- 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/Surface_mesh_topology/include/CGAL/Path_on_surface.h b/Surface_mesh_topology/include/CGAL/Path_on_surface.h index 7def68b162c..dadbaab735f 100644 --- a/Surface_mesh_topology/include/CGAL/Path_on_surface.h +++ b/Surface_mesh_topology/include/CGAL/Path_on_surface.h @@ -1161,6 +1161,23 @@ public: get_opposite_ith_real_dart(i)); } + /// @return the turn between dart number i-1 and dart number i. + std::size_t prev_positive_turn(std::size_t i) const + { + // CGAL_assertion(is_valid()); + CGAL_assertion(i0); + return next_positive_turn(prev_index(i)); + } + /// @return the negative turn between dart number i-1 and dart number i. + std::size_t prev_negative_turn(std::size_t i) const + { + // CGAL_assertion(is_valid()); + CGAL_assertion(i0); + return next_negative_turn(prev_index(i)); + } + /// Computes all positive turns of this path. std::vector compute_positive_turns() const { diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Path_on_surface_with_rle.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Path_on_surface_with_rle.h index aa8dd8a2336..a865439ccb3 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Path_on_surface_with_rle.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Path_on_surface_with_rle.h @@ -97,10 +97,10 @@ protected: // Small wrapper to provide per dart iterator on a Path_on_surface_with_rle template -class Dart_iterator +class CDart_iterator { public: - typedef Dart_iterator Self; + typedef CDart_iterator Self; typedef Path_ Path; typedef typename Path::Map Map; typedef typename Map::Dart_handle Dart_handle; @@ -113,7 +113,7 @@ public: typedef Dart_const_handle& reference; typedef std::bidirectional_iterator_tag iterator_category; - Dart_iterator(const Path_& path, const List_iterator& it_flat, bool is_end = false) + CDart_iterator(const Path_& path, const List_iterator& it_flat, bool is_end = false) : m_path(path), m_it_flat(it_flat), m_curr_idx_in_flat(0), @@ -220,11 +220,11 @@ public: typedef CFlat Flat; typedef std::list List_of_flats; typedef typename List_of_flats::iterator List_iterator; - typedef Dart_iterator Dart_iterator; + typedef CDart_iterator Dart_iterator; // TODO typedef typename List_of_dart_length::const_iterator List_const_iterator; friend class Path_on_surface; - friend Dart_iterator; + friend CDart_iterator; struct List_iterator_hash { @@ -282,15 +282,15 @@ public: if (apath.is_closed()) { - if (!use_only_negative && apath.next_positive_turn(i)==2) + if (!use_only_negative && apath.prev_positive_turn(i)==2) { positive_flat=true; negative_flat=false; } - else if (!use_only_positive && apath.next_negative_turn(i)==2) + else if (!use_only_positive && apath.prev_negative_turn(i)==2) { positive_flat=false; negative_flat=true; } - while ((positive_flat && apath.next_positive_turn(i)==2) || - (negative_flat && apath.next_negative_turn(i)==2)) + while ((positive_flat && apath.prev_positive_turn(i)==2) || + (negative_flat && apath.prev_negative_turn(i)==2)) { - i=apath.next_index(i); + i=apath.prev_index(i); if (i==0) // Case of a closed path, made of only one flat part. { m_path.push_back(Flat(apath.real_front(), apath.real_back(), @@ -301,8 +301,7 @@ public: return; } } - // Here i is the last dart of a flat - i=apath.next_index(i); // Now we are sure that i is the beginning of a flat + // Here i is the first dart of a flat } starti=i; diff --git a/Surface_mesh_topology/test/Surface_mesh_topology/path_tests.cpp b/Surface_mesh_topology/test/Surface_mesh_topology/path_tests.cpp index ee9e5ba0765..a9beb93422d 100644 --- a/Surface_mesh_topology/test/Surface_mesh_topology/path_tests.cpp +++ b/Surface_mesh_topology/test/Surface_mesh_topology/path_tests.cpp @@ -93,7 +93,7 @@ bool basic_tests() internal::Light_MQ lmq(p6.get_map()); internal::Path_on_surface_with_rle > p7(lmq, p6); - if (!p7.is_valid() || p7.size_of_list()!=2) + if (!p7.is_valid() || p7.size_of_list()!=3) { std::cerr<<"path_tests ERROR: !p7.is_valid() || size_of_list()!=2."< Date: Tue, 7 Jul 2020 12:09:28 -0400 Subject: [PATCH 022/248] Remove Dart_iterator and dart switching from Path_on_surface_with_rle --- .../internal/Path_on_surface_with_rle.h | 167 ------------------ 1 file changed, 167 deletions(-) diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Path_on_surface_with_rle.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Path_on_surface_with_rle.h index a865439ccb3..eba86291765 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Path_on_surface_with_rle.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Path_on_surface_with_rle.h @@ -95,119 +95,6 @@ protected: const Local_map& m_map; }; -// Small wrapper to provide per dart iterator on a Path_on_surface_with_rle -template -class CDart_iterator -{ -public: - typedef CDart_iterator Self; - typedef Path_ Path; - typedef typename Path::Map Map; - typedef typename Map::Dart_handle Dart_handle; - typedef typename Map::Dart_const_handle Dart_const_handle; - typedef CFlat Flat; - typedef typename Path::List_iterator List_iterator; - typedef std::ptrdiff_t difference_type; - typedef Dart_const_handle value_type; - typedef Dart_const_handle* pointer; - typedef Dart_const_handle& reference; - typedef std::bidirectional_iterator_tag iterator_category; - - CDart_iterator(const Path_& path, const List_iterator& it_flat, bool is_end = false) - : m_path(path), - m_it_flat(it_flat), - m_curr_idx_in_flat(0), - m_curr_dart(is_end ? nullptr : it_flat->begin) - {} - - Dart_const_handle operator*() const { - CGAL_assertion(m_it_flat != m_path.m_path.end()); - return m_curr_dart; - } - - Self& operator++() { - CGAL_assertion(m_it_flat != m_path.m_path.end()); - increment(); - return *this; - } - - Self operator++(int) { - CGAL_assertion(m_it_flat != m_path.m_path.end()); - Self pre_increment(*this); - increment(); - return pre_increment; - } - - Self& operator--() { - CGAL_assertion(m_it_flat != m_path.m_path.begin()); - decrement(); - return *this; - } - - Self operator--(int) { - CGAL_assertion(m_it_flat != m_path.m_path.begin()); - Self pre_decrement(*this); - decrement(); - return pre_decrement; - } - - void increment() { - if (m_curr_idx_in_flat == std::abs(m_it_flat->length)) { - m_it_flat = std::next(m_it_flat); - m_curr_idx_in_flat = 0; - if (m_it_flat != m_path.m_path.end()) { - m_curr_dart = m_it_flat->begin; - } - } - else { - ++m_curr_idx_in_flat; - if (m_it_flat->length > 0) { - m_curr_dart = m_path.get_map().template beta<1, 2, 1>(m_curr_dart); - } - else { - m_curr_dart = m_path.get_map().template beta<2, 0, 2, 0, 2>(m_curr_dart); - } - } - } - - void decrement() { - if (m_curr_idx_in_flat == 0) { - m_it_flat = std::prev(m_it_flat); - m_curr_idx_in_flat = std::abs(m_it_flat->length); - m_curr_dart = m_it_flat->end; - } - else { - --m_curr_idx_in_flat; - if (m_it_flat->length > 0) { - m_curr_dart = m_path.get_map().template beta<0, 2, 0>(m_curr_dart); - } - else { - m_curr_dart = m_path.get_map().template beta<2, 1, 2, 1, 2>(m_curr_dart); - } - } - } - - bool operator==(const Self& other) const { - return m_it_flat == other.m_it_flat && m_curr_idx_in_flat == other.m_curr_idx_in_flat; - } - - bool operator!=(const Self& other) const { - return !(*this == other); - } - - Self& operator=(const Self& other) { - m_it_flat = other.m_it_flat; - m_curr_idx_in_flat = other.m_curr_idx_in_flat; - m_curr_dart = other.m_curr_dart; - return *this; - } - - const Path_& m_path; - List_iterator m_it_flat; - std::size_t m_curr_idx_in_flat; - Dart_const_handle m_curr_dart; -}; - template // MQ for minimal quadrangulation class Path_on_surface_with_rle { @@ -220,11 +107,9 @@ public: typedef CFlat Flat; typedef std::list List_of_flats; typedef typename List_of_flats::iterator List_iterator; - typedef CDart_iterator Dart_iterator; // TODO typedef typename List_of_dart_length::const_iterator List_const_iterator; friend class Path_on_surface; - friend CDart_iterator; struct List_iterator_hash { @@ -547,18 +432,6 @@ public: return end_of_flat(std::prev(m_path.end())); } - /// @return the beginning of an iterator through all the darts - Dart_iterator begin() - { - return Dart_iterator(*this, m_path.begin(), is_empty()); - } - - /// @return the end of the iterator through all the darts - Dart_iterator end() - { - return Dart_iterator(*this, m_path.end(), true); - } - /// @return true iff df can be added at the end of the path. bool can_be_pushed(Dart_const_handle dh) { @@ -1349,12 +1222,6 @@ public: return (t==1 && flat_length(it) >= 0); } - /// @return true iff the dart 'it_dart' forms a switchable subpath (aka left-L-shape) - bool is_switchable(const Dart_iterator& it_dart) { - CGAL_assertion(it_dart != end()); - return is_switchable(it_dart.m_it_flat); - } - /// Add the given dart 'dh' before the flat 'it'. void add_dart_before(const List_iterator& it, Dart_const_handle dh, Set_of_it& modified_flats) @@ -1593,40 +1460,6 @@ public: it1=merge_modified_flats_when_possible(modified_flats); } - /// Switch the left-L-shape of the subpath starting at 'it' - void switch_dart(Dart_iterator& it_dart) - { - CGAL_assertion(is_switchable(it_dart)); - List_iterator it = it_dart.m_it_flat; - Set_of_it modified_flats; - /// Break current flat into 3 pieces: - /// previous unswitched flat, current dart, next switched flat - if (it_dart.m_curr_idx_in_flat > 0) { - add_dart_before(it, it->begin, modified_flats); - List_iterator it_prev = std::prev(it); - set_end_of_flat(it_prev, get_map().template beta<0, 2, 0>(*it_dart)); - set_flat_length(it_prev, it_dart.m_curr_idx_in_flat - 1); - flat_modified(it_prev, modified_flats); - } - /// Need to switch to t1-1 turn - List_iterator it_next = next_iterator(it); - Dart_const_handle d_new_first_dart = get_map().template beta<0, 2>(*it_dart); - Dart_const_handle d_new_flat_begin = get_map().template beta<2, 0, 2>(d_new_first_dart); - Dart_const_handle d_new_flat_end = get_map().template beta<1, 2>(begin_of_flat(it_next)); - - add_dart_before(it, d_new_first_dart, modified_flats); - set_begin_of_flat(it, d_new_flat_begin); - set_end_of_flat(it, d_new_flat_end); - set_flat_length(it, -(it->length - it_dart.m_curr_idx_in_flat)); - flat_modified(it, modified_flats); - reduce_flat_from_beginning(it_next, modified_flats); - flat_modified(it_next, modified_flats); - - merge_modified_flats_when_possible(modified_flats); - it_dart = Dart_iterator(*this, it); - --it_dart; - } - /// Right push the path, if all all l-shape are pushed, otherwise only one. /// @return true iff the path was pushed bool right_push(bool all=true) From 7bda116f3bb46f3d66bf38d479ab912c192c4340 Mon Sep 17 00:00:00 2001 From: Youmu Date: Tue, 7 Jul 2020 12:17:33 -0400 Subject: [PATCH 023/248] Remove factorize from Path_on_surface_with_rle --- .../internal/Minimal_quadrangulation.h | 26 ++++++++++--------- .../internal/Path_on_surface_with_rle.h | 7 ----- 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h index 17c1fb07db5..fed2c0bfd7b 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h @@ -570,29 +570,31 @@ public: } else { - // TODO: genus > 1 and not contractible, perform unzip algorithm + // genus > 1 and not contractible, perform unzip algorithm internal::Path_on_surface_with_rle pt=transform_original_path_into_quad_surface_with_rle(p); pt.canonize(); // Use non-rle path from now on - auto factorization=pt.factorize(); - Path_on_surface pr(factorization.first); - pr.simplify_flips(); - Path_on_surface p_original(pr); + Path_on_surface p_canonized(pt); + auto factorization=p_canonized.factorize(); if (factorization.second <= 1) { // If the curve is not primitive, there must be at least // one self intersection + Path_on_surface pr(factorization.first); + pr.simplify_flips(); + Path_on_surface p_original(pr); + // Compute the backward cyclic KMP failure table for the curve std::vector suffix_len = compute_common_circular_suffix(pr); pr.compute_switchable(); - size_type degree = get_local_map().template info<0>(get_local_map().darts().begin()); + size_type src_degree = degree(get_local_map(), get_local_map().darts().begin()); typedef typename boost::intrusive::rbtree> rbtree; std::vector rb_nodes; rb_nodes.reserve(pr.length()); - std::vector trees(degree); + std::vector trees(src_degree); for (std::size_t i = 0; i < pr.length(); ++i) { @@ -1970,10 +1972,10 @@ protected: size_type get_order_relative_to(Dart_const_handle x, Dart_const_handle ref) const { - size_type degree = get_local_map().template info<0>(ref); + size_type ref_degree = degree(get_local_map(), get_local_map().darts().begin()); size_type ref_order = get_dart_absolute_order_relative_to(ref, ref), x_order = get_dart_absolute_order_relative_to(x, ref); - return x_order <= ref_order ? (x_order + degree - ref_order - 1) : (x_order - ref_order - 1); + return x_order <= ref_order ? (x_order + ref_degree - ref_order - 1) : (x_order - ref_order - 1); } int get_previous_idx_relative_to(const Path_on_surface&p, std::size_t i, Dart_const_handle ref) const @@ -2020,10 +2022,10 @@ protected: size_type get_dart_absolute_order_relative_to(Dart_const_handle x, Dart_const_handle ref) const { - size_type degree = get_local_map().template info<0>(ref); + size_type ref_degree = degree(get_local_map(), get_local_map().darts().begin()); return get_local_map().template belong_to_same_cell<0>(x, ref) ? - get_dart_id(x) % degree : - get_dart_id(get_local_map().opposite2(x)) % degree; + get_dart_id(x) % ref_degree : + get_dart_id(get_local_map().opposite2(x)) % ref_degree; } bool is_same_corner(const Path_on_surface& p, std::size_t j, std::size_t ref) const diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Path_on_surface_with_rle.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Path_on_surface_with_rle.h index eba86291765..701c2eea61f 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Path_on_surface_with_rle.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Path_on_surface_with_rle.h @@ -1507,13 +1507,6 @@ public: CGAL_assertion(is_valid()); } - /// Factorize the path into primitive - std::pair factorize() { - Path_on_surface p(*this); - auto result = p.factorize(); - return std::make_pair(Self(m_MQ, result.first, m_use_only_positive, m_use_only_negative), result.second); - } - void display_positive_turns() { std::cout<<"+("; From 3c0d5123f10a2210280ea0b04ff93e85ed3d7398 Mon Sep 17 00:00:00 2001 From: Youmu Date: Tue, 7 Jul 2020 22:44:11 -0400 Subject: [PATCH 024/248] Add a test on double torus --- .../test/Surface_mesh_topology/CMakeLists.txt | 1 + .../simplicity_double_torus.cpp | 92 +++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 Surface_mesh_topology/test/Surface_mesh_topology/simplicity_double_torus.cpp diff --git a/Surface_mesh_topology/test/Surface_mesh_topology/CMakeLists.txt b/Surface_mesh_topology/test/Surface_mesh_topology/CMakeLists.txt index 36cc15870a8..37b23c93389 100644 --- a/Surface_mesh_topology/test/Surface_mesh_topology/CMakeLists.txt +++ b/Surface_mesh_topology/test/Surface_mesh_topology/CMakeLists.txt @@ -34,6 +34,7 @@ set(SOURCE_FILES path_tests.cpp path_with_rle_deformation_tests.cpp shortest_noncontractible_cycle_tests.cpp + simplicity_double_torus.cpp test_homotopy.cpp test_homotopy_with_polygonal_schema.cpp test_shortest_cycle_non_contractible.cpp diff --git a/Surface_mesh_topology/test/Surface_mesh_topology/simplicity_double_torus.cpp b/Surface_mesh_topology/test/Surface_mesh_topology/simplicity_double_torus.cpp new file mode 100644 index 00000000000..8623a7d6cac --- /dev/null +++ b/Surface_mesh_topology/test/Surface_mesh_topology/simplicity_double_torus.cpp @@ -0,0 +1,92 @@ +#include +#include +#include + +using namespace CGAL::Surface_mesh_topology; +typedef Polygonal_schema_with_combinatorial_map<> PS; + +/////////////////////////////////////////////////////////////////////////////// +void create_path_1(Path_on_surface& p) +{ + p.push_back_by_label("b b a b -d -d -d -c -d a"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_path_2(Path_on_surface& p) +{ + p.push_back_by_label("b b a b d c d d d a"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_path_3(Path_on_surface& p) +{ + p.push_back_by_label("a b b b a b b a b b"); + p.push_back_by_label("d c"); + p.push_back_by_label("d c d c d"); + p.push_back_by_label("-c -d"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_path_4(Path_on_surface& p) +{ + p.push_back_by_label("a b b b a b b a b b"); + p.push_back_by_label("d c"); + p.push_back_by_label("-d -c -d -c -d"); + p.push_back_by_label("-c -d"); +} + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + PS ps; + ps.add_facet("a b -a -b c d -c -d"); + + Curves_on_surface_topology cst(ps); + Path_on_surface p1(ps), p2(ps), p3(ps), p4(ps); + create_path_1(p1); + create_path_2(p2); + create_path_3(p3); + create_path_4(p4); + + bool res=true; + + if(!cst.is_homotopic_to_simple_cycle(p1)) + { + std::cout<<"ERROR simplicity_double_torus test1: " + <<"Path p1 should be homotopic to a simple cycle" + < Date: Thu, 9 Jul 2020 21:55:03 -0400 Subject: [PATCH 025/248] WIP: Correctly handle case when there are more than 2 vertices in the minimal quadrangulation. Correctly check well-pairedness up to rotation. --- .../internal/Minimal_quadrangulation.h | 238 ++++++++++-------- 1 file changed, 136 insertions(+), 102 deletions(-) diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h index fed2c0bfd7b..90299212f42 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h @@ -588,18 +588,17 @@ public: // Compute the backward cyclic KMP failure table for the curve std::vector suffix_len = compute_common_circular_suffix(pr); pr.compute_switchable(); - size_type src_degree = degree(get_local_map(), get_local_map().darts().begin()); typedef typename boost::intrusive::rbtree> rbtree; std::vector rb_nodes; rb_nodes.reserve(pr.length()); - std::vector trees(src_degree); + std::unordered_map trees; for (std::size_t i = 0; i < pr.length(); ++i) { Dart_const_handle dh = pr[i]; - auto dart_id = get_dart_absolute_order_relative_to(pr[i], pr[0]); + auto dart_id = get_absolute_idx(dh); rb_nodes.emplace_back(i); auto& node = rb_nodes.back(); @@ -608,7 +607,7 @@ public: { // Look at the t-1 turn of [i-1, i, i + 1] Dart_const_handle dleft = get_local_map().template beta<0, 2>(dh); - auto dleft_id = get_dart_absolute_order_relative_to(dleft, pr[0]); + auto dleft_id = get_absolute_idx(dleft); // Binary search within potential switch trigger // TODO: apply the optimization Francis mentioned by only look at the largest one // Convert a dart to a circular ordering index @@ -618,7 +617,7 @@ public: return this->get_order_relative_to(dprev, dleft); }; size_type key_val = get_order_relative_to(pr[i - 1], dleft); - if (get_local_map().template belong_to_same_cell<0>(dh, pr[0])) + if (is_absolutely_directed(dleft)) { auto comparator = [&to_order] (const std::size_t& key, const rbtree::value_type& b) -> bool { return key > to_order(b.m_idx); @@ -641,7 +640,7 @@ public: } } dh = pr[i]; - dart_id = get_dart_absolute_order_relative_to(pr[i], pr[0]); + dart_id = get_absolute_idx(pr[i]); } // Insert current darts if (trees[dart_id].empty()) @@ -650,7 +649,7 @@ public: } else { - size_type prev_dart_id = get_dart_absolute_order_relative_to(pr[i - 1], pr[0]); + size_type prev_dart_id = get_absolute_idx(pr[i - 1]); auto it_prev = trees[prev_dart_id].iterator_to(rb_nodes[i - 1]); if (it_prev != trees[prev_dart_id].begin() && is_same_corner(pr, std::prev(it_prev)->m_idx, i - 1)) { @@ -664,128 +663,153 @@ public: } else { - if (get_local_map().template belong_to_same_cell<0>(dh, pr[0])) - { - auto comparator = [this, &pr, &p_original, &suffix_len] (const std::size_t& key, const rbtree::value_type& b) -> bool { - if (b.m_idx == 0 && pr[key] == pr[0]) + auto less_than_in_tree = is_absolutely_directed(dh)? + std::function{std::less()} : std::function{std::greater()}; + auto comparator = [this, &pr, &p_original, &suffix_len, &less_than_in_tree] (const std::size_t& key, const rbtree::value_type& b) -> bool { + if (b.m_idx == 0 && pr[key] == pr[0]) + { + if(pr[key] != p_original[key]) { + // current edge was switched so it should always be on the right side (more counter-clockwise) + return false; + } + std::size_t current_dividing_idx = key + p_original.length() - 1 - suffix_len[key - 1]; + std::size_t path_end_dividing_idx = p_original.length() - 1 - suffix_len[key - 1]; + std::size_t last_same_idx = (path_end_dividing_idx == p_original.length() - 1) ? 0 : path_end_dividing_idx + 1; + if (current_dividing_idx >= p_original.length()) { - if(pr[key] != p_original[key]) { - // current edge was switched so it should always be on the right side (more counter-clockwise) - return false; - } - std::size_t current_dividing_idx = key + p_original.length() - 1 - suffix_len[key - 1]; - std::size_t path_end_dividing_idx = p_original.length() - 1 - suffix_len[key - 1]; - std::size_t last_same_idx = (path_end_dividing_idx == p_original.length() - 1) ? 0 : path_end_dividing_idx + 1; - if (current_dividing_idx >= p_original.length()) - { - current_dividing_idx -= p_original.length(); - } - Dart_const_handle dbase = p_original[last_same_idx], - dcur = p_original[current_dividing_idx], - d0 = p_original[path_end_dividing_idx]; + current_dividing_idx -= p_original.length(); + } + Dart_const_handle dbase = p_original[last_same_idx], + dcur = p_original[current_dividing_idx], + d0 = p_original[path_end_dividing_idx]; - std::size_t key_prev_order = this->get_order_relative_to(dcur, dbase); - std::size_t b_prev_order = this->get_order_relative_to(d0, dbase); - return b_prev_order < key_prev_order; - } - else - { - std::size_t key_prev_order = this->get_order_relative_to(pr[key - 1], pr[key]); - Dart_const_handle bprev = this->get_previous_relative_to(pr, b.m_idx, pr[key]); - std::size_t b_prev_order = this->get_order_relative_to(bprev, pr[key]); - return b_prev_order < key_prev_order; - } - }; - auto it_after = trees[dart_id].upper_bound(i, comparator); - trees[dart_id].insert_before(it_after, node); - } - else - { - auto comparator = [this, &pr, &p_original] (const std::size_t& key, const rbtree::value_type& b) -> bool { - /// It is impossible that pr[key] == pr[b.m_idx] == pr[0] + std::size_t key_prev_order = this->get_order_relative_to(dcur, dbase); + std::size_t b_prev_order = this->get_order_relative_to(d0, dbase); + return less_than_in_tree(b_prev_order, key_prev_order); + } + else + { std::size_t key_prev_order = this->get_order_relative_to(pr[key - 1], pr[key]); Dart_const_handle bprev = this->get_previous_relative_to(pr, b.m_idx, pr[key]); std::size_t b_prev_order = this->get_order_relative_to(bprev, pr[key]); - return b_prev_order > key_prev_order; - }; - auto it_after = trees[dart_id].upper_bound(i, comparator); - trees[dart_id].insert_before(it_after, node); - } + return less_than_in_tree(b_prev_order, key_prev_order); + } + }; + auto it_after = trees[dart_id].upper_bound(i, comparator); + trees[dart_id].insert_before(it_after, node); } } } // Check whether orders form a valid parenthesis expression // First for the same direction of pr[0] res = true; - Dart_const_handle dcur = pr[0], dstart = pr[0]; - std::stack parenthesis_pairing; - do { - auto dart_id = get_dart_absolute_order_relative_to(dcur, pr[0]); - for (auto it = trees[dart_id].begin(); it != trees[dart_id].end(); ++it) + + pr.display(); + std::cout << std::endl; + pr.display_pos_and_neg_turns(); + std::cout << std::endl; + p_original.display(); + std::cout << std::endl; + p_original.display_pos_and_neg_turns(); + std::cout << std::endl; + auto marktemp=get_local_map().get_new_mark(); + for (auto it=get_local_map().darts().begin(); + it!=get_local_map().darts().end(); ++it) + { + if (!get_local_map().is_marked(it, marktemp)) { - if (parenthesis_pairing.empty()) - { - parenthesis_pairing.push(it->m_idx); - } - else - { - std::size_t prev = parenthesis_pairing.top(); - std::size_t next = it->m_idx; - if(prev > next) + std::stack parenthesis_pairing; + std::vector rotated_darts; + bool start_pairing = false; + Dart_const_handle dh2=it; + auto construct_parenthesis = [&pr, &it, &parenthesis_pairing, &start_pairing, &rotated_darts, this] (const rbtree::value_type& node) { + std::cout << get_local_map().darts().index(pr[node.m_idx]) << '@' << node.m_idx << ' '; + if (!start_pairing) { - std::swap(prev, next); + if (rotated_darts.empty()) + { + rotated_darts.emplace_back(node); + return; + } + else + { + std::size_t prev = rotated_darts.back().m_idx; + std::size_t next = node.m_idx; + if(prev > next) + { + std::swap(prev, next); + } + std::size_t distance = next - prev; + if(next == pr.length() - 1 && prev == 0) + { + distance = 1; + std::swap(prev, next); + } + if(distance == 1 && this->get_local_map().template belong_to_same_cell<0>(pr[next], it)) + { + start_pairing = true; + std::cout << "starting "; + } + else + { + rotated_darts.emplace_back(node); + return; + } + } } - if(next == prev + 1 && get_local_map().template belong_to_same_cell<0>(pr[next], dstart)) + if (parenthesis_pairing.empty()) { - parenthesis_pairing.pop(); - } - else if(next == pr.length() - 1 && prev == 0) - { - parenthesis_pairing.pop(); + parenthesis_pairing.push(node.m_idx); } else { - parenthesis_pairing.push(it->m_idx); + std::size_t prev = parenthesis_pairing.top(); + std::size_t next = node.m_idx; + if(prev > next) + { + std::swap(prev, next); + } + std::size_t distance = next - prev; + if(next == pr.length() - 1 && prev == 0) + { + distance = 1; + std::swap(prev, next); + } + if(distance == 1 && this->get_local_map().template belong_to_same_cell<0>(pr[next], it)) + { + parenthesis_pairing.pop(); + } + else + { + parenthesis_pairing.push(node.m_idx); + } } - } - } - dcur = get_local_map().template beta<2, 1>(dcur); - } while (dcur != dstart); - res = parenthesis_pairing.empty(); - while (!parenthesis_pairing.empty()) - { parenthesis_pairing.pop(); } - // Next check for the opposite direction of pr[0] - dcur = get_local_map().opposite2(pr[0]); - dstart = get_local_map().opposite2(pr[0]); - do { - auto dart_id = get_dart_absolute_order_relative_to(dcur, pr[0]); - for (auto it = trees[dart_id].rbegin(); it != trees[dart_id].rend(); ++it) - { - if (parenthesis_pairing.empty()) + }; + do { - parenthesis_pairing.push(it->m_idx); - } - else - { - std::size_t prev = parenthesis_pairing.top(); - std::size_t next = it->m_idx; - if(prev > next) + get_local_map().mark(dh2, marktemp); + auto dart_id = get_absolute_idx(dh2); + std::cout << get_local_map().darts().index(dh2) << ':'; + if(is_absolutely_directed(dh2)) { - std::swap(prev, next); - } - if(next == prev + 1 && get_local_map().template belong_to_same_cell<0>(pr[next], dstart)) - { - parenthesis_pairing.pop(); + std::for_each(trees[dart_id].begin(), trees[dart_id].end(), construct_parenthesis); } else { - parenthesis_pairing.push(it->m_idx); + std::for_each(trees[dart_id].rbegin(), trees[dart_id].rend(), construct_parenthesis); } + std::cout << std::endl; + dh2 = get_local_map().template beta<2, 1>(dh2); } + while(dh2!=it); + std::cout << "leftover:"; + std::for_each(rotated_darts.begin(), rotated_darts.end(), construct_parenthesis); + std::cout << std::endl; + std::cout << std::endl; + res = res && parenthesis_pairing.empty(); } - dcur = get_local_map().template beta<2, 1>(dcur); - } while (dcur != dstart); - res = res && parenthesis_pairing.empty(); + } + get_local_map().free_mark(marktemp); } } @@ -2020,6 +2044,16 @@ protected: return p[j]; } + size_type get_absolute_idx(Dart_const_handle dh) const + { + return std::min(get_local_map().darts().index(dh), get_local_map().darts().index(get_local_map().opposite(dh))); + } + + bool is_absolutely_directed(Dart_const_handle dh) const + { + return get_local_map().darts().index(dh) < get_local_map().darts().index(get_local_map().opposite(dh)); + } + size_type get_dart_absolute_order_relative_to(Dart_const_handle x, Dart_const_handle ref) const { size_type ref_degree = degree(get_local_map(), get_local_map().darts().begin()); From 3b88d5a0e81b1b8acb3e80e8766458e62a3d0611 Mon Sep 17 00:00:00 2001 From: Youmu Date: Thu, 9 Jul 2020 22:10:04 -0400 Subject: [PATCH 026/248] Prevent last dart in the dart from switching --- Surface_mesh_topology/include/CGAL/Path_on_surface.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Surface_mesh_topology/include/CGAL/Path_on_surface.h b/Surface_mesh_topology/include/CGAL/Path_on_surface.h index dadbaab735f..6bd1c7bf7e4 100644 --- a/Surface_mesh_topology/include/CGAL/Path_on_surface.h +++ b/Surface_mesh_topology/include/CGAL/Path_on_surface.h @@ -1294,8 +1294,8 @@ public: m_switchable[j - 1] = false; } /// Last dart may become switchable - if ((is_switchable(j) && next_positive_turn(j - 1) == 2) || - next_positive_turn(j - 1) == 1) + if (j < length() && ((is_switchable(j) && next_positive_turn(j - 1) == 2) || + next_positive_turn(j - 1) == 1)) { m_switchable[j - 1] = true; } From 7687c3d854a909c6badca4d5eea677cdf624ee43 Mon Sep 17 00:00:00 2001 From: Youmu Date: Wed, 15 Jul 2020 00:03:16 -0400 Subject: [PATCH 027/248] Move switchable computation to Minimal_quadrangulation --- .../include/CGAL/Path_on_surface.h | 76 ------ .../internal/Minimal_quadrangulation.h | 230 +++++++++++------- 2 files changed, 145 insertions(+), 161 deletions(-) diff --git a/Surface_mesh_topology/include/CGAL/Path_on_surface.h b/Surface_mesh_topology/include/CGAL/Path_on_surface.h index 6bd1c7bf7e4..702e0c55647 100644 --- a/Surface_mesh_topology/include/CGAL/Path_on_surface.h +++ b/Surface_mesh_topology/include/CGAL/Path_on_surface.h @@ -1240,68 +1240,6 @@ public: return true; } - /// Compute whether each dart is switchable - void compute_switchable() - { - m_switchable.clear(); - m_switchable.resize(length(), false); - std::vector turns = compute_positive_turns(); - /// Skip the last dart since it can never be switched, nor can it - /// be the second last dart of a switch - std::size_t i = 1; - while (i < length()) - { - std::size_t idx = length() - 1 - i; - if (turns[idx] == 1) - { - /// This is the end of a possible switchbale subpath - m_switchable[idx].flip(); - ++i; - idx = length() - 1 - i; - while (i < length() && turns[idx] == 2) - { - m_switchable[idx].flip(); - ++i; - idx = length() - 1 - i; - } - } else - { - ++i; - } - } - m_switchable[0] = false; - } - - /// Report whether 'i'-th dart is switchable, needs to compute switchable first - bool is_switchable(std::size_t i) const - { - CGAL_assertion(m_switchable.size() == length()); - return i < length() && m_switchable[i]; - } - - /// Perform a switch starting at 'i'-th dart - void switch_dart(std::size_t i) - { - CGAL_assertion(is_switchable(i)); - m_path[i] = get_map().template beta<0, 2>(m_path[i]); - m_path[i + 1] = get_map().template beta<2, 0, 2>(m_path[i]); - m_switchable[i] = false; - /// It is guarantee that the last dart is not switchable - std::size_t j = i + 2; - for(; is_switchable(j - 1); ++j) - { - m_path[j] = get_map().template beta<2, 0, 2, 0, 2>(m_path[j - 1]); - m_switchable[j - 1] = false; - } - /// Last dart may become switchable - if (j < length() && ((is_switchable(j) && next_positive_turn(j - 1) == 2) || - next_positive_turn(j - 1) == 1)) - { - m_switchable[j - 1] = true; - } - CGAL_assertion(is_valid()); - } - bool same_turns(const char* turns) const { std::vector resplus=compute_positive_turns(); @@ -1357,25 +1295,11 @@ public: { std::cout<<" c "; } //<::storage_type m_map; // The underlying map std::vector m_path; /// The sequence of darts bool m_is_closed; /// True iff the path is a cycle std::vector m_flip; /// The sequence of flips - std::vector m_switchable; /// True iff the correspondent dart is switchable }; } // namespace Surface_mesh_topology diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h index 90299212f42..8cecd875dcd 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h @@ -581,21 +581,26 @@ public: // If the curve is not primitive, there must be at least // one self intersection - Path_on_surface pr(factorization.first); - pr.simplify_flips(); - Path_on_surface p_original(pr); + auto& p_original = factorization.first; + p_original.simplify_flips(); + std::vector pr; + pr.reserve(p_original.length()); + for(std::size_t i = 0; i < p_original.length(); ++i) + { + pr.emplace_back(p_original[i]); + } // Compute the backward cyclic KMP failure table for the curve - std::vector suffix_len = compute_common_circular_suffix(pr); - pr.compute_switchable(); + std::vector suffix_len = compute_common_circular_suffix(p_original); + std::vector switchable = compute_switchable(p_original); typedef typename boost::intrusive::rbtree> rbtree; std::vector rb_nodes; - rb_nodes.reserve(pr.length()); + rb_nodes.reserve(pr.size()); std::unordered_map trees; - for (std::size_t i = 0; i < pr.length(); ++i) + for (std::size_t i = 0; i < pr.size(); ++i) { Dart_const_handle dh = pr[i]; auto dart_id = get_absolute_idx(dh); @@ -603,44 +608,22 @@ public: auto& node = rb_nodes.back(); // Check whether current darts needs to be switched - if (i > 0 && pr.is_switchable(i)) + if (i > 0 && switchable[i]) { // Look at the t-1 turn of [i-1, i, i + 1] Dart_const_handle dleft = get_local_map().template beta<0, 2>(dh); - auto dleft_id = get_absolute_idx(dleft); - // Binary search within potential switch trigger - // TODO: apply the optimization Francis mentioned by only look at the largest one - // Convert a dart to a circular ordering index - auto to_order = [this, &pr, &dleft] (const std::size_t& j) -> size_type + size_type dleft_id = get_absolute_idx(dleft); + if(trees[dleft_id].size() > 0) { - Dart_const_handle dprev = this->get_previous_relative_to(pr, j, dleft); - return this->get_order_relative_to(dprev, dleft); - }; - size_type key_val = get_order_relative_to(pr[i - 1], dleft); - if (is_absolutely_directed(dleft)) - { - auto comparator = [&to_order] (const std::size_t& key, const rbtree::value_type& b) -> bool { - return key > to_order(b.m_idx); - }; - auto it_trigger = trees[dleft_id].upper_bound(key_val, comparator); - if (it_trigger != trees[dleft_id].end() && !get_local_map().template belong_to_same_cell<1>(pr[it_trigger->m_idx], dh)) + std::size_t max_turn_idx = is_absolutely_directed(dleft) ? trees[dleft_id].begin()->m_idx : trees[dleft_id].rbegin()->m_idx; + Dart_const_handle dprev = get_previous_relative_to(pr, max_turn_idx, dleft); + if(get_order_relative_to(pr[i - 1], dleft) > get_order_relative_to(dprev, dleft)) { - pr.switch_dart(i); + switch_dart(pr, i, switchable); + dh = pr[i]; + dart_id = get_absolute_idx(pr[i]); } } - else - { - auto comparator = [&to_order] (const std::size_t& key, const rbtree::value_type& b) -> bool { - return key < to_order(b.m_idx); - }; - auto it_trigger = trees[dleft_id].upper_bound(0, comparator); - if (it_trigger != trees[dleft_id].end() && to_order(it_trigger->m_idx) < key_val) - { - pr.switch_dart(i); - } - } - dh = pr[i]; - dart_id = get_absolute_idx(pr[i]); } // Insert current darts if (trees[dart_id].empty()) @@ -653,24 +636,38 @@ public: auto it_prev = trees[prev_dart_id].iterator_to(rb_nodes[i - 1]); if (it_prev != trees[prev_dart_id].begin() && is_same_corner(pr, std::prev(it_prev)->m_idx, i - 1)) { - auto it_after = trees[dart_id].iterator_to(rb_nodes[get_next_idx_relative_to(pr, std::prev(it_prev)->m_idx, pr[i - 1])]); - trees[dart_id].insert_before(it_after, node); + auto it_adjacent = trees[dart_id].iterator_to(rb_nodes[get_next_idx_relative_to(pr, std::prev(it_prev)->m_idx, pr[i - 1])]); + if(is_absolutely_directed(pr[i - 1]) == is_absolutely_directed(dh)) + { + trees[dart_id].insert_before(std::next(it_adjacent), node); + } + else + { + trees[dart_id].insert_before(it_adjacent, node); + } } else if (std::next(it_prev) != trees[prev_dart_id].end() && is_same_corner(pr, std::next(it_prev)->m_idx, i - 1)) { - auto it_before = trees[dart_id].iterator_to(rb_nodes[get_next_idx_relative_to(pr, std::next(it_prev)->m_idx, pr[i-1])]); - trees[dart_id].insert_before(std::next(it_before), node); + auto it_adjacent = trees[dart_id].iterator_to(rb_nodes[get_next_idx_relative_to(pr, std::next(it_prev)->m_idx, pr[i-1])]); + if(is_absolutely_directed(pr[i - 1]) == is_absolutely_directed(dh)) + { + trees[dart_id].insert_before(it_adjacent, node); + } + else + { + trees[dart_id].insert_before(std::next(it_adjacent), node); + } } else { auto less_than_in_tree = is_absolutely_directed(dh)? - std::function{std::less()} : std::function{std::greater()}; + std::function{std::greater()} : std::function{std::less()}; auto comparator = [this, &pr, &p_original, &suffix_len, &less_than_in_tree] (const std::size_t& key, const rbtree::value_type& b) -> bool { if (b.m_idx == 0 && pr[key] == pr[0]) { if(pr[key] != p_original[key]) { // current edge was switched so it should always be on the right side (more counter-clockwise) - return false; + return less_than_in_tree(1, 0); } std::size_t current_dividing_idx = key + p_original.length() - 1 - suffix_len[key - 1]; std::size_t path_end_dividing_idx = p_original.length() - 1 - suffix_len[key - 1]; @@ -685,14 +682,14 @@ public: std::size_t key_prev_order = this->get_order_relative_to(dcur, dbase); std::size_t b_prev_order = this->get_order_relative_to(d0, dbase); - return less_than_in_tree(b_prev_order, key_prev_order); + return less_than_in_tree(key_prev_order, b_prev_order); } else { std::size_t key_prev_order = this->get_order_relative_to(pr[key - 1], pr[key]); Dart_const_handle bprev = this->get_previous_relative_to(pr, b.m_idx, pr[key]); std::size_t b_prev_order = this->get_order_relative_to(bprev, pr[key]); - return less_than_in_tree(b_prev_order, key_prev_order); + return less_than_in_tree(key_prev_order, b_prev_order); } }; auto it_after = trees[dart_id].upper_bound(i, comparator); @@ -704,14 +701,28 @@ public: // First for the same direction of pr[0] res = true; - pr.display(); - std::cout << std::endl; - pr.display_pos_and_neg_turns(); - std::cout << std::endl; p_original.display(); std::cout << std::endl; - p_original.display_pos_and_neg_turns(); + for(std::size_t i = 0; i < p_original.length(); ++i) + { + std::cout << (i>0?" ":"") << positive_turn(p_original[i], p_original.get_next_dart(i)); + } + std::cout << ")" << std::endl; + + Path_on_surface p_temp(get_local_map()); + for(auto& dart : pr) + { + p_temp.push_back(dart); + } + p_temp.display(); std::cout << std::endl; + std::cout << "+("; + for(std::size_t i = 0; i < p_temp.length(); ++i) + { + std::cout << (i>0?" ":"") << positive_turn(p_temp[i], p_temp.get_next_dart(i)); + } + std::cout << ")" << std::endl; + auto marktemp=get_local_map().get_new_mark(); for (auto it=get_local_map().darts().begin(); it!=get_local_map().darts().end(); ++it) @@ -740,7 +751,7 @@ public: std::swap(prev, next); } std::size_t distance = next - prev; - if(next == pr.length() - 1 && prev == 0) + if(next == pr.size() - 1 && prev == 0) { distance = 1; std::swap(prev, next); @@ -770,7 +781,7 @@ public: std::swap(prev, next); } std::size_t distance = next - prev; - if(next == pr.length() - 1 && prev == 0) + if(next == pr.size() - 1 && prev == 0) { distance = 1; std::swap(prev, next); @@ -1994,54 +2005,111 @@ protected: return result; } + /// Compute a boolean array of whether there is an left-L-shape at i-th dart, aka whether it is swicthable + std::vector compute_switchable(const Path_on_surface& p) const + { + std::vector switchable(p.length(), false); + /// Skip the last dart and the first dart since it can never be switched, nor can it + /// be the second last dart of a switch + std::size_t idx = p.length() - 2; + while (idx > 0) + { + if (positive_turn(p[idx], p[idx + 1]) == 1) + { + /// This is the end of a possible switchbale subpath + switchable[idx].flip(); + --idx; + while (idx > 0 && positive_turn(p[idx], p[idx + 1]) == 2) + { + switchable[idx].flip(); + --idx; + } + } else + { + --idx; + } + } + return switchable; + } + + /// Actually switch the dart in a vector of darts + void switch_dart(std::vector& p, std::size_t i, std::vector& switchable) const + { + CGAL_assertion(static_cast(switchable[i])); + p[i] = get_local_map().template beta<0, 2>(p[i]); + p[i + 1] = get_local_map().template beta<2, 0, 2>(p[i]); + switchable[i] = false; + /// It is guarantee that the last dart is not switchable + std::size_t j = i + 2; + for(; switchable[j - 1]; ++j) + { + p[j] = get_local_map().template beta<2, 0, 2, 0, 2>(p[j - 1]); + switchable[j - 1] = false; + } + /// Last dart may become switchable + if (j < p.size() && ((switchable[j] && positive_turn(p[j - 1], p[j]) == 2) || + positive_turn(p[j - 1], p[j]) == 1)) + { + switchable[j - 1] = true; + } + } + size_type get_order_relative_to(Dart_const_handle x, Dart_const_handle ref) const { - size_type ref_degree = degree(get_local_map(), get_local_map().darts().begin()); - size_type ref_order = get_dart_absolute_order_relative_to(ref, ref), - x_order = get_dart_absolute_order_relative_to(x, ref); - return x_order <= ref_order ? (x_order + ref_degree - ref_order - 1) : (x_order - ref_order - 1); + CGAL_assertion(get_local_map().template belong_to_same_cell<0>(get_local_map().opposite2(x), ref)); + return get_local_map().positive_turn(get_local_map().opposite2(ref), get_local_map().opposite2(x)); } - int get_previous_idx_relative_to(const Path_on_surface&p, std::size_t i, Dart_const_handle ref) const + int get_previous_idx_relative_to(const std::vector& p, std::size_t i, Dart_const_handle ref) const { - return get_local_map().template belong_to_same_cell<0>(p[i], ref) ? (static_cast(i) - 1) : (static_cast(i) + 1); + CGAL_assertion(get_local_map().template belong_to_same_cell<1>(p[i], ref)); + return p[i] == ref ? (static_cast(i) - 1) : (static_cast(i) + 1); } - bool has_previous_relative_to(const Path_on_surface& p, std::size_t i, Dart_const_handle ref) const + bool has_previous_relative_to(const std::vector& p, std::size_t i, Dart_const_handle ref) const { CGAL_assertion(get_local_map().template belong_to_same_cell<1>(p[i], ref)); int j = get_previous_idx_relative_to(p, i, ref); - return j >= 0 && j < p.length(); + return j >= 0 && j < p.size(); } - Dart_const_handle get_previous_relative_to(const Path_on_surface& p, std::size_t i, Dart_const_handle ref) const + Dart_const_handle get_previous_relative_to(const std::vector& p, std::size_t i, Dart_const_handle ref) const { CGAL_assertion(get_local_map().template belong_to_same_cell<1>(p[i], ref)); - int j = get_previous_idx_relative_to(p, i, ref); - if (j < 0) { j += p.length(); } - else if (j >= p.length()) { j -= p.length(); } - return p[j]; + if (p[i] == ref) + { + return p[(i == 0) ? (p.size() - 1) : i - 1]; + } + else + { + return get_local_map().opposite2(p[(i == p.size() - 1) ? 0 : i + 1]); + } } - int get_next_idx_relative_to(const Path_on_surface&p, std::size_t i, Dart_const_handle ref) const + int get_next_idx_relative_to(const std::vector& p, std::size_t i, Dart_const_handle ref) const { - return get_local_map().template belong_to_same_cell<0>(p[i], ref) ? (static_cast(i) + 1) : (static_cast(i) - 1); + CGAL_assertion(get_local_map().template belong_to_same_cell<1>(p[i], ref)); + return p[i] == ref ? (static_cast(i) + 1) : (static_cast(i) - 1); } - bool has_next_relative_to(const Path_on_surface& p, std::size_t i, Dart_const_handle ref) const + bool has_next_relative_to(const std::vector& p, std::size_t i, Dart_const_handle ref) const { CGAL_assertion(get_local_map().template belong_to_same_cell<1>(p[i], ref)); int j = get_next_idx_relative_to(p, i, ref); - return j >= 0 && j < p.length(); + return j >= 0 && j < p.size(); } - Dart_const_handle get_next_relative_to(const Path_on_surface& p, std::size_t i, Dart_const_handle ref) const + Dart_const_handle get_next_relative_to(const std::vector& p, std::size_t i, Dart_const_handle ref) const { CGAL_assertion(get_local_map().template belong_to_same_cell<1>(p[i], ref)); - int j = get_next_idx_relative_to(p, i, ref); - if (j < 0) { j += p.length(); } - else if (j >= p.length()) { j -= p.length(); } - return p[j]; + if (p[i] == ref) + { + return p[(i == p.size() - 1) ? 0 : i + 1]; + } + else + { + return get_local_map().opposite2(p[(i == 0) ? (p.size() - 1) : i - 1]); + } } size_type get_absolute_idx(Dart_const_handle dh) const @@ -2054,21 +2122,13 @@ protected: return get_local_map().darts().index(dh) < get_local_map().darts().index(get_local_map().opposite(dh)); } - size_type get_dart_absolute_order_relative_to(Dart_const_handle x, Dart_const_handle ref) const - { - size_type ref_degree = degree(get_local_map(), get_local_map().darts().begin()); - return get_local_map().template belong_to_same_cell<0>(x, ref) ? - get_dart_id(x) % ref_degree : - get_dart_id(get_local_map().opposite2(x)) % ref_degree; - } - - bool is_same_corner(const Path_on_surface& p, std::size_t j, std::size_t ref) const + bool is_same_corner(const std::vector& p, std::size_t j, std::size_t ref) const { if (!has_next_relative_to(p, j, p[ref])) { return false; } - return get_local_map().template belong_to_same_cell<1>(get_next_relative_to(p, j, p[ref]), p[ref + 1]); + return get_next_relative_to(p, j, p[ref]) == p[ref + 1]; } protected: From 40093649e280001d2c6270af0d25d322734bcec4 Mon Sep 17 00:00:00 2001 From: Youmu Date: Wed, 15 Jul 2020 00:03:54 -0400 Subject: [PATCH 028/248] Add test for double torus with holes --- .../test/Surface_mesh_topology/CMakeLists.txt | 1 + .../simplicity_double_torus_with_holes.cpp | 137 ++++++++++++++++++ 2 files changed, 138 insertions(+) create mode 100644 Surface_mesh_topology/test/Surface_mesh_topology/simplicity_double_torus_with_holes.cpp diff --git a/Surface_mesh_topology/test/Surface_mesh_topology/CMakeLists.txt b/Surface_mesh_topology/test/Surface_mesh_topology/CMakeLists.txt index 37b23c93389..a360e7ea87c 100644 --- a/Surface_mesh_topology/test/Surface_mesh_topology/CMakeLists.txt +++ b/Surface_mesh_topology/test/Surface_mesh_topology/CMakeLists.txt @@ -35,6 +35,7 @@ set(SOURCE_FILES path_with_rle_deformation_tests.cpp shortest_noncontractible_cycle_tests.cpp simplicity_double_torus.cpp + simplicity_double_torus_with_holes.cpp test_homotopy.cpp test_homotopy_with_polygonal_schema.cpp test_shortest_cycle_non_contractible.cpp diff --git a/Surface_mesh_topology/test/Surface_mesh_topology/simplicity_double_torus_with_holes.cpp b/Surface_mesh_topology/test/Surface_mesh_topology/simplicity_double_torus_with_holes.cpp new file mode 100644 index 00000000000..dc74265eff9 --- /dev/null +++ b/Surface_mesh_topology/test/Surface_mesh_topology/simplicity_double_torus_with_holes.cpp @@ -0,0 +1,137 @@ +#define CGAL_TRACE_CMAP_TOOLS +#include +#include +#include + +using namespace CGAL::Surface_mesh_topology; +typedef Polygonal_schema_with_combinatorial_map<> PS; + +/////////////////////////////////////////////////////////////////////////////// +void create_mesh1(PS& ps) +{ + ps.add_facet("b -a g f e"); + ps.add_facet("-b k i -g"); + ps.add_facet("-f -i -h"); + ps.add_facet("a -e h j"); + ps.add_facet("-k -m -l -j"); + ps.add_facet("c -r o m"); + ps.add_facet("-o -p -n"); + ps.add_facet("-d l n -q"); + ps.add_facet("d -c q p r"); + ps.perforate_facet("-i"); + ps.perforate_facet("-o"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_mesh2(PS& ps) +{ + ps.add_facet("a b -a -b o"); + ps.add_facet("-o -p"); + ps.add_facet("c d -c -d p"); + ps.perforate_facet("-o"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_mesh3(PS& ps) +{ + ps.add_facet("a b -a -b s"); + ps.add_facet("c d -c -d -s"); + ps.perforate_facet("s"); + ps.perforate_facet("-s"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_path_1(Path_on_surface& p) +{ + p.push_back_by_label("b b a b -d -d -d -c -d a"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_path_2(Path_on_surface& p) +{ + p.push_back_by_label("b b a b d c d d d a"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_path_3(Path_on_surface& p) +{ + p.push_back_by_label("a b b b a b b a b b"); + p.push_back_by_label("d c"); + p.push_back_by_label("d c d c d"); + p.push_back_by_label("-c -d"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_path_4(Path_on_surface& p) +{ + p.push_back_by_label("a b b b a b b a b b"); + p.push_back_by_label("d c"); + p.push_back_by_label("-d -c -d -c -d"); + p.push_back_by_label("-c -d"); +} + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + PS ps[3]; + create_mesh1(ps[0]); + create_mesh2(ps[1]); + create_mesh3(ps[2]); + + std::size_t num_ps = sizeof(ps) / sizeof(PS); + bool res=true; + + for(std::size_t i = 0; i < num_ps; ++i) + { + Curves_on_surface_topology cst(ps[i]); + Path_on_surface p1(ps[i]), p2(ps[i]), p3(ps[i]), p4(ps[i]); + create_path_1(p1); + create_path_2(p2); + create_path_3(p3); + create_path_4(p4); + + if(!cst.is_homotopic_to_simple_cycle(p1)) + { + std::cout<<"ERROR simplicity_double_torus_with_holes surface" + << i << "/test1: " + <<"Path p1 should be homotopic to a simple cycle" + < Date: Wed, 15 Jul 2020 15:47:40 -0400 Subject: [PATCH 029/248] Use better parenthesis pairing mechanism --- .../internal/Minimal_quadrangulation.h | 129 +++++------------- 1 file changed, 32 insertions(+), 97 deletions(-) diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h index 8cecd875dcd..429a9e0615b 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h @@ -700,123 +700,58 @@ public: // Check whether orders form a valid parenthesis expression // First for the same direction of pr[0] res = true; - - p_original.display(); - std::cout << std::endl; - for(std::size_t i = 0; i < p_original.length(); ++i) - { - std::cout << (i>0?" ":"") << positive_turn(p_original[i], p_original.get_next_dart(i)); - } - std::cout << ")" << std::endl; - - Path_on_surface p_temp(get_local_map()); - for(auto& dart : pr) - { - p_temp.push_back(dart); - } - p_temp.display(); - std::cout << std::endl; - std::cout << "+("; - for(std::size_t i = 0; i < p_temp.length(); ++i) - { - std::cout << (i>0?" ":"") << positive_turn(p_temp[i], p_temp.get_next_dart(i)); - } - std::cout << ")" << std::endl; - auto marktemp=get_local_map().get_new_mark(); for (auto it=get_local_map().darts().begin(); it!=get_local_map().darts().end(); ++it) { if (!get_local_map().is_marked(it, marktemp)) { - std::stack parenthesis_pairing; - std::vector rotated_darts; - bool start_pairing = false; + std::stack> parenthesis_pairing; Dart_const_handle dh2=it; - auto construct_parenthesis = [&pr, &it, &parenthesis_pairing, &start_pairing, &rotated_darts, this] (const rbtree::value_type& node) { - std::cout << get_local_map().darts().index(pr[node.m_idx]) << '@' << node.m_idx << ' '; - if (!start_pairing) - { - if (rotated_darts.empty()) - { - rotated_darts.emplace_back(node); - return; - } - else - { - std::size_t prev = rotated_darts.back().m_idx; - std::size_t next = node.m_idx; - if(prev > next) - { - std::swap(prev, next); - } - std::size_t distance = next - prev; - if(next == pr.size() - 1 && prev == 0) - { - distance = 1; - std::swap(prev, next); - } - if(distance == 1 && this->get_local_map().template belong_to_same_cell<0>(pr[next], it)) - { - start_pairing = true; - std::cout << "starting "; - } - else - { - rotated_darts.emplace_back(node); - return; - } - } - } - if (parenthesis_pairing.empty()) - { - parenthesis_pairing.push(node.m_idx); - } - else - { - std::size_t prev = parenthesis_pairing.top(); - std::size_t next = node.m_idx; - if(prev > next) - { - std::swap(prev, next); - } - std::size_t distance = next - prev; - if(next == pr.size() - 1 && prev == 0) - { - distance = 1; - std::swap(prev, next); - } - if(distance == 1 && this->get_local_map().template belong_to_same_cell<0>(pr[next], it)) - { - parenthesis_pairing.pop(); - } - else - { - parenthesis_pairing.push(node.m_idx); - } - } - }; do { get_local_map().mark(dh2, marktemp); auto dart_id = get_absolute_idx(dh2); - std::cout << get_local_map().darts().index(dh2) << ':'; + auto handle_node = [&dh2, &pr, &parenthesis_pairing] (const rbtree::value_type& node) { + auto curr_dart = std::make_pair(node.m_idx, pr[node.m_idx] == dh2); + if (parenthesis_pairing.empty()) + { + parenthesis_pairing.push(curr_dart); + } + else + { + auto prev_dart = parenthesis_pairing.top(); + auto next_dart = curr_dart; + if (next_dart < prev_dart) + { + std::swap(next_dart, prev_dart); + } + if (next_dart.first == pr.size() - 1 && prev_dart.first == 0) + { + std::swap(next_dart, prev_dart); + } + if ((next_dart.first - prev_dart.first == 1 || next_dart.first == 0) && + (!prev_dart.second && next_dart.second)) + { + parenthesis_pairing.pop(); + } + else + { + parenthesis_pairing.push(curr_dart); + } + } + }; if(is_absolutely_directed(dh2)) { - std::for_each(trees[dart_id].begin(), trees[dart_id].end(), construct_parenthesis); + std::for_each(trees[dart_id].begin(), trees[dart_id].end(), handle_node); } else { - std::for_each(trees[dart_id].rbegin(), trees[dart_id].rend(), construct_parenthesis); + std::for_each(trees[dart_id].rbegin(), trees[dart_id].rend(), handle_node); } - std::cout << std::endl; dh2 = get_local_map().template beta<2, 1>(dh2); } while(dh2!=it); - std::cout << "leftover:"; - std::for_each(rotated_darts.begin(), rotated_darts.end(), construct_parenthesis); - std::cout << std::endl; - std::cout << std::endl; res = res && parenthesis_pairing.empty(); } } From 88c795027b92e0b12728fe17dec2e1576f4addb8 Mon Sep 17 00:00:00 2001 From: Youmu Date: Wed, 15 Jul 2020 15:48:26 -0400 Subject: [PATCH 030/248] Remove some debugging output --- .../Surface_mesh_topology/simplicity_double_torus_with_holes.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Surface_mesh_topology/test/Surface_mesh_topology/simplicity_double_torus_with_holes.cpp b/Surface_mesh_topology/test/Surface_mesh_topology/simplicity_double_torus_with_holes.cpp index dc74265eff9..2ace679dcd5 100644 --- a/Surface_mesh_topology/test/Surface_mesh_topology/simplicity_double_torus_with_holes.cpp +++ b/Surface_mesh_topology/test/Surface_mesh_topology/simplicity_double_torus_with_holes.cpp @@ -1,4 +1,3 @@ -#define CGAL_TRACE_CMAP_TOOLS #include #include #include From 784395c2072a0e5d167d66cfaec1783956d7ebb6 Mon Sep 17 00:00:00 2001 From: Youmu Date: Wed, 15 Jul 2020 16:20:28 -0400 Subject: [PATCH 031/248] Use faster method to compute turn depending on compilation flag --- .../internal/Minimal_quadrangulation.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h index 429a9e0615b..f956df5bb9f 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h @@ -1989,10 +1989,19 @@ protected: } } + /// Essentially compute the positive turn between ref and x + /// Requires x and ref outgoing at the same vertex size_type get_order_relative_to(Dart_const_handle x, Dart_const_handle ref) const { CGAL_assertion(get_local_map().template belong_to_same_cell<0>(get_local_map().opposite2(x), ref)); - return get_local_map().positive_turn(get_local_map().opposite2(ref), get_local_map().opposite2(x)); +#if defined(CGAL_PWRLE_TURN_V2) || defined(CGAL_PWRLE_TURN_V3) + size_type ref_degree = get_local_map().template info<0>(ref); + size_type x_order = get_dart_id(get_local_map().opposite2(x)) % ref_degree; + size_type base_order = get_dart_id(ref) % ref_degree; + return (x_order < base_order) ? (x_order + ref_degree - base_order) : (x_order - base_order); +#else + return get_local_map().negative_turn(x, ref); +#endif } int get_previous_idx_relative_to(const std::vector& p, std::size_t i, Dart_const_handle ref) const From 95aef9e1e8e208c6dff5052782a8f8544a51b23a Mon Sep 17 00:00:00 2001 From: Youmu Date: Wed, 15 Jul 2020 16:21:20 -0400 Subject: [PATCH 032/248] Add comments --- .../internal/Minimal_quadrangulation.h | 35 +++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h index f956df5bb9f..18afc4ef6ca 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h @@ -617,6 +617,7 @@ public: { std::size_t max_turn_idx = is_absolutely_directed(dleft) ? trees[dleft_id].begin()->m_idx : trees[dleft_id].rbegin()->m_idx; Dart_const_handle dprev = get_previous_relative_to(pr, max_turn_idx, dleft); + // If there exists a crossing that can be avoided, switch if(get_order_relative_to(pr[i - 1], dleft) > get_order_relative_to(dprev, dleft)) { switch_dart(pr, i, switchable); @@ -632,6 +633,9 @@ public: } else { + // First check whether there is another corner in the previous part of the path + // where it matches p[i - 1] -> p[i] + // If so, p[i] must be inserted adjacent to one such corner size_type prev_dart_id = get_absolute_idx(pr[i - 1]); auto it_prev = trees[prev_dart_id].iterator_to(rb_nodes[i - 1]); if (it_prev != trees[prev_dart_id].begin() && is_same_corner(pr, std::prev(it_prev)->m_idx, i - 1)) @@ -660,6 +664,8 @@ public: } else { + /// There is no same corner in the previous of the path + /// Perform usual unzip insertion auto less_than_in_tree = is_absolutely_directed(dh)? std::function{std::greater()} : std::function{std::less()}; auto comparator = [this, &pr, &p_original, &suffix_len, &less_than_in_tree] (const std::size_t& key, const rbtree::value_type& b) -> bool { @@ -667,8 +673,9 @@ public: { if(pr[key] != p_original[key]) { // current edge was switched so it should always be on the right side (more counter-clockwise) - return less_than_in_tree(1, 0); + return less_than_in_tree(0, 1); } + /// Comparing to pr[0], needs to check longest suffix std::size_t current_dividing_idx = key + p_original.length() - 1 - suffix_len[key - 1]; std::size_t path_end_dividing_idx = p_original.length() - 1 - suffix_len[key - 1]; std::size_t last_same_idx = (path_end_dividing_idx == p_original.length() - 1) ? 0 : path_end_dividing_idx + 1; @@ -698,7 +705,6 @@ public: } } // Check whether orders form a valid parenthesis expression - // First for the same direction of pr[0] res = true; auto marktemp=get_local_map().get_new_mark(); for (auto it=get_local_map().darts().begin(); @@ -720,6 +726,9 @@ public: } else { + /// We can cancel a pair of dart iff + /// 1) They are adjacent in the path (wrap around for the last dart) + /// 2) The first one is going in and the second one is going out auto prev_dart = parenthesis_pairing.top(); auto next_dart = curr_dart; if (next_dart < prev_dart) @@ -2004,12 +2013,18 @@ protected: #endif } + /// Extend p[i] towards the reverse direction of ref + /// Requires p[i] and ref on the same 1-cell + /// @return the index int get_previous_idx_relative_to(const std::vector& p, std::size_t i, Dart_const_handle ref) const { CGAL_assertion(get_local_map().template belong_to_same_cell<1>(p[i], ref)); return p[i] == ref ? (static_cast(i) - 1) : (static_cast(i) + 1); } + /// Extend p[i] towards the reverse direction of ref + /// Requires p[i] and ref on the same 1-cell + /// @return whether the extension is viable without crossing the first and the last dart bool has_previous_relative_to(const std::vector& p, std::size_t i, Dart_const_handle ref) const { CGAL_assertion(get_local_map().template belong_to_same_cell<1>(p[i], ref)); @@ -2017,6 +2032,9 @@ protected: return j >= 0 && j < p.size(); } + /// Extend p[i] towards the reverse direction of ref + /// Requires p[i] and ref on the same 1-cell + /// @return the actual dart, wrap around if reaching boundary Dart_const_handle get_previous_relative_to(const std::vector& p, std::size_t i, Dart_const_handle ref) const { CGAL_assertion(get_local_map().template belong_to_same_cell<1>(p[i], ref)); @@ -2030,12 +2048,18 @@ protected: } } + /// Extend p[i] towards the direction of ref + /// Requires p[i] and ref on the same 1-cell + /// @return the index int get_next_idx_relative_to(const std::vector& p, std::size_t i, Dart_const_handle ref) const { CGAL_assertion(get_local_map().template belong_to_same_cell<1>(p[i], ref)); return p[i] == ref ? (static_cast(i) + 1) : (static_cast(i) - 1); } + /// Extend p[i] towards the direction of ref + /// Requires p[i] and ref on the same 1-cell + /// @return whether the extension is viable without crossing the first and the last dart bool has_next_relative_to(const std::vector& p, std::size_t i, Dart_const_handle ref) const { CGAL_assertion(get_local_map().template belong_to_same_cell<1>(p[i], ref)); @@ -2043,6 +2067,9 @@ protected: return j >= 0 && j < p.size(); } + /// Extend p[i] towards the direction of ref + /// Requires p[i] and ref on the same 1-cell + /// @return the actual dart, wrap around if reaching boundary Dart_const_handle get_next_relative_to(const std::vector& p, std::size_t i, Dart_const_handle ref) const { CGAL_assertion(get_local_map().template belong_to_same_cell<1>(p[i], ref)); @@ -2056,16 +2083,20 @@ protected: } } + /// @return a unique 1-cell id for the dart size_type get_absolute_idx(Dart_const_handle dh) const { return std::min(get_local_map().darts().index(dh), get_local_map().darts().index(get_local_map().opposite(dh))); } + /// @return true if the dart is the representative for the unique 1-cell id bool is_absolutely_directed(Dart_const_handle dh) const { return get_local_map().darts().index(dh) < get_local_map().darts().index(get_local_map().opposite(dh)); } + /// @return true if p[ref] -> p[ref + 1] forms the same corner as p[j] + /// Requires p[j] and p[ref] on the same 1-cell bool is_same_corner(const std::vector& p, std::size_t j, std::size_t ref) const { if (!has_next_relative_to(p, j, p[ref])) From 0933e9a86f1386020147a913850b1a8c8abed4aa Mon Sep 17 00:00:00 2001 From: Youmu Date: Wed, 15 Jul 2020 16:39:14 -0400 Subject: [PATCH 033/248] Add a test based on homology group --- .../test/Surface_mesh_topology/CMakeLists.txt | 1 + .../simplicity_homology_group.cpp | 131 ++++++++++++++++++ 2 files changed, 132 insertions(+) create mode 100644 Surface_mesh_topology/test/Surface_mesh_topology/simplicity_homology_group.cpp diff --git a/Surface_mesh_topology/test/Surface_mesh_topology/CMakeLists.txt b/Surface_mesh_topology/test/Surface_mesh_topology/CMakeLists.txt index a360e7ea87c..890e96964d9 100644 --- a/Surface_mesh_topology/test/Surface_mesh_topology/CMakeLists.txt +++ b/Surface_mesh_topology/test/Surface_mesh_topology/CMakeLists.txt @@ -36,6 +36,7 @@ set(SOURCE_FILES shortest_noncontractible_cycle_tests.cpp simplicity_double_torus.cpp simplicity_double_torus_with_holes.cpp + simplicity_homology_group.cpp test_homotopy.cpp test_homotopy_with_polygonal_schema.cpp test_shortest_cycle_non_contractible.cpp diff --git a/Surface_mesh_topology/test/Surface_mesh_topology/simplicity_homology_group.cpp b/Surface_mesh_topology/test/Surface_mesh_topology/simplicity_homology_group.cpp new file mode 100644 index 00000000000..e8d23f7e4eb --- /dev/null +++ b/Surface_mesh_topology/test/Surface_mesh_topology/simplicity_homology_group.cpp @@ -0,0 +1,131 @@ +#include +#include +#include + +using namespace CGAL::Surface_mesh_topology; +typedef Polygonal_schema_with_combinatorial_map<> PS; + +/////////////////////////////////////////////////////////////////////////////// +void create_mesh1(PS& ps) +{ + ps.add_facet("a b -a -b c d -c -d"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_mesh1_path1(Path_on_surface& p) +{ + p.push_back_by_label("a b c c -a -a -a b"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_mesh1_path2(Path_on_surface& p) +{ + p.push_back_by_label("a c a a c -a"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_mesh1_path3(Path_on_surface& p) +{ + p.push_back_by_label("d -c a a b a d b -c -c d b"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_mesh2(PS& ps) +{ + ps.add_facet("a b -a -b c d -c -d e f -e -f"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_mesh2_path1(Path_on_surface& p) +{ + p.push_back_by_label("b -c e -f c -f c b e c"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_mesh2_path2(Path_on_surface& p) +{ + p.push_back_by_label("a f -e a -e f"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_mesh2_path3(Path_on_surface& p) +{ + p.push_back_by_label("f a f -b -e -e b a"); +} + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + PS ps1, ps2; + create_mesh1(ps1); + create_mesh2(ps2); + + bool res=true; + + Curves_on_surface_topology cst1(ps1), cst2(ps2); + Path_on_surface p1_1(ps1), p2_1(ps1), p3_1(ps1), + p1_2(ps2), p2_2(ps2), p3_2(ps2); + + create_mesh1_path1(p1_1); + create_mesh1_path2(p2_1); + create_mesh1_path3(p3_1); + create_mesh2_path1(p1_2); + create_mesh2_path2(p2_2); + create_mesh2_path3(p3_2); + + if(cst1.is_homotopic_to_simple_cycle(p1_1)) + { + std::cout<<"ERROR simplicity_homology_group test1" + <<"Path p1_1 should not be homotopic to a simple cycle" + < Date: Wed, 15 Jul 2020 21:03:57 -0400 Subject: [PATCH 034/248] Short-circuit when verifying well-pairedness of darts --- .../Surface_mesh_topology/internal/Minimal_quadrangulation.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h index 18afc4ef6ca..346cbdce625 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h @@ -708,7 +708,7 @@ public: res = true; auto marktemp=get_local_map().get_new_mark(); for (auto it=get_local_map().darts().begin(); - it!=get_local_map().darts().end(); ++it) + res && it!=get_local_map().darts().end(); ++it) { if (!get_local_map().is_marked(it, marktemp)) { @@ -760,7 +760,7 @@ public: } dh2 = get_local_map().template beta<2, 1>(dh2); } - while(dh2!=it); + while(dh2!=it && res); res = res && parenthesis_pairing.empty(); } } From c99a7d095006a8adc3d3a4b3e8982d3f684d4cfa Mon Sep 17 00:00:00 2001 From: Youmu Date: Thu, 16 Jul 2020 16:35:20 -0400 Subject: [PATCH 035/248] Fix the calculation of power in factorization --- Surface_mesh_topology/include/CGAL/Path_on_surface.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Surface_mesh_topology/include/CGAL/Path_on_surface.h b/Surface_mesh_topology/include/CGAL/Path_on_surface.h index 702e0c55647..c7643fb764e 100644 --- a/Surface_mesh_topology/include/CGAL/Path_on_surface.h +++ b/Surface_mesh_topology/include/CGAL/Path_on_surface.h @@ -1121,10 +1121,11 @@ public: ; /// It can be proved that the first match location is the length of match auto primitiveSize = itMatch - pp2.m_path.begin(); + auto originalLength = pp1.length(); CGAL_assertion(pp1.length() % primitiveSize == 0); pp1.cut(primitiveSize); CGAL_assertion(pp1.is_closed()); - return std::make_pair(pp1, pp1.length() / primitiveSize); + return std::make_pair(pp1, originalLength / primitiveSize); } /// @return the turn between dart number i and dart number i+1. From 400762f0d5fa241519a01fd05d6fc0037a6fb01f Mon Sep 17 00:00:00 2001 From: Youmu Date: Thu, 16 Jul 2020 16:36:32 -0400 Subject: [PATCH 036/248] Fix parenthesis checking when the lenght of path is only 2 --- .../internal/Minimal_quadrangulation.h | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h index 346cbdce625..c98c8176c43 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h @@ -731,15 +731,11 @@ public: /// 2) The first one is going in and the second one is going out auto prev_dart = parenthesis_pairing.top(); auto next_dart = curr_dart; - if (next_dart < prev_dart) + if(!next_dart.second) { std::swap(next_dart, prev_dart); } - if (next_dart.first == pr.size() - 1 && prev_dart.first == 0) - { - std::swap(next_dart, prev_dart); - } - if ((next_dart.first - prev_dart.first == 1 || next_dart.first == 0) && + if ((next_dart.first - prev_dart.first == 1 || (next_dart.first == 0 && prev_dart.first == pr.size() - 1)) && (!prev_dart.second && next_dart.second)) { parenthesis_pairing.pop(); From 0cfe005e8602c43785ea01fee46cfa347d678540 Mon Sep 17 00:00:00 2001 From: Youmu Date: Thu, 16 Jul 2020 16:37:54 -0400 Subject: [PATCH 037/248] Skip checking if the length of canonical path is 1 --- .../internal/Minimal_quadrangulation.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h index c98c8176c43..f59d575f1e1 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h @@ -577,7 +577,9 @@ public: // Use non-rle path from now on Path_on_surface p_canonized(pt); auto factorization=p_canonized.factorize(); - if (factorization.second <= 1) { + // If the path length is 1, it must be simple + res = factorization.second <= 1 && factorization.first.length() <= 1; + if (factorization.second <= 1 && !res) { // If the curve is not primitive, there must be at least // one self intersection @@ -672,7 +674,7 @@ public: if (b.m_idx == 0 && pr[key] == pr[0]) { if(pr[key] != p_original[key]) { - // current edge was switched so it should always be on the right side (more counter-clockwise) + // current edge was switched so it should always be on the right side (more clockwise) return less_than_in_tree(0, 1); } /// Comparing to pr[0], needs to check longest suffix From 6078a8cdb6118e3a4e4f9c4ec3358a15a734d136 Mon Sep 17 00:00:00 2001 From: Youmu Date: Thu, 16 Jul 2020 16:38:55 -0400 Subject: [PATCH 038/248] Remove special case for cylinder. Fix the condition for torus --- .../internal/Minimal_quadrangulation.h | 46 +------------------ 1 file changed, 1 insertion(+), 45 deletions(-) diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h index f59d575f1e1..bf6fa1ce2a9 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h @@ -553,15 +553,7 @@ public: count_edges_of_path_on_torus(pt, a, b); a = std::abs(a); b = std::abs(b); - res=(a == 0 || b == 0 || CGAL::gcd(a, b) - 1 == 0); - } - else if (local_map_is_a_cylinder()) - { - internal::Path_on_surface_with_rle - pt=transform_original_path_into_quad_surface_with_rle(p); - - int p = count_edges_of_path_on_cylinder(pt); - res=(std::abs(p) <= 1); + res=((a == 0 && b == 1) || (b == 0 && a == 1) || CGAL::gcd(a, b) - 1 == 0); } else if (is_contractible(p)) { @@ -812,35 +804,6 @@ protected: } } - int count_edges_of_path_on_cylinder - (const Path_on_surface& path) const - { - CGAL_assertion(local_map_is_a_cylinder()); - int p = 0; - - Dart_const_handle dhp=get_local_map().darts().begin(); - Dart_const_handle dhn=get_local_map().template beta<2>(dhp); - for (std::size_t i = 0; i < path.length(); ++i) - { - if(path.get_ith_flip(i)) - { - if (path[i]==dhp || path[i]==get_local_map().template beta<1>(dhp)) - { --p; } - else if (path[i]==dhn || path[i]==get_local_map().template beta<1>(dhn)) - { ++p; } - } - else - { - if (path[i]==dhp || path[i]==get_local_map().template beta<1>(dhp)) - { ++p; } - else if (path[i]==dhn || path[i]==get_local_map().template beta<1>(dhn)) - { --p; } - } - } - - return p/2; - } - Path_on_surface transform_original_path_into_quad_surface_for_torus (const Path_on_surface& path) const @@ -1736,13 +1699,6 @@ protected: return (get_local_map().number_of_marked_darts(m_mark_perforated)==0); } - bool local_map_is_a_cylinder() const - { - if (get_local_map().number_of_darts()!=4) - { return false; } - return (get_local_map().number_of_marked_darts(m_mark_perforated)==4); - } - /// @return true iff the perforated faces are correctly marked /// (i.e. either fully marked or fully unmarked). bool perforated_faces_correctly_marked() const From 1f8ccad1e9cc7f3b61bd96f1c09098346c15006e Mon Sep 17 00:00:00 2001 From: Youmu Date: Thu, 16 Jul 2020 16:39:59 -0400 Subject: [PATCH 039/248] Add test for cylinder and torus --- .../test/Surface_mesh_topology/CMakeLists.txt | 2 + .../simplicity_cylinder.cpp | 114 ++++++++++++++++++ .../simplicity_double_torus_with_holes.cpp | 20 +-- .../simplicity_homology_group.cpp | 2 +- .../simplicity_torus.cpp | 86 +++++++++++++ 5 files changed, 213 insertions(+), 11 deletions(-) create mode 100644 Surface_mesh_topology/test/Surface_mesh_topology/simplicity_cylinder.cpp create mode 100644 Surface_mesh_topology/test/Surface_mesh_topology/simplicity_torus.cpp diff --git a/Surface_mesh_topology/test/Surface_mesh_topology/CMakeLists.txt b/Surface_mesh_topology/test/Surface_mesh_topology/CMakeLists.txt index 890e96964d9..4c20a8c48c7 100644 --- a/Surface_mesh_topology/test/Surface_mesh_topology/CMakeLists.txt +++ b/Surface_mesh_topology/test/Surface_mesh_topology/CMakeLists.txt @@ -34,9 +34,11 @@ set(SOURCE_FILES path_tests.cpp path_with_rle_deformation_tests.cpp shortest_noncontractible_cycle_tests.cpp + simplicity_cylinder.cpp simplicity_double_torus.cpp simplicity_double_torus_with_holes.cpp simplicity_homology_group.cpp + simplicity_torus.cpp test_homotopy.cpp test_homotopy_with_polygonal_schema.cpp test_shortest_cycle_non_contractible.cpp diff --git a/Surface_mesh_topology/test/Surface_mesh_topology/simplicity_cylinder.cpp b/Surface_mesh_topology/test/Surface_mesh_topology/simplicity_cylinder.cpp new file mode 100644 index 00000000000..0f06e0ec5fa --- /dev/null +++ b/Surface_mesh_topology/test/Surface_mesh_topology/simplicity_cylinder.cpp @@ -0,0 +1,114 @@ +#include +#include +#include + +using namespace CGAL::Surface_mesh_topology; +typedef Polygonal_schema_with_combinatorial_map<> PS; + +/////////////////////////////////////////////////////////////////////////////// +void create_mesh_1(PS& ps) +{ + ps.add_facet("a b c d"); + ps.add_facet("-b e -d f"); + ps.add_facet("-a -e"); + ps.add_facet("-c -f"); + ps.perforate_facet("-a"); + ps.perforate_facet("-c"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_mesh_2(PS& ps) +{ + ps.add_facet("a b c d"); + ps.add_facet("-b e -d f"); + ps.add_facet("-a -e"); + ps.add_facet("-c -f"); + ps.perforate_facet("-a"); + ps.perforate_facet("-c"); + ps.perforate_facet("a"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_mesh_3(PS& ps) +{ + ps.add_facet("a b c d"); + ps.add_facet("-b e -d f"); + ps.add_facet("-a -e"); + ps.add_facet("-c -f"); + ps.perforate_facet("-a"); + ps.perforate_facet("-c"); + ps.perforate_facet("e"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_path_1(Path_on_surface& p) +{ + p.push_back_by_label("a e"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_path_2(Path_on_surface& p) +{ + p.push_back_by_label("a b -f d a e"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_path_3(Path_on_surface& p) +{ + p.push_back_by_label("a b c d"); +} + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + PS ps[2]; + create_mesh_1(ps[0]); + create_mesh_2(ps[1]); + + std::size_t num_ps = sizeof(ps) / sizeof(PS); + bool res=true; + + for(std::size_t i = 0; i < num_ps; ++i) + { + Curves_on_surface_topology cst(ps[i]); + Path_on_surface p1(ps[i]), p2(ps[i]), p3(ps[i]); + create_path_1(p1); + create_path_2(p2); + create_path_3(p3); + + if(!cst.is_homotopic_to_simple_cycle(p1)) + { + std::cout<<"ERROR simplicity_cylinder surface" + << (i+1) << "/test1: " + <<"Path p1 should be homotopic to a simple cycle" + < PS; /////////////////////////////////////////////////////////////////////////////// -void create_mesh1(PS& ps) +void create_mesh_1(PS& ps) { ps.add_facet("b -a g f e"); ps.add_facet("-b k i -g"); @@ -22,7 +22,7 @@ void create_mesh1(PS& ps) } /////////////////////////////////////////////////////////////////////////////// -void create_mesh2(PS& ps) +void create_mesh_2(PS& ps) { ps.add_facet("a b -a -b o"); ps.add_facet("-o -p"); @@ -31,7 +31,7 @@ void create_mesh2(PS& ps) } /////////////////////////////////////////////////////////////////////////////// -void create_mesh3(PS& ps) +void create_mesh_3(PS& ps) { ps.add_facet("a b -a -b s"); ps.add_facet("c d -c -d -s"); @@ -73,9 +73,9 @@ void create_path_4(Path_on_surface& p) int main() { PS ps[3]; - create_mesh1(ps[0]); - create_mesh2(ps[1]); - create_mesh3(ps[2]); + create_mesh_1(ps[0]); + create_mesh_2(ps[1]); + create_mesh_3(ps[2]); std::size_t num_ps = sizeof(ps) / sizeof(PS); bool res=true; @@ -92,7 +92,7 @@ int main() if(!cst.is_homotopic_to_simple_cycle(p1)) { std::cout<<"ERROR simplicity_double_torus_with_holes surface" - << i << "/test1: " + << (i+1) << "/test1: " <<"Path p1 should be homotopic to a simple cycle" < +#include +#include + +using namespace CGAL::Surface_mesh_topology; +typedef Polygonal_schema_with_combinatorial_map<> PS; + +/////////////////////////////////////////////////////////////////////////////// +void create_path_1(Path_on_surface& p) +{ + p.push_back_by_label("a b a a b"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_path_2(Path_on_surface& p) +{ + p.push_back_by_label("a b"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_path_3(Path_on_surface& p) +{ + p.push_back_by_label("-a b a b b"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_path_4(Path_on_surface& p) +{ + p.push_back_by_label("-a -b a a -b -b a a -b a -b -b"); +} + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + PS ps; + ps.add_facet("a b -a -b"); + + Curves_on_surface_topology cst(ps); + Path_on_surface p1(ps), p2(ps), p3(ps), p4(ps); + create_path_1(p1); + create_path_2(p2); + create_path_3(p3); + create_path_4(p4); + + bool res=true; + + if(!cst.is_homotopic_to_simple_cycle(p1)) + { + std::cout<<"ERROR simplicity_torus test1: " + <<"Path p1 should be homotopic to a simple cycle" + < Date: Tue, 21 Jul 2020 20:40:01 -0400 Subject: [PATCH 040/248] First version of documentation --- Documentation/doc/biblio/cgal_manual.bib | 19 +++++++++++ .../CGAL/Curves_on_surface_topology.h | 5 +++ .../Surface_mesh_topology.txt | 34 ++++++++++++++++++- .../doc/Surface_mesh_topology/examples.txt | 2 ++ 4 files changed, 59 insertions(+), 1 deletion(-) diff --git a/Documentation/doc/biblio/cgal_manual.bib b/Documentation/doc/biblio/cgal_manual.bib index e2a2fd57555..0f4162ca63f 100644 --- a/Documentation/doc/biblio/cgal_manual.bib +++ b/Documentation/doc/biblio/cgal_manual.bib @@ -628,6 +628,25 @@ Mourrain and Monique Teillaud" keywords = "Convex hull problem, Frame, Linear programming, Data envelopment analysis, Redundancy" } +@article{cgal:dl-cginc-19, + author = {Despr\'{e}, Vincent and Lazarus, Francis}, + title = {Computing the Geometric Intersection Number of Curves}, + year = {2019}, + issue_date = {December 2019}, + publisher = {Association for Computing Machinery}, + address = {New York, NY, USA}, + volume = {66}, + number = {6}, + issn = {0004-5411}, + url = {https://doi.org/10.1145/3363367}, + doi = {10.1145/3363367}, + journal = {J. ACM}, + month = nov, + articleno = {45}, + numpages = {49}, + keywords = {combinatorial geodesic, Computational topology, intersection number, curves on surfaces} +} + @unpublished{cgal:dl-cosfa-08, author = "J.H. Dul\'a and F.J. L\'opez", title = "Competing Output-Sensitive Frame Algorithms", diff --git a/Surface_mesh_topology/doc/Surface_mesh_topology/CGAL/Curves_on_surface_topology.h b/Surface_mesh_topology/doc/Surface_mesh_topology/CGAL/Curves_on_surface_topology.h index ada0f528d73..2a0986b7311 100644 --- a/Surface_mesh_topology/doc/Surface_mesh_topology/CGAL/Curves_on_surface_topology.h +++ b/Surface_mesh_topology/doc/Surface_mesh_topology/CGAL/Curves_on_surface_topology.h @@ -39,6 +39,11 @@ namespace Surface_mesh_topology { */ bool is_contractible(const Path_on_surface& p) const; + /*! returns `true` if the closed path `p` is homotopic to some simple cycle. + * @pre `p` must be a closed path on `amesh`. + */ + bool is_homotopic_to_simple_cycle(const Path_on_surface& p) const; + /*! returns a non-contractible cycle of type `Path_on_surface` with minimal number of edges. This number of edges is the edge width of the mesh. */ Path_on_surface compute_edge_width() const; diff --git a/Surface_mesh_topology/doc/Surface_mesh_topology/Surface_mesh_topology.txt b/Surface_mesh_topology/doc/Surface_mesh_topology/Surface_mesh_topology.txt index 6d13664f032..e44fc13d9c8 100644 --- a/Surface_mesh_topology/doc/Surface_mesh_topology/Surface_mesh_topology.txt +++ b/Surface_mesh_topology/doc/Surface_mesh_topology/Surface_mesh_topology.txt @@ -46,7 +46,14 @@ The second query asks if the curves are freely homotopic while the thir The algorithms used are based on a paper by Erickson and Whittlesey \cgalCite{ew-tcsr-13}, providing a linear time algorithm for the above homotopy tests. This is a simplified version of the linear time algorithm by Lazarus and Rivaud \cgalCite{lr-hts-12}. +\subsection SMTopology_simplicity Simplicity Test +Given a cycle drawn on a surface one can ask if the cycle can be continously deformed to a cycle that does not intersect with itself. Cycles that deform to a non-self-intersecting cycle are said simple. Any contractible cycle is simple but this is not true for cycles on more complicated topology. The algorithm in this section is purely topological and do not assume any geometry on the input surface. + +The algorithm implemented in this package builds a data structure to efficiently answer queries of the following forms: +- Given a combinatorial surface \f$\cal{M}\f$ and a closed combinatorial curve specified as a sequence of edges of \f$\cal{M}\f$, decide if the curve is simple on \f$\cal{M}\f$. + +The algorithm used is based on a paper by Despré and Lazarus \cgalCite{cgal:dl-cginc-19}, providing a \f$O(n + l\log{l})\f$-time algorithm where \f$n\f$ is the complexity of \f$\cal{M}\f$ and \f$l\f$ is the length of the path. \section SMTopology_HowToUse API Description @@ -120,6 +127,18 @@ the input surface. This is otherwise independent of the size of input surface, Each time a `Surface_mesh_topology::Path_on_surface` is provided for a homotopy test, it is first transformed to an equivalent path in the quadrangulation stored by the `Surface_mesh_topology::Curves_on_surface_topology`. This transformation is transparent to the user who has never access to the quadrangulation. +\subsection SMTopology_Query_Simplicity Testing Simplicity + +Given a `Surface_mesh_topology::Path_on_surface` \f$p\f$, the class `Surface_mesh_topology::Curves_on_surface_topology` provides the following function: + +- \ref Surface_mesh_topology::Curves_on_surface_topology::is_homotopic_to_simple_cycle "is_homotopic_to_simple_cycle"(\f$p\f$) returns `true` if the closed curve \f$p\f$ is homotopic to some simple cycle. + +Like homotopy tests, the first step is to simplify the input combinatorial surface. The algorithm will share the surface with homotopy tests and invoke the simplification if the preprocessing has not been done yet. +\note The user must not modify the input surface as long as simplicity tests are performed with this `Surface_mesh_topology::Curves_on_surface_topology`. + +Each time a `Surface_mesh_topology::Path_on_surface` is provided for a simplicity test, it is first transformed to an equivalent path in the quadrangulation stored by the `Surface_mesh_topology::Curves_on_surface_topology`. This transformation is transparent to the user who has never access to the quadrangulation. + + \section SMTopology_Examples Examples \subsection SMTopology_Example_I_II_III Compute Shortest Non-contractible Cycle @@ -146,6 +165,10 @@ The following example computes the face width, and visualizes it if CGAL_Qt5 is The following example shows how to load an off file and how to create three closed paths on this surface. Contractibility and free homotopy tests are then performed. The example also shows how to use the \cgal viewer if CGAL_Qt5 is enabled. \cgalExample{Surface_mesh_topology/path_homotopy_double_torus.cpp} +\subsection SMTopology_Example_VI Basic Simplicity Test +The following example shows how to test the simplicity of a closed path on a double torus. The original path is visualized if CGAL_Qt5 is enabled. +\cgalExample{Surface_mesh_topology/path_simplicity_double_torus_2.cpp} + \subsection SMTopology_Example_VI_VII Polygonal Schema Here, we show with two examples how to create a surface from a list of faces specified by edge label sequences. In this first example, we build a genus two torus surface from a single face, also called a polygonal schema. See left \cgalFigureRef{fig_sm_incremental-builder} for an illustration. Two closed paths are then created. The paths are freely homotopic but not homotopic with fixed endpoint. @@ -262,9 +285,18 @@ The canonical form of a curve is obtained by flattening its brackets, removing i \subsection SMTopology_Homotopy_Test Homotopy Test It can be proven that the canonical form is uniquely defined and only depends on the homotopy class of the curve. Hence, the curves \f$C'\f$ and \f$D'\f$ in \f$\cal{Q}\f$ are homotopic if and only if their canonical forms are equal. Since each curve is defined as a sequence of (oriented) edges up to a cyclic permutation, we resort to the Knuth-Morris-Pratt algorithm to decide in linear time if the canonical forms are the same up to a cyclic permutation. +\subsection SMTopology_Simplicity_Test Simplicity Test +It can be shown that a closed curve is simple up to homotopy if and only if there is no intersection between any two geodesic liftings of the curve to the universal covering space embedded in a Poincaré Disk. Moreover, the Poincaré Disk can be tessellated by regular fundamental polygons. + +The quadrangulation represents the local connectivity information of the tesselation. Let \f$C\f$ be a closed curve and \f$\cal{C}\f$ be its canonical form. It can be proven that instead of considering the geodesic in a Poincaré Disk, \f$C\f$ is simple up to homotopy if and only if it is possible to arrange an ordering for edges in \f$\cal{C}\f$ with the same projection such that there is no self-intersection in the projection of \f$\cal{C}\f$ while allowing certain homotopy-preserving operation known as switch. + +Given \f$\cal{C}\f$, the algorithm preprocesses the path in linear time to identify all possible switches. The algorithm then processes edges in \f$\cal{C}\f$ one by one, tries to switch if an intersection can be avoided and then tries to insert the edge in the existing ordering without creating any intersection. Finally the ordering is checked to make sure it is indeed intersection free. + +To speed up determining relative order to the first edge, the algorithm uses a modified version of Knuth-Morris-Pratt algorithm to pre-compute the relative ordering in linear time. The orderings are maintained in red-black trees, contributing to the \f$\log{l}\f$ factor in the running time. + \section Implementation History -The code was developed in 2018 by Guillaume Damiand and Francis Lazarus. Felix Castillon contributed to the extension of the homotopy test to the case of surfaces with boundaries. Thien Hoang added methods to compute shortest non-contractible cycles, edge width and face width as part of the program Google Summer of Code 2019. +The code was developed in 2018 by Guillaume Damiand and Francis Lazarus. Felix Castillon contributed to the extension of the homotopy test to the case of surfaces with boundaries. Thien Hoang added methods to compute shortest non-contractible cycles, edge width and face width as part of the program Google Summer of Code 2019. Shuhao Tan added methods to test simplicity of a closed curve as part of the program Google Summer of Code 2020. */ } /* namespace CGAL */ diff --git a/Surface_mesh_topology/doc/Surface_mesh_topology/examples.txt b/Surface_mesh_topology/doc/Surface_mesh_topology/examples.txt index 0d740fdbd48..1c5bdf3ff9e 100644 --- a/Surface_mesh_topology/doc/Surface_mesh_topology/examples.txt +++ b/Surface_mesh_topology/doc/Surface_mesh_topology/examples.txt @@ -5,5 +5,7 @@ \example Surface_mesh_topology/path_homotopy_double_torus.cpp \example Surface_mesh_topology/path_homotopy_with_symbols.cpp \example Surface_mesh_topology/path_homotopy_with_symbols_2.cpp +\example Surface_mesh_topology/path_simplicity_double_torus.cpp +\example Surface_mesh_topology/path_simplicity_double_torus_2.cpp \example Surface_mesh_topology/open_path_homotopy.cpp */ From 7a06ca83ca8fb59630cfaaeecac3f8f41e93e588 Mon Sep 17 00:00:00 2001 From: Youmu Date: Wed, 22 Jul 2020 22:02:16 -0400 Subject: [PATCH 041/248] WIP: more user friendly documentation on implementation details --- .../Surface_mesh_topology.txt | 32 ++- .../fig/relative_order_corner.svg | 184 ++++++++++++++++++ .../fig/relative_order_normal.svg | 171 ++++++++++++++++ 3 files changed, 381 insertions(+), 6 deletions(-) create mode 100644 Surface_mesh_topology/doc/Surface_mesh_topology/fig/relative_order_corner.svg create mode 100644 Surface_mesh_topology/doc/Surface_mesh_topology/fig/relative_order_normal.svg diff --git a/Surface_mesh_topology/doc/Surface_mesh_topology/Surface_mesh_topology.txt b/Surface_mesh_topology/doc/Surface_mesh_topology/Surface_mesh_topology.txt index e44fc13d9c8..a39d61571ec 100644 --- a/Surface_mesh_topology/doc/Surface_mesh_topology/Surface_mesh_topology.txt +++ b/Surface_mesh_topology/doc/Surface_mesh_topology/Surface_mesh_topology.txt @@ -48,10 +48,10 @@ The algorithms used are based on a paper by Erickson and Whittlesey \cgalCite{ew \subsection SMTopology_simplicity Simplicity Test -Given a cycle drawn on a surface one can ask if the cycle can be continously deformed to a cycle that does not intersect with itself. Cycles that deform to a non-self-intersecting cycle are said simple. Any contractible cycle is simple but this is not true for cycles on more complicated topology. The algorithm in this section is purely topological and do not assume any geometry on the input surface. +Given a cycle drawn on a surface one can ask if the cycle can be continously deformed to a cycle that does not intersect with itself. Any contractible cycle deforms to a simple cycle but this is not true for more complicated cycles. The algorithm in this section is purely topological and do not assume any geometry on the input surface. The algorithm implemented in this package builds a data structure to efficiently answer queries of the following forms: -- Given a combinatorial surface \f$\cal{M}\f$ and a closed combinatorial curve specified as a sequence of edges of \f$\cal{M}\f$, decide if the curve is simple on \f$\cal{M}\f$. +- Given a combinatorial surface \f$\cal{M}\f$ and a closed combinatorial curve specified as a sequence of edges of \f$\cal{M}\f$, decide if the curve is homotopic to a simple one on \f$\cal{M}\f$. The algorithm used is based on a paper by Despré and Lazarus \cgalCite{cgal:dl-cginc-19}, providing a \f$O(n + l\log{l})\f$-time algorithm where \f$n\f$ is the complexity of \f$\cal{M}\f$ and \f$l\f$ is the length of the path. @@ -286,13 +286,33 @@ The canonical form of a curve is obtained by flattening its brackets, removing i It can be proven that the canonical form is uniquely defined and only depends on the homotopy class of the curve. Hence, the curves \f$C'\f$ and \f$D'\f$ in \f$\cal{Q}\f$ are homotopic if and only if their canonical forms are equal. Since each curve is defined as a sequence of (oriented) edges up to a cyclic permutation, we resort to the Knuth-Morris-Pratt algorithm to decide in linear time if the canonical forms are the same up to a cyclic permutation. \subsection SMTopology_Simplicity_Test Simplicity Test -It can be shown that a closed curve is simple up to homotopy if and only if there is no intersection between any two geodesic liftings of the curve to the universal covering space embedded in a Poincaré Disk. Moreover, the Poincaré Disk can be tessellated by regular fundamental polygons. +It can be shown that a closed curve is homotopic to a simple one if and only if its canonical form can be made intersection free via infinitesimal perturbations and some homotopy preserving operations. One can imagine each edge in the quadrangulation has width and each vertex in the quadrangulation has area so that paths visiting the same vertex/edge multiple times can avoid intersection within a vertex or an edge. See \cgalFigureRef{fig_perturbation_sample} for an example. +\cgalFigureBegin{fig_perturbation_sample,perturbation_sample.svg} + Applying perturbation to reduce 2 intersections between red subpath and blue subpath. + \cgalFigureEnd -The quadrangulation represents the local connectivity information of the tesselation. Let \f$C\f$ be a closed curve and \f$\cal{C}\f$ be its canonical form. It can be proven that instead of considering the geodesic in a Poincaré Disk, \f$C\f$ is simple up to homotopy if and only if it is possible to arrange an ordering for edges in \f$\cal{C}\f$ with the same projection such that there is no self-intersection in the projection of \f$\cal{C}\f$ while allowing certain homotopy-preserving operation known as switch. +Such perturbation can be expressed as orderings of edges from the canonical form which cross the same edge in the quadrangulation. The idea of the algorithm is to inductively build such ordering and try to avoid intersection as best as we can. -Given \f$\cal{C}\f$, the algorithm preprocesses the path in linear time to identify all possible switches. The algorithm then processes edges in \f$\cal{C}\f$ one by one, tries to switch if an intersection can be avoided and then tries to insert the edge in the existing ordering without creating any intersection. Finally the ordering is checked to make sure it is indeed intersection free. +\subsubsection SMTopology_Simplicity_Test_Primitive Detect Repetition +It can be proven that if the canonical form can be expressed as concatenation of two or more copies of the same path, the path can never be made to be intersection free. So the first step of the algorithm is to detect repetition. -To speed up determining relative order to the first edge, the algorithm uses a modified version of Knuth-Morris-Pratt algorithm to pre-compute the relative ordering in linear time. The orderings are maintained in red-black trees, contributing to the \f$\log{l}\f$ factor in the running time. +Let \f$P\f$ be a path and let \f$+\f$ be the operator of concatenation. It can be shown that \f$P\f$ contains no repetition if and only if there are only 2 matchings of \f$P\f$ in \f$P+P\f$ (matching the first and the second copy). The algorithm resorts to the Knuth-Morris-Pratt algorithm to decide in linear time if the canonical form contains no repetition. + +\subsubsection SMTopology_Simplicity_Test_Switch Avoid Crossing by Switching +Apart from applying perturbation, the algorithm also tries to avoid crossing using a homotopy-preserving operation known as switch. A switch is triggered when intersection could be avoided by turning a left L-shaped subpath into a right L-shaped subpath. See \cgalFigureRef{fig_switch_sample} for an example. + +\subsubsection SMTopology_Simplicity_Test_Relative_Order Decide Relative Order +Since the algorithm inductively builds an ordering, it has to determine relative order between the edge being processed and edges that has been ordered. There are three cases to consider. + +-# The predecessor of the current edge is adjacent to another edge which forms the same turn of the predecessor and the current edge. In this case, the current edge must be adjacent to the edge forming the turn. See \cgalFigureRef{fig_relative_order_corner}. +\cgalFigureBegin{fig_relative_order_corner,relative_order_corner.svg} + The red edge is being processed. The blue edge is adjacent to green edge (the predecessor of the red edge) in the previously constructed ordering and forms a turn (blue-pink turn) same to the green-red turn. The red edge must be right next to the pink edge in the ordering. + \cgalFigureEnd + +-# Comparing the current edge with another edge by the predecessor of the current edge. If the edge being compared against has predecessor/successor extended to the direction of the predecessor of the current edge, and they doesn't form the same turn. The relative order of edges around the vertex can be used as the relative order between the edges. See \cgalFigureRef{fig_relative_order_normal}. +\cgalFigureBegin{fig_relative_order_normal,relative_order_normal.svg} + The red edge is being processed and is compared against the pink edge. Since the green edge (the predecessor of the red edge) is to the right of the blue edge around the vertex, red edge must be to the right of the pink edge in the ordering. + \cgalFigureEnd \section Implementation History diff --git a/Surface_mesh_topology/doc/Surface_mesh_topology/fig/relative_order_corner.svg b/Surface_mesh_topology/doc/Surface_mesh_topology/fig/relative_order_corner.svg new file mode 100644 index 00000000000..a5751b57668 --- /dev/null +++ b/Surface_mesh_topology/doc/Surface_mesh_topology/fig/relative_order_corner.svg @@ -0,0 +1,184 @@ + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + diff --git a/Surface_mesh_topology/doc/Surface_mesh_topology/fig/relative_order_normal.svg b/Surface_mesh_topology/doc/Surface_mesh_topology/fig/relative_order_normal.svg new file mode 100644 index 00000000000..96d3c467480 --- /dev/null +++ b/Surface_mesh_topology/doc/Surface_mesh_topology/fig/relative_order_normal.svg @@ -0,0 +1,171 @@ + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + From 48d7c611de460bbe4114d05206fc863f1841a0bb Mon Sep 17 00:00:00 2001 From: Youmu Date: Wed, 22 Jul 2020 22:04:40 -0400 Subject: [PATCH 042/248] Add figure for small perturbation --- .../fig/perturbation_sample.svg | 222 ++++++++++++++++++ 1 file changed, 222 insertions(+) create mode 100644 Surface_mesh_topology/doc/Surface_mesh_topology/fig/perturbation_sample.svg diff --git a/Surface_mesh_topology/doc/Surface_mesh_topology/fig/perturbation_sample.svg b/Surface_mesh_topology/doc/Surface_mesh_topology/fig/perturbation_sample.svg new file mode 100644 index 00000000000..fa5b1dd3500 --- /dev/null +++ b/Surface_mesh_topology/doc/Surface_mesh_topology/fig/perturbation_sample.svg @@ -0,0 +1,222 @@ + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + u + v + e + e + v + u + + + + + + + + + + From 4970883849e90ffa133916b827b762ed663eea71 Mon Sep 17 00:00:00 2001 From: Youmu Date: Thu, 23 Jul 2020 18:17:52 -0400 Subject: [PATCH 043/248] Finished revision of documentation on simplicity test --- .../Surface_mesh_topology.txt | 12 +- .../fig/relative_order_first.svg | 229 ++++++++++++++++++ 2 files changed, 240 insertions(+), 1 deletion(-) create mode 100644 Surface_mesh_topology/doc/Surface_mesh_topology/fig/relative_order_first.svg diff --git a/Surface_mesh_topology/doc/Surface_mesh_topology/Surface_mesh_topology.txt b/Surface_mesh_topology/doc/Surface_mesh_topology/Surface_mesh_topology.txt index a39d61571ec..8f4a15100bd 100644 --- a/Surface_mesh_topology/doc/Surface_mesh_topology/Surface_mesh_topology.txt +++ b/Surface_mesh_topology/doc/Surface_mesh_topology/Surface_mesh_topology.txt @@ -309,11 +309,21 @@ Since the algorithm inductively builds an ordering, it has to determine relative The red edge is being processed. The blue edge is adjacent to green edge (the predecessor of the red edge) in the previously constructed ordering and forms a turn (blue-pink turn) same to the green-red turn. The red edge must be right next to the pink edge in the ordering. \cgalFigureEnd --# Comparing the current edge with another edge by the predecessor of the current edge. If the edge being compared against has predecessor/successor extended to the direction of the predecessor of the current edge, and they doesn't form the same turn. The relative order of edges around the vertex can be used as the relative order between the edges. See \cgalFigureRef{fig_relative_order_normal}. +-# Comparing the current edge with another edge by the predecessor of the current edge. If the edge being compared against has predecessor/successor extended to the direction of the predecessor of the current edge, and they doesn't form the same turn. The relative order of edges around the vertex can be used as the relative order between the edges. See \cgalFigureRef{fig_relative_order_normal}. \cgalFigureBegin{fig_relative_order_normal,relative_order_normal.svg} The red edge is being processed and is compared against the pink edge. Since the green edge (the predecessor of the red edge) is to the right of the blue edge around the vertex, red edge must be to the right of the pink edge in the ordering. \cgalFigureEnd +-# If the current edge crosses the same edge in the quadrangulation as the first edge of the path, the predecessor of the first edge (aka the last edge of the path) has not been processed yet. Hence if they form the same turn, we cannot determine the relative order of the predecessors. So the idea is to keep following the predecessors of current edge and the first edge until they diverge, at which point the relative order around the vertex can be used to determine the relative order. See \cgalFigureRef{fig_relative_order_first}. This can be precomputed by finding the all the longest common suffices of the path against its circular shifts. A modified Knuth-Morris-Pratt algorithm is applied to preprocess the path in linear time. +\cgalFigureBegin{fig_relative_order_first,relative_order_first.svg} + The red edge is being processed and is compared against the pink edge which is the first edge of the path. The blue and green edges are the first diverging pair when tracing backward. The dashed line means that edges may not be processed yet. Since the green edge is to the right of the blue edge around the vertex, red edge must be to the right of the pink edge in the ordering. + \cgalFigureEnd + +The ordering is stored in a red-black tree on each edge of the quadrangulation. So each insertion and search takes \f$O(\log{l})\f$ time. + +\subsubsection SMTopology_Simplicity_Test_Verification Verify Ordering +After computing a tentative ordering within the edges of the path, we have to verify such ordering could result in a intersection free arrangement. Since there is no intersection within an edge, we only need to verify this for each vertex in the quadrangulation. We can consider the two consecutive edges composing a turn (one going in the vertex, one going out of the vertex) at the vertex being verified a pair. The ordering at the vertex is intersection free if and only if there is no two pairs crossing each other according to the clockwise ordering around the vertex. In other words, for any two pairs \f$(a, a')\f$ and \f$(b, b')\f$, subsequence \f$a, b, a', b'\f$ should not appear in the clockwise ordering. This is very similar to verifying balanced parentheses in a string. We traverse clockwise at each vertex and use a stack-based algorithm to verify in linear time that the ordering produces a cycle without self-intersection. + \section Implementation History The code was developed in 2018 by Guillaume Damiand and Francis Lazarus. Felix Castillon contributed to the extension of the homotopy test to the case of surfaces with boundaries. Thien Hoang added methods to compute shortest non-contractible cycles, edge width and face width as part of the program Google Summer of Code 2019. Shuhao Tan added methods to test simplicity of a closed curve as part of the program Google Summer of Code 2020. diff --git a/Surface_mesh_topology/doc/Surface_mesh_topology/fig/relative_order_first.svg b/Surface_mesh_topology/doc/Surface_mesh_topology/fig/relative_order_first.svg new file mode 100644 index 00000000000..c1b1aa15d57 --- /dev/null +++ b/Surface_mesh_topology/doc/Surface_mesh_topology/fig/relative_order_first.svg @@ -0,0 +1,229 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + From 8eb69e8883c77ea48b1834aa1b297f8b589a54b7 Mon Sep 17 00:00:00 2001 From: Youmu Date: Thu, 23 Jul 2020 20:28:34 -0400 Subject: [PATCH 044/248] Separate ordering computing and verification into separate functions --- .../internal/Minimal_quadrangulation.h | 393 ++++++++++-------- 1 file changed, 216 insertions(+), 177 deletions(-) diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h index bf6fa1ce2a9..99101c61e3d 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h @@ -571,190 +571,18 @@ public: auto factorization=p_canonized.factorize(); // If the path length is 1, it must be simple res = factorization.second <= 1 && factorization.first.length() <= 1; - if (factorization.second <= 1 && !res) { + if (factorization.second <= 1 && !res) + { // If the curve is not primitive, there must be at least // one self intersection auto& p_original = factorization.first; p_original.simplify_flips(); - std::vector pr; - pr.reserve(p_original.length()); - for(std::size_t i = 0; i < p_original.length(); ++i) - { - pr.emplace_back(p_original[i]); - } + + auto perturbation = compute_perturbation(p_original); - // Compute the backward cyclic KMP failure table for the curve - std::vector suffix_len = compute_common_circular_suffix(p_original); - std::vector switchable = compute_switchable(p_original); - - typedef typename boost::intrusive::rbtree> rbtree; - std::vector rb_nodes; - rb_nodes.reserve(pr.size()); - std::unordered_map trees; - - for (std::size_t i = 0; i < pr.size(); ++i) - { - Dart_const_handle dh = pr[i]; - auto dart_id = get_absolute_idx(dh); - rb_nodes.emplace_back(i); - auto& node = rb_nodes.back(); - - // Check whether current darts needs to be switched - if (i > 0 && switchable[i]) - { - // Look at the t-1 turn of [i-1, i, i + 1] - Dart_const_handle dleft = get_local_map().template beta<0, 2>(dh); - size_type dleft_id = get_absolute_idx(dleft); - if(trees[dleft_id].size() > 0) - { - std::size_t max_turn_idx = is_absolutely_directed(dleft) ? trees[dleft_id].begin()->m_idx : trees[dleft_id].rbegin()->m_idx; - Dart_const_handle dprev = get_previous_relative_to(pr, max_turn_idx, dleft); - // If there exists a crossing that can be avoided, switch - if(get_order_relative_to(pr[i - 1], dleft) > get_order_relative_to(dprev, dleft)) - { - switch_dart(pr, i, switchable); - dh = pr[i]; - dart_id = get_absolute_idx(pr[i]); - } - } - } - // Insert current darts - if (trees[dart_id].empty()) - { - trees[dart_id].push_back(node); - } - else - { - // First check whether there is another corner in the previous part of the path - // where it matches p[i - 1] -> p[i] - // If so, p[i] must be inserted adjacent to one such corner - size_type prev_dart_id = get_absolute_idx(pr[i - 1]); - auto it_prev = trees[prev_dart_id].iterator_to(rb_nodes[i - 1]); - if (it_prev != trees[prev_dart_id].begin() && is_same_corner(pr, std::prev(it_prev)->m_idx, i - 1)) - { - auto it_adjacent = trees[dart_id].iterator_to(rb_nodes[get_next_idx_relative_to(pr, std::prev(it_prev)->m_idx, pr[i - 1])]); - if(is_absolutely_directed(pr[i - 1]) == is_absolutely_directed(dh)) - { - trees[dart_id].insert_before(std::next(it_adjacent), node); - } - else - { - trees[dart_id].insert_before(it_adjacent, node); - } - } - else if (std::next(it_prev) != trees[prev_dart_id].end() && is_same_corner(pr, std::next(it_prev)->m_idx, i - 1)) - { - auto it_adjacent = trees[dart_id].iterator_to(rb_nodes[get_next_idx_relative_to(pr, std::next(it_prev)->m_idx, pr[i-1])]); - if(is_absolutely_directed(pr[i - 1]) == is_absolutely_directed(dh)) - { - trees[dart_id].insert_before(it_adjacent, node); - } - else - { - trees[dart_id].insert_before(std::next(it_adjacent), node); - } - } - else - { - /// There is no same corner in the previous of the path - /// Perform usual unzip insertion - auto less_than_in_tree = is_absolutely_directed(dh)? - std::function{std::greater()} : std::function{std::less()}; - auto comparator = [this, &pr, &p_original, &suffix_len, &less_than_in_tree] (const std::size_t& key, const rbtree::value_type& b) -> bool { - if (b.m_idx == 0 && pr[key] == pr[0]) - { - if(pr[key] != p_original[key]) { - // current edge was switched so it should always be on the right side (more clockwise) - return less_than_in_tree(0, 1); - } - /// Comparing to pr[0], needs to check longest suffix - std::size_t current_dividing_idx = key + p_original.length() - 1 - suffix_len[key - 1]; - std::size_t path_end_dividing_idx = p_original.length() - 1 - suffix_len[key - 1]; - std::size_t last_same_idx = (path_end_dividing_idx == p_original.length() - 1) ? 0 : path_end_dividing_idx + 1; - if (current_dividing_idx >= p_original.length()) - { - current_dividing_idx -= p_original.length(); - } - Dart_const_handle dbase = p_original[last_same_idx], - dcur = p_original[current_dividing_idx], - d0 = p_original[path_end_dividing_idx]; - - std::size_t key_prev_order = this->get_order_relative_to(dcur, dbase); - std::size_t b_prev_order = this->get_order_relative_to(d0, dbase); - return less_than_in_tree(key_prev_order, b_prev_order); - } - else - { - std::size_t key_prev_order = this->get_order_relative_to(pr[key - 1], pr[key]); - Dart_const_handle bprev = this->get_previous_relative_to(pr, b.m_idx, pr[key]); - std::size_t b_prev_order = this->get_order_relative_to(bprev, pr[key]); - return less_than_in_tree(key_prev_order, b_prev_order); - } - }; - auto it_after = trees[dart_id].upper_bound(i, comparator); - trees[dart_id].insert_before(it_after, node); - } - } - } // Check whether orders form a valid parenthesis expression - res = true; - auto marktemp=get_local_map().get_new_mark(); - for (auto it=get_local_map().darts().begin(); - res && it!=get_local_map().darts().end(); ++it) - { - if (!get_local_map().is_marked(it, marktemp)) - { - std::stack> parenthesis_pairing; - Dart_const_handle dh2=it; - do - { - get_local_map().mark(dh2, marktemp); - auto dart_id = get_absolute_idx(dh2); - auto handle_node = [&dh2, &pr, &parenthesis_pairing] (const rbtree::value_type& node) { - auto curr_dart = std::make_pair(node.m_idx, pr[node.m_idx] == dh2); - if (parenthesis_pairing.empty()) - { - parenthesis_pairing.push(curr_dart); - } - else - { - /// We can cancel a pair of dart iff - /// 1) They are adjacent in the path (wrap around for the last dart) - /// 2) The first one is going in and the second one is going out - auto prev_dart = parenthesis_pairing.top(); - auto next_dart = curr_dart; - if(!next_dart.second) - { - std::swap(next_dart, prev_dart); - } - if ((next_dart.first - prev_dart.first == 1 || (next_dart.first == 0 && prev_dart.first == pr.size() - 1)) && - (!prev_dart.second && next_dart.second)) - { - parenthesis_pairing.pop(); - } - else - { - parenthesis_pairing.push(curr_dart); - } - } - }; - if(is_absolutely_directed(dh2)) - { - std::for_each(trees[dart_id].begin(), trees[dart_id].end(), handle_node); - } - else - { - std::for_each(trees[dart_id].rbegin(), trees[dart_id].rend(), handle_node); - } - dh2 = get_local_map().template beta<2, 1>(dh2); - } - while(dh2!=it && res); - res = res && parenthesis_pairing.empty(); - } - } - get_local_map().free_mark(marktemp); + res = is_ordering_simple(perturbation.first, perturbation.second); } } @@ -1869,6 +1697,217 @@ protected: return res; } + /// Compute a tentative ordering to avoid intersection + /// @pre the input path should be primitive + /// @return A pair of final path and correspondent ordering + std::pair, std::unordered_map>> compute_perturbation(const Path_on_surface& p) const + { + std::vector pr; + pr.reserve(p.length()); + for(std::size_t i = 0; i < p.length(); ++i) + { + pr.emplace_back(p[i]); + } + + // Compute the backward cyclic KMP failure table for the curve + std::vector suffix_len = compute_common_circular_suffix(p); + std::vector switchable = compute_switchable(p); + + typedef typename boost::intrusive::rbtree> rbtree; + std::vector rb_nodes; + rb_nodes.reserve(pr.size()); + std::unordered_map trees; + + for (std::size_t i = 0; i < pr.size(); ++i) + { + Dart_const_handle dh = pr[i]; + auto dart_id = get_absolute_idx(dh); + rb_nodes.emplace_back(i); + auto& node = rb_nodes.back(); + + // Check whether current darts needs to be switched + if (i > 0 && switchable[i]) + { + // Look at the t-1 turn of [i-1, i, i + 1] + Dart_const_handle dleft = get_local_map().template beta<0, 2>(dh); + size_type dleft_id = get_absolute_idx(dleft); + if(trees[dleft_id].size() > 0) + { + std::size_t max_turn_idx = is_absolutely_directed(dleft) ? trees[dleft_id].begin()->m_idx : trees[dleft_id].rbegin()->m_idx; + Dart_const_handle dprev = get_previous_relative_to(pr, max_turn_idx, dleft); + // If there exists a crossing that can be avoided, switch + if(get_order_relative_to(pr[i - 1], dleft) > get_order_relative_to(dprev, dleft)) + { + switch_dart(pr, i, switchable); + dh = pr[i]; + dart_id = get_absolute_idx(pr[i]); + } + } + } + // Insert current darts + if (trees[dart_id].empty()) + { + trees[dart_id].push_back(node); + } + else + { + // First check whether there is another corner in the previous part of the path + // where it matches p[i - 1] -> p[i] + // If so, p[i] must be inserted adjacent to one such corner + size_type prev_dart_id = get_absolute_idx(pr[i - 1]); + auto it_prev = trees[prev_dart_id].iterator_to(rb_nodes[i - 1]); + if (it_prev != trees[prev_dart_id].begin() && is_same_corner(pr, std::prev(it_prev)->m_idx, i - 1)) + { + auto it_adjacent = trees[dart_id].iterator_to(rb_nodes[get_next_idx_relative_to(pr, std::prev(it_prev)->m_idx, pr[i - 1])]); + if(is_absolutely_directed(pr[i - 1]) == is_absolutely_directed(dh)) + { + trees[dart_id].insert_before(std::next(it_adjacent), node); + } + else + { + trees[dart_id].insert_before(it_adjacent, node); + } + } + else if (std::next(it_prev) != trees[prev_dart_id].end() && is_same_corner(pr, std::next(it_prev)->m_idx, i - 1)) + { + auto it_adjacent = trees[dart_id].iterator_to(rb_nodes[get_next_idx_relative_to(pr, std::next(it_prev)->m_idx, pr[i-1])]); + if(is_absolutely_directed(pr[i - 1]) == is_absolutely_directed(dh)) + { + trees[dart_id].insert_before(it_adjacent, node); + } + else + { + trees[dart_id].insert_before(std::next(it_adjacent), node); + } + } + else + { + /// There is no same corner in the previous of the path + /// Perform usual unzip insertion + auto less_than_in_tree = is_absolutely_directed(dh)? + std::function{std::greater()} : std::function{std::less()}; + auto comparator = [this, &pr, &p, &suffix_len, &less_than_in_tree] (const std::size_t& key, const rbtree::value_type& b) -> bool { + if (b.m_idx == 0 && pr[key] == pr[0]) + { + if(pr[key] != p[key]) { + // current edge was switched so it should always be on the right side (more clockwise) + return less_than_in_tree(0, 1); + } + /// Comparing to pr[0], needs to check longest suffix + std::size_t current_dividing_idx = key + p.length() - 1 - suffix_len[key - 1]; + std::size_t path_end_dividing_idx = p.length() - 1 - suffix_len[key - 1]; + std::size_t last_same_idx = (path_end_dividing_idx == p.length() - 1) ? 0 : path_end_dividing_idx + 1; + if (current_dividing_idx >= p.length()) + { + current_dividing_idx -= p.length(); + } + Dart_const_handle dbase = p[last_same_idx], + dcur = p[current_dividing_idx], + d0 = p[path_end_dividing_idx]; + + std::size_t key_prev_order = this->get_order_relative_to(dcur, dbase); + std::size_t b_prev_order = this->get_order_relative_to(d0, dbase); + return less_than_in_tree(key_prev_order, b_prev_order); + } + else + { + std::size_t key_prev_order = this->get_order_relative_to(pr[key - 1], pr[key]); + Dart_const_handle bprev = this->get_previous_relative_to(pr, b.m_idx, pr[key]); + std::size_t b_prev_order = this->get_order_relative_to(bprev, pr[key]); + return less_than_in_tree(key_prev_order, b_prev_order); + } + }; + auto it_after = trees[dart_id].upper_bound(i, comparator); + trees[dart_id].insert_before(it_after, node); + } + } + } + + Path_on_surface p_perturbed(get_local_map()); + for(const auto& dp: pr) + { + p_perturbed.push_back(dp); + } + std::unordered_map> ordering; + for(const auto& edge_ordering: trees) + { + std::transform(edge_ordering.second.begin(), edge_ordering.second.end(), + std::back_inserter(ordering[edge_ordering.first]), + [] (const rbtree::value_type& node) + { + return node.m_idx; + }); + } + return std::make_pair(p_perturbed, ordering); + } + + /// @return true iff the ordering of the edges in the input path is intersection free + bool is_ordering_simple(const Path_on_surface& p, const std::unordered_map>& ordering) const + { + bool res = true; + auto marktemp=get_local_map().get_new_mark(); + for (auto it=get_local_map().darts().begin(); + res && it!=get_local_map().darts().end(); ++it) + { + if (!get_local_map().is_marked(it, marktemp)) + { + std::stack> parenthesis_pairing; + Dart_const_handle dh2=it; + do + { + get_local_map().mark(dh2, marktemp); + auto dart_id = get_absolute_idx(dh2); + auto handle_node = [&dh2, &p, &parenthesis_pairing] (const std::size_t& idx) { + auto curr_dart = std::make_pair(idx, p[idx] == dh2); + if (parenthesis_pairing.empty()) + { + parenthesis_pairing.push(curr_dart); + } + else + { + /// We can cancel a pair of dart iff + /// 1) They are adjacent in the path (wrap around for the last dart) + /// 2) The first one is going in and the second one is going out + auto prev_dart = parenthesis_pairing.top(); + auto next_dart = curr_dart; + if(!next_dart.second) + { + std::swap(next_dart, prev_dart); + } + if ((next_dart.first - prev_dart.first == 1 || (next_dart.first == 0 && prev_dart.first == p.length() - 1)) && + (!prev_dart.second && next_dart.second)) + { + parenthesis_pairing.pop(); + } + else + { + parenthesis_pairing.push(curr_dart); + } + } + }; + auto it_dart_ordering = ordering.find(dart_id); + if (it_dart_ordering != ordering.cend()) + { + if (is_absolutely_directed(dh2)) + { + std::for_each(it_dart_ordering->second.cbegin(), it_dart_ordering->second.cend(), handle_node); + } + else + { + std::for_each(it_dart_ordering->second.crbegin(), it_dart_ordering->second.crend(), handle_node); + } + } + dh2 = get_local_map().template beta<2, 1>(dh2); + } + while(dh2!=it); + res = res && parenthesis_pairing.empty(); + } + } + get_local_map().free_mark(marktemp); + return res; + } + /// Compute the longest common suffix of a path against all of it circular shifts /// Based on a modification of Knuth-Morris-Pratt algorithm std::vector compute_common_circular_suffix(const Path_on_surface& p) const From 756d4b926182e4f44e3f16f70163640982ed9768 Mon Sep 17 00:00:00 2001 From: Youmu Date: Tue, 28 Jul 2020 14:44:13 -0400 Subject: [PATCH 045/248] Update documentation for switch operation --- .../Surface_mesh_topology.txt | 3 + .../fig/switch_sample.svg | 819 ++++++++++++++++++ 2 files changed, 822 insertions(+) create mode 100644 Surface_mesh_topology/doc/Surface_mesh_topology/fig/switch_sample.svg diff --git a/Surface_mesh_topology/doc/Surface_mesh_topology/Surface_mesh_topology.txt b/Surface_mesh_topology/doc/Surface_mesh_topology/Surface_mesh_topology.txt index 8f4a15100bd..559bf4a4006 100644 --- a/Surface_mesh_topology/doc/Surface_mesh_topology/Surface_mesh_topology.txt +++ b/Surface_mesh_topology/doc/Surface_mesh_topology/Surface_mesh_topology.txt @@ -300,6 +300,9 @@ Let \f$P\f$ be a path and let \f$+\f$ be the operator of concatenation. It can b \subsubsection SMTopology_Simplicity_Test_Switch Avoid Crossing by Switching Apart from applying perturbation, the algorithm also tries to avoid crossing using a homotopy-preserving operation known as switch. A switch is triggered when intersection could be avoided by turning a left L-shaped subpath into a right L-shaped subpath. See \cgalFigureRef{fig_switch_sample} for an example. +\cgalFigureBegin{fig_switch_sample,switch_sample.svg} + Top-left, an intersection between red subpath and green subpath at the start of a left L-shaped red subpath. Top-right, switch the left L-shape to right L-shape to avoid the intersection. Bottom, no switch because no intersection can be avoided. + \cgalFigureEnd \subsubsection SMTopology_Simplicity_Test_Relative_Order Decide Relative Order Since the algorithm inductively builds an ordering, it has to determine relative order between the edge being processed and edges that has been ordered. There are three cases to consider. diff --git a/Surface_mesh_topology/doc/Surface_mesh_topology/fig/switch_sample.svg b/Surface_mesh_topology/doc/Surface_mesh_topology/fig/switch_sample.svg new file mode 100644 index 00000000000..0cccf3f118f --- /dev/null +++ b/Surface_mesh_topology/doc/Surface_mesh_topology/fig/switch_sample.svg @@ -0,0 +1,819 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From e3aee2fa3bfa3886d6f6882e679a6cf02d885262 Mon Sep 17 00:00:00 2001 From: Youmu Date: Fri, 31 Jul 2020 15:59:34 -0400 Subject: [PATCH 046/248] Add description of changes --- Installation/CHANGES.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Installation/CHANGES.md b/Installation/CHANGES.md index dbc8910ac48..02838bb4bb7 100644 --- a/Installation/CHANGES.md +++ b/Installation/CHANGES.md @@ -3,6 +3,9 @@ Release History [Release 5.1] (https://github.com/CGAL/cgal/releases/tag/releases%2FCGAL-5.1) +### Surface Mesh Topology +- Added the function `CGAL::Curves_on_surface::is_homotopic_to_simple_cycle()`, which can be used to determine whehter a closed path on a surface mesh can be continously transformed to a cycle without self intersection. + ### 3D Fast Intersection and Distance Computation - The introduction of the usage of the search tree by default for all distance queries in the 5.0 release was actually not lazy contrary to what was announced. The behavior of the From e7b84948d5fc44df0e662a11bed59e0025950058 Mon Sep 17 00:00:00 2001 From: Youmu Date: Mon, 3 Aug 2020 18:33:48 -0400 Subject: [PATCH 047/248] Fix package name --- Installation/CHANGES.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Installation/CHANGES.md b/Installation/CHANGES.md index 02838bb4bb7..0403caa7b99 100644 --- a/Installation/CHANGES.md +++ b/Installation/CHANGES.md @@ -4,7 +4,8 @@ Release History [Release 5.1] (https://github.com/CGAL/cgal/releases/tag/releases%2FCGAL-5.1) ### Surface Mesh Topology -- Added the function `CGAL::Curves_on_surface::is_homotopic_to_simple_cycle()`, which can be used to determine whehter a closed path on a surface mesh can be continously transformed to a cycle without self intersection. +- Added the function `CGAL::Surface_mesh_topology::Curves_on_surface_topology::is_homotopic_to_simple_cycle()`, which can be used to determine whehter a closed path + on a surface mesh can be continously transformed to a cycle without self intersection. ### 3D Fast Intersection and Distance Computation - The introduction of the usage of the search tree by default for all distance queries From d9a12e37b43cd4400d9e7f6b094853be60ddba60 Mon Sep 17 00:00:00 2001 From: Youmu Date: Thu, 6 Aug 2020 00:11:20 -0400 Subject: [PATCH 048/248] Remove trailing whitespace --- .../Surface_mesh_topology/internal/Minimal_quadrangulation.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h index 99101c61e3d..6847890dfdc 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h @@ -578,7 +578,7 @@ public: auto& p_original = factorization.first; p_original.simplify_flips(); - + auto perturbation = compute_perturbation(p_original); // Check whether orders form a valid parenthesis expression From 4ed7e9339b8c5f25088bb6551690761685184894 Mon Sep 17 00:00:00 2001 From: Youmu Date: Thu, 6 Aug 2020 18:24:09 -0400 Subject: [PATCH 049/248] Change name of simplicity_homology_group to more appropriate simplicity_fundamental_polygon --- Surface_mesh_topology/test/Surface_mesh_topology/CMakeLists.txt | 2 +- ...ty_homology_group.cpp => simplicity_fundamental_polygon.cpp} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename Surface_mesh_topology/test/Surface_mesh_topology/{simplicity_homology_group.cpp => simplicity_fundamental_polygon.cpp} (100%) diff --git a/Surface_mesh_topology/test/Surface_mesh_topology/CMakeLists.txt b/Surface_mesh_topology/test/Surface_mesh_topology/CMakeLists.txt index 4c20a8c48c7..cb933492261 100644 --- a/Surface_mesh_topology/test/Surface_mesh_topology/CMakeLists.txt +++ b/Surface_mesh_topology/test/Surface_mesh_topology/CMakeLists.txt @@ -37,7 +37,7 @@ set(SOURCE_FILES simplicity_cylinder.cpp simplicity_double_torus.cpp simplicity_double_torus_with_holes.cpp - simplicity_homology_group.cpp + simplicity_fundamental_polygon.cpp simplicity_torus.cpp test_homotopy.cpp test_homotopy_with_polygonal_schema.cpp diff --git a/Surface_mesh_topology/test/Surface_mesh_topology/simplicity_homology_group.cpp b/Surface_mesh_topology/test/Surface_mesh_topology/simplicity_fundamental_polygon.cpp similarity index 100% rename from Surface_mesh_topology/test/Surface_mesh_topology/simplicity_homology_group.cpp rename to Surface_mesh_topology/test/Surface_mesh_topology/simplicity_fundamental_polygon.cpp From 142823f0d79c94dc942e582c27a72f71073d9c57 Mon Sep 17 00:00:00 2001 From: Youmu Date: Sun, 9 Aug 2020 13:45:36 -0400 Subject: [PATCH 050/248] use \link to have the backticks around the function name --- .../doc/Surface_mesh_topology/Surface_mesh_topology.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Surface_mesh_topology/doc/Surface_mesh_topology/Surface_mesh_topology.txt b/Surface_mesh_topology/doc/Surface_mesh_topology/Surface_mesh_topology.txt index 7efc0d71342..c232370ce48 100644 --- a/Surface_mesh_topology/doc/Surface_mesh_topology/Surface_mesh_topology.txt +++ b/Surface_mesh_topology/doc/Surface_mesh_topology/Surface_mesh_topology.txt @@ -131,7 +131,7 @@ Each time a `Surface_mesh_topology::Path_on_surface` is provided for a homotopy Given a `Surface_mesh_topology::Path_on_surface` \f$p\f$, the class `Surface_mesh_topology::Curves_on_surface_topology` provides the following function: -- \ref Surface_mesh_topology::Curves_on_surface_topology::is_homotopic_to_simple_cycle "is_homotopic_to_simple_cycle"(\f$p\f$) returns `true` if the closed curve \f$p\f$ is homotopic to some simple cycle. +- \link Surface_mesh_topology::Curves_on_surface_topology::is_homotopic_to_simple_cycle `is_homotopic_to_simple_cycle(p)` \endlink returns `true` if the closed curve \f$p\f$ is homotopic to some simple cycle. Like homotopy tests, the first step is to simplify the input combinatorial surface. The algorithm will share the surface with homotopy tests and invoke the simplification if the preprocessing has not been done yet. \note The user must not modify the input surface as long as simplicity tests are performed with this `Surface_mesh_topology::Curves_on_surface_topology`. From 8fd70861134c1a523ee24328ab52114b2b84e037 Mon Sep 17 00:00:00 2001 From: John Date: Sun, 9 Aug 2020 13:47:51 -0400 Subject: [PATCH 051/248] Adopting grammar error fixes Co-authored-by: Sebastien Loriot --- .../doc/Surface_mesh_topology/Surface_mesh_topology.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Surface_mesh_topology/doc/Surface_mesh_topology/Surface_mesh_topology.txt b/Surface_mesh_topology/doc/Surface_mesh_topology/Surface_mesh_topology.txt index c232370ce48..1134216fcde 100644 --- a/Surface_mesh_topology/doc/Surface_mesh_topology/Surface_mesh_topology.txt +++ b/Surface_mesh_topology/doc/Surface_mesh_topology/Surface_mesh_topology.txt @@ -288,7 +288,7 @@ It can be proven that the canonical form is uniquely defined and only depends on \subsection SMTopology_Simplicity_Test Simplicity Test It can be shown that a closed curve is homotopic to a simple one if and only if its canonical form can be made intersection free via infinitesimal perturbations and some homotopy preserving operations. One can imagine each edge in the quadrangulation has width and each vertex in the quadrangulation has area so that paths visiting the same vertex/edge multiple times can avoid intersection within a vertex or an edge. See \cgalFigureRef{fig_perturbation_sample} for an example. \cgalFigureBegin{fig_perturbation_sample,perturbation_sample.svg} - Applying perturbation to reduce 2 intersections between red subpath and blue subpath. + Applying a perturbation to reduce 2 intersections between red subpath and blue subpath. \cgalFigureEnd Such perturbation can be expressed as orderings of edges from the canonical form which cross the same edge in the quadrangulation. The idea of the algorithm is to inductively build such ordering and try to avoid intersection as best as we can. From b493eac3e2679e13490183eb09c04ed44fa9e159 Mon Sep 17 00:00:00 2001 From: John Date: Sun, 9 Aug 2020 13:51:02 -0400 Subject: [PATCH 052/248] Fix grammar errors from suggestions Co-authored-by: Sebastien Loriot --- .../Surface_mesh_topology.txt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Surface_mesh_topology/doc/Surface_mesh_topology/Surface_mesh_topology.txt b/Surface_mesh_topology/doc/Surface_mesh_topology/Surface_mesh_topology.txt index 1134216fcde..a7f45e2a0fb 100644 --- a/Surface_mesh_topology/doc/Surface_mesh_topology/Surface_mesh_topology.txt +++ b/Surface_mesh_topology/doc/Surface_mesh_topology/Surface_mesh_topology.txt @@ -286,15 +286,15 @@ The canonical form of a curve is obtained by flattening its brackets, removing i It can be proven that the canonical form is uniquely defined and only depends on the homotopy class of the curve. Hence, the curves \f$C'\f$ and \f$D'\f$ in \f$\cal{Q}\f$ are homotopic if and only if their canonical forms are equal. Since each curve is defined as a sequence of (oriented) edges up to a cyclic permutation, we resort to the Knuth-Morris-Pratt algorithm to decide in linear time if the canonical forms are the same up to a cyclic permutation. \subsection SMTopology_Simplicity_Test Simplicity Test -It can be shown that a closed curve is homotopic to a simple one if and only if its canonical form can be made intersection free via infinitesimal perturbations and some homotopy preserving operations. One can imagine each edge in the quadrangulation has width and each vertex in the quadrangulation has area so that paths visiting the same vertex/edge multiple times can avoid intersection within a vertex or an edge. See \cgalFigureRef{fig_perturbation_sample} for an example. +It can be shown that a closed curve is homotopic to a simple one if and only if its canonical form can be made intersection free via infinitesimal perturbations and some homotopy preserving operations. One can imagine each edge in the quadrangulation has a width and each vertex in the quadrangulation has an area so that paths visiting the same vertex/edge multiple times can avoid intersection within a vertex or an edge. See \cgalFigureRef{fig_perturbation_sample} for an example. \cgalFigureBegin{fig_perturbation_sample,perturbation_sample.svg} Applying a perturbation to reduce 2 intersections between red subpath and blue subpath. \cgalFigureEnd -Such perturbation can be expressed as orderings of edges from the canonical form which cross the same edge in the quadrangulation. The idea of the algorithm is to inductively build such ordering and try to avoid intersection as best as we can. +Such a perturbation can be expressed as orderings of edges from the canonical form which cross the same edge in the quadrangulation. The idea of the algorithm is to inductively build such ordering and try to avoid intersection as best as we can. \subsubsection SMTopology_Simplicity_Test_Primitive Detect Repetition -It can be proven that if the canonical form can be expressed as concatenation of two or more copies of the same path, the path can never be made to be intersection free. So the first step of the algorithm is to detect repetition. +It can be proven that if the canonical form can be expressed as concatenation of two or more copies of the same path, the path can never be made intersection free. So the first step of the algorithm is to detect repetition. Let \f$P\f$ be a path and let \f$+\f$ be the operator of concatenation. It can be shown that \f$P\f$ contains no repetition if and only if there are only 2 matchings of \f$P\f$ in \f$P+P\f$ (matching the first and the second copy). The algorithm resorts to the Knuth-Morris-Pratt algorithm to decide in linear time if the canonical form contains no repetition. @@ -305,7 +305,7 @@ Apart from applying perturbation, the algorithm also tries to avoid crossing usi \cgalFigureEnd \subsubsection SMTopology_Simplicity_Test_Relative_Order Decide Relative Order -Since the algorithm inductively builds an ordering, it has to determine relative order between the edge being processed and edges that has been ordered. There are three cases to consider. +Since the algorithm inductively builds an ordering, it has to determine a relative order between the edge being processed and the edges that has been ordered. There are three cases to consider. -# The predecessor of the current edge is adjacent to another edge which forms the same turn of the predecessor and the current edge. In this case, the current edge must be adjacent to the edge forming the turn. See \cgalFigureRef{fig_relative_order_corner}. \cgalFigureBegin{fig_relative_order_corner,relative_order_corner.svg} @@ -317,15 +317,15 @@ Since the algorithm inductively builds an ordering, it has to determine relative The red edge is being processed and is compared against the pink edge. Since the green edge (the predecessor of the red edge) is to the right of the blue edge around the vertex, red edge must be to the right of the pink edge in the ordering. \cgalFigureEnd --# If the current edge crosses the same edge in the quadrangulation as the first edge of the path, the predecessor of the first edge (aka the last edge of the path) has not been processed yet. Hence if they form the same turn, we cannot determine the relative order of the predecessors. So the idea is to keep following the predecessors of current edge and the first edge until they diverge, at which point the relative order around the vertex can be used to determine the relative order. See \cgalFigureRef{fig_relative_order_first}. This can be precomputed by finding the all the longest common suffices of the path against its circular shifts. A modified Knuth-Morris-Pratt algorithm is applied to preprocess the path in linear time. +-# If the current edge crosses the same edge in the quadrangulation as the first edge of the path, the predecessor of the first edge (aka the last edge of the path) has not been processed yet. Hence if they form the same turn, we cannot determine the relative order of the predecessors. So the idea is to keep following the predecessors of current edge and the first edge until they diverge, at which point the relative order around the vertex can be used to determine the relative order. See \cgalFigureRef{fig_relative_order_first}. This can be precomputed by finding all the longest common suffices of the path against its circular shifts. A modified Knuth-Morris-Pratt algorithm is applied to preprocess the path in linear time. \cgalFigureBegin{fig_relative_order_first,relative_order_first.svg} - The red edge is being processed and is compared against the pink edge which is the first edge of the path. The blue and green edges are the first diverging pair when tracing backward. The dashed line means that edges may not be processed yet. Since the green edge is to the right of the blue edge around the vertex, red edge must be to the right of the pink edge in the ordering. + The red edge is being processed and is compared against the pink edge which is the first edge of the path. The blue and green edges are the first diverging pair when tracing backward. The dashed line means that edges may not be processed yet. Since the green edge is to the right of the blue edge around the vertex, the red edge must be to the right of the pink edge in the ordering. \cgalFigureEnd The ordering is stored in a red-black tree on each edge of the quadrangulation. So each insertion and search takes \f$O(\log{l})\f$ time. \subsubsection SMTopology_Simplicity_Test_Verification Verify Ordering -After computing a tentative ordering within the edges of the path, we have to verify such ordering could result in a intersection free arrangement. Since there is no intersection within an edge, we only need to verify this for each vertex in the quadrangulation. We can consider the two consecutive edges composing a turn (one going in the vertex, one going out of the vertex) at the vertex being verified a pair. The ordering at the vertex is intersection free if and only if there is no two pairs crossing each other according to the clockwise ordering around the vertex. In other words, for any two pairs \f$(a, a')\f$ and \f$(b, b')\f$, subsequence \f$a, b, a', b'\f$ should not appear in the clockwise ordering. This is very similar to verifying balanced parentheses in a string. We traverse clockwise at each vertex and use a stack-based algorithm to verify in linear time that the ordering produces a cycle without self-intersection. +After computing a tentative ordering within the edges of the path, we have to verify that such an ordering could result in an intersection free arrangement. Since there is no intersection within an edge, we only need to verify this for each vertex in the quadrangulation. We can consider the two consecutive edges composing a turn (one going in the vertex, one going out of the vertex) at the vertex being verified a pair. The ordering at the vertex is intersection free if and only if there is no two pairs crossing each other according to the clockwise ordering around the vertex. In other words, for any two pairs \f$(a, a')\f$ and \f$(b, b')\f$, subsequence \f$a, b, a', b'\f$ should not appear in the clockwise ordering. This is very similar to verifying balanced parentheses in a string. We traverse clockwise at each vertex and use a stack-based algorithm to verify in linear time that the ordering produces a cycle without self-intersection. \section Implementation History From 7f57b5a4163417f490746c8e3f45763ccc729886 Mon Sep 17 00:00:00 2001 From: Youmu Date: Sun, 9 Aug 2020 15:03:26 -0400 Subject: [PATCH 053/248] Fix wording in the documentation --- .../doc/Surface_mesh_topology/Surface_mesh_topology.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Surface_mesh_topology/doc/Surface_mesh_topology/Surface_mesh_topology.txt b/Surface_mesh_topology/doc/Surface_mesh_topology/Surface_mesh_topology.txt index a7f45e2a0fb..2933f7e2492 100644 --- a/Surface_mesh_topology/doc/Surface_mesh_topology/Surface_mesh_topology.txt +++ b/Surface_mesh_topology/doc/Surface_mesh_topology/Surface_mesh_topology.txt @@ -309,7 +309,7 @@ Since the algorithm inductively builds an ordering, it has to determine a relati -# The predecessor of the current edge is adjacent to another edge which forms the same turn of the predecessor and the current edge. In this case, the current edge must be adjacent to the edge forming the turn. See \cgalFigureRef{fig_relative_order_corner}. \cgalFigureBegin{fig_relative_order_corner,relative_order_corner.svg} - The red edge is being processed. The blue edge is adjacent to green edge (the predecessor of the red edge) in the previously constructed ordering and forms a turn (blue-pink turn) same to the green-red turn. The red edge must be right next to the pink edge in the ordering. + The red edge is being processed. The blue edge is adjacent to green edge (the predecessor of the red edge) in the previously constructed ordering and forms a turn (blue-pink turn) same as the green-red turn. The red edge must be right next to the pink edge in the ordering. \cgalFigureEnd -# Comparing the current edge with another edge by the predecessor of the current edge. If the edge being compared against has predecessor/successor extended to the direction of the predecessor of the current edge, and they doesn't form the same turn. The relative order of edges around the vertex can be used as the relative order between the edges. See \cgalFigureRef{fig_relative_order_normal}. @@ -322,7 +322,7 @@ Since the algorithm inductively builds an ordering, it has to determine a relati The red edge is being processed and is compared against the pink edge which is the first edge of the path. The blue and green edges are the first diverging pair when tracing backward. The dashed line means that edges may not be processed yet. Since the green edge is to the right of the blue edge around the vertex, the red edge must be to the right of the pink edge in the ordering. \cgalFigureEnd -The ordering is stored in a red-black tree on each edge of the quadrangulation. So each insertion and search takes \f$O(\log{l})\f$ time. +The ordering is stored in a red-black tree for each edge of the quadrangulation. So each insertion and search takes \f$O(\log{l})\f$ time. \subsubsection SMTopology_Simplicity_Test_Verification Verify Ordering After computing a tentative ordering within the edges of the path, we have to verify that such an ordering could result in an intersection free arrangement. Since there is no intersection within an edge, we only need to verify this for each vertex in the quadrangulation. We can consider the two consecutive edges composing a turn (one going in the vertex, one going out of the vertex) at the vertex being verified a pair. The ordering at the vertex is intersection free if and only if there is no two pairs crossing each other according to the clockwise ordering around the vertex. In other words, for any two pairs \f$(a, a')\f$ and \f$(b, b')\f$, subsequence \f$a, b, a', b'\f$ should not appear in the clockwise ordering. This is very similar to verifying balanced parentheses in a string. We traverse clockwise at each vertex and use a stack-based algorithm to verify in linear time that the ordering produces a cycle without self-intersection. From 37d55a466f8911484dad7d5f705b74b9360121f5 Mon Sep 17 00:00:00 2001 From: Youmu Date: Sun, 9 Aug 2020 15:04:00 -0400 Subject: [PATCH 054/248] Match message with the condition --- Surface_mesh_topology/test/Surface_mesh_topology/path_tests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Surface_mesh_topology/test/Surface_mesh_topology/path_tests.cpp b/Surface_mesh_topology/test/Surface_mesh_topology/path_tests.cpp index a9beb93422d..28cbe41a528 100644 --- a/Surface_mesh_topology/test/Surface_mesh_topology/path_tests.cpp +++ b/Surface_mesh_topology/test/Surface_mesh_topology/path_tests.cpp @@ -95,7 +95,7 @@ bool basic_tests() internal::Path_on_surface_with_rle > p7(lmq, p6); if (!p7.is_valid() || p7.size_of_list()!=3) { - std::cerr<<"path_tests ERROR: !p7.is_valid() || size_of_list()!=2."< Date: Thu, 13 Aug 2020 17:59:32 -0400 Subject: [PATCH 055/248] Add a class level switch to control the error output to std::cerr --- .../CGAL/Curves_on_surface_topology.h | 5 +++ .../include/CGAL/Curves_on_surface_topology.h | 22 ++++++++++--- .../internal/Minimal_quadrangulation.h | 32 +++++++++++++------ 3 files changed, 44 insertions(+), 15 deletions(-) diff --git a/Surface_mesh_topology/doc/Surface_mesh_topology/CGAL/Curves_on_surface_topology.h b/Surface_mesh_topology/doc/Surface_mesh_topology/CGAL/Curves_on_surface_topology.h index bb68d51ae23..e5d6efc1b0d 100644 --- a/Surface_mesh_topology/doc/Surface_mesh_topology/CGAL/Curves_on_surface_topology.h +++ b/Surface_mesh_topology/doc/Surface_mesh_topology/CGAL/Curves_on_surface_topology.h @@ -61,6 +61,11 @@ namespace Surface_mesh_topology { /*! returns a vector of darts representing a non-contractible curve with a minimal number of intersection with the graph of the mesh. This curve can be described by the alternating sequence of faces and vertices it goes through, so that each dart in the returned vector belongs to both a face and the next vertex in the alternating sequence. (Here, faces and vertices are viewed as subsets of darts.) The size of the returned vector is the face width of the mesh. */ std::vector compute_face_width() const; + + /*! set whether the function should output error message to `std::cerr` when the prerequisite of the argument(s) is not met. + * Affects \link Surface_mesh_topology::Curves_on_surface_topology::are_freely_homotopic `are_freely_homotopic(p1, p2)`\endlink, \link Surface_mesh_topology::Curves_on_surface_topology::are_homotopic_with_fixed_endpoints `are_homotopic_with_fixed_endpoints(p1, p2)`\endlink, \link Surface_mesh_topology::Curves_on_surface_topology::is_contractible `is_contractible(p)`\endlink, and \link Surface_mesh_topology::Curves_on_surface_topology::is_homotopic_to_simple_cycle `is_homotopic_to_simple_cycle(p)`\endlink + */ + void set_verbose(bool is_verbose); }; /*! diff --git a/Surface_mesh_topology/include/CGAL/Curves_on_surface_topology.h b/Surface_mesh_topology/include/CGAL/Curves_on_surface_topology.h index 231a7147b4a..6c0a3cd9627 100644 --- a/Surface_mesh_topology/include/CGAL/Curves_on_surface_topology.h +++ b/Surface_mesh_topology/include/CGAL/Curves_on_surface_topology.h @@ -42,7 +42,8 @@ public: m_original_mesh(amesh), m_minimal_quadrangulation(nullptr), m_shortest_noncontractible_cycle(nullptr), - m_facewidth(nullptr) + m_facewidth(nullptr), + m_is_verbose(false) {} //================================================================================ @@ -75,7 +76,7 @@ public: bool display_time=false) const { compute_minimal_quadrangulation(display_time); - return m_minimal_quadrangulation->is_contractible(p, display_time); + return m_minimal_quadrangulation->is_contractible(p, display_time, m_is_verbose); } /// @return true iff 'p1' and 'p2' are freely homotopic. @@ -85,7 +86,7 @@ public: { compute_minimal_quadrangulation(display_time); return m_minimal_quadrangulation->are_freely_homotopic(p1, p2, - display_time); + display_time, m_is_verbose); } /// @return true iff 'p1' and 'p2' are base point freely homotopic. @@ -95,7 +96,7 @@ public: { compute_minimal_quadrangulation(display_time); return m_minimal_quadrangulation->are_base_point_homotopic(p1, p2, - display_time); + display_time, m_is_verbose); } //================================================================================ @@ -173,7 +174,17 @@ public: bool display_time=false) const { compute_minimal_quadrangulation(display_time); - return m_minimal_quadrangulation->is_homotopic_to_simple_cycle(p, display_time); + return m_minimal_quadrangulation->is_homotopic_to_simple_cycle(p, display_time, m_is_verbose); + } + +//================================================================================ +// Utility functions + + // Set whether to display warning message in `std::cerr` when input doesn't meet + // prerequesite + void set_verbose(bool is_verbose) + { + m_is_verbose = is_verbose; } protected: @@ -181,6 +192,7 @@ protected: mutable std::unique_ptr m_minimal_quadrangulation; mutable std::unique_ptr m_shortest_noncontractible_cycle; mutable std::unique_ptr m_facewidth; + bool m_is_verbose; }; } // namespace Surface_mesh_topology diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h index b30104d8f00..dbc89a9d6fb 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h @@ -290,14 +290,17 @@ public: /// @return true iff 'p' is contractible. bool is_contractible(const Path_on_surface& p, - bool display_time=false) const + bool display_time=false, bool is_verbose=false) const { if (p.is_empty()) { return true; } if (!p.is_closed()) { - std::cerr<<"Error: is_contractible requires a closed path."<& p1, const Path_on_surface& p2, - bool display_time=false) const + bool display_time=false, bool is_verbose=false) const { if (p1.is_empty() && p2.is_empty()) { return true; } if ((!p1.is_empty() && !p1.is_closed()) || (!p2.is_empty() && !p2.is_closed())) { - std::cerr<<"Error: are_freely_homotopic requires two closed paths." - <& p1, const Path_on_surface& p2, - bool display_time=false) const + bool display_time=false, bool is_verbose=false) const { if (p1.is_empty() && p2.is_empty()) { return true; } if (p1.is_empty() || p2.is_empty()) { return false; } @@ -413,8 +419,11 @@ public: (p1.back_flip()?p1.back():get_original_map().template beta<1>(p1.back()), p2.back_flip()?p2.back():get_original_map().template beta<1>(p2.back()))) { - std::cerr<<"Error: are_base_point_homotopic requires two paths that" - <<" share the same vertices as extremities."<& p, - bool display_time=false) const + bool display_time=false, bool is_verbose=false) const { if (p.is_empty()) { return true; } if (!p.is_closed()) { - std::cerr<<"Error: is_homotopic_to_simple_cycle requires a closed path."< Date: Fri, 6 Nov 2020 18:35:16 +0100 Subject: [PATCH 056/248] Remove long deprecated, empty and useless Alpha Shapes traits classes --- .../Weighted_alpha_shape_euclidean_traits_2.h | 26 ------------- .../doc/Alpha_shapes_2/PackageDescription.txt | 1 - .../Weighted_alpha_shape_euclidean_traits_2.h | 37 ------------------- Alpha_shapes_3/TODO | 8 ---- .../CGAL/Alpha_shape_euclidean_traits_3.h | 27 -------------- .../Weighted_alpha_shape_euclidean_traits_3.h | 36 ------------------ 6 files changed, 135 deletions(-) delete mode 100644 Alpha_shapes_2/doc/Alpha_shapes_2/CGAL/Weighted_alpha_shape_euclidean_traits_2.h delete mode 100644 Alpha_shapes_2/include/CGAL/Weighted_alpha_shape_euclidean_traits_2.h delete mode 100644 Alpha_shapes_3/include/CGAL/Alpha_shape_euclidean_traits_3.h delete mode 100644 Alpha_shapes_3/include/CGAL/Weighted_alpha_shape_euclidean_traits_3.h diff --git a/Alpha_shapes_2/doc/Alpha_shapes_2/CGAL/Weighted_alpha_shape_euclidean_traits_2.h b/Alpha_shapes_2/doc/Alpha_shapes_2/CGAL/Weighted_alpha_shape_euclidean_traits_2.h deleted file mode 100644 index b182ba9e388..00000000000 --- a/Alpha_shapes_2/doc/Alpha_shapes_2/CGAL/Weighted_alpha_shape_euclidean_traits_2.h +++ /dev/null @@ -1,26 +0,0 @@ - -namespace CGAL { - -/*! -\ingroup PkgAlphaShapes2Ref - -\deprecated The class is deprecated since \cgal 4.10, as the weighted point and the function -objects for weighted points are part of the concept `Kernel`. The class is kept for backward -compatibility. - -The class `Weighted_alpha_shape_euclidean_traits_2` was the default model for the concept -`AlphaShapeTraits_2` for the regular version of Alpha Shapes. - -\tparam K must be a model of `Kernel`. - -\cgalModels `AlphaShapeTraits_2` - -*/ -template< typename K > -class Weighted_alpha_shape_euclidean_traits_2 - : public K -{ -public: - -}; /* end Weighted_alpha_shape_euclidean_traits_2 */ -} /* end namespace CGAL */ diff --git a/Alpha_shapes_2/doc/Alpha_shapes_2/PackageDescription.txt b/Alpha_shapes_2/doc/Alpha_shapes_2/PackageDescription.txt index 3203f168390..d3d6f39d19a 100644 --- a/Alpha_shapes_2/doc/Alpha_shapes_2/PackageDescription.txt +++ b/Alpha_shapes_2/doc/Alpha_shapes_2/PackageDescription.txt @@ -75,7 +75,6 @@ finite number of different \f$ \alpha\f$-shapes and corresponding \cgalCRPSection{Classes} - `CGAL::Alpha_shape_2
` -- `CGAL::Weighted_alpha_shape_euclidean_traits_2` - `CGAL::Alpha_shape_vertex_base_2` - `CGAL::Alpha_shape_face_base_2` diff --git a/Alpha_shapes_2/include/CGAL/Weighted_alpha_shape_euclidean_traits_2.h b/Alpha_shapes_2/include/CGAL/Weighted_alpha_shape_euclidean_traits_2.h deleted file mode 100644 index 58847dc2a43..00000000000 --- a/Alpha_shapes_2/include/CGAL/Weighted_alpha_shape_euclidean_traits_2.h +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) 1997 INRIA Sophia-Antipolis (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org). -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial -// -// Author(s) : Tran Kai Frank DA -// Andreas Fabri - -#ifndef CGAL_WEIGHTED_ALPHA_SHAPE_EUCLIDEAN_TRAITS_2_H -#define CGAL_WEIGHTED_ALPHA_SHAPE_EUCLIDEAN_TRAITS_2_H - -#include - -#define CGAL_DEPRECATED_HEADER "" -#define CGAL_DEPRECATED_MESSAGE_DETAILS \ - "The kernel K can be used directly as traits since weighted points and "\ - "the associated function objects are now part of the concept Kernel." -#include - -namespace CGAL { - -template< class K_ > -class Weighted_alpha_shape_euclidean_traits_2 - : public K_ -{ -public: - Weighted_alpha_shape_euclidean_traits_2() { } - Weighted_alpha_shape_euclidean_traits_2(const K_& k) : K_(k) { } -}; - -} // namespace CGAL - -#endif // CGAL_WEIGHTED_ALPHA_SHAPE_EUCLIDEAN_TRAITS_2_H diff --git a/Alpha_shapes_3/TODO b/Alpha_shapes_3/TODO index 6567995aaed..03c111e94d4 100644 --- a/Alpha_shapes_3/TODO +++ b/Alpha_shapes_3/TODO @@ -12,14 +12,6 @@ when alpha is given as an int. Alpha_shape_3(Dt& dt, bool swap=true, NT alpha = 0, Mode m = REGULARIZED) The triangulation is swapped if swap=true and copied otherwise. -- suppress the traits classes Alpha_shape_euclidean_traits_3.h - and Weighted_alpha_shape_euclidean_traits_3.h - their purpose was to rename the Compute_squared_radius_3 constructor. - The same can be achieved in class Alpha_shapes_3 using the Weighted_tag - of the triangulation - -- same as previous for Alpha_shapes_2 - - test the taking into account of paramater alpha in functions get_alpha_shape_edges get_alpha_shape_facets diff --git a/Alpha_shapes_3/include/CGAL/Alpha_shape_euclidean_traits_3.h b/Alpha_shapes_3/include/CGAL/Alpha_shape_euclidean_traits_3.h deleted file mode 100644 index bcfb4c4f46c..00000000000 --- a/Alpha_shapes_3/include/CGAL/Alpha_shape_euclidean_traits_3.h +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) 1997 INRIA Sophia-Antipolis (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org). -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial -// -// -// Author(s) : Tran Kai Frank DA - -#ifndef CGAL_ALPHA_SHAPE_EUCLIDEAN_TRAITS_3_H -#define CGAL_ALPHA_SHAPE_EUCLIDEAN_TRAITS_3_H - -#include - - -namespace CGAL { - -template -class Alpha_shape_euclidean_traits_3 : public K {}; - - -} //namespace CGAL - -#endif //CGAL_ALPHA_SHAPE_EUCLIDEAN_TRAITS_3_H diff --git a/Alpha_shapes_3/include/CGAL/Weighted_alpha_shape_euclidean_traits_3.h b/Alpha_shapes_3/include/CGAL/Weighted_alpha_shape_euclidean_traits_3.h deleted file mode 100644 index e1fd36c933e..00000000000 --- a/Alpha_shapes_3/include/CGAL/Weighted_alpha_shape_euclidean_traits_3.h +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) 1997 INRIA Sophia-Antipolis (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org). -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial -// -// Author(s) : Tran Kai Frank DA - -#ifndef CGAL_WEIGHTED_ALPHA_SHAPE_EUCLIDEAN_TRAITS_3_H -#define CGAL_WEIGHTED_ALPHA_SHAPE_EUCLIDEAN_TRAITS_3_H - -#include - -#define CGAL_DEPRECATED_HEADER "" -#define CGAL_DEPRECATED_MESSAGE_DETAILS \ - "The kernel K can be used directly as traits since weighted points and "\ - "the associated function objects are now part of the concept Kernel." -#include - -namespace CGAL { - -template < class K_ > -class Weighted_alpha_shape_euclidean_traits_3 - : public K_ -{ -public: - Weighted_alpha_shape_euclidean_traits_3() { } - Weighted_alpha_shape_euclidean_traits_3(const K_& k) : K_(k) { } -}; - -} // namespace CGAL - -#endif // CGAL_WEIGHTED_ALPHA_SHAPE_EUCLIDEAN_TRAITS_3_H From 2341612609ff743dfe6079c39130db37e93c382e Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Thu, 23 Jul 2020 11:47:52 +0200 Subject: [PATCH 057/248] Add chain of inner CCB handling to Arr_dcel_base --- .../include/CGAL/Arr_dcel_base.h | 85 ++++++++++++++++--- 1 file changed, 71 insertions(+), 14 deletions(-) diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_dcel_base.h b/Arrangement_on_surface_2/include/CGAL/Arr_dcel_base.h index 2c685385abc..c30b0ddfca6 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_dcel_base.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_dcel_base.h @@ -478,7 +478,16 @@ public: const Inner_ccb* inner_ccb() const { CGAL_precondition(is_on_inner_ccb()); - return (reinterpret_cast(_clean_pointer(this->p_comp))); + + const Inner_ccb* out = reinterpret_cast(_clean_pointer(this->p_comp)); + if (out->is_valid()) + return out; + // else + while (!out->is_valid()) + out = out->next(); + const_cast(this)->set_inner_ccb(out); + + return out; } /*! Get an incident inner CCB (non-const version). @@ -487,11 +496,20 @@ public: Inner_ccb* inner_ccb() { CGAL_precondition(is_on_inner_ccb()); - return (reinterpret_cast(_clean_pointer(this->p_comp))); + + Inner_ccb* out = reinterpret_cast(_clean_pointer(this->p_comp)); + if (out->is_valid()) + return out; + // else + while (!out->is_valid()) + out = out->next(); + set_inner_ccb(out); + + return out; } /*! Set the incident inner CCB. */ - void set_inner_ccb(Inner_ccb *ic) + void set_inner_ccb(const Inner_ccb *ic) { // Set the component pointer and set its LSB. this->p_comp = _set_lsb(ic); @@ -768,18 +786,27 @@ public: typedef typename Face::Inner_ccb_iterator Inner_ccb_iterator; private: - Face* p_f; // The face the contains the CCB in its interior. + union + { + Face* f; // The face the contains the CCB in its interior. + Arr_inner_ccb* icc; // next inner CCB in chain to valid icc + } f_or_icc; Inner_ccb_iterator iter; // The inner CCB identifier. - bool iter_is_not_singular; + enum + { + ITER_IS_SINGULAR, + ITER_IS_NOT_SINGULAR, + INVALID + } status; public: /*! Default constructor. */ - Arr_inner_ccb() : p_f(nullptr), iter_is_not_singular(false) {} + Arr_inner_ccb() : status(ITER_IS_SINGULAR) { f_or_icc.f = nullptr; } /*! Copy constructor. */ Arr_inner_ccb(const Arr_inner_ccb& other) : - p_f(other.p_f), iter_is_not_singular(other.iter_is_not_singular) - { if (other.iter_is_not_singular) iter = other.iter; } + f_or_icc(other.f_or_icc), status(other.status) + { if (other.status == ITER_IS_NOT_SINGULAR) iter = other.iter; } /*! Get a halfedge along the component (const version). */ const Halfedge* halfedge() const { return (*iter); } @@ -791,33 +818,63 @@ public: void set_halfedge(Halfedge *he) { *iter = he; } /*! Get the incident face (const version). */ - const Face* face() const { return (p_f); } + const Face* face() const + { + CGAL_assertion (status != INVALID); + return f_or_icc.f; + } /*! Get the incident face (non-const version). */ - Face* face() { return (p_f); } + Face* face() + { + CGAL_assertion (status != INVALID); + return f_or_icc.f; + } /*! Set the incident face. */ - void set_face(Face* f) { p_f = f; } + void set_face(Face* f) + { + CGAL_assertion (status != INVALID); + f_or_icc.f = f; + } /*! Get the iterator (const version). */ Inner_ccb_iterator iterator() const { - CGAL_assertion(iter_is_not_singular); + CGAL_assertion(status == ITER_IS_NOT_SINGULAR); return (iter); } /*! Get the iterator (non-const version). */ Inner_ccb_iterator iterator() { - CGAL_assertion(iter_is_not_singular); + CGAL_assertion(status == ITER_IS_NOT_SINGULAR); return (iter); } /*! Set the inner CCB iterator. */ void set_iterator(Inner_ccb_iterator it) { + CGAL_assertion (status != INVALID); iter = it; - iter_is_not_singular = true; + status = ITER_IS_NOT_SINGULAR; + } + + /*! Check validity */ + bool is_valid() const { return (status != INVALID); } + + /*! Get the next CCB to primary chain. */ + Arr_inner_ccb* next() const + { + CGAL_assertion (status == INVALID); + return f_or_icc.icc; + } + + /*! Set the next CCB to primary chain. */ + void set_next(Arr_inner_ccb* next) + { + status = INVALID; + f_or_icc.icc = next; } }; From 2f9cdd068b884b8b530b2c948c9defa1e2a3b1f9 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Thu, 23 Jul 2020 14:37:18 +0200 Subject: [PATCH 058/248] Sweep mode for Arrangement_2 --- .../include/CGAL/Arr_dcel_base.h | 53 ++++++++++++++----- .../Arrangement_on_surface_2_impl.h | 22 +++++--- .../include/CGAL/Arrangement_on_surface_2.h | 42 +++++++++++++++ .../Arr_construction_ss_visitor.h | 19 ++++++- .../Surface_sweep_2/Arr_overlay_ss_visitor.h | 2 + 5 files changed, 118 insertions(+), 20 deletions(-) diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_dcel_base.h b/Arrangement_on_surface_2/include/CGAL/Arr_dcel_base.h index c30b0ddfca6..a32d7eb0de7 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_dcel_base.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_dcel_base.h @@ -482,11 +482,10 @@ public: const Inner_ccb* out = reinterpret_cast(_clean_pointer(this->p_comp)); if (out->is_valid()) return out; - // else - while (!out->is_valid()) - out = out->next(); - const_cast(this)->set_inner_ccb(out); + // else + out = const_cast(out)->reduce_path(); + const_cast(this)->set_inner_ccb(out); return out; } @@ -500,14 +499,19 @@ public: Inner_ccb* out = reinterpret_cast(_clean_pointer(this->p_comp)); if (out->is_valid()) return out; - // else - while (!out->is_valid()) - out = out->next(); - set_inner_ccb(out); + // else + out = out->reduce_path(); + set_inner_ccb(out); return out; } + Inner_ccb* inner_ccb_no_redirect() + { + CGAL_precondition(is_on_inner_ccb()); + return reinterpret_cast(_clean_pointer(this->p_comp)); + } + /*! Set the incident inner CCB. */ void set_inner_ccb(const Inner_ccb *ic) { @@ -809,13 +813,25 @@ public: { if (other.status == ITER_IS_NOT_SINGULAR) iter = other.iter; } /*! Get a halfedge along the component (const version). */ - const Halfedge* halfedge() const { return (*iter); } + const Halfedge* halfedge() const + { + CGAL_assertion (is_valid()); + return (*iter); + } /*! Get a halfedge along the component (non-const version). */ - Halfedge* halfedge() { return (*iter); } + Halfedge* halfedge() + { + CGAL_assertion (is_valid()); + return (*iter); + } /*! Set a representative halfedge for the component. */ - void set_halfedge(Halfedge *he) { *iter = he; } + void set_halfedge(Halfedge *he) + { + CGAL_assertion (is_valid()); + *iter = he; + } /*! Get the incident face (const version). */ const Face* face() const @@ -855,7 +871,7 @@ public: /*! Set the inner CCB iterator. */ void set_iterator(Inner_ccb_iterator it) { - CGAL_assertion (status != INVALID); + CGAL_assertion (is_valid()); iter = it; status = ITER_IS_NOT_SINGULAR; } @@ -876,6 +892,15 @@ public: status = INVALID; f_or_icc.icc = next; } + + Arr_inner_ccb* reduce_path() + { + if (is_valid()) + return this; + // else + f_or_icc.icc = f_or_icc.icc->reduce_path(); + return f_or_icc.icc; + } }; /*! \class @@ -999,6 +1024,7 @@ public: typedef typename Face_list::iterator Face_iterator; typedef CGAL::N_step_adaptor_derived Edge_iterator; + typedef typename Inner_ccb_list::iterator Inner_ccb_iterator; // Definitions of const iterators. typedef typename Vertex_list::const_iterator Vertex_const_iterator; @@ -1075,6 +1101,9 @@ public: { return make_prevent_deref_range(edges_begin(), edges_end()); } + + Inner_ccb_iterator inner_ccbs_begin() { return in_ccbs.begin(); } + Inner_ccb_iterator inner_ccbs_end() { return in_ccbs.end(); } //@} /// \name Obtaining constant iterators. diff --git a/Arrangement_on_surface_2/include/CGAL/Arrangement_2/Arrangement_on_surface_2_impl.h b/Arrangement_on_surface_2/include/CGAL/Arrangement_2/Arrangement_on_surface_2_impl.h index 8c3fd571803..7dca8f1abae 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arrangement_2/Arrangement_on_surface_2_impl.h +++ b/Arrangement_on_surface_2/include/CGAL/Arrangement_2/Arrangement_on_surface_2_impl.h @@ -2739,14 +2739,22 @@ _insert_at_vertices(DHalfedge* he_to, he1->set_inner_ccb(ic1); he2->set_inner_ccb(ic1); - // Make all halfedges along ic2 to point to ic1. - DHalfedge* curr; + if (m_sweep_mode) + { + CGAL_assertion(ic1->is_valid()); + CGAL_assertion(ic2->is_valid()); + ic2->set_next(ic1); + } + else + { + // Make all halfedges along ic2 to point to ic1. + DHalfedge* curr; + for (curr = he2->next(); curr != he1; curr = curr->next()) + curr->set_inner_ccb(ic1); - for (curr = he2->next(); curr != he1; curr = curr->next()) - curr->set_inner_ccb(ic1); - - // Delete the redundant inner CCB. - _dcel().delete_inner_ccb(ic2); + // Delete the redundant inner CCB. + _dcel().delete_inner_ccb(ic2); + } // Notify the observers that we have merged the two inner CCBs. _notify_after_merge_inner_ccb(fh, (Halfedge_handle(he1))->ccb()); diff --git a/Arrangement_on_surface_2/include/CGAL/Arrangement_on_surface_2.h b/Arrangement_on_surface_2/include/CGAL/Arrangement_on_surface_2.h index ddcc1c6229b..e8756fe562d 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arrangement_on_surface_2.h +++ b/Arrangement_on_surface_2/include/CGAL/Arrangement_on_surface_2.h @@ -909,6 +909,14 @@ protected: bool m_own_traits; // inidicates whether the geometry // traits should be freed up. + bool m_sweep_mode = false; + // sweep mode efficiently + // merges inner CCB but + // keeps invalid inner CCB + // and memory overhead that + // should be cleaned + // afterwards + public: /// \name Constructors. //@{ @@ -939,6 +947,9 @@ public: /*! Destructor. */ virtual ~Arrangement_on_surface_2(); + /*! Change mode. */ + void set_sweep_mode (bool mode) { m_sweep_mode = mode; } + /*! Clear the arrangement. */ virtual void clear(); //@} @@ -1516,6 +1527,37 @@ public: //@} + /*! + * Cleans the inner CCB if sweep mode was used, by removing all + * non-valid inner CCBs + */ + void clean_inner_ccbs() + { + for (DHalfedge_iter he = _dcel().halfedges_begin(); + he != _dcel().halfedges_end(); ++ he) + { + if (!he->is_on_inner_ccb()) + continue; + + DInner_ccb* ic1 = he->inner_ccb_no_redirect(); + if (ic1->is_valid()) + continue; + + DInner_ccb* ic2 = he->inner_ccb(); + if (!ic2->halfedge()->is_on_inner_ccb() + || ic2->halfedge()->inner_ccb_no_redirect() != ic2) + ic2->set_halfedge(&(*he)); + } + + typename Dcel::Inner_ccb_iterator it = _dcel().inner_ccbs_begin(); + while (it != _dcel().inner_ccbs_end()) + { + typename Dcel::Inner_ccb_iterator current = it ++; + if (!current->is_valid()) + _dcel().delete_inner_ccb(&*current); + } + } + protected: /// \name Determining the boundary-side conditions. //@{ diff --git a/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_construction_ss_visitor.h b/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_construction_ss_visitor.h index c8c9b9b57f0..da3f13d1934 100644 --- a/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_construction_ss_visitor.h +++ b/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_construction_ss_visitor.h @@ -142,6 +142,9 @@ public: /* A notification issued before the sweep process starts. */ inline void before_sweep(); + /* A notification issued after the sweep process stops. */ + inline void after_sweep(); + /*! * A notification invoked before the sweep-line starts handling the given * event. @@ -267,7 +270,21 @@ private: // Notifies the helper that the sweep process now starts. template void Arr_construction_ss_visitor::before_sweep() -{ m_helper.before_sweep(); } +{ + m_helper.before_sweep(); + m_arr->set_sweep_mode(true); +} + + +//----------------------------------------------------------------------------- +// A notification issued after the sweep process stops. +template +void Arr_construction_ss_visitor::after_sweep() +{ + m_arr->clean_inner_ccbs(); + m_arr->set_sweep_mode(false); +} + //----------------------------------------------------------------------------- // A notification invoked before the sweep-line starts handling the given diff --git a/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_overlay_ss_visitor.h b/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_overlay_ss_visitor.h index f9f697a3b40..8fbcc861d5f 100644 --- a/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_overlay_ss_visitor.h +++ b/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_overlay_ss_visitor.h @@ -552,6 +552,8 @@ Arr_overlay_ss_visitor::update_event(Event* e, template void Arr_overlay_ss_visitor::after_sweep() { + Base::after_sweep(); + // Notify boundary vertices: typename Vertex_map::iterator it; for (it = m_vertices_map.begin(); it != m_vertices_map.end(); ++it) { From becf548ee12a303f73c35079562df11f01b14c04 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Wed, 12 Aug 2020 12:46:49 +0200 Subject: [PATCH 059/248] Update from review --- .../include/CGAL/Arr_dcel_base.h | 38 +++++++++---------- .../Arrangement_on_surface_2_impl.h | 2 + .../include/CGAL/Arrangement_on_surface_2.h | 10 +++-- .../Arr_construction_ss_visitor.h | 2 +- 4 files changed, 28 insertions(+), 24 deletions(-) diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_dcel_base.h b/Arrangement_on_surface_2/include/CGAL/Arr_dcel_base.h index a32d7eb0de7..03381dcd760 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_dcel_base.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_dcel_base.h @@ -483,10 +483,13 @@ public: if (out->is_valid()) return out; - // else - out = const_cast(out)->reduce_path(); - const_cast(this)->set_inner_ccb(out); - return out; + // else reduce path and get valid iccb + const Inner_ccb* valid = out->next(); + while (!valid->is_valid()) + valid = valid->next(); + const_cast(out)->set_next(const_cast(valid)); + const_cast(this)->set_inner_ccb(valid); + return valid; } /*! Get an incident inner CCB (non-const version). @@ -500,10 +503,13 @@ public: if (out->is_valid()) return out; - // else - out = out->reduce_path(); - set_inner_ccb(out); - return out; + // else reduce path and get valid iccb + Inner_ccb* valid = out->next(); + while (!valid->is_valid()) + valid = valid->next(); + out->set_next(valid); + set_inner_ccb(valid); + return valid; } Inner_ccb* inner_ccb_no_redirect() @@ -798,9 +804,11 @@ private: Inner_ccb_iterator iter; // The inner CCB identifier. enum { - ITER_IS_SINGULAR, - ITER_IS_NOT_SINGULAR, - INVALID + ITER_IS_SINGULAR, // singular = default iterator, not initialized + ITER_IS_NOT_SINGULAR, // not singular = iterator was assigned and is valid + INVALID // invalid = the inner CCB is invalid and + // only links to another inner CCB + // in chain to valid CCB } status; public: @@ -893,14 +901,6 @@ public: f_or_icc.icc = next; } - Arr_inner_ccb* reduce_path() - { - if (is_valid()) - return this; - // else - f_or_icc.icc = f_or_icc.icc->reduce_path(); - return f_or_icc.icc; - } }; /*! \class diff --git a/Arrangement_on_surface_2/include/CGAL/Arrangement_2/Arrangement_on_surface_2_impl.h b/Arrangement_on_surface_2/include/CGAL/Arrangement_2/Arrangement_on_surface_2_impl.h index 7dca8f1abae..8c1581f45e3 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arrangement_2/Arrangement_on_surface_2_impl.h +++ b/Arrangement_on_surface_2/include/CGAL/Arrangement_2/Arrangement_on_surface_2_impl.h @@ -2741,6 +2741,8 @@ _insert_at_vertices(DHalfedge* he_to, if (m_sweep_mode) { + // Inner CCB are obtained using Halfedge::inner_ccb() which + // performs path reduction and always return valid iCCB CGAL_assertion(ic1->is_valid()); CGAL_assertion(ic2->is_valid()); ic2->set_next(ic1); diff --git a/Arrangement_on_surface_2/include/CGAL/Arrangement_on_surface_2.h b/Arrangement_on_surface_2/include/CGAL/Arrangement_on_surface_2.h index e8756fe562d..8df551ee7aa 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arrangement_on_surface_2.h +++ b/Arrangement_on_surface_2/include/CGAL/Arrangement_on_surface_2.h @@ -1531,7 +1531,7 @@ public: * Cleans the inner CCB if sweep mode was used, by removing all * non-valid inner CCBs */ - void clean_inner_ccbs() + void clean_inner_ccbs_after_sweep() { for (DHalfedge_iter he = _dcel().halfedges_begin(); he != _dcel().halfedges_end(); ++ he) @@ -1543,10 +1543,12 @@ public: if (ic1->is_valid()) continue; + // Calling Halfedge::inner_ccb() reduces the path and makes the + // halfedge point to a correct CCB DInner_ccb* ic2 = he->inner_ccb(); - if (!ic2->halfedge()->is_on_inner_ccb() - || ic2->halfedge()->inner_ccb_no_redirect() != ic2) - ic2->set_halfedge(&(*he)); + CGAL_USE(ic2); + CGAL_assertion (ic2->halfedge()->is_on_inner_ccb() + && ic2->halfedge()->inner_ccb_no_redirect() == ic2); } typename Dcel::Inner_ccb_iterator it = _dcel().inner_ccbs_begin(); diff --git a/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_construction_ss_visitor.h b/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_construction_ss_visitor.h index da3f13d1934..1e3544ec566 100644 --- a/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_construction_ss_visitor.h +++ b/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_construction_ss_visitor.h @@ -281,7 +281,7 @@ void Arr_construction_ss_visitor::before_sweep() template void Arr_construction_ss_visitor::after_sweep() { - m_arr->clean_inner_ccbs(); + m_arr->clean_inner_ccbs_after_sweep(); m_arr->set_sweep_mode(false); } From f0e94d5efa9dac6aa93d45a33f81d94b968f20e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Sat, 5 Dec 2020 10:08:13 +0100 Subject: [PATCH 060/248] Fix typo --- AABB_tree/include/CGAL/AABB_tree.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AABB_tree/include/CGAL/AABB_tree.h b/AABB_tree/include/CGAL/AABB_tree.h index 5f0521e219f..1bb4d0b2d17 100644 --- a/AABB_tree/include/CGAL/AABB_tree.h +++ b/AABB_tree/include/CGAL/AABB_tree.h @@ -126,7 +126,7 @@ namespace CGAL { Self& operator=(const Self&) = delete; /** - * @brief Builds the datastructure from a sequence of primitives. + * @brief Builds the data structure from a sequence of primitives. * @param first iterator over first primitive to insert * @param beyond past-the-end iterator * From 389084d0360145fd416ebb3616b2cd7715eeef33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Sat, 5 Dec 2020 10:16:01 +0100 Subject: [PATCH 061/248] Properly document the traits requirements of DT3 in advancing front recons. --- ...ancingFrontSurfaceReconstructionTraits_3.h | 159 ++++++++++++++++++ .../PackageDescription.txt | 7 + .../dependencies | 1 + .../Advancing_front_surface_reconstruction.h | 25 ++- 4 files changed, 186 insertions(+), 6 deletions(-) create mode 100644 Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Concepts/AdvancingFrontSurfaceReconstructionTraits_3.h diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Concepts/AdvancingFrontSurfaceReconstructionTraits_3.h b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Concepts/AdvancingFrontSurfaceReconstructionTraits_3.h new file mode 100644 index 00000000000..54d047f6a0e --- /dev/null +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Concepts/AdvancingFrontSurfaceReconstructionTraits_3.h @@ -0,0 +1,159 @@ + +/*! +\ingroup PkgAdvancingFrontSurfaceReconstructionRef +\cgalConcept + +The concept `AdvancingFrontSurfaceReconstructionTraits_3` describes the requirements +for the the geometric traits of the class `CGAL::Delaunay_triangulation_3` +used in the class `CGAL::Advancing_front_surface_reconstruction`. +It defines the geometric objects (points, segments...) forming the triangulation +together with a few geometric predicates and constructions on these objects. + +\cgalRefines `DelaunayTriangulationTraits_3` + +\cgalHasModel All models of `Kernel`. +*/ +class AdvancingFrontSurfaceReconstructionTraits_3 +{ +public: + +/// \name Types +/// @{ + +/*! +The coordinate type. +*/ +typedef unspecified_type FT; + +/*! +The vector type. +*/ +typedef unspecified_type Vector_3; + +/*! +The sphere type. +*/ +typedef unspecified_type Sphere_3; + +/*! +A constructor object that must provide the function operator + +`Vector_3 operator()(Point_3 p, Point_3 q)`, + +which constructs the vector `q-p`. +*/ +typedef unspecified_type Construct_vector_3; + +/*! +A constructor object that must provide the function operators + +`Vector_3 operator()(Vector_3 v, Vector_3 w)`, + +which returns the cross product of `v` and `w`. +*/ +typedef unspecified_type Construct_cross_product_vector_3; + +/*! +A constructor object that must provide the function operators + +`FT operator()(Vector_3 v, Vector_3 w)`, + +which returns the scalar (inner) product of `v` and `w`. +*/ +typedef unspecified_type Compute_scalar_product_3; + +/*! +A constructor object that must provide the function operator + +`Sphere_3 operator()(Point_3 p, Point_3 q, Point_3 r)`, + +which constructs a sphere initialized to the smallest sphere which passes +through the points `p`, `q`, and `r`. +*/ +typedef unspecified_type Construct_sphere_3; + +/*! +A constructor object that must provide the function operator + +`Point_3 operator()(Sphere_3 s)`, + +which returns the center of the sphere `s`. +*/ +typedef unspecified_type Construct_center_3; + +/*! +A constructor object that must provide the function operators + +`FT operator()(Point_3 p, Point_3 q, Point_3 r, Point_3 s)`, + +which returns the squared radius of the sphere passing through `p`, `q` and `r`, +and whose center is in the plane defined by these three points. + +and + +`FT operator()(Point_3 p, Point_3 q, Point_3 r, Point_3 s)`, + +which returns the squared radius of the sphere passing through `p`, `q`, `r`, and `s`. + +and + +`FT operator()(Sphere_3 s)`, + +which returns the squared radius of the sphere `s`. +*/ +typedef unspecified_type Compute_squared_radius_3; + +/*! +A constructor object that must provide the function operators + +`FT operator()(Point_3 p, Point_3 q)`, + +which returns the squared distance between the points `p` and `q`. +*/ +typedef unspecified_type Compute_squared_distance_3; + +/// @} + +/// \name Operations +/// The following functions give access to the predicate and construction objects: +/// @{ + +/*! +gives access to the `Construct_vector_3` construction. +*/ +Construct_vector_3 construct_vector_3_object(); + +/*! +gives access to the `Construct_cross_product_vector_3` construction. +*/ +Construct_cross_product_vector_3 construct_cross_product_vector_3_object(); + +/*! +gives access to the `Compute_scalar_product_3` construction. +*/ +Compute_scalar_product_3 compute_scalar_product_3_object(); + +/*! +gives access to the `Construct_sphere_3` construction. +*/ +Construct_sphere_3 construct_sphere_3_object(); + +/*! +gives access to the `Construct_center_3` construction. +*/ +Construct_center_3 construct_center_3_object(); + +/*! +gives access to the `Compute_squared_radius_3` construction. +*/ +Compute_squared_radius_3 compute_squared_radius_3_object(); + +/*! +gives access to the `Compute_squared_distance_3` construction. +*/ +Compute_squared_distance_3 compute_squared_distance_3_object(); + +/// @} + +}; /* end AdvancingFrontSurfaceReconstructionTraits_3 */ + diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/PackageDescription.txt b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/PackageDescription.txt index 1adb33ca94e..5d50c10442c 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/PackageDescription.txt +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/PackageDescription.txt @@ -1,5 +1,8 @@ /// \defgroup PkgAdvancingFrontSurfaceReconstructionRef Advancing Front Surface Reconstruction Reference +/// \defgroup PkgAdvancingFrontSurfaceReconstructionRefConcepts Concepts +/// \ingroup PkgAdvancingFrontSurfaceReconstructionRef + /*! \addtogroup PkgAdvancingFrontSurfaceReconstructionRef @@ -25,6 +28,10 @@ of topological singularities. } \cgalClassifedRefPages +\cgalCRPSection{Concepts} + +- `AdvancingFrontSurfaceReconstructionTraits_3` + \cgalCRPSection{Classes} - `CGAL::Advancing_front_surface_reconstruction` diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/dependencies b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/dependencies index 9b91259b814..69d8724660e 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/dependencies +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/dependencies @@ -5,6 +5,7 @@ Algebraic_foundations Circulator Stream_support TDS_2 +TDS_3 Triangulation_2 Triangulation_3 Number_types diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index e997bd55870..cb9349ba2a5 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -175,13 +175,26 @@ namespace CGAL { store handles to the vertices and faces of the 3D triangulation, which enables the user to explore the 2D as well as 3D neighborhood of vertices and facets of the surface. - \tparam Dt must be a `Delaunay_triangulation_3` with - `Advancing_front_surface_reconstruction_vertex_base_3` and `Advancing_front_surface_reconstruction_cell_base_3` blended into the vertex and cell type. - The default uses the `Exact_predicates_inexact_constructions_kernel` as geometric traits class. + \tparam Dt must be a `Delaunay_triangulation_3` whose `Traits` template parameter must be a model of + `AdvancingFrontSurfaceReconstructionTraits_3` and whose `Tds` template parameter must be + a model of `TriangulationDataStructure_3` with `Advancing_front_surface_reconstruction_vertex_base_3` and + `Advancing_front_surface_reconstruction_cell_base_3` blended into the vertex and cell type, respectively. + The default value is: + \code + CGAL::Delaunay_triangulation_3, + CGAL::Advancing_front_surface_reconstruction_cell_base_3< + CGAL::Exact_predicates_inexact_constructions_kernel> > >` + \endcode - \tparam P must be a functor with `double operator()(AdvancingFront,Cell_handle,int)` returning the - priority of the facet `(Cell_handle,int)`. This functor enables the user to choose how candidate - triangles are prioritized. If a facet should not appear in the output, + \tparam P must be a functor offering + \code + FT operator()(Advancing_front_surface_reconstruction,Cell_handle,int) + \endcode + returning the priority of the facet `(Cell_handle,int)`. This functor enables the user + to choose how candidate triangles are prioritized. If a facet should not appear in the output, `infinity()` must be returned. It defaults to a functor that returns the `smallest_radius_delaunay_sphere()`. From f3f52a8e8e4b28051099de4a40eb64f239fdb890 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Sat, 5 Dec 2020 10:45:13 +0100 Subject: [PATCH 062/248] Use traits functors rather than global functions --- .../Advancing_front_surface_reconstruction.h | 86 ++++++++++++------- 1 file changed, 55 insertions(+), 31 deletions(-) diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index cb9349ba2a5..299e037a558 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -281,6 +281,7 @@ namespace CGAL { typedef Advancing_front_surface_reconstruction Extract; typedef typename Triangulation_3::Geom_traits Geom_traits; + typedef typename Kernel::FT FT; typedef typename Kernel::FT coord_type; typedef typename Kernel::Point_3 Point; @@ -390,7 +391,23 @@ namespace CGAL { std::list nbe_pool; std::list ist_pool; + public: + Vector construct_vector(const Point& p, const Point& q) const + { + return T.geom_traits().construct_vector_3_object()(p, q); + } + Vector construct_cross_product(const Vector& v, const Vector& w) const + { + return T.geom_traits().construct_cross_product_vector_3_object()(v, w); + } + + FT compute_scalar_product(const Vector& v, const Vector& w) const + { + return T.geom_traits().compute_scalar_product_3_object()(v, w); + } + + private: Intern_successors_type* new_border() { nbe_pool.resize(nbe_pool.size()+1); @@ -692,12 +709,14 @@ namespace CGAL { ++it; }while(collinear(p,q,it->point())); const Point& r = it->point(); - Vector u = q-r; - Vector v = q-p; - Vector w = r-p; - Vector vw = cross_product(v,w); - double len = (std::max)(u*u,(std::max)(v*v,w*w)); - Point s = p + 10* len * (vw/(vw*vw)); + Vector u = construct_vector(r, q); + Vector v = construct_vector(p, q); + Vector w = construct_vector(p, r); + Vector vw = construct_cross_product(v,w); + double len = (std::max)(compute_scalar_product(u,u), + (std::max)(compute_scalar_product(v,v), + compute_scalar_product(w,w))); + Point s = p + 10 * len * (vw/compute_scalar_product(vw,vw)); added_vertex = T.insert(s); } } @@ -1199,7 +1218,7 @@ namespace CGAL { \param index index of the facet in `c` */ - coord_type + FT smallest_radius_delaunay_sphere(const Cell_handle& c, const int& index) const { @@ -1262,16 +1281,16 @@ namespace CGAL { const Point& pp2 = cc->vertex(i2)->point(); const Point& pp3 = cc->vertex(i3)->point(); - Sphere facet_sphere(pp1, pp2, pp3); - if (squared_distance(facet_sphere.center(), pp0) < - facet_sphere.squared_radius()) + Sphere facet_sphere = T.geom_traits().construct_sphere_3_object()(pp1, pp2, pp3); + if (squared_distance(T.geom_traits().construct_center_3_object()(facet_sphere), pp0) < + T.geom_traits().compute_squared_radius_3_object()(facet_sphere)) { #ifdef AFSR_LAZY value = lazy_squared_radius(cc); #else // qualified with CGAL, to avoid a compilation error with clang if(volume(pp0, pp1, pp2, pp3) != 0){ - value = CGAL::squared_radius(pp0, pp1, pp2, pp3); + value = T.geom_traits().compute_squared_radius_3_object()(pp0, pp1, pp2, pp3); } else { typedef Exact_predicates_exact_constructions_kernel EK; Cartesian_converter to_exact; @@ -1293,26 +1312,30 @@ namespace CGAL { cc = lazy_circumcenter(c); cn = lazy_circumcenter(n); #else - cc = CGAL::circumcenter(cp0, cp1, cp2, cp3); - cn = CGAL::circumcenter(np0, np1, np2, np3); + cc = T.geom_traits().construct_circumcenter_3_object()(cp0, cp1, cp2, cp3); + cn = T.geom_traits().construct_circumcenter_3_object()(np0, np1, np2, np3); #endif // computation of the distance of cp1 to the dual segment cc, cn... - Vector V(cc - cn), Vc(cc - cp1), Vn(cp1 - cn); - coord_type ac(V * Vc), an(V * Vn), norm_V(V * V); + Vector V = construct_vector(cn, cc), + Vc = construct_vector(cp1, cc), + Vn = construct_vector(cn, cp1); + coord_type ac = compute_scalar_product(V, Vc), + an = compute_scalar_product(V, Vn), + norm_V = compute_scalar_product(V, V); if ((ac > 0) && (an > 0)) { - value = (Vc*Vc) - ac*ac/norm_V; + value = compute_scalar_product(Vc, Vc) - ac*ac/norm_V; if ((value < 0)||(norm_V > inv_eps_2)){ // qualified with CGAL, to avoid a compilation error with clang - value = CGAL::squared_radius(cp1, cp2, cp3); + value = T.geom_traits().compute_squared_radius_3_object()(cp1, cp2, cp3); } } else { if (ac <= 0) - value = squared_distance(cc, cp1); + value = T.geom_traits().compute_squared_distance_3_object()(cc, cp1); else // (an <= 0) - value = squared_distance(cn, cp1); + value = T.geom_traits().compute_squared_distance_3_object()(cn, cp1); } } } @@ -1354,9 +1377,9 @@ namespace CGAL { const Point& p2 = c->vertex(i2)->point(); const Point& pc = c->vertex(i3)->point(); - Vector P2P1 = p1-p2, P2Pn, PnP1; + Vector P2P1 = construct_vector(p2, p1), P2Pn, PnP1; - Vector v2, v1 = cross_product(pc-p2, P2P1); + Vector v2, v1 = construct_cross_product(construct_vector(p2, pc), P2P1); coord_type norm, norm1 = v1*v1; coord_type norm12 = P2P1*P2P1; @@ -1388,12 +1411,12 @@ namespace CGAL { { const Point& pn = neigh->vertex(n_i3)->point(); - P2Pn = pn-p2; - v2 = cross_product(P2P1,P2Pn); + P2Pn = construct_vector(p2, pn); + v2 = construct_cross_product(P2P1,P2Pn); //pas necessaire de normer pour un bon echantillon: // on peut alors tester v1*v2 >= 0 - norm = sqrt(norm1 * (v2*v2)); + norm = sqrt(norm1 * compute_scalar_product(v2,v2)); pscal = v1*v2; // check if the triangle will produce a sliver on the surface bool sliver_facet = (pscal <= COS_ALPHA_SLIVER*norm); @@ -1407,10 +1430,9 @@ namespace CGAL { // We skip triangles having an internal angle along e // whose cosinus is smaller than -DELTA // that is the angle is larger than arcos(-DELTA) - border_facet = !((P2P1*P2Pn >= - -DELTA*sqrt(norm12*(P2Pn*P2Pn)))&& - (P2P1*PnP1 >= - -DELTA*sqrt(norm12*(PnP1*PnP1)))); + border_facet = + !((P2P1*P2Pn >= -DELTA*sqrt(norm12*compute_scalar_product(P2Pn,P2Pn))) && + (P2P1*PnP1 >= -DELTA*sqrt(norm12*compute_scalar_product(PnP1,PnP1)))); // \todo investigate why we simply do not skip this triangle // but continue looking for a better candidate // if (!border_facet){ @@ -1582,9 +1604,11 @@ namespace CGAL { int n_i3 = (6 - n_ind - n_i1 - n_i2); const Point& pn = neigh->vertex(n_i3)->point(); - Vector v1 = cross_product(pc-p2,p1-p2), - v2 = cross_product(p1-p2,pn-p2); - coord_type norm = sqrt((v1*v1)*(v2*v2)); + Vector v1 = construct_cross_product(construct_vector(p2, pc), + construct_vector(p2, p1)), + v2 = construct_cross_product(construct_vector(p2, p1), + construct_vector(p2, pn)); + coord_type norm = sqrt(compute_scalar_product(v1, v1) * compute_scalar_product(v2, v2)); if (v1*v2 > COS_BETA*norm) return 1; // label bonne pliure sinon: From eac26fcabc9c3fb0d280d4386999b8f7c03f4afc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Sat, 5 Dec 2020 10:46:01 +0100 Subject: [PATCH 063/248] Misc doc fixes in advancing front reconstruction --- .../Advancing_front_surface_reconstruction.h | 57 +++++++++++-------- 1 file changed, 34 insertions(+), 23 deletions(-) diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index 299e037a558..f8ffee4dd4d 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -199,12 +199,18 @@ namespace CGAL { `smallest_radius_delaunay_sphere()`. */ - template < - class Dt = Default, - class P = Default> - class Advancing_front_surface_reconstruction { - - typedef typename Default::Get, Advancing_front_surface_reconstruction_cell_base_3 > > >::type Triangulation; + template + class Advancing_front_surface_reconstruction + { + typedef typename Default::Get, + Advancing_front_surface_reconstruction_cell_base_3< + Exact_predicates_inexact_constructions_kernel> > > >::type Triangulation; typedef typename Default::Get::type Priority; public: @@ -215,9 +221,9 @@ namespace CGAL { /*! The type of the 2D triangulation data structure describing the reconstructed surface, being a model of `TriangulationDataStructure_2`. - The type `Triangulation_data_structure_2::Vertex` is model of the concept `TriangulationDataStructure_2::Vertex` and has additionally the - method `vertex_3()` that returns a `#Vertex_handle` to the associated 3D vertex. + method `vertex_3()` that returns a `Vertex_handle` to the associated 3D vertex. - The type `Triangulation_data_structure_2::Face` is model of the concept `TriangulationDataStructure_2::Face` and has additionally the - method `facet()` that returns the associated `#Facet`, and a method `bool is_on_surface()` + method `facet()` that returns the associated `Facet`, and a method `bool is_on_surface()` for testing if a face is part of the reconstructed surface or a face incident to a boundary edge. In case the surface has boundaries, the 2D surface has one vertex which is associated to the infinite @@ -226,15 +232,20 @@ namespace CGAL { typedef unspecified_type Triangulation_data_structure_2; /*! - The type of the 3D triangulation. + The type of the 3D Delaunay triangulation (the first template parameter). */ typedef unspecified_type Triangulation_3; /*! - The type of the facet priority functor. + The type of the facet priority functor (the second template parameter). */ typedef unspecified_type Priority; + /*! + The number type. + */ + typedef typename Triangulation_3::Geom_traits::FT FT; + /*! The point type. */ @@ -258,21 +269,21 @@ namespace CGAL { /*! A bidirectional iterator range which enables to enumerate all points that were removed from the 3D Delaunay triangulation during the surface reconstruction. The value type - of the iterator is `#Point`. + of the iterator is `Point`. */ typedef unspecified_type Outlier_range; + /*! + A bidirectional iterator range which enables to visit all vertices on a boundary. + The value type of the iterator is `Vertex_handle`. + */ + typedef unspecified_type Vertex_on_boundary_range; + /*! A bidirectional iterator range which enables to visit all boundaries. The value type of the iterator is `Vertex_on_boundary_range`. */ typedef unspecified_type Boundary_range; - - /*! - A bidirectional iterator range which enables to visit all vertices on a boundary. - The value type of the iterator is `#Vertex_handle` - */ - typedef unspecified_type Vertex_on_boundary_range; /// @} #endif @@ -768,9 +779,9 @@ namespace CGAL { \param radius_ratio_bound candidates incident to surface triangles which are not in the beta-wedge are discarded, if the ratio of their radius and the radius of the surface triangle is larger than `radius_ratio_bound`. - Described in Section \ref AFSR_Boundaries + Described in Section \ref AFSR_Boundaries. \param beta half the angle of the wedge in which only the radius of triangles counts for the plausibility of candidates. - Described in Section \ref AFSR_Selection + Described in Section \ref AFSR_Selection. */ void run(double radius_ratio_bound=5, double beta= 0.52) @@ -1350,7 +1361,7 @@ namespace CGAL { returns the infinite floating value that prevents a facet to be used. */ - coord_type infinity() const { return std::numeric_limits::infinity(); } + FT infinity() const { return std::numeric_limits::infinity(); } /// @} //--------------------------------------------------------------------- @@ -2524,9 +2535,9 @@ namespace CGAL { \param out output iterator \param radius_ratio_bound candidates incident to surface triangles which are not in the beta-wedge are discarded, if the ratio of their radius and the radius of the surface triangle is larger than `radius_ratio_bound`. - Described in Section \ref AFSR_Boundaries + Described in Section \ref AFSR_Boundaries. \param beta half the angle of the wedge in which only the radius of triangles counts for the plausibility of candidates. - Described in Section \ref AFSR_Selection + Described in Section \ref AFSR_Selection. */ template @@ -2570,7 +2581,7 @@ namespace CGAL { be convertible to `Exact_predicates_inexact_constructions_kernel::Point_3` with the `Cartesian_converter`. \tparam IndicesOutputIterator must be an output iterator to which `std::array` can be assigned. - \tparam Priority must be a functor with `double operator()(AdvancingFront,Cell_handle,int)` returning the + \tparam Priority must be a functor with `double operator()(Advancing_front_surface_reconstruction,Cell_handle,int)` returning the priority of the facet `(Cell_handle,int)`. \param b iterator on the first point of the sequence From 6b87fe393d29451b72bf6e55fdb1b76ee8e83d53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Sat, 5 Dec 2020 11:11:33 +0100 Subject: [PATCH 064/248] Fix various grammar issues --- .../doc/Algebraic_foundations/CGAL/number_utils.h | 2 +- .../include/CGAL/Algebraic_kernel_d/Curve_analysis_2.h | 2 +- .../doc/Apollonius_graph_2/CGAL/Apollonius_graph_2.h | 2 +- .../CGAL/Apollonius_graph_hierarchy_2.h | 2 +- .../Arrangement_on_surface_2/Arrangement_on_surface_2.txt | 2 +- .../CGAL/Arr_polycurve_traits_2.h | 2 +- Arrangement_on_surface_2/include/CGAL/Arr_overlay_2.h | 2 +- .../CGAL/Arrangement_2/Arrangement_on_surface_2_impl.h | 2 +- .../include/CGAL/L1_voronoi_traits_2.h | 2 +- GraphicsView/include/CGAL/Qt/keyFrameInterpolator_impl.h | 2 +- Interpolation/TODO | 2 +- .../include/CGAL/Linear_cell_complex_constructors.h | 2 +- .../include/CGAL/Polygon_2/Polygon_2_algorithms_impl.h | 2 +- .../include/CGAL/internal/hypothesis.h | 2 +- .../demo/Polyhedron/Plugins/PMP/Hole_filling_plugin.cpp | 2 +- Polyhedron_IO/include/CGAL/IO/Polyhedron_scan_OFF.h | 2 +- STL_Extension/include/CGAL/Multiset.h | 2 +- .../doc/Spatial_sorting/CGAL/Multiscale_sort.h | 2 +- Spatial_sorting/include/CGAL/Hilbert_sort_median_d.h | 2 +- .../doc/Straight_skeleton_2/Straight_skeleton_2.txt | 2 +- .../include/CGAL/Straight_skeleton_builder_2.h | 2 +- Stream_support/include/CGAL/IO/write_3mf.h | 2 +- TDS_2/doc/TDS_2/TDS_2.txt | 2 +- Three/include/CGAL/Three/Scene_draw_interface.h | 8 ++++---- Triangulation_2/doc/Triangulation_2/Triangulation_2.txt | 2 +- 25 files changed, 28 insertions(+), 28 deletions(-) diff --git a/Algebraic_foundations/doc/Algebraic_foundations/CGAL/number_utils.h b/Algebraic_foundations/doc/Algebraic_foundations/CGAL/number_utils.h index f81aa3945c2..74d7c452e99 100644 --- a/Algebraic_foundations/doc/Algebraic_foundations/CGAL/number_utils.h +++ b/Algebraic_foundations/doc/Algebraic_foundations/CGAL/number_utils.h @@ -22,7 +22,7 @@ namespace CGAL { \ingroup PkgAlgebraicFoundationsRef The template function `compare()` compares the first argument with respect to -the second, i.e.\ it returns `CGAL::LARGER` if \f$ x\f$ is larger then \f$ y\f$. +the second, i.e.\ it returns `CGAL::LARGER` if \f$ x\f$ is larger than \f$ y\f$. In case the argument types `NT1` and `NT2` differ, `compare` is performed with the semantic of the type determined via diff --git a/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Curve_analysis_2.h b/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Curve_analysis_2.h index a0747b89dd2..f834448e65f 100644 --- a/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Curve_analysis_2.h +++ b/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Curve_analysis_2.h @@ -2007,7 +2007,7 @@ public: * * For each status line at an event and each status line that represents * an interval, all y-coordinates are approximated such that their - * isolating interval has absolute size smaller then \c precision. + * isolating interval has absolute size smaller than \c precision. */ void refine_all(Bound precision) { diff --git a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_2.h b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_2.h index c20ebc9846d..4f62df5899b 100644 --- a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_2.h +++ b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_2.h @@ -721,7 +721,7 @@ Checks the validity of the Apollonius graph. If `verbose` is is 0, only the data structure is validated. If `level` is 1, then both the data structure and the Apollonius graph are validated. Negative values of `level` always return true, and -values greater then 1 are equivalent to `level` being 1. +values greater than 1 are equivalent to `level` being 1. */ bool is_valid(bool verbose = false, int level = 1); diff --git a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_hierarchy_2.h b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_hierarchy_2.h index 24a11cebc80..b331d57fcef 100644 --- a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_hierarchy_2.h +++ b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_hierarchy_2.h @@ -209,7 +209,7 @@ is validated, as well as the inter-level pointers. If `level` is 1, then the data structure at all levels is validated, the inter-level pointers are validated and all levels of the Apollonius graph hierarchy are also validated. Negative values of `level` always -return `true`, and values greater then 1 are equivalent to +return `true`, and values greater than 1 are equivalent to `level` being 1. */ bool is_valid(bool verbose = false, int level = 1) const; diff --git a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/Arrangement_on_surface_2.txt b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/Arrangement_on_surface_2.txt index 1caa255411b..dcb07d711c0 100644 --- a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/Arrangement_on_surface_2.txt +++ b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/Arrangement_on_surface_2.txt @@ -3728,7 +3728,7 @@ of the general ones; e.g., `insert()`.
  • When the curves to be inserted into an arrangement are segments that are pairwise disjoint in their interior, it is more efficient to use -the traits class `Arr_non_caching_segment_traits_2` rather then +the traits class `Arr_non_caching_segment_traits_2` rather than the default one (`Arr_segment_traits_2`). If the segments may intersect each other, the default traits class diff --git a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_polycurve_traits_2.h b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_polycurve_traits_2.h index 16788a94596..99d4f50fbf4 100644 --- a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_polycurve_traits_2.h +++ b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_polycurve_traits_2.h @@ -408,7 +408,7 @@ namespace CGAL { size_type number_of_subcurves() const; /*! Obtain the \f$ k\f$th subcurve of the polycurve. - * \pre \f$k\f$ is not greater then or equal to \f$n-1\f$, where + * \pre \f$k\f$ is not greater than or equal to \f$n-1\f$, where * \f$n\f$ is the number of subcurves. */ typename SubcurveTraits_2::X_monotone_curve_2 diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_overlay_2.h b/Arrangement_on_surface_2/include/CGAL/Arr_overlay_2.h index 393958f3424..285faa4c183 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_overlay_2.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_overlay_2.h @@ -168,7 +168,7 @@ overlay(const Arrangement_on_surface_2& arr1 typedef Arrangement_on_surface_2 Arr_res; typedef typename Arr_res::Allocator Allocator; - // some type assertions (not all, but better then nothing). + // some type assertions (not all, but better than nothing). #if !defined(CGAL_NO_ASSERTIONS) typedef typename Agt2::Point_2 A_point; typedef typename Bgt2::Point_2 B_point; diff --git a/Arrangement_on_surface_2/include/CGAL/Arrangement_2/Arrangement_on_surface_2_impl.h b/Arrangement_on_surface_2/include/CGAL/Arrangement_2/Arrangement_on_surface_2_impl.h index 7b714c12412..eef9f3ba0a6 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arrangement_2/Arrangement_on_surface_2_impl.h +++ b/Arrangement_on_surface_2/include/CGAL/Arrangement_2/Arrangement_on_surface_2_impl.h @@ -4042,7 +4042,7 @@ _defines_outer_ccb_of_new_face(const DHalfedge* he_to, // - No smallest has bin recorded so far, or // - The current target vertex and the recorded vertex are the same and // * The current curve is smaller than the recorded curve, or - // - The current curve end is smaller then the recorded curve end. + // - The current curve end is smaller than the recorded curve end. // smaller than its source, so we should check whether it is also smaller // Note that we compare the vertices lexicographically: first by the // indices, then by x, then by y. diff --git a/GraphicsView/demo/L1_Voronoi_diagram_2/include/CGAL/L1_voronoi_traits_2.h b/GraphicsView/demo/L1_Voronoi_diagram_2/include/CGAL/L1_voronoi_traits_2.h index 91adae16d13..7b23ba84ef7 100644 --- a/GraphicsView/demo/L1_Voronoi_diagram_2/include/CGAL/L1_voronoi_traits_2.h +++ b/GraphicsView/demo/L1_Voronoi_diagram_2/include/CGAL/L1_voronoi_traits_2.h @@ -88,7 +88,7 @@ public: // Walk on the horizontal edge of the rectangle and then on the vertical. - // There is a chance that the width of the rectangle is smaller then the mid-dist. + // There is a chance that the width of the rectangle is smaller than the mid-dist. FT walk_x = (CGAL::min)(abs_x, dist); mid_x += sign_x * walk_x; dist -= walk_x; diff --git a/GraphicsView/include/CGAL/Qt/keyFrameInterpolator_impl.h b/GraphicsView/include/CGAL/Qt/keyFrameInterpolator_impl.h index 143a1b2175f..86acab83413 100644 --- a/GraphicsView/include/CGAL/Qt/keyFrameInterpolator_impl.h +++ b/GraphicsView/include/CGAL/Qt/keyFrameInterpolator_impl.h @@ -320,7 +320,7 @@ qreal KeyFrameInterpolator::keyFrameTime(int index) const { /*! Returns the duration of the KeyFrameInterpolator path, expressed in seconds. Simply corresponds to lastTime() - firstTime(). Returns 0.0 if the path has - less than 2 keyFrames. See also keyFrameTime(). */ + fewer than 2 keyFrames. See also keyFrameTime(). */ CGAL_INLINE_FUNCTION qreal KeyFrameInterpolator::duration() const { return lastTime() - firstTime(); diff --git a/Interpolation/TODO b/Interpolation/TODO index b1cde04626a..574426e92ef 100644 --- a/Interpolation/TODO +++ b/Interpolation/TODO @@ -181,6 +181,6 @@ long and hold to much information at once for a manual. For example: predicate you have to read at least twice before getting the meaning. More, but simpler sentences would do a lot, especially as people look up the manual on the web. Partly it just simply reads more like a -scientific paper then like a manual. +scientific paper than like a manual. =================== diff --git a/Linear_cell_complex/include/CGAL/Linear_cell_complex_constructors.h b/Linear_cell_complex/include/CGAL/Linear_cell_complex_constructors.h index c7cc340c51f..be2f3499208 100644 --- a/Linear_cell_complex/include/CGAL/Linear_cell_complex_constructors.h +++ b/Linear_cell_complex/include/CGAL/Linear_cell_complex_constructors.h @@ -207,7 +207,7 @@ namespace CGAL { std::cerr << " " << std::endl; std::cerr << "Polyhedron_scan_OFF::" << std::endl; std::cerr << "operator()(): input error: facet " << i - << " has less than 3 vertices." << std::endl; + << " has fewer than 3 vertices." << std::endl; } B.rollback(); in.clear( std::ios::badbit); diff --git a/Polygon/include/CGAL/Polygon_2/Polygon_2_algorithms_impl.h b/Polygon/include/CGAL/Polygon_2/Polygon_2_algorithms_impl.h index 431fa2effa0..8338ce335a2 100644 --- a/Polygon/include/CGAL/Polygon_2/Polygon_2_algorithms_impl.h +++ b/Polygon/include/CGAL/Polygon_2/Polygon_2_algorithms_impl.h @@ -519,7 +519,7 @@ Orientation orientation_2(ForwardIterator first, if (next == last) next = first; - // if the range [first,last) contains less than three points, then some + // if the range [first,last) contains fewer than three points, then some // of the points (prev,i,next) will coincide // return the orientation of the triple (prev,i,next) diff --git a/Polygonal_surface_reconstruction/include/CGAL/internal/hypothesis.h b/Polygonal_surface_reconstruction/include/CGAL/internal/hypothesis.h index af6a1cac0e5..ca4c3e6dca3 100644 --- a/Polygonal_surface_reconstruction/include/CGAL/internal/hypothesis.h +++ b/Polygonal_surface_reconstruction/include/CGAL/internal/hypothesis.h @@ -680,7 +680,7 @@ namespace CGAL { template void Hypothesis::compute_triplet_intersections() { triplet_intersections_.clear(); - if (supporting_planes_.size() < 4) // no closed surface will be constructed from less than 4 planes + if (supporting_planes_.size() < 4) // no closed surface will be constructed from fewer than 4 planes return; for (std::size_t i = 0; i < supporting_planes_.size(); ++i) { diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Hole_filling_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Hole_filling_plugin.cpp index ec1181416fb..935f073a6f4 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Hole_filling_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Hole_filling_plugin.cpp @@ -939,7 +939,7 @@ void Polyhedron_demo_hole_filling_plugin::hole_filling_polyline_action() { continue; } if(it->size() < 4) { // no triangle, skip it (needs at least 3 + 1 repeat) - print_message("Warning: skipping polyline which has less than 4 points!"); + print_message("Warning: skipping polyline which has fewer than 4 points!"); continue; } diff --git a/Polyhedron_IO/include/CGAL/IO/Polyhedron_scan_OFF.h b/Polyhedron_IO/include/CGAL/IO/Polyhedron_scan_OFF.h index 78b929a2356..d8c0e02be12 100644 --- a/Polyhedron_IO/include/CGAL/IO/Polyhedron_scan_OFF.h +++ b/Polyhedron_IO/include/CGAL/IO/Polyhedron_scan_OFF.h @@ -105,7 +105,7 @@ Polyhedron_scan_OFF:: operator()( HDS& target) { std::cerr << " " << std::endl; std::cerr << "Polyhedron_scan_OFF::" << std::endl; std::cerr << "operator()(): input error: facet " << i - << " has less than 3 vertices." << std::endl; + << " has fewer than 3 vertices." << std::endl; } B.rollback(); m_in.clear( std::ios::badbit); diff --git a/STL_Extension/include/CGAL/Multiset.h b/STL_Extension/include/CGAL/Multiset.h index 389880ded7c..5be3bc3b41c 100644 --- a/STL_Extension/include/CGAL/Multiset.h +++ b/STL_Extension/include/CGAL/Multiset.h @@ -1196,7 +1196,7 @@ public: /*! * Split the tree such that all remaining objects are less than a given - * key, and all objects greater then (or equal to) this key form + * key, and all objects greater than (or equal to) this key form * a new output tree. [takes O(log n) operations] * \param key The split key. * \param comp_key A comparison functor for comparing keys and objects. diff --git a/Spatial_sorting/doc/Spatial_sorting/CGAL/Multiscale_sort.h b/Spatial_sorting/doc/Spatial_sorting/CGAL/Multiscale_sort.h index e6f85f14238..acb46863901 100644 --- a/Spatial_sorting/doc/Spatial_sorting/CGAL/Multiscale_sort.h +++ b/Spatial_sorting/doc/Spatial_sorting/CGAL/Multiscale_sort.h @@ -8,7 +8,7 @@ Given a range of `n` points:
    1. it applies `Sort` on the last `(1 - ratio) * n` points,
    2. it recurses on the first `ratio * n` points, -stopping when there are less than `threshold` points. +stopping when there are fewer than `threshold` points.
    */ diff --git a/Spatial_sorting/include/CGAL/Hilbert_sort_median_d.h b/Spatial_sorting/include/CGAL/Hilbert_sort_median_d.h index df4c3858e5c..a88b3926006 100644 --- a/Spatial_sorting/include/CGAL/Hilbert_sort_median_d.h +++ b/Spatial_sorting/include/CGAL/Hilbert_sort_median_d.h @@ -114,7 +114,7 @@ public: current_dir = (current_dir +1) % _dimension; }while (current_dir != last_dir); - if ( end-begin < two_to_dim) return; // less than 2^dim points + if ( end-begin < two_to_dim) return; // fewer than 2^dim points /////////////start recursive calls last_dir = (direction + _dimension -1) % _dimension; diff --git a/Straight_skeleton_2/doc/Straight_skeleton_2/Straight_skeleton_2.txt b/Straight_skeleton_2/doc/Straight_skeleton_2/Straight_skeleton_2.txt index 9180253eda1..f795e14f2a3 100644 --- a/Straight_skeleton_2/doc/Straight_skeleton_2/Straight_skeleton_2.txt +++ b/Straight_skeleton_2/doc/Straight_skeleton_2/Straight_skeleton_2.txt @@ -266,7 +266,7 @@ If `Polygon_with_holes_2` is used, you can pass an instance of it directly to th \subsection Straight_skeleton_2CreateOffsetPolygonsfrom Create Offset Polygons from a Straight Skeleton -If you already have a straight skeleton instance, the simpler way to generate offset polygons is to call `create_offset_polygons_2()` as shown in the next example, passing the desired offset and the straight skeleton. You can reuse the same skeleton to generate offsets at a different distance, which is recommended because producing the straight skeleton is much slower then generating offset polygons. +If you already have a straight skeleton instance, the simpler way to generate offset polygons is to call `create_offset_polygons_2()` as shown in the next example, passing the desired offset and the straight skeleton. You can reuse the same skeleton to generate offsets at a different distance, which is recommended because producing the straight skeleton is much slower than generating offset polygons. \cgalExample{Straight_skeleton_2/Create_offset_polygons_2.cpp} diff --git a/Straight_skeleton_2/include/CGAL/Straight_skeleton_builder_2.h b/Straight_skeleton_2/include/CGAL/Straight_skeleton_builder_2.h index 894b39e5959..c111ae8ccac 100644 --- a/Straight_skeleton_2/include/CGAL/Straight_skeleton_builder_2.h +++ b/Straight_skeleton_2/include/CGAL/Straight_skeleton_builder_2.h @@ -1325,7 +1325,7 @@ public: } else { - CGAL_STSKEL_BUILDER_TRACE(0,"Degenerate contour (less than 3 non-degenerate vertices)."); + CGAL_STSKEL_BUILDER_TRACE(0,"Degenerate contour (fewer than 3 non-degenerate vertices)."); } } else diff --git a/Stream_support/include/CGAL/IO/write_3mf.h b/Stream_support/include/CGAL/IO/write_3mf.h index 8820cae5733..5c42cd00130 100644 --- a/Stream_support/include/CGAL/IO/write_3mf.h +++ b/Stream_support/include/CGAL/IO/write_3mf.h @@ -243,7 +243,7 @@ bool write_points(const PointRange& points, NMR::lib3mf_release(pModel); return false; } - //add 3 demmy vertices to be sure to have a valid triangle and accept point sets with less than 3 vertices. + //add 3 demmy vertices to be sure to have a valid triangle and accept point sets with fewer than 3 vertices. for(int i = 0; i< 3; ++i) pVertices.push_back(tmf_internal::fnCreateVertex(0,0,0)); for( auto point : points) diff --git a/TDS_2/doc/TDS_2/TDS_2.txt b/TDS_2/doc/TDS_2/TDS_2.txt index 79080f93963..2444eb1fb60 100644 --- a/TDS_2/doc/TDS_2/TDS_2.txt +++ b/TDS_2/doc/TDS_2/TDS_2.txt @@ -74,7 +74,7 @@ equivalent to a two-dimensional triangulated sphere. This rules extends to lower dimensional triangulation data structure arising in degenerate cases or when the triangulations -have less than three vertices. +have fewer than three vertices. A one dimensional triangulation structure maintains a set of vertices and edges which forms a ring topologically equivalent to a \f$ 1\f$-sphere. diff --git a/Three/include/CGAL/Three/Scene_draw_interface.h b/Three/include/CGAL/Three/Scene_draw_interface.h index d91fb6df0ec..3cfa580110e 100644 --- a/Three/include/CGAL/Three/Scene_draw_interface.h +++ b/Three/include/CGAL/Three/Scene_draw_interface.h @@ -63,13 +63,13 @@ public: * \return true if the TextItem is visible. */ virtual bool testDisplayId(double x, double y, double z, CGAL::Three::Viewer_interface* viewer) = 0; - ///\brief displays all the vertices ids if there are less than max_textItems. + ///\brief displays all the vertices ids if there are fewer than max_textItems. virtual void printVertexIds() = 0; - ///\brief displays all the edges ids if there are less than max_textItems. + ///\brief displays all the edges ids if there are fewer than max_textItems. virtual void printEdgeIds() = 0; - ///\brief displays all the faces ids if there are less than max_textItems. + ///\brief displays all the faces ids if there are fewer than max_textItems. virtual void printFaceIds() = 0; - ///\brief displays all the primitive ids if there are less than max_textItems. + ///\brief displays all the primitive ids if there are fewer than max_textItems. virtual void printAllIds() = 0; //!\brief moves the camera orthogonally to the picked face. diff --git a/Triangulation_2/doc/Triangulation_2/Triangulation_2.txt b/Triangulation_2/doc/Triangulation_2/Triangulation_2.txt index 009f3845620..37544f3f199 100644 --- a/Triangulation_2/doc/Triangulation_2/Triangulation_2.txt +++ b/Triangulation_2/doc/Triangulation_2/Triangulation_2.txt @@ -165,7 +165,7 @@ Infinite vertex and infinite faces This extends to lower dimensional triangulations arising in degenerate cases or when the triangulations -as less than three vertices. +has fewer than three vertices. Including the infinite faces, a one dimensional triangulation is a ring of edges and vertices From 55d93eac0fd73380f3f02aa7f52b59c133f7535f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Sat, 5 Dec 2020 11:13:35 +0100 Subject: [PATCH 065/248] Fix Weighted alpha shape trait concepts not appearing in ref manuals --- .../doc/Alpha_shapes_2/Concepts/WeightedAlphaShapeTraits_2.h | 2 +- Alpha_shapes_2/doc/Alpha_shapes_2/PackageDescription.txt | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Alpha_shapes_2/doc/Alpha_shapes_2/Concepts/WeightedAlphaShapeTraits_2.h b/Alpha_shapes_2/doc/Alpha_shapes_2/Concepts/WeightedAlphaShapeTraits_2.h index 6a7dab82f54..ad7070f9a42 100644 --- a/Alpha_shapes_2/doc/Alpha_shapes_2/Concepts/WeightedAlphaShapeTraits_2.h +++ b/Alpha_shapes_2/doc/Alpha_shapes_2/Concepts/WeightedAlphaShapeTraits_2.h @@ -45,7 +45,7 @@ typedef unspecified_type FT; /*! A default constructor. */ - AlphaShapeTraits_2(); + WeightedAlphaShapeTraits_2(); /// @} diff --git a/Alpha_shapes_2/doc/Alpha_shapes_2/PackageDescription.txt b/Alpha_shapes_2/doc/Alpha_shapes_2/PackageDescription.txt index d3d6f39d19a..4d777772e4b 100644 --- a/Alpha_shapes_2/doc/Alpha_shapes_2/PackageDescription.txt +++ b/Alpha_shapes_2/doc/Alpha_shapes_2/PackageDescription.txt @@ -70,6 +70,7 @@ finite number of different \f$ \alpha\f$-shapes and corresponding \cgalCRPSection{Concepts} - `AlphaShapeTraits_2` +- `WeightedAlphaShapeTraits_2` - `AlphaShapeFace_2` - `AlphaShapeVertex_2` From f4300bbacd57b89fcf4b04e7f66186163c3463a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Sat, 5 Dec 2020 11:20:26 +0100 Subject: [PATCH 066/248] Add some missing const / references in documentations --- .../CGAL/Apollonius_graph_2.h | 109 ++++++++---------- .../CGAL/Apollonius_graph_hierarchy_2.h | 27 ++--- ...Apollonius_graph_hierarchy_vertex_base_2.h | 4 +- .../CGAL/Apollonius_graph_traits_2.h | 5 +- .../CGAL/Apollonius_graph_vertex_base_2.h | 4 +- .../CGAL/Apollonius_site_2.h | 11 +- .../CGAL/Segment_Delaunay_graph_2.h | 33 +++--- 7 files changed, 88 insertions(+), 105 deletions(-) diff --git a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_2.h b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_2.h index 4f62df5899b..6e2db82065d 100644 --- a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_2.h +++ b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_2.h @@ -261,63 +261,62 @@ operator=(const Apollonius_graph_2& other); /*! Returns a reference to the Apollonius graph traits object. */ -Geom_traits geom_traits(); +const Geom_traits& geom_traits() const; /*! Returns a reference to the underlying data structure. */ -Data_structure data_structure(); +const Data_structure& data_structure() const; /*! Same as `data_structure()`. This method has been added in compliance with the `DelaunayGraph_2` concept. */ -Data_structure tds(); +const Data_structure& tds() const; /*! Returns the dimension of the Apollonius graph. */ -int dimension(); +int dimension() const; /*! Returns the number of finite vertices. */ -size_type number_of_vertices(); +size_type number_of_vertices() const; /*! Returns the number of visible sites. */ -size_type number_of_visible_sites(); +size_type number_of_visible_sites() const; /*! Returns the number of hidden sites. */ -size_type number_of_hidden_sites(); +size_type number_of_hidden_sites() const; /*! Returns the number of faces (both finite and infinite) of the Apollonius graph. */ -size_type number_of_faces(); +size_type number_of_faces() const; /*! Returns a face incident to the `infinite_vertex`. */ -Face_handle infinite_face(); +Face_handle infinite_face() const; /*! Returns the `infinite_vertex`. */ -Vertex_handle -infinite_vertex(); +Vertex_handle infinite_vertex() const; /*! Returns a vertex distinct from the `infinite_vertex`. \pre The number of (visible) vertices in the Apollonius graph must be at least one. */ -Vertex_handle finite_vertex(); +Vertex_handle finite_vertex() const; /// @} @@ -337,63 +336,62 @@ Vertex_handle finite_vertex(); /*! Starts at an arbitrary finite vertex. */ -Finite_vertices_iterator finite_vertices_begin(); +Finite_vertices_iterator finite_vertices_begin() const; /*! Past-the-end iterator. */ -Finite_vertices_iterator finite_vertices_end(); +Finite_vertices_iterator finite_vertices_end() const; /*! Starts at an arbitrary finite edge. */ -Finite_edges_iterator finite_edges_begin(); +Finite_edges_iterator finite_edges_begin() const; /*! Past-the-end iterator. */ -Finite_edges_iterator finite_edges_end(); +Finite_edges_iterator finite_edges_end() const; /*! Starts at an arbitrary finite face. */ -Finite_faces_iterator finite_faces_begin(); +Finite_faces_iterator finite_faces_begin() const; /*! Past-the-end iterator. */ -Finite_faces_iterator finite_faces_end() -const; +Finite_faces_iterator finite_faces_end() const; /*! Starts at an arbitrary vertex. */ -All_vertices_iterator all_vertices_begin(); +All_vertices_iterator all_vertices_begin() const; /*! Past-the-end iterator. */ -All_vertices_iterator all_vertices_end(); +All_vertices_iterator all_vertices_end() const; /*! Starts at an arbitrary edge. */ -All_edges_iterator all_edges_begin(); +All_edges_iterator all_edges_begin() const; /*! Past-the-end iterator. */ -All_edges_iterator all_edges_end(); +All_edges_iterator all_edges_end() const; /*! Starts at an arbitrary face. */ -All_faces_iterator all_faces_begin(); +All_faces_iterator all_faces_begin() const; /*! Past-the-end iterator. */ -All_faces_iterator all_faces_end(); +All_faces_iterator all_faces_end() const; /// @} @@ -407,32 +405,32 @@ All_faces_iterator all_faces_end(); /*! Starts at an arbitrary site. */ -Sites_iterator sites_begin(); +Sites_iterator sites_begin() const; /*! Past-the-end iterator. */ -Sites_iterator sites_end(); +Sites_iterator sites_end() const; /*! Starts at an arbitrary visible site. */ -Visible_sites_iterator visible_sites_begin(); +Visible_sites_iterator visible_sites_begin() const; /*! Past-the-end iterator. */ -Visible_sites_iterator visible_sites_end(); +Visible_sites_iterator visible_sites_end() const; /*! Starts at an arbitrary hidden site. */ -Hidden_sites_iterator hidden_sites_begin(); +Hidden_sites_iterator hidden_sites_begin() const; /*! Past-the-end iterator. */ -Hidden_sites_iterator hidden_sites_end(); +Hidden_sites_iterator hidden_sites_end() const; /// @} @@ -454,39 +452,39 @@ Hidden_sites_iterator hidden_sites_end(); Starts at an arbitrary face incident to `v`. */ -Face_circulator incident_faces(Vertex_handle v); +Face_circulator incident_faces(Vertex_handle v) const; /*! Starts at face `f`. \pre Face `f` is incident to vertex `v`. */ -Face_circulator incident_faces(Vertex_handle v, Face_handle f); +Face_circulator incident_faces(Vertex_handle v, Face_handle f) const; /*! Starts at an arbitrary edge incident to `v`. */ -Edge_circulator incident_edges(Vertex_handle v); +Edge_circulator incident_edges(Vertex_handle v) const; /*! Starts at the first edge of `f` incident to `v`, in counterclockwise order around `v`. \pre Face `f` is incident to vertex `v`. */ -Edge_circulator incident_edges(Vertex_handle v, Face_handle f); +Edge_circulator incident_edges(Vertex_handle v, Face_handle f) const; /*! Starts at an arbitrary vertex incident to `v`. */ -Vertex_circulator incident_vertices(Vertex_handle v); +Vertex_circulator incident_vertices(Vertex_handle v) const; /*! Starts at the first vertex of `f` adjacent to `v` in counterclockwise order around `v`. \pre Face `f` is incident to vertex `v`. */ -Vertex_circulator incident_vertices(Vertex_handle v, Face_handle f); +Vertex_circulator incident_vertices(Vertex_handle v, Face_handle f) const; /// @} @@ -516,7 +514,7 @@ bool is_infinite(Face_handle f, int i) const; `true`, iff edge `e` is infinite. */ bool -is_infinite(Edge e) const; +is_infinite(const Edge& e) const; /*! `true`, iff edge `*ec` is infinite. @@ -544,7 +542,7 @@ site `s` in the Apollonius graph. If `s` is visible then the vertex handle of `s` is returned, otherwise `Vertex_handle(nullptr)` is returned. */ -Vertex_handle insert(Site_2 s); +Vertex_handle insert(const Site_2& s); /*! Inserts `s` in the Apollonius graph using the site @@ -553,8 +551,7 @@ the center of `s`. If `s` is visible then the vertex handle of `s` is returned, otherwise `Vertex_handle(nullptr)` is returned. */ -Vertex_handle insert(Site_2 s, Vertex_handle -vnear); +Vertex_handle insert(const Site_2& s, Vertex_handle vnear); /// @} @@ -581,7 +578,7 @@ arbitrarily and one of the nearest neighbors of `p` is returned. If there are no visible sites in the Apollonius diagram `Vertex_handle(nullptr)` is returned. */ -Vertex_handle nearest_neighbor(Point_2 p); +Vertex_handle nearest_neighbor(const Point_2& p) const; /*! Finds the nearest neighbor of the point @@ -591,8 +588,7 @@ arbitrarily and one of the nearest neighbors of `p` is returned. If there are no visible sites in the Apollonius diagram `Vertex_handle(nullptr)` is returned. */ -Vertex_handle nearest_neighbor(Point_2 p, -Vertex_handle vnear); +Vertex_handle nearest_neighbor(const Point_2& p, Vertex_handle vnear) const; /// @} @@ -645,7 +641,7 @@ the stream `str`. */ template< class Stream > -Stream& draw_primal(Stream& str); +Stream& draw_primal(Stream& str) const; /*! Draws the dual of the @@ -658,7 +654,7 @@ Apollonius graph, i.e., the Apollonius diagram, to the stream */ template < class Stream > -Stream& draw_dual(Stream& str); +Stream& draw_dual(Stream& str) const; /*! Draws the edge @@ -669,7 +665,7 @@ Draws the edge */ template< class Stream > -Stream& draw_primal_edge(Edge e, Stream& str); +Stream& draw_primal_edge(const Edge& e, Stream& str) const; /*! Draws the dual of the @@ -682,7 +678,7 @@ of the Apollonius diagram. */ template< class Stream > -Stream& draw_dual_edge(Edge e, Stream& str); +Stream& draw_dual_edge(const Edge& e, Stream& str) const; /*! Writes the current @@ -690,7 +686,7 @@ state of the Apollonius graph to an output stream. In particular, all visible and hidden sites are written as well as the underlying combinatorial data structure. */ -void file_output(std::ostream& os); +void file_output(std::ostream& os) const; /*! Reads the state of the @@ -701,14 +697,12 @@ void file_input(std::istream& is); /*! Writes the current state of the Apollonius graph to an output stream. */ -std::ostream& operator<<(std::ostream& os, -Apollonius_graph_2 ag); +std::ostream& operator<<(std::ostream& os, const Apollonius_graph_2& ag) const; /*! Reads the state of the Apollonius graph from an input stream. */ -std::istream& operator>>(std::istream& is, -Apollonius_graph_2 ag); +std::istream& operator>>(std::istream& is, const Apollonius_graph_2& ag); /// @} @@ -723,7 +717,7 @@ both the data structure and the Apollonius graph are validated. Negative values of `level` always return true, and values greater than 1 are equivalent to `level` being 1. */ -bool is_valid(bool verbose = false, int level = 1); +bool is_valid(bool verbose = false, int level = 1) const; /// @} @@ -737,12 +731,11 @@ void clear(); /*! The Apollonius graphs -`other` and `ag` are swapped. `ag`.`swap(other)` should -be preferred to `ag`` = other` or to `ag``(other)` if +`other` and `ag` are swapped. `ag.swap(other)` should +be preferred to `ag = other` or to `ag(other)` if `other` is deleted afterwards. */ -void swap(Apollonius_graph_2 -other); +void swap(Apollonius_graph_2& other); /// @} diff --git a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_hierarchy_2.h b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_hierarchy_2.h index b331d57fcef..742a7c14742 100644 --- a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_hierarchy_2.h +++ b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_hierarchy_2.h @@ -61,8 +61,7 @@ public: Creates an hierarchy of Apollonius graphs using `gt` as geometric traits. */ -Apollonius_graph_hierarchy_2(Gt -gt=Gt()); +Apollonius_graph_hierarchy_2(Gt gt=Gt()); /*! Creates an Apollonius graph hierarchy using @@ -79,8 +78,7 @@ are duplicated. After the construction, `agh` and `other` refer to two different Apollonius graph hierarchies: if `other` is modified, `agh` is not. */ -Apollonius_graph_hierarchy_2 -(Apollonius_graph_hierarchy_2 other); +Apollonius_graph_hierarchy_2(const Apollonius_graph_hierarchy_2& other); /*! Assignment. All faces, vertices and inter-level pointers @@ -112,7 +110,7 @@ site `s` in the Apollonius graph hierarchy. If `s` is visible then the vertex handle of `s` is returned, otherwise `Vertex_handle(nullptr)` is returned. */ -Vertex_handle insert(Site_2 s); +Vertex_handle insert(const Site_2& s); /*! Inserts `s` in the Apollonius graph hierarchy using the @@ -124,8 +122,7 @@ A call to this method is equivalent to `agh.insert(s);` and it has been added for the sake of conformity with the interface of the `Apollonius_graph_2` class. */ -Vertex_handle insert(Site_2 s, Vertex_handle -vnear); +Vertex_handle insert(const Site_2& s, Vertex_handle vnear); /// @} @@ -152,7 +149,7 @@ arbitrarily and one of the nearest neighbors of `p` is returned. If there are no visible sites in the Apollonius diagram `Vertex_handle(nullptr)` is returned. */ -Vertex_handle nearest_neighbor(Point p); +Vertex_handle nearest_neighbor(const Point_2& p) const; /*! Finds the nearest neighbor of the point @@ -163,8 +160,7 @@ A call to this method is equivalent to conformity with the interface of the `Apollonius_graph_2` class. */ -Vertex_handle nearest_neighbor(Point p, -Vertex_handle vnear); +Vertex_handle nearest_neighbor(const Point_2& p, Vertex_handle vnear) const; /// @} @@ -177,7 +173,7 @@ state of the Apollonius graph hierarchy to an output stream. In particular, all visible and hidden sites are written as well as the underlying combinatorial hierarchical data structure. */ -void file_output(std::ostream& os); +void file_output(std::ostream& os) const; /*! Reads the state of the @@ -189,7 +185,7 @@ void file_input(std::istream& is); Writes the current state of the Apollonius graph hierarchy to an output stream. */ -std::ostream& operator<<(std::ostream& os, Apollonius_graph_hierarchy_2 agh); +std::ostream& operator<<(std::ostream& os, Apollonius_graph_hierarchy_2 agh) const; /*! Reads the state of the Apollonius graph hierarchy from an input stream. @@ -227,11 +223,10 @@ void clear(); /*! The Apollonius graph hierarchies `other` and `agh` are -swapped. `agh`.`swap(other)` should be preferred to `agh`` = -other` or to `agh``(other)` if `other` is deleted afterwards. +swapped. `agh.swap(other)` should be preferred to `agh = other` +or to `agh(other)` if `other` is deleted afterwards. */ -void swap(Apollonius_graph_hierarchy_2 -other); +void swap(Apollonius_graph_hierarchy_2& other); /// @} diff --git a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_hierarchy_vertex_base_2.h b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_hierarchy_vertex_base_2.h index 3d6bc26db21..354dd734e8b 100644 --- a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_hierarchy_vertex_base_2.h +++ b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_hierarchy_vertex_base_2.h @@ -34,7 +34,7 @@ Apollonius_graph_hierarchy_vertex_base_2(); Constructs a vertex associated with the site `s` and embedded at the center of `s`. */ -Apollonius_graph_hierarchy_vertex_base_2(Site_2 s); +Apollonius_graph_hierarchy_vertex_base_2(const Site_2& s); /*! Constructs a vertex associated with @@ -42,7 +42,7 @@ the site `s`, embedded at the center of `s`, and pointing to the face associated with the face handle `f`. */ -Apollonius_graph_vertex_base_2(Site_2 s, Face_handle f); +Apollonius_graph_hierarchy_vertex_base_2(const Site_2& s, Face_handle f); /// @} diff --git a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_traits_2.h b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_traits_2.h index ae347df1437..091a2cb8f00 100644 --- a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_traits_2.h +++ b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_traits_2.h @@ -45,14 +45,13 @@ Apollonius_graph_traits_2(); /*! Copy constructor. */ -Apollonius_graph_traits_2(Apollonius_graph_traits_2 other); +Apollonius_graph_traits_2(const Apollonius_graph_traits_2& other); /*! Assignment operator. */ Apollonius_graph_traits_2 -operator=(Apollonius_graph_traits_2 -other); +operator=(const Apollonius_graph_traits_2& other); /// @} diff --git a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_vertex_base_2.h b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_vertex_base_2.h index a4ba4a49194..75bf5137d3d 100644 --- a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_vertex_base_2.h +++ b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_vertex_base_2.h @@ -43,7 +43,7 @@ Apollonius_graph_bertex_base_2(); Constructs a vertex associated with the site `s` and embedded at the center of `s`. */ -Apollonius_graph_vertex_base_2(Site_2 s); +Apollonius_graph_vertex_base_2(const Site_2& s); /*! Constructs a vertex associated with @@ -51,7 +51,7 @@ the site `s`, embedded at the center of `s`, and pointing to the face associated with the face handle `f`. */ -Apollonius_graph_vertex_base_2(Site_2 s, Face_handle f); +Apollonius_graph_vertex_base_2(const Site_2& s, Face_handle f); /// @} diff --git a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_site_2.h b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_site_2.h index 03bee290f37..30de7481481 100644 --- a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_site_2.h +++ b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_site_2.h @@ -44,7 +44,7 @@ Apollonius_site_2(Point_2 p=Point_2(), Weight w= Weight(0)); /*! Copy constructor. */ -Apollonius_site_2(Apollonius_site_2 other); +Apollonius_site_2(const Apollonius_site_2& other); /// @} @@ -57,8 +57,7 @@ Apollonius site `s` into the stream `os`. \pre The insert operator must be defined for `Point_2` and `Weight`. \relates Apollonius_site_2 */ -std::ostream& operator<<(std::ostream& os, -const Apollonius_site_2& s); +std::ostream& operator<<(std::ostream& os, const Apollonius_site_2& s) const; /*! Reads an Apollonius site from the stream `is` and assigns it @@ -67,8 +66,7 @@ to `s`. \pre The extract operator must be defined for `Point_2` and `Weight`. \relates Apollonius_site_2 */ -std::istream& operator>>(std::istream& is, -const Apollonius_site_2& s); +std::istream& operator>>(std::istream& is, const Apollonius_site_2& s); /*! Inserts the Apollonius site `s` into the `Qt_widget` stream `w`. @@ -76,7 +74,6 @@ Inserts the Apollonius site `s` into the `Qt_widget` stream `w`. \pre The insert operator must be defined for `K::Circle_2`. \relates Apollonius_site_2 */ -Qt_widget& operator<<(Qt_widget& w, -const Apollonius_site_2& s); +Qt_widget& operator<<(Qt_widget& w, const Apollonius_site_2& s) const; } /* end namespace CGAL */ diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_2.h b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_2.h index 9aa16d3a72c..388f9eed77b 100644 --- a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_2.h +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_2.h @@ -324,33 +324,32 @@ Point_container point_container(); /*! Starts at an arbitrary finite vertex. */ -Finite_vertices_iterator finite_vertices_begin(); +Finite_vertices_iterator finite_vertices_begin() const; /*! Past-the-end iterator. */ -Finite_vertices_iterator finite_vertices_end(); +Finite_vertices_iterator finite_vertices_end() const; /*! Starts at an arbitrary finite edge. */ -Finite_edges_iterator finite_edges_begin(); +Finite_edges_iterator finite_edges_begin() const; /*! Past-the-end iterator. */ -Finite_edges_iterator finite_edges_end(); +Finite_edges_iterator finite_edges_end() const; /*! Starts at an arbitrary finite face. */ -Finite_faces_iterator finite_faces_begin(); +Finite_faces_iterator finite_faces_begin() const; /*! Past-the-end iterator. */ -Finite_faces_iterator finite_faces_end() -const; +Finite_faces_iterator finite_faces_end() const; /// @} @@ -366,32 +365,32 @@ const; /*! Starts at an arbitrary vertex. */ -All_vertices_iterator all_vertices_begin(); +All_vertices_iterator all_vertices_begin() const; /*! Past-the-end iterator. */ -All_vertices_iterator all_vertices_end(); +All_vertices_iterator all_vertices_end() const; /*! Starts at an arbitrary edge. */ -All_edges_iterator all_edges_begin(); +All_edges_iterator all_edges_begin() const; /*! Past-the-end iterator. */ -All_edges_iterator all_edges_end(); +All_edges_iterator all_edges_end() const; /*! Starts at an arbitrary face. */ -All_faces_iterator all_faces_begin(); +All_faces_iterator all_faces_begin() const; /*! Past-the-end iterator. */ -All_faces_iterator all_faces_end(); +All_faces_iterator all_faces_end() const; /// @} @@ -405,22 +404,22 @@ All_faces_iterator all_faces_end(); /*! Starts at an arbitrary input site. */ -Input_sites_iterator input_sites_begin(); +Input_sites_iterator input_sites_begin() const; /*! Past-the-end iterator. */ -Input_sites_iterator input_sites_end(); +Input_sites_iterator input_sites_end() const; /*! Starts at an arbitrary output site. */ -Output_sites_iterator output_sites_begin(); +Output_sites_iterator output_sites_begin() const; /*! Past-the-end iterator. */ -Output_sites_iterator output_sites_end(); +Output_sites_iterator output_sites_end() const; /// @} From 702d2ddf863ab2d3f38a3bae3b8434b8fb8b8a5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Sat, 5 Dec 2020 11:42:21 +0100 Subject: [PATCH 067/248] Fix documentation of TDS vertex/face/cell requirements in TDS-using classes --- .../doc/Alpha_shapes_2/Alpha_shapes_2.txt | 5 ++- .../doc/Alpha_shapes_3/Alpha_shapes_3.txt | 8 ++--- .../CGAL/Apollonius_graph_2.h | 22 ++++++++----- .../CGAL/Apollonius_graph_hierarchy_2.h | 32 +++++++++---------- .../Hyperbolic_Delaunay_triangulation_2.h | 16 ++++++---- .../Hyperbolic_triangulation_2.txt | 8 ++--- .../doc/Mesh_2/CGAL/lloyd_optimize_mesh_2.h | 4 +-- .../Periodic_2_Delaunay_triangulation_2.h | 19 ++++++----- .../CGAL/Periodic_2_triangulation_2.h | 27 +++++++--------- .../CGAL/Periodic_2_triangulation_traits_2.h | 3 +- .../Periodic_2_triangulation_2.txt | 17 +++++----- .../Periodic_3_Delaunay_triangulation_3.h | 11 +++++-- .../CGAL/Periodic_3_regular_triangulation_3.h | 15 ++++++--- .../CGAL/Periodic_3_triangulation_3.h | 16 ++++++---- .../Periodic_3_triangulation_3.txt | 20 +++++------- ...ic_4_hyperbolic_Delaunay_triangulation_2.h | 8 +++-- .../Periodic_4_hyperbolic_triangulation_2.h | 9 +++--- .../Periodic_4_hyperbolic_triangulation_2.txt | 9 +++--- .../CGAL/Segment_Delaunay_graph_2.h | 21 +++++++++--- 19 files changed, 151 insertions(+), 119 deletions(-) diff --git a/Alpha_shapes_2/doc/Alpha_shapes_2/Alpha_shapes_2.txt b/Alpha_shapes_2/doc/Alpha_shapes_2/Alpha_shapes_2.txt index 545d92b3924..251b466a0da 100644 --- a/Alpha_shapes_2/doc/Alpha_shapes_2/Alpha_shapes_2.txt +++ b/Alpha_shapes_2/doc/Alpha_shapes_2/Alpha_shapes_2.txt @@ -134,9 +134,8 @@ All \cgal kernels are models of both concepts. The triangulation data structure of the triangulation has to be a model of the concept `TriangulationDataStructure_2`, -and it must be parameterized with -vertex and face classes which are models of the concepts -`AlphaShapeVertex_2` and `AlphaShapeFace_2`. +whose vertex and face classes are models of the concepts +`AlphaShapeVertex_2` and `AlphaShapeFace_2`, respectively. The classes `Alpha_shape_vertex_base_2` and `Alpha_shape_face_base_2` are models of these concepts and can be used for all type of alpha shapes, provided that the template parameters `Vb` and `Fb` are appropriately chosen, diff --git a/Alpha_shapes_3/doc/Alpha_shapes_3/Alpha_shapes_3.txt b/Alpha_shapes_3/doc/Alpha_shapes_3/Alpha_shapes_3.txt index 149e60567ad..45178678ee6 100644 --- a/Alpha_shapes_3/doc/Alpha_shapes_3/Alpha_shapes_3.txt +++ b/Alpha_shapes_3/doc/Alpha_shapes_3/Alpha_shapes_3.txt @@ -215,8 +215,8 @@ in the non-weighted case and `WeightedAlphaShapeTraits_3` in the weighted case. All \cgal kernels are models of both concepts. The triangulation data structure of the triangulation -has to be a model of the concept `TriangulationDataStructure_3`, -and it must be parameterized with vertex and cell classes, which are model of the concepts +has to be a model of the concept `TriangulationDataStructure_3` +whose vertex and cell classes are model of the concepts `AlphaShapeVertex_3` and `AlphaShapeCell_3`. The classes `Alpha_shape_vertex_base_3` and `Alpha_shape_cell_base_3` are models of these concepts and can be used for all type of alpha shapes, @@ -230,8 +230,8 @@ the traits class are described in the concepts `FixedAlphaShapeTraits_3` in the non-weighted case and `FixedWeightedAlphaShapeTraits_3` in the weighted case. All \cgal kernels are models of both concepts. The triangulation data structure of the triangulation -has to be a model of the concept `TriangulationDataStructure_3`, -and it must be parameterized with vertex and cell classes, which are model of the concepts +has to be a model of the concept `TriangulationDataStructure_3` +whose vertex and cell classes are model of the concepts `FixedAlphaShapeVertex_3` and `FixedAlphaShapeCell_3`. The package provides models `Fixed_alpha_shape_vertex_base_3` and `Fixed_alpha_shape_cell_base_3`, respectively. diff --git a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_2.h b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_2.h index 6e2db82065d..172eb125a0f 100644 --- a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_2.h +++ b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_2.h @@ -4,14 +4,20 @@ namespace CGAL { /*! \ingroup PkgApolloniusGraph2Ref -The class `Apollonius_graph_2` represents the -Apollonius graph. It supports insertions and deletions of sites. -It is templated by two template arguments `Gt`, which -must be a model of `ApolloniusGraphTraits_2`, and `Agds`, -which must be a model of `ApolloniusGraphDataStructure_2`. -The second template argument defaults to -`CGAL::Triangulation_data_structure_2< CGAL::Apollonius_graph_vertex_base_2, CGAL::Triangulation_face_base_2 >`. -\cgalModels `DelaunayGraph_2` +The class `Apollonius_graph_2` represents the Apollonius graph. +It supports insertions and deletions of sites. + +\tparam Gt is the geometric traits class and must be a model of `ApolloniusGraphTraits_2`. + +\tparam Agds is the Apollonius graph data structure and must be a model of `ApolloniusGraphDataStructure_2` +whose vertex and face must be models of `ApolloniusGraphVertexBase_2` and `TriangulationFaceBase_2`, +respectively. +It defaults to: +\code + CGAL::Triangulation_data_structure_2< + CGAL::Apollonius_graph_vertex_base_2, + CGAL::Triangulation_face_base_2 >` +\endcode \cgalHeading{Traversal of the Apollonius Graph} diff --git a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_hierarchy_2.h b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_hierarchy_2.h index 742a7c14742..4805d085632 100644 --- a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_hierarchy_2.h +++ b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_hierarchy_2.h @@ -19,36 +19,34 @@ find the nearest neighbor of \f$ p\f$ as in the we use the nearest neighbor found at level \f$ i+1\f$ to find the nearest neighbor at level \f$ i\f$. This is a variant of the corresponding hierarchy for points found in \cgalCite{d-iirdt-98}. + The class has two template parameters which have essentially the same -meaning as in the `Apollonius_graph_2` class. The first -template parameter must be a model of the -`ApolloniusGraphTraits_2` concept. -The second template parameter must be a model of the -`ApolloniusGraphDataStructure_2` concept. However, the vertex base -class that is to be used in the Apollonius graph data structure must -be a model of the `ApolloniusGraphHierarchyVertexBase_2` concept. -The second template parameter defaults to -`Triangulation_data_structure_2< Apollonius_graph_hierarchy_vertex_base_2< Apollonius_graph_vertex_base_2 >, Triangulation_face_base_2 >`. +meaning as in the `Apollonius_graph_2` class. + +\tparam Gt is the geometric traits class and must be a model of `ApolloniusGraphTraits_2`. + +\tparam Agds is the Apollonius graph data structure and must be a model of `ApolloniusGraphDataStructure_2` +whose vertex and face must be models of `ApolloniusGraphHierarchyVertexBase_2` and `TriangulationFaceBase_2`, respectively. +It defaults to: +\code + CGAL::Triangulation_data_structure_2< + CGAL::Apollonius_graph_hierarchy_vertex_base_2 >, + CGAL::Triangulation_face_base_2 > +\endcode + +\cgalHeading{Heritage} The `Apollonius_graph_hierarchy_2` class derives publicly from the `Apollonius_graph_2` class. The interface is the same with its base class. In the sequel only the methods overridden are documented. -\cgalHeading{Types} - `Apollonius_graph_hierarchy_2` does not introduce other types than those introduced by its base class `Apollonius_graph_2`. -\sa `ApolloniusGraphDataStructure_2` -\sa `ApolloniusGraphTraits_2` -\sa `ApolloniusGraphHierarchyVertexBase_2` \sa `CGAL::Apollonius_graph_2` -\sa `CGAL::Triangulation_data_structure_2` \sa `CGAL::Apollonius_graph_traits_2` \sa `CGAL::Apollonius_graph_filtered_traits_2` -\sa `CGAL::Apollonius_graph_hierarchy_vertex_base_2` - */ template< typename Gt, typename Agds > class Apollonius_graph_hierarchy_2 : public CGAL::Apollonius_graph_2 { diff --git a/Hyperbolic_triangulation_2/doc/Hyperbolic_triangulation_2/CGAL/Hyperbolic_Delaunay_triangulation_2.h b/Hyperbolic_triangulation_2/doc/Hyperbolic_triangulation_2/CGAL/Hyperbolic_Delaunay_triangulation_2.h index c07639e7c08..e91823b0dae 100644 --- a/Hyperbolic_triangulation_2/doc/Hyperbolic_triangulation_2/CGAL/Hyperbolic_Delaunay_triangulation_2.h +++ b/Hyperbolic_triangulation_2/doc/Hyperbolic_triangulation_2/CGAL/Hyperbolic_Delaunay_triangulation_2.h @@ -11,16 +11,18 @@ The class `Hyperbolic_Delaunay_triangulation_2` is the main class of the 2D Hype It is designed to represent Delaunay triangulations of sets of points in the hyperbolic plane. The hyperbolic plane is represented in the Poincaré disk model. -\tparam Gt must be a model of `HyperbolicDelaunayTriangulationTraits_2`. -\tparam Tds must be a model of `TriangulationDataStructure_2`. By default, this parameter is instantiated with -`Triangulation_data_structure_2< Triangulation_vertex_base_2, Hyperbolic_triangulation_face_base_2 >` +\tparam Gt is the geometric traits class and must be a model of `HyperbolicDelaunayTriangulationTraits_2`. +\tparam Tds is the triangulation graph data structure and must be a model of `TriangulationDataStructure_2` +whose vertex and face are models of `TriangulationVertexBase_2` and `HyperbolicTriangulationFaceBase_2`, respectively. +It defaults to: +\code +CGAL::Triangulation_data_structure_2< + CGAL::Triangulation_vertex_base_2, + CGAL::Hyperbolic_triangulation_face_base_2 > +\endcode -\sa `HyperbolicDelaunayTriangulationTraits_2` -\sa `TriangulationDataStructure_2` \sa `Delaunay_triangulation_2` - */ - template < class Gt, class Tds > class Hyperbolic_Delaunay_triangulation_2: private Delaunay_triangulation_2 { diff --git a/Hyperbolic_triangulation_2/doc/Hyperbolic_triangulation_2/Hyperbolic_triangulation_2.txt b/Hyperbolic_triangulation_2/doc/Hyperbolic_triangulation_2/Hyperbolic_triangulation_2.txt index 6c29153fc50..6ef7fadd068 100644 --- a/Hyperbolic_triangulation_2/doc/Hyperbolic_triangulation_2/Hyperbolic_triangulation_2.txt +++ b/Hyperbolic_triangulation_2/doc/Hyperbolic_triangulation_2/Hyperbolic_triangulation_2.txt @@ -104,11 +104,11 @@ parameters: primitives. The requirements on this first template parameter are described by the concept `HyperbolicDelaunayTriangulationTraits_2`, which refines - `DelaunayTriangulationTraits_2`. + `DelaunayTriangulationTraits_2`.
  • A triangulation data structure parameter, for which the - requirements are described by the concept - `TriangulationDataStructure_2`. The default for this second template parameter - is `Triangulation_data_structure_2< Triangulation_vertex_base_2, Hyperbolic_triangulation_face_base_2 >`. + requirements are described by the concept `TriangulationDataStructure_2`. + The vertex and face of this triangulation data structure must be models of + the concepts `TriangulationVertexBase_2` and `HyperbolicTriangulationFaceBase_2`, respectively.
  • Two models of the concept `HyperbolicDelaunayTriangulationTraits_2` diff --git a/Mesh_2/doc/Mesh_2/CGAL/lloyd_optimize_mesh_2.h b/Mesh_2/doc/Mesh_2/CGAL/lloyd_optimize_mesh_2.h index 908541e6a88..eab3ad645ab 100644 --- a/Mesh_2/doc/Mesh_2/CGAL/lloyd_optimize_mesh_2.h +++ b/Mesh_2/doc/Mesh_2/CGAL/lloyd_optimize_mesh_2.h @@ -19,8 +19,8 @@ and the Delaunay triangulation is updated. Vertices on the mesh boundaries are not moved. \tparam CDT is required to be or derive from `CGAL::Constrained_Delaunay_triangulation_2`, -with vertex base and face base of its underlying `TriangulationDataStructure_2` -respectively implementing the concepts `DelaunayMeshFaceBase_2` and `DelaunayMeshVertexBase_2`. +with vertex base and face base of its underlying `TriangulationDataStructure_2` +being models of `DelaunayMeshVertexBase_2` and `DelaunayMeshFaceBase_2`, respectively. The argument `cdt`, passed by reference, provides the initial mesh and is modified by the algorithm to represent the final optimized mesh. diff --git a/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/CGAL/Periodic_2_Delaunay_triangulation_2.h b/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/CGAL/Periodic_2_Delaunay_triangulation_2.h index 9bf894ca0d7..b95c3c7f607 100644 --- a/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/CGAL/Periodic_2_Delaunay_triangulation_2.h +++ b/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/CGAL/Periodic_2_Delaunay_triangulation_2.h @@ -16,12 +16,14 @@ The class `Periodic_2_Delaunay_triangulation_2` has two template parameters. The \tparam Traits is the geometric traits, it is to be instantiated by a model of the concept `Periodic_2DelaunayTriangulationTraits_2`. -The second parameter is the triangulation data structure, it has to be -instantiated by a model of the concept -`TriangulationDataStructure_2` with some additional functionality -in faces. By default, the triangulation data structure is instantiated -by -`CGAL::Triangulation_data_structure_2 < CGAL::Triangulation_vertex_base_2, CGAL::Periodic_2_triangulation_face_base_2 > >`. +\tparam Tds is the triangulation data data structure and must be a model of `TriangulationDataStructure_2` +whose vertex and face are models of `Periodic_2TriangulationVertexBase_2` and `Periodic_2TriangulationFaceBase_2`. +It defaults to: +\code +CGAL::Triangulation_data_structure_2< + CGAL::Periodic_2_triangulation_vertex_base_2, + CGAL::Periodic_2_triangulation_face_base_2 > > +\endcode \cgalHeading{Implementation} @@ -42,11 +44,8 @@ After a point location step, the nearest neighbor is found in time vertices distributed uniformly at random and any query point. \sa `CGAL::Periodic_2_triangulation_2` -\sa `CGAL::Delaunay_triangulation_2` -\sa `TriangulationDataStructure_2` -\sa `Periodic_2DelaunayTriangulationTraits_2` \sa `CGAL::Periodic_2_triangulation_hierarchy_2` - +\sa `CGAL::Delaunay_triangulation_2` */ template< typename Traits, typename Tds > class Periodic_2_Delaunay_triangulation_2 : public Periodic_2_triangulation_2 diff --git a/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/CGAL/Periodic_2_triangulation_2.h b/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/CGAL/Periodic_2_triangulation_2.h index f68062261eb..21dc5d73b09 100644 --- a/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/CGAL/Periodic_2_triangulation_2.h +++ b/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/CGAL/Periodic_2_triangulation_2.h @@ -11,15 +11,17 @@ The class `Periodic_2_triangulation_2` represents a 2-dimensional triangulation of a point set in \f$ \mathbb T_c^2\f$. \tparam Traits is the geometric traits, it -is to be instantiated by a model of the concept +has to be instantiated by a model of the concept `Periodic_2TriangulationTraits_2`. -\tparam TDS is the triangulation data structure, -it has to be instantiated by a model of the concept -`TriangulationDataStructure_2` with some additional -functionality in faces. -By default, the triangulation data structure is instantiated by -`CGAL::Triangulation_data_structure_2 < CGAL::Triangulation_vertex_base_2, CGAL::Periodic_2_triangulation_face_base_2 > >`. +\tparam Tds is the triangulation data data structure and must be a model of `TriangulationDataStructure_2` +whose vertex and face are models of `Periodic_2TriangulationVertexBase_2` and `Periodic_2TriangulationFaceBase_2`. +It defaults to: +\code +CGAL::Triangulation_data_structure_2< + CGAL::Periodic_2_triangulation_vertex_base_2, + CGAL::Periodic_2_triangulation_face_base_2 > > +\endcode \cgalHeading{Traversal of the Triangulation} @@ -67,14 +69,9 @@ their counterparts visiting all (non-virtual and virtual) features which are themselves derived from the corresponding iterators of the triangulation data structure. -\sa `Triangulation_2` -\sa `Periodic_2TriangulationTraits_2` -\sa `TriangulationDataStructure_2` -\sa `TriangulationDataStructure_2::Face` -\sa `TriangulationDataStructure_2::Vertex` -\sa `CGAL::Triangulation_data_structure_2` -\sa `CGAL::Periodic_2_triangulation_face_base_2` - +\sa `CGAL::Periodic_2_triangulation_2` +\sa `CGAL::Periodic_2_triangulation_hierarchy_2` +\sa `CGAL::Triangulation_2` */ template< typename Traits, typename Tds > class Periodic_2_triangulation_2 : public Triangulation_cw_ccw_2 diff --git a/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/CGAL/Periodic_2_triangulation_traits_2.h b/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/CGAL/Periodic_2_triangulation_traits_2.h index 726d2f5af83..bf17a102578 100644 --- a/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/CGAL/Periodic_2_triangulation_traits_2.h +++ b/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/CGAL/Periodic_2_triangulation_traits_2.h @@ -8,8 +8,7 @@ namespace CGAL \ingroup PkgPeriodic2Triangulation2TraitsClasses The class `Periodic_2_triangulation_traits_2` is designed as a default -traits class for the class -`Periodic_2_triangulation_2`. +traits class for the class `CGAL::Periodic_2_triangulation_2`. \tparam Traits must be a model of the `TriangulationTraits_2` concept. \tparam Periodic_2Offset_2 must be a model of the concept diff --git a/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/Periodic_2_triangulation_2.txt b/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/Periodic_2_triangulation_2.txt index 0db671e9a6f..93c54224799 100644 --- a/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/Periodic_2_triangulation_2.txt +++ b/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/Periodic_2_triangulation_2.txt @@ -256,18 +256,19 @@ The second parameter `Periodic_2Offset_2` defaults to The second template parameter of the main classes `Periodic_2_triangulation_2` and `Periodic_2_Delaunay_triangulation_2` is a -triangulation data structure class. This class can be seen as a container for +triangulation data structure class. This class must be a model of the concept +`TriangulationDataStructure_2`, which describes requirements for the class to be a container for the faces and vertices maintaining incidence and adjacency relations (see -Chapter \ref Chapter_2D_Triangulation_Data_Structure). A model of this triangulation data structure is -`Triangulation_data_structure_2`, and it is described by the -`TriangulationDataStructure_2` concept. This model is itself +Chapter \ref Chapter_2D_Triangulation_Data_Structure). In addition, the concepts +`TriangulationDataStructure_2::Vertex` and `TriangulationDataStructure_2::Face` are extended +to support periodicity: the vertex and face must be models of +`Periodic_2TriangulationVertexBase_2` and Periodic_2TriangulationFaceBase_2`. +A model of such concept is `CGAL::Triangulation_data_structure_2`. It is parameterized by a vertex base class and a face base class, which gives the possibility to customize the vertices and cells used by the triangulation data structure, and hence by the geometric triangulation using it. -To represent periodic triangulations the cell base and vertex base -classes need to meet the concepts -`Periodic_2TriangulationFaceBase_2` and -`Periodic_2TriangulationVertexBase_2`. +Basic models of the vertex and face concepts are provided: `CGAL::Periodic_2_triangulation_vertex_base_2` +and `CGAL::Periodic_2_triangulation_face_base_2`. A default value for the triangulation data structure parameter is provided in all the triangulation classes, so it does not need to be specified by diff --git a/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_Delaunay_triangulation_3.h b/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_Delaunay_triangulation_3.h index 784f44ff1c7..6a1e4c5d911 100644 --- a/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_Delaunay_triangulation_3.h +++ b/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_Delaunay_triangulation_3.h @@ -9,8 +9,15 @@ Delaunay triangulation in three-dimensional periodic space. \tparam PT must be a model of the concept `Periodic_3DelaunayTriangulationTraits_3`. -\tparam TDS must be a model of the concept `TriangulationDataStructure_3`. Its default value -is `Triangulation_data_structure_3>,Triangulation_cell_base_3>>`. +\tparam TDS must be a model of the concept `TriangulationDataStructure_3` whose +vertex and cell are models of `Periodic_3TriangulationDSVertexBase_3` and `Periodic_3TriangulationDSCellBase_3`, +respectively. +It defaults to: +\code +CGAL::Triangulation_data_structure_3< + CGAL::Triangulation_vertex_base_3 >, + CGAL::Triangulation_cell_base_3 > > +\endcode */ template< typename PT, typename TDS > diff --git a/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_regular_triangulation_3.h b/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_regular_triangulation_3.h index b15ac483eb2..31cc5a71d3d 100644 --- a/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_regular_triangulation_3.h +++ b/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_regular_triangulation_3.h @@ -9,11 +9,18 @@ weighted Delaunay triangulation in three-dimensional periodic space. \tparam PT must be a model of the concept `Periodic_3RegularTriangulationTraits_3`. -\tparam TDS must be a model of the concept `TriangulationDataStructure_3`. -Its default value is -`Triangulation_data_structure_3 >, - Regular_triangulation_cell_base_3>>`. +\tparam TDS must be a model of the concept `TriangulationDataStructure_3` whose +vertex and cell are models of `Periodic_3RegularTriangulationDSVertexBase_3` +and `Periodic_3RegularTriangulationDSCellBase_3`, respectively. +Its default value is: +\code +CGAL::Triangulation_data_structure_3< + CGAL::Regular_triangulation_vertex_base_3 >, + CGAL::Regular_triangulation_cell_base_3 > > +\endcond +\sa `CGAL::Periodic_3_triangulation_3` +\sa `CGAL::Periodic_3_Delaunay_triangulation_3` */ template< typename PT, typename TDS > class Periodic_3_regular_triangulation_3 : diff --git a/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_triangulation_3.h b/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_triangulation_3.h index 3bb1bb28506..66ddfe72eca 100644 --- a/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_triangulation_3.h +++ b/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_triangulation_3.h @@ -9,13 +9,17 @@ triangulation of a point set in \f$ \mathbb T_c^3\f$. \tparam Traits must be a model of the concept `Periodic_3TriangulationTraits_3`. -\tparam TDS must be a model of the concept `TriangulationDataStructure_3` -with some additional functionality in cells and vertices. -Its default value is -`Triangulation_data_structure_3>,Triangulation_cell_base_3>>`. +\tparam TDS must be a model of the concept `TriangulationDataStructure_3` with +vertex and cell are models of `Periodic_3TriangulationDSVertexBase_3` and `Periodic_3TriangulationDSCellBase_3`, +Its default value is: +\code +CGAL::Triangulation_data_structure_3< + CGAL::Triangulation_vertex_base_3 >, + CGAL::Triangulation_cell_base_3 > > +\endcond -\sa `Periodic_3_Delaunay_triangulation_3` -\sa `Periodic_3_regular_triangulation_3` +\sa `CGAL::Periodic_3_Delaunay_triangulation_3` +\sa `CGAL::Periodic_3_regular_triangulation_3` */ template< typename Traits, typename TDS > class Periodic_3_triangulation_3 { diff --git a/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/Periodic_3_triangulation_3.txt b/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/Periodic_3_triangulation_3.txt index a1998b9165b..31f06d7cc3e 100644 --- a/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/Periodic_3_triangulation_3.txt +++ b/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/Periodic_3_triangulation_3.txt @@ -290,18 +290,14 @@ triangles, and tetrahedra are used. \subsection P3Triangulation3sectds The Triangulation Data Structure Parameter The second template parameter of the periodic triangulation classes is a -triangulation data structure class. This class can be seen as a container for -the cells and vertices maintaining incidence and adjacency relations (see -Chapter \ref chapterTDS3 "3D Triangulation Data Structure"). A model of this triangulation data structure is -`Triangulation_data_structure_3`, and it is described by the -`TriangulationDataStructure_3` concept. This model is itself -parameterized by a vertex base class and a cell base class, which gives the -possibility to customize the vertices and cells used by the triangulation data -structure, and hence by the geometric triangulation using it. -To represent periodic triangulations the cell base and vertex base -classes need to meet the concepts -`Periodic_3TriangulationDSCellBase_3` and -`Periodic_3TriangulationDSVertexBase_3`. +triangulation data structure class. +This parameter must meet the requirements described in the concept `TriangulationDataStructure_3`, +for which \cgal offers the model `CGAL::Triangulation_data_structure_3`. +To represent periodic triangulations, +the face and vertex of the triangulation data structure must be also be models of extended concepts. +The model `CGAL::Triangulation_data_structure_3` is parameterized by a vertex +base class and a face base class, which gives the possibility to customize the vertices and +faces used by the triangulation data structure. A default value for the triangulation data structure parameter is provided in all the triangulation classes, so it does not need to be specified by diff --git a/Periodic_4_hyperbolic_triangulation_2/doc/Periodic_4_hyperbolic_triangulation_2/CGAL/Periodic_4_hyperbolic_Delaunay_triangulation_2.h b/Periodic_4_hyperbolic_triangulation_2/doc/Periodic_4_hyperbolic_triangulation_2/CGAL/Periodic_4_hyperbolic_Delaunay_triangulation_2.h index 514460645ab..aa67d8eee10 100644 --- a/Periodic_4_hyperbolic_triangulation_2/doc/Periodic_4_hyperbolic_triangulation_2/CGAL/Periodic_4_hyperbolic_Delaunay_triangulation_2.h +++ b/Periodic_4_hyperbolic_triangulation_2/doc/Periodic_4_hyperbolic_triangulation_2/CGAL/Periodic_4_hyperbolic_Delaunay_triangulation_2.h @@ -21,10 +21,12 @@ The class expects two template parameters. and faces, following the concepts `Periodic_4HyperbolicTriangulationVertexBase_2` and `Periodic_4HyperbolicTriangulationFaceBase_2`, respectively. The default value for this parameter is - `Triangulation_data_structure_2< Periodic_4_hyperbolic_triangulation_vertex_base_2, Periodic_4_hyperbolic_triangulation_face_base_2 >` - + \code + CGAL::Triangulation_data_structure_2< + CGAL::Periodic_4_hyperbolic_triangulation_vertex_base_2, + CGAL::Periodic_4_hyperbolic_triangulation_face_base_2 > + \endcode */ - template < class GT, class TDS > class Periodic_4_hyperbolic_Delaunay_triangulation_2: public Periodic_4_hyperbolic_triangulation_2 { diff --git a/Periodic_4_hyperbolic_triangulation_2/doc/Periodic_4_hyperbolic_triangulation_2/CGAL/Periodic_4_hyperbolic_triangulation_2.h b/Periodic_4_hyperbolic_triangulation_2/doc/Periodic_4_hyperbolic_triangulation_2/CGAL/Periodic_4_hyperbolic_triangulation_2.h index 6c71eb1993f..08ea200278e 100644 --- a/Periodic_4_hyperbolic_triangulation_2/doc/Periodic_4_hyperbolic_triangulation_2/CGAL/Periodic_4_hyperbolic_triangulation_2.h +++ b/Periodic_4_hyperbolic_triangulation_2/doc/Periodic_4_hyperbolic_triangulation_2/CGAL/Periodic_4_hyperbolic_triangulation_2.h @@ -21,11 +21,12 @@ The class expects two template parameters. and faces, following the concepts `Periodic_4HyperbolicTriangulationVertexBase_2` and `Periodic_4HyperbolicTriangulationFaceBase_2`, respectively. The default value for this parameter is - `Triangulation_data_structure_2< Periodic_4_hyperbolic_triangulation_vertex_base_2, Periodic_4_hyperbolic_triangulation_face_base_2 >` - + \code + CGAL::Triangulation_data_structure_2< + CGAL::Periodic_4_hyperbolic_triangulation_vertex_base_2, + CGAL::Periodic_4_hyperbolic_triangulation_face_base_2 > + \endcode */ - - template < class GT, class TDS > class Periodic_4_hyperbolic_triangulation_2 { diff --git a/Periodic_4_hyperbolic_triangulation_2/doc/Periodic_4_hyperbolic_triangulation_2/Periodic_4_hyperbolic_triangulation_2.txt b/Periodic_4_hyperbolic_triangulation_2/doc/Periodic_4_hyperbolic_triangulation_2/Periodic_4_hyperbolic_triangulation_2.txt index 586d94b3143..f5bdc8e3990 100644 --- a/Periodic_4_hyperbolic_triangulation_2/doc/Periodic_4_hyperbolic_triangulation_2/Periodic_4_hyperbolic_triangulation_2.txt +++ b/Periodic_4_hyperbolic_triangulation_2/doc/Periodic_4_hyperbolic_triangulation_2/Periodic_4_hyperbolic_triangulation_2.txt @@ -289,12 +289,13 @@ The triangulation data structure is a container for the faces and vertices and m incidence and adjacency relations. This parameter must meet the requirements described in the concept `TriangulationDataStructure_2`, for which \cgal offers the model `Triangulation_data_structure_2`. -This model is itself parameterized by a vertex -base class and a face base class, which gives the possibility to customize the vertices and -faces used by the triangulation data structure. To represent periodic hyperbolic triangulations, -the face base and vertex base classes must be models of the concepts +To represent periodic hyperbolic triangulations, +the face and vertex of the triangulation data structure must be models of the concepts `Periodic_4HyperbolicTriangulationFaceBase_2` and `Periodic_4HyperbolicTriangulationVertexBase_2`, respectively. +The model `CGAL::Triangulation_data_structure_2` is parameterized by a vertex +base class and a face base class, which gives the possibility to customize the vertices and +faces used by the triangulation data structure. The default value for the triangulation data structure parameter is `Triangulation_data_structure_2< Periodic_4_hyperbolic_triangulation_vertex_base_2, Periodic_4_hyperbolic_triangulation_face_base_2 >`, diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_2.h b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_2.h index 388f9eed77b..f83430d3f2f 100644 --- a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_2.h +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_2.h @@ -6,12 +6,25 @@ namespace CGAL { The class `Segment_Delaunay_graph_2` represents the segment Delaunay graph (which is the dual graph of the 2D segment Voronoi diagram). -Currently it supports only insertions of sites. +Currently it only supports the insertions of sites. + +\tparam Gt must be a model of `SegmentDelaunayGraphTraits_2`. + +\tparam St must be a model of `SegmentDelaunayGraphStorageTraits_2`. + By default, the storage traits is instantiated by `Segment_Delaunay_graph_storage_traits_2`. -\tparam Gt must be a model of `SegmentDelaunayGraphTraits_2` \tparam DS must be a model of `SegmentDelaunayGraphDataStructure_2`. -`DS` defaults to -`CGAL::Triangulation_data_structure_2< CGAL::Segment_Delaunay_graph_vertex_base_2, CGAL::Triangulation_face_base_2 >`. + `DS` defaults to `CGAL::Triangulation_data_structure_2< CGAL::Segment_Delaunay_graph_vertex_base_2, CGAL::Segment_Delaunay_graph_face_base_2 >`. + Any custom type can be used instead of `Segment_Delaunay_graph_vertex_base_2` + and `Segment_Delaunay_graph_face_base_2`, provided that they are models of the + concepts `SegmentDelaunayGraphVertexBase_2` and `TriangulationFaceBase_2`, respectively. + +\cgalHeading{Storage} + +To avoid redundancy in the storage of points, input points are stored in a container, +and the various types of sites (input points and segments, points of intersection, +subsegments with one or two points of intersection as endpoints) only store handles to the points +in the container. \cgalHeading{Traversal of the Segment Delaunay Graph} From 723890e3883404f6dcaa6320853df9f0ae33b0fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Sat, 5 Dec 2020 11:49:27 +0100 Subject: [PATCH 068/248] Misc tiny doc fixes (broken links, grammar, etc.) --- .../Apollonius_graph_2/Apollonius_graph_2.txt | 2 +- .../Apollonius_graph_2/CGAL/Apollonius_graph_2.h | 2 +- .../CGAL/Apollonius_graph_hierarchy_2.h | 2 +- .../ApolloniusGraphHierarchyVertexBase_2.h | 3 +-- .../Concepts/ApolloniusGraphVertexBase_2.h | 2 +- .../Developer_manual/Chapter_debugging.txt | 2 +- .../Concepts/HyperbolicTriangulationFaceBase_2.h | 2 +- Mesh_2/doc/Mesh_2/CGAL/lloyd_optimize_mesh_2.h | 3 +-- .../include/CGAL/Periodic_2_triangulation_2.h | 16 ++++++++-------- .../Periodic_3_Delaunay_triangulation_traits_3.h | 2 +- .../Periodic_3_regular_triangulation_traits_3.h | 2 +- .../Periodic_3RegularTriangulationDSCellBase_3.h | 4 ++-- ...eriodic_3RegularTriangulationDSVertexBase_3.h | 2 +- .../Periodic_3_triangulation_3.txt | 12 +++++------- .../include/CGAL/hierarchy_simplify_point_set.h | 2 +- .../CGAL/Segment_Delaunay_graph_2.h | 3 +-- .../CGAL/Triangulation_data_structure_3.h | 2 +- 17 files changed, 29 insertions(+), 34 deletions(-) diff --git a/Apollonius_graph_2/doc/Apollonius_graph_2/Apollonius_graph_2.txt b/Apollonius_graph_2/doc/Apollonius_graph_2/Apollonius_graph_2.txt index 34fb0255111..0b2f6aa2082 100644 --- a/Apollonius_graph_2/doc/Apollonius_graph_2/Apollonius_graph_2.txt +++ b/Apollonius_graph_2/doc/Apollonius_graph_2/Apollonius_graph_2.txt @@ -181,7 +181,7 @@ two visible circles. The 2D Apollonius graph class `Apollonius_graph_2` -follows the design of the triangulation package of \cgal. It is +follows the design of the triangulation packages of \cgal. It is parametrized by two arguments:
    • the geometric traits class. It provides the basic diff --git a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_2.h b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_2.h index 172eb125a0f..55ff10c27ba 100644 --- a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_2.h +++ b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_2.h @@ -98,7 +98,7 @@ typedef Gt::Site_2 Site_2; /// \name Handles And Iterators /// The vertices and faces of the Apollonius graph are accessed -/// through `handles`, `iterators` and `circulators`. The iterators +/// through `handles`, `iterators`, and `circulators`. The iterators /// and circulators are all bidirectional and non-mutable. The /// circulators and iterators are assignable to the corresponding /// handle types, and they are also convertible to the corresponding diff --git a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_hierarchy_2.h b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_hierarchy_2.h index 4805d085632..3f79f688977 100644 --- a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_hierarchy_2.h +++ b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_hierarchy_2.h @@ -71,7 +71,7 @@ Apollonius_graph_hierarchy_2(Input_iterator first, Input_iterator beyond, Gt gt=Gt()); /*! -Copy constructor. All faces, vertices and inter-level pointers +Copy constructor. All faces, vertices, and inter-level pointers are duplicated. After the construction, `agh` and `other` refer to two different Apollonius graph hierarchies: if `other` is modified, `agh` is not. diff --git a/Apollonius_graph_2/doc/Apollonius_graph_2/Concepts/ApolloniusGraphHierarchyVertexBase_2.h b/Apollonius_graph_2/doc/Apollonius_graph_2/Concepts/ApolloniusGraphHierarchyVertexBase_2.h index 7de3add41e0..bf053bb84e6 100644 --- a/Apollonius_graph_2/doc/Apollonius_graph_2/Concepts/ApolloniusGraphHierarchyVertexBase_2.h +++ b/Apollonius_graph_2/doc/Apollonius_graph_2/Concepts/ApolloniusGraphHierarchyVertexBase_2.h @@ -37,8 +37,7 @@ public: /// @{ /*! -Default -constructor. +%Default constructor. */ ApolloniusGraphHierarchyVertexBase_2(); diff --git a/Apollonius_graph_2/doc/Apollonius_graph_2/Concepts/ApolloniusGraphVertexBase_2.h b/Apollonius_graph_2/doc/Apollonius_graph_2/Concepts/ApolloniusGraphVertexBase_2.h index 78fad902088..fc00ffe57ee 100644 --- a/Apollonius_graph_2/doc/Apollonius_graph_2/Concepts/ApolloniusGraphVertexBase_2.h +++ b/Apollonius_graph_2/doc/Apollonius_graph_2/Concepts/ApolloniusGraphVertexBase_2.h @@ -77,7 +77,7 @@ typedef unspecified_type Hidden_sites_iterator; /// @{ /*! -Default constructor. +%Default constructor. */ ApolloniusGraphVertexBase_2(); diff --git a/Documentation/doc/Documentation/Developer_manual/Chapter_debugging.txt b/Documentation/doc/Documentation/Developer_manual/Chapter_debugging.txt index e6a586b59af..3415b457cec 100644 --- a/Documentation/doc/Documentation/Developer_manual/Chapter_debugging.txt +++ b/Documentation/doc/Documentation/Developer_manual/Chapter_debugging.txt @@ -101,7 +101,7 @@ named `Traits1` and `Traits2`, and a third parameter named other is (presumably) a traits class that always gives the right answer. The `Adapter` is needed since the `X_curve` types for `Traits1` and `Traits2` might be different. -This cross-checker does nothing other then asserting that the two traits +This cross-checker does nothing other than asserting that the two traits classes return the same values by calling the the counterparts in the member traits classes (`tr1`,`tr2`) and comparing the results. diff --git a/Hyperbolic_triangulation_2/doc/Hyperbolic_triangulation_2/Concepts/HyperbolicTriangulationFaceBase_2.h b/Hyperbolic_triangulation_2/doc/Hyperbolic_triangulation_2/Concepts/HyperbolicTriangulationFaceBase_2.h index 744a7872854..45675b33aa7 100644 --- a/Hyperbolic_triangulation_2/doc/Hyperbolic_triangulation_2/Concepts/HyperbolicTriangulationFaceBase_2.h +++ b/Hyperbolic_triangulation_2/doc/Hyperbolic_triangulation_2/Concepts/HyperbolicTriangulationFaceBase_2.h @@ -7,7 +7,7 @@ \cgalRefines TriangulationFaceBase_2 -The concept HyperbolicTriangulationFaceBase_2 describes the requirements for the base +The concept `HyperbolicTriangulationFaceBase_2` describes the requirements for the base face class of a hyperbolic triangulation data structure. This concept provides an interface for the functionality needed in faces to compute diff --git a/Mesh_2/doc/Mesh_2/CGAL/lloyd_optimize_mesh_2.h b/Mesh_2/doc/Mesh_2/CGAL/lloyd_optimize_mesh_2.h index eab3ad645ab..5f235d98aae 100644 --- a/Mesh_2/doc/Mesh_2/CGAL/lloyd_optimize_mesh_2.h +++ b/Mesh_2/doc/Mesh_2/CGAL/lloyd_optimize_mesh_2.h @@ -24,8 +24,7 @@ being models of `DelaunayMeshVertexBase_2` and `DelaunayMeshFaceBase_2`, respect The argument `cdt`, passed by reference, provides the initial mesh and is modified by the algorithm to represent the final optimized mesh. -\tparam PointIterator must be an iterator with value type `CGAL::Kernel::Point_2` - +\tparam PointIterator must be an iterator with value type `Kernel::Point_2`. The function has several optional parameters which are named parameters (we use the Boost.Parameter library). diff --git a/Periodic_2_triangulation_2/include/CGAL/Periodic_2_triangulation_2.h b/Periodic_2_triangulation_2/include/CGAL/Periodic_2_triangulation_2.h index a85f7239e69..ef8a5d063f9 100644 --- a/Periodic_2_triangulation_2/include/CGAL/Periodic_2_triangulation_2.h +++ b/Periodic_2_triangulation_2/include/CGAL/Periodic_2_triangulation_2.h @@ -292,12 +292,12 @@ public: { return _gt; } - /// Returns the datastructure storing the triangulation. + /// Returns the data structure storing the triangulation. const Triangulation_data_structure & tds() const { return _tds; } - /// Returns the datastructure storing the triangulation. + /// Returns the data structure storing the triangulation. Triangulation_data_structure & tds() { return _tds; @@ -357,17 +357,17 @@ public: else return _tds.number_of_faces() / 9; } - /// Returns the number of vertices stored in the datastructure. + /// Returns the number of vertices stored in the data structure. size_type number_of_stored_vertices() const { return _tds.number_of_vertices(); } - /// Returns the number of edges stored in the datastructure. + /// Returns the number of edges stored in the data structure. size_type number_of_stored_edges() const { return _tds.number_of_edges(); } - /// Returns the number of faces stored in the datastructure. + /// Returns the number of faces stored in the data structure. size_type number_of_stored_faces() const { return _tds.number_of_faces(); @@ -1812,7 +1812,7 @@ bool Periodic_2_triangulation_2::is_valid_too_long_edges(bool verbose, { if (too_long) { - if (verbose) std::cout << "1. Too long edge not in the datastructure" << std::endl; + if (verbose) std::cout << "1. Too long edge not in the data structure" << std::endl; result = false; } result &= !too_long; @@ -1826,7 +1826,7 @@ bool Periodic_2_triangulation_2::is_valid_too_long_edges(bool verbose, too_long_edges++; if (it2 == it->second.end()) { - if (verbose) std::cout << "2. Too long edge not in the datastructure" << std::endl; + if (verbose) std::cout << "2. Too long edge not in the data structure" << std::endl; result = false; } CGAL_triangulation_assertion(result); @@ -1835,7 +1835,7 @@ bool Periodic_2_triangulation_2::is_valid_too_long_edges(bool verbose, { if (it2 != it->second.end()) { - if (verbose) std::cout << "Edge is not too long, but contained in the datastructure" << std::endl; + if (verbose) std::cout << "Edge is not too long, but contained in the data structure" << std::endl; result = false; } CGAL_triangulation_assertion(result); diff --git a/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_Delaunay_triangulation_traits_3.h b/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_Delaunay_triangulation_traits_3.h index 770ac8e656c..d5c6de09876 100644 --- a/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_Delaunay_triangulation_traits_3.h +++ b/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_Delaunay_triangulation_traits_3.h @@ -8,7 +8,7 @@ The class `Periodic_3_Delaunay_triangulation_traits_3` is designed as a default class `Periodic_3_Delaunay_triangulation_3`. \tparam Traits must be a model of the `DelaunayTriangulationTraits_3` concept. -\tparam Offset must be a model of the concept `Periodic_3Offset_3` and defaults to `Periodic_3_offset_3`. +\tparam Offset must be a model of the concept `Periodic_3Offset_3` and defaults to `CGAL::Periodic_3_offset_3`. If `Traits` is a `CGAL::Filtered_kernel` (detected when `Traits::Has_filtered_predicates` exists and is `true`), this class automatically provides filtered predicates. Similarly, statically filtered predicates diff --git a/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_regular_triangulation_traits_3.h b/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_regular_triangulation_traits_3.h index 8a4ec39a0cf..acfe43f7c32 100644 --- a/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_regular_triangulation_traits_3.h +++ b/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_regular_triangulation_traits_3.h @@ -8,7 +8,7 @@ The class `Periodic_3_regular_triangulation_traits_3` is designed as a default t class `Periodic_3_regular_triangulation_3`. \tparam Traits must be a model of the `RegularTriangulationTraits_3` concept. -\tparam Offset must be a model of the concept `Periodic_3Offset_3` and defaults to `Periodic_3_offset_3`. +\tparam Offset must be a model of the concept `Periodic_3Offset_3` and defaults to `CGAL::Periodic_3_offset_3`. If `Traits` is a `CGAL::Filtered_kernel` (detected when `Traits::Has_filtered_predicates` exists and is `true`), this class automatically provides filtered predicates. diff --git a/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/Concepts/Periodic_3RegularTriangulationDSCellBase_3.h b/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/Concepts/Periodic_3RegularTriangulationDSCellBase_3.h index 98b07f6d6b7..59afc1e24c3 100644 --- a/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/Concepts/Periodic_3RegularTriangulationDSCellBase_3.h +++ b/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/Concepts/Periodic_3RegularTriangulationDSCellBase_3.h @@ -7,9 +7,9 @@ \cgalRefines `Periodic_3TriangulationDSCellBase_3` \cgalHasModel `CGAL::Regular_triangulation_cell_base_3 >` + Periodic_3_triangulation_ds_cell_base_3< > >` \cgalHasModel `CGAL::Regular_triangulation_cell_base_with_weighted_circumcenter_3 >` + Periodic_3_triangulation_ds_cell_base_3< > >` The template parameter `Periodic_3RegularTriangulationTraits_3` is expected to be the same as the traits class used in `CGAL::Periodic_3_regular_triangulation_3`. diff --git a/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/Concepts/Periodic_3RegularTriangulationDSVertexBase_3.h b/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/Concepts/Periodic_3RegularTriangulationDSVertexBase_3.h index 1d2a7bec41c..43ff786e30a 100644 --- a/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/Concepts/Periodic_3RegularTriangulationDSVertexBase_3.h +++ b/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/Concepts/Periodic_3RegularTriangulationDSVertexBase_3.h @@ -7,7 +7,7 @@ \cgalRefines `Periodic_3TriangulationDSVertexBase_3` \cgalHasModel `CGAL::Regular_triangulation_vertex_base_3 >` + Periodic_3_triangulation_ds_vertex_base_3< > >` The template parameter `Periodic_3RegularTriangulationTraits_3` is expected to be the same as the traits class used in `CGAL::Periodic_3_regular_triangulation_3`. diff --git a/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/Periodic_3_triangulation_3.txt b/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/Periodic_3_triangulation_3.txt index 31f06d7cc3e..92eb9015cef 100644 --- a/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/Periodic_3_triangulation_3.txt +++ b/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/Periodic_3_triangulation_3.txt @@ -219,17 +219,17 @@ The first template parameter of the triangulation class `Periodic_3_triangulation_3` is the geometric traits class, described by the concept `Periodic_3TriangulationTraits_3`. It is different to the -TriangulationTraits_3 (see +`TriangulationTraits_3` (see chapter \ref Triangulation3secTraits "3D Triangulations") in that it implements all objects, predicates and constructions using offsets. -The class `Periodic_3_triangulation_traits_3` +The class `CGAL::Periodic_3_triangulation_traits_3` provides the required functionality. It expects two template parameters: a model of the concept `TriangulationTraits_3` and a model of the concept `Periodic_3Offset_3`. The second parameter `Periodic_3Offset_3` defaults to -`Periodic_3_offset_3`. +`CGAL::Periodic_3_offset_3`. \subsubsection P3Triangulation3secTraitsP3DT3 Traits for Periodic Delaunay Triangulations @@ -237,7 +237,7 @@ The first template parameter of the Delaunay triangulation class `Periodic_3_Delaunay_triangulation_3` is the geometric traits class, described by the concept `Periodic_3DelaunayTriangulationTraits_3`. It is different to the -DelaunayTriangulationTraits_3 (see +`DelaunayTriangulationTraits_3` (see chapter \ref Triangulation3secTraits "3D Triangulations") in that it implements all objects, predicates and constructions using offsets. @@ -246,9 +246,7 @@ provides the required functionality. It expects two template parameters: a model of the concept `DelaunayTriangulationTraits_3` and a model of the concept `Periodic_3Offset_3`. -The second parameter `Periodic_3Offset_3` defaults to -`Periodic_3_offset_3`. - +The second parameter `Periodic_3Offset_3` defaults to `CGAL::Periodic_3_offset_3`. \subsubsection P3Triangulation3secTraitsP3regularT3 Traits for Periodic Regular Triangulations diff --git a/Point_set_processing_3/include/CGAL/hierarchy_simplify_point_set.h b/Point_set_processing_3/include/CGAL/hierarchy_simplify_point_set.h index 1c826ec63e2..6e60b94a4e2 100644 --- a/Point_set_processing_3/include/CGAL/hierarchy_simplify_point_set.h +++ b/Point_set_processing_3/include/CGAL/hierarchy_simplify_point_set.h @@ -109,7 +109,7 @@ namespace CGAL { \ingroup PkgPointSetProcessing3Algorithms Recursively split the point set in smaller clusters until the - clusters have less than `size` elements and until their variation + clusters have fewer than `size` elements and until their variation factor is below `var_max`. This method modifies the order of input points so as to pack all remaining points first, diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_2.h b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_2.h index f83430d3f2f..64ea405df03 100644 --- a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_2.h +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_2.h @@ -297,8 +297,7 @@ Face_handle infinite_face(); /*! Returns the `infinite_vertex`. */ -Vertex_handle -infinite_vertex(); +Vertex_handle infinite_vertex(); /*! Returns a vertex distinct from the `infinite_vertex`. diff --git a/TDS_3/include/CGAL/Triangulation_data_structure_3.h b/TDS_3/include/CGAL/Triangulation_data_structure_3.h index 7c01149ab44..29d4372c58d 100644 --- a/TDS_3/include/CGAL/Triangulation_data_structure_3.h +++ b/TDS_3/include/CGAL/Triangulation_data_structure_3.h @@ -3669,7 +3669,7 @@ is_valid(bool verbose, int level ) const { if ( number_of_vertices() < 2 ) { if (verbose) - std::cerr << "less than 2 vertices but dimension 0" << std::endl; + std::cerr << "fewer than 2 vertices but dimension 0" << std::endl; CGAL_triangulation_assertion(false); return false; } From 7de73bebf285e1559922e0a7af690db998a9d4a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Sat, 5 Dec 2020 11:51:02 +0100 Subject: [PATCH 069/248] Fix doc of TDS_2::copy_tds --- TDS_2/doc/TDS_2/Concepts/TriangulationDataStructure_2.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TDS_2/doc/TDS_2/Concepts/TriangulationDataStructure_2.h b/TDS_2/doc/TDS_2/Concepts/TriangulationDataStructure_2.h index 613eea9a70d..90a4a4cf2d8 100644 --- a/TDS_2/doc/TDS_2/Concepts/TriangulationDataStructure_2.h +++ b/TDS_2/doc/TDS_2/Concepts/TriangulationDataStructure_2.h @@ -229,7 +229,7 @@ otherwise `Vertex_handle()` is returned. \pre The optional argument `v` is a vertex of `tds_src` or is `Vertex_handle()`. */ template -Vertex_handle tds.copy_tds(const TDS_src& tds_src, typename TDS_src::Vertex_handle v, const ConvertVertex& convert_vertex, const ConvertFace& convert_face); +Vertex_handle copy_tds(const TDS_src& tds_src, typename TDS_src::Vertex_handle v, const ConvertVertex& convert_vertex, const ConvertFace& convert_face); /*! Swaps the triangulation data structure and `tds1`. From c21b84482c70b7f11dad04d336ea2de6761d91f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Sat, 5 Dec 2020 12:00:15 +0100 Subject: [PATCH 070/248] Fix encond / endcode typo --- .../CGAL/Periodic_3_regular_triangulation_3.h | 2 +- .../CGAL/Periodic_3_triangulation_3.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_regular_triangulation_3.h b/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_regular_triangulation_3.h index 31cc5a71d3d..5e8938db6c0 100644 --- a/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_regular_triangulation_3.h +++ b/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_regular_triangulation_3.h @@ -17,7 +17,7 @@ Its default value is: CGAL::Triangulation_data_structure_3< CGAL::Regular_triangulation_vertex_base_3 >, CGAL::Regular_triangulation_cell_base_3 > > -\endcond +\endcode \sa `CGAL::Periodic_3_triangulation_3` \sa `CGAL::Periodic_3_Delaunay_triangulation_3` diff --git a/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_triangulation_3.h b/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_triangulation_3.h index 66ddfe72eca..10569a5784c 100644 --- a/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_triangulation_3.h +++ b/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_triangulation_3.h @@ -16,7 +16,7 @@ Its default value is: CGAL::Triangulation_data_structure_3< CGAL::Triangulation_vertex_base_3 >, CGAL::Triangulation_cell_base_3 > > -\endcond +\endcode \sa `CGAL::Periodic_3_Delaunay_triangulation_3` \sa `CGAL::Periodic_3_regular_triangulation_3` From 472dd09a02bc2bf3d1456d9248509795108320cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Sat, 5 Dec 2020 15:18:34 +0100 Subject: [PATCH 071/248] Misc doc cleaning --- .../doc/Apollonius_graph_2/CGAL/Apollonius_graph_2.h | 12 +++--------- .../CGAL/Apollonius_graph_hierarchy_2.h | 3 +-- .../CGAL/Apollonius_graph_hierarchy_vertex_base_2.h | 5 ++--- .../CGAL/Apollonius_graph_traits_2.h | 5 ----- .../CGAL/Apollonius_graph_vertex_base_2.h | 9 ++------- .../doc/Apollonius_graph_2/CGAL/Apollonius_site_2.h | 3 --- .../Concepts/ApolloniusGraphDataStructure_2.h | 8 ++++---- .../Concepts/ApolloniusGraphHierarchyVertexBase_2.h | 7 +------ .../Concepts/ApolloniusGraphVertexBase_2.h | 10 ++++------ .../doc/Apollonius_graph_2/PackageDescription.txt | 4 ++-- .../CGAL/Periodic_2_triangulation_traits_2.h | 2 +- 11 files changed, 20 insertions(+), 48 deletions(-) diff --git a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_2.h b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_2.h index 55ff10c27ba..fb82e23c709 100644 --- a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_2.h +++ b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_2.h @@ -46,17 +46,11 @@ ag.incident_edges(ag.infinite_vertex()); ag.incident_edges(ag.infinite_vertex(), f); \endcode -\sa `DelaunayGraph_2` -\sa `ApolloniusGraphTraits_2` -\sa `ApolloniusGraphDataStructure_2` -\sa `ApolloniusGraphVertexBase_2` -\sa `TriangulationFaceBase_2` +\cgalModels `DelaunayGraph_2` + \sa `CGAL::Apollonius_graph_traits_2` \sa `CGAL::Apollonius_graph_filtered_traits_2` -\sa `CGAL::Triangulation_data_structure_2` -\sa `CGAL::Apollonius_graph_vertex_base_2` -\sa `CGAL::Triangulation_face_base_2` - +\sa `CGAL::Apollonius_graph_hierarchy_2` */ template< typename Gt, typename Agds > class Apollonius_graph_2 { diff --git a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_hierarchy_2.h b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_hierarchy_2.h index 3f79f688977..778dd9160e1 100644 --- a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_hierarchy_2.h +++ b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_hierarchy_2.h @@ -67,8 +67,7 @@ Creates an Apollonius graph hierarchy using range [`first`, `beyond`). */ template< class Input_iterator > -Apollonius_graph_hierarchy_2(Input_iterator -first, Input_iterator beyond, Gt gt=Gt()); +Apollonius_graph_hierarchy_2(Input_iterator first, Input_iterator beyond, Gt gt=Gt()); /*! Copy constructor. All faces, vertices, and inter-level pointers diff --git a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_hierarchy_vertex_base_2.h b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_hierarchy_vertex_base_2.h index 354dd734e8b..c09d6255ab5 100644 --- a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_hierarchy_vertex_base_2.h +++ b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_hierarchy_vertex_base_2.h @@ -13,10 +13,9 @@ of the `ApolloniusGraphVertexBase_2` concept. \cgalModels `ApolloniusGraphHierarchyVertexBase_2` -\sa `ApolloniusGraphVertexBase_2` -\sa `ApolloniusGraphHierarchyVertexBase_2` \sa `CGAL::Apollonius_graph_vertex_base_2` - +\sa `CGAL::Triangulation_data_structure_2` +\sa `CGAL::Apollonius_graph_hierarchy_2` */ template< typename Agvb > class Apollonius_graph_hierarchy_vertex_base_2 : Agvb { diff --git a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_traits_2.h b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_traits_2.h index 091a2cb8f00..3fe29ef740b 100644 --- a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_traits_2.h +++ b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_traits_2.h @@ -22,13 +22,8 @@ The way the predicates are evaluated is discussed in \cgalModels `ApolloniusGraphTraits_2` -\sa `Kernel` -\sa `ApolloniusGraphTraits_2` -\sa `CGAL::Integral_domain_without_division_tag` -\sa `CGAL::Field_with_sqrt_tag` \sa `CGAL::Apollonius_graph_2` \sa `CGAL::Apollonius_graph_filtered_traits_2` - */ template< typename K, typename Method_tag > class Apollonius_graph_traits_2 { diff --git a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_vertex_base_2.h b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_vertex_base_2.h index 75bf5137d3d..ae9eca3dc6e 100644 --- a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_vertex_base_2.h +++ b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_vertex_base_2.h @@ -19,13 +19,8 @@ discarded. By default `StoreHidden` is set to `true`. \cgalModels `ApolloniusGraphVertexBase_2` -\sa `ApolloniusGraphVertexBase_2` -\sa `ApolloniusGraphDataStructure_2` -\sa `ApolloniusGraphTraits_2` \sa `CGAL::Triangulation_data_structure_2` -\sa `CGAL::Apollonius_graph_traits_2` -\sa `CGAL::Apollonius_graph_filtered_traits_2` - +\sa `CGAL::Apollonius_graph_hierarchy_vertex_base_2` */ template< typename Gt, typename StoreHidden > class Apollonius_graph_vertex_base_2 { @@ -37,7 +32,7 @@ public: /*! %Default constructor. */ -Apollonius_graph_bertex_base_2(); +Apollonius_graph_vertex_base_2(); /*! Constructs a vertex associated with the site `s` and diff --git a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_site_2.h b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_site_2.h index 30de7481481..162a6e46259 100644 --- a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_site_2.h +++ b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_site_2.h @@ -22,12 +22,9 @@ The I/O operators are defined for `iostream`. The information output in the `iostream` is: the point of the Apollonius site and its weight. -\sa `Kernel` -\sa `ApolloniusSite_2` \sa `CGAL::Qt_widget` \sa `CGAL::Apollonius_graph_traits_2` \sa `CGAL::Apollonius_graph_filtered_traits_2` - */ template< typename K > class Apollonius_site_2 { diff --git a/Apollonius_graph_2/doc/Apollonius_graph_2/Concepts/ApolloniusGraphDataStructure_2.h b/Apollonius_graph_2/doc/Apollonius_graph_2/Concepts/ApolloniusGraphDataStructure_2.h index c2f31f5fa59..8c3209da2e8 100644 --- a/Apollonius_graph_2/doc/Apollonius_graph_2/Concepts/ApolloniusGraphDataStructure_2.h +++ b/Apollonius_graph_2/doc/Apollonius_graph_2/Concepts/ApolloniusGraphDataStructure_2.h @@ -42,10 +42,10 @@ public: /// @{ /*! -Inserts -a degree two vertex and two faces adjacent to it that have two common -edges. The edge defined by the face handle `f` and the integer -`i` is duplicated. It returns a handle to the vertex created. +inserts a degree two vertex and two faces adjacent to it that have two common edges. + +The edge defined by the face handle `f` and the integer `i` is duplicated. It returns a handle +to the vertex created. */ Vertex_handle insert_degree_2(Face_handle f, int i); diff --git a/Apollonius_graph_2/doc/Apollonius_graph_2/Concepts/ApolloniusGraphHierarchyVertexBase_2.h b/Apollonius_graph_2/doc/Apollonius_graph_2/Concepts/ApolloniusGraphHierarchyVertexBase_2.h index bf053bb84e6..8145923b669 100644 --- a/Apollonius_graph_2/doc/Apollonius_graph_2/Concepts/ApolloniusGraphHierarchyVertexBase_2.h +++ b/Apollonius_graph_2/doc/Apollonius_graph_2/Concepts/ApolloniusGraphHierarchyVertexBase_2.h @@ -19,17 +19,12 @@ next and previous level graphs. `ApolloniusGraphHierarchyVertexBase_2` does not introduce any types in addition to those of `ApolloniusGraphVertexBase_2`. -\cgalHasModel CGAL::Apollonius_graph_hierarchy_vertex_base_2 > +\cgalHasModel `CGAL::Apollonius_graph_hierarchy_vertex_base_2 >` \sa `ApolloniusGraphDataStructure_2` -\sa `ApolloniusGraphVertexBase_2` \sa `CGAL::Apollonius_graph_hierarchy_2` \sa `CGAL::Triangulation_data_structure_2` -\sa `CGAL::Apollonius_graph_vertex_base_2` -\sa `CGAL::Apollonius_graph_hierarchy_vertex_base_2` - */ - class ApolloniusGraphHierarchyVertexBase_2 { public: diff --git a/Apollonius_graph_2/doc/Apollonius_graph_2/Concepts/ApolloniusGraphVertexBase_2.h b/Apollonius_graph_2/doc/Apollonius_graph_2/Concepts/ApolloniusGraphVertexBase_2.h index fc00ffe57ee..e25279179aa 100644 --- a/Apollonius_graph_2/doc/Apollonius_graph_2/Concepts/ApolloniusGraphVertexBase_2.h +++ b/Apollonius_graph_2/doc/Apollonius_graph_2/Concepts/ApolloniusGraphVertexBase_2.h @@ -3,8 +3,6 @@ \ingroup PkgApolloniusGraph2Concepts \cgalConcept -\cgalRefines `TriangulationVertexBase_2` - The concept `ApolloniusGraphVertexBase_2` describes the requirements for the vertex base class of the `ApolloniusGraphDataStructure_2` concept. A vertex stores an @@ -12,14 +10,14 @@ Apollonius site and provides access to one of its incident faces through a `Face_handle`. In addition, it maintains a container of sites. The container stores the hidden sites related to the vertex. +\cgalRefines `TriangulationVertexBase_2` + \cgalHasModel `CGAL::Apollonius_graph_vertex_base_2` \sa `ApolloniusGraphDataStructure_2` -\sa `ApolloniusGraphTraits_2` -\sa `CGAL::Apollonius_graph_vertex_base_2` - +\sa `CGAL::Apollonius_graph_2` +\sa `CGAL::Triangulation_data_structure_2` */ - class ApolloniusGraphVertexBase_2 { public: diff --git a/Apollonius_graph_2/doc/Apollonius_graph_2/PackageDescription.txt b/Apollonius_graph_2/doc/Apollonius_graph_2/PackageDescription.txt index 706466df36b..f82d98db1ed 100644 --- a/Apollonius_graph_2/doc/Apollonius_graph_2/PackageDescription.txt +++ b/Apollonius_graph_2/doc/Apollonius_graph_2/PackageDescription.txt @@ -43,18 +43,18 @@ aforementioned concepts. \cgalCRPSection{Concepts} - `ApolloniusSite_2` +- `ApolloniusGraphTraits_2` - `ApolloniusGraphDataStructure_2` - `ApolloniusGraphVertexBase_2` -- `ApolloniusGraphTraits_2` - `ApolloniusGraphHierarchyVertexBase_2` \cgalCRPSection{Classes} - `CGAL::Apollonius_graph_2` - `CGAL::Apollonius_site_2` -- `CGAL::Apollonius_graph_vertex_base_2` - `CGAL::Apollonius_graph_traits_2` - `CGAL::Apollonius_graph_filtered_traits_2` +- `CGAL::Apollonius_graph_vertex_base_2` - `CGAL::Apollonius_graph_hierarchy_2` - `CGAL::Apollonius_graph_hierarchy_vertex_base_2` diff --git a/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/CGAL/Periodic_2_triangulation_traits_2.h b/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/CGAL/Periodic_2_triangulation_traits_2.h index bf17a102578..e14eab6d490 100644 --- a/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/CGAL/Periodic_2_triangulation_traits_2.h +++ b/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/CGAL/Periodic_2_triangulation_traits_2.h @@ -12,7 +12,7 @@ traits class for the class `CGAL::Periodic_2_triangulation_2 Date: Sat, 5 Dec 2020 15:20:31 +0100 Subject: [PATCH 072/248] Properly document SDG storage traits + many other SDG2 doc fixes --- .../CGAL/Segment_Delaunay_graph_2.h | 239 ++++++++---------- .../CGAL/Segment_Delaunay_graph_face_base_2.h | 27 ++ ...Segment_Delaunay_graph_filtered_traits_2.h | 13 +- .../CGAL/Segment_Delaunay_graph_hierarchy_2.h | 59 ++--- ...t_Delaunay_graph_hierarchy_vertex_base_2.h | 6 +- .../Segment_Delaunay_graph_storage_site_2.h | 15 +- .../Segment_Delaunay_graph_storage_traits_2.h | 34 +++ .../CGAL/Segment_Delaunay_graph_traits_2.h | 8 +- .../Segment_Delaunay_graph_vertex_base_2.h | 28 +- .../Concepts/SegmentDelaunayGraphFaceBase_2.h | 22 ++ ...egmentDelaunayGraphHierarchyVertexBase_2.h | 6 +- .../Concepts/SegmentDelaunayGraphSite_2.h | 2 +- .../SegmentDelaunayGraphStorageTraits_2.h | 92 +++++++ .../Concepts/SegmentDelaunayGraphTraits_2.h | 11 +- .../SegmentDelaunayGraphVertexBase_2.h | 47 ++-- .../PackageDescription.txt | 11 +- .../Segment_Delaunay_graph_2.txt | 13 +- .../Segment_Delaunay_graph_vertex_base_2.h | 8 +- .../CGAL/Triangulation_data_structure_2.h | 80 +++--- 19 files changed, 419 insertions(+), 302 deletions(-) create mode 100644 Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_face_base_2.h create mode 100644 Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_storage_traits_2.h create mode 100644 Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphFaceBase_2.h create mode 100644 Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphStorageTraits_2.h diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_2.h b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_2.h index 64ea405df03..4def14e0f8c 100644 --- a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_2.h +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_2.h @@ -13,18 +13,21 @@ Currently it only supports the insertions of sites. \tparam St must be a model of `SegmentDelaunayGraphStorageTraits_2`. By default, the storage traits is instantiated by `Segment_Delaunay_graph_storage_traits_2`. -\tparam DS must be a model of `SegmentDelaunayGraphDataStructure_2`. - `DS` defaults to `CGAL::Triangulation_data_structure_2< CGAL::Segment_Delaunay_graph_vertex_base_2, CGAL::Segment_Delaunay_graph_face_base_2 >`. - Any custom type can be used instead of `Segment_Delaunay_graph_vertex_base_2` - and `Segment_Delaunay_graph_face_base_2`, provided that they are models of the - concepts `SegmentDelaunayGraphVertexBase_2` and `TriangulationFaceBase_2`, respectively. +\tparam DS must be a model of `SegmentDelaunayGraphDataStructure_2` whose vertex and face are + models of the concepts `SegmentDelaunayGraphVertexBase_2` and `TriangulationFaceBase_2`, respectively. + It defaults to: + \code + `CGAL::Triangulation_data_structure_2< + CGAL::Segment_Delaunay_graph_vertex_base_2, + CGAL::Segment_Delaunay_graph_face_base_2 >` + \endcode \cgalHeading{Storage} To avoid redundancy in the storage of points, input points are stored in a container, and the various types of sites (input points and segments, points of intersection, subsegments with one or two points of intersection as endpoints) only store handles to the points -in the container. +in the container. See Section \ref Segment_Delaunay_graph_2StronglyIntersecting for more information. \cgalHeading{Traversal of the Segment Delaunay Graph} @@ -32,45 +35,34 @@ A segment Delaunay graph can be seen as a container of faces and vertices. Therefore the `Segment_Delaunay_graph_2` class provides several iterators and circulators that allow to traverse it (completely or partially). - - \cgalModels `DelaunayGraph_2` -\sa `DelaunayGraph_2` -\sa `SegmentDelaunayGraphTraits_2` -\sa `SegmentDelaunayGraphDataStructure_2` -\sa `SegmentDelaunayGraphVertexBase_2` -\sa `TriangulationFaceBase_2` -\sa `CGAL::Segment_Delaunay_graph_hierarchy_2` \sa `CGAL::Segment_Delaunay_graph_traits_2` \sa `CGAL::Segment_Delaunay_graph_traits_without_intersections_2` \sa `CGAL::Segment_Delaunay_graph_filtered_traits_2` \sa `CGAL::Segment_Delaunay_graph_filtered_traits_without_intersections_2` -\sa `CGAL::Triangulation_data_structure_2` -\sa `CGAL::Segment_Delaunay_graph_vertex_base_2` -\sa `CGAL::Triangulation_face_base_2` - +\sa `CGAL::Segment_Delaunay_graph_hierarchy_2` */ -template< typename Gt, typename DS > +template< typename Gt, typename St, typename DS > class Segment_Delaunay_graph_2 { public: /// \name Types - - - - /// @{ /*! -A type for the geometric traits. +Type for the geometric traits. */ typedef Gt Geom_traits; /*! -A type for the underlying -data structure. +Type for the storage traits. +*/ +typedef St Storage_traits; + +/*! +Type for the underlying data structure. */ typedef DS Data_structure; @@ -86,26 +78,29 @@ Size type (an unsigned integral type) typedef typename DS::size_type size_type; /*! -A type for the -point defined in the geometric traits. +Type for the point defined in the geometric traits. */ typedef typename Gt::Point_2 Point_2; /*! -A type for the segment Delaunay graph site, defined in the geometric -traits. +Type for the segment Delaunay graph site, defined in the geometric traits. */ typedef typename Gt::Site_2 Site_2; /*! -A type for the container of points. +Type for the segment Delaunay storage site, defined in the storage traits. */ -typedef unspecified_type Point_container; +typedef typename Storage_traits::Storage_site_2 Storage_site_2; /*! -A handle for points in the point container. +Type for the container of points. */ -typedef typename Point_container::iterator Point_handle; +typedef typename Storage_traits::Point_container Point_container; + +/*! +Handle type for points in the point container. +*/ +typedef typename Storage_traits::Point_handle Point_handle; /// @} @@ -138,67 +133,67 @@ The `Edge(f,i)` is the edge common to faces `f` and typedef typename DS::Edge Edge; /*! -A type for a vertex. +Type for a vertex. */ typedef typename DS::Vertex Vertex; /*! -A type for a face. +Type for a face. */ typedef typename DS::Face Face; /*! -A type for a handle to a vertex. +Type for a handle to a vertex. */ typedef typename DS::Vertex_handle Vertex_handle; /*! -A type for a handle to a face. +Type for a handle to a face. */ typedef typename DS::Face_handle Face_handle; /*! -A type for a circulator over vertices incident to a given vertex. +Type for a circulator over vertices incident to a given vertex. */ typedef typename DS::Vertex_circulator Vertex_circulator; /*! -A type for a circulator over faces incident to a given vertex. +Type for a circulator over faces incident to a given vertex. */ typedef typename DS::Face_circulator Face_circulator; /*! -A type for a circulator over edges incident to a given vertex. +Type for a circulator over edges incident to a given vertex. */ typedef typename DS::Edge_circulator Edge_circulator; /*! -A type for an iterator over all vertices. +Type for an iterator over all vertices. */ typedef typename DS::Vertex_iterator All_vertices_iterator; /*! -A type for an iterator over all faces. +Type for an iterator over all faces. */ typedef typename DS::Face_iterator All_faces_iterator; /*! -A type for an iterator over all edges. +Type for an iterator over all edges. */ typedef typename DS::Edge_iterator All_edges_iterator; /*! -A type for an iterator over finite vertices. +Type for an iterator over finite vertices. */ typedef unspecified_type Finite_vertices_iterator; /*! -A type for an iterator over finite faces. +Type for an iterator over finite faces. */ typedef unspecified_type Finite_faces_iterator; /*! -A type for an iterator over finite edges. +Type for an iterator over finite edges. */ typedef unspecified_type Finite_edges_iterator; @@ -217,12 +212,12 @@ typedef unspecified_type Finite_edges_iterator; /// @{ /*! -A type for a bidirectional iterator over all input sites. +Type for a bidirectional iterator over all input sites. */ typedef unspecified_type Input_sites_iterator; /*! -A type for a bidirectional iterator over all output sites (the sites +Type for a bidirectional iterator over all output sites (the sites in the Delaunay graph). */ typedef unspecified_type Output_sites_iterator; @@ -235,8 +230,7 @@ typedef unspecified_type Output_sites_iterator; /// @{ /*! -Creates the -segment Delaunay graph using `gt` as geometric traits. +Creates the segment Delaunay graph using `gt` as geometric traits. */ Segment_Delaunay_graph_2(Gt gt=Gt()); @@ -246,8 +240,7 @@ and inserts all sites in the range [`first`, `beyond`). \pre `Input_iterator` must be a model of `InputIterator`. The value type of `Input_iterator` must be either `Point_2` or `Site_2`. */ template< class Input_iterator > -Segment_Delaunay_graph_2(Input_iterator first, Input_iterator beyond, -Gt gt=Gt()); +Segment_Delaunay_graph_2(Input_iterator first, Input_iterator beyond, Gt gt = Gt()); /// @} @@ -255,9 +248,30 @@ Gt gt=Gt()); /// @{ /*! -Returns a reference to the segment Delaunay graph traits object. +Returns a reference to the segment Delaunay graph geometric traits object. */ -Geom_traits geom_traits(); +const Geom_traits& geom_traits() const; + +/*! +Returns a reference to the segment Delaunay graph storage traits object. +*/ +const Storage_traits& storage_traits() const; + +/*! +Returns a reference to the point container object. +*/ +Point_container point_container(); + +/*! +Returns a reference to the +segment Delaunay graph data structure object. +*/ +Data_structure data_structure(); + +/*! +Same as `data_structure()`. It has been added for compliance to the `DelaunayGraph_2` concept. +*/ +Data_structure tds(); /*! Returns the dimension of the segment Delaunay graph. The dimension @@ -305,24 +319,6 @@ Returns a vertex distinct from the `infinite_vertex`. */ Vertex_handle finite_vertex(); -/*! -Returns a reference to the -segment Delaunay graph data structure object. -*/ -Data_structure data_structure(); - -/*! -Same as `data_structure()`. It -has been added for compliance to the `DelaunayGraph_2` concept. -*/ -Data_structure tds(); - -/*! -Returns a reference to -the point container object. -*/ -Point_container point_container(); - /// @} /// \name Finite Face, Edge and Vertex Iterators @@ -533,41 +529,38 @@ bool is_infinite(Edge_circulator ec) const; /// @{ /*! -Inserts the sites in the range -[`first`,`beyond`). The number of additional sites inserted in -the Delaunay graph is returned. `Input_iterator` must be a model of -`InputIterator` and its value type must be -either `Point_2` or `Site_2`. +Iteratively inserts the sites in the range [`first`,`beyond`). +\tparam Input_iterator must be a model of `InputIterator` and its value type must be either `Point_2` or `Site_2`. +\return the number of sites inserted in the Delaunay graph */ template< class Input_iterator > size_type insert(Input_iterator first, Input_iterator beyond); /*! -Same as the previous method. `Input_iterator` must be a model of -`InputIterator` and its value type must be -either `Point_2` or `Site_2`. +Iteratively inserts the sites in the range [`first`,`beyond`). +\tparam Input_iterator must be a model of `InputIterator` and its value type must be either `Point_2` or `Site_2`. +\return the number of sites inserted in the Delaunay graph */ template< class Input_iterator > -size_type insert(Input_iterator first, Input_iterator beyond, Tag_false); +size_type insert(Input_iterator first, Input_iterator beyond, CGAL::Tag_false); /*! Decomposes the range [first,beyond) into a range of input points and a range of input segments that are respectively passed to `insert_segments()` and `insert_points()`. Non-input sites are first random_shuffled and then inserted one by one. -`Input_iterator` must be a model of `InputIterator` and its value type must be -either `Point_2`, `Segment_2` or `Site_2`. -\return the number of sites inserted in the Delaunay graph +\tparam Input_iterator must be a model of `InputIterator` and its value type must be either `Point_2`, `Segment_2` or `Site_2`. +\return the number of sites inserted in the Delaunay graph */ template< class Input_iterator > -size_type insert(Input_iterator first, Input_iterator beyond, Tag_true); +size_type insert(Input_iterator first, Input_iterator beyond, CGAL::Tag_true); /*! Inserts the points in the range [first,beyond) as sites. Note that this function is not guaranteed to insert the points following the order of `PointInputIterator`, as `spatial_sort()` is used to improve efficiency. -\return the number of points inserted in the Delaunay graph \tparam PointIterator must be an input iterator `Point_2` or `Site_2` as value_type. +\return the number of points inserted in the Delaunay graph */ template std::size_t insert_points(PointIterator first, PointIterator beyond); @@ -577,8 +570,8 @@ Inserts the segments in the range [first,beyond) as sites. Note that this function is not guaranteed to insert the segments following the order of `SegmentIterator`, as `spatial_sort()` is used to improve efficiency. -\return the number of segments inserted in the Delaunay graph \tparam SegmentIterator must be an input iterator with `Site_2`, `Segment_2` or `std::pair` as value type. +\return the number of segments inserted in the Delaunay graph */ template std::size_t insert_segments(SegmentIterator first, SegmentIterator beyond); @@ -588,33 +581,30 @@ Same as above except that each segment is given as a pair of indices of the poin in the range [points_first, points_beyond). The indices must start from 0 to `std::distance(points_first, points_beyond)` \tparam PointIterator is an input iterator with `Point_2` as value type. \tparam IndicesIterator is an input iterator with `std::pair` as value type. +\return the number of segments inserted in the Delaunay graph */ template std::size_t insert_segments(PointIterator points_first, PointIterator points_beyond, IndicesIterator indices_first, IndicesIterator indices_beyond); /*! -Inserts the -point `p` in the segment Delaunay graph. If `p` has already -been inserted, then the vertex handle of its already inserted copy is -returned. If `p` has not been inserted yet, the vertex handle of -`p` is returned. +Inserts the point `p` in the segment Delaunay graph. +If `p` has already been inserted, then the vertex handle of its already inserted copy is returned. +If `p` has not been inserted yet, the vertex handle of `p` is returned. */ Vertex_handle insert(Point_2 p); /*! -Inserts `p` in the segment Delaunay graph using the site -associated with `vnear` as an estimate for the nearest neighbor -of `p`. The vertex handle returned has the same semantics as -the vertex handle returned by the method +Inserts `p` in the segment Delaunay graph using the site associated with `vnear` +as an estimate for the nearest neighbor of `p`. +The vertex handle returned has the same semantics as the vertex handle returned by the method `Vertex_handle insert(Point_2 p)`. */ Vertex_handle insert(Point_2 p, Vertex_handle vnear); /*! -Inserts the -closed segment with endpoints `p1` and `p2` in the segment -Delaunay graph. If the segment has already been inserted in the +Inserts the closed segment with endpoints `p1` and `p2` in the segment Delaunay graph. +If the segment has already been inserted in the Delaunay graph then the vertex handle of its already inserted copy is returned. If the segment does not intersect any segment in the existing diagram, the vertex handle corresponding to its @@ -625,37 +615,31 @@ vertex handle to one of its open subsegments is returned. Vertex_handle insert(Point_2 p1, Point_2 p2); /*! -Inserts the segment whose endpoints are `p1` and `p2` -in the segment Delaunay graph using the site -associated with `vnear` as an estimate for the nearest neighbor -of `p1`. The vertex handle returned has the same semantics as the -vertex handle returned by the method +Inserts the segment whose endpoints are `p1` and `p2` in the segment Delaunay graph using the site +associated with `vnear` as an estimate for the nearest neighbor of `p1`. +The vertex handle returned has the same semantics as the vertex handle returned by the method `Vertex_handle insert(Point_2 p1, Point_2 p2)`. */ -Vertex_handle insert(Point_2 p1, Point_2 p2, Vertex_handle -vnear); +Vertex_handle insert(Point_2 p1, Point_2 p2, Vertex_handle vnear); /*! -Inserts the site `s` in the -segment Delaunay graph. The vertex handle returned has the same -semantics as the vertex handle returned by the methods -`Vertex_handle insert(Point_2 p)` and `Vertex_handle insert(Point_2 p1, Point_2 p2)`, depending on whether `s` -represents a point or a segment respectively. +Inserts the site `s` in the segment Delaunay graph. +The vertex handle returned has the same semantics as the vertex handle returned by the methods +`Vertex_handle insert(Point_2 p)` and `Vertex_handle insert(Point_2 p1, Point_2 p2)`, +depending on whether `s` represents a point or a segment respectively. \pre `s.is_input()` must be `true`. */ Vertex_handle insert(Site_2 s); /*! -Inserts `s` in the segment Delaunay graph using the site -associated with `vnear` as an estimate for the nearest neighbor of -`s`, if `s` is a point, or the first endpoint of `s`, if -`s` is a segment. The vertex handle returned has the same -semantics as the vertex handle returned by the method +Inserts `s` in the segment Delaunay graph using the site associated with `vnear` +as an estimate for the nearest neighbor of `s`, if `s` is a point, or the first endpoint of `s`, if +`s` is a segment. +The vertex handle returned has the same semantics as the vertex handle returned by the method `Vertex_handle insert(Site_2 s)`. \pre `s.is_input()` must be `true`. */ -Vertex_handle insert(Site_2 s, Vertex_handle -vnear); +Vertex_handle insert(Site_2 s, Vertex_handle vnear); /// @} @@ -679,8 +663,7 @@ arbitrarily and one of the nearest neighbors of `p` is returned. If there are no sites in the segment Delaunay graph `Vertex_handle()` is returned. */ -Vertex_handle nearest_neighbor(Point_2 p, -Vertex_handle vnear); +Vertex_handle nearest_neighbor(Point_2 p, Vertex_handle vnear); /// @} @@ -787,20 +770,19 @@ combinatorial data structure. void file_output(std::ostream& os); /*! -Reads the state of the -segment Delaunay graph from an input stream. +Reads the state of the segment Delaunay graph from an input stream. */ void file_input(std::istream& is); /*! Writes the current state of the segment Delaunay graph to an output stream. */ -std::ostream& operator<<(std::ostream& os, Segment_Delaunay_graph_2 sdg); +std::ostream& operator<<(std::ostream& os, const Segment_Delaunay_graph_2& sdg); /*! Reads the state of the segment Delaunay graph from an input stream. */ -std::istream& operator>>(std::istream& is, Segment_Delaunay_graph_2 sdg); +std::istream& operator>>(std::istream& is, Segment_Delaunay_graph_2& sdg); /// @} @@ -829,13 +811,12 @@ Clears all contents of the segment Delaunay graph. void clear(); /*! -The segment Delaunay graphs -`other` and `*this` are swapped. For a segment Delaunay graph `sdg`, the operation +The segment Delaunay graphs `other` and `*this` are swapped. +For a segment Delaunay graph `sdg`, the operation `sdg`.`swap(other)` should be preferred to `sdg``= other` or to `sdg``(other)` if `other` is deleted afterwards. */ -void swap(Segment_Delaunay_graph_2 -other); +void swap(Segment_Delaunay_graph_2& other); /// @} diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_face_base_2.h b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_face_base_2.h new file mode 100644 index 00000000000..69fc93cf421 --- /dev/null +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_face_base_2.h @@ -0,0 +1,27 @@ + +namespace CGAL { + +/*! +\ingroup PkgSegmentDelaunayGraph2Ref + +\cgalModels `SegmentDelaunayGraphFaceBase_2` + +The class `Segment_Delaunay_graph_face_base_2` provides a model for the +`SegmentDelaunayGraphFaceBase_2` concept which is the face +base required by the `SegmentDelaunayGraphDataStructure_2` +concept. + +\tparam Gt must be a model of the concept `SegmentDelaunayGraphTraits_2`. + This type must be identical to the template parameter used for `CGAL::Segment_Delaunay_graph_2`. + +\tparam Fb is a face base class from which `Segment_Delaunay_graph_face_base_2` derives. + It must be a model of the `TriangulationFaceBase_2` concept. + It has the default value `CGAL::Triangulation_face_base_2`. +*/ +template< typename Gt, typename Fb > +class Segment_Delaunay_graph_face_base_2 { +public: + +}; /* end Segment_Delaunay_graph_face_base_2 */ + +} /* end namespace CGAL */ diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_filtered_traits_2.h b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_filtered_traits_2.h index 214ca7577bc..d6e9d9726e0 100644 --- a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_filtered_traits_2.h +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_filtered_traits_2.h @@ -8,7 +8,7 @@ The class `Segment_Delaunay_graph_filtered_traits_2` provides a model for the `SegmentDelaunayGraphTraits_2` concept. The class `Segment_Delaunay_graph_filtered_traits_2` uses the filtering technique \cgalCite{cgal:bbp-iayed-01} -to achieve traits for the `Segment_Delaunay_graph_2` +to achieve traits for the `Segment_Delaunay_graph_2` class with efficient and exact predicates given an exact kernel `EK` and a filtering kernel `FK`. The geometric constructions associated provided by this class are equivalent @@ -58,12 +58,11 @@ The default values for the template parameters are as follows: \cgalModels `CopyConstructible` \cgalModels `Assignable` -\sa `Kernel` \sa `SegmentDelaunayGraphTraits_2` \sa `CGAL::Field_tag` \sa `CGAL::Field_with_sqrt_tag` -\sa `CGAL::Segment_Delaunay_graph_2` -\sa `CGAL::Segment_Delaunay_graph_hierarchy_2` +\sa `CGAL::Segment_Delaunay_graph_2` +\sa `CGAL::Segment_Delaunay_graph_hierarchy_2` \sa `CGAL::Segment_Delaunay_graph_traits_2` \sa `CGAL::Segment_Delaunay_graph_traits_without_intersections_2` \sa `CGAL::Segment_Delaunay_graph_filtered_traits_without_intersections_2` @@ -156,7 +155,7 @@ The class `Segment_Delaunay_graph_filtered_traits_without_intersections_2` provi `SegmentDelaunayGraphTraits_2` concept. The class `Segment_Delaunay_graph_filtered_traits_without_intersections_2` uses the filtering technique \cgalCite{cgal:bbp-iayed-01} -to achieve traits for the `Segment_Delaunay_graph_2` +to achieve traits for the `Segment_Delaunay_graph_2` class with efficient and exact predicates given an exact kernel `EK` and a filtering kernel `FK`. The geometric constructions associated provided by this class are equivalent @@ -221,8 +220,8 @@ default value is \sa `SegmentDelaunayGraphTraits_2` \sa `CGAL::Euclidean_ring_tag` \sa `CGAL::Field_with_sqrt_tag` -\sa `CGAL::Segment_Delaunay_graph_2` -\sa `CGAL::Segment_Delaunay_graph_hierarchy_2` +\sa `CGAL::Segment_Delaunay_graph_2` +\sa `CGAL::Segment_Delaunay_graph_hierarchy_2` \sa `CGAL::Segment_Delaunay_graph_traits_2` \sa `CGAL::Segment_Delaunay_graph_traits_without_intersections_2` \sa `CGAL::Segment_Delaunay_graph_filtered_traits_2` diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_hierarchy_2.h b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_hierarchy_2.h index 49b75205b61..450a299f188 100644 --- a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_hierarchy_2.h +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_hierarchy_2.h @@ -5,8 +5,9 @@ namespace CGAL { \ingroup PkgSegmentDelaunayGraph2Ref We provide an alternative to the class -`Segment_Delaunay_graph_2` for the incremental -construction of the segment Delaunay graph. The `Segment_Delaunay_graph_hierarchy_2` class +`Segment_Delaunay_graph_2` for the incremental +construction of the segment Delaunay graph. +The `Segment_Delaunay_graph_hierarchy_2` class maintains a hierarchy of Delaunay graphs. There are two possibilities as to how this hierarchy is constructed. @@ -21,44 +22,49 @@ In the second case the upper levels of the hierarchy contains not only points but also segments. A site that is in level \f$ i\f$, is in level \f$ i+1\f$ with probability \f$ 1/\beta\f$ where \f$ \beta > 1\f$ is some constant. -The difference between the `Segment_Delaunay_graph_2` +The difference between the `Segment_Delaunay_graph_2` class and the `Segment_Delaunay_graph_hierarchy_2` class (both versions of it) is on how the nearest neighbor location is done. Given a point \f$ p\f$ the location is done as follows: at the top most level we find the nearest neighbor of -\f$ p\f$ as in the `Segment_Delaunay_graph_2` class. At +\f$ p\f$ as in the `Segment_Delaunay_graph_2` class. At every subsequent level \f$ i\f$ we use the nearest neighbor found at level \f$ i+1\f$ to find the nearest neighbor at level \f$ i\f$. This is a variant of the corresponding hierarchy for points found in \cgalCite{cgal:d-dh-02}. The details are described in \cgalCite{cgal:k-reisv-04}. -The class has three template parameters. The first and third -have essentially the same semantics as in the -`Segment_Delaunay_graph_2` class. +The class has four template parameters. The first and fourth +have essentially the same semantics as in the `Segment_Delaunay_graph_2` class. \tparam Gt must be a model of the `SegmentDelaunayGraphTraits_2` concept. -\tparam STag The second template +\tparam St must be a model of `SegmentDelaunayGraphStorageTraits_2`. + By default, the storage traits is instantiated by `Segment_Delaunay_graph_storage_traits_2`. + +\tparam STag The third template parameter controls whether or not segments are added in the upper levels of the hierarchy. It's possible values are `Tag_true` and `Tag_false`. If it is set to `Tag_true`, segments are also inserted in the upper levels of the hierarchy. The value `Tag_false` indicates that only points are to be inserted in the upper levels of the hierarchy. The default value for -the second template parameter is `Tag_false`. +the third template parameter is `Tag_false`. \tparam DS must be a model of the `SegmentDelaunayGraphDataStructure_2` concept. However, the vertex base class that is to be used in the segment Delaunay graph data structure must be a model of the `SegmentDelaunayGraphHierarchyVertexBase_2` -concept. The third template parameter defaults to -`Triangulation_data_structure_2< Segment_Delaunay_graph_hierarchy_vertex_base_2< Segment_Delaunay_graph_vertex_base_2 >, Triangulation_face_base_2 >`. - - +concept. The fourth template parameter defaults to: +\code +`CGAL::Triangulation_data_structure_2< + CGAL::Segment_Delaunay_graph_hierarchy_vertex_base_2< + CGAL::Segment_Delaunay_graph_vertex_base_2, + CGAL::Segment_Delaunay_graph_face_base_2 >` +\endcode The `Segment_Delaunay_graph_hierarchy_2` class derives publicly from the -`Segment_Delaunay_graph_2` class. The interface is +`Segment_Delaunay_graph_2` class. The interface is the same with its base class. In the sequel only additional types and methods defined are documented. @@ -66,10 +72,7 @@ and methods defined are documented. \cgalModels `CopyConstructible` \cgalModels `Assignable` -\sa `SegmentDelaunayGraphDataStructure_2` -\sa `SegmentDelaunayGraphTraits_2` -\sa `SegmentDelaunayGraphHierarchyVertexBase_2` -\sa `CGAL::Segment_Delaunay_graph_2` +\sa `CGAL::Segment_Delaunay_graph_2` \sa `CGAL::Triangulation_data_structure_2` \sa `CGAL::Segment_Delaunay_graph_traits_2` \sa `CGAL::Segment_Delaunay_graph_traits_without_intersections_2` @@ -78,14 +81,15 @@ and methods defined are documented. \sa `CGAL::Segment_Delaunay_graph_hierarchy_vertex_base_2` */ -template< typename Gt, typename STag, typename DS > -class Segment_Delaunay_graph_hierarchy_2 : public CGAL::Segment_Delaunay_graph_2 { +template< typename Gt, typename St, typename STag, typename DS > +class Segment_Delaunay_graph_hierarchy_2 + : public CGAL::Segment_Delaunay_graph_2 { public: /// \name Types /// `Segment_Delaunay_graph_hierarchy_2` introduces the following /// types in addition to those introduced by its base class -/// `Segment_Delaunay_graph_2`. +/// `Segment_Delaunay_graph_2`. /// @{ /*! @@ -97,7 +101,7 @@ typedef STag Segments_in_hierarchy_tag; /*! A type for the base class. */ -typedef CGAL::Segment_Delaunay_graph_2 Base; +typedef CGAL::Segment_Delaunay_graph_2 Base; /// @} @@ -110,8 +114,7 @@ typedef CGAL::Segment_Delaunay_graph_2 Base; Creates a hierarchy of segment Delaunay graphs using `gt` as geometric traits. */ -Segment_Delaunay_graph_hierarchy_2(Gt -gt=Gt()); +Segment_Delaunay_graph_hierarchy_2(Gt gt=Gt()); /*! Creates a segment Delaunay graph hierarchy using @@ -121,9 +124,7 @@ model of `InputIterator`. The value type of `Input_iterator` must be either `Point_2` or `Site_2`. */ template< class Input_iterator > -Segment_Delaunay_graph_hierarchy_2(Input_iterator -first, Input_iterator beyond, Gt gt=Gt()); - +Segment_Delaunay_graph_hierarchy_2(Input_iterator first, Input_iterator beyond, Gt gt=Gt()); /// @} @@ -136,13 +137,13 @@ written to the stream (represented through appropriate input sites), as well as the underlying combinatorial hierarchical data structure. \relates Segment_Delaunay_graph_hierarchy_2 */ -std::ostream& operator<<(std::ostream& os, Segment_Delaunay_graph_hierarchy_2 svdh); +std::ostream& operator<<(std::ostream& os, const Segment_Delaunay_graph_hierarchy_2& svdh); /*! Reads the state of the segment Delaunay graph hierarchy from an input stream. \relates Segment_Delaunay_graph_hierarchy_2 */ -std::istream& operator>>(std::istream& is, Segment_Delaunay_graph_hierarchy_2 svdh); +std::istream& operator>>(std::istream& is, const Segment_Delaunay_graph_hierarchy_2& svdh); } /* end namespace CGAL */ diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_hierarchy_vertex_base_2.h b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_hierarchy_vertex_base_2.h index 56005dcd9d7..5ac99ae6de2 100644 --- a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_hierarchy_vertex_base_2.h +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_hierarchy_vertex_base_2.h @@ -7,7 +7,7 @@ namespace CGAL { The class `Segment_Delaunay_graph_hierarchy_vertex_base_2` provides a model for the `SegmentDelaunayGraphHierarchyVertexBase_2` concept, which is the vertex base required by the -`Segment_Delaunay_graph_hierarchy_2` class. +`Segment_Delaunay_graph_hierarchy_2` class. \tparam Vbb must be a model of the `SegmentDelaunayGraphVertexBase_2` concept. @@ -16,9 +16,9 @@ vertex base required by the \sa `SegmentDelaunayGraphVertexBase_2` \sa `SegmentDelaunayGraphHierarchyVertexBase_2` \sa `SegmentDelaunayGraphDataStructure_2` -\sa `CGAL::Segment_Delaunay_graph_vertex_base_2` +\sa `CGAL::Segment_Delaunay_graph_vertex_base_2` \sa `CGAL::Triangulation_data_structure_2` -\sa `CGAL::Segment_Delaunay_graph_hierarchy_2` +\sa `CGAL::Segment_Delaunay_graph_hierarchy_2` */ template< typename Vbb > diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_storage_site_2.h b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_storage_site_2.h index 8d11eb97bdd..596717be5cc 100644 --- a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_storage_site_2.h +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_storage_site_2.h @@ -7,20 +7,13 @@ namespace CGAL { The class `Segment_Delaunay_graph_storage_site_2` is a model for the concept `SegmentDelaunayGraphStorageSite_2`. -\tparam Gt must be a model of the `SegmentDelaunayGraphTraits_2` concept. +\tparam Gt must be a model of the `SegmentDelaunayGraphStorageTraits_2` concept. \cgalModels `SegmentDelaunayGraphStorageSite_2` -\sa `SegmentDelaunayGraphSite_2` -\sa `SegmentDelaunayGraphTraits_2` \sa `CGAL::Segment_Delaunay_graph_site_2` -\sa `CGAL::Segment_Delaunay_graph_traits_2` -\sa `CGAL::Segment_Delaunay_graph_traits_without_intersections_2` -\sa `CGAL::Segment_Delaunay_graph_filtered_traits_2` -\sa `CGAL::Segment_Delaunay_graph_filtered_traits_without_intersections_2` - */ -template< typename Gt > +template< typename St > class Segment_Delaunay_graph_storage_site_2 { public: @@ -31,9 +24,9 @@ public: /// @{ /*! -A type for the template parameter `Gt`. +A type for the template parameter `St`. */ -typedef Gt Geom_traits; +typedef St Storage_traits; /// @} diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_storage_traits_2.h b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_storage_traits_2.h new file mode 100644 index 00000000000..8fb333abcc0 --- /dev/null +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_storage_traits_2.h @@ -0,0 +1,34 @@ +namespace CGAL { + +/*! +\ingroup PkgSegmentDelaunayGraph2Ref + +The class `Segment_Delaunay_graph_storage_traits_2` provides a model for the +`SegmentDelaunayGraphStorageTraits_2` concept. + +To avoid redundancy in the storage of points, the input points of a segment Delaunay graph +are stored in a container, and the various types of sites (input points and segments, +points of intersection, subsegments with one or two points of intersection as endpoints) +only store handles to the points in the container. + +See section \ref Segment_Delaunay_graph_2StronglyIntersecting for more information. + +\tparam Gt must be a model of the concept `SegmentDelaunayGraphTraits_2`. + +\cgalModels `SegmentDelaunayGraphStorageTraits_2` + +\sa `CGAL::Segment_Delaunay_graph_hierarchy_2` +\sa `CGAL::Segment_Delaunay_graph_traits_without_intersections_2` +\sa `CGAL::Segment_Delaunay_graph_filtered_traits_2` +\sa `CGAL::Segment_Delaunay_graph_filtered_traits_without_intersections_2` +*/ +template +class Segment_Delaunay_graph_storage_traits_2 +{ +public: + /*! + */ + typedef unspecified_type Storage_site_2; +}; + +} //namespace CGAL diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_traits_2.h b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_traits_2.h index c27eef36376..1dead711c35 100644 --- a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_traits_2.h +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_traits_2.h @@ -28,8 +28,8 @@ part). \sa `SegmentDelaunayGraphTraits_2` \sa `CGAL::Field_tag` \sa `CGAL::Field_with_sqrt_tag` -\sa `CGAL::Segment_Delaunay_graph_2` -\sa `CGAL::Segment_Delaunay_graph_hierarchy_2` +\sa `CGAL::Segment_Delaunay_graph_2` +\sa `CGAL::Segment_Delaunay_graph_hierarchy_2` \sa `CGAL::Segment_Delaunay_graph_traits_without_intersections_2` \sa `CGAL::Segment_Delaunay_graph_filtered_traits_2` \sa `CGAL::Segment_Delaunay_graph_filtered_traits_without_intersections_2` @@ -101,8 +101,8 @@ part). \sa `SegmentDelaunayGraphTraits_2` \sa `CGAL::Euclidean_ring_tag` \sa `CGAL::Field_with_sqrt_tag` -\sa `CGAL::Segment_Delaunay_graph_2` -\sa `CGAL::Segment_Delaunay_graph_hierarchy_2` +\sa `CGAL::Segment_Delaunay_graph_2` +\sa `CGAL::Segment_Delaunay_graph_hierarchy_2` \sa `CGAL::Segment_Delaunay_graph_traits_2` \sa `CGAL::Segment_Delaunay_graph_filtered_traits_2` \sa `CGAL::Segment_Delaunay_graph_filtered_traits_without_intersections_2` diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_vertex_base_2.h b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_vertex_base_2.h index ed3e1069c1e..b7317d7aef1 100644 --- a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_vertex_base_2.h +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_vertex_base_2.h @@ -4,33 +4,23 @@ namespace CGAL { /*! \ingroup PkgSegmentDelaunayGraph2Ref +\cgalModels `SegmentDelaunayGraphVertexBase_2` + The class `Segment_Delaunay_graph_vertex_base_2` provides a model for the `SegmentDelaunayGraphVertexBase_2` concept which is the vertex base required by the `SegmentDelaunayGraphDataStructure_2` concept. -\tparam Gt must be a model of the concept `SegmentDelaunayGraphTraits_2`. -\tparam SSTag indicates whether -or not to use the simple storage site that does not support -intersecting segments, or the full storage site, that supports -intersecting segments. The possible values are `Tag_true` -and `Tag_false`. `Tag_true` indicates that the -full storage site is to be used, whereas `Tag_false` -indicates that the simple storage site is to be used. +\tparam St must be a model of the concept `SegmentDelaunayGraphStorageTraits_2`. + This type must be template parameter used for `CGAL::Segment_Delaunay_graph_2`. -\cgalModels `SegmentDelaunayGraphVertexBase_2` - -\sa `SegmentDelaunayGraphVertexBase_2` -\sa `SegmentDelaunayGraphDataStructure_2` -\sa `SegmentDelaunayGraphTraits_2` -\sa `CGAL::Triangulation_data_structure_2` -\sa `CGAL::Segment_Delaunay_graph_traits_2` -\sa `CGAL::Segment_Delaunay_graph_traits_without_intersections_2` -\sa `CGAL::Segment_Delaunay_graph_filtered_traits_2` -\sa `CGAL::Segment_Delaunay_graph_filtered_traits_without_intersections_2` +\tparam Vb is a vertex base class from which `Segment_Delaunay_graph_vertex_base_2` derives. + It must be a model of the `TriangulationVertexBase_2` concept. + It has the default value `CGAL::Triangulation_vertex_base_2`. +\sa `CGAL::Segment_Delaunay_graph_hierarchy_vertex_base_2` */ -template< typename Gt, typename SSTag > +template< typename St, typename Vb > class Segment_Delaunay_graph_vertex_base_2 { public: diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphFaceBase_2.h b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphFaceBase_2.h new file mode 100644 index 00000000000..8837bc14b74 --- /dev/null +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphFaceBase_2.h @@ -0,0 +1,22 @@ + +/*! +\ingroup PkgSegmentDelaunayGraph2Concepts +\cgalConcept + +The concept `SegmentDelaunayGraphFaceBase_2` describes the +requirements for the face base class of the +`SegmentDelaunayGraphDataStructure_2` concept. + +\cgalRefines `TriangulationFaceBase_2` + +\cgalHasModel `CGAL::Segment_Delaunay_graph_face_base_2` + +\sa `SegmentDelaunayGraphDataStructure_2` +\sa `SegmentDelaunayGraphTraits_2` +\sa `CGAL::Triangulation_data_structure_2` +*/ +class SegmentDelaunayGraphFaceBase_2 { +public: + +}; /* end SegmentDelaunayGraphFaceBase_2 */ + diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphHierarchyVertexBase_2.h b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphHierarchyVertexBase_2.h index e55017d68e7..626239edae2 100644 --- a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphHierarchyVertexBase_2.h +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphHierarchyVertexBase_2.h @@ -26,13 +26,13 @@ The `SegmentDelaunayGraphHierarchyVertexBase_2` concept does not introduce any constructors in addition to those of the `SegmentDelaunayGraphVertexBase_2` concept. -\cgalHasModel CGAL::Segment_Delaunay_graph_hierarchy_vertex_base_2 > +\cgalHasModel CGAL::Segment_Delaunay_graph_hierarchy_vertex_base_2 > \sa `SegmentDelaunayGraphDataStructure_2` \sa `SegmentDelaunayGraphVertexBase_2` -\sa `CGAL::Segment_Delaunay_graph_hierarchy_2` +\sa `CGAL::Segment_Delaunay_graph_hierarchy_2` \sa `CGAL::Triangulation_data_structure_2` -\sa `CGAL::Segment_Delaunay_graph_vertex_base_2` +\sa `CGAL::Segment_Delaunay_graph_vertex_base_2` \sa `CGAL::Segment_Delaunay_graph_hierarchy_vertex_base_2` */ diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphSite_2.h b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphSite_2.h index e6dbd01f666..d52818a7e70 100644 --- a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphSite_2.h +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphSite_2.h @@ -51,7 +51,7 @@ typedef unspecified_type RT; /// \name Creation /// In addition to the default and copy constructors the following -/// static methods are available for constructing sites: +/// static methods must be available for constructing sites: /// @{ /*! diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphStorageTraits_2.h b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphStorageTraits_2.h new file mode 100644 index 00000000000..63d1ae08db2 --- /dev/null +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphStorageTraits_2.h @@ -0,0 +1,92 @@ + +/*! +\ingroup PkgSegmentDelaunayGraph2Concepts +\cgalConcept + +The concept `SegmentDelaunayGraphStorageTraits_2` provides the +requirements for the storage traits of a segment Delaunay graph. + +To avoid redundancy in the storage of points, the input points of a segment Delaunay graph +are stored in a container, and the various types of sites (input points and segments, +points of intersection, subsegments with one or two points of intersection as endpoints) +only store handles to the points in the container. + +See section \ref Segment_Delaunay_graph_2StronglyIntersecting for more information. + +\cgalRefines `DefaultConstructible` +\cgalRefines `CopyConstructible` +\cgalRefines `Assignable` + +\cgalHasModel `CGAL::Segment_Delaunay_graph_storage_traits_2` + +\sa `SegmentDelaunayGraphTraits_2` +*/ + +class SegmentDelaunayGraphStorageTraits_2 { +public: + +/// \name Types +/// @{ + + /*! + The geometric traits type. It must be a model of `SegmentDelaunayGraphTraits_2`. + */ + typedef unspecified_type Geom_traits; + + /*! + A container of unique points, used to associate a unique handle to each + unique input geometric position. + */ + typedef std::set Point_container; + + /*! + */ + typedef Point_container::iterator Point_handle; + + /*! + */ + typedef Point_container::const_iterator const_Point_handle; + + /*! + Type for the storage site. It must be a model of `SegmentDelaunayGraphStorageSite_2`. + */ + typedef unspecified_type Storage_site_2; + + /*! + Type of the storage site construction functor. + */ + typedef CGAL::SegmentDelaunayGraph_2::Construct_storage_site_2 Construct_storage_site_2; + +/// @} + +/// \name Creation +/// @{ + + /*! + Constructor. + */ + SegmentDelaunayGraphStorageTraits_2(const Geom_traits& gt = Geom_traits()); + +/// @} + +/// \name Access Functions +/// @{ + + /*! + returns the geometric traits. + */ + const Geom_traits& geom_traits() const; + +/// @} + +/// \name Constructions +/// @{ + + /*! + returns a functor of type `Construct_storage_site_2`. + */ + Construct_storage_site_2 construct_storage_site_2_object() const +/// @} + +}; /* end SegmentDelaunayGraphStorageTraits_2 */ + diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphTraits_2.h b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphTraits_2.h index 240688dd27f..677d942fe8f 100644 --- a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphTraits_2.h +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphTraits_2.h @@ -1,14 +1,15 @@ /*! \ingroup PkgSegmentDelaunayGraph2Concepts + \cgalConcept \cgalRefines `TriangulationTraits_2` The concept `SegmentDelaunayGraphTraits_2` provides the traits -requirements for the `CGAL::Segment_Delaunay_graph_2` and -`CGAL::Segment_Delaunay_graph_hierarchy_2` classes. In -particular, it provides a type `Site_2`, which must be a model of +requirements for the `CGAL::Segment_Delaunay_graph_2` and +`CGAL::Segment_Delaunay_graph_hierarchy_2` classes. +In particular, it provides a type `Site_2`, which must be a model of the concept `SegmentDelaunayGraphSite_2`. It also provides constructions for sites and several function object types for the predicates. @@ -19,8 +20,8 @@ types for the predicates. \cgalHasModel `CGAL::Segment_Delaunay_graph_filtered_traits_without_intersections_2` \sa `SegmentDelaunayGraphSite_2` -\sa `CGAL::Segment_Delaunay_graph_2` -\sa `CGAL::Segment_Delaunay_graph_hierarchy_2` +\sa `CGAL::Segment_Delaunay_graph_2` +\sa `CGAL::Segment_Delaunay_graph_hierarchy_2` \sa `CGAL::Segment_Delaunay_graph_traits_2` \sa `CGAL::Segment_Delaunay_graph_traits_without_intersections_2` \sa `CGAL::Segment_Delaunay_graph_filtered_traits_2` diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphVertexBase_2.h b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphVertexBase_2.h index 639b99e3b13..4285991f5db 100644 --- a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphVertexBase_2.h +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphVertexBase_2.h @@ -11,19 +11,15 @@ requirements for the vertex base class of the site of the segment Delaunay graph and provides access to one of its incident faces through a `Face_handle`. -\cgalHasModel `CGAL::Segment_Delaunay_graph_vertex_base_2` +\cgalHasModel `CGAL::Segment_Delaunay_graph_vertex_base_2` -\sa `SegmentDelaunayGraphDataStructure_2` \sa `SegmentDelaunayGraphTraits_2` \sa `SegmentDelaunayGraphSite_2` \sa `SegmentDelaunayGraphStorageSite_2` -\sa `CGAL::Segment_Delaunay_graph_vertex_base_2` \sa `CGAL::Segment_Delaunay_graph_site_2` \sa `CGAL::Segment_Delaunay_graph_storage_site_2` \sa `CGAL::Triangulation_data_structure_2` - */ - class SegmentDelaunayGraphVertexBase_2 { public: @@ -31,46 +27,40 @@ public: /// @{ /*! -A type for the geometric traits that defines -the site. \pre The type `Geom_traits` must define the type `Site_2`. +A type for the geometric traits that defines the site. +\pre The type `Geom_traits` must define the type `Site_2`. */ typedef unspecified_type Geom_traits; /*! -A type for the site. This type must coincide -with the type `Geom_traits::Site_2`. +A type for the site. This type must coincide with the type `Geom_traits::Site_2`. */ typedef unspecified_type Site_2; /*! -A type that indicates what kind of -storage type to use. `Storage_site_tag` must either be -`CGAL::Tag_true` or `CGAL::Tag_false`. +A type that indicates what kind of storage type to use. +`Storage_site_tag` must either be `CGAL::Tag_true` or `CGAL::Tag_false`. */ typedef unspecified_type Storage_site_tag; /*! -A type for the internal representation -of sites. This type must satisfy the requirements of the concept -`SegmentDelaunayGraphStorageSite_2`. +A type for the internal representation of sites. +This type must satisfy the requirements of the concept `SegmentDelaunayGraphStorageSite_2`. */ typedef unspecified_type Storage_site_2; /*! -A type for the -underlying data structure, to which the vertex belongs to. +A type for the underlying data structure, to which the vertex belongs to. */ typedef unspecified_type Data_structure; /*! -A type for the vertex handle of the -segment Delaunay graph data structure. +A type for the vertex handle of the segment Delaunay graph data structure. */ typedef unspecified_type Vertex_handle; /*! -A type for the face handle of the -segment Delaunay graph data structure. +A type for the face handle of the segment Delaunay graph data structure. */ typedef unspecified_type Face_handle; @@ -82,18 +72,15 @@ typedef unspecified_type Face_handle; /// @{ /*! -Constructs a vertex associated with the site represented by the -storage site `ss`. +Constructs a vertex associated with the site represented by the storage site `ss`. */ -SegmentDelaunayGraphVertexBase_2(Storage_site_2 ss); +SegmentDelaunayGraphVertexBase_2(const Storage_site_2& ss); /*! -Constructs a vertex associated with -the site represented by the storage site `ss`, +Constructs a vertex associated with the site represented by the storage site `ss`, and pointing to the face associated with the face handle `f`. */ -SegmentDelaunayGraphVertexBase_2(Storage_site_2 ss, -Face_handle f); +SegmentDelaunayGraphVertexBase_2(const Storage_site_2& ss, Face_handle f); /// @} @@ -103,7 +90,7 @@ Face_handle f); /*! Returns the storage site representing the site. */ -Storage_site_2 storage_site(); +const Storage_site_2& storage_site(); /*! Returns the site. @@ -123,7 +110,7 @@ Face_handle face(); /*! Sets the storage site. */ -void set_site(Storage_site_2 ss); +void set_site(const Storage_site_2& ss); /*! Sets the incident face. diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/PackageDescription.txt b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/PackageDescription.txt index 0c74e16e383..d10645a2c72 100644 --- a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/PackageDescription.txt +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/PackageDescription.txt @@ -20,7 +20,7 @@ \cgalPkgShortInfoEnd \cgalPkgDescriptionEnd -\cgal provides the class `CGAL::Segment_Delaunay_graph_2` for +\cgal provides the class `CGAL::Segment_Delaunay_graph_2` for computing the 2D Delaunay graph of segments and points. The two template parameters must be models of the `SegmentDelaunayGraphTraits_2` and @@ -44,6 +44,7 @@ the class - `SegmentDelaunayGraphSite_2` - `SegmentDelaunayGraphStorageSite_2` +- `SegmentDelaunayGraphStorageTraits_2` - `SegmentDelaunayGraphDataStructure_2` - `SegmentDelaunayGraphVertexBase_2` - `SegmentDelaunayGraphTraits_2` @@ -51,15 +52,17 @@ the class \cgalCRPSection{Classes} -- `CGAL::Segment_Delaunay_graph_2` +- `CGAL::Segment_Delaunay_graph_2` - `CGAL::Segment_Delaunay_graph_site_2` - `CGAL::Segment_Delaunay_graph_storage_site_2` -- `CGAL::Segment_Delaunay_graph_vertex_base_2` +- `CGAL::Segment_Delaunay_graph_storage_traits_2` +- `CGAL::Segment_Delaunay_graph_vertex_base_2` +- `CGAL::Segment_Delaunay_graph_face_base_2` - `CGAL::Segment_Delaunay_graph_traits_2` - `CGAL::Segment_Delaunay_graph_traits_without_intersections_2` - `CGAL::Segment_Delaunay_graph_filtered_traits_2` - `CGAL::Segment_Delaunay_graph_filtered_traits_without_intersections_2` -- `CGAL::Segment_Delaunay_graph_hierarchy_2` +- `CGAL::Segment_Delaunay_graph_hierarchy_2` - `CGAL::Segment_Delaunay_graph_hierarchy_vertex_base_2` */ diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Segment_Delaunay_graph_2.txt b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Segment_Delaunay_graph_2.txt index 03cf5c807c3..306fa9e2a91 100644 --- a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Segment_Delaunay_graph_2.txt +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Segment_Delaunay_graph_2.txt @@ -294,8 +294,8 @@ points of intersection. To avoid this redundancy, input points are stored in a container, and the various types of sites (input points and segments, points of intersection, subsegments with one or two points of intersection as endpoints) only store handles to the points -in the container. This is achieved by the -`Segment_Delaunay_graph_storage_site_2` class which is a +in the container. This is achieved with the +`Segment_Delaunay_graph_storage_site_2` class, which is a model of the corresponding concept: `SegmentDelaunayGraphStorageSite_2`. This concept enforces a site to be represented by up to 6 handles (which are very lightweight @@ -449,9 +449,8 @@ class is used, the possible values are `Field_with_sqrt_tag` and \section secsdg2hierarchy The Segment Delaunay Graph Hierarchy -The -`Segment_Delaunay_graph_hierarchy_2` class is the analogue -of the `Triangulation_hierarchy_2` or the +The `Segment_Delaunay_graph_hierarchy_2` +class is the analogue of the `Triangulation_hierarchy_2` or the `Apollonius_graph_hierarchy_2` classes, applied to the segment Delaunay graph. It consists of a hierarchy of segment Delaunay graphs constructed in a manner analogous to the @@ -480,9 +479,9 @@ Delaunay graphs. If `SSTag` is set to `true`, we have segment Delaunay graphs at all levels of the hierarchy. The class -`Segment_Delaunay_graph_hierarchy_2` +`Segment_Delaunay_graph_hierarchy_2` has exactly the same interface and functionality as the -`Segment_Delaunay_graph_2` +`Segment_Delaunay_graph_2` class. Using the segment Delaunay graph hierarchy involves an additional cost in space and time for maintaining the hierarchy. Our experiments have shown that it usually pays off to use the hierarchy diff --git a/Segment_Delaunay_graph_2/include/CGAL/Segment_Delaunay_graph_vertex_base_2.h b/Segment_Delaunay_graph_2/include/CGAL/Segment_Delaunay_graph_vertex_base_2.h index b7876255e4b..4e4d9d989e6 100644 --- a/Segment_Delaunay_graph_2/include/CGAL/Segment_Delaunay_graph_vertex_base_2.h +++ b/Segment_Delaunay_graph_2/include/CGAL/Segment_Delaunay_graph_vertex_base_2.h @@ -22,15 +22,15 @@ #include -#include +#include #include #include - - namespace CGAL { -template < class STraits, class Vb = Triangulation_ds_vertex_base_2<> > +template < class STraits, + class Vb = Triangulation_vertex_base_2< + typename STraits::Geom_traits> > class Segment_Delaunay_graph_vertex_base_2 : public Vb { diff --git a/TDS_2/doc/TDS_2/CGAL/Triangulation_data_structure_2.h b/TDS_2/doc/TDS_2/CGAL/Triangulation_data_structure_2.h index a5af1b6c1f0..4b2569c1607 100644 --- a/TDS_2/doc/TDS_2/CGAL/Triangulation_data_structure_2.h +++ b/TDS_2/doc/TDS_2/CGAL/Triangulation_data_structure_2.h @@ -40,8 +40,6 @@ guarantee the combinatorial validity of the resulting data structure. template< typename VertexBase, typename FaceBase > class Triangulation_data_structure_2 { public: - - /// \name Types /// @{ @@ -60,10 +58,9 @@ public: /// @} -/// \name +/// \name Ranges /// \cgalAdvancedBegin -/// In addition to the interface documented in the concept, -/// the class offers the following types. +/// In addition to the interface documented in the concept, the class offers the following types. /// \cgalAdvancedEnd /// @{ @@ -87,24 +84,24 @@ typedef Compact_container Face_range; /// @{ /*! -Returns a reference to the container of faces. +returns a reference to the container of faces. */ -Face_range & faces() const; +Face_range& faces() const; /*! -Returns a reference to the container of faces. +returns a reference to the container of faces. */ -Face_range & faces(); +Face_range& faces(); /*! -Returns a reference to the container of vertices. +returns a reference to the container of vertices. */ -Vertex_range & vertices() const; +Vertex_range& vertices() const; /*! -Returns a reference to the container of vertices. +returns a reference to the container of vertices. */ -Vertex_range & vertices(); +Vertex_range& vertices(); /// @} @@ -112,67 +109,58 @@ Vertex_range & vertices(); /// @{ /*! -Joins -the vertices that are endpoints of the edge `(f,i)`, and returns -a vertex handle to common vertex (see -Fig.\ \ref figtdssplitjoin). +joins the vertices that are endpoints of the edge `(f,i)`, and returns a vertex handle to common vertex +(see Fig.\ \ref figtdssplitjoin). + \pre `f` must be different from `Face_handle()` and `i` must be `0`, `1` or `2`. */ Vertex_handle join_vertices(Face_handle f, int i); /*! -Joins -the vertices that are endpoints of the edge `e`, and returns -a vertex handle to common vertex. +joins the vertices that are endpoints of the edge `e`, and returns a vertex handle to common vertex. */ Vertex_handle join_vertices(Edge e); /*! -Joins -the vertices that are endpoints of the edge `*eit`, and returns -a vertex handle to common vertex. +joins the vertices that are endpoints of the edge `*eit`, and returns a vertex handle to common vertex. */ Vertex_handle join_vertices(Edge_iterator eit); /*! -Joins -the vertices that are endpoints of the edge `*ec`, and returns -a vertex handle to common vertex. +joins the vertices that are endpoints of the edge `*ec`, and returns a vertex handle to common vertex. */ Vertex_handle join_vertices(Edges_circulator ec); /*! -Splits the vertex `v` into two vertices `v1` and -`v2`. The common faces `f` and `g` of `v1` and -`v2` are created after (in the counter-clockwise sense) the -faces `f1` and `f2`. The 4-tuple `(v1,v2,f,g)` is -returned (see Fig. \ref figtdssplitjoin). +splits the vertex `v` into two vertices `v1` and `v2`. + +The common faces `f` and `g` of `v1` and `v2` are created after (in the counter-clockwise sense) the +faces `f1` and `f2`. The 4-tuple `(v1,v2,f,g)` is returned (see Fig. \ref figtdssplitjoin). + \pre `dimension()` must be equal to `2`, `f1` and `f2` must be different from `Face_handle()` and `v` must be a vertex of both `f1` and `f2`. */ -boost::tuples::tuple -split_vertex(Vertex_handle v, Face_handle f1, Face_handle -f2); +boost::tuples::tuple +split_vertex(Vertex_handle v, Face_handle f1, Face_handle f2); /*! -Inserts -a degree two vertex and two faces adjacent to it that have two common -edges. The edge defined by the face handle `f` and the integer -`i` is duplicated. It returns a handle to the vertex created -(see Fig. \ref figtdsirdeg2). +inserts a degree two vertex and two faces adjacent to it that have two common edges. + +The edge defined by the face handle `f` and the integer `i` is duplicated. It returns a handle +to the vertex created (see Fig. \ref figtdsirdeg2). */ -Vertex_handle insert_degree_2(Face_handle f, int i); +Vertex_handle insert_degree_2(Face_handle f, int i); // @fixme Missing from SDG concept. Remove from here? Picture in Apollonius and SDG? /*! -Removes a degree 2 -vertex and the two faces adjacent to it. The two edges of the star of -`v` that are not incident to it are collapsed -(see Fig. \ref figtdsirdeg2). +removes a degree 2 vertex and the two faces adjacent to it. + +The two edges of the star of `v` that are not incident to it are collapsed (see Fig. \ref figtdsirdeg2). + \pre The degree of `v` must be equal to 2. */ -void remove_degree_2(Vertex_handle v); +void remove_degree_2(Vertex_handle v); // @fixme Missing from SDG concept. Remove from here? Picture in Apollonius and SDG? /// @} }; /* end Triangulation_data_structure_2 */ + } /* end namespace CGAL */ From 60429465817ea884df6748cb5a9cda71d2dadb8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Sun, 6 Dec 2020 12:37:58 +0100 Subject: [PATCH 073/248] Misc fixes --- ...ancingFrontSurfaceReconstructionTraits_3.h | 6 +- .../Advancing_front_surface_reconstruction.h | 4 +- .../CGAL/Segment_Delaunay_graph_2.h | 76 ++++++++++--------- .../PackageDescription.txt | 1 + 4 files changed, 45 insertions(+), 42 deletions(-) diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Concepts/AdvancingFrontSurfaceReconstructionTraits_3.h b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Concepts/AdvancingFrontSurfaceReconstructionTraits_3.h index 54d047f6a0e..458f63668af 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Concepts/AdvancingFrontSurfaceReconstructionTraits_3.h +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Concepts/AdvancingFrontSurfaceReconstructionTraits_3.h @@ -45,7 +45,7 @@ which constructs the vector `q-p`. typedef unspecified_type Construct_vector_3; /*! -A constructor object that must provide the function operators +A constructor object that must provide the function operator `Vector_3 operator()(Vector_3 v, Vector_3 w)`, @@ -54,7 +54,7 @@ which returns the cross product of `v` and `w`. typedef unspecified_type Construct_cross_product_vector_3; /*! -A constructor object that must provide the function operators +A constructor object that must provide the function operator `FT operator()(Vector_3 v, Vector_3 w)`, @@ -104,7 +104,7 @@ which returns the squared radius of the sphere `s`. typedef unspecified_type Compute_squared_radius_3; /*! -A constructor object that must provide the function operators +A constructor object that must provide the function operator `FT operator()(Point_3 p, Point_3 q)`, diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index f8ffee4dd4d..a54eaf9db24 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -275,7 +275,7 @@ namespace CGAL { /*! A bidirectional iterator range which enables to visit all vertices on a boundary. - The value type of the iterator is `Vertex_handle`. + The value type of the iterator is `Vertex_handle`. */ typedef unspecified_type Vertex_on_boundary_range; @@ -1361,7 +1361,7 @@ namespace CGAL { returns the infinite floating value that prevents a facet to be used. */ - FT infinity() const { return std::numeric_limits::infinity(); } + FT infinity() const { return std::numeric_limits::infinity(); } /// @} //--------------------------------------------------------------------- diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_2.h b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_2.h index 4def14e0f8c..55d5ea7bc7f 100644 --- a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_2.h +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_2.h @@ -230,17 +230,19 @@ typedef unspecified_type Output_sites_iterator; /// @{ /*! -Creates the segment Delaunay graph using `gt` as geometric traits. +Creates the segment Delaunay graph using `gt` as geometric traits and `st` as storage traits. */ -Segment_Delaunay_graph_2(Gt gt=Gt()); +Segment_Delaunay_graph_2(Gt gt=Gt(), St st=St()); /*! -Creates the segment Delaunay graph using `gt` as geometric traits +Creates the segment Delaunay graph using `gt` as geometric traits, `st` as storage traits, and inserts all sites in the range [`first`, `beyond`). -\pre `Input_iterator` must be a model of `InputIterator`. The value type of `Input_iterator` must be either `Point_2` or `Site_2`. +\pre `Input_iterator` must be a model of `InputIterator`. +The value type of `Input_iterator` must be either `Point_2` or `Site_2`. */ template< class Input_iterator > -Segment_Delaunay_graph_2(Input_iterator first, Input_iterator beyond, Gt gt = Gt()); +Segment_Delaunay_graph_2(Input_iterator first, Input_iterator beyond, + Gt gt = Gt(), St gt = St()); /// @} @@ -260,18 +262,18 @@ const Storage_traits& storage_traits() const; /*! Returns a reference to the point container object. */ -Point_container point_container(); +const Point_container& point_container() const; /*! Returns a reference to the segment Delaunay graph data structure object. */ -Data_structure data_structure(); +const Data_structure& data_structure() const; /*! Same as `data_structure()`. It has been added for compliance to the `DelaunayGraph_2` concept. */ -Data_structure tds(); +const Data_structure& tds() const; /*! Returns the dimension of the segment Delaunay graph. The dimension @@ -279,45 +281,45 @@ is \f$ -1\f$ if the graph contains no sites, \f$ 0\f$ if the graph contains one site, \f$ 1\f$ if it contains two sites and \f$ 2\f$ if it contains three or more sites. */ -int dimension(); +int dimension() const; /*! Returns the number of finite vertices of the segment Delaunay graph. */ -size_type number_of_vertices(); +size_type number_of_vertices() const; /*! Returns the number of faces (both finite and infinite) of the segment Delaunay graph. */ -size_type number_of_faces(); +size_type number_of_faces() const; /*! Return the number of input sites. */ -size_type number_of_input_sites(); +size_type number_of_input_sites() const; /*! Return the number of output sites. This is equal to the number of vertices in the segment Delaunay graph. */ -size_type number_of_output_sites(); +size_type number_of_output_sites() const; /*! Returns a face incident to the `infinite_vertex`. */ -Face_handle infinite_face(); +Face_handle infinite_face() const; /*! Returns the `infinite_vertex`. */ -Vertex_handle infinite_vertex(); +Vertex_handle infinite_vertex() const; /*! Returns a vertex distinct from the `infinite_vertex`. \pre The number of sites in the segment Delaunay graph must be at least one. */ -Vertex_handle finite_vertex(); +Vertex_handle finite_vertex() const; /// @} @@ -457,39 +459,39 @@ Output_sites_iterator output_sites_end() const; Starts at an arbitrary face incident to `v`. */ -Face_circulator incident_faces(Vertex_handle v); +Face_circulator incident_faces(Vertex_handle v) const; /*! Starts at face `f`. \pre Face `f` is incident to vertex `v`. */ -Face_circulator incident_faces(Vertex_handle v, Face_handle f); +Face_circulator incident_faces(Vertex_handle v, Face_handle f) const; /*! Starts at an arbitrary edge incident to `v`. */ -Edge_circulator incident_edges(Vertex_handle v); +Edge_circulator incident_edges(Vertex_handle v) const; /*! Starts at the first edge of `f` incident to `v`, in counterclockwise order around `v`. \pre Face `f` is incident to vertex `v`. */ -Edge_circulator incident_edges(Vertex_handle v, Face_handle f); +Edge_circulator incident_edges(Vertex_handle v, Face_handle f) const; /*! Starts at an arbitrary vertex incident to `v`. */ -Vertex_circulator incident_vertices(Vertex_handle v); +Vertex_circulator incident_vertices(Vertex_handle v) const; /*! Starts at the first vertex of `f` adjacent to `v` in counterclockwise order around `v`. \pre Face `f` is incident to vertex `v`. */ -Vertex_circulator incident_vertices(Vertex_handle v, Face_handle f); +Vertex_circulator incident_vertices(Vertex_handle v, Face_handle f) const; /// @} @@ -592,7 +594,7 @@ Inserts the point `p` in the segment Delaunay graph. If `p` has already been inserted, then the vertex handle of its already inserted copy is returned. If `p` has not been inserted yet, the vertex handle of `p` is returned. */ -Vertex_handle insert(Point_2 p); +Vertex_handle insert(const Point_2& p); /*! Inserts `p` in the segment Delaunay graph using the site associated with `vnear` @@ -600,7 +602,7 @@ as an estimate for the nearest neighbor of `p`. The vertex handle returned has the same semantics as the vertex handle returned by the method `Vertex_handle insert(Point_2 p)`. */ -Vertex_handle insert(Point_2 p, Vertex_handle vnear); +Vertex_handle insert(const Point_2& p, Vertex_handle vnear); /*! Inserts the closed segment with endpoints `p1` and `p2` in the segment Delaunay graph. @@ -612,7 +614,7 @@ corresponding open segment is returned. Finally, if the segment intersects other segments in the existing Delaunay graph, the vertex handle to one of its open subsegments is returned. */ -Vertex_handle insert(Point_2 p1, Point_2 p2); +Vertex_handle insert(const Point_2& p1, const Point_2& p2); /*! Inserts the segment whose endpoints are `p1` and `p2` in the segment Delaunay graph using the site @@ -620,7 +622,7 @@ associated with `vnear` as an estimate for the nearest neighbor of `p1`. The vertex handle returned has the same semantics as the vertex handle returned by the method `Vertex_handle insert(Point_2 p1, Point_2 p2)`. */ -Vertex_handle insert(Point_2 p1, Point_2 p2, Vertex_handle vnear); +Vertex_handle insert(const Point_2& p1, const Point_2& p2, Vertex_handle vnear); /*! Inserts the site `s` in the segment Delaunay graph. @@ -629,7 +631,7 @@ The vertex handle returned has the same semantics as the vertex handle returned depending on whether `s` represents a point or a segment respectively. \pre `s.is_input()` must be `true`. */ -Vertex_handle insert(Site_2 s); +Vertex_handle insert(const Site_2& s); /*! Inserts `s` in the segment Delaunay graph using the site associated with `vnear` @@ -639,7 +641,7 @@ The vertex handle returned has the same semantics as the vertex handle returned `Vertex_handle insert(Site_2 s)`. \pre `s.is_input()` must be `true`. */ -Vertex_handle insert(Site_2 s, Vertex_handle vnear); +Vertex_handle insert(const Site_2& s, Vertex_handle vnear); /// @} @@ -653,7 +655,7 @@ finds the site whose segment Voronoi diagram cell contains of `p` is returned. If there are no sites in the segment Delaunay graph `Vertex_handle()` is returned. */ -Vertex_handle nearest_neighbor(Point_2 p); +Vertex_handle nearest_neighbor(const Point_2& p) const; /*! Finds the nearest neighbor of the point @@ -663,7 +665,7 @@ arbitrarily and one of the nearest neighbors of `p` is returned. If there are no sites in the segment Delaunay graph `Vertex_handle()` is returned. */ -Vertex_handle nearest_neighbor(Point_2 p, Vertex_handle vnear); +Vertex_handle nearest_neighbor(const Point_2& p, Vertex_handle vnear) const; /// @} @@ -683,7 +685,7 @@ defined: */ template < class Stream > -Stream& draw_dual(Stream& str); +Stream& draw_dual(Stream& str) const; /*! Draws the segment Voronoi @@ -699,7 +701,7 @@ The following operators must be defined: */ template < class Stream > -Stream& draw_skeleton(Stream& str); +Stream& draw_skeleton(Stream& str) const; /*! Draws the edge `e` of @@ -714,7 +716,7 @@ The following operators must be defined: \pre `e` must be a finite edge. */ template< class Stream > -Stream& draw_dual_edge(Edge e, Stream& str); +Stream& draw_dual_edge(Edge e, Stream& str) const; /*! Draws the edge `*ec` of the segment Voronoi diagram to the stream @@ -729,7 +731,7 @@ The following operators must be defined: \pre `*ec` must be a finite edge. */ template< class Stream > -Stream& draw_dual_edge(Edge_circulator ec, Stream& str); +Stream& draw_dual_edge(Edge_circulator ec, Stream& str) const; /*! Draws the edge `*eit` of the segment Voronoi diagram to the @@ -744,7 +746,7 @@ The following operators must be defined: \pre `*eit` must be a finite edge. */ template< class Stream > -Stream& draw_dual_edge(All_edges_iterator eit, Stream& str); +Stream& draw_dual_edge(All_edges_iterator eit, Stream& str) const; /*! Draws the edge `*eit` of the segment Voronoi diagram to the @@ -758,7 +760,7 @@ The following operators must be defined: `Stream& operator<<(Stream&, Gt::Line_2)` */ template< class Stream > -Stream& draw_dual_edge(Finite_edges_iterator eit, Stream& str); +Stream& draw_dual_edge(Finite_edges_iterator eit, Stream& str) const; /*! Writes the current @@ -798,7 +800,7 @@ Delaunay graph are validated. Negative values of `level` always return true, and values greater than 1 are equivalent to `level` being 1. */ -bool is_valid(bool verbose = false, int level = 1); +bool is_valid(bool verbose = false, int level = 1) const; /// @} diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/PackageDescription.txt b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/PackageDescription.txt index d10645a2c72..b07d2b2a84b 100644 --- a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/PackageDescription.txt +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/PackageDescription.txt @@ -47,6 +47,7 @@ the class - `SegmentDelaunayGraphStorageTraits_2` - `SegmentDelaunayGraphDataStructure_2` - `SegmentDelaunayGraphVertexBase_2` +- `SegmentDelaunayGraphFaceBase_2` - `SegmentDelaunayGraphTraits_2` - `SegmentDelaunayGraphHierarchyVertexBase_2` From 634fe394bad2e1a6f3e5c85488fbed7f31007cdf Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Wed, 30 Dec 2020 19:56:58 +0100 Subject: [PATCH 074/248] Skip filtering on trivial predicates --- .../CGAL/NewKernel_d/Cartesian_LA_functors.h | 6 +++--- .../CGAL/NewKernel_d/Cartesian_filter_K.h | 18 ++++++++++++------ .../CGAL/NewKernel_d/Filtered_predicate2.h | 1 + .../include/CGAL/NewKernel_d/Lazy_cartesian.h | 4 +++- .../CGAL/NewKernel_d/Types/Hyperplane.h | 2 +- .../include/CGAL/NewKernel_d/Types/Sphere.h | 2 +- .../NewKernel_d/function_objects_cartesian.h | 12 ++++++------ .../CGAL/NewKernel_d/functor_properties.h | 2 +- 8 files changed, 28 insertions(+), 19 deletions(-) diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_LA_functors.h b/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_LA_functors.h index b717a80bac4..365760185cd 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_LA_functors.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_LA_functors.h @@ -137,7 +137,7 @@ template struct Compute_cartesian_coordinate { typedef typename Get_type::type RT; typedef typename R::Vector_ first_argument_type; typedef int second_argument_type; - typedef Tag_true Is_exact; + typedef Tag_true Uses_no_arithmetic; typedef decltype(std::declval()[0]) result_type; template @@ -153,7 +153,7 @@ template struct Construct_cartesian_const_iterator { typedef typename R::LA_vector S_; typedef typename R::Point_cartesian_const_iterator result_type; // same as Vector - typedef Tag_true Is_exact; + typedef Tag_true Uses_no_arithmetic; result_type operator()(argument_type const& v,Begin_tag)const{ return S_::vector_begin(v); @@ -282,7 +282,7 @@ template struct PV_dimension { typedef typename R::Vector_ argument_type; typedef int result_type; typedef typename R::LA_vector LA; - typedef Tag_true Is_exact; + typedef Tag_true Uses_no_arithmetic; template result_type operator()(T const& v) const { diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_filter_K.h b/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_filter_K.h index ed164e844da..c02efa6dcc6 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_filter_K.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_filter_K.h @@ -42,7 +42,7 @@ template<> struct Functors_without_division > { }; // FIXME: -// - Is_exact (which should be renamed to Uses_no_arithmetic) predicates should not be filtered +// - Uses_no_arithmetic predicates should not be filtered // - Functors_without_division should be defined near/in the actual functors template < typename Base_, typename AK_, typename EK_, typename Pred_list = typeset_all > @@ -78,18 +78,24 @@ struct Cartesian_filter_K : public Base_ // TODO: only fix some types, based on some criterion? template struct Type : Get_type {}; - template::type, bool=Pred_list::template contains::value> struct Functor : - Inherit_functor {}; - template struct Functor { + template::type>::value> struct Pred_helper { typedef typename Get_functor::type AP; typedef typename Get_functor::type EP; typedef Filtered_predicate2 type; }; + // Less_cartesian_coordinate doesn't usually need filtering + // This fixes the predicate, as opposed to Inherit_functor which would leave it open (is that good?) + template struct Pred_helper : + Get_functor {}; + + template::type, bool=Pred_list::template contains::value> struct Functor : + Inherit_functor {}; + template struct Functor : + Pred_helper {}; + // TODO: // template struct Functor : // Kernel_base::template Functor {}; -// TODO: -// detect when Less_cartesian_coordinate doesn't need filtering }; } //namespace CGAL diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Filtered_predicate2.h b/NewKernel_d/include/CGAL/NewKernel_d/Filtered_predicate2.h index c3d2281ad96..5a0d6f20255 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Filtered_predicate2.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Filtered_predicate2.h @@ -39,6 +39,7 @@ namespace CGAL { // not, or we let all this up to the compiler optimizer to figure out ? // - Some caching could be done at the Point_2 level. +// FIXME: understand and document what the parameter 'Protection' means exactly template class Filtered_predicate2 diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Lazy_cartesian.h b/NewKernel_d/include/CGAL/NewKernel_d/Lazy_cartesian.h index 56ecd5df953..e0bd33da4ca 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Lazy_cartesian.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Lazy_cartesian.h @@ -294,7 +294,9 @@ struct Lazy_cartesian : template struct Functor { typedef typename Get_functor::type FA; typedef typename Get_functor::type FE; - typedef Filtered_predicate2 type; + // Careful if operator< for Interval_nt ever starts using arithmetic... + // Not done directly in Filtered_predicate2 because of C2A + typedef Filtered_predicate2::value> type; }; template struct Functor { typedef Lazy_construction2 type; diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Types/Hyperplane.h b/NewKernel_d/include/CGAL/NewKernel_d/Types/Hyperplane.h index c3c1de8adb9..7cf4f2189ed 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Types/Hyperplane.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Types/Hyperplane.h @@ -127,7 +127,7 @@ template struct Hyperplane_translation { CGAL_FUNCTOR_INIT_IGNORE(Hyperplane_translation) typedef typename Get_type::type Hyperplane; typedef typename Get_type::type result_type; - // TODO: Is_exact? + // TODO: Uses_no_arithmetic? result_type operator()(Hyperplane const&s)const{ return s.translation(); } diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Types/Sphere.h b/NewKernel_d/include/CGAL/NewKernel_d/Types/Sphere.h index 92a5aa65c0b..19d601c6b6d 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Types/Sphere.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Types/Sphere.h @@ -83,7 +83,7 @@ template struct Squared_radius { CGAL_FUNCTOR_INIT_IGNORE(Squared_radius) typedef typename Get_type::type Sphere; typedef typename Get_type::type const& result_type; - // TODO: Is_exact? + // TODO: Uses_no_arithmetic? result_type operator()(Sphere const&s)const{ return s.squared_radius(); } diff --git a/NewKernel_d/include/CGAL/NewKernel_d/function_objects_cartesian.h b/NewKernel_d/include/CGAL/NewKernel_d/function_objects_cartesian.h index 3ab117131dc..605db974423 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/function_objects_cartesian.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/function_objects_cartesian.h @@ -1108,7 +1108,7 @@ template struct Less_point_cartesian_coordinate : private Store_kernel typedef typename Get_functor::type Cc; // TODO: This is_exact thing should be reengineered. // the goal is to have a way to tell: don't filter this - typedef typename CGAL::Is_exact Is_exact; + typedef typename CGAL::Uses_no_arithmetic Uses_no_arithmetic; template result_type operator()(V const&a, W const&b, I i)const{ @@ -1128,7 +1128,7 @@ template struct Compare_point_cartesian_coordinate : private Store_ker typedef typename Get_functor::type Cc; // TODO: This is_exact thing should be reengineered. // the goal is to have a way to tell: don't filter this - typedef typename CGAL::Is_exact Is_exact; + typedef typename CGAL::Uses_no_arithmetic Uses_no_arithmetic; template result_type operator()(V const&a, W const&b, I i)const{ @@ -1148,7 +1148,7 @@ template struct Compare_lexicographically : private Store_kernel { typedef typename Get_functor >::type CI; // TODO: This is_exact thing should be reengineered. // the goal is to have a way to tell: don't filter this - typedef typename CGAL::Is_exact Is_exact; + typedef typename CGAL::Uses_no_arithmetic Uses_no_arithmetic; template result_type operator()(V const&a, W const&b)const{ @@ -1176,7 +1176,7 @@ template struct Less_lexicographically : private Store_kernel { typedef R_ R; typedef typename Get_type::type result_type; typedef typename Get_functor::type CL; - typedef typename CGAL::Is_exact Is_exact; + typedef typename CGAL::Uses_no_arithmetic Uses_no_arithmetic; template result_type operator() (V const&a, W const&b) const { @@ -1194,7 +1194,7 @@ template struct Less_or_equal_lexicographically : private Store_kernel typedef R_ R; typedef typename Get_type::type result_type; typedef typename Get_functor::type CL; - typedef typename CGAL::Is_exact Is_exact; + typedef typename CGAL::Uses_no_arithmetic Uses_no_arithmetic; template result_type operator() (V const&a, W const&b) const { @@ -1214,7 +1214,7 @@ template struct Equal_points : private Store_kernel { typedef typename Get_functor >::type CI; // TODO: This is_exact thing should be reengineered. // the goal is to have a way to tell: don't filter this - typedef typename CGAL::Is_exact Is_exact; + typedef typename CGAL::Uses_no_arithmetic Uses_no_arithmetic; template result_type operator()(V const&a, W const&b)const{ diff --git a/NewKernel_d/include/CGAL/NewKernel_d/functor_properties.h b/NewKernel_d/include/CGAL/NewKernel_d/functor_properties.h index eb2f767c7a2..f8608d9fd4d 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/functor_properties.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/functor_properties.h @@ -24,7 +24,7 @@ namespace CGAL { template \ struct Is_pretty : T::Is_pretty {} -CGAL_STRAWBERRY(Is_exact); +CGAL_STRAWBERRY(Uses_no_arithmetic); CGAL_STRAWBERRY(Is_fast); CGAL_STRAWBERRY(Is_stored); #undef CGAL_STRAWBERRY From caef69cdef5f9fe7c6175fc9ea2e3242f546d997 Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Wed, 30 Dec 2020 23:28:03 +0100 Subject: [PATCH 075/248] Protection parameter of Filtered_predicate2 --- Filtered_kernel/include/CGAL/Filtered_predicate.h | 4 ++++ NewKernel_d/include/CGAL/NewKernel_d/Filtered_predicate2.h | 7 +++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Filtered_kernel/include/CGAL/Filtered_predicate.h b/Filtered_kernel/include/CGAL/Filtered_predicate.h index 63199a63a32..da9e4b1c4fb 100644 --- a/Filtered_kernel/include/CGAL/Filtered_predicate.h +++ b/Filtered_kernel/include/CGAL/Filtered_predicate.h @@ -37,6 +37,10 @@ namespace CGAL { // not, or we let all this up to the compiler optimizer to figure out ? // - Some caching could be done at the Point_2 level. +// Protection is undocumented and currently always true, meaning that it +// assumes a default rounding mode of round-to-nearest. false would correspond +// to a default of round-towards-infinity, so interval arithmetic does not +// require protection but regular code may. template class Filtered_predicate diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Filtered_predicate2.h b/NewKernel_d/include/CGAL/NewKernel_d/Filtered_predicate2.h index 5a0d6f20255..2064af0b986 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Filtered_predicate2.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Filtered_predicate2.h @@ -39,7 +39,11 @@ namespace CGAL { // not, or we let all this up to the compiler optimizer to figure out ? // - Some caching could be done at the Point_2 level. -// FIXME: understand and document what the parameter 'Protection' means exactly +// Protection has a different meaning than in Filtered_predicate, it says +// whether we need to set the rounding mode: some predicates only do +// comparisons and don't need it. Probably this should be done inside this +// class, based on Uses_no_arithmetic, but I have some doubts about C2A, +// converting a long long to Interval_nt requires protection. template class Filtered_predicate2 @@ -88,7 +92,6 @@ public: catch (Uncertain_conversion_exception&) {} } CGAL_BRANCH_PROFILER_BRANCH(tmp); - Protect_FPU_rounding p(CGAL_FE_TONEAREST); return ep(c2e(std::forward(args))...); } }; From ece8478a904413a466a0bd90e8a4d7f4c33f8bc3 Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Thu, 31 Dec 2020 16:23:31 +0100 Subject: [PATCH 076/248] static filter for 2d Side_of_oriented_sphere --- .../NewKernel_d/Cartesian_static_filters.h | 70 +++++++++++++------ 1 file changed, 49 insertions(+), 21 deletions(-) diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_static_filters.h b/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_static_filters.h index 507e4144694..24b35fb4969 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_static_filters.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_static_filters.h @@ -15,37 +15,46 @@ #include #include // bug, should be included by the next one #include +#include #include namespace CGAL { namespace SFA { // static filter adapter // Note that this would be quite a bit simpler without stateful kernels +template struct Adapter_2 { + typedef typename Get_type::type Point; + typedef typename Get_functor::type CC; + typedef typename Get_functor::type Orientation_base; + typedef typename Get_functor::type Side_of_oriented_circle_base; + struct Point_2 { + R_ const&r; CC const&c; Point const& p; + Point_2(R_ const&r_, CC const&c_, Point const&p_):r(r_),c(c_),p(p_){} + decltype(auto) x()const{return c(p,0);} + decltype(auto) y()const{return c(p,1);} + }; + struct Vector_2 {}; + struct Circle_2 {}; + struct Orientation_2 { + typedef typename Get_type::type result_type; + auto operator()(Point_2 const&A, Point_2 const&B, Point_2 const&C)const{ + Point const* t[3]={&A.p,&B.p,&C.p}; + return Orientation_base(A.r)(make_transforming_iterator(t+0),make_transforming_iterator(t+3)); + } + }; + struct Side_of_oriented_circle_2 { + typedef typename Get_type::type result_type; + auto operator()(Point_2 const&A, Point_2 const&B, Point_2 const&C, Point_2 const&D)const{ + Point const* t[3]={&A.p,&B.p,&C.p}; + return Side_of_oriented_circle_base(A.r)(make_transforming_iterator(t+0),make_transforming_iterator(t+3),D.p); + } + }; +}; template struct Orientation_of_points_2 : private Store_kernel { CGAL_FUNCTOR_INIT_STORE(Orientation_of_points_2) typedef typename Get_type::type Point; typedef typename Get_type::type result_type; - typedef typename Get_type::type FT; typedef typename Get_functor::type CC; - typedef typename Get_functor::type Orientation_base; - // TODO: Move this out for easy reuse - struct Adapter { - struct Point_2 { - R_ const&r; CC const&c; Point const& p; - Point_2(R_ const&r_, CC const&c_, Point const&p_):r(r_),c(c_),p(p_){} - // use result_of instead? - typename CC::result_type x()const{return c(p,0);} - typename CC::result_type y()const{return c(p,1);} - }; - struct Vector_2 {}; - struct Circle_2 {}; - struct Orientation_2 { - typedef typename Orientation_of_points_2::result_type result_type; - result_type operator()(Point_2 const&A, Point_2 const&B, Point_2 const&C)const{ - Point const* t[3]={&A.p,&B.p,&C.p}; - return Orientation_base(A.r)(make_transforming_iterator(t+0),make_transforming_iterator(t+3)); - } - }; - }; + typedef Adapter_2 Adapter; template result_type operator()(Iter f, Iter CGAL_assertion_code(e))const{ CC c(this->kernel()); Point const& A=*f; @@ -56,6 +65,22 @@ template struct Orientation_of_points_2 : private Store_k return typename internal::Static_filters_predicates::Orientation_2()(P(this->kernel(),c,A),P(this->kernel(),c,B),P(this->kernel(),c,C)); } }; +template struct Side_of_oriented_sphere_2 : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Side_of_oriented_sphere_2) + typedef typename Get_type::type Point; + typedef typename Get_type::type result_type; + typedef typename Get_functor::type CC; + typedef Adapter_2 Adapter; + template result_type operator()(Iter f, Iter CGAL_assertion_code(e), Point const& D)const{ + CC c(this->kernel()); + Point const& A=*f; + Point const& B=*++f; + Point const& C=*++f; + CGAL_assertion(++f==e); + typedef typename Adapter::Point_2 P; + return typename internal::Static_filters_predicates::Side_of_oriented_circle_2()(P(this->kernel(),c,A),P(this->kernel(),c,B),P(this->kernel(),c,C),P(this->kernel(),c,D)); + } +}; } template @@ -80,6 +105,9 @@ struct Cartesian_static_filters, R_, Derived_> : public R_ { // >::type type; }; + template struct Functor { + typedef SFA::Side_of_oriented_sphere_2 type; + }; }; } From 986bb7ff731604581c5bf49067cc76b07c6a8ebe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 6 Jan 2021 11:27:08 +0100 Subject: [PATCH 077/248] remove mentions to python2 --- Documentation/doc/CMakeLists.txt | 2 +- Documentation/doc/scripts/generate_how_to_cite.py | 2 +- Documentation/doc/scripts/html_output_post_processing.py | 2 +- Documentation/doc/scripts/pkglist_filter.py | 2 +- Documentation/doc/scripts/testsuite.py | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Documentation/doc/CMakeLists.txt b/Documentation/doc/CMakeLists.txt index 94fc5649ef8..00d20d34bae 100644 --- a/Documentation/doc/CMakeLists.txt +++ b/Documentation/doc/CMakeLists.txt @@ -27,7 +27,7 @@ else() endif() find_package(Doxygen) -find_package(PythonInterp 2.6.7) +find_package(PythonInterp) if(NOT DOXYGEN_FOUND) message(WARNING "Cannot build the documentation without Doxygen!") diff --git a/Documentation/doc/scripts/generate_how_to_cite.py b/Documentation/doc/scripts/generate_how_to_cite.py index caad53d6392..2120824773e 100644 --- a/Documentation/doc/scripts/generate_how_to_cite.py +++ b/Documentation/doc/scripts/generate_how_to_cite.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python # coding: utf8 import re diff --git a/Documentation/doc/scripts/html_output_post_processing.py b/Documentation/doc/scripts/html_output_post_processing.py index f07bd3d2ced..4771a010ae5 100755 --- a/Documentation/doc/scripts/html_output_post_processing.py +++ b/Documentation/doc/scripts/html_output_post_processing.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python # Copyright (c) 2012 GeometryFactory (France). All rights reserved. # All rights reserved. # diff --git a/Documentation/doc/scripts/pkglist_filter.py b/Documentation/doc/scripts/pkglist_filter.py index af99777d529..92208a6f4d9 100755 --- a/Documentation/doc/scripts/pkglist_filter.py +++ b/Documentation/doc/scripts/pkglist_filter.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python3 +#!/usr/bin/env python import codecs import re diff --git a/Documentation/doc/scripts/testsuite.py b/Documentation/doc/scripts/testsuite.py index 1fda305b1e0..255191e61c4 100755 --- a/Documentation/doc/scripts/testsuite.py +++ b/Documentation/doc/scripts/testsuite.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python # Copyright (c) 2012 GeometryFactory (France). All rights reserved. # All rights reserved. # From 1623097ed675664eef0e51bd3e57552c5596cc5d Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 30 Dec 2020 14:48:04 +0100 Subject: [PATCH 078/248] Don't force cmake options if INIT_FILE is defined --- .../cgal_test_with_cmake | 44 ++++++++++++------- .../test/Surface_sweep_2/cgal_test_base | 38 ++++++++++------ 2 files changed, 54 insertions(+), 28 deletions(-) diff --git a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/cgal_test_with_cmake b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/cgal_test_with_cmake index c1183a846d8..099686a5d81 100755 --- a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/cgal_test_with_cmake +++ b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/cgal_test_with_cmake @@ -128,23 +128,37 @@ TRIM=35 configure() { echo "Configuring... " - rm -rf CMakeCache.txt CMakeFiles/ - echo "cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} "$CMAKE_GENERATOR" -DRUNNING_CGAL_AUTO_TEST=TRUE \ - -DCGAL_DIR=\"$CGAL_DIR\" \ - -DCGAL_CXX_FLAGS:STRING=\"$TESTSUITE_CXXFLAGS -I../../include\" \ - -DCGAL_EXE_LINKER_FLAGS=\"$TESTSUITE_LDFLAGS\" \ - -DCMAKE_BUILD_TYPE=NOTFOUND \ - ." - if eval 'cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} "$CMAKE_GENERATOR" -DRUNNING_CGAL_AUTO_TEST=TRUE \ - -DCGAL_DIR="$CGAL_DIR" \ - -DCGAL_CXX_FLAGS:STRING="$TESTSUITE_CXXFLAGS -I../../include" \ - -DCGAL_EXE_LINKER_FLAGS="$TESTSUITE_LDFLAGS" \ - -DCMAKE_BUILD_TYPE=NOTFOUND \ - .' ; then + if [ -f "$INIT_FILE" ] + then + if eval 'cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} "$CMAKE_GENERATOR" -DRUNNING_CGAL_AUTO_TEST=TRUE \ + -DCGAL_DIR="$CGAL_DIR" \ + -DCGAL_CXX_FLAGS:STRING="$CGAL_CXX_FLAGS $TESTSUITE_CXXFLAGS -I../../include" \ + -DCGAL_EXE_LINKER_FLAGS="$CGAL_EXE_LINKER_FLAGS $TESTSUITE_LDFLAGS" \ + .' ; then - echo " successful configuration" >> $ERRORFILE + echo " successful configuration" >> $ERRORFILE + else + echo " ERROR: configuration" >> $ERRORFILE + fi else - echo " ERROR: configuration" >> $ERRORFILE + rm -rf CMakeCache.txt CMakeFiles/ + echo "cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} "$CMAKE_GENERATOR" -DRUNNING_CGAL_AUTO_TEST=TRUE \ + - DCGAL_DIR=\"$CGAL_DIR\" \ + - DCGAL_CXX_FLAGS:STRING=\"$TESTSUITE_CXXFLAGS -I../../include\" \ + - DCGAL_EXE_LINKER_FLAGS=\"$TESTSUITE_LDFLAGS\" \ + - DCMAKE_BUILD_TYPE=NOTFOUND \ + . " + if eval 'cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} "$CMAKE_GENERATOR" -DRUNNING_CGAL_AUTO_TEST=TRUE \ + -DCGAL_DIR="$CGAL_DIR" \ + -DCGAL_CXX_FLAGS:STRING="$TESTSUITE_CXXFLAGS -I../../include" \ + -DCGAL_EXE_LINKER_FLAGS="$TESTSUITE_LDFLAGS" \ + -DCMAKE_BUILD_TYPE=NOTFOUND \ + .' ; then + + echo " successful configuration" >> $ERRORFILE + else + echo " ERROR: configuration" >> $ERRORFILE + fi fi } diff --git a/Surface_sweep_2/test/Surface_sweep_2/cgal_test_base b/Surface_sweep_2/test/Surface_sweep_2/cgal_test_base index 59f380da802..f816494641d 100755 --- a/Surface_sweep_2/test/Surface_sweep_2/cgal_test_base +++ b/Surface_sweep_2/test/Surface_sweep_2/cgal_test_base @@ -28,21 +28,33 @@ fi configure() { - echo "Configuring... " + echo "Configuring... " - rm CMakeCache.txt + rm CMakeCache.txt + if [ -f "$INIT_FILE" ] + then + if eval 'cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} "$CMAKE_GENERATOR" -DRUNNING_CGAL_AUTO_TEST=TRUE \ + -DCGAL_DIR="$CGAL_DIR" \ + -DCGAL_CXX_FLAGS:STRING="$CGAL_CXX_FLAGS $TESTSUITE_CXXFLAGS" \ + -DCGAL_EXE_LINKER_FLAGS="CGAL_EXE_LINKER_FLAGS $TESTSUITE_LDFLAGS" \ + .' ; then + echo " successful configuration" >> $ERRORFILE + else + echo " ERROR: configuration" >> $ERRORFILE + fi + else + if eval 'cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} "$CMAKE_GENERATOR" -DRUNNING_CGAL_AUTO_TEST=TRUE \ + -DCGAL_DIR="$CGAL_DIR" \ + -DCGAL_CXX_FLAGS:STRING="$TESTSUITE_CXXFLAGS" \ + -DCGAL_EXE_LINKER_FLAGS="$TESTSUITE_LDFLAGS" \ + -DCMAKE_BUILD_TYPE=NOTFOUND \ + .' ; then - if eval 'cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} "$CMAKE_GENERATOR" -DRUNNING_CGAL_AUTO_TEST=TRUE \ - -DCGAL_DIR="$CGAL_DIR" \ - -DCGAL_CXX_FLAGS:STRING="$TESTSUITE_CXXFLAGS" \ - -DCGAL_EXE_LINKER_FLAGS="$TESTSUITE_LDFLAGS" \ - -DCMAKE_BUILD_TYPE=NOTFOUND \ - .' ; then - - echo " successful configuration" >> $ERRORFILE - else - echo " ERROR: configuration" >> $ERRORFILE - fi + echo " successful configuration" >> $ERRORFILE + else + echo " ERROR: configuration" >> $ERRORFILE + fi + fi } compile() From 44260a88fcaeae7ab2979c94b55501d47dd1bc28 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 13 Jan 2021 20:56:34 +0000 Subject: [PATCH 079/248] Store vertex handles in the MPQ and have a map from Vertex_handle to Vertices_in_constaint_iterator --- .../CGAL/Polyline_simplification_2/simplify.h | 126 +++++++++++++++--- .../Polyline_constraint_hierarchy_2.h | 4 +- 2 files changed, 108 insertions(+), 22 deletions(-) diff --git a/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/simplify.h b/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/simplify.h index 77b150ea9b2..26416805d72 100644 --- a/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/simplify.h +++ b/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/simplify.h @@ -57,11 +57,15 @@ class Polyline_simplification_2 public: typedef typename PCT::Point Point; + typedef typename PCT::Edge Edge; typedef typename PCT::Constraint_id Constraint_id; + typedef typename PCT::Constrained_edges_iterator Constrained_edges_iterator; typedef typename PCT::Constraint_iterator Constraint_iterator; typedef typename PCT::Vertices_in_constraint_iterator Vertices_in_constraint_iterator; + typedef typename PCT::Finite_vertices_iterator Finite_vertices_iterator; //typedef typename PCT::Points_in_constraint_iterator Points_in_constraint_iterator; typedef typename PCT::Vertex_handle Vertex_handle; + typedef typename PCT::Face_handle Face_handle; typedef typename PCT::Vertex_circulator Vertex_circulator; typedef typename PCT::Geom_traits::FT FT; @@ -71,6 +75,11 @@ public: StopFunction stop; std::size_t pct_initial_number_of_vertices, number_of_unremovable_vertices; + std::map > vertex_to_iterator; + + typedef std::map Vertex_index_map; + + Vertex_index_map vertex_index_map; struct Compare_cost { @@ -79,6 +88,12 @@ public: { return (*x)->cost() < (*y)->cost(); } + + bool operator() (const Vertex_handle& x,const Vertex_handle& y) const + { + return x->cost() < y->cost(); + } + } ; struct Id_map : public boost::put_get_helper @@ -86,12 +101,24 @@ public: typedef boost::readable_property_map_tag category; typedef std::size_t value_type; typedef value_type reference; - typedef Vertices_in_constraint_iterator key_type; + // typedef Vertices_in_constraint_iterator key_type; + typedef Vertex_handle key_type; - reference operator[] ( key_type const& x ) const { return x.base()->id ; } + Vertex_index_map* vertex_index_map; + + Id_map(const Vertex_index_map& vertex_index_map) + : vertex_index_map(& const_cast(vertex_index_map)) + {} + + reference operator[] ( key_type const& x ) const + { + // return x.base()->id ; + return (*vertex_index_map)[x]; + } } ; - typedef CGAL::Modifiable_priority_queue MPQ ; + //typedef CGAL::Modifiable_priority_queue MPQ ; + typedef CGAL::Modifiable_priority_queue MPQ ; MPQ* mpq; @@ -101,7 +128,7 @@ public: int m = initialize_indices(); initialize_unremovable(); Compare_cost cc; - Id_map idm; + Id_map idm(vertex_index_map); mpq = new MPQ(m, cc, idm); initialize_costs(); } @@ -124,8 +151,60 @@ public: delete mpq; } + // endpoints of constraints are unremovable + // vertices which are not endpoint and have != 2 incident constained edges are unremovable void initialize_unremovable() { + Constraint_iterator cit = pct.constraints_begin(), e = pct.constraints_end(); + for(; cit!=e; ++cit){ + Constraint_id cid = *cit; + Vertices_in_constraint_iterator it = pct.vertices_in_constraint_begin(cid); + (*it)->set_removable(false); + it = pct.vertices_in_constraint_end(cid); + it = boost::prior(it); + (*it)->set_removable(false); + } + + std::map degrees; + for (Constrained_edges_iterator it = pct.constrained_edges_begin(); it != pct.constrained_edges_end(); ++it) { + Edge e = *it; + Face_handle fh = e.first; + int ei = e.second; + Vertex_handle vh = fh->vertex(pct.cw(ei)); + ++degrees[vh]; + vh = fh->vertex(pct.ccw(ei)); + ++degrees[vh]; + } + + for(Finite_vertices_iterator it = pct.finite_vertices_begin(); it != pct.finite_vertices_end(); ++it){ + if( it->is_removable() && (degrees[it] != 2) ){ + it->set_removable(false); + } + } + + cit = pct.constraints_begin(), e = pct.constraints_end(); + for(; cit!=e; ++cit){ + Constraint_id cid = *cit; + for(Vertices_in_constraint_iterator it = pct.vertices_in_constraint_begin(cid); + it != pct.vertices_in_constraint_end(cid); + ++it){ + if((*it)->is_removable()){ + vertex_to_iterator[*it].push_back(it); + } + } + } + + /* + // debug output + for(Finite_vertices_iterator it = pct.finite_vertices_begin(); it != pct.finite_vertices_end(); ++it){ + if(it->is_removable()){ + std::cout << it->point() << " is removable" << std::endl; + } + } + */ + + /* + // the previous code does mark vertices with more than one constraint on it as unremovable std::set vertices; Constraint_iterator cit = pct.constraints_begin(), e = pct.constraints_end(); for(; cit!=e; ++cit){ @@ -142,6 +221,7 @@ public: it = boost::prior(it); (*it)->set_removable(false); } + */ } // For all polyline constraints we compute the cost of all unremovable and not removed vertices @@ -156,7 +236,7 @@ public: boost::optional dist = cost(pct, it); if(dist){ (*it)->set_cost(*dist); - (*mpq).push(it); + (*mpq).push(*it); ++n; } else { // no need to set the costs as this vertex is not in the priority queue @@ -239,10 +319,15 @@ public: initialize_indices() { int id = 0; + /* Constraint_iterator b = pct.constraints_begin(), e = pct.constraints_end(); for(; b!=e; ++b){ id = initialize_indices(*b, id); } + */ + for(Finite_vertices_iterator it = pct.finite_vertices_begin(); it != pct.finite_vertices_end(); ++it){ + vertex_index_map[it] = id++; + } return id; } @@ -252,29 +337,30 @@ operator()() if((*mpq).empty()){ return false; } - Vertices_in_constraint_iterator v = (*mpq).top(); + Vertex_handle v = (*mpq).top(); (*mpq).pop(); - if(stop(pct, *v, (*v)->cost(), pct_initial_number_of_vertices, pct.number_of_vertices())){ + if(stop(pct, v, v->cost(), pct_initial_number_of_vertices, pct.number_of_vertices())){ return false; } - if(is_removable(v)){ - Vertices_in_constraint_iterator u = boost::prior(v), w = boost::next(v); - pct.simplify(v); + Vertices_in_constraint_iterator vit = vertex_to_iterator[v].front(); + if(is_removable(vit)){ + Vertices_in_constraint_iterator u = boost::prior(vit), w = boost::next(vit); + pct.simplify(vit); if((*u)->is_removable()){ boost::optional dist = cost(pct, u); if(! dist){ // cost is undefined - if( mpq->contains(u) ){ - mpq->erase(u); + if( mpq->contains(*u) ){ + mpq->erase(*u); } } else { (*u)->set_cost(*dist); - if(mpq->contains(u)){ - mpq->update(u, true); + if(mpq->contains(*u)){ + mpq->update(*u, true); } else{ - mpq->push(u); + mpq->push(*u); } } } @@ -283,16 +369,16 @@ operator()() boost::optional dist = cost(pct, w); if(! dist){ // cost is undefined - if( mpq->contains(w) ){ - mpq->erase(w); + if( mpq->contains(*w) ){ + mpq->erase(*w); } } else { (*w)->set_cost(*dist); - if(mpq->contains(w)){ - mpq->update(w, true); + if(mpq->contains(*w)){ + mpq->update(*w, true); } else{ - mpq->push(w); + mpq->push(*w); } } 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 be275140aec..d46c76a3666 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 @@ -46,14 +46,14 @@ private: class Node { public: explicit Node(Vertex_handle vh, bool input = false) - : vertex_(vh), id(-1), input(input) + : vertex_(vh), /* id(-1),*/ input(input) {} const Point& point() const { return vertex_->point(); } Vertex_handle vertex() const { return vertex_; } private: Vertex_handle vertex_; public: - int id; + // int id; bool input; }; From 105b93b35add01308e1fbba4c5cd3e0b718c265f Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Thu, 14 Jan 2021 08:51:39 +0000 Subject: [PATCH 080/248] Now it should work with overlapping polylines --- .../simplify_overlapping_polyline.cpp | 51 +++++++++++++ .../CGAL/Polyline_simplification_2/simplify.h | 42 ++++------ .../Polyline_constraint_hierarchy_2.h | 76 +++++++++++-------- 3 files changed, 111 insertions(+), 58 deletions(-) create mode 100644 Polyline_simplification_2/examples/Polyline_simplification_2/simplify_overlapping_polyline.cpp diff --git a/Polyline_simplification_2/examples/Polyline_simplification_2/simplify_overlapping_polyline.cpp b/Polyline_simplification_2/examples/Polyline_simplification_2/simplify_overlapping_polyline.cpp new file mode 100644 index 00000000000..2df47f53932 --- /dev/null +++ b/Polyline_simplification_2/examples/Polyline_simplification_2/simplify_overlapping_polyline.cpp @@ -0,0 +1,51 @@ +#include +#include +#include +#include +#include +#include +#include + +namespace PS = CGAL::Polyline_simplification_2; + +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; + +typedef PS::Vertex_base_2 Vb; +typedef CGAL::Constrained_triangulation_face_base_2 Fb; +typedef CGAL::Triangulation_data_structure_2 TDS; +typedef CGAL::Constrained_Delaunay_triangulation_2 CDT; +typedef CGAL::Constrained_triangulation_plus_2 CT; + +typedef CT::Point Point; +typedef CT::Constraint_iterator Constraint_iterator; +typedef CT::Vertices_in_constraint_iterator Vertices_in_constraint_iterator; +typedef CT::Points_in_constraint_iterator Points_in_constraint_iterator; +typedef PS::Stop_below_count_ratio_threshold Stop; +typedef PS::Squared_distance_cost Cost; + +int main() +{ + CT ct; + + std::vector P = { Point(0,1), Point(1,1), Point(2,2), Point(3,1), Point(4,1), Point(5,1) }; + std::vector Q = { Point(5,0), Point(4,1), Point(3,1), Point(2,2), Point(1,1), Point(0,0) }; + std::vector R = { Point(3,1), Point(4,1) }; + + ct.insert_constraint(P); + ct.insert_constraint(Q); + ct.insert_constraint(R); + + PS::simplify(ct, Cost(), Stop(0.5)); + + for(Constraint_iterator cit = ct.constraints_begin(); + cit != ct.constraints_end(); + ++cit) { + std::cout << "simplified polyline" << std::endl; + for(Points_in_constraint_iterator vit = + ct.points_in_constraint_begin(*cit); + vit != ct.points_in_constraint_end(*cit); + ++vit) + std::cout << *vit << std::endl; + } + return 0; +} diff --git a/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/simplify.h b/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/simplify.h index 26416805d72..579bcfc9707 100644 --- a/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/simplify.h +++ b/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/simplify.h @@ -101,7 +101,6 @@ public: typedef boost::readable_property_map_tag category; typedef std::size_t value_type; typedef value_type reference; - // typedef Vertices_in_constraint_iterator key_type; typedef Vertex_handle key_type; Vertex_index_map* vertex_index_map; @@ -112,12 +111,10 @@ public: reference operator[] ( key_type const& x ) const { - // return x.base()->id ; - return (*vertex_index_map)[x]; + return (*vertex_index_map)[x]; } } ; - //typedef CGAL::Modifiable_priority_queue MPQ ; typedef CGAL::Modifiable_priority_queue MPQ ; MPQ* mpq; @@ -189,7 +186,17 @@ public: it != pct.vertices_in_constraint_end(cid); ++it){ if((*it)->is_removable()){ - vertex_to_iterator[*it].push_back(it); + typename std::map >::iterator lit; + lit = vertex_to_iterator.find(*it); + + if(lit != vertex_to_iterator.end()){ + std::list& ilist = lit->second; + if(std::find(ilist.begin(),ilist.end(),it) == ilist.end()){ + ilist.push_back(it); + } + }else{ + vertex_to_iterator[*it].push_back(it); + } } } } @@ -202,26 +209,6 @@ public: } } */ - - /* - // the previous code does mark vertices with more than one constraint on it as unremovable - std::set vertices; - Constraint_iterator cit = pct.constraints_begin(), e = pct.constraints_end(); - for(; cit!=e; ++cit){ - Constraint_id cid = *cit; - Vertices_in_constraint_iterator it = pct.vertices_in_constraint_begin(cid); - (*it)->set_removable(false); - for(; it != pct.vertices_in_constraint_end(cid); ++it){ - if(vertices.find(*it) != vertices.end()){ - (*it)->set_removable(false); - } else { - vertices.insert(*it); - } - } - it = boost::prior(it); - (*it)->set_removable(false); - } - */ } // For all polyline constraints we compute the cost of all unremovable and not removed vertices @@ -236,7 +223,9 @@ public: boost::optional dist = cost(pct, it); if(dist){ (*it)->set_cost(*dist); - (*mpq).push(*it); + if(! (*mpq).contains(*it)){ + (*mpq).push(*it); + } ++n; } else { // no need to set the costs as this vertex is not in the priority queue @@ -342,6 +331,7 @@ operator()() if(stop(pct, v, v->cost(), pct_initial_number_of_vertices, pct.number_of_vertices())){ return false; } + Vertices_in_constraint_iterator vit = vertex_to_iterator[v].front(); if(is_removable(vit)){ Vertices_in_constraint_iterator u = boost::prior(vit), w = boost::next(vit); 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 d46c76a3666..4b739c74f2c 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 @@ -46,14 +46,13 @@ private: class Node { public: explicit Node(Vertex_handle vh, bool input = false) - : vertex_(vh), /* id(-1),*/ input(input) + : vertex_(vh), input(input) {} const Point& point() const { return vertex_->point(); } Vertex_handle vertex() const { return vertex_; } private: Vertex_handle vertex_; public: - // int id; bool input; }; @@ -585,45 +584,58 @@ void Polyline_constraint_hierarchy_2::simplify(Vertex_it uc, Vertex_it wc) { + // TODO: How do we (want to) deal with u == w ??? Vertex_handle u = *uc, v = *vc, w = *wc; typename Sc_to_c_map::iterator uv_sc_iter = sc_to_c_map.find(make_edge(u, v)); - CGAL_assertion_msg( uv_sc_iter != sc_to_c_map.end(), "not a subconstraint" ); + typename Sc_to_c_map::iterator vw_sc_iter = sc_to_c_map.find(make_edge(v, w)); Context_list* uv_hcl = uv_sc_iter->second; - CGAL_assertion_msg((u == w) || (uv_hcl->size() == 1), "more than one constraint passing through the subconstraint" ); - - if(*(uv_hcl->front().current()) != u) { - std::swap(u,w); - uv_sc_iter = sc_to_c_map.find(make_edge(u, v)); - CGAL_assertion_msg( uv_sc_iter != sc_to_c_map.end(), "not a subconstraint" ); - uv_hcl = (*uv_sc_iter).second; - CGAL_assertion_msg((u == w) || (uv_hcl->size() == 1), "more than one constraint passing through the subconstraint" ); - } - // now u,v, and w are ordered along the polyline constraint + Context_list* vw_hcl = vw_sc_iter->second; + // AF: what is input() about??? if(vc.input()){ uc.input() = true; wc.input() = true; } - typename Sc_to_c_map::iterator vw_sc_iter = sc_to_c_map.find(make_edge(v, w)); - CGAL_assertion_msg( vw_sc_iter != sc_to_c_map.end(), "not a subconstraint" ); - Context_list* vw_hcl = vw_sc_iter->second; - CGAL_assertion_msg((u == w) || (vw_hcl->size() == 1), "more than one constraint passing through the subconstraint" ); - Vertex_list* vertex_list = uv_hcl->front().id().vl_ptr(); - CGAL_assertion_msg(vertex_list == vw_hcl->front().id().vl_ptr(), "subconstraints from different polyline constraints" ); - // Remove the list item which points to v - vertex_list->skip(vc.base()); - - if(u != w){ - // Remove the entries for [u,v] and [v,w] - sc_to_c_map.erase(uv_sc_iter); - sc_to_c_map.erase(vw_sc_iter); - delete vw_hcl; - // reuse other context list - sc_to_c_map[make_edge(u,w)] = uv_hcl; - }else{ - sc_to_c_map.erase(uv_sc_iter); - delete vw_hcl; + // Take contexts from the two context lists depending on the orientation of the constraints + // These are the contexts where current is either u or w + // remove from uv_hcl the contexts where current is not u + // remove from vw_hcl the contexts where current is not w + // splice into uv_hcl + typename Context_list::iterator it = uv_hcl->begin(); + while(it != uv_hcl->end()){ + if((*it->current()) != u){ + it = uv_hcl->erase(it); + }else{ + // Remove the list item which points to v + Vertex_list* vertex_list = it->id().vl_ptr(); + Vertex_it vc_in_context = it->current(); + vc_in_context = boost::next(vc_in_context); + vertex_list->skip(vc_in_context.base()); + ++it; + } } + it = vw_hcl->begin(); + while(it != vw_hcl->end()){ + if((*it->current()) != w){ + it = vw_hcl->erase(it); + }else{ + // Remove the list item which points to v + Vertex_list* vertex_list = it->id().vl_ptr(); + Vertex_it vc_in_context = it->current(); + vc_in_context = boost::next(vc_in_context); + vertex_list->skip(vc_in_context.base()); + ++it; + } + } + + uv_hcl->splice(uv_hcl->end(),*vw_hcl); + delete vw_hcl; + + sc_to_c_map.erase(uv_sc_iter); + sc_to_c_map.erase(vw_sc_iter); + + // reuse other context list + sc_to_c_map[make_edge(u,w)] = uv_hcl; } From 1ee14b23bc676d6135944e734ad2fb18f7add50e Mon Sep 17 00:00:00 2001 From: Maxime GIMENO Date: Thu, 14 Jan 2021 10:32:34 +0100 Subject: [PATCH 081/248] Update Arrangement_on_surface_2/test/Arrangement_on_surface_2/cgal_test_with_cmake Co-authored-by: Laurent Rineau --- .../test/Arrangement_on_surface_2/cgal_test_with_cmake | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/cgal_test_with_cmake b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/cgal_test_with_cmake index 099686a5d81..befa82faa0a 100755 --- a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/cgal_test_with_cmake +++ b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/cgal_test_with_cmake @@ -143,10 +143,10 @@ configure() else rm -rf CMakeCache.txt CMakeFiles/ echo "cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} "$CMAKE_GENERATOR" -DRUNNING_CGAL_AUTO_TEST=TRUE \ - - DCGAL_DIR=\"$CGAL_DIR\" \ - - DCGAL_CXX_FLAGS:STRING=\"$TESTSUITE_CXXFLAGS -I../../include\" \ - - DCGAL_EXE_LINKER_FLAGS=\"$TESTSUITE_LDFLAGS\" \ - - DCMAKE_BUILD_TYPE=NOTFOUND \ + -DCGAL_DIR=\"$CGAL_DIR\" \ + -DCGAL_CXX_FLAGS:STRING=\"$TESTSUITE_CXXFLAGS -I../../include\" \ + -DCGAL_EXE_LINKER_FLAGS=\"$TESTSUITE_LDFLAGS\" \ + -DCMAKE_BUILD_TYPE=NOTFOUND \ . " if eval 'cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} "$CMAKE_GENERATOR" -DRUNNING_CGAL_AUTO_TEST=TRUE \ -DCGAL_DIR="$CGAL_DIR" \ From 107567e8095d40cbdb245fccdb8e1bb3512eee51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 15 Jan 2021 15:38:28 +0100 Subject: [PATCH 082/248] add an extra operator to have an exact plane --- .../doc/Kernel_23/Concepts/FunctionObjectConcepts.h | 10 ++++++++++ Kernel_23/include/CGAL/Kernel/function_objects.h | 7 +++++++ 2 files changed, 17 insertions(+) diff --git a/Kernel_23/doc/Kernel_23/Concepts/FunctionObjectConcepts.h b/Kernel_23/doc/Kernel_23/Concepts/FunctionObjectConcepts.h index 44e13cfbbe4..f84f64533f8 100644 --- a/Kernel_23/doc/Kernel_23/Concepts/FunctionObjectConcepts.h +++ b/Kernel_23/doc/Kernel_23/Concepts/FunctionObjectConcepts.h @@ -9277,6 +9277,16 @@ public: Oriented_side operator()(const Kernel::Plane_3&h, const Kernel::Point_3&p); + /*! + returns \ref CGAL::ON_ORIENTED_BOUNDARY, + \ref CGAL::ON_NEGATIVE_SIDE, or the constant \ref CGAL::ON_POSITIVE_SIDE, + depending on the position of `p` relative to the oriented plane constructed + from `plane_point` and `plane_vector`. + */ + Oriented_side operator()(const Kernel::Point_3& plane_point, + const Kernel::Vector_3& plane_vector, + const Kernel::Point_3&p); + /*! returns \ref CGAL::ON_ORIENTED_BOUNDARY, \ref CGAL::ON_NEGATIVE_SIDE, or the constant \ref CGAL::ON_POSITIVE_SIDE, diff --git a/Kernel_23/include/CGAL/Kernel/function_objects.h b/Kernel_23/include/CGAL/Kernel/function_objects.h index b462f6ef001..65243f0c4c3 100644 --- a/Kernel_23/include/CGAL/Kernel/function_objects.h +++ b/Kernel_23/include/CGAL/Kernel/function_objects.h @@ -3787,6 +3787,7 @@ namespace CommonKernelFunctors { class Oriented_side_3 { typedef typename K::Point_3 Point_3; + typedef typename K::Vector_3 Vector_3; typedef typename K::Tetrahedron_3 Tetrahedron_3; typedef typename K::Plane_3 Plane_3; typedef typename K::Sphere_3 Sphere_3; @@ -3801,6 +3802,12 @@ namespace CommonKernelFunctors { operator()( const Plane_3& pl, const Point_3& p) const { return pl.rep().oriented_side(p); } + result_type + operator()( const Point_3& plane_pt, const Vector_3& plane_normal, const Point_3& query) const + { + return typename K::Construct_plane_3()(plane_pt, plane_normal).rep().oriented_side(query); + } + result_type operator()( const Tetrahedron_3& t, const Point_3& p) const { return t.rep().oriented_side(p); } From 27de834e3004b2eab757dc940f108d7f3021bad9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 18 Jan 2021 11:30:02 +0100 Subject: [PATCH 083/248] move non-documented/exp function in experimental namespace --- BGL/include/CGAL/boost/graph/selection.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/BGL/include/CGAL/boost/graph/selection.h b/BGL/include/CGAL/boost/graph/selection.h index ec8dcd57366..668bc4707e0 100644 --- a/BGL/include/CGAL/boost/graph/selection.h +++ b/BGL/include/CGAL/boost/graph/selection.h @@ -561,6 +561,9 @@ regularize_face_selection_borders( /// \endcond /// \cond SKIP_IN_MANUAL + +namespace experimental { + // TODO: improve and document if useful // // Variant of regularization without graphcut but with brut-force @@ -703,6 +706,8 @@ regularize_face_selection_borders( put(is_selected, fd, true); } } + +} /// \endcond From dd8db935026fa80684b4070243e876488fb2a5d1 Mon Sep 17 00:00:00 2001 From: Guillaume Damiand Date: Mon, 18 Jan 2021 11:51:43 +0100 Subject: [PATCH 084/248] Add << operator --- Surface_mesh_topology/include/CGAL/Path_on_surface.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Surface_mesh_topology/include/CGAL/Path_on_surface.h b/Surface_mesh_topology/include/CGAL/Path_on_surface.h index a6d2bfbbaeb..7a56a82156a 100644 --- a/Surface_mesh_topology/include/CGAL/Path_on_surface.h +++ b/Surface_mesh_topology/include/CGAL/Path_on_surface.h @@ -1300,6 +1300,12 @@ public: { std::cout<<" c "; } //<::storage_type m_map; // The underlying map std::vector m_path; /// The sequence of darts From e26af3a445f6c4ef7ab714ed784e5640f20f8765 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Mon, 18 Jan 2021 17:27:35 +0100 Subject: [PATCH 085/248] Add some documentation for insert_if_in_star methode of Regular_triangulation --- .../CGAL/Regular_triangulation.h | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/Triangulation/doc/Triangulation/CGAL/Regular_triangulation.h b/Triangulation/doc/Triangulation/CGAL/Regular_triangulation.h index 7e552c06494..4beb5141930 100644 --- a/Triangulation/doc/Triangulation/CGAL/Regular_triangulation.h +++ b/Triangulation/doc/Triangulation/CGAL/Regular_triangulation.h @@ -123,6 +123,43 @@ type `Weighted_point`. template< typename ForwardIterator > std::ptrdiff_t insert(ForwardIterator s, ForwardIterator e); +/*! +Inserts weighted point `p` in the triangulation and returns the corresponding +vertex if `p` is in the star defined by `star_center`. + +If this insertion creates a vertex, this vertex is returned. + +If `p` coincides with an existing vertex and has a greater weight, +then `p` replaces it as vertex of the triangulation. + +If `p` coincides with an already existing vertex (both point and +weights being equal), then this vertex is returned and the triangulation +remains unchanged. + +Otherwise if `p` does not appear as a vertex of the triangulation, +then this method returns the default constructed handle. + +Prior to the actual insertion, `p` is located in the triangulation; +`start` is used as a starting place for locating `p`. +*/ +Vertex_handle insert_if_in_star(const Weighted_point & p, Vertex_handle star_center, + Full_cell_handle start = Full_cell_handle()); + +/*! +Same as the above `insert_if_in_star()`, but uses a vertex as starting place for the search. +*/ +Vertex_handle insert_if_in_star(const Weighted_point & p, Vertex_handle star_center, + Vertex_handle hint); + +/*! +Inserts weighted point `p` in the triangulation. +Similar to the above `insert_if_in_star()` function, but takes as additional +parameter the return values of a previous location query. See description of +`Triangulation::locate()`. +*/ +insert_if_in_star(const Weighted_point & p, Vertex_handle star_center, Locate_type lt, + const Face & f, const Facet &, Full_cell_handle s); + /// @} /// \name Queries From 41a3d1c448ced0bb1ee30f0ccef857d015a37ff5 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 19 Jan 2021 16:43:17 +0000 Subject: [PATCH 086/248] Add initial version of doc of with_info classes --- ..._Delaunay_graph_storage_site_with_info_2.h | 50 +++++++++++++++++++ ...elaunay_graph_storage_traits_with_info_2.h | 35 +++++++++++++ .../PackageDescription.txt | 3 +- 3 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_storage_site_with_info_2.h create mode 100644 Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_storage_traits_with_info_2.h diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_storage_site_with_info_2.h b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_storage_site_with_info_2.h new file mode 100644 index 00000000000..fc8180ff3d8 --- /dev/null +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_storage_site_with_info_2.h @@ -0,0 +1,50 @@ + +namespace CGAL { + +/*! +\ingroup PkgSegmentDelaunayGraph2Ref + +The class `Segment_Delaunay_graph_storage_site_with_info_2` is a model for the concept +`SegmentDelaunayGraphStorageSite_2`. + +\tparam STraits must be a model of the `SegmentDelaunayGraphStorageTraits_2` concept. +\tparam Base must be a model of `SegmentDelaunayGraphStorageSite_2` + +\cgalModels `SegmentDelaunayGraphStorageSite_2` + +\sa `CGAL::Segment_Delaunay_graph_site_2` +*/ +template< typename STraits, typename Info_, typename Base > +class Segment_Delaunay_graph_storage_site_with_info_2 : public Base { +public: + + /// \name Types + /// The class + /// @{ + + typedef STraits Storage_traits; + /*! + */ + typedef Info_ Info; + + typedef typename Storage_traits::Geom_traits Geom_traits; + typedef typename Geom_traits::Site_2 Site_2; + typedef typename Storage_traits::Point_handle Point_handle; + + struct Has_info_tag {}; + /// @} + + /*! + */ + const Info& info() const; + + /*! + */ + void set_info(const Info&) const; + + /*! + */ + bool info_has_been_set() const; + +}; /* end Segment_Delaunay_graph_storage_site_with_info_2 */ +} /* end namespace CGAL */ diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_storage_traits_with_info_2.h b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_storage_traits_with_info_2.h new file mode 100644 index 00000000000..eb032cea795 --- /dev/null +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_storage_traits_with_info_2.h @@ -0,0 +1,35 @@ +namespace CGAL { + +/*! +\ingroup PkgSegmentDelaunayGraph2Ref + +The class `Segment_Delaunay_graph_storage_traits_with_info_2` provides a model for the +`SegmentDelaunayGraphStorageTraits_2` concept. + + +\tparam Gt must be a model of the concept `SegmentDelaunayGraphTraits_2`. + +\cgalModels `SegmentDelaunayGraphStorageTraits_2` + +\sa `CGAL::`Segment_Delaunay_graph_storage_site_with_info_2` +*/ + template +class Segment_Delaunay_graph_storage_traits_with_info_2 + : public Segment_Delaunay_graph_storage_traits_2 +{ +public: + /*! + */ + typedef Info_ Info; + typedef Converter Convert_info; + typedef Merger Merge_info; + typedef typename Base::Geom_traits Geom_traits; + + typedef + Segment_Delaunay_graph_storage_site_with_info_2 Storage_site_2; + +}; + +} //namespace CGAL diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/PackageDescription.txt b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/PackageDescription.txt index b07d2b2a84b..947f7034f0d 100644 --- a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/PackageDescription.txt +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/PackageDescription.txt @@ -56,7 +56,9 @@ the class - `CGAL::Segment_Delaunay_graph_2` - `CGAL::Segment_Delaunay_graph_site_2` - `CGAL::Segment_Delaunay_graph_storage_site_2` +- `CGAL::Segment_Delaunay_graph_storage_site_with_info_2` - `CGAL::Segment_Delaunay_graph_storage_traits_2` +- `CGAL::Segment_Delaunay_graph_storage_traits_with_info_2` - `CGAL::Segment_Delaunay_graph_vertex_base_2` - `CGAL::Segment_Delaunay_graph_face_base_2` - `CGAL::Segment_Delaunay_graph_traits_2` @@ -67,4 +69,3 @@ the class - `CGAL::Segment_Delaunay_graph_hierarchy_vertex_base_2` */ - From fb79442e9ff3777e1e9c6b5d30cc29bfac1c09c0 Mon Sep 17 00:00:00 2001 From: FrancisGipsa Date: Wed, 20 Jan 2021 16:41:50 +0100 Subject: [PATCH 087/248] modify implementation details for the simplicity test --- .../Surface_mesh_topology.txt | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/Surface_mesh_topology/doc/Surface_mesh_topology/Surface_mesh_topology.txt b/Surface_mesh_topology/doc/Surface_mesh_topology/Surface_mesh_topology.txt index 2933f7e2492..8337baa4022 100644 --- a/Surface_mesh_topology/doc/Surface_mesh_topology/Surface_mesh_topology.txt +++ b/Surface_mesh_topology/doc/Surface_mesh_topology/Surface_mesh_topology.txt @@ -286,46 +286,46 @@ The canonical form of a curve is obtained by flattening its brackets, removing i It can be proven that the canonical form is uniquely defined and only depends on the homotopy class of the curve. Hence, the curves \f$C'\f$ and \f$D'\f$ in \f$\cal{Q}\f$ are homotopic if and only if their canonical forms are equal. Since each curve is defined as a sequence of (oriented) edges up to a cyclic permutation, we resort to the Knuth-Morris-Pratt algorithm to decide in linear time if the canonical forms are the same up to a cyclic permutation. \subsection SMTopology_Simplicity_Test Simplicity Test -It can be shown that a closed curve is homotopic to a simple one if and only if its canonical form can be made intersection free via infinitesimal perturbations and some homotopy preserving operations. One can imagine each edge in the quadrangulation has a width and each vertex in the quadrangulation has an area so that paths visiting the same vertex/edge multiple times can avoid intersection within a vertex or an edge. See \cgalFigureRef{fig_perturbation_sample} for an example. +The simplicity test relies on the fact that a closed curve is homotopic to a simple one if and only if its canonical form can be made intersection free via infinitesimal perturbations together with some homotopy preserving operations. One can imagine each edge in the quadrangulation has a width and each vertex in the quadrangulation has an area so that paths visiting the same vertex/edge multiple times can avoid intersection after perturbation within a vertex or an edge. See \cgalFigureRef{fig_perturbation_sample} for an example. \cgalFigureBegin{fig_perturbation_sample,perturbation_sample.svg} - Applying a perturbation to reduce 2 intersections between red subpath and blue subpath. + Applying a perturbation to remove 2 intersections between the red and the blue subpaths. \cgalFigureEnd -Such a perturbation can be expressed as orderings of edges from the canonical form which cross the same edge in the quadrangulation. The idea of the algorithm is to inductively build such ordering and try to avoid intersection as best as we can. +Such a perturbation can be encoded as a transverse ordering of the edges from the canonical form which traverse the same edge in the quadrangulation. The idea of the algorithm is to traverse the canonical form, one edge at a time, to inductively build such orderings and try to avoid intersection as best as we can. \subsubsection SMTopology_Simplicity_Test_Primitive Detect Repetition -It can be proven that if the canonical form can be expressed as concatenation of two or more copies of the same path, the path can never be made intersection free. So the first step of the algorithm is to detect repetition. +There is an easy case where we know for sure that a closed curve cannot be deformed to simple one: If the canonical form can be expressed as concatenation of two or more copies of the same path. So the first step of the algorithm is to detect repetition. -Let \f$P\f$ be a path and let \f$+\f$ be the operator of concatenation. It can be shown that \f$P\f$ contains no repetition if and only if there are only 2 matchings of \f$P\f$ in \f$P+P\f$ (matching the first and the second copy). The algorithm resorts to the Knuth-Morris-Pratt algorithm to decide in linear time if the canonical form contains no repetition. +Let \f$P\f$ be a path and let \f$+\f$ be the operator of concatenation. It can be shown that \f$P\f$ contains no repetition if and only if there are only 2 matchings of \f$P\f$ in \f$P+P\f$ (matching the first and the second copy). The algorithm resorts to the Knuth-Morris-Pratt algorithm to decide in linear time if the canonical form contains repetitions. \subsubsection SMTopology_Simplicity_Test_Switch Avoid Crossing by Switching -Apart from applying perturbation, the algorithm also tries to avoid crossing using a homotopy-preserving operation known as switch. A switch is triggered when intersection could be avoided by turning a left L-shaped subpath into a right L-shaped subpath. See \cgalFigureRef{fig_switch_sample} for an example. +Apart from applying perturbation, the algorithm also tries to avoid crossings using a homotopy-preserving operation called as a switch. A switch is triggered whenever an intersection could be avoided by turning a left L-shaped subpath into a right L-shaped subpath. See \cgalFigureRef{fig_switch_sample} for an example. \cgalFigureBegin{fig_switch_sample,switch_sample.svg} - Top-left, an intersection between red subpath and green subpath at the start of a left L-shaped red subpath. Top-right, switch the left L-shape to right L-shape to avoid the intersection. Bottom, no switch because no intersection can be avoided. + Top-left, an intersection between the red subpath and the green subpath at the start of the left L-shaped red subpath. Top-right, switch the left L-shape to right L-shape to avoid the intersection. Bottom-left or right, no switch is performed because no intersection can be avoided. \cgalFigureEnd \subsubsection SMTopology_Simplicity_Test_Relative_Order Decide Relative Order -Since the algorithm inductively builds an ordering, it has to determine a relative order between the edge being processed and the edges that has been ordered. There are three cases to consider. +As the algorithm inductively builds orderings, it has to determine a relative order between the edge being processed and the edges that have been ordered. There are three cases to consider. --# The predecessor of the current edge is adjacent to another edge which forms the same turn of the predecessor and the current edge. In this case, the current edge must be adjacent to the edge forming the turn. See \cgalFigureRef{fig_relative_order_corner}. +-# The current edge and its predecessor, say \f$e\f$, form a subpath of length two so that a parallel copy of this subpath has already been processed, and \f$e\f$ is adjacent to its parallel copy in the previously constructed ordering. In this case, the current edge must be adjacent to its copy in the transverse ordering. See \cgalFigureRef{fig_relative_order_corner}. \cgalFigureBegin{fig_relative_order_corner,relative_order_corner.svg} - The red edge is being processed. The blue edge is adjacent to green edge (the predecessor of the red edge) in the previously constructed ordering and forms a turn (blue-pink turn) same as the green-red turn. The red edge must be right next to the pink edge in the ordering. + The red edge is being processed. The blue edge is adjacent to the green edge (the predecessor \f$e\f$ of the red edge) in the previously constructed ordering and forms the same turn (blue-pink turn) as the green-red turn. The red edge should be right next to the pink edge in the ordering so as to avoid crossings. \cgalFigureEnd --# Comparing the current edge with another edge by the predecessor of the current edge. If the edge being compared against has predecessor/successor extended to the direction of the predecessor of the current edge, and they doesn't form the same turn. The relative order of edges around the vertex can be used as the relative order between the edges. See \cgalFigureRef{fig_relative_order_normal}. +-# When the previous situation does not occur, the current edge has to be compared against every parallel copy already processed. In this case, the predecessors of the copy and of the current edge form a Y shape with the current edge. The circular order of the edges in this Y can be used to determine the relative order between the current edge and its copy. See \cgalFigureRef{fig_relative_order_normal}. \cgalFigureBegin{fig_relative_order_normal,relative_order_normal.svg} - The red edge is being processed and is compared against the pink edge. Since the green edge (the predecessor of the red edge) is to the right of the blue edge around the vertex, red edge must be to the right of the pink edge in the ordering. + The red edge is being processed and is compared against the pink edge. Since the green edge (the predecessor of the red edge) is to the right of the blue edge around the vertex, the red edge must be to the right of the pink edge in the transverse ordering. \cgalFigureEnd --# If the current edge crosses the same edge in the quadrangulation as the first edge of the path, the predecessor of the first edge (aka the last edge of the path) has not been processed yet. Hence if they form the same turn, we cannot determine the relative order of the predecessors. So the idea is to keep following the predecessors of current edge and the first edge until they diverge, at which point the relative order around the vertex can be used to determine the relative order. See \cgalFigureRef{fig_relative_order_first}. This can be precomputed by finding all the longest common suffices of the path against its circular shifts. A modified Knuth-Morris-Pratt algorithm is applied to preprocess the path in linear time. +-# There is one special case where the comparison of the current edge with a parallel copy cannot be deduced form previous computations: When this copy happens to be the very first edge processed in the traversal. Indeed, the predecessor of the first edge (aka the last edge of the path) has not been processed yet. If the last edge runs parallel to the predecessor of the current edge, we cannot determine their relative order. So the idea is to keep following the predecessors of the current edge and of the first edge until they diverge, at which point the relative order around the vertex can be used to determine the relative order. See \cgalFigureRef{fig_relative_order_first}. This can be precomputed by finding all the longest common suffixes of the path against its circular shifts. A modified Knuth-Morris-Pratt algorithm is applied to preprocess the path in linear time. \cgalFigureBegin{fig_relative_order_first,relative_order_first.svg} - The red edge is being processed and is compared against the pink edge which is the first edge of the path. The blue and green edges are the first diverging pair when tracing backward. The dashed line means that edges may not be processed yet. Since the green edge is to the right of the blue edge around the vertex, the red edge must be to the right of the pink edge in the ordering. + The red edge is being processed and is compared against the pink edge which is the first edge of the path. The blue and green edges are the first diverging pair when tracing backward. The dashed line means that edges have not been processed yet. Since the green edge lies to the right of the blue edge around the vertex, the red edge must be to the right of the pink edge in the ordering. \cgalFigureEnd -The ordering is stored in a red-black tree for each edge of the quadrangulation. So each insertion and search takes \f$O(\log{l})\f$ time. +The transverse orderings are stored in red-black trees, one for each edge of the quadrangulation. So each insertion or search takes \f$O(\log{l})\f$ time, where \f$l\f$ is the length of the closed curve. \subsubsection SMTopology_Simplicity_Test_Verification Verify Ordering -After computing a tentative ordering within the edges of the path, we have to verify that such an ordering could result in an intersection free arrangement. Since there is no intersection within an edge, we only need to verify this for each vertex in the quadrangulation. We can consider the two consecutive edges composing a turn (one going in the vertex, one going out of the vertex) at the vertex being verified a pair. The ordering at the vertex is intersection free if and only if there is no two pairs crossing each other according to the clockwise ordering around the vertex. In other words, for any two pairs \f$(a, a')\f$ and \f$(b, b')\f$, subsequence \f$a, b, a', b'\f$ should not appear in the clockwise ordering. This is very similar to verifying balanced parentheses in a string. We traverse clockwise at each vertex and use a stack-based algorithm to verify in linear time that the ordering produces a cycle without self-intersection. +After computing a tentative ordering within the edges of the path, we have to verify that such an ordering could result in an intersection free arrangement. Since there is no intersection within an edge, we only need to verify this for each vertex in the quadrangulation. Each vertex is naturally associated with a circular ordering of the incident path edges by concatenating clockwise the orderings computed for every incident edge in the quadrangulation. We consider the two consecutive edges composing a turn (one going in the vertex, one going out of the vertex) at the vertex being verified as a pair. The ordering at the vertex is intersection free if and only if there is no two pairs crossing each other according to the clockwise ordering around the vertex. In other words, for any two pairs \f$(a, a')\f$ and \f$(b, b')\f$, none of the subsequences \f$a, b, a', b'\f$ or \f$a, b', a', b\f$ should appear in the clockwise ordering. This is very similar to verifying balanced parentheses in a string. We traverse clockwise at each vertex and use a stack-based algorithm to verify in linear time that the ordering produces a cycle without self-intersection. \section Implementation History From 3b838da50a474075d0f25d9626460ac6516f8044 Mon Sep 17 00:00:00 2001 From: Guillaume Damiand Date: Wed, 27 Jan 2021 18:47:38 +0100 Subject: [PATCH 088/248] Re-add clipping plane. --- GraphicsView/include/CGAL/Basic_shaders.h | 275 ++++++++ .../include/CGAL/Qt/Basic_viewer_qt.h | 636 ++++++++++++------ 2 files changed, 697 insertions(+), 214 deletions(-) create mode 100644 GraphicsView/include/CGAL/Basic_shaders.h diff --git a/GraphicsView/include/CGAL/Basic_shaders.h b/GraphicsView/include/CGAL/Basic_shaders.h new file mode 100644 index 00000000000..429f2b52f00 --- /dev/null +++ b/GraphicsView/include/CGAL/Basic_shaders.h @@ -0,0 +1,275 @@ +// Copyright (c) 2018 GeometryFactory Sarl (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Guillaume Damiand + +#ifndef CGAL_BASIC_SHADERS_H +#define CGAL_BASIC_SHADERS_H + +namespace CGAL +{ + +//------------------------------------------------------------------------------ +const char vertex_source_color[]=R"DELIM( +#version 120 +attribute highp vec4 vertex; +attribute highp vec3 normal; +attribute highp vec3 color; + +uniform highp mat4 mvp_matrix; +uniform highp mat4 mv_matrix; + +varying highp vec4 fP; +varying highp vec3 fN; +varying highp vec4 fColor; + +uniform highp float point_size; + +varying highp vec4 m_vertex; + +void main(void) +{ + fP = mv_matrix * vertex; + fN = mat3(mv_matrix)* normal; + fColor = vec4(color, 1.0); + gl_PointSize = point_size; + + m_vertex = vertex; + + gl_Position = mvp_matrix * vertex; +} +)DELIM"; + +const char fragment_source_color[]=R"DELIM( +#version 120 +varying highp vec4 fP; +varying highp vec3 fN; +varying highp vec4 fColor; + +varying highp vec4 m_vertex; + +uniform highp vec4 light_pos; +uniform highp vec4 light_diff; +uniform highp vec4 light_spec; +uniform highp vec4 light_amb; +uniform highp float spec_power; + +uniform highp vec4 clipPlane; +uniform highp float rendering_mode; +uniform highp float rendering_transparency; + +void main(void) +{ + highp vec3 L = light_pos.xyz - fP.xyz; + highp vec3 V = -fP.xyz; + + highp vec3 N = normalize(fN); + L = normalize(L); + V = normalize(V); + + highp vec3 R = reflect(-L, N); + highp vec4 diffuse = vec4(max(dot(N,L), 0.0) * light_diff.rgb * fColor.rgb, 1.0); + highp vec4 ambient = vec4(light_amb.rgb * fColor.rgb, 1.0); + highp vec4 specular = pow(max(dot(R,V), 0.0), spec_power) * light_spec; + + // onPlane == 1: inside clipping plane, should be solid; + // onPlane == -1: outside clipping plane, should be transparent; + // onPlane == 0: on clipping plane, whatever; + float onPlane = sign(dot(m_vertex.xyz, clipPlane.xyz) - clipPlane.w); + + // rendering_mode == -1: draw all solid; + // rendering_mode == 0: draw solid only; + // rendering_mode == 1: draw transparent only; + if (rendering_mode == (onPlane+1)/2) { + // discard other than the corresponding half when rendering + discard; + } + + // draw corresponding part + gl_FragColor = rendering_mode < 1 ? (diffuse + ambient) : + vec4(diffuse.rgb + ambient.rgb, rendering_transparency); +} +)DELIM"; + +const char vertex_source_p_l[]=R"DELIM( +#version 120 +attribute highp vec4 vertex; +attribute highp vec3 color; + +uniform highp mat4 mvp_matrix; +varying highp vec4 fColor; + +varying highp vec4 m_vertex; + +uniform highp float point_size; +void main(void) +{ + gl_PointSize = point_size; + fColor = vec4(color, 1.0); + m_vertex = vertex; + gl_Position = mvp_matrix * vertex; +} +)DELIM"; + +const char fragment_source_p_l[]=R"DELIM( +#version 120 +varying highp vec4 fColor; +varying highp vec4 m_vertex; +uniform highp vec4 clipPlane; +uniform highp float rendering_mode; + +void main(void) +{ + // onPlane == 1: inside clipping plane, should be solid; + // onPlane == -1: outside clipping plane, should be transparent; + // onPlane == 0: on clipping plane, whatever; + float onPlane = sign(dot(m_vertex.xyz, clipPlane.xyz) - clipPlane.w); + + // rendering_mode == -1: draw both inside and outside; + // rendering_mode == 0: draw inside only; + // rendering_mode == 1: draw outside only; + if (rendering_mode == (onPlane+1)/2) { + // discard other than the corresponding half when rendering + discard; + } + + gl_FragColor = fColor; +} +)DELIM"; + +const char vertex_source_clipping_plane[]=R"DELIM( +#version 120 +attribute highp vec4 vertex; + +uniform highp mat4 vp_matrix; +uniform highp mat4 m_matrix; + +void main(void) +{ + gl_Position = vp_matrix * m_matrix * vertex; +} +)DELIM"; + +const char fragment_source_clipping_plane[]=R"DELIM( +#version 120 +void main(void) +{ + gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); +} +)DELIM"; + +//------------------------------------------------------------------------------ +// compatibility shaders + +const char vertex_source_color_comp[]=R"DELIM( +attribute highp vec4 vertex; +attribute highp vec3 normal; +attribute highp vec3 color; + +uniform highp mat4 mvp_matrix; +uniform highp mat4 mv_matrix; + +varying highp vec4 fP; +varying highp vec3 fN; +varying highp vec4 fColor; + +uniform highp float point_size; + +void main(void) +{ + fP = mv_matrix * vertex; + highp mat3 mv_matrix_3; + mv_matrix_3[0] = mv_matrix[0].xyz; + mv_matrix_3[1] = mv_matrix[1].xyz; + mv_matrix_3[2] = mv_matrix[2].xyz; + fN = mv_matrix_3* normal; + fColor = vec4(color, 1.0); + gl_PointSize = point_size; + + gl_Position = mvp_matrix * vertex; +} +)DELIM"; + +const char fragment_source_color_comp[]=R"DELIM( +varying highp vec4 fP; +varying highp vec3 fN; +varying highp vec4 fColor; + +uniform highp vec4 light_pos; +uniform highp vec4 light_diff; +uniform highp vec4 light_spec; +uniform highp vec4 light_amb; +uniform highp float spec_power ; + +void main(void) +{ + highp vec3 L = light_pos.xyz - fP.xyz; + highp vec3 V = -fP.xyz; + + highp vec3 N = normalize(fN); + L = normalize(L); + V = normalize(V); + + highp vec3 R = reflect(-L, N); + highp vec4 diffuse = max(dot(N,L), 0.0) * light_diff * fColor; + highp vec4 specular = pow(max(dot(R,V), 0.0), spec_power) * light_spec; + + gl_FragColor = light_amb*fColor + diffuse; +} +)DELIM"; + +const char vertex_source_p_l_comp[]=R"DELIM( +attribute highp vec4 vertex; +attribute highp vec3 color; + +uniform highp mat4 mvp_matrix; +varying highp vec4 fColor; + +uniform highp float point_size; + +void main(void) +{ + gl_PointSize = point_size; + fColor = vec4(color, 1.0); + gl_Position = mvp_matrix * vertex; +} +)DELIM"; + +const char fragment_source_p_l_comp[]=R"DELIM( +varying highp vec4 fColor; +void main(void) +{ + gl_FragColor = fColor; +} +)DELIM"; + +/* const char vertex_source_clipping_plane_comp[]=R"DELIM( +attribute highp vec4 vertex; + +uniform highp mat4 vp_matrix; +uniform highp mat4 m_matrix; + +void main(void) +{ + gl_Position = vp_matrix * m_matrix * vertex; +} +)DELIM"; + +const char fragment_source_clipping_plane_comp[]=R"DELIM( +void main(void) +{ + gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); +} +)DELIM"; +*/ + +} + +#endif // CGAL_BASIC_SHADERS_H diff --git a/GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h b/GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h index 11058fe04e6..be88ad7fce4 100644 --- a/GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h +++ b/GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h @@ -48,179 +48,13 @@ #include #include +#include #include #include #include namespace CGAL { - -//------------------------------------------------------------------------------ -const char vertex_source_color[] = - { - "#version 120 \n" - "attribute highp vec4 vertex;\n" - "attribute highp vec3 normal;\n" - "attribute highp vec3 color;\n" - - "uniform highp mat4 mvp_matrix;\n" - "uniform highp mat4 mv_matrix; \n" - - "varying highp vec4 fP; \n" - "varying highp vec3 fN; \n" - "varying highp vec4 fColor; \n" - - "uniform highp float point_size; \n" - "void main(void)\n" - "{\n" - " fP = mv_matrix * vertex; \n" - " fN = mat3(mv_matrix)* normal; \n" - " fColor = vec4(color, 1.0); \n" - " gl_PointSize = point_size;\n" - " gl_Position = mvp_matrix * vertex;\n" - "}" - }; - -const char fragment_source_color[] = - { - "#version 120 \n" - "varying highp vec4 fP; \n" - "varying highp vec3 fN; \n" - "varying highp vec4 fColor; \n" - "uniform highp vec4 light_pos; \n" - "uniform highp vec4 light_diff; \n" - "uniform highp vec4 light_spec; \n" - "uniform highp vec4 light_amb; \n" - "uniform float spec_power ; \n" - - "void main(void) { \n" - " highp vec3 L = light_pos.xyz - fP.xyz; \n" - " highp vec3 V = -fP.xyz; \n" - - " highp vec3 N = normalize(fN); \n" - " L = normalize(L); \n" - " V = normalize(V); \n" - - " highp vec3 R = reflect(-L, N); \n" - " highp vec4 diffuse = max(dot(N,L), 0.0) * light_diff * fColor; \n" - " highp vec4 specular = pow(max(dot(R,V), 0.0), spec_power) * light_spec; \n" - " gl_FragColor = light_amb*fColor + diffuse ; \n" - "} \n" - "\n" - }; - -const char vertex_source_p_l[] = - { - "#version 120 \n" - "attribute highp vec4 vertex;\n" - "attribute highp vec3 color;\n" - "uniform highp mat4 mvp_matrix;\n" - "varying highp vec4 fColor; \n" - "uniform highp float point_size; \n" - "void main(void)\n" - "{\n" - " gl_PointSize = point_size;\n" - " fColor = vec4(color, 1.0); \n" - " gl_Position = mvp_matrix * vertex;\n" - "}" - }; - -const char fragment_source_p_l[] = - { - "#version 120 \n" - "varying highp vec4 fColor; \n" - "void main(void) { \n" - "gl_FragColor = fColor; \n" - "} \n" - "\n" - }; - -//------------------------------------------------------------------------------ -// compatibility shaders - -const char vertex_source_color_comp[] = - { - "attribute highp vec4 vertex;\n" - "attribute highp vec3 normal;\n" - "attribute highp vec3 color;\n" - - "uniform highp mat4 mvp_matrix;\n" - "uniform highp mat4 mv_matrix; \n" - - "varying highp vec4 fP; \n" - "varying highp vec3 fN; \n" - "varying highp vec4 fColor; \n" - - "uniform highp float point_size; \n" - "void main(void)\n" - "{\n" - " fP = mv_matrix * vertex; \n" - " highp mat3 mv_matrix_3; \n" - " mv_matrix_3[0] = mv_matrix[0].xyz; \n" - " mv_matrix_3[1] = mv_matrix[1].xyz; \n" - " mv_matrix_3[2] = mv_matrix[2].xyz; \n" - " fN = mv_matrix_3* normal; \n" - " fColor = vec4(color, 1.0); \n" - " gl_PointSize = point_size;\n" - " gl_Position = mvp_matrix * vertex;\n" - "}" - }; - -const char fragment_source_color_comp[] = - { - "varying highp vec4 fP; \n" - "varying highp vec3 fN; \n" - "varying highp vec4 fColor; \n" - "uniform highp vec4 light_pos; \n" - "uniform highp vec4 light_diff; \n" - "uniform highp vec4 light_spec; \n" - "uniform highp vec4 light_amb; \n" - "uniform highp float spec_power ; \n" - - "void main(void) { \n" - - " highp vec3 L = light_pos.xyz - fP.xyz; \n" - " highp vec3 V = -fP.xyz; \n" - - " highp vec3 N = normalize(fN); \n" - " L = normalize(L); \n" - " V = normalize(V); \n" - - " highp vec3 R = reflect(-L, N); \n" - " highp vec4 diffuse = max(dot(N,L), 0.0) * light_diff * fColor; \n" - " highp vec4 specular = pow(max(dot(R,V), 0.0), spec_power) * light_spec; \n" - - "gl_FragColor = light_amb*fColor + diffuse ; \n" - "} \n" - "\n" - }; - -const char vertex_source_p_l_comp[] = - { - "attribute highp vec4 vertex;\n" - "attribute highp vec3 color;\n" - "uniform highp mat4 mvp_matrix;\n" - "varying highp vec4 fColor; \n" - "uniform highp float point_size; \n" - "void main(void)\n" - "{\n" - " gl_PointSize = point_size;\n" - " fColor = vec4(color, 1.0); \n" - " gl_Position = mvp_matrix * vertex;\n" - "}" - }; - -const char fragment_source_p_l_comp[] = - { - "varying highp vec4 fColor; \n" - "void main(void) { \n" - "gl_FragColor = fColor; \n" - "} \n" - "\n" - }; - - - //------------------------------------------------------------------------------ inline CGAL::Color get_random_color(CGAL::Random& random) { @@ -329,6 +163,8 @@ public: setShortcut(qglviewer::EXIT_VIEWER, ::Qt::CTRL+::Qt::Key_Q); // Add custom key description (see keyPressEvent). + setKeyDescription(::Qt::Key_C, "Switch clipping plane display mode"); + setKeyDescription(::Qt::Key_C+::Qt::AltModifier, "Toggle clipping plane rendering on/off"); setKeyDescription(::Qt::Key_E, "Toggles edges display"); setKeyDescription(::Qt::Key_M, "Toggles mono color"); setKeyDescription(::Qt::Key_N, "Inverse direction of normals"); @@ -345,6 +181,11 @@ public: setKeyDescription(::Qt::Key_PageUp, "Decrease light (all colors, use shift/alt/ctrl for one rgb component)"); setKeyDescription(::Qt::Key_O, "Toggles 2D mode only"); + // Add custom mouse description + setMouseBindingDescription(::Qt::Key_C, ::Qt::ControlModifier, ::Qt::LeftButton, "Rotate the clipping plane when enabled"); + setMouseBindingDescription(::Qt::Key_C, ::Qt::ControlModifier, ::Qt::RightButton, "Translate the clipping plane when enabled"); + setMouseBindingDescription(::Qt::Key_C, ::Qt::ControlModifier, ::Qt::MidButton, "Control the clipping plane transparency when enabled"); + if (title[0]==0) setWindowTitle("CGAL Basic Viewer"); else @@ -623,6 +464,7 @@ protected: { rendering_program_face.removeAllShaders(); rendering_program_p_l.removeAllShaders(); + rendering_program_clipping_plane.removeAllShaders(); // Create the buffers for (unsigned int i=0; icompileSourceCode(source_)) - { std::cerr<<"Compiling fragmentsource FAILED"<compileSourceCode(source_)) + { std::cerr << "Compiling vertex source for clipping plane FAILED" << std::endl; } + + source_ = fragment_source_clipping_plane; + + QOpenGLShader *fragment_shader_clipping_plane = new QOpenGLShader(QOpenGLShader::Fragment); + if (!fragment_shader_clipping_plane->compileSourceCode(source_)) + { std::cerr << "Compiling fragment source for clipping plane FAILED" << std::endl; } + + if (!rendering_program_clipping_plane.addShader(vertex_shader_clipping_plane)) + { std::cerr << "Adding vertex shader for clipping plane FAILED" << std::endl;} + if (!rendering_program_clipping_plane.addShader(fragment_shader_clipping_plane)) + { std::cerr << "Adding fragment shader for clipping plane FAILED" << std::endl; } + if (!rendering_program_clipping_plane.link()) + { std::cerr << "Linking Program for clipping plane FAILED" << std::endl; } + + } + + // source_ = isOpenGL_4_3() + // ? vertex_source_clipping_plane + // : vertex_source_clipping_plane_comp; + + // QOpenGLShader *vertex_shader_clipping_plane = new QOpenGLShader(QOpenGLShader::Vertex); + // if (!vertex_shader_clipping_plane->compileSourceCode(source_)) + // { std::cerr << "Compiling vertex source for clipping plane FAILED" << std::endl; } + + // source_ = isOpenGL_4_3() + // ? fragment_source_clipping_plane + // : fragment_source_clipping_plane_comp; + + // QOpenGLShader *fragment_shader_clipping_plane = new QOpenGLShader(QOpenGLShader::Fragment); + // if (!fragment_shader_clipping_plane->compileSourceCode(source_)) + // { std::cerr << "Compiling fragment source for clipping plane FAILED" << std::endl; } + + // if (!rendering_program_clipping_plane.addShader(vertex_shader_clipping_plane)) + // { std::cerr << "Adding vertex shader for clipping plane FAILED" << std::endl;} + // if (!rendering_program_clipping_plane.addShader(fragment_shader_clipping_plane)) + // { std::cerr << "Adding fragment shader for clipping plane FAILED" << std::endl; } + // if (!rendering_program_clipping_plane.link()) + // { std::cerr << "Linking Program for clipping plane FAILED" << std::endl; } } void initialize_buffers() @@ -962,6 +853,25 @@ protected: rendering_program_face.release(); + // 6) clipping plane shader + if (isOpenGL_4_3()) + { + rendering_program_clipping_plane.bind(); + + vao[VAO_CLIPPING_PLANE].bind(); + ++bufn; + assert(bufn < NB_VBO_BUFFERS); + buffers[bufn].bind(); + buffers[bufn].allocate(arrays[POS_CLIPPING_PLANE].data(), + static_cast(arrays[POS_CLIPPING_PLANE].size() * sizeof(float))); + rendering_program_clipping_plane.enableAttributeArray("vertex"); + rendering_program_clipping_plane.setAttributeBuffer("vertex", GL_FLOAT, 0, 3); + + buffers[bufn].release(); + + rendering_program_clipping_plane.release(); + } + m_are_buffers_initialized = true; } @@ -1028,6 +938,21 @@ protected: int mvpLocation2 = rendering_program_p_l.uniformLocation("mvp_matrix"); rendering_program_p_l.setUniformValue(mvpLocation2, mvpMatrix); rendering_program_p_l.release(); + + if (isOpenGL_4_3()) + { + QMatrix4x4 clipping_mMatrix; + clipping_mMatrix.setToIdentity(); + clipping_mMatrix.rotate(clipping_plane_rotation); + clipping_mMatrix.translate(0.0, 0.0, clipping_plane_translation_z); + + rendering_program_clipping_plane.bind(); + int vpLocation = rendering_program_clipping_plane.uniformLocation("vp_matrix"); + int mLocation = rendering_program_clipping_plane.uniformLocation("m_matrix"); + rendering_program_clipping_plane.setUniformValue(vpLocation, mvpMatrix); + rendering_program_clipping_plane.setUniformValue(mLocation, clipping_mMatrix); + rendering_program_clipping_plane.release(); + } } // Returns true if the data structure lies on a plane @@ -1039,6 +964,13 @@ protected: virtual void draw() { glEnable(GL_DEPTH_TEST); + + // get clipping plane model matrix + QMatrix4x4 clipping_mMatrix; + clipping_mMatrix.setToIdentity(); + clipping_mMatrix.rotate(clipping_plane_rotation); + QVector4D clipPlane = clipping_mMatrix * QVector4D(0.0, 0.0, 1.0, clipping_plane_translation_z); + if(!m_are_buffers_initialized) { initialize_buffers(); } @@ -1071,31 +1003,55 @@ protected: { rendering_program_p_l.bind(); - vao[VAO_MONO_POINTS].bind(); - color.setRgbF((double)m_vertices_mono_color.red()/(double)255, - (double)m_vertices_mono_color.green()/(double)255, - (double)m_vertices_mono_color.blue()/(double)255); - rendering_program_p_l.setAttributeValue("color",color); - rendering_program_p_l.setUniformValue("point_size", GLfloat(m_size_points)); - glDrawArrays(GL_POINTS, 0, static_cast(arrays[POS_MONO_POINTS].size()/3)); - vao[VAO_MONO_POINTS].release(); - - vao[VAO_COLORED_POINTS].bind(); - if (m_use_mono_color) - { + // rendering_mode == -1: draw all + // rendering_mode == 0: draw inside clipping plane + // rendering_mode == 1: draw outside clipping plane + auto renderer = [this, &color, &clipPlane](float rendering_mode) { + vao[VAO_MONO_POINTS].bind(); color.setRgbF((double)m_vertices_mono_color.red()/(double)255, (double)m_vertices_mono_color.green()/(double)255, - (double)m_vertices_mono_color.blue()/(double)255); - rendering_program_p_l.disableAttributeArray("color"); + (double)m_vertices_mono_color.blue()/(double)255); rendering_program_p_l.setAttributeValue("color",color); + rendering_program_p_l.setUniformValue("point_size", GLfloat(m_size_points)); + rendering_program_p_l.setUniformValue("clipPlane", clipPlane); + rendering_program_p_l.setUniformValue("rendering_mode", rendering_mode); + glDrawArrays(GL_POINTS, 0, static_cast(arrays[POS_MONO_POINTS].size()/3)); + vao[VAO_MONO_POINTS].release(); + + vao[VAO_COLORED_POINTS].bind(); + if (m_use_mono_color) + { + color.setRgbF((double)m_vertices_mono_color.red()/(double)255, + (double)m_vertices_mono_color.green()/(double)255, + (double)m_vertices_mono_color.blue()/(double)255); + rendering_program_p_l.disableAttributeArray("color"); + rendering_program_p_l.setAttributeValue("color",color); + } + else + { + rendering_program_p_l.enableAttributeArray("color"); + } + rendering_program_p_l.setUniformValue("point_size", GLfloat(m_size_points)); + rendering_program_p_l.setUniformValue("clipPlane", clipPlane); + rendering_program_p_l.setUniformValue("rendering_mode", rendering_mode); + glDrawArrays(GL_POINTS, 0, static_cast(arrays[POS_COLORED_POINTS].size()/3)); + vao[VAO_COLORED_POINTS].release(); + }; + + enum { + DRAW_ALL = -1, // draw all + DRAW_INSIDE_ONLY, // draw only the part inside the clipping plane + DRAW_OUTSIDE_ONLY // draw only the part outside the clipping plane + }; + + if (m_use_clipping_plane == CLIPPING_PLANE_SOLID_HALF_ONLY) + { + renderer(DRAW_INSIDE_ONLY); } else { - rendering_program_p_l.enableAttributeArray("color"); + renderer(DRAW_ALL); } - rendering_program_p_l.setUniformValue("point_size", GLfloat(m_size_points)); - glDrawArrays(GL_POINTS, 0, static_cast(arrays[POS_COLORED_POINTS].size()/3)); - vao[VAO_COLORED_POINTS].release(); rendering_program_p_l.release(); } @@ -1104,31 +1060,55 @@ protected: { rendering_program_p_l.bind(); - vao[VAO_MONO_SEGMENTS].bind(); - color.setRgbF((double)m_edges_mono_color.red()/(double)255, - (double)m_edges_mono_color.green()/(double)255, - (double)m_edges_mono_color.blue()/(double)255); - rendering_program_p_l.setAttributeValue("color",color); - glLineWidth(m_size_edges); - glDrawArrays(GL_LINES, 0, static_cast(arrays[POS_MONO_SEGMENTS].size()/3)); - vao[VAO_MONO_SEGMENTS].release(); - - vao[VAO_COLORED_SEGMENTS].bind(); - if (m_use_mono_color) - { + // rendering_mode == -1: draw all + // rendering_mode == 0: draw inside clipping plane + // rendering_mode == 1: draw outside clipping plane + auto renderer = [this, &color, &clipPlane](float rendering_mode) { + vao[VAO_MONO_SEGMENTS].bind(); color.setRgbF((double)m_edges_mono_color.red()/(double)255, (double)m_edges_mono_color.green()/(double)255, (double)m_edges_mono_color.blue()/(double)255); - rendering_program_p_l.disableAttributeArray("color"); rendering_program_p_l.setAttributeValue("color",color); + rendering_program_p_l.setUniformValue("clipPlane", clipPlane); + rendering_program_p_l.setUniformValue("rendering_mode", rendering_mode); + glLineWidth(m_size_edges); + glDrawArrays(GL_LINES, 0, static_cast(arrays[POS_MONO_SEGMENTS].size()/3)); + vao[VAO_MONO_SEGMENTS].release(); + + vao[VAO_COLORED_SEGMENTS].bind(); + if (m_use_mono_color) + { + color.setRgbF((double)m_edges_mono_color.red()/(double)255, + (double)m_edges_mono_color.green()/(double)255, + (double)m_edges_mono_color.blue()/(double)255); + rendering_program_p_l.disableAttributeArray("color"); + rendering_program_p_l.setAttributeValue("color",color); + } + else + { + rendering_program_p_l.enableAttributeArray("color"); + } + rendering_program_p_l.setUniformValue("clipPlane", clipPlane); + rendering_program_p_l.setUniformValue("rendering_mode", rendering_mode); + glLineWidth(m_size_edges); + glDrawArrays(GL_LINES, 0, static_cast(arrays[POS_COLORED_SEGMENTS].size()/3)); + vao[VAO_COLORED_SEGMENTS].release(); + }; + + enum { + DRAW_ALL = -1, // draw all + DRAW_INSIDE_ONLY, // draw only the part inside the clipping plane + DRAW_OUTSIDE_ONLY // draw only the part outside the clipping plane + }; + + if (m_use_clipping_plane == CLIPPING_PLANE_SOLID_HALF_ONLY) + { + renderer(DRAW_INSIDE_ONLY); } else { - rendering_program_p_l.enableAttributeArray("color"); + renderer(DRAW_ALL); } - glLineWidth(m_size_edges); - glDrawArrays(GL_LINES, 0, static_cast(arrays[POS_COLORED_SEGMENTS].size()/3)); - vao[VAO_COLORED_SEGMENTS].release(); rendering_program_p_l.release(); } @@ -1214,29 +1194,102 @@ protected: { rendering_program_face.bind(); + // reference: https://stackoverflow.com/questions/37780345/opengl-how-to-create-order-independent-transparency + // rendering_mode == -1: draw all as solid; + // rendering_mode == 0: draw solid only; + // rendering_mode == 1: draw transparent only; + auto renderer = [this, &color, &clipPlane](float rendering_mode) { + vao[VAO_MONO_FACES].bind(); color.setRgbF((double)m_faces_mono_color.red()/(double)255, (double)m_faces_mono_color.green()/(double)255, (double)m_faces_mono_color.blue()/(double)255); rendering_program_face.setAttributeValue("color",color); + rendering_program_face.setUniformValue("rendering_mode", rendering_mode); + rendering_program_face.setUniformValue("rendering_transparency", clipping_plane_rendering_transparency); + rendering_program_face.setUniformValue("clipPlane", clipPlane); glDrawArrays(GL_TRIANGLES, 0, static_cast(arrays[POS_MONO_FACES].size()/3)); vao[VAO_MONO_FACES].release(); - vao[VAO_COLORED_FACES].bind(); - if (m_use_mono_color) + vao[VAO_COLORED_FACES].bind(); + if (m_use_mono_color) + { + color.setRgbF((double)m_faces_mono_color.red()/(double)255, + (double)m_faces_mono_color.green()/(double)255, + (double)m_faces_mono_color.blue()/(double)255); + rendering_program_face.disableAttributeArray("color"); + rendering_program_face.setAttributeValue("color",color); + } + else + { + rendering_program_face.enableAttributeArray("color"); + } + rendering_program_face.setUniformValue("rendering_mode", rendering_mode); + rendering_program_face.setUniformValue("rendering_transparency", clipping_plane_rendering_transparency); + rendering_program_face.setUniformValue("clipPlane", clipPlane); + glDrawArrays(GL_TRIANGLES, 0, static_cast(arrays[POS_COLORED_FACES].size()/3)); + vao[VAO_COLORED_FACES].release(); + }; + + auto renderer_clipping_plane = [this](bool clipping_plane_rendering) { + if (!isOpenGL_4_3()) return; + if (!clipping_plane_rendering) return; + // render clipping plane here + rendering_program_clipping_plane.bind(); + vao[VAO_CLIPPING_PLANE].bind(); + glLineWidth(0.1f); + glDrawArrays(GL_LINES, 0, static_cast(arrays[POS_CLIPPING_PLANE].size() / 3)); + glLineWidth(1.0f); + vao[VAO_CLIPPING_PLANE].release(); + rendering_program_clipping_plane.release(); + }; + + enum { + DRAW_SOLID_ALL = -1, // draw all mesh in solid mode + DRAW_SOLID_HALF, // draw only the mesh inside the clipping plane as solid + DRAW_TRANSPARENT_HALF // draw only the mesh outside the clipping plane as transparent + }; + + if (m_use_clipping_plane == CLIPPING_PLANE_SOLID_HALF_TRANSPARENT_HALF) { - color.setRgbF((double)m_faces_mono_color.red()/(double)255, - (double)m_faces_mono_color.green()/(double)255, - (double)m_faces_mono_color.blue()/(double)255); - rendering_program_face.disableAttributeArray("color"); - rendering_program_face.setAttributeValue("color",color); + // The z-buffer will prevent transparent objects from being displayed behind other transparent objects. + // Before rendering all transparent objects, disable z-testing first. + + // 1. draw solid first + renderer(DRAW_SOLID_HALF); + + // 2. draw transparent layer second with back face culling to avoid messy triangles + glDepthMask(false); //disable z-testing + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + glFrontFace(GL_CW); + renderer(DRAW_TRANSPARENT_HALF); + + // 3. draw solid again without culling and blend to make sure the solid mesh is visible + glDepthMask(true); //enable z-testing + glDisable(GL_CULL_FACE); + glDisable(GL_BLEND); + renderer(DRAW_SOLID_HALF); + + // 4. render clipping plane here + renderer_clipping_plane(clipping_plane_rendering); + } + else if (m_use_clipping_plane == CLIPPING_PLANE_SOLID_HALF_WIRE_HALF || + m_use_clipping_plane == CLIPPING_PLANE_SOLID_HALF_ONLY) + { + // 1. draw solid HALF + renderer(DRAW_SOLID_HALF); + + // 2. render clipping plane here + renderer_clipping_plane(clipping_plane_rendering); } else { - rendering_program_face.enableAttributeArray("color"); + // 1. draw solid FOR ALL + renderer(DRAW_SOLID_ALL); } - glDrawArrays(GL_TRIANGLES, 0, static_cast(arrays[POS_COLORED_FACES].size()/3)); - vao[VAO_COLORED_FACES].release(); if (is_two_dimensional()) glPolygonOffset(offset_factor, offset_units); @@ -1294,6 +1347,32 @@ protected: bb.ymax(), bb.zmax())); + // init clipping plane array + auto generate_clipping_plane = [this](qreal size, int nbSubdivisions) + { + for (int i = 0; i <= nbSubdivisions; i++) + { + const float pos = float(size*(2.0*i/nbSubdivisions-1.0)); + arrays[POS_CLIPPING_PLANE].push_back(pos); + arrays[POS_CLIPPING_PLANE].push_back(float(-size)); + arrays[POS_CLIPPING_PLANE].push_back(0.f); + + arrays[POS_CLIPPING_PLANE].push_back(pos); + arrays[POS_CLIPPING_PLANE].push_back(float(+size)); + arrays[POS_CLIPPING_PLANE].push_back(0.f); + + arrays[POS_CLIPPING_PLANE].push_back(float(-size)); + arrays[POS_CLIPPING_PLANE].push_back(pos); + arrays[POS_CLIPPING_PLANE].push_back(0.f); + + arrays[POS_CLIPPING_PLANE].push_back(float(size)); + arrays[POS_CLIPPING_PLANE].push_back(pos); + arrays[POS_CLIPPING_PLANE].push_back(0.f); + } + }; + clipping_plane_rendering_size = ((bb.xmax() - bb.xmin()) + (bb.ymax() - bb.ymin()) + (bb.zmax() - bb.zmin())) / 3; + generate_clipping_plane(3.0 * clipping_plane_rendering_size, 30); + this->showEntireScene(); } @@ -1307,7 +1386,45 @@ protected: { const ::Qt::KeyboardModifiers modifiers = e->modifiers(); - if ((e->key()==::Qt::Key_E) && (modifiers==::Qt::NoButton)) + if ((e->key()==::Qt::Key_C) && (modifiers==::Qt::NoButton)) + { + if (!isOpenGL_4_3()) return; + if (!is_two_dimensional()) + { + // toggle clipping plane + m_use_clipping_plane = (m_use_clipping_plane + 1) % CLIPPING_PLANE_END_INDEX; + switch(m_use_clipping_plane) + { + case CLIPPING_PLANE_OFF: displayMessage(QString("Draw clipping = flase")); break; + case CLIPPING_PLANE_SOLID_HALF_TRANSPARENT_HALF: clipping_plane_rendering=true; displayMessage(QString("Draw clipping = solid half & transparent half")); break; + case CLIPPING_PLANE_SOLID_HALF_WIRE_HALF: displayMessage(QString("Draw clipping = solid half & wireframe half")); break; + case CLIPPING_PLANE_SOLID_HALF_ONLY: displayMessage(QString("Draw clipping = solid half only")); break; + default: break; + } + update(); + } + } + else if ((e->key()==::Qt::Key_C) && (modifiers==::Qt::ControlModifier)) + { + if (!isOpenGL_4_3()) return; + if (m_use_clipping_plane!=CLIPPING_PLANE_OFF) + { + // enable clipping operation i.e. rotation, translation, and transparency adjustment + clipping_plane_operation = true; + update(); + } + } + else if ((e->key()==::Qt::Key_C) && (modifiers==::Qt::AltModifier)) + { + if (!isOpenGL_4_3()) return; + if (m_use_clipping_plane!=CLIPPING_PLANE_OFF) + { + clipping_plane_rendering = !clipping_plane_rendering; + displayMessage(QString("Draw clipping plane=%1.").arg(clipping_plane_rendering?"true":"false")); + update(); + } + } + else if ((e->key()==::Qt::Key_E) && (modifiers==::Qt::NoButton)) { m_draw_edges=!m_draw_edges; displayMessage(QString("Draw edges=%1.").arg(m_draw_edges?"true":"false")); @@ -1489,6 +1606,73 @@ protected: CGAL::QGLViewer::keyPressEvent(e); } + virtual void keyReleaseEvent(QKeyEvent *e) + { + const ::Qt::KeyboardModifiers modifiers = e->modifiers(); + if ((e->key()==::Qt::Key_C)) + { + clipping_plane_operation = false; + } + } + + virtual void mousePressEvent(QMouseEvent *e) { + if (clipping_plane_operation && e->modifiers() == ::Qt::ControlModifier && e->buttons() == ::Qt::LeftButton) { + // rotation starting point + clipping_plane_rotation_tracker = QVector2D(e->localPos()); + } + else if (clipping_plane_operation && e->modifiers() == ::Qt::ControlModifier && e->buttons() == ::Qt::RightButton) + { + // translation starting point + clipping_plane_translation_tracker = QVector2D(e->localPos()); + } + else + { + CGAL::QGLViewer::mousePressEvent(e); + } + } + + virtual void mouseMoveEvent(QMouseEvent *e) { + if (clipping_plane_operation && e->modifiers() == ::Qt::ControlModifier && e->buttons() == ::Qt::LeftButton) + { + // rotation ending point + QVector2D diff = QVector2D(e->localPos()) - clipping_plane_rotation_tracker; + clipping_plane_rotation_tracker = QVector2D(e->localPos()); + + QVector3D axis = QVector3D(diff.y(), diff.x(), 0.0); + float angle = diff.length(); + clipping_plane_rotation = QQuaternion::fromAxisAndAngle(axis, angle) * clipping_plane_rotation; + + update(); + } + else if (clipping_plane_operation && e->modifiers() == ::Qt::ControlModifier && e->buttons() == ::Qt::RightButton) + { + // translation ending point + QVector2D diff = QVector2D(e->localPos()) - clipping_plane_translation_tracker; + clipping_plane_translation_tracker = QVector2D(e->localPos()); + + clipping_plane_translation_z += clipping_plane_rendering_size / 500 * (diff.y() > 0 ? -1.0 : diff.y() < 0 ? 1.0 : 0.0) * diff.length(); + + update(); + } + else + { + CGAL::QGLViewer::mouseMoveEvent(e); + } + } + + virtual void wheelEvent(QWheelEvent *e) + { + if (clipping_plane_operation && e->modifiers() == ::Qt::ControlModifier) { + clipping_plane_rendering_transparency += (e->delta() / 120.0) / 50.0; + // clip to 0-1 + clipping_plane_rendering_transparency = clipping_plane_rendering_transparency > 1.0 ? 1.0 : clipping_plane_rendering_transparency < 0.0 ? 0.0 : clipping_plane_rendering_transparency; + } + else + { + CGAL::QGLViewer::wheelEvent(e); + } + } + virtual QString helpString() const { return helpString("CGAL Basic Viewer"); } @@ -1536,6 +1720,16 @@ protected: bool m_draw_text; bool m_no_2D_mode; + enum { + CLIPPING_PLANE_OFF = 0, + CLIPPING_PLANE_SOLID_HALF_TRANSPARENT_HALF, + CLIPPING_PLANE_SOLID_HALF_WIRE_HALF, + CLIPPING_PLANE_SOLID_HALF_ONLY, + CLIPPING_PLANE_END_INDEX + }; + + int m_use_clipping_plane = CLIPPING_PLANE_OFF; + double m_size_points; double m_size_edges; double m_size_rays; @@ -1568,6 +1762,7 @@ protected: POS_COLORED_LINES, POS_MONO_FACES, POS_COLORED_FACES, + POS_CLIPPING_PLANE, END_POS, BEGIN_COLOR=END_POS, COLOR_POINTS=BEGIN_COLOR, @@ -1596,6 +1791,7 @@ protected: Buffer_for_vao m_buffer_for_colored_lines; Buffer_for_vao m_buffer_for_mono_faces; Buffer_for_vao m_buffer_for_colored_faces; + Buffer_for_vao m_buffer_for_clipping_plane; static const unsigned int NB_VBO_BUFFERS=(END_POS-BEGIN_POS)+ (END_COLOR-BEGIN_COLOR)+2; // +2 for 2 vectors of normals @@ -1614,12 +1810,24 @@ protected: VAO_COLORED_LINES, VAO_MONO_FACES, VAO_COLORED_FACES, + VAO_CLIPPING_PLANE, NB_VAO_BUFFERS }; QOpenGLVertexArrayObject vao[NB_VAO_BUFFERS]; QOpenGLShaderProgram rendering_program_face; QOpenGLShaderProgram rendering_program_p_l; + QOpenGLShaderProgram rendering_program_clipping_plane; + + // variables for clipping plane + bool clipping_plane_operation = false; // will be enabled/diabled when ctrl+c is pressed/released, which is used for clipping plane translation and rotation; + QVector2D clipping_plane_rotation_tracker; // will be enabled when ctrl+c+left is pressed, which is used to record rotation; + QQuaternion clipping_plane_rotation; // real rotation; + QVector2D clipping_plane_translation_tracker; // will be enabled when ctrl+c+right is pressed, which is used to record translation; + float clipping_plane_translation_z = 0.0f; // real translation; + bool clipping_plane_rendering = true; // will be toggled when alt+c is pressed, which is used for indicating whether or not to render the clipping plane ; + float clipping_plane_rendering_transparency = 0.5f; // to what extent the transparent part should be rendered; + float clipping_plane_rendering_size; // to what extent the size of clipping plane should be rendered; std::vector > m_texts; }; From de7dd44307b8016f26568dc0897feac4b810f7a1 Mon Sep 17 00:00:00 2001 From: Guillaume Damiand Date: Wed, 27 Jan 2021 18:53:59 +0100 Subject: [PATCH 089/248] add licence header --- GraphicsView/include/CGAL/Basic_shaders.h | 2 ++ GraphicsView/include/CGAL/Buffer_for_vao.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/GraphicsView/include/CGAL/Basic_shaders.h b/GraphicsView/include/CGAL/Basic_shaders.h index 429f2b52f00..92422b0dc3a 100644 --- a/GraphicsView/include/CGAL/Basic_shaders.h +++ b/GraphicsView/include/CGAL/Basic_shaders.h @@ -13,6 +13,8 @@ #ifndef CGAL_BASIC_SHADERS_H #define CGAL_BASIC_SHADERS_H +#include + namespace CGAL { diff --git a/GraphicsView/include/CGAL/Buffer_for_vao.h b/GraphicsView/include/CGAL/Buffer_for_vao.h index c27e24e50c9..2be331a35f5 100644 --- a/GraphicsView/include/CGAL/Buffer_for_vao.h +++ b/GraphicsView/include/CGAL/Buffer_for_vao.h @@ -908,7 +908,7 @@ protected: bool m_zero_y; /// True iff all points have y==0 bool m_zero_z; /// True iff all points have z==0 - bool m_inverse_normal;; + bool m_inverse_normal; // Local variables, used when we started a new face.g bool m_face_started; From 1eb035085d49d9ac9d1ab393ae1a48428d1c8ac2 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 28 Jan 2021 10:53:28 +0100 Subject: [PATCH 090/248] Fix Surface_sweep_2 tests --- .../test/Surface_sweep_2/cgal_test_base | 84 +++++++++---------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/Surface_sweep_2/test/Surface_sweep_2/cgal_test_base b/Surface_sweep_2/test/Surface_sweep_2/cgal_test_base index f816494641d..20ec132f55b 100755 --- a/Surface_sweep_2/test/Surface_sweep_2/cgal_test_base +++ b/Surface_sweep_2/test/Surface_sweep_2/cgal_test_base @@ -36,7 +36,7 @@ configure() if eval 'cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} "$CMAKE_GENERATOR" -DRUNNING_CGAL_AUTO_TEST=TRUE \ -DCGAL_DIR="$CGAL_DIR" \ -DCGAL_CXX_FLAGS:STRING="$CGAL_CXX_FLAGS $TESTSUITE_CXXFLAGS" \ - -DCGAL_EXE_LINKER_FLAGS="CGAL_EXE_LINKER_FLAGS $TESTSUITE_LDFLAGS" \ + -DCGAL_EXE_LINKER_FLAGS="$CGAL_EXE_LINKER_FLAGS $TESTSUITE_LDFLAGS" \ .' ; then echo " successful configuration" >> $ERRORFILE else @@ -78,12 +78,12 @@ compile() compile_and_run() { - + echo "---$1---" # running general test if compile $1 $2 $3 ; then - echo " compilation of $1 succeeded" >> $ERRORFILE + echo " compilation of $1 succeeded" >> $ERRORFILE SUBCURVES="" run $1 $2 $3 $4 SUBCURVES="subcurves" @@ -100,14 +100,14 @@ clean_tests() { if [ "${TEST_WITH_CMAKE}" != "FALSE" ]; then # - # The clean target generated by CMake under cygwin + # The clean target generated by CMake under cygwin # always fails for some reason # - if ! ( uname | grep -q "CYGWIN" ) ; then - "${MAKE_CMD}" -f Makefile clean - fi + if ! ( uname | grep -q "CYGWIN" ) ; then + "${MAKE_CMD}" -f Makefile clean + fi else - eval "${MAKE_CMD} clean > /dev/null 2>&1" + eval "${MAKE_CMD} clean > /dev/null 2>&1" fi } @@ -117,7 +117,7 @@ compile_and_run_sweep() # running general test if compile $1 $2 $3 ; then - echo " compilation of $1 succeeded" >> $ERRORFILE + echo " compilation of $1 succeeded" >> $ERRORFILE run $1 $2 $3 $4 else echo " ERROR: compilation of $1 failed" >> $ERRORFILE @@ -134,28 +134,28 @@ run() for DATAFILE in ${datafiles} do if [ -d $DATAFILE ]; then - echo "$DATEFILE is a directory" + echo "$DATEFILE is a directory" continue fi if [ -f $1 ] ; then DATANAME=`basename $DATAFILE` - if [ $SUBCURVES="subcurves" ] ; then - OUTPUTFILE=ProgramOutput.$3.$1.$DATANAME.$SUBCURVES.$PLATFORM.$2 + if [ $SUBCURVES="subcurves" ] ; then + OUTPUTFILE=ProgramOutput.$3.$1.$DATANAME.$SUBCURVES.$PLATFORM.$2 else - OUTPUTFILE=ProgramOutput.$3.$1.$DATANAME.$PLATFORM.$2 - fi - rm -f $OUTPUTFILE - COMMAND="./$1 $DATAFILE $SUBCURVES" - echo "Executing $1 $DATANAME $SUBCURVES ... " - echo - if eval $COMMAND > $OUTPUTFILE 2>&1 ; then - echo " execution of $1 $DATAFILE $SUBCURVES succeeded" >> $ERRORFILE - else - echo " ERROR: execution of $1 $DATAFILE $SUBCURVES failed" >> $ERRORFILE - fi + OUTPUTFILE=ProgramOutput.$3.$1.$DATANAME.$PLATFORM.$2 + fi + rm -f $OUTPUTFILE + COMMAND="./$1 $DATAFILE $SUBCURVES" + echo "Executing $1 $DATANAME $SUBCURVES ... " + echo + if eval $COMMAND > $OUTPUTFILE 2>&1 ; then + echo " execution of $1 $DATAFILE $SUBCURVES succeeded" >> $ERRORFILE + else + echo " ERROR: execution of $1 $DATAFILE $SUBCURVES failed" >> $ERRORFILE + fi else - echo " ERROR: could not execute $1 $DATAFILE $SUBCURVES" >> $ERRORFILE + echo " ERROR: could not execute $1 $DATAFILE $SUBCURVES" >> $ERRORFILE fi done @@ -178,33 +178,33 @@ run_io() for DATAFILE in ${datafiles} do - + if [ -d $DATAFILE ]; then - echo "$DATEFILE is a directory" + echo "$DATEFILE is a directory" continue fi - + IOFILE="${iofiles}`basename ${DATAFILE}`_${SUFFIO}" echo $IOFILE - + if [ -f $1 ] ; then rm -f arr.txt - + DATANAME=`basename $DATAFILE` - IONAME=`basename $IOFILE` + IONAME=`basename $IOFILE` OUTPUTFILE=ProgramOutput.$3.$1.$DATANAME.$PLATFORM.$2 - rm -f $OUTPUTFILE - COMMAND="./$1 $IOFILE $DATAFILE" - echo "Executing $1 $IONAME $DATANAME ... " - echo - if eval $COMMAND > $OUTPUTFILE 2>&1 ; then - echo " execution of $1 $DATAFILE succeeded" >> $ERRORFILE - else - echo " ERROR: execution of $1 $DATAFILE failed" >> $ERRORFILE - fi + rm -f $OUTPUTFILE + COMMAND="./$1 $IOFILE $DATAFILE" + echo "Executing $1 $IONAME $DATANAME ... " + echo + if eval $COMMAND > $OUTPUTFILE 2>&1 ; then + echo " execution of $1 $DATAFILE succeeded" >> $ERRORFILE + else + echo " ERROR: execution of $1 $DATAFILE failed" >> $ERRORFILE + fi else - echo " ERROR: could not execute $1 $DATAFILE " >> $ERRORFILE + echo " ERROR: could not execute $1 $DATAFILE " >> $ERRORFILE fi done @@ -224,8 +224,8 @@ touch $ERRORFILE if [ $# -ne 0 ] ; then case $1 in - -cmake) TEST_WITH_CMAKE="TRUE" ;; - *)TEST_WITH_CMAKE="FALSE" ;; + -cmake) TEST_WITH_CMAKE="TRUE" ;; + *)TEST_WITH_CMAKE="FALSE" ;; esac else TEST_WITH_CMAKE="FALSE" From 5039f813ae82cb5866563ba65b3ff32c78225ede Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 28 Jan 2021 11:21:32 +0100 Subject: [PATCH 091/248] Add move assign to Rigid_triangle_mesh_collision_detection --- .../Rigid_triangle_mesh_collision_detection.h | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/Polygon_mesh_processing/include/CGAL/Rigid_triangle_mesh_collision_detection.h b/Polygon_mesh_processing/include/CGAL/Rigid_triangle_mesh_collision_detection.h index 66db17ed253..4ca03b1cf86 100644 --- a/Polygon_mesh_processing/include/CGAL/Rigid_triangle_mesh_collision_detection.h +++ b/Polygon_mesh_processing/include/CGAL/Rigid_triangle_mesh_collision_detection.h @@ -176,6 +176,25 @@ public: : m_free_id(0) {} + /** + * Constructor moving an instance of Rigid_triangle_mesh_collision_detection to a new memory + * location with minimal memory copy. + * @param other The instance to be moved + */ + Rigid_triangle_mesh_collision_detection(Rigid_triangle_mesh_collision_detection&& other) + : + m_own_aabb_trees {std::move(other.m_own_aabb_trees)} + ,m_aabb_trees {std::move(other.m_aabb_trees)} + ,m_is_closed {std::move(other.m_is_closed)} + ,m_points_per_cc {std::move(other.m_points_per_cc)} + ,m_traversal_traits {std::move(other.m_traversal_traits)} + ,m_free_id {std::move(other.m_free_id)} + ,m_id_pool {std::move(other.m_id_pool)} + { + for(std::size_t i = 0; i< other.m_own_aabb_trees.size(); ++i) + other.m_own_aabb_trees[i]= false; + } + ~Rigid_triangle_mesh_collision_detection() { for (std::size_t k=0; k Date: Thu, 28 Jan 2021 12:00:40 +0100 Subject: [PATCH 092/248] clean-up --- .../CGAL/Rigid_triangle_mesh_collision_detection.h | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Rigid_triangle_mesh_collision_detection.h b/Polygon_mesh_processing/include/CGAL/Rigid_triangle_mesh_collision_detection.h index 4ca03b1cf86..e3addd9a1da 100644 --- a/Polygon_mesh_processing/include/CGAL/Rigid_triangle_mesh_collision_detection.h +++ b/Polygon_mesh_processing/include/CGAL/Rigid_triangle_mesh_collision_detection.h @@ -176,11 +176,7 @@ public: : m_free_id(0) {} - /** - * Constructor moving an instance of Rigid_triangle_mesh_collision_detection to a new memory - * location with minimal memory copy. - * @param other The instance to be moved - */ + //! move constructor Rigid_triangle_mesh_collision_detection(Rigid_triangle_mesh_collision_detection&& other) : m_own_aabb_trees {std::move(other.m_own_aabb_trees)} @@ -204,12 +200,7 @@ public: } } - /** - * Assign operator moving an instance of Rigid_triangle_mesh_collision_detection to this - * location with minimal memory copy. - * @param other The instance to be moved - * @return A reference to this - */ + //! move assignment operator Rigid_triangle_mesh_collision_detection& operator=(Rigid_triangle_mesh_collision_detection&& other) { m_own_aabb_trees = std::move(other.m_own_aabb_trees); From a0686c10ec11946d6c1035e99bc0600ebcf39996 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 28 Jan 2021 12:15:18 +0100 Subject: [PATCH 093/248] use *this = std::move(other); --- .../CGAL/Rigid_triangle_mesh_collision_detection.h | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Rigid_triangle_mesh_collision_detection.h b/Polygon_mesh_processing/include/CGAL/Rigid_triangle_mesh_collision_detection.h index e3addd9a1da..9ef6d87f8ef 100644 --- a/Polygon_mesh_processing/include/CGAL/Rigid_triangle_mesh_collision_detection.h +++ b/Polygon_mesh_processing/include/CGAL/Rigid_triangle_mesh_collision_detection.h @@ -179,16 +179,8 @@ public: //! move constructor Rigid_triangle_mesh_collision_detection(Rigid_triangle_mesh_collision_detection&& other) : - m_own_aabb_trees {std::move(other.m_own_aabb_trees)} - ,m_aabb_trees {std::move(other.m_aabb_trees)} - ,m_is_closed {std::move(other.m_is_closed)} - ,m_points_per_cc {std::move(other.m_points_per_cc)} - ,m_traversal_traits {std::move(other.m_traversal_traits)} - ,m_free_id {std::move(other.m_free_id)} - ,m_id_pool {std::move(other.m_id_pool)} { - for(std::size_t i = 0; i< other.m_own_aabb_trees.size(); ++i) - other.m_own_aabb_trees[i]= false; + *this = std::move(other); } ~Rigid_triangle_mesh_collision_detection() From 7a91d9f1a575c85036d604c3a2b4ed8ac8ac3497 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Mon, 1 Feb 2021 12:36:34 +0000 Subject: [PATCH 094/248] With a subsequence p-q-p we do not simplify q --- .../simplify_overlapping_polyline.cpp | 2 +- .../include/CGAL/Polyline_simplification_2/simplify.h | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Polyline_simplification_2/examples/Polyline_simplification_2/simplify_overlapping_polyline.cpp b/Polyline_simplification_2/examples/Polyline_simplification_2/simplify_overlapping_polyline.cpp index 2df47f53932..96fa16269a3 100644 --- a/Polyline_simplification_2/examples/Polyline_simplification_2/simplify_overlapping_polyline.cpp +++ b/Polyline_simplification_2/examples/Polyline_simplification_2/simplify_overlapping_polyline.cpp @@ -27,7 +27,7 @@ int main() { CT ct; - std::vector P = { Point(0,1), Point(1,1), Point(2,2), Point(3,1), Point(4,1), Point(5,1) }; + std::vector P = { Point(0,1), Point(1,1), Point(2,2), Point(3,1), Point(4,1), Point(4,2), Point(4,1), Point(5,1) }; std::vector Q = { Point(5,0), Point(4,1), Point(3,1), Point(2,2), Point(1,1), Point(0,0) }; std::vector R = { Point(3,1), Point(4,1) }; diff --git a/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/simplify.h b/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/simplify.h index 579bcfc9707..1b40efc3202 100644 --- a/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/simplify.h +++ b/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/simplify.h @@ -155,9 +155,15 @@ public: Constraint_iterator cit = pct.constraints_begin(), e = pct.constraints_end(); for(; cit!=e; ++cit){ Constraint_id cid = *cit; - Vertices_in_constraint_iterator it = pct.vertices_in_constraint_begin(cid); + Vertices_in_constraint_iterator it = pct.vertices_in_constraint_begin(cid), + ite = pct.vertices_in_constraint_end(cid); (*it)->set_removable(false); - it = pct.vertices_in_constraint_end(cid); + ++it; + for(; it != ite; ++it){ + if((boost::next(it) != ite) && (boost::prior(it)== boost::next(it))){ + (*it)->set_removable(false); + } + } it = boost::prior(it); (*it)->set_removable(false); } From f339c25635bae2b4959b6ac02094e331dbc22b7f Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Mon, 1 Feb 2021 13:03:58 +0000 Subject: [PATCH 095/248] Use unordered_map --- .../include/CGAL/Polyline_simplification_2/simplify.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/simplify.h b/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/simplify.h index 1b40efc3202..41a046e9e69 100644 --- a/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/simplify.h +++ b/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/simplify.h @@ -17,6 +17,7 @@ #include #include +#include #include #include @@ -75,9 +76,9 @@ public: StopFunction stop; std::size_t pct_initial_number_of_vertices, number_of_unremovable_vertices; - std::map > vertex_to_iterator; + std::unordered_map > vertex_to_iterator; - typedef std::map Vertex_index_map; + typedef std::unordered_map Vertex_index_map; Vertex_index_map vertex_index_map; @@ -149,7 +150,7 @@ public: } // endpoints of constraints are unremovable - // vertices which are not endpoint and have != 2 incident constained edges are unremovable + // vertices which are not endpoint and have != 2 incident constrained edges are unremovable void initialize_unremovable() { Constraint_iterator cit = pct.constraints_begin(), e = pct.constraints_end(); @@ -168,7 +169,7 @@ public: (*it)->set_removable(false); } - std::map degrees; + std::unordered_map degrees; for (Constrained_edges_iterator it = pct.constrained_edges_begin(); it != pct.constrained_edges_end(); ++it) { Edge e = *it; Face_handle fh = e.first; @@ -192,7 +193,7 @@ public: it != pct.vertices_in_constraint_end(cid); ++it){ if((*it)->is_removable()){ - typename std::map >::iterator lit; + typename std::unordered_map >::iterator lit; lit = vertex_to_iterator.find(*it); if(lit != vertex_to_iterator.end()){ From 6dc30a144289381a5274b6b6f102aeeb54011321 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Mon, 1 Feb 2021 13:09:49 +0000 Subject: [PATCH 096/248] Update the change log --- Installation/CHANGES.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Installation/CHANGES.md b/Installation/CHANGES.md index 1bd032a7859..a7f93ab440a 100644 --- a/Installation/CHANGES.md +++ b/Installation/CHANGES.md @@ -21,10 +21,13 @@ A comprehensive list of the supported file formats is available in the Stream_su Bolun Wang, Teseo Schneider, Yixin Hu, Marco Attene, and Daniele Panozzo. "Exact and efficient polyhedral envelope containment check." (ACM Trans. Graph., 39-4, July 2020). -### [Surface Mesh Simplification](https://doc.cgal.org/5.3/Manual/packages.html#PkgSurfaceMeshSimplification) +### [Surface Mesh Simplification](https://doc.cgal.org/5.3/Manual/packages.html#PkgSurfaceMeshSimplification2) - Added a filtering mechanism so that costly tests get only applied to the next candidate for the edge collapse. - Added the class `Polyhedral_envelope_filter` that enables to perform mesh simplification inside a polyhedral envelope of the input mesh. +### [2D Polyline Simplification](https://doc.cgal.org/5.3/Manual/packages.html#PkgPolylineSiimplification) +- Subsequences of polylines that are shared are no longer marked as unremovable. + [Release 5.2](https://github.com/CGAL/cgal/releases/tag/v5.2) ----------- From a7a3931f0ac67a730a7a063b53010066b5061526 Mon Sep 17 00:00:00 2001 From: Guillaume Damiand Date: Tue, 2 Feb 2021 10:27:57 +0100 Subject: [PATCH 097/248] Update shaders --- GraphicsView/include/CGAL/Basic_shaders.h | 88 ++++++++++++----------- 1 file changed, 47 insertions(+), 41 deletions(-) diff --git a/GraphicsView/include/CGAL/Basic_shaders.h b/GraphicsView/include/CGAL/Basic_shaders.h index 92422b0dc3a..b3204549697 100644 --- a/GraphicsView/include/CGAL/Basic_shaders.h +++ b/GraphicsView/include/CGAL/Basic_shaders.h @@ -20,21 +20,21 @@ namespace CGAL //------------------------------------------------------------------------------ const char vertex_source_color[]=R"DELIM( -#version 120 -attribute highp vec4 vertex; -attribute highp vec3 normal; -attribute highp vec3 color; +#version 150 +in highp vec4 vertex; +in highp vec3 normal; +in highp vec3 color; uniform highp mat4 mvp_matrix; uniform highp mat4 mv_matrix; -varying highp vec4 fP; -varying highp vec3 fN; -varying highp vec4 fColor; +out highp vec4 fP; +out highp vec3 fN; +out highp vec4 fColor; uniform highp float point_size; -varying highp vec4 m_vertex; +out highp vec4 m_vertex; void main(void) { @@ -50,12 +50,13 @@ void main(void) )DELIM"; const char fragment_source_color[]=R"DELIM( -#version 120 -varying highp vec4 fP; -varying highp vec3 fN; -varying highp vec4 fColor; +#version 150 +out highp vec4 fP; +out highp vec3 fN; +out highp vec4 fColor; -varying highp vec4 m_vertex; +out highp vec4 m_vertex; +out highp vec4 out_color; uniform highp vec4 light_pos; uniform highp vec4 light_diff; @@ -95,20 +96,20 @@ void main(void) } // draw corresponding part - gl_FragColor = rendering_mode < 1 ? (diffuse + ambient) : + out_color = rendering_mode < 1 ? (diffuse + ambient) : vec4(diffuse.rgb + ambient.rgb, rendering_transparency); } )DELIM"; const char vertex_source_p_l[]=R"DELIM( -#version 120 -attribute highp vec4 vertex; -attribute highp vec3 color; +#version 150 +in highp vec4 vertex; +in highp vec3 color; uniform highp mat4 mvp_matrix; -varying highp vec4 fColor; +out highp vec4 fColor; -varying highp vec4 m_vertex; +out highp vec4 m_vertex; uniform highp float point_size; void main(void) @@ -121,9 +122,10 @@ void main(void) )DELIM"; const char fragment_source_p_l[]=R"DELIM( -#version 120 -varying highp vec4 fColor; -varying highp vec4 m_vertex; +#version 150 +out highp vec4 fColor; +out highp vec4 m_vertex; +out highp vec4 out_color; uniform highp vec4 clipPlane; uniform highp float rendering_mode; @@ -142,13 +144,13 @@ void main(void) discard; } - gl_FragColor = fColor; + out_color = fColor; } )DELIM"; const char vertex_source_clipping_plane[]=R"DELIM( -#version 120 -attribute highp vec4 vertex; +#version 150 +in highp vec4 vertex; uniform highp mat4 vp_matrix; uniform highp mat4 m_matrix; @@ -160,10 +162,11 @@ void main(void) )DELIM"; const char fragment_source_clipping_plane[]=R"DELIM( -#version 120 +#version 150 +out highp vec4 out_color; void main(void) { - gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); + out_color = vec4(0.0, 0.0, 0.0, 1.0); } )DELIM"; @@ -171,16 +174,16 @@ void main(void) // compatibility shaders const char vertex_source_color_comp[]=R"DELIM( -attribute highp vec4 vertex; -attribute highp vec3 normal; -attribute highp vec3 color; +in highp vec4 vertex; +in highp vec3 normal; +in highp vec3 color; uniform highp mat4 mvp_matrix; uniform highp mat4 mv_matrix; -varying highp vec4 fP; -varying highp vec3 fN; -varying highp vec4 fColor; +out highp vec4 fP; +out highp vec3 fN; +out highp vec4 fColor; uniform highp float point_size; @@ -200,9 +203,10 @@ void main(void) )DELIM"; const char fragment_source_color_comp[]=R"DELIM( -varying highp vec4 fP; -varying highp vec3 fN; -varying highp vec4 fColor; +out highp vec4 fP; +out highp vec3 fN; +out highp vec4 fColor; +out highp vec4 out_color; uniform highp vec4 light_pos; uniform highp vec4 light_diff; @@ -223,13 +227,13 @@ void main(void) highp vec4 diffuse = max(dot(N,L), 0.0) * light_diff * fColor; highp vec4 specular = pow(max(dot(R,V), 0.0), spec_power) * light_spec; - gl_FragColor = light_amb*fColor + diffuse; + out_color = light_amb*fColor + diffuse; } )DELIM"; const char vertex_source_p_l_comp[]=R"DELIM( -attribute highp vec4 vertex; -attribute highp vec3 color; +in highp vec4 vertex; +in highp vec3 color; uniform highp mat4 mvp_matrix; varying highp vec4 fColor; @@ -246,9 +250,10 @@ void main(void) const char fragment_source_p_l_comp[]=R"DELIM( varying highp vec4 fColor; +out highp vec4 out_color; void main(void) { - gl_FragColor = fColor; + out_color = fColor; } )DELIM"; @@ -265,9 +270,10 @@ void main(void) )DELIM"; const char fragment_source_clipping_plane_comp[]=R"DELIM( +out highp vec4 out_color; void main(void) { - gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); + out_color = vec4(0.0, 0.0, 0.0, 1.0); } )DELIM"; */ From 4fd0e5ca31f96015855447582af7ad84303604f7 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 2 Feb 2021 10:11:42 +0000 Subject: [PATCH 098/248] Add equal_to, minus, multiplies to CGAL::Kernel_d with a nested result_type --- Kernel_d/include/CGAL/Kernel_d/Iso_box_d.h | 39 ++++++++++++++++++++-- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/Kernel_d/include/CGAL/Kernel_d/Iso_box_d.h b/Kernel_d/include/CGAL/Kernel_d/Iso_box_d.h index 3794119da67..addd748e2a6 100644 --- a/Kernel_d/include/CGAL/Kernel_d/Iso_box_d.h +++ b/Kernel_d/include/CGAL/Kernel_d/Iso_box_d.h @@ -32,6 +32,39 @@ namespace CGAL { struct Begin {}; struct End {}; struct Cartesian_end {}; + + template + struct equal_to { + typedef bool result_type; + + bool operator()(const T &lhs, const T &rhs) const + { + return lhs == rhs; + } + + }; + + template + struct minus { + typedef bool result_type; + + T operator()(const T &lhs, const T &rhs) const + { + return lhs - rhs; + } + + }; + + template + struct multiplies { + typedef bool result_type; + + T operator()(const T &lhs, const T &rhs) const + { + return lhs * rhs; + } + + }; } // namespace Kernel_d template < typename Point_, typename Functor_ > @@ -277,11 +310,11 @@ namespace CGAL { RT volume_nominator() const { - typedef typename CIRT::template Iterator >::type + typedef typename CIRT::template Iterator >::type Iter; Iter b(ptr()->upper, ptr()->lower, Begin()); Iter e(ptr()->upper, ptr()->lower, Cartesian_end()); - return std::accumulate(b, e, RT(1), std::multiplies()); + return std::accumulate(b, e, RT(1), Kernel_d::multiplies()); } RT volume_denominator() const @@ -373,7 +406,7 @@ public: bool is_degenerate() const { typedef typename CIRT:: - template Iterator >::type Iter; + template Iterator >::type Iter; // omit homogenizing coordinates Iter e(ptr()->lower, ptr()->upper, Cartesian_end()); return From 77b9ebc19c16fe03bb41046b058a550a79124510 Mon Sep 17 00:00:00 2001 From: Guillaume Damiand Date: Tue, 2 Feb 2021 12:06:40 +0100 Subject: [PATCH 099/248] Update shaders --- GraphicsView/include/CGAL/Basic_shaders.h | 46 +++++++++++------------ 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/GraphicsView/include/CGAL/Basic_shaders.h b/GraphicsView/include/CGAL/Basic_shaders.h index b3204549697..19b1d09f2de 100644 --- a/GraphicsView/include/CGAL/Basic_shaders.h +++ b/GraphicsView/include/CGAL/Basic_shaders.h @@ -27,13 +27,11 @@ in highp vec3 color; uniform highp mat4 mvp_matrix; uniform highp mat4 mv_matrix; +uniform highp float point_size; out highp vec4 fP; out highp vec3 fN; out highp vec4 fColor; - -uniform highp float point_size; - out highp vec4 m_vertex; void main(void) @@ -51,12 +49,10 @@ void main(void) const char fragment_source_color[]=R"DELIM( #version 150 -out highp vec4 fP; -out highp vec3 fN; -out highp vec4 fColor; - -out highp vec4 m_vertex; -out highp vec4 out_color; +in highp vec4 fP; +in highp vec3 fN; +in highp vec4 fColor; +in highp vec4 m_vertex; uniform highp vec4 light_pos; uniform highp vec4 light_diff; @@ -68,6 +64,8 @@ uniform highp vec4 clipPlane; uniform highp float rendering_mode; uniform highp float rendering_transparency; +out highp vec4 out_color; + void main(void) { highp vec3 L = light_pos.xyz - fP.xyz; @@ -107,11 +105,11 @@ in highp vec4 vertex; in highp vec3 color; uniform highp mat4 mvp_matrix; -out highp vec4 fColor; +uniform highp float point_size; +out highp vec4 fColor; out highp vec4 m_vertex; -uniform highp float point_size; void main(void) { gl_PointSize = point_size; @@ -123,12 +121,14 @@ void main(void) const char fragment_source_p_l[]=R"DELIM( #version 150 -out highp vec4 fColor; -out highp vec4 m_vertex; -out highp vec4 out_color; +in highp vec4 fColor; +in highp vec4 m_vertex; + uniform highp vec4 clipPlane; uniform highp float rendering_mode; +out highp vec4 out_color; + void main(void) { // onPlane == 1: inside clipping plane, should be solid; @@ -180,13 +180,12 @@ in highp vec3 color; uniform highp mat4 mvp_matrix; uniform highp mat4 mv_matrix; +uniform highp float point_size; out highp vec4 fP; out highp vec3 fN; out highp vec4 fColor; -uniform highp float point_size; - void main(void) { fP = mv_matrix * vertex; @@ -203,10 +202,9 @@ void main(void) )DELIM"; const char fragment_source_color_comp[]=R"DELIM( -out highp vec4 fP; -out highp vec3 fN; -out highp vec4 fColor; -out highp vec4 out_color; +in highp vec4 fP; +in highp vec3 fN; +in highp vec4 fColor; uniform highp vec4 light_pos; uniform highp vec4 light_diff; @@ -214,6 +212,8 @@ uniform highp vec4 light_spec; uniform highp vec4 light_amb; uniform highp float spec_power ; +out highp vec4 out_color; + void main(void) { highp vec3 L = light_pos.xyz - fP.xyz; @@ -236,10 +236,10 @@ in highp vec4 vertex; in highp vec3 color; uniform highp mat4 mvp_matrix; -varying highp vec4 fColor; - uniform highp float point_size; +out highp vec4 fColor; + void main(void) { gl_PointSize = point_size; @@ -249,7 +249,7 @@ void main(void) )DELIM"; const char fragment_source_p_l_comp[]=R"DELIM( -varying highp vec4 fColor; +in highp vec4 fColor; out highp vec4 out_color; void main(void) { From 9e9e48538726bb9ef77d962aa786601a4569627b Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 2 Feb 2021 11:19:53 +0000 Subject: [PATCH 100/248] Fix result_type --- Kernel_d/include/CGAL/Kernel_d/Iso_box_d.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Kernel_d/include/CGAL/Kernel_d/Iso_box_d.h b/Kernel_d/include/CGAL/Kernel_d/Iso_box_d.h index addd748e2a6..3b4c46fadc4 100644 --- a/Kernel_d/include/CGAL/Kernel_d/Iso_box_d.h +++ b/Kernel_d/include/CGAL/Kernel_d/Iso_box_d.h @@ -46,7 +46,7 @@ namespace CGAL { template struct minus { - typedef bool result_type; + typedef T result_type; T operator()(const T &lhs, const T &rhs) const { @@ -57,7 +57,7 @@ namespace CGAL { template struct multiplies { - typedef bool result_type; + typedef T result_type; T operator()(const T &lhs, const T &rhs) const { From a09a4684f4aa726ccd0f2777654e5af12163cb6a Mon Sep 17 00:00:00 2001 From: Guillaume Damiand Date: Wed, 3 Feb 2021 08:56:52 +0100 Subject: [PATCH 101/248] Start to use manipulated frame for clipping plane --- .../include/CGAL/Qt/Basic_viewer_qt.h | 45 +++++++++++++++++-- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h b/GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h index be88ad7fce4..b815e85593e 100644 --- a/GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h +++ b/GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h @@ -31,8 +31,8 @@ #include #include +#include #include -#include #include #include #include @@ -186,6 +186,15 @@ public: setMouseBindingDescription(::Qt::Key_C, ::Qt::ControlModifier, ::Qt::RightButton, "Translate the clipping plane when enabled"); setMouseBindingDescription(::Qt::Key_C, ::Qt::ControlModifier, ::Qt::MidButton, "Control the clipping plane transparency when enabled"); + /* + TODO + + setMouseBinding(::Qt::NoModifier, ::Qt::LeftButton, qglviewer::FRAME, qglviewer::ROTATE); + setMouseBinding(::Qt::NoModifier, ::Qt::RightButton, qglviewer::FRAME, qglviewer::TRANSLATE); + setMouseBinding(::Qt::NoModifier, ::Qt::MidButton, qglviewer::FRAME, qglviewer::ZOOM); + setWheelBinding(::Qt::NoModifier, qglviewer::FRAME, qglviewer::ZOOM); + */ + if (title[0]==0) setWindowTitle("CGAL Basic Viewer"); else @@ -464,7 +473,7 @@ protected: { rendering_program_face.removeAllShaders(); rendering_program_p_l.removeAllShaders(); - rendering_program_clipping_plane.removeAllShaders(); + rendering_program_clipping_plane.removeAllShaders(); // TODO remove this shader: replace by QGLViewer::drawGrid // Create the buffers for (unsigned int i=0; imatrix()); // Linker error + // Scale down the drawings + // glScalef(0.3f, 0.3f, 0.3f); // Linker error + // Draw an axis using the QGLViewer static function + // drawAxis(); } virtual void init() @@ -1348,6 +1366,7 @@ protected: bb.zmax())); // init clipping plane array + // TODO REMOVE auto generate_clipping_plane = [this](qreal size, int nbSubdivisions) { for (int i = 0; i <= nbSubdivisions; i++) @@ -1393,6 +1412,19 @@ protected: { // toggle clipping plane m_use_clipping_plane = (m_use_clipping_plane + 1) % CLIPPING_PLANE_END_INDEX; + // TODO verify + if (m_use_clipping_plane==CLIPPING_PLANE_OFF) + { + delete m_frame_plane; + m_frame_plane=nullptr; + setManipulatedFrame(nullptr); + } + else if (m_frame_plane==nullptr) + { + m_frame_plane=new CGAL::qglviewer::ManipulatedFrame; + setManipulatedFrame(m_frame_plane); + } + switch(m_use_clipping_plane) { case CLIPPING_PLANE_OFF: displayMessage(QString("Draw clipping = flase")); break; @@ -1606,6 +1638,7 @@ protected: CGAL::QGLViewer::keyPressEvent(e); } + // TODO maybe remove virtual void keyReleaseEvent(QKeyEvent *e) { const ::Qt::KeyboardModifiers modifiers = e->modifiers(); @@ -1615,6 +1648,7 @@ protected: } } + // TODO maybe remove virtual void mousePressEvent(QMouseEvent *e) { if (clipping_plane_operation && e->modifiers() == ::Qt::ControlModifier && e->buttons() == ::Qt::LeftButton) { // rotation starting point @@ -1631,6 +1665,7 @@ protected: } } + // TODO maybe remove virtual void mouseMoveEvent(QMouseEvent *e) { if (clipping_plane_operation && e->modifiers() == ::Qt::ControlModifier && e->buttons() == ::Qt::LeftButton) { @@ -1660,6 +1695,7 @@ protected: } } + // TODO maybe remove virtual void wheelEvent(QWheelEvent *e) { if (clipping_plane_operation && e->modifiers() == ::Qt::ControlModifier) { @@ -1728,7 +1764,8 @@ protected: CLIPPING_PLANE_END_INDEX }; - int m_use_clipping_plane = CLIPPING_PLANE_OFF; + int m_use_clipping_plane=CLIPPING_PLANE_OFF; + CGAL::qglviewer::ManipulatedFrame* m_frame_plane=nullptr; double m_size_points; double m_size_edges; From a1189511f922abf81fb260892b10cd1306588aad Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 3 Feb 2021 09:10:59 +0000 Subject: [PATCH 102/248] No need for multiplies --- Kernel_d/include/CGAL/Kernel_d/Iso_box_d.h | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/Kernel_d/include/CGAL/Kernel_d/Iso_box_d.h b/Kernel_d/include/CGAL/Kernel_d/Iso_box_d.h index 3b4c46fadc4..2f150262095 100644 --- a/Kernel_d/include/CGAL/Kernel_d/Iso_box_d.h +++ b/Kernel_d/include/CGAL/Kernel_d/Iso_box_d.h @@ -37,7 +37,7 @@ namespace CGAL { struct equal_to { typedef bool result_type; - bool operator()(const T &lhs, const T &rhs) const + result_type operator()(const T &lhs, const T &rhs) const { return lhs == rhs; } @@ -48,23 +48,13 @@ namespace CGAL { struct minus { typedef T result_type; - T operator()(const T &lhs, const T &rhs) const + result_type operator()(const T &lhs, const T &rhs) const { return lhs - rhs; } }; - template - struct multiplies { - typedef T result_type; - - T operator()(const T &lhs, const T &rhs) const - { - return lhs * rhs; - } - - }; } // namespace Kernel_d template < typename Point_, typename Functor_ > @@ -314,7 +304,7 @@ namespace CGAL { Iter; Iter b(ptr()->upper, ptr()->lower, Begin()); Iter e(ptr()->upper, ptr()->lower, Cartesian_end()); - return std::accumulate(b, e, RT(1), Kernel_d::multiplies()); + return std::accumulate(b, e, RT(1), std::multiplies()); } RT volume_denominator() const From 75bdca5e9fedfe2f5404029df082c73887cf6db5 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 3 Feb 2021 09:31:33 +0000 Subject: [PATCH 103/248] Use solution which does not depend on result_type as proposedby Laurent --- Kernel_d/include/CGAL/Kernel_d/Iso_box_d.h | 36 ++++++---------------- 1 file changed, 10 insertions(+), 26 deletions(-) diff --git a/Kernel_d/include/CGAL/Kernel_d/Iso_box_d.h b/Kernel_d/include/CGAL/Kernel_d/Iso_box_d.h index 2f150262095..3964fa2ada7 100644 --- a/Kernel_d/include/CGAL/Kernel_d/Iso_box_d.h +++ b/Kernel_d/include/CGAL/Kernel_d/Iso_box_d.h @@ -25,6 +25,7 @@ #include #include #include +#include namespace CGAL { @@ -32,29 +33,6 @@ namespace CGAL { struct Begin {}; struct End {}; struct Cartesian_end {}; - - template - struct equal_to { - typedef bool result_type; - - result_type operator()(const T &lhs, const T &rhs) const - { - return lhs == rhs; - } - - }; - - template - struct minus { - typedef T result_type; - - result_type operator()(const T &lhs, const T &rhs) const - { - return lhs - rhs; - } - - }; - } // namespace Kernel_d template < typename Point_, typename Functor_ > @@ -64,7 +42,13 @@ namespace CGAL { typedef typename Point::Cartesian_const_iterator Iterator; typedef Cartesian_iterator Self; - typedef typename Functor::result_type value_type; + + typedef typename std::iterator_traits::value_type + Coordinate_type; + + typedef decltype( + std::declval()(std::declval(), + std::declval())) value_type; typedef value_type& reference; typedef value_type* pointer; typedef std::ptrdiff_t difference_type; @@ -300,7 +284,7 @@ namespace CGAL { RT volume_nominator() const { - typedef typename CIRT::template Iterator >::type + typedef typename CIRT::template Iterator >::type Iter; Iter b(ptr()->upper, ptr()->lower, Begin()); Iter e(ptr()->upper, ptr()->lower, Cartesian_end()); @@ -396,7 +380,7 @@ public: bool is_degenerate() const { typedef typename CIRT:: - template Iterator >::type Iter; + template Iterator >::type Iter; // omit homogenizing coordinates Iter e(ptr()->lower, ptr()->upper, Cartesian_end()); return From 5e63293747b98142bd14bde5ef2644e3fdddfab4 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 3 Feb 2021 11:39:41 +0100 Subject: [PATCH 104/248] Replace plane manipulation by frame manipulation. --- GraphicsView/include/CGAL/Basic_shaders.h | 6 +- .../include/CGAL/Qt/Basic_viewer_qt.h | 146 +++++------------- 2 files changed, 40 insertions(+), 112 deletions(-) diff --git a/GraphicsView/include/CGAL/Basic_shaders.h b/GraphicsView/include/CGAL/Basic_shaders.h index 19b1d09f2de..1e9f7697c0a 100644 --- a/GraphicsView/include/CGAL/Basic_shaders.h +++ b/GraphicsView/include/CGAL/Basic_shaders.h @@ -61,6 +61,7 @@ uniform highp vec4 light_amb; uniform highp float spec_power; uniform highp vec4 clipPlane; +uniform highp vec4 pointPlane; uniform highp float rendering_mode; uniform highp float rendering_transparency; @@ -83,7 +84,7 @@ void main(void) // onPlane == 1: inside clipping plane, should be solid; // onPlane == -1: outside clipping plane, should be transparent; // onPlane == 0: on clipping plane, whatever; - float onPlane = sign(dot(m_vertex.xyz, clipPlane.xyz) - clipPlane.w); + float onPlane = sign(dot((m_vertex.xyz-pointPlane.xyz), clipPlane.xyz)); // rendering_mode == -1: draw all solid; // rendering_mode == 0: draw solid only; @@ -125,6 +126,7 @@ in highp vec4 fColor; in highp vec4 m_vertex; uniform highp vec4 clipPlane; +uniform highp vec4 pointPlane; uniform highp float rendering_mode; out highp vec4 out_color; @@ -134,7 +136,7 @@ void main(void) // onPlane == 1: inside clipping plane, should be solid; // onPlane == -1: outside clipping plane, should be transparent; // onPlane == 0: on clipping plane, whatever; - float onPlane = sign(dot(m_vertex.xyz, clipPlane.xyz) - clipPlane.w); + float onPlane = sign(dot((m_vertex.xyz-pointPlane.xyz), clipPlane.xyz)); // rendering_mode == -1: draw both inside and outside; // rendering_mode == 0: draw inside only; diff --git a/GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h b/GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h index b815e85593e..02ed93e8ca2 100644 --- a/GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h +++ b/GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h @@ -186,14 +186,15 @@ public: setMouseBindingDescription(::Qt::Key_C, ::Qt::ControlModifier, ::Qt::RightButton, "Translate the clipping plane when enabled"); setMouseBindingDescription(::Qt::Key_C, ::Qt::ControlModifier, ::Qt::MidButton, "Control the clipping plane transparency when enabled"); - /* - TODO + setMouseBinding(::Qt::ControlModifier, ::Qt::LeftButton, qglviewer::FRAME, qglviewer::NO_MOUSE_ACTION); + setMouseBinding(::Qt::ControlModifier, ::Qt::RightButton, qglviewer::FRAME, qglviewer::NO_MOUSE_ACTION); + setMouseBinding(::Qt::ControlModifier, ::Qt::MidButton, qglviewer::FRAME, qglviewer::NO_MOUSE_ACTION); + setWheelBinding(::Qt::ControlModifier, qglviewer::FRAME, qglviewer::NO_MOUSE_ACTION); - setMouseBinding(::Qt::NoModifier, ::Qt::LeftButton, qglviewer::FRAME, qglviewer::ROTATE); - setMouseBinding(::Qt::NoModifier, ::Qt::RightButton, qglviewer::FRAME, qglviewer::TRANSLATE); - setMouseBinding(::Qt::NoModifier, ::Qt::MidButton, qglviewer::FRAME, qglviewer::ZOOM); - setWheelBinding(::Qt::NoModifier, qglviewer::FRAME, qglviewer::ZOOM); - */ + setMouseBinding(::Qt::Key_C, ::Qt::ControlModifier, ::Qt::LeftButton, qglviewer::FRAME, qglviewer::ROTATE); + setMouseBinding(::Qt::Key_C, ::Qt::ControlModifier, ::Qt::RightButton, qglviewer::FRAME, qglviewer::TRANSLATE); + setMouseBinding(::Qt::Key_C, ::Qt::ControlModifier, ::Qt::MidButton, qglviewer::FRAME, qglviewer::ZOOM); + setWheelBinding(::Qt::Key_C, ::Qt::ControlModifier, qglviewer::FRAME, qglviewer::ZOOM); if (title[0]==0) setWindowTitle("CGAL Basic Viewer"); @@ -473,7 +474,7 @@ protected: { rendering_program_face.removeAllShaders(); rendering_program_p_l.removeAllShaders(); - rendering_program_clipping_plane.removeAllShaders(); // TODO remove this shader: replace by QGLViewer::drawGrid + rendering_program_clipping_plane.removeAllShaders(); // Create the buffers for (unsigned int i=0; imatrix()[i]; + } rendering_program_clipping_plane.bind(); int vpLocation = rendering_program_clipping_plane.uniformLocation("vp_matrix"); @@ -976,12 +980,15 @@ protected: { glEnable(GL_DEPTH_TEST); - // get clipping plane model matrix QMatrix4x4 clipping_mMatrix; clipping_mMatrix.setToIdentity(); - clipping_mMatrix.rotate(clipping_plane_rotation); - QVector4D clipPlane = clipping_mMatrix * QVector4D(0.0, 0.0, 1.0, clipping_plane_translation_z); - + if(m_frame_plane) + { + for(int i=0; i< 16 ; i++) + clipping_mMatrix.data()[i] = m_frame_plane->matrix()[i]; + } + QVector4D clipPlane = clipping_mMatrix * QVector4D(0.0, 0.0, 1.0, 0.0); + QVector4D plane_point = clipping_mMatrix * QVector4D(0,0,0,1); if(!m_are_buffers_initialized) { initialize_buffers(); } @@ -1017,7 +1024,7 @@ protected: // rendering_mode == -1: draw all // rendering_mode == 0: draw inside clipping plane // rendering_mode == 1: draw outside clipping plane - auto renderer = [this, &color, &clipPlane](float rendering_mode) { + auto renderer = [this, &color, &clipPlane, &plane_point](float rendering_mode) { vao[VAO_MONO_POINTS].bind(); color.setRgbF((double)m_vertices_mono_color.red()/(double)255, (double)m_vertices_mono_color.green()/(double)255, @@ -1025,6 +1032,7 @@ protected: rendering_program_p_l.setAttributeValue("color",color); rendering_program_p_l.setUniformValue("point_size", GLfloat(m_size_points)); rendering_program_p_l.setUniformValue("clipPlane", clipPlane); + rendering_program_p_l.setUniformValue("pointPlane", plane_point); rendering_program_p_l.setUniformValue("rendering_mode", rendering_mode); glDrawArrays(GL_POINTS, 0, static_cast(arrays[POS_MONO_POINTS].size()/3)); vao[VAO_MONO_POINTS].release(); @@ -1044,6 +1052,7 @@ protected: } rendering_program_p_l.setUniformValue("point_size", GLfloat(m_size_points)); rendering_program_p_l.setUniformValue("clipPlane", clipPlane); + rendering_program_p_l.setUniformValue("pointPlane", plane_point); rendering_program_p_l.setUniformValue("rendering_mode", rendering_mode); glDrawArrays(GL_POINTS, 0, static_cast(arrays[POS_COLORED_POINTS].size()/3)); vao[VAO_COLORED_POINTS].release(); @@ -1074,13 +1083,14 @@ protected: // rendering_mode == -1: draw all // rendering_mode == 0: draw inside clipping plane // rendering_mode == 1: draw outside clipping plane - auto renderer = [this, &color, &clipPlane](float rendering_mode) { + auto renderer = [this, &color, &clipPlane, &plane_point](float rendering_mode) { vao[VAO_MONO_SEGMENTS].bind(); color.setRgbF((double)m_edges_mono_color.red()/(double)255, (double)m_edges_mono_color.green()/(double)255, (double)m_edges_mono_color.blue()/(double)255); rendering_program_p_l.setAttributeValue("color",color); rendering_program_p_l.setUniformValue("clipPlane", clipPlane); + rendering_program_p_l.setUniformValue("pointPlane", plane_point); rendering_program_p_l.setUniformValue("rendering_mode", rendering_mode); glLineWidth(m_size_edges); glDrawArrays(GL_LINES, 0, static_cast(arrays[POS_MONO_SEGMENTS].size()/3)); @@ -1100,6 +1110,7 @@ protected: rendering_program_p_l.enableAttributeArray("color"); } rendering_program_p_l.setUniformValue("clipPlane", clipPlane); + rendering_program_p_l.setUniformValue("pointPlane", plane_point); rendering_program_p_l.setUniformValue("rendering_mode", rendering_mode); glLineWidth(m_size_edges); glDrawArrays(GL_LINES, 0, static_cast(arrays[POS_COLORED_SEGMENTS].size()/3)); @@ -1209,7 +1220,7 @@ protected: // rendering_mode == -1: draw all as solid; // rendering_mode == 0: draw solid only; // rendering_mode == 1: draw transparent only; - auto renderer = [this, &color, &clipPlane](float rendering_mode) { + auto renderer = [this, &color, &clipPlane, &plane_point](float rendering_mode) { vao[VAO_MONO_FACES].bind(); color.setRgbF((double)m_faces_mono_color.red()/(double)255, @@ -1219,6 +1230,7 @@ protected: rendering_program_face.setUniformValue("rendering_mode", rendering_mode); rendering_program_face.setUniformValue("rendering_transparency", clipping_plane_rendering_transparency); rendering_program_face.setUniformValue("clipPlane", clipPlane); + rendering_program_face.setUniformValue("pointPlane", plane_point); glDrawArrays(GL_TRIANGLES, 0, static_cast(arrays[POS_MONO_FACES].size()/3)); vao[VAO_MONO_FACES].release(); @@ -1238,6 +1250,7 @@ protected: rendering_program_face.setUniformValue("rendering_mode", rendering_mode); rendering_program_face.setUniformValue("rendering_transparency", clipping_plane_rendering_transparency); rendering_program_face.setUniformValue("clipPlane", clipPlane); + rendering_program_face.setUniformValue("pointPlane", plane_point); glDrawArrays(GL_TRIANGLES, 0, static_cast(arrays[POS_COLORED_FACES].size()/3)); vao[VAO_COLORED_FACES].release(); }; @@ -1366,7 +1379,6 @@ protected: bb.zmax())); // init clipping plane array - // TODO REMOVE auto generate_clipping_plane = [this](qreal size, int nbSubdivisions) { for (int i = 0; i <= nbSubdivisions; i++) @@ -1412,12 +1424,11 @@ protected: { // toggle clipping plane m_use_clipping_plane = (m_use_clipping_plane + 1) % CLIPPING_PLANE_END_INDEX; - // TODO verify - if (m_use_clipping_plane==CLIPPING_PLANE_OFF) + if (m_use_clipping_plane==CLIPPING_PLANE_OFF && m_frame_plane) { + setManipulatedFrame(nullptr); delete m_frame_plane; m_frame_plane=nullptr; - setManipulatedFrame(nullptr); } else if (m_frame_plane==nullptr) { @@ -1436,16 +1447,7 @@ protected: update(); } } - else if ((e->key()==::Qt::Key_C) && (modifiers==::Qt::ControlModifier)) - { - if (!isOpenGL_4_3()) return; - if (m_use_clipping_plane!=CLIPPING_PLANE_OFF) - { - // enable clipping operation i.e. rotation, translation, and transparency adjustment - clipping_plane_operation = true; - update(); - } - } + else if ((e->key()==::Qt::Key_C) && (modifiers==::Qt::AltModifier)) { if (!isOpenGL_4_3()) return; @@ -1638,77 +1640,6 @@ protected: CGAL::QGLViewer::keyPressEvent(e); } - // TODO maybe remove - virtual void keyReleaseEvent(QKeyEvent *e) - { - const ::Qt::KeyboardModifiers modifiers = e->modifiers(); - if ((e->key()==::Qt::Key_C)) - { - clipping_plane_operation = false; - } - } - - // TODO maybe remove - virtual void mousePressEvent(QMouseEvent *e) { - if (clipping_plane_operation && e->modifiers() == ::Qt::ControlModifier && e->buttons() == ::Qt::LeftButton) { - // rotation starting point - clipping_plane_rotation_tracker = QVector2D(e->localPos()); - } - else if (clipping_plane_operation && e->modifiers() == ::Qt::ControlModifier && e->buttons() == ::Qt::RightButton) - { - // translation starting point - clipping_plane_translation_tracker = QVector2D(e->localPos()); - } - else - { - CGAL::QGLViewer::mousePressEvent(e); - } - } - - // TODO maybe remove - virtual void mouseMoveEvent(QMouseEvent *e) { - if (clipping_plane_operation && e->modifiers() == ::Qt::ControlModifier && e->buttons() == ::Qt::LeftButton) - { - // rotation ending point - QVector2D diff = QVector2D(e->localPos()) - clipping_plane_rotation_tracker; - clipping_plane_rotation_tracker = QVector2D(e->localPos()); - - QVector3D axis = QVector3D(diff.y(), diff.x(), 0.0); - float angle = diff.length(); - clipping_plane_rotation = QQuaternion::fromAxisAndAngle(axis, angle) * clipping_plane_rotation; - - update(); - } - else if (clipping_plane_operation && e->modifiers() == ::Qt::ControlModifier && e->buttons() == ::Qt::RightButton) - { - // translation ending point - QVector2D diff = QVector2D(e->localPos()) - clipping_plane_translation_tracker; - clipping_plane_translation_tracker = QVector2D(e->localPos()); - - clipping_plane_translation_z += clipping_plane_rendering_size / 500 * (diff.y() > 0 ? -1.0 : diff.y() < 0 ? 1.0 : 0.0) * diff.length(); - - update(); - } - else - { - CGAL::QGLViewer::mouseMoveEvent(e); - } - } - - // TODO maybe remove - virtual void wheelEvent(QWheelEvent *e) - { - if (clipping_plane_operation && e->modifiers() == ::Qt::ControlModifier) { - clipping_plane_rendering_transparency += (e->delta() / 120.0) / 50.0; - // clip to 0-1 - clipping_plane_rendering_transparency = clipping_plane_rendering_transparency > 1.0 ? 1.0 : clipping_plane_rendering_transparency < 0.0 ? 0.0 : clipping_plane_rendering_transparency; - } - else - { - CGAL::QGLViewer::wheelEvent(e); - } - } - virtual QString helpString() const { return helpString("CGAL Basic Viewer"); } @@ -1857,11 +1788,6 @@ protected: QOpenGLShaderProgram rendering_program_clipping_plane; // variables for clipping plane - bool clipping_plane_operation = false; // will be enabled/diabled when ctrl+c is pressed/released, which is used for clipping plane translation and rotation; - QVector2D clipping_plane_rotation_tracker; // will be enabled when ctrl+c+left is pressed, which is used to record rotation; - QQuaternion clipping_plane_rotation; // real rotation; - QVector2D clipping_plane_translation_tracker; // will be enabled when ctrl+c+right is pressed, which is used to record translation; - float clipping_plane_translation_z = 0.0f; // real translation; bool clipping_plane_rendering = true; // will be toggled when alt+c is pressed, which is used for indicating whether or not to render the clipping plane ; float clipping_plane_rendering_transparency = 0.5f; // to what extent the transparent part should be rendered; float clipping_plane_rendering_size; // to what extent the size of clipping plane should be rendered; From cd70b9b172fb832d386e097e835082a96b3b8e21 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 3 Feb 2021 10:46:28 +0000 Subject: [PATCH 105/248] Use operator< instead of operator> as OM only implements the former --- .../doc/Polygon_mesh_processing/examples.txt | 1 + .../examples/Polygon_mesh_processing/CMakeLists.txt | 4 ++++ .../internal/Corefinement/intersection_impl.h | 6 +++--- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt index 9fa1de58990..c87df3edbb0 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt @@ -19,6 +19,7 @@ \example Poisson_surface_reconstruction_3/poisson_reconstruction_example.cpp \example Polygon_mesh_processing/corefinement_difference_remeshed.cpp \example Polygon_mesh_processing/corefinement_mesh_union.cpp +\example Polygon_mesh_processing/corefinement_OM_union.cpp \example Polygon_mesh_processing/corefinement_mesh_union_and_intersection.cpp \example Polygon_mesh_processing/corefinement_consecutive_bool_op.cpp \example Polygon_mesh_processing/detect_features_example.cpp diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt b/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt index 81294d51e01..b33d408d44d 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt @@ -95,6 +95,10 @@ if(OpenMesh_FOUND) target_link_libraries(compute_normals_example_OM PRIVATE ${OPENMESH_LIBRARIES}) + create_single_source_cgal_program("corefinement_OM_union.cpp") + target_link_libraries(corefinement_OM_union + PRIVATE ${OPENMESH_LIBRARIES}) + if(TARGET CGAL::Eigen3_support) create_single_source_cgal_program("hole_filling_example_OM.cpp") target_link_libraries(hole_filling_example_OM PRIVATE CGAL::Eigen3_support diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/intersection_impl.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/intersection_impl.h index 8fba16f9380..60aecbe0f23 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/intersection_impl.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/intersection_impl.h @@ -325,7 +325,7 @@ class Intersection_of_triangle_meshes case ON_EDGE : { h1=opposite(ipt.info_1,tm1); - if (h1>ipt.info_1) h1=ipt.info_1; + if (ipt.info_1 < h1) h1=ipt.info_1; } break; case ON_FACE : @@ -340,7 +340,7 @@ class Intersection_of_triangle_meshes case ON_EDGE : { h2=opposite(ipt.info_2,tm2); - if (h2>ipt.info_2) h2=ipt.info_2; + if (ipt.info_2 < h2) h2=ipt.info_2; } break; case ON_FACE : @@ -350,7 +350,7 @@ class Intersection_of_triangle_meshes } Key key(ipt.type_1, ipt.type_2, h1, h2); - if (&tm1==&tm2 && h1>h2) + if (&tm1==&tm2 && h2::iterator,bool> res= From 3f05cf313941e3607c9971cca90caf368779325b Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 3 Feb 2021 11:08:56 +0000 Subject: [PATCH 106/248] Add the example --- .../corefinement_OM_union.cpp | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 Polygon_mesh_processing/examples/Polygon_mesh_processing/corefinement_OM_union.cpp diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/corefinement_OM_union.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/corefinement_OM_union.cpp new file mode 100644 index 00000000000..f01c5252aee --- /dev/null +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/corefinement_OM_union.cpp @@ -0,0 +1,39 @@ +#include +#include +#include + +#include + +#include + +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef OpenMesh::PolyMesh_ArrayKernelT< > Mesh; + + +namespace PMP = CGAL::Polygon_mesh_processing; + +int main(int argc, char* argv[]) +{ + const char* filename1 = (argc > 1) ? argv[1] : "data/blobby.off"; + const char* filename2 = (argc > 2) ? argv[2] : "data/eight.off"; + + Mesh mesh1, mesh2; + + OpenMesh::IO::read_mesh(mesh1, filename1); + OpenMesh::IO::read_mesh(mesh2, filename2); + + Mesh out; + bool valid_union = PMP::corefine_and_compute_union(mesh1,mesh2, out); + + if (valid_union) + { + std::cout << "Union was successfully computed\n"; + OpenMesh::IO::write_mesh(out, "union.off"); + return 0; + } + std::cout << "Union could not be computed\n"; + return 1; +} From 96769b28733ea131329787246c0d1abe5636739a Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 3 Feb 2021 12:38:25 +0000 Subject: [PATCH 107/248] Use 2 template parameters so that it matches for a handle and a smart handle --- .../include/CGAL/Polygon_mesh_processing/orientation.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index e85a3f6acfc..5e170ff0203 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -53,8 +53,8 @@ namespace internal{ {} typedef bool result_type; - template - bool operator()(vertex_descriptor v1, vertex_descriptor v2) const + template + bool operator()(vertex_descriptor1 v1, vertex_descriptor2 v2) const { return CGAL::SMALLER == compare_z(get(vpmap, v1), get(vpmap, v2)); } From bdbc4a3ca0cbd2d24c90a90932776bfdfc9864bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 3 Feb 2021 14:09:22 +0100 Subject: [PATCH 108/248] remove unused typedef --- .../Polygon_mesh_processing/corefinement_consecutive_bool_op.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/corefinement_consecutive_bool_op.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/corefinement_consecutive_bool_op.cpp index 6ade126528c..2696bd1b85b 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/corefinement_consecutive_bool_op.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/corefinement_consecutive_bool_op.cpp @@ -11,7 +11,6 @@ typedef CGAL::Exact_predicates_exact_constructions_kernel EK; typedef CGAL::Surface_mesh Mesh; typedef boost::graph_traits::vertex_descriptor vertex_descriptor; typedef Mesh::Property_map Exact_point_map; -typedef Mesh::Property_map Exact_point_computed; namespace PMP = CGAL::Polygon_mesh_processing; namespace params = PMP::parameters; From 29379aec95eb7e02d3adb333e18ccd07d59a3e92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 3 Feb 2021 14:09:33 +0100 Subject: [PATCH 109/248] use EPECK --- .../corefinement_OM_union.cpp | 67 ++++++++++++++++++- 1 file changed, 65 insertions(+), 2 deletions(-) diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/corefinement_OM_union.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/corefinement_OM_union.cpp index f01c5252aee..fd858fd1341 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/corefinement_OM_union.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/corefinement_OM_union.cpp @@ -1,4 +1,5 @@ #include +#include #include #include @@ -9,10 +10,58 @@ #include #include -typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; // default kernel for OpenMesh point type +typedef CGAL::Exact_predicates_exact_constructions_kernel EK; // alternatice kernel we want to use typedef OpenMesh::PolyMesh_ArrayKernelT< > Mesh; +typedef boost::property_map >::type Exact_point_map; + +struct Exact_vertex_point_map +{ + // typedef for the property map + typedef boost::property_traits::value_type value_type; + typedef boost::property_traits::reference reference; + typedef boost::property_traits::category category; + typedef boost::property_traits::key_type key_type; + + // exterior references + Exact_point_map exact_point_map; + Mesh* tm_ptr; + + // Converters + CGAL::Cartesian_converter to_exact; + CGAL::Cartesian_converter to_input; + + Exact_vertex_point_map() + : tm_ptr(nullptr) + {} + + Exact_vertex_point_map(const Exact_point_map& ep, Mesh& tm) + : exact_point_map(ep) + , tm_ptr(&tm) + { + for (key_type v : vertices(tm)) + put(exact_point_map, v, to_exact(get(boost::vertex_point, tm, v))); + } + + friend + reference get(const Exact_vertex_point_map& map, key_type k) + { + CGAL_precondition(map.tm_ptr!=nullptr); + return get(map.exact_point_map, k); + } + + friend + void put(const Exact_vertex_point_map& map, key_type k, const EK::Point_3& p) + { + CGAL_precondition(map.tm_ptr!=nullptr); + put(map.exact_point_map, k, p); + // create the input point from the exact one + put(boost::vertex_point, *map.tm_ptr, k, map.to_input(p)); + } +}; + namespace PMP = CGAL::Polygon_mesh_processing; int main(int argc, char* argv[]) @@ -26,7 +75,21 @@ int main(int argc, char* argv[]) OpenMesh::IO::read_mesh(mesh2, filename2); Mesh out; - bool valid_union = PMP::corefine_and_compute_union(mesh1,mesh2, out); + + // Create exact map properties + Exact_point_map pm_1 = get(CGAL::dynamic_vertex_property_t(), mesh1); + Exact_point_map pm_2 = get(CGAL::dynamic_vertex_property_t(), mesh2); + Exact_point_map pm_out = get(CGAL::dynamic_vertex_property_t(), out); + + // Create exact vertex point map that will provide the point to another kernel and fill the default map + Exact_vertex_point_map vpm_1(pm_1, mesh1); + Exact_vertex_point_map vpm_2(pm_2, mesh2); + Exact_vertex_point_map vpm_out(pm_out, out); + + bool valid_union = PMP::corefine_and_compute_union(mesh1, mesh2, out, + CGAL::parameters::vertex_point_map(vpm_1), + CGAL::parameters::vertex_point_map(vpm_2), + CGAL::parameters::vertex_point_map(vpm_out)); if (valid_union) { From 0cf9990bf08c2f84f844001023771d43e7db136d Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Thu, 4 Feb 2021 08:33:54 +0100 Subject: [PATCH 110/248] Fix conversion warning in RANSAC --- .../Shape_detection/Efficient_RANSAC/Efficient_RANSAC.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Shape_detection/include/CGAL/Shape_detection/Efficient_RANSAC/Efficient_RANSAC.h b/Shape_detection/include/CGAL/Shape_detection/Efficient_RANSAC/Efficient_RANSAC.h index ec22801ba1d..820eee71576 100644 --- a/Shape_detection/include/CGAL/Shape_detection/Efficient_RANSAC/Efficient_RANSAC.h +++ b/Shape_detection/include/CGAL/Shape_detection/Efficient_RANSAC/Efficient_RANSAC.h @@ -1030,8 +1030,10 @@ namespace CGAL { } inline FT stop_probability(std::size_t largest_candidate, std::size_t num_pts, std::size_t num_candidates, std::size_t octree_depth) const { - return (std::min)(std::pow((FT) 1.f - (FT) largest_candidate - / (FT(num_pts) * (octree_depth+1) * (1 << (m_required_samples - 1))), (int) num_candidates), (FT) 1); + return (std::min)(std::pow(FT(1) - FT(largest_candidate) + / (FT(num_pts) * FT(octree_depth+1) + * FT(1 << (m_required_samples - 1))), + int(num_candidates)), FT(1)); } private: From 26793aeaea38c5d79205991ab6978967308fb40c Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Thu, 4 Feb 2021 08:49:06 +0100 Subject: [PATCH 111/248] Fix conversion warnings in PSP --- .../include/CGAL/edge_aware_upsample_point_set.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Point_set_processing_3/include/CGAL/edge_aware_upsample_point_set.h b/Point_set_processing_3/include/CGAL/edge_aware_upsample_point_set.h index 57f0c12154f..2beb500eb88 100644 --- a/Point_set_processing_3/include/CGAL/edge_aware_upsample_point_set.h +++ b/Point_set_processing_3/include/CGAL/edge_aware_upsample_point_set.h @@ -212,8 +212,8 @@ update_new_point( for (unsigned int j = 0; j < candidate_num; j++) { - FT psi = std::exp(-std::pow(1 - normal_cadidate[j] * t.normal, 2) - / sharpness_bandwidth); + FT psi = std::exp(-std::pow(FT(1) - normal_cadidate[j] * t.normal, FT(2)) + / sharpness_bandwidth); FT project_diff_t_v = (t.pt - new_v.pt) * t.normal; FT weight = psi * theta; @@ -435,7 +435,8 @@ edge_aware_upsample_point_set( FT(neighbor_radius)); // - FT cos_sigma = static_cast(std::cos(CGAL::to_double(sharpness_angle) / 180.0 * CGAL_PI)); + FT cos_sigma = static_cast(std::cos(FT(CGAL::to_double(sharpness_angle)) + / FT(180) * FT(CGAL_PI))); FT sharpness_bandwidth = std::pow((CGAL::max)((FT)1e-8, (FT)1.0 - cos_sigma), 2); FT sum_density = 0.0; From 4953ff71e0d31d2a1c3b463a2e4edf63f047c6d8 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Thu, 4 Feb 2021 11:22:06 +0000 Subject: [PATCH 112/248] fix typo --- Installation/CHANGES.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Installation/CHANGES.md b/Installation/CHANGES.md index a7f93ab440a..f03ce6d5d42 100644 --- a/Installation/CHANGES.md +++ b/Installation/CHANGES.md @@ -21,11 +21,11 @@ A comprehensive list of the supported file formats is available in the Stream_su Bolun Wang, Teseo Schneider, Yixin Hu, Marco Attene, and Daniele Panozzo. "Exact and efficient polyhedral envelope containment check." (ACM Trans. Graph., 39-4, July 2020). -### [Surface Mesh Simplification](https://doc.cgal.org/5.3/Manual/packages.html#PkgSurfaceMeshSimplification2) +### [Surface Mesh Simplification](https://doc.cgal.org/5.3/Manual/packages.html#PkgSurfaceMeshSimplification) - Added a filtering mechanism so that costly tests get only applied to the next candidate for the edge collapse. - Added the class `Polyhedral_envelope_filter` that enables to perform mesh simplification inside a polyhedral envelope of the input mesh. -### [2D Polyline Simplification](https://doc.cgal.org/5.3/Manual/packages.html#PkgPolylineSiimplification) +### [2D Polyline Simplification](https://doc.cgal.org/5.3/Manual/packages.html#PkgPolylineSimplification2) - Subsequences of polylines that are shared are no longer marked as unremovable. [Release 5.2](https://github.com/CGAL/cgal/releases/tag/v5.2) From 25105714486143362edb1ec0a70ee98b6c0d6b89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 4 Feb 2021 16:26:47 +0100 Subject: [PATCH 113/248] always init faces of patches --- .../internal/Corefinement/face_graph_utils.h | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h index c188231238c..c15a4f60ef6 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h @@ -437,22 +437,18 @@ void extract_patch_simplices( typedef typename GT::vertex_descriptor vertex_descriptor; typedef typename GT::face_descriptor face_descriptor; - for(face_descriptor f : faces(pm)) + for(face_descriptor f : patch_faces) { - if ( patch_ids[ get(fids, f) ]==patch_id ) + for(halfedge_descriptor h : + halfedges_around_face(halfedge(f, pm),pm)) { - patch_faces.push_back( f ); - for(halfedge_descriptor h : - halfedges_around_face(halfedge(f, pm),pm)) + if ( !is_intersection_edge.count(edge(h, pm)) ) { - if ( !is_intersection_edge.count(edge(h, pm)) ) - { - if ( h < opposite(h,pm) || is_border(opposite(h,pm),pm) ) - interior_edges.push_back( h ); - } - else - shared_edges.push_back(h); + if ( h < opposite(h,pm) || is_border(opposite(h,pm),pm) ) + interior_edges.push_back( h ); } + else + shared_edges.push_back(h); } } @@ -494,7 +490,13 @@ struct Patch_container{ , patch_ids(patch_ids) , fids(fids) , is_intersection_edge(is_intersection_edge) - {} + { + typedef boost::graph_traits GT; + typedef typename GT::face_descriptor face_descriptor; + + for(face_descriptor f : faces(pm)) + patches[patch_ids[ get(fids, f) ]].faces.push_back( f ); + } Patch_description& operator[](std::size_t i) { if ( !patches[i].is_initialized ) From fb3746168db9fdca4fd16e0119e4066bf41f5333 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 5 Feb 2021 11:10:20 +0100 Subject: [PATCH 114/248] remove \sc --- .../Arrangement_on_surface_2.txt | 106 ++++++------ BGL/doc/BGL/BGL.txt | 76 ++++----- .../CGAL/HalfedgeDS_face_max_base_with_id.h | 2 +- .../HalfedgeDS_halfedge_max_base_with_id.h | 2 +- .../CGAL/HalfedgeDS_vertex_max_base_with_id.h | 2 +- BGL/doc/BGL/CGAL/Polyhedron_items_with_id_3.h | 2 +- .../CGAL/Triangulation_face_base_with_id_2.h | 2 +- .../Triangulation_vertex_base_with_id_2.h | 2 +- BGL/doc/BGL/CGAL/boost/graph/properties.h | 4 +- BGL/doc/BGL/Concepts/HalfedgeGraph.h | 2 +- BGL/doc/BGL/NamedParameters.txt | 6 +- BGL/doc/BGL/PackageDescription.txt | 10 +- BGL/doc/BGL/graph_traits.txt | 4 +- .../Developer_manual/cmakelist_script.txt | 2 +- .../doc/Documentation/Third_party.txt | 156 +++++++++--------- Documentation/doc/Documentation/Usage.txt | 12 +- .../advanced/Configuration_variables.txt | 98 +++++------ .../Documentation/advanced/Installation.txt | 14 +- Documentation/doc/Documentation/manual.txt | 2 +- Documentation/doc/Documentation/windows.txt | 4 +- .../doc/resources/1.8.13/BaseDoxyfile.in | 62 +++++-- .../doc/resources/1.8.14/BaseDoxyfile.in | 62 +++++-- .../doc/resources/1.8.20/BaseDoxyfile.in | 62 +++++-- Envelope_3/doc/Envelope_3/Envelope_3.txt | 2 +- .../doc/GraphicsView/PackageDescription.txt | 2 +- Number_types/doc/Number_types/CGAL/Gmpfr.h | 2 +- ...Segment_Delaunay_graph_filtered_traits_2.h | 4 +- .../doc/Solver_interface/Solver_interface.txt | 2 +- 28 files changed, 404 insertions(+), 302 deletions(-) diff --git a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/Arrangement_on_surface_2.txt b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/Arrangement_on_surface_2.txt index 1caa255411b..41ab2e2581e 100644 --- a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/Arrangement_on_surface_2.txt +++ b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/Arrangement_on_surface_2.txt @@ -34,11 +34,11 @@ conveniently embedded as a planar graph, whose vertices are associated with curve endpoints or with isolated points, and whose edges are associated with subcurves. It is easy to see that \f$ \cal A(\cal C) = \cal A(\cal C'')\f$. This graph can be represented using a -doubly-connected edge list data-structure (\sc{Dcel} for short), +doubly-connected edge list data-structure (\dcel for short), which consists of containers of vertices, edges and faces and maintains the incidence relations among these objects. -The main idea behind the \sc{Dcel} data-structure is to represent +The main idea behind the \dcel data-structure is to represent each edge using a pair of directed halfedges, one going from the \f$ xy\f$-lexicographically smaller (left) endpoint of the curve toward its the \f$ xy\f$-lexicographically larger (right) endpoint, and the other, @@ -75,11 +75,11 @@ as it may have no area, or alternatively it may consist of several connected faces. Every face can have several holes contained in its interior (or no holes at all). In addition, every face may contain isolated vertices in its interior. See \cgalFigureRef{arr_figseg_dcel} -for an illustration of the various \sc{Dcel} features. For more details -on the \sc{Dcel} data structure see \cgalCite{bkos-cgaa-00} Chapter 2. +for an illustration of the various \dcel features. For more details +on the \dcel data structure see \cgalCite{bkos-cgaa-00} Chapter 2. \cgalFigureBegin{arr_figseg_dcel,arr_segs.png} -An arrangement of interior-disjoint line segments with some of the \sc{Dcel} records that represent it. The unbounded face \f$ f_0\f$ has a single connected component that forms a hole inside it, and this hole is comprised of several faces. The half-edge \f$ e\f$ is directed from its source vertex \f$ v_1\f$ to its target vertex \f$ v_2\f$. This edge, together with its twin \f$ e'\f$, correspond to a line segment that connects the points associated with \f$ v_1\f$ and \f$ v_2\f$ and separates the face \f$ f_1\f$ from \f$ f_2\f$. The predecessor \f$ e_{\rm prev}\f$ and successor \f$ e_{\rm next}\f$ of \f$ e\f$ are part of the chain that form the outer boundary of the face \f$ f_2\f$. The face \f$ f_1\f$ has a more complicated structure as it contains two holes in its interior: One hole consists of two adjacent faces \f$ f_3\f$ and \f$ f_4\f$, while the other hole is comprised of two edges. \f$ f_1\f$ also contains two isolated vertices \f$ u_1\f$ and \f$ u_2\f$ in its interior. +An arrangement of interior-disjoint line segments with some of the \dcel records that represent it. The unbounded face \f$ f_0\f$ has a single connected component that forms a hole inside it, and this hole is comprised of several faces. The half-edge \f$ e\f$ is directed from its source vertex \f$ v_1\f$ to its target vertex \f$ v_2\f$. This edge, together with its twin \f$ e'\f$, correspond to a line segment that connects the points associated with \f$ v_1\f$ and \f$ v_2\f$ and separates the face \f$ f_1\f$ from \f$ f_2\f$. The predecessor \f$ e_{\rm prev}\f$ and successor \f$ e_{\rm next}\f$ of \f$ e\f$ are part of the chain that form the outer boundary of the face \f$ f_2\f$. The face \f$ f_1\f$ has a more complicated structure as it contains two holes in its interior: One hole consists of two adjacent faces \f$ f_3\f$ and \f$ f_4\f$, while the other hole is comprised of two edges. \f$ f_1\f$ also contains two isolated vertices \f$ u_1\f$ and \f$ u_2\f$ in its interior. \cgalFigureEnd The \f$ x\f$-monotone curves of an arrangement are embedded in an @@ -110,7 +110,7 @@ to construct arrangements of different families of curves. In Section \ref arr_secnotif we review the notification mechanism that allows external classes to keep track of the changes that an arrangement instance goes through. Section \ref arr_secex_dcel -explains how to extend the \sc{Dcel} records, to store extra data +explains how to extend the \dcel records, to store extra data with them, and to efficiently update this data. In Section \ref arr_secoverlay we introduce the fundamental operation of overlaying two arrangements. @@ -127,7 +127,7 @@ the arrangement package. It is used to represent planar arrangements and it provides the interface needed to construct them, traverse them, and maintain them. An arrangement is defined by a geometric traits class that determines the family of planar -curves that form the arrangement, and a \sc{Dcel} class, which +curves that form the arrangement, and a \dcel class, which represents the topological structure of the planar subdivision. It supplies a minimal set of geometric operations (predicates and constructions) required to construct and maintain the arrangement @@ -159,7 +159,7 @@ parameters of the `Arrangement_2` template:
    • The `Dcel` template-parameter should be instantiated with a class that is a model of the `ArrangementDcel` concept. The value of this parameter is `Arr_default_dcel` by default. However, in - many applications it is necessary to extend the \sc{Dcel} features; + many applications it is necessary to extend the \dcel features; see Section \ref arr_secex_dcel for further explanations and examples.
    @@ -212,7 +212,7 @@ The simplest and most fundamental arrangement operations are the various traversal methods, which allow users to systematically go over the relevant features of the arrangement at hand. -As mentioned above, the arrangement is represented as a \sc{Dcel}, +As mentioned above, the arrangement is represented as a \dcel, which stores three containers of vertices, halfedges and faces. Thus, the `Arrangement_2` class supplies iterators for these containers. For example, the methods `vertices_begin()` and @@ -486,7 +486,7 @@ for more details and examples. \cgalFigureBegin{arr_figex_1,insert.png} - The various specialized insertion procedures. The inserted \f$ x\f$-monotone curve is drawn with a light dashed line, surrounded by two solid arrows that represent the pair of twin half-edges added to the \sc{Dcel}. Existing vertices are shown as black dots while new vertices are shown as light dots. Existing half-edges that are affected by the insertion operations are drawn as dashed arrows. (a) Inserting a curve as a new hole inside the face \f$ f\f$. (b) Inserting a curve from an existing vertex \f$ u\f$ that corresponds to one of its endpoints. (c) Inserting an \f$ x\f$-monotone curve whose endpoints are the already existing vertices \f$ u_1\f$ and \f$ u_2\f$. In our case, the new pair of half-edges close a new face \f$ f'\f$, where the hole \f$ h_1\f$, which used to belong to \f$ f\f$, now becomes an enclave in this new face. + The various specialized insertion procedures. The inserted \f$ x\f$-monotone curve is drawn with a light dashed line, surrounded by two solid arrows that represent the pair of twin half-edges added to the \dcel. Existing vertices are shown as black dots while new vertices are shown as light dots. Existing half-edges that are affected by the insertion operations are drawn as dashed arrows. (a) Inserting a curve as a new hole inside the face \f$ f\f$. (b) Inserting a curve from an existing vertex \f$ u\f$ that corresponds to one of its endpoints. (c) Inserting an \f$ x\f$-monotone curve whose endpoints are the already existing vertices \f$ u_1\f$ and \f$ u_2\f$. In our case, the new pair of half-edges close a new face \f$ f'\f$, where the hole \f$ h_1\f$, which used to belong to \f$ f\f$, now becomes an enclave in this new face. \cgalFigureEnd @@ -1349,7 +1349,7 @@ construct it from scratch. (ii) We have to insert \f$ m\f$ input curves to a non-empty arrangement `arr`. In the first case, we sweep over the input curves, compute -their intersection points and construct the \sc{Dcel} that represents +their intersection points and construct the \dcel that represents their planar arrangement. This process is performed in \f$ O\left((m + k)\log m\right)\f$ time, where \f$ k\f$ is the total number of intersection points. The running time is asymptotically better @@ -1567,7 +1567,7 @@ exists. This implied that collinearity indeed exists as explained above. \cgalAdvancedBegin \cgalFigureBegin{typenormal,unb_dcel.png} -A \sc{Dcel} representing an arrangement of four lines. Halfedges are drawn as thin arrows. The vertices \f$ v_1, \ldots, v_8\f$ lie at infinity, and are not associated with valid points. The halfedges that connect them are fictitious, and are not associated with concrete curves. The face denoted \f$ f_0\f$ (lightly shaded) is the fictitious "unbounded face" which lies outside the bounding rectangle (dashed) that bounds the actual arrangement. The four fictitious vertices \f$ v_{\rm bl}, v_{\rm tl}, v_{\rm br}\f$ and \f$ v_{\rm tr}\f$ represent the four corners of the bounding rectangle. +A \dcel representing an arrangement of four lines. Halfedges are drawn as thin arrows. The vertices \f$ v_1, \ldots, v_8\f$ lie at infinity, and are not associated with valid points. The halfedges that connect them are fictitious, and are not associated with concrete curves. The face denoted \f$ f_0\f$ (lightly shaded) is the fictitious "unbounded face" which lies outside the bounding rectangle (dashed) that bounds the actual arrangement. The four fictitious vertices \f$ v_{\rm bl}, v_{\rm tl}, v_{\rm br}\f$ and \f$ v_{\rm tr}\f$ represent the four corners of the bounding rectangle. \cgalFigureEnd @@ -1580,7 +1580,7 @@ finite curve endpoints and intersection points between curves in straightforward to compute the arrangement induced by this set. However, we would like to operate directly on the unbounded curves without having to preprocess them. Therefore, we use an implicit -bounding rectangle embedded in the \sc{Dcel} structure. +bounding rectangle embedded in the \dcel structure. \cgalFigureRef{arr_figunb_dcel} shows the arrangement of four lines that subdivide the plane into eight unbounded faces and two bounded ones. Notice that in this case the unbounded faces have outer @@ -1881,7 +1881,7 @@ of the `ArrangementXMonotoneTraits_2` concept. \subsection Arrangement_on_surface_2SupportingUnbounded Supporting Unbounded Curves An arrangement that supports unbounded \f$ x\f$-monotone curves maintains -an implicit bounding rectangle in the \sc{Dcel} structure; see +an implicit bounding rectangle in the \dcel structure; see Section \ref arr_ssecunb_rep. The unbounded ends of vertical rays, vertical lines, and curves with vertical asymptotes are represented by vertices that lie on the bottom or top sides of this bounding @@ -2840,7 +2840,7 @@ Geometric traits-class decorators allow you to attach auxiliary data to curves and to points. The data is automatically manipulated by the decorators and distributed to the constructed geometric entities. Note that additional information can alternatively be maintained by extending -the vertex, halfedge, or face types provided by the \sc{Dcel} class used +the vertex, halfedge, or face types provided by the \dcel class used by the arrangement; see the details in Section \ref arr_secex_dcel. The arrangement package includes a generic traits-class decorator @@ -3065,7 +3065,7 @@ depicted in \cgalFigureRef{arr_figex_19} : \cgalExample{Arrangement_on_surface_2/observer.cpp} -Observers are especially useful when the \sc{Dcel} records are +Observers are especially useful when the \dcel records are extended and store additional data, as they help updating this data on-line. See Section \ref arr_secex_dcel for more details and examples. @@ -3080,28 +3080,28 @@ objects and edges (halfedge pairs) are associated with it is possible to extend the traits-class type by using a traits-class decorator, as explained in Section \ref arr_ssecmeta_tr, which may be a sufficient solution for some applications. -However, the \sc{Dcel} faces are not associated with any geometric object, +However, the \dcel faces are not associated with any geometric object, so it is impossible to extend them using a traits-class decorator. -Extending the \sc{Dcel} face records comes handy is such cases. As a matter -of fact, it is possible to conveniently extend all \sc{Dcel} records +Extending the \dcel face records comes handy is such cases. As a matter +of fact, it is possible to conveniently extend all \dcel records (namely vertices, halfedges and faces), which can also be advantageous for some applications. All examples presented so far use the default `Arr_default_dcel`. This is done implicitly, as this class serves as a default parameter for -the `Arrangement_2` template. The default \sc{Dcel} class just associates +the `Arrangement_2` template. The default \dcel class just associates points with vertices and \f$ x\f$-monotone curves with halfedge, but nothing more. -In this section we show how to use alternative \sc{Dcel} types to extend the -desired \sc{Dcel} records. +In this section we show how to use alternative \dcel types to extend the +desired \dcel records. \subsection arr_ssecex_dcel_face Extending the DCEL Faces The `Arr_face_extended_dcel` class-template is used to associate auxiliary data field of type `FaceData` to -each face record in the \sc{Dcel}. +each face record in the \dcel. When an `Arrangement_2` object is parameterized by this -\sc{Dcel} class, its nested `Face` type is extended with the access function +\dcel class, its nested `Face` type is extended with the access function `data()` and with the modifier `set_data()`. Using these extra functions it is straightforward to access and maintain the auxiliary face-data field. @@ -3135,14 +3135,14 @@ segments:\cgalFootnote{For simplicity, the particular observer used must be atta The `Arr_extended_dcel` class-template is used to associate auxiliary data fields of types `VertexData` `HalfedgeData`, and `FaceData` to -each \sc{Dcel} vertex, halfedge, and face record types, respectively. +each \dcel vertex, halfedge, and face record types, respectively. When an `Arrangement_2` object is injected with this -\sc{Dcel} class, each one of its nested `Vertex`, `Halfedge` and +\dcel class, each one of its nested `Vertex`, `Halfedge` and `Face` classes is extended by the access function `data()` and by the modifier `set_data()`. -The next example shows how to use a \sc{Dcel} with extended vertex, +The next example shows how to use a \dcel with extended vertex, halfedge, and face records. In this example each vertex is associated with a color, which may be blue, red, or white, depending on whether the vertex is isolated, represents a segment endpoint, or whether it @@ -3161,11 +3161,11 @@ is copied to another arrangement instance: \cgalExample{Arrangement_on_surface_2/dcel_extension.cpp} \cgalAdvancedBegin -The various \sc{Dcel} classes presented in this section are perfectly +The various \dcel classes presented in this section are perfectly sufficient for most applications based on the arrangement package. -However, users may also use their own implementation of a \sc{Dcel} class +However, users may also use their own implementation of a \dcel class to instantiate the `Arrangement_2` class-template, in case they need -special functionality from their \sc{Dcel}. Such a class must be a model of the +special functionality from their \dcel. Such a class must be a model of the concept `ArrangementDcel`, whose exact specification is listed in the Reference Manual. \cgalAdvancedEnd @@ -3197,16 +3197,16 @@ types nested in geometry traits `Traits_R`. The same holds for all types nested in geometry traits `Traits_B`. The `ovl_traits` parameter is an instance of an overlay traits-class, which enables the creation of -`Dcel_R` records in the overlaid arrangement from the \sc{Dcel} features +`Dcel_R` records in the overlaid arrangement from the \dcel features of `arr_a` and `arr_b` that they correspond to. In principle, we distinguish between three levels of overlay:
    Simple overlay:
    An overlay of two arrangements that store no additional data -with their \sc{Dcel} records. That is, they are defined using the default -\sc{Dcel} class `Arr_default_dcel`. Typically, the overlaid -arrangement in this case stores no extra data with its \sc{Dcel} records as +with their \dcel records. That is, they are defined using the default +\dcel class `Arr_default_dcel`. Typically, the overlaid +arrangement in this case stores no extra data with its \dcel records as well (or if it does, the additional data fields cannot be computed by the overlay operation), so by overlaying the two arrangement we just compute the arrangement of all curves that induce `arr_a` and `arr_b`. @@ -3227,7 +3227,7 @@ the overlaid face. The `Arr_face_overlay_traits` class should be used as an overlay traits-class for face-overlay operations. It operates on arrangement, whose -\sc{Dcel} representation is based on the `Arr_face_extended_dcel` +\dcel representation is based on the `Arr_face_extended_dcel` class-template (see Section \ref arr_ssecex_dcel_face). The face-overlay traits-class is parameterized by a functor that is capable of combining two face-data fields of types `Dcel_A::Face_data` and @@ -3236,11 +3236,11 @@ object. The overlay traits-class uses this functor to properly construct the overlaid faces.
    Full overlay:
    An overlay of two arrangements that store additional data -fields with all their \sc{Dcel} records. That is, their \sc{Dcel} classes +fields with all their \dcel records. That is, their \dcel classes are instantiations of the `Arr_extended_dcel` class-template (see Section \ref arr_ssecex_dcel_all), where the resulting arrangement -also extends it \sc{Dcel} records with data fields computed on the basis -of the overlapping \sc{Dcel} features of the two input arrangements. +also extends it \dcel records with data fields computed on the basis +of the overlapping \dcel features of the two input arrangements.
    In the following subsections we give some examples for the simple and the @@ -3263,8 +3263,8 @@ The next program constructs two simple arrangements, as depicted in \subsection arr_ssecface_ovl Examples for a Face Overlay The following example shows how to compute the intersection of two polygons -using the `overlay()` function. It uses a face-extended \sc{Dcel} class -to define our arrangement class. The \sc{Dcel} extends each face with a Boolean +using the `overlay()` function. It uses a face-extended \dcel class +to define our arrangement class. The \dcel extends each face with a Boolean flag. A polygon is represented as a marked arrangement face, (whose flag is set). The example uses a face-overlay traits class, instantiated with a functor that simply performs a logical and operations on Boolean flags. @@ -3295,7 +3295,7 @@ when one constructs an arrangement induced by a set \f$ \cal C\f$ of arbitrary planar curves, she or he constructs a collection \f$ \cal C''\f$ of \f$ x\f$-monotone subcurves of \f$ \cal C\f$ that are pairwise disjoint in their interior, and these subcurves are associated with the arrangement edges (more precisely, with the -\sc{Dcel} halfedges). Doing so, the connection between the originating input +\dcel halfedges). Doing so, the connection between the originating input curves and the arrangement edges is lost. This loss might be acceptable for some applications. However, in many practical cases it is important to determine the input curves that give rise to the final subcurves. @@ -3308,8 +3308,8 @@ used for instantiating the template should be a model of the `ArrangementTraits_2` concept (see Section \ref arr_sssecinsert_gen). That is, it should define the `Curve_2` type (and not just the `X_monotone_curve_2` type). The `Dcel` parameter should model the -`ArrangementDcel` concept. Users can use the default \sc{Dcel} class or -an extended \sc{Dcel} class according to their needs. +`ArrangementDcel` concept. Users can use the default \dcel class or +an extended \dcel class according to their needs. \subsection arr_ssecarrwh_traverse Traversing an Arrangement with History @@ -3362,7 +3362,7 @@ instantiated by the same traits class. In this case, the resulting arrangement will store a consolidated container of input curves, and automatically preserve the cross-mapping between the arrangement edges and the consolidated curve set. Users can employ an overlay-traits class -to maintain any type of auxiliary data stored with the \sc{Dcel} features +to maintain any type of auxiliary data stored with the \dcel features (see Section \ref arr_secoverlay). \subsection arr_ssecmodif_traverse Modifying an Arrangement with History @@ -3503,7 +3503,7 @@ the arrangement features. Thus, they are ideal for arrangements instantiated using the `Arr_default_dcel` class. However, as explained in Section \ref arr_secex_dcel, one can easily extend the arrangement faces by using the `Arr_face_extended_dcel` -template, or extend all \sc{Dcel} records by using the `Arr_extended_dcel` +template, or extend all \dcel records by using the `Arr_extended_dcel` template. In such cases, it might be crucial that the auxiliary data fields are written to the file and read from there. @@ -3520,13 +3520,13 @@ auxiliary data that may be associated with the arrangement features. This is the default formatter used by the arrangement inserter and the arrangement extractor, as defined above.
  • `Arr_face_extended_text_formatter` operates on -arrangements whose \sc{Dcel} representation is based on the +arrangements whose \dcel representation is based on the `Arr_face_extended_dcel` class (see Section \ref arr_ssecex_dcel_face). It supports reading and writing the auxiliary data objects stored with the arrangement faces provided that the `FaceData` class supports an inserter and an extractor.
  • `Arr_extended_dcel_text_formatter` operates on -arrangements whose \sc{Dcel} representation is based on the +arrangements whose \dcel representation is based on the `Arr_extended_dcel` class (see Section \ref arr_ssecex_dcel_all). It supports reading and writing the auxiliary data objects stored with the arrangement vertices, edges @@ -3599,10 +3599,10 @@ the graph algorithms implemented in the bgl to `Arra An instance of `Arrangement_2` is adapted to a Boost graph through the provision of a set of free functions that operate on the arrangement features and conform with the relevant BGL concepts. Besides the straightforward -adaptation, which associates a vertex with each \sc{Dcel} vertex and an edge -with each \sc{Dcel} halfedge, the package also offer a dual adaptor, which -associates a graph vertex with each \sc{Dcel} face, such that two vertices are -connected, iff there is a \sc{Dcel} halfedge that connects the two corresponding +adaptation, which associates a vertex with each \dcel vertex and an edge +with each \dcel halfedge, the package also offer a dual adaptor, which +associates a graph vertex with each \dcel face, such that two vertices are +connected, iff there is a \dcel halfedge that connects the two corresponding faces. \subsection arr_ssecbgl_primal The Primal Arrangement Representation @@ -3706,7 +3706,7 @@ used for associating arbitrary data with the arrangement faces. In the following example we construct the same arrangement as in example `bgl_primal_adapter.cpp` (see \cgalFigureRef{arr_figex_bgl}), and perform breadth-first search on the graph faces, starting from the -unbounded face. We extend the \sc{Dcel} faces +unbounded face. We extend the \dcel faces with an unsigned integer, marking the discover time of the face using `boost` visitors and a property-map class that directly accesses the extended data of the faces: @@ -3751,7 +3751,7 @@ arrangement. The specialized insertion functions, i.e., can be used according to the available information. These functions hardly involve any geometric operations, if at all. They accept topologically related parameters, and use them to operate directly on -the \sc{Dcel} records, thus saving algebraic operations, which are +the \dcel records, thus saving algebraic operations, which are especially expensive when high-degree curves are involved. A polygon, represented by a list of segments along its boundary, can diff --git a/BGL/doc/BGL/BGL.txt b/BGL/doc/BGL/BGL.txt index 130bb0444e5..e03f3304e30 100644 --- a/BGL/doc/BGL/BGL.txt +++ b/BGL/doc/BGL/BGL.txt @@ -16,9 +16,9 @@ faces as edges of the dual graph. The scope of \cgal is geometry and not graph algorithms. Nevertheless, this package provides the necessary classes and functions that enable using the algorithms of the Boost Graph Library \cgalCite{cgal:sll-bgl-02} -(\sc{Bgl} for short) with \cgal data structures. +(\bgl for short) with \cgal data structures. -Furthermore, this package extends the \sc{Bgl} +Furthermore, this package extends the \bgl by introducing concepts such as `HalfedgeGraph` and `FaceGraph` allowing to handle *halfedges* and *faces*. These concepts reflect the design of the halfedge data structure described @@ -26,7 +26,7 @@ in Chapter \ref PkgHalfedgeDS, with opposite halfedges and circular sequences of halfedges around vertices and around faces. This chapter is organized as follows: -- The first section, Section \ref BGLA, summarizes the main ideas of the \sc{Bgl}. +- The first section, Section \ref BGLA, summarizes the main ideas of the \bgl. - Section \ref BGLHeader then explains where to find header files and the chosen naming conventions, as we blend two different libraries. - The four following sections give examples on how to use CGAL graph and mesh data structures @@ -34,13 +34,13 @@ such as \link PkgSurfaceMesh Surface_mesh \endlink, \link PkgPolyhedron Polyhedron \endlink, \link PkgArrangementOnSurface2 Arrangement_2 \endlink, and the -\link PkgTriangulation2 2D triangulation \endlink classes as models of the \sc{Bgl} concepts. +\link PkgTriangulation2 2D triangulation \endlink classes as models of the \bgl concepts. - Starting with Section \ref BGLExtensions, we introduce new graph concepts, classes, -and functions that extend the functionalities of the \sc{Bgl}. +and functions that extend the functionalities of the \bgl. \section BGLA A Short Introduction to the Boost Graph Library -The algorithms of the \sc{Bgl} operate on models of various graph concepts. +The algorithms of the \bgl operate on models of various graph concepts. The traits class `boost::graph_traits` enable algorithms to determine the types of vertices and edges (similar to `std::iterator_traits` for iterators). Free functions that operate on graphs enable algorithms to obtain, @@ -53,7 +53,7 @@ arbitrary order. \subsection BGLGraphConcepts Graph Concepts -The \sc{Bgl} introduces several graph concepts, +The \bgl introduces several graph concepts, which have different sets of characteristics and requirements. For example, iterating through all vertices or all edges in a graph, obtaining the outgoing or in-going edges of a vertex, inserting vertices and edges into a graph, @@ -101,16 +101,16 @@ std::pair vertices(const Graph& g); \subsection BGLPropertyMaps Property Maps -Another feature extensively used in the \sc{Bgl} is the *property map*, +Another feature extensively used in the \bgl is the *property map*, which is offered by the Boost Property Map Library. Property maps are a general purpose interface for mapping key objects to corresponding value objects. -The \sc{Bgl} uses property maps to associate information with vertices and edges. +The \bgl uses property maps to associate information with vertices and edges. This mechanism uses a traits class (`boost::property_traits`) and free functions to read (`get`) and write (`put`) information in vertices, edges, and also in halfedges and faces for models of the \cgal graph concepts. -For example, the \sc{Bgl} +For example, the \bgl Dijksta's shortest path algorithm writes the predecessor of each vertex, as well as the distance to the source in such a property map. @@ -138,14 +138,14 @@ Examples of such event points in graph algorithms are when a vertex is traversed or when all outgoing edges of a vertex have been traversed.
    See also Section Visitor Concepts -in the \sc{Bgl} manual. +in the \bgl manual. \subsection BGLNamedParameters Named Parameters -The notion of named parameters was introduced in the \sc{Bgl}, +The notion of named parameters was introduced in the \bgl, and allow the user to specify only those parameters which are really needed, by name, making the parameter ordering unimportant. See also this page -in the manual of the \sc{Bgl} for more information. +in the manual of the \bgl for more information. Say there is a function `f()` that takes 3 parameters called name, age and gender, and you have variables `n`, `a` and `g` to pass as parameters to that function. @@ -186,32 +186,32 @@ refine(pmesh, \section BGLHeader Header Files, Namespaces, and Naming Conventions This package provides the necessary classes and functions that enable using -\cgal data structures as models of the \sc{Bgl} graph concepts. +\cgal data structures as models of the \bgl graph concepts. To this end, we offer partial specializations of the `boost::graph_traits` for various \cgal packages. For each such package, denoted `PACKAGE`, the partial specializations live in the namespace `boost` and are located in the header file `CGAL/boost/graph/graph_traits_PACKAGE.h`. Free functions are in the namespace `CGAL`, and the compiler uses argument-dependent lookup to find them. %Euler operations, described in Section \ref BGLEulerOperations, are in the namespace `CGAL::Euler`, as the function `remove_face()` is at the same time a low-level and an %Euler operation. -Concerning the naming conventions, we have to use those of the \sc{Bgl}, -as to fulfill the requirements of the concepts defined in the \sc{Bgl}. +Concerning the naming conventions, we have to use those of the \bgl, +as to fulfill the requirements of the concepts defined in the \bgl. Note that these partial specializations are often providing more than is required, making these classes not only models of the graph concepts -of the \sc{Bgl}, but also models of the CGAL graph concepts, that will be +of the \bgl, but also models of the CGAL graph concepts, that will be described in detail in Section \ref BGLExtensions. Correspondence tables -between the types of a \cgal data structure and their \sc{Bgl} equivalents +between the types of a \cgal data structure and their \bgl equivalents can be found in the \ref PkgBGLTraits documentation page. We present in the following sections some examples of utilization of some -\cgal data structures as \sc{Bgl} graphs. +\cgal data structures as \bgl graphs. \section BGLSurface_mesh The Class Surface_mesh as Model of the Boost Graph Concept -The class `Surface_mesh` is a model of most of the graph concepts of the \sc{Bgl} +The class `Surface_mesh` is a model of most of the graph concepts of the \bgl as well as the concepts provided by \cgal. A complete list can be found in the documentation of \link BGLSMGT boost::graph_traits \endlink. -The examples show how to use some of the \sc{Bgl} algorithms with `Surface_mesh` and show how to use +The examples show how to use some of the \bgl algorithms with `Surface_mesh` and show how to use the concepts provided by \cgal to implement a simple algorithm. \subsection BGLExampleMinimumSpanningTreeofaSurfaceMesh Example: Minimum Spanning Tree of a Surface_mesh @@ -221,16 +221,16 @@ More examples can be found in Chapters \ref PkgSurfaceMeshSimplification, \ref PkgSurfaceMeshSegmentation, and \ref PkgSurfaceMeshDeformation. The surface mesh class uses integer indices to address vertices and edges, -and it comes with a built-in property mechanism that maps nicely on the \sc{Bgl}. +and it comes with a built-in property mechanism that maps nicely on the \bgl. \cgalExample{BGL_surface_mesh/prim.cpp} \section BGLPolyhedral The Class Polyhedron_3 as Model of the Boost Graph Concept -The class `Polyhedron_3` is a model of most of the graph concepts of the \sc{Bgl} +The class `Polyhedron_3` is a model of most of the graph concepts of the \bgl as well as the concepts provided by \cgal. A complete list can be found in the documentation of \link BGLPolyGT boost::graph_traits \endlink. -The examples show how to use some of the \sc{Bgl} algorithms with `Polyhedron_3` and show how to use +The examples show how to use some of the \bgl algorithms with `Polyhedron_3` and show how to use the concepts provided by \cgal to implement a simple algorithm. \subsection BGLExampleMinimumSpanningTreeofaPolyhedral Example: Minimum Spanning Tree of a Polyhedral Surface @@ -243,7 +243,7 @@ More examples can be found in the Chapter \subsection BGLExampleUsingVerticesandEdgeswithanID Example: Using Vertices, and Edges with an ID -The following example program shows a call to the \sc{Bgl} +The following example program shows a call to the \bgl Kruskal's minimum spanning tree algorithm accessing the `id()` field stored in a polyhedron vertex. @@ -275,7 +275,7 @@ integers in the range `[0, t.number_of_vertices())`. \subsection BGLExampleStoringtheVertexIDintheVertex Example: Storing the Vertex ID in the Vertex -The algorithms of the \sc{Bgl} extensively use of the indices of +The algorithms of the \bgl extensively use of the indices of vertices. In the previous example we stored the indices in a `std::map` and turned that map in a property map. This property map was then passed as argument to the shortest path function. @@ -316,7 +316,7 @@ edges in our boost graph. Given an `Arrangement_2` instance, we can efficiently traverse its vertices and halfedges. Thus, the arrangement graph is a model of the concepts -`VertexListGraph` and `EdgeListGraph` introduced by the \sc{Bgl}. +`VertexListGraph` and `EdgeListGraph` introduced by the \bgl. At the same time, we use an iterator adapter of the circulator over the halfedges incident to a vertex (`Halfedge_around_target_circulator` - see Section \ref arr_sssectr_vertex "Traversal Methods for an Arrangement Vertex" @@ -327,11 +327,11 @@ is a model of the concept `BidirectionalGraph` (this concept refines It is important to notice that the vertex descriptors we use are `Vertex_handle` objects and not vertex indices. However, in order -to gain more efficiency in most \sc{Bgl} algorithm, it is better to have them +to gain more efficiency in most \bgl algorithm, it is better to have them indexed \f$ 0, 1, \ldots, (n-1)\f$, where \f$ n\f$ is the number of vertices. We therefore introduce the `Arr_vertex_index_map` class-template, which maintains a mapping of vertex handles to indices, as required by the -\sc{Bgl}. An instance of this class must be attached to a valid arrangement +\bgl. An instance of this class must be attached to a valid arrangement vertex when it is created. It uses the notification mechanism (see Section \ref arr_secnotif) to automatically maintain the mapping of vertices to indices, even when new vertices are inserted into the arrangement or @@ -340,7 +340,7 @@ existing vertices are removed. A complete description of the types correspondences can be found in the documentation of \link BGLArgtGT boost::graph_traits \endlink. -In most algorithm provided by the \sc{Bgl}, the output is given by +In most algorithm provided by the \bgl, the output is given by property maps, such that each map entry corresponds to a vertex. For example, when we compute the shortest paths from a given source vertex \f$ s\f$ to all other vertices we can obtain a map of distances and a map of @@ -353,7 +353,7 @@ template allows for an efficient mapping of `Vertex_handle` objects to properties of type `Type`. Note however that unlike the `Arr_vertex_index_map` class, the vertex property-map class is not kept synchronized with the number of vertices in the arrangement, so it -should not be reused in calls to the \sc{Bgl} functions in case the arrangement +should not be reused in calls to the \bgl functions in case the arrangement is modified in between these calls. \cgalFigureBegin{figex_bgl,ex_bgl.png} @@ -362,7 +362,7 @@ An arrangement of 7 line segments, as constructed by `ex_bgl_primal_adapter.cpp` In the following example we construct an arrangement of 7 line segments, as shown in \cgalFigureRef{figex_bgl}, -then use the \sc{Bgl} Dijkstra's shortest-paths algorithm to compute +then use the \bgl Dijkstra's shortest-paths algorithm to compute the graph distance of all vertices from the leftmost vertex in the arrangement \f$ v_0\f$. Note the usage of the `Arr_vertex_index_map` and the `Arr_vertex_property_map` classes. The latter one, instantiated by @@ -400,7 +400,7 @@ data with the arrangement faces. In the following example we construct the same arrangement as in example `ex_bgl_primal_adapter.cpp` (see \cgalFigureRef{arr_figex_bgl}), and perform breadth-first search on the graph faces, starting from the -unbounded face. We extend the \sc{Dcel} faces +unbounded face. We extend the \dcel faces with an unsigned integer, marking the discover time of the face and use a breadth-first-search visitor to obtain these times and update the faces accordingly: @@ -411,9 +411,9 @@ accordingly: The previous sections introduced partial specializations and free functions so that several \cgal data structures are adapted as models of some -of the \sc{Bgl} graph concepts. +of the \bgl graph concepts. In this section, we introduce new concepts, iterators, and property maps inspired -by the functionalities of the \sc{Bgl}. +by the functionalities of the \bgl. \subsection BGLExtensionsGraphConcepts Graph concepts @@ -485,7 +485,7 @@ stored in the vertex record.) \subsubsection BGLExampleNormalHalfedgeGraph Example: Calculating Facet Normals using HalfedgeGraph The following example program shows a simple algorithm for calculating -facet normals for a polyhedron using the \sc{Bgl} API. A +facet normals for a polyhedron using the \bgl API. A boost::vector_property_map is used to to store the calculated normals instead of changing the Polyhedron items class. @@ -579,13 +579,13 @@ as shown in the following example. \subsection BGLSeamMesh The Seam Mesh The class `Seam_mesh` allows to mark edges of a mesh as seam edges -so that they virtually become border edges when exploring a seam mesh with the \sc{Bgl} API. +so that they virtually become border edges when exploring a seam mesh with the \bgl API. The input mesh is referred to as underlying mesh of the seam mesh. We denote `tm` and `sm` the underlying mesh and the seam mesh respectively. Figure \cgalFigureRef{fig_Seam_mesh_1} shows an example of mesh on which two edges, defined by the halfedge pairs `h2-h3` and `h6-h7`, are marked as seams. -The introduction of virtual borders modifies the elementary \sc{Bgl} graph traversal +The introduction of virtual borders modifies the elementary \bgl graph traversal operations: when we circulate around the target of `h7` in the underlying mesh, we traverse `h7`, `h1`, `h3`, `h5`, before arriving at `h7` again. However, when we circulate in the seam mesh, we traverse `h7`, `h1`, `h3*`, diff --git a/BGL/doc/BGL/CGAL/HalfedgeDS_face_max_base_with_id.h b/BGL/doc/BGL/CGAL/HalfedgeDS_face_max_base_with_id.h index c106f1d9644..5518ffb5c0c 100644 --- a/BGL/doc/BGL/CGAL/HalfedgeDS_face_max_base_with_id.h +++ b/BGL/doc/BGL/CGAL/HalfedgeDS_face_max_base_with_id.h @@ -9,7 +9,7 @@ concept. It is equivalent to `HalfedgeDS_face_base< Refs, Tag_true>` with an added integer field which can be used to index faces -in \sc{Bgl} algorithms. +in \bgl algorithms. The class contains support for the incident halfedge pointer and the required type definitions. It can be used for deriving own faces. diff --git a/BGL/doc/BGL/CGAL/HalfedgeDS_halfedge_max_base_with_id.h b/BGL/doc/BGL/CGAL/HalfedgeDS_halfedge_max_base_with_id.h index 965f513863a..f57951dc82e 100644 --- a/BGL/doc/BGL/CGAL/HalfedgeDS_halfedge_max_base_with_id.h +++ b/BGL/doc/BGL/CGAL/HalfedgeDS_halfedge_max_base_with_id.h @@ -7,7 +7,7 @@ namespace CGAL { The class `HalfedgeDS_halfedge_max_base_with_id` is a model of the `HalfedgeDSHalfedge` concept. It is equivalent to `HalfedgeDS_halfedge_base< Refs, Tag_true, Tag_true, Tag_true>` with an added integer -field which can be used to index halfedges in \sc{Bgl} algorithms. +field which can be used to index halfedges in \bgl algorithms. The class contains support for the previous, next, opposite, vertex and face pointers and the required type definitions. It can be used for deriving own halfedges. diff --git a/BGL/doc/BGL/CGAL/HalfedgeDS_vertex_max_base_with_id.h b/BGL/doc/BGL/CGAL/HalfedgeDS_vertex_max_base_with_id.h index 328c65aa8c4..15fad92af97 100644 --- a/BGL/doc/BGL/CGAL/HalfedgeDS_vertex_max_base_with_id.h +++ b/BGL/doc/BGL/CGAL/HalfedgeDS_vertex_max_base_with_id.h @@ -8,7 +8,7 @@ The class `HalfedgeDS_vertex_max_base_with_id` is a model of the `HalfedgeDSVert concept. It is equivalent to `HalfedgeDS_vertex_base< Refs, Tag_true>` with an added integer field which can be used to index vertices -in \sc{Bgl} algorithms.. +in \bgl algorithms.. The class contains support for the point and the required type definitions. It can be used for deriving own vertices. diff --git a/BGL/doc/BGL/CGAL/Polyhedron_items_with_id_3.h b/BGL/doc/BGL/CGAL/Polyhedron_items_with_id_3.h index 91f9fa32188..7db19153e87 100644 --- a/BGL/doc/BGL/CGAL/Polyhedron_items_with_id_3.h +++ b/BGL/doc/BGL/CGAL/Polyhedron_items_with_id_3.h @@ -7,7 +7,7 @@ namespace CGAL { The class `Polyhedron_items_with_id_3` is a model of the `PolyhedronItems_3` concept. It provides definitions for vertices with points, halfedges, and faces with plane equations, all of them with an additional integer -field which can be used to index the items in a \sc{Bgl} algorithm. +field which can be used to index the items in a \bgl algorithm. The polyhedron traits class must provide the respective types for the point and the plane equation. Vertices and facets both contain a halfedge handle to an incident diff --git a/BGL/doc/BGL/CGAL/Triangulation_face_base_with_id_2.h b/BGL/doc/BGL/CGAL/Triangulation_face_base_with_id_2.h index e1b380ac939..e6bdbbc6577 100644 --- a/BGL/doc/BGL/CGAL/Triangulation_face_base_with_id_2.h +++ b/BGL/doc/BGL/CGAL/Triangulation_face_base_with_id_2.h @@ -6,7 +6,7 @@ namespace CGAL { The class `Triangulation_face_base_with_id_2` is a model of the concept `TriangulationFaceBase_2`, the base face of a 2D-triangulation. It provides an integer field that can be used to -index faces for \sc{Bgl} algorithms. +index faces for \bgl algorithms. Note that the user is in charge of setting indices correctly before running a graph algorithm, by calling the function diff --git a/BGL/doc/BGL/CGAL/Triangulation_vertex_base_with_id_2.h b/BGL/doc/BGL/CGAL/Triangulation_vertex_base_with_id_2.h index 0c71e6b72af..d9a58761062 100644 --- a/BGL/doc/BGL/CGAL/Triangulation_vertex_base_with_id_2.h +++ b/BGL/doc/BGL/CGAL/Triangulation_vertex_base_with_id_2.h @@ -6,7 +6,7 @@ namespace CGAL { The class `Triangulation_vertex_base_with_id_2` is a model of the concept `TriangulationVertexBase_2`, the base vertex of a 2D-triangulation. It provides an integer field that can be used to -index vertices for \sc{Bgl} algorithms. +index vertices for \bgl algorithms. Note that the user is in charge of setting indices correctly before running a graph algorithm, by calling the function diff --git a/BGL/doc/BGL/CGAL/boost/graph/properties.h b/BGL/doc/BGL/CGAL/boost/graph/properties.h index 40ca966a8e2..01f6df7b62f 100644 --- a/BGL/doc/BGL/CGAL/boost/graph/properties.h +++ b/BGL/doc/BGL/CGAL/boost/graph/properties.h @@ -4,7 +4,7 @@ namespace CGAL { /// \ingroup PkgBGLProperties /// @{ -/// The constant `vertex_index` is a property tag which identifies the index property of a vertex of a \sc{Bgl} +/// The constant `vertex_index` is a property tag which identifies the index property of a vertex of a \bgl /// Graph. /// \cgalModels PropertyTag enum vertex_index_t { vertex_index }; @@ -15,7 +15,7 @@ enum vertex_index_t { vertex_index }; /// \cgalModels PropertyTag enum halfedge_index_t { halfedge_index }; -/// The constant `edge_index` is a property tag which identifies the index property of an edge of a \sc{Bgl} +/// The constant `edge_index` is a property tag which identifies the index property of an edge of a \bgl /// Graph. /// \cgalModels PropertyTag enum edge_index_t { edge_index }; diff --git a/BGL/doc/BGL/Concepts/HalfedgeGraph.h b/BGL/doc/BGL/Concepts/HalfedgeGraph.h index 3769db82e16..a6fc002b0aa 100644 --- a/BGL/doc/BGL/Concepts/HalfedgeGraph.h +++ b/BGL/doc/BGL/Concepts/HalfedgeGraph.h @@ -2,7 +2,7 @@ \ingroup PkgBGLConcepts \cgalConcept -The concept `HalfedgeGraph` is a refinement of the \sc{Bgl} concept +The concept `HalfedgeGraph` is a refinement of the \bgl concept `IncidenceGraph` and adds the notion of a *halfedge*: Each edge is associated with two *opposite* halfedges with source and target vertices swapped. Furthermore, halfedges have a *successor* and *predecessor*, diff --git a/BGL/doc/BGL/NamedParameters.txt b/BGL/doc/BGL/NamedParameters.txt index d0a492fd54a..70a9e8a8029 100644 --- a/BGL/doc/BGL/NamedParameters.txt +++ b/BGL/doc/BGL/NamedParameters.txt @@ -2,7 +2,7 @@ \defgroup bgl_namedparameters Named Parameters \ingroup PkgBGLRef -The algorithms of the Boost Graph Library (\sc{Bgl}) often have many parameters with default +The algorithms of the Boost Graph Library (\bgl) often have many parameters with default values that are appropriate for most cases. In general, when no special treatment is applied, the values of such parameters are passed as a sequence. Deviating from the default for a certain parameter @@ -18,7 +18,7 @@ vertex_descriptor s = vertex(A, g); dijkstra_shortest_paths(g, s, predecessor_map(&p[0]).distance_map(&d[0])); \endcode -In the \sc{Bgl} manual, this is called +In the \bgl manual, this is called named parameters. The named parameters in the snippet use the tags `predecessor_map` and `distance_map` and they are concatenated using the dot operator.
    @@ -26,7 +26,7 @@ and they are concatenated using the dot operator.
    A similar mechanism was introduced in \cgal, with the small difference that the named parameters tag live in the `CGAL::parameters::` namespace and `CGAL::parameters::all_default()` can be used to indicate that default values of optional named parameters must be used. -As in the \sc{BGL}, named parameters in \cgal are also concatenated using +As in the \bgl, named parameters in \cgal are also concatenated using the dot operator, and a typical usage is thus: \code {.cpp} diff --git a/BGL/doc/BGL/PackageDescription.txt b/BGL/doc/BGL/PackageDescription.txt index 8a5d946cd9e..cf7e059049b 100644 --- a/BGL/doc/BGL/PackageDescription.txt +++ b/BGL/doc/BGL/PackageDescription.txt @@ -3,9 +3,9 @@ /*! \defgroup PkgBGLConcepts Concepts \ingroup PkgBGLRef - We extend the Boost Graph Library (\sc{Bgl} for short) with a set of new concepts. + We extend the Boost Graph Library (\bgl for short) with a set of new concepts. In order to make this documentation self-contained we here also document - concepts that are defined in the original version of the \sc{Bgl}. + concepts that are defined in the original version of the \bgl. The documentation of the concepts lists at the same time the functions related to it. Models of the concept and their related functions must be in the same namespace (they will be found by Koenig lookup). @@ -586,9 +586,9 @@ Methods to read and write graphs. \cgalPkgSummaryBegin \cgalPkgAuthors{Andreas Fabri, Fernando Cacciola, Philipp Moeller, and Ron Wein} \cgalPkgDesc{This package provides a framework for interfacing \cgal data structures - with the algorithms of the Boost Graph Library, or \sc{BGL} for short. + with the algorithms of the Boost Graph Library, or \bgl for short. It allows to run graph algorithms directly on \cgal data structures which are model - of the \sc{BGL} graph concepts, for example the shortest path algorithm + of the \bgl graph concepts, for example the shortest path algorithm on a Delaunay triangulation in order to compute the Euclidean minimum spanning tree. Furthermore, it introduces several new graph concepts describing halfedge data structures.} \cgalPkgManuals{Chapter_CGAL_and_the_Boost_Graph_Library,PkgBGLRef} @@ -621,7 +621,7 @@ Methods to read and write graphs. \cgalCRPSection{%CGAL Classes Adapted for the Graph API} -A number of \cgal structures have been adapted as graphs for the \sc{Bgl}. All +A number of \cgal structures have been adapted as graphs for the \bgl. All adapted types are listed here. The pages document which concepts they model, the properties they support, and any possible caveats that a user might encounter. diff --git a/BGL/doc/BGL/graph_traits.txt b/BGL/doc/BGL/graph_traits.txt index 87c96903b6f..d6f87e7b868 100644 --- a/BGL/doc/BGL/graph_traits.txt +++ b/BGL/doc/BGL/graph_traits.txt @@ -3,7 +3,7 @@ \ingroup PkgBGLRef -The \sc{Bgl} defines the class template +The \bgl defines the class template `boost::graph_traits` as a uniform interface to the properties and types of %graph types. @@ -156,7 +156,7 @@ vertex, or walking through the faces container. The mapping between vertices, edges, and faces of the triangulation and the graph is rather straightforward, but there are some subtleties. The -value type of the \sc{Bgl} iterators is the vertex or edge descriptor, +value type of the \bgl iterators is the vertex or edge descriptor, whereas in \cgal all iterators and circulators are also handles and hence have as value type Vertex or Edge. diff --git a/Documentation/doc/Documentation/Developer_manual/cmakelist_script.txt b/Documentation/doc/Documentation/Developer_manual/cmakelist_script.txt index 60af5578426..64ce1695e41 100644 --- a/Documentation/doc/Documentation/Developer_manual/cmakelist_script.txt +++ b/Documentation/doc/Documentation/Developer_manual/cmakelist_script.txt @@ -26,7 +26,7 @@ source file. libraries (i.e.\ "Core", "ImageIO", and "Qt5"). An example is `-c Core`.
    `-b boost1:boost2:...`
    Lists components ("boost1", -"boost2") of \sc{Boost} to which the executable(s) should be +"boost2") of \boost to which the executable(s) should be linked. Valid options are, for instance, "filesystem" or "program_options". diff --git a/Documentation/doc/Documentation/Third_party.txt b/Documentation/doc/Documentation/Third_party.txt index d376747423e..f11cc709977 100644 --- a/Documentation/doc/Documentation/Third_party.txt +++ b/Documentation/doc/Documentation/Third_party.txt @@ -11,11 +11,11 @@ supporting C++14 or later. | Operating System | Compiler | | :------- | :--------------- | -| Linux | \sc{Gnu} `g++` 6.3 or later\cgalFootnote{`http://gcc.gnu.org/`} | +| Linux | \gnu `g++` 6.3 or later\cgalFootnote{`http://gcc.gnu.org/`} | | | `Clang` \cgalFootnote{`http://clang.llvm.org/`} compiler version 8.0.0 | -| \sc{MS} Windows | \sc{Gnu} `g++` 6.3 or later\cgalFootnote{`http://gcc.gnu.org/`} | -| | \sc{MS} Visual `C++` 14.0, 15.9, 16.0 (\sc{Visual Studio} 2015, 2017, and 2019)\cgalFootnote{`https://visualstudio.microsoft.com/`} | -| MacOS X | \sc{Gnu} `g++` 6.3 or later\cgalFootnote{`http://gcc.gnu.org/`} | +| \ms Windows | \gnu `g++` 6.3 or later\cgalFootnote{`http://gcc.gnu.org/`} | +| | \ms Visual `C++` 14.0, 15.9, 16.0 (\visualstudio 2015, 2017, and 2019)\cgalFootnote{`https://visualstudio.microsoft.com/`} | +| MacOS X | \gnu `g++` 6.3 or later\cgalFootnote{`http://gcc.gnu.org/`} | | | Apple `Clang` compiler versions 7.0.2 and 10.0.1 | @@ -58,38 +58,38 @@ The \stl comes with the compiler, and as such no installation is required. \subsection thirdpartyBoost Boost Version 1.66 or later -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 +The \boost libraries are a set of portable C++ source libraries. +Most of \boost libraries are header-only, but a few of them need to be compiled or installed as binaries. -\cgal only requires the headers of the \sc{Boost} libraries, but some demos and examples +\cgal only requires the headers of the \boost libraries, but some demos and examples depend on the binary library `Boost.Program_options`. -In case the \sc{Boost} libraries are not installed on your system already, you +In case the \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/`. -As there is no canonical directory for where to find \sc{Boost} on Windows, +As there is no canonical directory for where to find \boost on Windows, we recommend that you define the environment variable -`BOOST_ROOT` and set it to where you have installed \sc{Boost}, e.g., `C:\boost\boost_1_69_0`. +`BOOST_ROOT` and set it to where you have installed \boost, e.g., `C:\boost\boost_1_69_0`. \subsection thirdpartyMPFR GNU Multiple Precision Arithmetic (GMP) and GNU Multiple Precision Floating-Point Reliably (MPFR) Libraries GMP Version 4.2 or later, MPFR Version 2.2.1 or later The components `libCGAL`, `libCGAL_Core`, and `libCGAL_Qt5` require -\sc{Gmp} and \sc{Mpfr} which are libraries for multi precision integers and rational numbers, +\gmp and \mpfr which are libraries for multi precision integers and rational numbers, and for multi precision floating point numbers. \cgal combines floating point arithmetic with exact arithmetic in order to be efficient and reliable. \cgal has a built-in -number type for that, but \sc{Gmp} and \sc{Mpfr} provide a faster +number type for that, but \gmp and \mpfr provide a faster solution, and we recommend to use them. These libraries can be obtained from `https://gmplib.org/` and `https://www.mpfr.org/`. -Since Visual \cpp is not properly supported by the \sc{Gmp} and \sc{Mpfr} projects, -we provide precompiled versions of \sc{Gmp} and \sc{Mpfr}, which can be downloaded with the installer +Since Visual \cpp is not properly supported by the \gmp and \mpfr projects, +we provide precompiled versions of \gmp and \mpfr, which can be downloaded with the installer `CGAL-\cgalReleaseNumber``-Setup.exe`. \section secoptional3rdpartysoftware Optional Third Party Libraries @@ -108,155 +108,155 @@ the location of third-party software during configuration. Qt is a cross-platform application and UI framework. The component libCGAL_Qt5 is essential to run the \cgal demos and basic viewers. -It requires \sc{Qt}5 installed on your system. -In case \sc{Qt} is not yet installed on your system, you can download +It requires \qt5 installed on your system. +In case \qt is not yet installed on your system, you can download it from `https://www.qt-project.org/`. -The exhaustive list of \sc{Qt}5 components used in demos is: +The exhaustive list of \qt5 components used in demos is: `Core`, `Gui`, `Help`, `OpenGL`, `Script`, `ScriptTools`, `Svg`, `Widgets`, `qcollectiongenerator` (with `sqlite` driver plugin), and `Xml`. \subsection thirdpartyEigen Eigen Version 3.1 or later -\sc{Eigen} is a `C++` template library for linear algebra. \sc{Eigen} supports all +\eigen is a `C++` template library for linear algebra. \eigen supports all matrix sizes, various matrix decomposition methods and sparse linear solvers. -In \cgal, \sc{Eigen} is used in many packages such as \ref +In \cgal, \eigen is used in many packages such as \ref PkgPoissonSurfaceReconstruction3 or \ref PkgJetFitting3, providing sparse linear solvers and singular value decompositions. A package -dependency over \sc{Eigen} is marked on the Package Overview page. In order to use Eigen in \cgal programs, the executables should be linked with the CMake imported target `CGAL::Eigen3_support` provided in `CGAL_Eigen3_support.cmake`. -The \sc{Eigen} web site is `http://eigen.tuxfamily.org`. +The \eigen web site is `http://eigen.tuxfamily.org`. \subsection thirdpartyOpenGR OpenGR -\sc{OpenGR} is a set C++ libraries for 3D Global Registration released under the terms of the APACHE V2 licence. +\opengr is a set C++ libraries for 3D Global Registration released under the terms of the APACHE V2 licence. -\cgal provides wrappers for the Super4PCS algorithm of \sc{OpenGR} in the \ref PkgPointSetProcessing3Ref -packages. In order to use \sc{OpenGR} in \cgal programs, the executables should be linked with the CMake imported target `CGAL::OpenGR_support` provided in `CGAL_OpenGR_support.cmake`. +\cgal provides wrappers for the Super4PCS algorithm of \opengr in the \ref PkgPointSetProcessing3Ref +packages. In order to use \opengr in \cgal programs, the executables should be linked with the CMake imported target `CGAL::OpenGR_support` provided in `CGAL_OpenGR_support.cmake`. -The \sc{OpenGR} web site is `https://github.com/STORM-IRIT/OpenGR`. +The \opengr web site is `https://github.com/STORM-IRIT/OpenGR`. \subsection thirdpartylibpointmatcher PointMatcher -\sc{libpointmatcher} is a modular library implementing the Iterative Closest Point (ICP) algorithm for aligning point clouds, released under a permissive BSD license. +\libpointmatcher is a modular library implementing the Iterative Closest Point (ICP) algorithm for aligning point clouds, released under a permissive BSD license. -\cgal provides wrappers for the ICP algorithm of \sc{libpointmatcher} in the \ref PkgPointSetProcessing3Ref -packages. In order to use \sc{libpointmatcher} in \cgal programs, the +\cgal provides wrappers for the ICP algorithm of \libpointmatcher in the \ref PkgPointSetProcessing3Ref +packages. In order to use \libpointmatcher in \cgal programs, the executables should be linked with the CMake imported target `CGAL::pointmatcher_support` provided in `CGAL_pointmatcher_support.cmake`. -The \sc{libpointmatcher} web site is `https://github.com/ethz-asl/libpointmatcher`. \subsection thirdpartyLeda LEDA Version 6.2 or later \leda is a library of efficient data structures and -algorithms. Like \sc{Core}, \leda offers a real number data type. +algorithms. Like \core, \leda offers a real number data type. In \cgal this library is optional, and its number types can -be used as an alternative to \sc{Gmp}, \sc{Mpfr}, and \sc{Core}. +be used as an alternative to \gmp, \mpfr, and \core. Free and commercial editions of \leda are available from `https://www.algorithmic-solutions.com`. \subsection thirdpartyMPFI Multiple Precision Floating-point Interval (MPFI) Version 1.4 or later -\sc{Mpfi} provides arbitrary precision interval arithmetic with intervals -represented using \sc{Mpfr} reliable floating-point numbers. -It is based on the libraries \sc{Gmp} and \sc{Mpfr}. +\mpfi provides arbitrary precision interval arithmetic with intervals +represented using \mpfr reliable floating-point numbers. +It is based on the libraries \gmp and \mpfr. In the setting of \cgal, this library is optional: it is used by some models of the \ref PkgAlgebraicKernelD "Algebraic Kernel". -\sc{Mpfi} can be downloaded from `https://mpfi.gforge.inria.fr/`. +\mpfi can be downloaded from `https://mpfi.gforge.inria.fr/`. \subsection thirdpartyRS3 RS and RS3 -\sc{Rs} (Real Solutions) is devoted to the study of the real roots of +\rs (Real Solutions) is devoted to the study of the real roots of polynomial systems with a finite number of complex roots (including -univariate polynomials). In \cgal, \sc{Rs} is used by one model of the +univariate polynomials). In \cgal, \rs is used by one model of the \ref PkgAlgebraicKernelD "Algebraic Kernel". -\sc{Rs} is freely distributable for non-commercial use. You can download it -from `http://vegas.loria.fr/rs/`. Actually, the \sc{Rs} package also includes \sc{Rs3}, the -successor of \sc{Rs}, which is used in conjunction with it. +\rs is freely distributable for non-commercial use. You can download it +from `http://vegas.loria.fr/rs/`. Actually, the \rs package also includes \rs3, the +successor of \rs, which is used in conjunction with it. -The libraries \sc{Rs} and \sc{Rs3} need \sc{Mpfi}, which can be downloaded from +The libraries \rs and \rs3 need \mpfi, which can be downloaded from `https://mpfi.gforge.inria.fr/`. \subsection thirdpartyNTL NTL Version 5.1 or later -\sc{Ntl} provides data structures and algorithms for signed, arbitrary +\ntl provides data structures and algorithms for signed, arbitrary length integers, and for vectors, matrices, and polynomials over the -integers and over finite fields. The optional library \sc{Ntl} is used by \cgal -to speed up operations of the Polynomial package, such as GCDs. It is recommended to install \sc{Ntl} with support from \sc{Gmp}. +integers and over finite fields. The optional library \ntl is used by \cgal +to speed up operations of the Polynomial package, such as GCDs. It is recommended to install \ntl with support from \gmp. -\sc{Ntl} can be downloaded from `https://www.shoup.net/ntl/`. +\ntl can be downloaded from `https://www.shoup.net/ntl/`. \subsection thirdpartyESBTL ESBTL -The \sc{Esbtl} (Easy Structural Biology Template Library) is a library that allows -the handling of \sc{Pdb} data. +The \esbtl (Easy Structural Biology Template Library) is a library that allows +the handling of \pdb data. -In \cgal, the \sc{Esbtl} is used in an example of the \ref PkgSkinSurface3 package. +In \cgal, the \esbtl is used in an example of the \ref PkgSkinSurface3 package. It can be downloaded from `http://esbtl.sourceforge.net/`. \subsection thirdpartyTBB Intel TBB -\sc{Tbb} (Threading Building Blocks) is a library developed by Intel Corporation for writing software +\tbb (Threading Building Blocks) is a library developed by Intel Corporation for writing software programs that take advantage of multi-core processors. -In \cgal, \sc{Tbb} is used by the packages that offer parallel -code. In order to use \sc{Tbb} in \cgal programs, the executables +In \cgal, \tbb is used by the packages that offer parallel +code. In order to use \tbb in \cgal programs, the executables should be linked with the CMake imported target `CGAL::TBB_support` provided in `CGAL_TBB_support.cmake`. -The \sc{Tbb} web site is `https://www.threadingbuildingblocks.org`. +The \tbb web site is `https://www.threadingbuildingblocks.org`. \subsection thirdpartyLASlib LASlib -\sc{LASlib} is a `C++` library for handling LIDAR data sets stored in +\laslib is a `C++` library for handling LIDAR data sets stored in the LAS format (or the compressed LAZ format). -In \cgal, \sc{LASlib} is used to provide input and output functions in -the \ref PkgPointSetProcessing3 package. In order to use \sc{LASlib} +In \cgal, \laslib is used to provide input and output functions in +the \ref PkgPointSetProcessing3 package. In order to use \laslib in \cgal programs, the executables should be linked with the CMake imported target `CGAL::LASLIB_support` provided in `CGAL_LASLIB_support.cmake`. -The \sc{LASlib} web site is `https://rapidlasso.com/lastools/`. \sc{LASlib} +The \laslib web site is `https://rapidlasso.com/lastools/`. \laslib is usually distributed along with LAStools: for simplicity, \cgal provides a fork with a CMake based install procedure. \subsection thirdpartyOpenCV OpenCV -\sc{OpenCV} (Open Computer Vision) is a library designed for computer +\opencv (Open Computer Vision) is a library designed for computer vision, computer graphics and machine learning. -In \cgal, \sc{OpenCV} is used by the \ref PkgClassification -package. In order to use \sc{OpenCV} in \cgal programs, the +In \cgal, \opencv is used by the \ref PkgClassification +package. In order to use \opencv in \cgal programs, the executables should be linked with the CMake imported target `CGAL::OpenCV_support` provided in `CGAL_OpenCV_support.cmake`. -The \sc{OpenCV} web site is `https://opencv.org/`. +The \opencv web site is `https://opencv.org/`. \subsection thirdpartyTensorFlow TensorFlow -\sc{TensorFlow} is a library designed for machine learning and deep learning. +\tensorflow is a library designed for machine learning and deep learning. -In \cgal, the C++ API of \sc{TensorFlow} is used by the \ref +In \cgal, the C++ API of \tensorflow is used by the \ref PkgClassification package for neural network. The C++ API can be compiled using CMake: it is distributed as part of the official package and is located in `tensorflow/contrib/cmake`. Be sure to @@ -266,20 +266,20 @@ enable and compile the following targets: - `tensorflow_BUILD_PYTHON_BINDINGS` - `tensorflow_BUILD_SHARED_LIB`. -In order to use \sc{TensorFlow} in \cgal programs, the executables +In order to use \tensorflow in \cgal programs, the executables should be linked with the CMake imported target `CGAL::TensorFlow_support` provided in `CGAL_TensorFlow_support.cmake`. -The \sc{TensorFlow} web site is `https://www.tensorflow.org/`. +The \tensorflow web site is `https://www.tensorflow.org/`. \subsection thirdpartyMETIS METIS Version 5.1 or later -\sc{METIS} is a library developed by the Karypis Lab +\metis is a library developed by the Karypis Lab and designed to partition graphs and produce fill-reducing matrix orderings. -\cgal offers wrappers around some of the methods of the \sc{METIS} library +\cgal offers wrappers around some of the methods of the \metis library to allow the partitioning of graphs that are models of the concepts of the Boost Graph Library, and, by extension, of surface meshes (see Section \ref BGLPartitioning of the package \ref PkgBGL). @@ -289,7 +289,7 @@ at `http://glaro \subsection thirdpartyzlib zlib -\sc{zlib} is a data compression library, and is essential for the component libCGAL_ImageIO. +\zlib is a data compression library, and is essential for the component libCGAL_ImageIO. In \cgal, this library is used in the examples of the \ref PkgSurfaceMesher3 package. @@ -298,9 +298,9 @@ for instance, on Windows, you can download it from `ceres-solver.org` @@ -308,26 +308,26 @@ for more information. \subsection thirdpartyGLPK GLPK -\sc{GLPK} (GNU Linear Programming Kit) is a library for solving linear programming (LP), mixed integer programming (MIP), and other related problems. +\glpk (GNU Linear Programming Kit) is a library for solving linear programming (LP), mixed integer programming (MIP), and other related problems. -In \cgal, \sc{GLPK} provides an optional linear integer program solver +In \cgal, \glpk provides an optional linear integer program solver in the \ref PkgPolygonalSurfaceReconstruction package. In order to use -\sc{GLPK} in \cgal programs, the executables should be linked with the +\glpk in \cgal programs, the executables should be linked with the CMake imported target `CGAL::GLPK_support` provided in `CGAL_GLPK_support.cmake`. -The \sc{GLPK} web site is `https://www.gnu.org/software/glpk/`. +The \glpk web site is `https://www.gnu.org/software/glpk/`. \subsection thirdpartySCIP SCIP -\sc{SCIP} (Solving Constraint Integer Programs) is currently one of the fastest open source solvers for mixed integer programming (MIP) and mixed integer nonlinear programming (MINLP). +\scip (Solving Constraint Integer Programs) is currently one of the fastest open source solvers for mixed integer programming (MIP) and mixed integer nonlinear programming (MINLP). -In \cgal, \sc{SCIP} provides an optional linear integer program solver +In \cgal, \scip provides an optional linear integer program solver in the \ref PkgPolygonalSurfaceReconstruction package. In order to use -\sc{SCIP} in \cgal programs, the executables should be linked with the +\scip in \cgal programs, the executables should be linked with the CMake imported target `CGAL::SCIP_support` provided in `CGAL_SCIP_support.cmake`. -The \sc{SCIP} web site is `http://scip.zib.de/`. +The \scip web site is `http://scip.zib.de/`. */ diff --git a/Documentation/doc/Documentation/Usage.txt b/Documentation/doc/Documentation/Usage.txt index eba087fdaa6..ae504aecf7c 100644 --- a/Documentation/doc/Documentation/Usage.txt +++ b/Documentation/doc/Documentation/Usage.txt @@ -83,9 +83,9 @@ contains the following subdirectories: | Directory | Contents | | :------------------------- | :----------| -| `auxiliary` (Windows only) | precompiled \sc{Gmp} and \sc{Mpfr} for Windows | +| `auxiliary` (Windows only) | precompiled \gmp and \mpfr for Windows | | `cmake/modules` | modules for finding and using libraries | -| `demo` | demo programs (most of them need \sc{Qt}, geomview or other third-party products) | +| `demo` | demo programs (most of them need \qt, geomview or other third-party products) | | `doc_html` | documentation (HTML) | | `examples` | example programs | | `include` | header files | @@ -94,13 +94,13 @@ contains the following subdirectories: The directories `include/CGAL/CORE` and `src/CGALCore` contain a distribution of the Core library version 1.7 for -dealing with algebraic numbers. Note that \sc{Core} is not part of \cgal and has its +dealing with algebraic numbers. Note that \core is not part of \cgal and has its own license. The directory `include/CGAL/OpenNL` contains a distribution of the Open Numerical Library, which provides solvers for sparse linear systems, especially designed for the Computer Graphics community. -\sc{OpenNL} is not part of \cgal and has its own license. +\opennl is not part of \cgal and has its own license. The only documentation shipped within \cgal sources is the present manual. The \cgal manual can also be accessed online at @@ -123,7 +123,7 @@ a standard location (such as `/usr/local/include`): For more advanced installations, we refer to Section \ref installation_configwithcmake. Note that even though \cgal is a header-only library, not all its dependencies -are header-only. The libraries \sc{Gmp} and \sc{Mpfr}, for example, are not +are header-only. The libraries \gmp and \mpfr, for example, are not header-only. As such, these dependencies must be built or installed independently. \section usage_configuring Configuring your Program @@ -235,7 +235,7 @@ The results of a successful configuration are build files that control the build The nature of the build files depends on the generator used during configuration, but in most cases they contain several targets, such as all the examples of the Triangulation_2 package. -In a \sc{Unix}-like environment the default generator produces makefiles. +In a \unix-like environment the default generator produces makefiles. You can use the `make` command-line tool for the succeeding build step as follows: cd CGAL-\cgalReleaseNumber/examples/Triangulation_2 diff --git a/Documentation/doc/Documentation/advanced/Configuration_variables.txt b/Documentation/doc/Documentation/advanced/Configuration_variables.txt index 2a880f1e488..191bb353d59 100644 --- a/Documentation/doc/Documentation/advanced/Configuration_variables.txt +++ b/Documentation/doc/Documentation/advanced/Configuration_variables.txt @@ -103,30 +103,30 @@ other but never both. \subsection installation_boost Boost Libraries -In most cases, if \sc{Boost} is not automatically found, setting the `BOOST_ROOT` +In most cases, if \boost is not automatically found, setting the `BOOST_ROOT` variable is enough. If it is not, you can specify the header and library directories individually. You can also provide the full pathname to a specific compiled library if it cannot be found in the library directory or its name is non-standard. -By default, when \sc{Boost} binary libraries are needed, the shared versions +By default, when \boost binary libraries are needed, the shared versions are used if present. You can set the variable `CGAL_Boost_USE_STATIC_LIBS` to `ON` if you want to link with static versions explicitly. -On Windows, if you link with \sc{Boost} shared libraries, you must ensure that +On Windows, if you link with \boost shared libraries, you must ensure that the `.dll` files are found by the dynamic linker, at run time. -For example, you can add the path to the \sc{Boost} `.dll` to the +For example, you can add the path to the \boost `.dll` to the `PATH` environment variable. | Variable | Description | Type | | :- | :- | :- | -| `BOOST_ROOT`\cgalFootnote{The environment variable can be spelled either `BOOST_ROOT` or `BOOSTROOT`} | Root directory of your \sc{Boost} installation | Either CMake or Environment | +| `BOOST_ROOT`\cgalFootnote{The environment variable can be spelled either `BOOST_ROOT` or `BOOSTROOT`} | Root directory of your \boost installation | Either CMake or Environment | | `Boost_INCLUDE_DIR` | Directory containing the `boost/version.hpp` file | CMake | | `BOOST_INCLUDEDIR` | Idem | Environment | -| `Boost_LIBRARY_DIRS` | Directory containing the compiled \sc{Boost} libraries | CMake | +| `Boost_LIBRARY_DIRS` | Directory containing the compiled \boost libraries | CMake | | `BOOST_LIBRARYDIR` | Idem | Environment | -| `Boost_(xyz)_LIBRARY_RELEASE` | Full pathname to a release build of the compiled 'xyz' \sc{Boost} library | CMake | -| `Boost_(xyz)_LIBRARY_DEBUG` | Full pathname to a debug build of the compiled 'xyz' \sc{Boost} library | CMake | +| `Boost_(xyz)_LIBRARY_RELEASE` | Full pathname to a release build of the compiled 'xyz' \boost library | CMake | +| `Boost_(xyz)_LIBRARY_DEBUG` | Full pathname to a debug build of the compiled 'xyz' \boost library | CMake | \subsection installation_gmp GMP and MPFR Libraries @@ -136,42 +136,42 @@ containing the libraries is needed and you would specify `GMP|MPFR_LIBRARY_DIR` `GMP|MPFR_LIBRARIES`. On the other hand, under Linux the actual library filename is needed. Thus you would specify `GMP|MPFR_LIBRARIES`. In no case you need to specify both. -\cgal uses both \sc{Gmp} and \sc{Mpfr} so both need to be supported. If either of them is unavailable the -usage of \sc{Gmp} and of \sc{Mpfr} will be disabled. +\cgal uses both \gmp and \mpfr so both need to be supported. If either of them is unavailable the +usage of \gmp and of \mpfr will be disabled. | Variable | Description | Type | | :- | :- | :- | -| `CGAL_DISABLE_GMP` | Indicates whether to search and use \sc{Gmp}/\sc{Mpfr} or not | CMake | -| `GMP_DIR` | Directory of \sc{Gmp} default installation | Environment | +| `CGAL_DISABLE_GMP` | Indicates whether to search and use \gmp/\mpfr or not | CMake | +| `GMP_DIR` | Directory of \gmp default installation | Environment | | `GMP_INCLUDE_DIR` | Directory containing the `gmp.h` file | CMake | | `GMP_INC_DIR` | Idem | Environment | -| `GMP_LIBRARIES_DIR` | Directory containing the compiled \sc{Gmp} library | CMake | +| `GMP_LIBRARIES_DIR` | Directory containing the compiled \gmp library | CMake | | `GMP_LIB_DIR` | Idem | Environment | -| `GMP_LIBRARIES` | Full pathname of the compiled \sc{Gmp} library | CMake | +| `GMP_LIBRARIES` | Full pathname of the compiled \gmp library | CMake | | `MPFR_INCLUDE_DIR` | Directory containing the `mpfr.h` file | CMake | | `MPFR_INC_DIR` | Idem | Environment | -| `MPFR_LIBRARIES_DIR` | Directory containing the compiled \sc{Mpfr} library | CMake | +| `MPFR_LIBRARIES_DIR` | Directory containing the compiled \mpfr library | CMake | | `MPFR_LIB_DIR` | Idem | Environment | -| `MPFR_LIBRARIES` | Full pathname of the compiled \sc{Mpfr} library | CMake | +| `MPFR_LIBRARIES` | Full pathname of the compiled \mpfr library | CMake | -Under Linux, the \sc{Gmpxx} is also searched for, and you may specify the following variables: +Under Linux, the \gmpxx is also searched for, and you may specify the following variables: | Variable | Description | Type | | :- | :- | :- | -| `GMPXX_DIR` | Directory of \sc{gmpxx} default installation | Environment | +| `GMPXX_DIR` | Directory of \gmpxx default installation | Environment | | `GMPXX_INCLUDE_DIR` | Directory containing the `gmpxx.h` file | CMake | -| `GMPXX_LIBRARIES` | Full pathname of the compiled \sc{Gmpxx} library | CMake | +| `GMPXX_LIBRARIES` | Full pathname of the compiled \gmpxx library | CMake | \subsection installation_qt5 Qt5 Library You must set the cmake or environment variable `Qt5_DIR` to point to the path -to the directory containing the file `Qt5Config.cmake` created by your \sc{Qt}5 installation. If you are +to the directory containing the file `Qt5Config.cmake` created by your \qt5 installation. If you are using the open source edition it should be `/qt-everywhere-opensource-src-/qtbase/lib/cmake/Qt5`. \subsection installation_leda LEDA Library @@ -188,7 +188,7 @@ The variables specifying definitions and flags can be left undefined if they are | Variable | Description | Type | | :- | :- | :- | | `WITH_LEDA` | Indicates whether to search and use \leda or not | CMake | -| `LEDA_DIR` | Directory of \sc{LEDA} default installation | Environment | +| `LEDA_DIR` | Directory of \leda default installation | Environment | | `LEDA_INCLUDE_DIR` | Directory containing the file `LEDA/system/basic.h` | CMake | | `LEDA_LIBRARIES` | Directory containing the compiled \leda libraries | CMake | | `LEDA_INC_DIR` | Directory containing the file `LEDA/system/basic.h` | Environment | @@ -203,21 +203,21 @@ The variables specifying definitions and flags can be left undefined if they are \subsection installation_mpfi MPFI Library \cgal provides a number type based on this library, but the \cgal library -itself does not depend on \sc{Mpfi}. This means that this library must be +itself does not depend on \mpfi. This means that this library must be configured when compiling an application that uses the above number type. -When \sc{Mpfi} files are not on the standard path, the locations of the headers +When \mpfi files are not on the standard path, the locations of the headers and library files must be specified by using environment variables. | Variable | Description | Type | | :- | :- | :- | -| `MPFI_DIR` |Directory of \sc{MPFI} default installation | Environment | +| `MPFI_DIR` |Directory of \mpfi default installation | Environment | | `MPFI_INCLUDE_DIR` | Directory containing the `mpfi.h` file | CMake | | `MPFI_INC_DIR` | Idem | Environment | -| `MPFI_LIBRARIES_DIR` | Directory containing the compiled \sc{Mpfi} library | CMake | +| `MPFI_LIBRARIES_DIR` | Directory containing the compiled \mpfi library | CMake | | `MPFI_LIB_DIR` | Idem | Environment | -| `MPFI_LIBRARIES` | Full pathname of the compiled \sc{Mpfi} library | CMake | +| `MPFI_LIBRARIES` | Full pathname of the compiled \mpfi library | CMake | @@ -231,55 +231,55 @@ CMake will try to find Rs in the standard header and library directories. When it is not automatically detected, the locations of the headers and library files must be specified using environment variables. -Rs needs \sc{Gmp} 4.2 or later and \sc{Mpfi} 1.3.4 or later. The variables +Rs needs \gmp 4.2 or later and \mpfi 1.3.4 or later. The variables related to the latter library may also need to be defined. | Variable | Description | Type | | :- | :- | :- | -| `RS_DIR` | Directory of \sc{Rs} default installation | Environment | +| `RS_DIR` | Directory of \rs default installation | Environment | | `RS_INCLUDE_DIR` | Directory containing the `rs_exports.h` file | CMake | | `RS_INC_DIR` | Idem | Environment | -| `RS_LIBRARIES_DIR` | Directory containing the compiled \sc{Rs} library | CMake | +| `RS_LIBRARIES_DIR` | Directory containing the compiled \rs library | CMake | | `RS_LIB_DIR` | Idem | Environment | -| `RS_LIBRARIES` | Full pathname of the compiled \sc{Rs} library | CMake | +| `RS_LIBRARIES` | Full pathname of the compiled \rs library | CMake | -Similar variables exist for \sc{Rs3}. +Similar variables exist for \rs3. | Variable | Description | Type | | :- | :- | :- -| `RS3_DIR` | Directory of \sc{Rs3} default installation | Environment | +| `RS3_DIR` | Directory of \rs3 default installation | Environment | | `RS3_INCLUDE_DIR` | Directory containing the file `rs3_fncts.h` file | CMake | | `RS3_INC_DIR` | Idem | Environment | -| `RS3_LIBRARIES_DIR` | Directory containing the compiled \sc{Rs3} library | CMake | +| `RS3_LIBRARIES_DIR` | Directory containing the compiled \rs3 library | CMake | | `RS3_LIB_DIR` | Idem | Environment | -| `RS3_LIBRARIES` | Full pathname of the compiled \sc{Rs3} library | CMake | +| `RS3_LIBRARIES` | Full pathname of the compiled \rs3 library | CMake | \subsection installation_ntl NTL Library Some polynomial computations in \cgal's algebraic kernel -are speed up when \sc{Ntl} is available. +are speed up when \ntl is available. As the algebraic kernel is not compiled as a part of the \cgal library, this library is not detected nor configured at installation time. -CMake will try to find \sc{Ntl} in the standard header and library +CMake will try to find \ntl in the standard header and library directories. When it is not automatically detected, the locations of the headers and library files must be specified using environment variables. | Variable | Description | Type | | :- | :- | :- | -| `NTL_DIR` | Directory of \sc{NTL} default installation | Environment | +| `NTL_DIR` | Directory of \ntl default installation | Environment | | `NTL_INCLUDE_DIR` | Directory containing the `NTL/ZZX.h` file | CMake | | `NTL_INC_DIR` | Idem | Environment | -| `NTL_LIBRARIES_DIR` | Directory containing the compiled \sc{Ntl} library | CMake | +| `NTL_LIBRARIES_DIR` | Directory containing the compiled \ntl library | CMake | | `NTL_LIB_DIR` | Idem | Environment | -| `NTL_LIBRARIES` | Full pathname of the compiled \sc{Ntl} library | CMake | +| `NTL_LIBRARIES` | Full pathname of the compiled \ntl library | CMake | \subsection installation_eigen Eigen Library -\sc{Eigen} is a header-only template library. -Only the directory containing the header files of \sc{Eigen} 3.1 (or greater) is needed. +\eigen is a header-only template library. +Only the directory containing the header files of \eigen 3.1 (or greater) is needed. | Variable | Description | Type | @@ -289,35 +289,35 @@ Only the directory containing the header files of \sc{Eigen} 3.1 (or grea \subsection installation_esbtl ESBTL Library -One skin surface example requires the \sc{Esbtl} library in order to read \sc{Pdb} files. +One skin surface example requires the \esbtl library in order to read \pdb files. -If \sc{Esbtl} is not automatically found, setting the `ESBTL_INC_DIR` +If \esbtl is not automatically found, setting the `ESBTL_INC_DIR` environment variable is sufficient. | Variable | Description | Type | | :- | :- | :- | -| `ESBTL_DIR` | Directory of \sc{ESBTL} default installation | Environment | +| `ESBTL_DIR` | Directory of \esbtl default installation | Environment | | `ESBTL_INC_DIR` | Directory containing the `ESBTL/default.h` file | Environment | | `ESBTL_INCLUDE_DIR` | Directory containing the `ESBTL/default.h` file | CMake | \subsection installation_metis METIS Library -Some BGL examples require the \sc{Metis} library in order to partition \sc{Metis} meshes. +Some BGL examples require the \metis library in order to partition \metis meshes. -If \sc{Metis} is not automatically found, setting the `METIS_INCLUDE_DIR` and `METIS_LIBRARY` +If \metis is not automatically found, setting the `METIS_INCLUDE_DIR` and `METIS_LIBRARY` cmake variables is necessary. | Variable | Description | Type | | :- | :- | :- | -| `METIS_INCLUDE_DIR` | Directory of \sc{Metis} default installation | CMAKE | +| `METIS_INCLUDE_DIR` | Directory of \metis default installation | CMAKE | | `METIS_LIBRARY` | Directory containing the `libmetis.so or .lib` file | CMAKE | \subsection installation_tbb TBB Library -If \sc{Tbb} is not automatically found, the user must set the `TBB_ROOT` +If \tbb is not automatically found, the user must set the `TBB_ROOT` environment variable. The environment variable `TBB_ARCH_PLATFORM=/` must be set. `` is `ia32` or `intel64`. `` describes the Linux kernel, gcc version or Visual Studio version used. It should be set to what is used in `$TBB_ROOT/lib/`. @@ -328,7 +328,7 @@ Note that the variables in the table below are being used. | Variable | Description | Type | | :- | :- | :- | -| `TBB_ROOT` | Directory of \sc{Tbb} default installation | Environment | +| `TBB_ROOT` | Directory of \tbb default installation | Environment | | `TBB_INCLUDE_DIRS` | Directory containing the `tbb/tbb.h` file | CMake | | `TBB_LIBRARY_DIRS` | Directory(ies) containing the compiled TBB libraries | CMake | | `TBB_LIBRARIES` | Full pathnames of the compiled TBB libraries (both release and debug versions, using "optimized" and "debug" CMake keywords). Note that if the debug versions are not found, the release versions will be used instead for the debug mode. | CMake | diff --git a/Documentation/doc/Documentation/advanced/Installation.txt b/Documentation/doc/Documentation/advanced/Installation.txt index 314ead765e1..e5dd13a0e80 100644 --- a/Documentation/doc/Documentation/advanced/Installation.txt +++ b/Documentation/doc/Documentation/advanced/Installation.txt @@ -60,10 +60,10 @@ Note that some libraries have specific dependencies in addition to the essential | Library | CMake Variable | Functionality | Dependencies | | :-------- | :------------- | :------------ | :----------- | -| `%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 | +| `%CGAL` | none | Main library | \gmp, \mpfr, \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 \core library distributed by \cgal for the user convenience and it has it's own license.} | \gmp and \mpfr | +| `CGAL_ImageIO` | `WITH_CGAL_ImageIO` | Utilities to read and write image files | \zlib, \vtk (optional) | +| `CGAL_Qt5` | `WITH_CGAL_Qt5` | `QGraphicsView` support for \qt5-based demos | \qt5 | Shared libraries, also called dynamic-link libraries, are built by default (`.so` on Linux, `.dylib` on macOS). You @@ -77,7 +77,7 @@ the \cgal libraries, unless you set the variables `WITH_examples=ON` and/or `WIT Additionally, even when configured with \cgal, they are not automatically built along with the libraries. You must build the `examples` or `demos` targets (or IDE projects) explicitly. -If you do not plan to compile any demos, you may skip some of the dependencies (such as \sc{Qt}), +If you do not plan to compile any demos, you may skip some of the dependencies (such as \qt), as the corresponding \cgal-libraries will not be used. Note, however, that your own demos might need these \cgal-libraries and thus their dependencies. See the page \ref secessential3rdpartysoftware for more information. @@ -215,7 +215,7 @@ The nature of the build files depends on the generator used during configuration contain several targets, one per library, and a default global target corresponding to all the libraries. -For example, in a \sc{Unix}-like environment the default generator produces makefiles. +For example, in a \unix-like environment the default generator produces makefiles. You can use the `make` command-line tool for the succeeding build step as follows: # build all the selected libraries at once @@ -277,7 +277,7 @@ the installation simply amounts to: \cgalAdvancedBegin The files are copied into a directory tree relative to the installation directory determined by the -CMake variable `CMAKE_INSTALL_PREFIX`. This variable defaults to `/usr/local` under \sc{Unix}-like operating systems. +CMake variable `CMAKE_INSTALL_PREFIX`. This variable defaults to `/usr/local` under \unix-like operating systems. If you want to install to a different location, you must override that CMake variable explicitly at the configuration time and not when executing the install step. \cgalAdvancedEnd diff --git a/Documentation/doc/Documentation/manual.txt b/Documentation/doc/Documentation/manual.txt index 38bc7bb37ee..060c0686bd4 100644 --- a/Documentation/doc/Documentation/manual.txt +++ b/Documentation/doc/Documentation/manual.txt @@ -11,7 +11,7 @@ of computational geometry. Each part consists of several chapters, and each chapter is split into a *User Manual* and a *Reference Manual*. The User Manual gives the general idea and comes with examples. -The Reference Manual presents the \sc{Api} of the various classes +The Reference Manual presents the \api of the various classes and functions. The manual has a \ref packages with a short paragraph explaining diff --git a/Documentation/doc/Documentation/windows.txt b/Documentation/doc/Documentation/windows.txt index 77021a27a28..c8e7484552a 100644 --- a/Documentation/doc/Documentation/windows.txt +++ b/Documentation/doc/Documentation/windows.txt @@ -2,8 +2,8 @@ \page windows Using %CGAL on Windows (with Visual C++) \cgalAutoToc -\cgal \cgalReleaseNumber is supported for the following \sc{MS} Visual `C++` compilers: -14.0, 15.9, 16.0 (\sc{Visual Studio} 2015, 2017, and 2019). +\cgal \cgalReleaseNumber is supported for the following \ms Visual `C++` compilers: +14.0, 15.9, 16.0 (\visualstudio 2015, 2017, and 2019). \cgal is a library that has mandatory dependencies that must be first installed: \ref thirdpartyBoost and \ref thirdpartyMPFR. diff --git a/Documentation/doc/resources/1.8.13/BaseDoxyfile.in b/Documentation/doc/resources/1.8.13/BaseDoxyfile.in index 85d7742a660..93ef2198d79 100644 --- a/Documentation/doc/resources/1.8.13/BaseDoxyfile.in +++ b/Documentation/doc/resources/1.8.13/BaseDoxyfile.in @@ -228,19 +228,53 @@ TAB_SIZE = 4 # "Side Effects:". You can put \n's in the value part of an alias to insert # newlines. -ALIASES = "sc{1}=\1" \ - "cgal=\sc{%CGAL}" \ - "protocgal=\sc{C++gal}" \ - "plageo=\sc{Plageo}" \ - "stl=\sc{STL}" \ - "gmp=\sc{GMP}" \ - "mpir=\sc{MPIR}" \ - "mpfr=\sc{MPFR}" \ - "leda=\sc{LEDA}" \ - "gcc=\sc{GCC}" \ - "cpp=\sc{C++}" \ - "cpp11=\sc{C++11}" \ - "CC=\sc{C++}" \ +ALIASES = "cgal=CGAL" \ + "protocgal=C++gal" \ + "plageo=Plageo" \ + "stl=STL" \ + "gmp=GMP" \ + "gmpxx=GMPXX" \ + "mpir=MPIR" \ + "mpfr=MPFR" \ + "leda=LEDA" \ + "gcc=GCC" \ + "dcel=DCEL" \ + "bgl=BGL" \ + "boost=Boost" \ + "gnu=GNU" \ + "ms=MS" \ + "qt=Qt" \ + "qt5=Qt5" \ + "eigen=Eigen" \ + "opengr=OpenGR" \ + "libpointmatcher=libpointmatcher" \ + "core=Core" \ + "mpfi=MPFI" \ + "ntl=NTL" \ + "pdb=PDB" \ + "esbtl=ESBTL" \ + "tbb=TBB" \ + "laslib=LASlib" \ + "opencv=OpenCV" \ + "tensorflow=TensorFlow" \ + "metis=METIS" \ + "zlib=zlib" \ + "ceres=Ceres" \ + "glpk=GLPK" \ + "scip=SCIP" \ + "rs=RS" \ + "rs3=RS3" \ + "unix=Unix" \ + "api=API" \ + "vtk=VTK" \ + "visualstudio=Visual Studio" \ + "taucs=TAUCS" \ + "lapack=LAPACK" \ + "blas=BLAS" \ + "opennl=OpenNL" \ + "cpp=C++" \ + "cpp11=C++11" \ + "CC=C++" \ "cgalExample{1}=
    File \ref \1 \include \1" \ "cgalFigureAnchor{1}=\anchor fig__\1" \ "cgalFigureRef{1}=\ref fig__\1" \ @@ -950,7 +984,7 @@ EXCLUDE_SYMBOLS = Tr \ Fb \ K \ Traits \ - internal + internal # The EXAMPLE_PATH tag can be used to specify one or more files or directories # that contain example code fragments that are included (see the \include diff --git a/Documentation/doc/resources/1.8.14/BaseDoxyfile.in b/Documentation/doc/resources/1.8.14/BaseDoxyfile.in index aad98822d2f..faca6fc348e 100644 --- a/Documentation/doc/resources/1.8.14/BaseDoxyfile.in +++ b/Documentation/doc/resources/1.8.14/BaseDoxyfile.in @@ -229,19 +229,53 @@ TAB_SIZE = 4 # newlines (in the resulting output). You can put ^^ in the value part of an # alias to insert a newline as if a physical newline was in the original file. -ALIASES = "sc{1}=\1" \ - "cgal=\sc{%CGAL}" \ - "protocgal=\sc{C++gal}" \ - "plageo=\sc{Plageo}" \ - "stl=\sc{STL}" \ - "gmp=\sc{GMP}" \ - "mpir=\sc{MPIR}" \ - "mpfr=\sc{MPFR}" \ - "leda=\sc{LEDA}" \ - "gcc=\sc{GCC}" \ - "cpp=\sc{C++}" \ - "cpp11=\sc{C++11}" \ - "CC=\sc{C++}" \ +ALIASES = "cgal=CGAL" \ + "protocgal=C++gal" \ + "plageo=Plageo" \ + "stl=STL" \ + "gmp=GMP" \ + "gmpxx=GMPXX" \ + "mpir=MPIR" \ + "mpfr=MPFR" \ + "leda=LEDA" \ + "gcc=GCC" \ + "dcel=DCEL" \ + "bgl=BGL" \ + "boost=Boost" \ + "gnu=GNU" \ + "ms=MS" \ + "qt=Qt" \ + "qt5=Qt5" \ + "eigen=Eigen" \ + "opengr=OpenGR" \ + "libpointmatcher=libpointmatcher" \ + "core=Core" \ + "mpfi=MPFI" \ + "ntl=NTL" \ + "pdb=PDB" \ + "esbtl=ESBTL" \ + "tbb=TBB" \ + "laslib=LASlib" \ + "opencv=OpenCV" \ + "tensorflow=TensorFlow" \ + "metis=METIS" \ + "zlib=zlib" \ + "ceres=Ceres" \ + "glpk=GLPK" \ + "scip=SCIP" \ + "rs=RS" \ + "rs3=RS3" \ + "unix=Unix" \ + "api=API" \ + "vtk=VTK" \ + "visualstudio=Visual Studio" \ + "taucs=TAUCS" \ + "lapack=LAPACK" \ + "blas=BLAS" \ + "opennl=OpenNL" \ + "cpp=C++" \ + "cpp11=C++11" \ + "CC=C++" \ "cgalExample{1}=
    File \ref \1 \include \1" \ "cgalFigureAnchor{1}=\anchor fig__\1" \ "cgalFigureRef{1}=\ref fig__\1" \ @@ -941,7 +975,7 @@ EXCLUDE_SYMBOLS = Tr \ Fb \ K \ Traits \ - internal + internal # The EXAMPLE_PATH tag can be used to specify one or more files or directories # that contain example code fragments that are included (see the \include diff --git a/Documentation/doc/resources/1.8.20/BaseDoxyfile.in b/Documentation/doc/resources/1.8.20/BaseDoxyfile.in index e7cce2eb165..93dad8c7100 100644 --- a/Documentation/doc/resources/1.8.20/BaseDoxyfile.in +++ b/Documentation/doc/resources/1.8.20/BaseDoxyfile.in @@ -259,19 +259,53 @@ TAB_SIZE = 4 # commands \{ and \} for these it is advised to use the version @{ and @} or use # a double escape (\\{ and \\}) -ALIASES = "sc{1}=\1" \ - "cgal=\sc{%CGAL}" \ - "protocgal=\sc{C++gal}" \ - "plageo=\sc{Plageo}" \ - "stl=\sc{STL}" \ - "gmp=\sc{GMP}" \ - "mpir=\sc{MPIR}" \ - "mpfr=\sc{MPFR}" \ - "leda=\sc{LEDA}" \ - "gcc=\sc{GCC}" \ - "cpp=\sc{C++}" \ - "cpp11=\sc{C++11}" \ - "CC=\sc{C++}" \ +ALIASES = "cgal=CGAL" \ + "protocgal=C++gal" \ + "plageo=Plageo" \ + "stl=STL" \ + "gmp=GMP" \ + "gmpxx=GMPXX" \ + "mpir=MPIR" \ + "mpfr=MPFR" \ + "leda=LEDA" \ + "gcc=GCC" \ + "dcel=DCEL" \ + "bgl=BGL" \ + "boost=Boost" \ + "gnu=GNU" \ + "ms=MS" \ + "qt=Qt" \ + "qt5=Qt5" \ + "eigen=Eigen" \ + "opengr=OpenGR" \ + "libpointmatcher=libpointmatcher" \ + "core=Core" \ + "mpfi=MPFI" \ + "ntl=NTL" \ + "pdb=PDB" \ + "esbtl=ESBTL" \ + "tbb=TBB" \ + "laslib=LASlib" \ + "opencv=OpenCV" \ + "tensorflow=TensorFlow" \ + "metis=METIS" \ + "zlib=zlib" \ + "ceres=Ceres" \ + "glpk=GLPK" \ + "scip=SCIP" \ + "rs=RS" \ + "rs3=RS3" \ + "unix=Unix" \ + "api=API" \ + "vtk=VTK" \ + "visualstudio=Visual Studio" \ + "taucs=TAUCS" \ + "lapack=LAPACK" \ + "blas=BLAS" \ + "opennl=OpenNL" \ + "cpp=C++" \ + "cpp11=C++11" \ + "CC=C++" \ "cgalExample{1}=
    File \ref \1 \include \1" \ "cgalFigureAnchor{1}=\anchor fig__\1" \ "cgalFigureRef{1}=\ref fig__\1" \ @@ -1006,7 +1040,7 @@ EXCLUDE_SYMBOLS = Tr \ Fb \ K \ Traits \ - internal + internal # The EXAMPLE_PATH tag can be used to specify one or more files or directories # that contain example code fragments that are included (see the \include diff --git a/Envelope_3/doc/Envelope_3/Envelope_3.txt b/Envelope_3/doc/Envelope_3/Envelope_3.txt index 3d994446e0e..d6a614d5e80 100644 --- a/Envelope_3/doc/Envelope_3/Envelope_3.txt +++ b/Envelope_3/doc/Envelope_3/Envelope_3.txt @@ -58,7 +58,7 @@ both these diagrams as envelope diagrams. It is easy to see that an envelope diagram is no more than a planar arrangement (see Chapter \ref chapterArrangement_on_surface_2 "2D Arrangements"), represented -using an extended \sc{Dcel} structure, such that every \sc{Dcel} +using an extended \dcel structure, such that every \dcel record (namely each face, halfedge and vertex) stores an additional container of it originators: the \f$ xy\f$-monotone surfaces that induce this feature. diff --git a/GraphicsView/doc/GraphicsView/PackageDescription.txt b/GraphicsView/doc/GraphicsView/PackageDescription.txt index a6597c649e5..3c32ad7863c 100644 --- a/GraphicsView/doc/GraphicsView/PackageDescription.txt +++ b/GraphicsView/doc/GraphicsView/PackageDescription.txt @@ -18,7 +18,7 @@ \cgalPkgSummaryEnd \cgalPkgShortInfoBegin \cgalPkgSince{3.4} -\cgalPkgDependsOn{\sc{Qt} 5} +\cgalPkgDependsOn{\qt 5} \cgalPkgBib{cgal:fr-cqgvf} \cgalPkgLicense{\ref licensesGPL "GPL"} \cgalPkgShortInfoEnd diff --git a/Number_types/doc/Number_types/CGAL/Gmpfr.h b/Number_types/doc/Number_types/CGAL/Gmpfr.h index e3785df15f2..ae7ce118966 100644 --- a/Number_types/doc/Number_types/CGAL/Gmpfr.h +++ b/Number_types/doc/Number_types/CGAL/Gmpfr.h @@ -189,7 +189,7 @@ static std::float_round_style set_default_rndmode(std::float_round_style r); /*! \name Flags -\sc{Mpfr} provides some flags to know whether +\mpfr provides some flags to know whether performed operations were exact or not, or they incurred in overflow or underflow, if the exponent is out of range, or the result was `NaN` (not-a-number). One can clear the flags before a set of operations and diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_filtered_traits_2.h b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_filtered_traits_2.h index 214ca7577bc..ba380ea3d64 100644 --- a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_filtered_traits_2.h +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_filtered_traits_2.h @@ -50,7 +50,7 @@ The default values for the template parameters are as follows:
  • `EM = Field_tag`,
  • `FK = Simple_cartesian >`,
  • `FM = Field_with_sqrt_tag`. -
  • If the \sc{Gmp} package is installed with \cgal, the template parameter `EK` has the default value: `EK = Simple_cartesian`, otherwise its default value is `EK = Simple_cartesian >`. +
  • If the \gmp package is installed with \cgal, the template parameter `EK` has the default value: `EK = Simple_cartesian`, otherwise its default value is `EK = Simple_cartesian >`. \cgalModels `SegmentDelaunayGraphTraits_2` @@ -205,7 +205,7 @@ will be the entry for the template parameter `CK`),
  • `EM = CGAL::Euclidean_ring_tag`,
  • `FK = CGAL::Simple_cartesian >`,
  • `FM = CGAL::Field_with_sqrt_tag`. -
  • If the \sc{Gmp} package is +
  • If the \gmp package is installed with \cgal, the template parameter `EK` has the default value: `EK = CGAL::Simple_cartesian`, otherwise its default value is diff --git a/Solver_interface/doc/Solver_interface/Solver_interface.txt b/Solver_interface/doc/Solver_interface/Solver_interface.txt index 587442df349..e5fded45ffa 100644 --- a/Solver_interface/doc/Solver_interface/Solver_interface.txt +++ b/Solver_interface/doc/Solver_interface/Solver_interface.txt @@ -118,7 +118,7 @@ This package is the result of the increasing needs for linear solvers in \cgal. The first packages that introduced the solver concepts were \ref PkgSurfaceMeshParameterization, \ref PkgPoissonSurfaceReconstruction3 and \ref PkgJetFitting3. At that time, these packages were relying -on \sc{Taucs}, \sc{LAPACK}, \sc{BLAS} and \sc{OpenNL}. Gaël Guennebaud +on \taucs, \lapack, \blas and \opennl. Gaël Guennebaud then introduced new models using the \ref thirdpartyEigen library that became the only supported models by \cgal. Later on the packages \ref PkgSurfaceMeshSkeletonization and \ref PkgSurfaceMeshDeformation From d71057ce96724f7a12a3c8404613bdd190b5023a Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Fri, 5 Feb 2021 12:25:27 +0000 Subject: [PATCH 115/248] Test if there is something on the optional --- .../Iso_cuboid_3_Plane_3_intersection.h | 82 ++++++++++--------- 1 file changed, 45 insertions(+), 37 deletions(-) diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h index 977c7dcc584..50562e06dfa 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h @@ -97,11 +97,11 @@ intersection( case 1: { //adj to an edge - if(points.size() == 4) + if(points.size() == 4) // plane outside of cub and just touching at the edge, and hence the endpoints of 4 other edges { return result_type(std::forward(segments.front())); } - //plane intersecting through an edge (not 2) + //plane intersecting through an edge (not 2) This then intersects 2 other edges in points else { Poly res(4); @@ -251,43 +251,51 @@ intersection( CGAL::Plane_3 >::result_type Pl_pl_type; std::vector plane_intersections; - Pl_pl_type pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(0), - cub.vertex(1), - cub.vertex(5))); - if(const Line_3* line = boost::get(&*pl_inter)){ - plane_intersections.push_back(*line); - } - pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(0), - cub.vertex(3), - cub.vertex(4))); - if(const Line_3* line = boost::get(&*pl_inter)){ - plane_intersections.push_back(*line); - } - pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(0), - cub.vertex(1), - cub.vertex(3))); - if(const Line_3* line = boost::get(&*pl_inter)){ - plane_intersections.push_back(*line); - } - pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(7), - cub.vertex(6), - cub.vertex(1))); - if(const Line_3* line = boost::get(&*pl_inter)){ - plane_intersections.push_back(*line); - } - pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(7), - cub.vertex(4), - cub.vertex(3))); - if(const Line_3* line = boost::get(&*pl_inter)){ - plane_intersections.push_back(*line); - } - pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(7), - cub.vertex(6), - cub.vertex(4))); - if(const Line_3* line = boost::get(&*pl_inter)){ - plane_intersections.push_back(*line); + Pl_pl_type pl_inter; + + if(pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(0), + cub.vertex(1), + cub.vertex(5)))){ + if(const Line_3* line = boost::get(&*pl_inter)){ + plane_intersections.push_back(*line); + } } + if (pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(0), + cub.vertex(3), + cub.vertex(4)))){ + if(const Line_3* line = boost::get(&*pl_inter)){ + plane_intersections.push_back(*line); + } + } + if (pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(0), + cub.vertex(1), + cub.vertex(3)))){ + if(const Line_3* line = boost::get(&*pl_inter)){ + plane_intersections.push_back(*line); + } + } + if (pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(7), + cub.vertex(6), + cub.vertex(1)))){ + if(const Line_3* line = boost::get(&*pl_inter)){ + plane_intersections.push_back(*line); + } + } + if (pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(7), + cub.vertex(4), + cub.vertex(3)))){ + if(const Line_3* line = boost::get(&*pl_inter)){ + plane_intersections.push_back(*line); + } + } + if (pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(7), + cub.vertex(6), + cub.vertex(4)))){ + if(const Line_3* line = boost::get(&*pl_inter)){ + plane_intersections.push_back(*line); + } + } std::list tmp_segs; for(const auto& line : plane_intersections) { From 0f556c05b63de6a1045f34b7fc462a2ad3545983 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Mon, 8 Feb 2021 09:53:14 +0100 Subject: [PATCH 116/248] Fix compatibility of Poisson with Simple_cartesian --- .../include/CGAL/poisson_surface_reconstruction.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Poisson_surface_reconstruction_3/include/CGAL/poisson_surface_reconstruction.h b/Poisson_surface_reconstruction_3/include/CGAL/poisson_surface_reconstruction.h index dddb6759fe7..c6f852ad469 100644 --- a/Poisson_surface_reconstruction_3/include/CGAL/poisson_surface_reconstruction.h +++ b/Poisson_surface_reconstruction_3/include/CGAL/poisson_surface_reconstruction.h @@ -96,7 +96,7 @@ namespace CGAL { typedef typename Kernel::Sphere_3 Sphere; typedef CGAL::Poisson_reconstruction_function Poisson_reconstruction_function; - typedef CGAL::Surface_mesh_default_triangulation_3 STr; + typedef typename CGAL::Surface_mesher::Surface_mesh_default_triangulation_3_generator::Type STr; typedef CGAL::Surface_mesh_complex_2_in_triangulation_3 C2t3; typedef CGAL::Implicit_surface_3 Surface_3; From 848aa7d8ab40dcf9f04098f60eaa225bac460308 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Mon, 8 Feb 2021 10:16:59 +0100 Subject: [PATCH 117/248] Fix compatibility of Poisson with Simple_cartesian --- Number_types/include/CGAL/NT_converter.h | 22 +++++++++++++++++++ .../include/CGAL/compute_average_spacing.h | 2 +- .../CGAL/Poisson_mesh_cell_criteria_3.h | 9 ++++---- .../CGAL/Poisson_reconstruction_function.h | 11 +++++----- .../CGAL/poisson_surface_reconstruction.h | 7 +++--- 5 files changed, 38 insertions(+), 13 deletions(-) diff --git a/Number_types/include/CGAL/NT_converter.h b/Number_types/include/CGAL/NT_converter.h index 1d7c4a8d639..ac225f1e0cb 100644 --- a/Number_types/include/CGAL/NT_converter.h +++ b/Number_types/include/CGAL/NT_converter.h @@ -61,6 +61,17 @@ struct NT_converter < NT1, double > } }; +template < class NT1 > +struct NT_converter < NT1, float > + : public CGAL::cpp98::unary_function< NT1, float > +{ + float + operator()(const NT1 &a) const + { + return static_cast(to_double(a)); + } +}; + template <> struct NT_converter < double, double > : public CGAL::cpp98::unary_function< double, double > @@ -72,6 +83,17 @@ struct NT_converter < double, double > } }; +template <> +struct NT_converter < float, float > + : public CGAL::cpp98::unary_function< float, float > +{ + const float & + operator()(const float &a) const + { + return a; + } +}; + template < class NT1, bool b > struct NT_converter < NT1, Interval_nt > : public CGAL::cpp98::unary_function< NT1, Interval_nt > diff --git a/Point_set_processing_3/include/CGAL/compute_average_spacing.h b/Point_set_processing_3/include/CGAL/compute_average_spacing.h index bb66e4b5ef9..fe6840810be 100644 --- a/Point_set_processing_3/include/CGAL/compute_average_spacing.h +++ b/Point_set_processing_3/include/CGAL/compute_average_spacing.h @@ -81,7 +81,7 @@ compute_average_spacing(const typename NeighborQuery::Kernel::Point_3& query, // boost::make_function_output_iterator ([&](const Point& p) { - sum_distances += std::sqrt(CGAL::squared_distance (query,p)); + sum_distances += CGAL::approximate_sqrt(CGAL::squared_distance (query,p)); ++ i; })); diff --git a/Poisson_surface_reconstruction_3/include/CGAL/Poisson_mesh_cell_criteria_3.h b/Poisson_surface_reconstruction_3/include/CGAL/Poisson_mesh_cell_criteria_3.h index 74d507927ea..4c78d772ce5 100644 --- a/Poisson_surface_reconstruction_3/include/CGAL/Poisson_mesh_cell_criteria_3.h +++ b/Poisson_surface_reconstruction_3/include/CGAL/Poisson_mesh_cell_criteria_3.h @@ -27,15 +27,16 @@ namespace Poisson { template class Constant_sizing_field { - double sq_radius_bound; + typedef typename Tr::FT FT; + FT sq_radius_bound; public: - double cell_radius_bound() const { return CGAL::sqrt(sq_radius_bound); } + FT cell_radius_bound() const { return CGAL::approximate_sqrt(sq_radius_bound); } - Constant_sizing_field(double sq_radius_bound = 0.) + Constant_sizing_field(FT sq_radius_bound = 0.) : sq_radius_bound(sq_radius_bound) {} template - double operator()(const Point&) const { return sq_radius_bound; } + FT operator()(const Point&) const { return sq_radius_bound; } }; // end class Constant_sizing_field } // end namespace Poisson diff --git a/Poisson_surface_reconstruction_3/include/CGAL/Poisson_reconstruction_function.h b/Poisson_surface_reconstruction_3/include/CGAL/Poisson_reconstruction_function.h index 80e3a9d10ff..7fb5c3e68f3 100644 --- a/Poisson_surface_reconstruction_3/include/CGAL/Poisson_reconstruction_function.h +++ b/Poisson_surface_reconstruction_3/include/CGAL/Poisson_reconstruction_function.h @@ -110,18 +110,19 @@ struct Poisson_visitor { // The wrapper stores only pointers to the two functors. template struct Special_wrapper_of_two_functions_keep_pointers { + typedef typename F2::FT FT; F1 *f1; F2 *f2; Special_wrapper_of_two_functions_keep_pointers(F1* f1, F2* f2) : f1(f1), f2(f2) {} template - double operator()(const X& x) const { + FT operator()(const X& x) const { return (std::max)((*f1)(x), CGAL::square((*f2)(x))); } template - double operator()(const X& x) { + FT operator()(const X& x) { return (std::max)((*f1)(x), CGAL::square((*f2)(x))); } }; // end struct Special_wrapper_of_two_functions_keep_pointers @@ -211,7 +212,7 @@ private: { private: std::atomic m_state; - std::array m_bary; + std::array m_bary; public: Cached_bary_coord() : m_state (UNINITIALIZED) { } @@ -242,8 +243,8 @@ private: void set_initialized() { m_state = INITIALIZED; } - const double& operator[] (const std::size_t& idx) const { return m_bary[idx]; } - double& operator[] (const std::size_t& idx) { return m_bary[idx]; } + const FT& operator[] (const std::size_t& idx) const { return m_bary[idx]; } + FT& operator[] (const std::size_t& idx) { return m_bary[idx]; } }; // Wrapper for thread safety of maintained cell hint for fast diff --git a/Poisson_surface_reconstruction_3/include/CGAL/poisson_surface_reconstruction.h b/Poisson_surface_reconstruction_3/include/CGAL/poisson_surface_reconstruction.h index c6f852ad469..3a79d458803 100644 --- a/Poisson_surface_reconstruction_3/include/CGAL/poisson_surface_reconstruction.h +++ b/Poisson_surface_reconstruction_3/include/CGAL/poisson_surface_reconstruction.h @@ -94,6 +94,7 @@ namespace CGAL { typedef typename boost::property_traits::value_type Point; typedef typename Kernel_traits::Kernel Kernel; typedef typename Kernel::Sphere_3 Sphere; + typedef typename Kernel::FT FT; typedef CGAL::Poisson_reconstruction_function Poisson_reconstruction_function; typedef typename CGAL::Surface_mesher::Surface_mesh_default_triangulation_3_generator::Type STr; @@ -106,10 +107,10 @@ namespace CGAL { Point inner_point = function.get_inner_point(); Sphere bsphere = function.bounding_sphere(); - double radius = std::sqrt(bsphere.squared_radius()); + FT radius = CGAL::approximate_sqrt(bsphere.squared_radius()); - double sm_sphere_radius = 5.0 * radius; - double sm_dichotomy_error = sm_distance * spacing / 1000.0; + FT sm_sphere_radius = 5.0 * radius; + FT sm_dichotomy_error = sm_distance * spacing / 1000.0; Surface_3 surface(function, Sphere (inner_point, sm_sphere_radius * sm_sphere_radius), From 564e4a1d9f72eb147ab1810ee333769ef758abfb Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Mon, 8 Feb 2021 10:24:40 +0100 Subject: [PATCH 118/248] Fix --- .../include/CGAL/Rigid_triangle_mesh_collision_detection.h | 1 - 1 file changed, 1 deletion(-) diff --git a/Polygon_mesh_processing/include/CGAL/Rigid_triangle_mesh_collision_detection.h b/Polygon_mesh_processing/include/CGAL/Rigid_triangle_mesh_collision_detection.h index 9ef6d87f8ef..c93f3338999 100644 --- a/Polygon_mesh_processing/include/CGAL/Rigid_triangle_mesh_collision_detection.h +++ b/Polygon_mesh_processing/include/CGAL/Rigid_triangle_mesh_collision_detection.h @@ -178,7 +178,6 @@ public: //! move constructor Rigid_triangle_mesh_collision_detection(Rigid_triangle_mesh_collision_detection&& other) - : { *this = std::move(other); } From 99751661bed8b57b4df97adfaf66933942c08da2 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Mon, 8 Feb 2021 11:21:10 +0100 Subject: [PATCH 119/248] Another try for aos2 --- .../cgal_test_with_cmake | 377 +++++++++--------- 1 file changed, 189 insertions(+), 188 deletions(-) diff --git a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/cgal_test_with_cmake b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/cgal_test_with_cmake index befa82faa0a..7c96355065a 100755 --- a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/cgal_test_with_cmake +++ b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/cgal_test_with_cmake @@ -128,38 +128,39 @@ TRIM=35 configure() { echo "Configuring... " - if [ -f "$INIT_FILE" ] - then - if eval 'cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} "$CMAKE_GENERATOR" -DRUNNING_CGAL_AUTO_TEST=TRUE \ - -DCGAL_DIR="$CGAL_DIR" \ - -DCGAL_CXX_FLAGS:STRING="$CGAL_CXX_FLAGS $TESTSUITE_CXXFLAGS -I../../include" \ - -DCGAL_EXE_LINKER_FLAGS="$CGAL_EXE_LINKER_FLAGS $TESTSUITE_LDFLAGS" \ - .' ; then + rm -rf CMakeCache.txt CMakeFiles/ - echo " successful configuration" >> $ERRORFILE - else - echo " ERROR: configuration" >> $ERRORFILE - fi +if [ -f "$INIT_FILE" ] +then + if eval 'cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} "$CMAKE_GENERATOR" -DRUNNING_CGAL_AUTO_TEST=TRUE \ + -DCGAL_DIR="$CGAL_DIR" \ + -DCGAL_CXX_FLAGS:STRING="$CGAL_CXX_FLAGS $TESTSUITE_CXXFLAGS -I../../include" \ + -DCGAL_EXE_LINKER_FLAGS="$CGAL_EXE_LINKER_FLAGS $TESTSUITE_LDFLAGS" \ + .' ; then + + echo " successful configuration" >> $ERRORFILE else - rm -rf CMakeCache.txt CMakeFiles/ - echo "cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} "$CMAKE_GENERATOR" -DRUNNING_CGAL_AUTO_TEST=TRUE \ + echo " ERROR: configuration" >> $ERRORFILE + fi +else + echo "cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} "$CMAKE_GENERATOR" -DRUNNING_CGAL_AUTO_TEST=TRUE \ -DCGAL_DIR=\"$CGAL_DIR\" \ -DCGAL_CXX_FLAGS:STRING=\"$TESTSUITE_CXXFLAGS -I../../include\" \ -DCGAL_EXE_LINKER_FLAGS=\"$TESTSUITE_LDFLAGS\" \ -DCMAKE_BUILD_TYPE=NOTFOUND \ - . " - if eval 'cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} "$CMAKE_GENERATOR" -DRUNNING_CGAL_AUTO_TEST=TRUE \ - -DCGAL_DIR="$CGAL_DIR" \ - -DCGAL_CXX_FLAGS:STRING="$TESTSUITE_CXXFLAGS -I../../include" \ - -DCGAL_EXE_LINKER_FLAGS="$TESTSUITE_LDFLAGS" \ - -DCMAKE_BUILD_TYPE=NOTFOUND \ - .' ; then + ." + if eval 'cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} "$CMAKE_GENERATOR" -DRUNNING_CGAL_AUTO_TEST=TRUE \ + -DCGAL_DIR="$CGAL_DIR" \ + -DCGAL_CXX_FLAGS:STRING="$TESTSUITE_CXXFLAGS -I../../include" \ + -DCGAL_EXE_LINKER_FLAGS="$TESTSUITE_LDFLAGS" \ + -DCMAKE_BUILD_TYPE=NOTFOUND \ + .' ; then - echo " successful configuration" >> $ERRORFILE - else - echo " ERROR: configuration" >> $ERRORFILE - fi + echo " successful configuration" >> $ERRORFILE + else + echo " ERROR: configuration" >> $ERRORFILE fi +fi } compile_test_with_flags() @@ -412,77 +413,77 @@ execute_commands_old_structure() commands_indicator[CONSTRUCTOR]=1 i=1 if [ $# -gt 2 ] ; then - for arg in $* ; do - if [ $i -gt 2 ] ; then - commands_indicator[$arg]=0 - fi - let "i+=1" - done + for arg in $* ; do + if [ $i -gt 2 ] ; then + commands_indicator[$arg]=0 + fi + let "i+=1" + done fi if [ ${commands_indicator[$COMPARE]} -ne 0 ] ; then - run_trapped_test test_traits \ - data/compare.pt data/empty.zero \ - data/empty.zero data/compare $2 + run_trapped_test test_traits \ + data/compare.pt data/empty.zero \ + data/empty.zero data/compare $2 fi if [ ${commands_indicator[$VERTEX]} -ne 0 ] ; then - run_trapped_test test_traits \ - data/$1/vertex.pt data/$1/vertex.xcv \ - data/empty.zero data/$1/vertex $2 + run_trapped_test test_traits \ + data/$1/vertex.pt data/$1/vertex.xcv \ + data/empty.zero data/$1/vertex $2 fi if [ ${commands_indicator[$IS_VERTICAL]} -ne 0 ] ; then - run_trapped_test test_traits \ - data/empty.zero data/$1/is_vertical.xcv data/empty.zero \ - data/$1/is_vertical $2 + run_trapped_test test_traits \ + data/empty.zero data/$1/is_vertical.xcv data/empty.zero \ + data/$1/is_vertical $2 fi if [ ${commands_indicator[$COMPARE_Y_AT_X]} -ne 0 ] ; then - run_trapped_test test_traits \ - data/$1/compare_y_at_x.pt data/$1/compare_y_at_x.xcv \ - data/empty.zero data/$1/compare_y_at_x $2 + run_trapped_test test_traits \ + data/$1/compare_y_at_x.pt data/$1/compare_y_at_x.xcv \ + data/empty.zero data/$1/compare_y_at_x $2 fi if [ ${commands_indicator[$COMPARE_Y_AT_X_LEFT]} -ne 0 ] ; then - run_trapped_test test_traits \ - data/$1/compare_y_at_x_left.pt data/$1/compare_y_at_x_left.xcv \ - data/empty.zero data/$1/compare_y_at_x_left $2 + run_trapped_test test_traits \ + data/$1/compare_y_at_x_left.pt data/$1/compare_y_at_x_left.xcv \ + data/empty.zero data/$1/compare_y_at_x_left $2 fi if [ ${commands_indicator[$COMPARE_Y_AT_X_RIGHT]} -ne 0 ] ; then - run_trapped_test test_traits \ - data/$1/compare_y_at_x_right.pt data/$1/compare_y_at_x_right.xcv \ - data/empty.zero data/$1/compare_y_at_x_right $2 + run_trapped_test test_traits \ + data/$1/compare_y_at_x_right.pt data/$1/compare_y_at_x_right.xcv \ + data/empty.zero data/$1/compare_y_at_x_right $2 fi if [ ${commands_indicator[$MAKE_X_MONOTONE]} -ne 0 ] ; then - run_trapped_test test_traits \ - data/empty.zero data/$1/make_x_monotone.xcv \ - data/$1/make_x_monotone.cv data/$1/make_x_monotone $2 + run_trapped_test test_traits \ + data/empty.zero data/$1/make_x_monotone.xcv \ + data/$1/make_x_monotone.cv data/$1/make_x_monotone $2 fi if [ ${commands_indicator[$INTERSECT]} -ne 0 ] ; then - run_trapped_test test_traits \ - data/$1/intersect.pt data/$1/intersect.xcv \ - data/empty.zero data/$1/intersect $2 + run_trapped_test test_traits \ + data/$1/intersect.pt data/$1/intersect.xcv \ + data/empty.zero data/$1/intersect $2 fi if [ ${commands_indicator[$SPLIT]} -ne 0 ] ; then - run_trapped_test test_traits \ - data/$1/split.pt data/$1/split.xcv \ - data/empty.zero data/$1/split $2 + run_trapped_test test_traits \ + data/$1/split.pt data/$1/split.xcv \ + data/empty.zero data/$1/split $2 fi if [ ${commands_indicator[$ARE_MERGEABLE]} -ne 0 ] ; then - run_trapped_test test_traits \ - data/empty.zero data/$1/are_mergeable.xcv \ - data/empty.zero data/$1/are_mergeable $2 + run_trapped_test test_traits \ + data/empty.zero data/$1/are_mergeable.xcv \ + data/empty.zero data/$1/are_mergeable $2 fi if [ ${commands_indicator[$MERGE]} -ne 0 ] ; then - run_trapped_test test_traits \ - data/empty.zero data/$1/merge.xcv \ - data/empty.zero data/$1/merge $2 + run_trapped_test test_traits \ + data/empty.zero data/$1/merge.xcv \ + data/empty.zero data/$1/merge $2 fi if [ ${commands_indicator[$ASSERTIONS]} -ne 0 ] ; then - run_trapped_test test_traits \ - data/$1/assertions.pt data/$1/assertions.xcv \ - data/empty.zero data/$1/assertions $2 + run_trapped_test test_traits \ + data/$1/assertions.pt data/$1/assertions.xcv \ + data/empty.zero data/$1/assertions $2 fi if [ ${commands_indicator[$CONSTRUCTOR]} -ne 0 ] ; then - run_trapped_test test_traits \ - data/empty.zero data/$1/constructor.xcv \ - data/$1/constructor.cv data/$1/constructor $2 + run_trapped_test test_traits \ + data/empty.zero data/$1/constructor.xcv \ + data/$1/constructor.cv data/$1/constructor $2 fi } @@ -525,120 +526,120 @@ execute_commands_new_structure() commands_indicator[TRIM]=0 i=1 if [ $# -gt 2 ] ; then - for arg in $* ; do - if [ $i -gt 2 ] ; then - commands_indicator[$arg]=1 - fi - let "i+=1" - done + for arg in $* ; do + if [ $i -gt 2 ] ; then + commands_indicator[$arg]=1 + fi + let "i+=1" + done fi if [ ${commands_indicator[$COMPARE]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/compare $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/compare $2 fi if [ ${commands_indicator[$VERTEX]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/vertex $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/vertex $2 fi if [ ${commands_indicator[$IS_VERTICAL]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/is_vertical $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/is_vertical $2 fi if [ ${commands_indicator[$COMPARE_X_AT_LIMIT]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/compare_x_at_limit $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/compare_x_at_limit $2 fi if [ ${commands_indicator[$COMPARE_X_NEAR_LIMIT]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/compare_x_near_limit $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/compare_x_near_limit $2 fi if [ ${commands_indicator[$COMPARE_X_ON_BOUNDARY]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/compare_x_on_boundary $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/compare_x_on_boundary $2 fi if [ ${commands_indicator[$COMPARE_X_NEAR_BOUNDARY]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/compare_x_near_boundary $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/compare_x_near_boundary $2 fi if [ ${commands_indicator[$COMPARE_Y_NEAR_BOUNDARY]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/compare_y_near_boundary $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/compare_y_near_boundary $2 fi if [ ${commands_indicator[$PARAMETER_SPACE_X]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/parameter_space_x $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/parameter_space_x $2 fi if [ ${commands_indicator[$PARAMETER_SPACE_Y]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/parameter_space_y $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/parameter_space_y $2 fi if [ ${commands_indicator[$COMPARE_Y_AT_X]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/compare_y_at_x $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/compare_y_at_x $2 fi if [ ${commands_indicator[$COMPARE_Y_AT_X_LEFT]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/compare_y_at_x_left $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/compare_y_at_x_left $2 fi if [ ${commands_indicator[$COMPARE_Y_AT_X_RIGHT]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/compare_y_at_x_right $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/compare_y_at_x_right $2 fi if [ ${commands_indicator[$MAKE_X_MONOTONE]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/make_x_monotone $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/make_x_monotone $2 fi if [ ${commands_indicator[$INTERSECT]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/intersect $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/intersect $2 fi if [ ${commands_indicator[$SPLIT]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/split $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/split $2 fi if [ ${commands_indicator[$ARE_MERGEABLE]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/are_mergeable $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/are_mergeable $2 fi if [ ${commands_indicator[$MERGE]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/merge $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/merge $2 fi if [ ${commands_indicator[$ASSERTIONS]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/assertions $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/assertions $2 fi if [ ${commands_indicator[$CONSTRUCTOR]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/constructor $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/constructor $2 fi if [ ${commands_indicator[$EQUAL]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/equal $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/equal $2 fi if [ ${commands_indicator[$PUSH_BACK]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/push_back $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/push_back $2 fi if [ ${commands_indicator[$PUSH_FRONT]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/push_front $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/push_front $2 fi if [ ${commands_indicator[$NUMBER_OF_POINTS]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/number_of_points $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/number_of_points $2 fi if [ ${commands_indicator[$COMPARE_ENDPOINTS_XY]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/compare_endpoints_xy $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/compare_endpoints_xy $2 fi if [ ${commands_indicator[$CONSTRUCT_OPPOSITE]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/construct_opposite $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/construct_opposite $2 fi if [ ${commands_indicator[$TRIM]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/trim $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/trim $2 fi } @@ -668,100 +669,100 @@ execute_commands_traits_adaptor() i=1 if [ $# -gt 2 ] ; then - for arg in $* ; do - if [ $i -gt 2 ] ; then - commands_indicator[$arg]=1 - fi - let "i+=1" - done + for arg in $* ; do + if [ $i -gt 2 ] ; then + commands_indicator[$arg]=1 + fi + let "i+=1" + done fi if [ ${commands_indicator[$PARAMETER_SPACE_X]} -ne 0 ] ; then - run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ - data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ - data/test_adaptor/$1/parameter_space_x $2 + run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ + data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ + data/test_adaptor/$1/parameter_space_x $2 fi if [ ${commands_indicator[$PARAMETER_SPACE_Y]} -ne 0 ] ; then - run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ - data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ - data/test_adaptor/$1/parameter_space_y $2 + run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ + data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ + data/test_adaptor/$1/parameter_space_y $2 fi if [ ${commands_indicator[$COMPARE_X_AT_LIMIT]} -ne 0 ] ; then - run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ - data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ - data/test_adaptor/$1/compare_x_at_limit $2 + run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ + data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ + data/test_adaptor/$1/compare_x_at_limit $2 fi if [ ${commands_indicator[$COMPARE_X_NEAR_LIMIT]} -ne 0 ] ; then - run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ - data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ - data/test_adaptor/$1/compare_x_near_limit $2 + run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ + data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ + data/test_adaptor/$1/compare_x_near_limit $2 fi if [ ${commands_indicator[$COMPARE_X_ON_BOUNDARY]} -ne 0 ] ; then - run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ - data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ - data/test_adaptor/$1/compare_x_on_boundary $2 + run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ + data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ + data/test_adaptor/$1/compare_x_on_boundary $2 fi if [ ${commands_indicator[$COMPARE_X_NEAR_BOUNDARY]} -ne 0 ] ; then - run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ - data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ - data/test_adaptor/$1/compare_x_near_boundary $2 + run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ + data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ + data/test_adaptor/$1/compare_x_near_boundary $2 fi if [ ${commands_indicator[$COMPARE_Y_NEAR_BOUNDARY]} -ne 0 ] ; then - run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ - data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ - data/test_adaptor/$1/compare_y_near_boundary $2 + run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ + data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ + data/test_adaptor/$1/compare_y_near_boundary $2 fi if [ ${commands_indicator[$COMPARE_Y_AT_X_LEFT]} -ne 0 ] ; then - run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ - data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ - data/test_adaptor/$1/compare_y_at_x_left $2 + run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ + data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ + data/test_adaptor/$1/compare_y_at_x_left $2 fi if [ ${commands_indicator[$ARE_MERGEABLE]} -ne 0 ] ; then - run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ - data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ - data/test_adaptor/$1/are_mergeable $2 + run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ + data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ + data/test_adaptor/$1/are_mergeable $2 fi if [ ${commands_indicator[$MERGE]} -ne 0 ] ; then - run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ - data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ - data/test_adaptor/$1/merge $2 + run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ + data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ + data/test_adaptor/$1/merge $2 fi if [ ${commands_indicator[X_ON_IDENTIFICATION]} -ne 0 ] ; then - run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ - data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ - data/test_adaptor/$1/x_on_idintification $2 + run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ + data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ + data/test_adaptor/$1/x_on_idintification $2 fi if [ ${commands_indicator[Y_ON_IDENTIFICATION]} -ne 0 ] ; then - run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ - data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ - data/test_adaptor/$1/x_on_idintification $2 + run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ + data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ + data/test_adaptor/$1/x_on_idintification $2 fi if [ ${commands_indicator[IS_BOUNDED]} -ne 0 ] ; then - run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ - data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ - data/test_adaptor/$1/is_bounded $2 + run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ + data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ + data/test_adaptor/$1/is_bounded $2 fi if [ ${commands_indicator[IS_IN_X_RANGE]} -ne 0 ] ; then - run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ - data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ - data/test_adaptor/$1/is_in_x_range $2 + run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ + data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ + data/test_adaptor/$1/is_in_x_range $2 fi if [ ${commands_indicator[COMPARE_Y_POSITION]} -ne 0 ] ; then - run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ - data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ - data/test_adaptor/$1/compare_y_position $2 + run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ + data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ + data/test_adaptor/$1/compare_y_position $2 fi if [ ${commands_indicator[IS_BETWEEN_CW]} -ne 0 ] ; then - run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ - data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ - data/test_adaptor/$1/is_between_cw $2 + run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ + data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ + data/test_adaptor/$1/is_between_cw $2 fi if [ ${commands_indicator[COMPARE_CW_AROUND_POINT]} -ne 0 ] ; then - run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ - data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ - data/test_adaptor/$1/compare_cw_around_point $2 + run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ + data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ + data/test_adaptor/$1/compare_cw_around_point $2 fi } @@ -1670,8 +1671,8 @@ touch $ERRORFILE if [ $# -ne 0 ] ; then case $1 in - -cmake) TEST_WITH_CMAKE="TRUE" ;; - *)TEST_WITH_CMAKE="FALSE" ;; + -cmake) TEST_WITH_CMAKE="TRUE" ;; + *)TEST_WITH_CMAKE="FALSE" ;; esac else TEST_WITH_CMAKE="FALSE" From f55d586d9d0b93b8c15b18e57647b0cecb0efc5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 8 Feb 2021 15:50:48 +0100 Subject: [PATCH 120/248] Re-introduce some kind of zipping as a first step to boundary cycle stitching Zipping was removed when local stitching was introduced, and a common interface between stitching-within-a-cycle and normal-stitching was introduced. However, that common interface does not handle any non-manifold configuration, even if it's a folded cycle with obvious stitching (consecutive equal edges). So, some kind of zipping is re-added. It is cheap anyway (compared to e.g. calling PMP::connected_components on the whole mesh). --- .../Polygon_mesh_processing/stitch_borders.h | 181 +++++++++++++++++- 1 file changed, 174 insertions(+), 7 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/stitch_borders.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/stitch_borders.h index 4387c52030b..10b3949d45c 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/stitch_borders.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/stitch_borders.h @@ -787,8 +787,8 @@ template & to_stitch, const CandidateHalfedgeRange& representative_candidates, PolygonMesh& pmesh, - MaintainerVisitor& mv, - const VertexPointMap& vpm) + const VertexPointMap& vpm, + MaintainerVisitor& mv) { typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; @@ -832,7 +832,7 @@ std::size_t stitch_halfedge_range(const std::vector& to_stitch, const VertexPointMap& vpm) { Dummy_cycle_rep_maintainer mv(pmesh); - return stitch_halfedge_range(to_stitch, halfedges(pmesh), pmesh, mv, vpm); + return stitch_halfedge_range(to_stitch, halfedges(pmesh), pmesh, vpm, mv); } //overload to avoid a useless copy @@ -855,6 +855,169 @@ std::size_t stitch_halfedge_range_dispatcher(const HalfedgePairRange& to_stitch_ return stitch_halfedge_range(to_stitch, pmesh, vpm); } +// collect_duplicated_stitchable_boundary_edges() cannot handle any configuration with non-manifoldness. +// However, even if non-manifoldness exists within a loop, it is safe choice to stitch consecutive +// stitchable halfedges +template +std::size_t zip_boundary_cycle(const typename boost::graph_traits::halfedge_descriptor h, + const HalfedgeRange& cycle_halfedges, + PolygonMesh& pmesh, + const VPM vpm, + const HalfedgeKeeper& hd_kpr, + MaintainerVisitor& mv) +{ + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + + std::size_t stitched_boundary_cycles_n = 0; + + // A boundary cycle might need to be stitched starting from different extremities + // + // v11 ------ v10 + // | | + // v0 --- v1(v13) === v2(v12) v5(v9) === v6(v8) --- v7 + // | | + // v3 ------- v4 + // + // As long as we find vertices on the boundary with both incident halfedges being compatible, + // we zip it up as much as possible. + + // not everything is always stitchable + std::set unstitchable_halfedges; + + const halfedge_descriptor null_h = boost::graph_traits::null_halfedge(); + halfedge_descriptor bh = h; + for(;;) // until there is nothing to stitch anymore + { + if(bh == null_h) // the complete boundary cycle is stitched + break; + +#ifdef CGAL_PMP_STITCHING_DEBUG + std::cout << "Walking border from halfedge: " << edge(bh, pmesh) << std::endl; +#endif + + CGAL_assertion(is_border(bh, pmesh)); + + halfedge_descriptor hn = next(bh, pmesh), start_h = null_h; + do + { + halfedge_descriptor hnn = next(hn, pmesh); + CGAL_assertion(get(vpm, target(hn, pmesh)) == get(vpm, source(hnn, pmesh))); + + if(get(vpm, source(hn, pmesh)) == get(vpm, target(hnn, pmesh)) && + !is_degenerate_edge(edge(hn, pmesh), pmesh, parameters::vertex_point_map(vpm))) + { + if(unstitchable_halfedges.count(hn) == 0) + { + start_h = hn; + break; + } + } + + hn = hnn; + } + while(hn != bh); + + if(start_h == null_h) // nothing to be stitched on this boundary cycle + break; + +#ifdef CGAL_PMP_STITCHING_DEBUG_PP + std::cout << "Starting stitching from halfedge: " + << get(vpm, source(edge(start_h, pmesh), pmesh)) << " " + << get(vpm, target(edge(start_h, pmesh), pmesh)) << std::endl; +#endif + + CGAL_assertion(is_border(start_h, pmesh)); + + // Associate as many consecutive halfedge pairs as possible ("zipping") + std::vector > hedges_to_stitch; + + halfedge_descriptor curr_h = start_h; + halfedge_descriptor curr_hn = next(curr_h, pmesh); + for(;;) // while we can expand the zipping range + { + // Don't create an invalid polygon mesh, even if the geometry allows it + if(face(opposite(curr_h, pmesh), pmesh) == face(opposite(curr_hn, pmesh), pmesh)) + { + unstitchable_halfedges.insert(curr_h); + bh = curr_hn; + break; + } + + CGAL_assertion(is_border(curr_h, pmesh)); + CGAL_assertion(is_border(curr_hn, pmesh)); + + if(hd_kpr(curr_h, curr_hn) == curr_h) + hedges_to_stitch.emplace_back(curr_h, curr_hn); + else + hedges_to_stitch.emplace_back(curr_hn, curr_h); + +#ifdef CGAL_PMP_STITCHING_DEBUG_PP + std::cout << "expand zip with:\n" + << edge(curr_h, pmesh) << "\n\t" << source(curr_h, pmesh) << "\t(" << get(vpm, source(curr_h, pmesh)) << ")" + << "\n\t" << target(curr_h, pmesh) << "\t(" << get(vpm, target(curr_h, pmesh)) << ")\n" + << edge(curr_hn, pmesh) << "\n\t" << source(curr_hn, pmesh) << "\t(" << get(vpm, source(curr_hn, pmesh)) << ")" + << "\n\t" << target(curr_hn, pmesh) << "\t(" << get(vpm, target(curr_hn, pmesh)) << ")" << std::endl; +#endif + + // check if we have reached the end of the boundary cycle + if(prev(curr_h, pmesh) == curr_hn || prev(curr_h, pmesh) == next(curr_hn, pmesh)) + { + bh = null_h; + break; + } + + curr_h = prev(curr_h, pmesh); + curr_hn = next(curr_hn, pmesh); + + // check if the next two halfedges are not geometrically compatible + if(get(vpm, source(curr_h, pmesh)) != get(vpm, target(curr_hn, pmesh)) || + is_degenerate_edge(edge(curr_hn, pmesh), pmesh, parameters::vertex_point_map(vpm))) + { + bh = curr_hn; + break; + } + } + + // bh must be a boundary halfedge on the border that will not be impacted by any stitching + CGAL_assertion_code(if(bh != null_h) {) + CGAL_assertion_code( for(const auto& hp : hedges_to_stitch) {) + CGAL_assertion( bh != hp.first && bh != hp.second); + CGAL_assertion_code(}}) + + if(!hedges_to_stitch.empty()) + { +#ifdef CGAL_PMP_STITCHING_DEBUG_PP + std::cout << hedges_to_stitch.size() " halfedge pairs to stitch on border containing:\n" + << edge(h, pmesh) << "\n\t" << source(h, pmesh) << "\t(" << get(vpm, source(h, pmesh)) << ")" + << "\n\t" << target(h, pmesh) << "\t(" << get(vpm, target(h, pmesh)) << ")" << std::endl; +#endif + + mv.remove_representative(bh); + + std::size_t local_stitches = internal::stitch_halfedge_range(hedges_to_stitch, cycle_halfedges, pmesh, vpm, mv); + stitched_boundary_cycles_n += local_stitches; + + if(local_stitches == 0) // refused to stitch this halfedge pair range due to manifold issue + { +#ifdef CGAL_PMP_STITCHING_DEBUG_PP + std::cout << "Failed to stitch this range!" << std::endl; +#endif + + for(const auto& hp : hedges_to_stitch) + { + unstitchable_halfedges.insert(hp.first); + unstitchable_halfedges.insert(hp.second); + } + } + } + } + + return stitched_boundary_cycles_n; +} /// High-level functions @@ -888,6 +1051,8 @@ std::size_t stitch_boundary_cycle(const typename boost::graph_traits to_stitch; internal::collect_duplicated_stitchable_boundary_edges(cycle_halfedges, pmesh, hd_kpr, false /*per cc*/, @@ -895,7 +1060,9 @@ std::size_t stitch_boundary_cycle(const typename boost::graph_traits::%vertex_descriptor` /// as key type and `%Point_3` as value type} -/// \cgalParamDefault{`boost::get(CGAL::vertex_point, pm)`} +/// \cgalParamDefault{`boost::get(CGAL::vertex_point, pmesh)`} /// \cgalParamExtra{If this parameter is omitted, an internal property map for `CGAL::vertex_point_t` /// must be available in `PolygonMesh`.} /// \cgalParamNEnd @@ -988,7 +1155,7 @@ std::size_t stitch_boundary_cycles(const BorderHalfedgeRange& boundary_cycle_rep /// \cgalParamDescription{a property map associating points to the vertices of `pm`} /// \cgalParamType{a class model of `ReadWritePropertyMap` with `boost::graph_traits::%vertex_descriptor` /// as key type and `%Point_3` as value type} -/// \cgalParamDefault{`boost::get(CGAL::vertex_point, pm)`} +/// \cgalParamDefault{`boost::get(CGAL::vertex_point, pmesh)`} /// \cgalParamExtra{If this parameter is omitted, an internal property map for `CGAL::vertex_point_t` /// must be available in `PolygonMesh`.} /// \cgalParamNEnd @@ -1147,7 +1314,7 @@ std::size_t stitch_borders(const BorderHalfedgeRange& boundary_cycle_representat internal::collect_duplicated_stitchable_boundary_edges(to_consider, pmesh, hd_kpr, per_cc, std::back_inserter(to_stitch), np); - res += stitch_halfedge_range(to_stitch, to_consider, pmesh, mv, vpm); + res += stitch_halfedge_range(to_stitch, to_consider, pmesh, vpm, mv); const auto& new_representatives = mv.cycle_representatives(); From 1b01b67c86b8a42a51aa82b085441c4fd04a5093 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 8 Feb 2021 15:54:52 +0100 Subject: [PATCH 121/248] Added a test for zipping-based boundary cycle stitching --- .../data_stitching/folded_cycle.off | 59 +++++++++++++++++++ .../test_stitching.cpp | 5 +- 2 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 Polygon_mesh_processing/test/Polygon_mesh_processing/data_stitching/folded_cycle.off diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/data_stitching/folded_cycle.off b/Polygon_mesh_processing/test/Polygon_mesh_processing/data_stitching/folded_cycle.off new file mode 100644 index 00000000000..f2a40878de9 --- /dev/null +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/data_stitching/folded_cycle.off @@ -0,0 +1,59 @@ +# Output of a CGAL tool +#CBP +# polyhedral_surface 0 +# halfedges 0 +# triangulated 0 +# non_empty_facets 0 +# terrain 0 +# normalized_to_sphere 0 +# radius 0 +# rounded 0 +# rounded_bits 0 +# ENDCBP + +NOFF +16 16 0 + +# 16 vertices +# ------------------------------------------ + + +-21.8983 -6.38823 63.7562 0.521628 -0.428916 0.73752 +-21.9152 -6.40483 63.7541 0.42945 -0.529738 0.731403 +-21.9057 -6.32693 63.7553 0.99181 0.00120314 0.127719 +-21.8832 -6.80033 63.7582 0.126127 6.70899e-05 -0.992014 +-21.9216 -6.40893 63.551 0.67402 -0.738711 -0.00201436 +-21.9075 -6.25023 63.7552 -0.995002 -0.0234773 -0.0970594 +-21.8983 -6.38823 63.7562 0.117647 -0.000135467 -0.993055 +-21.9021 -6.75613 63.7558 0.117647 -0.000135467 -0.993055 +-21.9057 -6.32693 63.7553 -0.0977085 -0.99516 -0.010509 +-21.8752 -6.32923 63.7592 -0.126943 -0.00144678 0.991909 +-21.9611 -6.89043 63.7501 0.0910592 0.000407086 -0.995845 +-21.9418 -6.23043 63.7515 -0.109893 -0.00197042 0.993942 +-21.927 -6.32803 63.7529 -0.111856 -0.00218345 0.993722 +-21.9001 -6.39073 63.5534 0.765209 -0.643781 0.00114436 +-21.8874 -6.29763 63.7577 0.341741 -0.938826 0.0426494 +-21.882 -6.36043 63.7583 0.551822 -0.379642 0.742539 + +# 16 facets +# ------------------------------------------ + +3 0 4 13 +3 15 0 13 +3 8 10 5 +3 8 1 0 +3 6 2 14 +3 9 14 2 +3 6 7 10 +3 1 4 0 +3 7 6 14 +3 1 8 12 +3 0 15 2 +3 15 9 2 +3 5 11 8 +3 3 7 14 +3 6 10 8 +3 8 11 12 + + +# End of OFF # diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_stitching.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_stitching.cpp index 7ae4b674f9a..7fd2d5d820e 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_stitching.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_stitching.cpp @@ -73,6 +73,7 @@ void test_stitch_boundary_cycles() test_stitch_boundary_cycles("data_stitching/boundary_cycle.off", 4); test_stitch_boundary_cycles("data_stitching/boundary_cycle_2.off", 2); test_stitch_boundary_cycles("data_stitching/complex_hole.off", 3); + test_stitch_boundary_cycles("data_stitching/folded_cycle.off", 2); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -119,9 +120,9 @@ void test_stitch_borders(const char* fname, typedef PMP::internal::Halfedges_keeper_with_marked_edge_priority Keeper; Marked_edges marks = get(Edge_property_tag(), mesh); - int id = 0; + int eid = 0; for(edge_descriptor e : edges(mesh)) - put(marks, e, (unconstrained_edge_ids.count(id++) == 0)); + put(marks, e, (unconstrained_edge_ids.count(eid++) == 0)); Keeper kpr(marks, mesh); From 21cda32aef14a14d9b34d1bd3546131859398efa Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Tue, 9 Feb 2021 09:27:02 +0100 Subject: [PATCH 122/248] Simplify `value_type` and change `reference` --- Kernel_d/include/CGAL/Kernel_d/Iso_box_d.h | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/Kernel_d/include/CGAL/Kernel_d/Iso_box_d.h b/Kernel_d/include/CGAL/Kernel_d/Iso_box_d.h index 3964fa2ada7..402ef35b8f5 100644 --- a/Kernel_d/include/CGAL/Kernel_d/Iso_box_d.h +++ b/Kernel_d/include/CGAL/Kernel_d/Iso_box_d.h @@ -42,15 +42,11 @@ namespace CGAL { typedef typename Point::Cartesian_const_iterator Iterator; typedef Cartesian_iterator Self; - - typedef typename std::iterator_traits::value_type - Coordinate_type; - - typedef decltype( - std::declval()(std::declval(), - std::declval())) value_type; - typedef value_type& reference; - typedef value_type* pointer; + typedef decltype(std::declval()( + *std::declval(), + *std::declval())) value_type; + typedef value_type reference; + typedef const value_type* pointer; typedef std::ptrdiff_t difference_type; typedef std::input_iterator_tag iterator_category; @@ -96,7 +92,7 @@ namespace CGAL { return tmp; } - value_type operator*() const { return f(*pb, *qb); } + reference operator*() const { return f(*pb, *qb); } pointer operator->() const { return &(**this); } const Functor& functor() const { return f; } From ab5517e1acb494cba28496a07437be9a7af2a39d Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Tue, 9 Feb 2021 09:27:30 +0100 Subject: [PATCH 123/248] Apply the same for Homogeneous_iterator --- Kernel_d/include/CGAL/Kernel_d/Iso_box_d.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Kernel_d/include/CGAL/Kernel_d/Iso_box_d.h b/Kernel_d/include/CGAL/Kernel_d/Iso_box_d.h index 402ef35b8f5..12ff9aeb723 100644 --- a/Kernel_d/include/CGAL/Kernel_d/Iso_box_d.h +++ b/Kernel_d/include/CGAL/Kernel_d/Iso_box_d.h @@ -121,9 +121,12 @@ namespace CGAL { typedef typename Point::Homogeneous_const_iterator Iterator; typedef Homogeneous_iterator Self; - typedef typename Functor::result_type value_type; - typedef value_type& reference; - typedef value_type* pointer; + typedef typename Kernel_traits::Kernel::RT RT; + typedef decltype(std::declval()( + *std::declval() * std::declval(), + *std::declval() * std::declval())) value_type; + typedef value_type reference; + typedef const value_type* pointer; typedef std::ptrdiff_t difference_type; typedef std::input_iterator_tag iterator_category; @@ -131,7 +134,6 @@ namespace CGAL { Iterator pb, qb; Functor f; - typedef typename Kernel_traits::Kernel::RT RT; RT hp, hq; // homogenizing coordinates public: @@ -280,7 +282,7 @@ namespace CGAL { RT volume_nominator() const { - typedef typename CIRT::template Iterator >::type + typedef typename CIRT::template Iterator >::type Iter; Iter b(ptr()->upper, ptr()->lower, Begin()); Iter e(ptr()->upper, ptr()->lower, Cartesian_end()); From 7161686c46989f7624b0019072489a0ee0bcfc48 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Tue, 9 Feb 2021 10:04:53 +0100 Subject: [PATCH 124/248] fix !git into ! git --- .github/workflows/delete_doc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/delete_doc.yml b/.github/workflows/delete_doc.yml index 1304a7895c9..d648a601e91 100644 --- a/.github/workflows/delete_doc.yml +++ b/.github/workflows/delete_doc.yml @@ -26,7 +26,7 @@ jobs: git rm -r ${PR_NUMBER} fi #git diff exits with 1 if there is a diff - if !git diff --quiet; then + if ! git diff --quiet; then git commit -a --amend -m"base commit" && git push -f -u origin master fi From 6d438a0f945b311f30764dd64510716f2cf4522e Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 9 Feb 2021 15:48:03 +0000 Subject: [PATCH 125/248] WIP --- .../Iso_cuboid_3_Plane_3_intersection.h | 432 ++++++------------ .../test/Intersections_3/issue_5428.cpp | 40 ++ 2 files changed, 186 insertions(+), 286 deletions(-) create mode 100644 Intersections_3/test/Intersections_3/issue_5428.cpp diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h index 50562e06dfa..69e0b6198b9 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -27,319 +28,178 @@ namespace CGAL { namespace Intersections { namespace internal { -template -void filter_points(std::vector& input, - std::vector& output) +template +int +inter_pt_index(int i, int j, + const Plane_3& plane, + std::vector& points, + std::map, int>& id_map) { - std::sort(input.begin(), input.end()); - auto last = std::unique(input.begin(), input.end()); - input.erase(last, input.end()); - output = std::move(input); + std::pair, int>::iterator, bool> res = + id_map.insert(std::make_pair(make_sorted_pair(i, j), + static_cast (points.size()))); + if (res.second) + points.push_back(typename Geom_traits::Construct_plane_line_intersection_point_3() + (plane, points[i], points[j])); + + return res.first->second; } -//Tetrahedron_3 Line_3 +//Iso_cuboid_3 Plane_3 template typename Intersection_traits::result_type intersection( - const typename K::Iso_cuboid_3 &cub, - const typename K::Plane_3 &pl, - const K& k) + const typename K::Iso_cuboid_3& cub, + const typename K::Plane_3& plane, + const K& k) { typedef typename K::Point_3 Point_3; - typedef typename K::Segment_3 Segment_3; - typedef typename K::Line_3 Line_3; - typedef typename K::Plane_3 Plane_3; typedef std::vector Poly; + typedef typename Intersection_traits::result_type result_type; - typedef typename Intersection_traits, - CGAL::Plane_3 >::result_type result_type; + std::vector corners(8); + corners.reserve(14); // 8 corners + up to 6 polygon points + corners[0] = cub[0]; + corners[1] = cub[3]; + corners[2] = cub[2]; + corners[3] = cub[1]; + corners[4] = cub[5]; + corners[5] = cub[4]; + corners[6] = cub[7]; + corners[7] = cub[6]; - typedef typename Intersection_traits, - CGAL::Plane_3 >::result_type Inter_type; + std::array orientations = { { + plane.oriented_side(corners[0]), + plane.oriented_side(corners[1]), + plane.oriented_side(corners[2]), + plane.oriented_side(corners[3]), + plane.oriented_side(corners[4]), + plane.oriented_side(corners[5]), + plane.oriented_side(corners[6]), + plane.oriented_side(corners[7]) + } }; - std::vector edges; - edges.reserve(12); + // description of faces of the bbox + std::array face_indices = + { { 0, 1, 2, 3, + 2, 1, 5, 6, + 3, 2, 6, 7, + 1, 0, 4, 5, + 4, 0, 3, 7, + 6, 5, 4, 7 } }; - //get all edges of cub - for(int i=0; i< 4; ++i) - edges.emplace_back(cub.vertex(i), cub.vertex((i+1)%4)); - for(int i=0; i < 4; ++i) - edges.emplace_back(cub.vertex(i+4), cub.vertex((i+1)%4+4)); - for(int i=0; i < 4; ++i) - edges.emplace_back(cub.vertex(i), cub.vertex((i+1)%4+4)); + std::map, int> id_map; + bool all_in = true; + bool all_out = true; - //get all intersections between pl and cub edges - std::vector segments; - std::vector points; + std::vector next(14, -1); + std::vector prev(14, -1); - for(int i=0; i < 12; ++i) - { - // Intersect_3 checks the orientation of the segment's extremities to avoid actually computing - // the intersection if possible - Inter_type inter = typename K::Intersect_3()(pl, edges[i]); - if(inter) + int start = -1; + int solo = -1; + // for each face of the bbox, we look for intersection of the plane with its edges + std::vector ids; + for (int i = 0; i < 6; ++i) { - if(const Segment_3* seg = boost::get(&*inter)) - segments.push_back(*seg); - else if(const Point_3* p = boost::get(&*inter)) - points.push_back(*p); - } - } - - if(segments.empty() && points.empty()) - return result_type(); - - switch(segments.size()) - { - case 0: - //points dealt with later - break; - case 1: - { - //adj to an edge - if(points.size() == 4) // plane outside of cub and just touching at the edge, and hence the endpoints of 4 other edges - { - return result_type(std::forward(segments.front())); - } - //plane intersecting through an edge (not 2) This then intersects 2 other edges in points - else - { - Poly res(4); - const Segment_3& entry_seg(segments.front()); - Point_3 p1, p2; - bool p1_found(false), - p2_found(false); - - for(const Point_3& p : points) + ids.clear(); + for (int k = 0; k < 4; ++k) { - if(!k.equal_3_object()(entry_seg.source(), p) - && ! k.equal_3_object()(entry_seg.target(), p)) - { - if(!p1_found) + + int current_id = face_indices[4 * i + k]; + int next_id = face_indices[4 * i + (k + 1) % 4]; + + switch (orientations[current_id]) { - p1 = p; - p1_found = true; + case ON_NEGATIVE_SIDE: + { + all_out = false; + // check for intersection of the edge + if (orientations[next_id] == ON_POSITIVE_SIDE) + { + ids.push_back( + inter_pt_index(current_id, next_id, plane, corners, id_map)); + } + break; + } + case ON_POSITIVE_SIDE: + { + all_in = false; + // check for intersection of the edge + if (orientations[next_id] != ON_NEGATIVE_SIDE) + { + ids.push_back( + inter_pt_index(current_id, next_id, plane, corners, id_map)); + } + break; + } + case ON_ORIENTED_BOUNDARY: + { + all_in = all_out = false; + ids.push_back(current_id); + } } - else { - p2 = p; - p2_found = true; - break; - } - } } - CGAL_USE(p2_found); - CGAL_assertion(p1_found && p2_found); - res[0] = entry_seg.target(); - res[1] = p2; - res[2] = p1; - res[3] = entry_seg.source(); - - typename K::Coplanar_orientation_3 coplanar_orientation = - k.coplanar_orientation_3_object(); - - if( coplanar_orientation(res[0], res[1], res[2]) - != coplanar_orientation(res[0], res[1], res[3])) - { - std::swap(res[1], res[2]); - } - + if (ids.size() == 4){ + std::vector res(4); + res[0] = corners[ids[0]]; + res[1] = corners[ids[1]]; + res[2] = corners[ids[2]]; + res[3] = corners[ids[3]]; return result_type(std::forward(res)); - } - } - break; - - case 2: //intersects diagonally - { - Poly res(4); - Segment_3 &front(segments.front()), - &back(segments.back()); - res[0] = front.target(); - res[1] = back.target(); - res[2] = back.source(); - res[3] = front.source(); - typename K::Coplanar_orientation_3 coplanar_orientation = - k.coplanar_orientation_3_object(); - - if( coplanar_orientation(res[0], res[1], res[2]) - != coplanar_orientation(res[0], res[1], res[3])) - { - std::swap(res[1], res[2]); - } - - return result_type(std::forward(res)); - } - break; - case 4: // intersects a face - { - Poly res; - res.reserve(4); - typename K::Has_on_3 has_on; - if(has_on(pl, cub.vertex(0)) - && has_on(pl, cub.vertex(5)) - && has_on(pl, cub.vertex(4))) - { - res.push_back(cub.vertex(0)); - res.push_back(cub.vertex(5)); - res.push_back(cub.vertex(4)); - res.push_back(cub.vertex(3)); - } - else if(has_on(pl, cub.vertex(0)) - && has_on(pl, cub.vertex(1)) - && has_on(pl, cub.vertex(6))) - { - res.push_back(cub.vertex(0)); - res.push_back(cub.vertex(1)); - res.push_back(cub.vertex(6)); - res.push_back(cub.vertex(5)); - - } - else if(has_on(pl, cub.vertex(1)) - && has_on(pl, cub.vertex(2)) - && has_on(pl, cub.vertex(7))) - { - res.push_back(cub.vertex(1)); - res.push_back(cub.vertex(2)); - res.push_back(cub.vertex(7)); - res.push_back(cub.vertex(6)); - } - else if(has_on(pl, cub.vertex(2)) - && has_on(pl, cub.vertex(3)) - && has_on(pl, cub.vertex(4))) - { - res.push_back(cub.vertex(2)); - res.push_back(cub.vertex(3)); - res.push_back(cub.vertex(4)); - res.push_back(cub.vertex(7)); - } - else if(has_on(pl, cub.vertex(6)) - && has_on(pl, cub.vertex(7)) - && has_on(pl, cub.vertex(4))) - { - res.push_back(cub.vertex(6)); - res.push_back(cub.vertex(7)); - res.push_back(cub.vertex(4)); - res.push_back(cub.vertex(5)); - } - else if(has_on(pl, cub.vertex(2)) - && has_on(pl, cub.vertex(1)) - && has_on(pl, cub.vertex(0))) - { - res.push_back(cub.vertex(2)); - res.push_back(cub.vertex(1)); - res.push_back(cub.vertex(0)); - res.push_back(cub.vertex(3)); - } - return result_type(std::forward(res)); - } - break; - default: - break; - } - - Poly filtered_points; - filter_points(points, filtered_points); - - //adjacent to a vertex - if(filtered_points.size() == 1) - { - return result_type(std::forward(filtered_points.front())); - } - - //get intersections between pl and each face -> line. Foreach line, creates segment with points. Then use helper_function to recover polygon. - typedef typename Intersection_traits, - CGAL::Plane_3 >::result_type Pl_pl_type; - - std::vector plane_intersections; - Pl_pl_type pl_inter; - - if(pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(0), - cub.vertex(1), - cub.vertex(5)))){ - if(const Line_3* line = boost::get(&*pl_inter)){ - plane_intersections.push_back(*line); - } - } - - if (pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(0), - cub.vertex(3), - cub.vertex(4)))){ - if(const Line_3* line = boost::get(&*pl_inter)){ - plane_intersections.push_back(*line); - } - } - if (pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(0), - cub.vertex(1), - cub.vertex(3)))){ - if(const Line_3* line = boost::get(&*pl_inter)){ - plane_intersections.push_back(*line); - } - } - if (pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(7), - cub.vertex(6), - cub.vertex(1)))){ - if(const Line_3* line = boost::get(&*pl_inter)){ - plane_intersections.push_back(*line); - } - } - if (pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(7), - cub.vertex(4), - cub.vertex(3)))){ - if(const Line_3* line = boost::get(&*pl_inter)){ - plane_intersections.push_back(*line); - } - } - if (pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(7), - cub.vertex(6), - cub.vertex(4)))){ - if(const Line_3* line = boost::get(&*pl_inter)){ - plane_intersections.push_back(*line); - } - } - std::list tmp_segs; - for(const auto& line : plane_intersections) - { - bool first_found = false; - Point_3 first_p; - typename K::Has_on_3 has_on; - for(const auto &p : filtered_points) - { - if(has_on(line, p)) - { - if(!first_found) + } else { - first_found = true; - first_p = p; + if (ids.size() == 2) + { + if (start == -1) start = ids[0]; + if (next[ids[0]] == -1) { + next[ids[0]] = ids[1]; + } + else { + prev[ids[0]] = ids[1]; + } + if (next[ids[1]] == -1) { + next[ids[1]] = ids[0]; + } + else { + prev[ids[1]] = ids[0]; + } + + } + else + if (ids.size() == 1) + solo = ids[0]; } - else - { - tmp_segs.emplace_back(first_p, p); - break; - } - } } - } - if(tmp_segs.size() < 3) - return result_type(); + if (all_in || all_out) return boost::none; + if (start == -1) return { result_type(corners[solo]) }; - std::list tmp_pts; - fill_points_list(tmp_segs,tmp_pts); - - Poly res; - for(const auto& p : tmp_pts) - res.push_back(p); - - if(res.size() == 3){ - typename K::Triangle_3 tr(res[0], res[1], res[2]); - return result_type(std::forward(tr)); - } - else - { - return result_type(std::forward(res)); - } + int pre = -1; + int cur = start; + std::vector res; + res.reserve(6); + do { + res.push_back(corners[cur]); + int n = next[cur] == pre ? prev[cur] : next[cur]; + if (n == -1 || n == start){ + if(res.size() == 2){ + typename K::Segment_3 seg(res[0], res[1]); + return result_type(std::forward(seg)); + } + if(res.size() == 3){ + typename K::Triangle_3 tr(res[0], res[1], res[2]); + return result_type(std::forward(tr)); + } + return result_type(std::forward(res));; + } + pre = cur; + cur = n; + } while (true); } + + + template typename Intersection_traits::result_type intersection( @@ -350,6 +210,6 @@ intersection( return intersection(cub, pl, k); } -}}} + }}} #endif // CGAL_INTERNAL_INTERSECTIONS_3_ISO_CUBOID_3_PLANE_3_INTERSECTION_H diff --git a/Intersections_3/test/Intersections_3/issue_5428.cpp b/Intersections_3/test/Intersections_3/issue_5428.cpp new file mode 100644 index 00000000000..7750c069516 --- /dev/null +++ b/Intersections_3/test/Intersections_3/issue_5428.cpp @@ -0,0 +1,40 @@ +#include +#include + +typedef CGAL::Exact_predicates_exact_constructions_kernel EPECK; +typedef CGAL::Exact_predicates_inexact_constructions_kernel EPICK; + +typedef CGAL::Cartesian_converter IK_to_EK; + +typedef EPICK::Point_3 Point; + +int main() +{ + IK_to_EK to_exact; + + //EPICK::Plane_3 pl(Point(0,0,10),Point(1,0,10),Point(0,1,10)); + + // EPICK::Plane_3 pl(0.265189, 0.902464, 0.33946, -2.47551); + + EPICK::Plane_3 pl(Point(1, 1, 1), Point(1, 2, 1), Point(1, 2, 2)); + + EPECK::Plane_3 epl = to_exact(pl); + + std::vector pts; + pts.push_back(Point(1,1,1)); + pts.push_back(Point(2,2,2)); + CGAL::Bbox_3 cub = CGAL::bbox_3(pts.begin(), pts.end()); + + EPECK::Iso_cuboid_3 ecub = to_exact(cub); + + auto result = intersection(cub,pl); + + //auto result2 = intersection(ecub,epl); + + const std::vector* res = boost::get >(&*result); + for (Point p : *res) { + std::cout << p << std::endl; + } + + return 0; +} From e511b68d4cfa28c644f0c1f0e8bb303d6d9a12ed Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Tue, 9 Feb 2021 17:32:00 +0100 Subject: [PATCH 126/248] Code review: Add the fix proposal from @MaelIRL --- Triangulation/include/CGAL/Regular_triangulation.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Triangulation/include/CGAL/Regular_triangulation.h b/Triangulation/include/CGAL/Regular_triangulation.h index fddb395c036..86075657b06 100644 --- a/Triangulation/include/CGAL/Regular_triangulation.h +++ b/Triangulation/include/CGAL/Regular_triangulation.h @@ -974,7 +974,8 @@ Regular_triangulation // => we don't insert it if (!in_conflict) { - m_hidden_points.push_back(p); + if(only_if_this_vertex_is_in_the_cz == Vertex_handle()) + m_hidden_points.push_back(p); return Vertex_handle(); } else From fb731259d72ada512dfaa955f31007b63ac6095c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 9 Feb 2021 17:51:01 +0100 Subject: [PATCH 127/248] fix comparison --- .../internal/Iso_cuboid_3_Plane_3_intersection.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h index 69e0b6198b9..2cbb0a7f0f2 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h @@ -125,7 +125,7 @@ intersection( { all_in = false; // check for intersection of the edge - if (orientations[next_id] != ON_NEGATIVE_SIDE) + if (orientations[next_id] == ON_NEGATIVE_SIDE) { ids.push_back( inter_pt_index(current_id, next_id, plane, corners, id_map)); From b363977c87e0700914bb10e7d3ad029e60fd17cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 9 Feb 2021 17:58:25 +0100 Subject: [PATCH 128/248] clean up --- .../Iso_cuboid_3_Plane_3_intersection.h | 184 +++++++++--------- 1 file changed, 93 insertions(+), 91 deletions(-) diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h index 2cbb0a7f0f2..8ed1fff6400 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h @@ -8,7 +8,7 @@ // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // // -// Author(s) : Maxime Gimeno +// Author(s) : Sebastien Loriot and Andreas Fabri // #ifndef CGAL_INTERNAL_INTERSECTIONS_3_ISO_CUBOID_3_PLANE_3_INTERSECTION_H @@ -28,7 +28,7 @@ namespace CGAL { namespace Intersections { namespace internal { -template +template int inter_pt_index(int i, int j, const Plane_3& plane, @@ -39,7 +39,7 @@ inter_pt_index(int i, int j, id_map.insert(std::make_pair(make_sorted_pair(i, j), static_cast (points.size()))); if (res.second) - points.push_back(typename Geom_traits::Construct_plane_line_intersection_point_3() + points.push_back(typename K::Construct_plane_line_intersection_point_3() (plane, points[i], points[j])); return res.first->second; @@ -54,8 +54,8 @@ intersection( const K& k) { typedef typename K::Point_3 Point_3; - typedef std::vector Poly; typedef typename Intersection_traits::result_type result_type; + typename K::Oriented_side_3 oriented_side = k.oriented_side_3_object(); std::vector corners(8); corners.reserve(14); // 8 corners + up to 6 polygon points @@ -69,14 +69,14 @@ intersection( corners[7] = cub[6]; std::array orientations = { { - plane.oriented_side(corners[0]), - plane.oriented_side(corners[1]), - plane.oriented_side(corners[2]), - plane.oriented_side(corners[3]), - plane.oriented_side(corners[4]), - plane.oriented_side(corners[5]), - plane.oriented_side(corners[6]), - plane.oriented_side(corners[7]) + oriented_side(plane, corners[0]), + oriented_side(plane, corners[1]), + oriented_side(plane, corners[2]), + oriented_side(plane, corners[3]), + oriented_side(plane, corners[4]), + oriented_side(plane, corners[5]), + oriented_side(plane, corners[6]), + oriented_side(plane, corners[7]) } }; // description of faces of the bbox @@ -95,105 +95,107 @@ intersection( std::vector next(14, -1); std::vector prev(14, -1); - int start = -1; - int solo = -1; + int start_id = -1; + int solo_id = -1; // for each face of the bbox, we look for intersection of the plane with its edges std::vector ids; for (int i = 0; i < 6; ++i) + { + ids.clear(); + for (int k = 0; k < 4; ++k) { - ids.clear(); - for (int k = 0; k < 4; ++k) + + int current_id = face_indices[4 * i + k]; + int next_id = face_indices[4 * i + (k + 1) % 4]; + + switch (orientations[current_id]) + { + case ON_NEGATIVE_SIDE: { - - int current_id = face_indices[4 * i + k]; - int next_id = face_indices[4 * i + (k + 1) % 4]; - - switch (orientations[current_id]) - { - case ON_NEGATIVE_SIDE: - { - all_out = false; - // check for intersection of the edge - if (orientations[next_id] == ON_POSITIVE_SIDE) - { - ids.push_back( - inter_pt_index(current_id, next_id, plane, corners, id_map)); - } - break; - } - case ON_POSITIVE_SIDE: - { - all_in = false; - // check for intersection of the edge - if (orientations[next_id] == ON_NEGATIVE_SIDE) - { - ids.push_back( - inter_pt_index(current_id, next_id, plane, corners, id_map)); - } - break; - } - case ON_ORIENTED_BOUNDARY: - { - all_in = all_out = false; - ids.push_back(current_id); - } - } + all_out = false; + // check for intersection of the edge + if (orientations[next_id] == ON_POSITIVE_SIDE) + { + ids.push_back( + inter_pt_index(current_id, next_id, plane, corners, id_map)); + } + break; } - if (ids.size() == 4){ - std::vector res(4); - res[0] = corners[ids[0]]; - res[1] = corners[ids[1]]; - res[2] = corners[ids[2]]; - res[3] = corners[ids[3]]; - return result_type(std::forward(res)); - } else + case ON_POSITIVE_SIDE: { - if (ids.size() == 2) - { - if (start == -1) start = ids[0]; - if (next[ids[0]] == -1) { - next[ids[0]] = ids[1]; - } - else { - prev[ids[0]] = ids[1]; - } - if (next[ids[1]] == -1) { - next[ids[1]] = ids[0]; - } - else { - prev[ids[1]] = ids[0]; - } - - } - else - if (ids.size() == 1) - solo = ids[0]; + all_in = false; + // check for intersection of the edge + if (orientations[next_id] == ON_NEGATIVE_SIDE) + { + ids.push_back(inter_pt_index(current_id, next_id, plane, corners, id_map)); + } + break; } + case ON_ORIENTED_BOUNDARY: + { + all_in = all_out = false; + ids.push_back(current_id); + } + } } - if (all_in || all_out) return boost::none; - if (start == -1) return { result_type(corners[solo]) }; + switch (ids.size()) + { + case 4: + { + std::vector res({ corners[ids[0]], + corners[ids[1]], + corners[ids[2]], + corners[ids[3]] }); + return result_type(res); + } + case 2: + { + if (start_id == -1) start_id = ids[0]; + if (next[ids[0]] == -1) { + next[ids[0]] = ids[1]; + } + else { + prev[ids[0]] = ids[1]; + } + if (next[ids[1]] == -1) { + next[ids[1]] = ids[0]; + } + else { + prev[ids[1]] = ids[0]; + } + break; + } + case 1: + solo_id = ids[0]; + default: + break; + } + } - int pre = -1; - int cur = start; + if (all_in || all_out) return boost::none; + if (start_id == -1) return { result_type(corners[solo_id]) }; + + int prv_id = -1; + int cur_id = start_id; std::vector res; res.reserve(6); do { - res.push_back(corners[cur]); - int n = next[cur] == pre ? prev[cur] : next[cur]; - if (n == -1 || n == start){ + res.push_back(corners[cur_id]); + int nxt_id = next[cur_id] == prv_id ? prev[cur_id] : next[cur_id]; + if (nxt_id == -1 || nxt_id == start_id){ if(res.size() == 2){ typename K::Segment_3 seg(res[0], res[1]); - return result_type(std::forward(seg)); + return result_type(seg); } if(res.size() == 3){ typename K::Triangle_3 tr(res[0], res[1], res[2]); - return result_type(std::forward(tr)); + return result_type(tr); } - return result_type(std::forward(res));; + return result_type(res); } - pre = cur; - cur = n; + prv_id = cur_id; + cur_id = nxt_id; } while (true); } @@ -210,6 +212,6 @@ intersection( return intersection(cub, pl, k); } - }}} +}}} #endif // CGAL_INTERNAL_INTERSECTIONS_3_ISO_CUBOID_3_PLANE_3_INTERSECTION_H From 95bd626bbdc470d6533a6d73b64b8f26c6de1f16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 9 Feb 2021 18:01:55 +0100 Subject: [PATCH 129/248] use one vector --- .../Iso_cuboid_3_Plane_3_intersection.h | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h index 8ed1fff6400..57d29d2efcc 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h @@ -92,8 +92,7 @@ intersection( bool all_in = true; bool all_out = true; - std::vector next(14, -1); - std::vector prev(14, -1); + std::vector> neighbor_ids(14, {-1,-1}); int start_id = -1; int solo_id = -1; @@ -152,17 +151,17 @@ intersection( case 2: { if (start_id == -1) start_id = ids[0]; - if (next[ids[0]] == -1) { - next[ids[0]] = ids[1]; + if (neighbor_ids[ids[0]][0] == -1) { + neighbor_ids[ids[0]][0] = ids[1]; } else { - prev[ids[0]] = ids[1]; + neighbor_ids[ids[0]][1] = ids[1]; } - if (next[ids[1]] == -1) { - next[ids[1]] = ids[0]; + if (neighbor_ids[ids[1]][0] == -1) { + neighbor_ids[ids[1]][0] = ids[0]; } else { - prev[ids[1]] = ids[0]; + neighbor_ids[ids[1]][1] = ids[0]; } break; } @@ -182,7 +181,9 @@ intersection( res.reserve(6); do { res.push_back(corners[cur_id]); - int nxt_id = next[cur_id] == prv_id ? prev[cur_id] : next[cur_id]; + int nxt_id = neighbor_ids[cur_id][0] == prv_id + ? neighbor_ids[cur_id][1] + : neighbor_ids[cur_id][0]; if (nxt_id == -1 || nxt_id == start_id){ if(res.size() == 2){ typename K::Segment_3 seg(res[0], res[1]); @@ -199,9 +200,6 @@ intersection( } while (true); } - - - template typename Intersection_traits::result_type intersection( From 81a6fe16e835aeec499251e4df6df6d65837f36d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 9 Feb 2021 18:27:58 +0100 Subject: [PATCH 130/248] remove idmap --- .../Iso_cuboid_3_Plane_3_intersection.h | 51 +++++++++++-------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h index 57d29d2efcc..dc126efdf8a 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h @@ -28,23 +28,6 @@ namespace CGAL { namespace Intersections { namespace internal { -template -int -inter_pt_index(int i, int j, - const Plane_3& plane, - std::vector& points, - std::map, int>& id_map) -{ - std::pair, int>::iterator, bool> res = - id_map.insert(std::make_pair(make_sorted_pair(i, j), - static_cast (points.size()))); - if (res.second) - points.push_back(typename K::Construct_plane_line_intersection_point_3() - (plane, points[i], points[j])); - - return res.first->second; -} - //Iso_cuboid_3 Plane_3 template typename Intersection_traits::result_type @@ -68,7 +51,7 @@ intersection( corners[6] = cub[7]; corners[7] = cub[6]; - std::array orientations = { { + const std::array orientations { { oriented_side(plane, corners[0]), oriented_side(plane, corners[1]), oriented_side(plane, corners[2]), @@ -80,7 +63,7 @@ intersection( } }; // description of faces of the bbox - std::array face_indices = + constexpr std::array face_indices { { 0, 1, 2, 3, 2, 1, 5, 6, 3, 2, 6, 7, @@ -88,7 +71,30 @@ intersection( 4, 0, 3, 7, 6, 5, 4, 7 } }; - std::map, int> id_map; + constexpr std::array edge_indices + { { 0, 1, 2, 3, + 1, 4, 5, 6, + 2, 6, 7, 8, + 0, 9, 10, 4, + 9, 3, 8, 11, + 5, 10, 11, 7 } }; + + std::array edge_ipt_id; + edge_ipt_id.fill(-1); + + auto inter_pt_index = + [&plane, &corners, &edge_ipt_id](int i, int j, int edge_id) + { + if (edge_ipt_id[edge_id]==-1) + { + edge_ipt_id[edge_id] = static_cast (corners.size()); + corners.push_back(typename K::Construct_plane_line_intersection_point_3() + (plane, corners[i], corners[j])); + } + + return edge_ipt_id[edge_id]; + }; + bool all_in = true; bool all_out = true; @@ -106,6 +112,7 @@ intersection( int current_id = face_indices[4 * i + k]; int next_id = face_indices[4 * i + (k + 1) % 4]; + int edge_id = edge_indices[4 * i + k]; switch (orientations[current_id]) { @@ -116,7 +123,7 @@ intersection( if (orientations[next_id] == ON_POSITIVE_SIDE) { ids.push_back( - inter_pt_index(current_id, next_id, plane, corners, id_map)); + inter_pt_index(current_id, next_id, edge_id)); } break; } @@ -126,7 +133,7 @@ intersection( // check for intersection of the edge if (orientations[next_id] == ON_NEGATIVE_SIDE) { - ids.push_back(inter_pt_index(current_id, next_id, plane, corners, id_map)); + ids.push_back(inter_pt_index(current_id, next_id, edge_id)); } break; } From 81ba9da2929371ab65ed43be33d307e0e5487576 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 9 Feb 2021 18:42:39 +0100 Subject: [PATCH 131/248] remove tabs --- Intersections_3/test/Intersections_3/issue_5428.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Intersections_3/test/Intersections_3/issue_5428.cpp b/Intersections_3/test/Intersections_3/issue_5428.cpp index 7750c069516..844b41943c7 100644 --- a/Intersections_3/test/Intersections_3/issue_5428.cpp +++ b/Intersections_3/test/Intersections_3/issue_5428.cpp @@ -33,7 +33,7 @@ int main() const std::vector* res = boost::get >(&*result); for (Point p : *res) { - std::cout << p << std::endl; + std::cout << p << std::endl; } return 0; From a595e529c547b9d9049b784c81e0e4e16c43f216 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 9 Feb 2021 18:43:05 +0100 Subject: [PATCH 132/248] remove edge map and inter pt set --- .../CGAL/Polygon_mesh_processing/clip.h | 84 +++++++++++-------- 1 file changed, 47 insertions(+), 37 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/clip.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/clip.h index 16a42066d03..74d62e9ab84 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/clip.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/clip.h @@ -33,6 +33,7 @@ #include #include +#include namespace CGAL{ namespace Polygon_mesh_processing { @@ -40,24 +41,6 @@ namespace Polygon_mesh_processing { namespace internal { -template -int -inter_pt_index(int i, int j, - const Plane_3& plane, - std::vector& points, - std::map, int>& id_map) -{ - std::pair, int>::iterator, bool> res = - id_map.insert(std::make_pair(make_sorted_pair(i,j), - static_cast (points.size()))); - if(res.second) - points.push_back( - typename Geom_traits::Construct_plane_line_intersection_point_3() - (plane, points[i], points[j])); - - return res.first->second; -} - template @@ -98,19 +81,42 @@ clip_to_bbox(const Plane_3& plane, }}; // description of faces of the bbox - std::array face_indices = - {{ 0, 1, 2, 3, - 2, 1, 5, 6, - 3, 2, 6, 7, - 1, 0, 4, 5, - 4, 0, 3, 7, - 6, 5, 4, 7 }}; + constexpr std::array face_indices + { { 0, 1, 2, 3, + 2, 1, 5, 6, + 3, 2, 6, 7, + 1, 0, 4, 5, + 4, 0, 3, 7, + 6, 5, 4, 7 } }; + + constexpr std::array edge_indices + { { 0, 1, 2, 3, + 1, 4, 5, 6, + 2, 6, 7, 8, + 0, 9, 10, 4, + 9, 3, 8, 11, + 5, 10, 11, 7 } }; + + std::array edge_ipt_id; + edge_ipt_id.fill(-1); + + auto inter_pt_index = + [&plane, &corners, &edge_ipt_id](int i, int j, int edge_id) + { + if (edge_ipt_id[edge_id]==-1) + { + edge_ipt_id[edge_id] = static_cast (corners.size()); + corners.push_back(typename Geom_traits::Construct_plane_line_intersection_point_3() + (plane, corners[i], corners[j])); + } + + return edge_ipt_id[edge_id]; + }; - std::map, int> id_map; std::vector< std::vector > output_faces(6); bool all_in = true; bool all_out = true; - std::set in_point_ids; // to collect the set of points in the clipped bbox + std::bitset<14> in_point_bits; // to collect the set of points in the clipped bbox // for each face of the bbox, we look for intersection of the plane with its edges for(int i=0; i<6; ++i) @@ -119,6 +125,7 @@ clip_to_bbox(const Plane_3& plane, { int current_id = face_indices[4*i + k]; int next_id = face_indices[4*i + (k+1)%4]; + int edge_id = edge_indices[4 * i + k]; switch(orientations[ current_id ]) { @@ -127,13 +134,13 @@ clip_to_bbox(const Plane_3& plane, all_out=false; // point on or on the negative side output_faces[i].push_back(current_id); - in_point_ids.insert(output_faces[i].back()); + in_point_bits.set(output_faces[i].back()); // check for intersection of the edge if(orientations[ next_id ] == ON_POSITIVE_SIDE) { output_faces[i].push_back( - inter_pt_index(current_id, next_id, plane, corners, id_map)); - in_point_ids.insert(output_faces[i].back()); + inter_pt_index(current_id, next_id, edge_id)); + in_point_bits.set(output_faces[i].back()); } break; } @@ -144,15 +151,15 @@ clip_to_bbox(const Plane_3& plane, if(orientations[ next_id ] == ON_NEGATIVE_SIDE) { output_faces[i].push_back( - inter_pt_index(current_id, next_id, plane, corners, id_map)); - in_point_ids.insert(output_faces[i].back()); + inter_pt_index(current_id, next_id, edge_id)); + in_point_bits.set(output_faces[i].back()); } break; } case ON_ORIENTED_BOUNDARY: { output_faces[i].push_back(current_id); - in_point_ids.insert(output_faces[i].back()); + in_point_bits.set(output_faces[i].back()); } } } @@ -174,11 +181,14 @@ clip_to_bbox(const Plane_3& plane, typedef typename graph_traits::face_descriptor face_descriptor; std::map out_vertices; - for(int i : in_point_ids) + for(int i=0; i<14;++i) { - vertex_descriptor v = add_vertex(tm_out); - out_vertices.insert(std::make_pair(i, v)); - put(vpm_out, v, corners[i]); + if (in_point_bits.test(i)) + { + vertex_descriptor v = add_vertex(tm_out); + out_vertices.insert(std::make_pair(i, v)); + put(vpm_out, v, corners[i]); + } } std::map< std::pair, halfedge_descriptor> hedge_map; From 38142dc101ab984c676a95dccd44d1956639af8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 9 Feb 2021 18:51:38 +0100 Subject: [PATCH 133/248] update include directives --- .../internal/Iso_cuboid_3_Plane_3_intersection.h | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h index dc126efdf8a..311c397ddfa 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h @@ -18,11 +18,8 @@ #include #include -#include -#include -#include - -#include +#include +#include namespace CGAL { namespace Intersections { From 231e9f1b9321d0c6bab3595e2b0e79c504ef6a4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 10 Feb 2021 10:29:02 +0100 Subject: [PATCH 134/248] handle cases when plane contains an edge --- .../Iso_cuboid_3_Plane_3_intersection.h | 27 ++++++++++--------- .../Intersections_3/test_intersections_3.cpp | 7 ++--- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h index 311c397ddfa..270693f2fb9 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h @@ -97,6 +97,19 @@ intersection( std::vector> neighbor_ids(14, {-1,-1}); + auto add_neighbor = [&neighbor_ids](int i, int j) + { + if (neighbor_ids[i][0] == -1 ) { + neighbor_ids[i][0] = j; + } + else { + if (neighbor_ids[i][0]!=j && neighbor_ids[i][1]==-1) + { + neighbor_ids[i][1] = j; + } + } + }; + int start_id = -1; int solo_id = -1; // for each face of the bbox, we look for intersection of the plane with its edges @@ -155,18 +168,8 @@ intersection( case 2: { if (start_id == -1) start_id = ids[0]; - if (neighbor_ids[ids[0]][0] == -1) { - neighbor_ids[ids[0]][0] = ids[1]; - } - else { - neighbor_ids[ids[0]][1] = ids[1]; - } - if (neighbor_ids[ids[1]][0] == -1) { - neighbor_ids[ids[1]][0] = ids[0]; - } - else { - neighbor_ids[ids[1]][1] = ids[0]; - } + add_neighbor(ids[0], ids[1]); + add_neighbor(ids[1], ids[0]); break; } case 1: diff --git a/Intersections_3/test/Intersections_3/test_intersections_3.cpp b/Intersections_3/test/Intersections_3/test_intersections_3.cpp index 7247a3c472e..ea68b96e871 100644 --- a/Intersections_3/test/Intersections_3/test_intersections_3.cpp +++ b/Intersections_3/test/Intersections_3/test_intersections_3.cpp @@ -907,7 +907,7 @@ struct Test { //edge check_intersection (cub, Pl(P(1,1,1), P(1,2,1), P(1.5,0,0)), - S(P(1,2,1), P(1,1,1))); + S(P(1,1,1), P(1,2,1))); //face @@ -924,6 +924,7 @@ struct Test { assert(p.x() == 1); } res = CGAL::intersection(cub, Pl(P(1,1,1), P(1,2,1), P(2,2,2))); + poly = boost::get >(&*res); assert(poly != nullptr); assert(poly->size() == 4); @@ -940,8 +941,8 @@ struct Test { check_intersection (cub, Pl(P(2, 1.66, 2), P(1.66,2,2), P(2,2,1.66)), - Tr(P(2, 2, 1.66), - P(1.66,2,2), + Tr(P(1.66,2,2), + P(2, 2, 1.66), P(2,1.66,2))); //other edge From 482db1f0ccbb2c28330da25ffa3bd604c555cfcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 10 Feb 2021 11:11:01 +0100 Subject: [PATCH 135/248] forget to update bbox case --- .../test/Intersections_3/test_intersections_3.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Intersections_3/test/Intersections_3/test_intersections_3.cpp b/Intersections_3/test/Intersections_3/test_intersections_3.cpp index ea68b96e871..deb48c9913f 100644 --- a/Intersections_3/test/Intersections_3/test_intersections_3.cpp +++ b/Intersections_3/test/Intersections_3/test_intersections_3.cpp @@ -1101,7 +1101,7 @@ struct Test { //edge check_intersection (cub, Pl(P(1,1,1), P(1,2,1), P(1.5,0,0)), - S(P(1,2,1), P(1,1,1))); + S(P(1,1,1), P(1,2,1))); //face typedef typename CGAL::Intersection_traits Date: Wed, 10 Feb 2021 15:41:45 +0000 Subject: [PATCH 136/248] WIP: try to do plane/tet intersection. I think the edge indexing is wrong --- .../Tetrahedron_3_Plane_3_intersection.h | 228 ++++++++++++------ 1 file changed, 148 insertions(+), 80 deletions(-) diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersection.h index fa55cb268f2..9bc5c0916a0 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersection.h @@ -32,101 +32,169 @@ template typename Intersection_traits::result_type intersection( const typename K::Tetrahedron_3 &tet, - const typename K::Plane_3 &pl, - const K&) + const typename K::Plane_3 &plane, + const K& k) { - typedef typename Intersection_traits::result_type result_type; + typedef typename K::Point_3 Point_3; + typedef typename Intersection_traits::result_type result_type; + typename K::Oriented_side_3 oriented_side = k.oriented_side_3_object(); - typedef typename Intersection_traits::result_type Inter_type; + std::vector corners(4); + corners.reserve(8); // 4 corners + up to 4 polygon points + corners[0] = tet[0]; + corners[1] = tet[1]; + corners[2] = tet[2]; + corners[3] = tet[3]; - typedef typename K::Segment_3 Segment_3; - Inter_type intersections[4]; - int p_id = -1; - std::vector points; - std::vector segments; - for(int i = 0; i < 4; ++i) + const std::array orientations { { + oriented_side(plane, corners[0]), + oriented_side(plane, corners[1]), + oriented_side(plane, corners[2]), + oriented_side(plane, corners[3]) + } }; + + // description of faces of the bbox + constexpr std::array face_indices + { { 0, 1, 2, + 0, 1, 3, + 1, 2, 3, + 2, 0, 3 } }; + + constexpr std::array edge_indices + { { 0, 1, 2, + 0, 3, 5, + 1, 4, 3, + 2, 5, 4 } }; + + std::array edge_ipt_id; + edge_ipt_id.fill(-1); + + auto inter_pt_index = + [&plane, &corners, &edge_ipt_id](int i, int j, int edge_id) { - const typename K::Triangle_3 triangle(tet.vertex((i+1)%4), - tet.vertex((i+2)%4), - tet.vertex((i+3)%4)); - intersections[i] = typename K::Intersect_3()(pl, triangle); - if(intersections[i]){ - if(const typename K::Triangle_3* tr = boost::get(&*intersections[i])) + if (edge_ipt_id[edge_id]==-1) + { + edge_ipt_id[edge_id] = static_cast (corners.size()); + corners.push_back(typename K::Construct_plane_line_intersection_point_3() + (plane, corners[i], corners[j])); + } + + return edge_ipt_id[edge_id]; + }; + + bool all_in = true; + bool all_out = true; + + std::vector> neighbor_ids(8, {-1,-1}); + + auto add_neighbor = [&neighbor_ids](int i, int j) + { + if (neighbor_ids[i][0] == -1 ) { + neighbor_ids[i][0] = j; + } + else { + if (neighbor_ids[i][0]!=j && neighbor_ids[i][1]==-1) { - typename K::Triangle_3 res = *tr; - return result_type(std::forward(res)); - } - else if( const Segment_3* s - = boost::get(&*intersections[i])) - { - segments.push_back(*s); - } - else if( const typename K::Point_3* p - = boost::get(&*intersections[i])) - { - points.push_back(*p); - p_id = i; + neighbor_ids[i][1] = j; } } - } - CGAL_assertion(segments.size() != 1); + }; - switch(segments.size()) + int start_id = -1; + int solo_id = -1; + // for each face of the bbox, we look for intersection of the plane with its edges + std::vector ids; + for (int i = 0; i < 4; ++i) { - case 0: - { - if(p_id == -1) - return result_type(); - else + ids.clear(); + for (int k = 0; k < 3; ++k) { - typename K::Point_3 p - = *boost::get(&*intersections[p_id]); - return result_type(std::forward(p)); + int current_id = face_indices[3 * i + k]; + int next_id = face_indices[3 * i + (k + 1) % 3]; + int edge_id = edge_indices[3 * i + k]; + + switch (orientations[current_id]) + { + case ON_NEGATIVE_SIDE: + { + all_out = false; + // check for intersection of the edge + if (orientations[next_id] == ON_POSITIVE_SIDE) + { + ids.push_back( + inter_pt_index(current_id, next_id, edge_id)); + } + break; + } + case ON_POSITIVE_SIDE: + { + all_in = false; + // check for intersection of the edge + if (orientations[next_id] == ON_NEGATIVE_SIDE) + { + ids.push_back(inter_pt_index(current_id, next_id, edge_id)); + } + break; + } + case ON_ORIENTED_BOUNDARY: + { + all_in = all_out = false; + ids.push_back(current_id); + } + } } - } - break; - case 2: - { - return result_type(std::forward(segments.back())); - } - break; - default: - { - std::set all_points; - for (const auto& s : segments) + + switch (ids.size()) { - all_points.insert(s.source()); - all_points.insert(s.target()); - } - if(all_points.size() == 3) - { - auto p_it = all_points.begin(); - ++p_it; - typename K::Point_3 mid_point = *p_it; - ++p_it; - typename K::Triangle_3 result(*all_points.begin(), mid_point, *p_it ); - return result_type(std::forward(result)); - } - else //size = 4 - { - std::list segs(segments.begin(), segments.end()); - std::list tmp; - fill_points_list(segs, tmp); - std::vector res; - for( const auto& p : tmp) - res.push_back(p); - return result_type(std::forward >(res)); + case 3: + { + std::vector res({ corners[ids[0]], + corners[ids[1]], + corners[ids[2]] }); + return result_type(res); + } + case 2: + { + if (start_id == -1) start_id = ids[0]; + add_neighbor(ids[0], ids[1]); + add_neighbor(ids[1], ids[0]); + break; + } + case 1: + solo_id = ids[0]; + default: + break; } } - break; - } - CGAL_assertion(false); - return result_type(); + + if (all_in || all_out) return boost::none; + if (start_id == -1) return { result_type(corners[solo_id]) }; + + int prv_id = -1; + int cur_id = start_id; + std::vector res; + res.reserve(4); + do { + res.push_back(corners[cur_id]); + int nxt_id = neighbor_ids[cur_id][0] == prv_id + ? neighbor_ids[cur_id][1] + : neighbor_ids[cur_id][0]; + if (nxt_id == -1 || nxt_id == start_id){ + if(res.size() == 2){ + typename K::Segment_3 seg(res[0], res[1]); + return result_type(seg); + } + if(res.size() == 3){ + typename K::Triangle_3 tr(res[0], res[1], res[2]); + return result_type(tr); + } + return result_type(res); + } + prv_id = cur_id; + cur_id = nxt_id; + } while (true); + } template From ba04933076d696f2c69d54e2cd26ff0a31471e5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 11 Feb 2021 10:27:23 +0100 Subject: [PATCH 137/248] update doc to no longer mention the executable --- Documentation/doc/Documentation/windows.txt | 25 ++++++++++++--------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/Documentation/doc/Documentation/windows.txt b/Documentation/doc/Documentation/windows.txt index 77021a27a28..70b4b667e31 100644 --- a/Documentation/doc/Documentation/windows.txt +++ b/Documentation/doc/Documentation/windows.txt @@ -16,9 +16,9 @@ installation instructions. If you choose to use `vcpkg`, you might have to bootstrap and download and compile it, but from then on `vcpkg` will make your life easier. -On the other hand, if you need to specify a specific version, or have already installed +On the other hand, if you need to use a specific version, or have already installed a certain version of a dependency and do not wish to potentially have multiple versions installed, -you will want to use the \cgal Installer. +you will want to use the \cgal source archive. We explain the two approaches in the next two sections. @@ -146,11 +146,19 @@ you are advised to look at the `CMakeLists.txt` files in the example folder of the package(s) that you are using to learn how to specify \cgal and additional third party dependencies. -\section install-with-installer Installing with the CGAL Installer +\section install-from-source Installing from the Source Archive + +You can download and extract `CGAL-\cgalReleaseNumber``.zip` from https://www.cgal.org/download/windows.html. + +\subsection ssect-installer-gmp-mpfr Installing GMP and MPFR + +Precompiled version of \gmp and \mpfr are provided in the asset GMP and MPFR libraries, for Windows 64bits +from https://github.com/CGAL/cgal/releases. +If you only install those libraries to use \cgal, then you should extract this archive inside the directory +`CGAL-\cgalReleaseNumber` created when extracting the \cgal zip source archive. +That way those dependencies will be automatically detected by cmake +(you should then get the directory `CGAL-\cgalReleaseNumber``\``auxiliary``\``gmp`). -You can download and run `CGAL-\cgalReleaseNumber``-Setup.exe` from https://www.cgal.org/download/windows.html. -It is a self-extracting executable that downloads the \cgal header files, and optionally the source code of the -examples and demos. Additionally, it can download precompiled versions of \gmp and \mpfr. \subsection ssect-installer-boost Installing Boost @@ -267,9 +275,4 @@ you are advised to look at the `CMakeLists.txt` files in the example folder of the package(s) that you are using to learn how to specify \cgal and additional third party dependencies. -\section install-with-tarball Installing from the Source Archive - -Instead of the installer you can also download release tarballs. The sole difference -is that the installer also downloads precompiled \gmp and \mpfr libraries. - */ From 76794e90aa3f43ab89fbad7547a548746349c510 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 11 Feb 2021 10:37:08 +0100 Subject: [PATCH 138/248] remove travis and wininst --- .travis.yml | 80 --- .travis/build_package.sh | 144 ------ .travis/generate_travis.sh | 94 ---- .travis/install.sh | 16 - .travis/install_openmesh.sh | 16 - .travis/packages.txt | 140 ------ .travis/template.txt | 34 -- .travis/test_package.sh | 30 -- .travis/windows.h | 12 - copyright | 1 - wininst/developer_scripts/CGAL.bmp | Bin 297702 -> 0 bytes wininst/developer_scripts/DumpLogToFile.nsh | 47 -- wininst/developer_scripts/EnvVarUpdate.nsh | 360 ------------- wininst/developer_scripts/TextLog.nsh | 68 --- wininst/developer_scripts/WriteEnvStr.nsh | 183 ------- wininst/developer_scripts/cgal.ico | Bin 1078 -> 0 bytes .../cgal_very_small_FFFFFF.bmp | Bin 15594 -> 0 bytes .../developer_scripts/default_variants.ini | 93 ---- .../environment_variables.ini | 90 ---- wininst/developer_scripts/fixup_projects.ini | 27 - wininst/developer_scripts/locate.zip | Bin 47393 -> 0 bytes wininst/developer_scripts/script_cgal.nsh | 65 --- wininst/developer_scripts/script_cgal.nsi | 471 ------------------ wininst/developer_scripts/variants.ini | 19 - wininst/developer_scripts/zirkel.bmp | Bin 88182 -> 0 bytes wininst/package_info/wininst/copyright | 5 - wininst/package_info/wininst/dependencies | 0 wininst/package_info/wininst/description.txt | 1 - wininst/package_info/wininst/maintainer | 1 - 29 files changed, 1997 deletions(-) delete mode 100644 .travis.yml delete mode 100755 .travis/build_package.sh delete mode 100755 .travis/generate_travis.sh delete mode 100644 .travis/install.sh delete mode 100644 .travis/install_openmesh.sh delete mode 100644 .travis/packages.txt delete mode 100644 .travis/template.txt delete mode 100644 .travis/test_package.sh delete mode 100644 .travis/windows.h delete mode 100644 wininst/developer_scripts/CGAL.bmp delete mode 100644 wininst/developer_scripts/DumpLogToFile.nsh delete mode 100644 wininst/developer_scripts/EnvVarUpdate.nsh delete mode 100644 wininst/developer_scripts/TextLog.nsh delete mode 100644 wininst/developer_scripts/WriteEnvStr.nsh delete mode 100644 wininst/developer_scripts/cgal.ico delete mode 100644 wininst/developer_scripts/cgal_very_small_FFFFFF.bmp delete mode 100644 wininst/developer_scripts/default_variants.ini delete mode 100644 wininst/developer_scripts/environment_variables.ini delete mode 100644 wininst/developer_scripts/fixup_projects.ini delete mode 100644 wininst/developer_scripts/locate.zip delete mode 100644 wininst/developer_scripts/script_cgal.nsh delete mode 100644 wininst/developer_scripts/script_cgal.nsi delete mode 100644 wininst/developer_scripts/variants.ini delete mode 100644 wininst/developer_scripts/zirkel.bmp delete mode 100644 wininst/package_info/wininst/copyright delete mode 100644 wininst/package_info/wininst/dependencies delete mode 100644 wininst/package_info/wininst/description.txt delete mode 100644 wininst/package_info/wininst/maintainer diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index f9e0528d35d..00000000000 --- a/.travis.yml +++ /dev/null @@ -1,80 +0,0 @@ -language: cpp -dist: bionic -sudo: required -git: - depth: 3 -env: - matrix: - - PACKAGE='CHECK' - - PACKAGE='AABB_tree Advancing_front_surface_reconstruction Algebraic_foundations ' - - PACKAGE='Algebraic_kernel_d Algebraic_kernel_for_circles Algebraic_kernel_for_spheres ' - - PACKAGE='Alpha_shapes_2 Alpha_shapes_3 Apollonius_graph_2 ' - - PACKAGE='Arithmetic_kernel Arrangement_on_surface_2 BGL ' - - PACKAGE='Barycentric_coordinates_2 Boolean_set_operations_2 Bounding_volumes ' - - PACKAGE='Box_intersection_d CGAL_Core CGAL_ImageIO ' - - PACKAGE='CGAL_ipelets Cartesian_kernel Circular_kernel_2 ' - - PACKAGE='Circular_kernel_3 Circulator Classification ' - - PACKAGE='Combinatorial_map Cone_spanners_2 Convex_decomposition_3 ' - - PACKAGE='Convex_hull_2 Convex_hull_3 Convex_hull_d ' - - PACKAGE='Distance_2 Distance_3 Envelope_2 ' - - PACKAGE='Envelope_3 Filtered_kernel Generalized_map ' - - PACKAGE='Generator Geomview GraphicsView ' - - PACKAGE='HalfedgeDS Hash_map Heat_method_3 ' - - PACKAGE='Homogeneous_kernel Hyperbolic_triangulation_2 Inscribed_areas ' - - PACKAGE='Installation Interpolation Intersections_2 ' - - PACKAGE='Intersections_3 Interval_skip_list Interval_support ' - - PACKAGE='Inventor Jet_fitting_3 Kernel_23 ' - - PACKAGE='Kernel_d LEDA Linear_cell_complex ' - - PACKAGE='MacOSX Maintenance Matrix_search ' - - PACKAGE='Mesh_2 Mesh_3 Mesher_level ' - - PACKAGE='Minkowski_sum_2 Minkowski_sum_3 Modifier ' - - PACKAGE='Modular_arithmetic Nef_2 Nef_3 ' - - PACKAGE='Nef_S2 NewKernel_d Number_types ' - - PACKAGE='OpenNL Optimal_bounding_box Optimal_transportation_reconstruction_2 ' - - PACKAGE='Optimisation_basic Partition_2 Periodic_2_triangulation_2 ' - - PACKAGE='Periodic_3_mesh_3 Periodic_3_triangulation_3 Periodic_4_hyperbolic_triangulation_2 ' - - PACKAGE='Point_set_2 Point_set_3 Point_set_processing_3 ' - - PACKAGE='Poisson_surface_reconstruction_3 Polygon Polygon_mesh_processing ' - - PACKAGE='Polygonal_surface_reconstruction Polyhedron Polyhedron_IO ' - - PACKAGE='Polyline_simplification_2 Polynomial Polytope_distance_d ' - - PACKAGE='Principal_component_analysis Principal_component_analysis_LGPL Profiling_tools ' - - PACKAGE='Property_map QP_solver Random_numbers ' - - PACKAGE='Ridges_3 STL_Extension Scale_space_reconstruction_3 ' - - PACKAGE='Scripts SearchStructures Segment_Delaunay_graph_2 ' - - PACKAGE='Segment_Delaunay_graph_Linf_2 Set_movable_separability_2 Shape_detection ' - - PACKAGE='Skin_surface_3 Snap_rounding_2 Solver_interface ' - - PACKAGE='Spatial_searching Spatial_sorting Straight_skeleton_2 ' - - PACKAGE='Stream_lines_2 Stream_support Subdivision_method_3 ' - - PACKAGE='Surface_mesh Surface_mesh_approximation Surface_mesh_deformation ' - - PACKAGE='Surface_mesh_parameterization Surface_mesh_segmentation Surface_mesh_shortest_path ' - - PACKAGE='Surface_mesh_simplification Surface_mesh_skeletonization Surface_mesh_topology ' - - PACKAGE='Surface_mesher Surface_sweep_2 TDS_2 ' - - PACKAGE='TDS_3 Testsuite Tetrahedral_remeshing ' - - PACKAGE='Three Triangulation Triangulation_2 ' - - PACKAGE='Triangulation_3 Union_find Visibility_2 ' - - PACKAGE='Voronoi_diagram_2 wininst ' -compiler: clang -install: - - echo "$PWD" - - if [ -n "$TRAVIS_PULL_REQUEST_BRANCH" ] && [ "$PACKAGE" != CHECK ]; then DO_IGNORE=FALSE; for ARG in $(echo "$PACKAGE");do if [ "$ARG" = "Maintenance" ]; then continue; fi; . $PWD/.travis/test_package.sh "$PWD" "$ARG"; echo "DO_IGNORE is $DO_IGNORE"; if [ "$DO_IGNORE" = "FALSE" ]; then break; fi; done; if [ "$DO_IGNORE" = "TRUE" ]; then travis_terminate 0; fi;fi - - /usr/bin/time -f 'Spend time of %C -- %E (real)' bash .travis/install.sh - - export CXX=clang++-10 CC=clang-10; -before_script: - - wget -O doxygen_exe https://cgal.geometryfactory.com/~mgimeno/doxygen_exe - - sudo mv doxygen_exe /usr/bin/doxygen - - sudo chmod +x /usr/bin/doxygen - - mkdir -p build - - cd build - - /usr/bin/time -f 'Spend time of %C -- %E (real)' cmake -DCMAKE_CXX_FLAGS="-std=c++1y" -DCGAL_HEADER_ONLY=ON -DCMAKE_CXX_FLAGS_RELEASE=-DCGAL_NDEBUG -DWITH_examples=ON -DWITH_demos=ON -DWITH_tests=ON .. - - /usr/bin/time -f 'Spend time of %C -- %E (real)' make - - /usr/bin/time -f 'Spend time of %C -- %E (real)' sudo make install &>/dev/null - - cd .. -script: - - cd ./.travis - - /usr/bin/time -f 'Spend time of %C -- %E (real)' bash ./build_package.sh $PACKAGE -notifications: - email: - on_success: change - # default: always - on_failure: always - # default: always diff --git a/.travis/build_package.sh b/.travis/build_package.sh deleted file mode 100755 index dc41aa16dd1..00000000000 --- a/.travis/build_package.sh +++ /dev/null @@ -1,144 +0,0 @@ -#!/bin/bash -set -e -[ -n "$CGAL_DEBUG_TRAVIS" ] && set -x - -CXX_FLAGS="-DCGAL_NDEBUG -ftemplate-backtrace-limit=0" - -function mytime { - /usr/bin/time -f "Spend time of %C: %E (real)" "$@" -} -old_IFS=$IFS -IFS=$' ' -ROOT="$PWD/.." -for ARG in $(echo "$@") -do -#skip package maintenance - if [ "$ARG" = "Maintenance" ]; then - continue - fi -cd $ROOT - -#install openmesh only if necessary - if [ "$ARG" = "CHECK" ] || [ "$ARG" = BGL ] || [ "$ARG" = Convex_hull_3 ] ||\ - [ "$ARG" = Polygon_mesh_processing ] || [ "$ARG" = Property_map ] ||\ - [ "$ARG" = Surface_mesh_deformation ] || [ "$ARG" = Surface_mesh_shortest_path ] ||\ - [ "$ARG" = Surface_mesh_simplification ]; then - mytime sudo bash .travis/install_openmesh.sh - fi - - - if [ "$ARG" = "CHECK" ] - then - cd .travis - mytime ./generate_travis.sh --check - cd .. - IFS=$old_IFS - mytime zsh $ROOT/Scripts/developer_scripts/test_merge_of_branch HEAD - #test dependencies - cd $ROOT - mytime bash Scripts/developer_scripts/cgal_check_dependencies.sh --check_headers /usr/bin/doxygen - - cd .travis - #parse current matrix and check that no package has been forgotten - - IFS=$'\n' - COPY=0 - MATRIX=() - for LINE in $(cat "$PWD/packages.txt") - do - MATRIX+="$LINE " - done - - PACKAGES=() - cd .. - for f in * - do - if [ -d "$f/package_info/$f" ] - then - PACKAGES+="$f " - fi - done - - DIFFERENCE=$(echo ${MATRIX[@]} ${PACKAGES[@]} | tr ' ' '\n' | sort | uniq -u) - IFS=$' ' - if [ "${DIFFERENCE[0]}" != "" ] - then - echo "The matrix and the actual package list differ : ." - echo ${DIFFERENCE[*]} - echo "You should run generate_travis.sh." - exit 1 - fi - echo "Matrix is up to date." - #check if non standard cgal installation works - cd $ROOT - mkdir build_test - cd build_test - mytime cmake -DCMAKE_INSTALL_PREFIX=install/ -DCGAL_BUILD_THREE_DOC=TRUE .. - mytime make install - # test install with minimal downstream example - mkdir installtest - cd installtest - touch main.cpp - mkdir build - echo 'project(Example)' >> CMakeLists.txt - echo 'set(PROJECT_SRCS ${PROJECT_SOURCE_DIR}/main.cpp)' >> CMakeLists.txt - echo 'find_package(CGAL REQUIRED)' >> CMakeLists.txt - echo 'add_executable(${PROJECT_NAME} ${PROJECT_SRCS})' >> CMakeLists.txt - echo 'target_link_libraries(${PROJECT_NAME} CGAL::CGAL)' >> CMakeLists.txt - echo '#include "CGAL/remove_outliers.h"' >> main.cpp - cd build - mytime cmake -DCMAKE_INSTALL_PREFIX=../../install -DCGAL_BUILD_THREE_DOC=TRUE .. - exit 0 - fi - - if [ "$ARG" = "Installation" ] - then - mkdir build_dir - cd build_dir - cmake -DWITH_tests=ON -DBUILD_TESTING=ON .. - ctest -j2 -L CGAL_cmake_testsuite --output-on-failure - cd .. - rm -rf ./build_dir - #==-- configure all CGAL with -DWITH_examples=ON -DWITH_demos=ON -DWITH_tests=ON, and then launch CTest on a few labels. --== - mkdir config_dir - cd config_dir - cmake -DWITH_examples=ON -DWITH_demos=ON -DWITH_tests=ON -DBUILD_TESTING=ON .. - ctest -j2 -L AABB_tree --output-on-failure - cd .. - rm -rf ./config_dir - exit 0 - fi - - IFS=$old_IFS - - if [ -n "$TRAVIS_PULL_REQUEST_BRANCH" ]; then - DO_IGNORE=FALSE - . $ROOT/.travis/test_package.sh "$ROOT" "$ARG" - echo "DO_IGNORE is $DO_IGNORE" - if [ "$DO_IGNORE" = "TRUE" ]; then - continue - fi - fi - IFS=$' ' - mkdir -p build-travis - cd build-travis - WITHDEMOS=ON - if [ "$ARG" = "Polyhedron" ]; then - WITHDEMOS=OFF - fi - EXTRA_CXX_FLAGS= - case "$CC" in - clang*) - EXTRA_CXX_FLAGS="-Werror=inconsistent-missing-override" - ;; - esac - - - mytime cmake -DCMAKE_CXX_FLAGS="${CXX_FLAGS} ${EXTRA_CXX_FLAGS}" -DCGAL_DONT_OVERRIDE_CMAKE_FLAGS:BOOL=ON -DBUILD_TESTING=ON -DWITH_tests=ON -DWITH_examples=ON -DWITH_demos=$WITHDEMOS .. - mytime ctest -j2 -L $ARG'([_][A-Z]|$)' -E execution___of__ --output-on-failure -done -IFS=$old_IFS -# Local Variables: -# tab-width: 2 -# sh-basic-offset: 2 -# End: diff --git a/.travis/generate_travis.sh b/.travis/generate_travis.sh deleted file mode 100755 index cef9ff07c49..00000000000 --- a/.travis/generate_travis.sh +++ /dev/null @@ -1,94 +0,0 @@ -#!/bin/bash - -CHECK= -case $1 in - --check) CHECK=y;; -esac - -set -e -cd ../ - -if [ -f "$PWD/.travis/packages.txt" ] -then - rm "$PWD/.travis/packages.txt" -fi - -#find all the packages -PACKAGES=() -INDEX=0 -i=0 -for f in * -do - if [ -d "$f/package_info/$f" ] - then - echo "$f" >> ./tmp.txt - fi -done - LC_ALL=C sort ./tmp.txt > ./.travis/packages.txt - rm ./tmp.txt - while read p; do - PACKAGES[$INDEX]+="$p " - i=$[i+1] - if [ $i = 3 ] - then - i=0 - INDEX=$[INDEX+1] - fi -done <./.travis/packages.txt -if [ -f ".travis.yml" ] -then - #copy the current .travis.yml for later check - mv ./.travis.yml ./.travis.old -fi -#writes the first part of the file -old_IFS=$IFS -IFS=$'\n' -for LINE in $(cat "$PWD/.travis/template.txt") -do - if [ "$LINE" != " matrix:" ] - then - echo "$LINE" >> .travis.yml - else - break - fi -done -echo " matrix:" >> .travis.yml -#writes the matrix -echo " - PACKAGE='CHECK'" >> .travis.yml -for package in ${PACKAGES[@]} -do -echo " - PACKAGE='$package'" >> .travis.yml -done - -#writes the end of the file -COPY=0 -for LINE in $(cat "$PWD/.travis/template.txt") -do - if [ "$LINE" = "compiler: clang" ] - then - COPY=1 - fi - if [ $COPY = 1 ] - then - echo "$LINE" >> .travis.yml - fi -done -IFS=$' ' -#check if there are differences between the files -if ! cmp -s ./.travis.yml ./.travis.old; -then - echo ".travis.yml has changed : " - diff ./.travis.yml ./.travis.old - if [ -n "$CHECK" ]; then - echo "You should modify the file .travis/template.txt" - exit 1 - fi -fi -#erase old travis -rm ./.travis.old -IFS=$old_IFS - -# Local Variables: -# tab-width: 2 -# sh-basic-offset: 2 -# End: diff --git a/.travis/install.sh b/.travis/install.sh deleted file mode 100644 index ec1791b750e..00000000000 --- a/.travis/install.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -[ -n "$CGAL_DEBUG_TRAVIS" ] && set -x -DONE=0 -sudo add-apt-repository ppa:mikhailnov/pulseeffects -y -sudo apt-get update - -while [ $DONE = 0 ] -do - DONE=1 && sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install clang-10 zsh \ -flex bison cmake graphviz libgmp-dev libmpfr-dev libmpfi-dev zlib1g-dev libeigen3-dev \ -qtbase5-dev libqt5sql5-sqlite libqt5opengl5-dev qtscript5-dev libqt5svg5-dev qttools5-dev qttools5-dev-tools qml-module-qtgraphicaleffects libopencv-dev mesa-common-dev libmetis-dev libglu1-mesa-dev \ -libboost1.72-dev || DONE=0 && sudo apt-get update -done -exit 0 - diff --git a/.travis/install_openmesh.sh b/.travis/install_openmesh.sh deleted file mode 100644 index 9b7a4f8e890..00000000000 --- a/.travis/install_openmesh.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash -mkdir -p openmesh -cd openmesh -wget -O openmesh.tar.gz https://www.openmesh.org/media/Releases/6.3/OpenMesh-6.3.tar.gz -tar xf openmesh.tar.gz --strip-components=1 -sed -i '94i #include ' src/OpenMesh/Tools/Utils/conio.cc - -mkdir build -cd build -cmake -DBUILD_APPS=FALSE .. -make -j2 -sudo make -j2 install &>/dev/null - -#clean up -cd ../.. -rm -rf ./openmesh diff --git a/.travis/packages.txt b/.travis/packages.txt deleted file mode 100644 index 6e75cd0ad14..00000000000 --- a/.travis/packages.txt +++ /dev/null @@ -1,140 +0,0 @@ -AABB_tree -Advancing_front_surface_reconstruction -Algebraic_foundations -Algebraic_kernel_d -Algebraic_kernel_for_circles -Algebraic_kernel_for_spheres -Alpha_shapes_2 -Alpha_shapes_3 -Apollonius_graph_2 -Arithmetic_kernel -Arrangement_on_surface_2 -BGL -Barycentric_coordinates_2 -Boolean_set_operations_2 -Bounding_volumes -Box_intersection_d -CGAL_Core -CGAL_ImageIO -CGAL_ipelets -Cartesian_kernel -Circular_kernel_2 -Circular_kernel_3 -Circulator -Classification -Combinatorial_map -Cone_spanners_2 -Convex_decomposition_3 -Convex_hull_2 -Convex_hull_3 -Convex_hull_d -Distance_2 -Distance_3 -Envelope_2 -Envelope_3 -Filtered_kernel -Generalized_map -Generator -Geomview -GraphicsView -HalfedgeDS -Hash_map -Heat_method_3 -Homogeneous_kernel -Hyperbolic_triangulation_2 -Inscribed_areas -Installation -Interpolation -Intersections_2 -Intersections_3 -Interval_skip_list -Interval_support -Inventor -Jet_fitting_3 -Kernel_23 -Kernel_d -LEDA -Linear_cell_complex -MacOSX -Maintenance -Matrix_search -Mesh_2 -Mesh_3 -Mesher_level -Minkowski_sum_2 -Minkowski_sum_3 -Modifier -Modular_arithmetic -Nef_2 -Nef_3 -Nef_S2 -NewKernel_d -Number_types -OpenNL -Optimal_bounding_box -Optimal_transportation_reconstruction_2 -Optimisation_basic -Partition_2 -Periodic_2_triangulation_2 -Periodic_3_mesh_3 -Periodic_3_triangulation_3 -Periodic_4_hyperbolic_triangulation_2 -Point_set_2 -Point_set_3 -Point_set_processing_3 -Poisson_surface_reconstruction_3 -Polygon -Polygon_mesh_processing -Polygonal_surface_reconstruction -Polyhedron -Polyhedron_IO -Polyline_simplification_2 -Polynomial -Polytope_distance_d -Principal_component_analysis -Principal_component_analysis_LGPL -Profiling_tools -Property_map -QP_solver -Random_numbers -Ridges_3 -STL_Extension -Scale_space_reconstruction_3 -Scripts -SearchStructures -Segment_Delaunay_graph_2 -Segment_Delaunay_graph_Linf_2 -Set_movable_separability_2 -Shape_detection -Skin_surface_3 -Snap_rounding_2 -Solver_interface -Spatial_searching -Spatial_sorting -Straight_skeleton_2 -Stream_lines_2 -Stream_support -Subdivision_method_3 -Surface_mesh -Surface_mesh_approximation -Surface_mesh_deformation -Surface_mesh_parameterization -Surface_mesh_segmentation -Surface_mesh_shortest_path -Surface_mesh_simplification -Surface_mesh_skeletonization -Surface_mesh_topology -Surface_mesher -Surface_sweep_2 -TDS_2 -TDS_3 -Testsuite -Tetrahedral_remeshing -Three -Triangulation -Triangulation_2 -Triangulation_3 -Union_find -Visibility_2 -Voronoi_diagram_2 -wininst diff --git a/.travis/template.txt b/.travis/template.txt deleted file mode 100644 index 3b99af1ff13..00000000000 --- a/.travis/template.txt +++ /dev/null @@ -1,34 +0,0 @@ -language: cpp -dist: bionic -sudo: required -git: - depth: 3 -env: - matrix: - PACKAGES_MATRIX - -compiler: clang -install: - - echo "$PWD" - - if [ -n "$TRAVIS_PULL_REQUEST_BRANCH" ] && [ "$PACKAGE" != CHECK ]; then DO_IGNORE=FALSE; for ARG in $(echo "$PACKAGE");do if [ "$ARG" = "Maintenance" ]; then continue; fi; . $PWD/.travis/test_package.sh "$PWD" "$ARG"; echo "DO_IGNORE is $DO_IGNORE"; if [ "$DO_IGNORE" = "FALSE" ]; then break; fi; done; if [ "$DO_IGNORE" = "TRUE" ]; then travis_terminate 0; fi;fi - - /usr/bin/time -f 'Spend time of %C -- %E (real)' bash .travis/install.sh - - export CXX=clang++-10 CC=clang-10; -before_script: - - wget -O doxygen_exe https://cgal.geometryfactory.com/~mgimeno/doxygen_exe - - sudo mv doxygen_exe /usr/bin/doxygen - - sudo chmod +x /usr/bin/doxygen - - mkdir -p build - - cd build - - /usr/bin/time -f 'Spend time of %C -- %E (real)' cmake -DCMAKE_CXX_FLAGS="-std=c++1y" -DCGAL_HEADER_ONLY=ON -DCMAKE_CXX_FLAGS_RELEASE=-DCGAL_NDEBUG -DWITH_examples=ON -DWITH_demos=ON -DWITH_tests=ON .. - - /usr/bin/time -f 'Spend time of %C -- %E (real)' make - - /usr/bin/time -f 'Spend time of %C -- %E (real)' sudo make install &>/dev/null - - cd .. -script: - - cd ./.travis - - /usr/bin/time -f 'Spend time of %C -- %E (real)' bash ./build_package.sh $PACKAGE -notifications: - email: - on_success: change - # default: always - on_failure: always - # default: always diff --git a/.travis/test_package.sh b/.travis/test_package.sh deleted file mode 100644 index 7b01d24ceb4..00000000000 --- a/.travis/test_package.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash - -#Will cd $1 and test package named $2 -#to find out if it or one of its dependencies has changed in the current branch - -DO_IGNORE=FALSE -cd $1 - -if [ ! -d "$2" ]; then - echo "$2 : MISSING PACKAGE. Ignoring." - DO_IGNORE=TRUE - exit 1 -fi - - -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) -LIST_OF_DEPS=$(cat "$2/package_info/$2/dependencies") -echo "$LIST_OF_DEPS" -for flie in $LIST_OF_DEPS -do - [[ $LIST_OF_FILES =~ (^|[[:space:]])$flie($|[[:space:]]) ]] && return -done -echo "Package ignored because none of its dependencies has been modified." -DO_IGNORE=TRUE - diff --git a/.travis/windows.h b/.travis/windows.h deleted file mode 100644 index a774a068df3..00000000000 --- a/.travis/windows.h +++ /dev/null @@ -1,12 +0,0 @@ -#define MAX(a,b) (((a) > (b)) ? (a) : (b)) -#define max(a,b) (((a) > (b)) ? (a) : (b)) - -#define MIN(a,b) (((a) < (b)) ? (a) : (b)) -#define min(a,b) (((a) < (b)) ? (a) : (b)) - - -#define FAR #error named reserved in windows.h -#define far #error named reserved in windows.h - -#define Polyline #error named reserved in windows.h -#define Polygon #error named reserved in windows.h diff --git a/copyright b/copyright index cecd857d055..876931746d3 100644 --- a/copyright +++ b/copyright @@ -124,4 +124,3 @@ R = RU Groningen Width_3 E iostream ETIMU kdtree T - wininst ETIMU diff --git a/wininst/developer_scripts/CGAL.bmp b/wininst/developer_scripts/CGAL.bmp deleted file mode 100644 index ab1c3f16f2dc7030e89d635c0b2330e51010d6cc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 297702 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 ${NSIS_MAX_STRLEN} - SetErrors - MessageBox MB_OK|MB_ICONEXCLAMATION "Current $R0 $1 length ($6) too long to modify in NSIS; set manually if needed" - DetailPrint "Current $R0 $1 length ($6) too long to modify in NSIS; set manually if needed" - Pop $8 - Pop $7 - Pop $6 - Goto EnvVarUpdate_Restore_Vars - ${EndIf} - Pop $8 - Pop $7 - Pop $6 - ;;khc - - ; Make sure we've got some work to do - ${If} $5 == "" - ${AndIf} $2 == "R" - SetErrors - DetailPrint "$1 is empty - Nothing to remove" - Goto EnvVarUpdate_Restore_Vars - ${EndIf} - - ; Step 2: Scrub EnvVar - ; - StrCpy $0 $5 ; Copy the contents to $0 - ; Remove spaces around semicolons (NOTE: spaces before the 1st entry or - ; after the last one are not removed here but instead in Step 3) - ${If} $0 != "" ; If EnvVar is not empty ... - ${Do} - ${${UN}StrStr} $7 $0 " ;" - ${If} $7 == "" - ${ExitDo} - ${EndIf} - ${${UN}StrRep} $0 $0 " ;" ";" ; Remove ';' - ${Loop} - ${Do} - ${${UN}StrStr} $7 $0 "; " - ${If} $7 == "" - ${ExitDo} - ${EndIf} - ${${UN}StrRep} $0 $0 "; " ";" ; Remove ';' - ${Loop} - ${Do} - ${${UN}StrStr} $7 $0 ";;" - ${If} $7 == "" - ${ExitDo} - ${EndIf} - ${${UN}StrRep} $0 $0 ";;" ";" - ${Loop} - - ; Remove a leading or trailing semicolon from EnvVar - StrCpy $7 $0 1 0 - ${If} $7 == ";" - StrCpy $0 $0 "" 1 ; Change ';' to '' - ${EndIf} - StrLen $6 $0 - IntOp $6 $6 - 1 - StrCpy $7 $0 1 $6 - ${If} $7 == ";" - StrCpy $0 $0 $6 ; Change ';' to '' - ${EndIf} - ; DetailPrint "Scrubbed $1: [$0]" ; Uncomment to debug - ${EndIf} - - /* Step 3. Remove all instances of the target path/string (even if "A" or "P") - $6 = bool flag (1 = found and removed PathString) - $7 = a string (e.g. path) delimited by semicolon(s) - $8 = entry counter starting at 0 - $9 = copy of $0 - $R0 = tempChar */ - - ${If} $5 != "" ; If EnvVar is not empty ... - StrCpy $9 $0 - StrCpy $0 "" - StrCpy $8 0 - StrCpy $6 0 - - ${Do} - ${${UN}StrTok} $7 $9 ";" $8 "0" ; $7 = next entry, $8 = entry counter - - ${If} $7 == "" ; If we've run out of entries, - ${ExitDo} ; were done - ${EndIf} ; - - ; Remove leading and trailing spaces from this entry (critical step for Action=Remove) - ${Do} - StrCpy $R0 $7 1 - ${If} $R0 != " " - ${ExitDo} - ${EndIf} - StrCpy $7 $7 "" 1 ; Remove leading space - ${Loop} - ${Do} - StrCpy $R0 $7 1 -1 - ${If} $R0 != " " - ${ExitDo} - ${EndIf} - StrCpy $7 $7 -1 ; Remove trailing space - ${Loop} - ${If} $7 == $4 ; If string matches, remove it by not appending it - StrCpy $6 1 ; Set 'found' flag - ${ElseIf} $7 != $4 ; If string does NOT match - ${AndIf} $0 == "" ; and the 1st string being added to $0, - StrCpy $0 $7 ; copy it to $0 without a prepended semicolon - ${ElseIf} $7 != $4 ; If string does NOT match - ${AndIf} $0 != "" ; and this is NOT the 1st string to be added to $0, - StrCpy $0 $0;$7 ; append path to $0 with a prepended semicolon - ${EndIf} ; - - IntOp $8 $8 + 1 ; Bump counter - ${Loop} ; Check for duplicates until we run out of paths - ${EndIf} - - ; Step 4: Perform the requested Action - ; - ${If} $2 != "R" ; If Append or Prepend - ${If} $6 == 1 ; And if we found the target - DetailPrint "Target is already present in $1. It will be removed and" - ${EndIf} - ${If} $0 == "" ; If EnvVar is (now) empty - StrCpy $0 $4 ; just copy PathString to EnvVar - ${If} $6 == 0 ; If found flag is either 0 - ${OrIf} $6 == "" ; or blank (if EnvVarName is empty) - DetailPrint "$1 was empty and has been updated with the target" - ${EndIf} - ${ElseIf} $2 == "A" ; If Append (and EnvVar is not empty), - StrCpy $0 $0;$4 ; append PathString - ${If} $6 == 1 - DetailPrint "appended to $1" - ${Else} - DetailPrint "Target was appended to $1" - ${EndIf} - ${Else} ; If Prepend (and EnvVar is not empty), - StrCpy $0 $4;$0 ; prepend PathString - ${If} $6 == 1 - DetailPrint "prepended to $1" - ${Else} - DetailPrint "Target was prepended to $1" - ${EndIf} - ${EndIf} - ${Else} ; If Action = Remove - ${If} $6 == 1 ; and we found the target - DetailPrint "Target was found and removed from $1" - ${Else} - DetailPrint "Target was NOT found in $1 (nothing to remove)" - ${EndIf} - ${If} $0 == "" - DetailPrint "$1 is now empty" - ${EndIf} - ${EndIf} - - ; Step 5: Update the registry at RegLoc with the updated EnvVar and announce the change - ; - ClearErrors - ${If} $3 == HKLM - WriteRegExpandStr ${hklm_all_users} $1 $0 ; Write it in all users section - ${ElseIf} $3 == HKCU - WriteRegExpandStr ${hkcu_current_user} $1 $0 ; Write it to current user section - ${EndIf} - - IfErrors 0 +4 - MessageBox MB_OK|MB_ICONEXCLAMATION "Could not write updated $1 to $3" - DetailPrint "Could not write updated $1 to $3" - Goto EnvVarUpdate_Restore_Vars - - ; "Export" our change - SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 - - EnvVarUpdate_Restore_Vars: - ; - ; Restore the user's variables and return ResultVar - Pop $R0 - Pop $9 - Pop $8 - Pop $7 - Pop $6 - Pop $5 - Pop $4 - Pop $3 - Pop $2 - Pop $1 - Push $0 ; Push my $0 (ResultVar) - Exch - Pop $0 ; Restore his $0 - -FunctionEnd - -!macroend ; EnvVarUpdate UN -!insertmacro EnvVarUpdate "" -!insertmacro EnvVarUpdate "un." -;----------------------------------- EnvVarUpdate end---------------------------------------- - -!verbose pop -!endif diff --git a/wininst/developer_scripts/TextLog.nsh b/wininst/developer_scripts/TextLog.nsh deleted file mode 100644 index d5acf247746..00000000000 --- a/wininst/developer_scripts/TextLog.nsh +++ /dev/null @@ -1,68 +0,0 @@ -# TextLog.nsh v1.1 - 2005-12-26 -# Written by Mike Schinkel [http://www.mikeschinkel.com/blog/] - -Var /GLOBAL __TextLog_FileHandle -Var /GLOBAL __TextLog_FileName -Var /GLOBAL __TextLog_State - -!define LogMsg '!insertmacro LogMsgCall' -!macro LogMsgCall _text - Call LogSetOn - Push "${_text}" - Call LogText - Call LogSetOff -!macroend - - -!define LogText '!insertmacro LogTextCall' -!macro LogTextCall _text - Push "${_text}" - Call LogText -!macroend - -Function LogText - Exch $0 ; pABC -> 0ABC - FileWrite $__TextLog_FileHandle "$0$\r$\n" - Pop $0 ; 0ABC -> ABC -FunctionEnd - -!define LogSetFileName '!insertmacro LogSetFileNameCall' -!macro LogSetFileNameCall _filename - Push "${_filename}" - Call LogSetFileName -!macroend - -Function LogSetFileName - Exch $0 ; pABC -> 0ABC - StrCpy $__TextLog_FileName "$0" - StrCmp $__TextLog_State "open" +1 +3 - Call LogSetOff - Call LogSetOn - Pop $0 ; 0ABC -> ABC -FunctionEnd - -!define LogSetOn '!insertmacro LogSetOnCall' -!macro LogSetOnCall - Call LogSetOn -!macroend - -Function LogSetOn - StrCmp $__TextLog_FileName "" +1 AlreadySet - StrCpy $__TextLog_FileName "$INSTDIR\install.log" -AlreadySet: - StrCmp $__TextLog_State "open" +2 - FileOpen $__TextLog_FileHandle "$__TextLog_FileName" a - FileSeek $__TextLog_FileHandle 0 END - StrCpy $__TextLog_State "open" -FunctionEnd - -!define LogSetOff '!insertmacro LogSetOffCall' -!macro LogSetOffCall - Call LogSetOff -!macroend - -Function LogSetOff - StrCmp $__TextLog_State "open" +1 +2 - FileClose $__TextLog_FileHandle - StrCpy $__TextLog_State "" -FunctionEnd \ No newline at end of file diff --git a/wininst/developer_scripts/WriteEnvStr.nsh b/wininst/developer_scripts/WriteEnvStr.nsh deleted file mode 100644 index 2cc863b3344..00000000000 --- a/wininst/developer_scripts/WriteEnvStr.nsh +++ /dev/null @@ -1,183 +0,0 @@ -# -# Taken from http://nsis.sourceforge.net/Setting_Environment_Variables -# User handling modified by Fernando Cacciola -# Laurent Rineau added un.DeleteEnvStr and adapted it to handle user. -# -!ifndef _WriteEnvStr_nsh -!define _WriteEnvStr_nsh - -# -# Macro definition added by Fernando Cacciola -# -!define WriteEnvStr "!insertmacro WriteEnvStr" -!macro WriteEnvStr name value all_users - Push ${name} - Push ${value} - Push ${all_users} - Call WriteEnvStr -!macroend - -!define un.DeleteEnvStr "!insertmacro un.DeleteEnvStr" -!macro un.DeleteEnvStr name all_users - Push ${name} - Push ${all_users} - Call un.DeleteEnvStr -!macroend - -!include WinMessages.nsh - -!define WriteEnvStr_RegKey_AllUsers 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"' - -!define WriteEnvStr_RegKey_CurrentUser 'HKCU "Environment"' - -# -# WriteEnvStr - Writes an environment variable -# Note: Win9x systems requires reboot -# -# Example: -# Push "HOMEDIR" # name -# Push "C:\New Home Dir\" # value -# Push 1 (all users) or 0 (current user only) -# Call WriteEnvStr -# -Function WriteEnvStr - Exch $2 ; $2 all users? - Exch - Exch $1 ; $1 has environment variable value - Exch 2 - Exch $0 ; $0 has environment variable name - Push $3 - - Call IsNT - Pop $3 - StrCmp $3 1 WriteEnvStr_NT - ; Not on NT - StrCpy $3 $WINDIR 2 ; Copy drive of windows (c:) - FileOpen $3 "$3\autoexec.bat" a - FileSeek $3 0 END - FileWrite $3 "$\r$\nSET $0=$1$\r$\n" - FileClose $3 - SetRebootFlag true - Goto WriteEnvStr_done - - WriteEnvStr_NT: - StrCmp $2 1 AllUsers - WriteRegExpandStr ${WriteEnvStr_RegKey_CurrentUser} $0 $1 - Goto Written - AllUsers: - WriteRegExpandStr ${WriteEnvStr_RegKey_AllUsers} $0 $1 - Written: - SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 - - WriteEnvStr_done: - Pop $3 - Pop $2 - Pop $0 - Pop $1 -FunctionEnd - -# -# un.DeleteEnvStr - Removes an environment variable -# Note: Win9x systems requires reboot -# -# Example: -# Push "HOMEDIR" # name -# Push 1 (all users) or 0 (current user only) -# Call un.DeleteEnvStr -# -Function un.DeleteEnvStr - Exch $1 ; $1 all users? - Exch - Exch $0 ; $0 now has the name of the variable - Push $2 - Push $3 - Push $4 - Push $5 - Push $6 - - Call un.IsNT - Pop $2 - StrCmp $2 1 DeleteEnvStr_NT - ; Not on NT - StrCpy $2 $WINDIR 2 - FileOpen $2 "$2\autoexec.bat" r - GetTempFileName $5 - FileOpen $3 $5 w - StrCpy $0 "SET $0=" - SetRebootFlag true - - DeleteEnvStr_dosLoop: - FileRead $2 $4 - StrLen $6 $0 - StrCpy $6 $4 $6 - StrCmp $6 $0 DeleteEnvStr_dosLoop - StrCmp $6 "" DeleteEnvStr_dosLoopEnd - FileWrite $3 $4 - Goto DeleteEnvStr_dosLoop - - DeleteEnvStr_dosLoopEnd: - FileClose $3 - FileClose $2 - StrCpy $2 $WINDIR 2 - Delete "$2\autoexec.bat" - CopyFiles /SILENT $5 "$2\autoexec.bat" - Delete $5 - Goto DeleteEnvStr_done - - DeleteEnvStr_NT: - StrCmp $1 1 DelAllUsers - DeleteRegValue ${WriteEnvStr_RegKey_CurrentUser} $0 - Goto DelWritten - DelAllUsers: - DeleteRegValue ${WriteEnvStr_RegKey_AllUsers} $0 - DelWritten: - SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} \ - 0 "STR:Environment" /TIMEOUT=5000 - - DeleteEnvStr_done: - Pop $6 - Pop $5 - Pop $4 - Pop $3 - Pop $2 - Pop $1 - Pop $0 -FunctionEnd - -!ifndef IsNT_KiCHiK -!define IsNT_KiCHiK - -# -# [un.]IsNT - Pushes 1 if running on NT, 0 if not -# -# Example: -# Call IsNT -# Pop $0 -# StrCmp $0 1 +3 -# MessageBox MB_OK "Not running on NT!" -# Goto +2 -# MessageBox MB_OK "Running on NT!" -# -!macro IsNT UN -Function ${UN}IsNT - Push $0 - ReadRegStr $0 HKLM \ - "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion - StrCmp $0 "" 0 IsNT_yes - ; we are not NT. - Pop $0 - Push 0 - Return - - IsNT_yes: - ; NT!!! - Pop $0 - Push 1 -FunctionEnd -!macroend -!insertmacro IsNT "" -!insertmacro IsNT "un." - -!endif ; IsNT_KiCHiK - -!endif ; _WriteEnvStr_nsh diff --git a/wininst/developer_scripts/cgal.ico b/wininst/developer_scripts/cgal.ico deleted file mode 100644 index 8b074d58e5aaa6382285cbc7803742ccf01db9d5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1078 zcmc(dF>b>!3`OanfCnu(f~O+K=m~n3Y#OxqNZK@T@ezEC-okxfvJxjiivS%;NBaKc zr$o{*8|-A~^VwvV!R#HJrpCWcW}o;j_~e;bgT1kv&2?{^Vl6{_Zozr38tuHYW?Pnp z_*Q?mZF*zz$i?Q}f@e1iE(|!)RqVWDu9}|ZE{;@rSv$FRY+Cp|-u3$lT=OT>oF>)> ztIvt?-t5&mt?Nq83v=4*&NjxVd9|CoSaiQyV#(kLGd$VIFuhzgm{B|=CRD1f@!~w0 zxOt6xig=9lofj$Kq4AQ$bKv%Reu9-GURr+Rs^ZS|MLivOv=GUs4ws&8=qRZlaPRVG zklxTY9251a?S>(wLh(+kH>6lB6=BBz#3fg}B6&y7U*>_|bY0)i{SBY%Io7MXANpYq KPp0nv)4l;Q7-zQt diff --git a/wininst/developer_scripts/cgal_very_small_FFFFFF.bmp b/wininst/developer_scripts/cgal_very_small_FFFFFF.bmp deleted file mode 100644 index 31c859b9ce7e7cf34f3c14339c6248f7970aa5ce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15594 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 diff --git a/wininst/developer_scripts/default_variants.ini b/wininst/developer_scripts/default_variants.ini deleted file mode 100644 index 3a60f973c27..00000000000 --- a/wininst/developer_scripts/default_variants.ini +++ /dev/null @@ -1,93 +0,0 @@ -[Settings] -NumFields=11 - -[Field 1] -Type=GroupBox -Left=0 -Right=-1 -Top=0 -Bottom=-5 -Text=Select default variants - -[Field 2] -Type=GroupBox -Left=5 -Right=100 -Top=10 -Bottom=-10 -Text=Compilers - -[Field 3] -Type=GroupBox -Left=105 -Right=-5 -Top=10 -Bottom=-10 -Text=Variants - -[Field 4] -Type=CheckBox -Left=10 -Top=22 -Right=95 -Bottom=32 -Text=Visual C++ 7.1 - -[Field 5] -Type=CheckBox -Left=10 -Top=35 -Right=95 -Bottom=45 -Text=Visual C++ 8.0 - -; -- Variants - -[Field 6] -Type=CheckBox -Left=110 -Top=22 -Right=-10 -Bottom=32 -Text=Multithread Debug - -[Field 7] -Type=CheckBox -Left=110 -Right=-15 -Top=35 -Bottom=45 -Text=Multithread - -[Field 8] -Type=CheckBox -Left=110 -Right=-10 -Top=48 -Bottom=58 -Text=Multithread, static runtime - -[Field 9] -Type=CheckBox -Left=110 -Right=-10 -Top=61 -Bottom=71 -Text=Multithread Debug, static runtime - -[Field 10] -Type=CheckBox -Left=110 -Right=-10 -Top=74 -Bottom=84 -Text=Single thread, static runtime - -[Field 11] -Type=CheckBox -Left=110 -Right=-10 -Top=87 -Bottom=97 -Text=Single thread Debug, static runtime - diff --git a/wininst/developer_scripts/environment_variables.ini b/wininst/developer_scripts/environment_variables.ini deleted file mode 100644 index deab1792eae..00000000000 --- a/wininst/developer_scripts/environment_variables.ini +++ /dev/null @@ -1,90 +0,0 @@ -[Settings] -NumFields=10 - -[Field 1] -Type=GroupBox -Left=0 -Right=-1 -Top=0 -Bottom=23 -Text=Select user - -[Field 2] -Type=RadioButton -Left=10 -Right=80 -Top=10 -Bottom=20 -Text=All users -State=0 - -[Field 3] -Type=RadioButton -Left=90 -Right=160 -Top=10 -Bottom=20 -Text=Current user -State=1 - -[Field 4] -Type=GroupBox -Left=0 -Right=-1 -Top=25 -Bottom=-1 -Text=Environment variables to set - -[Field 5] -Type=Label -Left=10 -Right=-10 -Top=40 -Bottom=50 -Text=Directory where CGAL has been installed. - - -[Field 6] -Type=CheckBox -Left=20 -Right=75 -Top=55 -Bottom=65 -Text=CGAL_DIR -State=1 - -[Field 7] -Type=Text -Left=20 -Right=-10 -Top=70 -Bottom=85 -Text= -Flags=READONLY - -[Field 8] -Type=Label -Left=80 -Right=-10 -Top=55 -Bottom=65 -Text= -Flags=DISABLED - -[Field 9] -Type=CheckBox -Left=10 -Right=-10 -Top=95 -Bottom=105 -Text=Add CGAL/auxiliary/gmp/lib to the PATH -State=1 - -[Field 10] -Type=Label -Left=10 -Right=-10 -Top=110 -Bottom=135 -Text=CGAL/auxiliary/gmp/lib contains DLL files. If you do not add this to the PATH, make sure to manually move the DLLs to a directory already in the PATH. -Flags=DISABLED diff --git a/wininst/developer_scripts/fixup_projects.ini b/wininst/developer_scripts/fixup_projects.ini deleted file mode 100644 index af0f5856c55..00000000000 --- a/wininst/developer_scripts/fixup_projects.ini +++ /dev/null @@ -1,27 +0,0 @@ -[Settings] -NumFields=3 - -[Field 1] -Type=GroupBox -Left=0 -Right=-1 -Top=0 -Bottom=-5 -Text=Post-install changes to Visual Studio project files - -[Field 2] -Type=CheckBox -Left=10 -Right=-10 -Top=20 -Bottom=30 -Text=Remove CGAL_USE_GMP from all installed project files -State=1 - -[Field 3] -Type=Label -Left=20 -Right=-10 -Top=35 -Bottom=45 -Text=(because MPFR/GMP has not been installed) diff --git a/wininst/developer_scripts/locate.zip b/wininst/developer_scripts/locate.zip deleted file mode 100644 index 372f1eda265e25d491bf20a14ecf1eb519a928ca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47393 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

    RMVcm;Bv7W+!aV&v@lIv>ToW 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%0D%9^YL&Ow(KGv}n7yXD)rt_ZC-deTt<4lqtjS=) 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 0 - ${Do} - ${locate::Find} $0 $1 $2 $3 $4 $5 $6 - ${If} "$1" != "" - ZipDLL::extractall $1 $2 - Pop $7 - ${If} "$7" == "success" - Delete $1 - ${EndIf} - ${EndIf} - ${LoopUntil} "$1" == "" - ${EndIf} - ${locate::Close} $0 - ${locate::Unload} - -SectionEnd - -;-------------------------------- -;Uninstaller Section - -Section "Uninstall" - - ;ADD YOUR OWN FILES HERE... - - Delete "$INSTDIR\Uninstall.exe" - - RMDir /r "$INSTDIR" - - ReadRegStr $RegLoc HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${CGAL_SRC}" \ - "CGALUninstallRegLoc" - - DeleteRegKey /ifempty HKCU "Software\${CGAL_SRC}" - DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${CGAL_SRC}" - - ${un.EnvVarUpdate} $0 "PATH" "R" $RegLoc "$INSTDIR\auxiliary\gmp\lib" - ${If} $RegLoc == HKLM - ${un.DeleteEnvStr} "CGAL_DIR" 1 - ${Else} - ${un.DeleteEnvStr} "CGAL_DIR" 0 - ${EndIf} - -SectionEnd - - - - -;-------------------------------- -;Descriptions - - ;Language strings - LangString DESC_MAIN ${LANG_ENGLISH} "The main components of the CGAL Library." - LangString DESC_SAMPLES ${LANG_ENGLISH} "The CGAL demos and examples, for which you need Qt 5 in order to build them (and Qt 3 for some)." - LangString DESC_GMP_LIB ${LANG_ENGLISH} "The precompiled GMP and MPFR libraries (needed for exact constructions)." - LangString DESC_DOC ${LANG_ENGLISH} "The HTML manuals." - LangString DESC_ENVSET ${LANG_ENGLISH} "already set" - - ;Assign language strings to sections - !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN - !insertmacro MUI_DESCRIPTION_TEXT ${MAIN_Idx} $(DESC_MAIN) - !insertmacro MUI_DESCRIPTION_TEXT ${SAMPLES_Idx} $(DESC_SAMPLES) - !insertmacro MUI_DESCRIPTION_TEXT ${GMP_LIB_Idx} $(DESC_GMP_LIB) - !insertmacro MUI_DESCRIPTION_TEXT ${DOC_Idx} $(DESC_DOC) - !insertmacro MUI_FUNCTION_DESCRIPTION_END - - -;-------------------------------- -; Functions -;-------------------------------- - -Function .onInit - - # Setup the default installation dir - ${If} $InstDir == "" ; /D= was not used on the command line - StrCpy $InstDir "C:\dev\${CGAL_SRC}" - ${EndIf} - - !ifdef DebugLog - ${LogSetFileName} "${CGAL_SRC}_install_log.txt" - ${LogSetOn} - !endif - - StrCpy $Platform "win32" - - # the plugins dir is automatically deleted when the installer exits - InitPluginsDir - File /oname=$PLUGINSDIR\splash.bmp ".\CGAL.bmp" - advsplash::show 1000 600 400 -1 $PLUGINSDIR\splash - - !insertmacro MUI_INSTALLOPTIONS_EXTRACT "variants.ini" - !insertmacro MUI_INSTALLOPTIONS_EXTRACT "environment_variables.ini" - -FunctionEnd - - -Function .onInstSuccess - - ${If} $SetCGAL_DIR != "" - ; RegLoc can be either HKLM (all users) or HKCU (current user). - ${If} $RegLoc == HKLM - ${WriteEnvStr} "CGAL_DIR" $SetCGAL_DIR 1 - ${Else} - ${WriteEnvStr} "CGAL_DIR" $SetCGAL_DIR 0 - ${Endif} - ${EndIf} - - ${If} $Add_GMP_LIB_DIR_to_PATH = 1 - ; Append "$INSTDIR\auxiliary\gmp\lib" to the PATH. - ; RegLoc can be either HKLM (all users) or HKCU (current user). - ; The return value goes to $0 - ${EnvVarUpdate} $0 "PATH" "A" $RegLoc "$INSTDIR\auxiliary\gmp\lib" - ${EndIf} - -FunctionEnd - -Function VariantsPage - - !insertmacro MUI_HEADER_TEXT "Select platform" "Choose the platform for precompiled libraries." - !insertmacro MUI_INSTALLOPTIONS_INITDIALOG "variants.ini" - !insertmacro MUI_INSTALLOPTIONS_SHOW - - !insertmacro MUI_INSTALLOPTIONS_READ $0 "variants.ini" "Field 1" "State" - ${If} $0 = 1 - StrCpy $Platform "win32" - ${Else} - StrCpy $Platform "x64" - ${Endif} - -FunctionEnd - -# Disables the env var checkbox # FN and textbox # FN+1 -!macro UncheckEnvStrCheckbox FN - !insertmacro MUI_INSTALLOPTIONS_WRITE "environment_variables.ini" "Field ${FN}" "State" "0" -!macroend - -!macro CheckEnvStrCheckbox FN - !insertmacro MUI_INSTALLOPTIONS_WRITE "environment_variables.ini" "Field ${FN}" "State" "1" -!macroend - -!macro DisableEnvStrCheckbox FN - !insertmacro MUI_INSTALLOPTIONS_WRITE "environment_variables.ini" "Field ${FN}" "Flags" "DISABLED" -!macroend - -!macro EnableEnvStrCheckbox FN - !insertmacro MUI_INSTALLOPTIONS_WRITE "environment_variables.ini" "Field ${FN}" "Flags" "" -!macroend - -# Disables the env var checkbox # FN -!macro SetEnvStrValueSlot FN VAL - !insertmacro MUI_INSTALLOPTIONS_WRITE "environment_variables.ini" "Field ${FN}" "State" "${VAL}" -!macroend - -!macro SetEnvStrLabel FN VAL - !insertmacro MUI_INSTALLOPTIONS_WRITE "environment_variables.ini" "Field ${FN}" "Text" "${VAL}" -!macroend - - -Function envarsPage - - Push $0 - Push $1 - Push $2 - Push $3 - Push $4 - Push $5 - - - !insertmacro MUI_HEADER_TEXT "Setting Environment Variables" "Choose whether to set or not the following environment variables" - - ReadEnvStr $1 "CGAL_DIR" # $1 = existing value for CGAL_DIR - - !insertmacro SetEnvStrValueSlot 7 $INSTDIR - !insertmacro SetEnvStrValueSlot 7 $INSTDIR - - ${If} $1 != "" - StrCpy $3 "($(DESC_ENVSET): $1 )" - !insertmacro UncheckEnvStrCheckbox 6 - !insertmacro SetEnvStrLabel 8 $3 - ${Endif} - - SectionGetText ${GMP_LIB_Idx} $2 - - SectionGetFlags ${GMP_LIB_Idx} $1 - IntOp $2 $1 & ${SF_SELECTED} - - ${If} $2 == 0 - !insertmacro UncheckEnvStrCheckbox 9 - !insertmacro DisableEnvStrCheckbox 9 - ${Else} - !insertmacro CheckEnvStrCheckbox 9 - !insertmacro EnableEnvStrCheckbox 9 - ${Endif} - - !insertmacro MUI_INSTALLOPTIONS_INITDIALOG "environment_variables.ini" - - !insertmacro MUI_INSTALLOPTIONS_SHOW_RETURN - Pop $0 - ${If} "$0" = "success" - # PROCESSING - Installs selected environment variables - - !insertmacro MUI_INSTALLOPTIONS_READ $3 "environment_variables.ini" "Field 2" "State" # $3=Is ALL USERS selected - - ${If} $3 == 1 - StrCpy $RegLoc "HKLM" - ${Else} - StrCpy $RegLoc "HKCU" - ${EndIf} - - !insertmacro MUI_INSTALLOPTIONS_READ $3 "environment_variables.ini" "Field 6" "State" # CGAL_DIR checkbox - !insertmacro MUI_INSTALLOPTIONS_READ $4 "environment_variables.ini" "Field 7" "State" # CGAL_DIR value - ${If} $3 == 1 - StrCpy $SetCGAL_DIR $4 - ${EndIF} - - !insertmacro MUI_INSTALLOPTIONS_READ $5 "environment_variables.ini" "Field 9" "State" # Add to PATH checkbox - ${If} $5 == 1 - StrCpy $Add_GMP_LIB_DIR_to_PATH 1 - ${EndIF} - - ${EndIf} - - Pop $5 - Pop $4 - Pop $3 - Pop $2 - Pop $1 - Pop $0 - -FunctionEnd diff --git a/wininst/developer_scripts/variants.ini b/wininst/developer_scripts/variants.ini deleted file mode 100644 index 2b838dbff97..00000000000 --- a/wininst/developer_scripts/variants.ini +++ /dev/null @@ -1,19 +0,0 @@ -[Settings] -NumFields=2 - -[Field 1] -Type=RadioButton -Text=32-bits -Left=10 -Right=-10 -Top=2 -Bottom=12 -State=1 - -[Field 2] -Type=RadioButton -Text=64-bits -Left=10 -Right=-10 -Top=15 -Bottom=24 diff --git a/wininst/developer_scripts/zirkel.bmp b/wininst/developer_scripts/zirkel.bmp deleted file mode 100644 index e4ef234b0b2ff68995c72f5b1b898c8a91df80bc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 88182 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 diff --git a/wininst/package_info/wininst/copyright b/wininst/package_info/wininst/copyright deleted file mode 100644 index a35c66ade4c..00000000000 --- a/wininst/package_info/wininst/copyright +++ /dev/null @@ -1,5 +0,0 @@ -Utrecht University (The Netherlands), -ETH Zurich (Switzerland), -INRIA Sophia-Antipolis (France), -Max-Planck-Institute Saarbruecken (Germany), -Tel-Aviv University (Israel). diff --git a/wininst/package_info/wininst/dependencies b/wininst/package_info/wininst/dependencies deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/wininst/package_info/wininst/description.txt b/wininst/package_info/wininst/description.txt deleted file mode 100644 index 083e45cb0e2..00000000000 --- a/wininst/package_info/wininst/description.txt +++ /dev/null @@ -1 +0,0 @@ -Win32-specific installation procedures diff --git a/wininst/package_info/wininst/maintainer b/wininst/package_info/wininst/maintainer deleted file mode 100644 index 4f45ddcd216..00000000000 --- a/wininst/package_info/wininst/maintainer +++ /dev/null @@ -1 +0,0 @@ -Andreas Fabri From c1bb6b144b4b3ee1f70600b1943804a09478e5b4 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 2 Feb 2021 08:37:00 +0000 Subject: [PATCH 139/248] SDG_Linf_2: Cast enum to fix warning --- .../Voronoi_vertex_sqrt_field_new_C2.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Segment_Delaunay_graph_Linf_2/include/CGAL/Segment_Delaunay_graph_Linf_2/Voronoi_vertex_sqrt_field_new_C2.h b/Segment_Delaunay_graph_Linf_2/include/CGAL/Segment_Delaunay_graph_Linf_2/Voronoi_vertex_sqrt_field_new_C2.h index b9f1f840a89..31dac449264 100644 --- a/Segment_Delaunay_graph_Linf_2/include/CGAL/Segment_Delaunay_graph_Linf_2/Voronoi_vertex_sqrt_field_new_C2.h +++ b/Segment_Delaunay_graph_Linf_2/include/CGAL/Segment_Delaunay_graph_Linf_2/Voronoi_vertex_sqrt_field_new_C2.h @@ -684,11 +684,11 @@ private: vv = Point_2(is_r_horizontal ? (pp.x() + qq.x()) : (comp == LARGER) ? - RT(2)*coordr + CGAL::sign(signrdist)*pqdist : + RT(2)*coordr + int(CGAL::sign(signrdist))*pqdist : coordr + pp.x(), is_r_horizontal ? (comp == LARGER) ? - RT(2)*coordr + CGAL::sign(signrdist)*pqdist : + RT(2)*coordr + int(CGAL::sign(signrdist))*pqdist : coordr + pp.y() : (pp.y() + qq.y()), RT(2)); From ddd4968a5c5b7953b1a78cc758f42ba8d8617cfb Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 3 Feb 2021 16:05:24 +0000 Subject: [PATCH 140/248] More int(..) --- .../Voronoi_vertex_sqrt_field_new_C2.h | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/Segment_Delaunay_graph_Linf_2/include/CGAL/Segment_Delaunay_graph_Linf_2/Voronoi_vertex_sqrt_field_new_C2.h b/Segment_Delaunay_graph_Linf_2/include/CGAL/Segment_Delaunay_graph_Linf_2/Voronoi_vertex_sqrt_field_new_C2.h index 31dac449264..8ea07173025 100644 --- a/Segment_Delaunay_graph_Linf_2/include/CGAL/Segment_Delaunay_graph_Linf_2/Voronoi_vertex_sqrt_field_new_C2.h +++ b/Segment_Delaunay_graph_Linf_2/include/CGAL/Segment_Delaunay_graph_Linf_2/Voronoi_vertex_sqrt_field_new_C2.h @@ -579,7 +579,7 @@ private: vort = Aort - (dort)/(FT(2)); } else { vpar = Apar; - vort = Aort - CGAL::sign(dort)*absdpar; + vort = Aort - int(CGAL::sign(dort))*absdpar; } vv = Point_2(vx_, vy_); } @@ -725,9 +725,9 @@ private: } else { vv = Point_2(is_r_horizontal ? (pp.x() + qq.x()) : - (RT(2)*coordr + CGAL::sign(sdistf)*pqdist), + (RT(2)*coordr + int(CGAL::sign(sdistf))*pqdist), is_r_horizontal ? - (RT(2)*coordr + CGAL::sign(sdistf)*pqdist) : + (RT(2)*coordr + int(CGAL::sign(sdistf))*pqdist) : (pp.y() + qq.y()), RT(2)); } @@ -771,8 +771,8 @@ private: Point_2(pcoord, lineval) : Point_2(lineval, pcoord); const FT sidelen = (CGAL::max)(CGAL::abs(corner.x() - q.point().x()), CGAL::abs(corner.y() - q.point().y())); - vv = Point_2(FT(2)*corner.x() + signla*sidelen, - FT(2)*corner.y() + signlb*sidelen, + vv = Point_2(FT(2)*corner.x() + int(signla)*sidelen, + FT(2)*corner.y() + int(signlb)*sidelen, FT(2)); return; } @@ -783,8 +783,8 @@ private: Point_2(lineval, qcoord) : Point_2(qcoord, lineval); const FT sidelen = (CGAL::max)(CGAL::abs(corner.x() - p.point().x()), CGAL::abs(corner.y() - p.point().y())); - vv = Point_2(FT(2)*corner.x() + signla*sidelen, - FT(2)*corner.y() + signlb*sidelen, + vv = Point_2(FT(2)*corner.x() + int(signla)*sidelen, + FT(2)*corner.y() + int(signlb)*sidelen, FT(2)); return; } @@ -812,8 +812,8 @@ private: // is shorter than Linf p, q distance const Point_2 corner = pos_slope? Point_2(pcoord, plineval) : Point_2(plineval, pcoord); - vv = Point_2(FT(2)*corner.x() + signla*pqdist, - FT(2)*corner.y() + signlb*pqdist, + vv = Point_2(FT(2)*corner.x() + int(signla)*pqdist, + FT(2)*corner.y() + int(signlb)*pqdist, FT(2)); return; } @@ -829,8 +829,8 @@ private: // is shorter than Linf p, q distance const Point_2 corner = pos_slope? Point_2(qlineval, qcoord) : Point_2(qcoord, qlineval); - vv = Point_2(FT(2)*corner.x() + signla*pqdist, - FT(2)*corner.y() + signlb*pqdist, + vv = Point_2(FT(2)*corner.x() + int(signla)*pqdist, + FT(2)*corner.y() + int(signlb)*pqdist, FT(2)); return; } @@ -1421,12 +1421,12 @@ private: RT ux_, uy_, uz_; if (cmp == LARGER) { ux_ = is_q_hor ? r_coord + p_coord_r : q_coord + p_coord_q; - uy_ = is_q_hor ? (RT(2)*q_coord + CGAL::sign(sdistq)*dx) : - (RT(2)*r_coord + CGAL::sign(sdistr)*dx) ; + uy_ = is_q_hor ? (RT(2)*q_coord + int(CGAL::sign(sdistq))*dx) : + (RT(2)*r_coord + int(CGAL::sign(sdistr))*dx) ; } else if (cmp == SMALLER) { uy_ = is_r_hor ? r_coord + p_coord_r : q_coord + p_coord_q; - ux_ = is_r_hor ? (RT(2)*q_coord + CGAL::sign(sdistq)*dy) : - (RT(2)*r_coord + CGAL::sign(sdistr)*dy) ; + ux_ = is_r_hor ? (RT(2)*q_coord + int(CGAL::sign(sdistq))*dy) : + (RT(2)*r_coord + int(CGAL::sign(sdistr))*dy) ; } else { ux_ = is_q_hor ? r_coord + p_coord_r : q_coord + p_coord_q; uy_ = is_q_hor ? q_coord + p_coord_q : r_coord + p_coord_r; From 4bc161a332edf22fdf9643c7d7d948bd14b1759f Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Fri, 12 Feb 2021 09:42:52 +0000 Subject: [PATCH 141/248] Return a triangle not a vector --- .../internal/Tetrahedron_3_Plane_3_intersection.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersection.h index 9bc5c0916a0..498ab69a56e 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersection.h @@ -36,6 +36,7 @@ intersection( const K& k) { typedef typename K::Point_3 Point_3; + typedef typename K::Triangle_3 Triangle_3; typedef typename Intersection_traits::result_type result_type; typename K::Oriented_side_3 oriented_side = k.oriented_side_3_object(); @@ -149,9 +150,9 @@ intersection( { case 3: { - std::vector res({ corners[ids[0]], - corners[ids[1]], - corners[ids[2]] }); + Triangle_3 res(corners[ids[0]], + corners[ids[1]], + corners[ids[2]]); return result_type(res); } case 2: From e833e86598aec6f4a536165573749deb317c1ab4 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Fri, 12 Feb 2021 09:43:14 +0000 Subject: [PATCH 142/248] Change the expected result (a permutation) --- Intersections_3/test/Intersections_3/test_intersections_3.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Intersections_3/test/Intersections_3/test_intersections_3.cpp b/Intersections_3/test/Intersections_3/test_intersections_3.cpp index deb48c9913f..97b895b9c1c 100644 --- a/Intersections_3/test/Intersections_3/test_intersections_3.cpp +++ b/Intersections_3/test/Intersections_3/test_intersections_3.cpp @@ -672,7 +672,8 @@ struct Test { P(0,1,0)); check_intersection (tet, Pl(P(0,0.5,0), P(1,0.5,-5), P(0.5,0.5,0.5)), - Tr(P(0.5,0.5,0), P(0,0.5,0), P(0,0.5,0.5))); + Tr(P(0, 0.5, 0), P(0.5,0.5,0), P(0,0.5,0.5))); + Pl pl(P(0,0.9,0), P(0.9,0,0), P(0.9,0.01,0.06)); typedef typename CGAL::Intersection_traits Date: Fri, 12 Feb 2021 10:36:53 +0000 Subject: [PATCH 143/248] remove trailing whitespace --- Intersections_3/test/Intersections_3/test_intersections_3.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Intersections_3/test/Intersections_3/test_intersections_3.cpp b/Intersections_3/test/Intersections_3/test_intersections_3.cpp index 97b895b9c1c..f93026b3d11 100644 --- a/Intersections_3/test/Intersections_3/test_intersections_3.cpp +++ b/Intersections_3/test/Intersections_3/test_intersections_3.cpp @@ -673,7 +673,7 @@ struct Test { check_intersection (tet, Pl(P(0,0.5,0), P(1,0.5,-5), P(0.5,0.5,0.5)), Tr(P(0, 0.5, 0), P(0.5,0.5,0), P(0,0.5,0.5))); - + Pl pl(P(0,0.9,0), P(0.9,0,0), P(0.9,0.01,0.06)); typedef typename CGAL::Intersection_traits Date: Fri, 12 Feb 2021 14:06:20 +0000 Subject: [PATCH 144/248] Restore issue to the initial bug report --- .../test/Intersections_3/issue_5428.cpp | 22 +++---------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/Intersections_3/test/Intersections_3/issue_5428.cpp b/Intersections_3/test/Intersections_3/issue_5428.cpp index 844b41943c7..ea6dc18cd0f 100644 --- a/Intersections_3/test/Intersections_3/issue_5428.cpp +++ b/Intersections_3/test/Intersections_3/issue_5428.cpp @@ -1,36 +1,20 @@ #include -#include -typedef CGAL::Exact_predicates_exact_constructions_kernel EPECK; typedef CGAL::Exact_predicates_inexact_constructions_kernel EPICK; -typedef CGAL::Cartesian_converter IK_to_EK; - typedef EPICK::Point_3 Point; int main() { - IK_to_EK to_exact; - - //EPICK::Plane_3 pl(Point(0,0,10),Point(1,0,10),Point(0,1,10)); - - // EPICK::Plane_3 pl(0.265189, 0.902464, 0.33946, -2.47551); - - EPICK::Plane_3 pl(Point(1, 1, 1), Point(1, 2, 1), Point(1, 2, 2)); - - EPECK::Plane_3 epl = to_exact(pl); + EPICK::Plane_3 pl(Point(0, 0, 0), Point(1, 0, 0), Point(0, 1, 0)); std::vector pts; - pts.push_back(Point(1,1,1)); - pts.push_back(Point(2,2,2)); + pts.push_back(Point(-10,-10,-10)); + pts.push_back(Point(10,10,10)); CGAL::Bbox_3 cub = CGAL::bbox_3(pts.begin(), pts.end()); - EPECK::Iso_cuboid_3 ecub = to_exact(cub); - auto result = intersection(cub,pl); - //auto result2 = intersection(ecub,epl); - const std::vector* res = boost::get >(&*result); for (Point p : *res) { std::cout << p << std::endl; From 4bb0406240d4377405a7bd84b1fa4fdf9fdeb050 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 4 Feb 2021 18:12:12 +0100 Subject: [PATCH 145/248] do not include boost/bind.hpp (shouldn't be used anymore) + fix remaining bind (nasty using namespace boost!) --- .../CGAL/Convex_hull_2/convexity_check_2_impl.h | 11 +++++------ Kernel_23/examples/Kernel_23/intersections.cpp | 2 -- Mesh_3/include/CGAL/Mesh_3/Slivers_exuder.h | 1 - .../include/CGAL/Partition_2/Rotation_tree_2.h | 1 - .../Periodic_4_hyperbolic_Delaunay_triangulation_2.h | 2 -- .../include/CGAL/Regular_triangulation_2.h | 1 - .../include/CGAL/Regular_triangulation_3.h | 1 - 7 files changed, 5 insertions(+), 14 deletions(-) diff --git a/Convex_hull_2/include/CGAL/Convex_hull_2/convexity_check_2_impl.h b/Convex_hull_2/include/CGAL/Convex_hull_2/convexity_check_2_impl.h index 2b9d92a8edb..3e5b88d8d6a 100644 --- a/Convex_hull_2/include/CGAL/Convex_hull_2/convexity_check_2_impl.h +++ b/Convex_hull_2/include/CGAL/Convex_hull_2/convexity_check_2_impl.h @@ -18,7 +18,6 @@ #include #include -#include namespace CGAL { @@ -139,8 +138,6 @@ ch_brute_force_check_2(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, const Traits& ch_traits) { - using namespace boost; - typedef typename Traits::Left_turn_2 Left_of_line; ForwardIterator1 iter11; ForwardIterator2 iter21; @@ -165,12 +162,13 @@ ch_brute_force_check_2(ForwardIterator1 first1, ForwardIterator1 last1, while (iter22 != last2) { iter11 = std::find_if( first1, last1, - bind(left_turn, *iter22++, *iter21++, _1) ); + [left_turn, iter22, iter21](const auto& p){ return left_turn(*iter22, *iter21, p); } ); + ++iter22; ++iter21; if (iter11 != last1 ) return false; } iter11 = std::find_if( first1, last1, - bind(left_turn, *first2, *iter21, _1) ); + [left_turn, first2, iter21](const auto& p){ return left_turn(*first2, *iter21, p); } ); if (iter11 != last1 ) return false; return true; } @@ -203,7 +201,8 @@ ch_brute_force_chain_check_2(ForwardIterator1 first1, while (iter22 != last2) { iter11 = std::find_if( first1, last1, - bind(left_turn, *iter22++, *iter21++, _1) ); + [left_turn, iter22, iter21](const auto& p){ return left_turn(*iter22, *iter21, p); } ); + ++iter22; ++iter21; if (iter11 != last1 ) return false; } diff --git a/Kernel_23/examples/Kernel_23/intersections.cpp b/Kernel_23/examples/Kernel_23/intersections.cpp index 283fd5b9aad..bbe913a36df 100644 --- a/Kernel_23/examples/Kernel_23/intersections.cpp +++ b/Kernel_23/examples/Kernel_23/intersections.cpp @@ -2,8 +2,6 @@ #include #include -#include - typedef CGAL::Exact_predicates_exact_constructions_kernel K; typedef K::Point_2 Point; typedef K::Segment_2 Segment; diff --git a/Mesh_3/include/CGAL/Mesh_3/Slivers_exuder.h b/Mesh_3/include/CGAL/Mesh_3/Slivers_exuder.h index 29c4817021f..ee91f1d3f70 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Slivers_exuder.h +++ b/Mesh_3/include/CGAL/Mesh_3/Slivers_exuder.h @@ -36,7 +36,6 @@ #include -#include #include #include #include diff --git a/Partition_2/include/CGAL/Partition_2/Rotation_tree_2.h b/Partition_2/include/CGAL/Partition_2/Rotation_tree_2.h index 07fb9bb3bb4..fa78978a4dd 100644 --- a/Partition_2/include/CGAL/Partition_2/Rotation_tree_2.h +++ b/Partition_2/include/CGAL/Partition_2/Rotation_tree_2.h @@ -34,7 +34,6 @@ #include #include -#include namespace CGAL { diff --git a/Periodic_4_hyperbolic_triangulation_2/include/CGAL/Periodic_4_hyperbolic_Delaunay_triangulation_2.h b/Periodic_4_hyperbolic_triangulation_2/include/CGAL/Periodic_4_hyperbolic_Delaunay_triangulation_2.h index cd4166330cd..0c74a7a8be4 100644 --- a/Periodic_4_hyperbolic_triangulation_2/include/CGAL/Periodic_4_hyperbolic_Delaunay_triangulation_2.h +++ b/Periodic_4_hyperbolic_triangulation_2/include/CGAL/Periodic_4_hyperbolic_Delaunay_triangulation_2.h @@ -27,8 +27,6 @@ #include #include -#include - #include #include #include diff --git a/Triangulation_2/include/CGAL/Regular_triangulation_2.h b/Triangulation_2/include/CGAL/Regular_triangulation_2.h index f9bf3b1ceb8..49a20bd585d 100644 --- a/Triangulation_2/include/CGAL/Regular_triangulation_2.h +++ b/Triangulation_2/include/CGAL/Regular_triangulation_2.h @@ -22,7 +22,6 @@ #include #include -#include #include #include #include diff --git a/Triangulation_3/include/CGAL/Regular_triangulation_3.h b/Triangulation_3/include/CGAL/Regular_triangulation_3.h index d927efad23b..34186b034a0 100644 --- a/Triangulation_3/include/CGAL/Regular_triangulation_3.h +++ b/Triangulation_3/include/CGAL/Regular_triangulation_3.h @@ -55,7 +55,6 @@ #include #endif -#include #include #include #include From 5ba988c6fa6952a334e39af595b779af40651c6d Mon Sep 17 00:00:00 2001 From: Giles Bathgate Date: Fri, 12 Feb 2021 17:38:24 +0000 Subject: [PATCH 146/248] Bypass coplanarity assertion for triangular facets --- .../CGAL/Nef_3/polygon_mesh_to_nef_3.h | 28 +++++++++++++------ 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/Nef_3/include/CGAL/Nef_3/polygon_mesh_to_nef_3.h b/Nef_3/include/CGAL/Nef_3/polygon_mesh_to_nef_3.h index f7d33128ad2..7f3dcde907b 100644 --- a/Nef_3/include/CGAL/Nef_3/polygon_mesh_to_nef_3.h +++ b/Nef_3/include/CGAL/Nef_3/polygon_mesh_to_nef_3.h @@ -192,16 +192,21 @@ void polygon_mesh_to_nef_3(PolygonMesh& P, SNC_structure& S, FaceIndexMap fimap, typedef Halfedge_around_target_circulator Halfedge_around_vertex_const_circulator; + struct Face_info + { + Vector_3 normal; + CGAL_assertion_code(std::size_t num_edges); + }; PMap pmap = get(CGAL::vertex_point,P); - std::vector normals(num_faces(P)); + std::vector face_info(num_faces(P)); for(face_descriptor f : faces(P)){ Vertex_around_face_circulator vafc(halfedge(f,P),P), done(vafc); Vector_3 v; normal_vector_newell_3(vafc, done, pmap, v); - normals[get(fimap,f)] = - v; + face_info[get(fimap,f)] = {-v,CGAL_assertion_code(circulator_size(vafc))}; } Face_graph_index_adderpoint())); + CGAL_assertion_code(if(fi.num_edges > 3) { + CGAL_assertion(ss_circle.has_on(sp)); + CGAL_assertion(ss_circle.has_on(sv_prev->point())); + }); SHalfedge_handle e = SM.new_shalfedge_pair(sv_prev, sv); e->circle() = ss_circle; @@ -280,12 +288,14 @@ void polygon_mesh_to_nef_3(PolygonMesh& P, SNC_structure& S, FaceIndexMap fimap, with_border = true; e = sv_prev->out_sedge(); } else { - Plane ss_plane( CGAL::ORIGIN, normals[get(fimap,face(pe_prev,P))] ); + const Face_info& fi=face_info[get(fimap,face(pe_prev,P))]; + Plane ss_plane( CGAL::ORIGIN, fi.normal); Sphere_circle ss_circle(ss_plane); - CGAL_assertion(ss_plane.has_on(sv_prev->point())); - CGAL_assertion(ss_circle.has_on(sp_0)); - CGAL_assertion(ss_circle.has_on(sv_prev->point())); + CGAL_assertion_code(if(fi.num_edges > 3) { + CGAL_assertion(ss_circle.has_on(sp_0)); + CGAL_assertion(ss_circle.has_on(sv_prev->point())); + }); e = SM.new_shalfedge_pair(sv_prev, sv_0); e->circle() = ss_circle; From c0c664a7e41b8ce5cd981ff2428d92ad9851fbd0 Mon Sep 17 00:00:00 2001 From: Giles Bathgate Date: Sat, 13 Feb 2021 07:27:36 +0000 Subject: [PATCH 147/248] Fix pedantic warning in polygon_mesh_to_nef_3 --- Nef_3/include/CGAL/Nef_3/polygon_mesh_to_nef_3.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Nef_3/include/CGAL/Nef_3/polygon_mesh_to_nef_3.h b/Nef_3/include/CGAL/Nef_3/polygon_mesh_to_nef_3.h index 7f3dcde907b..d3fb6660c8f 100644 --- a/Nef_3/include/CGAL/Nef_3/polygon_mesh_to_nef_3.h +++ b/Nef_3/include/CGAL/Nef_3/polygon_mesh_to_nef_3.h @@ -195,7 +195,7 @@ void polygon_mesh_to_nef_3(PolygonMesh& P, SNC_structure& S, FaceIndexMap fimap, struct Face_info { Vector_3 normal; - CGAL_assertion_code(std::size_t num_edges); + CGAL_assertion_code(std::size_t num_edges;) }; PMap pmap = get(CGAL::vertex_point,P); @@ -261,7 +261,7 @@ void polygon_mesh_to_nef_3(PolygonMesh& P, SNC_structure& S, FaceIndexMap fimap, CGAL_assertion_code(if(fi.num_edges > 3) { CGAL_assertion(ss_circle.has_on(sp)); CGAL_assertion(ss_circle.has_on(sv_prev->point())); - }); + };) SHalfedge_handle e = SM.new_shalfedge_pair(sv_prev, sv); e->circle() = ss_circle; @@ -295,7 +295,7 @@ void polygon_mesh_to_nef_3(PolygonMesh& P, SNC_structure& S, FaceIndexMap fimap, CGAL_assertion_code(if(fi.num_edges > 3) { CGAL_assertion(ss_circle.has_on(sp_0)); CGAL_assertion(ss_circle.has_on(sv_prev->point())); - }); + };) e = SM.new_shalfedge_pair(sv_prev, sv_0); e->circle() = ss_circle; From ff9ebb584731f828e27bd7412beed4c32cc37ac6 Mon Sep 17 00:00:00 2001 From: Giles Bathgate Date: Sat, 13 Feb 2021 08:23:54 +0000 Subject: [PATCH 148/248] Avoid duplicate lookups of pv in polygon_mesh_to_nef_3 --- .../include/CGAL/Nef_3/polygon_mesh_to_nef_3.h | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/Nef_3/include/CGAL/Nef_3/polygon_mesh_to_nef_3.h b/Nef_3/include/CGAL/Nef_3/polygon_mesh_to_nef_3.h index d3fb6660c8f..fa40ede4cc7 100644 --- a/Nef_3/include/CGAL/Nef_3/polygon_mesh_to_nef_3.h +++ b/Nef_3/include/CGAL/Nef_3/polygon_mesh_to_nef_3.h @@ -214,10 +214,12 @@ void polygon_mesh_to_nef_3(PolygonMesh& P, SNC_structure& S, FaceIndexMap fimap, for(vertex_descriptor pv : vertices(P) ) { + + Point_3 npv = get(pmap,pv); Vertex_handle nv = S.new_vertex(); - nv->point() = get(pmap,pv); + nv->point() = npv; nv->mark() = true; - CGAL_NEF_TRACEN("v "<< get(pmap,pv)); + CGAL_NEF_TRACEN("v "<< npv); SM_decorator SM(&*nv); Halfedge_around_vertex_const_circulator pec(pv,P), pec_prev(pec), done(pec); @@ -226,7 +228,7 @@ void polygon_mesh_to_nef_3(PolygonMesh& P, SNC_structure& S, FaceIndexMap fimap, // CGAL_assertion( pe != 0 ); Point_3 pe_target_0(get(pmap,target(opposite(pe,P),P))); - Point_3 sp_point_0(CGAL::ORIGIN+(pe_target_0 - get(pmap,pv))); + Point_3 sp_point_0(CGAL::ORIGIN+(pe_target_0 - npv)); Sphere_point sp_0(sp_point_0); SVertex_handle sv_0 = SM.new_svertex(sp_0); sv_0->mark() = true; @@ -239,11 +241,11 @@ void polygon_mesh_to_nef_3(PolygonMesh& P, SNC_structure& S, FaceIndexMap fimap, bool with_border = false; do { CGAL_assertion(face(pe_prev,P) == face(opposite(pe,P),P)); - CGAL_assertion(get(pmap,target(pe_prev,P)) == get(pmap,pv)); - CGAL_assertion(get(pmap,target(pe,P)) == get(pmap,pv)); + CGAL_assertion(get(pmap,target(pe_prev,P)) == npv); + CGAL_assertion(get(pmap,target(pe,P)) == npv); Point_3 pe_target = get(pmap,target(opposite(pe,P),P)); - Point_3 sp_point = CGAL::ORIGIN+(pe_target - get(pmap,pv)); + Point_3 sp_point = CGAL::ORIGIN+(pe_target - npv); Sphere_point sp(sp_point); SVertex_handle sv = SM.new_svertex(sp); sv->mark() = true; @@ -280,8 +282,8 @@ void polygon_mesh_to_nef_3(PolygonMesh& P, SNC_structure& S, FaceIndexMap fimap, while( pec != done ); CGAL_assertion(face(pe_prev,P) == face(opposite(*pe_0,P),P)); - CGAL_assertion(get(pmap,target(pe_prev,P)) == get(pmap,pv)); - CGAL_assertion(get(pmap,target(*pe_0,P)) == get(pmap,pv)); + CGAL_assertion(get(pmap,target(pe_prev,P)) == npv); + CGAL_assertion(get(pmap,target(*pe_0,P)) == npv); SHalfedge_handle e; if(is_border(pe_prev,P)) { From cf54055b820482d9ad1f7d730b60df95e5873b64 Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Sun, 14 Feb 2021 01:16:52 +0100 Subject: [PATCH 149/248] bitrot in Kernel_[23]_interface --- .../include/CGAL/NewKernel_d/Cartesian_LA_functors.h | 2 +- NewKernel_d/include/CGAL/NewKernel_d/Kernel_2_interface.h | 6 ++++-- NewKernel_d/include/CGAL/NewKernel_d/Kernel_3_interface.h | 6 ++++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_LA_functors.h b/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_LA_functors.h index b717a80bac4..a3d64cbc7c2 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_LA_functors.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_LA_functors.h @@ -50,7 +50,7 @@ template struct Construct_LA_vector // Makes no sense for an unknown dimension. return typename Constructor::Dimension()(this->kernel().dimension()); } - result_type operator()(result_type const& v)const{ + result_type const& operator()(result_type const& v)const{ return v; } result_type operator()(result_type&& v)const{ diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Kernel_2_interface.h b/NewKernel_d/include/CGAL/NewKernel_d/Kernel_2_interface.h index d1515d152fc..3d6d588b142 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Kernel_2_interface.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Kernel_2_interface.h @@ -79,10 +79,11 @@ template struct Kernel_2_interface : public Base_ { Side_of_oriented_circle_2(Kernel const&k):sos(k){} result_type operator()(Point_2 const&a, Point_2 const&b, Point_2 const&c, Point_2 const&d) { //return sos(a,b,c,d); - Point_2 const* t[4]={&a,&b,&c,&d}; - return sos(make_transforming_iterator(t+0),make_transforming_iterator(t+4)); + Point_2 const* t[4]={&a,&b,&c}; + return sos(make_transforming_iterator(t+0),make_transforming_iterator(t+3), d); } }; + typedef typename Get_functor >::type Construct_point_2; Less_x_2 less_x_2_object()const{ return Less_x_2(*this); } Less_y_2 less_y_2_object()const{ return Less_y_2(*this); } Compare_x_2 compare_x_2_object()const{ return Compare_x_2(*this); } @@ -90,6 +91,7 @@ template struct Kernel_2_interface : public Base_ { Compare_distance_2 compare_distance_2_object()const{ return Compare_distance_2(*this); } Orientation_2 orientation_2_object()const{ return Orientation_2(*this); } Side_of_oriented_circle_2 side_of_oriented_circle_2_object()const{ return Side_of_oriented_circle_2(*this); } + Construct_point_2 construct_point_2_object()const{ return Construct_point_2(*this); } }; } diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Kernel_3_interface.h b/NewKernel_d/include/CGAL/NewKernel_d/Kernel_3_interface.h index 6c85a4161b9..de0258ea492 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Kernel_3_interface.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Kernel_3_interface.h @@ -76,10 +76,11 @@ template struct Kernel_3_interface : public Base_ { Side_of_oriented_sphere_3(Kernel const&k):sos(k){} result_type operator()(Point_3 const&a, Point_3 const&b, Point_3 const&c, Point_3 const&d, Point_3 const&e) { //return sos(a,b,c,d); - Point_3 const* t[5]={&a,&b,&c,&d,&e}; - return sos(make_transforming_iterator(t+0),make_transforming_iterator(t+5)); + Point_3 const* t[5]={&a,&b,&c,&d}; + return sos(make_transforming_iterator(t+0),make_transforming_iterator(t+4),e); } }; + typedef typename Get_functor >::type Construct_point_3; // I don't have the Coplanar predicates (yet) @@ -88,6 +89,7 @@ template struct Kernel_3_interface : public Base_ { Compare_distance_3 compare_distance_3_object()const{ return Compare_distance_3(*this); } Orientation_3 orientation_3_object()const{ return Orientation_3(*this); } Side_of_oriented_sphere_3 side_of_oriented_sphere_3_object()const{ return Side_of_oriented_sphere_3(*this); } + Construct_point_3 construct_point_3_object()const{ return Construct_point_3(*this); } }; } From 82fa63d7209534fe4695bcfec239b939d8206677 Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Mon, 15 Feb 2021 21:06:38 +0100 Subject: [PATCH 150/248] New benchmark/test. --- NewKernel_d/test/NewKernel_d/tri2.cpp | 77 +++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 NewKernel_d/test/NewKernel_d/tri2.cpp diff --git a/NewKernel_d/test/NewKernel_d/tri2.cpp b/NewKernel_d/test/NewKernel_d/tri2.cpp new file mode 100644 index 00000000000..eab4e5d2d62 --- /dev/null +++ b/NewKernel_d/test/NewKernel_d/tri2.cpp @@ -0,0 +1,77 @@ +// Benchmark on the construction of Delaunay 2D with Epick (Kernel_23) vs +// something based on NewKernel_d that uses Eigen::Vector2d as Point_2. +#if __cpp_aligned_new >= 201606L +#if 1 +#define CGAL_NEWKERNEL_D_USE_EIGEN_VECTOR 1 +#include +#include +#include + +namespace CGAL { +struct Epick_2_help1 +: Cartesian_filter_K< + Cartesian_base_d>, + Cartesian_base_d>, + Cartesian_base_d::Type, CGAL::Dimension_tag<2>> + > +{ +}; +struct Epick_2_help2 +: Cartesian_filter_K< + Epick_2_help1, + Cartesian_base_d>, + Cartesian_base_d::Type, CGAL::Dimension_tag<2>>, + Functors_without_division>::type + > +{ }; +struct Epick_2 +: Kernel_2_interface,Epick_2_help2>> +{ }; +template <> +struct Triangulation_structural_filtering_traits { + typedef Tag_true Use_structural_filtering_tag; +}; +} +typedef CGAL::Epick_2 K; +static_assert(std::is_same::value, ""); +#else +#include +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +#endif + +#include +#include +#include +#include +#include + +typedef CGAL::Delaunay_triangulation_2 DT; +typedef DT::Point Point_2; + +int main(int argc,char** argv) +{ + int n = (argc > 1) ? atoi(argv[1]) : 100000; + std::vector points; + points.reserve( n ); + + std::mt19937 gen(1234); + std::uniform_real_distribution<> dis(1.0, 2.0); + for(int i=0;i +int main(){ + std::cerr << "This program requires C++17 or later.\n"; +} +#endif From bf2940de3d8924c4ffe6f822f23f678ec0076b1d Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Mon, 15 Feb 2021 21:29:17 +0100 Subject: [PATCH 151/248] Tell cmake to build those tests... --- NewKernel_d/test/NewKernel_d/CMakeLists.txt | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/NewKernel_d/test/NewKernel_d/CMakeLists.txt b/NewKernel_d/test/NewKernel_d/CMakeLists.txt index c039a4e45b0..931c38db9a0 100644 --- a/NewKernel_d/test/NewKernel_d/CMakeLists.txt +++ b/NewKernel_d/test/NewKernel_d/CMakeLists.txt @@ -18,13 +18,20 @@ find_package(CGAL REQUIRED) find_package(Eigen3) include(CGAL_Eigen3_support) if(TARGET CGAL::Eigen3_support) - create_single_source_cgal_program("Epick_d.cpp") - target_link_libraries(Epick_d PUBLIC CGAL::Eigen3_support) + file( + GLOB cppfiles + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) + foreach(cppfile ${cppfiles}) + get_filename_component(target ${cppfile} NAME_WE) + create_single_source_cgal_program("${cppfile}") + target_link_libraries(${target} PUBLIC CGAL::Eigen3_support) + endforeach() else() message( STATUS - "NOTICE: This program requires the Eigen3 library, and will not be compiled." + "NOTICE: These programs require the Eigen3 library, and will not be compiled." ) endif() From ed44ebff0fc9ade061f03bed01972f806a0348c9 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 16 Feb 2021 10:43:04 +0000 Subject: [PATCH 152/248] Improve documentation of overlapping polylines --- Installation/CHANGES.md | 2 +- .../Polyline_simplification_2.txt | 10 ++++++++++ .../doc/Polyline_simplification_2/examples.txt | 1 + .../fig/overlapping_polylines.png | Bin 0 -> 6604 bytes ...ne.cpp => simplify_overlapping_polylines.cpp} | 0 5 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 Polyline_simplification_2/doc/Polyline_simplification_2/fig/overlapping_polylines.png rename Polyline_simplification_2/examples/Polyline_simplification_2/{simplify_overlapping_polyline.cpp => simplify_overlapping_polylines.cpp} (100%) diff --git a/Installation/CHANGES.md b/Installation/CHANGES.md index f03ce6d5d42..4e57c07e69b 100644 --- a/Installation/CHANGES.md +++ b/Installation/CHANGES.md @@ -26,7 +26,7 @@ A comprehensive list of the supported file formats is available in the Stream_su - Added the class `Polyhedral_envelope_filter` that enables to perform mesh simplification inside a polyhedral envelope of the input mesh. ### [2D Polyline Simplification](https://doc.cgal.org/5.3/Manual/packages.html#PkgPolylineSimplification2) -- Subsequences of polylines that are shared are no longer marked as unremovable. +- When polylines have common subsequences of vertices these subsequences may be simplifified simultaneously. [Release 5.2](https://github.com/CGAL/cgal/releases/tag/v5.2) ----------- diff --git a/Polyline_simplification_2/doc/Polyline_simplification_2/Polyline_simplification_2.txt b/Polyline_simplification_2/doc/Polyline_simplification_2/Polyline_simplification_2.txt index 63a0387263f..1900522d579 100644 --- a/Polyline_simplification_2/doc/Polyline_simplification_2/Polyline_simplification_2.txt +++ b/Polyline_simplification_2/doc/Polyline_simplification_2/Polyline_simplification_2.txt @@ -167,6 +167,16 @@ over all vertices of all polyline constraints. \cgalExample{Polyline_simplification_2/simplify.cpp} +Note that when polylines share subsequences of polyline vertices they can get simplified simultaneously. + +\cgalFigureBegin{figure_overlapping_polylines, overlapping_polylines.png} +Simplification of overlapping subsequence of polyline vertices +\cgalFigureEnd + +\cgalExample{Polyline_simplification_2/simplify_overlapping_polylines.cpp} + + + \subsection Subsection_PolylineSimplification_Keeping Keeping Points While Removing Vertices diff --git a/Polyline_simplification_2/doc/Polyline_simplification_2/examples.txt b/Polyline_simplification_2/doc/Polyline_simplification_2/examples.txt index a0713d4fd20..4f5338858ee 100644 --- a/Polyline_simplification_2/doc/Polyline_simplification_2/examples.txt +++ b/Polyline_simplification_2/doc/Polyline_simplification_2/examples.txt @@ -1,6 +1,7 @@ /*! \example Polyline_simplification_2/simplify_polygon.cpp \example Polyline_simplification_2/simplify.cpp +\example Polyline_simplification_2/simplify_overlapping_polylines.cpp \example Polyline_simplification_2/simplify_terrain.cpp \example Polyline_simplification_2/points_and_vertices.cpp */ diff --git a/Polyline_simplification_2/doc/Polyline_simplification_2/fig/overlapping_polylines.png b/Polyline_simplification_2/doc/Polyline_simplification_2/fig/overlapping_polylines.png new file mode 100644 index 0000000000000000000000000000000000000000..83b27735ab3ca4a71db849926f9cafe3d4e51a24 GIT binary patch literal 6604 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 Date: Tue, 16 Feb 2021 13:33:55 +0000 Subject: [PATCH 153/248] bug fix so that it compiles --- .../include/CGAL/Polyline_simplification_2/simplify.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/simplify.h b/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/simplify.h index 790ab4c9f13..82855c7af63 100644 --- a/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/simplify.h +++ b/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/simplify.h @@ -137,7 +137,7 @@ public: int m = initialize_indices(cid); initialize_unremovable(); Compare_cost cc; - Id_map idm; + Id_map idm(vertex_index_map); mpq = new MPQ(m, cc, idm); initialize_costs(cid); } @@ -306,7 +306,8 @@ public: for(Vertices_in_constraint_iterator it = pct.vertices_in_constraint_begin(cid); it != pct.vertices_in_constraint_end(cid); ++it){ - it.base()->id = id++; + Vertex_handle vh = *it; + vertex_index_map[vh] = id++; } return id; } From 53cb7cd6647134f79208dd5b6ddf46caddb6f70f Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 16 Feb 2021 13:41:28 +0000 Subject: [PATCH 154/248] Simplify the code --- .../Polyline_simplification_2/Vertex_base_2.h | 3 ++ .../CGAL/Polyline_simplification_2/simplify.h | 36 ++++--------------- 2 files changed, 10 insertions(+), 29 deletions(-) diff --git a/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/Vertex_base_2.h b/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/Vertex_base_2.h index b1d090583f8..d5f2856e239 100644 --- a/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/Vertex_base_2.h +++ b/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/Vertex_base_2.h @@ -37,6 +37,9 @@ class Vertex_base_2 bool m_removable; FT m_cost; +public: + std::size_t ID; + #ifndef DOXYGEN_RUNNING public: template < typename TDS2 > diff --git a/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/simplify.h b/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/simplify.h index 82855c7af63..ee681c767d4 100644 --- a/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/simplify.h +++ b/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/simplify.h @@ -78,10 +78,6 @@ public: std::unordered_map > vertex_to_iterator; - typedef std::unordered_map Vertex_index_map; - - Vertex_index_map vertex_index_map; - struct Compare_cost { bool operator() ( Vertices_in_constraint_iterator const& x, @@ -104,15 +100,10 @@ public: typedef value_type reference; typedef Vertex_handle key_type; - Vertex_index_map* vertex_index_map; - - Id_map(const Vertex_index_map& vertex_index_map) - : vertex_index_map(& const_cast(vertex_index_map)) - {} reference operator[] ( key_type const& x ) const { - return (*vertex_index_map)[x]; + return x->ID; } } ; @@ -126,7 +117,7 @@ public: int m = initialize_indices(); initialize_unremovable(); Compare_cost cc; - Id_map idm(vertex_index_map); + Id_map idm; mpq = new MPQ(m, cc, idm); initialize_costs(); } @@ -137,7 +128,7 @@ public: int m = initialize_indices(cid); initialize_unremovable(); Compare_cost cc; - Id_map idm(vertex_index_map); + Id_map idm; mpq = new MPQ(m, cc, idm); initialize_costs(cid); } @@ -207,15 +198,6 @@ public: } } } - - /* - // debug output - for(Finite_vertices_iterator it = pct.finite_vertices_begin(); it != pct.finite_vertices_end(); ++it){ - if(it->is_removable()){ - std::cout << it->point() << " is removable" << std::endl; - } - } - */ } // For all polyline constraints we compute the cost of all unremovable and not removed vertices @@ -307,7 +289,8 @@ public: it != pct.vertices_in_constraint_end(cid); ++it){ Vertex_handle vh = *it; - vertex_index_map[vh] = id++; + vh->ID = id++; + //vertex_index_map[vh] = id++; } return id; } @@ -316,14 +299,9 @@ public: initialize_indices() { int id = 0; - /* - Constraint_iterator b = pct.constraints_begin(), e = pct.constraints_end(); - for(; b!=e; ++b){ - id = initialize_indices(*b, id); - } - */ + for(Finite_vertices_iterator it = pct.finite_vertices_begin(); it != pct.finite_vertices_end(); ++it){ - vertex_index_map[it] = id++; + it->ID = id++; } return id; } From fe22b0ff276da81a003686ef2e30f1ec9056c8e5 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 16 Feb 2021 16:13:33 +0000 Subject: [PATCH 155/248] Add Point_3/Tetrahedron_3 --- Distance_3/include/CGAL/squared_distance_3.h | 1 + .../include/CGAL/squared_distance_3_3.h | 85 +++++++++++++++++++ .../test/Distance_3/test_distance_3.cpp | 10 ++- 3 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 Distance_3/include/CGAL/squared_distance_3_3.h diff --git a/Distance_3/include/CGAL/squared_distance_3.h b/Distance_3/include/CGAL/squared_distance_3.h index b805dd8af33..b55542f5e7f 100644 --- a/Distance_3/include/CGAL/squared_distance_3.h +++ b/Distance_3/include/CGAL/squared_distance_3.h @@ -21,5 +21,6 @@ #include #include #include +#include #endif diff --git a/Distance_3/include/CGAL/squared_distance_3_3.h b/Distance_3/include/CGAL/squared_distance_3_3.h new file mode 100644 index 00000000000..c190d6e9c01 --- /dev/null +++ b/Distance_3/include/CGAL/squared_distance_3_3.h @@ -0,0 +1,85 @@ +// Copyright (c) 1998-2021 +// 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) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman, Andreas Fabri + + +#ifndef CGAL_DISTANCE_3_3_H +#define CGAL_DISTANCE_3_3_H + +#include + +#include +#include + +namespace CGAL { + +namespace internal { + +template +inline +typename K::FT +squared_distance(const typename K::Tetrahedron_3 & tet, + const typename K::Point_3 & pt, + const K& k) +{ + CGAL_assertion(orientation(tet[0],tet[1],tet[2],tet[3]) == POSITIVE); + + if(orientation(tet[0],tet[1],tet[2],pt) != POSITIVE){ + const Triangle_3 tr = {tet[0], tet[1], tet[2]}; + return CGAL::squared_distance(tr, pt); + } + + if(orientation(tet[1],tet[3],tet[2],pt) != POSITIVE){ + const Triangle_3 tr = {tet[1], tet[3], tet[2]}; + return CGAL::squared_distance(tr, pt); + } + + if(orientation(tet[2],tet[3],tet[0],pt) != POSITIVE){ + const Triangle_3 tr = {tet[2], tet[3], tet[0]}; + return CGAL::squared_distance(tr, pt); + } + + if(orientation(tet[0],tet[3],tet[1],pt) != POSITIVE){ + const Triangle_3 tr = {tet[0], tet[3], tet[1]}; + return CGAL::squared_distance(tr, pt); + } + + return K::FT(0); + } + +} // namespace internal + + +template +typename K::FT +squared_distance(const Tetrahedron_3 & t, + const Point_3 & pt) +{ + return internal::squared_distance(t,pt,K()); +} + + +template +typename K::FT +squared_distance(const Point_3 & pt, + const Tetrahedron_3 & t) +{ + return internal::squared_distance(t,pt,K()); +} + +} //namespace CGAL + + +#endif diff --git a/Distance_3/test/Distance_3/test_distance_3.cpp b/Distance_3/test/Distance_3/test_distance_3.cpp index 4290da9919c..c15875dbf06 100644 --- a/Distance_3/test/Distance_3/test_distance_3.cpp +++ b/Distance_3/test/Distance_3/test_distance_3.cpp @@ -56,6 +56,7 @@ struct Test { typedef CGAL::Triangle_3< K > T; typedef CGAL::Plane_3< K > Pl; typedef CGAL::Iso_cuboid_3< K > Cub; + typedef CGAL::Tetrahedron_3< K > Tet; template < typename Type > @@ -109,10 +110,16 @@ struct Test { void P_T() { - std::cout << "Point - Segment\n"; + std::cout << "Point - Triangle\n"; check_squared_distance (p(0, 1, 2), T(p(0, 0, 0), p( 2, 0, 0), p( 0, 2, 0)), 4); } + void P_Tet() + { + std::cout << "Point - Tetrahedron\n"; + check_squared_distance (p(0, 0, 0), Tet(p(0, 0, 0), p( 1, 0, 0), p( 0, 1, 0), p( 0, 0, 1)), 0); + } + void S_S() { std::cout << "Segment - Segment\n"; @@ -238,6 +245,7 @@ struct Test { P_P(); P_S(); P_T(); + P_Tet(); S_S(); P_R(); R_R(); From 6186a2acf341d8644ba04d87b750e7fb42845c97 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 16 Feb 2021 16:26:45 +0000 Subject: [PATCH 156/248] Add doc --- Kernel_23/doc/Kernel_23/CGAL/squared_distance_2.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Kernel_23/doc/Kernel_23/CGAL/squared_distance_2.h b/Kernel_23/doc/Kernel_23/CGAL/squared_distance_2.h index 21c220fd95b..5927a121da3 100644 --- a/Kernel_23/doc/Kernel_23/CGAL/squared_distance_2.h +++ b/Kernel_23/doc/Kernel_23/CGAL/squared_distance_2.h @@ -40,7 +40,8 @@ following: - `Plane_3` as well as combinations `Point_3`/`Triangle_3`, -and `Weighted_point_3`/`Triangle_3`. +and `Weighted_point_3`/`Triangle_3`, as well as `Point_3`/`Tetrahedron_3`, +and `Weighted_point_3`/`Tetrahedron_3` \sa `compare_distance_to_point_grp` \sa `compare_signed_distance_to_line_grp` From 42866756b9610fa1c256f10cee7a3798d3cf4505 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 16 Feb 2021 16:45:02 +0000 Subject: [PATCH 157/248] After the code review --- .../include/CGAL/squared_distance_3_3.h | 37 ++++++++----------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/Distance_3/include/CGAL/squared_distance_3_3.h b/Distance_3/include/CGAL/squared_distance_3_3.h index c190d6e9c01..56873801937 100644 --- a/Distance_3/include/CGAL/squared_distance_3_3.h +++ b/Distance_3/include/CGAL/squared_distance_3_3.h @@ -30,35 +30,28 @@ namespace internal { template inline typename K::FT -squared_distance(const typename K::Tetrahedron_3 & tet, +squared_distance(const typename K::Tetrahedron_3 & t, const typename K::Point_3 & pt, const K& k) { - CGAL_assertion(orientation(tet[0],tet[1],tet[2],tet[3]) == POSITIVE); - - if(orientation(tet[0],tet[1],tet[2],pt) != POSITIVE){ - const Triangle_3 tr = {tet[0], tet[1], tet[2]}; - return CGAL::squared_distance(tr, pt); - } - - if(orientation(tet[1],tet[3],tet[2],pt) != POSITIVE){ - const Triangle_3 tr = {tet[1], tet[3], tet[2]}; - return CGAL::squared_distance(tr, pt); - } - - if(orientation(tet[2],tet[3],tet[0],pt) != POSITIVE){ - const Triangle_3 tr = {tet[2], tet[3], tet[0]}; - return CGAL::squared_distance(tr, pt); - } - - if(orientation(tet[0],tet[3],tet[1],pt) != POSITIVE){ - const Triangle_3 tr = {tet[0], tet[3], tet[1]}; - return CGAL::squared_distance(tr, pt); - } + if (! t.has_on_unbounded_side(pt)){ return K::FT(0); } + const typename K::Triangle_3 t0 = {t[0], t[1], t[2]}; + const typename K::Triangle_3 t1 = {t[0], t[1], t[3]}; + const typename K::Triangle_3 t2 = {t[1], t[2], t[3]}; + const typename K::Triangle_3 t3 = {t[0], t[2], t[3]}; + + const typename K::FT d0 = squared_distance(pt, t0, k); + const typename K::FT d1 = squared_distance(pt, t1, k); + const typename K::FT d2 = squared_distance(pt, t2, k); + const typename K::FT d3 = squared_distance(pt, t3, k); + + return (std::min)({d0, d1, d2, d3}); +} + } // namespace internal From c5721c38c8ffcf2a6f99b133ed0a61693722ee36 Mon Sep 17 00:00:00 2001 From: Vincent Rouvreau <10407034+VincentRouvreau@users.noreply.github.com> Date: Tue, 16 Feb 2021 18:14:54 +0100 Subject: [PATCH 158/248] doc review: Apply proposed changes Co-authored-by: Mael --- .../CGAL/Regular_triangulation.h | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/Triangulation/doc/Triangulation/CGAL/Regular_triangulation.h b/Triangulation/doc/Triangulation/CGAL/Regular_triangulation.h index 4beb5141930..af9ae40f7a9 100644 --- a/Triangulation/doc/Triangulation/CGAL/Regular_triangulation.h +++ b/Triangulation/doc/Triangulation/CGAL/Regular_triangulation.h @@ -124,23 +124,30 @@ template< typename ForwardIterator > std::ptrdiff_t insert(ForwardIterator s, ForwardIterator e); /*! -Inserts weighted point `p` in the triangulation and returns the corresponding -vertex if `p` is in the star defined by `star_center`. +inserts the weighted point `p` in the triangulation on the +condition that the vertex `star_center` appears +in the conflict zone of `p` (that is, `p` would appear +in the star of `star_center` after the insertion). -If this insertion creates a vertex, this vertex is returned. +If the insertion of `p` creates a new vertex, this vertex is returned. +Otherwise, a default constructed handle is returned. -If `p` coincides with an existing vertex and has a greater weight, -then `p` replaces it as vertex of the triangulation. +If the dimension of the triangulation is `0` and if `p` coincides +with an existing vertex and has a greater weight, +then `p` replaces it as vertex of the triangulation +and this vertex is returned. -If `p` coincides with an already existing vertex (both point and -weights being equal), then this vertex is returned and the triangulation +If `p` coincides with an already existing vertex, with both point and +weights being equal, then this vertex is returned and the triangulation remains unchanged. -Otherwise if `p` does not appear as a vertex of the triangulation, -then this method returns the default constructed handle. +By convention, if the insertion of `p` would increase the dimension +of the triangulation, it is inserted. Prior to the actual insertion, `p` is located in the triangulation; `start` is used as a starting place for locating `p`. + +\sa `Regular_triangulation::compute_conflict_zone()` */ Vertex_handle insert_if_in_star(const Weighted_point & p, Vertex_handle star_center, Full_cell_handle start = Full_cell_handle()); From 17fca4bf1f33cc5ee83adcd32996daa0feb409a3 Mon Sep 17 00:00:00 2001 From: Vincent Rouvreau <10407034+VincentRouvreau@users.noreply.github.com> Date: Tue, 16 Feb 2021 18:15:21 +0100 Subject: [PATCH 159/248] code review: apply changes Co-authored-by: Mael --- .../doc/Triangulation/CGAL/Regular_triangulation.h | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Triangulation/doc/Triangulation/CGAL/Regular_triangulation.h b/Triangulation/doc/Triangulation/CGAL/Regular_triangulation.h index af9ae40f7a9..7d7d1634221 100644 --- a/Triangulation/doc/Triangulation/CGAL/Regular_triangulation.h +++ b/Triangulation/doc/Triangulation/CGAL/Regular_triangulation.h @@ -159,10 +159,13 @@ Vertex_handle insert_if_in_star(const Weighted_point & p, Vertex_handle star_cen Vertex_handle hint); /*! -Inserts weighted point `p` in the triangulation. -Similar to the above `insert_if_in_star()` function, but takes as additional -parameter the return values of a previous location query. See description of -`Triangulation::locate()`. +inserts the weighted point `p` in the triangulation. + +This function is similar to the above `insert_if_in_star()` function, +but takes as additional parameters the return values of the location query +of `p`. + +\sa `Triangulation::locate()`. */ insert_if_in_star(const Weighted_point & p, Vertex_handle star_center, Locate_type lt, const Face & f, const Facet &, Full_cell_handle s); From 59d7b2295900b867739cbba72abd09129c078b42 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 17 Feb 2021 09:53:28 +0000 Subject: [PATCH 160/248] Hope to get it right now --- .../include/CGAL/squared_distance_3_2.h | 4 ++ .../include/CGAL/squared_distance_3_3.h | 70 ++++++++++++++++--- .../test/Distance_3/test_distance_3.cpp | 3 + 3 files changed, 66 insertions(+), 11 deletions(-) diff --git a/Distance_3/include/CGAL/squared_distance_3_2.h b/Distance_3/include/CGAL/squared_distance_3_2.h index d3d20182a1f..78af20db08f 100644 --- a/Distance_3/include/CGAL/squared_distance_3_2.h +++ b/Distance_3/include/CGAL/squared_distance_3_2.h @@ -225,6 +225,7 @@ squared_distance_to_triangle( const typename K::Point_3 & t0, const typename K::Point_3 & t1, const typename K::Point_3 & t2, + bool & inside, const K& k) { typename K::Construct_vector_3 vector; @@ -239,6 +240,7 @@ squared_distance_to_triangle( && on_left_of_triangle_edge(pt, normal, t2, t0, k)) { // the projection of pt is inside the triangle + inside = true; return squared_distance_to_plane(normal, vector(t0, pt), k); } else { @@ -267,10 +269,12 @@ squared_distance( const K& k) { typename K::Construct_vertex_3 vertex; + bool inside = false; return squared_distance_to_triangle(pt, vertex(t, 0), vertex(t, 1), vertex(t, 2), + inside, k); } diff --git a/Distance_3/include/CGAL/squared_distance_3_3.h b/Distance_3/include/CGAL/squared_distance_3_3.h index 56873801937..ca691545f09 100644 --- a/Distance_3/include/CGAL/squared_distance_3_3.h +++ b/Distance_3/include/CGAL/squared_distance_3_3.h @@ -34,22 +34,70 @@ squared_distance(const typename K::Tetrahedron_3 & t, const typename K::Point_3 & pt, const K& k) { + bool on_bounded_side = true; + const typename K::Point_3 t0 = t[0]; + const typename K::Point_3 t1 = t[1]; + const typename K::Point_3 t2 = t[2]; + const typename K::Point_3 t3 = t[3]; - if (! t.has_on_unbounded_side(pt)){ - return K::FT(0); + bool dmin_initialized = false; + typename K::FT dmin; + bool inside = false; + if(orientation(t0,t1,t2, pt) == NEGATIVE){ + on_bounded_side = false; + dmin = squared_distance_to_triangle(pt, t0, t1, t2, inside, k); + dmin_initialized = true; + if(inside){ + return dmin; + } } - const typename K::Triangle_3 t0 = {t[0], t[1], t[2]}; - const typename K::Triangle_3 t1 = {t[0], t[1], t[3]}; - const typename K::Triangle_3 t2 = {t[1], t[2], t[3]}; - const typename K::Triangle_3 t3 = {t[0], t[2], t[3]}; + if(orientation(t0,t3,t1, pt) == NEGATIVE){ + on_bounded_side = false; + const typename K::FT d = squared_distance_to_triangle(pt, t0, t3, t1, inside, k); + if(inside){ + return d; + } + if(! dmin_initialized){ + dmin = d; + dmin_initialized = true; + }else{ + dmin = std::min(d,dmin); + } + } - const typename K::FT d0 = squared_distance(pt, t0, k); - const typename K::FT d1 = squared_distance(pt, t1, k); - const typename K::FT d2 = squared_distance(pt, t2, k); - const typename K::FT d3 = squared_distance(pt, t3, k); + if(orientation(t1,t3,t2, pt) == NEGATIVE){ + on_bounded_side = false; + const typename K::FT d = squared_distance_to_triangle(pt, t1, t3, t2, inside, k); + if(inside){ + return d; + } + if(! dmin_initialized){ + dmin = d; + dmin_initialized = true; + }else{ + dmin = std::min(d,dmin); + } + } - return (std::min)({d0, d1, d2, d3}); + if(orientation(t2,t3,t0, pt) == NEGATIVE){ + on_bounded_side = false; + const typename K::FT d = squared_distance_to_triangle(pt, t2, t3, t0, inside, k); + if(inside){ + return d; + } + if(! dmin_initialized){ + dmin = d; + dmin_initialized = true; + }else{ + dmin = std::min(d,dmin); + } + } + + if(on_bounded_side){ + return K::FT(0); + } + return dmin; } } // namespace internal diff --git a/Distance_3/test/Distance_3/test_distance_3.cpp b/Distance_3/test/Distance_3/test_distance_3.cpp index c15875dbf06..3a1f72fe786 100644 --- a/Distance_3/test/Distance_3/test_distance_3.cpp +++ b/Distance_3/test/Distance_3/test_distance_3.cpp @@ -118,6 +118,9 @@ struct Test { { std::cout << "Point - Tetrahedron\n"; check_squared_distance (p(0, 0, 0), Tet(p(0, 0, 0), p( 1, 0, 0), p( 0, 1, 0), p( 0, 0, 1)), 0); + check_squared_distance (p(0, 0, 2), Tet(p(0, 0, 0), p( 1, 0, 0), p( 0, 1, 0), p( 0, 0, 1)), 1); + check_squared_distance (p(0, 0, -1), Tet(p(0, 0, 0), p( 1, 0, 0), p( 0, 1, 0), p( 0, 0, 1)), 1); + check_squared_distance (p(5, 0, 0), Tet(p(0, 0, 0), p( 1, 0, 0), p( 0, 1, 0), p( 4, 0, 1)), 2); } void S_S() From 87ecfae6f39fa5fdfe219efd413f2b717754cddf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 17 Feb 2021 10:55:59 +0100 Subject: [PATCH 161/248] Change SDG2 vertex base's requirement to TDS2 vertex (full T2 vertex not needed) --- .../CGAL/Segment_Delaunay_graph_vertex_base_2.h | 4 ++-- .../Concepts/SegmentDelaunayGraphVertexBase_2.h | 2 +- .../CGAL/Segment_Delaunay_graph_vertex_base_2.h | 11 ++--------- 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_vertex_base_2.h b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_vertex_base_2.h index b7317d7aef1..b925fa57dd9 100644 --- a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_vertex_base_2.h +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_vertex_base_2.h @@ -15,8 +15,8 @@ concept. This type must be template parameter used for `CGAL::Segment_Delaunay_graph_2`. \tparam Vb is a vertex base class from which `Segment_Delaunay_graph_vertex_base_2` derives. - It must be a model of the `TriangulationVertexBase_2` concept. - It has the default value `CGAL::Triangulation_vertex_base_2`. + It must be a model of the `TriangulationDSVertexBase_2` concept. + It has the default value `CGAL::Triangulation_ds_vertex_base_2<>`. \sa `CGAL::Segment_Delaunay_graph_hierarchy_vertex_base_2` */ diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphVertexBase_2.h b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphVertexBase_2.h index 4285991f5db..903d9e92b68 100644 --- a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphVertexBase_2.h +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphVertexBase_2.h @@ -3,7 +3,7 @@ \ingroup PkgSegmentDelaunayGraph2Concepts \cgalConcept -\cgalRefines `TriangulationVertexBase_2` +\cgalRefines `TriangulationDSVertexBase_2` The concept `SegmentDelaunayGraphVertexBase_2` describes the requirements for the vertex base class of the diff --git a/Segment_Delaunay_graph_2/include/CGAL/Segment_Delaunay_graph_vertex_base_2.h b/Segment_Delaunay_graph_2/include/CGAL/Segment_Delaunay_graph_vertex_base_2.h index 4e4d9d989e6..d9267828e29 100644 --- a/Segment_Delaunay_graph_2/include/CGAL/Segment_Delaunay_graph_vertex_base_2.h +++ b/Segment_Delaunay_graph_2/include/CGAL/Segment_Delaunay_graph_vertex_base_2.h @@ -11,8 +11,6 @@ // Author(s) : Menelaos Karavelas - - #ifndef CGAL_SEGMENT_DELAUNAY_GRAPH_VERTEX_BASE_2_H #define CGAL_SEGMENT_DELAUNAY_GRAPH_VERTEX_BASE_2_H @@ -21,16 +19,11 @@ #include #include - -#include -#include -#include +#include namespace CGAL { -template < class STraits, - class Vb = Triangulation_vertex_base_2< - typename STraits::Geom_traits> > +template < class STraits, class Vb = Triangulation_ds_vertex_base_2<> > class Segment_Delaunay_graph_vertex_base_2 : public Vb { From 098c88167c5c4c11add09c9839d96192530008ef Mon Sep 17 00:00:00 2001 From: Vincent Rouvreau <10407034+VincentRouvreau@users.noreply.github.com> Date: Wed, 17 Feb 2021 14:26:29 +0100 Subject: [PATCH 162/248] code review: apply suggested changes Co-authored-by: Mael --- Triangulation/doc/Triangulation/CGAL/Regular_triangulation.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Triangulation/doc/Triangulation/CGAL/Regular_triangulation.h b/Triangulation/doc/Triangulation/CGAL/Regular_triangulation.h index 7d7d1634221..be06cc28c2c 100644 --- a/Triangulation/doc/Triangulation/CGAL/Regular_triangulation.h +++ b/Triangulation/doc/Triangulation/CGAL/Regular_triangulation.h @@ -167,8 +167,8 @@ of `p`. \sa `Triangulation::locate()`. */ -insert_if_in_star(const Weighted_point & p, Vertex_handle star_center, Locate_type lt, - const Face & f, const Facet &, Full_cell_handle s); +Vertex_handle insert_if_in_star(const Weighted_point& p, Vertex_handle star_center, Locate_type lt, + const Face& f, const Facet&, Full_cell_handle s); /// @} From a4e7261e1edb4f759d3e6c76d1ca2f40614bc9cb Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Wed, 17 Feb 2021 14:37:47 +0100 Subject: [PATCH 163/248] code review: remove trailing whitespaces --- .../doc/Triangulation/CGAL/Regular_triangulation.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Triangulation/doc/Triangulation/CGAL/Regular_triangulation.h b/Triangulation/doc/Triangulation/CGAL/Regular_triangulation.h index be06cc28c2c..70cd0736acb 100644 --- a/Triangulation/doc/Triangulation/CGAL/Regular_triangulation.h +++ b/Triangulation/doc/Triangulation/CGAL/Regular_triangulation.h @@ -141,7 +141,7 @@ If `p` coincides with an already existing vertex, with both point and weights being equal, then this vertex is returned and the triangulation remains unchanged. -By convention, if the insertion of `p` would increase the dimension +By convention, if the insertion of `p` would increase the dimension of the triangulation, it is inserted. Prior to the actual insertion, `p` is located in the triangulation; @@ -161,9 +161,9 @@ Vertex_handle insert_if_in_star(const Weighted_point & p, Vertex_handle star_cen /*! inserts the weighted point `p` in the triangulation. -This function is similar to the above `insert_if_in_star()` function, +This function is similar to the above `insert_if_in_star()` function, but takes as additional parameters the return values of the location query -of `p`. +of `p`. \sa `Triangulation::locate()`. */ From 18f7f91c3cf3f113484d2e72f44e4110f84766b5 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 17 Feb 2021 14:41:41 +0000 Subject: [PATCH 164/248] Add test; remove the word 'constant' in the documenation --- Kernel_23/doc/Kernel_23/Concepts/FunctionObjectConcepts.h | 8 ++++---- Kernel_23/test/Kernel_23/include/CGAL/_test_new_3.h | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Kernel_23/doc/Kernel_23/Concepts/FunctionObjectConcepts.h b/Kernel_23/doc/Kernel_23/Concepts/FunctionObjectConcepts.h index f84f64533f8..1ccb1bb4079 100644 --- a/Kernel_23/doc/Kernel_23/Concepts/FunctionObjectConcepts.h +++ b/Kernel_23/doc/Kernel_23/Concepts/FunctionObjectConcepts.h @@ -9271,7 +9271,7 @@ public: /*! returns \ref CGAL::ON_ORIENTED_BOUNDARY, - \ref CGAL::ON_NEGATIVE_SIDE, or the constant \ref CGAL::ON_POSITIVE_SIDE, + \ref CGAL::ON_NEGATIVE_SIDE, or \ref CGAL::ON_POSITIVE_SIDE, depending on the position of `p` relative to the oriented plane `h`. */ Oriented_side operator()(const Kernel::Plane_3&h, @@ -9279,7 +9279,7 @@ public: /*! returns \ref CGAL::ON_ORIENTED_BOUNDARY, - \ref CGAL::ON_NEGATIVE_SIDE, or the constant \ref CGAL::ON_POSITIVE_SIDE, + \ref CGAL::ON_NEGATIVE_SIDE, or \ref CGAL::ON_POSITIVE_SIDE, depending on the position of `p` relative to the oriented plane constructed from `plane_point` and `plane_vector`. */ @@ -9289,7 +9289,7 @@ public: /*! returns \ref CGAL::ON_ORIENTED_BOUNDARY, - \ref CGAL::ON_NEGATIVE_SIDE, or the constant \ref CGAL::ON_POSITIVE_SIDE, + \ref CGAL::ON_NEGATIVE_SIDE, or \ref CGAL::ON_POSITIVE_SIDE, depending on the position of `p` relative to the oriented tetrahedron `t`. */ Oriented_side operator()(const Kernel::Tetrahedron_3&t, @@ -9297,7 +9297,7 @@ public: /*! returns \ref CGAL::ON_ORIENTED_BOUNDARY, - \ref CGAL::ON_NEGATIVE_SIDE, or the \ref CGAL::ON_POSITIVE_SIDE, + \ref CGAL::ON_NEGATIVE_SIDE, or \ref CGAL::ON_POSITIVE_SIDE, depending on the position of `p` relative to the oriented sphere `s`. */ Oriented_side operator()(const Kernel::Sphere_3& s, 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 540eafe080f..0beec86c962 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 @@ -747,6 +747,7 @@ test_new_3(const R& rep) = rep.oriented_side_3_object(); Oriented_side tmp39 = oriented_side(h2,p2); tmp39 = oriented_side(sp9,p2); + tmp39 = oriented_side(p2,v1,p2); (void) tmp39; typename R::Bounded_side_3 bounded_side From 05b4734a6e827ec3ba5a0fae65b845d31602f98e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 17 Feb 2021 15:49:08 +0100 Subject: [PATCH 165/248] add missing const --- Property_map/include/CGAL/property_map.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Property_map/include/CGAL/property_map.h b/Property_map/include/CGAL/property_map.h index 988c7ab6583..d57c53310e8 100644 --- a/Property_map/include/CGAL/property_map.h +++ b/Property_map/include/CGAL/property_map.h @@ -473,7 +473,7 @@ struct Constant_property_map typedef KeyType key_type; typedef ValueType value_type; - typedef value_type& reference; + typedef const value_type& reference; typedef boost::read_write_property_map_tag category; Constant_property_map(const value_type& default_value = value_type()) : default_value (default_value) { } From 3b9dafb23b1d175df1f74dd32f014ed07b5faa9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 17 Feb 2021 15:49:30 +0100 Subject: [PATCH 166/248] fix after BOOST_FOREACH -> for replacement --- Mesh_3/include/CGAL/internal/Mesh_3/helpers.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mesh_3/include/CGAL/internal/Mesh_3/helpers.h b/Mesh_3/include/CGAL/internal/Mesh_3/helpers.h index 4095bb37baf..f0782b66ed1 100644 --- a/Mesh_3/include/CGAL/internal/Mesh_3/helpers.h +++ b/Mesh_3/include/CGAL/internal/Mesh_3/helpers.h @@ -45,7 +45,7 @@ void dump_graph_edges(std::ostream& out, const Graph& g) typedef typename boost::graph_traits::edge_descriptor edge_descriptor; out.precision(17); - for(edge_descriptor e : edges(g)) + for(edge_descriptor e : CGAL::make_range(edges(g))) { vertex_descriptor s = source(e, g); vertex_descriptor t = target(e, g); From 98e48385e8af880c4fc966f761431e0c2f52a81d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 17 Feb 2021 15:49:48 +0100 Subject: [PATCH 167/248] a RIGHT angle is also a corner --- Mesh_3/include/CGAL/internal/Mesh_3/helpers.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mesh_3/include/CGAL/internal/Mesh_3/helpers.h b/Mesh_3/include/CGAL/internal/Mesh_3/helpers.h index f0782b66ed1..f51af8cd0b3 100644 --- a/Mesh_3/include/CGAL/internal/Mesh_3/helpers.h +++ b/Mesh_3/include/CGAL/internal/Mesh_3/helpers.h @@ -82,7 +82,7 @@ struct Angle_tester const typename Kernel::Point_3& p1 = g[v1]; const typename Kernel::Point_3& p2 = g[v2]; - return (CGAL::angle(p1, p, p2) == CGAL::ACUTE); + return (CGAL::angle(p1, p, p2) != CGAL::OBTUSE); } } }; From 113298056d982a9075c24b236dd96a211dbd3b46 Mon Sep 17 00:00:00 2001 From: Giles Bathgate Date: Tue, 16 Feb 2021 20:12:59 +0000 Subject: [PATCH 168/248] Explicitly call simplify after marking bounded volumes --- Nef_3/include/CGAL/Nef_polyhedron_3.h | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/Nef_3/include/CGAL/Nef_polyhedron_3.h b/Nef_3/include/CGAL/Nef_polyhedron_3.h index 3eb723d37b7..525bc7d1d0a 100644 --- a/Nef_3/include/CGAL/Nef_polyhedron_3.h +++ b/Nef_3/include/CGAL/Nef_polyhedron_3.h @@ -349,6 +349,12 @@ protected: es.build_external_structure(); } + private: + void mark_bounded_volumes() { + CGAL::Mark_bounded_volumes mbv(true); + delegate(mbv, /*compute_external*/ false, /*simplify*/ false); + } + public: /*{\Mcreation 3}*/ @@ -602,9 +608,8 @@ protected: polyhedron_3_to_nef_3 , SNC_structure>( P, snc()); build_external_structure(); + mark_bounded_volumes(); simplify(); - CGAL::Mark_bounded_volumes mbv(true); - delegate(mbv); set_snc(snc()); } @@ -616,9 +621,8 @@ protected: initialize_infibox_vertices(EMPTY); polygon_mesh_to_nef_3(const_cast(pm), snc()); build_external_structure(); + mark_bounded_volumes(); simplify(); - CGAL::Mark_bounded_volumes mbv(true); - delegate(mbv); set_snc(snc()); } @@ -637,9 +641,8 @@ protected: initialize_infibox_vertices(EMPTY); polygon_mesh_to_nef_3(const_cast(pm), snc(), fim, him); build_external_structure(); + mark_bounded_volumes(); simplify(); - CGAL::Mark_bounded_volumes mbv(true); - delegate(mbv); set_snc(snc()); } @@ -651,9 +654,8 @@ protected: initialize_infibox_vertices(EMPTY); shell_to_nef_3(N, sf, snc()); build_external_structure(); + mark_bounded_volumes(); simplify(); - CGAL::Mark_bounded_volumes mbv(true); - delegate(mbv); set_snc(snc()); } From 6b36ea0763f2b82655c2806117478a619250a1f2 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 17 Feb 2021 16:48:39 +0000 Subject: [PATCH 169/248] Replace built-in array with std::array --- .../include/CGAL/Box_intersection_d/Box_d.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Box_intersection_d/include/CGAL/Box_intersection_d/Box_d.h b/Box_intersection_d/include/CGAL/Box_intersection_d/Box_d.h index 08718db8abd..a6326ed6cae 100644 --- a/Box_intersection_d/include/CGAL/Box_intersection_d/Box_d.h +++ b/Box_intersection_d/include/CGAL/Box_intersection_d/Box_d.h @@ -24,6 +24,7 @@ #include #include +#include namespace CGAL { @@ -63,8 +64,9 @@ class Box_d; template class Box_d< NT_, N, ID_NONE> { protected: - NT_ lo[N]; - NT_ hi[N]; + std::array lo; + std::array hi; + public: typedef NT_ NT; typedef std::size_t ID; @@ -72,8 +74,8 @@ public: Box_d() {} Box_d(bool complete) { init(complete); } Box_d(NT l[N], NT h[N]) { - std::copy( l, l + N, lo ); - std::copy( h, h + N, hi ); + std::copy( l, l + N, &lo[0] ); + std::copy( h, h + N, &hi[0] ); } void init (bool complete = false) { NT inf = box_limits::inf(); From ad73f44a896e63115167373405741adde6e20dd7 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 18 Feb 2021 12:41:52 +0100 Subject: [PATCH 170/248] add bbox axis lengths to the tooltip of an item --- Polyhedron/demo/Polyhedron/MainWindow.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/MainWindow.cpp b/Polyhedron/demo/Polyhedron/MainWindow.cpp index 490ad9e0094..0fc2dac5fea 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.cpp +++ b/Polyhedron/demo/Polyhedron/MainWindow.cpp @@ -1794,13 +1794,16 @@ void MainWindow::updateInfo() { QString item_filename = item->property("source filename").toString(); CGAL::Bbox_3 bbox = item->bbox(); if(bbox !=CGAL::Bbox_3()) - item_text += QString("

    ") + item_text += QString("
    Bounding box: min (%1,%2,%3), max (%4,%5,%6), axis lengths (%7, %8, %9)
    ") .arg(bbox.xmin(),0, 'g', 17) .arg(bbox.ymin(),0, 'g', 17) .arg(bbox.zmin(),0, 'g', 17) .arg(bbox.xmax(),0, 'g', 17) .arg(bbox.ymax(),0, 'g', 17) - .arg(bbox.zmax(),0, 'g', 17); + .arg(bbox.zmax(),0, 'g', 17) + .arg(bbox.xmax() - bbox.xmin(), 0, 'g', 17) + .arg(bbox.ymax() - bbox.ymin(), 0, 'g', 17) + .arg(bbox.zmax() - bbox.zmin(), 0, 'g', 17); if(!item_filename.isEmpty()) { item_text += QString("
    File: %1
    ").arg(item_filename); } From 64597d7cabd6a760ec516dacb8f6d6a00dce146b Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 18 Feb 2021 13:30:47 +0100 Subject: [PATCH 171/248] fix sphere lighting --- Polyhedron/demo/Polyhedron/create_sphere.h | 2 +- .../compatibility_shaders/shader_spheres.vert | 19 ++++++++++--------- .../Polyhedron/resources/shader_spheres.vert | 17 +++++++++-------- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/create_sphere.h b/Polyhedron/demo/Polyhedron/create_sphere.h index a10cdbacc2b..c2fd27266d1 100644 --- a/Polyhedron/demo/Polyhedron/create_sphere.h +++ b/Polyhedron/demo/Polyhedron/create_sphere.h @@ -197,7 +197,7 @@ void create_flat_and_wire_sphere(FLOAT R, const float sectors=float(prec); const float to_rad = static_cast(CGAL_PI / 180.0); - create_flat_sphere(R, positions_spheres, normals_spheres); + create_flat_sphere(R, positions_spheres, normals_spheres, prec); float T, P; float x[4],y[4],z[4]; diff --git a/Polyhedron/demo/Polyhedron/resources/compatibility_shaders/shader_spheres.vert b/Polyhedron/demo/Polyhedron/resources/compatibility_shaders/shader_spheres.vert index 2bdf861c0eb..b1b8bee89f1 100644 --- a/Polyhedron/demo/Polyhedron/resources/compatibility_shaders/shader_spheres.vert +++ b/Polyhedron/demo/Polyhedron/resources/compatibility_shaders/shader_spheres.vert @@ -1,4 +1,4 @@ -//#version 100 +//#version 100 attribute highp vec4 vertex; attribute highp vec3 normals; attribute highp vec3 colors; @@ -19,12 +19,13 @@ void main(void) for(int i=0; i<6; ++i) dist[i] = 1.0; color = vec4(colors, 1.0); - fP = mv_matrix * vertex; - mat3 mv_matrix_3; - mv_matrix_3[0] = mv_matrix[0].xyz; - mv_matrix_3[1] = mv_matrix[1].xyz; - mv_matrix_3[2] = mv_matrix[2].xyz; - fN = mv_matrix_3* normals; - gl_Position = mvp_matrix * f_matrix * - vec4(radius*vertex.x + center.x, radius* vertex.y + center.y, radius*vertex.z + center.z, 1.0) ; + vec4 transformed_vertex = + vec4(radius*vertex.x + center.x, radius* vertex.y + center.y, radius*vertex.z + center.z, 1.0); + fP = mv_matrix * transformed_vertex; + mat3 mv_matrix_3; + mv_matrix_3[0] = mv_matrix[0].xyz; + mv_matrix_3[1] = mv_matrix[1].xyz; + mv_matrix_3[2] = mv_matrix[2].xyz; + fN = mv_matrix_3* normals; + gl_Position = mvp_matrix * f_matrix * transformed_vertex; } diff --git a/Polyhedron/demo/Polyhedron/resources/shader_spheres.vert b/Polyhedron/demo/Polyhedron/resources/shader_spheres.vert index 8a97ca290ba..809756fdac1 100644 --- a/Polyhedron/demo/Polyhedron/resources/shader_spheres.vert +++ b/Polyhedron/demo/Polyhedron/resources/shader_spheres.vert @@ -19,12 +19,13 @@ void main(void) for(int i=0; i<6; ++i) dist[i] = 1.0; color = vec4(colors, 1.0); - fP = mv_matrix * vertex; - mat3 mv_matrix_3; - mv_matrix_3[0] = mv_matrix[0].xyz; - mv_matrix_3[1] = mv_matrix[1].xyz; - mv_matrix_3[2] = mv_matrix[2].xyz; - fN = mv_matrix_3* normals; - gl_Position = mvp_matrix * f_matrix * - vec4(radius*vertex.x + center.x, radius* vertex.y + center.y, radius*vertex.z + center.z, 1.0) ; + vec4 transformed_vertex = + vec4(radius*vertex.x + center.x, radius* vertex.y + center.y, radius*vertex.z + center.z, 1.0); + fP = mv_matrix * f_matrix * transformed_vertex; + mat3 mv_matrix_3; + mv_matrix_3[0] = mv_matrix[0].xyz; + mv_matrix_3[1] = mv_matrix[1].xyz; + mv_matrix_3[2] = mv_matrix[2].xyz; + fN = mv_matrix_3* normals; + gl_Position = mvp_matrix * f_matrix * transformed_vertex; } From 23b1024f1be944a6a484f2673b3e78399927812d Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 18 Feb 2021 13:51:04 +0100 Subject: [PATCH 172/248] fix direction-constraint in qglviewer --- GraphicsView/include/CGAL/Qt/constraint_impl.h | 2 +- .../demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/GraphicsView/include/CGAL/Qt/constraint_impl.h b/GraphicsView/include/CGAL/Qt/constraint_impl.h index abb97f9d29d..513900a9fbd 100644 --- a/GraphicsView/include/CGAL/Qt/constraint_impl.h +++ b/GraphicsView/include/CGAL/Qt/constraint_impl.h @@ -59,7 +59,7 @@ void AxisPlaneConstraint::setTranslationConstraintDirection( if ((translationConstraintType() != AxisPlaneConstraint::FREE) && (translationConstraintType() != AxisPlaneConstraint::FORBIDDEN)) { const qreal norm = direction.norm(); - if (norm < 1E-8) { + if (norm == 0) { qWarning("AxisPlaneConstraint::setTranslationConstraintDir: null vector " "for translation constraint"); translationConstraintType_ = AxisPlaneConstraint::FREE; diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp index cada4c95506..820af1b3aa4 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp @@ -809,12 +809,13 @@ bool Scene_edit_box_item::eventFilter(QObject *obj, QEvent *event) d->selected_vertices.push_back(d->faces[picked].vertices[i]); Kernel::Point_3 a1(d->faces[picked].vertices[1]->position()), a0(d->faces[picked].vertices[0]->position()) ,a3(d->faces[picked].vertices[3]->position()); - QVector3D a(a1.x()-a0.x(), a1.y()-a0.y(),a1.z()-a0.z()),b(a3.x()-a0.x(), a3.y()-a0.y(),a3.z()-a0.z()); - QVector3D n = QVector3D::crossProduct(a,b); + Kernel::Vector_3 a(a1.x()-a0.x(), a1.y()-a0.y(),a1.z()-a0.z()),b(a3.x()-a0.x(), a3.y()-a0.y(),a3.z()-a0.z()); + Kernel::Vector_3 n = CGAL::cross_product(a,b); d->remodel_frame->setConstraint(&d->constraint); d->constraint.setTranslationConstraintType(CGAL::qglviewer::AxisPlaneConstraint::AXIS); d->constraint.setTranslationConstraintDirection(CGAL::qglviewer::Vec(n.x(), n.y(), n.z())); + } viewer->setManipulatedFrame(d->remodel_frame); From 5bffc2875808b0acfa8327dc2dcbe79a95086b60 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 18 Feb 2021 14:12:35 +0100 Subject: [PATCH 173/248] Invalidate aabb_tree after moving vertex --- .../demo/Polyhedron/Scene_polyhedron_selection_item.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp index 10b5b4e3fb8..630022bd92d 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp @@ -1022,6 +1022,10 @@ bool Scene_polyhedron_selection_item::treat_selection(const std::setinvalidate_aabb_tree(); + setProperty("need_invalidate_aabb_tree", false); + } invalidateOpenGLBuffers(); Q_EMIT updateInstructions("Ctrl+Right-click to move the point. \nHit Ctrl+Z to leave the selection. (2/2)"); } @@ -1949,6 +1953,7 @@ void Scene_polyhedron_selection_item::moveVertex() put(vpm, vh, Point_3(d->manipulated_frame->position().x-offset.x, d->manipulated_frame->position().y-offset.y, d->manipulated_frame->position().z-offset.z)); + setProperty("need_invalidate_aabb_tree", true); invalidateOpenGLBuffers(); poly_item->updateVertex(vh); // poly_item->invalidateOpenGLBuffers(); @@ -1968,6 +1973,10 @@ void Scene_polyhedron_selection_item::validateMoveVertex() set_highlighting(true); setProperty("need_hl_restore", false); } + if(property("need_invalidate_aabb_tree").toBool()){ + polyhedron_item()->invalidate_aabb_tree(); + setProperty("need_invalidate_aabb_tree", false); + } Q_EMIT updateInstructions("Select a vertex. (1/2)"); } From 7109dd9de90df79e09aa95a42be14593ac841c6d Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 18 Feb 2021 14:15:02 +0100 Subject: [PATCH 174/248] clean-up --- Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp index 820af1b3aa4..0cb165c03f6 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp @@ -809,7 +809,8 @@ bool Scene_edit_box_item::eventFilter(QObject *obj, QEvent *event) d->selected_vertices.push_back(d->faces[picked].vertices[i]); Kernel::Point_3 a1(d->faces[picked].vertices[1]->position()), a0(d->faces[picked].vertices[0]->position()) ,a3(d->faces[picked].vertices[3]->position()); - Kernel::Vector_3 a(a1.x()-a0.x(), a1.y()-a0.y(),a1.z()-a0.z()),b(a3.x()-a0.x(), a3.y()-a0.y(),a3.z()-a0.z()); + Kernel::Vector_3 a = a1 - a0, + b = a3 - a0; Kernel::Vector_3 n = CGAL::cross_product(a,b); d->remodel_frame->setConstraint(&d->constraint); From e023f3f958e2459b61a90fb050e4064504769378 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 18 Feb 2021 15:07:29 +0100 Subject: [PATCH 175/248] add .js in the end of a scene's filename if needed. --- Polyhedron/demo/Polyhedron/MainWindow.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Polyhedron/demo/Polyhedron/MainWindow.cpp b/Polyhedron/demo/Polyhedron/MainWindow.cpp index 4b7cd1b1c69..7cac1ff44b0 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.cpp +++ b/Polyhedron/demo/Polyhedron/MainWindow.cpp @@ -2947,6 +2947,8 @@ void MainWindow::on_actionSa_ve_Scene_as_Script_triggered() last_saved_dir, "Qt Script files (*.js)"); } + if(!filename.endsWith(".js")) + filename.append(".js"); std::ofstream os(filename.toUtf8(), std::ofstream::binary); if(!os) return; From 483104f5145bc80afe44152642a4b498986a538a Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 18 Feb 2021 15:39:37 +0100 Subject: [PATCH 176/248] Don't forget 1.8.4 --- .../doc/resources/1.8.4/BaseDoxyfile.in | 61 +++++++++++++++---- 1 file changed, 48 insertions(+), 13 deletions(-) diff --git a/Documentation/doc/resources/1.8.4/BaseDoxyfile.in b/Documentation/doc/resources/1.8.4/BaseDoxyfile.in index d5b6d350ea7..eaca76a8e42 100644 --- a/Documentation/doc/resources/1.8.4/BaseDoxyfile.in +++ b/Documentation/doc/resources/1.8.4/BaseDoxyfile.in @@ -197,19 +197,54 @@ TAB_SIZE = 4 # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. -ALIASES = "sc{1}=\1" -ALIASES += "cgal=\sc{%CGAL}" -ALIASES += "protocgal=\sc{C++gal}" -ALIASES += "plageo=\sc{Plageo}" -ALIASES += "gmp=\sc{GMP}" -ALIASES += "mpir=\sc{MPIR}" -ALIASES += "mpfr=\sc{MPFR}" -ALIASES += "stl=\sc{STL}" -ALIASES += "leda=\sc{LEDA}" -ALIASES += "gcc=\sc{GCC}" -ALIASES += "cpp=\sc{C++}" -ALIASES += "cpp11=\sc{C++11}" -ALIASES += "CC=\sc{C++}" +ALIASES = "cgal=CGAL" +ALIASES += "protocgal=C++gal" +ALIASES += "plageo=Plageo" +ALIASES += "stl=STL" +ALIASES += "gmp=GMP" +ALIASES += "gmpxx=GMPXX" +ALIASES += "mpir=MPIR" +ALIASES += "mpfr=MPFR" +ALIASES += "leda=LEDA" +ALIASES += "gcc=GCC" +ALIASES += "dcel=DCEL" +ALIASES += "bgl=BGL" +ALIASES += "boost=Boost" +ALIASES += "gnu=GNU" +ALIASES += "ms=MS" +ALIASES += "qt=Qt" +ALIASES += "qt5=Qt5" +ALIASES += "eigen=Eigen" +ALIASES += "opengr=OpenGR" +ALIASES += "libpointmatcher=libpointmatcher" +ALIASES += "core=Core" +ALIASES += "mpfi=MPFI" +ALIASES += "ntl=NTL" +ALIASES += "pdb=PDB" +ALIASES += "esbtl=ESBTL" +ALIASES += "tbb=TBB" +ALIASES += "laslib=LASlib" +ALIASES += "opencv=OpenCV" +ALIASES += "tensorflow=TensorFlow" +ALIASES += "metis=METIS" +ALIASES += "zlib=zlib" +ALIASES += "ceres=Ceres" +ALIASES += "glpk=GLPK" +ALIASES += "scip=SCIP" +ALIASES += "rs=RS" +ALIASES += "rs3=RS3" +ALIASES += "unix=Unix" +ALIASES += "api=API" +ALIASES += "vtk=VTK" +ALIASES += "visualstudio=Visual Studio" +ALIASES += "taucs=TAUCS" +ALIASES += "lapack=LAPACK" +ALIASES += "blas=BLAS" +ALIASES += "opennl=OpenNL" +ALIASES += "cpp=C++" +ALIASES += "cpp11=C++11" +ALIASES += "CC=C++" + ALIASES += "cgalExample{1}=
    File \ref \1 \include \1" ALIASES += "cgalFigureAnchor{1}=\anchor fig__\1" ALIASES += "cgalFigureRef{1}=\ref fig__\1" From faff1c144422f08bae2c12ee66c3179d966a57cd Mon Sep 17 00:00:00 2001 From: Mael Date: Thu, 18 Feb 2021 19:45:35 +0100 Subject: [PATCH 177/248] Tiny changes in doc of insert_if_in_star --- .../doc/Triangulation/CGAL/Regular_triangulation.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Triangulation/doc/Triangulation/CGAL/Regular_triangulation.h b/Triangulation/doc/Triangulation/CGAL/Regular_triangulation.h index 70cd0736acb..ca7b27c53b9 100644 --- a/Triangulation/doc/Triangulation/CGAL/Regular_triangulation.h +++ b/Triangulation/doc/Triangulation/CGAL/Regular_triangulation.h @@ -149,14 +149,14 @@ Prior to the actual insertion, `p` is located in the triangulation; \sa `Regular_triangulation::compute_conflict_zone()` */ -Vertex_handle insert_if_in_star(const Weighted_point & p, Vertex_handle star_center, - Full_cell_handle start = Full_cell_handle()); +Vertex_handle insert_if_in_star(const Weighted_point& p, Vertex_handle star_center, + Full_cell_handle start = Full_cell_handle()); /*! Same as the above `insert_if_in_star()`, but uses a vertex as starting place for the search. */ -Vertex_handle insert_if_in_star(const Weighted_point & p, Vertex_handle star_center, - Vertex_handle hint); +Vertex_handle insert_if_in_star(const Weighted_point& p, Vertex_handle star_center, + Vertex_handle hint); /*! inserts the weighted point `p` in the triangulation. @@ -168,7 +168,7 @@ of `p`. \sa `Triangulation::locate()`. */ Vertex_handle insert_if_in_star(const Weighted_point& p, Vertex_handle star_center, Locate_type lt, - const Face& f, const Facet&, Full_cell_handle s); + const Face& f, const Facet& fr, Full_cell_handle start); /// @} From cf533e9016f2423e273ca14c0bd10b74eef2407c Mon Sep 17 00:00:00 2001 From: Mael Date: Thu, 18 Feb 2021 19:46:45 +0100 Subject: [PATCH 178/248] Typo --- Triangulation/doc/Triangulation/CGAL/Regular_triangulation.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Triangulation/doc/Triangulation/CGAL/Regular_triangulation.h b/Triangulation/doc/Triangulation/CGAL/Regular_triangulation.h index ca7b27c53b9..717debb853e 100644 --- a/Triangulation/doc/Triangulation/CGAL/Regular_triangulation.h +++ b/Triangulation/doc/Triangulation/CGAL/Regular_triangulation.h @@ -168,7 +168,7 @@ of `p`. \sa `Triangulation::locate()`. */ Vertex_handle insert_if_in_star(const Weighted_point& p, Vertex_handle star_center, Locate_type lt, - const Face& f, const Facet& fr, Full_cell_handle start); + const Face& f, const Facet& ft, Full_cell_handle start); /// @} From 0eb50900132bd662db2e019c9f3ab4f954f52672 Mon Sep 17 00:00:00 2001 From: Mael Date: Thu, 18 Feb 2021 19:48:58 +0100 Subject: [PATCH 179/248] Revert variable name change --- Triangulation/doc/Triangulation/CGAL/Regular_triangulation.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Triangulation/doc/Triangulation/CGAL/Regular_triangulation.h b/Triangulation/doc/Triangulation/CGAL/Regular_triangulation.h index 717debb853e..54d9f9d9a73 100644 --- a/Triangulation/doc/Triangulation/CGAL/Regular_triangulation.h +++ b/Triangulation/doc/Triangulation/CGAL/Regular_triangulation.h @@ -168,7 +168,7 @@ of `p`. \sa `Triangulation::locate()`. */ Vertex_handle insert_if_in_star(const Weighted_point& p, Vertex_handle star_center, Locate_type lt, - const Face& f, const Facet& ft, Full_cell_handle start); + const Face& f, const Facet& ft, Full_cell_handle s); /// @} From 48aff9e9a157ee3a481d5625e728f88f68fcfe48 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 19 Feb 2021 11:17:20 +0100 Subject: [PATCH 180/248] Fix indentation --- .../cgal_test_with_cmake | 383 +++++++++--------- .../test/Surface_sweep_2/cgal_test_base | 82 ++-- 2 files changed, 232 insertions(+), 233 deletions(-) diff --git a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/cgal_test_with_cmake b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/cgal_test_with_cmake index 7c96355065a..2b9a9aee225 100755 --- a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/cgal_test_with_cmake +++ b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/cgal_test_with_cmake @@ -129,38 +129,37 @@ configure() { echo "Configuring... " rm -rf CMakeCache.txt CMakeFiles/ + if [ -f "$INIT_FILE" ] + then + if eval 'cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} "$CMAKE_GENERATOR" -DRUNNING_CGAL_AUTO_TEST=TRUE \ + -DCGAL_DIR="$CGAL_DIR" \ + -DCGAL_CXX_FLAGS:STRING="$CGAL_CXX_FLAGS $TESTSUITE_CXXFLAGS -I../../include" \ + -DCGAL_EXE_LINKER_FLAGS="$CGAL_EXE_LINKER_FLAGS $TESTSUITE_LDFLAGS" \ + .' ; then -if [ -f "$INIT_FILE" ] -then - if eval 'cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} "$CMAKE_GENERATOR" -DRUNNING_CGAL_AUTO_TEST=TRUE \ - -DCGAL_DIR="$CGAL_DIR" \ - -DCGAL_CXX_FLAGS:STRING="$CGAL_CXX_FLAGS $TESTSUITE_CXXFLAGS -I../../include" \ - -DCGAL_EXE_LINKER_FLAGS="$CGAL_EXE_LINKER_FLAGS $TESTSUITE_LDFLAGS" \ - .' ; then - - echo " successful configuration" >> $ERRORFILE + echo " successful configuration" >> $ERRORFILE + else + echo " ERROR: configuration" >> $ERRORFILE + fi else - echo " ERROR: configuration" >> $ERRORFILE - fi -else - echo "cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} "$CMAKE_GENERATOR" -DRUNNING_CGAL_AUTO_TEST=TRUE \ - -DCGAL_DIR=\"$CGAL_DIR\" \ - -DCGAL_CXX_FLAGS:STRING=\"$TESTSUITE_CXXFLAGS -I../../include\" \ - -DCGAL_EXE_LINKER_FLAGS=\"$TESTSUITE_LDFLAGS\" \ - -DCMAKE_BUILD_TYPE=NOTFOUND \ - ." - if eval 'cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} "$CMAKE_GENERATOR" -DRUNNING_CGAL_AUTO_TEST=TRUE \ - -DCGAL_DIR="$CGAL_DIR" \ - -DCGAL_CXX_FLAGS:STRING="$TESTSUITE_CXXFLAGS -I../../include" \ - -DCGAL_EXE_LINKER_FLAGS="$TESTSUITE_LDFLAGS" \ - -DCMAKE_BUILD_TYPE=NOTFOUND \ - .' ; then + echo "cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} "$CMAKE_GENERATOR" -DRUNNING_CGAL_AUTO_TEST=TRUE \ + -DCGAL_DIR=\"$CGAL_DIR\" \ + -DCGAL_CXX_FLAGS:STRING=\"$TESTSUITE_CXXFLAGS -I../../include\" \ + -DCGAL_EXE_LINKER_FLAGS=\"$TESTSUITE_LDFLAGS\" \ + -DCMAKE_BUILD_TYPE=NOTFOUND \ + ." + if eval 'cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} "$CMAKE_GENERATOR" -DRUNNING_CGAL_AUTO_TEST=TRUE \ + -DCGAL_DIR="$CGAL_DIR" \ + -DCGAL_CXX_FLAGS:STRING="$TESTSUITE_CXXFLAGS -I../../include" \ + -DCGAL_EXE_LINKER_FLAGS="$TESTSUITE_LDFLAGS" \ + -DCMAKE_BUILD_TYPE=NOTFOUND \ + .' ; then - echo " successful configuration" >> $ERRORFILE - else - echo " ERROR: configuration" >> $ERRORFILE + echo " successful configuration" >> $ERRORFILE + else + echo " ERROR: configuration" >> $ERRORFILE + fi fi -fi } compile_test_with_flags() @@ -413,77 +412,77 @@ execute_commands_old_structure() commands_indicator[CONSTRUCTOR]=1 i=1 if [ $# -gt 2 ] ; then - for arg in $* ; do - if [ $i -gt 2 ] ; then - commands_indicator[$arg]=0 - fi - let "i+=1" - done + for arg in $* ; do + if [ $i -gt 2 ] ; then + commands_indicator[$arg]=0 + fi + let "i+=1" + done fi if [ ${commands_indicator[$COMPARE]} -ne 0 ] ; then - run_trapped_test test_traits \ - data/compare.pt data/empty.zero \ - data/empty.zero data/compare $2 + run_trapped_test test_traits \ + data/compare.pt data/empty.zero \ + data/empty.zero data/compare $2 fi if [ ${commands_indicator[$VERTEX]} -ne 0 ] ; then - run_trapped_test test_traits \ - data/$1/vertex.pt data/$1/vertex.xcv \ - data/empty.zero data/$1/vertex $2 + run_trapped_test test_traits \ + data/$1/vertex.pt data/$1/vertex.xcv \ + data/empty.zero data/$1/vertex $2 fi if [ ${commands_indicator[$IS_VERTICAL]} -ne 0 ] ; then - run_trapped_test test_traits \ - data/empty.zero data/$1/is_vertical.xcv data/empty.zero \ - data/$1/is_vertical $2 + run_trapped_test test_traits \ + data/empty.zero data/$1/is_vertical.xcv data/empty.zero \ + data/$1/is_vertical $2 fi if [ ${commands_indicator[$COMPARE_Y_AT_X]} -ne 0 ] ; then - run_trapped_test test_traits \ - data/$1/compare_y_at_x.pt data/$1/compare_y_at_x.xcv \ - data/empty.zero data/$1/compare_y_at_x $2 + run_trapped_test test_traits \ + data/$1/compare_y_at_x.pt data/$1/compare_y_at_x.xcv \ + data/empty.zero data/$1/compare_y_at_x $2 fi if [ ${commands_indicator[$COMPARE_Y_AT_X_LEFT]} -ne 0 ] ; then - run_trapped_test test_traits \ - data/$1/compare_y_at_x_left.pt data/$1/compare_y_at_x_left.xcv \ - data/empty.zero data/$1/compare_y_at_x_left $2 + run_trapped_test test_traits \ + data/$1/compare_y_at_x_left.pt data/$1/compare_y_at_x_left.xcv \ + data/empty.zero data/$1/compare_y_at_x_left $2 fi if [ ${commands_indicator[$COMPARE_Y_AT_X_RIGHT]} -ne 0 ] ; then - run_trapped_test test_traits \ - data/$1/compare_y_at_x_right.pt data/$1/compare_y_at_x_right.xcv \ - data/empty.zero data/$1/compare_y_at_x_right $2 + run_trapped_test test_traits \ + data/$1/compare_y_at_x_right.pt data/$1/compare_y_at_x_right.xcv \ + data/empty.zero data/$1/compare_y_at_x_right $2 fi if [ ${commands_indicator[$MAKE_X_MONOTONE]} -ne 0 ] ; then - run_trapped_test test_traits \ - data/empty.zero data/$1/make_x_monotone.xcv \ - data/$1/make_x_monotone.cv data/$1/make_x_monotone $2 + run_trapped_test test_traits \ + data/empty.zero data/$1/make_x_monotone.xcv \ + data/$1/make_x_monotone.cv data/$1/make_x_monotone $2 fi if [ ${commands_indicator[$INTERSECT]} -ne 0 ] ; then - run_trapped_test test_traits \ - data/$1/intersect.pt data/$1/intersect.xcv \ - data/empty.zero data/$1/intersect $2 + run_trapped_test test_traits \ + data/$1/intersect.pt data/$1/intersect.xcv \ + data/empty.zero data/$1/intersect $2 fi if [ ${commands_indicator[$SPLIT]} -ne 0 ] ; then - run_trapped_test test_traits \ - data/$1/split.pt data/$1/split.xcv \ - data/empty.zero data/$1/split $2 + run_trapped_test test_traits \ + data/$1/split.pt data/$1/split.xcv \ + data/empty.zero data/$1/split $2 fi if [ ${commands_indicator[$ARE_MERGEABLE]} -ne 0 ] ; then - run_trapped_test test_traits \ - data/empty.zero data/$1/are_mergeable.xcv \ - data/empty.zero data/$1/are_mergeable $2 + run_trapped_test test_traits \ + data/empty.zero data/$1/are_mergeable.xcv \ + data/empty.zero data/$1/are_mergeable $2 fi if [ ${commands_indicator[$MERGE]} -ne 0 ] ; then - run_trapped_test test_traits \ - data/empty.zero data/$1/merge.xcv \ - data/empty.zero data/$1/merge $2 + run_trapped_test test_traits \ + data/empty.zero data/$1/merge.xcv \ + data/empty.zero data/$1/merge $2 fi if [ ${commands_indicator[$ASSERTIONS]} -ne 0 ] ; then - run_trapped_test test_traits \ - data/$1/assertions.pt data/$1/assertions.xcv \ - data/empty.zero data/$1/assertions $2 + run_trapped_test test_traits \ + data/$1/assertions.pt data/$1/assertions.xcv \ + data/empty.zero data/$1/assertions $2 fi if [ ${commands_indicator[$CONSTRUCTOR]} -ne 0 ] ; then - run_trapped_test test_traits \ - data/empty.zero data/$1/constructor.xcv \ - data/$1/constructor.cv data/$1/constructor $2 + run_trapped_test test_traits \ + data/empty.zero data/$1/constructor.xcv \ + data/$1/constructor.cv data/$1/constructor $2 fi } @@ -526,120 +525,120 @@ execute_commands_new_structure() commands_indicator[TRIM]=0 i=1 if [ $# -gt 2 ] ; then - for arg in $* ; do - if [ $i -gt 2 ] ; then - commands_indicator[$arg]=1 - fi - let "i+=1" - done + for arg in $* ; do + if [ $i -gt 2 ] ; then + commands_indicator[$arg]=1 + fi + let "i+=1" + done fi if [ ${commands_indicator[$COMPARE]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/compare $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/compare $2 fi if [ ${commands_indicator[$VERTEX]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/vertex $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/vertex $2 fi if [ ${commands_indicator[$IS_VERTICAL]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/is_vertical $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/is_vertical $2 fi if [ ${commands_indicator[$COMPARE_X_AT_LIMIT]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/compare_x_at_limit $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/compare_x_at_limit $2 fi if [ ${commands_indicator[$COMPARE_X_NEAR_LIMIT]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/compare_x_near_limit $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/compare_x_near_limit $2 fi if [ ${commands_indicator[$COMPARE_X_ON_BOUNDARY]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/compare_x_on_boundary $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/compare_x_on_boundary $2 fi if [ ${commands_indicator[$COMPARE_X_NEAR_BOUNDARY]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/compare_x_near_boundary $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/compare_x_near_boundary $2 fi if [ ${commands_indicator[$COMPARE_Y_NEAR_BOUNDARY]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/compare_y_near_boundary $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/compare_y_near_boundary $2 fi if [ ${commands_indicator[$PARAMETER_SPACE_X]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/parameter_space_x $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/parameter_space_x $2 fi if [ ${commands_indicator[$PARAMETER_SPACE_Y]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/parameter_space_y $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/parameter_space_y $2 fi if [ ${commands_indicator[$COMPARE_Y_AT_X]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/compare_y_at_x $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/compare_y_at_x $2 fi if [ ${commands_indicator[$COMPARE_Y_AT_X_LEFT]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/compare_y_at_x_left $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/compare_y_at_x_left $2 fi if [ ${commands_indicator[$COMPARE_Y_AT_X_RIGHT]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/compare_y_at_x_right $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/compare_y_at_x_right $2 fi if [ ${commands_indicator[$MAKE_X_MONOTONE]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/make_x_monotone $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/make_x_monotone $2 fi if [ ${commands_indicator[$INTERSECT]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/intersect $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/intersect $2 fi if [ ${commands_indicator[$SPLIT]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/split $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/split $2 fi if [ ${commands_indicator[$ARE_MERGEABLE]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/are_mergeable $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/are_mergeable $2 fi if [ ${commands_indicator[$MERGE]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/merge $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/merge $2 fi if [ ${commands_indicator[$ASSERTIONS]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/assertions $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/assertions $2 fi if [ ${commands_indicator[$CONSTRUCTOR]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/constructor $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/constructor $2 fi if [ ${commands_indicator[$EQUAL]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/equal $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/equal $2 fi if [ ${commands_indicator[$PUSH_BACK]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/push_back $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/push_back $2 fi if [ ${commands_indicator[$PUSH_FRONT]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/push_front $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/push_front $2 fi if [ ${commands_indicator[$NUMBER_OF_POINTS]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/number_of_points $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/number_of_points $2 fi if [ ${commands_indicator[$COMPARE_ENDPOINTS_XY]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/compare_endpoints_xy $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/compare_endpoints_xy $2 fi if [ ${commands_indicator[$CONSTRUCT_OPPOSITE]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/construct_opposite $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/construct_opposite $2 fi if [ ${commands_indicator[$TRIM]} -ne 0 ] ; then - run_trapped_test test_traits data/$1/points \ - data/$1/xcurves data/$1/curves data/$1/trim $2 + run_trapped_test test_traits data/$1/points \ + data/$1/xcurves data/$1/curves data/$1/trim $2 fi } @@ -669,100 +668,100 @@ execute_commands_traits_adaptor() i=1 if [ $# -gt 2 ] ; then - for arg in $* ; do - if [ $i -gt 2 ] ; then - commands_indicator[$arg]=1 - fi - let "i+=1" - done + for arg in $* ; do + if [ $i -gt 2 ] ; then + commands_indicator[$arg]=1 + fi + let "i+=1" + done fi if [ ${commands_indicator[$PARAMETER_SPACE_X]} -ne 0 ] ; then - run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ - data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ - data/test_adaptor/$1/parameter_space_x $2 + run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ + data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ + data/test_adaptor/$1/parameter_space_x $2 fi if [ ${commands_indicator[$PARAMETER_SPACE_Y]} -ne 0 ] ; then - run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ - data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ - data/test_adaptor/$1/parameter_space_y $2 + run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ + data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ + data/test_adaptor/$1/parameter_space_y $2 fi if [ ${commands_indicator[$COMPARE_X_AT_LIMIT]} -ne 0 ] ; then - run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ - data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ - data/test_adaptor/$1/compare_x_at_limit $2 + run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ + data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ + data/test_adaptor/$1/compare_x_at_limit $2 fi if [ ${commands_indicator[$COMPARE_X_NEAR_LIMIT]} -ne 0 ] ; then - run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ - data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ - data/test_adaptor/$1/compare_x_near_limit $2 + run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ + data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ + data/test_adaptor/$1/compare_x_near_limit $2 fi if [ ${commands_indicator[$COMPARE_X_ON_BOUNDARY]} -ne 0 ] ; then - run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ - data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ - data/test_adaptor/$1/compare_x_on_boundary $2 + run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ + data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ + data/test_adaptor/$1/compare_x_on_boundary $2 fi if [ ${commands_indicator[$COMPARE_X_NEAR_BOUNDARY]} -ne 0 ] ; then - run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ - data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ - data/test_adaptor/$1/compare_x_near_boundary $2 + run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ + data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ + data/test_adaptor/$1/compare_x_near_boundary $2 fi if [ ${commands_indicator[$COMPARE_Y_NEAR_BOUNDARY]} -ne 0 ] ; then - run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ - data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ - data/test_adaptor/$1/compare_y_near_boundary $2 + run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ + data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ + data/test_adaptor/$1/compare_y_near_boundary $2 fi if [ ${commands_indicator[$COMPARE_Y_AT_X_LEFT]} -ne 0 ] ; then - run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ - data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ - data/test_adaptor/$1/compare_y_at_x_left $2 + run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ + data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ + data/test_adaptor/$1/compare_y_at_x_left $2 fi if [ ${commands_indicator[$ARE_MERGEABLE]} -ne 0 ] ; then - run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ - data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ - data/test_adaptor/$1/are_mergeable $2 + run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ + data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ + data/test_adaptor/$1/are_mergeable $2 fi if [ ${commands_indicator[$MERGE]} -ne 0 ] ; then - run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ - data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ - data/test_adaptor/$1/merge $2 + run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ + data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ + data/test_adaptor/$1/merge $2 fi if [ ${commands_indicator[X_ON_IDENTIFICATION]} -ne 0 ] ; then - run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ - data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ - data/test_adaptor/$1/x_on_idintification $2 + run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ + data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ + data/test_adaptor/$1/x_on_idintification $2 fi if [ ${commands_indicator[Y_ON_IDENTIFICATION]} -ne 0 ] ; then - run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ - data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ - data/test_adaptor/$1/x_on_idintification $2 + run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ + data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ + data/test_adaptor/$1/x_on_idintification $2 fi if [ ${commands_indicator[IS_BOUNDED]} -ne 0 ] ; then - run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ - data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ - data/test_adaptor/$1/is_bounded $2 + run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ + data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ + data/test_adaptor/$1/is_bounded $2 fi if [ ${commands_indicator[IS_IN_X_RANGE]} -ne 0 ] ; then - run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ - data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ - data/test_adaptor/$1/is_in_x_range $2 + run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ + data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ + data/test_adaptor/$1/is_in_x_range $2 fi if [ ${commands_indicator[COMPARE_Y_POSITION]} -ne 0 ] ; then - run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ - data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ - data/test_adaptor/$1/compare_y_position $2 + run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ + data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ + data/test_adaptor/$1/compare_y_position $2 fi if [ ${commands_indicator[IS_BETWEEN_CW]} -ne 0 ] ; then - run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ - data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ - data/test_adaptor/$1/is_between_cw $2 + run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ + data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ + data/test_adaptor/$1/is_between_cw $2 fi if [ ${commands_indicator[COMPARE_CW_AROUND_POINT]} -ne 0 ] ; then - run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ - data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ - data/test_adaptor/$1/compare_cw_around_point $2 + run_trapped_test test_traits_adaptor data/test_adaptor/$1/points \ + data/test_adaptor/$1/xcurves data/test_adaptor/$1/curves \ + data/test_adaptor/$1/compare_cw_around_point $2 fi } @@ -1671,8 +1670,8 @@ touch $ERRORFILE if [ $# -ne 0 ] ; then case $1 in - -cmake) TEST_WITH_CMAKE="TRUE" ;; - *)TEST_WITH_CMAKE="FALSE" ;; + -cmake) TEST_WITH_CMAKE="TRUE" ;; + *)TEST_WITH_CMAKE="FALSE" ;; esac else TEST_WITH_CMAKE="FALSE" diff --git a/Surface_sweep_2/test/Surface_sweep_2/cgal_test_base b/Surface_sweep_2/test/Surface_sweep_2/cgal_test_base index 20ec132f55b..52f282475ee 100755 --- a/Surface_sweep_2/test/Surface_sweep_2/cgal_test_base +++ b/Surface_sweep_2/test/Surface_sweep_2/cgal_test_base @@ -78,12 +78,12 @@ compile() compile_and_run() { - + echo "---$1---" # running general test if compile $1 $2 $3 ; then - echo " compilation of $1 succeeded" >> $ERRORFILE + echo " compilation of $1 succeeded" >> $ERRORFILE SUBCURVES="" run $1 $2 $3 $4 SUBCURVES="subcurves" @@ -100,14 +100,14 @@ clean_tests() { if [ "${TEST_WITH_CMAKE}" != "FALSE" ]; then # - # The clean target generated by CMake under cygwin + # The clean target generated by CMake under cygwin # always fails for some reason # - if ! ( uname | grep -q "CYGWIN" ) ; then - "${MAKE_CMD}" -f Makefile clean - fi + if ! ( uname | grep -q "CYGWIN" ) ; then + "${MAKE_CMD}" -f Makefile clean + fi else - eval "${MAKE_CMD} clean > /dev/null 2>&1" + eval "${MAKE_CMD} clean > /dev/null 2>&1" fi } @@ -117,7 +117,7 @@ compile_and_run_sweep() # running general test if compile $1 $2 $3 ; then - echo " compilation of $1 succeeded" >> $ERRORFILE + echo " compilation of $1 succeeded" >> $ERRORFILE run $1 $2 $3 $4 else echo " ERROR: compilation of $1 failed" >> $ERRORFILE @@ -134,28 +134,28 @@ run() for DATAFILE in ${datafiles} do if [ -d $DATAFILE ]; then - echo "$DATEFILE is a directory" + echo "$DATEFILE is a directory" continue fi if [ -f $1 ] ; then DATANAME=`basename $DATAFILE` - if [ $SUBCURVES="subcurves" ] ; then - OUTPUTFILE=ProgramOutput.$3.$1.$DATANAME.$SUBCURVES.$PLATFORM.$2 + if [ $SUBCURVES="subcurves" ] ; then + OUTPUTFILE=ProgramOutput.$3.$1.$DATANAME.$SUBCURVES.$PLATFORM.$2 else - OUTPUTFILE=ProgramOutput.$3.$1.$DATANAME.$PLATFORM.$2 - fi - rm -f $OUTPUTFILE - COMMAND="./$1 $DATAFILE $SUBCURVES" - echo "Executing $1 $DATANAME $SUBCURVES ... " - echo - if eval $COMMAND > $OUTPUTFILE 2>&1 ; then - echo " execution of $1 $DATAFILE $SUBCURVES succeeded" >> $ERRORFILE - else - echo " ERROR: execution of $1 $DATAFILE $SUBCURVES failed" >> $ERRORFILE - fi + OUTPUTFILE=ProgramOutput.$3.$1.$DATANAME.$PLATFORM.$2 + fi + rm -f $OUTPUTFILE + COMMAND="./$1 $DATAFILE $SUBCURVES" + echo "Executing $1 $DATANAME $SUBCURVES ... " + echo + if eval $COMMAND > $OUTPUTFILE 2>&1 ; then + echo " execution of $1 $DATAFILE $SUBCURVES succeeded" >> $ERRORFILE + else + echo " ERROR: execution of $1 $DATAFILE $SUBCURVES failed" >> $ERRORFILE + fi else - echo " ERROR: could not execute $1 $DATAFILE $SUBCURVES" >> $ERRORFILE + echo " ERROR: could not execute $1 $DATAFILE $SUBCURVES" >> $ERRORFILE fi done @@ -178,33 +178,33 @@ run_io() for DATAFILE in ${datafiles} do - + if [ -d $DATAFILE ]; then - echo "$DATEFILE is a directory" + echo "$DATEFILE is a directory" continue fi - + IOFILE="${iofiles}`basename ${DATAFILE}`_${SUFFIO}" echo $IOFILE - + if [ -f $1 ] ; then rm -f arr.txt - + DATANAME=`basename $DATAFILE` - IONAME=`basename $IOFILE` + IONAME=`basename $IOFILE` OUTPUTFILE=ProgramOutput.$3.$1.$DATANAME.$PLATFORM.$2 - rm -f $OUTPUTFILE - COMMAND="./$1 $IOFILE $DATAFILE" - echo "Executing $1 $IONAME $DATANAME ... " - echo - if eval $COMMAND > $OUTPUTFILE 2>&1 ; then - echo " execution of $1 $DATAFILE succeeded" >> $ERRORFILE - else - echo " ERROR: execution of $1 $DATAFILE failed" >> $ERRORFILE - fi + rm -f $OUTPUTFILE + COMMAND="./$1 $IOFILE $DATAFILE" + echo "Executing $1 $IONAME $DATANAME ... " + echo + if eval $COMMAND > $OUTPUTFILE 2>&1 ; then + echo " execution of $1 $DATAFILE succeeded" >> $ERRORFILE + else + echo " ERROR: execution of $1 $DATAFILE failed" >> $ERRORFILE + fi else - echo " ERROR: could not execute $1 $DATAFILE " >> $ERRORFILE + echo " ERROR: could not execute $1 $DATAFILE " >> $ERRORFILE fi done @@ -224,8 +224,8 @@ touch $ERRORFILE if [ $# -ne 0 ] ; then case $1 in - -cmake) TEST_WITH_CMAKE="TRUE" ;; - *)TEST_WITH_CMAKE="FALSE" ;; + -cmake) TEST_WITH_CMAKE="TRUE" ;; + *)TEST_WITH_CMAKE="FALSE" ;; esac else TEST_WITH_CMAKE="FALSE" From 7ab4a8f6a21a5becdda26407c51c40389b44e2c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 19 Feb 2021 14:38:20 +0100 Subject: [PATCH 181/248] handle constrained edges removed upon collapse --- .../repair_degeneracies.h | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair_degeneracies.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair_degeneracies.h index d5a25a32138..0e250f83b58 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair_degeneracies.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair_degeneracies.h @@ -112,6 +112,7 @@ void collect_badly_shaped_triangles(const typename boost::graph_traits Date: Fri, 19 Feb 2021 16:04:34 +0100 Subject: [PATCH 182/248] prevent bad_alloc with LUTSize larger than LUT.max_size() this could happen when size of object was very small and cellSize smaller, e.g. cellSize = 1e-9 thresholding maxMin was not consistent with the size of the object --- .../CGAL/Tetrahedral_remeshing/internal/FMLS.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/FMLS.h b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/FMLS.h index abc0b02c4be..e04a3e8535e 100644 --- a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/FMLS.h +++ b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/FMLS.h @@ -382,11 +382,17 @@ private: minMax[3 + j] = PN[6 * i + j]; } for (std::size_t i = 0; i < 3; i++) { - minMax[i] -= 0.001f; - minMax[3 + i] += 0.001f; + minMax[i] *= 0.99; + minMax[3 + i] *= 1.01; } + for (std::size_t i = 0; i < 3; i++) - res[i] = (std::size_t)ceil((minMax[3 + i] - minMax[i]) / cellSize); + { + if(minMax[3 + i] == minMax[i]) + res[i] = 1; + else + res[i] = (std::size_t)ceil((minMax[3 + i] - minMax[i]) / cellSize); + } std::size_t LUTSize = res[0] * res[1] * res[2]; LUT.resize(LUTSize); LUT.assign(LUTSize, 0); From b5277495e2b1111be2cea1cf7327c700fda776d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 19 Feb 2021 16:10:32 +0100 Subject: [PATCH 183/248] remove no longer needed variables --- .../internal/Corefinement/face_graph_utils.h | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h index c15a4f60ef6..d17227966f0 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h @@ -420,12 +420,9 @@ struct Patch_description{ // shared_edges will be filled by halfedges pointing in the patch // that are inside `is_intersection_edge`, thus mesh boundary halfedges // are not necessarily inside. -template +template void extract_patch_simplices( - std::size_t patch_id, PolygonMesh& pm, - const FaceIndexMap fids, - const std::vector& patch_ids, std::vector::face_descriptor>& patch_faces, std::set::vertex_descriptor>& interior_vertices, std::vector::halfedge_descriptor>& interior_edges, @@ -502,8 +499,7 @@ struct Patch_container{ if ( !patches[i].is_initialized ) { extract_patch_simplices( - i, pm, - fids, patch_ids, + pm, patches[i].faces, patches[i].interior_vertices, patches[i].interior_edges, patches[i].shared_edges, is_intersection_edge From a75ad50a3150200d1b4c8644716f471dbb0d2db4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 19 Feb 2021 16:53:01 +0100 Subject: [PATCH 184/248] allow to handle a triangle as a cap if the collapse_length_threshold is not met --- .../CGAL/Polygon_mesh_processing/repair_degeneracies.h | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair_degeneracies.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair_degeneracies.h index 0e250f83b58..3ed02dfa520 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair_degeneracies.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair_degeneracies.h @@ -79,12 +79,10 @@ is_badly_shaped(const typename boost::graph_traits::face_descripto return make_array(res, null_h); } } - else // let's not make it possible to have a face be both a cap and a needle (for now) - { - res = PMP::is_cap_triangle_face(f, tmesh, cap_threshold, parameters::vertex_point_map(vpm).geom_traits(gt)); - if(res != null_h && !get(ecm, edge(res, tmesh))) - return make_array(null_h, res); - } + + res = PMP::is_cap_triangle_face(f, tmesh, cap_threshold, parameters::vertex_point_map(vpm).geom_traits(gt)); + if(res != null_h && !get(ecm, edge(res, tmesh))) + return make_array(null_h, res); return make_array(null_h, null_h); } From aacd453965695a8a12ee086897161b1aed99d556 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 19 Feb 2021 17:38:34 +0100 Subject: [PATCH 185/248] Do not stitch two halfedges if both are incident to the same degenerate face --- .../CGAL/Polygon_mesh_processing/stitch_borders.h | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/stitch_borders.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/stitch_borders.h index 10b3949d45c..5c3047c7e7a 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/stitch_borders.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/stitch_borders.h @@ -332,17 +332,22 @@ void fill_pairs(const Halfedge& he, bool insertion_ok; std::tie(set_it, insertion_ok) = border_halfedge_map.emplace(he, std::make_pair(1,0)); - if(!insertion_ok) // we found already a halfedge with the points + if(!insertion_ok) // there is already a halfedge with the points { ++set_it->second.first; // increase the multiplicity if(set_it->second.first == 2) { + const Halfedge other_he = set_it->first; set_it->second.second = halfedge_pairs.size(); // set the id of the pair in the vector - halfedge_pairs.emplace_back(set_it->first, he); - if(get(vpm, source(he,pmesh)) == get(vpm, target(set_it->first, pmesh)) && - get(vpm, target(he,pmesh)) == get(vpm, source(set_it->first, pmesh))) + halfedge_pairs.emplace_back(other_he, he); + if(get(vpm, source(he,pmesh)) == get(vpm, target(other_he, pmesh)) && + get(vpm, target(he,pmesh)) == get(vpm, source(other_he, pmesh))) { - manifold_halfedge_pairs.push_back(true); + // Even if the halfedges are compatible, refuse to stitch if that would break the graph + if(face(opposite(he, pmesh), pmesh) == face(opposite(other_he, pmesh), pmesh)) + manifold_halfedge_pairs.push_back(false); + else + manifold_halfedge_pairs.push_back(true); } else { From 8afeab71e76e9f79014355c4c3a5d2cb16696a43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 19 Feb 2021 18:02:15 +0100 Subject: [PATCH 186/248] Various fixes for PMP::remove_almost_degenerate_faces See https://github.com/CGAL/cgal/pull/5476 --- .../repair_degeneracies.h | 296 +++++++++--------- 1 file changed, 144 insertions(+), 152 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair_degeneracies.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair_degeneracies.h index 3ed02dfa520..5698dceb557 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair_degeneracies.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair_degeneracies.h @@ -73,7 +73,7 @@ is_badly_shaped(const typename boost::graph_traits::face_descripto if(res != null_h && !get(ecm, edge(res, tmesh))) { // don't want to collapse edges that are too large - if(collapse_length_threshold == 0 || + if(collapse_length_threshold == 0 || edge_length(res, tmesh, parameters::vertex_point_map(vpm).geom_traits(gt)) <= collapse_length_threshold) { return make_array(res, null_h); @@ -87,7 +87,7 @@ is_badly_shaped(const typename boost::graph_traits::face_descripto return make_array(null_h, null_h); } -template void collect_badly_shaped_triangles(const typename boost::graph_traits::face_descriptor f, TriangleMesh& tmesh, @@ -97,8 +97,8 @@ void collect_badly_shaped_triangles(const typename boost::graph_traits cap const double needle_threshold, // longest edge / shortest edge over this ratio ==> needle const double collapse_length_threshold, // max length of edges allowed to be collapsed - EdgeContainer& edges_to_collapse, - EdgeContainer& edges_to_flip) + HalfedgeContainer& edges_to_collapse, + HalfedgeContainer& edges_to_flip) { typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; @@ -107,21 +107,23 @@ void collect_badly_shaped_triangles(const typename boost::graph_traits::null_halfedge()) { -#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES +#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES_EXTRA std::cout << "add new needle: " << edge(res[0], tmesh) << std::endl; #endif - CGAL_assertion( !get(ecm, edge(res[0], tmesh)) ); - edges_to_collapse.insert(edge(res[0], tmesh)); + CGAL_assertion(!is_border(res[0], tmesh)); + CGAL_assertion(!get(ecm, edge(res[0], tmesh))); + edges_to_collapse.insert(res[0]); } else // let's not make it possible to have a face be both a cap and a needle (for now) { if(res[1] != boost::graph_traits::null_halfedge()) { -#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES +#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES_EXTRA std::cout << "add new cap: " << edge(res[1],tmesh) << std::endl; #endif - CGAL_assertion( !get(ecm, edge(res[1], tmesh)) ); - edges_to_flip.insert(edge(res[1], tmesh)); + CGAL_assertion(!is_border(res[1], tmesh)); + CGAL_assertion(!get(ecm, edge(res[1], tmesh))); + edges_to_flip.insert(res[1]); } } } @@ -381,6 +383,9 @@ bool remove_almost_degenerate_faces(const FaceRange& face_range, typedef typename boost::property_map::type DVCM; DVCM vcm = get(Vertex_property_tag(), tmesh); + CGAL_precondition(is_valid_polygon_mesh(tmesh)); + CGAL_precondition(is_triangle_mesh(tmesh)); + for(face_descriptor f : face_range) { if(f == boost::graph_traits::null_face()) @@ -401,15 +406,22 @@ bool remove_almost_degenerate_faces(const FaceRange& face_range, } // Start the process of removing bad elements - std::set edges_to_collapse; - std::set edges_to_flip; + std::set edges_to_collapse; + std::set edges_to_flip; // @todo could probably do something a bit better by looping edges, consider the incident faces // f1 / f2 and look at f1 if f1 next_edges_to_collapse; - std::set next_edges_to_flip; + std::set next_edges_to_collapse; + std::set next_edges_to_flip; - // treat needles + // Treat needles =============================================================================== #ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES_EXTRA int kk=0; std::ofstream(std::string("tmp/n-00000.off")) << tmesh; #endif while(!edges_to_collapse.empty()) { - edge_descriptor e = *edges_to_collapse.begin(); + halfedge_descriptor h = *edges_to_collapse.begin(); edges_to_collapse.erase(edges_to_collapse.begin()); - CGAL_assertion(!get(ecm, e)); + CGAL_assertion(!is_border(h, tmesh)); - if(get(vcm, source(e, tmesh)) && get(vcm, target(e, tmesh))) + const edge_descriptor e = edge(h, tmesh); + CGAL_assertion(!get(ecm, edge(h, tmesh))); + + if(get(vcm, source(h, tmesh)) && get(vcm, target(h, tmesh))) continue; -#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES - std::cout << " treat needle: " << e << " (" << tmesh.point(source (e, tmesh)) - << " --- " << tmesh.point(target(e, tmesh)) << ")" << std::endl; +#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES_EXTRA + std::cout << " treat needle: " << e + << " (" << source(e, tmesh) << " " << tmesh.point(source(h, tmesh)) + << " --- " << source(e, tmesh) << " " << tmesh.point(target(h, tmesh)) << ")" << std::endl; #endif if(CGAL::Euler::does_satisfy_link_condition(e, tmesh)) { - // the following edges are removed by the collapse - halfedge_descriptor h = halfedge(e, tmesh); - CGAL_assertion(!is_border(h, tmesh)); // because extracted from a face - - std::array nc = + // Verify that the element is still badly shaped + const std::array nc = internal::is_badly_shaped(face(h, tmesh), tmesh, vpm, ecm, gt, cap_threshold, needle_threshold, collapse_length_threshold); if(nc[0] != h) { -#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES - std::cerr << "Warning: Needle criteria no longer verified " << tmesh.point(source(e, tmesh)) << " " - << tmesh.point(target(e, tmesh)) << std::endl; -#endif - // the opposite edge might also have been inserted in the set and might still be a needle - h = opposite(h, tmesh); - if(is_border(h, tmesh)) - continue; - - nc = internal::is_badly_shaped(face(h, tmesh), tmesh, vpm, ecm, gt, - cap_threshold, needle_threshold, - collapse_length_threshold); - if(nc[0] != h) - continue; - } - - int nb_cst=0; - bool too_much_constrained = false; - for(int i=0; i<2; ++i) - { - if(!is_border(h, tmesh)) - { - edge_descriptor pe = edge(prev(h, tmesh), tmesh); - if ( get(ecm, pe) ) - { - ++nb_cst; - pe = edge(next(h, tmesh), tmesh); - if ( get(ecm, pe) ) - { - too_much_constrained = true; - break; - } - } - CGAL_assertion( !get(ecm, pe) ); - edges_to_flip.erase(pe); - next_edges_to_collapse.erase(pe); - edges_to_collapse.erase(pe); - } - - h = opposite(h, tmesh); - } - - if ( too_much_constrained ) - { -#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES - std::cerr << "Warning: cannot collapse: too much constrained! " - << tmesh.point(source(e, tmesh)) << " " - << tmesh.point(target(e, tmesh)) << std::endl; +#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES_EXTRA + std::cout << "\t Needle criteria no longer verified" << std::endl; #endif continue; } // pick the orientation of edge to keep the vertex minimizing the volume variation - h = internal::get_best_edge_orientation(e, tmesh, vpm, vcm, gt); - - if(h == boost::graph_traits::null_halfedge()) + const halfedge_descriptor best_h = internal::get_best_edge_orientation(e, tmesh, vpm, vcm, gt); + if(best_h == boost::graph_traits::null_halfedge()) { -#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES - std::cerr << "Warning: geometrically invalid edge collapse! " - << tmesh.point(source(e, tmesh)) << " " - << tmesh.point(target(e, tmesh)) << std::endl; +#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES_EXTRA + std::cout << "\t Geometrically invalid edge collapse!" << std::endl; #endif - next_edges_to_collapse.insert(e); + next_edges_to_collapse.insert(h); continue; } - edges_to_flip.erase(e); - next_edges_to_collapse.erase(e); // for edges added in faces incident to a vertex kept after a collapse + // Proceeding with the collapse, purge the sets from halfedges being removed + for(int i=0; i<2; ++i) + { + if(!is_border(h, tmesh)) + { + edges_to_flip.erase(h); + edges_to_collapse.erase(h); + next_edges_to_collapse.erase(h); + + halfedge_descriptor rm_h = prev(h, tmesh); + if(get(ecm, edge(rm_h, tmesh))) + rm_h = next(h, tmesh); + + edges_to_flip.erase(rm_h); + edges_to_collapse.erase(rm_h); + next_edges_to_collapse.erase(rm_h); + + halfedge_descriptor opp_rm_h = opposite(rm_h, tmesh); + edges_to_flip.erase(opp_rm_h); + edges_to_collapse.erase(opp_rm_h); + next_edges_to_collapse.erase(opp_rm_h); + } + + h = opposite(h, tmesh); + } + #ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES_EXTRA - std::cerr << " " << kk << " -- Collapsing " << tmesh.point(source(h, tmesh)) << " " - << tmesh.point(target(h, tmesh)) << std::endl; + std::cout << " " << kk << " -- Collapsing " << tmesh.point(source(best_h, tmesh)) << " " + << tmesh.point(target(best_h, tmesh)) << std::endl; #endif + + CGAL_assertion(!get(vcm, source(best_h, tmesh))); + + // The function get_best_edge_orientation() has ensured that get(vcm, source(h, tmesh)) + // is not constrained, so get(ecm, e) is also not constrained for all e incident + // to source(h, tmesh). + // + // The function Euler::collapse_edge() removes edge(prev(h, tmesh)), but that edge + // might be constrained. In that case, next() must be removed instead. + vertex_descriptor v; + if(get(ecm, edge(prev(h, tmesh), tmesh))) + v = Euler::collapse_edge(edge(best_h, tmesh), tmesh, ecm); + else + v = Euler::collapse_edge(edge(best_h, tmesh), tmesh); + // moving to the midpoint is not a good idea. On a circle for example you might endpoint with // a bad geometry because you iteratively move one point // auto mp = midpoint(tmesh.point(source(h, tmesh)), tmesh.point(target(h, tmesh))); + // tmesh.point(v) = mp; - vertex_descriptor v = nb_cst == 0 ? Euler::collapse_edge(edge(h, tmesh), tmesh) - : Euler::collapse_edge(edge(h, tmesh), tmesh, ecm); - - //tmesh.point(v) = mp; // examine all faces incident to the vertex kept for(halfedge_descriptor hv : halfedges_around_target(v, tmesh)) { @@ -568,92 +569,87 @@ bool remove_almost_degenerate_faces(const FaceRange& face_range, #endif something_was_done = true; } - else + else // ! CGAL::Euler::does_satisfy_link_condition(e, tmesh) { -#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES - std::cerr << "Warning: uncollapsable edge! " << tmesh.point(source(e, tmesh)) << " " - << tmesh.point(target(e, tmesh)) << std::endl; +#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES_EXTRA + std::cout << "\t Uncollapsable edge!" << std::endl; #endif - next_edges_to_collapse.insert(e); + next_edges_to_collapse.insert(h); } } - // treat caps + // Treat caps ================================================================================== + CGAL_assertion(next_edges_to_flip.empty()); + #ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES_EXTRA kk=0; std::ofstream(std::string("tmp/c-000.off")) << tmesh; #endif while(!edges_to_flip.empty()) { - edge_descriptor e = *edges_to_flip.begin(); + halfedge_descriptor h = *edges_to_flip.begin(); edges_to_flip.erase(edges_to_flip.begin()); + CGAL_assertion(!is_border(h, tmesh)); + + const edge_descriptor e = edge(h, tmesh); CGAL_assertion(!get(ecm, e)); if(get(vcm, source(e, tmesh)) && get(vcm, target(e, tmesh))) continue; -#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES - std::cout << "treat cap: " << e << " (" << tmesh.point(source(e, tmesh)) - << " --- " << tmesh.point(target(e, tmesh)) << ")" << std::endl; +#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES_EXTRA + std::cout << " treat cap: " << e + << " (" << source(e, tmesh) << " " << tmesh.point(source(h, tmesh)) + << " --- " << target(e, tmesh) << " " << tmesh.point(target(h, tmesh)) << ")" << std::endl; #endif - halfedge_descriptor h = halfedge(e, tmesh); std::array nc = internal::is_badly_shaped(face(h, tmesh), tmesh, vpm, ecm, gt, cap_threshold, needle_threshold, collapse_length_threshold); - // First check the triangle is still a cap + // Check the triangle is still a cap if(nc[1] != h) { -#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES - std::cerr << "Warning: Cap criteria no longer verified " << tmesh.point(source(e, tmesh)) << " --- " - << tmesh.point(target(e, tmesh)) << std::endl; +#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES_EXTRA + std::cout << "\t Cap criteria no longer verified" << std::endl; #endif - // the opposite edge might also have been inserted in the set and might still be a cap - h = opposite(h, tmesh); - if(is_border(h, tmesh)) - continue; - - nc = internal::is_badly_shaped(face(h, tmesh), tmesh, vpm, ecm, gt, - cap_threshold, needle_threshold, collapse_length_threshold); - if(nc[1] != h) - continue; + continue; } - // special case on the border + // special case of `edge(h, tmesh)` being a border edge --> remove the face if(is_border(opposite(h, tmesh), tmesh)) { - // remove the triangle - edges_to_flip.erase(edge(prev(h, tmesh), tmesh)); - edges_to_flip.erase(edge(next(h, tmesh), tmesh)); - next_edges_to_collapse.erase(edge(prev(h, tmesh), tmesh)); - next_edges_to_collapse.erase(edge(next(h, tmesh), tmesh)); + for(halfedge_descriptor hh : CGAL::halfedges_around_face(h, tmesh)) + { + // Remove from even 'next_edges_to_flip' because it might have been re-added from a flip + edges_to_flip.erase(hh); + next_edges_to_flip.erase(hh); + next_edges_to_collapse.erase(hh); + } + Euler::remove_face(h, tmesh); + something_was_done = true; continue; } + CGAL_assertion(!is_border(e, tmesh)); + // condition for the flip to be valid (the edge to be created does not already exist) if(!halfedge(target(next(h, tmesh), tmesh), target(next(opposite(h, tmesh), tmesh), tmesh), tmesh).second) { - if(!internal::should_flip(e, tmesh, vpm, gt)) { -#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES - std::cout << "Flipping prevented: not the best diagonal" << std::endl; +#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES_EXTRA + std::cout << "\t Flipping prevented: not the best diagonal" << std::endl; #endif - next_edges_to_flip.insert(e); + next_edges_to_flip.insert(h); continue; } -#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES - std::cout << "Flipping" << std::endl; -#endif #ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES_EXTRA - std::cerr << "step " << kk << "\n"; - std::cerr << " Flipping " << tmesh.point(source(h, tmesh)) << " " - << tmesh.point(target(h, tmesh)) << std::endl; + std::cout << "\t step " << kk << " -- Flipping" << std::endl; #endif Euler::flip_edge(h, tmesh); CGAL_assertion(edge(h, tmesh) == e); @@ -666,30 +662,25 @@ bool remove_almost_degenerate_faces(const FaceRange& face_range, internal::is_badly_shaped(face(h, tmesh), tmesh, vpm, ecm, gt, cap_threshold, needle_threshold, collapse_length_threshold); - if(nc[1] != boost::graph_traits::null_halfedge()) - { - if(edge(nc[1], tmesh) != e) - next_edges_to_flip.insert(edge(nc[1], tmesh)); - } - else - { - if(nc[0] != boost::graph_traits::null_halfedge()) - { - next_edges_to_collapse.insert(edge(nc[0], tmesh)); - } - } + if(nc[1] != boost::graph_traits::null_halfedge() && nc[1] != h) + next_edges_to_flip.insert(nc[1]); + else if(nc[0] != boost::graph_traits::null_halfedge()) + next_edges_to_collapse.insert(nc[0]); + h = opposite(h, tmesh); } + something_was_done = true; } -#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES - else + else // flipped edge already exists in the mesh { - std::cerr << "Warning: unflippable edge! " << tmesh.point(source(h, tmesh)) << " --- " - << tmesh.point(target(h, tmesh)) << std::endl; - next_edges_to_flip.insert(e); - } +#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES_EXTRA + std::cout << "\t Unflippable edge!" << std::endl; #endif + CGAL_assertion(!is_border(h, tmesh)); + next_edges_to_flip.insert(h); + } + #ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES_EXTRA std::string nb = std::to_string(++kk); if(kk<10) nb = std::string("0")+nb; @@ -700,11 +691,11 @@ bool remove_almost_degenerate_faces(const FaceRange& face_range, #endif } - std::swap(edges_to_collapse, next_edges_to_collapse); - std::swap(edges_to_flip, next_edges_to_flip); - if(!something_was_done) return false; + + std::swap(edges_to_collapse, next_edges_to_collapse); + std::swap(edges_to_flip, next_edges_to_flip); } return false; @@ -1522,7 +1513,7 @@ bool remove_degenerate_edges(const EdgeRange& edge_range, face_set.insert(face(hd, tmesh)); } - CGAL_assertion(is_valid_polygon_mesh(tmesh)); + CGAL_expensive_assertion(is_valid_polygon_mesh(tmesh)); } } } @@ -1609,6 +1600,7 @@ bool remove_degenerate_faces(const FaceRange& face_range, const NamedParameters& np) { CGAL_assertion(CGAL::is_triangle_mesh(tmesh)); + CGAL_assertion(CGAL::is_valid_polygon_mesh(tmesh)); using parameters::get_parameter; using parameters::choose_parameter; From 68f53bc518ec9c4203a942bf4e60300307528c0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 19 Feb 2021 18:04:58 +0100 Subject: [PATCH 187/248] Clean preconditions of is_needle/cap --- .../include/CGAL/Polygon_mesh_processing/shape_predicates.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/shape_predicates.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/shape_predicates.h index ebfb661d346..fb05b41b819 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/shape_predicates.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/shape_predicates.h @@ -358,6 +358,8 @@ is_needle_triangle_face(typename boost::graph_traits::face_descrip const NamedParameters& np) { CGAL_precondition(threshold >= 1.); + CGAL_precondition(f != boost::graph_traits::null_face()); + CGAL_precondition(CGAL::is_triangle(halfedge(f, tm), tm)); using parameters::get_parameter; using parameters::choose_parameter; @@ -462,7 +464,8 @@ is_cap_triangle_face(typename boost::graph_traits::face_descriptor const double threshold, const NamedParameters& np) { - CGAL_precondition(CGAL::is_triangle_mesh(tm)); + CGAL_precondition(f != boost::graph_traits::null_face()); + CGAL_precondition(CGAL::is_triangle(halfedge(f, tm), tm)); CGAL_precondition(threshold >= -1.); CGAL_precondition(threshold <= 0.); From d5a5b20ce89999c7e4db1a86981dc38ba58ab987 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Fri, 19 Feb 2021 20:23:20 +0000 Subject: [PATCH 188/248] Make it clear that the functor is not part of the Kernel concept --- Filtered_kernel/include/CGAL/Lazy.h | 2 +- Filtered_kernel/include/CGAL/Lazy_kernel.h | 6 ++--- .../CGAL/Intersections_3/Line_3_Plane_3.h | 8 +++---- .../CGAL/Intersections_3/Plane_3_Plane_3.h | 4 ++-- .../include/CGAL/Kernel/function_objects.h | 6 ++++- .../include/CGAL/Kernel/interface_macros.h | 4 ++-- .../include/CGAL/Polyhedral_envelope.h | 24 +++++++++---------- 7 files changed, 29 insertions(+), 25 deletions(-) diff --git a/Filtered_kernel/include/CGAL/Lazy.h b/Filtered_kernel/include/CGAL/Lazy.h index 539ebbff948..82d6ff20f58 100644 --- a/Filtered_kernel/include/CGAL/Lazy.h +++ b/Filtered_kernel/include/CGAL/Lazy.h @@ -874,7 +874,7 @@ struct Lazy_construction_bbox template -struct Lazy_construction_optional +struct Lazy_construction_optional_for_polygonal_envelope { static const bool Protection = true; typedef typename LK::Approximate_kernel AK; diff --git a/Filtered_kernel/include/CGAL/Lazy_kernel.h b/Filtered_kernel/include/CGAL/Lazy_kernel.h index 71edc17eff7..89a84b5f150 100644 --- a/Filtered_kernel/include/CGAL/Lazy_kernel.h +++ b/Filtered_kernel/include/CGAL/Lazy_kernel.h @@ -178,7 +178,7 @@ private: // The case distinction goes as follows: // result_type == FT => NT // result_type == Object => Object - // result_type == boost::optional => OPTIONAL_ + // result_type == boost::optional => OPTIONAL_ Only for Intersect_point_3_for_polyhedral_envelope which returns a handle for a singleton // result_type == Bbox_2 || result_type == Bbox_3 => BBOX // default => NONE // no result_type => NONE @@ -214,7 +214,7 @@ private: CGAL_WRAPPER_TRAIT(Intersect_2, VARIANT) CGAL_WRAPPER_TRAIT(Intersect_3, VARIANT) - CGAL_WRAPPER_TRAIT(Intersect_point_3, OPTIONAL_) + CGAL_WRAPPER_TRAIT(Intersect_point_3_for_polyhedral_envelope, OPTIONAL_) CGAL_WRAPPER_TRAIT(Compute_squared_radius_2, NT) CGAL_WRAPPER_TRAIT(Compute_x_3, NT) CGAL_WRAPPER_TRAIT(Compute_y_3, NT) @@ -258,7 +258,7 @@ private: template struct Select_wrapper_impl { template - struct apply { typedef Lazy_construction_optional type; }; + struct apply { typedef Lazy_construction_optional_for_polygonal_envelope type; }; }; template diff --git a/Intersections_3/include/CGAL/Intersections_3/Line_3_Plane_3.h b/Intersections_3/include/CGAL/Intersections_3/Line_3_Plane_3.h index 5dc93e65edd..49f64fa5fca 100644 --- a/Intersections_3/include/CGAL/Intersections_3/Line_3_Plane_3.h +++ b/Intersections_3/include/CGAL/Intersections_3/Line_3_Plane_3.h @@ -26,17 +26,17 @@ CGAL_DO_INTERSECT_FUNCTION(Plane_3, Line_3, 3) template < class K > inline boost::optional -intersection_point(const Plane_3& plane, const Line_3& line) +intersection_point_for_polyhedral_envelope(const Plane_3& plane, const Line_3& line) { - return K().intersect_point_3_object()(plane, line); + return K().intersect_point_3_for_polyhedral_envelope_object()(plane, line); } template < class K > inline boost::optional - intersection_point(const Line_3& line, const Plane_3& plane) + intersection_point_for_polyhedral_envelope(const Line_3& line, const Plane_3& plane) { - return K().intersect_point_3_object()(plane, line); + return K().intersect_point_3_for_polyhedral_envelope_object()(plane, line); } } diff --git a/Intersections_3/include/CGAL/Intersections_3/Plane_3_Plane_3.h b/Intersections_3/include/CGAL/Intersections_3/Plane_3_Plane_3.h index 5f3a176056c..7f82f23b740 100644 --- a/Intersections_3/include/CGAL/Intersections_3/Plane_3_Plane_3.h +++ b/Intersections_3/include/CGAL/Intersections_3/Plane_3_Plane_3.h @@ -26,9 +26,9 @@ CGAL_DO_INTERSECT_FUNCTION_SELF(Plane_3, 3) template < class K > inline boost::optional -intersection_point(const Plane_3& p0, const Plane_3& p1, const Plane_3& p2) +intersection_point_for_polyhedral_envelope(const Plane_3& p0, const Plane_3& p1, const Plane_3& p2) { - return K().intersect_point_3_object()(p0, p1, p2); + return K().intersect_point_3_for_polyhedral_envelope_object()(p0, p1, p2); } } diff --git a/Kernel_23/include/CGAL/Kernel/function_objects.h b/Kernel_23/include/CGAL/Kernel/function_objects.h index b462f6ef001..eaf86e7fa33 100644 --- a/Kernel_23/include/CGAL/Kernel/function_objects.h +++ b/Kernel_23/include/CGAL/Kernel/function_objects.h @@ -3568,8 +3568,12 @@ namespace CommonKernelFunctors { }; + // This functor is not part of the documented Kernel API, but an implementation detail + // of Polygon_mesh_processing::Polyhedral_envelope + // When used with the Lazy_kernel (that is Epeck) the returned point + // is a singleton (so its coordinates will be changed by another call). template - class Intersect_point_3 + class Intersect_point_3_for_polyhedral_envelope { public: typedef typename K::Point_3 Point_3; diff --git a/Kernel_23/include/CGAL/Kernel/interface_macros.h b/Kernel_23/include/CGAL/Kernel/interface_macros.h index 43f5ff7a2f7..a4caf77e7be 100644 --- a/Kernel_23/include/CGAL/Kernel/interface_macros.h +++ b/Kernel_23/include/CGAL/Kernel/interface_macros.h @@ -542,8 +542,8 @@ CGAL_Kernel_cons(Intersect_2, intersect_2_object) CGAL_Kernel_cons(Intersect_3, intersect_3_object) -CGAL_Kernel_cons(Intersect_point_3, - intersect_point_3_object) +CGAL_Kernel_cons(Intersect_point_3_for_polyhedral_envelope, + intersect_point_3_for_polyhedral_envelope_object) CGAL_Kernel_pred(Is_degenerate_2, is_degenerate_2_object) CGAL_Kernel_pred_RT(Is_degenerate_3, diff --git a/Polygon_mesh_processing/include/CGAL/Polyhedral_envelope.h b/Polygon_mesh_processing/include/CGAL/Polyhedral_envelope.h index 53c16127926..b1d76c12950 100644 --- a/Polygon_mesh_processing/include/CGAL/Polyhedral_envelope.h +++ b/Polygon_mesh_processing/include/CGAL/Polyhedral_envelope.h @@ -729,7 +729,7 @@ private: for (unsigned int i = 0; i < cutp.size(); i++){ const Plane& plane_i = prism[cutp[i]]; - boost::optional op = intersection_point(line, plane_i.eplane); + boost::optional op = intersection_point_for_polyhedral_envelope(line, plane_i.eplane); if(! op){ std::cout << "there must be an intersection 2" << std::endl; } @@ -850,8 +850,8 @@ private: } for (unsigned int j = 0; j < cidl.size(); j++) { - boost::optional op = intersection_point(line, - halfspace[prismindex[queue[i]]][cidl[j]].eplane); + boost::optional op = intersection_point_for_polyhedral_envelope(line, + halfspace[prismindex[queue[i]]][cidl[j]].eplane); const ePoint_3& ip = *op; inter = Implicit_Seg_Facet_interpoint_Out_Prism_return_local_id (ip, idlist, jump1, check_id); @@ -1034,7 +1034,7 @@ private: const Plane& plane_i = prism[cutp[i]]; const eLine_3& eline = *(seg[k]); - boost::optional op = intersection_point(eline, plane_i.eplane); + boost::optional op = intersection_point_for_polyhedral_envelope(eline, plane_i.eplane); if(! op){ #ifdef CGAL_ENVELOPE_DEBUG std::cout << "there must be an intersection 6" << std::endl; @@ -1088,7 +1088,7 @@ private: int inter = 0; - boost::optional ipp = intersection_point(tri_eplane, prism[cutp[i]].eplane, prism[cutp[j]].eplane); + boost::optional ipp = intersection_point_for_polyhedral_envelope(tri_eplane, prism[cutp[i]].eplane, prism[cutp[j]].eplane); if(ipp){ inter = is_3_triangle_cut_float_fast(tri0, tri1, tri2, n, @@ -1528,8 +1528,8 @@ private: if (!cut) continue; for (unsigned int j = 0; j < cidl.size(); j++) { - boost::optional op = intersection_point(eline, - halfspace[prismindex[queue[i]]][cidl[j]].eplane); + boost::optional op = intersection_point_for_polyhedral_envelope(eline, + halfspace[prismindex[queue[i]]][cidl[j]].eplane); const ePoint_3& ip = *op; inter = Implicit_Seg_Facet_interpoint_Out_Prism_return_local_id(ip, idlist, jump1, check_id); @@ -1612,8 +1612,8 @@ private: } // now we know that there exists an intesection point - boost::optional op = intersection_point(eline, - halfspace[filtered_intersection[queue[i]]][intersect_face[queue[i]][j]].eplane); + boost::optional op = intersection_point_for_polyhedral_envelope(eline, + halfspace[filtered_intersection[queue[i]]][intersect_face[queue[i]][j]].eplane); const ePoint_3& ip = *op; inter = Implicit_Seg_Facet_interpoint_Out_Prism_return_local_id_with_face_order(ip, idlist, idlistorder, jump1, check_id); @@ -1696,9 +1696,9 @@ private: // We moved the intersection here // In case there is no intersection point we continue boost::optional - op = intersection_point(etriangle_eplane, - halfspace[jump1][intersect_face[queue[i]][k]].eplane, - halfspace[jump2][intersect_face[queue[j]][h]].eplane); + op = intersection_point_for_polyhedral_envelope(etriangle_eplane, + halfspace[jump1][intersect_face[queue[i]][k]].eplane, + halfspace[jump2][intersect_face[queue[j]][h]].eplane); if(! op){ continue; } From 2aa9b0297ccfbf36351f6d426537ad9026d981e7 Mon Sep 17 00:00:00 2001 From: Dmitry Anisimov Date: Sat, 20 Feb 2021 11:03:11 +0100 Subject: [PATCH 189/248] kd tree using vector constructor instead of insert --- Spatial_searching/include/CGAL/Kd_tree.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Spatial_searching/include/CGAL/Kd_tree.h b/Spatial_searching/include/CGAL/Kd_tree.h index f4cf65bd057..4e8eb8abaa3 100644 --- a/Spatial_searching/include/CGAL/Kd_tree.h +++ b/Spatial_searching/include/CGAL/Kd_tree.h @@ -281,10 +281,8 @@ public: template Kd_tree(InputIterator first, InputIterator beyond, Splitter s = Splitter(),const SearchTraits traits=SearchTraits()) - : traits_(traits),split(s), built_(false), removed_(false) - { - pts.insert(pts.end(), first, beyond); - } + : traits_(traits), split(s), pts(first, beyond), built_(false), removed_(false) + { } bool empty() const { return pts.empty(); From 9689ad23c23f590de422827a077705cf5b4125d9 Mon Sep 17 00:00:00 2001 From: Dmitry Anisimov Date: Fri, 19 Feb 2021 11:21:02 +0100 Subject: [PATCH 190/248] added RUN_SERIAL option to the parallel tests in Triangulation_3 and Mesh_3 --- Mesh_3/test/Mesh_3/CMakeLists.txt | 15 +++++++++++++++ .../examples/Triangulation_3/CMakeLists.txt | 5 +++++ .../test/Triangulation_3/CMakeLists.txt | 8 ++++++-- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/Mesh_3/test/Mesh_3/CMakeLists.txt b/Mesh_3/test/Mesh_3/CMakeLists.txt index 404c607d889..e070ffc792c 100644 --- a/Mesh_3/test/Mesh_3/CMakeLists.txt +++ b/Mesh_3/test/Mesh_3/CMakeLists.txt @@ -119,6 +119,21 @@ if ( CGAL_FOUND ) target_link_libraries(${target} PUBLIC CGAL::TBB_support) endif() endforeach() + + if(BUILD_TESTING) + set_property(TEST execution___of__test_meshing_verbose PROPERTY RUN_SERIAL 1) + set_property(TEST execution___of__test_meshing_polyhedron_with_features PROPERTY RUN_SERIAL 1) + set_property(TEST execution___of__test_meshing_implicit_function PROPERTY RUN_SERIAL 1) + set_property(TEST execution___of__test_meshing_3D_image PROPERTY RUN_SERIAL 1) + set_property(TEST execution___of__test_meshing_3D_gray_image PROPERTY RUN_SERIAL 1) + set_property(TEST execution___of__test_meshing_unit_tetrahedron PROPERTY RUN_SERIAL 1) + set_property(TEST execution___of__test_meshing_polyhedron PROPERTY RUN_SERIAL 1) + set_property(TEST execution___of__test_meshing_polyhedral_complex PROPERTY RUN_SERIAL 1) + set_property(TEST execution___of__test_mesh_capsule_var_distance_bound PROPERTY RUN_SERIAL 1) + set_property(TEST execution___of__test_mesh_3_issue_1554 PROPERTY RUN_SERIAL 1) + set_property(TEST execution___of__test_mesh_polyhedral_domain_with_features_deprecated PROPERTY RUN_SERIAL 1) + set_property(TEST execution___of__test_mesh_cell_base_3 PROPERTY RUN_SERIAL 1) + endif() endif() else() diff --git a/Triangulation_3/examples/Triangulation_3/CMakeLists.txt b/Triangulation_3/examples/Triangulation_3/CMakeLists.txt index a44531dec74..8976d00e6b3 100644 --- a/Triangulation_3/examples/Triangulation_3/CMakeLists.txt +++ b/Triangulation_3/examples/Triangulation_3/CMakeLists.txt @@ -52,6 +52,11 @@ if ( CGAL_FOUND ) message(STATUS "NOTICE: a few examples require TBB and will not be compiled.") endif() + if(BUILD_TESTING) + set_property(TEST execution___of__parallel_insertion_and_removal_in_regular_3 PROPERTY RUN_SERIAL 1) + set_property(TEST execution___of__parallel_insertion_in_delaunay_3 PROPERTY RUN_SERIAL 1) + set_property(TEST execution___of__sequential_parallel PROPERTY RUN_SERIAL 1) + endif() else() message(STATUS "This program requires the CGAL library, and will not be compiled.") diff --git a/Triangulation_3/test/Triangulation_3/CMakeLists.txt b/Triangulation_3/test/Triangulation_3/CMakeLists.txt index 4dfcc8c4bb5..7b1222f44b9 100644 --- a/Triangulation_3/test/Triangulation_3/CMakeLists.txt +++ b/Triangulation_3/test/Triangulation_3/CMakeLists.txt @@ -40,7 +40,11 @@ if ( CGAL_FOUND ) endforeach() endif() - if(BUILD_TESTING) + if(BUILD_TESTING) + set_property(TEST execution___of__test_delaunay_3 PROPERTY RUN_SERIAL 1) + set_property(TEST execution___of__test_regular_3 PROPERTY RUN_SERIAL 1) + set_property(TEST execution___of__test_regular_insert_range_with_info PROPERTY RUN_SERIAL 1) + set_tests_properties( execution___of__test_delaunay_hierarchy_3 execution___of__test_delaunay_hierarchy_3_old @@ -53,5 +57,5 @@ if ( CGAL_FOUND ) else() message(STATUS "This program requires the CGAL library, and will not be compiled.") - + endif() From 5ca5472ba43cc58cd1551588af652b80dc0e085d Mon Sep 17 00:00:00 2001 From: Dmitry Anisimov Date: Fri, 19 Feb 2021 13:15:09 +0100 Subject: [PATCH 191/248] better style --- Mesh_3/test/Mesh_3/CMakeLists.txt | 26 ++++++++++--------- .../examples/Triangulation_3/CMakeLists.txt | 8 +++--- .../test/Triangulation_3/CMakeLists.txt | 12 +++++---- 3 files changed, 26 insertions(+), 20 deletions(-) diff --git a/Mesh_3/test/Mesh_3/CMakeLists.txt b/Mesh_3/test/Mesh_3/CMakeLists.txt index e070ffc792c..2792abc27a2 100644 --- a/Mesh_3/test/Mesh_3/CMakeLists.txt +++ b/Mesh_3/test/Mesh_3/CMakeLists.txt @@ -121,18 +121,20 @@ if ( CGAL_FOUND ) endforeach() if(BUILD_TESTING) - set_property(TEST execution___of__test_meshing_verbose PROPERTY RUN_SERIAL 1) - set_property(TEST execution___of__test_meshing_polyhedron_with_features PROPERTY RUN_SERIAL 1) - set_property(TEST execution___of__test_meshing_implicit_function PROPERTY RUN_SERIAL 1) - set_property(TEST execution___of__test_meshing_3D_image PROPERTY RUN_SERIAL 1) - set_property(TEST execution___of__test_meshing_3D_gray_image PROPERTY RUN_SERIAL 1) - set_property(TEST execution___of__test_meshing_unit_tetrahedron PROPERTY RUN_SERIAL 1) - set_property(TEST execution___of__test_meshing_polyhedron PROPERTY RUN_SERIAL 1) - set_property(TEST execution___of__test_meshing_polyhedral_complex PROPERTY RUN_SERIAL 1) - set_property(TEST execution___of__test_mesh_capsule_var_distance_bound PROPERTY RUN_SERIAL 1) - set_property(TEST execution___of__test_mesh_3_issue_1554 PROPERTY RUN_SERIAL 1) - set_property(TEST execution___of__test_mesh_polyhedral_domain_with_features_deprecated PROPERTY RUN_SERIAL 1) - set_property(TEST execution___of__test_mesh_cell_base_3 PROPERTY RUN_SERIAL 1) + set_property(TEST + execution___of__test_meshing_verbose + execution___of__test_meshing_polyhedron_with_features + execution___of__test_meshing_implicit_function + execution___of__test_meshing_3D_image + execution___of__test_meshing_3D_gray_image + execution___of__test_meshing_unit_tetrahedron + execution___of__test_meshing_polyhedron + execution___of__test_meshing_polyhedral_complex + execution___of__test_mesh_capsule_var_distance_bound + execution___of__test_mesh_3_issue_1554 + execution___of__test_mesh_polyhedral_domain_with_features_deprecated + execution___of__test_mesh_cell_base_3 + PROPERTY RUN_SERIAL 1) endif() endif() diff --git a/Triangulation_3/examples/Triangulation_3/CMakeLists.txt b/Triangulation_3/examples/Triangulation_3/CMakeLists.txt index 8976d00e6b3..d25ea650600 100644 --- a/Triangulation_3/examples/Triangulation_3/CMakeLists.txt +++ b/Triangulation_3/examples/Triangulation_3/CMakeLists.txt @@ -53,9 +53,11 @@ if ( CGAL_FOUND ) endif() if(BUILD_TESTING) - set_property(TEST execution___of__parallel_insertion_and_removal_in_regular_3 PROPERTY RUN_SERIAL 1) - set_property(TEST execution___of__parallel_insertion_in_delaunay_3 PROPERTY RUN_SERIAL 1) - set_property(TEST execution___of__sequential_parallel PROPERTY RUN_SERIAL 1) + set_property(TEST + execution___of__parallel_insertion_and_removal_in_regular_3 + execution___of__parallel_insertion_in_delaunay_3 + execution___of__sequential_parallel + PROPERTY RUN_SERIAL 1) endif() else() diff --git a/Triangulation_3/test/Triangulation_3/CMakeLists.txt b/Triangulation_3/test/Triangulation_3/CMakeLists.txt index 7b1222f44b9..1741af02164 100644 --- a/Triangulation_3/test/Triangulation_3/CMakeLists.txt +++ b/Triangulation_3/test/Triangulation_3/CMakeLists.txt @@ -41,10 +41,12 @@ if ( CGAL_FOUND ) endif() if(BUILD_TESTING) - set_property(TEST execution___of__test_delaunay_3 PROPERTY RUN_SERIAL 1) - set_property(TEST execution___of__test_regular_3 PROPERTY RUN_SERIAL 1) - set_property(TEST execution___of__test_regular_insert_range_with_info PROPERTY RUN_SERIAL 1) - + set_property(TEST + execution___of__test_delaunay_3 + execution___of__test_regular_3 + execution___of__test_regular_insert_range_with_info + PROPERTY RUN_SERIAL 1) + set_tests_properties( execution___of__test_delaunay_hierarchy_3 execution___of__test_delaunay_hierarchy_3_old @@ -57,5 +59,5 @@ if ( CGAL_FOUND ) else() message(STATUS "This program requires the CGAL library, and will not be compiled.") - + endif() From a61653b2d84fedfd5469a073d1a40ba5a59a94a1 Mon Sep 17 00:00:00 2001 From: Dmitry Anisimov Date: Mon, 22 Feb 2021 12:03:05 +0100 Subject: [PATCH 192/248] all parallel tests are executed serial only in case of TBB on --- .../examples/Triangulation_3/CMakeLists.txt | 18 +++++++++--------- .../test/Triangulation_3/CMakeLists.txt | 16 +++++++++------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/Triangulation_3/examples/Triangulation_3/CMakeLists.txt b/Triangulation_3/examples/Triangulation_3/CMakeLists.txt index d25ea650600..5cfa58d2d27 100644 --- a/Triangulation_3/examples/Triangulation_3/CMakeLists.txt +++ b/Triangulation_3/examples/Triangulation_3/CMakeLists.txt @@ -47,18 +47,18 @@ if ( CGAL_FOUND ) create_single_source_cgal_program( "sequential_parallel.cpp" ) target_link_libraries( parallel_insertion_and_removal_in_regular_3 PUBLIC CGAL::TBB_support) target_link_libraries( parallel_insertion_in_delaunay_3 PUBLIC CGAL::TBB_support ) - target_link_libraries( sequential_parallel PUBLIC CGAL::TBB_support) + target_link_libraries( sequential_parallel PUBLIC CGAL::TBB_support) + + if(BUILD_TESTING) + set_property(TEST + execution___of__parallel_insertion_and_removal_in_regular_3 + execution___of__parallel_insertion_in_delaunay_3 + execution___of__sequential_parallel + PROPERTY RUN_SERIAL 1) + endif() else() message(STATUS "NOTICE: a few examples require TBB and will not be compiled.") endif() - - if(BUILD_TESTING) - set_property(TEST - execution___of__parallel_insertion_and_removal_in_regular_3 - execution___of__parallel_insertion_in_delaunay_3 - execution___of__sequential_parallel - PROPERTY RUN_SERIAL 1) - endif() else() message(STATUS "This program requires the CGAL library, and will not be compiled.") diff --git a/Triangulation_3/test/Triangulation_3/CMakeLists.txt b/Triangulation_3/test/Triangulation_3/CMakeLists.txt index 1741af02164..444dd43a145 100644 --- a/Triangulation_3/test/Triangulation_3/CMakeLists.txt +++ b/Triangulation_3/test/Triangulation_3/CMakeLists.txt @@ -38,15 +38,17 @@ if ( CGAL_FOUND ) test_regular_insert_range_with_info) target_link_libraries(${target} PUBLIC CGAL::TBB_support) endforeach() + + if(BUILD_TESTING) + set_property(TEST + execution___of__test_delaunay_3 + execution___of__test_regular_3 + execution___of__test_regular_insert_range_with_info + PROPERTY RUN_SERIAL 1) + endif() endif() - if(BUILD_TESTING) - set_property(TEST - execution___of__test_delaunay_3 - execution___of__test_regular_3 - execution___of__test_regular_insert_range_with_info - PROPERTY RUN_SERIAL 1) - + if(BUILD_TESTING) set_tests_properties( execution___of__test_delaunay_hierarchy_3 execution___of__test_delaunay_hierarchy_3_old From 85a9962892c501fb2e4cd5183cb89fc9bd284abe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 22 Feb 2021 14:50:41 +0100 Subject: [PATCH 193/248] 2 fixes: - an edge cannot be collapsed if both its endpoints are constrained -> allow cap classification - an edge with two constrained endpoints can be flipped (if not constrained) --- .../repair_degeneracies.h | 25 ++++++++----------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair_degeneracies.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair_degeneracies.h index 5698dceb557..4a0ca4f70f7 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair_degeneracies.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair_degeneracies.h @@ -50,11 +50,12 @@ namespace CGAL { namespace Polygon_mesh_processing { namespace internal { -template +template std::array::halfedge_descriptor, 2> is_badly_shaped(const typename boost::graph_traits::face_descriptor f, TriangleMesh& tmesh, const VPM& vpm, + const VCM& vcm, const ECM& ecm, const Traits& gt, const double cap_threshold, // angle over 160° ==> cap @@ -70,7 +71,7 @@ is_badly_shaped(const typename boost::graph_traits::face_descripto halfedge_descriptor res = PMP::is_needle_triangle_face(f, tmesh, needle_threshold, parameters::vertex_point_map(vpm) .geom_traits(gt)); - if(res != null_h && !get(ecm, edge(res, tmesh))) + if(res != null_h && (!get(vcm, source(res, tmesh)) || !get(vcm, target(res, tmesh))) ) { // don't want to collapse edges that are too large if(collapse_length_threshold == 0 || @@ -88,10 +89,11 @@ is_badly_shaped(const typename boost::graph_traits::face_descripto } template + typename VPM, typename VCM, typename ECM, typename Traits> void collect_badly_shaped_triangles(const typename boost::graph_traits::face_descriptor f, TriangleMesh& tmesh, const VPM& vpm, + const VCM& vcm, const ECM& ecm, const Traits& gt, const double cap_threshold, // angle over this threshold (as a cosine) ==> cap @@ -102,7 +104,7 @@ void collect_badly_shaped_triangles(const typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - std::array res = is_badly_shaped(f, tmesh, vpm, ecm, gt, cap_threshold, + std::array res = is_badly_shaped(f, tmesh, vpm, vcm, ecm, gt, cap_threshold, needle_threshold, collapse_length_threshold); if(res[0] != boost::graph_traits::null_halfedge()) @@ -256,8 +258,6 @@ get_best_edge_orientation(typename boost::graph_traits::edge_descr halfedge_descriptor h = halfedge(e, tmesh), ho = opposite(h, tmesh); - CGAL_assertion(!get(vcm, source(h, tmesh)) || !get(vcm, target(h, tmesh))); - boost::optional dv1 = get_collapse_volume(h, tmesh, vpm, gt); boost::optional dv2 = get_collapse_volume(ho, tmesh, vpm, gt); @@ -413,7 +413,7 @@ bool remove_almost_degenerate_faces(const FaceRange& face_range, // f1 / f2 and look at f1 if f1 nc = - internal::is_badly_shaped(face(h, tmesh), tmesh, vpm, ecm, gt, + internal::is_badly_shaped(face(h, tmesh), tmesh, vpm, vcm, ecm, gt, cap_threshold, needle_threshold, collapse_length_threshold); if(nc[0] != h) @@ -553,7 +553,7 @@ bool remove_almost_degenerate_faces(const FaceRange& face_range, { if(!is_border(hv, tmesh)) { - internal::collect_badly_shaped_triangles(face(hv, tmesh), tmesh, vpm, ecm, gt, + internal::collect_badly_shaped_triangles(face(hv, tmesh), tmesh, vpm, vcm, ecm, gt, cap_threshold, needle_threshold, collapse_length_threshold, edges_to_collapse, edges_to_flip); } @@ -595,16 +595,13 @@ bool remove_almost_degenerate_faces(const FaceRange& face_range, const edge_descriptor e = edge(h, tmesh); CGAL_assertion(!get(ecm, e)); - if(get(vcm, source(e, tmesh)) && get(vcm, target(e, tmesh))) - continue; - #ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES_EXTRA std::cout << " treat cap: " << e << " (" << source(e, tmesh) << " " << tmesh.point(source(h, tmesh)) << " --- " << target(e, tmesh) << " " << tmesh.point(target(h, tmesh)) << ")" << std::endl; #endif - std::array nc = internal::is_badly_shaped(face(h, tmesh), tmesh, vpm, ecm, gt, + std::array nc = internal::is_badly_shaped(face(h, tmesh), tmesh, vpm, vcm, ecm, gt, cap_threshold, needle_threshold, collapse_length_threshold); // Check the triangle is still a cap @@ -659,7 +656,7 @@ bool remove_almost_degenerate_faces(const FaceRange& face_range, { CGAL_assertion(!is_border(h, tmesh)); std::array nc = - internal::is_badly_shaped(face(h, tmesh), tmesh, vpm, ecm, gt, + internal::is_badly_shaped(face(h, tmesh), tmesh, vpm, vcm, ecm, gt, cap_threshold, needle_threshold, collapse_length_threshold); if(nc[1] != boost::graph_traits::null_halfedge() && nc[1] != h) From 99f8843197d3ec65679bc8465fc4bce7aa4796db Mon Sep 17 00:00:00 2001 From: Dmitry Anisimov Date: Mon, 22 Feb 2021 15:19:58 +0100 Subject: [PATCH 194/248] in case tbb is on, we use tbb captured execption in pmp --- .../include/CGAL/Polygon_mesh_processing/self_intersections.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h index 24426ac86d9..dd3c23fc2b5 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h @@ -503,7 +503,11 @@ bool does_self_intersect(const FaceRange& face_range, CGAL::Emptyset_iterator unused_out; internal::self_intersections_impl(face_range, tmesh, unused_out, true /*throw*/, np); } + #if defined(CGAL_LINKED_WITH_TBB) + catch(tbb::captured_exception&) + #else catch(CGAL::internal::Throw_at_output_exception&) + #endif { return true; } From c0627fc05f102b3e3b685753c1ed04c5ef9f61de Mon Sep 17 00:00:00 2001 From: Dmitry Anisimov Date: Mon, 22 Feb 2021 16:45:10 +0100 Subject: [PATCH 195/248] cleaner solution using std exception --- .../Polygon_mesh_processing/self_intersections.h | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h index dd3c23fc2b5..1de9be33e37 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h @@ -498,20 +498,12 @@ bool does_self_intersect(const FaceRange& face_range, { CGAL_precondition(CGAL::is_triangle_mesh(tmesh)); - try - { + try { CGAL::Emptyset_iterator unused_out; internal::self_intersections_impl(face_range, tmesh, unused_out, true /*throw*/, np); - } - #if defined(CGAL_LINKED_WITH_TBB) - catch(tbb::captured_exception&) - #else - catch(CGAL::internal::Throw_at_output_exception&) - #endif - { + } catch(const std::exception&) { return true; } - return false; } From b3d7977fac22fe4021d5bea863e9fd284b10f583 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 22 Feb 2021 16:50:52 +0100 Subject: [PATCH 196/248] Fix boundary cycle zipping not updating its representative --- .../Polygon_mesh_processing/stitch_borders.h | 42 +++++++++++++------ 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/stitch_borders.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/stitch_borders.h index 5c3047c7e7a..9fdb5d884e8 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/stitch_borders.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/stitch_borders.h @@ -150,6 +150,7 @@ struct Dummy_cycle_rep_maintainer } // Dummies just to fit the API + void add_representative(const halfedge_descriptor) const { } void remove_representative(const halfedge_descriptor) const { } void clear_representatives() const { } @@ -866,19 +867,20 @@ std::size_t stitch_halfedge_range_dispatcher(const HalfedgePairRange& to_stitch_ template -std::size_t zip_boundary_cycle(const typename boost::graph_traits::halfedge_descriptor h, + typename HalfedgeKeeper> +std::size_t zip_boundary_cycle(typename boost::graph_traits::halfedge_descriptor& bh, const HalfedgeRange& cycle_halfedges, PolygonMesh& pmesh, const VPM vpm, - const HalfedgeKeeper& hd_kpr, - MaintainerVisitor& mv) + const HalfedgeKeeper& hd_kpr) { typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; std::size_t stitched_boundary_cycles_n = 0; + // Zipping cannot change the topology of the hole so the maintenance is trivial + internal::Dummy_cycle_rep_maintainer dummy_maintainer(pmesh); + // A boundary cycle might need to be stitched starting from different extremities // // v11 ------ v10 @@ -894,7 +896,6 @@ std::size_t zip_boundary_cycle(const typename boost::graph_traits:: std::set unstitchable_halfedges; const halfedge_descriptor null_h = boost::graph_traits::null_halfedge(); - halfedge_descriptor bh = h; for(;;) // until there is nothing to stitch anymore { if(bh == null_h) // the complete boundary cycle is stitched @@ -1001,9 +1002,8 @@ std::size_t zip_boundary_cycle(const typename boost::graph_traits:: << "\n\t" << target(h, pmesh) << "\t(" << get(vpm, target(h, pmesh)) << ")" << std::endl; #endif - mv.remove_representative(bh); - - std::size_t local_stitches = internal::stitch_halfedge_range(hedges_to_stitch, cycle_halfedges, pmesh, vpm, mv); + std::size_t local_stitches = internal::stitch_halfedge_range(hedges_to_stitch, cycle_halfedges, + pmesh, vpm, dummy_maintainer); stitched_boundary_cycles_n += local_stitches; if(local_stitches == 0) // refused to stitch this halfedge pair range due to manifold issue @@ -1052,20 +1052,36 @@ std::size_t stitch_boundary_cycle(const typename boost::graph_traits()); + halfedge_descriptor bh = h, bh_mem = bh; + std::vector cycle_halfedges; for(halfedge_descriptor h : halfedges_around_face(bh, pmesh)) cycle_halfedges.push_back(h); - std::size_t res = internal::zip_boundary_cycle(bh, cycle_halfedges, pmesh, vpm, hd_kpr, mv); + std::size_t res = internal::zip_boundary_cycle(bh, cycle_halfedges, pmesh, vpm, hd_kpr); + if(bh == boost::graph_traits::null_halfedge()) // stitched everything + { + cycle_reps_maintainer.remove_representative(bh); + return res; + } + + // Re-compute the range if something was stitched + if(res != 0) + { + cycle_reps_maintainer.remove_representative(bh_mem); + cycle_reps_maintainer.add_representative(bh); + + cycle_halfedges.clear(); + for(halfedge_descriptor h : halfedges_around_face(bh, pmesh)) + cycle_halfedges.push_back(h); + } std::vector to_stitch; internal::collect_duplicated_stitchable_boundary_edges(cycle_halfedges, pmesh, hd_kpr, false /*per cc*/, std::back_inserter(to_stitch), np); - mv.remove_representative(bh); - - res += stitch_halfedge_range(to_stitch, cycle_halfedges, pmesh, vpm, mv); + res += stitch_halfedge_range(to_stitch, cycle_halfedges, pmesh, vpm, cycle_reps_maintainer); return res; } From abe1f6e5776cd76fbdaea93a74e842ec7a57deb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 22 Feb 2021 16:51:35 +0100 Subject: [PATCH 197/248] Misc cleaning --- .../Polygon_mesh_processing/stitch_borders.h | 85 +++++++++---------- .../test_stitching.cpp | 1 - 2 files changed, 42 insertions(+), 44 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/stitch_borders.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/stitch_borders.h index 9fdb5d884e8..e936df1bff9 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/stitch_borders.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/stitch_borders.h @@ -215,13 +215,13 @@ public: { typedef typename boost::property_traits::reference Point_ref; - CGAL_assertion(!cycle_halfedges.empty()); - #ifdef CGAL_PMP_STITCHING_DEBUG std::cout << "update_representatives(" << cycle_halfedges.size() << ", " << filtered_stitchable_halfedges.size() << ")" << std::endl; #endif + CGAL_assertion(!cycle_halfedges.empty()); + for(const halfedge_descriptor h : cycle_halfedges) put(m_candidate_halfedges, h, true); @@ -789,12 +789,12 @@ filter_stitchable_pairs(PolygonMesh& pmesh, } template + typename CycleRepMaintainer, typename VertexPointMap> std::size_t stitch_halfedge_range(const std::vector& to_stitch, const CandidateHalfedgeRange& representative_candidates, PolygonMesh& pmesh, const VertexPointMap& vpm, - MaintainerVisitor& mv) + CycleRepMaintainer& cycle_reps_maintainer) { typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; @@ -824,7 +824,7 @@ std::size_t stitch_halfedge_range(const std::vector& to_stitch, const std::vector& to_stitch_filtered = filter_stitchable_pairs(pmesh, to_stitch, to_stitch_local, uf_vertices, uf_handles); - mv.update_representatives(representative_candidates, to_stitch_filtered, vpm); + cycle_reps_maintainer.update_representatives(representative_candidates, to_stitch_filtered, vpm); // Actually stitching run_stitch_borders(pmesh, to_stitch_filtered, vpm, uf_vertices, uf_handles); @@ -837,11 +837,11 @@ std::size_t stitch_halfedge_range(const std::vector& to_stitch, PolygonMesh& pmesh, const VertexPointMap& vpm) { - Dummy_cycle_rep_maintainer mv(pmesh); - return stitch_halfedge_range(to_stitch, halfedges(pmesh), pmesh, vpm, mv); + Dummy_cycle_rep_maintainer cycle_reps_maintainer(pmesh); + return stitch_halfedge_range(to_stitch, halfedges(pmesh), pmesh, vpm, cycle_reps_maintainer); } -//overload to avoid a useless copy +// overload to avoid a useless copy template std::size_t stitch_halfedge_range_dispatcher(const std::vector& to_stitch, PolygonMesh& pmesh, @@ -850,7 +850,7 @@ std::size_t stitch_halfedge_range_dispatcher(const std::vector& to return stitch_halfedge_range(to_stitch, pmesh, vpm); } -//overload to doing the copy +// overload making a copy template std::size_t stitch_halfedge_range_dispatcher(const HalfedgePairRange& to_stitch_const, PolygonMesh& pmesh, @@ -861,7 +861,7 @@ std::size_t stitch_halfedge_range_dispatcher(const HalfedgePairRange& to_stitch_ return stitch_halfedge_range(to_stitch, pmesh, vpm); } -// collect_duplicated_stitchable_boundary_edges() cannot handle any configuration with non-manifoldness. +// collect_duplicated_stitchable_boundary_edges() cannot handle configurations with non-manifoldness. // However, even if non-manifoldness exists within a loop, it is safe choice to stitch consecutive // stitchable halfedges template ::halfed /// High-level functions -template -std::size_t stitch_boundary_cycle(const typename boost::graph_traits::halfedge_descriptor bh, +template +std::size_t stitch_boundary_cycle(const typename boost::graph_traits::halfedge_descriptor h, PolygonMesh& pmesh, - MaintainerVisitor& mv, + CycleRepMaintainer& cycle_reps_maintainer, const CGAL_PMP_NP_CLASS& np) { typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename std::pair halfedges_pair; - CGAL_precondition(bh != boost::graph_traits::null_halfedge()); - CGAL_precondition(is_border(bh, pmesh)); + CGAL_precondition(h != boost::graph_traits::null_halfedge()); + CGAL_precondition(is_border(h, pmesh)); CGAL_precondition(is_valid(pmesh)); using parameters::choose_parameter; @@ -1124,8 +1124,8 @@ std::size_t stitch_boundary_cycle(const typename boost::graph_traits mv(pmesh); - return internal::stitch_boundary_cycle(h, pmesh, mv, np); + internal::Dummy_cycle_rep_maintainer dummy_maintainer(pmesh); + return internal::stitch_boundary_cycle(h, pmesh, dummy_maintainer, np); } template @@ -1138,17 +1138,17 @@ std::size_t stitch_boundary_cycle(const typename boost::graph_traits + typename CycleRepMaintainer, typename CGAL_PMP_NP_TEMPLATE_PARAMETERS> std::size_t stitch_boundary_cycles(const BorderHalfedgeRange& boundary_cycle_representatives, PolygonMesh& pmesh, - MaintainerVisitor& mv, + CycleRepMaintainer& cycle_reps_maintainer, const CGAL_PMP_NP_CLASS& np) { typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; std::size_t stitched_boundary_cycles_n = 0; for(const halfedge_descriptor h : boundary_cycle_representatives) - stitched_boundary_cycles_n += stitch_boundary_cycle(h, pmesh, mv, np); + stitched_boundary_cycles_n += stitch_boundary_cycle(h, pmesh, cycle_reps_maintainer, np); return stitched_boundary_cycles_n; } @@ -1194,8 +1194,8 @@ std::size_t stitch_boundary_cycles(const BorderHalfedgeRange& boundary_cycle_rep { // If this API is called, we are not from stitch_borders() (otherwise there would be a maintainer) // so there is only one pass and we don't carea bout maintaining the cycle subset - internal::Dummy_cycle_rep_maintainer mv(pmesh); - return stitch_boundary_cycles(boundary_cycle_representatives, pmesh, mv, np); + internal::Dummy_cycle_rep_maintainer dummy_maintainer(pmesh); + return stitch_boundary_cycles(boundary_cycle_representatives, pmesh, dummy_maintainer, np); } ///\cond SKIP_IN_MANUAL @@ -1290,11 +1290,11 @@ std::size_t stitch_borders(PolygonMesh& pmesh, namespace internal { template std::size_t stitch_borders(const BorderHalfedgeRange& boundary_cycle_representatives, PolygonMesh& pmesh, - MaintainerVisitor& mv, + CycleRepMaintainer& cycle_maintainer, const CGAL_PMP_NP_CLASS& np) { typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; @@ -1318,35 +1318,34 @@ std::size_t stitch_borders(const BorderHalfedgeRange& boundary_cycle_representat bool per_cc = choose_parameter(get_parameter(np, internal_np::apply_per_connected_component), false); #ifdef CGAL_PMP_STITCHING_DEBUG - std::cout << "------- Stitch cycles... (" << boundary_cycle_representatives.size() << " cycle(s))" << std::endl; + std::cout << "------- Stitch cycles (#1)... (" << boundary_cycle_representatives.size() << " cycle(s))" << std::endl; #endif - std::size_t res = stitch_boundary_cycles(boundary_cycle_representatives, pmesh, mv, np); + std::size_t res = stitch_boundary_cycles(boundary_cycle_representatives, pmesh, cycle_maintainer, np); #ifdef CGAL_PMP_STITCHING_DEBUG - std::cout << "------- Stitched " << res << " in boundary cycles" << std::endl; + std::cout << "------- Stitched " << res << " halfedge pairs in boundary cycles" << std::endl; std::cout << "------- Stitch all..." << std::endl; #endif - const auto& to_consider = mv.halfedges_to_consider(); - mv.clear_representatives(); + const auto& to_consider = cycle_maintainer.halfedges_to_consider(); + cycle_maintainer.clear_representatives(); std::vector > to_stitch; internal::collect_duplicated_stitchable_boundary_edges(to_consider, pmesh, hd_kpr, per_cc, std::back_inserter(to_stitch), np); - - res += stitch_halfedge_range(to_stitch, to_consider, pmesh, vpm, mv); - - const auto& new_representatives = mv.cycle_representatives(); + res += stitch_halfedge_range(to_stitch, to_consider, pmesh, vpm, cycle_maintainer); #ifdef CGAL_PMP_STITCHING_DEBUG - std::cout << "------- Stitched " << res << " after cycles & general" << std::endl; - std::cout << "------- Stitch cycles (#2)... (" << new_representatives.size() << " cycles)" << std::endl; + std::cout << "------- Stitched " << res << " halfedge pairs after cycles & general" << std::endl; + std::cout << "------- Stitch cycles (#2)... (" << new_representatives.size() << " cycle(s))" << std::endl; #endif + const auto& new_representatives = cycle_maintainer.cycle_representatives(); + // Don't care about keeping track of the sub-cycles as this is the last pass - internal::Dummy_cycle_rep_maintainer null_mv(pmesh); - res += stitch_boundary_cycles(new_representatives, pmesh, null_mv, np); + internal::Dummy_cycle_rep_maintainer dummy_cycle_maintainer(pmesh); + res += stitch_boundary_cycles(new_representatives, pmesh, dummy_cycle_maintainer, np); #ifdef CGAL_PMP_STITCHING_DEBUG std::cout << "------- Stitched " << res << " (total)" << std::endl; @@ -1416,8 +1415,8 @@ std::size_t stitch_borders(const BorderHalfedgeRange& boundary_cycle_representat ) { // Need to keep track of the cycles since we are working on a subset of all the boundary cycles - internal::Boundary_cycle_rep_maintainer mv(pmesh); - return stitch_borders(boundary_cycle_representatives, pmesh, mv, np); + internal::Boundary_cycle_rep_maintainer cycle_reps_maintainer(pmesh); + return stitch_borders(boundary_cycle_representatives, pmesh, cycle_reps_maintainer, np); } /// \cond SKIP_IN_MANUAL @@ -1430,8 +1429,8 @@ std::size_t stitch_borders(const BorderHalfedgeRange& boundary_cycle_representat >::type* = 0) { // Need to keep track of the cycles since we are working on a subset of all the boundary cycles - internal::Boundary_cycle_rep_maintainer mv(pmesh); - return stitch_borders(boundary_cycle_representatives, pmesh, mv, parameters::all_default()); + internal::Boundary_cycle_rep_maintainer cycle_reps_maintainer(pmesh); + return stitch_borders(boundary_cycle_representatives, pmesh, cycle_reps_maintainer, parameters::all_default()); } template @@ -1444,8 +1443,8 @@ std::size_t stitch_borders(PolygonMesh& pmesh, extract_boundary_cycles(pmesh, std::back_inserter(boundary_cycle_representatives)); // We are working on all boundary cycles, so there is no need to keep track of any subset - internal::Dummy_cycle_rep_maintainer mv(pmesh); - return stitch_borders(boundary_cycle_representatives, pmesh, mv, np); + internal::Dummy_cycle_rep_maintainer dummy_maintainer(pmesh); + return stitch_borders(boundary_cycle_representatives, pmesh, dummy_maintainer, np); } template diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_stitching.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_stitching.cpp index 7fd2d5d820e..049ad81c971 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_stitching.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_stitching.cpp @@ -209,7 +209,6 @@ void test_degenerate() CGAL::make_triangle(Point(0,0,0), Point(1,0,0), Point(0,1,0), tm); std::size_t res = CGAL::Polygon_mesh_processing::stitch_borders(tm); - std::cout << "Stitched: " << res << std::endl; assert(res == 0); } From 08acf5d759c8e6b4fb62ba9dbe9d3b320ae5d9cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 22 Feb 2021 17:15:53 +0100 Subject: [PATCH 198/248] Remove Alpha_shape_euclidean_traits_2.h Use kernels directly instead. The class is not even documented anymore. --- .../CGAL/Alpha_shape_euclidean_traits_2.h | 29 ------------------- 1 file changed, 29 deletions(-) delete mode 100644 Alpha_shapes_2/include/CGAL/Alpha_shape_euclidean_traits_2.h diff --git a/Alpha_shapes_2/include/CGAL/Alpha_shape_euclidean_traits_2.h b/Alpha_shapes_2/include/CGAL/Alpha_shape_euclidean_traits_2.h deleted file mode 100644 index 84399ca3ef4..00000000000 --- a/Alpha_shapes_2/include/CGAL/Alpha_shape_euclidean_traits_2.h +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) 1997 INRIA Sophia-Antipolis (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org). -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial -// -// -// Author(s) : Tran Kai Frank DA -// Andreas Fabri - -#ifndef CGAL_ALPHA_SHAPE_EUCLIDEAN_TRAITS_H -#define CGAL_ALPHA_SHAPE_EUCLIDEAN_TRAITS_H - -#include - - - -namespace CGAL { - -template < class R > -class Alpha_shape_euclidean_traits_2 : public R -{}; - -} //namespace CGAL - -#endif From 57772f7e2c3d2f95706cb1c5fb1a5d40ac2b092f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 22 Feb 2021 17:16:53 +0100 Subject: [PATCH 199/248] Announce the removal of obsolete & deprecated alpha shape traits classes --- Installation/CHANGES.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Installation/CHANGES.md b/Installation/CHANGES.md index 1bd032a7859..62a9273997a 100644 --- a/Installation/CHANGES.md +++ b/Installation/CHANGES.md @@ -25,6 +25,12 @@ A comprehensive list of the supported file formats is available in the Stream_su - Added a filtering mechanism so that costly tests get only applied to the next candidate for the edge collapse. - Added the class `Polyhedral_envelope_filter` that enables to perform mesh simplification inside a polyhedral envelope of the input mesh. +### [2D and 3D Alpha Shapes](https://doc.cgal.org/5.3/Manual/packages.html#PkgAlphaShapes2) +- The following deprecated classes have been removed: `Alpha_shape_euclidean_traits_2`, + `Weighted_alpha_shape_euclidean_traits_2`, `Alpha_shape_euclidean_traits_3`, and + `Weighted_alpha_shape_euclidean_traits_3`. All CGAL kernel can be used directly as models + of the Alpha Shape concepts. + [Release 5.2](https://github.com/CGAL/cgal/releases/tag/v5.2) ----------- From e16e773fb870e76d2e090109318758e4911053b1 Mon Sep 17 00:00:00 2001 From: Dmitry Anisimov Date: Mon, 22 Feb 2021 17:37:57 +0100 Subject: [PATCH 200/248] fixed exception handling --- .../self_intersections.h | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h index 1de9be33e37..a6581cd65a6 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h @@ -498,12 +498,25 @@ bool does_self_intersect(const FaceRange& face_range, { CGAL_precondition(CGAL::is_triangle_mesh(tmesh)); - try { + try + { CGAL::Emptyset_iterator unused_out; internal::self_intersections_impl(face_range, tmesh, unused_out, true /*throw*/, np); - } catch(const std::exception&) { + } + catch (const CGAL::internal::Throw_at_output_exception&) + { return true; } + #if defined(CGAL_LINKED_WITH_TBB) + catch (tbb::captured_exception& e) + { + return true; + } + #endif + catch ( ... ) + { + throw; + } return false; } From 59550280107ec85aa8e797f124e49c7b86b42457 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Tue, 23 Feb 2021 08:18:47 +0100 Subject: [PATCH 201/248] Disable expensive tests by default --- .../test/Shape_detection/test_validity_sampled_data.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Shape_detection/test/Shape_detection/test_validity_sampled_data.cpp b/Shape_detection/test/Shape_detection/test_validity_sampled_data.cpp index 78e6bb06069..b7128b9cb64 100644 --- a/Shape_detection/test/Shape_detection/test_validity_sampled_data.cpp +++ b/Shape_detection/test/Shape_detection/test_validity_sampled_data.cpp @@ -20,6 +20,9 @@ #include +// Uncomment this line to run expensive test +// #define CGAL_SHAPE_DETECTION_RUN_EXPENSIVE_TESTS + namespace SD = CGAL::Shape_detection; using Kernel = CGAL::Simple_cartesian; @@ -64,7 +67,7 @@ int main (int argc, char** argv) test_copied_point_cloud (points, 2); test_copied_point_cloud (points, 5); test_copied_point_cloud (points, 10); -#ifndef CGAL_TEST_SUITE // Disable tests too large for testsuite +#ifdef CGAL_SHAPE_DETECTION_RUN_EXPENSIVE_TESTS test_copied_point_cloud (points, 20); test_copied_point_cloud (points, 50); #endif From 1561f3a5235ce44c8f040650b4d1f0b6ed15903a Mon Sep 17 00:00:00 2001 From: Guillaume Damiand Date: Tue, 23 Feb 2021 11:11:04 +0100 Subject: [PATCH 202/248] Remove duplicated shaders --- .../include/CGAL/Qt/Basic_viewer_qt.h | 166 ------------------ 1 file changed, 166 deletions(-) diff --git a/GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h b/GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h index ffdb131e2c2..f306e419ce7 100644 --- a/GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h +++ b/GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h @@ -55,172 +55,6 @@ namespace CGAL { -//------------------------------------------------------------------------------ -const char vertex_source_color[] = - { - "#version 150 \n" - "in highp vec4 vertex;\n" - "in highp vec3 normal;\n" - "in highp vec3 color;\n" - - "uniform highp mat4 mvp_matrix;\n" - "uniform highp mat4 mv_matrix; \n" - - "out highp vec4 fP; \n" - "out highp vec3 fN; \n" - "out highp vec4 fColor; \n" - - "uniform highp float point_size; \n" - "void main(void)\n" - "{\n" - " fP = mv_matrix * vertex; \n" - " fN = mat3(mv_matrix)* normal; \n" - " fColor = vec4(color, 1.0); \n" - " gl_PointSize = point_size;\n" - " gl_Position = mvp_matrix * vertex;\n" - "}" - }; - -const char fragment_source_color[] = - { - "#version 150 \n" - "in highp vec4 fP; \n" - "in highp vec3 fN; \n" - "in highp vec4 fColor; \n" - "uniform highp vec4 light_pos; \n" - "uniform highp vec4 light_diff; \n" - "uniform highp vec4 light_spec; \n" - "uniform highp vec4 light_amb; \n" - "uniform float spec_power ; \n" - "out vec4 out_color; \n" - - "void main(void) { \n" - " highp vec3 L = light_pos.xyz - fP.xyz; \n" - " highp vec3 V = -fP.xyz; \n" - - " highp vec3 N = normalize(fN); \n" - " L = normalize(L); \n" - " V = normalize(V); \n" - - " highp vec3 R = reflect(-L, N); \n" - " highp vec4 diffuse = max(dot(N,L), 0.0) * light_diff * fColor; \n" - " highp vec4 specular = pow(max(dot(R,V), 0.0), spec_power) * light_spec; \n" - " out_color = light_amb*fColor + diffuse ; \n" - "} \n" - "\n" - }; - -const char vertex_source_p_l[] = - { - "#version 150 \n" - "in highp vec4 vertex;\n" - "in highp vec3 color;\n" - "uniform highp mat4 mvp_matrix;\n" - "out highp vec4 fColor; \n" - "uniform highp float point_size; \n" - "void main(void)\n" - "{\n" - " gl_PointSize = point_size;\n" - " fColor = vec4(color, 1.0); \n" - " gl_Position = mvp_matrix * vertex;\n" - "}" - }; - -const char fragment_source_p_l[] = - { - "#version 150 \n" - "in highp vec4 fColor; \n" - "out vec4 out_color; \n" - "void main(void) { \n" - "out_color = fColor; \n" - "} \n" - "\n" - }; - -//------------------------------------------------------------------------------ -// compatibility shaders - -const char vertex_source_color_comp[] = - { - "attribute highp vec4 vertex;\n" - "attribute highp vec3 normal;\n" - "attribute highp vec3 color;\n" - - "uniform highp mat4 mvp_matrix;\n" - "uniform highp mat4 mv_matrix; \n" - - "varying highp vec4 fP; \n" - "varying highp vec3 fN; \n" - "varying highp vec4 fColor; \n" - - "uniform highp float point_size; \n" - "void main(void)\n" - "{\n" - " fP = mv_matrix * vertex; \n" - " highp mat3 mv_matrix_3; \n" - " mv_matrix_3[0] = mv_matrix[0].xyz; \n" - " mv_matrix_3[1] = mv_matrix[1].xyz; \n" - " mv_matrix_3[2] = mv_matrix[2].xyz; \n" - " fN = mv_matrix_3* normal; \n" - " fColor = vec4(color, 1.0); \n" - " gl_PointSize = point_size;\n" - " gl_Position = mvp_matrix * vertex;\n" - "}" - }; - -const char fragment_source_color_comp[] = - { - "varying highp vec4 fP; \n" - "varying highp vec3 fN; \n" - "varying highp vec4 fColor; \n" - "uniform highp vec4 light_pos; \n" - "uniform highp vec4 light_diff; \n" - "uniform highp vec4 light_spec; \n" - "uniform highp vec4 light_amb; \n" - "uniform highp float spec_power ; \n" - - "void main(void) { \n" - - " highp vec3 L = light_pos.xyz - fP.xyz; \n" - " highp vec3 V = -fP.xyz; \n" - - " highp vec3 N = normalize(fN); \n" - " L = normalize(L); \n" - " V = normalize(V); \n" - - " highp vec3 R = reflect(-L, N); \n" - " highp vec4 diffuse = max(dot(N,L), 0.0) * light_diff * fColor; \n" - " highp vec4 specular = pow(max(dot(R,V), 0.0), spec_power) * light_spec; \n" - - "gl_FragColor = light_amb*fColor + diffuse ; \n" - "} \n" - "\n" - }; - -const char vertex_source_p_l_comp[] = - { - "attribute highp vec4 vertex;\n" - "attribute highp vec3 color;\n" - "uniform highp mat4 mvp_matrix;\n" - "varying highp vec4 fColor; \n" - "uniform highp float point_size; \n" - "void main(void)\n" - "{\n" - " gl_PointSize = point_size;\n" - " fColor = vec4(color, 1.0); \n" - " gl_Position = mvp_matrix * vertex;\n" - "}" - }; - -const char fragment_source_p_l_comp[] = - { - "varying highp vec4 fColor; \n" - "void main(void) { \n" - "gl_FragColor = fColor; \n" - "} \n" - "\n" - }; - //------------------------------------------------------------------------------ inline CGAL::Color get_random_color(CGAL::Random& random) { From c63741dbb65d9b1660dedc06cb9140e584a8345c Mon Sep 17 00:00:00 2001 From: Dmitry Anisimov Date: Tue, 23 Feb 2021 12:40:18 +0100 Subject: [PATCH 203/248] better tbb exception --- .../CGAL/Polygon_mesh_processing/self_intersections.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h index a6581cd65a6..075c660d4de 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h @@ -47,6 +47,7 @@ #include #include #include +#include #include #ifdef DOXYGEN_RUNNING @@ -508,9 +509,14 @@ bool does_self_intersect(const FaceRange& face_range, return true; } #if defined(CGAL_LINKED_WITH_TBB) - catch (tbb::captured_exception& e) + catch (const tbb::captured_exception& e) { - return true; + const char* ti1 = e.name(); + const char* ti2 = typeid(const CGAL::internal::Throw_at_output_exception&).name(); + const std::string tn1(ti1); + const std::string tn2(ti2); + if (tn1 == tn2) return true; + else throw; } #endif catch ( ... ) From 688e76f70ae9c93f9334ceb47eac9fbcd07cda00 Mon Sep 17 00:00:00 2001 From: Dmitry Anisimov Date: Tue, 23 Feb 2021 14:05:29 +0100 Subject: [PATCH 204/248] Update Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h Co-authored-by: Laurent Rineau --- .../include/CGAL/Polygon_mesh_processing/self_intersections.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h index 075c660d4de..00f77025878 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h @@ -519,10 +519,6 @@ bool does_self_intersect(const FaceRange& face_range, else throw; } #endif - catch ( ... ) - { - throw; - } return false; } From ee2cd7bcde9e7a4976c3499f912b855280a8a75a Mon Sep 17 00:00:00 2001 From: Dmitry Anisimov Date: Tue, 23 Feb 2021 15:22:07 +0100 Subject: [PATCH 205/248] fixed various warnings popping out for the macOS test suite --- Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/VSA_wrapper.h | 2 +- Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp | 4 ++-- Polyhedron/demo/Polyhedron/Server_ws.cpp | 2 +- Polyhedron/demo/Polyhedron/Viewer.h | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/VSA_wrapper.h b/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/VSA_wrapper.h index 644e9fc1501..888146d8da3 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/VSA_wrapper.h +++ b/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/VSA_wrapper.h @@ -66,7 +66,7 @@ class VSA_WRAPPER_EXPORT VSA_wrapper { // fitting center Vector_3 center = CGAL::NULL_VECTOR; FT area(0.0); - for(const face_descriptor f : faces) { + for(const face_descriptor& f : faces) { center = center + (get(center_pmap, f) - CGAL::ORIGIN) * get(area_pmap, f); area += get(area_pmap, f); } diff --git a/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp b/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp index 521431ada8c..86596bfa994 100644 --- a/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp @@ -2410,7 +2410,7 @@ void Scene_surface_mesh_item::updateVertex(vertex_descriptor vh) getEdgeContainer(0)->getVbo(Ed::Vertices), new_point,id); - for(const auto & v_it : CGAL::vertices_around_target(vh, *face_graph())) + for(const auto v_it : CGAL::vertices_around_target(vh, *face_graph())) { EPICK::Vector_3 n = CGAL::Polygon_mesh_processing::compute_vertex_normal(v_it, *face_graph()); cgal_gl_data new_n[3]; @@ -2430,7 +2430,7 @@ void Scene_surface_mesh_item::updateVertex(vertex_descriptor vh) } - for(const auto& f_it : CGAL::faces_around_target( halfedge(vh, *face_graph()), *face_graph())) + for(const auto f_it : CGAL::faces_around_target( halfedge(vh, *face_graph()), *face_graph())) { if (f_it == boost::graph_traits::null_face()) continue; diff --git a/Polyhedron/demo/Polyhedron/Server_ws.cpp b/Polyhedron/demo/Polyhedron/Server_ws.cpp index 82bea309a37..b6d84b6d441 100644 --- a/Polyhedron/demo/Polyhedron/Server_ws.cpp +++ b/Polyhedron/demo/Polyhedron/Server_ws.cpp @@ -88,7 +88,7 @@ int main(int argc, char *argv[]) parser.addHelpOption(); QCommandLineOption portOption(QStringList() << "p" << "port", QCoreApplication::translate("main", "Port for echoserver [default: 1234]."), - QCoreApplication::translate("main", "port"), QLatin1Literal("1234")); + QCoreApplication::translate("main", "port"), QLatin1String("1234")); parser.addOption(portOption); parser.process(a); int port = parser.value(portOption).toInt(); diff --git a/Polyhedron/demo/Polyhedron/Viewer.h b/Polyhedron/demo/Polyhedron/Viewer.h index 00381648013..541674bd510 100644 --- a/Polyhedron/demo/Polyhedron/Viewer.h +++ b/Polyhedron/demo/Polyhedron/Viewer.h @@ -92,7 +92,7 @@ public: //!Set total number of depth peeling passes. void setTotalPass(int); void resetFov(); - const QVector3D& scaler() const; + const QVector3D& scaler() const override; Q_SIGNALS: void sendMessage(QString); void doneInitGL(CGAL::Three::Viewer_interface*); From 21745762b102870dd1c0825cd6705162d1b89e54 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 24 Feb 2021 09:58:04 +0100 Subject: [PATCH 206/248] add missing typedef --- Distance_3/include/CGAL/squared_distance_3_3.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Distance_3/include/CGAL/squared_distance_3_3.h b/Distance_3/include/CGAL/squared_distance_3_3.h index ca691545f09..39120823c9d 100644 --- a/Distance_3/include/CGAL/squared_distance_3_3.h +++ b/Distance_3/include/CGAL/squared_distance_3_3.h @@ -95,7 +95,7 @@ squared_distance(const typename K::Tetrahedron_3 & t, } if(on_bounded_side){ - return K::FT(0); + return typename K::FT(0); } return dmin; } From 9db3cdb22f976f3d87fc5b5c771bef3a6f1e300a Mon Sep 17 00:00:00 2001 From: Dmitry Anisimov Date: Wed, 24 Feb 2021 11:08:44 +0100 Subject: [PATCH 207/248] use tbb captured_exception only on the x86_64 platforms --- .../include/CGAL/Polygon_mesh_processing/self_intersections.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h index 00f77025878..cd5be80387a 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h @@ -508,7 +508,7 @@ bool does_self_intersect(const FaceRange& face_range, { return true; } - #if defined(CGAL_LINKED_WITH_TBB) + #if defined(CGAL_LINKED_WITH_TBB) && !TBB_USE_CAPTURED_EXCEPTION catch (const tbb::captured_exception& e) { const char* ti1 = e.name(); From 254ce42109481978e37b87f0a5ed1841a3df6f04 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 24 Feb 2021 17:40:23 +0000 Subject: [PATCH 208/248] Remove Face_info but keep a second vector for num_edges --- .../CGAL/Nef_3/polygon_mesh_to_nef_3.h | 26 ++++++++----------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/Nef_3/include/CGAL/Nef_3/polygon_mesh_to_nef_3.h b/Nef_3/include/CGAL/Nef_3/polygon_mesh_to_nef_3.h index fa40ede4cc7..e41b139b3f4 100644 --- a/Nef_3/include/CGAL/Nef_3/polygon_mesh_to_nef_3.h +++ b/Nef_3/include/CGAL/Nef_3/polygon_mesh_to_nef_3.h @@ -192,21 +192,18 @@ void polygon_mesh_to_nef_3(PolygonMesh& P, SNC_structure& S, FaceIndexMap fimap, typedef Halfedge_around_target_circulator Halfedge_around_vertex_const_circulator; - struct Face_info - { - Vector_3 normal; - CGAL_assertion_code(std::size_t num_edges;) - }; - PMap pmap = get(CGAL::vertex_point,P); - std::vector face_info(num_faces(P)); + std::vector normals(num_faces(P)); + CGAL_assertion_code(std::vector num_edges(num_faces(P));) for(face_descriptor f : faces(P)){ Vertex_around_face_circulator vafc(halfedge(f,P),P), done(vafc); Vector_3 v; normal_vector_newell_3(vafc, done, pmap, v); - face_info[get(fimap,f)] = {-v,CGAL_assertion_code(circulator_size(vafc))}; + int i = get(fimap,f); + normals[i] = -v; + CGAL_assertion_code(num_edges[i] = circulator_size(vafc)); } Face_graph_index_adder 3) { + CGAL_assertion_code(if(num_edges[i] > 3) { CGAL_assertion(ss_circle.has_on(sp)); CGAL_assertion(ss_circle.has_on(sv_prev->point())); };) @@ -290,11 +286,11 @@ void polygon_mesh_to_nef_3(PolygonMesh& P, SNC_structure& S, FaceIndexMap fimap, with_border = true; e = sv_prev->out_sedge(); } else { - const Face_info& fi=face_info[get(fimap,face(pe_prev,P))]; - Plane ss_plane( CGAL::ORIGIN, fi.normal); + int i = get(fimap,face(pe_prev,P)); + Plane ss_plane( CGAL::ORIGIN, normals[i]); Sphere_circle ss_circle(ss_plane); - CGAL_assertion_code(if(fi.num_edges > 3) { + CGAL_assertion_code(if(num_edges[i] > 3) { CGAL_assertion(ss_circle.has_on(sp_0)); CGAL_assertion(ss_circle.has_on(sv_prev->point())); };) From 2c816b9291aa2d2b69543d6d9e42edbf7b2cd29d Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 24 Feb 2021 18:02:42 +0000 Subject: [PATCH 209/248] Use property_traits --- Nef_3/include/CGAL/Nef_3/polygon_mesh_to_nef_3.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Nef_3/include/CGAL/Nef_3/polygon_mesh_to_nef_3.h b/Nef_3/include/CGAL/Nef_3/polygon_mesh_to_nef_3.h index e41b139b3f4..f80aaa6e7f2 100644 --- a/Nef_3/include/CGAL/Nef_3/polygon_mesh_to_nef_3.h +++ b/Nef_3/include/CGAL/Nef_3/polygon_mesh_to_nef_3.h @@ -212,7 +212,7 @@ void polygon_mesh_to_nef_3(PolygonMesh& P, SNC_structure& S, FaceIndexMap fimap, for(vertex_descriptor pv : vertices(P) ) { - Point_3 npv = get(pmap,pv); + typename boost::property_traits::reference npv = get(pmap,pv); Vertex_handle nv = S.new_vertex(); nv->point() = npv; nv->mark() = true; From 4e911a4be048cf548d36c8ea7caf39a427d7d324 Mon Sep 17 00:00:00 2001 From: Dmitry Anisimov Date: Thu, 25 Feb 2021 10:22:17 +0100 Subject: [PATCH 210/248] fixed syntax error --- .../include/CGAL/Polygon_mesh_processing/self_intersections.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h index cd5be80387a..3bbc6a0a800 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h @@ -508,7 +508,7 @@ bool does_self_intersect(const FaceRange& face_range, { return true; } - #if defined(CGAL_LINKED_WITH_TBB) && !TBB_USE_CAPTURED_EXCEPTION + #if defined(CGAL_LINKED_WITH_TBB) && defined(TBB_USE_CAPTURED_EXCEPTION) catch (const tbb::captured_exception& e) { const char* ti1 = e.name(); From a1edfa76dbb6c60674deb3c25b958aa21bdd7e92 Mon Sep 17 00:00:00 2001 From: Dmitry Anisimov Date: Thu, 25 Feb 2021 12:05:56 +0100 Subject: [PATCH 211/248] fixed tbb warning --- .../include/CGAL/Polygon_mesh_processing/self_intersections.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h index 3bbc6a0a800..15d649393f9 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h @@ -508,7 +508,7 @@ bool does_self_intersect(const FaceRange& face_range, { return true; } - #if defined(CGAL_LINKED_WITH_TBB) && defined(TBB_USE_CAPTURED_EXCEPTION) + #if defined(CGAL_LINKED_WITH_TBB) && TBB_USE_CAPTURED_EXCEPTION catch (const tbb::captured_exception& e) { const char* ti1 = e.name(); From 2eac79c32624b91f57a0a082eb3206bde8745c34 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 25 Feb 2021 14:20:42 +0100 Subject: [PATCH 212/248] Fix names of the diff items --- .../Operations_on_polyhedra/Diff_between_meshes_plugin.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Diff_between_meshes_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Diff_between_meshes_plugin.cpp index 37c8a08a7e6..3147fca83cf 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Diff_between_meshes_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Diff_between_meshes_plugin.cpp @@ -175,11 +175,11 @@ void Polyhedron_demo_diff_between_meshes_plugin::diff() Scene_surface_mesh_item* m1_over_m2_item = new Scene_surface_mesh_item(m1_over_m2); m1_over_m2_item->setColor(QColor(Qt::blue)); - m1_over_m2_item->setName(QString("%1 - %2").arg(m1_item->name()).arg(m2_item->name())); + m1_over_m2_item->setName(QString("%2 - %1").arg(m1_item->name()).arg(m2_item->name())); CGAL::Three::Three::scene()->addItem(m1_over_m2_item); Scene_surface_mesh_item* m2_over_m1_item = new Scene_surface_mesh_item(m2_over_m1); m2_over_m1_item->setColor(QColor(Qt::red)); - m2_over_m1_item->setName(QString("%2 - %1").arg(m1_item->name()).arg(m2_item->name())); + m2_over_m1_item->setName(QString("%1 - %2").arg(m1_item->name()).arg(m2_item->name())); CGAL::Three::Three::scene()->addItem(m2_over_m1_item); Scene_surface_mesh_item* common_item = new Scene_surface_mesh_item(common); common_item->setColor(QColor(Qt::green)); From 78db91135abdab186299b7ada35b6fc7f7920b60 Mon Sep 17 00:00:00 2001 From: Guillaume Damiand Date: Fri, 26 Feb 2021 07:17:42 +0100 Subject: [PATCH 213/248] Remove a warning --- .../Surface_mesh_topology/internal/Minimal_quadrangulation.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h index dbc89a9d6fb..3be71c59f49 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h @@ -2070,7 +2070,7 @@ protected: { CGAL_assertion(get_local_map().template belong_to_same_cell<1>(p[i], ref)); int j = get_next_idx_relative_to(p, i, ref); - return j >= 0 && j < p.size(); + return j >= 0 && j < static_cast(p.size()); } /// Extend p[i] towards the direction of ref From 2bb1e7f3c98fd5f8532cdd5e475176e5615fc1bc Mon Sep 17 00:00:00 2001 From: Dmitry Anisimov Date: Fri, 26 Feb 2021 09:58:52 +0100 Subject: [PATCH 214/248] avoid warnings due to the deprecated opengl on apple --- Surface_mesher/demo/Surface_mesher/volume.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Surface_mesher/demo/Surface_mesher/volume.cpp b/Surface_mesher/demo/Surface_mesher/volume.cpp index 62424155ccd..3ccb01681c5 100644 --- a/Surface_mesher/demo/Surface_mesher/volume.cpp +++ b/Surface_mesher/demo/Surface_mesher/volume.cpp @@ -1,3 +1,6 @@ +#ifdef __APPLE__ +#define GL_SILENCE_DEPRECATION +#endif #include #include "volume.h" From bcb9940eb768d150182e6afc0a269609ca99d912 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 26 Feb 2021 13:05:48 +0100 Subject: [PATCH 215/248] WIP for groups in save_scene --- Polyhedron/demo/Polyhedron/MainWindow.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Polyhedron/demo/Polyhedron/MainWindow.cpp b/Polyhedron/demo/Polyhedron/MainWindow.cpp index 0fc2dac5fea..ae89cf30dfa 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.cpp +++ b/Polyhedron/demo/Polyhedron/MainWindow.cpp @@ -2988,6 +2988,11 @@ void MainWindow::on_actionSa_ve_Scene_as_Script_triggered() if(!rem.hasMatch()) continue; ext = rem.captured(1); + //check if it is in a group + if(item->parentGroup()) + { + + } QListto_save; to_save.append(item); QString savename(tr("%1.%2").arg(item->name()).arg(ext)); From 20865d2544041b23af9ced5f41968873659bcd77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 26 Feb 2021 15:40:46 +0100 Subject: [PATCH 216/248] robustify side_of test --- .../Corefinement/Face_graph_output_builder.h | 61 +++++++++++------ .../internal/Corefinement/face_graph_utils.h | 68 +++++++++++++++++++ 2 files changed, 108 insertions(+), 21 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h index 6f57675de59..306f0d9144a 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h @@ -1109,7 +1109,14 @@ public: CGAL::Bounded_side in_tm2 = is_tm2_inside_out ? ON_UNBOUNDED_SIDE : ON_BOUNDED_SIDE; - Side_of_triangle_mesh inside_tm2(tm2, vpm2); + typedef typename Nodes_vector::Exact_kernel Exact_kernel; + typedef Side_of_vpm_helper VPM_helper; + typedef typename VPM_helper::type SOTM_vpm2; + + SOTM_vpm2 sotm_vpm2 = VPM_helper::get_vpm(vertex_to_node_id2, vpm2, nodes); + Side_of_triangle_mesh inside_tm2(tm2, sotm_vpm2); for(face_descriptor f : faces(tm1)) { @@ -1120,31 +1127,36 @@ public: patch_status_not_set_tm1.reset( patch_id ); halfedge_descriptor h = halfedge(f, tm1); Node_id index_p1 = get_node_id(target(h, tm1), vertex_to_node_id1); + std::array fnids = { index_p1, index_p1, index_p1 }; if (index_p1 != NID) { h=next(h, tm1); index_p1 = get_node_id(target(h, tm1), vertex_to_node_id1); + fnids[1]=index_p1; if (index_p1 != NID) { h=next(h, tm1); index_p1 = get_node_id(target(h, tm1), vertex_to_node_id1); + fnids[2]=index_p1; } } + if (index_p1 != NID) { - if (tm1_coplanar_faces.test(f_id)) + if (tm1_coplanar_faces.test(f_id)) // TODO delay the building of the tree? { coplanar_patches_of_tm1.set(patch_id); coplanar_patches_of_tm1_for_union_and_intersection.set(patch_id); } else { - // triangle which is tangent at its 3 vertices - // \todo improve this part which is not robust with a kernel - // with inexact constructions. - Bounded_side position = inside_tm2(centroid(get(vpm1, source(h, tm1)), - get(vpm1, target(h, tm1)), - get(vpm1, target(next(h, tm1), tm1)) )); + typename Exact_kernel::Point_3 e_centroid = + centroid(nodes.exact_node(fnids[0]), + nodes.exact_node(fnids[1]), + nodes.exact_node(fnids[2])); + + Bounded_side position = inside_tm2(e_centroid); + CGAL_assertion( position != ON_BOUNDARY); if ( position == in_tm2 ) is_patch_inside_tm2.set(patch_id); @@ -1152,9 +1164,7 @@ public: } else { - // TODO: tm2 might have been modified and an inexact vpm will - // provide a non-robust result. - Bounded_side position = inside_tm2( get(vpm1, target(h, tm1))); + Bounded_side position = inside_tm2( nodes.to_exact(get(vpm1, target(h, tm1)))); CGAL_assertion( position != ON_BOUNDARY); if ( position == in_tm2 ) is_patch_inside_tm2.set(patch_id); @@ -1171,7 +1181,15 @@ public: CGAL::Bounded_side in_tm1 = is_tm1_inside_out ? ON_UNBOUNDED_SIDE : ON_BOUNDED_SIDE; - Side_of_triangle_mesh inside_tm1(tm1, vpm1); + typedef typename Nodes_vector::Exact_kernel Exact_kernel; + typedef Side_of_vpm_helper VPM_helper; + typedef typename VPM_helper::type SOTM_vpm1; + + SOTM_vpm1 sotm_vpm1 = VPM_helper::get_vpm(vertex_to_node_id1, vpm1, nodes); + Side_of_triangle_mesh inside_tm1(tm1, sotm_vpm1); + for(face_descriptor f : faces(tm2)) { const std::size_t f_id = get(fids2, f); @@ -1181,30 +1199,33 @@ public: patch_status_not_set_tm2.reset( patch_id ); halfedge_descriptor h = halfedge(f, tm2); Node_id index_p2 = get_node_id(target(h, tm2), vertex_to_node_id2); + std::array fnids = { index_p2, index_p2, index_p2 }; if (index_p2 != NID) { h=next(h, tm2); index_p2 = get_node_id(target(h, tm2), vertex_to_node_id2); + fnids[1]=index_p2; if (index_p2 != NID) { h=next(h, tm2); index_p2 = get_node_id(target(h, tm2), vertex_to_node_id2); + fnids[2]=index_p2; } } if (index_p2 != NID) { - if (tm2_coplanar_faces.test(f_id)) + if (tm2_coplanar_faces.test(f_id)) // TODO delay the building of the tree? { coplanar_patches_of_tm2.set(patch_id); coplanar_patches_of_tm2_for_union_and_intersection.set(patch_id); } else { - // triangle which is tangent at its 3 vertices - // \todo improve this part which is not robust with a kernel - // with inexact constructions. - Bounded_side position = inside_tm1(midpoint(get(vpm2, source(h, tm2)), - get(vpm2, target(h, tm2)) )); + typename Exact_kernel::Point_3 e_centroid = + centroid(nodes.exact_node(fnids[0]), + nodes.exact_node(fnids[1]), + nodes.exact_node(fnids[2])); + Bounded_side position = inside_tm1(e_centroid); CGAL_assertion( position != ON_BOUNDARY); if ( position == in_tm1 ) is_patch_inside_tm1.set(patch_id); @@ -1212,9 +1233,7 @@ public: } else { - // TODO: tm1 might have been modified and an inexact vpm will - // provide a non-robust result. - Bounded_side position = inside_tm1( get(vpm2, target(h, tm2))); + Bounded_side position = inside_tm1( nodes.to_exact(get(vpm2, target(h, tm2)))); CGAL_assertion( position != ON_BOUNDARY); if ( position == in_tm1 ) is_patch_inside_tm1.set(patch_id); diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h index 4103dcd41ae..c4c07117619 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h @@ -146,6 +146,74 @@ void copy_edge_mark(G&, No_mark&) {} // nothing to do +template +struct Node_vector_exact_vertex_point_map +{ +// map type definitions + typedef typename boost::property_traits::key_type key_type; + typedef typename NodeVector::Exact_kernel Exact_kernel; + typedef typename Exact_kernel::Point_3 value_type; + typedef value_type reference; + typedef boost::readable_property_map_tag category; +// internal type definitions + typedef std::size_t Node_id; + + Node_vector_exact_vertex_point_map(){} + + Node_vector_exact_vertex_point_map(const Node_id_map& node_ids, + const VertexPointMap& vpm, + const NodeVector& node_vector) + : node_ids(&node_ids) + , vpm(&vpm) + , node_vector(&node_vector) + {} + + friend value_type get(Node_vector_exact_vertex_point_map m, key_type k) + { + typename Node_id_map::const_iterator it = m.node_ids->find(k); + if (it == m.node_ids->end()) + return m.node_vector->to_exact( get(*(m.vpm), k) ); + return m.node_vector->exact_node(it->second); + } + + const Node_id_map* node_ids; + const VertexPointMap* vpm; + const NodeVector* node_vector; +}; + +template +struct Side_of_vpm_helper +{ + typedef Node_vector_exact_vertex_point_map type; + static + type get_vpm(const Node_id_map& node_ids, + const VertexPointMap& vpm, + const NodeVector& node_vector) + { + return type(node_ids, vpm, node_vector); + } +}; + +template +struct Side_of_vpm_helper +{ + typedef VertexPointMap type; + static + type get_vpm(const Node_id_map&, + const VertexPointMap& vpm, + const NodeVector&) + { + return vpm; + } +}; + // Parts to get default property maps for output meshes based on the value type // of input vertex point maps. template From 3a9ffc89cf49d586257acbacd7644fb107a2f681 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Thu, 25 Feb 2021 20:44:16 +0000 Subject: [PATCH 217/248] Reorganize #ifdef as the edge_descriptor is not the one from OpenMesh --- STL_Extension/include/CGAL/hash_openmesh.h | 30 +++++++++------- .../test/STL_Extension/CMakeLists.txt | 15 ++++++++ .../test/STL_Extension/test_hash_OpenMesh.cpp | 36 +++++++++++++++++++ 3 files changed, 69 insertions(+), 12 deletions(-) create mode 100644 STL_Extension/test/STL_Extension/test_hash_OpenMesh.cpp diff --git a/STL_Extension/include/CGAL/hash_openmesh.h b/STL_Extension/include/CGAL/hash_openmesh.h index bab5dc40918..fb7fdd21edd 100644 --- a/STL_Extension/include/CGAL/hash_openmesh.h +++ b/STL_Extension/include/CGAL/hash_openmesh.h @@ -73,7 +73,7 @@ inline std::size_t hash_value(const CGAL::internal::OMesh_edge @@ -87,6 +87,8 @@ namespace std { #ifndef CGAL_CFG_NO_STD_HASH +#ifndef OM_HAS_HASH + template <> struct hash : public CGAL::cpp98::unary_function @@ -131,16 +133,6 @@ struct hash } }; -template <> -struct hash > - : public CGAL::cpp98::unary_function -{ - - std::size_t operator()(const CGAL::internal::OMesh_edge& h) const - { - return h.idx(); - } -}; template <> struct hash @@ -153,6 +145,20 @@ struct hash } }; +#endif // OM_HAS_HASH + +template +struct hash > + : public CGAL::cpp98::unary_function, std::size_t> +{ + + std::size_t operator()(const CGAL::internal::OMesh_edge& h) const + { + return h.idx(); + } +}; + + #endif // CGAL_CFG_NO_STD_HASH #if defined(BOOST_MSVC) @@ -162,6 +168,6 @@ struct hash } // namespace std -#endif // OM_HAS_HASH + #endif // CGAL_HASH_OPENMESH_H diff --git a/STL_Extension/test/STL_Extension/CMakeLists.txt b/STL_Extension/test/STL_Extension/CMakeLists.txt index f54723a483a..6c45f1a551f 100644 --- a/STL_Extension/test/STL_Extension/CMakeLists.txt +++ b/STL_Extension/test/STL_Extension/CMakeLists.txt @@ -9,6 +9,16 @@ find_package(CGAL REQUIRED) find_package( TBB QUIET ) include(CGAL_TBB_support) +find_package(OpenMesh QUIET) + +if(OpenMesh_FOUND) + include(UseOpenMesh) + add_definitions(-DCGAL_USE_OPENMESH) +else() + message(STATUS "Tests that use OpenMesh will not be compiled.") +endif() + + create_single_source_cgal_program( "test_Boolean_tag.cpp" ) create_single_source_cgal_program( "test_Cache.cpp" ) create_single_source_cgal_program( "test_Compact_container.cpp" ) @@ -49,3 +59,8 @@ create_single_source_cgal_program( "test_for_each.cpp" ) if(TARGET CGAL::TBB_support) target_link_libraries(test_for_each PUBLIC CGAL::TBB_support) endif() + +if(OpenMesh_FOUND) + create_single_source_cgal_program("test_hash_OpenMesh.cpp") + target_link_libraries(test_hash_OpenMesh PRIVATE ${OPENMESH_LIBRARIES}) +endif() diff --git a/STL_Extension/test/STL_Extension/test_hash_OpenMesh.cpp b/STL_Extension/test/STL_Extension/test_hash_OpenMesh.cpp new file mode 100644 index 00000000000..a13f4d78a75 --- /dev/null +++ b/STL_Extension/test/STL_Extension/test_hash_OpenMesh.cpp @@ -0,0 +1,36 @@ +#include + + +#include +#include +#include + +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; + +typedef OpenMesh::TriMesh_ArrayKernelT Mesh; + + +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef boost::graph_traits::face_descriptor face_descriptor; +typedef boost::graph_traits::halfedge_descriptor halfedge_descriptor; +typedef boost::graph_traits::edge_descriptor edge_descriptor; + +int main() +{ + { + std::unordered_map vmap; + std::unordered_map hmap; + std::unordered_map emap; + std::unordered_map fmap; + } + { + boost::unordered_map vmap; + boost::unordered_map hmap; + boost::unordered_map emap; + boost::unordered_map fmap; + } + return 0; +} From b787a0afd61732b94bf642d51c2130b44b512753 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Fri, 26 Feb 2021 16:45:33 +0000 Subject: [PATCH 218/248] (std::min) --- Distance_3/include/CGAL/squared_distance_3_3.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Distance_3/include/CGAL/squared_distance_3_3.h b/Distance_3/include/CGAL/squared_distance_3_3.h index 39120823c9d..8f2987a0d5f 100644 --- a/Distance_3/include/CGAL/squared_distance_3_3.h +++ b/Distance_3/include/CGAL/squared_distance_3_3.h @@ -62,7 +62,7 @@ squared_distance(const typename K::Tetrahedron_3 & t, dmin = d; dmin_initialized = true; }else{ - dmin = std::min(d,dmin); + dmin = (std::min)(d,dmin); } } @@ -76,7 +76,7 @@ squared_distance(const typename K::Tetrahedron_3 & t, dmin = d; dmin_initialized = true; }else{ - dmin = std::min(d,dmin); + dmin = (std::min)(d,dmin); } } @@ -90,7 +90,7 @@ squared_distance(const typename K::Tetrahedron_3 & t, dmin = d; dmin_initialized = true; }else{ - dmin = std::min(d,dmin); + dmin = (std::min)(d,dmin); } } From 57033b4b0313585af9ced42cb140da28c356e4e1 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Fri, 26 Feb 2021 16:58:22 +0000 Subject: [PATCH 219/248] int -> std::size_t --- Nef_3/include/CGAL/Nef_3/polygon_mesh_to_nef_3.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Nef_3/include/CGAL/Nef_3/polygon_mesh_to_nef_3.h b/Nef_3/include/CGAL/Nef_3/polygon_mesh_to_nef_3.h index f80aaa6e7f2..69a1ad95ebf 100644 --- a/Nef_3/include/CGAL/Nef_3/polygon_mesh_to_nef_3.h +++ b/Nef_3/include/CGAL/Nef_3/polygon_mesh_to_nef_3.h @@ -201,7 +201,7 @@ void polygon_mesh_to_nef_3(PolygonMesh& P, SNC_structure& S, FaceIndexMap fimap, Vertex_around_face_circulator vafc(halfedge(f,P),P), done(vafc); Vector_3 v; normal_vector_newell_3(vafc, done, pmap, v); - int i = get(fimap,f); + std::size_t i = get(fimap,f); normals[i] = -v; CGAL_assertion_code(num_edges[i] = circulator_size(vafc)); } @@ -253,7 +253,7 @@ void polygon_mesh_to_nef_3(PolygonMesh& P, SNC_structure& S, FaceIndexMap fimap, if(is_border(pe_prev,P)) with_border = true; else { - int i = get(fimap,face(pe_prev,P)); + std::size_t i = get(fimap,face(pe_prev,P)); Plane ss_plane( CGAL::ORIGIN, normals[i]); Sphere_circle ss_circle(ss_plane); CGAL_assertion_code(if(num_edges[i] > 3) { @@ -286,7 +286,7 @@ void polygon_mesh_to_nef_3(PolygonMesh& P, SNC_structure& S, FaceIndexMap fimap, with_border = true; e = sv_prev->out_sedge(); } else { - int i = get(fimap,face(pe_prev,P)); + std::size_t i = get(fimap,face(pe_prev,P)); Plane ss_plane( CGAL::ORIGIN, normals[i]); Sphere_circle ss_circle(ss_plane); From 1b8b7c144930b33e4d2092a060224ea568b54aee Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Fri, 26 Feb 2021 17:12:12 +0000 Subject: [PATCH 220/248] AOS: Compare with nullptr to avoid warning --- .../examples/Arrangement_on_surface_2/algebraic_segments.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/algebraic_segments.cpp b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/algebraic_segments.cpp index 1db0e105e69..e1cddea3f38 100644 --- a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/algebraic_segments.cpp +++ b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/algebraic_segments.cpp @@ -61,7 +61,7 @@ int main() // but not for this instance for(size_t i = 0; i < pre_segs.size(); ++i) { auto* curr_p = boost::get(&pre_segs[i]);; - CGAL_assertion(curr_p); + CGAL_assertion(curr_p != nullptr); segs.push_back(*curr_p); } // Construct an ellipse with equation 2*x^2+5*y^2-7=0 From 93c2d790d908705e37817f9c76170d2cc536ca7d Mon Sep 17 00:00:00 2001 From: Guillaume Damiand Date: Fri, 26 Feb 2021 18:14:26 +0100 Subject: [PATCH 221/248] std::min --- .../Surface_mesh_topology/internal/Minimal_quadrangulation.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h index 3be71c59f49..174ff1aec75 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h @@ -1950,7 +1950,7 @@ protected: std::vector result(suffix_len.begin() + p.length(), suffix_len.end()); for (std::size_t i = 0; i < result.size(); ++i) { - result[i] = std::min(result[i], p.length()); + result[i] = (std::min)(result[i], p.length()); } return result; } @@ -2092,7 +2092,7 @@ protected: /// @return a unique 1-cell id for the dart size_type get_absolute_idx(Dart_const_handle dh) const { - return std::min(get_local_map().darts().index(dh), get_local_map().darts().index(get_local_map().opposite(dh))); + return (std::min)(get_local_map().darts().index(dh), get_local_map().darts().index(get_local_map().opposite(dh))); } /// @return true if the dart is the representative for the unique 1-cell id From 7d21d5b62df94ad5df58dac24464e30d372dd4a3 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Mon, 1 Mar 2021 11:17:56 +0100 Subject: [PATCH 222/248] De-activate some things that depend on CGAL_Core if it is not FOUND --- .../Algebraic_kernel_d/CMakeLists.txt | 4 +- .../test/Algebraic_kernel_d/CMakeLists.txt | 44 ++++++----- .../Arrangement_on_surface_2/CMakeLists.txt | 46 ++++++++++- .../Hyperbolic_triangulation_2/CMakeLists.txt | 7 +- Installation/test/Installation/CMakeLists.txt | 2 +- Number_types/test/Number_types/CMakeLists.txt | 24 +++--- .../Plugins/Surface_mesh/CMakeLists.txt | 76 +++++++++---------- 7 files changed, 126 insertions(+), 77 deletions(-) diff --git a/Algebraic_kernel_d/examples/Algebraic_kernel_d/CMakeLists.txt b/Algebraic_kernel_d/examples/Algebraic_kernel_d/CMakeLists.txt index 02f1ac1c563..a680de07a5a 100644 --- a/Algebraic_kernel_d/examples/Algebraic_kernel_d/CMakeLists.txt +++ b/Algebraic_kernel_d/examples/Algebraic_kernel_d/CMakeLists.txt @@ -9,7 +9,7 @@ if ( CGAL_FOUND ) find_package(MPFI QUIET) endif() -if( CGAL_FOUND AND MPFI_FOUND) +if( CGAL_FOUND AND CGAL_Core_FOUND AND MPFI_FOUND) include( ${CGAL_USE_FILE} ) include( ${MPFI_USE_FILE} ) @@ -23,6 +23,6 @@ if( CGAL_FOUND AND MPFI_FOUND) else() - message(STATUS "This program requires the CGAL library and MPFI, and will not be compiled.") + message(STATUS "This program requires the CGAL, CGAL_Core and MPFI libraries, and will not be compiled.") endif() diff --git a/Algebraic_kernel_d/test/Algebraic_kernel_d/CMakeLists.txt b/Algebraic_kernel_d/test/Algebraic_kernel_d/CMakeLists.txt index 73b7294442b..f789001b5f0 100644 --- a/Algebraic_kernel_d/test/Algebraic_kernel_d/CMakeLists.txt +++ b/Algebraic_kernel_d/test/Algebraic_kernel_d/CMakeLists.txt @@ -42,26 +42,30 @@ include( ${CGAL_USE_FILE} ) # ########################################################## create_single_source_cgal_program( "cyclic.cpp" ) -create_single_source_cgal_program( "Algebraic_curve_kernel_2.cpp" ) -create_single_source_cgal_program( "algebraic_curve_kernel_2_tools.cpp" ) -create_single_source_cgal_program( "Algebraic_kernel_d_1_LEDA.cpp" ) - -create_single_source_cgal_program( "Algebraic_kernel_d_1_CORE_Integer_rational.cpp" ) -create_single_source_cgal_program( "Algebraic_kernel_d_1_CORE_SqrtII_rational.cpp" ) -create_single_source_cgal_program( "Algebraic_kernel_d_1_CORE_SqrtRI_rational.cpp" ) -create_single_source_cgal_program( "Algebraic_kernel_d_1_CORE_SqrtRR_rational.cpp" ) - -create_single_source_cgal_program( "Algebraic_kernel_d_1_GMP.cpp" ) -create_single_source_cgal_program( "Algebraic_kernel_d_2.cpp" ) -create_single_source_cgal_program( "Algebraic_real_d_1.cpp" ) -create_single_source_cgal_program( "Bitstream_descartes.cpp" ) -create_single_source_cgal_program( "Curve_analysis_2.cpp" ) -create_single_source_cgal_program( "Curve_pair_analysis_2.cpp" ) create_single_source_cgal_program( "Descartes.cpp" ) -create_single_source_cgal_program( "Real_embeddable_traits_extension.cpp" ) -if(RS_FOUND) - create_single_source_cgal_program( "Algebraic_kernel_rs_gmpq_d_1.cpp" ) - create_single_source_cgal_program( "Algebraic_kernel_rs_gmpz_d_1.cpp" ) +if(CGAL_Core_FOUND) + create_single_source_cgal_program( "Algebraic_curve_kernel_2.cpp" ) + create_single_source_cgal_program( "algebraic_curve_kernel_2_tools.cpp" ) + create_single_source_cgal_program( "Algebraic_kernel_d_1_LEDA.cpp" ) + + create_single_source_cgal_program( "Algebraic_kernel_d_1_CORE_Integer_rational.cpp" ) + create_single_source_cgal_program( "Algebraic_kernel_d_1_CORE_SqrtII_rational.cpp" ) + create_single_source_cgal_program( "Algebraic_kernel_d_1_CORE_SqrtRI_rational.cpp" ) + create_single_source_cgal_program( "Algebraic_kernel_d_1_CORE_SqrtRR_rational.cpp" ) + + create_single_source_cgal_program( "Algebraic_kernel_d_1_GMP.cpp" ) + create_single_source_cgal_program( "Algebraic_kernel_d_2.cpp" ) + create_single_source_cgal_program( "Algebraic_real_d_1.cpp" ) + create_single_source_cgal_program( "Bitstream_descartes.cpp" ) + create_single_source_cgal_program( "Curve_analysis_2.cpp" ) + create_single_source_cgal_program( "Curve_pair_analysis_2.cpp" ) + create_single_source_cgal_program( "Real_embeddable_traits_extension.cpp" ) + if(RS_FOUND) + create_single_source_cgal_program( "Algebraic_kernel_rs_gmpq_d_1.cpp" ) + create_single_source_cgal_program( "Algebraic_kernel_rs_gmpz_d_1.cpp" ) + else() + message(STATUS "NOTICE: Some tests require the RS library, and will not be compiled.") + endif() else() - message(STATUS "NOTICE: Some tests require the RS library, and will not be compiled.") + message(STATUS "NOTICE: Some tests require the CGAL_Core library, and will not be compiled.") endif() diff --git a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/CMakeLists.txt b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/CMakeLists.txt index 0ffdc893571..100eee87b0d 100644 --- a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/CMakeLists.txt +++ b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/CMakeLists.txt @@ -23,9 +23,49 @@ if ( CGAL_FOUND ) # create a target per cppfile file(GLOB cppfiles RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) - foreach(cppfile ${cppfiles}) - create_single_source_cgal_program( "${cppfile}" ) - endforeach() + + create_single_source_cgal_program("construction_test_suite_generator.cpp") + create_single_source_cgal_program("ex_kernel_point.cpp") + create_single_source_cgal_program("ex_kernel_segment.cpp") + create_single_source_cgal_program("test_arc_polycurve.cpp") + create_single_source_cgal_program("test_batched_point_location.cpp") + create_single_source_cgal_program("test_bezier_polycurve.cpp") + create_single_source_cgal_program("test_circular_arc_polycurve.cpp") + create_single_source_cgal_program("test_conic_polycurve.cpp") + create_single_source_cgal_program("test_construction.cpp") + create_single_source_cgal_program("test_data_traits.cpp") + create_single_source_cgal_program("test_do_equal.cpp") + create_single_source_cgal_program("test_do_intersect.cpp") + create_single_source_cgal_program("test_dual.cpp") + create_single_source_cgal_program("test_insertion.cpp") + create_single_source_cgal_program("test_io.cpp") + create_single_source_cgal_program("test_iso_verts.cpp") + create_single_source_cgal_program("test_observer.cpp") + create_single_source_cgal_program("test_overlay.cpp") + create_single_source_cgal_program("test_point_location.") + create_single_source_cgal_program("test_point_location_dynamic.cpp") + create_single_source_cgal_program("test_polycurve_intersection.cpp") + create_single_source_cgal_program("test_polylines.cpp") + create_single_source_cgal_program("test_rational_function_traits_2.cpp") + create_single_source_cgal_program("test_removal.cpp") + create_single_source_cgal_program("test_sgm.cpp") + create_single_source_cgal_program("test_spherical_merge.cpp") + create_single_source_cgal_program("test_spherical_overlay.cpp") + create_single_source_cgal_program("test_spherical_removal.cpp") + create_single_source_cgal_program("test_tags.cpp") + create_single_source_cgal_program("test_traits_adaptor.cpp") + create_single_source_cgal_program("test_traits_dispatching.cpp") + create_single_source_cgal_program("test_unbounded_rational_direct_insertion.cpp") + create_single_source_cgal_program("test_unbounded_rational_insertion.cpp") + create_single_source_cgal_program("test_unbounded_removal.cpp") + create_single_source_cgal_program("test_vertical_decomposition.cpp") + create_single_source_cgal_program("test_vert_ray_shoot_vert_segments.cpp") + create_single_source_cgal_program("test_zone.cpp") + if(CGAL_Core_FOUND) + create_single_source_cgal_program("test_traits.cpp") + else() + message(STATUS "NOTICE: Some tests require the CGAL_Core library, and will not be compiled.") + endif() endif() else() diff --git a/Hyperbolic_triangulation_2/demo/Hyperbolic_triangulation_2/CMakeLists.txt b/Hyperbolic_triangulation_2/demo/Hyperbolic_triangulation_2/CMakeLists.txt index 61dd2e41455..5febb776e27 100644 --- a/Hyperbolic_triangulation_2/demo/Hyperbolic_triangulation_2/CMakeLists.txt +++ b/Hyperbolic_triangulation_2/demo/Hyperbolic_triangulation_2/CMakeLists.txt @@ -27,7 +27,12 @@ if(CGAL_FOUND AND CGAL_Qt5_FOUND AND Qt5_FOUND AND (CGAL_Core_FOUND OR LEDA_FOUN # cpp files add_executable ( HDT2 HDT2.cpp ${CGAL_Qt5_RESOURCE_FILES} ${RESOURCE_FILES} ${UIS}) add_to_cached_list( CGAL_EXECUTABLE_TARGETS HDT2 ) - target_link_libraries ( HDT2 CGAL::CGAL CGAL::CGAL_Qt5 CGAL::CGAL_Core Qt5::Widgets) + target_link_libraries ( HDT2 CGAL::CGAL CGAL::CGAL_Qt5 Qt5::Widgets) + if(CGAL_Core_FOUND) + target_link_libraries ( HDT2 CGAL::CGAL_Core) + else() + target_link_libraries ( HDT2 ${LEDA_LIBRARIES}) + endif() else() message(STATUS "NOTICE: This demo requires CGAL, CGAL_Core (or LEDA), and Qt5 and will not be compiled.") endif() diff --git a/Installation/test/Installation/CMakeLists.txt b/Installation/test/Installation/CMakeLists.txt index 7c060ba89fb..ec826619dab 100644 --- a/Installation/test/Installation/CMakeLists.txt +++ b/Installation/test/Installation/CMakeLists.txt @@ -56,7 +56,7 @@ if ( CGAL_FOUND ) create_link_to_program(CGAL) - if ( WITH_CGAL_Core ) + if ( CGAL_Core_FOUND ) create_link_to_program(CGAL_Core) endif() diff --git a/Number_types/test/Number_types/CMakeLists.txt b/Number_types/test/Number_types/CMakeLists.txt index ce8952df0e9..3fff7f845a6 100644 --- a/Number_types/test/Number_types/CMakeLists.txt +++ b/Number_types/test/Number_types/CMakeLists.txt @@ -16,7 +16,6 @@ if ( CGAL_FOUND ) include( CGAL_VersionUtils ) include_directories( BEFORE include ) - create_single_source_cgal_program( "bench_interval.cpp" ) create_single_source_cgal_program( "constant.cpp" ) create_single_source_cgal_program( "CORE_BigFloat.cpp" ) @@ -69,26 +68,29 @@ if ( CGAL_FOUND ) create_single_source_cgal_program( "unsigned.cpp" ) create_single_source_cgal_program( "utilities.cpp" ) find_package( GMP ) - if( GMP_FOUND ) + if( GMP_FOUND AND NOT CGAL_DISABLE_GMP) create_single_source_cgal_program( "CORE_Expr_ticket_4296.cpp" ) find_package( MPFI ) if( MPFI_FOUND ) include( ${MPFI_USE_FILE} ) endif( MPFI_FOUND ) endif( GMP_FOUND ) + if(CGAL_Core_FOUND) + create_single_source_cgal_program( "Gmpfi.cpp" ) + create_single_source_cgal_program( "Gmpfr_bug.cpp" ) + create_single_source_cgal_program( "eigen.cpp" ) + find_package(Eigen3 3.2.0) #(requires 3.2.0 or greater) + include(CGAL_Eigen3_support) + if (TARGET CGAL::Eigen3_support) + target_link_libraries(eigen PUBLIC CGAL::Eigen3_support) + endif() + else() + message(STATUS "NOTICE: Some tests require the CGAL_Core library, and will not be compiled.") + endif() # all the programs below will be linked against MPFI in case it is present - create_single_source_cgal_program( "Gmpfi.cpp" ) - create_single_source_cgal_program( "Gmpfr_bug.cpp" ) create_single_source_cgal_program( "Quotient_new.cpp" ) create_single_source_cgal_program( "test_nt_Coercion_traits.cpp" ) - create_single_source_cgal_program( "eigen.cpp" ) - find_package(Eigen3 3.2.0) #(requires 3.2.0 or greater) - include(CGAL_Eigen3_support) - if (TARGET CGAL::Eigen3_support) - target_link_libraries(eigen PUBLIC CGAL::Eigen3_support) - endif() - else( CGAL_FOUND ) message(STATUS diff --git a/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/CMakeLists.txt b/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/CMakeLists.txt index bbcfb4b6ef5..97d1b3df99a 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/CMakeLists.txt @@ -4,47 +4,45 @@ if(POLICY CMP0074) cmake_policy(SET CMP0074 NEW) endif() -if(TARGET CGAL::Eigen3_support) - find_package(CGAL COMPONENTS Core) +find_package(CGAL COMPONENTS Core) +include(${CGAL_USE_FILE}) - include(${CGAL_USE_FILE}) - - qt5_wrap_ui(parameterizationUI_FILES Parameterization_widget.ui OTE_dialog.ui) - polyhedron_demo_plugin(parameterization_plugin Parameterization_plugin ${parameterizationUI_FILES}) - target_link_libraries(parameterization_plugin PUBLIC scene_surface_mesh_item scene_textured_item scene_selection_item CGAL::Eigen3_support) +if(CGAL_Core_FOUND) + qt5_wrap_ui( segmentationUI_FILES Mesh_segmentation_widget.ui) + polyhedron_demo_plugin(mesh_segmentation_plugin Mesh_segmentation_plugin ${segmentationUI_FILES}) + target_link_libraries(mesh_segmentation_plugin PUBLIC scene_surface_mesh_item CGAL::CGAL_Core) + qt5_wrap_ui( mesh_simplificationUI_FILES Mesh_simplification_dialog.ui) + polyhedron_demo_plugin(mesh_simplification_plugin Mesh_simplification_plugin ${mesh_simplificationUI_FILES}) + target_link_libraries(mesh_simplification_plugin PUBLIC scene_surface_mesh_item scene_selection_item) + qt5_wrap_ui( remeshingUI_FILES Remeshing_dialog.ui) + polyhedron_demo_plugin(offset_meshing_plugin Offset_meshing_plugin ${remeshingUI_FILES}) + target_link_libraries(offset_meshing_plugin PUBLIC scene_surface_mesh_item scene_polygon_soup_item) + qt5_wrap_ui( shortestPathUI_FILES Shortest_path_widget.ui ) + polyhedron_demo_plugin(shortest_path_plugin Shortest_path_plugin ${shortestPathUI_FILES}) + target_link_libraries(shortest_path_plugin PUBLIC scene_surface_mesh_item scene_shortest_path_item scene_basic_objects) + qt5_wrap_ui(basicUI_FILES Surface_mesh_approximation_dockwidget.ui) + polyhedron_demo_plugin(surface_mesh_approximation_plugin + Surface_mesh_approximation_plugin + ${basicUI_FILES} + VSA_wrapper) + target_link_libraries(surface_mesh_approximation_plugin + PUBLIC + scene_surface_mesh_item + scene_polygon_soup_item + scene_polylines_item) + if(TARGET CGAL::Eigen3_support) + qt5_wrap_ui(parameterizationUI_FILES Parameterization_widget.ui OTE_dialog.ui) + polyhedron_demo_plugin(parameterization_plugin Parameterization_plugin ${parameterizationUI_FILES}) + target_link_libraries(parameterization_plugin PUBLIC scene_surface_mesh_item scene_textured_item scene_selection_item CGAL::Eigen3_support) + target_link_libraries(offset_meshing_plugin PUBLIC CGAL::Eigen3_support) + else() + message(STATUS "NOTICE: Eigen 3.1 (or greater) was not found. The Parameterization plugin will not be available.") + endif() + if(TARGET CGAL::TBB_support) + target_link_libraries(offset_meshing_plugin PUBLIC CGAL::TBB_support) + endif() else() - message(STATUS "NOTICE: Eigen 3.1 (or greater) was not found. The Parameterization plugin will not be available.") + message(STATUS "NOTICE: Some tests require the CGAL_Core library, and will not be compiled.") endif() -qt5_wrap_ui( segmentationUI_FILES Mesh_segmentation_widget.ui) -polyhedron_demo_plugin(mesh_segmentation_plugin Mesh_segmentation_plugin ${segmentationUI_FILES}) -target_link_libraries(mesh_segmentation_plugin PUBLIC scene_surface_mesh_item) -qt5_wrap_ui( mesh_simplificationUI_FILES Mesh_simplification_dialog.ui) -polyhedron_demo_plugin(mesh_simplification_plugin Mesh_simplification_plugin ${mesh_simplificationUI_FILES}) -target_link_libraries(mesh_simplification_plugin PUBLIC scene_surface_mesh_item scene_selection_item) - -qt5_wrap_ui( remeshingUI_FILES Remeshing_dialog.ui) -polyhedron_demo_plugin(offset_meshing_plugin Offset_meshing_plugin ${remeshingUI_FILES}) -target_link_libraries(offset_meshing_plugin PUBLIC scene_surface_mesh_item scene_polygon_soup_item) -if(TARGET CGAL::Eigen3_support) - target_link_libraries(offset_meshing_plugin PUBLIC CGAL::Eigen3_support) -endif() -if(TARGET CGAL::TBB_support) - target_link_libraries(offset_meshing_plugin PUBLIC CGAL::TBB_support) -endif() - -qt5_wrap_ui( shortestPathUI_FILES Shortest_path_widget.ui ) -polyhedron_demo_plugin(shortest_path_plugin Shortest_path_plugin ${shortestPathUI_FILES}) -target_link_libraries(shortest_path_plugin PUBLIC scene_surface_mesh_item scene_shortest_path_item scene_basic_objects) - -qt5_wrap_ui(basicUI_FILES Surface_mesh_approximation_dockwidget.ui) -polyhedron_demo_plugin(surface_mesh_approximation_plugin - Surface_mesh_approximation_plugin - ${basicUI_FILES} - VSA_wrapper) -target_link_libraries(surface_mesh_approximation_plugin - PUBLIC - scene_surface_mesh_item - scene_polygon_soup_item - scene_polylines_item) From 82989ae1af04688336665fff6ebbf8ed8e298062 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Mon, 1 Mar 2021 13:11:00 +0100 Subject: [PATCH 223/248] specify CGAL::compare to prevent conflict with LEDA::compare() --- .../internal_functions_comparison_root_for_spheres_2_3.h | 6 +++--- Distance_2/include/CGAL/squared_distance_2_1.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Algebraic_kernel_for_spheres/include/CGAL/Algebraic_kernel_for_spheres/internal_functions_comparison_root_for_spheres_2_3.h b/Algebraic_kernel_for_spheres/include/CGAL/Algebraic_kernel_for_spheres/internal_functions_comparison_root_for_spheres_2_3.h index 1bfca81e065..1a79af038cc 100644 --- a/Algebraic_kernel_for_spheres/include/CGAL/Algebraic_kernel_for_spheres/internal_functions_comparison_root_for_spheres_2_3.h +++ b/Algebraic_kernel_for_spheres/include/CGAL/Algebraic_kernel_for_spheres/internal_functions_comparison_root_for_spheres_2_3.h @@ -30,19 +30,19 @@ namespace CGAL { template Comparison_result compare_x(const CGAL::Root_for_spheres_2_3& r1, const CGAL::Root_for_spheres_2_3& r2){ - return compare(r1.x(), r2.x()); + return CGAL::compare(r1.x(), r2.x()); } template Comparison_result compare_y(const CGAL::Root_for_spheres_2_3& r1, const CGAL::Root_for_spheres_2_3& r2){ - return compare(r1.y(), r2.y()); + return CGAL::compare(r1.y(), r2.y()); } template Comparison_result compare_z(const CGAL::Root_for_spheres_2_3& r1, const CGAL::Root_for_spheres_2_3& r2){ - return compare(r1.z(), r2.z()); + return CGAL::compare(r1.z(), r2.z()); } template diff --git a/Distance_2/include/CGAL/squared_distance_2_1.h b/Distance_2/include/CGAL/squared_distance_2_1.h index f9b62838e91..171b8fd1e81 100644 --- a/Distance_2/include/CGAL/squared_distance_2_1.h +++ b/Distance_2/include/CGAL/squared_distance_2_1.h @@ -234,7 +234,7 @@ namespace internal { c2s = CGAL::abs(wcross(seg1.source(), seg1.target(), seg2.source(), k)); c2e = CGAL::abs(wcross(seg1.source(), seg1.target(), seg2.target(), k)); - Comparison_result dm = compare(c2s,c2e); + Comparison_result dm = CGAL::compare(c2s,c2e); if (dm == SMALLER) { return internal::squared_distance(seg2.source(), seg1, k); @@ -249,7 +249,7 @@ namespace internal { } else { c1s = CGAL::abs(wcross(seg2.source(), seg2.target(), seg1.source(), k)); c1e = CGAL::abs(wcross(seg2.source(), seg2.target(), seg1.target(), k)); - Comparison_result dm = compare(c1s,c1e); + Comparison_result dm = CGAL::compare(c1s,c1e); if (crossing2) { if (dm == SMALLER) { return internal::squared_distance(seg1.source(), seg2, k); @@ -272,7 +272,7 @@ namespace internal { c2s = CGAL::abs(wcross(seg1.source(), seg1.target(), seg2.source(), k)); c2e = CGAL::abs(wcross(seg1.source(), seg1.target(), seg2.target(), k)); - dm = compare(c2s,c2e); + dm = CGAL::compare(c2s,c2e); if (dm == EQUAL) // should not happen. return internal::squared_distance_parallel(seg1, seg2, k); From fb174a2779988f7caada05a24c82d1ad32671ce5 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Mon, 1 Mar 2021 15:24:38 +0100 Subject: [PATCH 224/248] Add CGAL_DISABLE_GMP to the properties of the ctest tests --- .../test/Arrangement_on_surface_2/cgal_test.cmake | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/cgal_test.cmake b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/cgal_test.cmake index d6ae0f045bb..23068da7670 100644 --- a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/cgal_test.cmake +++ b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/cgal_test.cmake @@ -1424,3 +1424,9 @@ compile_and_run(test_io) compile_and_run(test_sgm) compile_and_run(test_polycurve_intersection) +if(CGAL_DISABLE_GMP) + get_directory_property(LIST_OF_TESTS TESTS) + foreach(_test ${LIST_OF_TESTS}) + set_tests_properties(${_test} PROPERTIES ENVIRONMENT CGAL_DISABLE_GMP=1) + endforeach() +endif() From a16bd23d0466bb4e1ff577fffd25c7cb37b8e477 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Tue, 2 Mar 2021 09:56:14 +0100 Subject: [PATCH 225/248] Replace Qt::MidButton by Qt::MiddleButton, qhich is the same thing but not deprecated --- GraphicsView/include/CGAL/Qt/qglviewer_impl.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/GraphicsView/include/CGAL/Qt/qglviewer_impl.h b/GraphicsView/include/CGAL/Qt/qglviewer_impl.h index 5e6ab9dae8a..9d77b64eb57 100644 --- a/GraphicsView/include/CGAL/Qt/qglviewer_impl.h +++ b/GraphicsView/include/CGAL/Qt/qglviewer_impl.h @@ -715,7 +715,7 @@ void CGAL::QGLViewer::setDefaultMouseBindings() { (mh == qglviewer::FRAME) ? frameKeyboardModifiers : cameraKeyboardModifiers; setMouseBinding(modifiers, ::Qt::LeftButton, mh, qglviewer::ROTATE); - setMouseBinding(modifiers, ::Qt::MidButton, mh, qglviewer::ZOOM); + setMouseBinding(modifiers, ::Qt::MiddleButton, mh, qglviewer::ZOOM); setMouseBinding(modifiers, ::Qt::RightButton, mh, qglviewer::TRANSLATE); setMouseBinding(::Qt::Key_R, modifiers, ::Qt::LeftButton, mh, qglviewer::SCREEN_ROTATE); @@ -724,7 +724,7 @@ void CGAL::QGLViewer::setDefaultMouseBindings() { } // Z o o m o n r e g i o n - setMouseBinding(::Qt::ShiftModifier, ::Qt::MidButton, qglviewer::CAMERA, qglviewer::ZOOM_ON_REGION); + setMouseBinding(::Qt::ShiftModifier, ::Qt::MiddleButton, qglviewer::CAMERA, qglviewer::ZOOM_ON_REGION); // S e l e c t setMouseBinding(::Qt::ShiftModifier, ::Qt::LeftButton, qglviewer::SELECT); @@ -732,7 +732,7 @@ void CGAL::QGLViewer::setDefaultMouseBindings() { setMouseBinding(::Qt::ShiftModifier, ::Qt::RightButton, qglviewer::RAP_FROM_PIXEL); // D o u b l e c l i c k setMouseBinding(::Qt::NoModifier, ::Qt::LeftButton, qglviewer::ALIGN_CAMERA, true); - setMouseBinding(::Qt::NoModifier, ::Qt::MidButton, qglviewer::SHOW_ENTIRE_SCENE, true); + setMouseBinding(::Qt::NoModifier, ::Qt::MiddleButton, qglviewer::SHOW_ENTIRE_SCENE, true); setMouseBinding(::Qt::NoModifier, ::Qt::RightButton, qglviewer::CENTER_SCENE, true); setMouseBinding(frameKeyboardModifiers, ::Qt::LeftButton, qglviewer::ALIGN_FRAME, true); @@ -1198,7 +1198,7 @@ static QString mouseButtonsString(::Qt::MouseButtons b) { result += CGAL::QGLViewer::tr("Left", "left mouse button"); addAmpersand = true; } - if (b & ::Qt::MidButton) { + if (b & ::Qt::MiddleButton) { if (addAmpersand) result += " & "; result += CGAL::QGLViewer::tr("Middle", "middle mouse button"); @@ -1733,7 +1733,7 @@ Mouse tab. \c ::Qt::AltModifier, \c ::Qt::ShiftModifier, \c ::Qt::MetaModifier). Possibly combined using the \c "|" operator. -\p button is one of the ::Qt::MouseButtons (\c ::Qt::LeftButton, \c ::Qt::MidButton, +\p button is one of the ::Qt::MouseButtons (\c ::Qt::LeftButton, \c ::Qt::MiddleButton, \c ::Qt::RightButton...). \p doubleClick indicates whether or not the user has to double click this button @@ -3008,27 +3008,27 @@ void CGAL::QGLViewer::toggleCameraMode() { camera()->frame()->stopSpinning(); setMouseBinding(modifiers, ::Qt::LeftButton, qglviewer::CAMERA, qglviewer::MOVE_FORWARD); - setMouseBinding(modifiers, ::Qt::MidButton, qglviewer::CAMERA, qglviewer::LOOK_AROUND); + setMouseBinding(modifiers, ::Qt::MiddleButton, qglviewer::CAMERA, qglviewer::LOOK_AROUND); setMouseBinding(modifiers, ::Qt::RightButton, qglviewer::CAMERA, qglviewer::MOVE_BACKWARD); setMouseBinding(::Qt::Key_R, modifiers, ::Qt::LeftButton, qglviewer::CAMERA, qglviewer::ROLL); setMouseBinding(::Qt::NoModifier, ::Qt::LeftButton, qglviewer::NO_CLICK_ACTION, true); - setMouseBinding(::Qt::NoModifier, ::Qt::MidButton, qglviewer::NO_CLICK_ACTION, true); + setMouseBinding(::Qt::NoModifier, ::Qt::MiddleButton, qglviewer::NO_CLICK_ACTION, true); setMouseBinding(::Qt::NoModifier, ::Qt::RightButton, qglviewer::NO_CLICK_ACTION, true); setWheelBinding(modifiers, qglviewer::CAMERA, qglviewer::MOVE_FORWARD); } else { // Should stop flyTimer. But unlikely and not easy. setMouseBinding(modifiers, ::Qt::LeftButton, qglviewer::CAMERA, qglviewer::ROTATE); - setMouseBinding(modifiers, ::Qt::MidButton, qglviewer::CAMERA, qglviewer::ZOOM); + setMouseBinding(modifiers, ::Qt::MiddleButton, qglviewer::CAMERA, qglviewer::ZOOM); setMouseBinding(modifiers, ::Qt::RightButton, qglviewer::CAMERA, qglviewer::TRANSLATE); setMouseBinding(::Qt::Key_R, modifiers, ::Qt::LeftButton, qglviewer::CAMERA, qglviewer::SCREEN_ROTATE); setMouseBinding(::Qt::NoModifier, ::Qt::LeftButton, qglviewer::ALIGN_CAMERA, true); - setMouseBinding(::Qt::NoModifier, ::Qt::MidButton, qglviewer::SHOW_ENTIRE_SCENE, true); + setMouseBinding(::Qt::NoModifier, ::Qt::MiddleButton, qglviewer::SHOW_ENTIRE_SCENE, true); setMouseBinding(::Qt::NoModifier, ::Qt::RightButton, qglviewer::CENTER_SCENE, true); setWheelBinding(modifiers, qglviewer::CAMERA, qglviewer::ZOOM); From 7c94a1f2bf5633d7ee8116a51384a4731d3e80ec Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Tue, 2 Mar 2021 08:53:53 +0100 Subject: [PATCH 226/248] Replace condition for a clearer equivalent one, and use APPEND for env property in Arrangement_2 --- .../examples/Algebraic_kernel_d/CMakeLists.txt | 2 +- .../test/Algebraic_kernel_d/CMakeLists.txt | 2 +- .../test/Arrangement_on_surface_2/CMakeLists.txt | 2 +- .../test/Arrangement_on_surface_2/cgal_test.cmake | 2 +- Number_types/test/Number_types/CMakeLists.txt | 14 +++++++------- .../Polyhedron/Plugins/Surface_mesh/CMakeLists.txt | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Algebraic_kernel_d/examples/Algebraic_kernel_d/CMakeLists.txt b/Algebraic_kernel_d/examples/Algebraic_kernel_d/CMakeLists.txt index a680de07a5a..2d709b0a14a 100644 --- a/Algebraic_kernel_d/examples/Algebraic_kernel_d/CMakeLists.txt +++ b/Algebraic_kernel_d/examples/Algebraic_kernel_d/CMakeLists.txt @@ -9,7 +9,7 @@ if ( CGAL_FOUND ) find_package(MPFI QUIET) endif() -if( CGAL_FOUND AND CGAL_Core_FOUND AND MPFI_FOUND) +if( CGAL_FOUND AND NOT CGAL_DISABLE_GMP AND MPFI_FOUND) include( ${CGAL_USE_FILE} ) include( ${MPFI_USE_FILE} ) diff --git a/Algebraic_kernel_d/test/Algebraic_kernel_d/CMakeLists.txt b/Algebraic_kernel_d/test/Algebraic_kernel_d/CMakeLists.txt index f789001b5f0..b142e7c24e8 100644 --- a/Algebraic_kernel_d/test/Algebraic_kernel_d/CMakeLists.txt +++ b/Algebraic_kernel_d/test/Algebraic_kernel_d/CMakeLists.txt @@ -43,7 +43,7 @@ include( ${CGAL_USE_FILE} ) create_single_source_cgal_program( "cyclic.cpp" ) create_single_source_cgal_program( "Descartes.cpp" ) -if(CGAL_Core_FOUND) +if(NOT CGAL_DISABLE_GMP) create_single_source_cgal_program( "Algebraic_curve_kernel_2.cpp" ) create_single_source_cgal_program( "algebraic_curve_kernel_2_tools.cpp" ) create_single_source_cgal_program( "Algebraic_kernel_d_1_LEDA.cpp" ) diff --git a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/CMakeLists.txt b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/CMakeLists.txt index 100eee87b0d..7db7b6ad5f3 100644 --- a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/CMakeLists.txt +++ b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/CMakeLists.txt @@ -61,7 +61,7 @@ if ( CGAL_FOUND ) create_single_source_cgal_program("test_vertical_decomposition.cpp") create_single_source_cgal_program("test_vert_ray_shoot_vert_segments.cpp") create_single_source_cgal_program("test_zone.cpp") - if(CGAL_Core_FOUND) + if(NOT CGAL_DISABLE_GMP) create_single_source_cgal_program("test_traits.cpp") else() message(STATUS "NOTICE: Some tests require the CGAL_Core library, and will not be compiled.") diff --git a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/cgal_test.cmake b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/cgal_test.cmake index 23068da7670..20a279a59fd 100644 --- a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/cgal_test.cmake +++ b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/cgal_test.cmake @@ -1427,6 +1427,6 @@ compile_and_run(test_polycurve_intersection) if(CGAL_DISABLE_GMP) get_directory_property(LIST_OF_TESTS TESTS) foreach(_test ${LIST_OF_TESTS}) - set_tests_properties(${_test} PROPERTIES ENVIRONMENT CGAL_DISABLE_GMP=1) + set_property(TEST ${_test} APPEND PROPERTY ENVIRONMENT CGAL_DISABLE_GMP=1) endforeach() endif() diff --git a/Number_types/test/Number_types/CMakeLists.txt b/Number_types/test/Number_types/CMakeLists.txt index 3fff7f845a6..61b13d9f00a 100644 --- a/Number_types/test/Number_types/CMakeLists.txt +++ b/Number_types/test/Number_types/CMakeLists.txt @@ -68,14 +68,14 @@ if ( CGAL_FOUND ) create_single_source_cgal_program( "unsigned.cpp" ) create_single_source_cgal_program( "utilities.cpp" ) find_package( GMP ) - if( GMP_FOUND AND NOT CGAL_DISABLE_GMP) + if( GMP_FOUND AND NOT CGAL_DISABLE_GMP ) create_single_source_cgal_program( "CORE_Expr_ticket_4296.cpp" ) find_package( MPFI ) if( MPFI_FOUND ) include( ${MPFI_USE_FILE} ) - endif( MPFI_FOUND ) - endif( GMP_FOUND ) - if(CGAL_Core_FOUND) + endif() #MPFI_FOUND + endif() #GMP_FOUND AND NOT CGAL_DISABLE_GMP + if(NOT CGAL_DISABLE_GMP) create_single_source_cgal_program( "Gmpfi.cpp" ) create_single_source_cgal_program( "Gmpfr_bug.cpp" ) create_single_source_cgal_program( "eigen.cpp" ) @@ -84,9 +84,9 @@ if ( CGAL_FOUND ) if (TARGET CGAL::Eigen3_support) target_link_libraries(eigen PUBLIC CGAL::Eigen3_support) endif() - else() - message(STATUS "NOTICE: Some tests require the CGAL_Core library, and will not be compiled.") - endif() + else()#NOT CGAL_DISABLE_GMP + message(STATUS "NOTICE: Some tests require the CGAL_Core library, and will not be compiled.") + endif()#NOT CGAL_DISABLE_GMP # all the programs below will be linked against MPFI in case it is present create_single_source_cgal_program( "Quotient_new.cpp" ) create_single_source_cgal_program( "test_nt_Coercion_traits.cpp" ) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/CMakeLists.txt b/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/CMakeLists.txt index 97d1b3df99a..ef07d03390c 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/CMakeLists.txt @@ -7,7 +7,7 @@ endif() find_package(CGAL COMPONENTS Core) include(${CGAL_USE_FILE}) -if(CGAL_Core_FOUND) +if(NOT CGAL_DISABLE_GMP) qt5_wrap_ui( segmentationUI_FILES Mesh_segmentation_widget.ui) polyhedron_demo_plugin(mesh_segmentation_plugin Mesh_segmentation_plugin ${segmentationUI_FILES}) target_link_libraries(mesh_segmentation_plugin PUBLIC scene_surface_mesh_item CGAL::CGAL_Core) From 714d7091ce6e3df4bdaf4de961e993cfd094648b Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Tue, 2 Mar 2021 15:44:00 +0100 Subject: [PATCH 227/248] WIP save items. Need tests. --- Polyhedron/demo/Polyhedron/MainWindow.cpp | 48 ++++++++++++++++++++++- Polyhedron/demo/Polyhedron/Scene.h | 2 +- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/MainWindow.cpp b/Polyhedron/demo/Polyhedron/MainWindow.cpp index ae89cf30dfa..6308d80dd88 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.cpp +++ b/Polyhedron/demo/Polyhedron/MainWindow.cpp @@ -1,3 +1,4 @@ + #ifdef CGAL_USE_SSH # include "CGAL/Use_ssh.h" #endif @@ -2970,6 +2971,7 @@ void MainWindow::on_actionSa_ve_Scene_as_Script_triggered() std::vector rendering_modes; QStringList not_saved; Polyhedron_demo_io_plugin_interface* camera_plugin = nullptr; + QMap > group_children_map; for(int i = 0; i < scene->numberOfEntries(); ++i) { Scene_item* item = scene->item(i); @@ -2991,7 +2993,8 @@ void MainWindow::on_actionSa_ve_Scene_as_Script_triggered() //check if it is in a group if(item->parentGroup()) { - + group_children_map[item->parentGroup()->name()].append(item->name()); + ; } QListto_save; to_save.append(item); @@ -3055,6 +3058,28 @@ void MainWindow::on_actionSa_ve_Scene_as_Script_triggered() //delete temp file QFile tmp_file(fullpath); tmp_file.remove(); + //group relations + if(!group_children_map.empty()) + { + os << "var groups = ["; + for(int i = 0; i< group_children_map.size() -1; ++i) + { + QString group_name = group_children_map.keys()[i]; + os << "[\'" << group_name.toStdString().c_str()<<"\', ["; + for(int j = 0; j Date: Tue, 2 Mar 2021 16:16:07 +0100 Subject: [PATCH 228/248] use custom functor for bbox and split primitives aabb tree build runtime is similar to using EPICK --- AABB_tree/include/CGAL/AABB_traits.h | 12 +- .../Corefinement/Face_graph_output_builder.h | 29 ++-- .../internal/Corefinement/face_graph_utils.h | 155 ++++++++++++++++-- 3 files changed, 167 insertions(+), 29 deletions(-) diff --git a/AABB_tree/include/CGAL/AABB_traits.h b/AABB_tree/include/CGAL/AABB_traits.h index 613d08c174b..e443e08a522 100644 --- a/AABB_tree/include/CGAL/AABB_traits.h +++ b/AABB_tree/include/CGAL/AABB_traits.h @@ -428,6 +428,11 @@ public: Closest_point closest_point_object() const {return Closest_point(*this);} Compare_distance compare_distance_object() const {return Compare_distance();} + typedef enum { CGAL_AXIS_X = 0, + CGAL_AXIS_Y = 1, + CGAL_AXIS_Z = 2} Axis; + + static Axis longest_axis(const Bounding_box& bbox); private: /** @@ -446,13 +451,6 @@ private: return internal::Primitive_helper::get_datum(pr,*this).bbox(); } - - typedef enum { CGAL_AXIS_X = 0, - CGAL_AXIS_Y = 1, - CGAL_AXIS_Z = 2} Axis; - - static Axis longest_axis(const Bounding_box& bbox); - /// Comparison functions static bool less_x(const Primitive& pr1, const Primitive& pr2,const AABB_traits& traits) { diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h index 306f0d9144a..2dd5efc3790 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h @@ -1110,13 +1110,17 @@ public: ? ON_UNBOUNDED_SIDE : ON_BOUNDED_SIDE; typedef typename Nodes_vector::Exact_kernel Exact_kernel; - typedef Side_of_vpm_helper VPM_helper; - typedef typename VPM_helper::type SOTM_vpm2; + typedef Side_of_helper VPM_helper; + typedef typename VPM_helper::VPM SOTM_vpm2; + typedef typename VPM_helper::Tree_type Tree_type; SOTM_vpm2 sotm_vpm2 = VPM_helper::get_vpm(vertex_to_node_id2, vpm2, nodes); - Side_of_triangle_mesh inside_tm2(tm2, sotm_vpm2); + Tree_type tree; + VPM_helper::build_tree(tm2, tree, vertex_to_node_id2, fids2, vpm2, nodes); + Side_of_triangle_mesh inside_tm2(tree); for(face_descriptor f : faces(tm1)) { @@ -1182,13 +1186,16 @@ public: ? ON_UNBOUNDED_SIDE : ON_BOUNDED_SIDE; typedef typename Nodes_vector::Exact_kernel Exact_kernel; - typedef Side_of_vpm_helper VPM_helper; - typedef typename VPM_helper::type SOTM_vpm1; + typedef Side_of_helper VPM_helper; + typedef typename VPM_helper::VPM SOTM_vpm1; + typedef typename VPM_helper::Tree_type Tree_type; - SOTM_vpm1 sotm_vpm1 = VPM_helper::get_vpm(vertex_to_node_id1, vpm1, nodes); - Side_of_triangle_mesh inside_tm1(tm1, sotm_vpm1); + Tree_type tree; + VPM_helper::build_tree(tm1, tree, vertex_to_node_id1, fids1, vpm1, nodes); + Side_of_triangle_mesh inside_tm1(tree); for(face_descriptor f : faces(tm2)) { diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h index c4c07117619..fcbd22db729 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h @@ -146,6 +146,8 @@ void copy_edge_mark(G&, No_mark&) {} // nothing to do + +// For exact side_of_triangle_mesh template @@ -183,35 +185,166 @@ struct Node_vector_exact_vertex_point_map const NodeVector* node_vector; }; -template +struct Split_primitives +{ + Split_primitives(TriangleMesh& tm, PPM ppm) + : tm(tm) + , ppm(ppm) + {} + + template + void operator()(PrimitiveIterator first, + PrimitiveIterator beyond, + const CGAL::Bbox_3& bbox) const + { + typedef typename std::iterator_traits::value_type Prmtv; + PrimitiveIterator middle = first + (beyond - first)/2; + typedef typename std::iterator_traits::value_type Prmtv; + switch(TreeTraits::longest_axis(bbox)) + { + case TreeTraits::CGAL_AXIS_X: // sort along x + std::nth_element(first, middle, beyond, [this](const Prmtv& p1, const Prmtv& p2){ return get(ppm, p1.id()).x() < get(ppm,p2.id()).x(); }); + break; + case TreeTraits::CGAL_AXIS_Y: // sort along y + std::nth_element(first, middle, beyond, [this](const Prmtv& p1, const Prmtv& p2){ return get(ppm, p1.id()).y() < get(ppm,p2.id()).y(); }); + break; + case TreeTraits::CGAL_AXIS_Z: // sort along z + std::nth_element(first, middle, beyond, [this](const Prmtv& p1, const Prmtv& p2){ return get(ppm, p1.id()).z() < get(ppm,p2.id()).z(); }); + break; + default: + CGAL_error(); + } + } + TriangleMesh& tm; + PPM ppm; +}; + +// For exact side_of_triangle_mesh +template +struct Compute_bbox { + Compute_bbox(const BPM& bpm) + : bpm(bpm) + {} + + template + CGAL::Bbox_3 operator()(ConstPrimitiveIterator first, + ConstPrimitiveIterator beyond) const + { + CGAL::Bbox_3 bbox = get(bpm, first->id()); + for(++first; first != beyond; ++first) + { + bbox += get(bpm, first->id()); + } + return bbox; + } + BPM bpm; +}; + +// For exact side_of_triangle_mesh +template -struct Side_of_vpm_helper +struct Side_of_helper { - typedef Node_vector_exact_vertex_point_map type; + typedef Node_vector_exact_vertex_point_map VPM; + + typedef CGAL::AABB_face_graph_triangle_primitive Primitive; + typedef CGAL::AABB_traits Traits; + typedef CGAL::AABB_tree Tree_type; + static - type get_vpm(const Node_id_map& node_ids, + VPM get_vpm(const Node_id_map& node_ids, const VertexPointMap& vpm, const NodeVector& node_vector) { - return type(node_ids, vpm, node_vector); + return VPM(node_ids, vpm, node_vector); + } + + template + static + void build_tree(TriangleMesh& tm, + Tree_type& tree, + const Node_id_map& node_ids, + FaceIdMap fid, + const VertexPointMap& vpm, + const NodeVector& node_vector) + { + typedef typename boost::graph_traits::face_descriptor face_descriptor; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + + // add primitives + tree.insert(faces(tm).begin(), faces(tm).end(), tm, get_vpm(node_ids, vpm, node_vector)); + + // pre-build bboxes (using approximation) + std::vector face_bboxes(num_faces(tm)); + + auto get_v_box = [&node_ids, &node_vector, &vpm](vertex_descriptor v) + { + typename Node_id_map::const_iterator it = node_ids.find(v); + if (it == node_ids.end()) + return get(vpm, v).bbox(); + return approx(node_vector.exact_node(it->second)).bbox(); + }; + + for (face_descriptor f : faces(tm)) + { + halfedge_descriptor h = halfedge(f, tm); + face_bboxes[get(fid, f)] = get_v_box( source(h, tm) ) + + get_v_box( target(h, tm) ) + + get_v_box( target(next(h, tm), tm) ); + } + + typedef CGAL::Pointer_property_map::type Id_to_box; + Id_to_box id_to_box = CGAL::make_property_map(face_bboxes); + typedef Property_map_binder BPM; + BPM bpm(fid, id_to_box); + Compute_bbox compute_bbox(bpm); + + typedef One_point_from_face_descriptor_map PPM; + PPM ppm(&tm, vpm); + + Split_primitives split_primitives(tm, ppm); + tree.custom_build(compute_bbox, split_primitives); } }; -template -struct Side_of_vpm_helper +struct Side_of_helper { - typedef VertexPointMap type; + typedef VertexPointMap VPM; static - type get_vpm(const Node_id_map&, - const VertexPointMap& vpm, - const NodeVector&) + VPM get_vpm(const Node_id_map&, + const VertexPointMap& vpm, + const NodeVector&) { return vpm; } + + typedef CGAL::AABB_face_graph_triangle_primitive Primitive; + typedef CGAL::AABB_traits Traits; + typedef CGAL::AABB_tree Tree_type; + + + template + static + void build_tree(TriangleMesh& tm, + Tree_type& tree, + const Node_id_map& /* node_ids */, + FaceIdMap /* fid */, + const VertexPointMap& vpm, + const NodeVector& /* node_vector */) + { + tree.insert(faces(tm).begin(), faces(tm).end(), tm, vpm); + tree.build(); + } }; // Parts to get default property maps for output meshes based on the value type From c1dcaac0201de72493579881152e2118c40cc45e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 2 Mar 2021 16:21:06 +0100 Subject: [PATCH 229/248] remove TODOs --- .../internal/Corefinement/Face_graph_output_builder.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h index 2dd5efc3790..341bd670405 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h @@ -1147,7 +1147,7 @@ public: if (index_p1 != NID) { - if (tm1_coplanar_faces.test(f_id)) // TODO delay the building of the tree? + if (tm1_coplanar_faces.test(f_id)) { coplanar_patches_of_tm1.set(patch_id); coplanar_patches_of_tm1_for_union_and_intersection.set(patch_id); @@ -1221,7 +1221,7 @@ public: } if (index_p2 != NID) { - if (tm2_coplanar_faces.test(f_id)) // TODO delay the building of the tree? + if (tm2_coplanar_faces.test(f_id)) { coplanar_patches_of_tm2.set(patch_id); coplanar_patches_of_tm2_for_union_and_intersection.set(patch_id); From fa47c352711a016a299bc990e31d98c16cc2e88e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 3 Mar 2021 08:28:28 +0100 Subject: [PATCH 230/248] remove unused variable --- .../internal/Corefinement/Face_graph_output_builder.h | 1 - 1 file changed, 1 deletion(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h index 341bd670405..3b3d9f82699 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h @@ -1117,7 +1117,6 @@ public: typedef typename VPM_helper::VPM SOTM_vpm2; typedef typename VPM_helper::Tree_type Tree_type; - SOTM_vpm2 sotm_vpm2 = VPM_helper::get_vpm(vertex_to_node_id2, vpm2, nodes); Tree_type tree; VPM_helper::build_tree(tm2, tree, vertex_to_node_id2, fids2, vpm2, nodes); Side_of_triangle_mesh inside_tm2(tree); From 8b058d90d9e71e1f4ea243e08897ec6782505631 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 3 Mar 2021 11:02:39 +0100 Subject: [PATCH 231/248] Fixes --- Polyhedron/demo/Polyhedron/MainWindow.cpp | 39 +++++++++++++++-------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/MainWindow.cpp b/Polyhedron/demo/Polyhedron/MainWindow.cpp index 6308d80dd88..03afabc58d9 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.cpp +++ b/Polyhedron/demo/Polyhedron/MainWindow.cpp @@ -2964,7 +2964,7 @@ void MainWindow::on_actionSa_ve_Scene_as_Script_triggered() std::ofstream os(filename.toUtf8(), std::ofstream::binary); if(!os) return; - CGAL::Three::Three::CursorScopeGuard cs(Qt::WaitCursor); + QApplication::setOverrideCursor(Qt::WaitCursor); std::vector > names; std::vector > loaders; std::vector colors; @@ -3009,9 +3009,12 @@ void MainWindow::on_actionSa_ve_Scene_as_Script_triggered() } if(loader.isEmpty()) { + QApplication::restoreOverrideCursor(); QMessageBox::warning(this, "", tr("No plugin found for %1. Not saved.").arg(item->name())); + QApplication::setOverrideCursor(Qt::WaitCursor); continue; } + loaders.push_back(std::make_pair(loader, ext)); colors.push_back(item->color()); rendering_modes.push_back(item->renderingMode()); @@ -3125,17 +3128,20 @@ void MainWindow::on_actionSa_ve_Scene_as_Script_triggered() os << " it.setRgbColor(r,g,b);\n"; os << " it.setRenderingMode(rendering_modes[index]);\n"; os << "});\n"; - os << "groups.forEach(function(group, index, array){\n"; - os << " main_window.selectSceneItem(-1);\n"; - os << " var group_name = group[0];\n"; - os << " var item_list = group[1];\n"; - os << " main_window.makeNewGroup();\n"; - os << " var it = scene.item(scene.numberOfEntries-1);\n"; - os << " it.setName(group_name);\n"; - os << " item_list.forEach(function(child, index, array){\n"; - os << " scene.changeGroup(scene.item(indexFromName(child)), it);\n"; - os << " });\n"; - os << "});\n"; + if(!group_children_map.empty()) + { + os << "groups.forEach(function(group, index, array){\n"; + os << " main_window.selectSceneItem(-1);\n"; + os << " var group_name = group[0];\n"; + os << " var item_list = group[1];\n"; + os << " main_window.makeNewGroup();\n"; + os << " var it = scene.item(scene.numberOfEntries-1);\n"; + os << " it.setName(group_name);\n"; + os << " item_list.forEach(function(child, index, array){\n"; + os << " scene.changeGroup(scene.item(indexFromName(child)), it);\n"; + os << " });\n"; + os << "});\n"; + } os << "viewer.moveCameraToCoordinates(camera, 0.05);\n"; if(has_camera_positions) { @@ -3144,11 +3150,14 @@ void MainWindow::on_actionSa_ve_Scene_as_Script_triggered() os<<" main_window.open(fullpath,\'camera_positions_plugin\');\n"; } os.close(); - if(!not_saved.empty()) + if(!not_saved.empty()){ + QApplication::restoreOverrideCursor(); QMessageBox::warning(this, "Items Not Saved", QString("The following items could not be saved: %1").arg( not_saved.join(", "))); + QApplication::setOverrideCursor(Qt::WaitCursor); + } #ifdef CGAL_USE_SSH using namespace CGAL::ssh_internal; if(do_upload) @@ -3190,6 +3199,7 @@ void MainWindow::on_actionSa_ve_Scene_as_Script_triggered() if(!ok) { ssh_free(session); + QApplication::restoreOverrideCursor(); return; } pass = pass.trimmed(); @@ -3207,11 +3217,13 @@ void MainWindow::on_actionSa_ve_Scene_as_Script_triggered() "Error", "The SSH session could not be started."); ssh_free(session); + QApplication::restoreOverrideCursor(); return; } res = push_file(session,path.toStdString().c_str(), filename.toStdString().c_str()); if(!res) { + QApplication::restoreOverrideCursor(); QMessageBox::warning(this, "Error", "The file could not be uploaded. Check your console for more information."); @@ -3230,6 +3242,7 @@ void MainWindow::on_actionSa_ve_Scene_as_Script_triggered() } } #endif + QApplication::restoreOverrideCursor(); } void MainWindow::setTransparencyPasses(int val) { From 2349ba6d39e3f85660381741d5c42412e1d57682 Mon Sep 17 00:00:00 2001 From: Maxime GIMENO Date: Wed, 3 Mar 2021 11:51:14 +0100 Subject: [PATCH 232/248] Update Polyhedron/demo/Polyhedron/MainWindow.cpp Co-authored-by: Laurent Rineau --- Polyhedron/demo/Polyhedron/MainWindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Polyhedron/demo/Polyhedron/MainWindow.cpp b/Polyhedron/demo/Polyhedron/MainWindow.cpp index 03afabc58d9..cbbcb0daeed 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.cpp +++ b/Polyhedron/demo/Polyhedron/MainWindow.cpp @@ -1795,7 +1795,7 @@ void MainWindow::updateInfo() { QString item_filename = item->property("source filename").toString(); CGAL::Bbox_3 bbox = item->bbox(); if(bbox !=CGAL::Bbox_3()) - item_text += QString("
    Bounding box: min (%1,%2,%3), max (%4,%5,%6), axis lengths (%7, %8, %9)
    ") + item_text += QString("
    Bounding box: min (%1,%2,%3), max (%4,%5,%6), dimensions (%7, %8, %9)
    ") .arg(bbox.xmin(),0, 'g', 17) .arg(bbox.ymin(),0, 'g', 17) .arg(bbox.zmin(),0, 'g', 17) From 1b5ca5ce2b78dfcac1d39339efec2a6be23a2f1f Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 3 Mar 2021 13:22:50 +0100 Subject: [PATCH 233/248] Remove completely the demo --- .../demo/Surface_mesher/CMakeLists.txt | 155 -- Surface_mesher/demo/Surface_mesher/File_XT.h | 211 --- .../demo/Surface_mesher/Raw_image_dialog.cpp | 28 - .../demo/Surface_mesher/Raw_image_dialog.h | 19 - .../demo/Surface_mesher/Surface_mesher.cpp | 23 - .../demo/Surface_mesher/binary_image.h | 190 -- .../demo/Surface_mesher/colorlisteditor.cpp | 69 - .../demo/Surface_mesher/colorlisteditor.h | 63 - .../Surface_mesher/get_polyhedral_surface.h | 8 - .../demo/Surface_mesher/icons/bbox-red.png | Bin 5268 -> 0 bytes .../demo/Surface_mesher/icons/bbox-red.svg | 209 --- .../demo/Surface_mesher/icons/bbox.png | Bin 4098 -> 0 bytes .../demo/Surface_mesher/icons/bbox.svg | 167 -- .../demo/Surface_mesher/icons/cgal_logo.xpm | 24 - .../demo/Surface_mesher/icons/fileopen.png | Bin 7317 -> 0 bytes .../demo/Surface_mesher/icons/filesave.png | Bin 11659 -> 0 bytes .../demo/Surface_mesher/icons/flip.png | Bin 8608 -> 0 bytes .../demo/Surface_mesher/icons/flip.svg | 207 --- .../demo/Surface_mesher/icons/minus.png | Bin 250 -> 0 bytes .../demo/Surface_mesher/icons/plus.png | Bin 462 -> 0 bytes .../demo/Surface_mesher/icons/resize.png | Bin 8105 -> 0 bytes .../demo/Surface_mesher/icons/resize.svg | 297 --- .../demo/Surface_mesher/icons/surface.png | Bin 12658 -> 0 bytes .../demo/Surface_mesher/icons/surface.svg | 166 -- .../demo/Surface_mesher/icons/twosides.png | Bin 8011 -> 0 bytes .../demo/Surface_mesher/icons/twosides.svg | 169 -- .../demo/Surface_mesher/mainwindow.cpp | 179 -- .../demo/Surface_mesher/mainwindow.h | 42 - .../Surface_mesher/polyhedral_surface.cpp | 407 ----- .../demo/Surface_mesher/polyhedral_surface.h | 102 -- Surface_mesher/demo/Surface_mesher/surface.h | 37 - .../demo/Surface_mesher/surface_mesher.qrc | 13 - .../demo/Surface_mesher/ui/mainwindow.ui | 808 --------- .../demo/Surface_mesher/ui/optionsdialog.ui | 128 -- .../demo/Surface_mesher/ui/raw_image.ui | 454 ----- .../demo/Surface_mesher/ui/values_list.ui | 118 -- .../demo/Surface_mesher/values_list.cpp | 280 --- .../demo/Surface_mesher/values_list.h | 79 - .../demo/Surface_mesher/values_list.qrc | 6 - Surface_mesher/demo/Surface_mesher/viewer.cpp | 66 - Surface_mesher/demo/Surface_mesher/viewer.h | 30 - Surface_mesher/demo/Surface_mesher/volume.cpp | 1616 ----------------- Surface_mesher/demo/Surface_mesher/volume.h | 392 ---- 43 files changed, 6762 deletions(-) delete mode 100644 Surface_mesher/demo/Surface_mesher/CMakeLists.txt delete mode 100644 Surface_mesher/demo/Surface_mesher/File_XT.h delete mode 100644 Surface_mesher/demo/Surface_mesher/Raw_image_dialog.cpp delete mode 100644 Surface_mesher/demo/Surface_mesher/Raw_image_dialog.h delete mode 100644 Surface_mesher/demo/Surface_mesher/Surface_mesher.cpp delete mode 100644 Surface_mesher/demo/Surface_mesher/binary_image.h delete mode 100644 Surface_mesher/demo/Surface_mesher/colorlisteditor.cpp delete mode 100644 Surface_mesher/demo/Surface_mesher/colorlisteditor.h delete mode 100644 Surface_mesher/demo/Surface_mesher/get_polyhedral_surface.h delete mode 100644 Surface_mesher/demo/Surface_mesher/icons/bbox-red.png delete mode 100644 Surface_mesher/demo/Surface_mesher/icons/bbox-red.svg delete mode 100644 Surface_mesher/demo/Surface_mesher/icons/bbox.png delete mode 100644 Surface_mesher/demo/Surface_mesher/icons/bbox.svg delete mode 100644 Surface_mesher/demo/Surface_mesher/icons/cgal_logo.xpm delete mode 100644 Surface_mesher/demo/Surface_mesher/icons/fileopen.png delete mode 100644 Surface_mesher/demo/Surface_mesher/icons/filesave.png delete mode 100644 Surface_mesher/demo/Surface_mesher/icons/flip.png delete mode 100644 Surface_mesher/demo/Surface_mesher/icons/flip.svg delete mode 100644 Surface_mesher/demo/Surface_mesher/icons/minus.png delete mode 100644 Surface_mesher/demo/Surface_mesher/icons/plus.png delete mode 100644 Surface_mesher/demo/Surface_mesher/icons/resize.png delete mode 100644 Surface_mesher/demo/Surface_mesher/icons/resize.svg delete mode 100644 Surface_mesher/demo/Surface_mesher/icons/surface.png delete mode 100644 Surface_mesher/demo/Surface_mesher/icons/surface.svg delete mode 100644 Surface_mesher/demo/Surface_mesher/icons/twosides.png delete mode 100644 Surface_mesher/demo/Surface_mesher/icons/twosides.svg delete mode 100644 Surface_mesher/demo/Surface_mesher/mainwindow.cpp delete mode 100644 Surface_mesher/demo/Surface_mesher/mainwindow.h delete mode 100644 Surface_mesher/demo/Surface_mesher/polyhedral_surface.cpp delete mode 100644 Surface_mesher/demo/Surface_mesher/polyhedral_surface.h delete mode 100644 Surface_mesher/demo/Surface_mesher/surface.h delete mode 100644 Surface_mesher/demo/Surface_mesher/surface_mesher.qrc delete mode 100644 Surface_mesher/demo/Surface_mesher/ui/mainwindow.ui delete mode 100644 Surface_mesher/demo/Surface_mesher/ui/optionsdialog.ui delete mode 100644 Surface_mesher/demo/Surface_mesher/ui/raw_image.ui delete mode 100644 Surface_mesher/demo/Surface_mesher/ui/values_list.ui delete mode 100644 Surface_mesher/demo/Surface_mesher/values_list.cpp delete mode 100644 Surface_mesher/demo/Surface_mesher/values_list.h delete mode 100644 Surface_mesher/demo/Surface_mesher/values_list.qrc delete mode 100644 Surface_mesher/demo/Surface_mesher/viewer.cpp delete mode 100644 Surface_mesher/demo/Surface_mesher/viewer.h delete mode 100644 Surface_mesher/demo/Surface_mesher/volume.cpp delete mode 100644 Surface_mesher/demo/Surface_mesher/volume.h diff --git a/Surface_mesher/demo/Surface_mesher/CMakeLists.txt b/Surface_mesher/demo/Surface_mesher/CMakeLists.txt deleted file mode 100644 index 96e3edb9472..00000000000 --- a/Surface_mesher/demo/Surface_mesher/CMakeLists.txt +++ /dev/null @@ -1,155 +0,0 @@ -set(prj Surface_mesher) - -cmake_minimum_required(VERSION 3.1...3.15) -project(Surface_mesher_Demo) - -if(NOT POLICY CMP0070 AND POLICY CMP0053) - # Only set CMP0053 to OLD with CMake<3.10, otherwise there is a warning. - cmake_policy(SET CMP0053 OLD) -endif() - -# Find includes in corresponding build directories -set(CMAKE_INCLUDE_CURRENT_DIR ON) -# Instruct CMake to run moc automatically when needed. -set(CMAKE_AUTOMOC ON) - -if(POLICY CMP0071) - cmake_policy(SET CMP0071 NEW) -endif() -if(POLICY CMP0072) - # About the use of OpenGL - cmake_policy(SET CMP0072 NEW) -endif() - -if(POLICY CMP0074) - cmake_policy(SET CMP0074 NEW) -endif() - -set(PACKAGE_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../..) - -# Add several CGAL packages to the include and link paths, -# if they lie in ${PACKAGE_ROOT}/. - -foreach(LIB_DIR ${PACKAGE_ROOT}/../CGAL_ImageIO/src/CGAL_ImageIO - ${PACKAGE_ROOT}/../GraphicsView/src/CGALQt5) - if(EXISTS ${LIB_DIR}) - link_directories(${LIB_DIR}) - endif() -endforeach() - -include_directories(./) - -# QGLViewer needs Qt5 configured with QtOpenGL - -find_package(CGAL REQUIRED COMPONENTS ImageIO Qt5) -if(CGAL_Qt5_FOUND AND CGAL_ImageIO_FOUND) - - add_definitions(-DQT_NO_KEYWORDS) - - find_package(Qt5 QUIET COMPONENTS OpenGL Svg) - find_package(OpenGL) - - if(Qt5_FOUND - AND OPENGL_FOUND - AND OPENGL_GLU_FOUND) - - set(sources - Raw_image_dialog.cpp - colorlisteditor.cpp - values_list.cpp - mainwindow.cpp - Surface_mesher.cpp - viewer.cpp - volume.cpp) - - if(EXISTS ${PACKAGE_ROOT}/../Marching_cube) - option(SURFACE_MESH_DEMO_USE_MARCHING_CUBE - "Embed a marching cube implementation in the Surface Mesh demo." - ON) - mark_as_advanced(SURFACE_MESH_DEMO_USE_MARCHING_CUBE) - endif() - - if(EXISTS ${PACKAGE_ROOT}/include/CGAL/Polyhedral_surface_3.h) - option(SURFACE_MESH_DEMO_WITH_POLYHEDRAL_SURFACE - "Compile the support for polyhedral surfaces." OFF) - mark_as_advanced(SURFACE_MESH_DEMO_WITH_POLYHEDRAL_SURFACE) - endif() - - option( - SURFACE_MESH_DEMO_VERBOSE - "Set this option if you want the Surface Mesh demo to display messages on standard output." - OFF) - mark_as_advanced(SURFACE_MESH_DEMO_VERBOSE) - - if(SURFACE_MESH_DEMO_VERBOSE) - add_definitions(-DCGAL_SURFACE_MESHER_VERBOSE) - endif() - - if(SURFACE_MESH_DEMO_WITH_POLYHEDRAL_SURFACE) - set(sources ${sources} polyhedral_surface.cpp) - else(SURFACE_MESH_DEMO_WITH_POLYHEDRAL_SURFACE) - add_definitions(-DCGAL_DO_NOT_USE_POLYHEDRAL_SURFACE) - endif(SURFACE_MESH_DEMO_WITH_POLYHEDRAL_SURFACE) - - if(SURFACE_MESH_DEMO_USE_MARCHING_CUBE) - set(sources ${sources} ${PACKAGE_ROOT}/../Marching_cube/src/mc/ply.c) - add_definitions(-DCGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE) - endif() - - qt5_generate_moc("surface.h" "${CMAKE_CURRENT_BINARY_DIR}/moc_surface.cpp") - - set(sources ${sources} moc_surface.cpp) - - qt5_wrap_ui(uis ui/values_list.ui ui/mainwindow.ui ui/optionsdialog.ui - ui/raw_image.ui) - - qt5_add_resources(CGAL_Qt5_RESOURCE_FILES values_list.qrc - surface_mesher.qrc) - - add_executable(${prj} ${sources} ${uis} ${CGAL_Qt5_RESOURCE_FILES} - ${CGAL_Qt5_MOC_FILES}) - - add_to_cached_list(CGAL_EXECUTABLE_TARGETS ${prj}) - - 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") - add_definitions(-DCGAL_USE_VTK) - if(TARGET VTK::IOImage) - set(VTK_LIBRARIES VTK::IOImage VTK::ImagingGeneral) - endif() - else() - message(STATUS "Vtk must be at least Rel 6") - endif() - else() - message(STATUS "For reading Dicom files install VTK first") - endif() - - target_link_libraries( - ${prj} PRIVATE CGAL::CGAL CGAL::CGAL_Qt5 CGAL::CGAL_ImageIO - ${OPENGL_LIBRARIES} ${VTK_LIBRARIES}) - - include(${CGAL_MODULES_DIR}/CGAL_add_test.cmake) - cgal_add_compilation_test(${prj}) - - include(${CGAL_MODULES_DIR}/CGAL_add_test.cmake) - cgal_add_compilation_test(${prj}) - endif( - Qt5_FOUND - AND OPENGL_FOUND - AND OPENGL_GLU_FOUND) -else( - CGAL_Qt5_FOUND - AND CGAL_ImageIO_FOUND) - if(RUNNING_CGAL_AUTO_TEST) - # Just to avoid a warning from CMake if that variable is set on the command line... - endif() - - message(STATUS "NOTICE: This demo needs Qt5, and will not be compiled.") -endif( - CGAL_Qt5_FOUND - AND CGAL_ImageIO_FOUND) diff --git a/Surface_mesher/demo/Surface_mesher/File_XT.h b/Surface_mesher/demo/Surface_mesher/File_XT.h deleted file mode 100644 index 0b723bba749..00000000000 --- a/Surface_mesher/demo/Surface_mesher/File_XT.h +++ /dev/null @@ -1,211 +0,0 @@ -/********************************************************************* -* 25 - 02 - 97 -* gestion des fichiers image ELF -* -*********************************************************************/ - -#ifndef CGAL_FILE_XT_H -#define CGAL_FILE_XT_H - -#include -#include - -#include - -namespace CGAL { -namespace Total { -namespace internal { - -//To avoid "fopen may be unsafe" on Visual. -bool open_file(FILE **fin, const char* filename) -{ -#if defined(BOOST_MSVC) - return (fopen_s(fin, filename, "rw") == 0); -#else - *fin = fopen(filename, "rw"); - return (fin != NULL); -#endif -} - -} // namespace internal - -void permuteLong(char *a) -{ - char tmp; - -#ifdef CGAL_LITTLE_ENDIAN -tmp=a[0]; a[0]=a[3]; a[3]=tmp; -tmp=a[1]; a[1]=a[2]; a[2]=tmp; -#endif -} - -void permuteLongTab(long *a,int nb) -{ - int i; - -#ifdef CGAL_LITTLE_ENDIAN -for(i=0;isetNum((int)image_word_size() * - dim_x->value() * - dim_y->value() * - dim_z->value()); -} - -unsigned int Raw_image_dialog::image_word_size() const { - if(short_bt->isChecked()) - return 2; - if(int_bt->isChecked()) - return 4; - else if(float_bt->isChecked()) - return 4; - else if(double_bt->isChecked()) - return 8; - else - return 1; -} - diff --git a/Surface_mesher/demo/Surface_mesher/Raw_image_dialog.h b/Surface_mesher/demo/Surface_mesher/Raw_image_dialog.h deleted file mode 100644 index 7f191fecaf6..00000000000 --- a/Surface_mesher/demo/Surface_mesher/Raw_image_dialog.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef RAW_IMAGE_DIALOG_H -#define RAW_IMAGE_DIALOG_H - -#include "ui_raw_image.h" - -class Raw_image_dialog : public QDialog, public Ui::Raw_image_dialog -{ - Q_OBJECT - -public: - Raw_image_dialog(QWidget* parent = 0); - - unsigned int image_word_size() const; - -private Q_SLOTS: - void update_image_size(); -}; - -#endif // RAW_IMAGE_DIALOG diff --git a/Surface_mesher/demo/Surface_mesher/Surface_mesher.cpp b/Surface_mesher/demo/Surface_mesher/Surface_mesher.cpp deleted file mode 100644 index b6c18695ab5..00000000000 --- a/Surface_mesher/demo/Surface_mesher/Surface_mesher.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include "mainwindow.h" -#include -#include -#include - -int main(int argc, char** argv) -{ - QApplication application(argc,argv); - - application.setOrganizationDomain("geometryfactory.com"); - application.setOrganizationName("GeometryFactory"); - application.setApplicationName("Surface mesher Qt5 demo"); - - MainWindow w; - - if(argc>1) - w.surface_open(argv[1]); - - w.show(); - std::setlocale(LC_ALL, "C"); - return application.exec(); - std::cerr << "Exit\n"; -} diff --git a/Surface_mesher/demo/Surface_mesher/binary_image.h b/Surface_mesher/demo/Surface_mesher/binary_image.h deleted file mode 100644 index 591e6159744..00000000000 --- a/Surface_mesher/demo/Surface_mesher/binary_image.h +++ /dev/null @@ -1,190 +0,0 @@ -// Copyright (c) 2005-2008 INRIA Sophia-Antipolis (France). -// Copyright (c) 2008 GeometryFactory (France) -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org). -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial -// -// Author(s) : Laurent RINEAU, Pierre ALLIEZ - -#ifndef BINARY_IMAGE_3 -#define BINARY_IMAGE_3 - -#include - -#include -#include -#include - -#include -#include - -#include - -#include - -template -class CBinary_image_3 : public CGAL::Image_3 -{ - bool interpolate_; - bool labellized_; - -public: - double min_value; - double max_value; - - typedef FT_ FT; - -public: - CBinary_image_3() - : Image_3(), interpolate_(true) - { - } - - CBinary_image_3(const Image_3& bi) - : Image_3(bi), interpolate_(true) - { - } - - - CBinary_image_3(const CBinary_image_3& bi) - : Image_3(bi), interpolate_(bi.interpolate_),labellized_(bi.labellized_) - { - std::cerr << "CBinary_image_3::copy_constructor\n"; - min_value = bi.min_value; - max_value = bi.max_value; - } - - - void finish_open() { - CGAL_IMAGE_IO_CASE(image_ptr.get(), - Word *min; Word *max; - (boost::tie(min, max)) = - (CGAL::min_max_element((Word*)(data()), - (Word*)(data()) + - xdim() * ydim() * zdim())); - min_value = *min; - max_value = *max;) - } - - float xmax() const - { - return (float)(((image_ptr->xdim) - 1.0)*(image_ptr->vx)); - } - - float ymax() const - { - return (float)(((image_ptr->ydim) - 1.0)*(image_ptr->vy)); - } - - float zmax() const - { - return (float)(((image_ptr->zdim) - 1.0)*(image_ptr->vz)); - } - - Point center() - { - FT cx = 0.5 * xmax(); - FT cy = 0.5 * ymax(); - FT cz = 0.5 * zmax(); - return Point(cx,cy,cz); - } - - FT radius() - { - return (std::max)((std::max)(xmax(),ymax()),zmax()); - } - - Point point(const std::size_t i, - const std::size_t j, - const std::size_t k) const - { - return Point(i * (image_ptr->vx), - j * (image_ptr->vy), - k * (image_ptr->vz)); - } - -public: - bool inside(const float x, - const float y, - const float z) const - { - return ( x >= 0.0f && - y >= 0.0f && - z >= 0.0f && - x <= xmax() && - y <= ymax() && - z <= zmax() ); - } - - float rand_x() { return (float)rand() / (float)RAND_MAX * xmax(); } - float rand_y() { return (float)rand() / (float)RAND_MAX * ymax(); } - float rand_z() { return (float)rand() / (float)RAND_MAX * zmax(); } - - void set_interpolation(const bool b) - { - interpolate_ = b; - } - - bool interpolation() const { - return interpolate_; - } - - void set_labellized(const bool b) - { - labellized_ = b; - } - - bool labellized() const { - return labellized_; - } - - FT operator()(Point p) const - { - const float x = static_cast(CGAL::to_double(p.x())); - const float y = static_cast(CGAL::to_double(p.y())); - const float z = static_cast(CGAL::to_double(p.z())); - - if(interpolation()) { - if(labellized()) { - CGAL_IMAGE_IO_CASE(image_ptr.get(), - return (this->labellized_trilinear_interpolation(x, y, z, min_value));) - } - else { - CGAL_IMAGE_IO_CASE(image_ptr.get(), - return (this->trilinear_interpolation(x, y, z, min_value));) - } - } - else { - const std::ptrdiff_t i = static_cast(x/image()->vx + 0.5f); - const std::ptrdiff_t j = static_cast(y/image()->vy + 0.5f); - const std::ptrdiff_t k = static_cast(z/image()->vz + 0.5f); - if( i < 0 || - j < 0 || - k < 0 ) - { - return 0; - } - else - { - const std::size_t ui = static_cast(i); - const std::size_t uj = static_cast(j); - const std::size_t uk = static_cast(k); - if( ui >= image()->xdim || - uj >= image()->ydim || - uk >= image()->zdim ) - { - return 0; - } - else - { - return this->value(ui, uj, uk); - } - } - } - return FT(); - } -}; // end CBinary_image_3 - -#endif // BINARY_IMAGE_3 diff --git a/Surface_mesher/demo/Surface_mesher/colorlisteditor.cpp b/Surface_mesher/demo/Surface_mesher/colorlisteditor.cpp deleted file mode 100644 index 508b532c090..00000000000 --- a/Surface_mesher/demo/Surface_mesher/colorlisteditor.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2007-2007 Trolltech ASA. All rights reserved. -** -** This file is part of the example classes of the Qt Toolkit. -** -** This file may be used under the terms of the GNU General Public -** License version 2.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of -** this file. Please review the following information to ensure GNU -** General Public Licensing requirements will be met: -** http://trolltech.com/products/qt/licenses/licensing/opensource/ -** -** If you are unsure which license is appropriate for your use, please -** review the following information: -** http://trolltech.com/products/qt/licenses/licensing/licensingoverview -** or contact the sales department at sales@trolltech.com. -** -** In addition, as a special exception, Trolltech gives you certain -** additional rights. These rights are described in the Trolltech GPL -** Exception version 1.0, which can be found at -** http://www.trolltech.com/products/qt/gplexception/ and in the file -** GPL_EXCEPTION.txt in this package. -** -** In addition, as a special exception, Trolltech, as the sole copyright -** holder for Qt Designer, grants users of the Qt/Eclipse Integration -** plug-in the right for the Qt/Eclipse Integration to link to -** functionality provided by Qt Designer and its related libraries. -** -** Trolltech reserves all rights not expressly granted herein. -** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** -** SPDX-License-Identifier: LGPL-2.0-only -** -****************************************************************************/ - -#include - -#include "colorlisteditor.h" - -ColorListEditor::ColorListEditor(QWidget *widget) : QComboBox(widget) -{ - populateList(); -} - -QColor ColorListEditor::color() const -{ - return itemData(currentIndex(), Qt::DecorationRole).value(); -} - -void ColorListEditor::setColor(QColor color) -{ - setCurrentIndex(findData(color, int(Qt::DecorationRole))); -} - -void ColorListEditor::populateList() -{ - QStringList colorNames = QColor::colorNames(); - - for (int i = 0; i < colorNames.size(); ++i) { - QColor color(colorNames[i]); - - insertItem(i, colorNames[i]); - setItemData(i, color, Qt::DecorationRole); - } -} - diff --git a/Surface_mesher/demo/Surface_mesher/colorlisteditor.h b/Surface_mesher/demo/Surface_mesher/colorlisteditor.h deleted file mode 100644 index 4763d52b3b0..00000000000 --- a/Surface_mesher/demo/Surface_mesher/colorlisteditor.h +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2007-2007 Trolltech ASA. All rights reserved. -** -** This file is part of the example classes of the Qt Toolkit. -** -** This file may be used under the terms of the GNU General Public -** License version 2.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of -** this file. Please review the following information to ensure GNU -** General Public Licensing requirements will be met: -** http://trolltech.com/products/qt/licenses/licensing/opensource/ -** -** If you are unsure which license is appropriate for your use, please -** review the following information: -** http://trolltech.com/products/qt/licenses/licensing/licensingoverview -** or contact the sales department at sales@trolltech.com. -** -** In addition, as a special exception, Trolltech gives you certain -** additional rights. These rights are described in the Trolltech GPL -** Exception version 1.0, which can be found at -** http://www.trolltech.com/products/qt/gplexception/ and in the file -** GPL_EXCEPTION.txt in this package. -** -** In addition, as a special exception, Trolltech, as the sole copyright -** holder for Qt Designer, grants users of the Qt/Eclipse Integration -** plug-in the right for the Qt/Eclipse Integration to link to -** functionality provided by Qt Designer and its related libraries. -** -** Trolltech reserves all rights not expressly granted herein. -** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** -** SPDX-License-Identifier: LGPL-2.0-only -** -****************************************************************************/ - -#ifndef COLORLISTEDITOR_H -#define COLORLISTEDITOR_H - -#include - -class QColor; -class QWidget; - -class ColorListEditor : public QComboBox -{ - Q_OBJECT - Q_PROPERTY(QColor color READ color WRITE setColor USER true) - -public: - ColorListEditor(QWidget *widget = 0); - -public: - QColor color() const; - void setColor(QColor c); - -private: - void populateList(); -}; - -#endif diff --git a/Surface_mesher/demo/Surface_mesher/get_polyhedral_surface.h b/Surface_mesher/demo/Surface_mesher/get_polyhedral_surface.h deleted file mode 100644 index 51ebed3272d..00000000000 --- a/Surface_mesher/demo/Surface_mesher/get_polyhedral_surface.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef _GET_POLYHEDRAL_SURFACE_H -#define _GET_POLYHEDRAL_SURFACE_H - -#include "surface.h" - -Surface* get_polyhedral_surface(QObject*, double, double); - -#endif // _GET_POLYHEDRAL_SURFACE_H diff --git a/Surface_mesher/demo/Surface_mesher/icons/bbox-red.png b/Surface_mesher/demo/Surface_mesher/icons/bbox-red.png deleted file mode 100644 index 0da5c8fdde31e7fd99b73ce301b71f8e342f824b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5268 zcmaJ_cTf{dun)cWCWr!2dT)wK3nWTYYD9rR5D=+>AWecK6bT>_K&prc2oj`77b!tN zLebEB6N2<&=>74%f8WfznZ2FeyPNsV?%m$*#+W_0$Hpwg3;+Pw3=O~*7aaW`G16bm zt=f*=7mU_V&(MnTVxSnEu@^FvkHKR<0DyYuKcYgHe1Tpl1)oD6J-0+WeIDqDbO8hg z1}eCDd-ypy`nV_{kgo4GG=%^FUM@p0$SNpn{e9S5-l3EZo!Y0DUXr?UsK8cjVCCFm zN#sKwQ#&Us&FeyZN%6%UABq(WpKH~RIjcu&onh~3z3BM~OVG)c$ec}Z;mQTKIXs4q zh~%ULXp8}2XaX}(=#|KT|9--XH{PM~1$1a&N_Ajr#_wr;vG-7D?M&ll)A2^gu8~!W zgphzef~6O{nd=5%ds9HArjbeCJNryXHzM!wFvuKwKCU??`2@gqizz6zfKnX8 zRFmB34FDqPw`}3hF7_-wLfjcE2IXM0STq4uZFUumb#(#UyB;R=8-Q1By@8_-_A;rk zMAlgcDqp+3415#pTH=vBm@F4w@7etVQTCh)NO7871gD&PD`E%A#DHml1TN^=J-3ar zZx`p}3Gw{>!n6N`;{IDZr=8TdN+_dB$p2%mO2f%z3f`bE{fY~tGoe9NCl%`GQ%};L z4C>hfQ1R*7GvNCdxZUVpGM&Unp#-)_%pwyAg(R5rMk+@irt&!RV2SpebmV&Vc%+q)Mf=O-eX{8um=oM0`IGL zm)7d!TnSPxP$;Xl3#;_~6?dZvx(xvKQ=PDD{1iPTEZ|?5R(F-a=7S13{u`Ggew zQ6)0ix*Y&^W(6rB>p=9Lb z>3DpZRc=<8PdiO|Izj} z6`kx7tlxE+a&Tp^_gurD3=z^~i%_4@7v3nMm2aLBEunv7J@iRSKF?efm`2qsmN^m@ zt$SE33wxTtstYcl^24;yy9r__s!Vb~9nQpB{jmLAaMKwr*SA#B45t;c3$PVQ6rmAJ_cA$$lmNpn5t;~zALmP4Vn-07px=A!v&<}q(&5jVi)|Lt7O22v5k^Yi z-%~{@$<(5gSNhN1v=y90V^r})D5=&9drJ7+>HBt4$Y^s`$cHQ55CcYF&S}qv^_r4J z9fx6Fw=4pwg021U_SR7y2d6hAx0ZX<`V5MUEW8 zh& `ca4%s1gewe4Y=YU=-Vl5IXVWtKGB47p{2& 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 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - diff --git a/Surface_mesher/demo/Surface_mesher/icons/bbox.png b/Surface_mesher/demo/Surface_mesher/icons/bbox.png deleted file mode 100644 index 28c0d50c6b3b9a0b3e481d8fc3504e10845452e6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4098 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 AhX4Qo diff --git a/Surface_mesher/demo/Surface_mesher/icons/bbox.svg b/Surface_mesher/demo/Surface_mesher/icons/bbox.svg deleted file mode 100644 index e23b746c510..00000000000 --- a/Surface_mesher/demo/Surface_mesher/icons/bbox.svg +++ /dev/null @@ -1,167 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/Surface_mesher/demo/Surface_mesher/icons/cgal_logo.xpm b/Surface_mesher/demo/Surface_mesher/icons/cgal_logo.xpm deleted file mode 100644 index 6a69b3d67e1..00000000000 --- a/Surface_mesher/demo/Surface_mesher/icons/cgal_logo.xpm +++ /dev/null @@ -1,24 +0,0 @@ -/* XPM */ -const char * demoicon_xpm[] = { -/* columns rows colors chars-per-pixel */ -"16 16 3 1", -" c None", -". c #FFFF00", -"+ c #000000", -/* pixels */ -"................", -"...++++...++++..", -"..+....+.+....+.", -"..+......+......", -"..+......+..+++.", -"..+......+....+.", -"..+....+.+....+.", -"...++++...++++..", -"................", -"...++++...+.....", -"..+....+..+.....", -"..+....+..+.....", -"..++++++..+.....", -"..+....+..+.....", -"..+....+..+++++.", -"................"}; diff --git a/Surface_mesher/demo/Surface_mesher/icons/fileopen.png b/Surface_mesher/demo/Surface_mesher/icons/fileopen.png deleted file mode 100644 index 82b79b7242bd1d6ef9f3c2107a652c5f6f71e0c8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7317 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 V%pPX{nDAE-P*>Jbs!*^B`9F`E+5i9m diff --git a/Surface_mesher/demo/Surface_mesher/icons/filesave.png b/Surface_mesher/demo/Surface_mesher/icons/filesave.png deleted file mode 100644 index 0c5a242bc58735273237c1beb888459d73c2cb24..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11659 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 diff --git a/Surface_mesher/demo/Surface_mesher/icons/flip.png b/Surface_mesher/demo/Surface_mesher/icons/flip.png deleted file mode 100644 index 3d28392a0f5367fc6b4b1abddcedf0538c7f1daf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8608 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 mb9$k7^BkJK+4I6(9Qc32ki7}{w(dRv0000 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - Jakub Steiner - - - http://jimmac.musichall.cz - - Go Next - - - go - next - right - arrow - pointer - > - - - - - - - - - - - - - - - - - - - - diff --git a/Surface_mesher/demo/Surface_mesher/icons/minus.png b/Surface_mesher/demo/Surface_mesher/icons/minus.png deleted file mode 100644 index d6f233d7399c4c07c6c66775f7806acac84b1870..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 250 zcmeAS@N?(olHy`uVBq!ia0vp^Vj#@H3?x5i&EW)6P60k4u0Wb3;FYqWamwl0TmSYg zzPEV)f9L4=uDMg50*&A=3GxeOV9U{Bm1EIh)b!)dNY8G|=4l2>MR>Y6hE&9zJ@3ia zpuppBkxMsqLg3#2p{{ow4y^sCTR&@AtNcZ-!c0XiUIF(fS@*p4-Mvkxubuwr)McGB zHm7G5zmh%w<-tAQYwQ=f{_Q#i|$63?4Gdn(WDhGy5?S*zvKV>UH^L*-tUX z$Jv{I&ffC7bM{5Qj4e}Ezbj}vVjnSc;_|19_y1onFfAQuu24ykUoZnB3o9G9teS?7 zt9NpGMrLu#@0UVzfU@^IT^vIy;%X<}%xf{=arHKHYQL~@ZfotgwYUG*$MH^!I&%2V z@)sJL`rl4pesV%`$+ja*^=&3!b{Hmgs`72G$lh?~sgSmhV3T|L)#5pvnp5W$R3F&x zq^-&N)%9FO2FOm@bA*rKR&a{^p(h(SexKRzobg)f!S5Tb z0(ReeejodN_$Ob%pPGvI-{X5McZ=;}w|{;sE!Zmj;a8K;+WTSWrcUlO+qsq1zw`F> zL$~g{I69@}|MDjqpAy@zuKLv`b1gzCeQUnq?;S;@b8|k;l-+S#KOj|nW)fHH0-#SB NJYD@<);T3K0RYVY#HauO diff --git a/Surface_mesher/demo/Surface_mesher/icons/resize.png b/Surface_mesher/demo/Surface_mesher/icons/resize.png deleted file mode 100644 index b3d930f1d7b6d13cba4ba39cb91241934c85310e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8105 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
    }X`}*gXmP8=VZ)n_KC;=Ycb%hg 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 hYrhEpzf;!lL3}2rtm@Hd7hG8#pr)h^t$vA!_&8 diff --git a/Surface_mesher/demo/Surface_mesher/icons/resize.svg b/Surface_mesher/demo/Surface_mesher/icons/resize.svg deleted file mode 100644 index ed30359a802..00000000000 --- a/Surface_mesher/demo/Surface_mesher/icons/resize.svg +++ /dev/null @@ -1,297 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Surface_mesher/demo/Surface_mesher/icons/surface.png b/Surface_mesher/demo/Surface_mesher/icons/surface.png deleted file mode 100644 index e3585c5d8166ebb83b698eddce41068cffd11c6f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12658 zcmW-nby!qi6UWce-Jpnc2-3BHu!Jt%A(GM|wMa zhX;N9@vI}D-}tUdhVB4h9Q}8}(B)-Mp+9Lov8+A+Sr4^0-qgY{Sm&xXn_uYY2qkvrp5@u}A{uV<%2 zoC5LR&)aSs3bs#(H?Bq+H!}RTX#|BezW083-MQB>riNT&&i$39*n7N6f;o&^l^P+f ziCpg78;Z-J1e}_l;2Y)_x()`G3lj1vQnzdp?o1%-Q^I?8X&KENr4;a}%mV}b zE+zp=N9}AS#4^~*&7cUlU{u9LWO3xmht73A$^Y+JGytnn7k}93N3pS6=_dWZeKt-< z7#TVrJZH+SLweAY_lM3eg#Le7VgTY64?q^i%mrGo(-nZ7#E3^Nxw>v zuKr3C2OSQ(N=cm|nl~T#9?6v>l8F!4`uwnpSzu(p1NwZhvBt9FxoxFN^fQl@<%+Lq zlzbV{c&iQoMLuTB(zI)@%0vG&Q(|C~2QYOu_fUw$l8aM^blw;=Ad^FNpX-;7e0h2# z5|D-Un;j6Dv!Km7RCt!$YT1%C0JIh%2)REW&u`E4>G*u+XUrO1jW+)96`ZMd&U34Z zLbV;IYDR-c)c@y#y)`!G3rH(3&mX3dI}z(^+SeJuP1=n>L{tJj@MJdkU^<^->j0FzI6YYMr5cAM*A z1vU+fu6~S*AptxbP{mzYF$@_HQ0SQwsQDWer<~)IoF(y{PWTh=Wdf^BR(z=W{YYezX-3Ydg;~ z;}$M*`G#jIh8#$uyTBWaGiG!E@<^BEp63@_KMX*^lG{@?-o%5e=__$qo?i2ekH=cL zJk9sa2$1EihO%K(ROp5e)-v}^WyS~n0$G3!~MwCDOV!gap(as zrzDRAdl*2j!rxSnuGwV6>yBNe0M8@~-G|`ed+075^YKq%$t-r*WsKCOkr7Cg%0bL^ z`c8ILB67tUT}7jB`R5@hjohSWX*$!QRDA$qKN$lxY<%VXgIe4}Q94)5P-BBWTNTmc ztWub4>=ROgco}Vj>416HM`^G8fGmsZavXPl$C;xt!EP~+RmH(i~Urt1O+ArMe^_~%Gojue1x0%0A)Upd`0v@j;j%YwzI$H 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 diff --git a/Surface_mesher/demo/Surface_mesher/icons/surface.svg b/Surface_mesher/demo/Surface_mesher/icons/surface.svg deleted file mode 100644 index b3ce5b253a7..00000000000 --- a/Surface_mesher/demo/Surface_mesher/icons/surface.svg +++ /dev/null @@ -1,166 +0,0 @@ - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - diff --git a/Surface_mesher/demo/Surface_mesher/icons/twosides.png b/Surface_mesher/demo/Surface_mesher/icons/twosides.png deleted file mode 100644 index a2da1eb1b39fd03cc220a2091b63525e65cfcd33..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8011 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 F{tu0~30eRE diff --git a/Surface_mesher/demo/Surface_mesher/icons/twosides.svg b/Surface_mesher/demo/Surface_mesher/icons/twosides.svg deleted file mode 100644 index e1effe1d026..00000000000 --- a/Surface_mesher/demo/Surface_mesher/icons/twosides.svg +++ /dev/null @@ -1,169 +0,0 @@ - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - Jakub Steiner - - - http://jimmac.musichall.cz - - Go Next - - - go - next - right - arrow - pointer - > - - - - - - - - - - - - - - - - - - - - diff --git a/Surface_mesher/demo/Surface_mesher/mainwindow.cpp b/Surface_mesher/demo/Surface_mesher/mainwindow.cpp deleted file mode 100644 index ebb1260a693..00000000000 --- a/Surface_mesher/demo/Surface_mesher/mainwindow.cpp +++ /dev/null @@ -1,179 +0,0 @@ -#include "mainwindow.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include // std::max -#include // std::sqrt -#include - -#include "ui_mainwindow.h" -#include "volume.h" -#ifndef CGAL_DO_NOT_USE_POLYHEDRAL_SURFACE -# include "polyhedral_surface.h" -#endif - -MainWindow::MainWindow(MainWindow* other_window /* = 0 */) : - CGAL::Qt::DemosMainWindow(), - surface(0) -{ - setupUi(this); - setAcceptDrops(true); - - if(other_window != 0) - { - viewer->setCamera(other_window->viewer->camera()); - connect(other_window, SIGNAL(destroyed()), - this, SLOT(close())); - } - - this->addAboutCGAL(); - this->addRecentFiles(this->menu_File, - this->action_Quit); - connect(this, SIGNAL(openRecentFile(QString)), - this, SLOT(surface_open(QString))); - - this->readState(); - - show_only(""); -} - -void MainWindow::dragEnterEvent(QDragEnterEvent *event) -{ - if (event->mimeData()->hasFormat("text/uri-list")) - event->acceptProposedAction(); -} - -void MainWindow::dropEvent(QDropEvent *event) -{ - QString filename = event->mimeData()->urls().at(0).toLocalFile(); - surface_open(filename); - event->acceptProposedAction(); -} - -void MainWindow::surface_open(const QString& filename) -{ - if(surface != 0) { - delete surface; - surface = 0; - } -#ifndef CGAL_DO_NOT_USE_POLYHEDRAL_SURFACE - surface = new Polyhedral_surface(this); - if(surface->open(filename)) { - this->addToRecentFiles(filename); - return; - } - delete surface; - surface = 0; -#endif - surface = new Volume(this); - if(surface->open(filename)) { - this->addToRecentFiles(filename); - } -} - -void MainWindow::show_only(QString tag) -{ -#if 0 - QTextStream err(stderr); -#else - QString dummy; - QTextStream err(&dummy); -#endif - err << "** Show only in \"" << tag << "\"\n"; - Q_FOREACH(QObject* object, - this->findChildren()) - { - QStringList show_only_in = object->property("show_only_in").toStringList(); - if(!show_only_in.isEmpty()) - { - err << object->metaObject()->className() - << " \"" << object->objectName() << "\" only in: "; - Q_FOREACH(QString s, show_only_in) - err << s << " "; - const bool visible = show_only_in.contains(tag); - err << (visible ? "(enabled)\n" : "(disabled)\n"); - if(QMenu* menu = qobject_cast(object)) { - menu->menuAction()->setVisible(visible); - } - else { - object->setProperty("visible", QVariant::fromValue(visible)); - } - } - } -} - -void MainWindow::on_action_Open_triggered() -{ - QSettings settings; - QString directory = settings.value("Open directory", - QDir::current().dirName()).toString(); - QString filename = QFileDialog::getOpenFileName(this, tr("Open File"), - directory, - tr("all Files (*.*)")); - if(!filename.isEmpty()) { - QFileInfo fileinfo(filename); - if(fileinfo.isFile() && fileinfo.isReadable()) { - settings.setValue("Open directory", - fileinfo.absoluteDir().absolutePath()); - surface_open(filename); - } - } -} - -void MainWindow::on_action_OpenDirectory_triggered() -{ - QSettings settings; - QString start_dir = settings.value("Open directory", - QDir::current().dirName()).toString(); - QString dir = - QFileDialog::getExistingDirectory(this, - tr("Open directory"), - start_dir, - QFileDialog::ShowDirsOnly - | QFileDialog::DontResolveSymlinks); - - if (!dir.isEmpty()) { - QFileInfo fileinfo(dir); - if (fileinfo.isDir() && fileinfo.isReadable()) - { - settings.setValue("Open directory", - fileinfo.absoluteDir().absolutePath()); - surface_open(dir); - } - } -} - -void MainWindow::on_action_Quit_triggered() -{ - this->writeState(); - qApp->exit(); -} - -void MainWindow::closeEvent(QCloseEvent *event) -{ - this->writeState(); - event->accept(); -} - -void MainWindow::on_action_Clone_triggered() -{ - MainWindow* other = new MainWindow(this); - other->show(); -} - diff --git a/Surface_mesher/demo/Surface_mesher/mainwindow.h b/Surface_mesher/demo/Surface_mesher/mainwindow.h deleted file mode 100644 index 36aa2db2138..00000000000 --- a/Surface_mesher/demo/Surface_mesher/mainwindow.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef _MAINWINDOW_H -#define _MAINWINDOW_H - -#include -#include "ui_mainwindow.h" -#include - -class QDragEnterEvent; -class QDropEvent; -class Surface; -class QDoubleSpinBox; -class QCloseEvent; - -namespace CGAL{ -class QGLViewer; -} - -class MainWindow : public CGAL::Qt::DemosMainWindow, public Ui::MainWindow -{ - Q_OBJECT -public: - MainWindow(MainWindow* other_window = 0); - void dragEnterEvent(QDragEnterEvent *); - void dropEvent(QDropEvent *event); - -public Q_SLOTS: - void show_only(QString); - void surface_open(const QString& filename); - -private Q_SLOTS: - void on_action_Open_triggered(); - void on_action_OpenDirectory_triggered(); - void on_action_Quit_triggered(); - void on_action_Clone_triggered(); - -private: - void closeEvent(QCloseEvent *event); - Surface* surface; -}; - - -#endif // _MAINWINDOW_H diff --git a/Surface_mesher/demo/Surface_mesher/polyhedral_surface.cpp b/Surface_mesher/demo/Surface_mesher/polyhedral_surface.cpp deleted file mode 100644 index 2ac24c2b2c4..00000000000 --- a/Surface_mesher/demo/Surface_mesher/polyhedral_surface.cpp +++ /dev/null @@ -1,407 +0,0 @@ -#include "polyhedral_surface.h" -#include "get_polyhedral_surface.h" - -#include -#include -#include -#include -#include -#include -#include "ui_optionsdialog.h" -#include -#include -#include -#include -#include "mainwindow.h" - -typedef CGAL_polyhedral_surface::Polyhedron Polyhedron; - -Polyhedral_surface::Polyhedral_surface(QObject* parent, - double sharp_edges_angle_lower_bound, - double sharp_edges_angle_upper_bound) - : Surface(parent), - m_inverse_normals(false), - surface_ptr(0), - parent(parent), - display_octree(false), - display_edges_octree(false), - display_surface(true), - display_all_edges(true), - display_control_edges(false), - sharp_edges_angle_lower_bound(sharp_edges_angle_lower_bound), - sharp_edges_angle_upper_bound(sharp_edges_angle_upper_bound), - is_octree_initialized(false), - selected_edge(-1), - selected_facet(-1), - is_dirty(true), - list_id(0) -{ - connection_map["actionDisplay_octree"] = - std::make_pair(SIGNAL(toggled(bool)), - SLOT(toggle_display_octree(bool))); - - connection_map["actionDisplay_edges_octree"] = - std::make_pair(SIGNAL(toggled(bool)), - SLOT(toggle_display_edges_octree(bool))); - - connection_map["actionDisplay_surface"] = - std::make_pair(SIGNAL(toggled(bool)), - SLOT(toggle_display_surface(bool))); - - connection_map["actionDisplay_all_edges"] = - std::make_pair(SIGNAL(toggled(bool)), - SLOT(toggle_display_all_edges(bool))); - - connection_map["actionDisplay_control_edges"] = - std::make_pair(SIGNAL(toggled(bool)), - SLOT(toggle_display_control_edges(bool))); - - connection_map["actionInverse_normals"] = - std::make_pair(SIGNAL(toggled(bool)), - SLOT(set_inverse_normals(bool))); - - connection_map["actionSubdivision"] = - std::make_pair(SIGNAL(triggered()), - SLOT(make_one_subdivision_step())); - connection_map["action_Options"] = - std::make_pair(SIGNAL(triggered()), - SLOT(on_action_Options_triggered())); -} - -Polyhedral_surface::~Polyhedral_surface() -{ - clear(); - delete surface_ptr; -} - -void Polyhedral_surface::on_action_Options_triggered() -{ - QDialog *options_dialog = new QDialog(qobject_cast(parent)); - Ui::OptionDialog ui; - ui.setupUi(options_dialog); - - QDoubleSpinBox* sb_upper = options_dialog->findChild("angle_upper_bound"); - QDoubleSpinBox* sb_lower = options_dialog->findChild("angle_lower_bound"); - - if(!sb_lower || !sb_upper) - return; - - sb_lower->setValue(sharp_edges_angle_lower_bound); - sb_upper->setValue(sharp_edges_angle_upper_bound); - if(options_dialog->exec() == QDialog::Accepted) - { - sharp_edges_angle_upper_bound = sb_upper->value(); - sharp_edges_angle_lower_bound = sb_lower->value(); - set_sharp_edges_angle_bounds(sharp_edges_angle_lower_bound, - sharp_edges_angle_upper_bound); - } -} - -void Polyhedral_surface::clear() { - for(Connection_map::const_iterator - it = connection_map.begin(), - end = connection_map.end(); - it != end; - ++it) - { - QAction* action = parent->findChild(it->first); - action->setVisible(false); - } -} - -void Polyhedral_surface::connect_actions() -{ - for(Connection_map::const_iterator - it = connection_map.begin(), - end = connection_map.end(); - it != end; - ++it) - { - QAction* action = parent->findChild(it->first); - action->setVisible(true); - if(action) - connect(action, it->second.first, - this, it->second.second); - } - MainWindow* mw = qobject_cast(parent); - if(mw) { -// mw->fix_menus_visibility(); - mw->show_only("polyhedral"); - } - - - connect(this, SIGNAL(changed()), this, SLOT(display_nb_elements_in_status_bar())); -} - -void Polyhedral_surface::display_nb_elements_in_status_bar() const -{ - QMainWindow* mw = qobject_cast(parent); - if(surface_ptr && mw) - { - mw->statusBar()->showMessage(QString("%1 vertices. %2 edges. %3 facets.") - .arg(surface_ptr->size_of_vertices()) - .arg(surface_ptr->size_of_halfedges()/2) - .arg(surface_ptr->size_of_facets())); - } -} - -void Polyhedral_surface::set_dirty() -{ - is_dirty = true; - Q_EMIT changed(); -} - -void Polyhedral_surface::busy() const -{ - QMainWindow* mw = qobject_cast(parent); - if(mw) - { - mw->statusBar()->showMessage(QString("Constructing octree...")); - } - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); -} - -void Polyhedral_surface::not_busy() const -{ - QApplication::restoreOverrideCursor(); - QMainWindow* mw = qobject_cast(parent); - if(mw) - { - mw->statusBar()->clearMessage(); - } -} - -void Polyhedral_surface::set_sharp_edges_angle_bounds(const double lower_bound, - const double upper_bound) -{ - sharp_edges_angle_lower_bound = lower_bound; - sharp_edges_angle_upper_bound = upper_bound; - if(surface_ptr) { - surface_ptr->set_sharp_edges_angle_bounds(lower_bound, upper_bound); - surface_ptr->set_sharp_vertices_angle_bounds(lower_bound, upper_bound); - update_data_structures(); - Q_EMIT set_dirty(); - } -} - -void Polyhedral_surface::update_data_structures() -{ - surface_ptr->compute_sharp_edges_incidence_graph(); - if(display_octree || display_edges_octree) { - construct_octree(); - is_octree_initialized = true; - } - else - is_octree_initialized = false; -} - -void Polyhedral_surface::construct_octree() -{ - busy(); - surface_ptr->construct_octree(); - not_busy(); -} - -void Polyhedral_surface::toggle_display_octree(bool b) -{ - if(surface_ptr && b && !is_octree_initialized) { - is_octree_initialized = true; - construct_octree(); - } - display_octree = b; - Q_EMIT set_dirty(); -} - -void Polyhedral_surface::toggle_display_edges_octree(bool b) -{ - if(surface_ptr && b && !is_octree_initialized) { - is_octree_initialized = true; - construct_octree(); - } - display_edges_octree = b; - Q_EMIT set_dirty(); -} - -void Polyhedral_surface::toggle_display_surface(bool b) -{ - display_surface = b; - Q_EMIT set_dirty(); -} - -void Polyhedral_surface::toggle_display_all_edges(bool b) -{ - display_all_edges = b; - Q_EMIT set_dirty(); -} - -void Polyhedral_surface::toggle_display_control_edges(bool b) -{ - display_control_edges = b; - Q_EMIT set_dirty(); -} - -void Polyhedral_surface::make_one_subdivision_step() -{ - if(surface_ptr) - { - Polyhedron output; - CSubdivider_loop pw_loop_subdiviser; - - pw_loop_subdiviser.subdivide(*surface_ptr, output); - static_cast(*surface_ptr) = output; - surface_ptr->compute_normals(); - surface_ptr->compute_type(); - update_data_structures(); - Q_EMIT set_dirty(); - } -} - -bool Polyhedral_surface::open(const QString& filename) -{ - clear(); - - std::cerr << "Opening file \"" << qPrintable(filename) << "\"..."; - std::ifstream in(filename.toUtf8()); - if(!in) return false; - - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - - if(surface_ptr) - delete surface_ptr; - surface_ptr = new CGAL_polyhedral_surface(in, - sharp_edges_angle_lower_bound, - sharp_edges_angle_upper_bound, - false /*do not construct - octree*/); - if(!in) { - QApplication::restoreOverrideCursor(); - return false; - } - is_octree_initialized = false; - selected_facet = selected_edge = -1; - update_data_structures(); - - connect_actions(); - std::cerr << " Done.\n"; - QApplication::restoreOverrideCursor(); - float xmin, ymin, zmin, xmax, ymax, zmax; - get_bbox(xmin, ymin, zmin, xmax, ymax, zmax); - const float xcenter = (xmin + xmax) / 2; - const float ycenter = (ymin + ymax) / 2; - const float zcenter = (zmin + zmax) / 2; - const float xdelta = (-xmin + xmax); - const float ydelta = (-ymin + ymax); - const float zdelta = (-zmin + zmax); -// const float radius = std::max(std::max(xdelta, ydelta), zdelta) * std::sqrt(3.)/ 2.; - std::cerr << boost::format("Bounding box: xmin=%1%, ymin=%2%, zmin=%3%\n" - " xmax=%4%, ymax=%5%, zmax=%6%\n" - " center=(%7%, %8%, %9%)\n") - % xmin % ymin % zmin % xmax % ymax % zmax - % xcenter % ycenter % zcenter - << boost::format(" span=(%1%,%2%,%3%)\n") - % xdelta % ydelta % zdelta; - viewer->camera()->setSceneBoundingBox(CGAL::qglviewer::Vec(xmin, ymin, zmin), - CGAL::qglviewer::Vec(xmax, ymax, zmax)); - viewer->setBackgroundColor(Qt::white); - viewer->showEntireScene(); - - QAction* actionInverse_normals = qFindChild(this, "actionInverse_normals"); - if(actionInverse_normals) actionInverse_normals->setChecked(false); - Q_EMIT set_dirty(); - return true; -} - -void Polyhedral_surface::close() -{ - delete surface_ptr; - surface_ptr = 0; -} - -void Polyhedral_surface::draw() { - draw(false); -} - -void Polyhedral_surface::drawWithNames() { - draw(true); -} - -void Polyhedral_surface::postSelection(const QPoint&) -{ - if(!surface_ptr) return; - - selected_facet = selected_edge = -1; - - const int nb_vertices = surface_ptr->incidence_graph.vertices.size(); - const int nb_edges = surface_ptr->incidence_graph.edges.size(); - if(viewer->selectedName() >= nb_edges + nb_vertices) - selected_facet = viewer->selectedName() - nb_edges - nb_vertices; - else if(viewer->selectedName() >= nb_vertices) - selected_edge = viewer->selectedName() - nb_vertices; - - std::cerr << boost::format("post-selection.\n" - "selectedName()=%1%\n" - "selected edge=%2%\n" - "selected facet=%3%\n") - % viewer->selectedName() % selected_edge % selected_facet; - - Q_EMIT set_dirty(); -} - -void Polyhedral_surface::draw(bool with_names) -{ - if(!list_id) - { - std::cerr << "Generating OpenGL display list ID: "; - std::cerr << (list_id = ::glGenLists(1)) << "\n"; - } - if(!with_names) - { - if(is_dirty) - ::glNewList(list_id, GL_COMPILE_AND_EXECUTE); - else if(::glIsList(list_id)) - { - ::glCallList(list_id); - return; - } - else - std::cerr << "Call list (" << list_id << ")failed.\n"; - } -} -void Polyhedral_surface::get_bbox(float& xmin, float& ymin, float& zmin, - float& xmax, float& ymax, float& zmax) -{ - if(surface_ptr) { - xmin=surface_ptr->bbox().xmin(); - ymin=surface_ptr->bbox().ymin(); - ymin=surface_ptr->bbox().zmin(); - xmax=surface_ptr->bbox().xmax(); - ymax=surface_ptr->bbox().ymax(); - zmax=surface_ptr->bbox().zmax(); - } - else - { - xmin = ymin = zmin = 0.f; - xmax = ymax = zmax = 1.f; - } -} - -void Polyhedral_surface::set_inverse_normals(const bool b) { - m_inverse_normals = b; - set_dirty(); -} - -bool Polyhedral_surface::inverse_normals() const { - return m_inverse_normals; -} - - -Surface* get_polyhedral_surface(QObject* parent, - double sharp_edges_angle_lower_bound, - double sharp_edges_angle_upper_bound = 180.) -{ - return new Polyhedral_surface(parent, - sharp_edges_angle_lower_bound, - sharp_edges_angle_upper_bound); -} - -#include "polyhedral_surface.moc" diff --git a/Surface_mesher/demo/Surface_mesher/polyhedral_surface.h b/Surface_mesher/demo/Surface_mesher/polyhedral_surface.h deleted file mode 100644 index 001eaee5fd6..00000000000 --- a/Surface_mesher/demo/Surface_mesher/polyhedral_surface.h +++ /dev/null @@ -1,102 +0,0 @@ -#ifndef _POLYHEDRAL_SURFACE_H -#define _POLYHEDRAL_SURFACE_H - -#define CGAL_SURFACE_MESHER_DEBUG_POLYHEDRAL_SURFACE_CONSTRUCTION - -#include "surface.h" -#include "viewer.h" - -#include -#include - -typedef std::pair Signal_slot_pair; -typedef std::map Connection_map; - -// CGAL -#include - -// kernel -#include - -// surface -#include - -// piece-wise loop subdivision -#include - -typedef CGAL::Exact_predicates_inexact_constructions_kernel Poly_kernel; -typedef Poly_kernel::FT FT; -typedef Poly_kernel::Point_3 Poly_point; -typedef Poly_kernel::Sphere_3 Sphere; -typedef Poly_kernel::Vector_3 Vector; -typedef Poly_kernel::Triangle_3 Triangle_3; - -typedef CGAL::Polyhedral_surface_3 CGAL_polyhedral_surface; - - -class Polyhedral_surface : public Surface -{ - Q_OBJECT; - -public: - Polyhedral_surface(QObject* parent, - double sharp_edges_angle_lower_bound = 90, - double sharp_edges_angle_upper_bound = 120); - - ~Polyhedral_surface(); -public Q_SLOTS: - void clear(); - void connect_actions(); - void display_nb_elements_in_status_bar() const; - void set_dirty(); - void busy() const; - void not_busy() const; - void set_sharp_edges_angle_bounds(const double lower_bound, - const double upper_bound); - void update_data_structures(); - void construct_octree(); - void toggle_display_octree(bool b); - void toggle_display_edges_octree(bool b); - void toggle_display_surface(bool b); - void toggle_display_all_edges(bool b); - void toggle_display_control_edges(bool b); - void make_one_subdivision_step(); - void on_action_Options_triggered(); - -public: - bool open(const QString& filename); - void close(); - void draw(); - void drawWithNames(); - void postSelection(const QPoint&); - void draw(bool with_names); - void get_bbox(float& xmin, float& ymin, float& zmin, - float& xmax, float& ymax, float& zmax); - -public Q_SLOTS: - void set_inverse_normals(const bool b); - -public: - bool inverse_normals() const; - -protected: - bool m_inverse_normals; - CGAL_polyhedral_surface* surface_ptr; - QObject* parent; - bool display_octree; - bool display_edges_octree; - bool display_surface; - bool display_all_edges; - bool display_control_edges; - double sharp_edges_angle_lower_bound; - double sharp_edges_angle_upper_bound; - bool is_octree_initialized; - int selected_edge; - int selected_facet; - bool is_dirty; - GLint list_id; - Connection_map connection_map; -}; - -#endif // _POLYHEDRAL_SURFACE_H diff --git a/Surface_mesher/demo/Surface_mesher/surface.h b/Surface_mesher/demo/Surface_mesher/surface.h deleted file mode 100644 index 62e4b597a24..00000000000 --- a/Surface_mesher/demo/Surface_mesher/surface.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef _SURFACE_H -#define _SURFACE_H - -#include -#include -#include - -#include "viewer.h" - -class Surface : public QObject -{ - Q_OBJECT -protected: - Surface(QObject* parent) - { - viewer = parent->findChild("viewer"); - - if(viewer) - connect(this, SIGNAL(changed()), viewer, SLOT(updateGL())); - viewer->set_surface(this); - } -public Q_SLOTS: - virtual bool open(const QString& filename) = 0; - virtual void close() = 0; - virtual void draw() = 0; - virtual void get_bbox(float&, float&, float&, - float&, float&, float&) = 0; - virtual void drawWithNames() {}; - virtual void postSelection(const QPoint&) {}; -Q_SIGNALS: - void changed(); - -protected: - Viewer* viewer; -}; - -#endif // _SURFACE_H diff --git a/Surface_mesher/demo/Surface_mesher/surface_mesher.qrc b/Surface_mesher/demo/Surface_mesher/surface_mesher.qrc deleted file mode 100644 index 9592cad50a0..00000000000 --- a/Surface_mesher/demo/Surface_mesher/surface_mesher.qrc +++ /dev/null @@ -1,13 +0,0 @@ - - - icons/bbox-red.png - icons/bbox.png - icons/cgal_logo.xpm - icons/fileopen.png - icons/filesave.png - icons/flip.png - icons/resize.png - icons/surface.png - icons/twosides.png - - diff --git a/Surface_mesher/demo/Surface_mesher/ui/mainwindow.ui b/Surface_mesher/demo/Surface_mesher/ui/mainwindow.ui deleted file mode 100644 index 65b8a528fa8..00000000000 --- a/Surface_mesher/demo/Surface_mesher/ui/mainwindow.ui +++ /dev/null @@ -1,808 +0,0 @@ - - - MainWindow - - - - 0 - 0 - 1147 - 648 - - - - CGAL Surface mesh generator - - - - :/icons/cgal_logo.xpm:/icons/cgal_logo.xpm - - - true - - - - - - - - 1 - 0 - - - - - - - - - - 0 - 0 - 1147 - 21 - - - - - &File - - - - - - - - - - - &Options - - - - volume - polyhedral - - - - - - - - - - - - - - - - - - - &Edit - - - - polyhedral - - - - - - - - - - - - Actions toolbar - - - Qt::AllToolBarAreas - - - TopToolBarArea - - - false - - - - - - - - - - - - - - - - true - - - Meshing toolbar - - - - volume - - - - TopToolBarArea - - - false - - - - - - - Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea - - - Images options - - - - volume - - - - 1 - - - - - - - - - - 0 - 0 - - - - &Image type - - - - volume - - - - - - - - 0 - 0 - - - - Grayscale image - - - true - - - - - - - - 0 - 0 - - - - Segmented image - - - - - - - - - - &Operations - - - - - - Trilinear interpolation - - - true - - - - - - - Search for seeds - - - true - - - - - - - - - - - 0 - 0 - - - - C&riteria - - - - volume - - - - - - - Manifold - - - - - - - Facets vertices have same index - - - - - - - - - &Sizing bound: - - - spinBox_radius_bound - - - - - - - 5 - - - 9999.989999999999782 - - - - - - - &Distance bound: - - - spinBox_distance_bound - - - - - - - 5 - - - 9999.989999999999782 - - - - - - - - - - - - - - Qt::Vertical - - - QSizePolicy::Expanding - - - - 20 - 0 - - - - - - - - - - - 0 - 0 - - - - Image sub-domaines - - - - volume - - - - 1 - - - - - 10 - 10 - - - - - - - - 0 - 5 - - - - - volume - - - - - - - - - - - :/icons/fileopen.png:/icons/fileopen.png - - - &Open... - - - Ctrl+O - - - - - &Quit - - - Ctrl+Q - - - QAction::QuitRole - - - - - true - - - - :/icons/flip.png:/icons/flip.png - - - &Inverse normals - - - Flip - - - Ctrl+I - - - - volume - polyhedral - - - - - - true - - - - :/icons/bbox.png:/icons/bbox.png - - - Display oc&tree - - - Ctrl+T - - - - polyhedral - - - - - - true - - - true - - - - :/icons/surface.png:/icons/surface.png - - - Display &surface - - - - polyhedral - - - - - - &Options... - - - - polyhedral - - - - - - Piecewise-smooth &subdivision - - - Ctrl+S - - - - polyhedral - - - - - - true - - - true - - - Display &all edges - - - Ctrl+A - - - - polyhedral - - - - - - true - - - false - - - Display &control edges - - - Ctrl+C - - - - polyhedral - - - - - - true - - - - :/icons/bbox-red.png:/icons/bbox-red.png - - - Display edges octree - - - - polyhedral - - - - - - Marching &cubes - - - Marching &cubes - - - - volume - - - - - - Surface &mesher - - - Surface &mesher - - - - volume - - - - - - true - - - true - - - - :/icons/twosides.png:/icons/twosides.png - - - Display facets with &front and back - - - Two-sides - - - Ctrl+F - - - - volume - polyhedral - - - - - - Clone - - - - - true - - - false - - - - :/icons/resize.png:/icons/resize.png - - - Auto-&resize - - - Auto-&resize - - - Automaticaly zoom in or out when the object change. - - - Ctrl+S - - - - volume - polyhedral - - - - - - true - - - true - - - Draw triangles &edges - - - Draw triangles &edges - - - Ctrl+E - - - - volume - - - - - - true - - - false - - - Use &Gouraud shading (marching cube only) - - - Use &Gouraud shading - - - Use Gouraud shading to display the marching cubes. - - - Ctrl+G - - - - volume - - - - - - true - - - Show the whole &triangulation (surface mesher only) - - - Ctrl+T - - - - volume - - - - - - Choose the triangulation edges &color... - - - - volume - - - - - - - :/icons/filesave.png:/icons/filesave.png - - - Export surface mesh to OFF... - - - - volume - - - - - - true - - - true - - - - :/icons/bbox.png:/icons/bbox.png - - - Show the image &bounding box - - - Ctrl+B - - - - volume - - - - - - - :/icons/filesave.png:/icons/filesave.png - - - Save the image as Inrimage... - - - - - - :/icons/fileopen.png:/icons/fileopen.png - - - Open directory... - - - - - - Values_list - QWidget -
    values_list.h
    - 1 -
    - - Viewer - QWidget -
    viewer.h
    -
    -
    - - viewer - grayLevelRadioButton - labellizedRadioButton - manifoldCheckBox - sameIndexCheckBox - spinBox_radius_bound - spinBox_distance_bound - - - - - - - labellizedRadioButton - toggled(bool) - sameIndexCheckBox - setDisabled(bool) - - - 130 - 172 - - - 139 - 414 - - - - -
    diff --git a/Surface_mesher/demo/Surface_mesher/ui/optionsdialog.ui b/Surface_mesher/demo/Surface_mesher/ui/optionsdialog.ui deleted file mode 100644 index 2ea13d120e1..00000000000 --- a/Surface_mesher/demo/Surface_mesher/ui/optionsdialog.ui +++ /dev/null @@ -1,128 +0,0 @@ - - OptionDialog - - - - 0 - 0 - 210 - 167 - - - - Set options - - - :/icons/cgal_logo.xpm - - - - - - Sharp edges angle bounds - - - - - - - - &Lower bound - - - angle_lower_bound - - - - - - - 180.000000000000000 - - - - - - - &Upper bound - - - angle_upper_bound - - - - - - - 180.000000000000000 - - - - - - - - - - - - Qt::Vertical - - - - 20 - 0 - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok - - - - - - - - - - - buttonBox - accepted() - OptionDialog - accept() - - - 227 - 215 - - - 157 - 90 - - - - - buttonBox - rejected() - OptionDialog - reject() - - - 243 - 221 - - - 252 - 90 - - - - - diff --git a/Surface_mesher/demo/Surface_mesher/ui/raw_image.ui b/Surface_mesher/demo/Surface_mesher/ui/raw_image.ui deleted file mode 100644 index e270d1de917..00000000000 --- a/Surface_mesher/demo/Surface_mesher/ui/raw_image.ui +++ /dev/null @@ -1,454 +0,0 @@ - - Raw_image_dialog - - - - 0 - 0 - 585 - 342 - - - - Open raw image - - - - - - Image &value type - - - - - - Short (16 bits) - - - - - - - Float - - - - - - - Int (32 bits) - - - - - - - Double - - - - - - - Signed - - - - - - - char (8 bits) - - - - - - - - - - Image dimensions - - - - - - - - &Dimensions: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - dim_x - - - - - - - &Spacing: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - spacing_x - - - - - - - x: - - - 100000000 - - - - - - - y: - - - 100000000 - - - - - - - z: - - - 100000000 - - - - - - - vx: - - - 5 - - - 1.000000000000000 - - - - - - - vy: - - - 5 - - - 1.000000000000000 - - - - - - - vz: - - - 5 - - - 1.000000000000000 - - - - - - - &Offset: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - offset - - - - - - - bytes - - - 999999999 - - - - - - - Image size: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - 0 - - - - - - - File size: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - 0 - - - - - - - - - - - - QDialogButtonBox::Cancel|QDialogButtonBox::Open - - - - - - - int_bt - short_bt - signed_bt - float_bt - double_bt - dim_x - dim_y - dim_z - spacing_x - spacing_y - spacing_z - offset - buttonBox - - - - - float_bt - toggled(bool) - signed_bt - setDisabled(bool) - - - 47 - 112 - - - 553 - 94 - - - - - double_bt - toggled(bool) - signed_bt - setDisabled(bool) - - - 564 - 127 - - - 564 - 94 - - - - - buttonBox - accepted() - Raw_image_dialog - accept() - - - 191 - 316 - - - 183 - 313 - - - - - buttonBox - rejected() - Raw_image_dialog - reject() - - - 253 - 319 - - - 252 - 312 - - - - - dim_x - valueChanged(int) - Raw_image_dialog - update_image_size() - - - 178 - 187 - - - 99 - 141 - - - - - dim_z - valueChanged(int) - Raw_image_dialog - update_image_size() - - - 473 - 178 - - - 441 - 142 - - - - - char_bt - clicked() - Raw_image_dialog - update_image_size() - - - 71 - 52 - - - 137 - 3 - - - - - short_bt - clicked() - Raw_image_dialog - update_image_size() - - - 117 - 81 - - - 49 - 6 - - - - - float_bt - clicked() - Raw_image_dialog - update_image_size() - - - 137 - 111 - - - 67 - -5 - - - - - int_bt - clicked() - Raw_image_dialog - update_image_size() - - - 358 - 49 - - - 584 - 52 - - - - - dim_y - valueChanged(int) - Raw_image_dialog - update_image_size() - - - 332 - 186 - - - 271 - 142 - - - - - double_bt - clicked() - Raw_image_dialog - update_image_size() - - - 514 - 119 - - - 581 - 116 - - - - - - update_image_size() - - diff --git a/Surface_mesher/demo/Surface_mesher/ui/values_list.ui b/Surface_mesher/demo/Surface_mesher/ui/values_list.ui deleted file mode 100644 index 9e7e4372813..00000000000 --- a/Surface_mesher/demo/Surface_mesher/ui/values_list.ui +++ /dev/null @@ -1,118 +0,0 @@ - - Values_list - - - - 0 - 0 - 429 - 632 - - - - Form - - - - - - QFrame::StyledPanel - - - 1 - - - QAbstractItemView::AnyKeyPressed|QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed|QAbstractItemView::NoEditTriggers|QAbstractItemView::SelectedClicked - - - true - - - QAbstractItemView::ExtendedSelection - - - 0 - - - false - - - true - - - false - - - true - - - false - - - 3 - - - - Iso-value - - - - - Color - - - - - Name - - - - - - - - - - ... - - - :/values/plus.png - - - - - - - ... - - - :/values/minus.png - - - Del - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - diff --git a/Surface_mesher/demo/Surface_mesher/values_list.cpp b/Surface_mesher/demo/Surface_mesher/values_list.cpp deleted file mode 100644 index b2e8a41e86f..00000000000 --- a/Surface_mesher/demo/Surface_mesher/values_list.cpp +++ /dev/null @@ -1,280 +0,0 @@ -#include "values_list.h" -#include "ui_values_list.h" -#include "colorlisteditor.h" -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0) -#include -#endif - -Values_delegate::Values_delegate(QWidget* parent) : QItemDelegate(parent) {} -void Values_delegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const -{ - switch(index.column()) - { - case Values_list::Color: { - painter->fillRect(option.rect, index.data().value()); - drawFocus(painter, option, option.rect); - break; - } - default: - QItemDelegate::paint(painter, option, index); - } -} - -QWidget *Values_delegate::createEditor(QWidget *parent, - const QStyleOptionViewItem & option, - const QModelIndex & index) const -{ - if(index.column() == Values_list::Color) - { - return new ColorListEditor(parent); - } - else if(index.column() == Values_list::Value) - { - QLineEdit* lineedit = new QLineEdit(parent); - lineedit->setAutoFillBackground(true); - lineedit->setValidator(new QDoubleValidator(lineedit)); - return lineedit; - } - else return QItemDelegate::createEditor(parent, option, index); -} - -void Values_delegate::setEditorData(QWidget *editor, - const QModelIndex &index) const -{ - if(index.column() == Values_list::Color) - { - ColorListEditor* coloreditor = qobject_cast(editor); - if(coloreditor) - coloreditor->setColor(index.data().value()); - } - else if(index.column() == Values_list::Value) - { - QLineEdit* lineedit = qobject_cast(editor); - if(lineedit) - lineedit->setText(index.data().toString()); - } - else QItemDelegate::setEditorData(editor, index); -} -void Values_delegate::setModelData(QWidget *editor, QAbstractItemModel *model, - const QModelIndex &index) const -{ - if(index.column() == Values_list::Color) - { - ColorListEditor* coloreditor = qobject_cast(editor); - if(coloreditor) - { - model->setData(index, coloreditor->color()); - Q_EMIT new_color(index); - } - } - else if(index.column() == Values_list::Value) - { - QLineEdit* lineedit = qobject_cast(editor); - if(lineedit) - { - model->setData(index, lineedit->text().toDouble()); - Q_EMIT new_value(index); - } - } - else QItemDelegate::setModelData(editor, model, index); -} - -const double Values_list::default_value = 0.0; - -Values_list::Values_list(QWidget* parent): - QWidget(parent) -{ - Ui::Values_list().setupUi(this); - - treeWidget = parent->findChild("treeWidget"); - Q_ASSERT_X(treeWidget, "Values_list constructor", "cannot find widget \"treeWidget\""); - - treeWidget->sortByColumn(Value, Qt::AscendingOrder); - - treeWidget->header()->setSectionsClickable(false); - - - Values_delegate* values_delegate = new Values_delegate(parent); - - treeWidget->setItemDelegate(values_delegate); - connect(values_delegate, SIGNAL(new_value(const QModelIndex&)), - this, SIGNAL(values_changed())); - connect(values_delegate, SIGNAL(new_color(const QModelIndex&)), - this, SIGNAL(colors_changed())); - connect(this->treeWidget->model(), - SIGNAL(dataChanged (const QModelIndex &, const QModelIndex &)), - this, SIGNAL(changed())); - - connect(this, SIGNAL(changed()), - this, SLOT(update_items_cache())); -} - -QColor Values_list::color(const int i) const -{ - if(i < 0 || i > treeWidget->topLevelItemCount()) - return QColor(); - else - return treeWidget->topLevelItem(i)->data(Color, Qt::DisplayRole).value(); -} - -QColor Values_list::color(const QTreeWidgetItem* item) const -{ - return item->data(Color, Qt::DisplayRole).value(); -} - -int Values_list::numberOfValues() const -{ - return treeWidget->topLevelItemCount(); -} - -double Values_list::value(const int i) const -{ - if(i < 0 || i > numberOfValues()) - return 0.; - else - return treeWidget->topLevelItem(i)->data(Value, Qt::DisplayRole).toDouble(); -} - -QString Values_list::name(const int i) const -{ - if(i < 0 || i > treeWidget->topLevelItemCount()) - return QString(); - else - return treeWidget->topLevelItem(i)->data(Name, Qt::DisplayRole).toString(); -} - -bool Values_list::enabled(const int i) const -{ - if(i < 0 || i > treeWidget->topLevelItemCount()) - return false; - else - return treeWidget->topLevelItem(i)->data(Value, Qt::CheckStateRole).toInt() > 0; -} - -bool Values_list::enabled(const QTreeWidgetItem* item) const -{ - return item->data(Value, Qt::CheckStateRole).toInt() > 0; -} - -const QTreeWidgetItem* Values_list::item(const int i) const -{ - if(i < 0 || i > treeWidget->topLevelItemCount()) - return 0; - else - return treeWidget->topLevelItem(i); -} - -void Values_list::save_values(QString filename) const -{ - QSettings settings; - - settings.beginGroup(QUrl::toPercentEncoding(filename)); - settings.beginWriteArray("values"); - for (int i = 0; i < numberOfValues(); ++i) { - settings.setArrayIndex(i); - settings.setValue("value", value(i)); - settings.setValue("color", color(i)); - settings.setValue("name", name(i)); - settings.setValue("enabled", enabled(i)); - } - settings.endArray(); - settings.endGroup(); -} - -void Values_list::load_values(QString filename) -{ - QSettings settings; - - treeWidget->clear(); - settings.beginGroup(QUrl::toPercentEncoding(filename)); - int nb = settings.beginReadArray("values"); - for (int i = 0; i < nb; ++i) { - settings.setArrayIndex(i); - QTreeWidgetItem *newItem = new QTreeWidgetItem(treeWidget); - newItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable); - newItem->setData(Value, Qt::CheckStateRole, settings.value("enabled").toBool() ? Qt::Checked : Qt::Unchecked); - newItem->setData(Value, Qt::DisplayRole, settings.value("value").toDouble()); - newItem->setData(Color, Qt::DisplayRole, settings.value("color").value()); - newItem->setData(Name, Qt::DisplayRole, settings.value("name").toString()); - } - settings.endArray(); - settings.endGroup(); - update_items_cache(); -} - -void Values_list::on_minusButton_clicked() -{ - Q_FOREACH(QTreeWidgetItem* item, treeWidget->selectedItems()) - { - // treeWidget->invisibleRootItem()->removeChild(item); - delete item; - } - Q_EMIT values_changed(); -} - -void Values_list::on_plusButton_clicked() -{ - addValue(); -} - -void Values_list::addValue(const double i) -{ - QTreeWidgetItem *newItem = new QTreeWidgetItem(treeWidget); - newItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable); - newItem->setData(Value, Qt::CheckStateRole, Qt::Checked); - newItem->setData(Value, Qt::DisplayRole, i); - QStringList colors = QColor::colorNames(); -#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0) - const int color_index = qrand() % colors.size(); -#else -const int color_index = QRandomGenerator::global()->generate() % colors.size(); -#endif - - QColor color = QColor(colors[color_index]); - newItem->setData(Color, Qt::DisplayRole, color); - newItem->setData(Name, Qt::DisplayRole, ""); - Q_EMIT values_changed(); -} - -void Values_list::update_items_cache() { - items_cache.clear(); - for(int i = 0, nb = numberOfValues(); i < nb; ++i) { - items_cache.insert(std::make_pair(value(i), item(i))); - } -} - -const QTreeWidgetItem* Values_list::search(const double value) const -{ - Items_cache::const_iterator it = items_cache.find(value); - if(it != items_cache.end()) { - return it->second; - } - else { - return 0; - } -} - -void Values_list::setHeaderTitle(QString title) -{ - treeWidget->headerItem()->setText(0, title); -} - diff --git a/Surface_mesher/demo/Surface_mesher/values_list.h b/Surface_mesher/demo/Surface_mesher/values_list.h deleted file mode 100644 index 03649fea0f0..00000000000 --- a/Surface_mesher/demo/Surface_mesher/values_list.h +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef _VALUES_LIST_H -#define _VALUES_LIST_H - -#include -#include -#include -#include -#include - -class QTreeWidget; -class QTreeWidgetItem; - -class Values_delegate : public QItemDelegate -{ - Q_OBJECT -public: - Values_delegate(QWidget* parent); - -Q_SIGNALS: - void new_color(const QModelIndex&) const; - void new_value(const QModelIndex&) const; - -protected: - void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const; - QWidget *createEditor(QWidget *parent, - const QStyleOptionViewItem & option, - const QModelIndex & index) const; - void setEditorData(QWidget *editor, - const QModelIndex &index) const; - void setModelData(QWidget *editor, QAbstractItemModel *model, - const QModelIndex &index) const; -}; - -class Values_list : public QWidget -{ - Q_OBJECT -public: - enum Field { Value = 0 , Color = 1, Name = 2}; - Values_list(QWidget* parent); - - // const accessors - int numberOfValues() const; - QColor color(const int i) const; - QColor color(const QTreeWidgetItem* i) const; - double value(const int i) const; - QString name(const int i) const; - bool enabled(const int i) const; - bool enabled(const QTreeWidgetItem* i) const; - const QTreeWidgetItem* item(const int i) const; - const QTreeWidgetItem* search(const double value) const; - -public Q_SLOTS: - void save_values(QString) const; - void load_values(QString); - void on_plusButton_clicked(); - void on_minusButton_clicked(); - - // setters - void addValue(const double v = Values_list::default_value); - - void setHeaderTitle(QString); - -private Q_SLOTS: - void update_items_cache(); - -Q_SIGNALS: - void changed(); - void colors_changed(); - void values_changed(); -private: - QTreeWidget* treeWidget; - typedef std::map Items_cache; - Items_cache items_cache; - - static const double default_value; -}; - -#endif // _VALUES_LIST_H - diff --git a/Surface_mesher/demo/Surface_mesher/values_list.qrc b/Surface_mesher/demo/Surface_mesher/values_list.qrc deleted file mode 100644 index 8a78bb1688a..00000000000 --- a/Surface_mesher/demo/Surface_mesher/values_list.qrc +++ /dev/null @@ -1,6 +0,0 @@ - - - icons/minus.png - icons/plus.png - - diff --git a/Surface_mesher/demo/Surface_mesher/viewer.cpp b/Surface_mesher/demo/Surface_mesher/viewer.cpp deleted file mode 100644 index 0cde258c258..00000000000 --- a/Surface_mesher/demo/Surface_mesher/viewer.cpp +++ /dev/null @@ -1,66 +0,0 @@ -#include "viewer.h" -#include "surface.h" -#include -#include - -Viewer::Viewer(QWidget* parent) - : CGAL::QGLViewer(parent), surface(nullptr) -{ -} - -void Viewer::init() -{ - setBackgroundColor(Qt::white); - glLineStipple(5, 0xaaaa); - glDisable(GL_LINE_STIPPLE); - - // anti-aliasing - glEnable(GL_BLEND); - glEnable(GL_LINE_SMOOTH); - glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); -} - -QString Viewer::helpString() const -{ - return "" - "

    Surface mesher demo

    \n" - "

    No help availlable for now.

    "; -} - -void Viewer::interpolateToFitBoundingBox(double xmin, double ymin, double zmin, - double xmax, double ymax, double zmax) -{ - QAction* auto_resize = parent()->parent()->findChild("actionAuto_resize"); - Q_ASSERT_X(auto_resize, "Viewer::interpolateToFitBoundingBox", "cannot find action \"actionAuto_resize\""); - if(auto_resize && auto_resize->isChecked()) - { - CGAL::qglviewer::Camera new_camera = *(camera ()); - new_camera.fitBoundingBox(CGAL::qglviewer::Vec(xmin, ymin, zmin), - CGAL::qglviewer::Vec(xmax, ymax, zmax)); - camera()->interpolateTo(*new_camera.frame(), 1.); - } -} - -void Viewer::draw() -{ - if(surface) - surface->draw(); -} - -void Viewer::drawWithNames() -{ - if(surface) - surface->drawWithNames(); -} -void Viewer::postSelection(const QPoint& p) -{ - if(surface) - surface->postSelection(p); -} - -void Viewer::set_surface(Surface* s) -{ - surface = s; -} - diff --git a/Surface_mesher/demo/Surface_mesher/viewer.h b/Surface_mesher/demo/Surface_mesher/viewer.h deleted file mode 100644 index 8c40a6a6612..00000000000 --- a/Surface_mesher/demo/Surface_mesher/viewer.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef _VIEWER_H -#define _VIEWER_H - -#include -#include - -class Surface; - -class Viewer : public CGAL::QGLViewer -{ - Q_OBJECT -public: - Viewer(QWidget* parent); - - void set_surface(Surface*); - -public Q_SLOTS: - void interpolateToFitBoundingBox(double, double, double, double, double, double); - -protected : - virtual void init(); - virtual void draw(); - virtual void drawWithNames(); - virtual void postSelection(const QPoint&); - virtual QString helpString() const; - - Surface* surface; -}; - -#endif // _VIEWER_H diff --git a/Surface_mesher/demo/Surface_mesher/volume.cpp b/Surface_mesher/demo/Surface_mesher/volume.cpp deleted file mode 100644 index 3ccb01681c5..00000000000 --- a/Surface_mesher/demo/Surface_mesher/volume.cpp +++ /dev/null @@ -1,1616 +0,0 @@ -#ifdef __APPLE__ -#define GL_SILENCE_DEPRECATION -#endif -#include - -#include "volume.h" - -#include // std::sort -#include -#include - -#include - -#include "viewer.h" -#include "mainwindow.h" -#include "values_list.h" - -#include "File_XT.h" // format XT from Total/ELF - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "Raw_image_dialog.h" -#include -// #include -#include -#include -#include -#include -#include - -struct Threshold : public CGAL::cpp98::unary_function { - double isovalue; - bool is_identity; - - Threshold(double isovalue) : isovalue(isovalue), is_identity(false) {} - - result_type operator()(FT value) - { - if(is_identity) - return static_cast(value); - else if(value >= isovalue) - return 1; - else - return 0; - } -}; - -class Classify_from_isovalue_list : - public CGAL::cpp98::unary_function -{ - typedef std::pair Isovalue; - typedef std::vector Isovalues; - boost::shared_ptr isovalues; - bool is_identity; - - struct Sort_isovalues : CGAL::cpp98::binary_function - { - bool operator()(const Isovalue& isoval1, const Isovalue& isoval2) - { - return isoval1.first < isoval2.first; - } - }; -public: - Classify_from_isovalue_list(Values_list * list) - : is_identity(false) - { - isovalues = boost::shared_ptr(new Isovalues(list->numberOfValues())); - for(int i = 0, nbs = list->numberOfValues(); i < nbs; ++i ) - (*isovalues)[i] = std::make_pair(list->value(i), i); - std::sort(isovalues->begin(), isovalues->end(), Sort_isovalues()); - } - - void set_identity(bool b) { - is_identity = b; - } - - result_type operator()(FT value) - { - if(is_identity) { - return static_cast(value); - } - result_type result = 0; -// std::cerr << "isovalues: "; - for(result_type i = 1, end = static_cast(isovalues->size()); i <= end; ++i) - { -// std::cerr << (*isovalues)[i-1] << ", "; - if(value >= (*isovalues)[i-1].first && - i >= result) - { - result = i; - } - } -// if(result>1) -// std::cerr << "result = " << (int)result << "/" << list->numberOfValues() << std::endl; -// else -// std::cerr << std::endl; - if(result>0) - return (*isovalues)[result-1].second + 1; - else - return 0; - } -}; - -class Generate_surface_identifiers : - public CGAL::cpp98::binary_function -{ - Values_list* list; - bool labellized; - -public: - Generate_surface_identifiers(Values_list* list) - : list(list), labellized(false) {}; - - void set_labellized_image(bool b) - { - labellized = b; - } - - result_type operator()(const Classify_from_isovalue_list::result_type& a, - const Classify_from_isovalue_list::result_type& b) - { - if(labellized) - return list->search((std::max)(a, b)); - else - return list->item((std::min)(a, b)); - } -}; - -// class Classify_from_isovalue_list : -// public CGAL::cpp98::unary_function -// { -// typedef std::pair Isovalue; -// typedef std::vector Isovalues; -// boost::shared_ptr isovalues; - -// struct Sort_isovalues : CGAL::cpp98::binary_function -// { -// bool operator()(const Isovalue& isoval1, const Isovalue& isoval2) -// { -// return isoval1.first < isoval2.first; -// } -// }; -// public: -// Classify_from_isovalue_list(Isovalues_list * list) -// { -// isovalues = boost::shared_ptr(new Isovalues(list->numberOfIsoValues())); -// for(int i = 0, nbs = list->numberOfIsoValues(); i < nbs; ++i ) -// (*isovalues)[i] = std::make_pair(list->isovalue(i), list->item(i)); -// std::sort(isovalues->begin(), isovalues->end(), Sort_isovalues()); -// } - -// result_type operator()(FT value) -// { -// int result = 0; -// // std::cerr << "isovalues: "; -// for(int i = 1, end = isovalues->size(); i <= end; ++i) -// { -// // std::cerr << (*isovalues)[i-1] << ", "; -// if(value >= (*isovalues)[i-1].first && -// i >= result) -// { -// result = i; -// } -// } -// if(result>1) -// std::cerr << boost::format("result = %1%/%2%\n") % result % isovalues->size(); -// if(result>0) -// return (*isovalues)[result-1].second; -// else -// return 0; -// } -// }; -Volume::Volume(MainWindow* mw) : - Surface(mw), - m_sm_angle(30), - m_sm_radius(0), - m_sm_distance(0), - m_relative_precision(0.000000001), - m_view_surface(false), - m_triangulation_color(QColor(Qt::green)), - m_inverse_normals(false), - two_sides(false), - del(), - c2t3(del), - mw(mw), - lists_draw_surface(), - lists_draw_surface_is_valid(false), -#ifdef CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE - list_draw_marching_cube(0), - list_draw_marching_cube_is_valid(false), - lists_draw_surface_mc(), -#endif // CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE - m_view_mc(false) -{ - spinBox_radius_bound = mw->findChild("spinBox_radius_bound"); - spinBox_distance_bound = mw->findChild("spinBox_distance_bound"); - Q_ASSERT_X(spinBox_radius_bound && spinBox_distance_bound, - "Volume::Volume()", "Cannot find spinboxes!"); - - values_list = mw->values; - - connect(spinBox_radius_bound, SIGNAL(valueChanged(double)), - this, SLOT(set_radius_bound(double))); - connect(spinBox_distance_bound, SIGNAL(valueChanged(double)), - this, SLOT(set_distance_bound(double))); - - connect(mw->actionSurface_mesher, SIGNAL(triggered()), - this, SLOT(display_surface_mesher_result())); - - connect(mw->actionInverse_normals, SIGNAL(toggled(bool)), - this, SLOT(set_inverse_normals(bool))); - m_inverse_normals = mw->actionInverse_normals->isChecked(); - - connect(mw->actionDisplay_front_and_back, SIGNAL(toggled(bool)), - this, SLOT(set_two_sides(bool))); - two_sides = mw->actionDisplay_front_and_back->isChecked(); - - connect(mw->actionDraw_triangles_edges, SIGNAL(toggled(bool)), - this, SLOT(set_draw_triangles_edges(bool))); - draw_triangles_edges = mw->actionDraw_triangles_edges->isChecked(); - - connect(mw->actionUse_Gouraud_shading, SIGNAL(toggled(bool)), - this, SLOT(set_use_gouraud(bool))); - use_gouraud = mw->actionUse_Gouraud_shading->isChecked(); - - connect(mw->actionShow_the_image_bounding_box, SIGNAL(toggled(bool)), - this, SLOT(set_show_bbox(bool))); - show_bbox = mw->actionShow_the_image_bounding_box->isChecked(); - - connect(mw->actionShow_triangulation, SIGNAL(toggled(bool)), - this, SLOT(set_draw_triangulation(bool))); - m_draw_triangulation = mw->actionShow_triangulation->isChecked(); - - connect(mw->actionTriangulation_edges_color, SIGNAL(triggered()), - this, SLOT(set_triangulation_edges_color())); - - connect(this, SIGNAL(new_bounding_box(double, double, double, double, double, double)), - mw->viewer, SLOT(interpolateToFitBoundingBox(double, double, double, double, double, double))); - - connect(values_list, SIGNAL(values_changed()), - this, SLOT(changed_parameters())); - connect(values_list, SIGNAL(changed()), - mw->viewer, SLOT(updateGL())); - connect(this, SIGNAL(changed()), - this, SLOT(check_can_export_off())); - - connect(mw->labellizedRadioButton, SIGNAL(toggled(bool)), - this, SLOT(labellizedToogled(bool))); - - mw->actionExport_surface_mesh_to_OFF->setEnabled(false); - connect(mw->actionExport_surface_mesh_to_OFF, SIGNAL(triggered()), - this, SLOT(export_off())); - - connect(mw->actionSave, SIGNAL(triggered()), - this, SLOT(save_image_to_inr())); - -#ifdef CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE - connect(mw->actionMarching_cubes, SIGNAL(triggered()), - this, SLOT(display_marchin_cube())); -#endif -} - -void Volume::set_inverse_normals(const bool b) { - m_inverse_normals = b; - - list_draw_marching_cube = 0; // Invalidate the display list for the - // marching cube. See gl_draw_marchingcube() - // for an explanation. - - Q_EMIT changed(); -} - -void Volume::set_two_sides(const bool b) { - two_sides = b; - Q_EMIT changed(); -} - -void Volume::set_draw_triangles_edges(const bool b) { - draw_triangles_edges = b; - Q_EMIT changed(); -} - -void Volume::set_draw_triangulation(const bool b) { - m_draw_triangulation = b; - Q_EMIT changed(); -} - -void Volume::set_triangulation_edges_color() { - const QColor color = QColorDialog::getColor(m_triangulation_color, mw); - if (color.isValid()) { - m_triangulation_color = color; - Q_EMIT changed(); - } -} - -void Volume::set_use_gouraud(const bool b) { - use_gouraud = b; - Q_EMIT changed(); -} - -void Volume::set_show_bbox(const bool b) { - show_bbox = b; - Q_EMIT changed(); -} - -void Volume::only_in() -{ - mw->show_only("volume"); -#ifndef CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE - mw->actionMarching_cubes->setVisible(false); -#endif -} - -#ifdef CGAL_USE_VTK - -#include - -#include -#include -#include -#include -#include - -Volume::~Volume() -{ - if(vtk_reader) vtk_reader->Delete(); - if(vtk_image) vtk_image->Delete(); - if(dicom_reader) dicom_reader->Delete(); - if(executive) executive->Delete(); - if(smoother) smoother->Delete(); -} - -bool Volume::opendir(const QString& dirname) -{ - bool result = true; - if(!fileinfo.isReadable()) - { - QMessageBox::warning(mw, mw->windowTitle(), - tr("Cannot read directory %1!").arg(dirname)); - status_message(tr("Opening of directory %1 failed!").arg(dirname)); - result = false; - } - else - { - dicom_reader = vtkDICOMImageReader::New(); - dicom_reader->SetDirectoryName(dirname.toUtf8()); - - executive = - vtkDemandDrivenPipeline::SafeDownCast(dicom_reader->GetExecutive()); - if (executive) - { - executive->SetReleaseDataFlag(0, 0); // where 0 is the port index - } - - smoother = vtkImageGaussianSmooth::New(); - smoother->SetStandardDeviations(1., 1., 1.); - smoother->SetInputConnection(dicom_reader->GetOutputPort()); - smoother->Update(); - vtk_image = smoother->GetOutput(); - vtk_image->Print(std::cerr); - m_image = CGAL::read_vtk_image_data(vtk_image); - if(m_image.image() == 0) - { - QMessageBox::warning(mw, mw->windowTitle(), - tr("Error with file %1/:\nunknown file format!").arg(dirname)); - status_message(tr("Opening of file %1/ failed!").arg(dirname)); - result = false; - } - else - { - status_message(tr("File %1/ successfully opened.").arg(dirname)); - finish_open(); - result = true; - } - // if(executive) executive->Delete(); - // dicom_reader->Delete(); - // smoother->Delete(); - } - return result; -} - -bool Volume::open_vtk(const QString& filename) -{ - only_in(); - - fileinfo.setFile(filename); - - if(fileinfo.isDir()) - { - return opendir(filename); - } - - if(!fileinfo.isReadable()) - { - QMessageBox::warning(mw, mw->windowTitle(), - tr("Cannot read file %1!").arg(filename)); - status_message(tr("Opening of file %1 failed!").arg(filename)); - return false; - } - else - { - vtk_reader = vtkImageReader::New(); - vtk_reader->SetFileName(filename.toUtf8()); - vtk_reader->SetDataScalarTypeToUnsignedChar(); - vtk_reader->SetDataExtent(0, 249, 0, 249, 0, 124); - vtk_reader->SetDataSpacing(1., 1., 1.); - vtk_reader->SetFileDimensionality(3); - vtk_reader->Update(); - vtk_reader->Print(std::cerr); - vtk_image = vtk_reader->GetOutput(); - vtk_image->Print(std::cerr); - m_image = CGAL::read_vtk_image_data(vtk_image); - if(m_image.image() == NULL) - { - QMessageBox::warning(mw, mw->windowTitle(), - tr("Error with file %1:\nunknown file format!").arg(filename)); - status_message(tr("Opening of file %1 failed!").arg(filename)); - return false; - } - else - { - status_message(tr("File %1 successfully opened.").arg(filename)); - finish_open(); - return true; - } - } -} - -// Total 3D images (XT format, that is the old Inrimage format, 1994. -bool Volume::open_xt(const QString& filename) -{ - only_in(); - - fileinfo.setFile(filename); - - if(fileinfo.isDir()) - { - return false; - } - - if(!fileinfo.isReadable()) - { - QMessageBox::warning(mw, mw->windowTitle(), - tr("Cannot read file %1!").arg(filename)); - status_message(tr("Opening of file %1 failed!").arg(filename)); - return false; - } - else - { - long dimx, dimy, dimz; - long word_dim; - long header_size; - const char* filename_stl = qPrintable(filename); - CGAL::Total::lire_longueur_entete(filename_stl, &header_size); - CGAL::Total::lire_nb_octet(filename_stl, &word_dim); - CGAL::Total::lire_longueur_trace(filename_stl, &dimx); - CGAL::Total::lire_nb_trace(filename_stl, &dimy); - CGAL::Total::lire_nb_plan(filename_stl, &dimz); - - vtkImageReader* vtk_reader = vtkImageReader::New(); - vtk_reader->SetFileName(filename_stl); - switch(word_dim) { - case 8: - vtk_reader->SetDataScalarTypeToUnsignedChar(); - break; - case 16: - vtk_reader->SetDataScalarTypeToUnsignedShort(); - break; - default: - return false; - } - vtk_reader->SetHeaderSize(header_size); - vtk_reader->SetDataExtent(1, int(dimx), 1, int(dimy), 1, int(dimz)); - vtk_reader->SetDataSpacing(1., 1., 1.); - vtk_reader->SetFileDimensionality(3); - vtk_reader->Update(); - vtk_reader->Print(std::cerr); - vtkImageData* vtk_image = vtk_reader->GetOutput(); - vtk_image->Print(std::cerr); - m_image = CGAL::read_vtk_image_data(vtk_image); - if(m_image.image() != NULL) - { - QMessageBox::warning(mw, mw->windowTitle(), - tr("Error with file %1:\nunknown file format!").arg(filename)); - status_message(tr("Opening of file %1 failed!").arg(filename)); - return false; - } - else - { - status_message(tr("File %1 successfully opened.").arg(filename)); - finish_open(); - } - return true; - } -} - -#else // CGAL_USE_VTK -Volume::~Volume() -{ -} - -bool Volume::opendir(const QString&) -{ - return false; -} - -bool Volume::open_xt(const QString&) -{ - return false; -} -#endif // CGAL_USE_VTK - -bool Volume::open(const QString& filename) -{ - only_in(); - - fileinfo.setFile(filename); - - if(fileinfo.isDir()) - { - return opendir(filename); - } - - if(!fileinfo.isReadable()) - { - QMessageBox::warning(mw, mw->windowTitle(), - tr("Cannot read file %1!").arg(filename)); - } - else - { - if(m_image.read(filename.toStdString().c_str())) - { - status_message(tr("File %1 successfully opened.").arg(filename)); - finish_open(); - return true; - } - else if(open_xt(filename)) { - return true; - } - else - { - QSettings settings; - settings.beginGroup(QUrl::toPercentEncoding(fileinfo.absoluteFilePath())); - if( settings.value("is_raw").toBool() && - m_image.read_raw(filename.toStdString().c_str(), - settings.value("dim_x").toInt(), - settings.value("dim_y").toInt(), - settings.value("dim_z").toInt(), - settings.value("spacing_x").toDouble(), - settings.value("spacing_y").toDouble(), - settings.value("spacing_z").toDouble(), - settings.value("offset").toInt()) ) - { - status_message(tr("File %1 successfully opened.").arg(filename)); - finish_open(); - return true; - } - else if(QMessageBox::warning(mw, mw->windowTitle(), - tr("Error with file %1:\n" - "unknown file format!\n" - "\n" - "Open it as a raw image?").arg(filename), - QMessageBox::Yes|QMessageBox::No) == QMessageBox::Yes) - { - Raw_image_dialog raw_dialog; - raw_dialog.label_file_size->setText(QString("%1 B").arg(fileinfo.size())); - if( raw_dialog.exec() && - m_image.read_raw(filename.toStdString().c_str(), - raw_dialog.dim_x->value(), - raw_dialog.dim_y->value(), - raw_dialog.dim_z->value(), - raw_dialog.spacing_x->value(), - raw_dialog.spacing_y->value(), - raw_dialog.spacing_z->value(), - raw_dialog.offset->value()) ) - { - status_message(tr("File %1 successfully opened.").arg(filename)); - QSettings settings; - settings.beginGroup(QUrl::toPercentEncoding(fileinfo.absoluteFilePath())); - settings.setValue("is_raw", true); - settings.setValue("dim_x", raw_dialog.dim_x->value()); - settings.setValue("dim_y", raw_dialog.dim_y->value()); - settings.setValue("dim_z", raw_dialog.dim_z->value()); - settings.setValue("spacing_x", raw_dialog.spacing_x->value()); - settings.setValue("spacing_y", raw_dialog.spacing_y->value()); - settings.setValue("spacing_z", raw_dialog.spacing_z->value()); - settings.setValue("offset", raw_dialog.offset->value()); - settings.endGroup(); - finish_open(); - return true; - } - } - } - } - status_message(tr("Opening of file %1 failed!").arg(filename)); - return false; -} - -void Volume::finish_open() -{ - m_image.finish_open(); - mw->viewer->camera()->setSceneBoundingBox(CGAL::qglviewer::Vec(0, 0, 0), - CGAL::qglviewer::Vec(m_image.xmax(), - m_image.ymax(), - m_image.zmax())); - - mw->viewer->showEntireScene(); - values_list->load_values(fileinfo.absoluteFilePath()); - load_image_settings(fileinfo.absoluteFilePath()); - changed_parameters(); - Q_EMIT changed(); -} - -void Volume::export_off() -{ - QFileDialog filedialog(mw, tr("Export surface to file")); - filedialog.setFileMode(QFileDialog::AnyFile); - - filedialog.setNameFilter(tr("OFF files (*.off);;" - "All files (*)")); - - filedialog.setAcceptMode(QFileDialog::AcceptSave); - filedialog.setDefaultSuffix("off"); - if(filedialog.exec()) - { - const QString filename = filedialog.selectedFiles().front(); - std::cerr << "Saving to file \"" << filename.toLocal8Bit().data() << "\"..."; - std::ofstream out(filename.toUtf8()); - CGAL::output_surface_facets_to_off(out, c2t3); - if(!out) - { - QMessageBox::warning(mw, mw->windowTitle(), - tr("Export to the OFF file %1 failed!").arg(filename)); - status_message(tr("Export to the OFF file %1 failed!").arg(filename)); - std::cerr << " failed!\n"; - } - else - { - std::cerr << " done.\n"; - status_message(tr("Successfull export to the OFF file %1.").arg(filename)); - } - } -} - -void Volume::save_image_to_inr() -{ - QFileDialog filedialog(mw, tr("Export image to Inrimage format")); - filedialog.setFileMode(QFileDialog::AnyFile); - - filedialog.setNameFilter(tr("Inrimage files (*.inr);;" - "Compressed Inrimage files (*.inr.gz)")); - - - filedialog.setAcceptMode(QFileDialog::AcceptSave); - filedialog.setDefaultSuffix("inr.gz"); - if(filedialog.exec()) - { - const QString filename = filedialog.selectedFiles().front(); - std::cerr << "Saving image to file \"" << filename.toLocal8Bit().data() << "\"..."; - const int result = ::_writeImage(m_image.image(), filename.toUtf8()); - if(result != ImageIO_NO_ERROR) - { - QMessageBox::warning(mw, mw->windowTitle(), - tr("Export to the Inrimage file %1 failed!").arg(filename)); - status_message(tr("Export to the Inrimage file %1 failed!").arg(filename)); - std::cerr << " failed!\n"; - } - else - { - std::cerr << " done.\n"; - status_message(tr("Successfull export to the Inrimage file %1.").arg(filename)); - } - } -} - -void Volume::check_can_export_off() -{ - mw->actionExport_surface_mesh_to_OFF->setEnabled(m_view_surface);// || m_view_mc); -} - -void Volume::status_message(QString string) -{ - std::cerr << qPrintable(string) << std::endl; - mw->statusBar()->showMessage(string); -} - -void Volume::busy() const -{ - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); -} - -void Volume::not_busy() const -{ - QApplication::restoreOverrideCursor(); -} - -void Volume::display_marchin_cube() -{ -#ifdef CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE - if(m_surface_mc.empty()) - { - QElapsedTimer total_time; - total_time.start(); - - values_list->save_values(fileinfo.absoluteFilePath()); - - unsigned int nx = m_image.xdim(); - unsigned int ny = m_image.ydim(); - unsigned int nz = m_image.zdim(); - if(nx * ny * nz == 0) - { - status_message("No volume loaded."); - return; - } - - mc_timer.reset(); - busy(); - status_message("Marching cubes..."); - - mc_timer.start(); - m_surface_mc.clear(); - - if(mc.ntrigs()!=0) - mc.clean_all(); - mc.set_resolution(nx,ny,nz); - mc.init_all(); - mc.set_ext_data(static_cast(m_image.image()->data)); - - nbs_of_mc_triangles.resize(values_list->numberOfValues()); - - for(int value_id = 0; - value_id < values_list->numberOfValues(); - ++value_id) - { - status_message(tr("Marching cubes, isovalue #%1...").arg(value_id)); - - // set data -// for(unsigned int i=0;i 0) - mc.init_temps(); - mc.run(values_list->value(value_id), - m_image.vx(), - m_image.vy(), - m_image.vz()); - mc.clean_temps(); - - std::vector facets; - mc.get_facets(facets); - - mc_timer.stop(); - const unsigned int begin = value_id == 0 ? 0 : nbs_of_mc_triangles[value_id-1]; - const unsigned int nbt = facets.size() / 9; - for(unsigned int i=begin;iitem(value_id))); - } - nbs_of_mc_triangles[value_id]=m_surface_mc.size(); - mc_timer.start(); - } - mc_timer.stop(); - not_busy(); - mc_total_time = total_time.elapsed(); - - // invalidate the display list - lists_draw_surface_mc_is_valid = false; - list_draw_marching_cube_is_valid = false; - } - CGAL::Bbox_3 bbox(0,0,0,0,0,0); - for(std::vector::const_iterator - it = m_surface_mc.begin(), end = m_surface_mc.end(); - it != end; ++it) - { - bbox = bbox + it->get<0>().bbox(); - } - - m_view_mc = true; - m_view_surface = false; - Q_EMIT changed(); - if(!m_surface_mc.empty()) - { - Q_EMIT new_bounding_box(bbox.xmin(), - bbox.ymin(), - bbox.zmin(), - bbox.xmax(), - bbox.ymax(), - bbox.zmax()); - } - status_message(tr("Marching cubes done. %2 facets in %1s (CPU time), total time is %3s.") - .arg(mc_timer.time()) - .arg(m_surface_mc.size()) - .arg(mc_total_time/1000.)); - - save_image_settings(fileinfo.absoluteFilePath()); -#endif // CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE -} - -void Volume::display_surface_mesher_result() -{ - if(m_surface.empty() || // Either the surface is not computed. - m_view_surface) // Or it is computed and displayed, and one want - // to recompute it. - { - QElapsedTimer total_time; - total_time.start(); - - values_list->save_values(fileinfo.absoluteFilePath()); - - std::size_t nx = m_image.xdim(); - std::size_t ny = m_image.ydim(); - std::size_t nz = m_image.zdim(); - if(nx * ny * nz == 0) - { - status_message("No volume loaded."); - return; - } - - m_surface.clear(); - sm_timer.reset(); - busy(); - - status_message("Surface meshing..."); - - sm_timer.start(); - - c2t3.clear(); - del.clear(); - Sphere bounding_sphere(m_image.center(),m_image.radius()*m_image.radius()); - - Classify_from_isovalue_list classify(values_list); - Generate_surface_identifiers generate_ids(values_list); - - m_image.set_interpolation(mw->interpolationCheckBox->isChecked()); - if(mw->labellizedRadioButton->isChecked()) { - std::cerr << "Labellized image\n"; - } - m_image.set_labellized(mw->labellizedRadioButton->isChecked()); - classify.set_identity(mw->labellizedRadioButton->isChecked()); - generate_ids.set_labellized_image(mw->labellizedRadioButton->isChecked()); - - // definition of the surface - Surface_3 surface(m_image, bounding_sphere, m_relative_precision); -// Threshold threshold(m_image.isovalue()); - - // surface mesh traits class - typedef CGAL::Surface_mesher::Implicit_surface_oracle_3 Oracle; - Oracle oracle(classify, generate_ids); - - if(mw->searchSeedsCheckBox->isChecked()) - { - typedef std::vector > Seeds; - Seeds seeds; - { - std::cerr << "Search seeds...\n"; - std::set domains; - search_for_connected_components(std::back_inserter(seeds), - CGAL::inserter(domains), - classify); - std::cerr << "Found " << seeds.size() << " seed(s).\n"; - - if(mw->labellizedRadioButton->isChecked() && - values_list->numberOfValues() == 0) - { - Q_FOREACH(unsigned char label, domains) { - if(label != 0) { - values_list->addValue(label); - } - } - } - } - std::ofstream seeds_out("seeds.off"); - std::ofstream segments_out("segments.txt"); - seeds_out.precision(18); - seeds_out << "OFF\n" << seeds.size() << " 0 0\n"; - segments_out.precision(18); - for(Seeds::const_iterator it = seeds.begin(), end = seeds.end(); - it != end; ++it) - { - seeds_out << it->first << std::endl; - CGAL::Random_points_on_sphere_3 random_points_on_sphere_3(it->second); - Oracle::Intersect_3 intersect = oracle.intersect_3_object(); - for(int i = 0; i < 20; ++i) - { - const Point_3 test = it->first + (*random_points_on_sphere_3++ - CGAL::ORIGIN); - CGAL::Object o = intersect(surface, Segment_3(it->first, test)); - if (const Point_3* intersection = CGAL::object_cast(&o)) { - segments_out << "2 " << it->first << " " << *intersection << std::endl; - del.insert(*intersection); - } - else - { - std::cerr << - boost::format("Error. Segment (%1%, %2%) does not intersect the surface! values=(%3%, %4%)\n") - % it->first % test - % surface(it->first) % surface(test); - } - } - } - } - else { - oracle.construct_initial_points_object()(surface, - CGAL::inserter(c2t3.triangulation()), - 20); - } - - std::ofstream points_out("initial-points.off"); - points_out.precision(18); - points_out << "OFF\n" << c2t3.triangulation().number_of_vertices() << " 0 0\n"; - for(const Tr::Vertex& v : - CGAL::make_range(c2t3.triangulation().vertices_begin(), - c2t3.triangulation().vertices_end())) - { - points_out << v.point() << std::endl; - } - - std::cerr << boost::format("Number of initial points: %1%\n") % del.number_of_vertices(); - - // defining meshing criteria - typedef CGAL::Surface_mesher::Refine_criterion Criterion; - CGAL::Surface_mesher::Curvature_size_criterion - curvature_size_criterion (m_sm_distance); - CGAL::Surface_mesher::Uniform_size_criterion - uniform_size_criterion (m_sm_radius); - CGAL::Surface_mesher::Aspect_ratio_criterion - aspect_ratio_criterion (m_sm_angle); - CGAL::Surface_mesher::Vertices_on_the_same_psc_element_criterion - vertices_on_the_same_psc_element_criterion(surface); - - std::vector criterion_vector; - criterion_vector.push_back(&aspect_ratio_criterion); - criterion_vector.push_back(&uniform_size_criterion); - criterion_vector.push_back(&curvature_size_criterion); - if(mw->sameIndexCheckBox->isChecked()) { - criterion_vector.push_back(&vertices_on_the_same_psc_element_criterion); - std::cerr << "vertices_on_the_same_psc_element_criterion is activated.\n"; - } - - typedef CGAL::Surface_mesher::Standard_criteria Criteria; - Criteria criteria(criterion_vector); - std::cerr << "Surface_mesher... angle=" << m_sm_angle << ", radius= " << m_sm_radius - << ", distance=" << m_sm_distance << "\n"; - - typedef CGAL::Surface_mesher_generator::type Surface_mesher_manifold; - - typedef CGAL::Surface_mesher_generator::type Surface_mesher_non_manifold; - - if(mw->manifoldCheckBox->isChecked()) { - // meshing surface - std::cerr << "manifold criteria is activated.\n"; -// make_surface_mesh(c2t3, surface, oracle, criteria, -// CGAL::Manifold_tag(), 0); - Surface_mesher_manifold manifold_mesher(c2t3, surface, oracle, criteria); - manifold_mesher.refine_mesh(); - } - else { -// m_view_surface = true; - Surface_mesher_non_manifold non_manifold_mesher(c2t3, surface, oracle, criteria); -#if 0 - int nb_steps = 0; -// direct_draw = true; - non_manifold_mesher.init(); - while(!non_manifold_mesher.is_algorithm_done()) { - CGAL::Null_mesh_visitor null_visitor; - non_manifold_mesher.one_step(null_visitor); - if(++nb_steps % 1000 == 0) { - CGAL::Timer timer; - std::cerr << "(process events..."; - timer.start(); - list_draw_marching_cube_is_valid = false; - lists_draw_surface_is_valid = false; - for(Tr::Finite_cells_iterator - cit = del.finite_cells_begin(), - end = del.finite_cells_end(); - cit != end; ++cit) - { - cit->info() = classify(surface(cit->circumcenter())); - } -// Q_EMIT changed(); - qApp->processEvents(); - timer.stop(); - std::cerr << timer.time() << " secondes)\n"; - } - } -#else - non_manifold_mesher.refine_mesh(); -#endif - } - sm_timer.stop(); - not_busy(); - direct_draw = false; - - for(Tr::Finite_cells_iterator - cit = del.finite_cells_begin(), - end = del.finite_cells_end(); - cit != end; ++cit) - { - cit->info() = classify(surface(cit->circumcenter())); - } - // get output surface - for(C2t3::Facet_iterator - fit = c2t3.facets_begin(), end = c2t3.facets_end(); - fit != end; ++fit) - { - const Tr::Cell_handle& cell = fit->first; - const int index = fit->second; - - // here "left" means nothing - const Point_3 left_circumcenter = cell->circumcenter(); - const Point_3 right_circumcenter = cell->neighbor(index)->circumcenter(); - - const Triangle_3 t = - Triangle_3(cell->vertex(del.vertex_triple_index(index, 0))->point(), - cell->vertex(del.vertex_triple_index(index, 1))->point(), - cell->vertex(del.vertex_triple_index(index, 2))->point()); - const Vector u = t[1] - t[0]; - const Vector v = t[2] - t[0]; - Vector n = CGAL::cross_product(u,v); - n = n / std::sqrt(n*n); - if(mw->labellizedRadioButton->isChecked()) - { - m_surface.push_back(Facet_(t, - n, - values_list->search((std::max)(surface(left_circumcenter), - surface(right_circumcenter))))); - } - else { - m_surface.push_back(Facet_(t,n,cell->vertex(del.vertex_triple_index(index, 0))->point().element_index())); - } - } - - // invalidate the display list - lists_draw_surface_is_valid = false; - sm_total_time = total_time.elapsed(); - } - - CGAL::Bbox_3 bbox(0,0,0,0,0,0); - for(std::vector::const_iterator - it = m_surface.begin(), end = m_surface.end(); - it != end; ++it) - { - bbox = bbox + it->get<0>().bbox(); - } - - // toggle visualization - m_view_mc = false; - m_view_surface = true; - Q_EMIT changed(); - if(!m_surface.empty()) - { - Q_EMIT new_bounding_box(bbox.xmin(), - bbox.ymin(), - bbox.zmin(), - bbox.xmax(), - bbox.ymax(), - bbox.zmax()); - } - status_message(tr("Surface meshing done. %1 facets in %2s (CPU time), total time is %3s.") - .arg(m_surface.size()) - .arg(sm_timer.time()) - .arg(sm_total_time/1000.)); - save_image_settings(fileinfo.absoluteFilePath()); -} - -void Volume::gl_draw_image_bbox(const float line_width, - const unsigned char red, - const unsigned char green, - const unsigned char blue) -{ - const _image* image_ptr = m_image.image(); - if(image_ptr == NULL) - return; - - glLineWidth(line_width); - glColor3ub(red,green,blue); - glBegin(GL_LINES); - - const double xmax = (image_ptr->xdim - 1.0)*(image_ptr->vx); - const double ymax = (image_ptr->ydim - 1.0)*(image_ptr->vy); - const double zmax = (image_ptr->zdim - 1.0)*(image_ptr->vz); - - glVertex3d(0.0,0.0,0.0); - glVertex3d(0.0,ymax,0.0); - - glVertex3d(0.0,ymax,0.0); - glVertex3d(0.0,ymax,zmax); - - glVertex3d(0.0,ymax,zmax); - glVertex3d(0.0,0.0,zmax); - - glVertex3d(0.0,0.0,zmax); - glVertex3d(0.0,0.0,0.0); - - glVertex3d(xmax,0.0,0.0); - glVertex3d(xmax,ymax,0.0); - - glVertex3d(xmax,ymax,0.0); - glVertex3d(xmax,ymax,zmax); - - glVertex3d(xmax,ymax,zmax); - glVertex3d(xmax,0.0,zmax); - - glVertex3d(xmax,0.0,zmax); - glVertex3d(xmax,0.0,0.0); - - glVertex3d(0.0,0.0,0.0); - glVertex3d(xmax,0.0,0.0); - - glVertex3d(0.0,0.0,zmax); - glVertex3d(xmax,0.0,zmax); - - glVertex3d(0.0,ymax,zmax); - glVertex3d(xmax,ymax,zmax); - - glVertex3d(0.0,ymax,0.0); - glVertex3d(xmax,ymax,0.0); - - glEnd(); -} - -void Volume::draw() -{ - float ambient[] = { 0.25f, - 0.20725f, - 0.20725f, - 0.922f }; - float diffuse[] = { 1.0f, - 0.829f, - 0.829f, - 0.922f }; - - float specular[] = { 0.296648f, - 0.296648f, - 0.296648f, - 0.522f }; - - float emission[] = { 0.3f, - 0.3f, - 0.3f, - 1.0f }; - float shininess[] = { 11.264f }; - - // apply - ::glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT, ambient); - ::glMaterialfv( GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse); - ::glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR, specular); - ::glMaterialfv( GL_FRONT_AND_BACK, GL_SHININESS, shininess); - ::glMaterialfv( GL_FRONT_AND_BACK, GL_EMISSION, emission); - - ::glEnable(GL_LINE_SMOOTH); - - if(two_sides) - ::glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); - else - ::glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); // default - - // draw surface mesh - if(m_view_surface) - { - ::glEnable(GL_LIGHTING); - ::glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); - ::glColor3f(0.2f, 0.2f, 1.f); - ::glEnable(GL_POLYGON_OFFSET_FILL); - ::glPolygonOffset(3.0f,-3.0f); - gl_draw_surface(); - - if(draw_triangles_edges) - { - ::glDisable(GL_LIGHTING); - ::glLineWidth(1.); - ::glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); - ::glColor3ub(0,0,0); - ::glDisable(GL_POLYGON_OFFSET_FILL); - gl_draw_surface(); - } - } - -#ifdef CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE - // draw MC surface mesh - if(m_view_mc) - { - ::glEnable(GL_LIGHTING); - ::glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); - ::glColor3f(0.2f, 0.2f, 1.f); - ::glEnable(GL_POLYGON_OFFSET_FILL); - ::glPolygonOffset(3.0f,-3.0f); - gl_draw_surface_mc(); - - if(draw_triangles_edges) - { - ::glDisable(GL_LIGHTING); - ::glLineWidth(1.); - ::glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); - ::glColor3ub(0,0,0); - ::glDisable(GL_POLYGON_OFFSET_FILL); - gl_draw_surface_mc(); - } - } -#endif // CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE - - if(show_bbox) { - ::glDisable(GL_LIGHTING); - gl_draw_image_bbox(3.0f,0,0,0); - } - - if(!m_view_mc && m_draw_triangulation) - { - // draw the triangualtion - ::glColor3d(m_triangulation_color.redF(), - m_triangulation_color.greenF(), - m_triangulation_color.blueF()); - ::glLineWidth(1.0); - ::glBegin(GL_LINES); - for(Tr::Finite_edges_iterator - eit = del.finite_edges_begin(), - end = del.finite_edges_end(); - eit != end; ++eit) - { - const Point_3 p1 = eit->first->vertex(eit->second)->point(); - const Point_3 p2 = eit->first->vertex(eit->third)->point(); - ::glVertex3d(p1.x(),p1.y(),p1.z()); - ::glVertex3d(p2.x(),p2.y(),p2.z()); - } - ::glEnd(); - } -} - -void Volume::set_radius_bound(double d) -{ - m_sm_radius = FT(d); - changed_parameters(); -} - -void Volume::set_distance_bound(double d) -{ - m_sm_distance = FT(d); - changed_parameters(); -} - -#ifdef CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE -void Volume::gl_draw_surface_mc() -{ - if(use_gouraud) - { - gl_draw_marchingcube(); - return; - } - - if(lists_draw_surface_mc_is_valid) - { - for(int i = 0, nbs = values_list->numberOfValues(); i < nbs; ++i ) - { - if(values_list->enabled(i)) - { - mw->viewer->qglColor(values_list->color(i)); - ::glCallList(lists_draw_surface_mc[i]); - } - } - } - else - { - lists_draw_surface_mc.resize(values_list->numberOfValues(), 0); - for(int i = 0, nbs = values_list->numberOfValues(); i < nbs; ++i ) - { - if(!lists_draw_surface_mc[i]) - { - lists_draw_surface_mc[i] = ::glGenLists(1); - } - - std::cerr << boost::format("(Re-)Generating list #%1% for marching cube surface #%2%" - " in gl_draw_surface(), ()\n") - % lists_draw_surface_mc[i] - % i; - - mw->viewer->qglColor(values_list->color(i)); - - if(lists_draw_surface_mc[i]) // If - ::glNewList(lists_draw_surface_mc[i], // lists_draw_surface[i]==0 then something - values_list->enabled(i) // got wrong in the list generation. - ? GL_COMPILE_AND_EXECUTE - : GL_COMPILE); - - - gl_draw_surface(m_surface_mc.begin(), - m_surface_mc.end(), - values_list->item(i)); - - if(lists_draw_surface_mc[i]) // If lists_draw_surface[i]==0 then - { // something got wrong in the list - ::glEndList(); // generation. - } - } - lists_draw_surface_mc_is_valid = (::glGetError() == GL_NO_ERROR); - } -} -#endif // CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE - -void Volume::gl_draw_surface() -{ -// if(mw->labellizedRadioButton->isChecked()) { -// mw->viewer->qglColor(::Qt::blue); -// gl_draw_surface(m_surface.begin(), -// m_surface.end(), -// 0); -// } -// else - if(direct_draw) { - ::glBegin(GL_TRIANGLES); - unsigned int counter = 0; - for(Tr::Finite_cells_iterator - cit = del.finite_cells_begin(), end = del.finite_cells_end(); - cit != end; ++cit) - { - for(int facet_index = 0; facet_index < 4; ++facet_index) - { - const Tr::Cell_handle& facet_cell = cit; - if(c2t3.face_status(facet_cell, facet_index) == C2t3::NOT_IN_COMPLEX) { - continue; - } - const Point_3& a = facet_cell->vertex(del.vertex_triple_index(facet_index, 0))->point(); - const Point_3& b = facet_cell->vertex(del.vertex_triple_index(facet_index, 1))->point(); - const Point_3& c = facet_cell->vertex(del.vertex_triple_index(facet_index, 2))->point(); - Vector n = CGAL::cross_product(b-a,c-a); - n = n / std::sqrt(n*n); // unit normal - if(m_inverse_normals) { - ::glNormal3d(-n.x(),-n.y(),-n.z()); - } else { - ::glNormal3d(n.x(),n.y(),n.z()); - } - ::glColor3d(values_list->color(values_list->search(facet_cell->info())).redF(), - values_list->color(values_list->search(facet_cell->info())).greenF(), - values_list->color(values_list->search(facet_cell->info())).blueF()); - ::glVertex3d(a.x(),a.y(),a.z()); - ::glVertex3d(b.x(),b.y(),b.z()); - ::glVertex3d(c.x(),c.y(),c.z()); - ++counter; - } - ::glEnd(); - } - return; - } - if(!direct_draw && lists_draw_surface_is_valid) - { - for(int i = 0, nbs = values_list->numberOfValues(); i < nbs; ++i ) - { - if(values_list->enabled(i)) - { - ::glColor3d(values_list->color(i).redF(), - values_list->color(i).greenF(), - values_list->color(i).blueF()); - ::glCallList(lists_draw_surface[i]); - } - } - } - else - { - lists_draw_surface.resize(values_list->numberOfValues(), 0); - for(int i = 0, nbs = values_list->numberOfValues(); i < nbs; ++i ) - { - if(!lists_draw_surface[i]) - { - lists_draw_surface[i] = ::glGenLists(1); - } - - std::cerr << boost::format("(Re-)Generating list #%1% for surface #%2%" - " in gl_draw_surface(), ()\n") - % lists_draw_surface[i] - % i; - - ::glColor3d(values_list->color(i).redF(), - values_list->color(i).greenF(), - values_list->color(i).blueF()); - - if(!direct_draw && lists_draw_surface[i]) // If - ::glNewList(lists_draw_surface[i], // lists_draw_surface[i]==0 - values_list->enabled(i) // then something got wrong - ? GL_COMPILE_AND_EXECUTE // in the list generation. - : GL_COMPILE); - - if(!mw->labellizedRadioButton->isChecked()) - { - gl_draw_surface(m_surface.begin(), - m_surface.end(), - values_list->item(i)); - } - else - { - const auto volume_index = static_cast(values_list->value(i)); - - ::glBegin(GL_TRIANGLES); - unsigned int counter = 0; - for(C2t3::Facet_iterator - fit = c2t3.facets_begin(), end = c2t3.facets_end(); - fit != end; ++fit) - { - Tr::Cell_handle facet_cell = fit->first; - int facet_index = fit->second; - Tr::Cell_handle opposite_cell = facet_cell->neighbor(facet_index); - int opposite_index = opposite_cell->index(facet_cell); - - if( facet_cell->info() != volume_index ) { - if( opposite_cell->info() == volume_index ) { - std::swap(facet_cell, opposite_cell); - std::swap(facet_index, opposite_index); - } - else - continue; // go to next facet - } - const Point_3& a = opposite_cell->vertex(del.vertex_triple_index(opposite_index, 0))->point(); - const Point_3& b = opposite_cell->vertex(del.vertex_triple_index(opposite_index, 1))->point(); - const Point_3& c = opposite_cell->vertex(del.vertex_triple_index(opposite_index, 2))->point(); - Vector n = CGAL::cross_product(b-a,c-a); - n = n / std::sqrt(n*n); // unit normal - if(m_inverse_normals) { - ::glNormal3d(-n.x(),-n.y(),-n.z()); - } else { - ::glNormal3d(n.x(),n.y(),n.z()); - } - ::glVertex3d(a.x(),a.y(),a.z()); - ::glVertex3d(b.x(),b.y(),b.z()); - ::glVertex3d(c.x(),c.y(),c.z()); - ++counter; - } - ::glEnd(); - std::cerr << boost::format("(c2t3) number of facets: %1%\n") - % counter; - } - - if(!direct_draw && lists_draw_surface[i]) - // If lists_draw_surface[i]==0 then - { // something got wrong in the list - ::glEndList(); // generation. - } - } - lists_draw_surface_is_valid = (::glGetError() == GL_NO_ERROR); - } -} - -template -void Volume::gl_draw_surface(Iterator begin, Iterator end, const QTreeWidgetItem* i) -{ - ::glBegin(GL_TRIANGLES); - unsigned int counter = 0; - for(Iterator it = begin; it != end; ++it) - { - const Facet_& f = *it; - - if(f.get<2>() != i) continue; - - const Vector& n = f.get<1>(); - - if(m_inverse_normals) - ::glNormal3d(-n.x(),-n.y(),-n.z()); - else - ::glNormal3d(n.x(),n.y(),n.z()); - - const Triangle_3& t = f.get<0>(); - const Point_3& a = t[0]; - const Point_3& b = t[1]; - const Point_3& c = t[2]; - - ::glVertex3d(a.x(),a.y(),a.z()); - ::glVertex3d(b.x(),b.y(),b.z()); - ::glVertex3d(c.x(),c.y(),c.z()); - ++counter; - } - ::glEnd(); - std::cerr << boost::format("number of facets: %1%\n") - % counter; -} - -void Volume::changed_parameters() -{ - m_surface.clear(); -#ifdef CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE - m_surface_mc.clear(); -#endif - list_draw_marching_cube_is_valid = false; - lists_draw_surface_is_valid = false; - c2t3.clear(); - del.clear(); - m_view_mc = m_view_surface = false; - Q_EMIT changed(); -} - -#ifdef CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE -void Volume::gl_draw_one_marching_cube_vertex(int i) -{ - if(!m_inverse_normals) - glArrayElement(i); - else - { - const Vertex* const vertex = mc.vert(i); - ::glNormal3d(-vertex->nx, -vertex->ny, -vertex->nz); - ::glVertex3d(vertex->x, vertex->y, vertex->z); - } -} - -void Volume::gl_draw_marchingcube() -{ - if(list_draw_marching_cube_is_valid) - ::glCallList(list_draw_marching_cube); - else - { - if(!list_draw_marching_cube) - list_draw_marching_cube = ::glGenLists(1); - std::cerr << boost::format("(Re-)Generating list #%1% for" - " gl_draw_marchingcube()\n") - % list_draw_marching_cube; - - if(list_draw_marching_cube) // If list_draw_marching_cube==0 then - ::glNewList(list_draw_marching_cube, // something got wrong in the list - GL_COMPILE_AND_EXECUTE); // generation. - - ::glVertexPointer(3, GL_DOUBLE, sizeof(Vertex), mc.vertices()); - ::glNormalPointer(GL_DOUBLE, sizeof(Vertex), &(mc.vertices()->nx)); - ::glEnableClientState(GL_VERTEX_ARRAY); - - // because of that conditionnal, the display list has to be - // reconstructed each time m_inverse_normals is toggled. - if(!m_inverse_normals) - ::glEnableClientState(GL_NORMAL_ARRAY); - - for(int i = 0, nbs = values_list->numberOfValues(); i < nbs; ++i) - { - const int begin = i == 0 ? 0 : nbs_of_mc_triangles[i-1]; - const int end = nbs_of_mc_triangles[i]; - mw->viewer->qglColor(values_list->color(i)); - ::glBegin(GL_TRIANGLES); - for(int i = begin; i < end; ++i) - { - const MC_Triangle* const trig = mc.trig(i); - gl_draw_one_marching_cube_vertex(trig->v1); - gl_draw_one_marching_cube_vertex(trig->v2); - gl_draw_one_marching_cube_vertex(trig->v3); - } - ::glEnd(); - } - if(list_draw_marching_cube > 0) // If list_draw_marching_cube==0 then - { // something got wrong in the list - ::glEndList(); // generation. - list_draw_marching_cube_is_valid = (::glGetError() == GL_NO_ERROR); - } - if(!list_draw_marching_cube_is_valid) - { - CGAL::Qt::opengl_check_errors(); - } - } -} -#endif // CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE - -void Volume::save_image_settings(QString filename) -{ - QSettings settings; - settings.beginGroup(QUrl::toPercentEncoding(filename)); - settings.setValue("labellized", mw->labellizedRadioButton->isChecked()); - settings.endGroup(); -} - -void Volume::load_image_settings(QString filename) -{ - QSettings settings; - settings.beginGroup(QUrl::toPercentEncoding(filename)); - mw->labellizedRadioButton->setChecked(settings.value("labellized").toBool()); - settings.endGroup(); -} - -void Volume::labellizedToogled(bool toggled) -{ - if(toggled) { - values_list->setHeaderTitle(tr("Label")); - } - else { - values_list->setHeaderTitle(tr("Iso-Value")); - } -} - diff --git a/Surface_mesher/demo/Surface_mesher/volume.h b/Surface_mesher/demo/Surface_mesher/volume.h deleted file mode 100644 index 09195f02d07..00000000000 --- a/Surface_mesher/demo/Surface_mesher/volume.h +++ /dev/null @@ -1,392 +0,0 @@ -#ifndef _VOLUME_H -#define _VOLUME_H - -#include -#include -#include - - -#include "surface.h" -#include "binary_image.h" - -#include -#include -#include -#include - -#include -#include -#include // std::back_inserter - -#include -#include - -#ifdef CGAL_USE_VTK -class vtkImageReader; -class vtkImageData; -class vtkDICOMImageReader; -class vtkDemandDrivenPipeline; -class vtkImageGaussianSmooth; -#endif // CGAL_USE_VTK - -class QTreeWidgetItem; - -// kernel -// #include -#include -typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel1; - -#include -struct Kernel : public Kernel1 { - typedef CGAL::Point_with_psc_localisation Point_3; -}; - -typedef Kernel::FT FT; -typedef Kernel::Point_3 Point_3; -typedef Kernel::Sphere_3 Sphere; -typedef Kernel::Vector_3 Vector; -typedef Kernel::Triangle_3 Triangle_3; -typedef Kernel::Segment_3 Segment_3; - -// typedef CGAL::Triple Facet; - -typedef boost::tuple Facet_; - - -typedef CBinary_image_3 Binary_image; - -class QTreeWidgetItem; - -// surface mesher -// #define CGAL_MESHES_NO_OUTPUT -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -typedef CGAL::Surface_mesh_vertex_base_3 Vb; -typedef CGAL::Triangulation_cell_base_with_info_3 Cb1; -typedef CGAL::Delaunay_triangulation_cell_base_3 Cb2; -typedef CGAL::Delaunay_triangulation_cell_base_with_circumcenter_3 Cb3; -typedef CGAL::Surface_mesh_cell_base_3 Cb; -typedef CGAL::Triangulation_data_structure_3 Tds; -typedef CGAL::Delaunay_triangulation_3 Tr; -typedef CGAL::Surface_mesh_complex_2_in_triangulation_3 C2t3; -typedef CGAL::Implicit_surface_3 Surface_3; - -#ifdef CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE -#include -#endif - -class MainWindow; -class QDoubleSpinBox; -class Viewer; -class Values_list; - -class Volume : public Surface -{ - Q_OBJECT -public: - Volume(MainWindow* mw); - ~Volume(); - -private: - Binary_image m_image; - - // options - FT m_sm_angle; - FT m_sm_radius; - FT m_sm_distance; - double m_relative_precision; - - // visualization - bool m_view_surface; - bool m_draw_triangulation; - QColor m_triangulation_color; - bool m_inverse_normals; - bool two_sides; - bool draw_triangles_edges; - bool use_gouraud; - bool show_bbox; - - std::vector m_surface; - Tr del; // 3D-Delaunay triangulation - C2t3 c2t3; // 2D complex in 3D triangulation - - MainWindow* mw; - QFileInfo fileinfo; - Values_list* values_list; - QDoubleSpinBox* spinBox_radius_bound; - QDoubleSpinBox* spinBox_distance_bound; - - bool direct_draw; // do not use display lists - std::vector lists_draw_surface; - bool lists_draw_surface_is_valid; - GLint list_draw_marching_cube; - bool list_draw_marching_cube_is_valid; - - CGAL::Timer sm_timer; - int sm_total_time; - -#ifdef CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE - std::vector m_surface_mc; - MarchingCubes mc ; - std::vector nbs_of_mc_triangles; - std::vector lists_draw_surface_mc; - bool lists_draw_surface_mc_is_valid; - CGAL::Timer mc_timer; - int mc_total_time; -public: - void gl_draw_surface_mc(); - void gl_draw_marchingcube(); -private: - void gl_draw_one_marching_cube_vertex(int); - -#endif // CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE - - bool m_view_mc; // that boolean is here even with if - // CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE - // is not defined. - -#ifdef CGAL_USE_VTK - vtkImageReader* vtk_reader; - vtkImageData* vtk_image; - vtkDICOMImageReader* dicom_reader; - vtkDemandDrivenPipeline* executive; - vtkImageGaussianSmooth* smoother; -#endif // CGAL_USE_VTK - -public Q_SLOTS: -void display_marchin_cube(); - -private: - template - void gl_draw_surface(Iterator begin, Iterator end, const QTreeWidgetItem* = 0); - void gl_draw_image_bbox(const float line_width, - const unsigned char red, - const unsigned char green, - const unsigned char blue); - - template - void search_for_connected_components(PointsOutputIterator, - DomainsOutputIterator, - TransformOperator); - -public: - void gl_draw_surface(); - -Q_SIGNALS: - - void new_bounding_box(double, double, double, double, double, double); - -public Q_SLOTS: - void only_in(); - void set_inverse_normals(const bool); - void set_two_sides(const bool); - void set_draw_triangles_edges(const bool); - void set_triangulation_edges_color(); - void set_draw_triangulation(const bool); - void set_use_gouraud(const bool); - void set_show_bbox(const bool); - bool open(const QString& filename); -#ifdef CGAL_USE_VTK - bool open_vtk(const QString& filename); -#endif - bool open_xt(const QString& filename); - bool opendir(const QString& dirname); - void finish_open(); - void export_off(); - void save_image_to_inr(); - void check_can_export_off(); - void draw(); - void get_bbox(float& /*xmin*/, float& /*ymin*/, float& /*zmin*/, - float& /*xmax*/, float& /*ymax*/, float& /*zmax*/) {} - void close() {} - void display_surface_mesher_result(); - void set_radius_bound(double); - void set_distance_bound(double); - void changed_parameters(); - - void labellizedToogled(bool); - - void save_image_settings(QString); - void load_image_settings(QString); -private: - void status_message(QString); - void busy() const; - void not_busy() const; -}; - -template -void Volume::search_for_connected_components(PointsOutputIterator it, - DomainsOutputIterator dom_it, - TransformOperator transform) -{ - const std::size_t nx = m_image.xdim(); - const std::size_t ny = m_image.ydim(); - const std::size_t nz = m_image.zdim(); - - const double max_v = (std::max)((std::max)(m_image.vx(), - m_image.vy()), - m_image.vz()); - - typedef unsigned char Marker; - typedef typename TransformOperator::result_type Label; - - boost::multi_array visited(boost::extents[nx][ny][nz]); - typedef boost::tuple - Indices; - typedef std::queue Indices_queue; - typedef std::vector Border_vector; - - int number_of_connected_components = 0; - for(std::size_t i=0; i0) - continue; - const Label current_label = transform(m_image.value(i, j, k)); - *dom_it++ = current_label; - if(current_label == Label()) { - visited[i][j][k] = 3; - continue; - } - - // if we reach here, (i, j, k) is a new connected component - ++number_of_connected_components; - std::cerr << boost::format("Found new connected component (#%5%) " - "at voxel (%1%, %2%, %3%), value=%4%, volume id=%6%\n") - % i % j % k - % m_image.value(i, j, k) - % number_of_connected_components - % (int)current_label; - - int nb_voxels = 0; - - Indices_queue queue; - Indices indices(i, j ,k, 0); - queue.push(indices); - - Border_vector border; - - /* - * First pass is a BFS to retrieve all the connected component, and - * its border. - * Second pass is a BFS initialized with all voxel of the border. - * The last voxel of that BFS is used as the seed. - */ - Marker pass = 1; // pass will be equal to 2 in second pass - - Indices bbox_min = indices; - Indices bbox_max = indices; - - while(!queue.empty()) // walk through the connected component - { - Indices indices = queue.front(); - queue.pop(); - - // warning: those indices i, j and k are local to the while loop - const std::size_t i = boost::get<0>(indices); - const std::size_t j = boost::get<1>(indices); - const std::size_t k = boost::get<2>(indices); - const std::size_t depth = boost::get<3>(indices); - - if(visited[i][j][k] < pass) - { - visited[i][j][k] = pass; - if(pass == 1 ) - { - ++nb_voxels; - boost::get<0>(bbox_min) = (std::min)(i, boost::get<0>(bbox_min)); - boost::get<0>(bbox_max) = (std::max)(i, boost::get<0>(bbox_max)); - boost::get<1>(bbox_min) = (std::min)(j, boost::get<1>(bbox_min)); - boost::get<1>(bbox_max) = (std::max)(j, boost::get<1>(bbox_max)); - boost::get<2>(bbox_min) = (std::min)(k, boost::get<2>(bbox_min)); - boost::get<2>(bbox_max) = (std::max)(k, boost::get<2>(bbox_max)); - } - - static const int neighbors_offset[6][3] = { { +1, 0, 0 }, - { -1, 0, 0 }, - { 0, +1, 0 }, - { 0, -1, 0 }, - { 0, 0, +1 }, - { 0, 0, -1 } }; - bool voxel_is_on_border = false; - - // Visit neighbors. - // (i_n, j_n, k_n) are indices of neighbors. - for(int n = 0; n < 6; ++n) - { - const ptrdiff_t i_n = i + neighbors_offset[n][0]; - const ptrdiff_t j_n = j + neighbors_offset[n][1]; - const ptrdiff_t k_n = k + neighbors_offset[n][2]; - if(i_n < 0 || i_n >= static_cast(nx) || - j_n < 0 || j_n >= static_cast(ny) || - k_n < 0 || k_n >= static_cast(nz)) - { - voxel_is_on_border = true; - continue; - } - else - { - if(transform(m_image.value(i_n, j_n, k_n)) == current_label) - { - if(visited[i_n][j_n][k_n] < pass) { - Indices indices(i_n, j_n, k_n, depth+1); - queue.push(indices); - } - } - else - voxel_is_on_border = true; - } - } // end for neighbors - - if(pass == 1 && voxel_is_on_border) - border.push_back(indices); - } // end if voxel not already visited - - if(queue.empty()) { - if(pass == 1) - { // End of first pass. Begin second pass with the voxels of - // the border. - for(typename Border_vector::const_iterator - border_it = border.begin(), border_end = border.end(); - border_it != border_end; ++border_it) - queue.push(*border_it); - pass = 2; - } - else // end of second pass, return the last visited voxel - { -// if(nb_voxels >= 100) - { - *it++ = std::make_pair(m_image.point(i, j, k), (depth+1)*max_v); - std::cerr << boost::format("Found seed %5%, which is voxel (%1%, %2%, %3%), value=%4%\n") - % i % j % k % m_image.value(i, j, k) % m_image.point(i, j, k); - } - } - } // end if queue.empty() - } // end while !queue.empty() (with local indices i, j, k) - - std::cerr << boost::format("There was %1% voxel(s) in that component.\n" - "The bounding box is (%2% %3% %4%, %5% %6% %7%).\n" - "%8% voxel(s) on border\n") - % nb_voxels - % boost::get<0>(bbox_min) % boost::get<1>(bbox_min) % boost::get<2>(bbox_min) - % boost::get<0>(bbox_max) % boost::get<1>(bbox_max) % boost::get<2>(bbox_max) - % border.size(); - } // end for i,j,k -} // end function Volume::search_for_connected_components() - -#endif // _VOLUME_H From e0ca02696d2c4b217873df351c0c495fb01d290f Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 3 Mar 2021 15:35:34 +0100 Subject: [PATCH 234/248] Update PckgDesctiption --- Surface_mesher/doc/Surface_mesher/PackageDescription.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Surface_mesher/doc/Surface_mesher/PackageDescription.txt b/Surface_mesher/doc/Surface_mesher/PackageDescription.txt index 90efa88c31c..092ae4fd68e 100644 --- a/Surface_mesher/doc/Surface_mesher/PackageDescription.txt +++ b/Surface_mesher/doc/Surface_mesher/PackageDescription.txt @@ -38,7 +38,7 @@ \cgalPkgDependsOn{\ref PkgTriangulation3} \cgalPkgBib{cgal:ry-smg} \cgalPkgLicense{\ref licensesGPL} -\cgalPkgDemo{Surface Mesh Generator,surface_mesher.zip} +\cgalPkgDemo{Polyhedron demo,polyhedron_3.zip} \cgalPkgShortInfoEnd \cgalPkgDescriptionEnd From ea73657ae1223292985533ec34bebc3a7d95c902 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 3 Mar 2021 15:50:46 +0100 Subject: [PATCH 235/248] no demo at all --- Surface_mesher/doc/Surface_mesher/PackageDescription.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/Surface_mesher/doc/Surface_mesher/PackageDescription.txt b/Surface_mesher/doc/Surface_mesher/PackageDescription.txt index 092ae4fd68e..bf46b3a6eba 100644 --- a/Surface_mesher/doc/Surface_mesher/PackageDescription.txt +++ b/Surface_mesher/doc/Surface_mesher/PackageDescription.txt @@ -38,7 +38,6 @@ \cgalPkgDependsOn{\ref PkgTriangulation3} \cgalPkgBib{cgal:ry-smg} \cgalPkgLicense{\ref licensesGPL} -\cgalPkgDemo{Polyhedron demo,polyhedron_3.zip} \cgalPkgShortInfoEnd \cgalPkgDescriptionEnd From 23791046b77aa047818fbf5576262028261f1908 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 4 Mar 2021 11:55:16 +0100 Subject: [PATCH 236/248] fix structure of getLUTIndex --- .../include/CGAL/Tetrahedral_remeshing/internal/FMLS.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/FMLS.h b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/FMLS.h index e04a3e8535e..6f588968c9b 100644 --- a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/FMLS.h +++ b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/FMLS.h @@ -469,7 +469,7 @@ private: { if (vp[j] < 0) p[j] = 0; - if (vp[j] >= res[j]) + else if (vp[j] >= res[j]) p[j] = res[j] - 1; else p[j] = static_cast(std::floor(vp[j])); From 5bb52bf4a4cc400b2c6d5595a1cb294158e029ad Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 4 Mar 2021 14:43:47 +0100 Subject: [PATCH 237/248] res[i] could still be 0. Avoid it --- .../include/CGAL/Tetrahedral_remeshing/internal/FMLS.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/FMLS.h b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/FMLS.h index 6f588968c9b..1eee358227b 100644 --- a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/FMLS.h +++ b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/FMLS.h @@ -388,11 +388,12 @@ private: for (std::size_t i = 0; i < 3; i++) { - if(minMax[3 + i] == minMax[i]) + res[i] = (std::size_t)ceil((minMax[3 + i] - minMax[i]) / cellSize); + if(res[1] == 0) res[i] = 1; - else - res[i] = (std::size_t)ceil((minMax[3 + i] - minMax[i]) / cellSize); + CGAL_assertion(res[i] > 0); } + std::size_t LUTSize = res[0] * res[1] * res[2]; LUT.resize(LUTSize); LUT.assign(LUTSize, 0); From ce8f779a55866812d981c0db3377084472e547c5 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 4 Mar 2021 14:44:22 +0100 Subject: [PATCH 238/248] remove debug assertion --- .../include/CGAL/Tetrahedral_remeshing/internal/FMLS.h | 1 - 1 file changed, 1 deletion(-) diff --git a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/FMLS.h b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/FMLS.h index 1eee358227b..500279aad4b 100644 --- a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/FMLS.h +++ b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/FMLS.h @@ -391,7 +391,6 @@ private: res[i] = (std::size_t)ceil((minMax[3 + i] - minMax[i]) / cellSize); if(res[1] == 0) res[i] = 1; - CGAL_assertion(res[i] > 0); } std::size_t LUTSize = res[0] * res[1] * res[2]; From fa44e3c5438e88da3ee257912db2411c9a1148db Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Fri, 5 Mar 2021 08:18:45 +0000 Subject: [PATCH 239/248] Add missing const --- STL_Extension/include/CGAL/hash_openmesh.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/STL_Extension/include/CGAL/hash_openmesh.h b/STL_Extension/include/CGAL/hash_openmesh.h index bab5dc40918..e9a70a1bb30 100644 --- a/STL_Extension/include/CGAL/hash_openmesh.h +++ b/STL_Extension/include/CGAL/hash_openmesh.h @@ -43,7 +43,10 @@ public: } bool - operator!=(const OMesh_edge& other) { return !(*this == other); } + operator!=(const OMesh_edge& other) const + { + return !(*this == other); + } Halfedge_handle opposite() const { return Halfedge_handle((halfedge_.idx() & 1) ? halfedge_.idx()-1 : halfedge_.idx()+1); } From bcae74fb335c8055b81dcfe0ae499c40f5261f69 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Mon, 8 Mar 2021 09:44:20 +0100 Subject: [PATCH 240/248] Update doc for vcpkg use --- Documentation/doc/Documentation/windows.txt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Documentation/doc/Documentation/windows.txt b/Documentation/doc/Documentation/windows.txt index 77021a27a28..23ab27957b5 100644 --- a/Documentation/doc/Documentation/windows.txt +++ b/Documentation/doc/Documentation/windows.txt @@ -43,12 +43,16 @@ We refer to the
    official documentation of `vcpkg` if you want to compile for an older version of a compiler. +Because of a bug with gmp in vcpkg for windows, you need to install `yasm-tool` in 32 bits to be able to correctly build gmp 64bits, needed for cgal: + + C:\dev\vcpkg> ./vcpkg.exe install yasm-tool:x86-windows + You are now ready to install \cgal: C:\dev\vcpkg> ./vcpkg.exe install cgal -This will take several minutes as it downloads \mpir (a fork of \gmp), -\mpfr, all boost header files, and it will compile \mpir and \mpfr, as well +This will take several minutes as it downloads \gmp, +\mpfr, all boost header files, and it will compile \gmp and \mpfr, as well as several boost libraries. Afterwards, you will find the include files, libraries, and dlls in the subdirectory `C:\dev\vcpkg\installed\x64-windows`. From eb04a9b3ced7bda67df70a56c7a89b65dbb17760 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Wed, 10 Mar 2021 11:42:07 +0100 Subject: [PATCH 241/248] Add change description in CHANGES.md --- Installation/CHANGES.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Installation/CHANGES.md b/Installation/CHANGES.md index 1bd032a7859..79d75c2e681 100644 --- a/Installation/CHANGES.md +++ b/Installation/CHANGES.md @@ -25,6 +25,9 @@ A comprehensive list of the supported file formats is available in the Stream_su - Added a filtering mechanism so that costly tests get only applied to the next candidate for the edge collapse. - Added the class `Polyhedral_envelope_filter` that enables to perform mesh simplification inside a polyhedral envelope of the input mesh. +### [dD Triangulations](https://cgal.geometryfactory.com/CGAL/doc/master/Manual/packages.html#PkgTriangulations) +- Added the function `insert_if_in_star()` to the class `CGAL::Regular_triangulation`, which enables users to insert a point `p` in a regular triangulation on the condition that `p` appears post-insertion in the star of a user-specified, existing vertex. + [Release 5.2](https://github.com/CGAL/cgal/releases/tag/v5.2) ----------- From 63779d416d6250582bc09a7c5de4abbead7b361b Mon Sep 17 00:00:00 2001 From: John Mullee Date: Tue, 16 Mar 2021 16:45:25 +0000 Subject: [PATCH 242/248] Tutorial_GIS.txt: fandom rorest -> random forest fandom rorest -> random forest --- Documentation/doc/Documentation/Tutorials/Tutorial_GIS.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/doc/Documentation/Tutorials/Tutorial_GIS.txt b/Documentation/doc/Documentation/Tutorials/Tutorial_GIS.txt index 255f39a5f5c..9ac43d3eb53 100644 --- a/Documentation/doc/Documentation/Tutorials/Tutorial_GIS.txt +++ b/Documentation/doc/Documentation/Tutorials/Tutorial_GIS.txt @@ -276,7 +276,7 @@ classifier currently available in \cgal is the %random forest from ETHZ. As it is a supervised classifier, a training set is needed. The following snippet shows how to use some manually selected training -set to train a %fandom rorest classifier and compute a classification +set to train a %random forest classifier and compute a classification regularized by a graph cut algorithm: \snippet Classification/gis_tutorial_example.cpp Classification From 11b69df045a7f418c211f7bc2dcdda9c3c93681e Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Wed, 17 Mar 2021 17:49:33 +0100 Subject: [PATCH 243/248] Fix tag_pr_per_release.sh to work with non-fast-forward updates --- Scripts/developer_scripts/tag_pr_per_release.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scripts/developer_scripts/tag_pr_per_release.sh b/Scripts/developer_scripts/tag_pr_per_release.sh index a8927dcfe17..36e8c56e859 100644 --- a/Scripts/developer_scripts/tag_pr_per_release.sh +++ b/Scripts/developer_scripts/tag_pr_per_release.sh @@ -30,7 +30,7 @@ REMOTE=`git config branch.releases/CGAL-${PREVIOUS_MAJOR_RELEASE}-branch.remote # Call git-fetch to refresh the branch, and fetch the references # refs/pull/*/head as well. -git fetch --tags "${REMOTE}" `git config "remote.${REMOTE}.fetch"` 'refs/pull/*/head:refs/pull/*/head' +git fetch --tags "${REMOTE}" `git config --get-all "remote.${REMOTE}.fetch"` '+refs/pull/*/head:refs/pull/*/head' PR_LIST=`git log --pretty='%D' v${PREVIOUS_MAJOR_RELEASE}..v${CURRENT_RELEASE} | awk 'match($0, /refs\/pull\/([0-9]+)\/head/, a) {print a[1]}' | sort -u` From a95295f9a647f47f090fc8c8f7781f4e3e79f8e9 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Wed, 17 Mar 2021 17:50:53 +0100 Subject: [PATCH 244/248] This branch now targets 5.1.4 --- Installation/include/CGAL/version.h | 4 ++-- Installation/lib/cmake/CGAL/CGALConfigVersion.cmake | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Installation/include/CGAL/version.h b/Installation/include/CGAL/version.h index 200d3f8c224..ce0eb66b83d 100644 --- a/Installation/include/CGAL/version.h +++ b/Installation/include/CGAL/version.h @@ -17,10 +17,10 @@ #define CGAL_VERSION_H #ifndef SWIG -#define CGAL_VERSION 5.1.3 +#define CGAL_VERSION 5.1.4 #define CGAL_GIT_HASH abcdef #endif -#define CGAL_VERSION_NR 1050131000 +#define CGAL_VERSION_NR 1050141000 #define CGAL_SVN_REVISION 99999 #define CGAL_RELEASE_DATE 20200908 diff --git a/Installation/lib/cmake/CGAL/CGALConfigVersion.cmake b/Installation/lib/cmake/CGAL/CGALConfigVersion.cmake index 9157d5e817e..27ba24fb747 100644 --- a/Installation/lib/cmake/CGAL/CGALConfigVersion.cmake +++ b/Installation/lib/cmake/CGAL/CGALConfigVersion.cmake @@ -1,8 +1,8 @@ set(CGAL_MAJOR_VERSION 5) set(CGAL_MINOR_VERSION 1) -set(CGAL_BUGFIX_VERSION 3) +set(CGAL_BUGFIX_VERSION 4) include(${CMAKE_CURRENT_LIST_DIR}/CGALConfigBuildVersion.cmake) -set(CGAL_VERSION_PUBLIC_RELEASE_VERSION "5.1.3") +set(CGAL_VERSION_PUBLIC_RELEASE_VERSION "5.1.4") set(CGAL_VERSION_PUBLIC_RELEASE_NAME "CGAL-${CGAL_VERSION_PUBLIC_RELEASE_VERSION}") if (CGAL_BUGFIX_VERSION AND CGAL_BUGFIX_VERSION GREATER 0) From ea27c113737056dd84e3842b63f55c73e3a4dae8 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Wed, 17 Mar 2021 17:51:40 +0100 Subject: [PATCH 245/248] This branch now targets 5.2.2 --- Installation/include/CGAL/version.h | 4 ++-- Installation/lib/cmake/CGAL/CGALConfigVersion.cmake | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Installation/include/CGAL/version.h b/Installation/include/CGAL/version.h index 223b67d3c8f..87f479368f1 100644 --- a/Installation/include/CGAL/version.h +++ b/Installation/include/CGAL/version.h @@ -17,10 +17,10 @@ #define CGAL_VERSION_H #ifndef SWIG -#define CGAL_VERSION 5.2.1 +#define CGAL_VERSION 5.2.2 #define CGAL_GIT_HASH abcdef #endif -#define CGAL_VERSION_NR 1050211000 +#define CGAL_VERSION_NR 1050221000 #define CGAL_SVN_REVISION 99999 #define CGAL_RELEASE_DATE 20201221 diff --git a/Installation/lib/cmake/CGAL/CGALConfigVersion.cmake b/Installation/lib/cmake/CGAL/CGALConfigVersion.cmake index 7bf82132599..ff1fd754f40 100644 --- a/Installation/lib/cmake/CGAL/CGALConfigVersion.cmake +++ b/Installation/lib/cmake/CGAL/CGALConfigVersion.cmake @@ -1,8 +1,8 @@ set(CGAL_MAJOR_VERSION 5) set(CGAL_MINOR_VERSION 2) -set(CGAL_BUGFIX_VERSION 1) +set(CGAL_BUGFIX_VERSION 2) include(${CMAKE_CURRENT_LIST_DIR}/CGALConfigBuildVersion.cmake) -set(CGAL_VERSION_PUBLIC_RELEASE_VERSION "5.2.1") +set(CGAL_VERSION_PUBLIC_RELEASE_VERSION "5.2.2") set(CGAL_VERSION_PUBLIC_RELEASE_NAME "CGAL-${CGAL_VERSION_PUBLIC_RELEASE_VERSION}") if (CGAL_BUGFIX_VERSION AND CGAL_BUGFIX_VERSION GREATER 0) From e2970844668bbf3002a20a1f373d62a28e772c0f Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Thu, 18 Mar 2021 12:07:14 +0100 Subject: [PATCH 246/248] Add CGAL-5.2-win64-auxiliary-libraries-gmp-mpfr.zip to the assert for releases --- Maintenance/public_release/scripts/prepare_release | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Maintenance/public_release/scripts/prepare_release b/Maintenance/public_release/scripts/prepare_release index 639f9fe5c63..889c7e99da3 100755 --- a/Maintenance/public_release/scripts/prepare_release +++ b/Maintenance/public_release/scripts/prepare_release @@ -81,6 +81,10 @@ pushd "$DEST_DIR/doc_html" zip -q -r ../cgal_manual.zip * popd +pushd /srv/CGAL/www/precompiled_libs/auxiliary/x64/ +cp CGAL-5.2-win64-auxiliary-libraries-gmp-mpfr.zip "$DEST_DIR/${PUBLIC_RELEASE_NAME}-win64-auxiliary-libraries-gmp-mpfr.zip" +popd + pushd "$DEST_DIR" printf "Compute md5sum.txt..." md5sum *.^txt > md5sum.txt From 64401b8a0611152459198fb1472e80f2fe5772c1 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Thu, 18 Mar 2021 12:08:08 +0100 Subject: [PATCH 247/248] Use gh (the official Github CLI) instead of github-release --- .../public_release/scripts/github-release-upload | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/Maintenance/public_release/scripts/github-release-upload b/Maintenance/public_release/scripts/github-release-upload index 760916fd838..8a253f112bd 100755 --- a/Maintenance/public_release/scripts/github-release-upload +++ b/Maintenance/public_release/scripts/github-release-upload @@ -3,11 +3,8 @@ # Should be run in the directory with the release files, and named after # the release name, like "CGAL-4.9.1". -# Use github-release from -# https://github.com/aktau/github-release +release=${${PWD:t}/CGAL-/} +tag=v${release} -source $HOME/private/github-token.txt - -for f in *.(zip|xz|txt|exe); do - github-release upload -u CGAL -r cgal -t v${${PWD:t}/CGAL-/} --name $f -f $f; -done +gh release upload "$tag" *.(zip|xz|txt|exe) -R CGAL/cgal +gh release upload "$tag" CGAL-${release}-win64-auxiliary-libraries-gmp-mpfr.zip'#GMP and MPFR libraries, for Windows 64bits' -R CGAL/cgal --clobber From 453b61100270295e8b046bb71c9ccc93146fdb33 Mon Sep 17 00:00:00 2001 From: albert-github Date: Fri, 19 Mar 2021 12:35:30 +0100 Subject: [PATCH 248/248] OUTPUT_TEXT_DIRECTION has been made obsolete The doxygen setting OUTPUT_TEXT_DIRECTION is obsolete --- Documentation/doc/resources/1.8.20/BaseDoxyfile.in | 8 -------- 1 file changed, 8 deletions(-) diff --git a/Documentation/doc/resources/1.8.20/BaseDoxyfile.in b/Documentation/doc/resources/1.8.20/BaseDoxyfile.in index 93dad8c7100..767fa9f07b2 100644 --- a/Documentation/doc/resources/1.8.20/BaseDoxyfile.in +++ b/Documentation/doc/resources/1.8.20/BaseDoxyfile.in @@ -93,14 +93,6 @@ ALLOW_UNICODE_NAMES = NO OUTPUT_LANGUAGE = English -# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all generated output in the proper direction. -# Possible values are: None, LTR, RTL and Context. -# The default value is: None. - -OUTPUT_TEXT_DIRECTION = None - # If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member # descriptions after the members that are listed in the file and class # documentation (similar to Javadoc). Set to NO to disable this.