diff --git a/Constrained_triangulation_3/include/CGAL/Conforming_constrained_Delaunay_triangulation_3.h b/Constrained_triangulation_3/include/CGAL/Conforming_constrained_Delaunay_triangulation_3.h index 75286ad367c..68452fbe32e 100644 --- a/Constrained_triangulation_3/include/CGAL/Conforming_constrained_Delaunay_triangulation_3.h +++ b/Constrained_triangulation_3/include/CGAL/Conforming_constrained_Delaunay_triangulation_3.h @@ -603,6 +603,39 @@ struct Output_rep, With_point_and_info_t template class Conforming_constrained_Delaunay_triangulation_3_impl; +namespace internal { +struct Pair_hash +{ + template + std::size_t operator()(const std::pair& p) const { + return boost::hash>()(p); + } + template + std::size_t hash(const Pair& p) const { + return this->operator()(p); + } + template + bool equal(const T& v1, const T& v2) const { + return v1 == v2; + } +}; + +template +struct Hash_map_of_pairs_type +{ + typedef CGAL::unordered_flat_map type; +}; + +#ifdef CGAL_LINKED_WITH_TBB +template +struct Hash_map_of_pairs_type +{ + typedef tbb::concurrent_hash_map type; +}; +#endif +} // namespace internal + + #endif // not DOXYGEN_RUNNING /*! @@ -1101,7 +1134,7 @@ class Conforming_constrained_Delaunay_triangulation_3 */ CDT_3_signed_index face_constraint_index(typename Triangulation::Cell_handle ch, int i) const { - return ch->ccdt_3_data().face_constraint_index(i); + return face_constraint_index(typename Triangulation::Facet(ch, i)); } /*! @@ -1111,7 +1144,7 @@ class Conforming_constrained_Delaunay_triangulation_3 */ CDT_3_signed_index face_constraint_index(const typename Triangulation::Facet& f) const { - return face_constraint_index(f.first, f.second); + return cdt_impl.face_constraint_index(f); } /*! @@ -1205,6 +1238,10 @@ class Conforming_constrained_Delaunay_triangulation_3 void write_facets(std::ostream& out, const CDT& cdt, FacetRange&& facets) const { cdt_impl.write_facets(out, cdt, std::forward(facets)); } + + friend std::ostream& operator<<(std::ostream& out, const Conforming_constrained_Delaunay_triangulation_3& ccdt) { + return out << ccdt.cdt_impl; + } }; #ifndef DOXYGEN_RUNNING @@ -1264,6 +1301,19 @@ class Conforming_constrained_Delaunay_triangulation_3_impl : public Conforming_D Constrained_facets_range constrained_facets() const { return {constrained_facets_begin(), constrained_facets_end()}; } + +public: // @tmp + struct Facet_prop + { + CDT_3_signed_index face_id = -1; + void* facet_2d = nullptr; + }; + using Surface_facet_info = + typename internal::Hash_map_of_pairs_type::type; + mutable Surface_facet_info surface_facet_info_; + private: struct CDT_2_types { @@ -1328,15 +1378,67 @@ class Conforming_constrained_Delaunay_triangulation_3_impl : public Conforming_D public: using Constrained_polyline_id = typename Constraint_hierarchy::Constraint_id; +public: + CDT_3_signed_index face_constraint_index(Cell_handle cell, int facet_index) const + { + return surface_facet_info_[Facet{cell, facet_index}].face_id; + } + CDT_3_signed_index face_constraint_index(const Facet& f) const + { + return face_constraint_index(f.first, f.second); + } + protected: + void set_face_constraint_index(Cell_handle cell, int facet_index, CDT_3_signed_index index) + { + surface_facet_info_[Facet{cell, facet_index}].face_id = index; + } + + template + auto face_2(const CDT_2& cdt, Cell_handle cell, int facet_index) const + { + using Face = typename CDT_2::Face; + auto ptr = static_cast(surface_facet_info_[Facet{cell, facet_index}].facet_2d); + return cdt.tds().faces().iterator_to(*ptr); + } + + template + void set_facet_constraint(Cell_handle cell, int facet_index, + CDT_3_signed_index face_id, + Facet_handle facet_2d) + { + const Facet facet{cell, facet_index}; + const auto f2d = static_cast(facet_2d == Facet_handle{} ? nullptr : std::addressof(*facet_2d)); + + auto surface_facet_info_it = surface_facet_info_.find(facet); + if(surface_facet_info_it != surface_facet_info_.end()) { + if(face_id >= 0) + { + surface_facet_info_it->second.face_id = face_id; + surface_facet_info_it->second.facet_2d = f2d; + } else + { + surface_facet_info_.erase(surface_facet_info_it);//not constrained anymore + } + } + else { + surface_facet_info_.emplace(facet, Facet_prop{face_id, f2d}); + } + } + + void cleanup_surface_facet_info(Cell_handle c) { + for(int i = 0; i < 4; ++i) { + surface_facet_info_.erase(Facet{c, i}); + } + } void register_facet_to_be_constrained(Cell_handle cell, int facet_index) { - const auto face_id = static_cast(cell->ccdt_3_data().face_constraint_index(facet_index)); + const auto face_id = static_cast(face_constraint_index(cell, facet_index)); this->face_constraint_misses_subfaces_set(face_id); - auto fh_2 = cell->ccdt_3_data().face_2(this->face_cdt_2(face_id), facet_index); + auto fh_2 = face_2(this->face_cdt_2(face_id), cell, facet_index); fh_2->info().facet_3d = Facet{}; fh_2->info().missing_subface = true; - this->set_facet_constrained({cell, facet_index}, -1, {}); + this->set_facet_unconstrained({cell, facet_index}); } void register_facet_to_be_constrained(Facet f) { @@ -1360,7 +1462,7 @@ class Conforming_constrained_Delaunay_triangulation_3_impl : public Conforming_D for(auto cell_it = cell_it_begin; cell_it != end; ++cell_it) { auto c = *cell_it; for(int li = first_li; li < 4; ++li) { - if(c->ccdt_3_data().is_facet_constrained(li)) { + if(self->is_facet_constrained(c, li)) { #if CGAL_CDT_3_DEBUG_MISSING_TRIANGLES auto face_id = static_cast(c->ccdt_3_data().face_constraint_index(li)); auto fh_2 = c->ccdt_3_data().face_2(self->face_cdt_2(face_id), li); @@ -1509,7 +1611,6 @@ class Conforming_constrained_Delaunay_triangulation_3_impl : public Conforming_D for(auto [ch, _] : exterior_border_facets_of_original_cavity) { ch->tds_data().clear(); } - bool the_infinite_vertex_is_in_the_cavity = false; std::set vertices_of_original_cavity; for(Cell_handle ch : cells_of_original_cavity) { @@ -1563,15 +1664,16 @@ class Conforming_constrained_Delaunay_triangulation_3_impl : public Conforming_D for(auto outside_facet : facets_of_cavity) { const auto [outside_cell, outside_face_index] = outside_facet; const auto mirror_facet = this->mirror_facet(outside_facet); - if(outside_cell->ccdt_3_data().is_facet_constrained(outside_face_index)) { - const auto polygon_id = outside_cell->ccdt_3_data().face_constraint_index(outside_face_index); + if(is_facet_constrained(outside_cell, outside_face_index)) { + const auto polygon_id = face_constraint_index(outside_cell, outside_face_index); const CDT_2& cdt_2 = face_cdt_2(polygon_id); - const auto f2d = outside_cell->ccdt_3_data().face_2(cdt_2, outside_face_index); + const auto f2d = face_2(cdt_2, outside_cell, outside_face_index); set_facet_constrained(mirror_facet, polygon_id, f2d); } } for(auto c: cells_of_cavity) { + this->cleanup_surface_facet_info(c); this->tds().delete_cell(c); } @@ -1752,13 +1854,16 @@ class Conforming_constrained_Delaunay_triangulation_3_impl : public Conforming_D } bool is_facet_constrained(Facet f) const { - return f.first->ccdt_3_data().is_facet_constrained(f.second); + return face_constraint_index(f.first, f.second) >= 0; + } + bool is_facet_constrained(Cell_handle c, int facet_index) const { + return face_constraint_index(c, facet_index) >= 0; } auto number_of_constrained_facets() const { return std::count_if(tr().all_facets_begin(), tr().all_facets_end(), - [this](auto f) { return is_facet_constrained(f); }); + [&](auto f) { return is_facet_constrained(f); }); } bool same_triangle(Facet f, CDT_2_face_handle fh) const { @@ -1781,10 +1886,11 @@ class Conforming_constrained_Delaunay_triangulation_3_impl : public Conforming_D CGAL_assertion(fh == CDT_2_face_handle{} || same_triangle(f, fh)); const auto [c, facet_index] = f; - c->ccdt_3_data().set_facet_constraint(facet_index, polygon_constraint_id, fh); + set_facet_constraint(c, facet_index, polygon_constraint_id, fh); + if(tr().dimension() > 2) { const auto [n, n_index] = tr().mirror_facet({c, facet_index}); - n->ccdt_3_data().set_facet_constraint(n_index, polygon_constraint_id, fh); + set_facet_constraint(n, n_index, polygon_constraint_id, fh); } if(fh == CDT_2_face_handle{}) return; @@ -1794,6 +1900,11 @@ class Conforming_constrained_Delaunay_triangulation_3_impl : public Conforming_D } } + void set_facet_unconstrained(Facet f) + { + this->set_facet_constrained(f, -1, {}); + } + template ) Polygon> std::optional register_new_constrained_polygon(Polygon&& polygon) { return insert_constrained_polygon(std::forward(polygon), false); @@ -2364,7 +2475,8 @@ class Conforming_constrained_Delaunay_triangulation_3_impl : public Conforming_D bool search_for_missing_subfaces(CDT_3_signed_index polygon_constraint_id, - Search_for_missing_subfaces_option option = Search_for_missing_subfaces_option::DEFAULT) { + Search_for_missing_subfaces_option option = Search_for_missing_subfaces_option::DEFAULT) + { bool something_has_changed = false; const CDT_2& cdt_2 = face_cdt_2(polygon_constraint_id); @@ -2398,7 +2510,9 @@ class Conforming_constrained_Delaunay_triangulation_3_impl : public Conforming_D << this->display_vert(v2) << '\n'; } } - set_facet_constrained({c, facet_index}, polygon_constraint_id, fh); + if(option != Search_for_missing_subfaces_option::SEARCH_FOR_UNCONSTRAINED_FACETS) { + set_facet_constrained({c, facet_index}, polygon_constraint_id, fh); + } } } if(option == Search_for_missing_subfaces_option::SEARCH_FOR_UNCONSTRAINED_FACETS && something_has_changed) { @@ -3585,16 +3699,17 @@ class Conforming_constrained_Delaunay_triangulation_3_impl : public Conforming_D if(this->debug().copy_triangulation_into_hole()) { std::cerr << "delete cell " << IO::oformat(c) << "\n"; } + this->cleanup_surface_facet_info(c); this->tds().delete_cell(c); } auto restore_markers = [&](Facet outside_facet) { const auto [outside_cell, outside_face_index] = outside_facet; const auto mirror_facet = this->mirror_facet(outside_facet); - if(outside_cell->ccdt_3_data().is_facet_constrained(outside_face_index)) { - const auto polygon_id = outside_cell->ccdt_3_data().face_constraint_index(outside_face_index); + if(is_facet_constrained(outside_cell, outside_face_index)) { + const auto polygon_id = face_constraint_index(outside_cell, outside_face_index); const CDT_2& cdt_2 = face_cdt_2(polygon_id); - const auto f2d = outside_cell->ccdt_3_data().face_2(cdt_2, outside_face_index); + const auto f2d = face_2(cdt_2, outside_cell, outside_face_index); set_facet_constrained(mirror_facet, polygon_id, f2d); } }; @@ -3780,7 +3895,7 @@ class Conforming_constrained_Delaunay_triangulation_3_impl : public Conforming_D } for(auto [cell, facet_index] : missing_faces) { facets_of_cavity_border.erase({cell, facet_index}); - if(cell->ccdt_3_data().is_facet_constrained(facet_index)) { + if(is_facet_constrained(cell, facet_index)) { result.interior_constrained_faces.emplace_back(cell, facet_index); } auto is_new_cell = cells_of_cavity.insert(cell).second; @@ -4104,7 +4219,7 @@ class Conforming_constrained_Delaunay_triangulation_3_impl : public Conforming_D const auto n_index = n->index(it); if(!this->is_infinite(n->vertex(n_index))) { - if(!it->ccdt_3_data().is_facet_constrained(i) && + if(!is_facet_constrained(it, i) && this->side_of_sphere(it, n->vertex(n_index)->point()) == ON_BOUNDED_SIDE) { if(verbose) { @@ -4301,7 +4416,11 @@ class Conforming_constrained_Delaunay_triangulation_3_impl : public Conforming_D CGAL_assertion_msg( recheck_for_missing_subfaces() && face_constraint_misses_subfaces_find_first() == face_constraint_misses_subfaces_npos, - "All faces have been restored, but the triangulation is still not a CDT. This should not happen."); + std::invoke([&] { + dump_triangulation_to_off(); + dump_triangulation(); + return "All faces have been restored, but the triangulation is still not a CDT. This should not happen."; + })); } void add_bbox_points_if_not_dimension_3() { @@ -4742,9 +4861,29 @@ class Conforming_constrained_Delaunay_triangulation_3_impl : public Conforming_D write_3d_triangulation_to_OFF(dump, tr); } - void dump_triangulation() const { - std::ofstream dump("dump.binary.cgal", std::ios::binary); - CGAL::IO::save_binary_file(dump, *this); + friend std::ostream& operator<<(std::ostream& out, const Conforming_constrained_Delaunay_triangulation_3_impl& ccdt_impl) { + out << ccdt_impl.tr(); + if(IO::is_ascii(out)) { + for(auto ch : ccdt_impl.tr().all_cell_handles()) { + for(int li = 0; li < 4; ++li) { + if(li > 0) out << " "; + out << ccdt_impl.face_constraint_index(ch, li); + } + out << '\n'; + } + } else { + for(auto ch : ccdt_impl.tr().all_cell_handles()) { + for(int li = 0; li < 4; ++li) { + CGAL::write(out, ccdt_impl.face_constraint_index(ch, li)); + } + } + } + return out; + } + + void dump_triangulation(std::string_view file_name = "dump.binary.cgal", IO::Mode mode = IO::BINARY) const { + std::ofstream dump(file_name.data(), mode == IO::BINARY ? std::ios::binary : std::ios::out); + CGAL::IO::save_binary_file(dump, *this, mode == IO::BINARY); } void dump_triangulation_to_off() const { @@ -5117,6 +5256,20 @@ auto get_remeshing_triangulation(Conforming_constrained_Delaunay_triangulation_3 } } + boost::unordered_map constraint_index_map; + for(auto [c, index] : ccdt.triangulation().finite_facets()) + { + if(ccdt.is_facet_constrained(c, index)) + { + typename Tr::Facet f(c, index); + + auto findex = ccdt.face_constraint_index(f); + constraint_index_map[f] = findex; + auto mirror_f = ccdt.triangulation().mirror_facet(f); + constraint_index_map[mirror_f] = findex; + } + } + auto tr = std::move(ccdt).triangulation(); using CDT_3 = Conforming_constrained_Delaunay_triangulation_3; @@ -5127,10 +5280,16 @@ auto get_remeshing_triangulation(Conforming_constrained_Delaunay_triangulation_3 for(auto ch : tr.all_cell_handles()) { ch->set_subdomain_index(0); } - for(auto [c, index] : tr.finite_facets()) { - if(c->ccdt_3_data().is_facet_constrained(index)) { - auto patch = c->ccdt_3_data().face_constraint_index(index) + 1; - c->set_surface_patch_index(index, patch); + for(const auto& f : tr.finite_facets()) + { + auto f_patch_it = constraint_index_map.find(f); + if(f_patch_it != constraint_index_map.end()) + { + const auto& patch = f_patch_it->second; + auto mirror_f = ccdt.triangulation().mirror_facet(f); + + f.first->set_surface_patch_index(f.second, patch); + mirror_f.first->set_surface_patch_index(mirror_f.second, patch); } } } else { @@ -5138,6 +5297,19 @@ auto get_remeshing_triangulation(Conforming_constrained_Delaunay_triangulation_3 ch->set_subdomain_index(-1); } + auto is_f_constrained = [&](typename Tr::Cell_handle ch, int index) -> bool + { + typename Tr::Facet f(ch, index); + return constraint_index_map.find(f) != constraint_index_map.end(); + }; + auto f_constraint_index = [&](typename Tr::Cell_handle ch, int index) -> std::size_t + { + typename Tr::Facet f(ch, index); + auto it = constraint_index_map.find(f); + CGAL_assertion(it != constraint_index_map.end()); + return it->second; + }; + // Use a flood algorithm to mark constrained connected components. // The connected component containing the infinite vertex is marked with index 0. // Nested components are marked with increasing indices. @@ -5148,7 +5320,10 @@ auto get_remeshing_triangulation(Conforming_constrained_Delaunay_triangulation_3 int next_odd_subdomain = 1; // Function to flood-fill a connected component with a given subdomain index - auto flood_component = [&border](typename Tr::Cell_handle start, int subdomain_index) { + auto flood_component + = [&border, &is_f_constrained] + (typename Tr::Cell_handle start, int subdomain_index) + { if(start->subdomain_index() != -1) return; @@ -5164,7 +5339,7 @@ auto get_remeshing_triangulation(Conforming_constrained_Delaunay_triangulation_3 typename Tr::Facet f(ch, i); auto n = ch->neighbor(i); if(n->subdomain_index() == -1) { - if(ch->ccdt_3_data().is_facet_constrained(i)) + if(is_f_constrained(ch, i)) border.push(f); else queue.push(n); @@ -5211,10 +5386,10 @@ auto get_remeshing_triangulation(Conforming_constrained_Delaunay_triangulation_3 for(auto f : tr.finite_facets()) { auto mf = tr.mirror_facet(f); - if(f.first->ccdt_3_data().is_facet_constrained(f.second) || - mf.first->ccdt_3_data().is_facet_constrained(mf.second)) + if(is_f_constrained(f.first, f.second) || + is_f_constrained(mf.first, mf.second)) { - auto patch = f.first->ccdt_3_data().face_constraint_index(f.second) + 1; + auto patch = f_constraint_index(f.first, f.second) + 1; f.first->set_surface_patch_index(f.second, patch); mf.first->set_surface_patch_index(mf.second, patch); } diff --git a/Constrained_triangulation_3/include/CGAL/Conforming_constrained_Delaunay_triangulation_cell_base_3.h b/Constrained_triangulation_3/include/CGAL/Conforming_constrained_Delaunay_triangulation_cell_base_3.h index f109feaed16..4bdc31758ff 100644 --- a/Constrained_triangulation_3/include/CGAL/Conforming_constrained_Delaunay_triangulation_cell_base_3.h +++ b/Constrained_triangulation_3/include/CGAL/Conforming_constrained_Delaunay_triangulation_cell_base_3.h @@ -70,9 +70,9 @@ class Conforming_constrained_Delaunay_triangulation_cell_base_3 } static std::string io_signature() { - static_assert( - std::is_same_v< - decltype(std::declval().face_constraint_index(0)), int>); +// static_assert( +// std::is_same_v< +// decltype(std::declval().face_constraint_index(0)), int>); return Get_io_signature()() + "+(" + Get_io_signature()() + ")[4]"; } @@ -82,13 +82,13 @@ class Conforming_constrained_Delaunay_triangulation_cell_base_3 const Conforming_constrained_Delaunay_triangulation_cell_base_3& c) { os << static_cast(c); - for( unsigned li = 0; li < 4; ++li ) { - if(IO::is_ascii(os)) { - os << " " << c.ccdt_3_data().face_constraint_index(li); - } else { - CGAL::write(os, c.ccdt_3_data().face_constraint_index(li)); - } - } + //for( unsigned li = 0; li < 4; ++li ) { + // if(IO::is_ascii(os)) { + // os << " " << face_constraint_index(c, li); + // } else { + // CGAL::write(os, face_constraint_index(c, li)); + // } + //} return os; } friend std::istream& @@ -97,16 +97,16 @@ class Conforming_constrained_Delaunay_triangulation_cell_base_3 { is >> static_cast(c); if(!is) return is; - for( int li = 0; li < 4; ++li ) { - int i; - if(IO::is_ascii(is)) { - is >> i; - } else { - CGAL::read(is, i); - } - if(!is) return is; - c->ccdt_3_data().set_face_constraint_index(li, i); - } +// for( int li = 0; li < 4; ++li ) { +// int i; +// if(IO::is_ascii(is)) { +// is >> i; +// } else { +// CGAL::read(is, i); +// } +// if(!is) return is; +// set_face_constraint_index(c, li, i); +// } return is; } }; diff --git a/Constrained_triangulation_3/include/CGAL/Conforming_constrained_Delaunay_triangulation_cell_data_3.h b/Constrained_triangulation_3/include/CGAL/Conforming_constrained_Delaunay_triangulation_cell_data_3.h index 91d9b73044a..9fb92555211 100644 --- a/Constrained_triangulation_3/include/CGAL/Conforming_constrained_Delaunay_triangulation_cell_data_3.h +++ b/Constrained_triangulation_3/include/CGAL/Conforming_constrained_Delaunay_triangulation_cell_data_3.h @@ -42,8 +42,6 @@ class Conforming_constrained_Delaunay_triangulation_cell_data_3 { template friend class Conforming_constrained_Delaunay_triangulation_3_impl; /// @endcond - std::array face_id = { -1, -1, -1, -1 }; - std::array facet_2d = {nullptr, nullptr, nullptr, nullptr}; std::bitset(CDT_3_cell_marker::nb_of_markers)> markers; bool is_marked() const { return markers.any(); } @@ -52,35 +50,6 @@ class Conforming_constrained_Delaunay_triangulation_cell_data_3 { void clear_mark(CDT_3_cell_marker m) { markers.reset(static_cast(m)); } void clear_marks() { markers.reset(); } - static unsigned int uint(int i) { return static_cast(i); } - - template - void set_facet_constraint(int i, CDT_3_signed_index face_id, - Facet_handle facet_2d) - { - this->face_id[uint(i)] = face_id; - this->facet_2d[uint(i)] = static_cast(facet_2d == Facet_handle{} ? nullptr : std::addressof(*facet_2d)); - } - - template - auto face_2 (const CDT_2& cdt, int i) const { - using Face = typename CDT_2::Face; - auto ptr = static_cast(facet_2d[uint(i)]); - return cdt.tds().faces().iterator_to(*ptr); - } -public: - /// @{ - // @cond SKIP_IN_MANUAL - bool is_facet_constrained(int i) const { return face_id[uint(i)] >= 0; } - - CDT_3_signed_index face_constraint_index(int i) const { - return face_id[uint(i)]; - } - - void set_face_constraint_index(int i, CDT_3_signed_index index) { - face_id[uint(i)] = index; - } - /// @endcond }; } // namespace CGAL diff --git a/Constrained_triangulation_3/include/CGAL/IO/write_MEDIT.h b/Constrained_triangulation_3/include/CGAL/IO/write_MEDIT.h index 94f48d27003..f975b7ac447 100644 --- a/Constrained_triangulation_3/include/CGAL/IO/write_MEDIT.h +++ b/Constrained_triangulation_3/include/CGAL/IO/write_MEDIT.h @@ -95,8 +95,10 @@ void write_MEDIT(std::ostream& os, const bool has_plc_face_id = choose_parameter(get_parameter(np, internal_np::with_plc_face_id), false); - auto plc_patch_map = boost::make_function_property_map([&](const Facet& f) - { return has_plc_face_id ? f.first->ccdt_3_data().face_constraint_index(f.second) + 1 : 1; }); + auto plc_patch_map = boost::make_function_property_map([&](const Facet& f) { + return has_plc_face_id + ? ccdt.face_constraint_index(f.first, f.second) + 1 + : 1; }); std::vector edges; return SMDS_3::output_to_medit(os, diff --git a/Constrained_triangulation_3/include/CGAL/draw_constrained_triangulation_3.h b/Constrained_triangulation_3/include/CGAL/draw_constrained_triangulation_3.h index 06787577176..4ca6d09908c 100644 --- a/Constrained_triangulation_3/include/CGAL/draw_constrained_triangulation_3.h +++ b/Constrained_triangulation_3/include/CGAL/draw_constrained_triangulation_3.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -34,35 +35,33 @@ void draw(const Conforming_constrained_Delaunay_triangulation_3& ccd { using Tr_ = CGAL::cpp20::remove_cvref_t; using Vertex_handle = typename Tr_::Vertex_handle; - using Cell_handle = typename Tr_::Cell_handle; using Edge_descriptor = typename Tr_::Finite_edges_iterator; using Facet_descriptor = typename Tr_::Finite_facets_iterator; - using Face_index = CGAL::cpp20::remove_cvref_t< - decltype(std::declval()->ccdt_3_data().face_constraint_index(0))>; + using Face_index = CDT_3_signed_index; Face_index nb_colors = 0; std::for_each( ccdt.constrained_facets_begin(), ccdt.constrained_facets_end(), [&](const auto& f) { auto [c, index] = f; - nb_colors = (std::max)(nb_colors, c->ccdt_3_data().face_constraint_index(index) + 1); + nb_colors = (std::max)(nb_colors, ccdt.face_constraint_index(c, index) + 1); }); std::vector colors(nb_colors); std::generate(colors.begin(), colors.end(), []() { return CGAL::get_random_color(CGAL::get_default_random()); }); CGAL::Graphics_scene_options options; - options.draw_face = [](const Tr_&, Facet_descriptor f) { + options.draw_face = [&](const Tr_&, Facet_descriptor f) { auto [c, index] = *f; - return c->ccdt_3_data().is_facet_constrained(index); + return ccdt.is_facet_constrained(c, index); }; options.colored_face = [](const Tr_&, Facet_descriptor) { return true; }; options.face_color = [&](const Tr_&, Facet_descriptor f) { auto [c, index] = *f; - return colors[c->ccdt_3_data().face_constraint_index(index)]; + return colors[ccdt.face_constraint_index(c, index)]; }; draw(ccdt.triangulation(), options, title); } diff --git a/Constrained_triangulation_3/test/Constrained_triangulation_3/cdt_3_from_off.cpp b/Constrained_triangulation_3/test/Constrained_triangulation_3/cdt_3_from_off.cpp index 635890f6b54..4ef93ed6c3a 100644 --- a/Constrained_triangulation_3/test/Constrained_triangulation_3/cdt_3_from_off.cpp +++ b/Constrained_triangulation_3/test/Constrained_triangulation_3/cdt_3_from_off.cpp @@ -386,7 +386,7 @@ std::function create_output_finalizer(const CDT& cdt, const CDT_options& cells_map[ch] = 0; for (int i = 0; i < 4; ++i) { - if(ch->ccdt_3_data().is_facet_constrained(i)) + if(cdt.is_facet_constrained(ch, i)) continue; auto n = ch->neighbor(i); if (cells_map[n] == 1) diff --git a/Generator/examples/Generator/random_points_in_tetrahedral_mesh_3.cpp b/Generator/examples/Generator/random_points_in_tetrahedral_mesh_3.cpp index 79a1ea4fd14..51c1853a9e6 100644 --- a/Generator/examples/Generator/random_points_in_tetrahedral_mesh_3.cpp +++ b/Generator/examples/Generator/random_points_in_tetrahedral_mesh_3.cpp @@ -32,7 +32,7 @@ typedef CGAL::Mesh_triangulation_3< typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; // (Unweighted) point type typedef Tr::Bare_point Point; diff --git a/Generator/examples/Generator/random_points_on_tetrahedral_mesh_3.cpp b/Generator/examples/Generator/random_points_on_tetrahedral_mesh_3.cpp index d564ee7c2f3..6620c9fb522 100644 --- a/Generator/examples/Generator/random_points_on_tetrahedral_mesh_3.cpp +++ b/Generator/examples/Generator/random_points_on_tetrahedral_mesh_3.cpp @@ -31,7 +31,7 @@ typedef CGAL::Mesh_triangulation_3< typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; // (Unweighted) point type typedef Tr::Bare_point Point; diff --git a/Generator/test/Generator/generic_random_test.cpp b/Generator/test/Generator/generic_random_test.cpp index 04fd728d915..1579c7f6374 100644 --- a/Generator/test/Generator/generic_random_test.cpp +++ b/Generator/test/Generator/generic_random_test.cpp @@ -55,7 +55,7 @@ typedef Mesh_domain::Curve_index Curve_index; typedef CGAL::Mesh_triangulation_3::type Tr; typedef CGAL::Mesh_complex_3_in_triangulation_3< Tr, Corner_index, Curve_index> C3t3; -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; typedef C3t3::Point Point; int test_triangles_2(const FT eps) diff --git a/Installation/CHANGES.md b/Installation/CHANGES.md index 36113d25617..25bde9dcb97 100644 --- a/Installation/CHANGES.md +++ b/Installation/CHANGES.md @@ -46,6 +46,15 @@ Release date: December 2026 - Deprecated the existing overload of `snap_rounding_2()`. - Added a new overload of `snap_rounding_2()` that automatically dispatch to either `vertical_slab_snap_rounding_2()` or `hot_pixel_snap_rounding_2()`, depending on the provided traits class. +### [3D Mesh Generation](https://doc.cgal.org/6.3/Manual/packages.html#PkgMesh3) + +- **Breaking change**: The template parameter of `CGAL::Mesh_cell_criteria_3`, + `CGAL::Mesh_edge_criteria_3`, and `CGAL::Mesh_facet_criteria_3` is now the + mesh complex type `C3T3`, rather than its triangulation type. Code that + explicitly instantiates these criteria classes must be updated accordingly. + `CGAL::Mesh_criteria_3` also uses `C3T3` as its template parameter, but + continues to accept the triangulation type for backward compatibility. + ### [3D Triangulations](https://doc.cgal.org/6.3/Manual/packages.html#PkgTriangulation3) - **Breaking change** Removed the class template `Regular_triangulation_euclidean_traits_3` which was deprecated since CGAL-4.10 - **Breaking change** Removed the member function `vertices_in_conflict()` of the Delaunay and the regular triangulation which were deprecated since CGAL-3.8 diff --git a/Installation/include/CGAL/Mesh_3/Mesh_complex_3_in_triangulation_3_fwd.h b/Installation/include/CGAL/Mesh_3/Mesh_complex_3_in_triangulation_3_fwd.h index 6d644faa1ec..79659554cb2 100644 --- a/Installation/include/CGAL/Mesh_3/Mesh_complex_3_in_triangulation_3_fwd.h +++ b/Installation/include/CGAL/Mesh_3/Mesh_complex_3_in_triangulation_3_fwd.h @@ -24,14 +24,14 @@ template class Mesh_complex_3_in_triangulation_3; -template -bool build_triangulation_from_file(std::istream& is, - Tr& tr, - bool replace_domain_0); - -template -bool build_triangulation_from_file(std::istream& is, - Tr& tr); +template +bool build_mesh_complex_from_file(std::istream& is, + C3T3& c3t3, + bool replace_domain_0); + +template +bool build_mesh_complex_from_file(std::istream& is, + C3T3& c3t3); } // CGAL #endif diff --git a/Installation/include/CGAL/SMDS_3/Mesh_complex_3_in_triangulation_3_fwd.h b/Installation/include/CGAL/SMDS_3/Mesh_complex_3_in_triangulation_3_fwd.h index c11579f4eb8..af85d209675 100644 --- a/Installation/include/CGAL/SMDS_3/Mesh_complex_3_in_triangulation_3_fwd.h +++ b/Installation/include/CGAL/SMDS_3/Mesh_complex_3_in_triangulation_3_fwd.h @@ -51,6 +51,16 @@ bool build_triangulation_from_file(std::istream& is, const bool allow_negative_orientation = false, CxEdgesOutputIterator cx_edges_oit = CxEdgesOutputIterator()); +template +bool build_mesh_complex_from_file(std::istream& is, + C3T3& c3t3, + const bool verbose = false, + const bool replace_domain_0 = false, + const bool allow_non_manifold = false, + const bool allow_negative_orientation = false, + CxEdgesOutputIterator cx_edges_oit = CxEdgesOutputIterator()); + } // namespace SMDS_3 } // namespace CGAL #endif diff --git a/Lab/demo/Lab/Plugins/IO/VTK_io_plugin.cpp b/Lab/demo/Lab/Plugins/IO/VTK_io_plugin.cpp index 3e062177458..0c92ac77046 100644 --- a/Lab/demo/Lab/Plugins/IO/VTK_io_plugin.cpp +++ b/Lab/demo/Lab/Plugins/IO/VTK_io_plugin.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include #include @@ -428,7 +429,7 @@ class CGAL_Lab_vtk_plugin : subdomains.push_back(si); } std::map border_facets; - //Preprocessing for build_triangulation + //Preprocessing for build_mesh_complex //check for orientation and swap in cells if not good. for(std::size_t i=0; i> feature_edges; std::vector> corners; + std::vector vertex_handle_vector; - CGAL::SMDS_3::build_triangulation_with_subdomains_range( - c3t3_item->c3t3().triangulation(), + CGAL::SMDS_3::build_mesh_complex_with_subdomains_range( + c3t3_item->c3t3(), points, finite_cells, subdomains, border_facets, feature_edges, corners, - CGAL::Emptyset_iterator(), + vertex_handle_vector, + CGAL::Emptyset_iterator{}, false, false, true, true); for( C3t3::Triangulation::Finite_cells_iterator @@ -464,9 +467,9 @@ class CGAL_Lab_vtk_plugin : c3t3_item->c3t3().add_to_complex(cit, cit->info()); for(int i=0; i < 4; ++i) { - if(cit->surface_patch_index(i)>0) + if(c3t3_item->c3t3().surface_patch_index(cit, i) > 0) { - c3t3_item->c3t3().add_to_complex(cit, i, cit->surface_patch_index(i)); + c3t3_item->c3t3().add_to_complex(cit, i, c3t3_item->c3t3().surface_patch_index(cit, i)); } } } @@ -485,11 +488,11 @@ class CGAL_Lab_vtk_plugin : Cell_handle nc = c->neighbor(fit->second); // By definition, Subdomain_index() is supposed to be the id of the exterior - if(c->subdomain_index() != C3t3::Triangulation::Cell::Subdomain_index() && - nc->subdomain_index() == C3t3::Triangulation::Cell::Subdomain_index()) + if(c3t3_item->c3t3().subdomain_index(c) != C3t3::Subdomain_index() && + c3t3_item->c3t3().subdomain_index(nc) == C3t3::Subdomain_index()) { // Color the border facet with the index of its cell - c3t3_item->c3t3().add_to_complex(c, fit->second, c->subdomain_index()); + c3t3_item->c3t3().add_to_complex(c, fit->second, c3t3_item->c3t3().subdomain_index(c)); } } } diff --git a/Lab/demo/Lab/Plugins/Mesh_3/C3t3_io_plugin.cpp b/Lab/demo/Lab/Plugins/Mesh_3/C3t3_io_plugin.cpp index 4e226a73472..9922f6c490e 100644 --- a/Lab/demo/Lab/Plugins/Mesh_3/C3t3_io_plugin.cpp +++ b/Lab/demo/Lab/Plugins/Mesh_3/C3t3_io_plugin.cpp @@ -167,7 +167,7 @@ CGAL_Lab_c3t3_binary_io_plugin::load( item->setName(fileinfo.completeBaseName()); - if (CGAL::IO::read_AVIZO_TETRA(in, item->c3t3().triangulation())) + if (CGAL::IO::read_AVIZO_TETRA(in, item->c3t3())) { update_c3t3(item->c3t3()); @@ -449,14 +449,14 @@ update_c3t3(C3t3& c3t3) c3t3.rescan_after_load_of_triangulation(); //fix counters for facets and cells for (Cell_handle cit : c3t3.triangulation().finite_cell_handles()) { - CGAL_assertion(cit->subdomain_index() >= 0); - if (cit->subdomain_index() != C3t3::Triangulation::Cell::Subdomain_index()) - c3t3.add_to_complex(cit, cit->subdomain_index()); + CGAL_assertion(c3t3.subdomain_index(cit) >= 0); + if (c3t3.subdomain_index(cit) != C3t3::Subdomain_index()) + c3t3.add_to_complex(cit, c3t3.subdomain_index(cit)); for (int i = 0; i < 4; ++i) { - if (cit->surface_patch_index(i) > 0) - c3t3.add_to_complex(cit, i, cit->surface_patch_index(i)); + if (c3t3.surface_patch_index(cit, i) > 0) + c3t3.add_to_complex(cit, i, c3t3.surface_patch_index(cit, i)); } } @@ -469,11 +469,11 @@ update_c3t3(C3t3& c3t3) Cell_handle nc = c->neighbor(fit.second); // By definition, Subdomain_index() is supposed to be the id of the exterior - if (c->subdomain_index() != C3t3::Triangulation::Cell::Subdomain_index() && - nc->subdomain_index() == C3t3::Triangulation::Cell::Subdomain_index()) + if (c3t3.subdomain_index(c) != C3t3::Subdomain_index() && + c3t3.subdomain_index(nc) == C3t3::Subdomain_index()) { // Color the border facet with the index of its cell - c3t3.add_to_complex(c, fit.second, c->subdomain_index()); + c3t3.add_to_complex(c, fit.second, c3t3.subdomain_index(c)); } } } diff --git a/Lab/demo/Lab/Plugins/Mesh_3/Mesh_function.h b/Lab/demo/Lab/Plugins/Mesh_3/Mesh_function.h index 902c8c64aef..6c3717c6560 100644 --- a/Lab/demo/Lab/Plugins/Mesh_3/Mesh_function.h +++ b/Lab/demo/Lab/Plugins/Mesh_3/Mesh_function.h @@ -118,7 +118,7 @@ class Mesh_function typedef C3t3::Vertex_handle Vertex_handle; typedef C3t3::Triangulation Tr; - typedef CGAL::Mesh_criteria_3 Mesh_criteria; + typedef CGAL::Mesh_criteria_3 Mesh_criteria; typedef Mesh_criteria::Edge_criteria Edge_criteria; typedef Mesh_criteria::Facet_criteria Facet_criteria; typedef Mesh_criteria::Cell_criteria Cell_criteria; @@ -409,10 +409,8 @@ launch() 0, &stop_); -#ifdef CGAL_MESH_3_PROFILING CGAL::Real_timer t; t.start(); -#endif #if CGAL_MESH_3_MESHER_STATUS_ACTIVATED mesher_->initialize(); @@ -430,7 +428,8 @@ launch() // Ensure c3t3 is ok (useful if process has been stop by the user) mesher_->fix_c3t3(); - std::cerr<<"Done."< void Mesh_function:: tweak_criteria(Mesh_criteria& c, Mesh_fnt::Polyhedral_domain_tag) { - typedef CGAL::Mesh_3::Facet_topological_criterion_with_adjacency New_topo_adj_crit; if(((int(c.facet_criteria_object().topology()) & diff --git a/Lab/demo/Lab/Plugins/Mesh_3/Offset_meshing_plugin.cpp b/Lab/demo/Lab/Plugins/Mesh_3/Offset_meshing_plugin.cpp index a21cdbbf655..6a5d2b85cad 100644 --- a/Lab/demo/Lab/Plugins/Mesh_3/Offset_meshing_plugin.cpp +++ b/Lab/demo/Lab/Plugins/Mesh_3/Offset_meshing_plugin.cpp @@ -272,8 +272,7 @@ SMesh* cgal_off_meshing(QWidget*, using Mesh_domain_base = CGAL::Labeled_mesh_domain_3; using Mesh_domain = CGAL::Mesh_domain_with_polyline_features_3; - using Tr = C3t3::Triangulation; - using Mesh_criteria = CGAL::Mesh_criteria_3; + using Mesh_criteria = CGAL::Mesh_criteria_3; const CGAL::Bbox_3 bbox = source_item->bbox(); diff --git a/Lab/demo/Lab/Plugins/Mesh_3/config_mesh_3.h b/Lab/demo/Lab/Plugins/Mesh_3/config_mesh_3.h index 451f8843d0a..0d21c6e1d6a 100644 --- a/Lab/demo/Lab/Plugins/Mesh_3/config_mesh_3.h +++ b/Lab/demo/Lab/Plugins/Mesh_3/config_mesh_3.h @@ -54,7 +54,6 @@ // MESH_3 GENERAL PARAMETERS // ========================================================================== -//#define CGAL_MESH_3_USE_OLD_SURFACE_RESTRICTED_DELAUNAY_UPDATE // WARNING: VERY SLOW //#define CGAL_MESH_3_INITIAL_POINTS_NO_RANDOM_SHOOTING //#define CGAL_MESHES_DEBUG_REFINEMENT_POINTS //#define CHECK_AND_DISPLAY_THE_NUMBER_OF_BAD_ELEMENTS_IN_THE_END diff --git a/Lab/demo/Lab/Plugins/Point_set/Surface_reconstruction_poisson_impl.cpp b/Lab/demo/Lab/Plugins/Point_set/Surface_reconstruction_poisson_impl.cpp index 4eafc0c5f5d..b78f7d3dfcb 100644 --- a/Lab/demo/Lab/Plugins/Point_set/Surface_reconstruction_poisson_impl.cpp +++ b/Lab/demo/Lab/Plugins/Point_set/Surface_reconstruction_poisson_impl.cpp @@ -187,7 +187,7 @@ SMesh* poisson_reconstruct(Point_set& points, typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; typedef typename CGAL::Mesh_triangulation_3::type Tr; typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; - typedef CGAL::Mesh_criteria_3 Mesh_criteria; + typedef CGAL::Mesh_criteria_3 Mesh_criteria; // AABB tree typedef CGAL::AABB_face_graph_triangle_primitive Primitive; diff --git a/Lab/demo/Lab/Scene_tetrahedra_item.cpp b/Lab/demo/Lab/Scene_tetrahedra_item.cpp index 56d7278ade4..d24be3d13e1 100644 --- a/Lab/demo/Lab/Scene_tetrahedra_item.cpp +++ b/Lab/demo/Lab/Scene_tetrahedra_item.cpp @@ -183,7 +183,7 @@ void Scene_tetrahedra_item::computeElements()const const Tr::Bare_point& pb = wp2p(cit->vertex(1)->point()); const Tr::Bare_point& pc = wp2p(cit->vertex(2)->point()); const Tr::Bare_point& pd = wp2p(cit->vertex(3)->point()); - const QColor color = d->c3t3_item->getSubdomainIndexColor(cit->subdomain_index()); + const QColor color = d->c3t3_item->getSubdomainIndexColor(c3t3.subdomain_index(cit)); //0 - 1 : dihedral angle double min_dihedral_angle = 360.0; double max_dihedral_angle = -360.0; diff --git a/Mesh_3/benchmark/Mesh_3/benchmark_config.h b/Mesh_3/benchmark/Mesh_3/benchmark_config.h index 0416e8abf93..3be8e88c5a7 100644 --- a/Mesh_3/benchmark/Mesh_3/benchmark_config.h +++ b/Mesh_3/benchmark/Mesh_3/benchmark_config.h @@ -28,7 +28,6 @@ // #define CGAL_MESH_3_POLYHEDRON_WITH_FEATURES // #define CGAL_MESH_3_IMPLICIT_WITH_FEATURES -// #define CGAL_MESH_3_USE_OLD_SURFACE_RESTRICTED_DELAUNAY_UPDATE // WARNING: VERY SLOW #define CGAL_MESH_3_INITIAL_POINTS_NO_RANDOM_SHOOTING // #define CGAL_MESH_3_BENCHMARK_LLOYD diff --git a/Mesh_3/benchmark/Mesh_3/benchmark_mesh_3.cpp b/Mesh_3/benchmark/Mesh_3/benchmark_mesh_3.cpp index ea91e0c585e..391255d37a1 100644 --- a/Mesh_3/benchmark/Mesh_3/benchmark_mesh_3.cpp +++ b/Mesh_3/benchmark/Mesh_3/benchmark_mesh_3.cpp @@ -148,7 +148,7 @@ enum Exit_code // the call to Mesh_3 happens here template Exit_code make_mesh(const Domain& domain, - const CGAL::Mesh_criteria_3& criteria, + const CGAL::Mesh_criteria_3& criteria, const std::string& output_filename) { #ifdef _DEBUG @@ -244,7 +244,7 @@ Exit_code make_mesh(const Domain& domain, double cell_sizing, double cell_shape, const std::string& output_filename) { - typedef CGAL::Mesh_criteria_3 Mesh_criteria; + typedef CGAL::Mesh_criteria_3 Mesh_criteria; const CGAL::Bbox_3 bbox = domain.bbox(); diff --git a/Mesh_3/doc/Mesh_3/Concepts/MeshCellCriteria_3.h b/Mesh_3/doc/Mesh_3/Concepts/MeshCellCriteria_3.h index 5e7306a5559..da98845b5ea 100644 --- a/Mesh_3/doc/Mesh_3/Concepts/MeshCellCriteria_3.h +++ b/Mesh_3/doc/Mesh_3/Concepts/MeshCellCriteria_3.h @@ -6,11 +6,12 @@ The Delaunay refinement process involved in the template functions `CGAL::make_mesh_3()` and `CGAL::refine_mesh_3()` is guided by a set of elementary refinement criteria that concern either mesh tetrahedra or surface facets. -The concept `MeshCellCriteria_3` describes the types that -handle the refinement criteria for mesh tetrahedra. +The concept `MeshCellCriteria_3` describes criteria for mesh tetrahedra. +For a mesh complex type `C3T3`, the criteria are evaluated on cells of its +nested triangulation. \cgalHasModelsBegin -\cgalHasModels{CGAL::Mesh_cell_criteria_3} +\cgalHasModels{CGAL::Mesh_cell_criteria_3} \cgalHasModelsEnd \sa `MeshEdgeCriteria_3` @@ -27,13 +28,6 @@ class MeshCellCriteria_3 { /// \name Types /// @{ -/*! -%Handle type for the cells of the -triangulation. Must match the `Cell_handle` type in the -triangulation type used by the mesh generation function. -*/ -typedef unspecified_type Cell_handle; - /*! Type representing the quality of a cell. Must be a model of CopyConstructible and @@ -44,8 +38,8 @@ typedef unspecified_type Cell_quality; /*! Type representing if a cell is bad or not. Must -be convertible to `bool`. If it converts to `true` then the cell is bad, otherwise -the cell is good with regard to the criteria. +be contextually convertible to `bool`. If it converts to `true` then the cell +is bad, otherwise the cell is good with regard to the criteria. In addition, an object of this type must contain an object of type `Cell_quality` if it represents @@ -60,10 +54,11 @@ typedef unspecified_type Is_cell_bad; /// @{ /*! -Returns the `Is_cell_bad` value of the cell `c`, which lives in the triangulation `tr`. -The type `Tr` must be identical to the triangulation type used by the mesh generation function. +Returns the `Is_cell_bad` value for the cell `c` of the triangulation nested +in `c3t3`, the mesh complex used by the mesh generation function. */ -Is_cell_bad operator()(const Tr& tr, Cell_handle c); +Is_cell_bad operator()(const C3T3& c3t3, + typename C3T3::Triangulation::Cell_handle c) const; /// @} diff --git a/Mesh_3/doc/Mesh_3/Concepts/MeshCriteriaWithFeatures_3.h b/Mesh_3/doc/Mesh_3/Concepts/MeshCriteriaWithFeatures_3.h index 895fa9e8c0f..1f2ad95125a 100644 --- a/Mesh_3/doc/Mesh_3/Concepts/MeshCriteriaWithFeatures_3.h +++ b/Mesh_3/doc/Mesh_3/Concepts/MeshCriteriaWithFeatures_3.h @@ -15,7 +15,7 @@ that describes the requirements, in terms of sizing, for the discretization of t \cgalRefines{MeshCriteria_3} \cgalHasModelsBegin -\cgalHasModels{CGAL::Mesh_criteria_3} +\cgalHasModels{CGAL::Mesh_criteria_3} \cgalHasModelsEnd \sa `MeshEdgeCriteria_3` diff --git a/Mesh_3/doc/Mesh_3/Concepts/MeshCriteria_3.h b/Mesh_3/doc/Mesh_3/Concepts/MeshCriteria_3.h index 22805028b7e..063765b1f35 100644 --- a/Mesh_3/doc/Mesh_3/Concepts/MeshCriteria_3.h +++ b/Mesh_3/doc/Mesh_3/Concepts/MeshCriteria_3.h @@ -13,7 +13,7 @@ are described by the concept `MeshFacetCriteria_3`. The concept `MeshCriteria_3` encapsulates these concepts. \cgalHasModelsBegin -\cgalHasModels{CGAL::Mesh_criteria_3} +\cgalHasModels{CGAL::Mesh_criteria_3} \cgalHasModelsEnd \sa `MeshEdgeCriteria_3` diff --git a/Mesh_3/doc/Mesh_3/Concepts/MeshDomainField_3.h b/Mesh_3/doc/Mesh_3/Concepts/MeshDomainField_3.h index 3d05823497b..0ca70fc6158 100644 --- a/Mesh_3/doc/Mesh_3/Concepts/MeshDomainField_3.h +++ b/Mesh_3/doc/Mesh_3/Concepts/MeshDomainField_3.h @@ -11,9 +11,9 @@ at any point of the space. \sa `MeshDomain_3` \sa `MeshDomainWithFeatures_3` -\sa `CGAL::Mesh_edge_criteria_3` -\sa `CGAL::Mesh_facet_criteria_3` -\sa `CGAL::Mesh_cell_criteria_3` +\sa `CGAL::Mesh_edge_criteria_3` +\sa `CGAL::Mesh_facet_criteria_3` +\sa `CGAL::Mesh_cell_criteria_3` */ diff --git a/Mesh_3/doc/Mesh_3/Concepts/MeshEdgeCriteria_3.h b/Mesh_3/doc/Mesh_3/Concepts/MeshEdgeCriteria_3.h index 2fad590a78e..0010633edcc 100644 --- a/Mesh_3/doc/Mesh_3/Concepts/MeshEdgeCriteria_3.h +++ b/Mesh_3/doc/Mesh_3/Concepts/MeshEdgeCriteria_3.h @@ -8,7 +8,7 @@ It provides an upper bound for the distance between two protecting ball centers that are consecutive on a 1-feature. \cgalHasModelsBegin -\cgalHasModels{CGAL::Mesh_edge_criteria_3} +\cgalHasModels{CGAL::Mesh_edge_criteria_3} \cgalHasModelsEnd \sa `MeshCellCriteria_3` @@ -26,13 +26,13 @@ class MeshEdgeCriteria_3 { /*! Point type. Must match the `Point_3` type in -the triangulation type used by the mesh generation function. +the triangulation nested in the mesh complex type used by the mesh generation function. */ typedef unspecified_type Point_3; /*! -Type for edges of the triangulation. Must match the -`Edge` type in the triangulation type used by the mesh generation function. +Type for edges of the triangulation. Must match the `Edge` type in the triangulation +nested in the mesh complex type used by the mesh generation function. */ typedef unspecified_type Edge; diff --git a/Mesh_3/doc/Mesh_3/Concepts/MeshFacetCriteria_3.h b/Mesh_3/doc/Mesh_3/Concepts/MeshFacetCriteria_3.h index 07a6626bb79..427d9a891f9 100644 --- a/Mesh_3/doc/Mesh_3/Concepts/MeshFacetCriteria_3.h +++ b/Mesh_3/doc/Mesh_3/Concepts/MeshFacetCriteria_3.h @@ -10,7 +10,7 @@ The concept `MeshFacetCriteria_3` describes the types that handle the refinement criteria for surface facets. \cgalHasModelsBegin -\cgalHasModels{CGAL::Mesh_facet_criteria_3} +\cgalHasModels{CGAL::Mesh_facet_criteria_3} \cgalHasModelsEnd \sa `MeshCellCriteria_3` @@ -30,14 +30,14 @@ class MeshFacetCriteria_3 { /*! Type for the facets of the triangulation. Must match the `Facet` type in the -triangulation type used by the mesh generation function. +triangulation nested in the mesh complex type used by the mesh generation function. */ typedef unspecified_type Facet; /*! Handle type for the cells of the triangulation. Must match the `Cell_handle` type in the -triangulation type used by the mesh generation function. +triangulation nested in the mesh complex type used by the mesh generation function. */ typedef unspecified_type Cell_handle; @@ -73,10 +73,11 @@ typedef unspecified_type FT; /// @{ /*! -Returns the `Is_facet_bad` value of the facet `f`, which lives in the triangulation `tr`. -The type `Tr` must be identical to the triangulation type used by the mesh generation function. +Returns the `Is_facet_bad` value of the facet `f`, which belongs to the mesh complex +`c3t3` used by the mesh generation function. +The type `C3T3` must be the mesh complex type used by the mesh generation function. */ -Is_facet_bad operator()(const Tr& tr, Facet f); +Is_facet_bad operator()(const C3T3& c3t3, Facet f); /** * @returns the squared value of minimal radius bound if set, diff --git a/Mesh_3/doc/Mesh_3/PackageDescription.txt b/Mesh_3/doc/Mesh_3/PackageDescription.txt index e08b7d53214..662e54a219d 100644 --- a/Mesh_3/doc/Mesh_3/PackageDescription.txt +++ b/Mesh_3/doc/Mesh_3/PackageDescription.txt @@ -92,10 +92,10 @@ related to the template parameters of some models of the main concepts: - `CGAL::Mesh_vertex_base_3` - `CGAL::Compact_mesh_cell_base_3` - `CGAL::Mesh_cell_base_3` -- `CGAL::Mesh_criteria_3` -- `CGAL::Mesh_cell_criteria_3` -- `CGAL::Mesh_facet_criteria_3` -- `CGAL::Mesh_edge_criteria_3` +- `CGAL::Mesh_criteria_3` +- `CGAL::Mesh_cell_criteria_3` +- `CGAL::Mesh_facet_criteria_3` +- `CGAL::Mesh_edge_criteria_3` - `CGAL::Mesh_constant_domain_field_3` The following classes are models of domain concepts diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_gray_image.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_gray_image.cpp index 1e309e9c08e..7686ad0276f 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_gray_image.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_gray_image.cpp @@ -21,7 +21,7 @@ typedef CGAL::Mesh_triangulation_3::type Tr; typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; namespace params = CGAL::parameters; diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_gray_image_multiple_values.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_gray_image_multiple_values.cpp index c7ba6b88638..c5fd7a738ed 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_gray_image_multiple_values.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_gray_image_multiple_values.cpp @@ -24,7 +24,7 @@ typedef CGAL::Mesh_triangulation_3::type Tr; typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; namespace params = CGAL::parameters; diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_gray_vtk_image.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_gray_vtk_image.cpp index 67be0325cf0..e36d5681952 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_gray_vtk_image.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_gray_vtk_image.cpp @@ -34,7 +34,7 @@ typedef CGAL::Mesh_triangulation_3::type Tr; typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; template class Is_interior { diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_image.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_image.cpp index 018a3f50696..503b24dd0c0 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_image.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_image.cpp @@ -24,7 +24,7 @@ typedef CGAL::Mesh_triangulation_3::t typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; namespace params = CGAL::parameters; diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_image_variable_size.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_image_variable_size.cpp index 2626ec0af6b..6035a97f9e2 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_image_variable_size.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_image_variable_size.cpp @@ -25,7 +25,7 @@ typedef CGAL::Mesh_triangulation_3::t typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; typedef CGAL::Mesh_constant_domain_field_3 Sizing_field; diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp index 664f3162660..c14a1440503 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp @@ -30,7 +30,7 @@ using Tr = CGAL::Mesh_triangulation_3; // Criteria -using Mesh_criteria = CGAL::Mesh_criteria_3; +using Mesh_criteria = CGAL::Mesh_criteria_3; namespace params = CGAL::parameters; diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_detection_of_features.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_detection_of_features.cpp index 0b1dc5eb6c1..0289626825d 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_detection_of_features.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_detection_of_features.cpp @@ -32,7 +32,7 @@ typedef CGAL::Mesh_triangulation_3::t typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; // To avoid verbose function and named parameters call namespace params = CGAL::parameters; diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_features.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_features.cpp index 713257ad694..9e48297a423 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_features.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_features.cpp @@ -32,7 +32,7 @@ typedef CGAL::Mesh_triangulation_3::t typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; namespace params = CGAL::parameters; diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_image_initialization.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_image_initialization.cpp index 133fec86966..0c294811003 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_image_initialization.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_image_initialization.cpp @@ -32,7 +32,7 @@ typedef CGAL::Mesh_triangulation_3::t typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; namespace params = CGAL::parameters; diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_initial_points.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_initial_points.cpp index b49ca1c2de0..3d641c63720 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_initial_points.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_initial_points.cpp @@ -30,7 +30,7 @@ typedef CGAL::Mesh_triangulation_3::t typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; namespace params = CGAL::parameters; diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_input_features.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_input_features.cpp index aa2266f15b1..1770bcb1650 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_input_features.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_input_features.cpp @@ -30,7 +30,7 @@ typedef CGAL::Mesh_triangulation_3::t typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; namespace params = CGAL::parameters; diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_weighted_image.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_weighted_image.cpp index fbe4751bdd5..59343e06389 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_weighted_image.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_weighted_image.cpp @@ -22,7 +22,7 @@ using Tr = CGAL::Mesh_triangulation_3; // Criteria -using Mesh_criteria = CGAL::Mesh_criteria_3; +using Mesh_criteria = CGAL::Mesh_criteria_3; namespace params = CGAL::parameters; diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_weighted_image_with_detection_of_features.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_weighted_image_with_detection_of_features.cpp index 8c3e6f33443..837afe3ee02 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_weighted_image_with_detection_of_features.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_weighted_image_with_detection_of_features.cpp @@ -30,7 +30,7 @@ using Tr = CGAL::Mesh_triangulation_3 using C3t3 = CGAL::Mesh_complex_3_in_triangulation_3; // Criteria -using Mesh_criteria = CGAL::Mesh_criteria_3; +using Mesh_criteria = CGAL::Mesh_criteria_3; // To avoid verbose function and named parameters call using namespace CGAL::parameters; diff --git a/Mesh_3/examples/Mesh_3/mesh_cubes_intersection.cpp b/Mesh_3/examples/Mesh_3/mesh_cubes_intersection.cpp index 8b413b1cec9..5df82b181d4 100644 --- a/Mesh_3/examples/Mesh_3/mesh_cubes_intersection.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_cubes_intersection.cpp @@ -35,7 +35,7 @@ typedef CGAL::Mesh_triangulation_3::type Tr; typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Mesh Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; typedef Mesh_criteria::Facet_criteria Facet_criteria; typedef Mesh_criteria::Cell_criteria Cell_criteria; diff --git a/Mesh_3/examples/Mesh_3/mesh_cubes_intersection_with_features.cpp b/Mesh_3/examples/Mesh_3/mesh_cubes_intersection_with_features.cpp index 9fe2a209ca3..71c2d607f2d 100644 --- a/Mesh_3/examples/Mesh_3/mesh_cubes_intersection_with_features.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_cubes_intersection_with_features.cpp @@ -37,7 +37,7 @@ typedef CGAL::Mesh_triangulation_3::type Tr; typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Mesh Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; typedef Mesh_criteria::Facet_criteria Facet_criteria; typedef Mesh_criteria::Cell_criteria Cell_criteria; diff --git a/Mesh_3/examples/Mesh_3/mesh_hybrid_mesh_domain.cpp b/Mesh_3/examples/Mesh_3/mesh_hybrid_mesh_domain.cpp index 7e95e1eff98..30e834be43a 100644 --- a/Mesh_3/examples/Mesh_3/mesh_hybrid_mesh_domain.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_hybrid_mesh_domain.cpp @@ -172,7 +172,7 @@ typedef CGAL::Mesh_triangulation_3::type Tr; typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; typedef Mesh_criteria::Edge_criteria Edge_criteria; typedef Mesh_criteria::Facet_criteria Facet_criteria; typedef Mesh_criteria::Cell_criteria Cell_criteria; diff --git a/Mesh_3/examples/Mesh_3/mesh_implicit_domains.cpp b/Mesh_3/examples/Mesh_3/mesh_implicit_domains.cpp index 68c7c4c5b37..e8a3ba2473e 100644 --- a/Mesh_3/examples/Mesh_3/mesh_implicit_domains.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_implicit_domains.cpp @@ -33,7 +33,7 @@ typedef CGAL::Mesh_triangulation_3::t typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Mesh Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; typedef Mesh_criteria::Facet_criteria Facet_criteria; typedef Mesh_criteria::Cell_criteria Cell_criteria; diff --git a/Mesh_3/examples/Mesh_3/mesh_implicit_domains_2.cpp b/Mesh_3/examples/Mesh_3/mesh_implicit_domains_2.cpp index 9c6eb9a0055..26e129af54e 100644 --- a/Mesh_3/examples/Mesh_3/mesh_implicit_domains_2.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_implicit_domains_2.cpp @@ -25,7 +25,7 @@ typedef CGAL::Mesh_triangulation_3::type Tr; typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Mesh Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; typedef Mesh_criteria::Facet_criteria Facet_criteria; typedef Mesh_criteria::Cell_criteria Cell_criteria; diff --git a/Mesh_3/examples/Mesh_3/mesh_implicit_ellipsoid.cpp b/Mesh_3/examples/Mesh_3/mesh_implicit_ellipsoid.cpp index db7dabd145e..48b7eaa472e 100644 --- a/Mesh_3/examples/Mesh_3/mesh_implicit_ellipsoid.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_implicit_ellipsoid.cpp @@ -21,7 +21,7 @@ typedef CGAL::Mesh_triangulation_3::type Tr; typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; typedef Mesh_criteria::Facet_criteria Facet_criteria; typedef Mesh_criteria::Cell_criteria Cell_criteria; diff --git a/Mesh_3/examples/Mesh_3/mesh_implicit_sphere.cpp b/Mesh_3/examples/Mesh_3/mesh_implicit_sphere.cpp index d2cec7e4d94..3f3a2fa589d 100644 --- a/Mesh_3/examples/Mesh_3/mesh_implicit_sphere.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_implicit_sphere.cpp @@ -26,7 +26,7 @@ typedef CGAL::Mesh_triangulation_3::t typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; namespace params = CGAL::parameters; diff --git a/Mesh_3/examples/Mesh_3/mesh_implicit_sphere_variable_size.cpp b/Mesh_3/examples/Mesh_3/mesh_implicit_sphere_variable_size.cpp index 7c4ad34100b..91d7dbc00ac 100644 --- a/Mesh_3/examples/Mesh_3/mesh_implicit_sphere_variable_size.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_implicit_sphere_variable_size.cpp @@ -26,7 +26,7 @@ typedef CGAL::Mesh_triangulation_3::t typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; // Sizing field struct Spherical_sizing_field diff --git a/Mesh_3/examples/Mesh_3/mesh_optimization_example.cpp b/Mesh_3/examples/Mesh_3/mesh_optimization_example.cpp index f6d5d53caef..ef4665aa5af 100644 --- a/Mesh_3/examples/Mesh_3/mesh_optimization_example.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_optimization_example.cpp @@ -24,7 +24,7 @@ typedef CGAL::Mesh_triangulation_3::t typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Mesh Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; namespace params = CGAL::parameters; diff --git a/Mesh_3/examples/Mesh_3/mesh_optimization_lloyd_example.cpp b/Mesh_3/examples/Mesh_3/mesh_optimization_lloyd_example.cpp index c24672f1fc8..01b75db5f7f 100644 --- a/Mesh_3/examples/Mesh_3/mesh_optimization_lloyd_example.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_optimization_lloyd_example.cpp @@ -24,7 +24,7 @@ typedef CGAL::Mesh_triangulation_3::t typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Mesh Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; namespace params = CGAL::parameters; diff --git a/Mesh_3/examples/Mesh_3/mesh_polyhedral_complex.cpp b/Mesh_3/examples/Mesh_3/mesh_polyhedral_complex.cpp index b502b7593e6..dcd39174ae0 100644 --- a/Mesh_3/examples/Mesh_3/mesh_polyhedral_complex.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_polyhedral_complex.cpp @@ -29,7 +29,7 @@ typedef CGAL::Mesh_complex_3_in_triangulation_3< Tr,Mesh_domain::Corner_index,Mesh_domain::Curve_index> C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; namespace params = CGAL::parameters; diff --git a/Mesh_3/examples/Mesh_3/mesh_polyhedral_complex_sm.cpp b/Mesh_3/examples/Mesh_3/mesh_polyhedral_complex_sm.cpp index 9bf6c385370..a75f6956f8f 100644 --- a/Mesh_3/examples/Mesh_3/mesh_polyhedral_complex_sm.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_polyhedral_complex_sm.cpp @@ -31,7 +31,7 @@ typedef CGAL::Mesh_complex_3_in_triangulation_3< Tr,Mesh_domain::Corner_index,Mesh_domain::Curve_index> C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; namespace params = CGAL::parameters; diff --git a/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain.cpp b/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain.cpp index c8e4d1c69b2..b3f43dfc6f4 100644 --- a/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain.cpp @@ -27,7 +27,7 @@ typedef CGAL::Mesh_triangulation_3::t typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; namespace params = CGAL::parameters; diff --git a/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain_sm.cpp b/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain_sm.cpp index 407a73bfcb5..d279ee18a1a 100644 --- a/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain_sm.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain_sm.cpp @@ -26,7 +26,7 @@ typedef CGAL::Mesh_triangulation_3::t typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; namespace params = CGAL::parameters; diff --git a/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain_with_edge_distance.cpp b/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain_with_edge_distance.cpp index 3c09a54129b..c5c1ff0650a 100644 --- a/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain_with_edge_distance.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain_with_edge_distance.cpp @@ -26,7 +26,7 @@ typedef CGAL::Mesh_complex_3_in_triangulation_3< Tr,Mesh_domain::Corner_index,Mesh_domain::Curve_index> C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; namespace params = CGAL::parameters; diff --git a/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain_with_features.cpp b/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain_with_features.cpp index d962568ce88..85b7cf06746 100644 --- a/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain_with_features.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain_with_features.cpp @@ -27,7 +27,7 @@ typedef CGAL::Mesh_complex_3_in_triangulation_3< Tr,Mesh_domain::Corner_index,Mesh_domain::Curve_index> C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; namespace params = CGAL::parameters; diff --git a/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain_with_features_sizing.cpp b/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain_with_features_sizing.cpp index ff0481f9208..fa957b24c40 100644 --- a/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain_with_features_sizing.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain_with_features_sizing.cpp @@ -29,7 +29,7 @@ typedef CGAL::Mesh_complex_3_in_triangulation_3< Tr,Mesh_domain::Corner_index,Mesh_domain::Curve_index> C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; namespace params = CGAL::parameters; diff --git a/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain_with_features_sm.cpp b/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain_with_features_sm.cpp index 2763bff0930..b01876b6b83 100644 --- a/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain_with_features_sm.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain_with_features_sm.cpp @@ -28,7 +28,7 @@ typedef CGAL::Mesh_complex_3_in_triangulation_3< Tr,Mesh_domain::Corner_index,Mesh_domain::Curve_index> C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; namespace params = CGAL::parameters; diff --git a/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain_with_lipschitz_sizing.cpp b/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain_with_lipschitz_sizing.cpp index e9426cae9c9..acf61382bb3 100644 --- a/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain_with_lipschitz_sizing.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain_with_lipschitz_sizing.cpp @@ -29,7 +29,7 @@ typedef CGAL::Mesh_complex_3_in_triangulation_3< Tr,Mesh_domain::Corner_index,Mesh_domain::Curve_index> C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; // Sizing field typedef CGAL::Mesh_3::Lipschitz_sizing Lip_sizing; diff --git a/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain_with_surface_inside.cpp b/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain_with_surface_inside.cpp index 09a4f349572..ae1bcb17163 100644 --- a/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain_with_surface_inside.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain_with_surface_inside.cpp @@ -24,7 +24,7 @@ typedef CGAL::Mesh_complex_3_in_triangulation_3< Tr,Mesh_domain::Corner_index,Mesh_domain::Curve_index> C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; namespace params = CGAL::parameters; diff --git a/Mesh_3/examples/Mesh_3/mesh_two_implicit_spheres_with_balls.cpp b/Mesh_3/examples/Mesh_3/mesh_two_implicit_spheres_with_balls.cpp index 781631cdb5a..5469c56a5a2 100644 --- a/Mesh_3/examples/Mesh_3/mesh_two_implicit_spheres_with_balls.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_two_implicit_spheres_with_balls.cpp @@ -35,7 +35,7 @@ typedef CGAL::Mesh_complex_3_in_triangulation_3< Tr,Mesh_domain::Corner_index,Mesh_domain::Curve_index> C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; namespace params = CGAL::parameters; diff --git a/Mesh_3/examples/Mesh_3/remesh_polyhedral_surface.cpp b/Mesh_3/examples/Mesh_3/remesh_polyhedral_surface.cpp index c9b99925003..59f57ddde0f 100644 --- a/Mesh_3/examples/Mesh_3/remesh_polyhedral_surface.cpp +++ b/Mesh_3/examples/Mesh_3/remesh_polyhedral_surface.cpp @@ -20,7 +20,7 @@ typedef CGAL::Mesh_complex_3_in_triangulation_3< Tr,Mesh_domain::Corner_index,Mesh_domain::Curve_index> C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; namespace params = CGAL::parameters; diff --git a/Mesh_3/examples/Mesh_3/remesh_polyhedral_surface_sm.cpp b/Mesh_3/examples/Mesh_3/remesh_polyhedral_surface_sm.cpp index 58aadb62dc7..3678cd16f1b 100644 --- a/Mesh_3/examples/Mesh_3/remesh_polyhedral_surface_sm.cpp +++ b/Mesh_3/examples/Mesh_3/remesh_polyhedral_surface_sm.cpp @@ -19,7 +19,7 @@ typedef CGAL::Mesh_complex_3_in_triangulation_3< Tr,Mesh_domain::Corner_index,Mesh_domain::Curve_index> C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; namespace params = CGAL::parameters; diff --git a/Mesh_3/include/CGAL/Compact_mesh_cell_base_3.h b/Mesh_3/include/CGAL/Compact_mesh_cell_base_3.h index fb1010106f1..174b38e735b 100644 --- a/Mesh_3/include/CGAL/Compact_mesh_cell_base_3.h +++ b/Mesh_3/include/CGAL/Compact_mesh_cell_base_3.h @@ -109,7 +109,9 @@ class Compact_mesh_cell_base_3_base Compact_mesh_cell_base_3_base() : bits_(0) { +#ifndef CGAL_MESH_3_NO_CIRCUMCENTER_CACHE internal_tbb::set_weighted_circumcenter(weighted_circumcenter_, nullptr); +#endif } public: @@ -152,16 +154,21 @@ class Compact_mesh_cell_base_3_base return ( (bits_ & (1 << facet)) != 0 ); } +#ifndef CGAL_MESH_3_NO_CIRCUMCENTER_CACHE /// Precondition weighted_circumcenter_ == nullptr void try_to_set_circumcenter(Point_3 *cc) const { CGAL_precondition(weighted_circumcenter_ == nullptr); weighted_circumcenter_ = cc; } +#endif -private: - char bits_; +protected: +#ifndef CGAL_MESH_3_NO_CIRCUMCENTER_CACHE + mutable Point_3* weighted_circumcenter_; +#endif +private: #if defined(CGAL_MESH_3_USE_LAZY_SORTED_REFINEMENT_QUEUE) \ || defined(CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE) @@ -169,8 +176,7 @@ class Compact_mesh_cell_base_3_base Erase_counter_type m_erase_counter; #endif -protected: - mutable Point_3* weighted_circumcenter_; + char bits_; }; @@ -184,7 +190,9 @@ class Compact_mesh_cell_base_3_base Compact_mesh_cell_base_3_base() { bits_ = 0; +#ifndef CGAL_MESH_3_NO_CIRCUMCENTER_CACHE weighted_circumcenter_ = nullptr; +#endif } public: @@ -234,6 +242,7 @@ class Compact_mesh_cell_base_3_base return ( (bits_ & char(1 << facet)) != 0 ); } +#ifndef CGAL_MESH_3_NO_CIRCUMCENTER_CACHE /// If the circumcenter is already set (weighted_circumcenter_ != nullptr), /// this function "deletes" cc void try_to_set_circumcenter(Point_3 *cc) const @@ -242,51 +251,54 @@ class Compact_mesh_cell_base_3_base if (!weighted_circumcenter_.compare_exchange_strong(base_test, cc)) delete cc; } +#endif + +protected: +#ifndef CGAL_MESH_3_NO_CIRCUMCENTER_CACHE + mutable std::atomic weighted_circumcenter_; +#endif private: typedef std::atomic Erase_counter_type; Erase_counter_type m_erase_counter; + /// Stores visited facets (4 first bits) std::atomic bits_; - -protected: - mutable std::atomic weighted_circumcenter_; }; #endif // CGAL_LINKED_WITH_TBB +namespace experimental { // Class Compact_mesh_cell_base_3 // Cell base class used in 3D meshing process. // Adds information to Cb about the cell of the input complex containing it template< class Point_3, - class Weighted_point_3, - class Subdomain_index_, - class Surface_patch_index_, + class WeightedPoint_3, + class SubdomainIndex, + class SurfacePatchIndex, class Index_, class TDS> class Compact_mesh_cell_3 : public Compact_mesh_cell_base_3_base { typedef Compact_mesh_cell_base_3_base Base; - using Base::weighted_circumcenter_; public: - typedef TDS Triangulation_data_structure; - typedef typename TDS::Vertex_handle Vertex_handle; - typedef typename TDS::Cell_handle Cell_handle; - typedef typename TDS::Vertex Vertex; - typedef typename TDS::Cell Cell; - typedef typename TDS::Cell_data TDS_data; + typedef TDS Triangulation_data_structure; + typedef typename TDS::Vertex_handle Vertex_handle; + typedef typename TDS::Cell_handle Cell_handle; + typedef typename TDS::Vertex Vertex; + typedef typename TDS::Cell Cell; + typedef typename TDS::Cell_data TDS_data; // Index Type - typedef Subdomain_index_ Subdomain_index; - typedef Surface_patch_index_ Surface_patch_index; - typedef Index_ Index; - - typedef Weighted_point_3 Point; + typedef SubdomainIndex Subdomain_index; + typedef SurfacePatchIndex Surface_patch_index; + typedef Index_ Index; + typedef WeightedPoint_3 Point; typedef Point* Point_container; typedef Point* Point_iterator; @@ -295,10 +307,12 @@ class Compact_mesh_cell_3 public: void invalidate_weighted_circumcenter_cache() const { - if (!internal_tbb::is_null(weighted_circumcenter_)) { - internal_tbb::delete_circumcenter(weighted_circumcenter_); - internal_tbb::set_weighted_circumcenter(weighted_circumcenter_, nullptr); +#ifndef CGAL_MESH_3_NO_CIRCUMCENTER_CACHE + if (!internal_tbb::is_null(this->weighted_circumcenter_)) { + internal_tbb::delete_circumcenter(this->weighted_circumcenter_); + internal_tbb::set_weighted_circumcenter(this->weighted_circumcenter_, nullptr); } +#endif } public: @@ -307,22 +321,15 @@ class Compact_mesh_cell_3 {} Compact_mesh_cell_3(const Compact_mesh_cell_3& rhs) - : N(rhs.N) + : subdomain_index_(rhs.subdomain_index_) + , N(rhs.N) , V(rhs.V) #ifdef CGAL_INTRUSIVE_LIST , next_intrusive_(rhs.next_intrusive_) , previous_intrusive_(rhs.previous_intrusive_) #endif , time_stamp_(rhs.time_stamp_) - , sliver_value_(rhs.sliver_value_) - , subdomain_index_(rhs.subdomain_index_) - , sliver_cache_validity_(false) { - for(int i=0; i <4; i++){ - surface_index_table_[i] = rhs.surface_index_table_[i]; - surface_center_table_[i]= rhs.surface_center_table_[i]; - surface_center_index_table_[i] = rhs.surface_center_index_table_[i]; - } } Compact_mesh_cell_3 (Vertex_handle v0, @@ -349,10 +356,12 @@ class Compact_mesh_cell_3 ~Compact_mesh_cell_3() { - if(!internal_tbb::is_null(weighted_circumcenter_)){ - internal_tbb::delete_circumcenter(weighted_circumcenter_); - internal_tbb::set_weighted_circumcenter(weighted_circumcenter_, nullptr); +#ifndef CGAL_MESH_3_NO_CIRCUMCENTER_CACHE + if(!internal_tbb::is_null(this->weighted_circumcenter_)){ + internal_tbb::delete_circumcenter(this->weighted_circumcenter_); + internal_tbb::set_weighted_circumcenter(this->weighted_circumcenter_, nullptr); } +#endif } // ACCESS FUNCTIONS @@ -416,8 +425,6 @@ class Compact_mesh_cell_3 } // SETTING - - void set_neighbor(int i, Cell_handle n) { CGAL_precondition( i >= 0 && i <= 3); @@ -460,7 +467,6 @@ class Compact_mesh_cell_3 TDS_data& tds_data() { return _tds_data; } const TDS_data& tds_data() const { return _tds_data; } - Point_iterator hidden_points_begin() const { return hidden_points_end(); } Point_iterator hidden_points_end() const { return nullptr; } void hide_point (const Point&) const { } @@ -492,11 +498,18 @@ class Compact_mesh_cell_3 } template - const Point_3& weighted_circumcenter(const GT_& gt) const + decltype(auto) weighted_circumcenter(const GT_& gt) const { +#ifdef CGAL_MESH_3_NO_CIRCUMCENTER_CACHE + return gt.construct_weighted_circumcenter_3_object() + (this->vertex(0)->point(), + this->vertex(1)->point(), + this->vertex(2)->point(), + this->vertex(3)->point()); +#else static_assert(std::is_same::value); - if (internal_tbb::is_null(weighted_circumcenter_)) { + if (internal_tbb::is_null(this->weighted_circumcenter_)) { this->try_to_set_circumcenter( new Point_3(gt.construct_weighted_circumcenter_3_object() (this->vertex(0)->point(), @@ -508,9 +521,10 @@ class Compact_mesh_cell_3 (this->vertex(0)->point(), this->vertex(1)->point(), this->vertex(2)->point(), - this->vertex(3)->point()) == *weighted_circumcenter_); + this->vertex(3)->point()) == *(this->weighted_circumcenter_)); } - return *weighted_circumcenter_; + return *(this->weighted_circumcenter_); +#endif } // Returns the index of the cell of the input complex that contains the cell @@ -520,21 +534,144 @@ class Compact_mesh_cell_3 void set_subdomain_index(const Subdomain_index& index) { subdomain_index_ = index; } - void set_sliver_value(double value) + static + std::string io_signature() { - sliver_cache_validity_ = true; - sliver_value_ = value; + using Geom_traits = typename Kernel_traits::type; + return + Get_io_signature()() + "+" + + Get_io_signature >()() + + "+(" + Get_io_signature()() + ")[4]"; } - double sliver_value() const +#ifdef CGAL_INTRUSIVE_LIST +public: + Cell_handle next_intrusive() const { return next_intrusive_; } + void set_next_intrusive(Cell_handle c) { - CGAL_assertion(is_cache_valid()); - return sliver_value_; + next_intrusive_ = c; } - bool is_cache_valid() const { return sliver_cache_validity_; } - void reset_cache_validity() const { sliver_cache_validity_ = false; } + Cell_handle previous_intrusive() const { return previous_intrusive_; } + void set_previous_intrusive(Cell_handle c) + { + previous_intrusive_ = c; + } +#endif // CGAL_INTRUSIVE_LIST + + /// For the determinism of Compact_container iterators + ///@{ + typedef Tag_true Has_timestamp; + + std::size_t time_stamp() const { + return time_stamp_; + } + void set_time_stamp(const std::size_t& ts) { + time_stamp_ = ts; + } + ///@} + +private: + // tds_data (1 byte) and subdomain index (4, usually) are at the top of the class members + // to use the tail padding from the base_base class (usually 8+1, or 8+4+1 with lazy queues) + TDS_data _tds_data; + // The index of the cell of the input complex that contains me + Subdomain_index subdomain_index_ = {}; + + std::array N; + std::array V; + +#ifdef CGAL_INTRUSIVE_LIST + Cell_handle next_intrusive_ = {}, previous_intrusive_ = {}; +#endif + + std::size_t time_stamp_ = Time_stamper::invalid_time_stamp; + + // Point_container _hidden; + +public: + friend std::istream& operator>>(std::istream &is, Compact_mesh_cell_3 &c) + { + Subdomain_index index; + if(IO::is_ascii(is)) + is >> index; + else + read(is, index); + if(is) { + c.set_subdomain_index(index); + } + return is; + } + + friend + std::ostream& operator<<(std::ostream &os, const Compact_mesh_cell_3 &c) + { + if(IO::is_ascii(os)) + os << c.subdomain_index(); + else + write(os, c.subdomain_index()); + return os; + } + +}; // class Compact_mesh_cell_3 + +} // namespace experimental + +template< class Point_3, + class WeightedPoint_3, + class SubdomainIndex, + class SurfacePatchIndex, + class Index_, + class TDS> +class Compact_mesh_cell_3 + : public experimental::Compact_mesh_cell_3 +{ + typedef CGAL::Compact_mesh_cell_3 Self; + typedef experimental::Compact_mesh_cell_3 Base; + +public: + typedef TDS Triangulation_data_structure; + typedef typename TDS::Vertex_handle Vertex_handle; + typedef typename TDS::Cell_handle Cell_handle; + typedef typename TDS::Vertex Vertex; + typedef typename TDS::Cell Cell; + typedef typename TDS::Cell_data TDS_data; + + + // Index Type + typedef SubdomainIndex Subdomain_index; + typedef SurfacePatchIndex Surface_patch_index; + typedef Index_ Index; + + typedef WeightedPoint_3 Point; + + typedef Point* Point_container; + typedef Point* Point_iterator; + typedef const Point* Point_const_iterator; + +public: + Compact_mesh_cell_3(const Self& rhs) + : Base(static_cast(rhs)) + , sliver_value_(rhs.sliver_value_) + , sliver_cache_validity_(false) + { + for(int i=0; i <4; i++){ + surface_index_table_[i] = rhs.surface_index_table_[i]; + surface_center_table_[i]= rhs.surface_center_table_[i]; + surface_center_index_table_[i] = rhs.surface_center_index_table_[i]; + } + } + + template + Compact_mesh_cell_3(Args&& ... args) + : Base(std::forward(args)...) + { } + +public: /// Set surface index of `facet` to `index` void set_surface_patch_index(const int facet, const Surface_patch_index& index) { @@ -557,7 +694,7 @@ class Compact_mesh_cell_3 } /// Returns surface center of `facet` - Point_3 get_facet_surface_center(const int facet) const + const Point_3& get_facet_surface_center(const int facet) const { CGAL_precondition(facet>=0 && facet<4); return surface_center_table_[facet]; @@ -601,75 +738,33 @@ class Compact_mesh_cell_3 // End backward Compatibility // ----------------------------------- - static - std::string io_signature() - { - using Geom_traits = typename Kernel_traits::type; - return - Get_io_signature()() + "+" + - Get_io_signature >()() - + "+(" + Get_io_signature()() + ")[4]"; - } + bool is_cache_valid() const { return sliver_cache_validity_; } + void reset_cache_validity() const { sliver_cache_validity_ = false; } -#ifdef CGAL_INTRUSIVE_LIST -public: - Cell_handle next_intrusive() const { return next_intrusive_; } - void set_next_intrusive(Cell_handle c) + void set_sliver_value(double value) { - next_intrusive_ = c; + sliver_cache_validity_ = true; + sliver_value_ = value; } - Cell_handle previous_intrusive() const { return previous_intrusive_; } - void set_previous_intrusive(Cell_handle c) + double sliver_value() const { - previous_intrusive_ = c; - } -#endif // CGAL_INTRUSIVE_LIST - - /// For the determinism of Compact_container iterators - ///@{ - typedef Tag_true Has_timestamp; - - std::size_t time_stamp() const { - return time_stamp_; - } - void set_time_stamp(const std::size_t& ts) { - time_stamp_ = ts; + CGAL_assertion(is_cache_valid()); + return sliver_value_; } - ///@} private: - - /// Stores surface_index for each facet of the cell std::array surface_index_table_ = {}; /// Stores surface center of each facet of the cell std::array surface_center_table_ = {}; /// Stores surface center index of each facet of the cell - - std::array N; - std::array V; - -#ifdef CGAL_INTRUSIVE_LIST - Cell_handle next_intrusive_ = {}, previous_intrusive_ = {}; -#endif - std::size_t time_stamp_ = Time_stamper::invalid_time_stamp; - std::array surface_center_index_table_ = {}; - /// Stores visited facets (4 first bits) - - // Point_container _hidden; double sliver_value_ = 0.; - - // The index of the cell of the input complex that contains me - Subdomain_index subdomain_index_ = {}; - - TDS_data _tds_data; mutable bool sliver_cache_validity_ = false; public: - friend std::istream& operator>>(std::istream &is, Compact_mesh_cell_3 &c) { Subdomain_index index; @@ -680,38 +775,36 @@ class Compact_mesh_cell_3 if(is) { c.set_subdomain_index(index); for(int i = 0; i < 4; ++i) - { - Surface_patch_index i2; - if(IO::is_ascii(is)) - is >> IO::iformat(i2); - else - { - read(is, i2); - } - c.set_surface_patch_index(i, i2); - } + { + Surface_patch_index i2; + if(IO::is_ascii(is)) + is >> IO::iformat(i2); + else + { + read(is, i2); + } + c.set_surface_patch_index(i, i2); + } } return is; } - friend - std::ostream& operator<<(std::ostream &os, const Compact_mesh_cell_3 &c) + friend std::ostream& operator<<(std::ostream &os, const Compact_mesh_cell_3 &c) { if(IO::is_ascii(os)) os << c.subdomain_index(); else write(os, c.subdomain_index()); for(int i = 0; i < 4; ++i) - { - if(IO::is_ascii(os)) - os << ' ' << IO::oformat(c.surface_patch_index(i)); - else - write(os, c.surface_patch_index(i)); - } + { + if(IO::is_ascii(os)) + os << ' ' << IO::oformat(c.surface_patch_index(i)); + else + write(os, c.surface_patch_index(i)); + } return os; } - -}; // end class Compact_mesh_cell_3 +}; /*! \ingroup PkgMesh3MeshClasses @@ -758,12 +851,21 @@ class Compact_mesh_cell_base_3 typedef Triangulation_data_structure::Cell_handle Cell_handle; template struct Rebind_TDS { +#ifdef CGAL_MESH_3_USE_EXPERIMENTAL_COMPACT_MESH_CELL_BASE_3 + typedef experimental::Compact_mesh_cell_3 Other; +#else typedef Compact_mesh_cell_3 Other; +#endif }; }; @@ -783,12 +885,21 @@ class Compact_mesh_cell_generator_3 typedef Triangulation_data_structure::Cell_handle Cell_handle; template struct Rebind_TDS { +#ifdef CGAL_MESH_3_USE_EXPERIMENTAL_COMPACT_MESH_CELL_BASE_3 + typedef experimental::Compact_mesh_cell_3 Other; +#else typedef Compact_mesh_cell_3 Other; +#endif }; }; diff --git a/Mesh_3/include/CGAL/Mesh_3/C3T3_helpers.h b/Mesh_3/include/CGAL/Mesh_3/C3T3_helpers.h index 4b900e0e602..7e15e1a4136 100644 --- a/Mesh_3/include/CGAL/Mesh_3/C3T3_helpers.h +++ b/Mesh_3/include/CGAL/Mesh_3/C3T3_helpers.h @@ -631,8 +631,8 @@ class C3T3_helpers_base template class C3T3_helpers -: public C3T3_helpers_base + : public C3T3_helpers_base { // ----------------------------------- // Private types @@ -703,7 +703,7 @@ class C3T3_helpers // ----------------------------------- // Public interface // ----------------------------------- - typedef std::optional Update_mesh; + typedef std::optional Update_mesh; using Base::try_lock_point; using Base::try_lock_vertex; @@ -905,14 +905,6 @@ class C3T3_helpers const FT& sliver_bound, OutputIterator out) const; - - template - OutputIterator - new_incident_slivers(const Vertex_handle& v, - const SliverCriterion& criterion, - const FT& sliver_bound, - OutputIterator out) const; - /** * Returns the sliver (wrt `criterion` and `sliver_bound`) incident to `v` */ @@ -927,17 +919,6 @@ class C3T3_helpers return slivers; } - template - Cell_vector - new_incident_slivers(const Vertex_handle& v, - const SliverCriterion& criterion, - const FT& sliver_bound) const - { - Cell_vector slivers; - new_incident_slivers(v, criterion, sliver_bound, std::back_inserter(slivers)); - return slivers; - } - /** * Returns the number of slivers incident to `v` @@ -964,16 +945,6 @@ class C3T3_helpers const SliverCriterion& criterion, const bool use_cache = true) const; - /** - * Reset cache validity of all cells of c3t3_ - */ - void reset_cache() const - { - for(typename C3T3::Cells_in_complex_iterator it = c3t3_.cells_in_complex_begin(); - it != c3t3_.cells_in_complex_end(); ++it) - it->reset_cache_validity(); - } - private: // ----------------------------------- // Useful Functors @@ -993,15 +964,10 @@ class C3T3_helpers void operator()(const Cell_handle& cell) { -#ifndef CGAL_MESH_3_NEW_GET_FACETS - for ( int i=0 ; i<4 ; ++i ) - if ( !tr_.is_infinite(cell,i) ) - *out_++ = canonical_facet(cell,i); -#else // Instead of iterating over the facets we iterate over the vertices // If a vertex is infinite we report only the facet opposite to it and return // If all vertices are finite we report all facets - // This approach makes less tests if vertices are infinite + // This approach performs fewer tests than a naive loop over all finite facets int i=0; for ( ; i<4 ; ++i ){ if ( tr_.is_infinite(cell->vertex(i)) ){ @@ -1012,24 +978,13 @@ class C3T3_helpers for ( i=0 ; i<4 ; ++i ){ *out_++ = canonical_facet(cell,i); } -#endif } private: Facet canonical_facet(const Cell_handle& c, const int i) const { -#ifndef CGAL_MESH_3_NEW_GET_FACETS - Facet facet(c,i); - Facet mirror = tr_.mirror_facet(facet); - return ( (mirrorneighbor(i); - if(c < n){ - return Facet(c,i); - }else{ - return Facet(n,n->index(c)); - } -#endif + return (c < n) ? Facet(c, i) : Facet(n, n->index(c)); } private: @@ -1068,28 +1023,19 @@ class C3T3_helpers const FT& bound = 0) : c3t3_(c3t3) , criterion_(criterion) - , bound_(bound) { } + , bound_(bound) + { + CGAL_assertion(bound_ <= criterion_.sliver_bound()); + } bool operator()(const Cell_handle& c) const { if ( c3t3_.is_in_complex(c) ) { - CGAL_assertion(!c3t3_.triangulation().is_infinite(c)); - - if ( ! c->is_cache_valid() ) - { - Sliver_criterion_value sc_value(c3t3_.triangulation(), - criterion_); - (void) sc_value(c); // 'sc_value::operator()' updates the cache of 'c' - } - else - { - CGAL_expensive_assertion(c->sliver_value() == criterion_(c)); - } - if(bound_ > 0) - return ( c->sliver_value() <= bound_ ); + if (bound_ > 0) + return (criterion_(c) <= bound_); else - return ( c->sliver_value() <= criterion_.sliver_bound() ); + return criterion_.is_sliver(c); } else return false; @@ -1262,9 +1208,9 @@ class C3T3_helpers #endif // NOT CGAL_MESH_3_NO_LONGER_CALLS_DO_INTERSECT_3 // Update facet surface center - Bare_point surface_center = std::get<0>(intersection); - facet.first->set_facet_surface_center(facet.second, surface_center); - facet_m.first->set_facet_surface_center(facet_m.second, surface_center); + const Bare_point& surface_center = std::get<0>(intersection); + c3t3_.set_surface_center(facet.first, facet.second, surface_center); + c3t3_.set_surface_center(facet_m.first, facet_m.second, surface_center); } } @@ -1321,52 +1267,13 @@ class C3T3_helpers }; // end class Facet_updater - - /** - * @class Sliver_criterion_value - * - * A functor which returns sliver criterion value for a Cell_handle - * and updates its cache value - */ - template - class Sliver_criterion_value - : public CGAL::cpp98::unary_function - { - public: - Sliver_criterion_value(const Tr& tr, - const SliverCriterion& criterion) - : p_tr_(&tr) - , criterion_(criterion) {} - - FT operator()(const Cell_handle& ch) const - { - CGAL_precondition(!p_tr_->is_infinite(ch)); - - if ( ! ch->is_cache_valid() ) - { - double sliver_value = criterion_(ch); - ch->set_sliver_value(sliver_value); - } - else - { - CGAL_expensive_assertion(ch->sliver_value() == criterion_(ch)); - } - return ch->sliver_value(); - } - - private: - // '=' is used, so p_tr_ must be a pointer ... - const Tr* p_tr_; - SliverCriterion criterion_; - }; - /** * to be used by the perturber */ class Cell_from_ids { public: - Cell_from_ids(const C3T3& c3t3, const Cell_handle& c) + Cell_from_ids(const Cell_handle& c, const C3T3& c3t3) : infinite_(c3t3.triangulation().is_infinite(c)) , vertices_() , sorted_vertices_() @@ -1408,11 +1315,15 @@ class C3T3_helpers class Cell_data_backup { + typedef std::array IndexMap; + public: - Cell_data_backup(const C3T3& c3t3, - const Cell_handle& c, + template + Cell_data_backup(const Cell_handle& c, + const C3T3& c3t3, + const SliverCriterion& criterion, const bool do_backup = true) - : cell_ids_(c3t3, c) + : cell_ids_(c, c3t3) { //backup is not done when constructor is called to //convert a newly created cell (has nothing to backup) @@ -1420,27 +1331,28 @@ class C3T3_helpers if(do_backup) { if (!c3t3.triangulation().is_infinite(c)) - backup_finite_cell(c); + backup_finite_cell(c, c3t3, criterion); else backup_infinite_cell(c, c3t3); } } private: - void backup_finite_cell(const Cell_handle& c) + template + void backup_finite_cell(const Cell_handle& c, + const C3T3& c3t3, + const SliverCriterion& criterion) { - if(c->is_cache_valid()) - sliver_value_ = c->sliver_value(); - else - sliver_value_ = 0.; + sliver_value_ = criterion.is_sliver(c) ? criterion(c) : 0.; - subdomain_index_ = c->subdomain_index(); + subdomain_index_ = c3t3.subdomain_index(c); for(std::size_t i = 0; i < 4; ++i) { const int ii = static_cast(i);//avoid warnings - surface_index_table_[i] = c->surface_patch_index(ii); - facet_surface_center_[i] = c->get_facet_surface_center(ii); - surface_center_index_table_[i] = c->get_facet_surface_center_index(ii); + if (c3t3.is_in_complex(Facet(c, ii))) + surface_prop_table_[i] = c3t3.surface_info(Facet(c, ii)); + else + surface_prop_table_[i] = Facet_prop(); } //note c->next_intrusive() and c->previous_intrusive() //are lost by 'backup' and 'restore', @@ -1451,16 +1363,11 @@ class C3T3_helpers void backup_infinite_cell(const Cell_handle& c, const C3T3& c3t3) { - for (int ii = 0; ii < 4; ++ii) - { - if (c3t3.triangulation().is_infinite(c->vertex(ii))) - { - surface_index_table_[0] = c->surface_patch_index(ii); - facet_surface_center_[0] = c->get_facet_surface_center(ii); - surface_center_index_table_[0] = c->get_facet_surface_center_index(ii); - break; - } - } + int infinite_index = c->index(c3t3.triangulation().infinite_vertex()); + if (c3t3.is_in_complex(Facet(c, infinite_index))) + surface_prop_table_[0] = c3t3.surface_info(Facet(c, infinite_index)); + else + surface_prop_table_[0] = Facet_prop(); } public: @@ -1474,7 +1381,10 @@ class C3T3_helpers * (checked before function is called) * resets new_cell's meta-data to its back-uped values */ - void restore(Cell_handle new_cell, C3T3& c3t3) + template + void restore(Cell_handle new_cell, + C3T3& c3t3, + const SliverCriterion& criterion) { if (c3t3.triangulation().is_infinite(new_cell)) return restore_infinite_cell(new_cell, c3t3); @@ -1497,18 +1407,18 @@ class C3T3_helpers }//end loop i CGAL_assertion(nbv_found == 4); - restore(new_cell, new_to_old_indices, c3t3); + restore_finite_cell(new_cell, new_to_old_indices, c3t3, criterion); } private: - typedef std::array IndexMap; - - void restore(Cell_handle c, - const IndexMap& index_map,//new_to_old_indices - C3T3& c3t3) + template + void restore_finite_cell(Cell_handle c, + const IndexMap& index_map,//new_to_old_indices + C3T3& c3t3, + const SliverCriterion& criterion) { if(sliver_value_ > 0.) - c->set_sliver_value(sliver_value_); + criterion.set_cache(c, sliver_value_); for(int i = 0; i < 4; ++i) c->reset_visited(i); @@ -1525,17 +1435,18 @@ class C3T3_helpers for(int i = 0; i < 4; ++i) { + Facet f(c, i); std::size_t old_i = index_map.at(static_cast(i)); - Surface_patch_index index = surface_index_table_[old_i]; + Surface_patch_index index = surface_prop_table_[old_i].surface_index_; //add_to_complex sets the index, and updates the facet counter - if(!( Surface_patch_index() == index )) - c3t3.add_to_complex(Facet(c, i), index); - else - c3t3.remove_from_complex(Facet(c,i)); - - c->set_facet_surface_center(i, facet_surface_center_[old_i]); - const Facet mirror = c3t3.triangulation().mirror_facet(Facet(c, i)); - mirror.first->set_facet_surface_center(mirror.second, facet_surface_center_[old_i]); + if(!( Surface_patch_index() == index )) { + c3t3.add_to_complex(f, index); + c3t3.set_surface_info(f, surface_prop_table_[old_i]); + const Facet mirror = c3t3.triangulation().mirror_facet(f); + c3t3.set_surface_info(mirror, surface_prop_table_[old_i]); + } else { + c3t3.remove_from_complex(f); + } } } @@ -1543,35 +1454,29 @@ class C3T3_helpers C3T3& c3t3) { c3t3.remove_from_complex(c);//infinite - for (unsigned int i = 0; i < 4; ++i) - { - if (!c3t3.triangulation().is_infinite(Facet(c,i))) - { - Surface_patch_index index = surface_index_table_[0]; - if (!( Surface_patch_index() == index )) - c3t3.add_to_complex(Facet(c, i), index); - else - c3t3.remove_from_complex(Facet(c, i)); - - c->set_facet_surface_center(i, facet_surface_center_[0]); - const Facet mirror = c3t3.triangulation().mirror_facet(Facet(c, i)); - mirror.first->set_facet_surface_center(mirror.second, facet_surface_center_[0]); - return; - } + + const int i = c->index(c3t3.triangulation().infinite_vertex()); + Facet f(c, i); + + Surface_patch_index index = surface_prop_table_[0].surface_index_; + if (!( Surface_patch_index() == index )) { + c3t3.add_to_complex(f, index); + c3t3.set_surface_info(f, surface_prop_table_[0]); + const Facet mirror = c3t3.triangulation().mirror_facet(f); + c3t3.set_surface_info(mirror, surface_prop_table_[0]); + } else { + c3t3.remove_from_complex(f); } } private: - typedef typename Tr::Cell::Subdomain_index Subdomain_index; - typedef typename Tr::Cell::Surface_patch_index Surface_patch_index; - typedef typename Tr::Cell::Index Index; + typedef typename C3T3::Subdomain_index Subdomain_index; + typedef typename C3T3::Facet_prop Facet_prop; Cell_from_ids cell_ids_; FT sliver_value_; Subdomain_index subdomain_index_; - std::array surface_index_table_; - std::array facet_surface_center_; - std::array surface_center_index_table_; + std::array surface_prop_table_; }; private: @@ -1635,14 +1540,15 @@ class C3T3_helpers /** * Backup cells meta-data to a vector of Cell_data_backup */ - template + template void fill_cells_backup(const CellsVector& cells, + const SliverCriterion& criterion, CellDataSet& cells_backup) const; - template - void restore_from_cells_backup(const CellsVector& cells, - CellDataSet& cells_backup) const; - + template + void restore_from_cells_backup(CellDataSet& cells_backup, + const SliverCriterion& criterion, + const CellsVector& cells) const; /** * Update mesh iff sliver criterion value does not decrease. @@ -1660,8 +1566,8 @@ class C3T3_helpers * Move point and returns the set of cells that are not valid anymore, and * the set of cells which have been deleted by the move process. */ - template < typename OutdatedCellsOutputIterator, - typename DeletedCellsOutputIterator > + template Vertex_handle move_point(const Vertex_handle& old_vertex, const Vector_3& move, OutdatedCellsOutputIterator outdated_cells, @@ -1673,13 +1579,15 @@ class C3T3_helpers Outdated_cell_set& outdated_cells_set, bool *could_lock_zone = nullptr) const; - template < typename OutdatedCellsOutputIterator, - typename DeletedCellsOutputIterator > + template Vertex_handle move_point_topo_change(const Vertex_handle& old_vertex, const Weighted_point& new_position, OutdatedCellsOutputIterator outdated_cells, - DeletedCellsOutputIterator deleted_cells) const; + DeletedCellsOutputIterator deleted_cells, + SliverCriterion* criterion = nullptr) const; Vertex_handle move_point_topo_change(const Vertex_handle& old_vertex, const Weighted_point& new_position) const; @@ -1735,17 +1643,20 @@ class C3T3_helpers * vertex located at `old_point` * and an output iterator on outdated cells */ - template + template Vertex_handle revert_move(const Vertex_handle& new_vertex, const Weighted_point& old_point, - OutputIterator outdated_cells) + OutputIterator outdated_cells, + SliverCriterion* criterion) { // Move vertex Vertex_handle revert_vertex = move_point_topo_change(new_vertex, old_point, outdated_cells, - CGAL::Emptyset_iterator()); //deleted cells + CGAL::Emptyset_iterator(), // deleted cells + criterion); CGAL_assertion(Vertex_handle() != revert_vertex); return revert_vertex; @@ -1957,7 +1868,7 @@ class C3T3_helpers { tbb::parallel_for_each( outdated_cells.begin(), outdated_cells.end(), - Update_cell_facets(tr_, updater)); + Update_cell_facets(tr_, updater)); } // Sequential else @@ -1968,7 +1879,7 @@ class C3T3_helpers it != outdated_cells.end(); ++it) { - Update_cell_facets ucf(tr_, updater); + Update_cell_facets ucf(tr_, updater); ucf(*it); } } @@ -1986,7 +1897,7 @@ class C3T3_helpers tbb::parallel_for ( tbb::blocked_range(0, outdated_cells_vector.size()), - Update_cell_facets_for_parallel_for( + Update_cell_facets_for_parallel_for( tr_, updater, outdated_cells_vector) ); } @@ -1999,7 +1910,7 @@ class C3T3_helpers it != outdated_cells_vector.end(); ++it) { - Update_cell_facets ucf(tr_, updater); + Update_cell_facets ucf(tr_, updater); ucf(*it); } } @@ -2059,16 +1970,16 @@ class C3T3_helpers fit != facets.end() ; ++fit ) { - if ( c3t3_.is_in_complex(*fit) ) - { + Surface_patch_index pid = c3t3_.surface_patch_index(*fit); + const bool facet_in_complex = !(pid == Surface_patch_index()); + if ( facet_in_complex ) surface_facets.push_back(*fit); - } + const Surface_patch sp = checker(*fit, false, /* do not update c3t3 */ true); /* update surface centers */ // false means "do not update the c3t3" - if ( c3t3_.is_in_complex(*fit) != (bool)sp || - ((bool)sp && !(c3t3_.surface_patch_index(*fit) == *sp) ) ) + if ( facet_in_complex != (bool)sp || ((bool)sp && !(pid == *sp) ) ) return false; } @@ -2148,21 +2059,32 @@ class C3T3_helpers } } - template - void reset_sliver_cache(CellRange& cell_range) const +public: + template + void reset_sliver_cache(const SliverCriterion& criterion, + CellForwardIterator cells_begin, + CellForwardIterator cells_end) const { - reset_sliver_cache(std::begin(cell_range), - std::end(cell_range)); + for (; cells_begin != cells_end; ++cells_begin) { + criterion.reset_cache(*cells_begin); + } } - template - void reset_sliver_cache(CellForwardIterator cells_begin, - CellForwardIterator cells_end) const + template + void reset_sliver_cache(const SliverCriterion& criterion, + const CellRange& cell_range) const { - while(cells_begin != cells_end) { - (*cells_begin)->reset_cache_validity(); - ++cells_begin; - } + reset_sliver_cache(criterion, std::begin(cell_range), std::end(cell_range)); + } + + /** + * Reset cache validity of all cells of c3t3_ + */ + template + void reset_sliver_cache(const SliverCriterion& criterion) const + { + for (Cell_handle ch : c3t3_.cells_in_complex()) + criterion.reset_cache(ch); } template @@ -2174,7 +2096,7 @@ class C3T3_helpers template void reset_circumcenter_cache(CellForwardIterator cells_begin, - CellForwardIterator cells_end) const + CellForwardIterator cells_end) const { while(cells_begin != cells_end) { (*cells_begin)->invalidate_weighted_circumcenter_cache(); @@ -2200,9 +2122,8 @@ class C3T3_helpers } private: - // Functor for update_facets function (base) - template + template class Update_cell_facets { Tr & m_tr; @@ -2258,7 +2179,7 @@ class C3T3_helpers public: // Constructor Update_cell_facets(Tr &tr, - FacetUpdater_& fu) + FacetUpdater_& fu) : m_tr(tr), m_facet_updater(fu) {} @@ -2276,11 +2197,11 @@ class C3T3_helpers #ifdef CGAL_LINKED_WITH_TBB // Same functor: special version for tbb:parallel_for - template + template class Update_cell_facets_for_parallel_for - : Update_cell_facets + : Update_cell_facets { - typedef Update_cell_facets Base; + typedef Update_cell_facets Base; using Base::update; const std::vector & m_outdated_cells; @@ -2425,7 +2346,8 @@ class C3T3_helpers m_updater(facet); // Update m_vertex_to_proj - if ( m_c3t3.is_in_complex(facet) ) + Surface_patch_index pid = m_c3t3.surface_patch_index(facet); + if ( !(pid == Surface_patch_index()) ) // // is facet in complex { // Iterate on vertices int k = facet.second; @@ -2434,8 +2356,7 @@ class C3T3_helpers const Vertex_handle& v = facet.first->vertex((k+i)&3); if ( m_c3t3.in_dimension(v) > 2 ) { - std::pair p - = std::make_pair(v, m_c3t3.surface_patch_index(facet)); + std::pair p = std::make_pair(v, pid); m_c3t3_helpers.lock_vertex_to_proj(); m_vertex_to_proj.insert(p); m_c3t3_helpers.unlock_vertex_to_proj(); @@ -2510,7 +2431,7 @@ update_mesh_no_topo_change(const Vertex_handle& old_vertex, //backup metadata std::set cells_backup; - fill_cells_backup(conflict_cells, cells_backup); + fill_cells_backup(conflict_cells, criterion, cells_backup); // Get old values criterion.before_move(c3t3_cells(conflict_cells)); @@ -2518,7 +2439,7 @@ update_mesh_no_topo_change(const Vertex_handle& old_vertex, // Move point reset_circumcenter_cache(conflict_cells); - reset_sliver_cache(conflict_cells); + reset_sliver_cache(criterion, conflict_cells); move_point_no_topo_change(old_vertex, move, new_position); // Check that surface mesh is still valid @@ -2542,13 +2463,13 @@ update_mesh_no_topo_change(const Vertex_handle& old_vertex, reset_circumcenter_cache(conflict_cells); // Sliver caches have been updated by valid_move - reset_sliver_cache(conflict_cells); + reset_sliver_cache(criterion, conflict_cells); move_point_no_topo_change(old_vertex, cov(move), old_position); // Restore meta-data (cells should have same connectivity as before move) // cells_backup does not contain infinite cells so they can be fewer CGAL_assertion(conflict_cells.size() >= cells_backup.size()); - restore_from_cells_backup(conflict_cells, cells_backup); + restore_from_cells_backup(cells_backup, criterion, conflict_cells); return std::make_pair(false, old_vertex); } @@ -2595,7 +2516,7 @@ update_mesh_topo_change(const Vertex_handle& old_vertex, // Backup metadata std::set cells_backup; - fill_cells_backup(conflict_cells, cells_backup); + fill_cells_backup(conflict_cells, criterion, cells_backup); CGAL_assertion(conflict_cells.size() == cells_backup.size()); criterion.before_move(c3t3_cells(conflict_cells)); @@ -2607,7 +2528,7 @@ update_mesh_topo_change(const Vertex_handle& old_vertex, get_surface_boundary(old_vertex, conflict_cells, old_incident_surface_vertices); reset_circumcenter_cache(conflict_cells); - reset_sliver_cache(conflict_cells); + reset_sliver_cache(criterion, conflict_cells); Cell_vector outdated_cells; outdated_cells.reserve(64); @@ -2655,17 +2576,18 @@ update_mesh_topo_change(const Vertex_handle& old_vertex, //reset caches in case cells are reused by the compact container reset_circumcenter_cache(outdated_cells); - reset_sliver_cache(outdated_cells); + reset_sliver_cache(criterion, outdated_cells); outdated_cells.clear(); // Revert move Vertex_handle revert_vertex = revert_move(new_vertex, old_position, - std::inserter(outdated_cells, outdated_cells.end())); + std::inserter(outdated_cells, outdated_cells.end()), + &criterion); //restore meta-data (cells should have same connectivity as before move) //cells should be the same (connectivity-wise) as before initial move CGAL_assertion(outdated_cells.size() == cells_backup.size()); - restore_from_cells_backup(outdated_cells, cells_backup); + restore_from_cells_backup(cells_backup, criterion, outdated_cells); return std::make_pair(false,revert_vertex); } @@ -2852,7 +2774,6 @@ rebuild_restricted_delaunay(ForwardIterator first_cell, { typename GT::Construct_point_3 cp = tr_.geom_traits().construct_point_3_object(); typename GT::Construct_vector_3 vector = tr_.geom_traits().construct_vector_3_object(); - typename GT::Equal_3 equal = tr_.geom_traits().equal_3_object(); Update_c3t3 updater(domain_,c3t3_); @@ -2906,7 +2827,8 @@ rebuild_restricted_delaunay(ForwardIterator first_cell, updater(*fit); // Update vertex_to_proj - if ( c3t3_.is_in_complex(*fit) ) + Surface_patch_index pid = c3t3_.surface_patch_index(*fit); + if ( !(pid == Surface_patch_index()) ) // is facet in complex { // Iterate on vertices int k = fit->second; @@ -2914,10 +2836,7 @@ rebuild_restricted_delaunay(ForwardIterator first_cell, { const Vertex_handle& v = fit->first->vertex((k+i)&3); if ( c3t3_.in_dimension(v) > 2 ) - { - vertex_to_proj.insert( - std::make_pair(v, c3t3_.surface_patch_index(*fit))); - } + vertex_to_proj.emplace(v, pid); } } } @@ -3034,7 +2953,7 @@ move_point(const Vertex_handle& old_vertex, if ( Th().no_topological_change(tr_, old_vertex, move, new_position, incident_cells_) ) { reset_circumcenter_cache(incident_cells_); - reset_sliver_cache(incident_cells_); + // reset_sliver_cache(incident_cells_); // global only std::copy(incident_cells_.begin(),incident_cells_.end(), outdated_cells); return move_point_no_topo_change(old_vertex, move, new_position); } @@ -3072,7 +2991,7 @@ move_point(const Vertex_handle& old_vertex, if ( Th().no_topological_change(tr_, old_vertex, move, new_position, incident_cells_) ) { reset_circumcenter_cache(incident_cells_); - reset_sliver_cache(incident_cells_); + // reset_sliver_cache(incident_cells_); // global mesh std::copy(incident_cells_.begin(),incident_cells_.end(), std::inserter(outdated_cells_set, outdated_cells_set.end())); return move_point_no_topo_change(old_vertex, move, new_position); @@ -3141,7 +3060,7 @@ move_point(const Vertex_handle& old_vertex, if ( Th().no_topological_change(tr_, old_vertex, move, new_position, incident_cells_) ) { reset_circumcenter_cache(incident_cells_); - reset_sliver_cache(incident_cells_); + // reset_sliver_cache(incident_cells_); // this function is for global mesh optimizers only lock_outdated_cells(); std::copy(incident_cells_.begin(),incident_cells_.end(), @@ -3215,9 +3134,9 @@ move_point_topo_change(const Vertex_handle& old_vertex, } reset_circumcenter_cache(removal_conflict_cells); - reset_sliver_cache(removal_conflict_cells); + // reset_sliver_cache(removal_conflict_cells); reset_circumcenter_cache(insertion_conflict_cells); - reset_sliver_cache(insertion_conflict_cells); + // reset_sliver_cache(insertion_conflict_cells); if (could_lock_zone && *could_lock_zone == false) { @@ -3272,13 +3191,15 @@ move_point_topo_change(const Vertex_handle& old_vertex, template template + typename DeletedCellsOutputIterator, + typename SliverCriterion> typename C3T3_helpers::Vertex_handle C3T3_helpers:: move_point_topo_change(const Vertex_handle& old_vertex, const Weighted_point& new_position, OutdatedCellsOutputIterator outdated_cells, - DeletedCellsOutputIterator deleted_cells) const + DeletedCellsOutputIterator deleted_cells, + SliverCriterion* criterion) const { Vertex_handle nv; #ifdef CGAL_MESH_3_C3T3_HELPERS_VERBOSE @@ -3298,9 +3219,13 @@ move_point_topo_change(const Vertex_handle& old_vertex, std::back_inserter(insertion_conflict_boundary), std::inserter(removal_conflict_cells, removal_conflict_cells.end())); reset_circumcenter_cache(removal_conflict_cells); - reset_sliver_cache(removal_conflict_cells); reset_circumcenter_cache(insertion_conflict_cells); - reset_sliver_cache(insertion_conflict_cells); + if constexpr (! std::is_same_v) { + if (criterion) { + reset_sliver_cache(*criterion, removal_conflict_cells); + reset_sliver_cache(*criterion, insertion_conflict_cells); + } + } if(insertion_conflict_boundary.empty()) { @@ -3449,7 +3374,7 @@ move_point_no_topo_change(const Vertex_handle& old_vertex, const Weighted_point& new_position) const { // Change vertex position - tr_.set_point(old_vertex, move, new_position); + Th().set_point(tr_, old_vertex, move, new_position); CGAL_expensive_postcondition(tr_.is_valid()); return old_vertex; } @@ -3561,7 +3486,7 @@ get_least_square_surface_plane(const Vertex_handle& v, ref_patch_index = f_patch_index; } - const Triangle ct = tr_.get_incident_triangle(f, v); + const Triangle ct = Th().get_incident_triangle(tr_, f, v); triangles.push_back(ct); } } @@ -3582,8 +3507,8 @@ get_least_square_surface_plane(const Vertex_handle& v, Default_diagonalize_traits()); // The surface center of a facet might have an offset in periodic triangulations - const Bare_point& ref_facet_scp = ref_facet.first->get_facet_surface_center(ref_facet.second); - const Bare_point& ref_point = tr_.get_closest_point(cp(position), ref_facet_scp); + const Bare_point& ref_facet_scp = c3t3_.surface_center(ref_facet.first, ref_facet.second); + const Bare_point& ref_point = Th().get_closest_point(tr_, cp(position), ref_facet_scp); return std::make_tuple(plane, ref_point, ref_patch_index); } @@ -3771,7 +3696,6 @@ try_lock_and_get_incident_slivers(const Vertex_handle& v, return try_lock_and_get_incident_cells(v, slivers, i_s); } - template template OutputIterator @@ -3782,28 +3706,6 @@ incident_slivers(const Vertex_handle& v, OutputIterator out) const { typedef SliverCriterion Sc; - - std::vector incident_cells_; - tr_.incident_cells(v, std::back_inserter(incident_cells_)); - - std::remove_copy_if(incident_cells_.begin(), - incident_cells_.end(), - out, - std::not_fn(Is_sliver(c3t3_, criterion, sliver_bound))); - - return out; -} - -template -template -OutputIterator -C3T3_helpers:: -new_incident_slivers(const Vertex_handle& v, - const SliverCriterion& criterion, - const FT& sliver_bound, - OutputIterator out) const -{ - typedef SliverCriterion Sc; typedef Filter > F; Is_sliver i_s(c3t3_, criterion, sliver_bound); @@ -3860,18 +3762,11 @@ min_sliver_value(const Cell_vector& cells, if ( ! use_cache ) { - reset_sliver_cache(cells.begin(),cells.end()); + reset_sliver_cache(criterion, cells.begin(),cells.end()); } - // Return min dihedral angle - //Sliver_criterion_value sc_value(tr_,criterion); - // - //return *(std::min_element(make_transform_iterator(cells.begin(),sc_value), - // make_transform_iterator(cells.end(),sc_value))); FT min_value = criterion.get_max_value(); - for(typename Cell_vector::const_iterator it = cells.begin(); - it != cells.end(); - ++it) + for(typename Cell_vector::const_iterator it = cells.begin(); it != cells.end(); ++it) { min_value = (std::min)(criterion(*it), min_value); } @@ -3909,37 +3804,39 @@ fill_modified_vertices(InputIterator cells_begin, template -template +template void C3T3_helpers:: fill_cells_backup(const CellsVector& cells, + const SliverCriterion& criterion, CellDataSet& cells_backup) const { typedef typename CellDataSet::value_type Cell_data; typename CellsVector::const_iterator cit; for(cit = cells.begin(); cit != cells.end(); ++cit) { - cells_backup.insert(Cell_data(c3t3_,*cit)); + cells_backup.insert(Cell_data(*cit, c3t3_, criterion)); } } template -template +template void C3T3_helpers:: -restore_from_cells_backup(const CellsVector& cells, - CellDataSet& cells_backup) const +restore_from_cells_backup(CellDataSet& cells_backup, + const SliverCriterion& criterion, + const CellsVector& cells) const { for(typename CellsVector::const_iterator cit = cells.begin(); cit != cells.end(); ++cit) { typename CellDataSet::const_iterator cd_it - = cells_backup.find(Cell_data_backup(c3t3_, *cit, false/*don't backup*/)); + = cells_backup.find(Cell_data_backup(*cit, c3t3_, criterion, false/*don't backup*/)); if(cd_it != cells_backup.end()) { typename CellDataSet::value_type cell_data = *cd_it; - cell_data.restore(*cit, c3t3_); + cell_data.restore(*cit, c3t3_, criterion); cells_backup.erase(cd_it); } else CGAL_error(); @@ -4073,9 +3970,9 @@ get_surface_boundary(const Vertex_handle& moving_vertex, typename Facet_vector::const_iterator fit = facets.begin(); for ( ; fit != facets.end() ; ++fit ) { - if ( c3t3_.is_in_complex(*fit) ) + const Surface_patch_index surface_index = c3t3_.surface_patch_index(*fit); + if ( !(surface_index == Surface_patch_index()) ) // is facet in complex { - const Surface_patch_index surface_index = c3t3_.surface_patch_index(*fit); const int k = fit->second; Vertex_handle v1 = fit->first->vertex((k+1)&3); Vertex_handle v2 = fit->first->vertex((k+2)&3); diff --git a/Mesh_3/include/CGAL/Mesh_3/Cell_criteria_visitor_with_balls.h b/Mesh_3/include/CGAL/Mesh_3/Cell_criteria_visitor_with_balls.h index 3e6824d27ea..2f3eefb5a94 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Cell_criteria_visitor_with_balls.h +++ b/Mesh_3/include/CGAL/Mesh_3/Cell_criteria_visitor_with_balls.h @@ -26,23 +26,24 @@ namespace CGAL { namespace Mesh_3 { -template +template class Cell_criteria_visitor_with_balls - : public Criterion_visitor + : public Criterion_visitor { - typedef Criterion_visitor Base; + typedef Criterion_visitor Base; typedef Cell_criteria_visitor_with_balls Self; public: - typedef Abstract_criterion Criterion; - typedef Mesh_3::Cell_radius_criterion Cell_radius_criterion; - typedef Mesh_3::Cell_radius_edge_criterion Cell_radius_edge_criterion; + typedef Abstract_criterion Criterion; + typedef Mesh_3::Cell_radius_criterion Cell_radius_criterion; + typedef Mesh_3::Cell_radius_edge_criterion Cell_radius_edge_criterion; typedef typename Base::Quality Cell_quality; typedef typename Base::Is_bad Is_cell_bad; typedef typename Base::Handle Handle; typedef Handle Cell_handle; + typedef typename C3T3::Triangulation Tr; typedef typename Tr::Bare_point Bare_point; typedef typename Tr::Weighted_point Weighted_point; typedef typename Tr::Geom_traits GT; @@ -56,9 +57,11 @@ class Cell_criteria_visitor_with_balls typedef typename Tr::Vertex_handle Vertex_handle; // Constructor - Cell_criteria_visitor_with_balls(const Tr& tr, const Cell_handle& ch) + Cell_criteria_visitor_with_balls(const C3T3& c3t3, const Cell_handle& ch) : Base(tr, ch) { + const Tr& tr = c3t3.triangulation(); + typename GT::Compare_weighted_squared_radius_3 compare_sq_radius = tr.geom_traits().compare_weighted_squared_radius_3_object(); typename GT::Squared_radius_orthogonal_sphere sq_radius_ortho_sphere = diff --git a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h index b3ebeca51d3..37617efc451 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/Construct_initial_points_labeled_image.h @@ -16,7 +16,7 @@ #include #include - +#include #include #include #include @@ -170,13 +170,16 @@ struct Construct_initial_points_labeled_image typedef typename MeshDomain::Index Index; typedef typename C3t3::Triangulation Tr; + typedef Mesh_3::Triangulation_helpers Th; + typedef typename Tr::Geom_traits GT; typedef typename GT::FT FT; typedef typename Tr::Weighted_point Weighted_point; typedef typename Tr::Segment Segment_3; + typedef typename GT::Vector_3 Vector_3; + typedef typename Tr::Vertex_handle Vertex_handle; typedef typename Tr::Cell_handle Cell_handle; - typedef typename GT::Vector_3 Vector_3; C3t3 c3t3; Tr& tr = c3t3.triangulation(); @@ -328,7 +331,7 @@ struct Construct_initial_points_labeled_image continue; // if the (squared) distance between intersect_point and cv is smaller or equal than cv's weight - if (cwsr(cv_wp, - tr.min_squared_distance(intersect_point, cp(cv_wp))) != CGAL::LARGER) + if (cwsr(cv_wp, - Th().min_squared_distance(tr, intersect_point, cp(cv_wp))) != CGAL::LARGER) { pi_inside_protecting_sphere = true; break; diff --git a/Mesh_3/include/CGAL/Mesh_3/Facet_criteria_visitor_with_balls.h b/Mesh_3/include/CGAL/Mesh_3/Facet_criteria_visitor_with_balls.h index 0db721cd9d9..e80fbcaba6d 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Facet_criteria_visitor_with_balls.h +++ b/Mesh_3/include/CGAL/Mesh_3/Facet_criteria_visitor_with_balls.h @@ -27,20 +27,20 @@ namespace CGAL { namespace Mesh_3 { -template +template class Facet_criterion_visitor_with_balls - : public Mesh_3::Criterion_visitor + : public Mesh_3::Criterion_visitor { - typedef Mesh_3::Criterion_visitor Base; - typedef Facet_criterion_visitor_with_balls Self; + typedef Mesh_3::Criterion_visitor Base; + typedef Facet_criterion_visitor_with_balls Self; public: - typedef Mesh_3::Abstract_criterion Criterion; - typedef Mesh_3::Curvature_size_criterion Curvature_size_criterion; - typedef Mesh_3::Aspect_ratio_criterion Aspect_ratio_criterion; - typedef Mesh_3::Facet_on_surface_criterion Facet_on_surface_criterion; - typedef Mesh_3::Uniform_size_criterion Uniform_size_criterion; - typedef Mesh_3::Facet_on_same_surface_criterion Facet_on_same_surface_criterion; + typedef Mesh_3::Abstract_criterion Criterion; + typedef Mesh_3::Curvature_size_criterion Curvature_size_criterion; + typedef Mesh_3::Aspect_ratio_criterion Aspect_ratio_criterion; + typedef Mesh_3::Facet_on_surface_criterion Facet_on_surface_criterion; + typedef Mesh_3::Uniform_size_criterion Uniform_size_criterion; + typedef Mesh_3::Facet_on_same_surface_criterion Facet_on_same_surface_criterion; typedef typename Base::Quality Facet_quality; @@ -48,6 +48,7 @@ class Facet_criterion_visitor_with_balls typedef typename Base::Handle Handle; typedef Handle Facet; + typedef typename C3T3::Triangulation Tr; typedef typename Tr::Bare_point Bare_point; typedef typename Tr::Weighted_point Weighted_point; typedef typename Tr::Geom_traits GT; @@ -62,24 +63,24 @@ class Facet_criterion_visitor_with_balls // Constructor - Facet_criterion_visitor_with_balls(const Tr& tr, const Facet& fh) - : Base(tr, fh) + Facet_criterion_visitor_with_balls(const C3T3& c3t3, const Facet& fh) + : Base(c3t3, fh) , wp_nb_(0) , radius_ortho_shpere(0.) , ratio(0.) { typename GT::Compare_weighted_squared_radius_3 compare_sq_radius = - tr.geom_traits().compare_weighted_squared_radius_3_object(); + c3t3.triangulation().geom_traits().compare_weighted_squared_radius_3_object(); typename GT::Compute_weight_3 cw = - tr.geom_traits().compute_weight_3_object(); + c3t3.triangulation().geom_traits().compute_weight_3_object(); typename GT::Construct_point_3 cp = - tr.geom_traits().construct_point_3_object(); + c3t3.triangulation().geom_traits().construct_point_3_object(); typename GT::Squared_radius_orthogonal_sphere sq_radius_ortho_sphere = - tr.geom_traits().compute_squared_radius_smallest_orthogonal_sphere_3_object(); + c3t3.triangulation().geom_traits().compute_squared_radius_smallest_orthogonal_sphere_3_object(); - Weighted_point wp1 = tr.point(fh.first, (fh.second+1)&3); - Weighted_point wp2 = tr.point(fh.first, (fh.second+2)&3); - Weighted_point wp3 = tr.point(fh.first, (fh.second+3)&3); + Weighted_point wp1 = c3t3.triangulation().point(fh.first, (fh.second+1)&3); + Weighted_point wp2 = c3t3.triangulation().point(fh.first, (fh.second+2)&3); + Weighted_point wp3 = c3t3.triangulation().point(fh.first, (fh.second+3)&3); if(compare_sq_radius(wp1, FT(0)) == CGAL::SMALLER) { ++wp_nb_; } if(compare_sq_radius(wp2, FT(0)) == CGAL::SMALLER) { ++wp_nb_; } diff --git a/Mesh_3/include/CGAL/Mesh_3/Facet_on_same_surface_criterion.h b/Mesh_3/include/CGAL/Mesh_3/Facet_on_same_surface_criterion.h index ed23d58d876..0a644e6ff91 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Facet_on_same_surface_criterion.h +++ b/Mesh_3/include/CGAL/Mesh_3/Facet_on_same_surface_criterion.h @@ -28,18 +28,19 @@ namespace CGAL { namespace Mesh_3 { -//template +//template //class Facet_on_same_surface_criterion : -//public Mesh_3::Abstract_criterion +//public Mesh_3::Abstract_criterion //{ //private: +// typedef typename C3T3::Triangulation Tr; // typedef typename Tr::Facet Facet; // -// typedef Mesh_3::Abstract_criterion Base; +// typedef Mesh_3::Abstract_criterion Base; // typedef typename Base::Quality Quality; // typedef typename Base::Is_bad Is_bad; // -// typedef Facet_on_same_surface_criterion Self; +// typedef Facet_on_same_surface_criterion Self; // //public: // /// Constructor diff --git a/Mesh_3/include/CGAL/Mesh_3/Is_mesh_domain_field_3.h b/Mesh_3/include/CGAL/Mesh_3/Is_mesh_domain_field_3.h index aab7f327d52..5e9bb84ac69 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Is_mesh_domain_field_3.h +++ b/Mesh_3/include/CGAL/Mesh_3/Is_mesh_domain_field_3.h @@ -32,7 +32,7 @@ namespace CGAL { public CGAL::Boolean_tag < boost::callable_traits::is_invocable_r< - typename Tr::FT, + typename Tr::Geom_traits::FT, Type, typename Tr::Bare_point, int, diff --git a/Mesh_3/include/CGAL/Mesh_3/Lloyd_move.h b/Mesh_3/include/CGAL/Mesh_3/Lloyd_move.h index 10473bc9e79..f00b9802015 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Lloyd_move.h +++ b/Mesh_3/include/CGAL/Mesh_3/Lloyd_move.h @@ -20,8 +20,10 @@ #include #include + #include #include +#include #include #include @@ -44,6 +46,7 @@ template Th; typedef typename Tr::Geom_traits GT; typedef typename Tr::Vertex_handle Vertex_handle; @@ -297,8 +300,7 @@ class Lloyd_move // calling a function 'get_closest_point(p, q)' that simply returns q // for a non-periodic triangulation, and checks all possible offsets for // periodic triangulations - points.push_back(tr.get_closest_point(cp(position), - cell->get_facet_surface_center(i))); + points.push_back(Th().get_closest_point(tr, cp(position), c3t3.surface_center(cell, i))); } return points; diff --git a/Mesh_3/include/CGAL/Mesh_3/Mesh_global_optimizer.h b/Mesh_3/include/CGAL/Mesh_3/Mesh_global_optimizer.h index c9eeebdcb9e..c2fbc431b95 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Mesh_global_optimizer.h +++ b/Mesh_3/include/CGAL/Mesh_3/Mesh_global_optimizer.h @@ -39,10 +39,6 @@ #include #endif -#include -#include -#include - #ifdef CGAL_LINKED_WITH_TBB # include # include @@ -50,6 +46,10 @@ # include #endif +#include +#include +#include + namespace CGAL { namespace Mesh_3 { diff --git a/Mesh_3/include/CGAL/Mesh_3/Mesher_3.h b/Mesh_3/include/CGAL/Mesh_3/Mesher_3.h index f2e5a29f7a7..7740fbc7a3d 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Mesher_3.h +++ b/Mesh_3/include/CGAL/Mesh_3/Mesher_3.h @@ -47,10 +47,6 @@ #include #include -#ifdef CGAL_MESH_3_USE_OLD_SURFACE_RESTRICTED_DELAUNAY_UPDATE -#include -#endif - #include #include @@ -202,17 +198,8 @@ class Mesher_3 Cells_level, Null_mesh_visitor> Facets_visitor; -#ifndef CGAL_MESH_3_USE_OLD_SURFACE_RESTRICTED_DELAUNAY_UPDATE /// Cells visitor : it just need to know previous level typedef Null_mesh_visitor_level Cells_visitor; -#else - /// Cells visitor : to update surface (restore restricted Delaunay) - /// when refining cells - typedef Surface_mesher::Visitor< - Triangulation, - Facets_level, - Facets_visitor> Cells_visitor; -#endif /// Constructor Mesher_3(C3T3& c3t3, @@ -384,11 +371,7 @@ Mesher_3::Mesher_3(C3T3& c3t3, ) , null_visitor_() , facets_visitor_(&cells_mesher_, &null_visitor_) -#ifndef CGAL_MESH_3_USE_OLD_SURFACE_RESTRICTED_DELAUNAY_UPDATE , cells_visitor_(facets_visitor_) -#else -, cells_visitor_(&facets_mesher_, &facets_visitor_) -#endif , r_c3t3_(c3t3) , maximal_number_of_vertices_(maximal_number_of_vertices) , error_code_(error_code) @@ -626,6 +609,12 @@ refine_mesh(std::string dump_after_refine_surface_prefix, const bool surface_onl std::cerr << "Total refining time: " << timer.time() + elapsed_time << "s" << std::endl; std::cerr << std::endl; + // memory footprint of r_c3t3_.surface_facet_info_ + std::cout << "final surface info map size:" << std::endl; + std::cout << " surface facet size: " << r_c3t3_.surface_facet_info_.size() << std::endl; + std::cout << " surface facet mem footprint bytes: " + << r_c3t3_.surface_facet_info_.size() * sizeof(typename C3T3::Surface_facet_info) << std::endl; + CGAL_postcondition(r_tr.is_valid()); #endif diff --git a/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h b/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h index 54f4994839d..9bbfc5040d6 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h +++ b/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h @@ -152,6 +152,8 @@ class Protect_edges_sizing_field public: typedef typename C3T3::Triangulation Tr; + typedef Mesh_3::Triangulation_helpers Th; + typedef typename Tr::Bare_point Bare_point; typedef typename Tr::Weighted_point Weighted_point; typedef typename Weighted_point::Weight Weight; @@ -860,9 +862,6 @@ Protect_edges_sizing_field(C3T3& c3t3, const MD& domain, , stop_ptr_(stop_ptr) #endif { -#ifndef CGAL_MESH_3_NO_PROTECTION_NON_LINEAR - set_nonlinear_growth_of_balls(); -#endif } @@ -1187,7 +1186,7 @@ smart_insert_point(const Bare_point& p, Weight w, int dim, const Index& index, if(!vertices_in_conflict_zone_set.insert(v).second) continue; - const FT sq_d = tr().min_squared_distance(p, cp(point(v))); + const FT sq_d = Th().min_squared_distance(tr(), p, cp(point(v))); if(use_minimal_size() && sq_d < minimal_weight()) { insert_a_special_ball = true; @@ -1242,7 +1241,7 @@ smart_insert_point(const Bare_point& p, Weight w, int dim, const Index& index, for (Vertex_handle it : tr().finite_vertex_handles()) { const Weighted_point& it_wp = point(it); - FT sq_d = tr().min_squared_distance(p, cp(it_wp)); + FT sq_d = Th().min_squared_distance(tr(), p, cp(it_wp)); if ( cwsr(it_wp, - sq_d) == CGAL::SMALLER ) { bool special_ball = false; @@ -1270,7 +1269,7 @@ smart_insert_point(const Bare_point& p, Weight w, int dim, const Index& index, for (Vertex_handle it : tr().finite_vertex_handles()) { const Weighted_point& it_wp = point(it); - FT sq_d = tr().min_squared_distance(p, cp(it_wp)); + FT sq_d = Th().min_squared_distance(tr(), p, cp(it_wp)); if(sq_d < min_sq_d) { min_sq_d = sq_d; #if CGAL_MESH_3_PROTECTION_DEBUG & 1 diff --git a/Mesh_3/include/CGAL/Mesh_3/Refine_cells_3.h b/Mesh_3/include/CGAL/Mesh_3/Refine_cells_3.h index a427766eec8..bb0845ac745 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Refine_cells_3.h +++ b/Mesh_3/include/CGAL/Mesh_3/Refine_cells_3.h @@ -262,6 +262,7 @@ class Refine_cells_3 typedef typename Tr::Facet Facet; typedef typename Tr::Lock_data_structure Lock_data_structure; typedef typename MeshDomain::Subdomain_index Subdomain_index; + typedef typename MeshDomain::Surface_patch_index Surface_patch_index; typedef typename MeshDomain::Index Index; typedef typename Criteria::Is_cell_bad Is_cell_bad; @@ -387,9 +388,9 @@ class Refine_cells_3 Bare_point refinement_point_impl(const Cell_handle& cell) const { this->set_last_vertex_index( - r_oracle_.index_from_subdomain_index(cell->subdomain_index()) ); + r_oracle_.index_from_subdomain_index(r_c3t3_.subdomain_index(cell)) ); - // last_vertex_index_ = Index(cell->subdomain_index()); + // last_vertex_index_ = Index(r_c3t3_.subdomain_index(cell)); // NB : dual() is optimized when the cell base class has circumcenter() return r_tr_.dual(cell); } @@ -411,11 +412,7 @@ class Refine_cells_3 // Job to do after insertion void after_insertion_impl(const Vertex_handle& v) -#ifndef CGAL_MESH_3_USE_OLD_SURFACE_RESTRICTED_DELAUNAY_UPDATE { update_star_self(v); } -#else - { update_star(v); } -#endif // Insertion implementation ; returns the inserted vertex Vertex_handle insert_impl(const Weighted_point& p, const Zone& zone); @@ -766,7 +763,7 @@ number_of_bad_elements_impl() const Subdomain subdomain = r_oracle_.is_in_domain_object()(r_tr_.dual(cell_it)); if ( subdomain ) { - const Is_cell_bad is_cell_bad = r_criteria_(r_tr_, cell_it); + const Is_cell_bad is_cell_bad = r_criteria_(r_c3t3_, cell_it); if( is_cell_bad ) ++count; } @@ -896,21 +893,10 @@ update_star_self(const Vertex_handle& vertex) // Restore surface const int& k = (*cell_it)->index(vertex); const Facet mirror_f = mirror_facet(*cell_it,k); - const Cell_handle& neighbor_cell = mirror_f.first; - const int& neighb_k = mirror_f.second; - - if ( neighbor_cell->is_facet_on_surface(neighb_k) ) - { - // Facet(*cell_it,k) is on surface - (*cell_it)->set_surface_patch_index( - k,neighbor_cell->surface_patch_index(neighb_k)); - - (*cell_it)->set_facet_surface_center( - k,neighbor_cell->get_facet_surface_center(neighb_k)); - (*cell_it)->set_facet_surface_center_index( - k,neighbor_cell->get_facet_surface_center_index(neighb_k)); - } + // @todo here and below is 2 map looks up which could be only one. + if (r_c3t3_.is_in_complex(mirror_f)) + r_c3t3_.set_surface_info(*cell_it, k, r_c3t3_.surface_info(mirror_f)); // Set subdomain index set_cell_in_domain(*cell_it, cells_subdomain); @@ -948,7 +934,7 @@ void Refine_cells_3:: is_bad(const Cell_handle& cell) { - const Is_cell_bad is_cell_bad = r_criteria_(r_tr_, cell); + const Is_cell_bad is_cell_bad = r_criteria_(r_c3t3_, cell); if( is_cell_bad ) { this->add_bad_element(this->from_cell_to_refinement_queue_element(cell), *is_cell_bad); @@ -961,6 +947,16 @@ Refine_cells_3:: insert_impl(const Weighted_point& point, const Zone& zone) { + // Remove the cell's facets from the complex (and from the hash map). + // Do *not* call the C3T3's remove_from_complex() because the information + // on the opposite facet must not be cleared for boundary facets. + auto cit = zone.cells.begin(); + for ( ; cit != zone.cells.end() ; ++cit ) + { + for (int i = 0 ; i < 4 ; ++i) + r_c3t3_.set_surface_patch_index(*cit, i, Surface_patch_index()); + } + // TODO: look at this if( zone.locate_type == Tr::VERTEX ) { diff --git a/Mesh_3/include/CGAL/Mesh_3/Refine_facets_3.h b/Mesh_3/include/CGAL/Mesh_3/Refine_facets_3.h index ddf932172fb..6469dba5805 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Refine_facets_3.h +++ b/Mesh_3/include/CGAL/Mesh_3/Refine_facets_3.h @@ -43,12 +43,12 @@ #include #include -#include #include #include -#include #include +#include +#include namespace CGAL { @@ -169,12 +169,12 @@ class Refine_facets_3_handle_queue_base #else - Facet + const Facet& from_facet_to_refinement_queue_element(const Facet &facet, const Facet &mirror) const { // Returns canonical facet - return (facet < mirror) ? facet : mirror; + return (facet.first < mirror.first) ? facet : mirror; } public: @@ -300,7 +300,7 @@ class Refine_facets_3_base } /// Gets the point to insert from the element to refine - Bare_point refinement_point_impl(const Facet& facet) const + decltype(auto) refinement_point_impl(const Facet& facet) const { #ifdef CGAL_MESHES_DEBUG_REFINEMENT_POINTS const Cell_handle c = facet.first; @@ -312,9 +312,11 @@ class Refine_facets_3_base << get_facet_surface_center(facet) << std::endl; #endif - CGAL_assertion (this->is_facet_on_surface(facet)); - this->set_last_vertex_index(get_facet_surface_center_index(facet)); - return get_facet_surface_center(facet); + CGAL_precondition(this->is_facet_on_surface(facet)); + + const auto& [surface_index, center_index, center] = this->r_c3t3_.surface_info(facet); + this->set_last_vertex_index(center_index); + return center; } Facet get_next_element_impl() @@ -420,20 +422,14 @@ class Refine_facets_3_base typedef typename MeshDomain::Surface_patch_index Surface_patch_index; typedef typename MeshDomain::Index Index; - struct Facet_prop - { - Surface_patch_index surface_patch_index; - Index index; - Bare_point point; - }; + typedef typename Complex3InTriangulation3::Facet_prop Facet_prop; typedef typename std::optional Facet_properties; - /// Returns canonical facet of facet - Facet canonical_facet(const Facet& facet) const + Facet canonical_facet(const Facet& f) const { - const Facet mirror = mirror_facet(facet); - return ( (facet < mirror)?facet:mirror ); + Cell_handle n = f.first->neighbor(f.second); + return (f.first < n) ? f : Facet(n, n->index(f.first)); } /// Returns true if `f` has already been visited. @@ -448,37 +444,32 @@ class Refine_facets_3_base f.first->set_facet_visited(f.second); } - /// Sets the facet `f` and its mirrored facet's surface centers to `p`. - void set_facet_surface_center(const Facet& f, - const Bare_point& p, - const Index& index) const - { - const Facet mirror = mirror_facet(f); - - f.first->set_facet_surface_center(f.second, p); - mirror.first->set_facet_surface_center(mirror.second, p); - - f.first->set_facet_surface_center_index(f.second,index); - mirror.first->set_facet_surface_center_index(mirror.second,index); - } - /// Returns facet surface center of `f`. - Bare_point get_facet_surface_center(const Facet& f) const + decltype(auto) get_facet_surface_center(const Facet& f) const { - return f.first->get_facet_surface_center(f.second); + return r_c3t3_.surface_center(f.first, f.second); } /// Returns index of surface center of facet `f`. Index get_facet_surface_center_index(const Facet& f) const { - return f.first->get_facet_surface_center_index(f.second); + return r_c3t3_.surface_center_index(f.first, f.second); } /// Sets `f` to surface facets, with index `index`. void set_facet_on_surface(const Facet& f, - const Surface_patch_index& index) + const Surface_patch_index& surface_index, + const Index& center_index, + const Bare_point& center) { - r_c3t3_.add_to_complex(f, index); + r_c3t3_.add_to_complex(f, surface_index); + + const Facet mirror = mirror_facet(f); + + // a little awkward: these are performed after add_to_complex() because otherwise + // the surface index is set up, and add_to_complex() will do nothing... + r_c3t3_.set_surface_info(f, {surface_index, center_index, center}); + r_c3t3_.set_surface_info(mirror, {surface_index, center_index, center}); } /// Returns index of facet `f`. @@ -622,11 +613,11 @@ class Refine_facets_3_base void treat_new_facet(Facet& facet); /** - * Computes simultaneously `is_facet_on_surface` and `facet_surface_center`. - * @param facet The input facet - * @return `true` if `facet` is on surface, `false` otherwise + * checks whether the facet is on the surface or not, and if it is, computes + * the surface patch index, the surface center, and the surface center index. */ - void compute_facet_properties(const Facet& facet, Facet_properties& fp, + void compute_facet_properties(const Facet& facet, + Facet_properties& fp, bool force_exact = false ) const; protected: @@ -834,7 +825,7 @@ class Refine_facets_3 int number_of_bad_elements_impl(); - Bare_point circumcenter_impl(const Facet& facet) const + decltype(auto) circumcenter_impl(const Facet& facet) const { return get_facet_surface_center(facet); } @@ -1015,7 +1006,16 @@ scan_triangulation_impl() # endif add_to_TLS_lists(true); - // PARALLEL FOR_EACH + // First loop on cells to initialize the possible circumcenter caches + tbb::parallel_for_each( + this->r_tr_.finite_cell_handles().begin(), this->r_tr_.finite_cell_handles().end(), + [&] (Cell_handle ch) + { + static_cast(this->r_tr_.dual(ch)); + } + ); + + // then loop on facets. tbb::parallel_for_each( this->r_tr_.finite_facets_begin(), this->r_tr_.finite_facets_end(), typename Rf_base::template Scan_facet(*this) @@ -1083,7 +1083,7 @@ Refine_facets_3:: number_of_bad_elements_impl() { typedef typename MD::Subdomain_index Subdomain_index; - typedef std::optional Subdomain; + typedef std::optional Subdomain; typedef typename Tr::Finite_facets_iterator Finite_facet_iterator; int count = 0, count_num_bad_surface_facets = 0; @@ -1136,7 +1136,7 @@ number_of_bad_elements_impl() const Facet f1(c, i); if (this->is_facet_on_surface(f1)) { - std::cerr << "*** f1 is " << (this->r_criteria_(this->r_tr_, f1) ? "bad" : "good") << std::endl; + std::cerr << "*** f1 is " << (this->r_criteria_(this->r_c3t3_, f1) ? "bad" : "good") << std::endl; #ifdef SHOW_REMAINING_BAD_ELEMENT_IN_RED c->mark = i; @@ -1154,7 +1154,7 @@ number_of_bad_elements_impl() const Facet f2(c, i); if (this->is_facet_on_surface(f2)) { - std::cerr << "*** f2 is " << (this->r_criteria_(this->r_tr_, f2) ? "bad" : "good") << std::endl; + std::cerr << "*** f2 is " << (this->r_criteria_(this->r_c3t3_, f2) ? "bad" : "good") << std::endl; #ifdef SHOW_REMAINING_BAD_ELEMENT_IN_RED mc->mark = i; @@ -1195,10 +1195,9 @@ number_of_bad_elements_impl() //const Bare_point& surface_center = std::get<2>(*properties); // Facet is on surface: set facet properties - //set_facet_surface_center(facet, surface_center, surface_center_index); - //set_facet_on_surface(facet, surface_index); + // set_facet_on_surface(facet, surface_index, surface_center_index, surface_center); - const typename Rf_base::Is_facet_bad is_facet_bad = this->r_criteria_(this->r_tr_, facet); + const typename Rf_base::Is_facet_bad is_facet_bad = this->r_criteria_(this->r_c3t3_, facet); if ( is_facet_bad ) { ++count; @@ -1375,11 +1374,9 @@ conflicts_zone_impl(const Weighted_point& point this->compute_facet_properties(facet, properties, /*force_exact=*/true); if ( properties ) { - const auto& [surface_index, surface_center_index, surface_center] = *properties; - // Facet is on surface: set facet properties - this->set_facet_surface_center(facet, surface_center, surface_center_index); - this->set_facet_on_surface(facet, surface_index); + const auto& [surface_index, surface_center_index, surface_center] = *properties; + this->set_facet_on_surface(facet, surface_index, surface_center_index, surface_center); } else { @@ -1435,11 +1432,9 @@ conflicts_zone_impl(const Weighted_point& point this->compute_facet_properties(facet, properties, /*force_exact=*/true); if ( properties ) { - const auto& [surface_index, surface_center_index, surface_center] = *properties; - // Facet is on surface: set facet properties - this->set_facet_surface_center(facet, surface_center, surface_center_index); - this->set_facet_on_surface(facet, surface_index); + const auto& [surface_index, surface_center_index, surface_center] = *properties; + this->set_facet_on_surface(facet, surface_index, surface_center_index, surface_center); } else { @@ -1601,14 +1596,12 @@ treat_new_facet(Facet& facet) compute_facet_properties(facet, properties); if ( properties ) { - const auto& [surface_index, surface_center_index, surface_center] = *properties; - // Facet is on surface: set facet properties - set_facet_surface_center(facet, surface_center, surface_center_index); - set_facet_on_surface(facet, surface_index); + const auto& [surface_index, surface_center_index, surface_center] = *properties; + set_facet_on_surface(facet, surface_index, surface_center_index, surface_center); // Insert facet into refinement queue if needed - const Is_facet_bad is_facet_bad = r_criteria_(r_tr_, facet); + const Is_facet_bad is_facet_bad = r_criteria_(r_c3t3_, facet); if ( is_facet_bad ) { @@ -1886,8 +1879,6 @@ before_insertion_handle_facet_in_conflict_zone(Facet& facet, return ( (facet == source_facet) || (other_side == source_facet) ); } - - template void Refine_facets_3_base:: @@ -1904,11 +1895,8 @@ after_insertion_handle_incident_facet(Facet& facet) treat_new_facet(facet); } - -} // end namespace Mesh_3 - - -} // end namespace CGAL +} // namespace Mesh_3 +} // namespace CGAL #include diff --git a/Mesh_3/include/CGAL/Mesh_3/Refine_facets_manifold_base.h b/Mesh_3/include/CGAL/Mesh_3/Refine_facets_manifold_base.h index ab2c08fac9c..d650b6bea15 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Refine_facets_manifold_base.h +++ b/Mesh_3/include/CGAL/Mesh_3/Refine_facets_manifold_base.h @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -28,7 +29,6 @@ #include #include -#include #include #include @@ -71,6 +71,8 @@ class Refine_facets_manifold_base typedef typename Triangulation_mesher_level_traits_3::Zone Zone; protected: + typedef Triangulation_helpers Th; + typedef typename Tr::Geom_traits GT; typedef typename GT::FT FT; @@ -136,10 +138,10 @@ class Refine_facets_manifold_base typename GT::Compute_weight_3 cw = this->r_tr_.geom_traits().compute_weight_3_object(); typename GT::Construct_point_3 cp = this->r_tr_.geom_traits().construct_point_3_object(); - const Bare_point& fcenter = f.first->get_facet_surface_center(f.second); + const Bare_point& fcenter = this->r_c3t3_.surface_center(f.first, f.second); const Weighted_point& wp = this->r_tr_.point(v); - return this->r_tr_.min_squared_distance(fcenter, cp(wp)) - cw(wp); + return Th().min_squared_distance(this->r_tr_, fcenter, cp(wp)) - cw(wp); } std::pair @@ -158,7 +160,7 @@ class Refine_facets_manifold_base typename std::vector::iterator fit = facets.begin(); while(fit != facets.end() && !this->r_c3t3_.is_in_complex(*fit)) ++fit; CGAL_assertion(fit!=facets.end()); - CGAL_assertion_code(std::size_t facet_counter = 1); + CGAL_assertion_code(int facet_counter = 1); Facet biggest_facet = *fit++; FT biggest_sq_dist = compute_sq_distance_to_facet_center(biggest_facet, v); @@ -187,8 +189,7 @@ class Refine_facets_manifold_base ++fit; while(fit != facets.end() && !this->r_c3t3_.is_in_complex(*fit)) ++fit; } - CGAL_assertion(v->cached_number_of_incident_facets() == - facet_counter); + CGAL_assertion(v->cached_number_of_incident_facets() == facet_counter); CGAL_assertion(this->r_c3t3_.is_in_complex(biggest_facet)); #ifdef CGAL_MESHES_DEBUG_REFINEMENT_POINTS std::cerr << "Biggest facet squared radius: " diff --git a/Mesh_3/include/CGAL/Mesh_3/Robust_intersection_traits_3.h b/Mesh_3/include/CGAL/Mesh_3/Robust_intersection_traits_3.h index f4eeebecef8..5df5b77408b 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Robust_intersection_traits_3.h +++ b/Mesh_3/include/CGAL/Mesh_3/Robust_intersection_traits_3.h @@ -179,7 +179,7 @@ struct Vector_plane_orientation_3_static_filter : }; // end struct template Vector_plane_orientation_3_static_filter // An exact line-plane intersection that returns always a point. -// The line it (pq), and the plane is (abc). +// The line is (pq), and the plane is (abc). // // Precondition: [pq] and [abc] are not coplanar. template diff --git a/Mesh_3/include/CGAL/Mesh_3/Sliver_perturber.h b/Mesh_3/include/CGAL/Mesh_3/Sliver_perturber.h index 8d452ee8036..6d0b1d482c3 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Sliver_perturber.h +++ b/Mesh_3/include/CGAL/Mesh_3/Sliver_perturber.h @@ -422,7 +422,7 @@ class Sliver_perturber_base template < typename C3T3, typename MeshDomain, typename SliverCriterion = Mesh_3::Min_dihedral_angle_criterion - , + , typename Visitor_ = Null_perturber_visitor > class Sliver_perturber : public Sliver_perturber_base int Sliver_perturber:: @@ -1086,15 +1078,13 @@ build_priority_queue(const FT& sliver_bound, PQueue& pqueue) const typedef boost::unordered_map M; M vpm; - for ( typename Tr::Finite_cells_iterator cit = tr_.finite_cells_begin(); - cit != tr_.finite_cells_end() ; - ++cit ) + for (Cell_handle ch : c3t3_.cells_in_complex()) { - if(helper_.is_sliver(cit, sliver_criterion_, sliver_bound)) + const double d = sliver_criterion_(ch); + if(d < sliver_bound) { - double d = cit->sliver_value(); for(int i=0; i< 4; i++){ - Vertex_handle vh = cit->vertex(i); + Vertex_handle vh = ch->vertex(i); PVertex& pv = vpm[vh]; if(pv.sliver_nb() ==0) { @@ -1127,40 +1117,6 @@ build_priority_queue(const FT& sliver_bound, PQueue& pqueue) const return pqueue_size; } -#else // not CGAL_FASTER_BUILD_QUEUE - -template -int -Sliver_perturber:: -build_priority_queue(const FT& sliver_bound, PQueue& pqueue) const -{ - CGAL_precondition(pqueue.empty()); - -#ifdef CGAL_MESH_3_PERTURBER_HIGH_VERBOSITY - CGAL::Real_timer timer; - timer.start(); - std::cerr << "Build pqueue..."; -#endif - - int pqueue_size = 0; - - for ( typename Tr::Finite_vertices_iterator vit = tr_.finite_vertices_begin(); - vit != tr_.finite_vertices_end() ; - ++vit ) - { - PVertex pv = make_pvertex(vit, sliver_bound, get_pvertex_id(vit)); - pqueue_size += update_priority_queue(pv, pqueue); - } - -#ifdef CGAL_MESH_3_PERTURBER_HIGH_VERBOSITY - std::cerr << "done (" << pqueue_size << " vertices inserted in " - << timer.time() << "s)\n"; -#endif - - return pqueue_size; -} -#endif // not CGAL_FASTER_BUILD_QUEUE - template int @@ -1426,13 +1382,8 @@ void Sliver_perturber:: update_pvertex(PVertex& pv, const FT& sliver_bound) const { -#ifdef CGAL_NEW_INCIDENT_SLIVERS Cell_vector slivers; - helper_.new_incident_slivers(pv.vertex(), sliver_criterion_, sliver_bound, std::back_inserter(slivers)); -#else - Cell_vector slivers = - helper_.incident_slivers(pv.vertex(), sliver_criterion_, sliver_bound); -#endif + helper_.incident_slivers(pv.vertex(), sliver_criterion_, sliver_bound, std::back_inserter(slivers)); pv.set_sliver_nb(static_cast(slivers.size())); pv.set_min_value(helper_.min_sliver_value(slivers, sliver_criterion_)); diff --git a/Mesh_3/include/CGAL/Mesh_3/Sliver_value_cache.h b/Mesh_3/include/CGAL/Mesh_3/Sliver_value_cache.h new file mode 100644 index 00000000000..1aa1dc89e7a --- /dev/null +++ b/Mesh_3/include/CGAL/Mesh_3/Sliver_value_cache.h @@ -0,0 +1,174 @@ +// Copyright (c) 2026 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) : Mael Rouxel-Labbé + +#ifndef CGAL_MESH_3_SLIVER_VALUE_CACHE_H +#define CGAL_MESH_3_SLIVER_VALUE_CACHE_H + +#include + +#include +#include +#include + +#ifdef CGAL_LINKED_WITH_TBB +#include +#endif + +#include + +namespace CGAL { +namespace Mesh_3 { + +template +struct Sliver_value_cache_in_cell +{ + bool has_value(const Cell_handle& c) const { return c->is_cache_valid(); } + FT get(const Cell_handle& c) const { return c->sliver_value(); } + void set(const Cell_handle& c, FT v) const { c->set_sliver_value(v); } + void invalidate(const Cell_handle& c) const { c->reset_cache_validity(); } + void clear() const {} +}; + +// Non-concurrent map-based cache +template +struct Sliver_value_cache_map +{ + typedef CGAL::Hash_handles_with_or_without_timestamps Hash_fct; + + std::shared_ptr > cache = + std::make_shared>(); + + bool has_value(const Cell_handle& c) const { return cache->find(c) != cache->end(); } + FT get(const Cell_handle& c) const { return cache->at(c); } + void set(const Cell_handle& c, FT v) const { (*cache)[c] = v; } + + void invalidate(const Cell_handle& c) const { + cache->erase(c); + } + + void clear() const { cache->clear(); } +}; + +#ifdef CGAL_LINKED_WITH_TBB +// Concurrent map-based cache +template +struct Sliver_value_cache_concurrent_map +{ + typedef tbb::concurrent_hash_map ConcurrentMap; + + // Shared ownership: all copies reference the same concurrent map + std::shared_ptr cache = std::make_shared(); + + bool has_value(const Cell_handle& c) const { + typename ConcurrentMap::const_accessor acc; + return cache->find(acc, c); + } + + FT get(const Cell_handle& c) const { + typename ConcurrentMap::const_accessor acc; + if (cache->find(acc, c)) return acc->second; + throw std::out_of_range("Cell_handle not found in concurrent cache"); + } + + void set(const Cell_handle& c, FT v) const { + typename ConcurrentMap::accessor acc; + cache->insert(acc, c); + acc->second = v; + } + + void invalidate(const Cell_handle& c) const { + cache->erase(c); + } + + void clear() const { + cache->clear(); + } +}; +#endif + +// Sanity checker cache: combines in-cell and map, checks consistency +template +struct Sliver_value_cache_sanity_checker +{ + Sliver_value_cache_in_cell in_cell; + Sliver_value_cache_map map; + + bool has_value(const Cell_handle& c) const { + bool a = in_cell.has_value(c); + bool b = map.has_value(c); + if (a != b) { + std::cerr << "[Sliver_value_cache_sanity_checker] has_value mismatch for C#" << c->time_stamp() << " in_cell=" << a << ", map=" << b << std::endl; + std::cerr << "map @ " << &(map.cache) << std::endl; + std::abort(); + } + return a; + } + + FT get(const Cell_handle& c) const { + FT a = in_cell.get(c); + FT b = map.get(c); + if (a != b) { + std::cerr << "[Sliver_value_cache_sanity_checker] get mismatch: in_cell=" << a << ", map=" << b << std::endl; + std::cerr << "map @ " << &(map.cache) << std::endl; + std::abort(); + } + return a; + } + + void set(const Cell_handle& c, FT v) const { + in_cell.set(c, v); + map.set(c, v); + } + + void invalidate(const Cell_handle& c) const { + in_cell.invalidate(c); + map.invalidate(c); + } + + void clear() const { + in_cell.clear(); + map.clear(); + } +}; + +// Metafunction to select the default sliver cache type for a triangulation +template +struct Default_sliver_cache +{ + CGAL_GENERATE_MEMBER_DETECTOR(set_sliver_value); + + using Cell_handle = typename Tr::Cell_handle; + using FT = typename Tr::Geom_traits::FT; + + using type = std::conditional_t< + has_set_sliver_value::value, + // if there is storage, use it + // Sliver_value_cache_sanity_checker, + Sliver_value_cache_in_cell, + // otherwise, use a hash map, concurrent or not +#ifdef CGAL_LINKED_WITH_TBB + std::conditional_t< + std::is_same::value, + Sliver_value_cache_concurrent_map, + Sliver_value_cache_map > >; +#else + Sliver_value_cache_map >; +#endif +}; + +template +using Default_sliver_cache_t = typename Default_sliver_cache::type; + +} // namespace Mesh_3 +} // namespace CGAL + +#endif // CGAL_MESH_3_SLIVER_VALUE_CACHE_H diff --git a/Mesh_3/include/CGAL/Mesh_3/Slivers_exuder.h b/Mesh_3/include/CGAL/Mesh_3/Slivers_exuder.h index 6fa0d8cf869..1f4288c62e7 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Slivers_exuder.h +++ b/Mesh_3/include/CGAL/Mesh_3/Slivers_exuder.h @@ -18,9 +18,9 @@ #include #include + #include #include - #include #include #include @@ -37,9 +37,9 @@ #include #include - #include #include + #include #include @@ -353,6 +353,8 @@ class Slivers_exuder typedef Slivers_exuder Self; typedef typename C3T3::Triangulation Tr; + typedef Triangulation_helpers Th; + typedef typename Tr::Weighted_point Weighted_point; typedef typename Tr::Bare_point Bare_point; typedef typename Tr::Cell_handle Cell_handle; @@ -678,9 +680,7 @@ class Slivers_exuder cit != c3t3_.cells_in_complex_end() ; ++cit) { - const FT value = sliver_criteria_(cit); - - if( value < sliver_criteria_.sliver_bound() ) + if (sliver_criteria_.is_sliver(cit)) return false; } @@ -1089,9 +1089,9 @@ initialize_prestar_and_criterion_values(const Vertex_handle& v, const Facet opposite_facet = tr_.mirror_facet(f); // Sliver criterion values initialization - if( c3t3_.is_in_complex(c) ) - { - criterion_values[f] = sliver_criteria_(c); + if( c3t3_.is_in_complex(c) ) { + if (sliver_criteria_.is_sliver(c)) + criterion_values[f] = sliver_criteria_(c); } // Pre_star initialization @@ -1104,7 +1104,7 @@ initialize_prestar_and_criterion_values(const Vertex_handle& v, const Cell_handle opposite_cell = opposite_facet.first; const int index_in_opposite = opposite_cell->index(c); FT power_distance_to_power_sphere = - tr_.compute_power_distance_to_power_sphere(opposite_facet.first, index_in_opposite); + Th().compute_power_distance_to_power_sphere(tr_, opposite_facet.first, index_in_opposite); pre_star.insert(f, power_distance_to_power_sphere); } } @@ -1180,7 +1180,7 @@ expand_prestar(const Cell_handle& cell_to_add, if ( ! tr_.is_infinite(current_mirror_cell) ) { new_power_distance_to_power_sphere = - tr_.compute_power_distance_to_power_sphere(current_mirror_cell, pumped_vertex); + Th().compute_power_distance_to_power_sphere(tr_, current_mirror_cell, pumped_vertex); pre_star.insert(current_facet, new_power_distance_to_power_sphere); @@ -1222,7 +1222,7 @@ expand_prestar(const Cell_handle& cell_to_add, // We can't use 'new_power_distance_to_power_sphere' because 'current_mirror_cell' // is infinite. So we compute the power distance to 'cell_to_add' instead. CGAL_assertion(!tr_.is_infinite(cell_to_add)); - new_weight += tr_.compute_power_distance_to_power_sphere(cell_to_add, pumped_vertex); + new_weight += Th().compute_power_distance_to_power_sphere(tr_, cell_to_add, pumped_vertex); curr_f = current_facet; } @@ -1236,7 +1236,7 @@ expand_prestar(const Cell_handle& cell_to_add, Tetrahedron_3 tet = tr_.tetrahedron(curr_f, ncr_pwp); FT new_value = sliver_criteria_(tet); - criterion_values.insert(std::make_pair(current_facet, new_value)); + criterion_values.emplace(current_facet, new_value); } } } @@ -1363,9 +1363,10 @@ get_umbrella(const Facet_vector& facets, // internal_facets of conflict zone typename Facet_vector::const_iterator fit = facets.begin(); for ( ; fit != facets.end() ; ++fit ) { - if ( c3t3_.is_in_complex(*fit) ) + const Facet f = *fit; + Surface_patch_index pid = c3t3_.surface_patch_index(f); + if ( !(pid == Surface_patch_index()) ) { - Facet f = *fit; Vertex_handle v1 = f.first->vertex((f.second+1)%4); Vertex_handle v2 = f.first->vertex((f.second+2)%4); Vertex_handle v3 = f.first->vertex((f.second+3)%4); @@ -1377,22 +1378,13 @@ get_umbrella(const Facet_vector& facets, // internal_facets of conflict zone for(std::size_t i = 0; i < 3; ++i) { - Ordered_edge oe = edges[i]; - typename Umbrella::iterator uit = umbrella.find(oe); - if(uit == umbrella.end()) //umbrella does not contain oe yet - { - umbrella.insert(std::make_pair(oe, - std::make_pair(c3t3_.surface_patch_index(f), 1))); - } - else //umbrella already contains oe. Increment counter or return - { - std::size_t count = (*uit).second.second; - if(count == 2) //there will be more than 3 after insertion - return std::nullopt; //non-manifold configuration - - umbrella.insert(uit, - std::make_pair(oe, - std::make_pair(c3t3_.surface_patch_index(f), count + 1))); + const Ordered_edge& oe = edges[i]; + auto result = umbrella.emplace(oe, std::make_pair(pid, 1)); + if(!result.second) { // already existed + auto& value = result.first->second; + if(value.second == 2) // there will be more than 3 after insertion + return std::nullopt; // non-manifold configuration + ++value.second; } } } @@ -1460,12 +1452,11 @@ restore_cells_and_boundary_facets( if ( !( it->second.second == Subdomain_index() ) ) c3t3_.add_to_complex(*cit, it->second.second); - // if the new cell is in the domain, and it criterion value is less that + // if the new cell is in the domain, and its criterion value is less that // the maximum, push it in the cells queue. if( c3t3_.is_in_complex(*cit) ) { FT criterion_value = sliver_criteria_(*cit); - if( criterion_value < sliver_criteria_.sliver_bound() ) add_cell_to_queue(*cit, criterion_value); } @@ -1571,6 +1562,10 @@ update_mesh(const Weighted_point& new_point, // Delete old cells from queue (they aren't in the triangulation anymore) this->delete_cells_from_queue(deleted_cells); + // Purge the cache + for (const Cell_handle& dc : deleted_cells) + sliver_criteria_.reset_cache(dc); + // Delete old cells & facets from c3t3 remove_from_c3t3(deleted_cells.begin(),deleted_cells.end()); remove_from_c3t3(boundary_facets.begin(),boundary_facets.end()); @@ -1660,7 +1655,7 @@ check_pre_star(const Pre_star& pre_star, if(! tr_.is_infinite(opposite_facet.first) ) { pre_star2.insert( - *fit, tr_.compute_power_distance_to_power_sphere(opposite_facet.first, v)); + *fit, Th().compute_power_distance_to_power_sphere(tr_, opposite_facet.first, v)); } } @@ -1789,8 +1784,8 @@ template bool Slivers_exuder:: check_ratios(const Sliver_values& criterion_values, - const Weighted_point& wp, - const Vertex_handle& vh) const + const Weighted_point& wp, + const Vertex_handle& vh) const { Cell_vector deleted_cells; Facet_vector internal_facets; @@ -1822,6 +1817,9 @@ check_ratios(const Sliver_values& criterion_values, Tetrahedron_3 tet = tr_.tetrahedron(*it, wp); FT ratio = sliver_criteria_(tet); + if (ratio > sliver_criteria_.sliver_bound()) + continue; + expected_ratios.push_back(ratio); bool found = false; diff --git a/Mesh_3/include/CGAL/Mesh_3/Triangulation_helpers.h b/Mesh_3/include/CGAL/Mesh_3/Triangulation_helpers.h index a09cdc1d022..646fb027ee2 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Triangulation_helpers.h +++ b/Mesh_3/include/CGAL/Mesh_3/Triangulation_helpers.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -36,18 +37,32 @@ #include #include - namespace CGAL { - namespace Mesh_3 { +namespace internal { + +// Trait to detect if Tr has a nested type Periodic_tag +BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_periodic_tag, Periodic_tag, false) -template +template +struct Get_periodic_tag +{ + typedef typename boost::mpl::if_c::value, + typename Tr::Periodic_tag, + CGAL::Tag_false>::type type; +}; + +} // namespace internal + +template ::type> class Triangulation_helpers { typedef typename Tr::Geom_traits GT; typedef typename GT::FT FT; typedef typename GT::Vector_3 Vector_3; + typedef typename GT::Triangle_3 Triangle_3; // If `Tr` is not a triangulation that has defined Bare_point, // use Point_3 as defined in the traits class. @@ -57,6 +72,8 @@ class Triangulation_helpers boost::mpl::identity >::type Bare_point; + typedef typename GT::Weighted_point_3 Weighted_point_3; + // 'Point' is either a bare point or a weighted point, depending on the triangulation. // Since 'Triangulation_helpers' can be templated by an unweighted triangulation, // this is one of the rare cases where we use 'Point'. @@ -64,6 +81,7 @@ class Triangulation_helpers typedef typename Tr::Vertex Vertex; typedef typename Tr::Vertex_handle Vertex_handle; + typedef typename Tr::Facet Facet; typedef typename Tr::Cell Cell; typedef typename Tr::Cell_handle Cell_handle; typedef typename Tr::Cell_iterator Cell_iterator; @@ -147,6 +165,66 @@ class Triangulation_helpers const Vertex_handle& vh, const Cell_vector& incident_cells); + // The undocumented, straightforward functions below are required for Mesh_3 + // because of Periodic_3_mesh_3: they are functions for which both triangulations + // have fundamentally different implementations (usually, Periodic_3_mesh_3 + // does not know the offset of a point and must brute-force check for all + // possibilities). To enable Periodic_3_mesh_3 to use Mesh_3's files, + // each mesh triangulation implements its own version. + + const Bare_point& get_closest_point(const Tr& /*tr*/, + const Bare_point& /*p*/, + const Bare_point& q) const + { + return q; + } + + Triangle_3 get_incident_triangle(const Tr& tr, + const Facet& f, + const Vertex_handle) const + { + return tr.triangle(f); + } + + void set_point(const Tr& /*tr*/, + const Vertex_handle v, + const Vector_3& /*move*/, + const Weighted_point_3& new_position) const + { + v->set_point(new_position); + } + + FT compute_power_distance_to_power_sphere(const Tr& tr, + const Cell_handle c, + const Vertex_handle v) const + { + typedef typename GT::Compute_power_distance_to_power_sphere_3 Critical_radius; + + Critical_radius critical_radius = + tr.geom_traits().compute_power_distance_to_power_sphere_3_object(); + + return critical_radius(tr.point(c, 0), tr.point(c, 1), tr.point(c, 2), tr.point(c, 3), tr.point(v)); + } + + // \pre c->neighbor(i) is finite + FT compute_power_distance_to_power_sphere(const Tr& tr, + const Cell_handle c, + const int i) const + { + Cell_handle nc = c->neighbor(i); + CGAL_precondition(!tr.is_infinite(nc)); + Vertex_handle v = nc->vertex(nc->index(c)); + + return compute_power_distance_to_power_sphere(tr, c, v); + } + + typename GT::FT min_squared_distance(const Tr& tr, + const Bare_point& p, + const Bare_point& q) const + { + return tr.geom_traits().compute_squared_distance_3_object()(p, q); + } + private: /** * Returns `true` if `v` is well_oriented on each cell of `cell_tos`. @@ -160,9 +238,9 @@ class Triangulation_helpers const Point_getter& pg) const; }; -template +template bool -Triangulation_helpers:: +Triangulation_helpers:: no_topological_change(Tr& tr, const Vertex_handle v0, const Vector_3& move, @@ -190,12 +268,12 @@ no_topological_change(Tr& tr, const Point fp = tr.point(v0); // move the point - tr.set_point(v0, move, p); + set_point(tr, v0, move, p); if(!well_oriented(tr, cells_tos)) { // Reset (restore) v0 - tr.set_point(v0, cov(move), fp); + set_point(tr, v0, cov(move), fp); return false; } @@ -241,14 +319,14 @@ no_topological_change(Tr& tr, } // Reset (restore) v0 - tr.set_point(v0, cov(move), fp); + set_point(tr, v0, cov(move), fp); return np; } -template +template bool -Triangulation_helpers:: +Triangulation_helpers:: no_topological_change__without_set_point( const Tr& tr, const Vertex_handle v0, @@ -339,9 +417,9 @@ no_topological_change__without_set_point( } -template +template bool -Triangulation_helpers:: +Triangulation_helpers:: no_topological_change(Tr& tr, const Vertex_handle v0, const Vector_3& move, @@ -353,9 +431,9 @@ no_topological_change(Tr& tr, return no_topological_change(tr, v0, move, p, cells_tos); } -template +template bool -Triangulation_helpers:: +Triangulation_helpers:: no_topological_change__without_set_point( const Tr& tr, const Vertex_handle v0, @@ -368,9 +446,9 @@ no_topological_change__without_set_point( } -template +template bool -Triangulation_helpers:: +Triangulation_helpers:: inside_protecting_balls(const Tr& tr, const Vertex_handle v, const Bare_point& p) const @@ -387,19 +465,20 @@ inside_protecting_balls(const Tr& tr, if(cwsr(nvwp, FT(0)) == CGAL::SMALLER) { - typename Tr::Geom_traits::Construct_point_3 cp = tr.geom_traits().construct_point_3_object(); + typename GT::Construct_point_3 cp = tr.geom_traits().construct_point_3_object(); const Point& nvwp = tr.point(nv); // 'true' if the distance between 'p' and 'nv' is smaller or equal than the weight of 'nv' - return (cwsr(nvwp , - tr.min_squared_distance(p, cp(nvwp))) != CGAL::LARGER); + return (cwsr(nvwp , - min_squared_distance(tr, p, cp(nvwp))) != CGAL::LARGER); } return false; } /// Return the squared distance from vh to its closest vertex -template -typename Triangulation_helpers::FT -Triangulation_helpers:: +/// if `Has_visited_for_vertex_extractor` is `true` +template +typename Triangulation_helpers::FT +Triangulation_helpers:: get_sq_distance_to_closest_vertex(const Tr& tr, const Vertex_handle& vh, const Cell_vector& incident_cells) @@ -408,7 +487,7 @@ get_sq_distance_to_closest_vertex(const Tr& tr, CGAL::TDS_3::Visited_vertex visited; - // There is no need to use tr.min_squared_distance() here because we are computing + // There is no need to use Th::min_squared_distance() here because we are computing // distances between 'v' and a neighboring vertex within a common cell, which means // that even if we are using a periodic triangulation, the distance is correctly computed. auto csqd = tr.geom_traits().compute_squared_distance_3_object(); @@ -430,8 +509,8 @@ get_sq_distance_to_closest_vertex(const Tr& tr, if(vn == Vertex_handle() || tr.is_infinite(vn)) continue; - if(visited(vn)) - continue; + if(visited(vn)) + continue; const Point& wpvn = tr.point(c, n); const FT sq_d = csqd(cp(wpvh), cp(wpvn)); @@ -444,15 +523,15 @@ get_sq_distance_to_closest_vertex(const Tr& tr, return min_sq_dist; } + /// This function well_oriented is called by no_topological_change after the /// position of the vertex has been (tentatively) modified. -template +template bool -Triangulation_helpers:: +Triangulation_helpers:: well_oriented(const Tr& tr, const Cell_vector& cells_tos) const { - typedef typename Tr::Geom_traits GT; typename GT::Orientation_3 orientation = tr.geom_traits().orientation_3_object(); typename GT::Construct_point_3 cp = tr.geom_traits().construct_point_3_object(); @@ -491,14 +570,13 @@ well_oriented(const Tr& tr, /// Another version for the parallel version /// Here, the set_point is not done before, but we use a Point_getter instance /// to get the point of a vertex. -template +template bool -Triangulation_helpers:: +Triangulation_helpers:: well_oriented(const Tr& tr, const Cell_vector& cells_tos, const Point_getter& pg) const { - typedef typename Tr::Geom_traits GT; typename GT::Orientation_3 orientation = tr.geom_traits().orientation_3_object(); typename GT::Construct_point_3 cp = tr.geom_traits().construct_point_3_object(); @@ -526,10 +604,7 @@ well_oriented(const Tr& tr, return true; } - - -} // end namespace Mesh_3 - -} //namespace CGAL +} // namespace Mesh_3 +} // namespace CGAL #endif // CGAL_MESH_3_TRIANGULATION_HELPERS_H diff --git a/Mesh_3/include/CGAL/Mesh_3/config.h b/Mesh_3/include/CGAL/Mesh_3/config.h index 3fd66c2f866..ee5067c7bd0 100644 --- a/Mesh_3/include/CGAL/Mesh_3/config.h +++ b/Mesh_3/include/CGAL/Mesh_3/config.h @@ -20,23 +20,16 @@ // Use optimizations of Mesh_3 # define CGAL_CONSTRUCT_INTRUSIVE_LIST_RANGE_CONSTRUCTOR 1 -# define CGAL_MESH_3_NEW_GET_FACETS 1 # define CGAL_MESH_3_GET_FACETS_USING_INTRUSIVE_LIST 1 # define CGAL_MESH_3_SIZING_FIELD_INEXACT_LOCATE 1 # define FORCE_STRUCTURAL_FILTERING 1 -# define CGAL_NEW_INCIDENT_SLIVERS 1 -# define CGAL_INTRUSIVE_LIST 1 +// # define CGAL_INTRUSIVE_LIST 1 //experimental -# define CGAL_FASTER_BUILD_QUEUE 1 //# define CGAL_SEQUENTIAL_MESH_3_ADD_OUTSIDE_POINTS_ON_A_FAR_SPHERE //# define CGAL_PARALLEL_MESH_3_DO_NOT_ADD_OUTSIDE_POINTS_ON_A_FAR_SPHERE // slower / not recommended -//should not be used -//#define CGAL_MESH_3_OLD_MINIMUM_DIHEDRAL_ANGLE 1 - //experimental -#define CGAL_MESH_3_NO_PROTECTION_NON_LINEAR 1 #define CGAL_MESH_3_NEW_ROBUST_INTERSECTION_TRAITS 1 diff --git a/Mesh_3/include/CGAL/Mesh_3/experimental/Facet_topological_criterion_with_adjacency.h b/Mesh_3/include/CGAL/Mesh_3/experimental/Facet_topological_criterion_with_adjacency.h index 2e3f3e313bb..7f65b670dd8 100644 --- a/Mesh_3/include/CGAL/Mesh_3/experimental/Facet_topological_criterion_with_adjacency.h +++ b/Mesh_3/include/CGAL/Mesh_3/experimental/Facet_topological_criterion_with_adjacency.h @@ -22,18 +22,19 @@ namespace CGAL { namespace Mesh_3 { -template +template class Facet_topological_criterion_with_adjacency : -public Mesh_3::Abstract_criterion +public Mesh_3::Abstract_criterion { private: + typedef typename C3T3::Triangulation Tr; typedef typename Tr::Facet Facet; - typedef Mesh_3::Abstract_criterion Base; + typedef Mesh_3::Abstract_criterion Base; typedef typename Base::Quality Quality; typedef typename Base::Is_bad Is_bad; - typedef Facet_topological_criterion_with_adjacency Self; + typedef Facet_topological_criterion_with_adjacency Self; typedef typename Tr::Geom_traits::FT FT; @@ -60,7 +61,7 @@ public Mesh_3::Abstract_criterion return new Self(*this); } - virtual Is_bad do_is_bad (const Tr& /*tr*/, const Facet& f) const + virtual Is_bad do_is_bad (const C3T3& c3t3, const Facet& f) const { typedef typename Tr::Vertex_handle Vertex_handle; typedef typename Tr::Cell_handle Cell_handle; @@ -70,7 +71,7 @@ public Mesh_3::Abstract_criterion typedef typename MeshDomain::Surface_patch_index Patch_index; - const Patch_index patch_index = ch->surface_patch_index(i); + const Patch_index patch_index = c3t3.surface_patch_index(ch, i); typedef std::vector Index_set; diff --git a/Mesh_3/include/CGAL/Mesh_3/internal/check_weights.h b/Mesh_3/include/CGAL/Mesh_3/internal/check_weights.h index b1c6080f30c..d87b7fc6923 100644 --- a/Mesh_3/include/CGAL/Mesh_3/internal/check_weights.h +++ b/Mesh_3/include/CGAL/Mesh_3/internal/check_weights.h @@ -23,6 +23,7 @@ #include #include #include + #include namespace CGAL { @@ -35,7 +36,7 @@ bool has_non_protecting_weights(const Triangulation& tr, { const bool with_features = ::CGAL::internal::Has_features::value; - typedef typename Triangulation::FT FT; + typedef typename Triangulation::Geom_traits::FT FT; typedef typename Triangulation::Weighted_point Weighted_point; typename Triangulation::Geom_traits::Compare_weighted_squared_radius_3 cwsr = diff --git a/Mesh_3/include/CGAL/Mesh_3/mesh_standard_cell_criteria.h b/Mesh_3/include/CGAL/Mesh_3/mesh_standard_cell_criteria.h index e9543925efb..993c1490a18 100644 --- a/Mesh_3/include/CGAL/Mesh_3/mesh_standard_cell_criteria.h +++ b/Mesh_3/include/CGAL/Mesh_3/mesh_standard_cell_criteria.h @@ -34,18 +34,19 @@ namespace CGAL { namespace Mesh_3 { -template +template class Cell_radius_edge_criterion - : public Abstract_criterion + : public Abstract_criterion { + typedef typename C3T3::Triangulation Tr; typedef typename Tr::Cell_handle Cell_handle; typedef typename Tr::Geom_traits::FT FT; - typedef Abstract_criterion Base; + typedef Abstract_criterion Base; typedef typename Base::Quality Quality; typedef typename Base::Is_bad Is_bad; - typedef Cell_radius_edge_criterion Self; + typedef Cell_radius_edge_criterion Self; public: // Constructor @@ -69,7 +70,7 @@ class Cell_radius_edge_criterion return new Self(*this); } - virtual Is_bad do_is_bad(const Tr& tr, const Cell_handle& ch) const + virtual Is_bad do_is_bad(const C3T3& c3t3, const Cell_handle& ch) const { typedef typename Tr::Geom_traits Geom_traits; typedef typename Tr::Bare_point Bare_point; @@ -79,6 +80,8 @@ class Cell_radius_edge_criterion typedef typename Geom_traits::Compute_squared_radius_3 Radius; typedef typename Geom_traits::Construct_point_3 Construct_point_3; + const Tr& tr = c3t3.triangulation(); + Distance distance = tr.geom_traits().compute_squared_distance_3_object(); Radius sq_radius = tr.geom_traits().compute_squared_radius_3_object(); Construct_point_3 cp = tr.geom_traits().construct_point_3_object(); @@ -121,24 +124,25 @@ class Cell_radius_edge_criterion -template +template class Cell_size_criterion - : public Abstract_criterion + : public Abstract_criterion { }; -template +template class Cell_uniform_size_criterion - : public Cell_size_criterion + : public Cell_size_criterion { + typedef typename C3T3::Triangulation Tr; typedef typename Tr::Cell_handle Cell_handle; typedef typename Tr::Geom_traits::FT FT; - typedef Abstract_criterion Base; + typedef Abstract_criterion Base; typedef typename Base::Quality Quality; typedef typename Base::Is_bad Is_bad; - typedef Cell_uniform_size_criterion Self; + typedef Cell_uniform_size_criterion Self; public: // Constructor @@ -168,7 +172,7 @@ class Cell_uniform_size_criterion return new Self(*this); } - virtual Is_bad do_is_bad(const Tr& tr, const Cell_handle& ch) const + virtual Is_bad do_is_bad(const C3T3& c3t3, const Cell_handle& ch) const { typedef typename Tr::Geom_traits Geom_traits; typedef typename Tr::Bare_point Bare_point; @@ -176,6 +180,9 @@ class Cell_uniform_size_criterion typedef typename Geom_traits::Compute_squared_radius_3 Radius; typedef typename Geom_traits::Construct_point_3 Construct_point_3; + + const Tr& tr = c3t3.triangulation(); + Radius sq_radius = tr.geom_traits().compute_squared_radius_3_object(); Construct_point_3 cp = tr.geom_traits().construct_point_3_object(); @@ -217,19 +224,20 @@ class Cell_uniform_size_criterion }; // end class Cell_uniform_size_criterion -template +template class Cell_variable_size_criterion -: public Cell_size_criterion +: public Cell_size_criterion { + typedef typename C3T3::Triangulation Tr; typedef typename Tr::Cell_handle Cell_handle; typedef typename Tr::Geom_traits::FT FT; typedef typename Tr::Vertex::Index Index; - typedef Abstract_criterion Base; + typedef Abstract_criterion Base; typedef typename Base::Quality Quality; typedef typename Base::Is_bad Is_bad; - typedef Cell_variable_size_criterion Self; + typedef Cell_variable_size_criterion Self; typedef SizingField Sizing_field; public: @@ -252,7 +260,7 @@ class Cell_variable_size_criterion return new Self(*this); } - virtual Is_bad do_is_bad(const Tr& tr, const Cell_handle& ch) const + virtual Is_bad do_is_bad(const C3T3& c3t3, const Cell_handle& ch) const { typedef typename Tr::Geom_traits Geom_traits; typedef typename Tr::Bare_point Bare_point; @@ -260,6 +268,9 @@ class Cell_variable_size_criterion typedef typename Geom_traits::Compute_squared_radius_3 Radius; typedef typename Geom_traits::Construct_point_3 Construct_point_3; + + const Tr& tr = c3t3.triangulation(); + Radius sq_radius = tr.geom_traits().compute_squared_radius_3_object(); Construct_point_3 cp = tr.geom_traits().construct_point_3_object(); @@ -274,7 +285,7 @@ class Cell_variable_size_criterion const FT size = sq_radius(p, q, r, s); const FT sq_bound = CGAL::square( size_(tr.dual(ch), 3, - Index(ch->subdomain_index())) ); + Index(c3t3.subdomain_index(ch))) ); if ( size > sq_bound ) { @@ -295,20 +306,19 @@ class Cell_variable_size_criterion /// New cell criterion that disallows a cell to have points on different /// surfaces, if they are all of dimension 2. -template +template class No_bridge_cell_criterion - : public Abstract_criterion + : public Abstract_criterion { - typedef C3t3_ C3t3; - typedef typename C3t3::Triangulation Tr; + typedef typename C3T3::Triangulation Tr; typedef typename Tr::Cell_handle Cell_handle; typedef typename Tr::Geom_traits::FT FT; - typedef Abstract_criterion Base; + typedef Abstract_criterion Base; typedef typename Base::Quality Quality; typedef typename Base::Is_bad Is_bad; - typedef No_bridge_cell_criterion Self; + typedef No_bridge_cell_criterion Self; public: // Constructor @@ -331,7 +341,7 @@ class No_bridge_cell_criterion return new Self(*this); } - virtual Is_bad do_is_bad(const Tr& /*tr*/, const Cell_handle& ch) const + virtual Is_bad do_is_bad(const C3T3& /*c3t3*/, const Cell_handle& ch) const { typedef typename Tr::Vertex_handle Vertex_handle; @@ -346,7 +356,7 @@ class No_bridge_cell_criterion vs->in_dimension() != 2) return Is_bad(); - typedef typename C3t3::Index Index; + typedef typename C3T3::Index Index; const Index& vp_index = vp->index(); if(vq->index() != vp_index || @@ -359,15 +369,15 @@ class No_bridge_cell_criterion }; // end class No_bridge_cell_criterion -template +template class Cell_criterion_visitor - : public Criterion_visitor + : public Criterion_visitor { - typedef Criterion_visitor Base; - typedef Cell_criterion_visitor Self; + typedef Criterion_visitor Base; + typedef Cell_criterion_visitor Self; public: - typedef Abstract_criterion Criterion; + typedef Abstract_criterion Criterion; typedef typename Base::Quality Cell_quality; typedef typename Base::Is_bad Is_cell_bad; typedef typename Base::Handle Handle; @@ -388,13 +398,14 @@ class Cell_criterion_visitor }; // end class Cell_criterion_visitor -template +template class Cell_criteria_visitor_with_features - : public Criterion_visitor + : public Criterion_visitor { - typedef Criterion_visitor Base; - typedef Cell_criteria_visitor_with_features Self; + typedef Criterion_visitor Base; + typedef Cell_criteria_visitor_with_features Self; + typedef typename C3T3::Triangulation Tr; typedef typename Tr::Geom_traits GT; typedef typename GT::FT FT; typedef typename Tr::Weighted_point Weighted_point; @@ -407,13 +418,15 @@ class Cell_criteria_visitor_with_features typedef Handle Cell_handle; // Constructor - Cell_criteria_visitor_with_features(const Tr& tr, const Cell_handle& ch) - : Base(tr, ch) + Cell_criteria_visitor_with_features(const C3T3& c3t3, const Cell_handle& ch) + : Base(c3t3, ch) , wp_nb_(0) , do_spheres_intersect_(false) , ratio_(0) , size_ratio_(0.5*0.5*4.) { + const Tr& tr = c3t3.triangulation(); + typename GT::Compare_weighted_squared_radius_3 compare = tr.geom_traits().compare_weighted_squared_radius_3_object(); typename GT::Compute_weight_3 cw = @@ -513,8 +526,8 @@ class Cell_criteria_visitor_with_features ~Cell_criteria_visitor_with_features() {} // visit functions - template - void visit(const Mesh_3::Cell_size_criterion& criterion) + template + void visit(const Mesh_3::Cell_size_criterion& criterion) { if ( ratio_ < size_ratio_ && (do_spheres_intersect_ || 1 == wp_nb_) ) @@ -526,8 +539,8 @@ class Cell_criteria_visitor_with_features Base::do_visit(criterion); } - template - void visit(const Mesh_3::Cell_radius_edge_criterion& criterion) + template + void visit(const Mesh_3::Cell_radius_edge_criterion& criterion) { if ( (wp_nb_ >= 2 && do_spheres_intersect_) || 1 == wp_nb_ ) @@ -539,8 +552,8 @@ class Cell_criteria_visitor_with_features Base::do_visit(criterion); } - template - void visit(const Abstract_criterion& criterion) + template + void visit(const Abstract_criterion& criterion) { Base::do_visit(criterion); } @@ -553,13 +566,14 @@ class Cell_criteria_visitor_with_features }; // end class Cell_criteria_visitor_with_features -template +template class Cell_criterion_visitor_with_radius_lower_bound - : public Cell_criteria_visitor_with_features + : public Cell_criteria_visitor_with_features { - typedef Cell_criteria_visitor_with_features Base; - typedef Cell_criterion_visitor_with_radius_lower_bound Self; + typedef Cell_criteria_visitor_with_features Base; + typedef Cell_criterion_visitor_with_radius_lower_bound Self; + typedef typename C3T3::Triangulation Tr; typedef typename Tr::Geom_traits GT; typedef typename GT::FT FT; @@ -570,9 +584,9 @@ class Cell_criterion_visitor_with_radius_lower_bound typedef Handle Cell_handle; // Constructor - Cell_criterion_visitor_with_radius_lower_bound(const Tr& tr, + Cell_criterion_visitor_with_radius_lower_bound(const C3T3& c3t3, const Cell_handle& ch) - : Base(tr, ch) + : Base(c3t3, ch) , dont_go_further_(false) {} @@ -581,7 +595,7 @@ class Cell_criterion_visitor_with_radius_lower_bound if (dont_go_further_) return Is_cell_bad(); else - return Base::is_bad(); + return Base::is_bad(); } bool go_further() const @@ -599,14 +613,14 @@ class Cell_criterion_visitor_with_radius_lower_bound Base::visit(criterion); } - template - void visit(const Mesh_3::Abstract_criterion& criterion) + template + void visit(const Mesh_3::Abstract_criterion& criterion) { Base::visit(criterion); } - template - void visit(const Mesh_3::Cell_uniform_size_criterion& criterion) + template + void visit(const Mesh_3::Cell_uniform_size_criterion& criterion) { Base::visit(criterion); diff --git a/Mesh_3/include/CGAL/Mesh_3/mesh_standard_criteria.h b/Mesh_3/include/CGAL/Mesh_3/mesh_standard_criteria.h index a3564c1b946..74397589b01 100644 --- a/Mesh_3/include/CGAL/Mesh_3/mesh_standard_criteria.h +++ b/Mesh_3/include/CGAL/Mesh_3/mesh_standard_criteria.h @@ -33,11 +33,13 @@ namespace Mesh_3 { /** * @class Abstract_criterion */ -template +template class Abstract_criterion { + typedef Abstract_criterion Self; + + typedef typename C3T3::Triangulation Tr; typedef typename Tr::Geom_traits::FT FT; - typedef Abstract_criterion Self; public: typedef FT Quality; @@ -48,36 +50,36 @@ class Abstract_criterion virtual ~Abstract_criterion() {} void accept(Visitor_& v) const { do_accept(v); } - Is_bad is_bad(const Tr& tr, const Handle& h) const { return do_is_bad(tr, h); } + Is_bad is_bad(const C3T3& c3t3, const Handle& h) const { return do_is_bad(c3t3, h); } Self* clone() const { return do_clone(); } protected: virtual void do_accept(Visitor_& v) const = 0; - virtual Is_bad do_is_bad(const Tr& tr, const Handle& h) const = 0; + virtual Is_bad do_is_bad(const C3T3& c3t3, const Handle& h) const = 0; virtual Self* do_clone() const = 0; }; // end class Abstract_criterion -template +template inline -Abstract_criterion* -new_clone(const Abstract_criterion& criterion) +Abstract_criterion* +new_clone(const Abstract_criterion& criterion) { return criterion.clone(); } -template +template class Criterion_visitor { - typedef Criterion_visitor Self; + typedef Criterion_visitor Self; public: typedef Handle_ Handle; protected: - typedef Abstract_criterion Criterion; + typedef Abstract_criterion Criterion; public: typedef std::pair Quality; @@ -85,8 +87,8 @@ class Criterion_visitor // Constructor - Criterion_visitor(const Tr& tr, const Handle_& h) - : tr_(tr) + Criterion_visitor(const C3T3& c3t3, const Handle_& h) + : c3t3_(c3t3) , handle_(h) , is_bad_() , criterion_counter_(0) {} @@ -116,11 +118,11 @@ class Criterion_visitor } template - void do_visit(const Abstract_criterion& criterion) + void do_visit(const Abstract_criterion& criterion) { - typedef typename Abstract_criterion::Is_bad Is_bad; + typedef typename Abstract_criterion::Is_bad Is_bad; - const Is_bad is_bad = criterion.is_bad(tr_, handle_); + const Is_bad is_bad = criterion.is_bad(c3t3_, handle_); if ( is_bad ) is_bad_ = std::make_pair(criterion_counter_, *is_bad); @@ -128,7 +130,7 @@ class Criterion_visitor } private: - const Tr& tr_; + const C3T3& c3t3_; Handle_ handle_; Is_bad is_bad_; int criterion_counter_; @@ -137,12 +139,12 @@ class Criterion_visitor -template +template class Criteria { - typedef Criteria Self; + typedef Criteria Self; - typedef Abstract_criterion Criterion; + typedef Abstract_criterion Criterion; typedef boost::ptr_vector Criterion_vector; typedef typename Visitor_::Quality Quality; typedef typename Visitor_::Is_bad Is_bad; @@ -164,10 +166,10 @@ class Criteria criterion_vector_.push_back(criterion); } - Is_bad operator()(const Tr& tr, + Is_bad operator()(const C3T3& c3t3, const typename Visitor_::Handle& h) const { - Visitor_ visitor(tr, h); + Visitor_ visitor(c3t3, h); typename Criterion_vector::const_iterator it = criterion_vector_.begin(); for ( ; it != criterion_vector_.end() ; ++it ) diff --git a/Mesh_3/include/CGAL/Mesh_3/mesh_standard_facet_criteria.h b/Mesh_3/include/CGAL/Mesh_3/mesh_standard_facet_criteria.h index 4e42d381005..798fc30a2ea 100644 --- a/Mesh_3/include/CGAL/Mesh_3/mesh_standard_facet_criteria.h +++ b/Mesh_3/include/CGAL/Mesh_3/mesh_standard_facet_criteria.h @@ -21,18 +21,17 @@ #include - #include -#include // for to_double #include -#include +#include +#include // for to_double -namespace CGAL { +#include +namespace CGAL { namespace Mesh_3 { - namespace details { template @@ -47,22 +46,21 @@ namespace details { } // end namespace details - - // Aspect_ratio Criterion class -template +template class Aspect_ratio_criterion : - public Mesh_3::Abstract_criterion + public Mesh_3::Abstract_criterion { private: + typedef typename C3T3::Triangulation Tr; typedef typename Tr::Facet Facet; typedef typename Tr::Geom_traits::FT FT; - typedef Mesh_3::Abstract_criterion Base; + typedef Mesh_3::Abstract_criterion Base; typedef typename Base::Quality Quality; typedef typename Base::Is_bad Is_bad; - typedef Aspect_ratio_criterion Self; + typedef Aspect_ratio_criterion Self; public: // Nb: the default bound of the criterion is such that the criterion @@ -97,9 +95,9 @@ class Aspect_ratio_criterion : } } - virtual Is_bad do_is_bad(const Tr& tr, const Facet& f) const + virtual Is_bad do_is_bad(const C3T3& c3t3, const Facet& f) const { - CGAL_assertion (f.first->is_facet_on_surface(f.second)); + CGAL_assertion (c3t3.is_in_complex(f)); CGAL_assertion (B_ != 0); typedef typename Tr::Geom_traits GT; @@ -111,6 +109,8 @@ class Aspect_ratio_criterion : typedef typename GT::Construct_point_3 Construct_point_3; typedef typename GT::Construct_triangle_3 Construct_triangle_3; + const Tr& tr = c3t3.triangulation(); + Area area = tr.geom_traits().compute_squared_area_3_object(); Distance distance = tr.geom_traits().compute_squared_distance_3_object(); Construct_point_3 cp = tr.geom_traits().construct_point_3_object(); @@ -152,24 +152,27 @@ class Aspect_ratio_criterion : // Curvature_adapted size Criterion class -template +template class Curvature_size_criterion : - public Mesh_3::Abstract_criterion + public Mesh_3::Abstract_criterion {}; -template +template class Uniform_curvature_size_criterion : - public Curvature_size_criterion + public Curvature_size_criterion { private: + typedef typename C3T3::Triangulation Tr; + typedef Triangulation_helpers Th; + typedef typename Tr::Facet Facet; typedef typename Tr::Geom_traits::FT FT; - typedef Mesh_3::Abstract_criterion Base; + typedef Mesh_3::Abstract_criterion Base; typedef typename Base::Quality Quality; typedef typename Base::Is_bad Is_bad; - typedef Uniform_curvature_size_criterion Self; + typedef Uniform_curvature_size_criterion Self; public: // Nb: the default bound of the criterion is such that the criterion @@ -188,15 +191,17 @@ class Uniform_curvature_size_criterion : return new Self(*this); } - virtual Is_bad do_is_bad(const Tr& tr, const Facet& f) const + virtual Is_bad do_is_bad(const C3T3& c3t3, const Facet& f) const { - CGAL_assertion(f.first->is_facet_on_surface(f.second)); + CGAL_assertion (c3t3.is_in_complex(f)); CGAL_assertion (B_ != 0); typedef typename Tr::Geom_traits GT; typedef typename Tr::Weighted_point Weighted_point; typedef typename Tr::Bare_point Bare_point; + const Tr& tr = c3t3.triangulation(); + typename GT::Construct_weighted_circumcenter_3 weighted_circumcenter = tr.geom_traits().construct_weighted_circumcenter_3_object(); @@ -205,9 +210,9 @@ class Uniform_curvature_size_criterion : const Weighted_point& p3 = tr.point(f.first, (f.second+3)&3); const Bare_point c = weighted_circumcenter(p1,p2,p3); - const Bare_point& center = f.first->get_facet_surface_center(f.second); + const Bare_point& center = c3t3.surface_center(f); - const FT sq_dist = tr.min_squared_distance(c, center); + const FT sq_dist = Th().min_squared_distance(tr, c, center); if ( sq_dist > B_ ) { @@ -227,20 +232,23 @@ class Uniform_curvature_size_criterion : }; // end Uniform_curvature_size_criterion // Variable size Criterion class -template +template class Variable_curvature_size_criterion : - public Curvature_size_criterion + public Curvature_size_criterion { private: + typedef typename C3T3::Triangulation Tr; + typedef Triangulation_helpers Th; + typedef typename Tr::Facet Facet; typedef typename Tr::Geom_traits::FT FT; typedef typename Tr::Vertex::Index Index; - typedef Mesh_3::Abstract_criterion Base; + typedef Mesh_3::Abstract_criterion Base; typedef typename Base::Quality Quality; typedef typename Base::Is_bad Is_bad; - typedef Variable_curvature_size_criterion Self; + typedef Variable_curvature_size_criterion Self; typedef SizingField Sizing_field; public: @@ -260,14 +268,16 @@ class Variable_curvature_size_criterion : return new Self(*this); } - virtual Is_bad do_is_bad(const Tr& tr, const Facet& f) const + virtual Is_bad do_is_bad(const C3T3& c3t3, const Facet& f) const { - CGAL_assertion (f.first->is_facet_on_surface(f.second)); + CGAL_assertion (c3t3.is_in_complex(f)); typedef typename Tr::Geom_traits GT; typedef typename Tr::Weighted_point Weighted_point; typedef typename Tr::Bare_point Bare_point; + const Tr& tr = c3t3.triangulation(); + typename GT::Construct_weighted_circumcenter_3 weighted_circumcenter = tr.geom_traits().construct_weighted_circumcenter_3_object(); @@ -276,10 +286,12 @@ class Variable_curvature_size_criterion : const Weighted_point& p3 = tr.point(f.first, (f.second+3)&3); const Bare_point c = weighted_circumcenter(p1,p2,p3); - const Bare_point& ball_center = f.first->get_facet_surface_center(f.second); - const Index& index = f.first->get_facet_surface_center_index(f.second); - const FT sq_dist = tr.min_squared_distance(c, ball_center); + // @todo use surface_info() + const Bare_point& ball_center = c3t3.surface_center(f); + const Index& index = c3t3.surface_center_index(f); + + const FT sq_dist = Th().min_squared_distance(tr, c, ball_center); const FT sq_bound = CGAL::square(size_(ball_center, 2, index)); CGAL_assertion(sq_bound > FT(0)); @@ -302,27 +314,30 @@ class Variable_curvature_size_criterion : }; // end Variable_curvature_size_criterion // Size Criterion base class -template < typename Tr, typename Visitor_ > +template < typename C3T3, typename Visitor_ > class Facet_size_criterion : - public Mesh_3::Abstract_criterion + public Mesh_3::Abstract_criterion { }; // Variable size Criterion class -template +template class Variable_size_criterion : - public Facet_size_criterion + public Facet_size_criterion { private: + typedef typename C3T3::Triangulation Tr; + typedef Triangulation_helpers Th; + typedef typename Tr::Facet Facet; typedef typename Tr::Geom_traits::FT FT; typedef typename Tr::Vertex::Index Index; - typedef Mesh_3::Abstract_criterion Base; + typedef Mesh_3::Abstract_criterion Base; typedef typename Base::Quality Quality; typedef typename Base::Is_bad Is_bad; - typedef Variable_size_criterion Self; + typedef Variable_size_criterion Self; typedef SizingField Sizing_field; public: @@ -342,22 +357,24 @@ class Variable_size_criterion : return new Self(*this); } - virtual Is_bad do_is_bad(const Tr& tr, const Facet& f) const + virtual Is_bad do_is_bad(const C3T3& c3t3, const Facet& f) const { - CGAL_assertion (f.first->is_facet_on_surface(f.second)); + CGAL_assertion (c3t3.is_in_complex(f)); typedef typename Tr::Geom_traits GT; typedef typename Tr::Bare_point Bare_point; typedef typename Tr::Weighted_point Weighted_point; + const Tr& tr = c3t3.triangulation(); + typename GT::Construct_point_3 cp = tr.geom_traits().construct_point_3_object(); const Weighted_point& wp1 = tr.point(f.first, (f.second+1)&3); const Bare_point& p1 = cp(wp1); - const Bare_point& ball_center = f.first->get_facet_surface_center(f.second); - const Index& index = f.first->get_facet_surface_center_index(f.second); + const Bare_point& ball_center = c3t3.surface_center(f); + const Index& index = c3t3.surface_center_index(f); - const FT sq_radius = tr.min_squared_distance(p1, ball_center); + const FT sq_radius = Th().min_squared_distance(tr, p1, ball_center); const FT sq_bound = CGAL::square(size_(ball_center, 2, index)); CGAL_assertion(sq_bound > FT(0)); @@ -381,19 +398,22 @@ class Variable_size_criterion : // Uniform size Criterion class -template +template class Uniform_size_criterion : - public Facet_size_criterion + public Facet_size_criterion { private: + typedef typename C3T3::Triangulation Tr; + typedef Triangulation_helpers Th; + typedef typename Tr::Facet Facet; typedef typename Tr::Geom_traits::FT FT; - typedef Mesh_3::Abstract_criterion Base; + typedef Mesh_3::Abstract_criterion Base; typedef typename Base::Quality Quality; typedef typename Base::Is_bad Is_bad; - typedef Uniform_size_criterion Self; + typedef Uniform_size_criterion Self; public: // Nb: the default bound of the criterion is such that the criterion @@ -421,22 +441,24 @@ class Uniform_size_criterion : return new Self(*this); } - virtual Is_bad do_is_bad(const Tr& tr, const Facet& f) const + virtual Is_bad do_is_bad(const C3T3& c3t3, const Facet& f) const { - CGAL_assertion (f.first->is_facet_on_surface(f.second)); + CGAL_assertion (c3t3.is_in_complex(f)); CGAL_assertion (B_ != 0); typedef typename Tr::Geom_traits GT; typedef typename Tr::Bare_point Bare_point; typedef typename Tr::Weighted_point Weighted_point; + const Tr& tr = c3t3.triangulation(); + typename GT::Construct_point_3 cp = tr.geom_traits().construct_point_3_object(); const Weighted_point& wp1 = tr.point(f.first, (f.second+1)&3); const Bare_point p1 = cp(wp1); - const Bare_point& ball_center = f.first->get_facet_surface_center(f.second); + const Bare_point& ball_center = c3t3.surface_center(f); - const FT sq_radius = tr.min_squared_distance(p1, ball_center); + const FT sq_radius = Th().min_squared_distance(tr, p1, ball_center); if (!is_lower_bound() && sq_radius > B_ ) { @@ -466,18 +488,19 @@ class Uniform_size_criterion : -template +template class Facet_on_surface_criterion : - public Mesh_3::Abstract_criterion + public Mesh_3::Abstract_criterion { private: + typedef typename C3T3::Triangulation Tr; typedef typename Tr::Facet Facet; - typedef Mesh_3::Abstract_criterion Base; + typedef Mesh_3::Abstract_criterion Base; typedef typename Base::Quality Quality; typedef typename Base::Is_bad Is_bad; - typedef Facet_on_surface_criterion Self; + typedef Facet_on_surface_criterion Self; public: /// Constructor @@ -497,7 +520,7 @@ class Facet_on_surface_criterion : return new Self(*this); } - virtual Is_bad do_is_bad(const Tr& /* tr */, const Facet& f) const + virtual Is_bad do_is_bad(const C3T3& /*c3t3*/, const Facet& f) const { typedef typename Tr::Vertex_handle Vertex_handle; typedef typename Tr::Cell_handle Cell_handle; @@ -524,18 +547,19 @@ class Facet_on_surface_criterion : }; // end class Facet_on_surface_criterion -template +template class Facet_on_same_surface_criterion : -public Mesh_3::Abstract_criterion +public Mesh_3::Abstract_criterion { private: + typedef typename C3T3::Triangulation Tr; typedef typename Tr::Facet Facet; - typedef Mesh_3::Abstract_criterion Base; + typedef Mesh_3::Abstract_criterion Base; typedef typename Base::Quality Quality; typedef typename Base::Is_bad Is_bad; - typedef Facet_on_same_surface_criterion Self; + typedef Facet_on_same_surface_criterion Self; public: /// Constructor @@ -555,7 +579,7 @@ public Mesh_3::Abstract_criterion return new Self(*this); } - virtual Is_bad do_is_bad(const Tr& /* tr */, const Facet& f) const + virtual Is_bad do_is_bad(const C3T3& /*c3t3*/, const Facet& f) const { typedef typename Tr::Vertex_handle Vertex_handle; typedef typename Tr::Cell_handle Cell_handle; @@ -616,15 +640,15 @@ public Mesh_3::Abstract_criterion -template +template class Facet_criterion_visitor - : public Mesh_3::Criterion_visitor + : public Mesh_3::Criterion_visitor { - typedef Mesh_3::Criterion_visitor Base; - typedef Facet_criterion_visitor Self; + typedef Mesh_3::Criterion_visitor Base; + typedef Facet_criterion_visitor Self; public: - typedef Mesh_3::Abstract_criterion Criterion; + typedef Mesh_3::Abstract_criterion Criterion; typedef typename Base::Quality Facet_quality; typedef typename Base::Is_bad Is_facet_bad; typedef typename Base::Handle Handle; @@ -645,16 +669,19 @@ class Facet_criterion_visitor }; // end class Facet_criterion_visitor - -template +template class Facet_criterion_visitor_with_features - : public Mesh_3::Criterion_visitor + : public Mesh_3::Criterion_visitor { - typedef Mesh_3::Criterion_visitor Base; - typedef Facet_criterion_visitor_with_features Self; + typedef Mesh_3::Criterion_visitor Base; + typedef Facet_criterion_visitor_with_features Self; - typedef typename Tr::Geom_traits GT; - typedef typename GT::FT FT; + typedef typename C3T3::Triangulation Tr; + typedef typename Tr::Weighted_point Weighted_point; + typedef typename Tr::Cell_handle Cell_handle; + + typedef typename Tr::Geom_traits GT; + typedef typename GT::FT FT; public: typedef typename Base::Quality Facet_quality; @@ -663,8 +690,8 @@ class Facet_criterion_visitor_with_features typedef Handle Facet; // Constructor - Facet_criterion_visitor_with_features(const Tr& tr, const Facet& fh) - : Base(tr, fh) + Facet_criterion_visitor_with_features(const C3T3& c3t3, const Facet& fh) + : Base(c3t3, fh) , wp_nb_(0) , do_spheres_intersect_(false) , ratio_(0.) @@ -672,9 +699,7 @@ class Facet_criterion_visitor_with_features , angle_ratio_(0.5*0.5*4.) , size_ratio_(0.4*0.4*4.) { - typedef typename Tr::Geom_traits GT; - typedef typename Tr::Weighted_point Weighted_point; - typedef typename Tr::Cell_handle Cell_handle; + const Tr& tr = c3t3.triangulation(); typename GT::Compute_squared_radius_smallest_orthogonal_sphere_3 sq_radius = tr.geom_traits().compute_squared_radius_smallest_orthogonal_sphere_3_object(); @@ -748,8 +773,8 @@ class Facet_criterion_visitor_with_features } // visit functions - template - void visit(const Mesh_3::Abstract_criterion& criterion) + template + void visit(const Mesh_3::Abstract_criterion& criterion) { if ( 3 == wp_nb_ && do_spheres_intersect_ ) { @@ -760,8 +785,8 @@ class Facet_criterion_visitor_with_features Base::do_visit(criterion); } - template - void visit(const Mesh_3::Curvature_size_criterion& criterion) + template + void visit(const Mesh_3::Curvature_size_criterion& criterion) { if ( ratio_ < approx_ratio_ && (do_spheres_intersect_ || 1 == wp_nb_ ) ) @@ -773,8 +798,8 @@ class Facet_criterion_visitor_with_features Base::do_visit(criterion); } - template - void visit(const Mesh_3::Aspect_ratio_criterion& criterion) + template + void visit(const Mesh_3::Aspect_ratio_criterion& criterion) { if ( ratio_ < angle_ratio_ && (do_spheres_intersect_ || 1 == wp_nb_) ) @@ -786,8 +811,8 @@ class Facet_criterion_visitor_with_features Base::do_visit(criterion); } - template - void visit(const Mesh_3::Facet_size_criterion& criterion) + template + void visit(const Mesh_3::Facet_size_criterion& criterion) { if ( ratio_ < size_ratio_ && (do_spheres_intersect_ || 1 == wp_nb_) ) @@ -807,18 +832,19 @@ class Facet_criterion_visitor_with_features FT angle_ratio_; FT size_ratio_; -}; // end class Facet_criterion_visitor +}; // end class Facet_criterion_visitor_with_features -template +template class Facet_criterion_visitor_with_radius_lower_bound - : public Facet_criterion_visitor_with_features + : public Facet_criterion_visitor_with_features { - typedef Facet_criterion_visitor_with_features Base; - typedef Facet_criterion_visitor_with_radius_lower_bound Self; + typedef Facet_criterion_visitor_with_features Base; + typedef Facet_criterion_visitor_with_radius_lower_bound Self; - typedef typename Tr::Geom_traits GT; - typedef typename GT::FT FT; + typedef typename C3T3::Triangulation Tr; + typedef typename Tr::Geom_traits GT; + typedef typename GT::FT FT; public: typedef typename Base::Quality Facet_quality; @@ -827,8 +853,8 @@ class Facet_criterion_visitor_with_radius_lower_bound typedef Handle Facet; // Constructor - Facet_criterion_visitor_with_radius_lower_bound(const Tr& tr, const Facet& fh) - : Base(tr, fh) + Facet_criterion_visitor_with_radius_lower_bound(const C3T3& c3t3, const Facet& fh) + : Base(c3t3, fh) , dont_go_further_(false) {} @@ -855,14 +881,14 @@ class Facet_criterion_visitor_with_radius_lower_bound Base::visit(criterion); } - template - void visit(const Mesh_3::Abstract_criterion& criterion) + template + void visit(const Mesh_3::Abstract_criterion& criterion) { Base::visit(criterion); } - template - void visit(const Mesh_3::Uniform_size_criterion& criterion) + template + void visit(const Mesh_3::Uniform_size_criterion& criterion) { Base::visit(criterion); @@ -872,8 +898,6 @@ class Facet_criterion_visitor_with_radius_lower_bound private: bool dont_go_further_; - - };// end class Facet_criterion_visitor_with_radius_lower_bound diff --git a/Mesh_3/include/CGAL/Mesh_3/min_dihedral_angle.h b/Mesh_3/include/CGAL/Mesh_3/min_dihedral_angle.h index 7678bc3eaf8..b666b37c08b 100644 --- a/Mesh_3/include/CGAL/Mesh_3/min_dihedral_angle.h +++ b/Mesh_3/include/CGAL/Mesh_3/min_dihedral_angle.h @@ -22,61 +22,8 @@ #include namespace CGAL { - namespace Mesh_3 { -#ifdef CGAL_MESH_3_OLD_MINIMUM_DIHEDRAL_ANGLE - -template -typename K::FT -minimum_dihedral_angle( - const typename K::Point_3& p0, - const typename K::Point_3& p1, - const typename K::Point_3& p2, - const typename K::Point_3& p3, - const K& k = K()) -{ - typedef typename K::FT FT; - - typename K::Compute_squared_distance_3 sq_distance = - k.compute_squared_distance_3_object(); - typename K::Compute_volume_3 volume = - k.compute_volume_3_object(); - typename K::Compute_area_3 area = - k.compute_area_3_object(); - - FT a_012 = area(p0,p1,p2); - FT a_013 = area(p0,p1,p3); - FT a_123 = area(p1,p2,p3); - FT a_023 = area(p0,p2,p3); - - FT min_quotient = - CGAL::sqrt(sq_distance(p0, p1)) / a_012 / a_013; - - min_quotient = - (CGAL::min)(min_quotient, - CGAL::sqrt(sq_distance(p0, p2)) / a_012 / a_023); - min_quotient = - (CGAL::min)(min_quotient, - CGAL::sqrt(sq_distance(p0, p3)) / a_013 / a_023); - min_quotient = - (CGAL::min)(min_quotient, - CGAL::sqrt(sq_distance(p1, p2)) / a_012 / a_123); - min_quotient = - (CGAL::min)(min_quotient, - CGAL::sqrt(sq_distance(p1, p3)) / a_013 / a_123); - min_quotient = - (CGAL::min)(min_quotient, - CGAL::sqrt(sq_distance(p2, p3)) / a_023 / a_123); - - const FT result (std::asin( FT(1.5) * volume(p0, p1, p2, p3) * min_quotient ) - * FT(180) / FT(CGAL_PI)); - - return CGAL::abs(result); -} - -#else // not CGAL_MESH_3_OLD_MINIMUM_DIHEDRAL_ANGLE - template typename K::FT minimum_dihedral_angle( @@ -122,7 +69,7 @@ minimum_dihedral_angle( min_quotient = (CGAL::min)(min_quotient, sp(v02,v02) / (a_012 * a_023)); min_quotient = (CGAL::min)(min_quotient, - (v03*v03) / (a_013 * a_023)); + sp(v03,v03) / (a_013 * a_023)); min_quotient = (CGAL::min)(min_quotient, sp(v12,v12) / (a_012 * a_123)); min_quotient = (CGAL::min)(min_quotient, @@ -135,8 +82,6 @@ minimum_dihedral_angle( * FT(180) / FT(CGAL_PI)); } -#endif // CGAL_MESH_3_OLD_MINIMUM_DIHEDRAL_ANGLE - template typename K::FT minimum_dihedral_angle(const typename K::Tetrahedron_3& t , const K& k = K()) diff --git a/Mesh_3/include/CGAL/Mesh_3/sliver_criteria.h b/Mesh_3/include/CGAL/Mesh_3/sliver_criteria.h index 6ecabd1aa90..a6b99cc86d1 100644 --- a/Mesh_3/include/CGAL/Mesh_3/sliver_criteria.h +++ b/Mesh_3/include/CGAL/Mesh_3/sliver_criteria.h @@ -23,15 +23,34 @@ #include #include +#include + #include // for CGAL::IA_force_to_double +#include +#include + #include namespace CGAL { - namespace Mesh_3 { -template::type, + typename SliverCachingPolicy = + std::conditional_t::value, + internal::Sliver_caching_always_tag, + internal::Sliver_caching_below_bound_tag>, typename Cell_vector_ = std::vector > class Sliver_criterion { @@ -44,17 +63,43 @@ class Sliver_criterion public: virtual double get_default_value() const = 0; virtual double get_max_value() const = 0; - //Sliver_perturber performs perturbation "unit-per-unit" + // Sliver_perturber performs perturbation "unit-per-unit" // so it needs to know how much is a unit for each criterion virtual double get_perturbation_unit() const = 0; + // Reset the entire cache (if any) + void reset_cache() const { + cache_.clear(); + } + + // Reset the cache for a single cell (if any) + void reset_cache(const Cell_handle& cell) const { + cache_.invalidate(cell); + } + + void set_cache(const Cell_handle& cell, const double value) const { + cache_.set(cell, value); + } + + bool is_sliver(Cell_handle cell) const + { + if (std::is_same_v) { + return cache_.has_value(cell); + } else { + // if we cache everything, the operator() will return the cached value + return operator()(cell) < this->sliver_bound_; + } + } + // returns the value of the criterion for t virtual double operator()(Cell_handle cell) const { - if(update_sliver_cache) - { - if( ! cell->is_cache_valid() ) - { + if (std::is_same_v) { + return operator()(tr_.tetrahedron(cell)); + } else { + if (cache_.has_value(cell)) { + return cache_.get(cell); + } else { // cell->sliver_value() is stored in a plain 64 bits floating point // number, and the value computed by operator() might be // computed using the 80 bits floating point registers of the x87 @@ -63,13 +108,16 @@ class Sliver_criterion // inconsistent when comparing caches and registers values // (see also the comment below) // IA_force_to_double is available in CGAL/FPU.h - double value - = CGAL::IA_force_to_double(operator()(tr_.tetrahedron(cell))); - cell->set_sliver_value(value); + const double value = CGAL::IA_force_to_double(operator()(tr_.tetrahedron(cell))); + if (std::is_same_v + && value > this->sliver_bound_) { + return value; + } else { + cache_.set(cell, value); + return value; + } } - return cell->sliver_value(); } - return operator()(tr_.tetrahedron(cell)); } virtual double operator()(const Tetrahedron_3& t) const = 0; @@ -84,9 +132,11 @@ class Sliver_criterion public: Sliver_criterion(const double& bound, - const Tr& tr) + const Tr& tr, + const Cache& cache = Cache()) : tr_(tr) , sliver_bound_(bound) + , cache_(cache) {} virtual ~Sliver_criterion(){} @@ -94,18 +144,20 @@ class Sliver_criterion protected: const Tr& tr_; double sliver_bound_; + mutable Cache cache_; }; template class Min_value; template + typename Cache = typename CGAL::Mesh_3::Default_sliver_cache::type, + typename SliverCachingPolicy = internal::Sliver_caching_below_bound_tag> class Min_dihedral_angle_criterion - : public Sliver_criterion + : public Sliver_criterion { protected: - typedef Sliver_criterion Base; + typedef Sliver_criterion Base; typedef typename Base::Tetrahedron_3 Tetrahedron_3; typedef typename Base::Cell_vector Cell_vector; typedef typename Base::GT GT; @@ -147,8 +199,9 @@ class Min_dihedral_angle_criterion public: Min_dihedral_angle_criterion(const double& sliver_bound, - const Tr& tr) - : Base(sliver_bound, tr), min_value_before_move_(0.) + const Tr& tr, + const Cache& cache = Cache()) + : Base(sliver_bound, tr, cache), min_value_before_move_(0.) {} private: @@ -157,16 +210,18 @@ class Min_dihedral_angle_criterion template + typename Cache = typename CGAL::Mesh_3::Default_sliver_cache::type, + typename SliverCachingPolicy = internal::Sliver_caching_below_bound_tag> class Radius_ratio_criterion - : public Sliver_criterion + : public Sliver_criterion { + typedef Radius_ratio_criterion Self; + protected: - typedef Sliver_criterion Base; + typedef Sliver_criterion Base; typedef typename Base::GT GT; typedef typename Base::Tetrahedron_3 Tetrahedron_3; typedef typename Base::Cell_vector Cell_vector; - typedef Radius_ratio_criterion RR_criterion; public: @@ -183,13 +238,13 @@ class Radius_ratio_criterion virtual void before_move(const Cell_vector& cells) const { - Min_value min_value_op(*this); + Min_value min_value_op(*this); min_value_before_move_ = min_value_op(cells); } virtual bool valid_move(const Cell_vector& cells, const bool soft = false) const { - Min_value min_value_op(*this); + Min_value min_value_op(*this); double min_val = min_value_op(cells); return (min_val > min_value_before_move_) || (soft && min_val > this->sliver_bound_); @@ -197,8 +252,9 @@ class Radius_ratio_criterion public: Radius_ratio_criterion(const double& sliver_bound, - const Tr& tr) - : Base(sliver_bound, tr) + const Tr& tr, + const Cache& cache = Cache()) + : Base(sliver_bound, tr, cache) {} private: diff --git a/Mesh_3/include/CGAL/Mesh_3/vertex_perturbation.h b/Mesh_3/include/CGAL/Mesh_3/vertex_perturbation.h index db9fca5c268..88f0970e55c 100644 --- a/Mesh_3/include/CGAL/Mesh_3/vertex_perturbation.h +++ b/Mesh_3/include/CGAL/Mesh_3/vertex_perturbation.h @@ -119,7 +119,7 @@ edge_sq_length(const typename Tr::Edge& e, typedef typename Tr::Bare_point Bare_point; typedef typename Tr::Weighted_point Weighted_point; - // There is no need to use tr.min_squared_distance() here because we are computing + // There is no need to use Th::min_squared_distance() here because we are computing // distances between vertices within a common cell, which means that even // if we are using a periodic triangulation, the distance is correctly computed. typename GT::Compute_squared_distance_3 sq_distance = @@ -979,7 +979,7 @@ class Dihedral_angle_perturbation CGAL_assertion(cell->has_vertex(v)); const typename C3T3::Triangulation& tr = c3t3.triangulation(); - // There is no need to use tr.min_squared_distance() here because we are computing + // There is no need to use Th::min_squared_distance() here because we are computing // distances between vertices within a common cell, which means that even // if we are using a periodic triangulation, the distance is correctly computed. typename GT::Compute_squared_distance_3 sq_distance = @@ -1380,14 +1380,7 @@ class Li_random_perturbation mod_vertices.insert(tmp_mod_vertices.begin(), tmp_mod_vertices.end()); - std::size_t nois; -#ifdef CGAL_NEW_INCIDENT_SLIVERS - nois = helper.number_of_incident_slivers(moving_vertex, criterion, sliver_bound); -#else - std::vector new_slivers = - helper.incident_slivers(moving_vertex, criterion, sliver_bound); - nois = new_slivers.size(); -#endif + std::size_t nois = helper.number_of_incident_slivers(moving_vertex, criterion, sliver_bound); // If sliver number has decreased, we won if(nois < slivers.size() ) diff --git a/Mesh_3/include/CGAL/Mesh_cell_criteria_3.h b/Mesh_3/include/CGAL/Mesh_cell_criteria_3.h index 4627578c5ef..c89a9b5939b 100644 --- a/Mesh_3/include/CGAL/Mesh_cell_criteria_3.h +++ b/Mesh_3/include/CGAL/Mesh_cell_criteria_3.h @@ -35,19 +35,17 @@ for the mesh tetrahedra, a uniform shape criterion and a sizing field which may be a uniform or variable field. -\tparam Tr must be identical to the nested type -`Triangulation` of the instance used as model of -`MeshComplex_3InTriangulation_3`. +\tparam C3T3 must be a model of `MeshComplex_3InTriangulation_3`. \cgalModels{MeshCellCriteria_3} \sa `MeshCriteria_3` -\sa `CGAL::Mesh_criteria_3` +\sa `CGAL::Mesh_criteria_3` \sa `CGAL::make_mesh_3()` */ -template + ,typename Visitor_ = Mesh_3::Cell_criterion_visitor_with_radius_lower_bound #endif > class Mesh_cell_criteria_3 @@ -56,6 +54,8 @@ class Mesh_cell_criteria_3 /// \name Types /// @{ + typedef typename C3T3::Triangulation Tr; + /*! Numerical type */ @@ -67,13 +67,13 @@ class Mesh_cell_criteria_3 typedef typename Visitor::Cell_quality Cell_quality; typedef typename Visitor::Is_cell_bad Is_cell_bad; - typedef Mesh_3::Abstract_criterion Abstract_criterion; + typedef Mesh_3::Abstract_criterion Abstract_criterion; private: - typedef Mesh_3::Criteria Criteria; + typedef Mesh_3::Criteria Criteria; typedef typename Tr::Cell_handle Cell_handle; - typedef Mesh_cell_criteria_3 Self; + typedef Mesh_cell_criteria_3 Self; public: @@ -127,7 +127,7 @@ class Mesh_cell_criteria_3 ,const FT& min_radius_bound = 0. #ifndef DOXYGEN_RUNNING ,std::enable_if_t< - Mesh_3::Is_mesh_domain_field_3::value + Mesh_3::Is_mesh_domain_field_3::value >* = 0 #endif ) @@ -148,12 +148,12 @@ class Mesh_cell_criteria_3 /** * @brief returns whether the cell `cell` is bad or not. - * @param tr the triangulation within which `cell` lives + * @param c3t3 the mesh complex within which `cell` lives * @param cell the cell */ - Is_cell_bad operator()(const Tr& tr, const Cell_handle& cell) const + Is_cell_bad operator()(const C3T3& c3t3, const Cell_handle& cell) const { - return criteria_(tr, cell); + return criteria_(c3t3, cell); } #ifndef DOXYGEN_RUNNING @@ -166,20 +166,20 @@ class Mesh_cell_criteria_3 private: void init_radius_edge(const FT& radius_edge_bound) { - typedef Mesh_3::Cell_radius_edge_criterion Radius_edge_criterion; + typedef Mesh_3::Cell_radius_edge_criterion Radius_edge_criterion; criteria_.add(new Radius_edge_criterion(radius_edge_bound)); } void init_radius(const FT& radius_bound) { - typedef Mesh_3::Cell_uniform_size_criterion Radius_criterion; + typedef Mesh_3::Cell_uniform_size_criterion Radius_criterion; criteria_.add(new Radius_criterion(radius_bound)); } template < typename Sizing_field> void init_radius(const Sizing_field& radius_bound) { - typedef Mesh_3::Cell_variable_size_criterion + typedef Mesh_3::Cell_variable_size_criterion Radius_criterion; criteria_.add(new Radius_criterion(radius_bound)); @@ -187,7 +187,7 @@ class Mesh_cell_criteria_3 void init_min_radius(const FT& min_radius_bound) { - typedef Mesh_3::Cell_uniform_size_criterion Radius_criterion; + typedef Mesh_3::Cell_uniform_size_criterion Radius_criterion; criteria_.add(new Radius_criterion(min_radius_bound, true/*lower bound*/)); } diff --git a/Mesh_3/include/CGAL/Mesh_criteria_3.h b/Mesh_3/include/CGAL/Mesh_criteria_3.h index 0b39efab273..3866b56e89f 100644 --- a/Mesh_3/include/CGAL/Mesh_criteria_3.h +++ b/Mesh_3/include/CGAL/Mesh_criteria_3.h @@ -26,21 +26,37 @@ #include #include #include +#include #include +#include + #include // for the macro DBL_MAX +#include // for std::void_t and std::is_base_of namespace CGAL { +namespace internal { +template +struct Get_c3t3 { + using type = CGAL::Mesh_complex_3_in_triangulation_3; +}; -namespace internal { +template +struct Get_c3t3().number_of_cells_in_complex())>> { + using type = C3t3; +}; + +template +using get_c3t3_t = typename Get_c3t3::type; // Class Mesh_criteria_3_impl -template < typename Tr, +template < typename C3T3, typename EdgeCriteria, typename FacetCriteria, typename CellCriteria > class Mesh_criteria_3_impl { + typedef typename C3T3::Triangulation Tr; typedef typename Tr::Geom_traits::FT FT; public: @@ -134,11 +150,8 @@ the class `Mesh_criteria_3` handles the definition of a sizing field to guide the discretization of 1-dimensional features. -\tparam Tr has to be instantiated with the type used for -`C3T3::Triangulation`, -where `C3T3` is the model of `MeshComplex_3InTriangulation_3` -used in the mesh generation process, -and `C3T3::Triangulation` its nested triangulation type. +\tparam C3T3 is the model of `MeshComplex_3InTriangulation_3` used in the +mesh generation process. \cgalModels{MeshCriteria_3,MeshCriteriaWithFeatures_3} @@ -146,17 +159,17 @@ and `C3T3::Triangulation` its nested triangulation type. \code{.cpp} -// Create a Mesh_criteria_3 object with all cell and facet parameters set -Mesh_criteria_3 criteria (parameters::facet_angle(30). - parameters::facet_size(1). - parameters::facet_distance(0.1). - parameters::cell_radius_edge_ratio(2). - parameters::cell_size(1.5)); +// Create a Mesh_criteria_3 object with all cell and facet parameters set +Mesh_criteria_3 criteria (parameters::facet_angle(30). + parameters::facet_size(1). + parameters::facet_distance(0.1). + parameters::cell_radius_edge_ratio(2). + parameters::cell_size(1.5)); -// Create a Mesh_criteria_3 object with size ignored (note that the order changed) -Mesh_criteria_3 criteria (parameters::cell_radius_edge_ratio(2). - parameters::facet_angle(30). - parameters::facet_distance(0.1)); +// Create a Mesh_criteria_3 object with size ignored (note that the order changed) +Mesh_criteria_3 criteria (parameters::cell_radius_edge_ratio(2). + parameters::facet_angle(30). + parameters::facet_distance(0.1)); \endcode @@ -166,25 +179,26 @@ Mesh_criteria_3 criteria (parameters::cell_radius_edge_ratio(2). \sa `MeshEdgeCriteria_3` \sa `MeshFacetCriteria_3` \sa `MeshDomainField_3` -\sa `CGAL::Mesh_cell_criteria_3` -\sa `CGAL::Mesh_edge_criteria_3` -\sa `CGAL::Mesh_facet_criteria_3` +\sa `CGAL::Mesh_cell_criteria_3` +\sa `CGAL::Mesh_edge_criteria_3` +\sa `CGAL::Mesh_facet_criteria_3` \sa `CGAL::Mesh_facet_topology` */ -template , - typename FacetCriteria = Mesh_facet_criteria_3, - typename CellCriteria = Mesh_cell_criteria_3 > +template >, + typename FacetCriteria = Mesh_facet_criteria_3>, + typename CellCriteria = Mesh_cell_criteria_3> > class Mesh_criteria_3 #ifndef DOXYGEN_RUNNING - : public internal::Mesh_criteria_3_impl< Tr, + : public internal::Mesh_criteria_3_impl< internal::get_c3t3_t, EdgeCriteria, FacetCriteria, CellCriteria > #endif { - typedef internal::Mesh_criteria_3_impl< Tr, + typedef internal::get_c3t3_t C3t3; + typedef internal::Mesh_criteria_3_impl< C3t3, EdgeCriteria, FacetCriteria, CellCriteria> Base; @@ -197,18 +211,18 @@ class Mesh_criteria_3 /*! The criteria for edges. */ -typedef Mesh_edge_criteria_3 Edge_criteria; +typedef Mesh_edge_criteria_3 Edge_criteria; /*! The criteria for facets. */ -typedef Mesh_facet_criteria_3 Facet_criteria; +typedef Mesh_facet_criteria_3 Facet_criteria; /*! The criteria for cells. */ -typedef Mesh_cell_criteria_3 Cell_criteria; +typedef Mesh_cell_criteria_3 Cell_criteria; /// @} #else diff --git a/Mesh_3/include/CGAL/Mesh_edge_criteria_3.h b/Mesh_3/include/CGAL/Mesh_edge_criteria_3.h index f743eb3f0fa..bab336408e6 100644 --- a/Mesh_3/include/CGAL/Mesh_edge_criteria_3.h +++ b/Mesh_3/include/CGAL/Mesh_edge_criteria_3.h @@ -93,17 +93,20 @@ namespace internal { The function object class `Mesh_edge_criteria_3` is a model of `MeshEdgeCriteria_3`. It provides bounds for the size and approximation criteria. +\tparam C3T3 must be a model of `MeshComplex_3InTriangulation_3`. + \cgalModels{MeshEdgeCriteria_3} \sa `MeshCriteriaWithFeatures_3` -\sa `CGAL::Mesh_criteria_3` +\sa `CGAL::Mesh_criteria_3` \sa `MeshDomainField_3` */ -template < typename Tr > +template < typename C3T3 > class Mesh_edge_criteria_3 { private: typedef Mesh_edge_criteria_3 Self; + typedef typename C3T3::Triangulation Tr; typedef typename Tr::Geom_traits GT; public: diff --git a/Mesh_3/include/CGAL/Mesh_facet_criteria_3.h b/Mesh_3/include/CGAL/Mesh_facet_criteria_3.h index 5292e0e9478..db4dff0610e 100644 --- a/Mesh_3/include/CGAL/Mesh_facet_criteria_3.h +++ b/Mesh_3/include/CGAL/Mesh_facet_criteria_3.h @@ -39,9 +39,7 @@ namespace CGAL { a uniform or variable distance field for the approximation error criterion. - \tparam Tr must be identical to the nested type - `Triangulation` of the instance used as model of - `MeshComplex_3InTriangulation_3`. + \tparam C3T3 must be a model of `MeshComplex_3InTriangulation_3`. \cgalModels{MeshFacetCriteria_3} @@ -49,17 +47,18 @@ namespace CGAL { \sa `MeshFacetCriteria_3` \sa `MeshDomainField_3` \sa `CGAL::Mesh_facet_topology` - \sa `CGAL::Mesh_criteria_3` + \sa `CGAL::Mesh_criteria_3` \sa `CGAL::make_mesh_3()` */ -template + ,typename Visitor_ = Mesh_3::Facet_criterion_visitor_with_radius_lower_bound #endif > class Mesh_facet_criteria_3 { + typedef typename C3T3::Triangulation Tr; public: /// \name Types @@ -76,14 +75,14 @@ class Mesh_facet_criteria_3 typedef typename Visitor::Facet_quality Facet_quality; typedef typename Visitor::Is_facet_bad Is_facet_bad; - typedef Mesh_3::Abstract_criterion Abstract_criterion; + typedef Mesh_3::Abstract_criterion Abstract_criterion; private: - typedef Mesh_3::Criteria Criteria; + typedef Mesh_3::Criteria Criteria; typedef typename Tr::Facet Facet; - typedef Mesh_facet_criteria_3 Self; + typedef Mesh_facet_criteria_3 Self; public: typedef CGAL::Tag_true Has_manifold_criterion; @@ -162,12 +161,12 @@ class Mesh_facet_criteria_3 /** * @brief returns whether the facet `facet` is bad or not. * - * @param tr the triangulation within which `facet` lives + * @param c3t3 the mesh complex within which `facet` lives * @param facet the facet */ - Is_facet_bad operator()(const Tr& tr, const Facet& facet) const + Is_facet_bad operator()(const C3T3& c3t3, const Facet& facet) const { - return criteria_(tr, facet); + return criteria_(c3t3, facet); } void add(Abstract_criterion* criterion) @@ -193,41 +192,41 @@ class Mesh_facet_criteria_3 private: void init_aspect(const FT& angle_bound) { - typedef Mesh_3::Aspect_ratio_criterion Aspect_criterion; + typedef Mesh_3::Aspect_ratio_criterion Aspect_criterion; criteria_.add(new Aspect_criterion(angle_bound)); } void init_radius(const FT& radius_bound, Tag_false) { if(FT(0) == radius_bound) return; - typedef Mesh_3::Uniform_size_criterion Uniform_size_criterion; + typedef Mesh_3::Uniform_size_criterion Uniform_size_criterion; criteria_.add(new Uniform_size_criterion(radius_bound)); } template void init_radius(const Sizing_field& radius_bound, Tag_true) { - typedef Mesh_3::Variable_size_criterion Variable_size_criterion; + typedef Mesh_3::Variable_size_criterion Variable_size_criterion; criteria_.add(new Variable_size_criterion(radius_bound)); } void init_min_radius(const FT& min_radius_bound) { - typedef Mesh_3::Uniform_size_criterion Uniform_size_criterion; + typedef Mesh_3::Uniform_size_criterion Uniform_size_criterion; criteria_.add(new Uniform_size_criterion(min_radius_bound, true/*lower bound*/)); } void init_distance(const FT& distance_bound, Tag_false) { if(FT(0) == distance_bound) return; - typedef Mesh_3::Uniform_curvature_size_criterion Criterion; + typedef Mesh_3::Uniform_curvature_size_criterion Criterion; criteria_.add(new Criterion(distance_bound)); } template void init_distance(const Sizing_field& distance_bound, Tag_true) { - typedef Mesh_3::Variable_curvature_size_criterion Criterion; criteria_.add(new Criterion(distance_bound)); @@ -240,7 +239,7 @@ class Mesh_facet_criteria_3 { case FACET_VERTICES_ON_SURFACE: { - typedef Mesh_3::Facet_on_surface_criterion On_surface_criterion; + typedef Mesh_3::Facet_on_surface_criterion On_surface_criterion; criteria_.add(new On_surface_criterion()); break; } @@ -249,7 +248,7 @@ class Mesh_facet_criteria_3 case FACET_VERTICES_ON_SAME_SURFACE_PATCH_WITH_ADJACENCY_CHECK: // @TODO: Implement adjacency check ! { - typedef Mesh_3::Facet_on_same_surface_criterion Same_surface_criterion; + typedef Mesh_3::Facet_on_same_surface_criterion Same_surface_criterion; criteria_.add(new Same_surface_criterion()); break; } diff --git a/Mesh_3/include/CGAL/Mesh_facet_topology.h b/Mesh_3/include/CGAL/Mesh_facet_topology.h index af660bdd936..a8e7d5a18ff 100644 --- a/Mesh_3/include/CGAL/Mesh_facet_topology.h +++ b/Mesh_3/include/CGAL/Mesh_facet_topology.h @@ -28,8 +28,8 @@ namespace CGAL { The enum `Mesh_facet_topology` is designed to tell which constraints have to be checked on each surface facet during the mesh refinement process. -\sa `CGAL::Mesh_criteria_3`, -\sa `CGAL::Mesh_facet_criteria_3`. +\sa `CGAL::Mesh_criteria_3`, +\sa `CGAL::Mesh_facet_criteria_3`. */ enum Mesh_facet_topology { diff --git a/Mesh_3/include/CGAL/Mesh_triangulation_3.h b/Mesh_3/include/CGAL/Mesh_triangulation_3.h index 6e62842812a..33720735397 100644 --- a/Mesh_3/include/CGAL/Mesh_triangulation_3.h +++ b/Mesh_3/include/CGAL/Mesh_triangulation_3.h @@ -45,85 +45,7 @@ struct Mesh_geom_traits_generator typedef type Type; }; // end struct Mesh_geom_traits_generator -} // end namespace details - -template -class Mesh_3_regular_triangulation_3_wrapper - : public Regular_triangulation_3 -{ -public: - typedef Regular_triangulation_3 Base; - - typedef typename Base::Geom_traits Geom_traits; - - typedef typename Geom_traits::FT FT; - typedef typename Base::Bare_point Bare_point; - typedef typename Base::Weighted_point Weighted_point; - typedef typename Base::Triangle Triangle; - - typedef typename Base::Vertex_handle Vertex_handle; - typedef typename Base::Facet Facet; - typedef typename Base::Cell_handle Cell_handle; - - typedef typename Geom_traits::Vector_3 Vector; - - using Base::geom_traits; - using Base::point; - using Base::triangle; - - static std::string io_signature() { return Get_io_signature()(); } - - // The undocumented, straightforward functions below are required for Mesh_3 - // because of Periodic_3_mesh_3: they are functions for which both triangulations - // have fundamentally different implementations (usually, Periodic_3_mesh_3 - // does not know the offset of a point and must brute-force check for all - // possibilities). To enable Periodic_3_mesh_3 to use Mesh_3's files, - // each mesh triangulation implements its own version. - - const Bare_point& get_closest_point(const Bare_point& /*p*/, const Bare_point& q) const - { - return q; - } - - Triangle get_incident_triangle(const Facet& f, const Vertex_handle) const - { - return triangle(f); - } - - void set_point(const Vertex_handle v, - const Vector& /*move*/, - const Weighted_point& new_position) - { - v->set_point(new_position); - } - - FT compute_power_distance_to_power_sphere(const Cell_handle c, - const Vertex_handle v) const - { - typedef typename Geom_traits::Compute_power_distance_to_power_sphere_3 Critical_radius; - - Critical_radius critical_radius = - geom_traits().compute_power_distance_to_power_sphere_3_object(); - - return critical_radius(point(c, 0), point(c, 1), point(c, 2), point(c, 3), point(v)); - } - - // \pre c->neighbor(i) is finite - FT compute_power_distance_to_power_sphere(const Cell_handle c, const int i) const - { - Cell_handle nc = c->neighbor(i); - CGAL_precondition(!this->is_infinite(nc)); - Vertex_handle v = nc->vertex(nc->index(c)); - - return compute_power_distance_to_power_sphere(c, v); - } - - typename Geom_traits::FT min_squared_distance(const Bare_point& p, const Bare_point& q) const - { - return geom_traits().compute_squared_distance_3_object()(p, q); - } -}; - +} // namespace details /*! \ingroup PkgMesh3MeshClasses @@ -188,8 +110,7 @@ struct Mesh_triangulation_3 typename Default::Get::type; struct Tds : public Triangulation_data_structure_3 {}; - using Triangulation = - Mesh_3_regular_triangulation_3_wrapper; + using Triangulation = Regular_triangulation_3; public: #ifndef DOXYGEN_RUNNING @@ -201,8 +122,8 @@ struct Mesh_triangulation_3 /*! The triangulation type to be used for the 3D triangulation embedding the mesh. - This type is a wrapper around the type `CGAL::Regular_triangulation_3`, whose vertex - and cell base classes are respectively `VertexBase` and `CellBase`. + This type is a `Regular_triangulation_3` type whose vertex and cell base classes are respectively + `VertexBase` and `CellBase`. */ typedef unspecified_type type; diff --git a/Mesh_3/include/CGAL/Mesh_vertex_base_3.h b/Mesh_3/include/CGAL/Mesh_vertex_base_3.h index 338e40f2860..3b53d34a4c8 100644 --- a/Mesh_3/include/CGAL/Mesh_vertex_base_3.h +++ b/Mesh_3/include/CGAL/Mesh_vertex_base_3.h @@ -115,9 +115,10 @@ template class Mesh_vertex_3 -: public Vb, - public Mesh_vertex_base_3_base< - typename Vb::Triangulation_data_structure::Concurrency_tag> +: public Mesh_vertex_base_3_base< + typename Vb::Triangulation_data_structure::Concurrency_tag>, + public Vb + { public: typedef Vb Cmvb3_base; @@ -131,12 +132,12 @@ class Mesh_vertex_3 // Constructor Mesh_vertex_3() : Vb() + , dimension_(-1) + , cache_validity(false) + , index_() , number_of_incident_facets_(0) , number_of_components_(0) - , index_() , meshing_info_(0) - , dimension_(-1) - , cache_validity(false) #ifdef CGAL_INTRUSIVE_LIST , next_intrusive_() , previous_intrusive_() @@ -201,7 +202,7 @@ class Mesh_vertex_3 std::size_t time_stamp() const { return time_stamp_; } - void set_time_stamp(const std::size_t& ts) { + void set_time_stamp(const std::size_t ts) { time_stamp_ = ts; } ///@} @@ -210,24 +211,23 @@ class Mesh_vertex_3 return cache_validity; } - void invalidate_c2t3_cache() - { + void invalidate_c2t3_cache() { cache_validity = false; } - void set_c2t3_cache(const std::size_t i, const std::size_t j) + void set_c2t3_cache(const int i, const int j) { number_of_incident_facets_ = i; number_of_components_ = j; cache_validity = true; } - std::size_t cached_number_of_incident_facets() const + int cached_number_of_incident_facets() const { return number_of_incident_facets_; } - std::size_t cached_number_of_components() const + int cached_number_of_components() const { return number_of_components_; } @@ -240,30 +240,31 @@ class Mesh_vertex_3 Get_io_signature()() + "+" + Get_io_signature()(); } -private: - std::size_t number_of_incident_facets_; - std::size_t number_of_components_; // number of components in the adjacency - // graph of incident facets (in complex) +private: + short dimension_; + // Dimension of the lowest dimensional face of the input 3D complex + // that contains me. Negative values are a marker for special vertices. + bool cache_validity; // Index of the lowest dimensional face of the input 3D complex // that contains me Index index_; + + int number_of_incident_facets_; + int number_of_components_; // number of components in the adjacency + // graph of incident facets (in complex) + // Stores info needed by optimizers FT meshing_info_; - // Dimension of the lowest dimensional face of the input 3D complex - // that contains me. Negative values are a marker for special vertices. - short dimension_; - bool cache_validity; #ifdef CGAL_INTRUSIVE_LIST Vertex_handle next_intrusive_; Vertex_handle previous_intrusive_; #endif std::size_t time_stamp_ = Time_stamper::invalid_time_stamp; public: - friend std::istream& operator>>(std::istream &is, Mesh_vertex_3& v) { is >> static_cast(v); diff --git a/Mesh_3/include/CGAL/Polygon_mesh_processing/surface_Delaunay_remeshing.h b/Mesh_3/include/CGAL/Polygon_mesh_processing/surface_Delaunay_remeshing.h index ea804af651a..b4fc66357b3 100644 --- a/Mesh_3/include/CGAL/Polygon_mesh_processing/surface_Delaunay_remeshing.h +++ b/Mesh_3/include/CGAL/Polygon_mesh_processing/surface_Delaunay_remeshing.h @@ -193,7 +193,7 @@ surface_Delaunay_remeshing(const TriangleMesh& tmesh, using C3t3 = CGAL::Mesh_complex_3_in_triangulation_3; - using Mesh_criteria = CGAL::Mesh_criteria_3; + using Mesh_criteria = CGAL::Mesh_criteria_3; using FT = typename GT::FT; using Point_3 = typename GT::Point_3; diff --git a/Mesh_3/include/CGAL/Polyhedral_mesh_domain_with_features_3.h b/Mesh_3/include/CGAL/Polyhedral_mesh_domain_with_features_3.h index b58229bca66..d831614c508 100644 --- a/Mesh_3/include/CGAL/Polyhedral_mesh_domain_with_features_3.h +++ b/Mesh_3/include/CGAL/Polyhedral_mesh_domain_with_features_3.h @@ -171,20 +171,20 @@ class Polyhedral_mesh_domain_with_features_3 If `polyhedron` is closed, its inside will be meshed, otherwise there will be no interior and only the surface will be meshed. */ - Polyhedral_mesh_domain_with_features_3(const Polyhedron& polyhedron + Polyhedral_mesh_domain_with_features_3(Polyhedron polyhedron #ifndef DOXYGEN_RUNNING , CGAL::Random* p_rng = nullptr #endif ) : Base(p_rng) , borders_detected_(false) { - stored_polyhedra.resize(1); - stored_polyhedra[0] = polyhedron; + stored_polyhedra.emplace_back(std::move(polyhedron)); get(face_patch_id_t(), stored_polyhedra[0]); this->add_primitives(stored_polyhedra[0]); + this->build(); - if(!is_closed(polyhedron)) + if(!is_closed(stored_polyhedra[0])) this->set_surface_only(); } @@ -196,22 +196,21 @@ class Polyhedral_mesh_domain_with_features_3 Using this constructor enables to mesh a polyhedral surface which is not closed, or has holes. The inside of `bounding_polyhedron` will be meshed. */ - Polyhedral_mesh_domain_with_features_3(const Polyhedron& polyhedron, - const Polyhedron& bounding_polyhedron + Polyhedral_mesh_domain_with_features_3(Polyhedron polyhedron, + Polyhedron bounding_polyhedron #ifndef DOXYGEN_RUNNING , CGAL::Random* p_rng = nullptr #endif ) : Base(p_rng) , borders_detected_(false) { - stored_polyhedra.resize(2); - stored_polyhedra[0] = polyhedron; - stored_polyhedra[1] = bounding_polyhedron; + stored_polyhedra.emplace_back(std::move(polyhedron)); + stored_polyhedra.emplace_back(std::move(bounding_polyhedron)); get(face_patch_id_t(), stored_polyhedra[0]); get(face_patch_id_t(), stored_polyhedra[1]); this->add_primitives(stored_polyhedra[0]); this->add_primitives(stored_polyhedra[1]); - if(CGAL::is_empty(bounding_polyhedron)) { + if(CGAL::is_empty(stored_polyhedra[1])) { this->set_surface_only(); } else { this->add_primitives_to_bounding_tree(stored_polyhedra[1]); @@ -240,7 +239,7 @@ class Polyhedral_mesh_domain_with_features_3 { stored_polyhedra.reserve(std::distance(begin, end)); for (; begin != end; ++begin) { - stored_polyhedra.push_back(**begin); + stored_polyhedra.emplace_back(std::move(**begin)); get(face_patch_id_t(), stored_polyhedra.back()); this->add_primitives(stored_polyhedra.back()); } @@ -272,7 +271,7 @@ class Polyhedral_mesh_domain_with_features_3 stored_polyhedra.reserve(std::distance(begin, end)+1); if(begin != end) { for (; begin != end; ++begin) { - stored_polyhedra.push_back(**begin); + stored_polyhedra.emplace_back(std::move(**begin)); get(face_patch_id_t(), stored_polyhedra.back()); this->add_primitives(stored_polyhedra.back()); } diff --git a/Mesh_3/test/Mesh_3/CMakeLists.txt b/Mesh_3/test/Mesh_3/CMakeLists.txt index 16d9af5df5a..4c224aaf9ec 100644 --- a/Mesh_3/test/Mesh_3/CMakeLists.txt +++ b/Mesh_3/test/Mesh_3/CMakeLists.txt @@ -58,6 +58,7 @@ create_single_source_cgal_program( "test_mesh_cell_base_3.cpp") create_single_source_cgal_program( "test_min_edge_length.cpp") create_single_source_cgal_program( "test_max_edge_distance.cpp") create_single_source_cgal_program( "test_remeshing_polyhedron.cpp" ) +create_single_source_cgal_program( "test_meshing_experimental_compact_cell_base.cpp" ) foreach(target surface_mesh_to_tetrahedral_mesh @@ -92,6 +93,7 @@ foreach(target test_min_size_criteria test_meshing_polyhedral_complex_with_manifold_and_min_size test_remeshing_polyhedron + test_meshing_experimental_compact_cell_base ) if(TARGET ${target}) target_link_libraries(${target} PRIVATE CGAL::Eigen3_support) @@ -119,6 +121,7 @@ if(TARGET CGAL::TBB_support) test_min_edge_length test_max_edge_distance test_min_size_criteria + test_meshing_experimental_compact_cell_base ) if(TARGET ${target}) target_link_libraries(${target} PRIVATE CGAL::TBB_support) diff --git a/Mesh_3/test/Mesh_3/surface_mesh_to_tetrahedral_mesh.cpp b/Mesh_3/test/Mesh_3/surface_mesh_to_tetrahedral_mesh.cpp index 83f48783ede..c77d53da14c 100644 --- a/Mesh_3/test/Mesh_3/surface_mesh_to_tetrahedral_mesh.cpp +++ b/Mesh_3/test/Mesh_3/surface_mesh_to_tetrahedral_mesh.cpp @@ -56,7 +56,7 @@ using C3t3 = CGAL::Mesh_complex_3_in_triangulation_3< // Criteria using Features_sizing_field = CGAL::Sizing_field_with_aabb_tree; -using Mesh_criteria = CGAL::Mesh_criteria_3; +using Mesh_criteria = CGAL::Mesh_criteria_3; std::atomic stop_meshing{false}; void signal_handler(int signal) diff --git a/Mesh_3/test/Mesh_3/test_criteria.cpp b/Mesh_3/test/Mesh_3/test_criteria.cpp index a10460ceee2..ae8ee8d4466 100644 --- a/Mesh_3/test/Mesh_3/test_criteria.cpp +++ b/Mesh_3/test/Mesh_3/test_criteria.cpp @@ -38,7 +38,8 @@ struct Tester typedef typename CGAL::Mesh_triangulation_3::type Tr; typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; - typedef CGAL::Mesh_criteria_3 Mesh_criteria; + typedef CGAL::Mesh_criteria_3 Mesh_criteria; // the template parameter is `Tr` on purpose, + // to test the backward compatibility typedef typename Mesh_criteria::Facet_criteria Facet_criteria; typedef typename Mesh_criteria::Cell_criteria Cell_criteria; @@ -85,8 +86,8 @@ struct Tester void init_facet(const Facet& f, const Bare_point& p) const { - f.first->set_surface_patch_index(f.second,Surface_patch_index(0,1)); - f.first->set_facet_surface_center(f.second,p); + c3t3_.set_surface_patch_index(f, Surface_patch_index(0,1)); + c3t3_.set_surface_center(f, p); for ( int i=0; i<4 ; ++i ) { @@ -213,15 +214,13 @@ struct Tester { typedef typename Cell_criteria::Is_cell_bad Is_bad; - const Tr& tr = c3t3_.triangulation(); - Cell_handle cell1 = cell_handle(c1_); Cell_handle cell2 = cell_handle(c2_); Cell_criteria cell_criteria(radius_edge,radius); - Is_bad b1 = cell_criteria(tr, cell1); - Is_bad b2 = cell_criteria(tr, cell2); + Is_bad b1 = cell_criteria(c3t3_, cell1); + Is_bad b2 = cell_criteria(c3t3_, cell2); std::cerr << "\t[Radius bound: " << radius << " - Radius-edge bound: " << radius_edge @@ -260,15 +259,13 @@ struct Tester { typedef typename Facet_criteria::Is_facet_bad Is_bad; - const Tr& tr = c3t3_.triangulation(); - Facet f1 = facet_handle(f1_); Facet f2 = facet_handle(f2_); Facet_criteria criteria(angle, radius, distance); - Is_bad b1 = criteria(tr, f1); - Is_bad b2 = criteria(tr, f2); + Is_bad b1 = criteria(c3t3_, f1); + Is_bad b2 = criteria(c3t3_, f2); std::cerr << "\t[Angle bound: " << angle << " - Radius bound: " << radius diff --git a/Mesh_3/test/Mesh_3/test_max_edge_distance.cpp b/Mesh_3/test/Mesh_3/test_max_edge_distance.cpp index 8f1a0d36586..58b42c95c97 100644 --- a/Mesh_3/test/Mesh_3/test_max_edge_distance.cpp +++ b/Mesh_3/test/Mesh_3/test_max_edge_distance.cpp @@ -117,7 +117,7 @@ struct Distance_polyhedral_tester : public Tester, public Edge_distance_t typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Criteria - typedef CGAL::Mesh_criteria_3 Mesh_criteria; + typedef CGAL::Mesh_criteria_3 Mesh_criteria; public: void operator()(const std::size_t min_vertices_expected = 0, @@ -196,7 +196,7 @@ struct Distance_label_image_tester : public Tester, public Edge_distance_ typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Criteria - typedef CGAL::Mesh_criteria_3 Mesh_criteria; + typedef CGAL::Mesh_criteria_3 Mesh_criteria; public: diff --git a/Mesh_3/test/Mesh_3/test_mesh_3_issue_1554.cpp b/Mesh_3/test/Mesh_3/test_mesh_3_issue_1554.cpp index f0371d3a96d..d1b59f03f9c 100644 --- a/Mesh_3/test/Mesh_3/test_mesh_3_issue_1554.cpp +++ b/Mesh_3/test/Mesh_3/test_mesh_3_issue_1554.cpp @@ -31,7 +31,7 @@ typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; // To avoid verbose function and named parameters call using namespace CGAL::parameters; diff --git a/Mesh_3/test/Mesh_3/test_mesh_3_issue_8773.cpp b/Mesh_3/test/Mesh_3/test_mesh_3_issue_8773.cpp index 3968930408b..f914a424f40 100644 --- a/Mesh_3/test/Mesh_3/test_mesh_3_issue_8773.cpp +++ b/Mesh_3/test/Mesh_3/test_mesh_3_issue_8773.cpp @@ -22,7 +22,7 @@ using Tr = CGAL::Mesh_triangulation_3; // Criteria -using Mesh_criteria = CGAL::Mesh_criteria_3; +using Mesh_criteria = CGAL::Mesh_criteria_3; namespace params = CGAL::parameters; diff --git a/Mesh_3/test/Mesh_3/test_mesh_capsule_var_distance_bound.cpp b/Mesh_3/test/Mesh_3/test_mesh_capsule_var_distance_bound.cpp index 9fa7eaad0c3..6ba7ab1ed10 100644 --- a/Mesh_3/test/Mesh_3/test_mesh_capsule_var_distance_bound.cpp +++ b/Mesh_3/test/Mesh_3/test_mesh_capsule_var_distance_bound.cpp @@ -24,7 +24,7 @@ typedef CGAL::Mesh_triangulation_3::type Tr; typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; // To avoid verbose function and named parameters call using namespace CGAL::parameters; diff --git a/Mesh_3/test/Mesh_3/test_mesh_cell_base_3.cpp b/Mesh_3/test/Mesh_3/test_mesh_cell_base_3.cpp index 318f5f32b35..4d946312702 100644 --- a/Mesh_3/test/Mesh_3/test_mesh_cell_base_3.cpp +++ b/Mesh_3/test/Mesh_3/test_mesh_cell_base_3.cpp @@ -1,3 +1,4 @@ +#include #include #include @@ -44,27 +45,29 @@ int main (int argc, char** argv){ // Open file - std::ifstream in (argc > 1 ? argv[1] : "data/elephant.mesh", - std::ios_base::in); + std::filesystem::path input_file = (argc > 1 ? argv[1] : CGAL::data_file_path("meshes/elephant.mesh")); + std::ifstream in (input_file, std::ios_base::in); if(!in) { - std::cerr << "Error! Cannot open file " << argv[1] << std::endl; + std::cerr << "Error! Cannot open file " << input_file << std::endl; return 1; } C3t3 c3t3; - if(CGAL::SMDS_3::build_triangulation_from_file(in, c3t3.triangulation())) + if(CGAL::SMDS_3::build_mesh_complex_from_file(in, c3t3)) { for( C3t3::Triangulation::Finite_cells_iterator cit = c3t3.triangulation().finite_cells_begin(); cit != c3t3.triangulation().finite_cells_end(); ++cit) { - assert(cit->subdomain_index() >= 0); - c3t3.add_to_complex(cit, cit->subdomain_index()); + auto subdomain_index = c3t3.subdomain_index(cit); + assert(subdomain_index >= 0); + if(subdomain_index > 0) + c3t3.add_to_complex(cit, subdomain_index); for(int i=0; i < 4; ++i) { - if(cit->surface_patch_index(i)>0) + if(c3t3.surface_patch_index(cit, i) > 0) { - c3t3.add_to_complex(cit, i, cit->surface_patch_index(i)); + c3t3.add_to_complex(cit, i, c3t3.surface_patch_index(cit, i)); } } } @@ -106,7 +109,7 @@ int main (int argc, char** argv){ Polyhedral_mesh_domain domain(polyhedron); namespace p = CGAL::parameters; // Mesh criteria (no cell_size set) - CGAL::Mesh_criteria_3 criteria(p::facet_angle=25); + CGAL::Mesh_criteria_3 criteria(p::facet_angle=25); // Mesh generation c3t3 = CGAL::make_mesh_3(domain, criteria); diff --git a/Mesh_3/test/Mesh_3/test_mesh_criteria_creation.cpp b/Mesh_3/test/Mesh_3/test_mesh_criteria_creation.cpp index 3ab51c43ba4..287f93e92ac 100644 --- a/Mesh_3/test/Mesh_3/test_mesh_criteria_creation.cpp +++ b/Mesh_3/test/Mesh_3/test_mesh_criteria_creation.cpp @@ -1,5 +1,7 @@ #include + #include +#include #include #include @@ -9,8 +11,10 @@ typedef CGAL::Polyhedral_mesh_domain_with_features_3 Mesh_domain; // Triangulation typedef CGAL::Mesh_triangulation_3::type Tr; +typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; + // Criteria -typedef CGAL::Mesh_criteria_3 Mc; +typedef CGAL::Mesh_criteria_3 Mc; typedef CGAL::Mesh_constant_domain_field_3 Sizing_field; @@ -28,7 +32,9 @@ int main() Tr::Point p3(0,1,0); Tr::Point p4(0,0,1); - Tr tr; + C3t3 c3t3; + Tr& tr = c3t3.triangulation(); + tr.insert(p1); tr.insert(p2); tr.insert(p3); @@ -45,16 +51,16 @@ int main() // Init cell tr.dual(ch); - ch->set_subdomain_index(sub_index); + c3t3.set_subdomain_index(ch, sub_index); // Init facet Tr::Bare_point facet_circum = tr.geom_traits().construct_weighted_circumcenter_3_object()( tr.point(ch, k+1), tr.point(ch, k+2), tr.point(ch, k+3)); - ch->set_surface_patch_index(k,surf_index); - ch->set_facet_surface_center(k,facet_circum); - ch->set_facet_surface_center_index(k,index); + c3t3.set_surface_patch_index(ch, k, surf_index); + c3t3.set_surface_center(ch, k, facet_circum); + c3t3.set_surface_center_index(ch, k, index); // Init vertices ch->vertex(0)->set_dimension(2); @@ -102,10 +108,10 @@ int main() FT facet_size_ok = radius_facet*FT(10); Mc fc1(facet_size = facet_size_ok); - assert( ! fc1.facet_criteria_object()(tr, f) ); + assert( ! fc1.facet_criteria_object()(c3t3, f) ); Mc fc3(facet_size = Fsf(facet_size_ok)); - assert( ! fc3.facet_criteria_object()(tr, f) ); + assert( ! fc3.facet_criteria_object()(c3t3, f) ); Mc fc8(facet_distance = 8.); Mc fc9(facet_angle = 9.); @@ -126,10 +132,10 @@ int main() // Test topological criterion creation Mc fc14(facet_topology = CGAL::FACET_VERTICES_ON_SURFACE); - assert( ! fc14.facet_criteria_object()(tr, f) ); + assert( ! fc14.facet_criteria_object()(c3t3, f) ); Mc fc15(facet_topology = CGAL::FACET_VERTICES_ON_SAME_SURFACE_PATCH); - assert( fc15.facet_criteria_object()(tr, f) ); + assert( fc15.facet_criteria_object()(c3t3, f) ); // ----------------------------------- // Test cell criteria @@ -142,13 +148,13 @@ int main() FT cell_size_ok = radius_cell*FT(10); Mc cc1(cell_size = cell_size_ok); - assert( ! cc1.cell_criteria_object()(tr, ch) ); + assert( ! cc1.cell_criteria_object()(c3t3, ch) ); Mc cc3(cell_size = Fsf(cell_size_ok)); - assert( ! cc3.cell_criteria_object()(tr, ch) ); + assert( ! cc3.cell_criteria_object()(c3t3, ch) ); Mc cc7(cell_size = Csf(cell_size_ok)); - assert( ! cc7.cell_criteria_object()(tr, ch) ); + assert( ! cc7.cell_criteria_object()(c3t3, ch) ); Mc cc8(cell_radius_edge_ratio = 8.); Mc cc9(cell_radius_edge_ratio = 9.1, diff --git a/Mesh_3/test/Mesh_3/test_meshing_3D_gray_image.cpp b/Mesh_3/test/Mesh_3/test_meshing_3D_gray_image.cpp index 5674087e2e0..3b853d151ac 100644 --- a/Mesh_3/test/Mesh_3/test_meshing_3D_gray_image.cpp +++ b/Mesh_3/test/Mesh_3/test_meshing_3D_gray_image.cpp @@ -47,7 +47,7 @@ struct Image_tester : public Tester CGAL::Kernel_traits::Kernel, Concurrency_tag>::type Tr; typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; - typedef CGAL::Mesh_criteria_3 Mesh_criteria; + typedef CGAL::Mesh_criteria_3 Mesh_criteria; CGAL_USE_TYPE(typename Mesh_domain::Surface_patch_index); diff --git a/Mesh_3/test/Mesh_3/test_meshing_3D_image.cpp b/Mesh_3/test/Mesh_3/test_meshing_3D_image.cpp index aeecb8641c4..d979ea67f39 100644 --- a/Mesh_3/test/Mesh_3/test_meshing_3D_image.cpp +++ b/Mesh_3/test/Mesh_3/test_meshing_3D_image.cpp @@ -35,7 +35,7 @@ struct Image_tester : public Tester Concurrency_tag>::type Tr; typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; - typedef CGAL::Mesh_criteria_3 Mesh_criteria; + typedef CGAL::Mesh_criteria_3 Mesh_criteria; typedef typename Mesh_criteria::Facet_criteria Facet_criteria; typedef typename Mesh_criteria::Cell_criteria Cell_criteria; @@ -90,5 +90,7 @@ int main() test_epic_p.image(); #endif + std::cout << "Done" << std::endl; + return EXIT_SUCCESS; } diff --git a/Mesh_3/test/Mesh_3/test_meshing_3D_image_with_features.cpp b/Mesh_3/test/Mesh_3/test_meshing_3D_image_with_features.cpp index 7dc5bf5fdcb..e96a750768a 100644 --- a/Mesh_3/test/Mesh_3/test_meshing_3D_image_with_features.cpp +++ b/Mesh_3/test/Mesh_3/test_meshing_3D_image_with_features.cpp @@ -60,7 +60,8 @@ struct Image_tester : public Tester ConcurrencyTag>::type Tr; typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; - typedef CGAL::Mesh_criteria_3 Mesh_criteria; + typedef CGAL::Mesh_criteria_3 Mesh_criteria; // the template parameter is `Tr` on purpose, + // to test the backward compatibility void mesh_and_verify(Mesh_domain& domain, const Image& image, const double volume) const { diff --git a/Mesh_3/test/Mesh_3/test_meshing_determinism.cpp b/Mesh_3/test/Mesh_3/test_meshing_determinism.cpp index fcb314f6ea6..8c5570346f5 100644 --- a/Mesh_3/test/Mesh_3/test_meshing_determinism.cpp +++ b/Mesh_3/test/Mesh_3/test_meshing_determinism.cpp @@ -32,6 +32,7 @@ void test() unsigned int nb_odt = 2; double perturb_bound = 10.; double exude_bound = 15.; + std::size_t nb_operations = 5; // Domain typedef CGAL::Exact_predicates_inexact_constructions_kernel K; @@ -44,7 +45,7 @@ void test() Tr,Mesh_domain::Corner_index,Mesh_domain::Curve_index> C3t3; // Mesh Criteria - typedef CGAL::Mesh_criteria_3 Mesh_criteria; + typedef CGAL::Mesh_criteria_3 Mesh_criteria; // Domain std::cout << "\tSeed is\t 0" << std::endl; @@ -70,85 +71,109 @@ void test() std::vector output_c3t3; std::vector output_surfaces; - const std::size_t nb_operations = 5; - output_c3t3.reserve(nb_operations * nb_runs); for(std::size_t i = 0; i < nb_runs; ++i) { std::cout << "------- Iteration " << (i+1) << " -------" << std::endl; - C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria, - no_perturb(), - no_exude()); - std::ostringstream oss; - CGAL::IO::write_MEDIT(oss, c3t3); - output_c3t3.push_back(oss.str()); //[5*i] - oss.clear(); - Polyhedron out_poly; - CGAL::facets_in_complex_3_to_triangle_mesh(c3t3, out_poly); - oss << out_poly; - output_surfaces.push_back(oss.str());//[5*i] - out_poly.clear(); - oss.clear(); - - //LLOYD (1) - CGAL::lloyd_optimize_mesh_3(c3t3, domain, max_iteration_number = nb_lloyd); - CGAL::IO::write_MEDIT(oss, c3t3); - output_c3t3.push_back(oss.str());//[i*5+1] - oss.clear(); - CGAL::facets_in_complex_3_to_triangle_mesh(c3t3, out_poly); - oss << out_poly; - output_surfaces.push_back(oss.str());//[i*5+1] - out_poly.clear(); - oss.clear(); - - //ODT (2) - CGAL::odt_optimize_mesh_3(c3t3, domain, max_iteration_number = nb_odt); - CGAL::IO::write_MEDIT(oss, c3t3); - output_c3t3.push_back(oss.str());//[i*5+2] - oss.clear(); - CGAL::facets_in_complex_3_to_triangle_mesh(c3t3, out_poly); - oss << out_poly; - output_surfaces.push_back(oss.str());//[i*5+2] - out_poly.clear(); - oss.clear(); - - //PERTURB (3) - CGAL::perturb_mesh_3(c3t3, domain, sliver_bound=perturb_bound); - CGAL::IO::write_MEDIT(oss, c3t3); - output_c3t3.push_back(oss.str());//[i*5+3] - oss.clear(); - CGAL::facets_in_complex_3_to_triangle_mesh(c3t3, out_poly); - oss << out_poly; - output_surfaces.push_back(oss.str());//[i*5+3] - out_poly.clear(); - oss.clear(); - - //EXUDE (4) - CGAL::exude_mesh_3(c3t3, sliver_bound=exude_bound); - CGAL::IO::write_MEDIT(oss, c3t3); - output_c3t3.push_back(oss.str());//[i*5+4] - oss.clear(); - CGAL::facets_in_complex_3_to_triangle_mesh(c3t3, out_poly); - oss << out_poly; - output_surfaces.push_back(oss.str());//[i*5+4] - out_poly.clear(); - oss.clear(); + + C3t3 c3t3; + + if (nb_operations >= 1) { + std::cout << " #1 Meshing..." << std::endl; + c3t3 = CGAL::make_mesh_3(domain, criteria, + no_perturb(), + no_exude()); + + std::stringstream oss; + CGAL::IO::write_MEDIT(oss, c3t3); + output_c3t3.push_back(oss.str()); //[5*i] + + std::stringstream oss_p; + Polyhedron out_poly; + CGAL::facets_in_complex_3_to_triangle_mesh(c3t3, out_poly); + oss_p << out_poly; + output_surfaces.push_back(oss_p.str());//[5*i] + } + + // LLOYD (1) + if (nb_operations >= 2) { + std::cout << " #2 Lloyd..." << std::endl; + CGAL::lloyd_optimize_mesh_3(c3t3, domain, max_iteration_number = nb_lloyd); + + std::stringstream oss; + CGAL::IO::write_MEDIT(oss, c3t3); + output_c3t3.push_back(oss.str());//[i*5+1] + + std::stringstream oss_p; + Polyhedron out_poly; + CGAL::facets_in_complex_3_to_triangle_mesh(c3t3, out_poly); + oss_p << out_poly; + output_surfaces.push_back(oss_p.str());//[i*5+1] + } + + // ODT (2) + if (nb_operations >= 3) { + std::cout << " #3 ODT..." << std::endl; + CGAL::odt_optimize_mesh_3(c3t3, domain, max_iteration_number = nb_odt); + + std::stringstream oss; + CGAL::IO::write_MEDIT(oss, c3t3); + output_c3t3.push_back(oss.str());//[i*5+2] + + std::stringstream oss_p; + Polyhedron out_poly; + CGAL::facets_in_complex_3_to_triangle_mesh(c3t3, out_poly); + oss_p << out_poly; + output_surfaces.push_back(oss_p.str());//[i*5+2] + } + + // PERTURB (3) + if (nb_operations >= 4) { + std::cout << " #4 Pertub..." << std::endl; + CGAL::perturb_mesh_3(c3t3, domain, sliver_bound=perturb_bound); + + std::stringstream oss; + CGAL::IO::write_MEDIT(oss, c3t3); + output_c3t3.push_back(oss.str());//[i*5+3] + + std::stringstream oss_p; + Polyhedron out_poly; + CGAL::facets_in_complex_3_to_triangle_mesh(c3t3, out_poly); + oss_p << out_poly; + output_surfaces.push_back(oss_p.str());//[i*5+3] + } + + // EXUDE (4) + if (nb_operations >= 5) { + std::cout << " #5 Exude..." << std::endl; + CGAL::exude_mesh_3(c3t3, sliver_bound=exude_bound); + + std::stringstream oss; + CGAL::IO::write_MEDIT(oss, c3t3); + output_c3t3.push_back(oss.str());//[i*5+4] + + std::stringstream oss_p; + Polyhedron out_poly; + CGAL::facets_in_complex_3_to_triangle_mesh(c3t3, out_poly); + oss_p << out_poly; + output_surfaces.push_back(oss_p.str());//[i*5+4] + } if(i == 0) continue; //else check - for(std::size_t j = 0; j < nb_operations; ++j) + for(std::size_t j=1; j<=nb_operations; ++j) { - std::size_t id1 = nb_operations * (i - 1) + j; - std::size_t id2 = nb_operations * i + j; + std::size_t id1 = nb_operations * (i - 1) + (j-1); + std::size_t id2 = nb_operations * i + (j-1); if(0 != output_c3t3[id1].compare(output_c3t3[id2])) { - std::cerr << "Meshing operation " << j << " is not deterministic.\n"; + std::cerr << "Meshing operation #" << j << " is not deterministic.\n"; assert(false); } if (0 != output_surfaces[id1].compare(output_surfaces[id2])) { - std::cerr << "Output surface after operation " << j << " is not deterministic.\n"; + std::cerr << "Output surface after operation #" << j << " is not deterministic.\n"; assert(false); } } diff --git a/Mesh_3/test/Mesh_3/test_meshing_experimental_compact_cell_base.cpp b/Mesh_3/test/Mesh_3/test_meshing_experimental_compact_cell_base.cpp new file mode 100644 index 00000000000..34d38122809 --- /dev/null +++ b/Mesh_3/test/Mesh_3/test_meshing_experimental_compact_cell_base.cpp @@ -0,0 +1,3 @@ +#define CGAL_MESH_3_USE_EXPERIMENTAL_COMPACT_MESH_CELL_BASE_3 1 +#define CGAL_MESH_3_NO_CIRCUMCENTER_CACHE +#include "test_meshing_polyhedron_with_features.cpp" diff --git a/Mesh_3/test/Mesh_3/test_meshing_implicit_function.cpp b/Mesh_3/test/Mesh_3/test_meshing_implicit_function.cpp index b4fcb318b43..3163bc156dc 100644 --- a/Mesh_3/test/Mesh_3/test_meshing_implicit_function.cpp +++ b/Mesh_3/test/Mesh_3/test_meshing_implicit_function.cpp @@ -26,7 +26,7 @@ struct Implicit_tester : public Tester Concurrency_tag>::type Tr; typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; - typedef CGAL::Mesh_criteria_3 Mesh_criteria; + typedef CGAL::Mesh_criteria_3 Mesh_criteria; typedef typename Mesh_criteria::Facet_criteria Facet_criteria; typedef typename Mesh_criteria::Cell_criteria Cell_criteria; diff --git a/Mesh_3/test/Mesh_3/test_meshing_polyhedral_complex.cpp b/Mesh_3/test/Mesh_3/test_meshing_polyhedral_complex.cpp index c3f7e999026..e1bce75f403 100644 --- a/Mesh_3/test/Mesh_3/test_meshing_polyhedral_complex.cpp +++ b/Mesh_3/test/Mesh_3/test_meshing_polyhedral_complex.cpp @@ -54,7 +54,7 @@ struct Polyhedral_complex_tester : public Tester Tr, typename Mesh_domain::Corner_index, typename Mesh_domain::Curve_index> C3t3; - typedef CGAL::Mesh_criteria_3 Mesh_criteria; + typedef CGAL::Mesh_criteria_3 Mesh_criteria; //Input const std::size_t nb_patches = sizeof(filenames) / sizeof(const char*); diff --git a/Mesh_3/test/Mesh_3/test_meshing_polyhedral_complex_with_manifold_and_min_size.cpp b/Mesh_3/test/Mesh_3/test_meshing_polyhedral_complex_with_manifold_and_min_size.cpp index 236e0069aec..1ae17f3e2c3 100644 --- a/Mesh_3/test/Mesh_3/test_meshing_polyhedral_complex_with_manifold_and_min_size.cpp +++ b/Mesh_3/test/Mesh_3/test_meshing_polyhedral_complex_with_manifold_and_min_size.cpp @@ -28,7 +28,7 @@ typedef CGAL::Mesh_complex_3_in_triangulation_3< Tr,Mesh_domain::Corner_index,Mesh_domain::Curve_index> C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; namespace params = CGAL::parameters; @@ -85,5 +85,7 @@ int main() CGAL::IO::write_MEDIT(medit_file, c3t3); medit_file.close(); + std::cout << "Done" << std::endl; + return EXIT_SUCCESS; } diff --git a/Mesh_3/test/Mesh_3/test_meshing_polyhedron.cpp b/Mesh_3/test/Mesh_3/test_meshing_polyhedron.cpp index 9d43786e1a1..8d2c332a355 100644 --- a/Mesh_3/test/Mesh_3/test_meshing_polyhedron.cpp +++ b/Mesh_3/test/Mesh_3/test_meshing_polyhedron.cpp @@ -46,7 +46,7 @@ struct Polyhedron_tester : public Tester Concurrency_tag>::type Tr; typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; - typedef CGAL::Mesh_criteria_3 Mesh_criteria; + typedef CGAL::Mesh_criteria_3 Mesh_criteria; typedef typename Mesh_criteria::Facet_criteria Facet_criteria; typedef typename Mesh_criteria::Cell_criteria Cell_criteria; diff --git a/Mesh_3/test/Mesh_3/test_meshing_polyhedron_with_features.cpp b/Mesh_3/test/Mesh_3/test_meshing_polyhedron_with_features.cpp index ac77144de61..efd9b74b07d 100644 --- a/Mesh_3/test/Mesh_3/test_meshing_polyhedron_with_features.cpp +++ b/Mesh_3/test/Mesh_3/test_meshing_polyhedron_with_features.cpp @@ -1,19 +1,3 @@ -// Copyright (c) 2010 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) : Stephane Tayeb -// -//****************************************************************************** -// File Description : -//****************************************************************************** - #include "test_meshing_utilities.h" #include #include @@ -91,7 +75,7 @@ struct Polyhedron_with_features_tester : public Tester typename Mesh_domain::Corner_index, typename Mesh_domain::Curve_index > C3t3; - typedef CGAL::Mesh_criteria_3 Mesh_criteria; + typedef CGAL::Mesh_criteria_3 Mesh_criteria; typedef typename Mesh_criteria::Edge_criteria Edge_criteria; typedef typename Mesh_criteria::Facet_criteria Facet_criteria; typedef typename Mesh_criteria::Cell_criteria Cell_criteria; @@ -99,11 +83,12 @@ struct Polyhedron_with_features_tester : public Tester //------------------------------------------------------- // Data generation //------------------------------------------------------- - std::cout << "\tSeed is\t" - << CGAL::get_default_random().get_seed() << std::endl; + std::cout << "\tSeed is\t" << CGAL::get_default_random().get_seed() << std::endl; + std::ifstream input(CGAL::data_file_path("meshes/cube.off")); Polyhedron polyhedron; input >> polyhedron; + Mesh_domain domain(polyhedron, &CGAL::get_default_random()); domain.detect_features(); @@ -123,7 +108,12 @@ struct Polyhedron_with_features_tester : public Tester #endif Mesh_criteria criteria(edge_criteria, facet_criteria, cell_criteria); + namespace params = CGAL::parameters; + // Mesh generation + std::cout << "sizeof(Vertex) " << sizeof(typename C3t3::Triangulation::Vertex) << std::endl; + std::cout << "sizeof(Cell) " << sizeof(typename C3t3::Triangulation::Cell) << std::endl; + C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria, CGAL::parameters::manifold(), CGAL::parameters::no_exude(), @@ -138,6 +128,10 @@ struct Polyhedron_with_features_tester : public Tester std::ofstream out_medit("test-medit.mesh"); CGAL::IO::write_MEDIT(out_medit, c3t3); CGAL::IO::output_to_tetgen("test-tetgen", c3t3); + std::ofstream out_ascii("test-ascii.mesh.cgal", + std::ios_base::out|std::ios_base::binary); + CGAL::IO::save_binary_file(out_ascii, c3t3, false); + out_ascii.close(); std::ofstream out_binary("test-binary.mesh.cgal", std::ios_base::out|std::ios_base::binary); CGAL::IO::save_binary_file(out_binary, c3t3); @@ -160,11 +154,13 @@ int main() } #ifdef CGAL_LINKED_WITH_TBB { - std::cerr << "Parallel mesh generation from a polyhedron with edges:\n"; + std::cerr << "\n\nParallel mesh generation from a polyhedron with edges:\n"; Polyhedron_with_features_tester test_epic_p("parallel"); test_epic_p(); } #endif + std::cout << "Done" << std::endl; + return EXIT_SUCCESS; } diff --git a/Mesh_3/test/Mesh_3/test_meshing_polylines_only.cpp b/Mesh_3/test/Mesh_3/test_meshing_polylines_only.cpp index 118a69a4676..52e95813bcd 100644 --- a/Mesh_3/test/Mesh_3/test_meshing_polylines_only.cpp +++ b/Mesh_3/test/Mesh_3/test_meshing_polylines_only.cpp @@ -43,7 +43,7 @@ typedef CGAL::Mesh_complex_3_in_triangulation_3< Tr,Mesh_domain::Corner_index,Mesh_domain::Curve_index> C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; // To avoid verbose function and named parameters call using namespace CGAL::parameters; diff --git a/Mesh_3/test/Mesh_3/test_meshing_unit_tetrahedron.cpp b/Mesh_3/test/Mesh_3/test_meshing_unit_tetrahedron.cpp index 3e62a7d11ae..8deb5409e7d 100644 --- a/Mesh_3/test/Mesh_3/test_meshing_unit_tetrahedron.cpp +++ b/Mesh_3/test/Mesh_3/test_meshing_unit_tetrahedron.cpp @@ -37,7 +37,7 @@ struct Polyhedron_tester : public Tester typename Mesh_domain::Curve_index> C3t3; // Criteria - typedef CGAL::Mesh_criteria_3 Mesh_criteria; + typedef CGAL::Mesh_criteria_3 Mesh_criteria; MeshPolyhedron_3 P; diff --git a/Mesh_3/test/Mesh_3/test_meshing_utilities.h b/Mesh_3/test/Mesh_3/test_meshing_utilities.h index 9ab4ba4ea4d..4fc8a4a3c49 100644 --- a/Mesh_3/test/Mesh_3/test_meshing_utilities.h +++ b/Mesh_3/test/Mesh_3/test_meshing_utilities.h @@ -122,7 +122,6 @@ struct Tester CGAL::parameters::no_perturb(), CGAL::parameters::no_reset_c3t3()); -#ifndef CGAL_MESH_3_USE_OLD_SURFACE_RESTRICTED_DELAUNAY_UPDATE // Using adjacencies instead of calling oracle to update restricted // Delaunay of the surface during the refinement of the volume // does not ensure that refinement is idempotent @@ -142,7 +141,6 @@ struct Tester f = c3t3.number_of_facets_in_complex(); c = c3t3.number_of_cells_in_complex(); assert ( n < 11 ); -#endif verify_c3t3(c3t3,domain,domain_type,v,v,f,f,c,c); verify_c3t3_hausdorff_distance(c3t3, domain, domain_type, hdist); @@ -206,19 +204,20 @@ struct Tester //------------------------------------------------------- // Verifications //------------------------------------------------------- - std::cerr << "\tNumber of cells: " << c3t3.number_of_cells_in_complex() - << " (expected in [" << min_cells_expected << ", " << max_cells_expected << "])\n"; - std::cerr << "\tNumber of facets: " << c3t3.number_of_facets_in_complex() - << " (expected in [" << min_facets_expected << ", " << max_facets_expected << "])\n"; - std::cerr << "\tNumber of vertices: " << c3t3.triangulation().number_of_vertices() - << " (expected in [" << min_vertices_expected << ", " << max_vertices_expected << "])\n"; - - dump_c3t3(c3t3, "dump_c3t3"); + std::cerr << "\tNumber of cells: " << c3t3.number_of_cells_in_complex() << " "; + std::cerr << "[expected: " << min_cells_expected << " - " << max_cells_expected << "]\n"; + std::cerr << "\tNumber of facets: " << c3t3.number_of_facets_in_complex() << " "; + std::cerr << "[expected: " << min_facets_expected << " - " << max_facets_expected << "]\n"; + std::cerr << "\tNumber of vertices: " << c3t3.triangulation().number_of_vertices() << " "; + std::cerr << "[expected: " << min_vertices_expected << " - " << max_vertices_expected << "]\n"; std::size_t dist_facets ( std::distance(c3t3.facets_in_complex_begin(), c3t3.facets_in_complex_end()) ); std::size_t dist_cells ( std::distance(c3t3.cells_in_complex_begin(), - c3t3.cells_in_complex_end()) ); + c3t3.cells_in_complex_end()) ); + + std::cout << "dist_facets " << dist_facets << std::endl; + std::cout << "dist_cells " << dist_cells << std::endl; assert(min_vertices_expected <= c3t3.triangulation().number_of_vertices()); assert(max_vertices_expected >= c3t3.triangulation().number_of_vertices()); @@ -327,11 +326,11 @@ struct Tester assert(index.first != index.second); Cell_handle c1 = f.first; Cell_handle c2 = f.first->neighbor(f.second); - if( c1->subdomain_index() == c2->subdomain_index() ) + if( c3t3.subdomain_index(c1) == c3t3.subdomain_index(c2) ) { std::cerr << "ERROR:" - << "\nc1->subdomain_index(): " << c1->subdomain_index() - << "\nc2->subdomain_index(): " << c2->subdomain_index() + << "\nc3t3.subdomain_index(c1): " << c3t3.subdomain_index(c1) + << "\nc3t3.subdomain_index(c2): " << c3t3.subdomain_index(c2) << "\nc3t3.surface_patch_index(f).first: " << index.first << "\nc3t3.surface_patch_index(f).second: " << index.second; if(tr.is_infinite(c1)) std::cerr << "\nc1 is infinite"; diff --git a/Mesh_3/test/Mesh_3/test_meshing_with_one_step.cpp b/Mesh_3/test/Mesh_3/test_meshing_with_one_step.cpp index 19199d8e08f..50bca77737d 100644 --- a/Mesh_3/test/Mesh_3/test_meshing_with_one_step.cpp +++ b/Mesh_3/test/Mesh_3/test_meshing_with_one_step.cpp @@ -25,7 +25,7 @@ typedef CGAL::Mesh_triangulation_3 C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; typedef CGAL::Mesh_3::Mesher_3 C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; typedef CGAL::Mesh_3::Mesher_3 C3t3; // Mesh Criteria - typedef CGAL::Mesh_criteria_3 Mesh_criteria; + typedef CGAL::Mesh_criteria_3 Mesh_criteria; // Domain std::cout << "\tSeed is\t 0" << std::endl; diff --git a/Mesh_3/test/Mesh_3/test_min_edge_length.cpp b/Mesh_3/test/Mesh_3/test_min_edge_length.cpp index ef70ce34c00..da1154121fb 100644 --- a/Mesh_3/test/Mesh_3/test_min_edge_length.cpp +++ b/Mesh_3/test/Mesh_3/test_min_edge_length.cpp @@ -25,7 +25,7 @@ struct Tester typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Criteria - typedef CGAL::Mesh_criteria_3 Mesh_criteria; + typedef CGAL::Mesh_criteria_3 Mesh_criteria; void operator()(const std::filesystem::path& fname, const std::filesystem::path& out_fname) { diff --git a/Mesh_3/test/Mesh_3/test_min_size_criteria.cpp b/Mesh_3/test/Mesh_3/test_min_size_criteria.cpp index d42bef33f80..1519f36fae0 100644 --- a/Mesh_3/test/Mesh_3/test_min_size_criteria.cpp +++ b/Mesh_3/test/Mesh_3/test_min_size_criteria.cpp @@ -36,12 +36,13 @@ struct Image_tester : public Tester CGAL::Kernel_traits::Kernel, Concurrency_tag>::type; using C3t3 = CGAL::Mesh_complex_3_in_triangulation_3; + using Th = CGAL::Mesh_3::Triangulation_helpers; using GT = typename Tr::Geom_traits; using FT = typename Tr::Geom_traits::FT; using Bare_point = typename Tr::Bare_point; - using Mesh_criteria = CGAL::Mesh_criteria_3; + using Mesh_criteria = CGAL::Mesh_criteria_3; using Facet_criteria = typename Mesh_criteria::Facet_criteria; using Cell_criteria = typename Mesh_criteria::Cell_criteria; @@ -79,6 +80,7 @@ struct Image_tester : public Tester CGAL::parameters::no_perturb()); const Tr& tr = c3t3.triangulation(); + typename GT::Construct_point_3 cp = tr.geom_traits().construct_point_3_object(); typename GT::Compute_squared_radius_3 sq_radius = tr.geom_traits().compute_squared_radius_3_object(); @@ -88,9 +90,9 @@ struct Image_tester : public Tester for (auto f : c3t3.facets_in_complex()) { const Bare_point p1 = cp(tr.point(f.first, (f.second + 1) & 3)); - const Bare_point& ball_center = f.first->get_facet_surface_center(f.second); + const Bare_point& ball_center = c3t3.surface_center(f); - const FT sqr = tr.min_squared_distance(p1, ball_center); + const FT sqr = Th().min_squared_distance(tr, p1, ball_center); max_sq_facet_radius = (std::max)(max_sq_facet_radius, sqr); } @@ -105,7 +107,7 @@ struct Image_tester : public Tester max_sq_cell_radius = (std::max)(max_sq_cell_radius, sqr); } - const std::size_t nbv = c3t3.triangulation().number_of_vertices(); + const std::size_t nbv = tr.number_of_vertices(); std::cout << "C3t3 initial = " << nbv << std::endl; //new criteria with really small facet_size and cell_size @@ -123,7 +125,7 @@ struct Image_tester : public Tester CGAL::parameters::no_perturb(), CGAL::parameters::no_exude()); - const std::size_t nbv2 = c3t3.triangulation().number_of_vertices(); + const std::size_t nbv2 = tr.number_of_vertices(); std::cout << "C3t3 after refinement = " << nbv2 << std::endl; assert(nbv == nbv2); diff --git a/Mesh_3/test/Mesh_3/test_remeshing_polyhedron.cpp b/Mesh_3/test/Mesh_3/test_remeshing_polyhedron.cpp index bd8c6955793..be880e0bf05 100644 --- a/Mesh_3/test/Mesh_3/test_remeshing_polyhedron.cpp +++ b/Mesh_3/test/Mesh_3/test_remeshing_polyhedron.cpp @@ -36,7 +36,7 @@ struct Polyhedron_tester : public Tester using Mesh_domain = CGAL::Polyhedral_mesh_domain_3; using Tr = typename CGAL::Mesh_triangulation_3::type; using C3t3 = CGAL::Mesh_complex_3_in_triangulation_3; - using Mesh_criteria = CGAL::Mesh_criteria_3; + using Mesh_criteria = CGAL::Mesh_criteria_3; Polyhedron polyhedron; std::ifstream input(filename); diff --git a/Mesh_3/test/Mesh_3/test_without_detect_features.cpp b/Mesh_3/test/Mesh_3/test_without_detect_features.cpp index c5928744074..e9360edc8ee 100644 --- a/Mesh_3/test/Mesh_3/test_without_detect_features.cpp +++ b/Mesh_3/test/Mesh_3/test_without_detect_features.cpp @@ -20,7 +20,7 @@ struct Tester { typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Criteria - typedef CGAL::Mesh_criteria_3 Mesh_criteria; + typedef CGAL::Mesh_criteria_3 Mesh_criteria; int operator()(const std::filesystem::path& fname, const std::filesystem::path& /*out_fname*/) { diff --git a/Periodic_3_mesh_3/examples/Periodic_3_mesh_3/mesh_implicit_multi_domain.cpp b/Periodic_3_mesh_3/examples/Periodic_3_mesh_3/mesh_implicit_multi_domain.cpp index bdb3320e240..243ca016fe2 100644 --- a/Periodic_3_mesh_3/examples/Periodic_3_mesh_3/mesh_implicit_multi_domain.cpp +++ b/Periodic_3_mesh_3/examples/Periodic_3_mesh_3/mesh_implicit_multi_domain.cpp @@ -38,7 +38,7 @@ typedef CGAL::Periodic_3_mesh_triangulation_3::type Tr; typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Periodic_mesh_criteria; +typedef CGAL::Mesh_criteria_3 Periodic_mesh_criteria; // To avoid verbose function and named parameters call namespace params = CGAL::parameters; diff --git a/Periodic_3_mesh_3/examples/Periodic_3_mesh_3/mesh_implicit_shape.cpp b/Periodic_3_mesh_3/examples/Periodic_3_mesh_3/mesh_implicit_shape.cpp index c742bc2d4cf..d82b5e2eb58 100644 --- a/Periodic_3_mesh_3/examples/Periodic_3_mesh_3/mesh_implicit_shape.cpp +++ b/Periodic_3_mesh_3/examples/Periodic_3_mesh_3/mesh_implicit_shape.cpp @@ -31,7 +31,7 @@ typedef CGAL::Periodic_3_mesh_triangulation_3::type Tr; typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Periodic_mesh_criteria; +typedef CGAL::Mesh_criteria_3 Periodic_mesh_criteria; // To avoid verbose function and named parameters call namespace params = CGAL::parameters; diff --git a/Periodic_3_mesh_3/examples/Periodic_3_mesh_3/mesh_implicit_shape_with_features.cpp b/Periodic_3_mesh_3/examples/Periodic_3_mesh_3/mesh_implicit_shape_with_features.cpp index 0be891eaa35..15146d08c1f 100644 --- a/Periodic_3_mesh_3/examples/Periodic_3_mesh_3/mesh_implicit_shape_with_features.cpp +++ b/Periodic_3_mesh_3/examples/Periodic_3_mesh_3/mesh_implicit_shape_with_features.cpp @@ -42,7 +42,7 @@ typedef CGAL::Mesh_complex_3_in_triangulation_3< Tr, Periodic_mesh_domain::Corner_index, Periodic_mesh_domain::Curve_index> C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Periodic_mesh_criteria; +typedef CGAL::Mesh_criteria_3 Periodic_mesh_criteria; // To avoid verbose function and named parameters call namespace params = CGAL::parameters; diff --git a/Periodic_3_mesh_3/examples/Periodic_3_mesh_3/mesh_implicit_shape_with_optimizers.cpp b/Periodic_3_mesh_3/examples/Periodic_3_mesh_3/mesh_implicit_shape_with_optimizers.cpp index 3aee4a2c6c7..32ab9765cc7 100644 --- a/Periodic_3_mesh_3/examples/Periodic_3_mesh_3/mesh_implicit_shape_with_optimizers.cpp +++ b/Periodic_3_mesh_3/examples/Periodic_3_mesh_3/mesh_implicit_shape_with_optimizers.cpp @@ -31,7 +31,7 @@ typedef CGAL::Periodic_3_mesh_triangulation_3::type Tr; typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Periodic_mesh_criteria; +typedef CGAL::Mesh_criteria_3 Periodic_mesh_criteria; // To avoid verbose function and named parameters call namespace params = CGAL::parameters; diff --git a/Periodic_3_mesh_3/examples/Periodic_3_mesh_3/mesh_implicit_shape_with_subdomains.cpp b/Periodic_3_mesh_3/examples/Periodic_3_mesh_3/mesh_implicit_shape_with_subdomains.cpp index 183e5e1674a..b578a8fa684 100644 --- a/Periodic_3_mesh_3/examples/Periodic_3_mesh_3/mesh_implicit_shape_with_subdomains.cpp +++ b/Periodic_3_mesh_3/examples/Periodic_3_mesh_3/mesh_implicit_shape_with_subdomains.cpp @@ -33,7 +33,7 @@ typedef CGAL::Periodic_3_mesh_triangulation_3::type Tr; typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Periodic_mesh_criteria; +typedef CGAL::Mesh_criteria_3 Periodic_mesh_criteria; // To avoid verbose function and named parameters call namespace params = CGAL::parameters; diff --git a/Periodic_3_mesh_3/examples/Periodic_3_mesh_3/mesh_periodic_polyhedral_domain.cpp b/Periodic_3_mesh_3/examples/Periodic_3_mesh_3/mesh_periodic_polyhedral_domain.cpp index 8e72bc854a7..1daebd7725c 100644 --- a/Periodic_3_mesh_3/examples/Periodic_3_mesh_3/mesh_periodic_polyhedral_domain.cpp +++ b/Periodic_3_mesh_3/examples/Periodic_3_mesh_3/mesh_periodic_polyhedral_domain.cpp @@ -84,7 +84,7 @@ using Tr = CGAL::Periodic_3_mesh_triangulation_3::type; using C3t3 = CGAL::Mesh_complex_3_in_triangulation_3; // Criteria -using Periodic_mesh_criteria = CGAL::Mesh_criteria_3; +using Periodic_mesh_criteria = CGAL::Mesh_criteria_3; // To avoid verbose function and named parameters call namespace params = CGAL::parameters; diff --git a/Periodic_3_mesh_3/include/CGAL/Periodic_3_mesh_3/Protect_edges_sizing_field.h b/Periodic_3_mesh_3/include/CGAL/Periodic_3_mesh_3/Protect_edges_sizing_field.h index b49379e5d28..7c32959ba0b 100644 --- a/Periodic_3_mesh_3/include/CGAL/Periodic_3_mesh_3/Protect_edges_sizing_field.h +++ b/Periodic_3_mesh_3/include/CGAL/Periodic_3_mesh_3/Protect_edges_sizing_field.h @@ -41,7 +41,7 @@ #endif #include #include -#include +#include #if CGAL_MESH_3_PROTECTION_DEBUG # include #endif @@ -89,6 +89,8 @@ class Protect_edges_sizing_field public: typedef typename C3T3::Triangulation Tr; + typedef CGAL::Mesh_3::Triangulation_helpers Th; + typedef typename Tr::Bare_point Bare_point; typedef typename Tr::Weighted_point Weighted_point; typedef typename Weighted_point::Weight Weight; @@ -398,7 +400,7 @@ class Protect_edges_sizing_field /// Computes the Euclidean distance between the bare points `p` and `q`. FT compute_distance(const Bare_point& p, const Bare_point& q) const { - // No need to call min_squared_distance() because 'p' and 'q' have been + // No need to call Th::min_squared_distance() because 'p' and 'q' have been // built to have proper respective positions in space return CGAL::sqrt(geom_traits(). compute_squared_distance_3_object()(p,q)); @@ -418,7 +420,7 @@ class Protect_edges_sizing_field const Weighted_point& wpa = point(va); const Weighted_point& wpb = point(vb); - return CGAL::sqrt(tr().min_squared_distance(cp(wpa), cp(wpb))); + return CGAL::sqrt(Th().min_squared_distance(tr(), cp(wpa), cp(wpb))); } /// Returns the radius of the ball of vertex `v`. @@ -583,9 +585,6 @@ Protect_edges_sizing_field(C3T3& c3t3, const MD& domain, , nonlinear_growth_of_balls(false) , vertex_handle_to_full_space_position() { -#ifndef CGAL_MESH_3_NO_PROTECTION_NON_LINEAR - set_nonlinear_growth_of_balls(); -#endif } @@ -691,7 +690,7 @@ insert_in_correspondence_map(const Vertex_handle v, const Curve_index_container& curve_indices, typename Curve_index_container::const_iterator* /*sfinae*/) { - CGAL_precondition(cp(point(v)) == tr().canonicalize_point(p)); + CGAL_precondition(cp(point(v)) == Th().canonicalize_point(tr(), p)); typename Curve_index_container::const_iterator cicit = curve_indices.begin(), ciend = curve_indices.end(); @@ -1345,7 +1344,7 @@ try_to_move_close_dummy_vertex(Vertex_handle& protection_vertex, const Weighted_point& pv_wp = point(protection_vertex); const Weighted_point& dv_wp = point(dummy_vertex); - const Weighted_point canonical_dv_wp = tr().get_closest_point(pv_wp, dv_wp); + const Weighted_point canonical_dv_wp = Th().get_closest_point(tr(), pv_wp, dv_wp); CGAL_precondition(pv_wp != canonical_dv_wp); Vector_3 dir(cp(pv_wp), cp(canonical_dv_wp)); @@ -1412,7 +1411,7 @@ insert_corners() for ( const auto& [_,p] : corners ) { - Dt_Vertex_handle dtvh = dt.insert(tr().canonicalize_point(p)); + Dt_Vertex_handle dtvh = dt.insert(Th().canonicalize_point(tr(), p)); CGAL_assertion(dtvh != Dt_Vertex_handle()); dt_point_vh_map[p] = dtvh; // note that p is not canonicalized here (there's no point to) } @@ -1685,7 +1684,7 @@ smart_insert_point(const Bare_point& p, Weight w, int dim, const Index& index, FT sq_d; std::tie(nearest_vh, sq_d) = tr().nearest_power_vertex_with_sq_distance(p, ch); CGAL_assertion(nearest_vh != Vertex_handle()); - CGAL_assertion(tr().point(nearest_vh) != cwp(tr().canonicalize_point(p))); + CGAL_assertion(point(nearest_vh) != cwp(Th().canonicalize_point(tr(), p))); #if CGAL_MESH_3_PROTECTION_DEBUG & 16 std::cerr << "Nearest power vertex of (" << p << ") is " @@ -1759,7 +1758,7 @@ smart_insert_point(const Bare_point& p, Weight w, int dim, const Index& index, bool is_v_dummy_vertex = is_dummy_vertex(v); #endif - const FT sq_d = tr().min_squared_distance(p, cp(point(v))); + const FT sq_d = Th().min_squared_distance(tr(), p, cp(point(v))); if(minimal_weight_ != Weight() && sq_d < minimal_weight_) { @@ -2442,7 +2441,7 @@ do_balls_intersect(const Vertex_handle& va, const Vertex_handle& vb) const const Weighted_point& wpb = point(vb); CGAL_precondition(va != vb && wpa != wpb); - return (tr().min_squared_distance(cp(wpa), cp(wpb)) <= + return (Th().min_squared_distance(tr(), cp(wpa), cp(wpb)) <= CGAL::square(CGAL::sqrt(cw(wpa)) + CGAL::sqrt(cw(wpa)))); } diff --git a/Periodic_3_mesh_3/include/CGAL/Periodic_3_mesh_3/Triangulation_helpers.h b/Periodic_3_mesh_3/include/CGAL/Periodic_3_mesh_3/Triangulation_helpers.h new file mode 100644 index 00000000000..f2b0383b683 --- /dev/null +++ b/Periodic_3_mesh_3/include/CGAL/Periodic_3_mesh_3/Triangulation_helpers.h @@ -0,0 +1,267 @@ +// Copyright (c) 2009 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) : Stephane Tayeb +// +//****************************************************************************** +// File Description : +//****************************************************************************** + +#ifndef CGAL_PERIODIC_3_MESH_3_TRIANGULATION_HELPERS_H +#define CGAL_PERIODIC_3_MESH_3_TRIANGULATION_HELPERS_H + +#include + +#include +#include +#include + +namespace CGAL { +namespace Mesh_3 { + +template +class Triangulation_helpers; + +// specialize for periodic triangulations +template +class Triangulation_helpers + : public Triangulation_helpers // inherit the non-periodic functions +{ + typedef typename Tr::Geom_traits GT; + typedef typename Tr::FT FT; + typedef typename GT::Vector_3 Vector_3; + typedef typename GT::Triangle_3 Triangle_3; + + // If `Tr` is not a triangulation that has defined Bare_point, + // use Point_3 as defined in the traits class. + typedef typename boost::mpl::eval_if_c< + CGAL::internal::Has_nested_type_Bare_point::value, + typename CGAL::internal::Bare_point_type, + boost::mpl::identity + >::type Bare_point; + + typedef typename GT::Weighted_point_3 Weighted_point_3; + + typedef typename Tr::Offset Offset; + + typedef typename Tr::Vertex Vertex; + typedef typename Tr::Vertex_handle Vertex_handle; + typedef typename Tr::Facet Facet; + typedef typename Tr::Cell Cell; + typedef typename Tr::Cell_handle Cell_handle; + +public: + Bare_point canonicalize_point(const Tr& tr, const Bare_point& p) const + { + return P3T3::internal::construct_canonical_point(p, tr.geom_traits()); + } + + // @fixme it might be dangerous to call robust_canonicalize() without also changing + // = construct_periodic_point(p) (lack of consistency in the result) + Weighted_point_3 canonicalize_point(const Tr& tr, const Weighted_point_3& p) const + { + return P3T3::internal::construct_canonical_point(p, tr.geom_traits()); + } + + // Warning: This function finds which offset 'Oq' should be applied to 'q' such + // that the distance between 'p' and '(q, Oq)' is minimal. + // + // \pre 'p' lives in the canonical instance. + Bare_point get_closest_point(const Tr& tr, + const Bare_point& p, + const Bare_point& q) const + { + CGAL_precondition(p.x() < tr.domain().xmax()); + CGAL_precondition(p.y() < tr.domain().ymax()); + CGAL_precondition(p.z() < tr.domain().zmax()); + CGAL_precondition(p.x() >= tr.domain().xmin()); + CGAL_precondition(p.y() >= tr.domain().ymin()); + CGAL_precondition(p.z() >= tr.domain().zmin()); + + typename GT::Compare_squared_distance_3 compare_sd = + tr.geom_traits().compare_squared_distance_3_object(); + typename GT::Construct_point_3 cp = + tr.geom_traits().construct_point_3_object(); + + std::pair pp_q = P3T3::internal::construct_periodic_point(q, tr.geom_traits()); + + Offset min_off; + Offset null_offset(0,0,0); + + for(int i = 0; i < 3; ++i) { + for(int j = 0; j < 3; ++j) { + for(int k = 0; k < 3; ++k) + { + const Offset o(i-1, j-1, k-1); + + if((i == 0 && j == 0 && k == 0) || + compare_sd(p, q, p, q, + null_offset, pp_q.second + o, + null_offset, pp_q.second + min_off) == SMALLER) + { + min_off = o; + } + } + } + } + + return cp(q, pp_q.second + min_off); + } + + Weighted_point_3 get_closest_point(const Tr& tr, + const Weighted_point_3& wp, + const Weighted_point_3& wq) const + { + typename GT::Compute_weight_3 cw = tr.geom_traits().compute_weight_3_object(); + typename GT::Construct_point_3 cp = tr.geom_traits().construct_point_3_object(); + typename GT::Construct_weighted_point_3 cwp = tr.geom_traits().construct_weighted_point_3_object(); + + return cwp(get_closest_point(tr, cp(wp), cp(wq)), cw(wq)); + } + + // returns the triangle corresponding to f, with a geometric shift + // so that it is incident to ref_v's canonical position + Triangle_3 get_incident_triangle(const Tr& tr, + const Facet& f, + const Vertex_handle ref_v) const + { + typename GT::Construct_point_3 cp = tr.geom_traits().construct_point_3_object(); + typename GT::Construct_translated_point_3 tp = tr.geom_traits().construct_translated_point_3_object(); + typename GT::Construct_vector_3 cv = tr.geom_traits().construct_vector_3_object(); + typename GT::Construct_triangle_3 ct = tr.geom_traits().construct_triangle_3_object(); + + CGAL_precondition(f.first != Cell_handle() && f.first->has_vertex(ref_v)); + const int ref_v_pos = f.first->index(ref_v); + const Bare_point& ref_p = cp(tr.point(ref_v)); + const Bare_point ref_p_in_f = cp(tr.point(f.first, ref_v_pos)); + Vector_3 move_to_canonical = cv(ref_p_in_f, ref_p); + + const int s = f.second; + const Bare_point mp0 = tp(cp(tr.point(f.first, (s+1)%4)), move_to_canonical); + const Bare_point mp1 = tp(cp(tr.point(f.first, (s+2)%4)), move_to_canonical); + const Bare_point mp2 = tp(cp(tr.point(f.first, (s+3)%4)), move_to_canonical); + const Triangle_3 t = ct(mp0, mp1, mp2); + + return t; + } + + void set_point(const Tr& tr, + const Vertex_handle v, + const Vector_3& move, + const Weighted_point_3& new_position) const + { + // calling robust canonical here means we don't necessarily have + // canonical(v + move) = new_position... @fixme + return tr.set_point(v, move, canonicalize_point(tr, new_position)); + } + + FT compute_power_distance_to_power_sphere(const Tr& tr, + const Cell_handle c, + const int i) const + { + typename GT::Compute_power_distance_to_power_sphere_3 cr = + tr.geom_traits().compute_power_distance_to_power_sphere_3_object(); + + Offset o_nb = tr.neighbor_offset(c, i, c->neighbor(i)); + Offset o_vt = tr.get_offset(c->neighbor(i), c->neighbor(i)->index(c)); + + const Weighted_point_3& wp0 = tr.point(c->vertex(0)); // need the canonical point + const Weighted_point_3& wp1 = tr.point(c->vertex(1)); + const Weighted_point_3& wp2 = tr.point(c->vertex(2)); + const Weighted_point_3& wp3 = tr.point(c->vertex(3)); + const Weighted_point_3& wq = tr.point(c->neighbor(i)->vertex(c->neighbor(i)->index(c))); + const Offset& op0 = tr.get_offset(c, 0); + const Offset& op1 = tr.get_offset(c, 1); + const Offset& op2 = tr.get_offset(c, 2); + const Offset& op3 = tr.get_offset(c, 3); + const Offset oq = o_vt - o_nb; + + return cr(wp0, wp1, wp2, wp3, wq, op0, op1, op2, op3, oq); + } + + // The functions below are used in Mesh_3 and need a specific implementation + // for the periodic case because we need to try with different offsets to get the result + FT compute_power_distance_to_power_sphere(const Tr& tr, + const Cell_handle c, + const Vertex_handle v) const + { + // @fixme need to introduce Compare_power_distances_to_power_sphere_3(4 points, query) + typename GT::Compute_power_distance_to_power_sphere_3 cr = + tr.geom_traits().compute_power_distance_to_power_sphere_3_object(); + + FT min_power_dist = std::numeric_limits::infinity(); + + const Weighted_point_3& wp0 = tr.point(c->vertex(0)); // need the canonical point + const Weighted_point_3& wp1 = tr.point(c->vertex(1)); + const Weighted_point_3& wp2 = tr.point(c->vertex(2)); + const Weighted_point_3& wp3 = tr.point(c->vertex(3)); + const Weighted_point_3& wq = tr.point(v); + const Offset& op0 = tr.get_offset(c, 0); + const Offset& op1 = tr.get_offset(c, 1); + const Offset& op2 = tr.get_offset(c, 2); + const Offset& op3 = tr.get_offset(c, 3); + + for(int i = 0; i < 3; ++i) { + for(int j = 0; j < 3; ++j) { + for(int k = 0; k < 3; ++k) { + const Offset oq(i-1, j-1, k-1); + + FT power_dist = cr(wp0, wp1, wp2, wp3, wq, op0, op1, op2, op3, oq); + + if(power_dist < min_power_dist) + min_power_dist = power_dist; + } + } + } + + return min_power_dist; + } + + // Warning: This is a periodic version that computes the smallest possible distance + // between 'p' and 'q', for all possible combinations of offsets + FT min_squared_distance(const Tr& tr, + const Bare_point& p, + const Bare_point& q) const + { + typename GT::Compare_squared_distance_3 compare_sd = + tr.geom_traits().compare_squared_distance_3_object(); + typename GT::Compute_squared_distance_3 compute_sd = + tr.geom_traits().compute_squared_distance_3_object(); + + std::pair pp_p = P3T3::internal::construct_periodic_point(p, tr.geom_traits()); + std::pair pp_q = P3T3::internal::construct_periodic_point(q, tr.geom_traits()); + + Offset min_off; + + for(int i = 0; i < 3; ++i) { + for(int j = 0; j < 3; ++j) { + for(int k = 0; k < 3; ++k) + { + const Offset o(i-1, j-1, k-1); + + if((i == 0 && j == 0 && k == 0) || + compare_sd(q, p, q, p, + pp_q.second, pp_p.second + o, + pp_q.second, pp_p.second + min_off) == SMALLER) + { + min_off = o; + } + } + } + } + + return compute_sd(q, p, pp_q.second, pp_p.second + min_off); + } +}; + +} // namespace Mesh_3 +} // namespace CGAL + +#endif // CGAL_PERIODIC_3_MESH_3_TRIANGULATION_HELPERS_H diff --git a/Periodic_3_mesh_3/include/CGAL/Periodic_3_mesh_3/config.h b/Periodic_3_mesh_3/include/CGAL/Periodic_3_mesh_3/config.h index 4b529afbce7..1ad328dbbc7 100644 --- a/Periodic_3_mesh_3/include/CGAL/Periodic_3_mesh_3/config.h +++ b/Periodic_3_mesh_3/include/CGAL/Periodic_3_mesh_3/config.h @@ -48,8 +48,8 @@ * available with some periodic triangulation traits. (cf. Periodic_3_triangulation_remove_traits_3.h) * Indeed, this feature needs the Triangulation_3::inexact_orientation() method. * - * A better solution would be to make Triangulation_3 compatible 'any' traits. - * By this way, Triangulation_3 would require the Bare_point concept which would use in + * A better solution would be to make Triangulation_3 compatible with 'any' traits. + * This way, Triangulation_3 would require the Bare_point concept which would use in * inexact_orientation(). So, we'd work with a Bare_point instead of a Point in this method. * In the 'default' Triangulation_3 traits, Bare_point would be equal to Point_3 * (or const Point_3& <- for avoiding useless copies). diff --git a/Periodic_3_mesh_3/include/CGAL/Periodic_3_mesh_triangulation_3.h b/Periodic_3_mesh_3/include/CGAL/Periodic_3_mesh_triangulation_3.h index fc1a3791cb4..fc231886779 100644 --- a/Periodic_3_mesh_3/include/CGAL/Periodic_3_mesh_triangulation_3.h +++ b/Periodic_3_mesh_3/include/CGAL/Periodic_3_mesh_triangulation_3.h @@ -19,8 +19,8 @@ #include -// traits class -#include +#include + #include #include #include @@ -66,8 +66,11 @@ class Periodic_3_regular_triangulation_3_wrapper void *get_lock_data_structure() const { return 0; } void set_lock_data_structure(void *) const { } + typedef Periodic_3_regular_triangulation_3_wrapper Self; typedef Periodic_3_regular_triangulation_3 Base; + typedef Mesh_3::Triangulation_helpers Th; + typedef typename Base::Geom_traits Geom_traits; typedef typename Base::Triangulation_data_structure Triangulation_data_structure; @@ -186,23 +189,6 @@ class Periodic_3_regular_triangulation_3_wrapper return (number_of_vertices() == 0) ? -2 : 3; } - void set_domain(const Iso_cuboid& domain) - { - Base::set_domain(domain); - } - - Bare_point canonicalize_point(const Bare_point& p) const - { - return P3T3::internal::construct_canonical_point(p, geom_traits()); - } - - // @fixme it might be dangerous to call robust_canonicalize() without also changing - // = construct_periodic_point(p) (lack of consistency in the result) - Weighted_point canonicalize_point(const Weighted_point& p) const - { - return P3T3::internal::construct_canonical_point(p, geom_traits()); - } - // 1-cover, so we can take a const& const Weighted_point& point(const Vertex_handle v) const { @@ -308,70 +294,11 @@ class Periodic_3_regular_triangulation_3_wrapper this->v_offsets.clear(); } - FT compute_power_distance_to_power_sphere(const Cell_handle c, const int i) const - { - typename Geom_traits::Compute_power_distance_to_power_sphere_3 cr = - geom_traits().compute_power_distance_to_power_sphere_3_object(); - - Offset o_nb = this->neighbor_offset(c, i, c->neighbor(i)); - Offset o_vt = get_offset(c->neighbor(i), c->neighbor(i)->index(c)); - - const Weighted_point& wp0 = point(c->vertex(0)); // need the canonical point - const Weighted_point& wp1 = point(c->vertex(1)); - const Weighted_point& wp2 = point(c->vertex(2)); - const Weighted_point& wp3 = point(c->vertex(3)); - const Weighted_point& wq = point(c->neighbor(i)->vertex(c->neighbor(i)->index(c))); - const Offset& op0 = get_offset(c, 0); - const Offset& op1 = get_offset(c, 1); - const Offset& op2 = get_offset(c, 2); - const Offset& op3 = get_offset(c, 3); - const Offset oq = o_vt - o_nb; - - return cr(wp0, wp1, wp2, wp3, wq, op0, op1, op2, op3, oq); - } - - // The functions below are used in Mesh_3 and need a specific implementation - // for the periodic case because we need to try with different offsets to get the result - FT compute_power_distance_to_power_sphere(const Cell_handle c, - const Vertex_handle v) const - { - // @fixme need to introduce Compare_power_distances_to_power_sphere_3(4 points, query) - typename Geom_traits::Compute_power_distance_to_power_sphere_3 cr = - geom_traits().compute_power_distance_to_power_sphere_3_object(); - - FT min_power_dist = std::numeric_limits::infinity(); - - const Weighted_point& wp0 = point(c->vertex(0)); // need the canonical point - const Weighted_point& wp1 = point(c->vertex(1)); - const Weighted_point& wp2 = point(c->vertex(2)); - const Weighted_point& wp3 = point(c->vertex(3)); - const Weighted_point& wq = point(v); - const Offset& op0 = get_offset(c, 0); - const Offset& op1 = get_offset(c, 1); - const Offset& op2 = get_offset(c, 2); - const Offset& op3 = get_offset(c, 3); - - for(int i = 0; i < 3; ++i) { - for(int j = 0; j < 3; ++j) { - for(int k = 0; k < 3; ++k) { - const Offset oq(i-1, j-1, k-1); - - FT power_dist = cr(wp0, wp1, wp2, wp3, wq, op0, op1, op2, op3, oq); - - if(power_dist < min_power_dist) - min_power_dist = power_dist; - } - } - } - - return min_power_dist; - } - // Return the tetrahedron made of 'f' + 'wp' // \pre there exists an offset such that 'f.first' is in conflict with 'wp' Tetrahedron tetrahedron(const Facet& f, const Weighted_point& wp) const { - Weighted_point canonic_wp = canonicalize_point(wp); + Weighted_point canonic_wp = Th().canonicalize_point(*this, wp); Conflict_tester tester(canonic_wp, this); const Cell_handle c = f.first; @@ -403,7 +330,7 @@ class Periodic_3_regular_triangulation_3_wrapper Bounded_side side_of_power_sphere(const Cell_handle c, const Weighted_point& p, bool perturb = false) const { - Weighted_point canonical_p = canonicalize_point(p); + Weighted_point canonical_p = Th().canonicalize_point(*this, p); Bounded_side bs = ON_UNBOUNDED_SIDE; for(int i = 0; i < 3; ++i) { @@ -421,116 +348,6 @@ class Periodic_3_regular_triangulation_3_wrapper return bs; } - // Warning: This is a periodic version that computes the smallest possible distance - // between 'p' and 'q', for all possible combinations of offsets - FT min_squared_distance(const Bare_point& p, const Bare_point& q) const - { - typename Geom_traits::Compare_squared_distance_3 compare_sd = - geom_traits().compare_squared_distance_3_object(); - typename Geom_traits::Compute_squared_distance_3 compute_sd = - geom_traits().compute_squared_distance_3_object(); - - std::pair pp_p = P3T3::internal::construct_periodic_point(p, geom_traits()); - std::pair pp_q = P3T3::internal::construct_periodic_point(q, geom_traits()); - - Offset min_off; - - for(int i = 0; i < 3; ++i) { - for(int j = 0; j < 3; ++j) { - for(int k = 0; k < 3; ++k) - { - const Offset o(i-1, j-1, k-1); - - if((i == 0 && j == 0 && k == 0) || - compare_sd(q, p, q, p, - pp_q.second, pp_p.second + o, - pp_q.second, pp_p.second + min_off) == SMALLER) - { - min_off = o; - } - } - } - } - - return compute_sd(q, p, pp_q.second, pp_p.second + min_off); - } - - // Warning: This function finds which offset 'Oq' should be applied to 'q' such - // that the distance between 'p' and '(q, Oq)' is minimal. - // - // \pre 'p' lives in the canonical instance. - Bare_point get_closest_point(const Bare_point& p, const Bare_point& q) const - { - CGAL_precondition(p.x() < domain().xmax()); - CGAL_precondition(p.y() < domain().ymax()); - CGAL_precondition(p.z() < domain().zmax()); - CGAL_precondition(p.x() >= domain().xmin()); - CGAL_precondition(p.y() >= domain().ymin()); - CGAL_precondition(p.z() >= domain().zmin()); - - typename Geom_traits::Compare_squared_distance_3 compare_sd = - geom_traits().compare_squared_distance_3_object(); - typename Geom_traits::Construct_point_3 cp = - geom_traits().construct_point_3_object(); - - std::pair pp_q = P3T3::internal::construct_periodic_point(q, geom_traits()); - - Offset min_off; - Offset null_offset(0,0,0); - - for(int i = 0; i < 3; ++i) { - for(int j = 0; j < 3; ++j) { - for(int k = 0; k < 3; ++k) - { - const Offset o(i-1, j-1, k-1); - - if((i == 0 && j == 0 && k == 0) || - compare_sd(p, q, p, q, - null_offset, pp_q.second + o, - null_offset, pp_q.second + min_off) == SMALLER) - { - min_off = o; - } - } - } - } - - return cp(q, pp_q.second + min_off); - } - - Weighted_point get_closest_point(const Weighted_point& wp, const Weighted_point& wq) const - { - typename Geom_traits::Compute_weight_3 cw = geom_traits().compute_weight_3_object(); - typename Geom_traits::Construct_point_3 cp = geom_traits().construct_point_3_object(); - typename Geom_traits::Construct_weighted_point_3 cwp = geom_traits().construct_weighted_point_3_object(); - - return cwp(get_closest_point(cp(wp), cp(wq)), cw(wq)); - } - - // returns the triangle corresponding to f, with a geometric shift - // so that it is incident to ref_v's canonical position - Triangle get_incident_triangle(const Facet& f, const Vertex_handle ref_v) const - { - typename Geom_traits::Construct_point_3 cp = geom_traits().construct_point_3_object(); - typename Geom_traits::Construct_translated_point_3 tr = geom_traits().construct_translated_point_3_object(); - typename Geom_traits::Construct_vector_3 cv = geom_traits().construct_vector_3_object(); - typename Geom_traits::Construct_triangle_3 ct = geom_traits().construct_triangle_3_object(); - - CGAL_precondition(f.first != Cell_handle() && f.first->has_vertex(ref_v)); - const int ref_v_pos = f.first->index(ref_v); - const Bare_point& ref_p = cp(point(ref_v)); - const Bare_point ref_p_in_f = cp(point(f.first, ref_v_pos)); - Vector_3 move_to_canonical = cv(ref_p_in_f, ref_p); - - const int s = f.second; - const Bare_point mp0 = tr(cp(point(f.first, (s+1)%4)), move_to_canonical); - const Bare_point mp1 = tr(cp(point(f.first, (s+2)%4)), move_to_canonical); - const Bare_point mp2 = tr(cp(point(f.first, (s+3)%4)), move_to_canonical); - const Triangle t = ct(mp0, mp1, mp2); - - return t; - } - // Warning: This is a periodic version that computes the smallest possible // distances between p and q, and between p and r FOR ALL POSSIBLE OFFSETS // before comparing these distances. @@ -597,12 +414,12 @@ class Periodic_3_regular_triangulation_3_wrapper /// @{ bool is_vertex(const Weighted_point& p, Vertex_handle& v) const { - return Base::is_vertex(canonicalize_point(p), v); + return Base::is_vertex(Th().canonicalize_point(*this, p), v); } Vertex_handle nearest_power_vertex(const Bare_point& p, Cell_handle start) const { - return Base::nearest_power_vertex(canonicalize_point(p), start); + return Base::nearest_power_vertex(Th().canonicalize_point(*this, p), start); } /// Return the squared distance (note: _NOT_ the power distance) @@ -614,7 +431,7 @@ class Periodic_3_regular_triangulation_3_wrapper // Any change should be mirrored. CGAL_precondition(number_of_vertices() > 0); - Bare_point canonical_p = canonicalize_point(p); + Bare_point canonical_p = Th().canonicalize_point(*this, p); Locate_type lt; int li, lj; @@ -718,7 +535,7 @@ class Periodic_3_regular_triangulation_3_wrapper bool* CGAL_assertion_code(could_lock_zone) = nullptr) const { CGAL_assertion(could_lock_zone == nullptr); - return Base::locate(canonicalize_point(p), start); + return Base::locate(Th().canonicalize_point(*this, p), start); } Cell_handle locate(const Weighted_point& p, @@ -728,7 +545,7 @@ class Periodic_3_regular_triangulation_3_wrapper CGAL_assertion(could_lock_zone == nullptr); // Compared to the non-periodic version in T3, the infinite cell cannot // be used as default hint, so `Cell_handle()` is used instead. - return Base::locate(canonicalize_point(p), + return Base::locate(Th().canonicalize_point(*this, p), hint == Vertex_handle() ? Cell_handle() : hint->cell()); } @@ -738,7 +555,7 @@ class Periodic_3_regular_triangulation_3_wrapper bool* CGAL_assertion_code(could_lock_zone) = nullptr) const { CGAL_assertion(could_lock_zone == nullptr); - return Base::locate(canonicalize_point(p), l, i, j, start); + return Base::locate(Th().canonicalize_point(*this, p), l, i, j, start); } Cell_handle locate(const Weighted_point& p, @@ -747,7 +564,7 @@ class Periodic_3_regular_triangulation_3_wrapper bool* CGAL_assertion_code(could_lock_zone) = nullptr) const { CGAL_assertion(could_lock_zone == nullptr); - return Base::locate(canonicalize_point(p), l, i, j, + return Base::locate(Th().canonicalize_point(*this, p), l, i, j, hint == Vertex_handle() ? Cell_handle() : hint->cell()); } /// @} @@ -786,7 +603,7 @@ class Periodic_3_regular_triangulation_3_wrapper clear_v_offsets(); - Weighted_point canonic_p = canonicalize_point(p); + Weighted_point canonic_p = Th().canonicalize_point(*this, p); Locate_type lt; int li, lj; @@ -841,15 +658,6 @@ class Periodic_3_regular_triangulation_3_wrapper } /// @} - void set_point(const Vertex_handle v, - const Vector_3& move, - const Weighted_point& new_position) - { - // calling robust canonical here means we don't necessarily have - // canonical(v + move) = new_position... @fixme - return Base::set_point(v, move, canonicalize_point(new_position)); - } - /// \name Insert functions /// /// Insert points in the triangulation. @@ -873,7 +681,7 @@ class Periodic_3_regular_triangulation_3_wrapper bool* CGAL_assertion_code(could_lock_zone) = nullptr) { CGAL_assertion(could_lock_zone == nullptr); - return Base::insert(canonicalize_point(p), start); + return Base::insert(Th().canonicalize_point(*this, p), start); } Vertex_handle insert(const Weighted_point& p, @@ -883,7 +691,7 @@ class Periodic_3_regular_triangulation_3_wrapper CGAL_assertion(could_lock_zone == nullptr); // compared to the non-periodic version in T3, the infinite cell cannot // be used; `Cell_handle()` is used instead - return Base::insert(canonicalize_point(p), + return Base::insert(Th().canonicalize_point(*this, p), hint == Vertex_handle() ? Cell_handle() : hint->cell()); } @@ -892,7 +700,7 @@ class Periodic_3_regular_triangulation_3_wrapper bool* CGAL_assertion_code(could_lock_zone) = nullptr) { CGAL_assertion(could_lock_zone == nullptr); - return Base::insert(canonicalize_point(p), lt, loc, li, lj); + return Base::insert(Th().canonicalize_point(*this, p), lt, loc, li, lj); } /// @} diff --git a/Periodic_3_mesh_3/include/CGAL/make_periodic_3_mesh_3.h b/Periodic_3_mesh_3/include/CGAL/make_periodic_3_mesh_3.h index 5bed7b2a3c1..8d2dc8c9d53 100644 --- a/Periodic_3_mesh_3/include/CGAL/make_periodic_3_mesh_3.h +++ b/Periodic_3_mesh_3/include/CGAL/make_periodic_3_mesh_3.h @@ -27,7 +27,6 @@ #include #include -#include #include #include @@ -234,11 +233,10 @@ struct C3t3_initializer * \tparam C3T3 is required to be a model of * the concept `MeshComplex_3InTriangulation_3`. This is the return type. * The type `C3T3` is in particular required to provide a nested type - * `C3T3::Triangulation` for the 3D triangulation - * embedding the mesh. The vertex and cell base classes of the - * triangulation `C3T3::Triangulation` are required to be models of the - * concepts `MeshVertexBase_3` and `MeshCellBase_3` - * respectively. + * `C3T3::Triangulation` for the 3D triangulation embedding the mesh. + * This type must be a `CGAL::Periodic_3_mesh_triangulation_3` whose + * vertex and cell base classes are be models of the + * concepts `MeshVertexBase_3` and `MeshCellBase_3`, respectively. * * \tparam MD is required to be a model of * the concept `MeshDomain_3`, or of the refined concept diff --git a/Periodic_3_mesh_3/include/CGAL/refine_periodic_3_mesh_3.h b/Periodic_3_mesh_3/include/CGAL/refine_periodic_3_mesh_3.h index 6ebb843f739..8f01e6ab7df 100644 --- a/Periodic_3_mesh_3/include/CGAL/refine_periodic_3_mesh_3.h +++ b/Periodic_3_mesh_3/include/CGAL/refine_periodic_3_mesh_3.h @@ -226,9 +226,7 @@ void project_dummy_points_of_surface(C3T3& c3t3, * will always satisfy this condition. * * - * \tparam C3T3 is required to be a model of - * the concept - * `MeshComplex_3InTriangulation_3`. + * \tparam C3T3 is required to be a model of the concept `MeshComplex_3InTriangulation_3`. * The argument `c3t3` is passed by * reference as this object is modified by the refinement process. As the * refinement process only adds points to the triangulation, all @@ -237,11 +235,10 @@ void project_dummy_points_of_surface(C3T3& c3t3, * specific points in the domain to ensure that they will be contained in the * final triangulation. * The type `C3T3` is in particular required to provide a nested type - * `C3T3::Triangulation` for the 3D triangulation - * embedding the mesh. The vertex and cell base classes of the - * triangulation `C3T3::Triangulation` are required to be models of the - * concepts `MeshVertexBase_3` and `MeshCellBase_3` - * respectively. + * `C3T3::Triangulation` for the 3D triangulation embedding the mesh. + * This type must be a `CGAL::Periodic_3_mesh_triangulation_3` whose + * vertex and cell base classes are be models of the + * concepts `MeshVertexBase_3` and `MeshCellBase_3`, respectively. * * \tparam MD is required to be a model of * the concept `Periodic_3MeshDomain_3` or of the refined concept diff --git a/Periodic_3_mesh_3/test/Periodic_3_mesh_3/test_implicit_shapes_bunch.cpp b/Periodic_3_mesh_3/test/Periodic_3_mesh_3/test_implicit_shapes_bunch.cpp index 87669ceb91d..b05b1216adf 100644 --- a/Periodic_3_mesh_3/test/Periodic_3_mesh_3/test_implicit_shapes_bunch.cpp +++ b/Periodic_3_mesh_3/test/Periodic_3_mesh_3/test_implicit_shapes_bunch.cpp @@ -37,7 +37,7 @@ typedef CGAL::Periodic_3_mesh_triangulation_3::type Tr; typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Periodic_mesh_criteria; +typedef CGAL::Mesh_criteria_3 Periodic_mesh_criteria; // To avoid verbose function and named parameters call using namespace CGAL::parameters; diff --git a/Periodic_3_mesh_3/test/Periodic_3_mesh_3/test_implicit_shapes_with_features.cpp b/Periodic_3_mesh_3/test/Periodic_3_mesh_3/test_implicit_shapes_with_features.cpp index 2a297d3f89b..1bda2d4c039 100644 --- a/Periodic_3_mesh_3/test/Periodic_3_mesh_3/test_implicit_shapes_with_features.cpp +++ b/Periodic_3_mesh_3/test/Periodic_3_mesh_3/test_implicit_shapes_with_features.cpp @@ -43,7 +43,7 @@ typedef CGAL::Mesh_complex_3_in_triangulation_3< Tr, Periodic_mesh_domain::Corner_index, Periodic_mesh_domain::Curve_index> C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Periodic_mesh_criteria; +typedef CGAL::Mesh_criteria_3 Periodic_mesh_criteria; // To avoid verbose function and named parameters call using namespace CGAL::parameters; diff --git a/Periodic_3_mesh_3/test/Periodic_3_mesh_3/test_triply_periodic_minimal_surfaces.cpp b/Periodic_3_mesh_3/test/Periodic_3_mesh_3/test_triply_periodic_minimal_surfaces.cpp index 864dc9376ed..09f1a8b6d23 100644 --- a/Periodic_3_mesh_3/test/Periodic_3_mesh_3/test_triply_periodic_minimal_surfaces.cpp +++ b/Periodic_3_mesh_3/test/Periodic_3_mesh_3/test_triply_periodic_minimal_surfaces.cpp @@ -41,7 +41,7 @@ typedef CGAL::Periodic_3_mesh_triangulation_3::type Tr; typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Periodic_mesh_criteria; +typedef CGAL::Mesh_criteria_3 Periodic_mesh_criteria; // To avoid verbose function and named parameters call using namespace CGAL::parameters; diff --git a/Periodic_3_triangulation_3/include/CGAL/Periodic_3_regular_triangulation_3.h b/Periodic_3_triangulation_3/include/CGAL/Periodic_3_regular_triangulation_3.h index 957b73bec46..eac6aecdccb 100644 --- a/Periodic_3_triangulation_3/include/CGAL/Periodic_3_regular_triangulation_3.h +++ b/Periodic_3_triangulation_3/include/CGAL/Periodic_3_regular_triangulation_3.h @@ -780,7 +780,7 @@ class Periodic_3_regular_triangulation_3 // They do not check the validity of the mesh. void set_point(const Vertex_handle v, const Vector& move, - const Weighted_point& new_position) + const Weighted_point& new_position) const { Bare_point p = geom_traits().construct_point_3_object()(point(v)); Bare_point moved_p = p + move; diff --git a/Poisson_surface_reconstruction_3/examples/Poisson_surface_reconstruction_3/poisson_and_parallel_mesh_3.cpp b/Poisson_surface_reconstruction_3/examples/Poisson_surface_reconstruction_3/poisson_and_parallel_mesh_3.cpp index 2919545344c..435e4a0675b 100644 --- a/Poisson_surface_reconstruction_3/examples/Poisson_surface_reconstruction_3/poisson_and_parallel_mesh_3.cpp +++ b/Poisson_surface_reconstruction_3/examples/Poisson_surface_reconstruction_3/poisson_and_parallel_mesh_3.cpp @@ -47,7 +47,7 @@ void poisson_reconstruction(const PointSet& points, const char* output) typedef CGAL::Poisson_mesh_domain_3 Mesh_domain; typedef typename CGAL::Mesh_triangulation_3::type Tr; typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; - typedef CGAL::Mesh_criteria_3 Mesh_criteria; + typedef CGAL::Mesh_criteria_3 Mesh_criteria; // Poisson options FT sm_angle = 20.0; // Min triangle angle in degrees. diff --git a/Poisson_surface_reconstruction_3/examples/Poisson_surface_reconstruction_3/poisson_reconstruction.cpp b/Poisson_surface_reconstruction_3/examples/Poisson_surface_reconstruction_3/poisson_reconstruction.cpp index f731e9bf255..fae208fee05 100644 --- a/Poisson_surface_reconstruction_3/examples/Poisson_surface_reconstruction_3/poisson_reconstruction.cpp +++ b/Poisson_surface_reconstruction_3/examples/Poisson_surface_reconstruction_3/poisson_reconstruction.cpp @@ -59,7 +59,7 @@ typedef CGAL::Poisson_reconstruction_function Poisson_reconstruction_fun typedef CGAL::Poisson_mesh_domain_3 Mesh_domain; typedef typename CGAL::Mesh_triangulation_3::type Tr; typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; // AABB tree typedef CGAL::AABB_face_graph_triangle_primitive Primitive; diff --git a/Poisson_surface_reconstruction_3/examples/Poisson_surface_reconstruction_3/poisson_reconstruction_example.cpp b/Poisson_surface_reconstruction_3/examples/Poisson_surface_reconstruction_3/poisson_reconstruction_example.cpp index 4d4806a7d25..0a789977ac7 100644 --- a/Poisson_surface_reconstruction_3/examples/Poisson_surface_reconstruction_3/poisson_reconstruction_example.cpp +++ b/Poisson_surface_reconstruction_3/examples/Poisson_surface_reconstruction_3/poisson_reconstruction_example.cpp @@ -35,7 +35,7 @@ typedef CGAL::Poisson_reconstruction_function Poisson_reconstruction_fun typedef CGAL::Poisson_mesh_domain_3 Mesh_domain; typedef CGAL::Mesh_triangulation_3::type Tr; typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; int main(void) { 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 818445fa6ec..408282ee37a 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 @@ -21,13 +21,12 @@ #include // for min namespace CGAL { - namespace internal { namespace Poisson { template class Constant_sizing_field { - typedef typename Tr::FT FT; + typedef typename Tr::Geom_traits::FT FT; FT sq_radius_bound; public: FT cell_radius_bound() const { return CGAL::approximate_sqrt(sq_radius_bound); } 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 d74572244d6..cb2260bc01c 100644 --- a/Poisson_surface_reconstruction_3/include/CGAL/poisson_surface_reconstruction.h +++ b/Poisson_surface_reconstruction_3/include/CGAL/poisson_surface_reconstruction.h @@ -102,7 +102,7 @@ namespace CGAL { typedef CGAL::Poisson_mesh_domain_3 Mesh_domain; typedef typename CGAL::Mesh_triangulation_3::type Tr; typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; - typedef CGAL::Mesh_criteria_3 Mesh_criteria; + typedef CGAL::Mesh_criteria_3 Mesh_criteria; Poisson_reconstruction_function function(begin, end, point_map, normal_map); if ( ! function.compute_implicit_function() ) diff --git a/Poisson_surface_reconstruction_3/test/Poisson_surface_reconstruction_3/compare_mesh_3_vs_Poisson_implicit_surface_3.cpp b/Poisson_surface_reconstruction_3/test/Poisson_surface_reconstruction_3/compare_mesh_3_vs_Poisson_implicit_surface_3.cpp index cca1794d598..ee964dbbeb0 100644 --- a/Poisson_surface_reconstruction_3/test/Poisson_surface_reconstruction_3/compare_mesh_3_vs_Poisson_implicit_surface_3.cpp +++ b/Poisson_surface_reconstruction_3/test/Poisson_surface_reconstruction_3/compare_mesh_3_vs_Poisson_implicit_surface_3.cpp @@ -65,12 +65,12 @@ typedef CGAL::Surface_mesh_complex_2_in_triangulation_3 C2t3; typedef CGAL::Labeled_mesh_domain_3 LMesh_domain; typedef typename CGAL::Mesh_triangulation_3::type LTr; typedef CGAL::Mesh_complex_3_in_triangulation_3 LC3t3; -typedef CGAL::Mesh_criteria_3 LMesh_criteria; +typedef CGAL::Mesh_criteria_3 LMesh_criteria; typedef CGAL::Poisson_mesh_domain_3 Mesh_domain; typedef typename CGAL::Mesh_triangulation_3::type Tr; typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; struct Counter { diff --git a/Poisson_surface_reconstruction_3/test/Poisson_surface_reconstruction_3/poisson_reconstruction_test_mesh_3.cpp b/Poisson_surface_reconstruction_3/test/Poisson_surface_reconstruction_3/poisson_reconstruction_test_mesh_3.cpp index 720e3f4b18b..7d5a95f3f78 100644 --- a/Poisson_surface_reconstruction_3/test/Poisson_surface_reconstruction_3/poisson_reconstruction_test_mesh_3.cpp +++ b/Poisson_surface_reconstruction_3/test/Poisson_surface_reconstruction_3/poisson_reconstruction_test_mesh_3.cpp @@ -62,13 +62,13 @@ typedef CGAL::Poisson_reconstruction_function Poisson_reconstruction_fun typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; typedef CGAL::Mesh_triangulation_3::type Tr; typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; // Mesh_3 using Poisson_mesh_domain_3 typedef CGAL::Poisson_mesh_domain_3 Poisson_mesh_domain; typedef CGAL::Mesh_triangulation_3::type Poisson_Tr; typedef CGAL::Mesh_complex_3_in_triangulation_3 Poisson_C3t3; -typedef CGAL::Mesh_criteria_3 Poisson_mesh_criteria; +typedef CGAL::Mesh_criteria_3 Poisson_mesh_criteria; namespace params = CGAL::parameters; diff --git a/SMDS_3/doc/SMDS_3/Concepts/SimplicialMeshVertexBase_3.h b/SMDS_3/doc/SMDS_3/Concepts/SimplicialMeshVertexBase_3.h index 54283950ef6..72293e7f90b 100644 --- a/SMDS_3/doc/SMDS_3/Concepts/SimplicialMeshVertexBase_3.h +++ b/SMDS_3/doc/SMDS_3/Concepts/SimplicialMeshVertexBase_3.h @@ -68,7 +68,7 @@ bool is_c2t3_cache_valid(); /*! Sets the cache. */ -void set_c2t3_cache(std::size_t i, std::size_t j) +void set_c2t3_cache(int i, int j) /*! Invalidates the cache. @@ -78,14 +78,14 @@ void invalidate_c2t3_cache(); /*! Returns the cached number of facets of the complex incident to the vertex. */ -std::size_t cached_number_of_incident_facets(); +int cached_number_of_incident_facets(); /*! This method concerns the adjacency graph of the facets of the complex incident to the vertex and returns a cached value for the number of connected components this graph. */ -std::size_t cached_number_of_components(); +int cached_number_of_components(); /// @} diff --git a/SMDS_3/include/CGAL/IO/File_avizo.h b/SMDS_3/include/CGAL/IO/File_avizo.h index 027907afbd3..9ca029e2051 100644 --- a/SMDS_3/include/CGAL/IO/File_avizo.h +++ b/SMDS_3/include/CGAL/IO/File_avizo.h @@ -234,7 +234,7 @@ output_to_avizo(std::ostream& os, end = c3t3.cells_in_complex_end(); cit != end; ++cit) { - os << cit->subdomain_index() << "\n"; + os << c3t3.subdomain_index(cit) << "\n"; } } // end output_to_avizo(...) @@ -386,11 +386,11 @@ namespace internal { return false; } - template - bool read_tetra_am(std::istream& input, Tr& tr) + template + bool read_tetra_am(std::istream& input, C3T3& c3t3) { using Material_type = unsigned char; - using Point_3 = typename Tr::Geom_traits::Point_3; + using Point_3 = typename C3T3::Triangulation::Geom_traits::Point_3; int n_nodes, n_tets, n_edges; std::vector data; @@ -505,26 +505,28 @@ namespace internal { struct Edge_with_index { int v0, v1; - typename Tr::Triangulation_data_structure::Vertex::Index curve_index; + typename C3T3::Index curve_index; }; struct Corner_with_index { int v; - typename Tr::Triangulation_data_structure::Vertex::Index corner_index; + typename C3T3::Index corner_index; }; boost::unordered_map, - typename Tr::Cell::Surface_patch_index> empty_facets_map; + typename C3T3::Surface_patch_index> empty_facets_map; std::vector no_edges; std::vector no_corners; + std::vector no_vertices; - CGAL::SMDS_3::build_triangulation_with_subdomains_range(tr, + CGAL::SMDS_3::build_mesh_complex_with_subdomains_range(c3t3, points, tetrahedra, labels, empty_facets_map, no_edges, no_corners, + no_vertices, CGAL::Emptyset_iterator(), true,//verbose false,//replace subdomain 0 @@ -537,15 +539,15 @@ namespace internal { }// end namespace internal - template - bool read_AVIZO_TETRA(std::istream& in, T3& tr) + template + bool read_AVIZO_TETRA(std::istream& in, C3T3& c3t3) { if (!in) { std::cerr << "Cannot open file " << std::endl; return false; } - return CGAL::IO::internal::read_tetra_am(in, tr); + return CGAL::IO::internal::read_tetra_am(in, c3t3); } } // end namespace IO diff --git a/SMDS_3/include/CGAL/IO/File_medit.h b/SMDS_3/include/CGAL/IO/File_medit.h index 390742e2385..69e79aa4c13 100644 --- a/SMDS_3/include/CGAL/IO/File_medit.h +++ b/SMDS_3/include/CGAL/IO/File_medit.h @@ -17,27 +17,31 @@ #include #include -#include +#include #include #include -#include #include -#include #include +#include +#include +#include +#include +#include #include +#include #include #include #include #include +#include #include #include #include #include #include -#include //for std::visit namespace CGAL { @@ -352,7 +356,7 @@ class Default_vertex_pmap return r_c3t3_.corner_index(vh); else return 0; - } + } friend int get(const Default_vertex_pmap& vmap, const Vertex_handle& vh) { @@ -440,119 +444,7 @@ struct Medit_pmap_generator -bool build_triangulation_from_file(std::istream& is, - Tr& tr, - const bool verbose, - const bool replace_domain_0, - const bool allow_non_manifold, - const bool allow_negative_orientation, - CxEdgesOutputIterator cx_edges_oit) -{ - using Point_3 = typename Tr::Point; - using Subdomain_index = typename Tr::Cell::Subdomain_index; - using Surface_patch_index = typename Tr::Cell::Surface_patch_index; - - using Edge = std::array; - using Facet = std::array; // 3 = id - using Tet = std::array; // 4 = id - - using Edge_with_index = CGAL::IO::internal::Edge_with_curve_index; - using Corner_with_index = CGAL::IO::internal::Vertex_with_corner_index; - - std::vector finite_cells; - std::vector subdomains; - std::vector points; - - std::vector facets; - std::vector edges; - std::vector corners, facet_refs, edge_refs, point_refs; - std::vector ignored_ridges; - - bool is_CGAL_mesh = false; - - if(verbose){ - std::cout << "Reading .mesh file..." << std::endl; - std::cout << "Replace domain #0 = " << replace_domain_0 << std::endl; - std::cout << "Allow non-manifoldness = " << allow_non_manifold << std::endl; - } - - bool ok = CGAL::IO::internal::read_MEDIT(is, points, finite_cells, - facets, true, - edges, true, - ignored_ridges, false, - corners, true, - point_refs, true, - subdomains, true, - facet_refs, true, - edge_refs, true, - verbose, - is_CGAL_mesh); - if(!ok){ - return false; - } - - std::vector edge_indices; - edge_indices.reserve(edges.size()); - for(std::size_t i = 0; i < edges.size(); ++i){ - Edge_with_index ewi; - ewi.v0 = edges[i][0]; - ewi.v1 = edges[i][1]; - ewi.curve_index = edge_refs[i]; - edge_indices.emplace_back(ewi); - } - - std::vector corner_indices; - corner_indices.reserve(corners.size()); - for(std::size_t i = 0; i < corners.size(); ++i){ - Corner_with_index cwi; - cwi.v = corners[i]; - cwi.corner_index = point_refs[i]; - corner_indices.emplace_back(cwi); - } - - boost::unordered_map border_facets; - border_facets.reserve(facets.size()); - - bool has_negative_surface_patch_ids = false; - int max_surface_patch_id{0}; - - for (std::size_t i = 0; i < facets.size(); ++i) - { - if (facet_refs[i] < 0) - has_negative_surface_patch_ids=true; - else if(facet_refs[i] > max_surface_patch_id) - max_surface_patch_id= facet_refs[i]; - border_facets.emplace(facets[i], facet_refs[i]); - } - - if(has_negative_surface_patch_ids) - { - if(verbose) - std::cerr << "Warning: negative surface patch ids" << std::endl; - for(auto& facet_and_patch_id : border_facets) { - if(facet_and_patch_id.second < 0) - facet_and_patch_id.second = max_surface_patch_id - facet_and_patch_id.second; - } - } - - if(!is_CGAL_mesh) - tr.may_have_badly_oriented_cells(true); - - return build_triangulation_with_subdomains_range(tr, - points, finite_cells, subdomains, border_facets, - edge_indices, - corner_indices, - cx_edges_oit, - verbose, - replace_domain_0 && !is_CGAL_mesh, - allow_non_manifold, - allow_negative_orientation); -return true; -} +CGAL_GENERATE_MEMBER_DETECTOR(meshing_info); // check if the vertex is a model of MeshVertexBase_3 template ())>::type>::value; + std::unordered_map V; int inum = 1; std::ostringstream oss; oss.precision(os.precision()); - for(auto v: vertices) { - auto& v_num = V[v]; - if(v_num != 0) return; - v_num = inum++; + // Assign unique ids to all vertices in the range, just like the map + for(auto v : vertices) { + if constexpr (use_meshing_info) { + v->set_meshing_info(inum++); + } else { + V[v] = inum++; + } + const auto& p = tr.point(v); oss << CGAL::to_double(p.x()) << ' ' << CGAL::to_double(p.y()) << ' ' @@ -612,7 +511,15 @@ output_to_medit(std::ostream& os, << get(vertex_pmap, v) << '\n'; } - os << "Vertices\n" << V.size() << "\n"; + auto vertex_index = [&](const Vertex_handle& v) { + constexpr bool use_meshing_info = + has_meshing_info())>::type>::value; + if constexpr (use_meshing_info) + return v->meshing_info(); + else + return V.at(v); + }; + os << "Vertices\n" << inum - 1 << "\n"; os << oss.str(); //------------------------------------------------------- @@ -630,23 +537,22 @@ output_to_medit(std::ostream& os, auto [c, index] = f; // Apply priority among subdomains, to get consistent facet orientation per subdomain-pair interface. if (print_each_facet_twice) { - auto mirror_facet = tr.mirror_facet(f); - [[maybe_unused]] auto [c2, _] = mirror_facet; + auto n = c->neighbor(index); // NOTE: We mirror a facet when needed to make it consistent with Use_cell_indices_pmap. - if (get(cell_pmap, c) > get(cell_pmap, c2)) { - f = mirror_facet; + if (get(cell_pmap, c) > get(cell_pmap, n)) { + f = {n, n->index(c)}; } } // Get facet vertices in CCW order. auto [vh1, vh2, vh3] = tr.vertices(f); - os << V[vh1] << ' ' << V[vh2] << ' ' << V[vh3] << ' '; + os << vertex_index(vh1) << ' ' << vertex_index(vh2) << ' ' << vertex_index(vh3) << ' '; os << get(facet_pmap, f) << '\n'; // Print triangle again if needed, with opposite orientation if (print_each_facet_twice) { - os << V[vh3] << ' ' << V[vh2] << ' ' << V[vh1] << ' '; + os << vertex_index(vh3) << ' ' << vertex_index(vh2) << ' ' << vertex_index(vh1) << ' '; os << get(facet_twice_pmap, f) << '\n'; } } @@ -657,8 +563,9 @@ output_to_medit(std::ostream& os, os << "Tetrahedra\n" << size(cells) << '\n'; for (const auto& c : cells) { - for (auto v : tr.vertices(c)) - os << V[v] << ' '; + for (auto v : tr.vertices(c)) { + os << vertex_index(v) << ' '; + } os << get(cell_pmap, c) << '\n'; } @@ -674,7 +581,7 @@ output_to_medit(std::ostream& os, os << "Corners\n" << size(corners) << '\n'; for(const auto& v : corners) { - os << V[v] << '\n'; + os << vertex_index(v) << '\n'; } //------------------------------------------------------- @@ -690,7 +597,7 @@ output_to_medit(std::ostream& os, auto index = (vh1->in_dimension() == 1) ? vh1->index() : (vh2->in_dimension() == 1 ? vh2->index() : 42 /*todo : magic id*/); - os << V[vh1] << ' ' << V[vh2] << ' '; + os << vertex_index(vh1) << ' ' << vertex_index(vh2) << ' '; os << IO::oformat(index); os << '\n'; } @@ -710,7 +617,6 @@ output_to_medit(std::ostream& os, } // end output_to_medit(...) - template ())>::type>::value; + std::unordered_map V; int inum = 1; std::ostringstream oss; oss.precision(os.precision()); - for(auto v: vertices) { - auto& v_num = V[v]; - if(v_num != 0) return; - v_num = inum++; + + // Assign unique ids to all vertices in the range, just like the map + for(auto v : vertices) { + if constexpr (use_meshing_info) { + v->set_meshing_info(inum++); + } else { + V[v] = inum++; + } + const auto& p = tr.point(v); oss << CGAL::to_double(p.x()) << ' ' << CGAL::to_double(p.y()) << ' ' @@ -758,7 +672,7 @@ output_T3_to_medit(std::ostream& os, << 0 << '\n'; } - os << "Vertices\n" << V.size() << "\n"; + os << "Vertices\n" << inum - 1 << "\n"; os << oss.str(); @@ -980,7 +894,7 @@ void write_MEDIT(std::ostream& os, using parameters::get_parameter; using parameters::choose_parameter; - bool renumber_subdomain_indices = choose_parameter(get_parameter(np, internal_np::rebind_labels), false);; + bool renumber_subdomain_indices = choose_parameter(get_parameter(np, internal_np::rebind_labels), false); bool show_patches = choose_parameter(get_parameter(np, internal_np::show_patches), true); bool all_c = choose_parameter(get_parameter(np, internal_np::all_cells), true); bool all_v = all_c || choose_parameter(get_parameter(np, internal_np::all_vertices), true); @@ -1050,13 +964,13 @@ template void write_MEDIT(std::ostream& os, - const CGAL::Mesh_complex_3_in_triangulation_3& c3t3, - const NamedParameters& np = parameters::default_values()) + const CGAL::Mesh_complex_3_in_triangulation_3& c3t3, + const NamedParameters& np = parameters::default_values()) { - using parameters::choose_parameter; using parameters::get_parameter; + using parameters::choose_parameter; - bool renumber_subdomain_indices = choose_parameter(get_parameter(np, internal_np::rebind_labels), false); + bool renumber_subdomain_indices = choose_parameter(get_parameter(np, internal_np::rebind_labels), false);; bool show_patches = choose_parameter(get_parameter(np, internal_np::show_patches), true); bool all_c = choose_parameter(get_parameter(np, internal_np::all_cells), true); bool all_v = all_c || choose_parameter(get_parameter(np, internal_np::all_vertices), true); @@ -1208,12 +1122,12 @@ bool read_MEDIT(std::istream& in, }; std::vector cx_edges; - bool built = CGAL::SMDS_3::build_triangulation_from_file(in, c3t3.triangulation(), - verbose, - false /*replace_domain_0*/, - non_manifold, - negative_allowed, - std::back_inserter(cx_edges)); + bool built = CGAL::SMDS_3::build_mesh_complex_from_file(in, c3t3, + verbose, + false /*replace_domain_0*/, + non_manifold, + negative_allowed, + std::back_inserter(cx_edges)); if(!built) { c3t3.triangulation().clear(); diff --git a/SMDS_3/include/CGAL/IO/output_to_vtu.h b/SMDS_3/include/CGAL/IO/output_to_vtu.h index 24506adc687..da9b6b2308b 100644 --- a/SMDS_3/include/CGAL/IO/output_to_vtu.h +++ b/SMDS_3/include/CGAL/IO/output_to_vtu.h @@ -388,7 +388,7 @@ void output_to_vtu(std::ostream& os, std::vector mids; for( Cell_handle c : c3t3.cells_in_complex()) { - mids.push_back(c->subdomain_index()); + mids.push_back(c3t3.subdomain_index(c)); } std::vector > atts; diff --git a/SMDS_3/include/CGAL/Mesh_complex_3_in_triangulation_3.h b/SMDS_3/include/CGAL/Mesh_complex_3_in_triangulation_3.h index 08738342212..e49041ab296 100644 --- a/SMDS_3/include/CGAL/Mesh_complex_3_in_triangulation_3.h +++ b/SMDS_3/include/CGAL/Mesh_complex_3_in_triangulation_3.h @@ -22,13 +22,20 @@ #include #include -#include #include #include -#include +#include #include +#include +#include +#include +#include +#include +#include +#include #include -#include +#include +#include #include #include @@ -36,65 +43,66 @@ #include #include #include +#include +#include +#include #include +#include +#include #include #include #include #include +#include #include -#include - +#include +#include +#include #ifdef CGAL_LINKED_WITH_TBB -#include #include +#include +#endif namespace CGAL { - template < class DSC, bool Const > - std::size_t tbb_hasher(const CGAL::internal::CC_iterator& it) +namespace SMDS_3 { +namespace details { + +struct Pair_hash +{ + template + std::size_t operator()(const std::pair& p) const { - return CGAL::internal::hash_value(it); + return boost::hash >()(p); } - // As Marc Glisse pointed out the TBB hash of a std::pair is - // simplistic and leads to the - // TBB Warning: Performance is not optimal because the hash function - // produces bad randomness in lower bits in class - // tbb::interface5::concurrent_hash_map - template < class DSC, bool Const > - std::size_t tbb_hasher(const std::pair, - CGAL::internal::CC_iterator >& p) + template + std::size_t hash(const Pair& p) const { - return boost::hash, - CGAL::internal::CC_iterator > >()(p); + return this->operator()(p); } - struct Hash_compare_for_TBB { - template < class DSC, bool Const > - std::size_t hash(const std::pair, - CGAL::internal::CC_iterator >& p) const - { - return tbb_hasher(p); - } - template < class DSC, bool Const > - std::size_t operator()(const CGAL::internal::CC_iterator& it) - { - return CGAL::internal::hash_value(it); - } - template - bool equal(const T& v1, const T& v2) const { - return v1 == v2; - } - }; -}//end namespace CGAL -#endif - -namespace CGAL { + template + bool equal(const T& v1, const T& v2) const { + return v1 == v2; + } +}; - namespace SMDS_3 { +template +struct Hash_map_of_pairs_type +{ + typedef CGAL::unordered_flat_map type; +}; - namespace details { +#ifdef CGAL_LINKED_WITH_TBB +template +struct Hash_map_of_pairs_type +{ + typedef tbb::concurrent_hash_map type; +}; +#endif template class C3t3_helper_class @@ -129,8 +137,8 @@ namespace CGAL { } }; // end class template C3t3_helper_class - } // end namespace SMDS_3::details - } //end namespace SMDS_3 +} // namespace details +} // namespace SMDS_3 /*! \ingroup PkgSMDS3Classes @@ -207,7 +215,10 @@ class Mesh_complex_3_in_triangulation_3 /// @{ typedef Tr Triangulation; typedef typename Tr::size_type size_type; + + typedef typename Tr::Geom_traits::Point_3 Bare_point; typedef typename Tr::Point Point; + typedef typename Tr::Edge Edge; typedef typename Tr::Facet Facet; typedef typename Tr::Vertex_handle Vertex_handle; @@ -234,6 +245,18 @@ class Mesh_complex_3_in_triangulation_3 typedef CurveIndex Curve_index; /// @} + struct Facet_prop + { + Surface_patch_index surface_index_; + Index center_index_; + Bare_point center_; + }; + + // in the configuration of a cell base still providing surface pathc info storage + // (i.e., index, center, center index), use that instead of the C3T3 hash map + CGAL_GENERATE_MEMBER_DETECTOR(set_surface_patch_index); + static constexpr bool store_surface_patch_info_in_cell = + has_set_surface_patch_index::value; private: // Type to store the edges: @@ -257,6 +280,8 @@ class Mesh_complex_3_in_triangulation_3 typedef std::vector Far_vertices_vec; public: + using Store_surface_patch_info_in_cell = Boolean_tag; + enum Face_status { NOT_IN_COMPLEX = 0, ISOLATED = 1, // - An ISOLATED edge is a marked edge, @@ -315,6 +340,8 @@ class Mesh_complex_3_in_triangulation_3 tr_.swap(rhs.tr_); swapper(rhs.number_of_cells_, number_of_cells_); + surface_facet_info_.swap(rhs.surface_facet_info_); + edges_.swap(rhs.edges_); corners_.swap(rhs.corners_); far_vertices_.swap(rhs.far_vertices_); @@ -325,7 +352,7 @@ class Mesh_complex_3_in_triangulation_3 /// \name Access Functions /// @{ /// returns a const reference to the triangulation - const Triangulation& triangulation() const { return tr_; } + const Triangulation& triangulation() const & { return tr_; } /// @} #ifndef DOXYGEN_RUNNING @@ -337,7 +364,9 @@ class Mesh_complex_3_in_triangulation_3 /// rebuilding critical C3T3 information such as the number of simplexes in complex. /// On the other hand, this is performed by `set_triangulation()` /// \cgalAdvancedEnd - Triangulation& triangulation() { return tr_; } + Triangulation& triangulation() & { return tr_; } + + Triangulation&& triangulation() && { return std::move(tr_); } /// @} #endif @@ -475,24 +504,159 @@ class Mesh_complex_3_in_triangulation_3 { vertex->set_index(index); } - /** sets the surface index of facet \p facet to \p index + + /** sets the surface index of facet \p f to \p index */ - void set_surface_patch_index(const Facet& f, const Surface_patch_index& index) + void set_surface_patch_index(const Facet& f, + const Surface_patch_index& index) const { - set_surface_patch_index(f.first, f.second, index); + if constexpr (store_surface_patch_info_in_cell) + { + f.first->set_surface_patch_index(f.second, index); + } + else + { + if (index == Surface_patch_index()) + { + // remove from the map as to avoid wasting memory + surface_facet_info_.erase(f); + } + else + { +#ifdef CGAL_LINKED_WITH_TBB + if constexpr (std::is_same_v) + { + typename Surface_facet_info::accessor accessor; + surface_facet_info_.insert(accessor, f); + accessor->second.surface_index_ = index; + } + else +#endif + { + surface_facet_info_[f].surface_index_ = index; + } + } + } } + /** sets the surface index of facet(\p cell, \p i) to \p index */ void set_surface_patch_index(const Cell_handle& cell, - const int i, - const Surface_patch_index& index) const + const int i, + const Surface_patch_index& index) const { - cell->set_surface_patch_index(i, index); + return set_surface_patch_index(Facet(cell, i), index); } + + void set_surface_center(const Facet& f, + const Bare_point& p) const + { + if constexpr (store_surface_patch_info_in_cell) + { + f.first->set_facet_surface_center(f.second, p); + } + else + { +#ifdef CGAL_LINKED_WITH_TBB + if constexpr (std::is_same_v) + { + typename Surface_facet_info::accessor accessor; + surface_facet_info_.insert(accessor, f); + accessor->second.center_ = p; + } + else +#endif + { + surface_facet_info_[f].center_ = p; + } + } + } + + /** sets the surface center of facet(\p cell, \p i) to \p p + */ + void set_surface_center(const Cell_handle& cell, + const int i, + const Bare_point& p) const + { + return set_surface_center(Facet(cell, i), p); + } + + void set_surface_center_index(const Facet& f, + const Index& index) const + { + if constexpr (store_surface_patch_info_in_cell) + { + f.first->set_facet_surface_center_index(f.second, index); + } + else + { +#ifdef CGAL_LINKED_WITH_TBB + if constexpr (std::is_same_v) + { + typename Surface_facet_info::accessor accessor; + surface_facet_info_.insert(accessor, f); + accessor->second.center_index_ = index; + } + else +#endif + { + surface_facet_info_[f].center_index_ = index; + } + } + } + + /** sets the surface center index of facet(\p cell, \p i) to \p index + */ + void set_surface_center_index(const Cell_handle& cell, + const int i, + const Index& index) const + { + return set_surface_center_index(Facet(cell, i), index); + } + + void set_surface_info(const Facet& f, + const Facet_prop& info) const + { + if constexpr (store_surface_patch_info_in_cell) + { + f.first->set_surface_patch_index(f.second, info.surface_index_); + f.first->set_facet_surface_center(f.second, info.center_); + f.first->set_facet_surface_center_index(f.second, info.center_index_); + } + else + { + if (info.surface_index_ == Surface_patch_index()) + { + surface_facet_info_.erase(f); + } + else + { +#ifdef CGAL_LINKED_WITH_TBB + if constexpr (std::is_same_v) + { + typename Surface_facet_info::accessor accessor; + surface_facet_info_.insert(accessor, f); + accessor->second = info; + } + else +#endif + { + surface_facet_info_[f] = info; + } + } + } + } + + void set_surface_info(const Cell_handle& cell, int i, + const Facet_prop& info) const + { + return set_surface_info(Facet(cell, i), info); + } + /** sets the subdomain index of cell \p cell to \p index */ void set_subdomain_index(const Cell_handle& cell, - const Subdomain_index& index) const + const Subdomain_index& index) const { cell->set_subdomain_index(index); } @@ -520,7 +684,29 @@ class Mesh_complex_3_in_triangulation_3 */ Surface_patch_index surface_patch_index(const Facet& f) const { - return surface_patch_index(f.first, f.second); + if constexpr (store_surface_patch_info_in_cell) + { + return f.first->surface_patch_index(f.second); + } + else + { +#ifdef CGAL_LINKED_WITH_TBB + if constexpr (std::is_same_v) + { + typename Surface_facet_info::const_accessor accessor; + if (surface_facet_info_.find(accessor, f)) + return accessor->second.surface_index_; + } + else +#endif + { + auto it = surface_facet_info_.find(f); + if (it != surface_facet_info_.end()) + return it->second.surface_index_; + } + } + + return Surface_patch_index(); } /** returns the surface index of facet(\p cell, \p i) @@ -528,8 +714,112 @@ class Mesh_complex_3_in_triangulation_3 Surface_patch_index surface_patch_index(const Cell_handle& cell, const int i) const { - return cell->surface_patch_index(i); + return surface_patch_index(Facet(cell, i)); + } + + decltype(auto) surface_center(const Facet& f) const + { + CGAL_precondition(is_in_complex(f)); + + if constexpr (store_surface_patch_info_in_cell) + { + return f.first->get_facet_surface_center(f.second); + } + else + { +# ifdef CGAL_LINKED_WITH_TBB + if constexpr (std::is_same_v) + { + typename Surface_facet_info::const_accessor accessor; + CGAL_assume_code(bool found =) + surface_facet_info_.find(accessor, f); + CGAL_assume(found); + return accessor->second.center_; + } + else +#endif + { + auto it = surface_facet_info_.find(f); + CGAL_assume(it != surface_facet_info_.end()); + return it->second.center_; + } + } + } + + /** returns the surface center of facet(\p cell, \p i) + */ + decltype(auto) surface_center(const Cell_handle& cell, + const int i) const + { + return surface_center(Facet(cell, i)); } + + Index surface_center_index(const Facet& f) const + { + CGAL_precondition(is_in_complex(f)); + + if constexpr (store_surface_patch_info_in_cell) + { + return f.first->get_facet_surface_center_index(f.second); + } + else + { +#ifdef CGAL_LINKED_WITH_TBB + if constexpr (std::is_same_v) + { + typename Surface_facet_info::const_accessor accessor; + CGAL_assume_code(bool found =) + surface_facet_info_.find(accessor, f); + CGAL_assume(found); + return accessor->second.center_index_; + } + else +#endif + { + auto it = surface_facet_info_.find(f); + CGAL_assume(it != surface_facet_info_.end()); + return it->second.center_index_; + } + } + } + + /** returns the surface center index of facet(\p cell, \p i) + */ + Index surface_center_index(const Cell_handle& cell, + const int i) const + { + return surface_center_index(Facet(cell, i)); + } + + decltype(auto) surface_info(const Facet& f) const + { + if constexpr (store_surface_patch_info_in_cell) + { + return Facet_prop{ f.first->surface_patch_index(f.second), + f.first->get_facet_surface_center_index(f.second), + f.first->get_facet_surface_center(f.second) }; + } + else + { +#ifdef CGAL_LINKED_WITH_TBB + if constexpr (std::is_same_v) + { + typename Surface_facet_info::const_accessor accessor; + CGAL_assume_code(bool found =) + surface_facet_info_.find(accessor, f); + CGAL_assume(found); + return accessor->second; + } + else +#endif + { + auto it = surface_facet_info_.find(f); + CGAL_assume(it != surface_facet_info_.end()); + return it->second; + } + } + } + /** returns the dimension of the lowest dimensional face of the input 3D * complex that contains the vertex */ @@ -594,11 +884,24 @@ class Mesh_complex_3_in_triangulation_3 far_vertices_.push_back(vh); } - void remove_isolated_vertex(Vertex_handle v) { Triangulation& tr = triangulation(); + std::vector old_cells; + old_cells.reserve(32); + tr.incident_cells(v, std::back_inserter(old_cells)); + + for (const Cell_handle& c : old_cells) + { + remove_from_complex(c); + for (int i = 0; i < 4; ++i) { + // Do *not* call the C3T3's remove_from_complex() because the information + // on the opposite facet must not be cleared for boundary facets. + set_surface_patch_index(c, i, Surface_patch_index()); + } + } + std::vector new_cells; new_cells.reserve(32); tr.remove_and_give_new_cells(v, std::back_inserter(new_cells)); @@ -613,10 +916,8 @@ class Mesh_complex_3_in_triangulation_3 Facet mirror_facet = tr.mirror_facet(std::make_pair(c, i)); if (is_in_complex(mirror_facet)) { - set_surface_patch_index(c, i, - surface_patch_index(mirror_facet)); - c->set_facet_surface_center(i, - mirror_facet.first->get_facet_surface_center(mirror_facet.second)); + set_surface_patch_index(c, i, surface_patch_index(mirror_facet)); + set_surface_center(c, i, surface_center(mirror_facet.first, mirror_facet.second)); } } /*int i_inf; @@ -624,10 +925,7 @@ class Mesh_complex_3_in_triangulation_3 { Facet mirror_facet = tr.mirror_facet(std::make_pair(c, i_inf)); if (is_in_complex(mirror_facet)) - { - set_surface_patch_index(c, i_inf, - surface_patch_index(mirror_facet)); - } + set_surface_patch_index(c, i_inf, surface_patch_index(mirror_facet)); }*/ } } @@ -679,7 +977,7 @@ class Mesh_complex_3_in_triangulation_3 for (Facet f :this->facets_in_complex()) { - for (int i = 1; i < 4; ++i) + for (int i = 1; i < 4; ++i) { Vertex_handle vi = f.first->vertex((f.second + i) % 4); vi->set_meshing_info(vi->meshing_info() + 1); @@ -771,19 +1069,20 @@ class Mesh_complex_3_in_triangulation_3 { return !(subdomain_index(cell) == Subdomain_index()); } - /** returns true if facet \p facet belongs to the 2D complex + /** returns true if facet \p f belongs to the 2D complex */ - bool is_in_complex(const Facet& facet) const + bool is_in_complex(const Facet& f) const { - return is_in_complex(facet.first, facet.second); + return !(surface_patch_index(f) == Surface_patch_index()); } /** returns true if facet (\p cell, \p i) belongs to the 2D complex */ bool is_in_complex(const Cell_handle& cell, const int i) const { - return (cell->is_facet_on_surface(i)); + return is_in_complex(Facet(cell, i)); } + /** * returns true if edge \p e belongs to the 1D complex */ @@ -1296,7 +1595,7 @@ class Mesh_complex_3_in_triangulation_3 Face_status face_status(const Vertex_handle v) const { if (!manifold_info_initialized_) init_manifold_info(); - const std::size_t n = v->cached_number_of_incident_facets(); + const int n = v->cached_number_of_incident_facets(); if (n == 0) return NOT_IN_COMPLEX; @@ -1328,7 +1627,7 @@ class Mesh_complex_3_in_triangulation_3 } // From here all incident edges (in complex) are REGULAR or BOUNDARY. - const std::size_t nb_components = union_find_of_incident_facets(v); + const int nb_components = union_find_of_incident_facets(v); if (nb_components > 1) { #ifdef CGAL_MESHES_DEBUG_REFINEMENT_POINTS std::cerr << "singular vertex: nb_components=" << nb_components << std::endl; @@ -1364,19 +1663,29 @@ class Mesh_complex_3_in_triangulation_3 if (!manifold_info_initialized_) init_manifold_info(); #ifdef CGAL_LINKED_WITH_TBB - typename Edge_facet_counter::const_accessor accessor; - if (!edge_facet_counter_.find(accessor, - this->make_ordered_pair(edge))) - return NOT_IN_COMPLEX; - switch (accessor->second) -#else // not CGAL_LINKED_WITH_TBB - switch (edge_facet_counter_[this->make_ordered_pair(edge)]) -#endif // not CGAL_LINKED_WITH_TBB + if constexpr (std::is_same_v) + { + typename Edge_facet_counter::const_accessor accessor; + if (!edge_facet_counter_.find(accessor, this->make_ordered_pair(edge))) + return NOT_IN_COMPLEX; + switch (accessor->second) + { + case 0: return NOT_IN_COMPLEX; + case 1: return BOUNDARY; + case 2: return REGULAR; + default: return SINGULAR; + } + } + else +#endif { - case 0: return NOT_IN_COMPLEX; - case 1: return BOUNDARY; - case 2: return REGULAR; - default: return SINGULAR; + switch (edge_facet_counter_[this->make_ordered_pair(edge)]) + { + case 0: return NOT_IN_COMPLEX; + case 1: return BOUNDARY; + case 2: return REGULAR; + default: return SINGULAR; + } } } @@ -1559,7 +1868,7 @@ class Mesh_complex_3_in_triangulation_3 end = triangulation().finite_vertices_end(); vit != end; ++vit) { - vit->set_c2t3_cache(0, (std::numeric_limits::max)()); + vit->set_c2t3_cache(0, -1); } edge_facet_counter_.clear(); @@ -1578,19 +1887,21 @@ class Mesh_complex_3_in_triangulation_3 const int edge_index_vb = tr_.vertex_triple_index(i, (j == 2) ? 0 : (j + 1)); const Vertex_handle edge_va = cell->vertex(edge_index_va); const Vertex_handle edge_vb = cell->vertex(edge_index_vb); -#ifndef CGAL_LINKED_WITH_TBB - ++edge_facet_counter_[this->make_ordered_pair(edge_va, edge_vb)]; -#else // CGAL_LINKED_WITH_TBB +#ifdef CGAL_LINKED_WITH_TBB + if constexpr (std::is_same_v) { typename Edge_facet_counter::accessor accessor; - edge_facet_counter_.insert(accessor, - this->make_ordered_pair(edge_va, edge_vb)); + edge_facet_counter_.insert(accessor, this->make_ordered_pair(edge_va, edge_vb)); ++accessor->second; } -#endif // CGAL_LINKED_WITH_TBB + else +#endif + { + ++edge_facet_counter_[this->make_ordered_pair(edge_va, edge_vb)]; + } - const std::size_t n = edge_va->cached_number_of_incident_facets(); - edge_va->set_c2t3_cache(n + 1, (std::numeric_limits::max)()); + const int n = edge_va->cached_number_of_incident_facets(); + edge_va->set_c2t3_cache(n + 1, -1); } } } @@ -1599,12 +1910,12 @@ class Mesh_complex_3_in_triangulation_3 /// Extract the subset `F` of facets of the complex incident to `v` and /// return the number of connected component of the adjacency graph of `F`. - std::size_t union_find_of_incident_facets(const Vertex_handle v) const + int union_find_of_incident_facets(const Vertex_handle v) const { if (v->is_c2t3_cache_valid()) { - const std::size_t n = v->cached_number_of_components(); - if (n != (std::numeric_limits::max)()) return n; + const int n = v->cached_number_of_components(); + if (n != -1) return n; } Union_find facets; @@ -1652,10 +1963,11 @@ class Mesh_complex_3_in_triangulation_3 } } } - const std::size_t nb_components = facets.number_of_sets(); - const std::size_t n = v->cached_number_of_incident_facets(); + const int n = v->cached_number_of_incident_facets(); + const int nb_components = static_cast(facets.number_of_sets()); v->set_c2t3_cache(n, nb_components); + return nb_components; } @@ -1722,16 +2034,20 @@ class Mesh_complex_3_in_triangulation_3 // Private data members Triangulation tr_; +private: typedef typename Base::Pair_of_vertices Pair_of_vertices; -#ifdef CGAL_LINKED_WITH_TBB - typedef tbb::concurrent_hash_map Edge_facet_counter; -#else // not CGAL_LINKED_WITH_TBB - typedef std::map Edge_facet_counter; -#endif // not CGAL_LINKED_WITH_TBB - + typedef typename SMDS_3::details::Hash_map_of_pairs_type::type Edge_facet_counter; mutable Edge_facet_counter edge_facet_counter_; +public: // @tmp + typedef typename SMDS_3::details::Hash_map_of_pairs_type::type Surface_facet_info; + mutable Surface_facet_info surface_facet_info_; + +private: typename Number_of_elements::type number_of_facets_; typename Number_of_elements::type number_of_cells_; @@ -1808,6 +2124,72 @@ Mesh_complex_3_in_triangulation_3(const Self& rhs) } CGAL_assertion(far_vertices_.size() == rhs.far_vertices_.size()); } + + for (const auto& e : rhs.surface_facet_info_) + { + auto get_this_vertex = [&](const Cell_handle& rhs_c, const int rhs_o) -> Vertex_handle { + if (rhs.triangulation().is_infinite(rhs_c->vertex(rhs_o))) { + return this->triangulation().infinite_vertex(); + } else { + const auto& rhs_p = rhs.triangulation().point(rhs_c, rhs_o); + Vertex_handle this_vh; + CGAL_assertion_code(bool found =) + this->triangulation().is_vertex(rhs_p, this_vh); + CGAL_assertion(found); + return this_vh; + } + }; + + // Find the corresponding facet in 'this' + const Facet& rhs_facet = e.first; + const Cell_handle& rhs_c = rhs_facet.first; + const int rhs_i = rhs_facet.second; + + Vertex_handle rhs_nv[5]; + rhs_nv[0] = get_this_vertex(rhs_c, rhs_i); + rhs_nv[1] = get_this_vertex(rhs_c, (rhs_i + 1) % 4); + rhs_nv[2] = get_this_vertex(rhs_c, (rhs_i + 2) % 4); + rhs_nv[3] = get_this_vertex(rhs_c, (rhs_i + 3) % 4); + + Cell_handle rhs_n = rhs_c->neighbor(rhs_i); + rhs_nv[4] = get_this_vertex(rhs_n, rhs_n->index(rhs_c)); + + Cell_handle this_cell; + CGAL_assertion_code(bool found =) + this->triangulation().is_cell(rhs_nv[0], rhs_nv[1], rhs_nv[2], rhs_nv[3], this_cell); + CGAL_assertion(found); + + Cell_handle this_n; + CGAL_assertion_code(found =) + this->triangulation().is_cell(rhs_nv[1], rhs_nv[2], rhs_nv[3], rhs_nv[4], this_n); + CGAL_assertion(found); + + const int this_opp = this_cell->index(this_n); + const Facet this_facet(this_cell, this_opp); + + // std::cout << "from rhs:\n"; + // std::cout << " facet: " << rhs.triangulation().point(rhs_c, (rhs_i + 1) % 4) << ", " + // << rhs.triangulation().point(rhs_c, (rhs_i + 2) % 4) << ", " + // << rhs.triangulation().point(rhs_c, (rhs_i + 3) % 4) << "\n"; + // std::cout << "to this:\n"; + // std::cout << " facet: " << this->triangulation().point(this_cell, (this_opp + 1) % 4) << ", " + // << this->triangulation().point(this_cell, (this_opp + 2) % 4) << ", " + // << this->triangulation().point(this_cell, (this_opp + 3) % 4) << "\n"; + +#ifdef CGAL_LINKED_WITH_TBB + if constexpr (std::is_same_v) + { + typename Surface_facet_info::accessor accessor; + surface_facet_info_.insert(accessor, this_facet); + accessor->second = e.second; + } + else +#endif + { + surface_facet_info_[this_facet] = e.second; + } + } + CGAL_postcondition(surface_facet_info_.size() == rhs.surface_facet_info_.size()); } template @@ -1816,6 +2198,7 @@ Mesh_complex_3_in_triangulation_3(Self&& rhs) : Base() , tr_(std::move(rhs.tr_)) , edge_facet_counter_(std::move(rhs.edge_facet_counter_)) + , surface_facet_info_(std::move(rhs.surface_facet_info_)) , manifold_info_initialized_(std::exchange(rhs.manifold_info_initialized_, false)) , edges_(std::move(rhs.edges_)) , corners_(std::move(rhs.corners_)) @@ -1946,18 +2329,20 @@ add_to_complex(const Cell_handle& cell, Vertex_handle edge_va = cell->vertex(edge_index_va); Vertex_handle edge_vb = cell->vertex(edge_index_vb); #ifdef CGAL_LINKED_WITH_TBB + if constexpr (std::is_same_v) { typename Edge_facet_counter::accessor accessor; - edge_facet_counter_.insert(accessor, - this->make_ordered_pair(edge_va, edge_vb)); + edge_facet_counter_.insert(accessor, this->make_ordered_pair(edge_va, edge_vb)); ++accessor->second; } -#else // not CGAL_LINKED_WITH_TBB - ++edge_facet_counter_[this->make_ordered_pair(edge_va, edge_vb)]; -#endif // not CGAL_LINKED_WITH_TBB + else +#endif + { + ++edge_facet_counter_[this->make_ordered_pair(edge_va, edge_vb)]; + } - const std::size_t n = edge_va->cached_number_of_incident_facets(); - const std::size_t m = edge_va->cached_number_of_components(); + const int n = edge_va->cached_number_of_incident_facets(); + const int m = edge_va->cached_number_of_components(); edge_va->set_c2t3_cache(n + 1, m); } const int dimension_plus_1 = tr_.dimension() + 1; @@ -1996,19 +2381,21 @@ remove_from_complex(const Facet& facet) const Vertex_handle edge_va = cell->vertex(edge_index_va); const Vertex_handle edge_vb = cell->vertex(edge_index_vb); #ifdef CGAL_LINKED_WITH_TBB + if constexpr (std::is_same_v) { typename Edge_facet_counter::accessor accessor; - edge_facet_counter_.insert(accessor, - this->make_ordered_pair(edge_va, edge_vb)); + edge_facet_counter_.insert(accessor, this->make_ordered_pair(edge_va, edge_vb)); --accessor->second; } -#else // not CGAL_LINKED_WITH_TBB - --edge_facet_counter_[this->make_ordered_pair(edge_va, edge_vb)]; -#endif // not CGAL_LINKED_WITH_TBB + else +#endif + { + --edge_facet_counter_[this->make_ordered_pair(edge_va, edge_vb)]; + } - const std::size_t n = edge_va->cached_number_of_incident_facets(); + const int n = edge_va->cached_number_of_incident_facets(); CGAL_assertion(n > 0); - const std::size_t m = edge_va->cached_number_of_components(); + const int m = edge_va->cached_number_of_components(); edge_va->set_c2t3_cache(n - 1, m); } const int dimension_plus_1 = tr_.dimension() + 1; @@ -2096,7 +2483,88 @@ operator<< (std::ostream& os, const Mesh_complex_3_in_triangulation_3 &c3t3) { // TODO: implement edge saving - return os << c3t3.triangulation(); + using C3t3 = Mesh_complex_3_in_triangulation_3; + if constexpr(C3t3::store_surface_patch_info_in_cell) { + return os << c3t3.triangulation(); + } else { + auto& tr = c3t3.triangulation(); + auto n = tr.number_of_vertices(); + if(IO::is_ascii(os)) { + os << tr.dimension() << std::endl << n << std::endl; + } else { + write(os, tr.dimension()); + write(os, n); + } + + if(n == 0) + return os; + + using Vertex_handle = typename Tr::Vertex_handle; + std::vector TV(n + 1); + auto i = 0u; + + // write the vertices + for(auto it = tr.vertices_begin(), end = tr.vertices_end(); it != end; ++it) + TV[i++] = it; + + CGAL_assertion(i == n + 1); + CGAL_assertion(tr.is_infinite(TV[0])); + + Unique_hash_map V; + V[tr.infinite_vertex()] = 0; + for(i = 1; i <= n; i++) { + os << *TV[i]; + V[TV[i]] = i; + if(IO::is_ascii(os)) + os << std::endl; + } + + // Asks the tds for the combinatorial information + tr.tds().print_cells(os, V); + + auto insert_cell = [&](std::ostream& os, typename Tr::Cell_handle ch) -> auto& { + if(IO::is_ascii(os)) + os << c3t3.subdomain_index(ch); + else + write(os, c3t3.subdomain_index(ch)); + + for(int i = 0; i < 4; ++i) { + if(IO::is_ascii(os)) + os << ' ' << IO::oformat(c3t3.surface_patch_index(ch, i)); + else + write(os, c3t3.surface_patch_index(ch, i)); + } + return os; + }; + + switch(tr.dimension()) { + case 3: { + for(auto it = tr.cells_begin(), end = tr.cells_end(); it != end; ++it) { + insert_cell(os, it); // other information + if(IO::is_ascii(os)) + os << std::endl; + } + break; + } + case 2: { + for(auto it = tr.facets_begin(), end = tr.facets_end(); it != end; ++it) { + insert_cell(os, (*it).first); // other information + if(IO::is_ascii(os)) + os << std::endl; + } + break; + } + case 1: { + for(auto it = tr.edges_begin(), end = tr.edges_end(); it != end; ++it) { + insert_cell(os, (*it).first); // other information + if(IO::is_ascii(os)) + os << std::endl; + } + break; + } + } + return os; + } } @@ -2106,8 +2574,79 @@ operator>> (std::istream& is, Mesh_complex_3_in_triangulation_3 &c3t3) { // TODO: implement edge loading + using C3t3 = Mesh_complex_3_in_triangulation_3; c3t3.clear(); - is >> c3t3.triangulation(); + if constexpr(C3t3::store_surface_patch_info_in_cell) { + is >> c3t3.triangulation(); + } else { + auto& tr = c3t3.triangulation(); + using Vertex_handle = typename Tr::Vertex_handle; + using Cell_handle = typename Tr::Cell_handle; + + + tr.tds().clear(); // infinite vertex deleted + tr.set_infinite_vertex(tr.tds().create_vertex()); + std::size_t n; + int d; + if(IO::is_ascii(is)) { + is >> d >> n; + } else { + read(is, d); + read(is, n); + } + if(!is) + return is; + + std::vector V; + if(d > 3 || d < -2 || (n + 1) > V.max_size()) { + is.setstate(std::ios_base::failbit); + return is; + } + tr.tds().set_dimension(d); + V.resize(n + 1); + V[0] = tr.infinite_vertex(); // the infinite vertex is numbered 0 + + for(std::size_t i = 1; i <= n; i++) { + V[i] = tr.tds().create_vertex(); + if(!(is >> *V[i])) + return is; + } + + std::vector C; + + std::size_t m; + tr.tds().read_cells(is, V, m, C); + + auto extract_cell = [&](std::istream& is, Cell_handle ch) -> auto& { + typename C3t3::Subdomain_index index; + if(IO::is_ascii(is)) + is >> index; + else + read(is, index); + if(is) { + c3t3.set_subdomain_index(ch, index); + for(int i = 0; i < 4; ++i) + { + typename C3t3::Surface_patch_index i2; + if(IO::is_ascii(is)) + is >> IO::iformat(i2); + else + { + read(is, i2); + } + c3t3.set_surface_patch_index(ch, i, i2); + } + } + + return is; + }; + + for(std::size_t j = 0; j < m; j++) + { + if(!extract_cell(is, C[j])) + return is; + } + } if (!is) { c3t3.clear(); diff --git a/SMDS_3/include/CGAL/SMDS_3/tet_soup_to_c3t3.h b/SMDS_3/include/CGAL/SMDS_3/tet_soup_to_c3t3.h index a6eea92dcd0..b76d2b49572 100644 --- a/SMDS_3/include/CGAL/SMDS_3/tet_soup_to_c3t3.h +++ b/SMDS_3/include/CGAL/SMDS_3/tet_soup_to_c3t3.h @@ -21,53 +21,32 @@ #include #include +#include +#include +#include +#include +#include #include #include +#include #include +#include #include +#include +#include +#include +#include +#include #include +#include #include #include #include namespace CGAL { -namespace SMDS_3_internal { -template -struct Has_in_dimension : std::false_type -{}; - -template -struct Has_in_dimension().in_dimension())>> - : std::true_type -{}; - -template -struct Has_is_corner : std::false_type -{}; - -template -struct Has_is_corner().is_corner())>> - : std::true_type -{}; - -template -bool is_corner(const typename Tr::Vertex_handle v, const Tr&) -{ - using V = typename Tr::Triangulation_data_structure::Vertex; - - if constexpr(Has_in_dimension::value) - return v->in_dimension() == 0; - else if constexpr(Has_is_corner::value) - return v->ccdt_3_data().is_corner(); - else - return false; -} - -} // namespace SMDS_3_internal - namespace SMDS_3 { template @@ -150,24 +129,30 @@ bool add_facet_to_incident_cells_map(const typename Tr::Cell_handle c, int i, return success; } -template -bool build_finite_cells(Tr& tr, +template +bool build_finite_cells(C3T3& c3t3, const CellRange& finite_cells, const SubdomainsRange& subdomains, - const std::vector& vertex_handle_vector, - boost::unordered_map, - std::vector > >& incident_cells_map, + const std::vector& vertex_handle_vector, + boost::unordered_map, + std::vector > >& incident_cells_map, const FacetPatchMap& border_facets, const bool verbose, const bool replace_domain_0, const bool allow_negative_orientation) { + typedef typename C3T3::Surface_patch_index Surface_patch_index; + typedef typename C3T3::Triangulation Tr; typedef typename Tr::Vertex_handle Vertex_handle; typedef typename Tr::Cell_handle Cell_handle; - typedef typename Tr::Cell::Surface_patch_index Surface_patch_index; bool success = true; + Tr& tr = c3t3.triangulation(); + typename Tr::Geom_traits::Construct_point_3 cp = tr.geom_traits().construct_point_3_object(); typename Tr::Geom_traits::Orientation_3 orientation = tr.geom_traits().orientation_3_object(); @@ -211,9 +196,9 @@ bool build_finite_cells(Tr& tr, cp(tr.point(vs[2])), cp(tr.point(vs[3]))) == POSITIVE); Cell_handle c = tr.tds().create_cell(vs[0], vs[1], vs[2], vs[3]); - c->set_subdomain_index(subdomains[i]); // the cell's info keeps the reference of the tetrahedron + c3t3.set_subdomain_index(c, subdomains[i]); // the cell's info keeps the reference of the tetrahedron if(replace_domain_0 && subdomains[i] == 0) - c->set_subdomain_index(max_domain+1); // the cell's info keeps the reference of the tetrahedron + c3t3.set_subdomain_index(c, max_domain+1); // the cell's info keeps the reference of the tetrahedron // assign cells to vertices for(int j=0; j<4; ++j) @@ -247,7 +232,7 @@ bool build_finite_cells(Tr& tr, typename FacetPatchMap::const_iterator it = border_facets.find(facet); if(it != border_facets.end()) { - c->set_surface_patch_index(j, it->second); + c3t3.set_surface_patch_index(c, j, it->second); } else { @@ -255,9 +240,9 @@ bool build_finite_cells(Tr& tr, it = border_facets.find(facet); if(it != border_facets.end()) - c->set_surface_patch_index(j, it->second); + c3t3.set_surface_patch_index(c, j, it->second); else - c->set_surface_patch_index(j, Surface_patch_index()); + c3t3.set_surface_patch_index(c, j, Surface_patch_index()); } } } @@ -284,19 +269,22 @@ bool add_infinite_facets_to_incident_cells_map(typename Tr::Cell_handle c, return b1 && b2 && b3; } -template -bool build_infinite_cells(Tr& tr, - boost::unordered_map, - std::vector > >& incident_cells_map, +template +bool build_infinite_cells(C3T3& c3t3, + boost::unordered_map, + std::vector > >& incident_cells_map, const bool verbose, const bool allow_non_manifold) { + typedef typename C3T3::Triangulation Tr; typedef typename Tr::Vertex_handle Vertex_handle; typedef typename Tr::Cell_handle Cell_handle; typedef std::array Facet_vvv; typedef std::pair Incident_cell; typedef boost::unordered_map > Incident_cells_map; + Tr& tr = c3t3.triangulation(); + bool success = true; std::vector infinite_cells; @@ -338,7 +326,7 @@ bool build_infinite_cells(Tr& tr, it->second.emplace_back(opp_c, 0); CGAL_assertion(it->second.size() == 2); - opp_c->set_surface_patch_index(0, c->surface_patch_index(i)); + c3t3.set_surface_patch_index(opp_c, 0, c3t3.surface_patch_index(c, i)); } #ifdef CGAL_TET_SOUP_TO_C3T3_DEBUG @@ -449,21 +437,21 @@ int euler_characteristic(const Tds& tds) return (cell_count - facet_count + edge_count - vertex_count); } -template -bool build_triangulation_impl(Tr& tr, +bool build_mesh_complex_impl(C3T3& c3t3, const PointRange& points, const CellRange& finite_cells, - const std::vector& subdomains, + const std::vector& subdomains, const FacetPatchMap& border_facets, const EdgesRange& edges, const CornersRange& corners, - std::vector& vertex_handle_vector, + std::vector& vertex_handle_vector, ComplexEdgesOutputIterator cx_edges_out, const bool verbose,// = false, const bool replace_domain_0,// = false, @@ -471,8 +459,9 @@ bool build_triangulation_impl(Tr& tr, const bool allow_negative_orientation) // = false { if (verbose) - std::cout << "build_triangulation_impl()..." << std::endl; + std::cout << "build_mesh_complex_impl()..." << std::endl; + typedef typename C3T3::Triangulation Tr; typedef typename Tr::Vertex_handle Vertex_handle; typedef typename Tr::Cell_handle Cell_handle; typedef std::array Facet_vvv; @@ -484,7 +473,10 @@ bool build_triangulation_impl(Tr& tr, CGAL_precondition(!points.empty()); + Tr& tr = c3t3.triangulation(); + bool success = true; + Incident_cells_map incident_cells_map; // id to vertex_handle @@ -510,9 +502,9 @@ bool build_triangulation_impl(Tr& tr, if (!finite_cells.empty()) { - if (!CGAL::SMDS_3::build_finite_cells(tr, finite_cells, subdomains, vertex_handle_vector, - incident_cells_map, border_facets, verbose, replace_domain_0, - allow_negative_orientation)) + if (!CGAL::SMDS_3::build_finite_cells(c3t3, finite_cells, subdomains, vertex_handle_vector, + incident_cells_map, border_facets, verbose, replace_domain_0, + allow_negative_orientation)) { if (verbose) std::cerr << "Error: build_finite_cells went wrong!" << std::endl; @@ -523,7 +515,7 @@ bool build_triangulation_impl(Tr& tr, std::cout << "build finite cells done (" << tr.tds().cells().size() << " cells)" << std::endl; } - if (!CGAL::SMDS_3::build_infinite_cells(tr, incident_cells_map, verbose, allow_non_manifold)) + if (!CGAL::SMDS_3::build_infinite_cells(c3t3, incident_cells_map, verbose, allow_non_manifold)) { if(verbose) std::cerr << "Error: build_infinite_cells went wrong!" << std::endl; @@ -548,7 +540,7 @@ bool build_triangulation_impl(Tr& tr, tr.tds().set_dimension(3); - if (!CGAL::SMDS_3::assign_neighbors(tr, incident_cells_map, allow_non_manifold)) + if (!CGAL::SMDS_3::assign_neighbors(c3t3.triangulation(), incident_cells_map, allow_non_manifold)) { if(verbose) std::cerr << "Error: assign_neighbors went wrong!" << std::endl; @@ -604,34 +596,35 @@ bool build_triangulation_impl(Tr& tr, return success; } -template -bool build_triangulation_one_subdomain(Tr& tr, - const PointRange& points, - const CellRange& finite_cells, - const typename Tr::Cell::Subdomain_index& subdomain, - const FacetPatchMap& border_facets, - const EdgesRange& edges, - const CornersRange& corners, - std::vector& vertex_handle_vector, - CxEdgesOutputIterator cx_edges_out, - const bool verbose,// = false, - const bool replace_domain_0,// = false - const bool allow_non_manifold,// = false - const bool allow_negative_orientation)// = false +bool build_mesh_complex_one_subdomain(C3T3& c3t3, + const PointRange& points, + const CellRange& finite_cells, + const typename C3T3::Subdomain_index& subdomain, + const FacetPatchMap& border_facets, + const EdgesRange& edges, + const CornersRange& corners, + std::vector& vertex_handle_vector, + CxEdgesOutputIterator cx_edges_out, + const bool verbose,// = false, + const bool replace_domain_0,// = false + const bool allow_non_manifold,// = false + const bool allow_negative_orientation)// = false { - std::vector subdomains(finite_cells.size(), subdomain); - return build_triangulation_impl(tr, points, finite_cells, subdomains, - border_facets, edges, corners, - vertex_handle_vector, - cx_edges_out, - verbose, replace_domain_0, - allow_non_manifold, allow_negative_orientation); + std::vector subdomains(finite_cells.size(), subdomain); + return build_mesh_complex_impl(c3t3, points, finite_cells, subdomains, + border_facets, edges, corners, + vertex_handle_vector, + cx_edges_out, + verbose, replace_domain_0, + allow_non_manifold, + allow_negative_orientation); } template + typename ComplexEdgesOutputIterator> bool build_triangulation_one_subdomain(Tr& tr, const PointRange& points, const CellRange& finite_cells, @@ -648,23 +641,57 @@ bool build_triangulation_one_subdomain(Tr& tr, const FacetPatchMap& border_facets, const EdgesRange& edges, const CornersRange& corners, - CxEdgesOutputIterator cx_edges_out, - const bool verbose, // = false, + ComplexEdgesOutputIterator cx_edges_out, + const bool verbose,// = false, const bool replace_domain_0,// = false const bool allow_non_manifold,// = false const bool allow_negative_orientation)// = false { - std::vector subdomains(finite_cells.size(), subdomain); + using C3T3 = CGAL::Mesh_complex_3_in_triangulation_3; + C3T3 c3t3; // @fixme what if 'tr' wasn't empty... std::vector vertex_handle_vector; - return build_triangulation_impl(tr, points, finite_cells, subdomains, - border_facets, - edges, corners, - vertex_handle_vector, - cx_edges_out, - verbose, replace_domain_0, - allow_non_manifold, allow_negative_orientation); + bool res = build_mesh_complex_one_subdomain(c3t3, points, finite_cells, subdomain, + border_facets, edges, corners, + vertex_handle_vector, cx_edges_out, + verbose, replace_domain_0, + allow_non_manifold, + allow_negative_orientation); + tr = std::move(c3t3).triangulation(); + return res; } +template +bool build_mesh_complex_with_subdomains_range(C3T3& c3t3, + const PointRange& points, + const CellRange& finite_cells, + const SubdomainsRange& subdomains, + const FacetPatchMap& border_facets, + const EdgesRange& edges, + const CornersRange& corners, + std::vector& vertex_handle_vector, + CxEdgesOutputIterator cx_edges_out, + const bool verbose,// = false + const bool replace_domain_0,// = false, + const bool allow_non_manifold,// = false, + const bool allow_negative_orientation)// = false +{ + std::vector subdomains_vector( + subdomains.begin(), subdomains.end()); + return build_mesh_complex_impl(c3t3, points, finite_cells, subdomains_vector, border_facets, + edges, corners, + vertex_handle_vector, + cx_edges_out, + verbose, replace_domain_0, + allow_non_manifold, + allow_negative_orientation); +} template c3t3; // @fixme what if 'tr' wasn't empty... + std::vector vertex_handle_vector; std::vector subdomains_vector( subdomains.begin(), subdomains.end()); - return build_triangulation_impl(tr, points, finite_cells, subdomains_vector, border_facets, - edges, corners, - vertex_handle_vector, - cx_edges_oit, - verbose, replace_domain_0, - allow_non_manifold, - allow_negative_orientation); + bool res = build_mesh_complex_with_subdomains_range(c3t3, points, finite_cells, subdomains_vector, border_facets, + edges, corners, + vertex_handle_vector, + cx_edges_oit, + verbose, replace_domain_0, + allow_non_manifold, + allow_negative_orientation); + tr = std::move(c3t3).triangulation(); + return res; } +template +bool build_mesh_complex_from_file(std::istream& is, + C3T3& c3t3, + const bool verbose, + const bool replace_domain_0, + const bool allow_non_manifold, + const bool allow_negative_orientation, + CxEdgesOutputIterator cx_edges_oit) +{ + using Tr = typename C3T3::Triangulation; + using Point_3 = typename Tr::Point; + using Subdomain_index = typename C3T3::Subdomain_index; + using Surface_patch_index = typename C3T3::Surface_patch_index; + using Curve_index = typename C3T3::Curve_index; + using Corner_index = typename C3T3::Corner_index; + + using Edge = std::array; + using Facet = std::array; // 3 = id + using Tet = std::array; // 4 = id + + using Edge_with_index = CGAL::IO::internal::Edge_with_curve_index; + using Corner_with_index = CGAL::IO::internal::Vertex_with_corner_index; + + std::vector finite_cells; + std::vector subdomains; + std::vector points; + + std::vector facets; + std::vector edges; + std::vector corners, facet_refs, edge_refs, point_refs; + std::vector ignored_ridges; + + bool is_CGAL_mesh = false; + + if(verbose) + { + std::cout << "Reading .mesh file..." << std::endl; + std::cout << "Replace domain #0 = " << replace_domain_0 << std::endl; + std::cout << "Allow non-manifoldness = " << allow_non_manifold << std::endl; + } + + bool ok = CGAL::IO::internal::read_MEDIT(is, points, finite_cells, + facets, true, + edges, true, + ignored_ridges, false, + corners, true, + point_refs, true, + subdomains, true, + facet_refs, true, + edge_refs, true, + verbose, + is_CGAL_mesh); + if(!ok) + return false; + + std::vector edge_indices; + edge_indices.reserve(edges.size()); + for(std::size_t i = 0; i < edges.size(); ++i) + { + Edge_with_index edge; + edge.v0 = edges[i][0]; + edge.v1 = edges[i][1]; + edge.curve_index = edge_refs[i]; + edge_indices.emplace_back(edge); + } + + std::vector corner_indices; + corner_indices.reserve(corners.size()); + for(std::size_t i = 0; i < corners.size(); ++i) + { + Corner_with_index corner; + corner.v = corners[i]; + corner.corner_index = point_refs[i]; + corner_indices.emplace_back(corner); + } + + boost::unordered_map border_facets; + border_facets.reserve(facets.size()); + + bool has_negative_surface_patch_ids = false; + int max_surface_patch_id = 0; + for(std::size_t i = 0; i < facets.size(); ++i) + { + if(facet_refs[i] < 0) + has_negative_surface_patch_ids = true; + else if(facet_refs[i] > max_surface_patch_id) + max_surface_patch_id = facet_refs[i]; + border_facets.emplace(facets[i], facet_refs[i]); + } + + if(has_negative_surface_patch_ids) + { + if(verbose) + std::cerr << "Warning: negative surface patch ids" << std::endl; + for(auto& facet_and_patch_id : border_facets) + if(facet_and_patch_id.second < 0) + facet_and_patch_id.second = max_surface_patch_id - facet_and_patch_id.second; + } + + if(!is_CGAL_mesh) + c3t3.triangulation().may_have_badly_oriented_cells(true); + + std::vector no_vertices; + return build_mesh_complex_with_subdomains_range(c3t3, points, finite_cells, + subdomains, border_facets, + edge_indices, corner_indices, + no_vertices, cx_edges_oit, + verbose, + replace_domain_0 && !is_CGAL_mesh, + allow_non_manifold, + allow_negative_orientation); +} + + +template +bool build_triangulation_from_file(std::istream& is, + Tr& tr, + const bool verbose, + const bool replace_domain_0, + const bool allow_non_manifold, + const bool allow_negative_orientation, + CxEdgesOutputIterator cx_edges_oit) +{ + using C3T3 = CGAL::Mesh_complex_3_in_triangulation_3; + C3T3 c3t3; // @fixme what if 'tr' wasn't empty... + bool res = build_mesh_complex_from_file(is, c3t3, verbose, replace_domain_0, + allow_non_manifold, + allow_negative_orientation, + cx_edges_oit); + tr = std::move(c3t3).triangulation(); + return res; +} } // namespace SMDS_3 } // namespace CGAL diff --git a/SMDS_3/include/CGAL/SMDS_3/utilities.h b/SMDS_3/include/CGAL/SMDS_3/utilities.h index 369bfc9df03..469028ab2e9 100644 --- a/SMDS_3/include/CGAL/SMDS_3/utilities.h +++ b/SMDS_3/include/CGAL/SMDS_3/utilities.h @@ -19,10 +19,15 @@ #include +#include #include +#include + #include #include #include +#include +#include namespace CGAL { namespace SMDS_3 { @@ -116,6 +121,40 @@ class Iterator_not_in_complex } // end namespace internal } // end namespace SMDS_3 + +namespace SMDS_3_internal { +template +struct Has_in_dimension : std::false_type +{}; + +template +struct Has_in_dimension().in_dimension())>> + : std::true_type +{}; + +template +struct Has_is_corner : std::false_type +{}; + +template +struct Has_is_corner().is_corner())>> + : std::true_type +{}; + +template +bool is_corner(const typename Tr::Vertex_handle v, const Tr&) +{ + using V = typename Tr::Triangulation_data_structure::Vertex; + + if constexpr(Has_in_dimension::value) + return v->in_dimension() == 0; + else if constexpr(Has_is_corner::value) + return v->ccdt_3_data().is_corner(); + else + return false; +} + +} // namespace SMDS_3_internal } //namespace CGAL #endif // CGAL_SMDS_3_UTILITIES_H diff --git a/SMDS_3/include/CGAL/Simplicial_mesh_vertex_base_3.h b/SMDS_3/include/CGAL/Simplicial_mesh_vertex_base_3.h index 9238c4d9b71..b28da674ae6 100644 --- a/SMDS_3/include/CGAL/Simplicial_mesh_vertex_base_3.h +++ b/SMDS_3/include/CGAL/Simplicial_mesh_vertex_base_3.h @@ -133,8 +133,6 @@ private : public: Simplicial_mesh_vertex_base_3() : Vb() - , number_of_incident_facets_(0) - , number_of_components_(0) , index_() , dimension_(-1) , cache_validity(false) @@ -185,19 +183,19 @@ private : cache_validity = false; } - void set_c2t3_cache(const std::size_t i, const std::size_t j) + void set_c2t3_cache(const int i, const int j) { number_of_incident_facets_ = i; number_of_components_ = j; cache_validity = true; } - std::size_t cached_number_of_incident_facets() const + int cached_number_of_incident_facets() const { return number_of_incident_facets_; } - std::size_t cached_number_of_components() const + int cached_number_of_components() const { return number_of_components_; } @@ -210,10 +208,10 @@ private : Get_io_signature()() + "+" + Get_io_signature()(); } -private: - std::size_t number_of_incident_facets_; - std::size_t number_of_components_; // number of components in the adjacency +private: + int number_of_incident_facets_ = 0; + int number_of_components_ = 0; // number of components in the adjacency // graph of incident facets (in complex) diff --git a/SMDS_3/include/CGAL/facets_in_complex_3_to_triangle_mesh.h b/SMDS_3/include/CGAL/facets_in_complex_3_to_triangle_mesh.h index d129641ef1a..7924373de64 100644 --- a/SMDS_3/include/CGAL/facets_in_complex_3_to_triangle_mesh.h +++ b/SMDS_3/include/CGAL/facets_in_complex_3_to_triangle_mesh.h @@ -94,7 +94,7 @@ void facets_in_complex_3_to_triangle_soup(const C3T3& c3t3, { const Cell_handle c = fit.first; const int s = fit.second; - const Surface_patch_index spi = c->surface_patch_index(s); + const Surface_patch_index spi = c3t3.surface_patch_index(c, s); const typename C3T3::Subdomain_index cell_sdi = c3t3.subdomain_index(c); const typename C3T3::Subdomain_index opp_sdi = c3t3.subdomain_index(c->neighbor(s)); diff --git a/SMDS_3/test/SMDS_3/test_c3t3_extract_subdomains_boundaries.cpp b/SMDS_3/test/SMDS_3/test_c3t3_extract_subdomains_boundaries.cpp index 851e8fe38c6..1c0da907716 100644 --- a/SMDS_3/test/SMDS_3/test_c3t3_extract_subdomains_boundaries.cpp +++ b/SMDS_3/test/SMDS_3/test_c3t3_extract_subdomains_boundaries.cpp @@ -53,7 +53,7 @@ typedef CGAL::Mesh_triangulation_3::type Tr; typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Mesh Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; typedef Mesh_criteria::Facet_criteria Facet_criteria; typedef Mesh_criteria::Cell_criteria Cell_criteria; diff --git a/SMDS_3/test/SMDS_3/test_c3t3_into_facegraph.cpp b/SMDS_3/test/SMDS_3/test_c3t3_into_facegraph.cpp index b31fbe22f0a..003e56c4852 100644 --- a/SMDS_3/test/SMDS_3/test_c3t3_into_facegraph.cpp +++ b/SMDS_3/test/SMDS_3/test_c3t3_into_facegraph.cpp @@ -43,18 +43,18 @@ int main (int argc, char** argv){ return 1; } C3t3 c3t3; - if(CGAL::SMDS_3::build_triangulation_from_file(in, c3t3.triangulation())) + if(CGAL::SMDS_3::build_mesh_complex_from_file(in, c3t3)) { for( Cell_handle cit : c3t3.triangulation().finite_cell_handles()) { - assert(cit->subdomain_index() >= 0); - if(cit->subdomain_index() > 0) - c3t3.add_to_complex(cit, cit->subdomain_index()); + assert(c3t3.subdomain_index(cit) >= 0); + if(c3t3.subdomain_index(cit) > 0) + c3t3.add_to_complex(cit, c3t3.subdomain_index(cit)); for(int i=0; i < 4; ++i) { - if(cit->surface_patch_index(i)>0) + if(c3t3.surface_patch_index(cit, i) > 0) { - c3t3.add_to_complex(cit, i, cit->surface_patch_index(i)); + c3t3.add_to_complex(cit, i, c3t3.surface_patch_index(cit, i)); } } } diff --git a/SMDS_3/test/SMDS_3/test_c3t3_io.cpp b/SMDS_3/test/SMDS_3/test_c3t3_io.cpp index cb9e1817151..2a2d1c46c24 100644 --- a/SMDS_3/test/SMDS_3/test_c3t3_io.cpp +++ b/SMDS_3/test/SMDS_3/test_c3t3_io.cpp @@ -292,7 +292,7 @@ struct Test_c3t3_io { end1 = t1.finite_cells_end(); cit1 != end1; ++cit1, ++cit2) { - if(cit1->subdomain_index() != cit2->subdomain_index() ) + if(c1.subdomain_index(cit1) != c2.subdomain_index(cit2) ) { std::cerr << "Error: cells are different:\n"; std::cerr << *cit1 << "\n" diff --git a/SMDS_3/test/SMDS_3/test_c3t3_io_MEDIT.cpp b/SMDS_3/test/SMDS_3/test_c3t3_io_MEDIT.cpp index 7f0ff4ee718..c39cb5fd65b 100644 --- a/SMDS_3/test/SMDS_3/test_c3t3_io_MEDIT.cpp +++ b/SMDS_3/test/SMDS_3/test_c3t3_io_MEDIT.cpp @@ -24,7 +24,7 @@ int test_MEDIT_with_features() using Mesh_domain = CGAL::Polyhedral_mesh_domain_with_features_3; using Tr = CGAL::Mesh_triangulation_3::type; using C3t3 = CGAL::Mesh_complex_3_in_triangulation_3; - using Mesh_criteria = CGAL::Mesh_criteria_3; + using Mesh_criteria = CGAL::Mesh_criteria_3; std::filesystem::path fname = CGAL::data_file_path("meshes/fandisk.off"); std::ifstream input(fname); diff --git a/TDS_3/include/CGAL/Triangulation_data_structure_3.h b/TDS_3/include/CGAL/Triangulation_data_structure_3.h index 94889e1ade5..40348035b8f 100644 --- a/TDS_3/include/CGAL/Triangulation_data_structure_3.h +++ b/TDS_3/include/CGAL/Triangulation_data_structure_3.h @@ -333,6 +333,7 @@ class Triangulation_data_structure_3 : _dimension(std::exchange(tds._dimension, -2)) , _cells(std::move(tds._cells)) , _vertices(std::move(tds._vertices)) + , _initial_Euler_characteristic(std::exchange(tds._initial_Euler_characteristic, 0)) { } @@ -351,6 +352,7 @@ class Triangulation_data_structure_3 _cells = std::move(tds._cells); _vertices = std::move(tds._vertices); _dimension = std::exchange(tds._dimension, -2); + _initial_Euler_characteristic = std::exchange(tds._initial_Euler_characteristic, 0); return *this; } diff --git a/TDS_3/include/CGAL/Triangulation_ds_vertex_base_3.h b/TDS_3/include/CGAL/Triangulation_ds_vertex_base_3.h index 61a02348a89..316f09268bf 100644 --- a/TDS_3/include/CGAL/Triangulation_ds_vertex_base_3.h +++ b/TDS_3/include/CGAL/Triangulation_ds_vertex_base_3.h @@ -66,7 +66,7 @@ class Triangulation_ds_vertex_base_3 Cell_handle _c; // The typedef and the bool are used by Triangulation_data_structure::Vertex_extractor - // The names are chooses complicated so that we do not have to document them + // The names are chosen complicated so that we do not have to document them // (privacy by obfuscation) public: typedef bool Has_visited_for_vertex_extractor; diff --git a/Tetrahedral_remeshing/examples/Tetrahedral_remeshing/mesh_and_remesh_c3t3.cpp b/Tetrahedral_remeshing/examples/Tetrahedral_remeshing/mesh_and_remesh_c3t3.cpp index d4664d8c66d..14ad26ffd76 100644 --- a/Tetrahedral_remeshing/examples/Tetrahedral_remeshing/mesh_and_remesh_c3t3.cpp +++ b/Tetrahedral_remeshing/examples/Tetrahedral_remeshing/mesh_and_remesh_c3t3.cpp @@ -32,7 +32,7 @@ using C3t3 = CGAL::Mesh_complex_3_in_triangulation_3< Tr, Mesh_domain::Corner_index, Mesh_domain::Curve_index>; // Criteria -using Mesh_criteria = CGAL::Mesh_criteria_3; +using Mesh_criteria = CGAL::Mesh_criteria_3; // Triangulation for Remeshing using Triangulation_3 = CGAL::Triangulation_3 using C3t3 = CGAL::Mesh_complex_3_in_triangulation_3; // Criteria -using Mesh_criteria = CGAL::Mesh_criteria_3; +using Mesh_criteria = CGAL::Mesh_criteria_3; // Triangulation for Remeshing using Triangulation_3 = CGAL::Triangulation_3; diff --git a/Tetrahedral_remeshing/examples/Tetrahedral_remeshing/mesh_and_remesh_polyhedral_domain_with_features.cpp b/Tetrahedral_remeshing/examples/Tetrahedral_remeshing/mesh_and_remesh_polyhedral_domain_with_features.cpp index 482e1a44d1f..b7fb51ac502 100644 --- a/Tetrahedral_remeshing/examples/Tetrahedral_remeshing/mesh_and_remesh_polyhedral_domain_with_features.cpp +++ b/Tetrahedral_remeshing/examples/Tetrahedral_remeshing/mesh_and_remesh_polyhedral_domain_with_features.cpp @@ -33,7 +33,7 @@ using C3t3 = CGAL::Mesh_complex_3_in_triangulation_3< Tr, Mesh_domain::Corner_index, Mesh_domain::Curve_index>; // Criteria -using Mesh_criteria = CGAL::Mesh_criteria_3; +using Mesh_criteria = CGAL::Mesh_criteria_3; // Triangulation for Remeshing using Triangulation_3 = CGAL::Triangulation_3::type; using C3t3 = CGAL::Mesh_complex_3_in_triangulation_3; // Criteria -using Mesh_criteria = CGAL::Mesh_criteria_3; +using Mesh_criteria = CGAL::Mesh_criteria_3; // Triangulation for Remeshing using T3 = CGAL::Triangulation_3: typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; // Triangulation for Remeshing using T3 = CGAL::Triangulation_3 C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; // Triangulation for Remeshing typedef CGAL::Triangulation_3 -#include - namespace CGAL { namespace Tetrahedral_remeshing diff --git a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/collapse_short_edges.h b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/collapse_short_edges.h index 831e0e94eaf..9383f9e053a 100644 --- a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/collapse_short_edges.h +++ b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/collapse_short_edges.h @@ -159,8 +159,8 @@ class CollapseTriangulation std::map border_facets;//unused here std::vector> feature_edges_and_indices;//unused here std::vector> corners_and_indices;//unused here - if (CGAL::SMDS_3::build_triangulation_impl( - triangulation, points, finite_cells, subdomains, border_facets, + if (CGAL::SMDS_3::build_mesh_complex_impl( + c3t3, points, finite_cells, subdomains, border_facets, feature_edges_and_indices, corners_and_indices, new_vertices, @@ -170,6 +170,7 @@ class CollapseTriangulation /*allow_non_manifold*/false, /*allow_negative_volumes*/true)) { + const Tr& triangulation = c3t3.triangulation(); CGAL_expensive_assertion(triangulation.tds().is_valid()); CGAL_assertion(triangulation.infinite_vertex() == new_vertices[0]); @@ -196,6 +197,8 @@ class CollapseTriangulation Result_type collapse() { + Tr& triangulation = c3t3.triangulation(); + if (not_an_edge) { #ifdef CGAL_TETRAHEDRAL_REMESHING_VERBOSE @@ -344,7 +347,7 @@ class CollapseTriangulation } protected: - Tr triangulation; + C3t3 c3t3; const Collapse_type collapse_type; @@ -852,12 +855,12 @@ void merge_surface_patch_indices(const typename C3t3::Facet& f1, if (in_cx_f1 && !in_cx_f2) { typename C3t3::Surface_patch_index patch = c3t3.surface_patch_index(f1); - f2.first->set_surface_patch_index(f2.second, patch); + c3t3.set_surface_patch_index(f2, patch); } else if (in_cx_f2 && !in_cx_f1) { typename C3t3::Surface_patch_index patch = c3t3.surface_patch_index(f2); - f1.first->set_surface_patch_index(f1.second, patch); + c3t3.set_surface_patch_index(f1, patch); } else if(in_cx_f1 && in_cx_f2) { @@ -865,7 +868,7 @@ void merge_surface_patch_indices(const typename C3t3::Facet& f1, typename C3t3::Surface_patch_index patch = c3t3.surface_patch_index(f2); c3t3.remove_from_complex(f2); - f2.first->set_surface_patch_index(f2.second, patch); + c3t3.set_surface_patch_index(f2, patch); } } diff --git a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/flip_edges.h b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/flip_edges.h index 6cff7befc6d..6b99e8887e7 100644 --- a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/flip_edges.h +++ b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/flip_edges.h @@ -1522,7 +1522,7 @@ Sliver_removal_result flip_on_surface(C3T3& c3t3, return NOT_FLIPPABLE; #endif Surface_patch_index patch = c3t3.surface_patch_index(ch0, ch0->index(vh4)); - CGAL_assertion(patch != Surface_patch_index()); + CGAL_assertion(!(patch == Surface_patch_index())); CGAL_assertion(c3t3.is_in_complex(ch0, ch0->index(vh4))); c3t3.remove_from_complex(ch0, ch0->index(vh4)); CGAL_assertion(c3t3.is_in_complex(ch3, ch3->index(vh4))); diff --git a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/smooth_vertices.h b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/smooth_vertices.h index 47512f50f59..42a67954057 100644 --- a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/smooth_vertices.h +++ b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/smooth_vertices.h @@ -802,7 +802,7 @@ std::size_t smooth_vertices_on_surfaces(C3t3& c3t3, continue; const Surface_patch_index si = incident_surface_patches[0]; - CGAL_assertion(si != Surface_patch_index()); + CGAL_assertion(!(si == Surface_patch_index())); CGAL_expensive_assertion_code(auto siv = surface_patch_index(v, c3t3)); CGAL_expensive_assertion(si == siv); diff --git a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/split_long_edges.h b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/split_long_edges.h index 8a53ed2ea9e..36e64155d8b 100644 --- a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/split_long_edges.h +++ b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/split_long_edges.h @@ -254,13 +254,13 @@ typename C3t3::Vertex_handle split_edge(const typename C3t3::Edge& e, const Facet_info v_and_opp_patch = facets_info.at(mfi); // facet opposite to new_v (status wrt c3t3 is unchanged) - new_cell->set_surface_patch_index(new_cell->index(new_v), - mfi.first->surface_patch_index(mfi.second)); + c3t3.set_surface_patch_index(new_cell, new_cell->index(new_v), + c3t3.surface_patch_index(mfi)); // new half-facet (added or not to c3t3 depending on the stored surface patch index) if (Surface_patch_index() == v_and_opp_patch.patch_index_) - new_cell->set_surface_patch_index(new_cell->index(v_and_opp_patch.opp_vertex_), - Surface_patch_index()); + c3t3.set_surface_patch_index(new_cell, new_cell->index(v_and_opp_patch.opp_vertex_), + Surface_patch_index()); else c3t3.add_to_complex(new_cell, new_cell->index(v_and_opp_patch.opp_vertex_), @@ -272,7 +272,7 @@ typename C3t3::Vertex_handle split_edge(const typename C3t3::Edge& e, const Vertex_handle vi = new_cell->vertex(i); if (vi == v1 || vi == v2) { - new_cell->set_surface_patch_index(i, Surface_patch_index()); + c3t3.set_surface_patch_index(new_cell, i, Surface_patch_index()); break; } } diff --git a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_adaptive_remeshing_impl.h b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_adaptive_remeshing_impl.h index 44140a48f6e..abc3c9a1218 100644 --- a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_adaptive_remeshing_impl.h +++ b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_adaptive_remeshing_impl.h @@ -576,7 +576,7 @@ class Adaptive_remesher for (Cell_handle cit : tr().finite_cell_handles()) { const Subdomain_index cid = cit->subdomain_index(); - if (cid > max_index && cid != Subdomain_index()) + if (cid > max_index && !(cid == Subdomain_index())) max_index = cid; } return max_index; diff --git a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_remeshing_helpers.h b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_remeshing_helpers.h index 79eada1496c..04148d1cf2a 100644 --- a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_remeshing_helpers.h +++ b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_remeshing_helpers.h @@ -2617,7 +2617,7 @@ void dump_cells_with_small_dihedral_angle(const Tr& tr, for (Cell_handle c : tr.finite_cell_handles()) { - if (c->subdomain_index() != Subdomain_index() && get(cell_select, c)) + if (!(c->subdomain_index() == Subdomain_index()) && get(cell_select, c)) { double dh = min_dihedral_angle(tr, c); if (dh < angle_bound) diff --git a/Tetrahedral_remeshing/test/Tetrahedral_remeshing/features_and_adaptive_sizing.cpp b/Tetrahedral_remeshing/test/Tetrahedral_remeshing/features_and_adaptive_sizing.cpp index ebda17beaa9..0876fa5f103 100644 --- a/Tetrahedral_remeshing/test/Tetrahedral_remeshing/features_and_adaptive_sizing.cpp +++ b/Tetrahedral_remeshing/test/Tetrahedral_remeshing/features_and_adaptive_sizing.cpp @@ -34,7 +34,7 @@ typedef CGAL::Mesh_complex_3_in_triangulation_3< Tr, Mesh_domain::Corner_index, Mesh_domain::Curve_index> C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; // Triangulation for Remeshing typedef CGAL::Triangulation_3::type Tr; typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Mesh Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; typedef Mesh_criteria::Facet_criteria Facet_criteria; typedef Mesh_criteria::Cell_criteria Cell_criteria; diff --git a/Tetrahedral_remeshing/test/Tetrahedral_remeshing/test_mesh_and_remesh_polyhedron_with_features.cpp b/Tetrahedral_remeshing/test/Tetrahedral_remeshing/test_mesh_and_remesh_polyhedron_with_features.cpp index 1150cbdf20b..d4e3ebaa79d 100644 --- a/Tetrahedral_remeshing/test/Tetrahedral_remeshing/test_mesh_and_remesh_polyhedron_with_features.cpp +++ b/Tetrahedral_remeshing/test/Tetrahedral_remeshing/test_mesh_and_remesh_polyhedron_with_features.cpp @@ -28,7 +28,7 @@ typedef CGAL::Mesh_complex_3_in_triangulation_3< Tr, Mesh_domain::Corner_index, Mesh_domain::Curve_index> C3t3; // Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; // To avoid verbose function and named parameters call using namespace CGAL::parameters; diff --git a/Tetrahedral_remeshing/test/Tetrahedral_remeshing/test_mesh_and_remesh_with_io.cpp b/Tetrahedral_remeshing/test/Tetrahedral_remeshing/test_mesh_and_remesh_with_io.cpp index 3950189693d..6aa3473e509 100644 --- a/Tetrahedral_remeshing/test/Tetrahedral_remeshing/test_mesh_and_remesh_with_io.cpp +++ b/Tetrahedral_remeshing/test/Tetrahedral_remeshing/test_mesh_and_remesh_with_io.cpp @@ -26,7 +26,7 @@ typedef CGAL::Mesh_triangulation_3::type Tr; typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Mesh Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; typedef Mesh_criteria::Facet_criteria Facet_criteria; typedef Mesh_criteria::Cell_criteria Cell_criteria; diff --git a/Tetrahedral_remeshing/test/Tetrahedral_remeshing/test_mesh_and_remesh_with_sizing_field.cpp b/Tetrahedral_remeshing/test/Tetrahedral_remeshing/test_mesh_and_remesh_with_sizing_field.cpp index 5cff611db9b..44d52e7007c 100644 --- a/Tetrahedral_remeshing/test/Tetrahedral_remeshing/test_mesh_and_remesh_with_sizing_field.cpp +++ b/Tetrahedral_remeshing/test/Tetrahedral_remeshing/test_mesh_and_remesh_with_sizing_field.cpp @@ -28,7 +28,7 @@ typedef CGAL::Triangulation_3 T3_remeshing; // Criteria -typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef CGAL::Mesh_criteria_3 Mesh_criteria; typedef Mesh_criteria::Facet_criteria Facet_criteria; typedef Mesh_criteria::Cell_criteria Cell_criteria; diff --git a/Triangulation_3/doc/Triangulation_3/Concepts/TriangulationTraits_3.h b/Triangulation_3/doc/Triangulation_3/Concepts/TriangulationTraits_3.h index 9bb4aa99b70..8f29ac49b23 100644 --- a/Triangulation_3/doc/Triangulation_3/Concepts/TriangulationTraits_3.h +++ b/Triangulation_3/doc/Triangulation_3/Concepts/TriangulationTraits_3.h @@ -7,7 +7,7 @@ The concept `TriangulationTraits_3` is the first template parameter of the class `CGAL::Triangulation_3`. It defines the geometric objects (points, segments, -triangles and tetrahedra) forming the triangulation together with a few +triangles, and tetrahedra) forming the triangulation together with a few geometric predicates and constructions on these objects: lexicographical comparison, orientation in case of coplanar points and orientation in space. diff --git a/Triangulation_3/doc/Triangulation_3/Triangulation_3.txt b/Triangulation_3/doc/Triangulation_3/Triangulation_3.txt index 7a82a310902..57b4fdfd298 100644 --- a/Triangulation_3/doc/Triangulation_3/Triangulation_3.txt +++ b/Triangulation_3/doc/Triangulation_3/Triangulation_3.txt @@ -255,7 +255,7 @@ The first template parameter of the triangulation class `Triangulation_3` is the geometric traits class, described by the concept `TriangulationTraits_3`. It must define the types of the geometric objects -(points, segments, triangles and tetrahedra) forming the triangulation together +(points, segments, triangles, and tetrahedra) forming the triangulation together with a few geometric predicates on these objects: orientation in space, orientation in case of coplanar points, order of collinear points. diff --git a/Triangulation_3/include/CGAL/Regular_triangulation_3.h b/Triangulation_3/include/CGAL/Regular_triangulation_3.h index 4739e0cd33b..3124c513b11 100644 --- a/Triangulation_3/include/CGAL/Regular_triangulation_3.h +++ b/Triangulation_3/include/CGAL/Regular_triangulation_3.h @@ -989,7 +989,7 @@ class Regular_triangulation_3 bool is_Gabriel(Vertex_handle v) const; // Dual functions - Bare_point dual(Cell_handle c) const; + decltype(auto) dual(Cell_handle c) const; Object dual(Cell_handle c, int i) const; Object dual(const Facet& facet) const; @@ -1742,7 +1742,7 @@ nearest_power_vertex(const Bare_point& p, Cell_handle start) const } template < class Gt, class Tds, class Lds > -typename Regular_triangulation_3::Bare_point +decltype(auto) Regular_triangulation_3:: dual(Cell_handle c) const { @@ -1755,7 +1755,7 @@ dual(Cell_handle c) const template < class Gt, class Tds, class Lds > void Regular_triangulation_3:: -dual_segment(Cell_handle c, int i, Bare_point& p, Bare_point&q) const +dual_segment(Cell_handle c, int i, Bare_point& p, Bare_point& q) const { Cell_handle n = c->neighbor(i); CGAL_assertion(! is_infinite(c) && ! is_infinite(n)); @@ -1938,8 +1938,8 @@ dual(Cell_handle c, int i) const if(! is_infinite(c) && ! is_infinite(n)) { // dual is a segment - Bare_point bp = dual(c); - Bare_point np = dual(n); + const auto& bp = dual(c); + const auto& np = dual(n); return construct_object(construct_segment(bp, np)); }