// Copyright (c) 2004 INRIA Sophia-Antipolis (France). // All rights reserved. // // This file is part of CGAL (www.cgal.org). // // $URL: https://github.com/CGAL/cgal/blob/v5.1/Mesh_2/include/CGAL/Triangulation_conformer_2.h $ // $Id: Triangulation_conformer_2.h 0779373 2020-03-26T13:31:46+01:00 Sébastien Loriot // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // // // Author(s) : Laurent RINEAU #ifndef CGAL_TRIANGULATION_CONFORMER_2_H #define CGAL_TRIANGULATION_CONFORMER_2_H #include #include #include namespace CGAL { template class Triangulation_conformer_2 { typedef typename Tr::Finite_edges_iterator Finite_edges_iterator; typedef typename Tr::Vertex_handle Vertex_handle; typedef Mesh_2::Refine_edges_with_clusters > Edges_level_Gabriel; typedef Mesh_2::Refine_edges_with_clusters > Edges_level_Delaunay; protected: /** \name INITIALIZED */ enum Initialization { NONE, /**< \c this is not initialized. */ CLUSTERS, /**< \c this clusters are initialized. */ DELAUNAY, /**< \c this has been \e Delaunay-initialized. */ GABRIEL /**< \c this has been \e Gabriel-initialized. */ }; // --- PROTECTED DATAS --- Initialization initialized; Tr& tr; Null_mesher_level null_level; Null_mesh_visitor null_visitor; Mesh_2::Clusters clusters; Edges_level_Gabriel edges_level_Gabriel; Edges_level_Delaunay edges_level_Delaunay; public: /** \name CONSTRUCTORS */ Triangulation_conformer_2(Tr& tr_) : initialized(NONE), tr(tr_), null_level(), null_visitor(), clusters(tr_), edges_level_Gabriel(tr, clusters, null_level), edges_level_Delaunay(tr, clusters, null_level) { } private: /** \name CHECKING METHODS*/ template bool is_conforming_XXX(Is_locally_conforming is_locally_conforming) const { for(Finite_edges_iterator ei = tr.finite_edges_begin(); ei != tr.finite_edges_end(); ++ei) if(ei->first->is_constrained(ei->second) && !is_locally_conforming(tr, ei->first, ei->second) ) return false; return true; } public: /** \name ACCESS TO CLUSTERS */ typedef typename Mesh_2::Clusters::Cluster_vertices_iterator Cluster_vertices_iterator; typedef typename Mesh_2::Clusters::Vertices_in_cluster_iterator Vertices_in_cluster_iterator; public: /** \name ACCESS FUNCTIONS */ /** Access to the private initialized member data. */ //@{ void set_initialized(Initialization init) { initialized = init; } Initialization get_initialized() const { return initialized; } //@} int number_of_constrained_edges() { int nedges = 0; for(typename Tr::Finite_edges_iterator eit = tr.finite_edges_begin(); eit != tr.finite_edges_end(); ++eit) if(eit->first->is_constrained(eit->second)) ++nedges; return nedges; } int number_of_clusters_vertices() const { return clusters.size(); } Cluster_vertices_iterator clusters_vertices_begin() const { return clusters.clusters_vertices_begin(); } Cluster_vertices_iterator clusters_vertices_end() const { return clusters.clusters_vertices_end(); } unsigned int number_of_clusters_at_vertex(const Vertex_handle& vh) { return clusters.number_of_clusters_at_vertex(vh); } #if 0 // returns the sequence of vertices belonging to the n-th cluster of vh std::pair vertices_in_cluster_sequence(const Vertex_handle& vh, const unsigned int n) { return clusters.vertices_in_cluster_sequence(); } #endif public: /** \name CHECKING METHODS */ bool is_conforming_Delaunay() { typedef typename Mesh_2::Is_locally_conforming_Delaunay Is_loc_conf; return is_conforming_XXX(Is_loc_conf()); } bool is_conforming_Gabriel() { typedef typename Mesh_2::Is_locally_conforming_Gabriel Is_loc_conf; return is_conforming_XXX(Is_loc_conf()); } /** \name CONFORMING FUNCTIONS */ void make_conforming_Delaunay() { if(initialized!=DELAUNAY) init_Delaunay(); edges_level_Delaunay.refine(null_visitor); } void make_conforming_Gabriel() { if(initialized!=GABRIEL) init_Gabriel(); edges_level_Gabriel.refine(null_visitor); } /** \name STEP BY STEP FUNCTIONS */ // Note: step by step functions are not efficient at all! private: void init_clusters() { if(initialized == NONE) clusters.create_clusters(); initialized = CLUSTERS; } public: /** Initializes the data structures (The call of this function is REQUIRED before any step by step operation). */ //@{ void init_Delaunay() { init_clusters(); initialized = DELAUNAY; edges_level_Delaunay.scan_triangulation(); } void init_Gabriel() { init_clusters(); initialized = GABRIEL; edges_level_Gabriel.scan_triangulation(); } //@} /** Tells if all constrained edges are conformed. */ bool is_conforming_done() // This function cannot be "const" because, as edges_to_be_conformed is // filtred, its empty() method is not const. { return ( edges_level_Gabriel.no_longer_element_to_refine() && edges_level_Delaunay.no_longer_element_to_refine() ); } /** Execute on step of the algorithm. init_XXX() should have been called before. */ //@{ bool try_one_step_conforming_Delaunay() { return edges_level_Delaunay.one_step(null_visitor); } bool try_one_step_conforming_Gabriel() { return edges_level_Gabriel.one_step(null_visitor); } bool step_by_step_conforming_Delaunay() { return edges_level_Delaunay.try_to_insert_one_point(null_visitor); } bool step_by_step_conforming_Gabriel() { return edges_level_Gabriel.try_to_insert_one_point(null_visitor); } //@} }; // end Triangulation_conformer_2 // --- GLOBAL FUNCTIONS --- template void make_conforming_Gabriel_2(Tr& t) { typedef Triangulation_conformer_2 Conform; Conform conform(t); conform.make_conforming_Gabriel(); } template void make_conforming_Delaunay_2(Tr& t) { typedef Triangulation_conformer_2 Conform; Conform conform(t); conform.make_conforming_Delaunay(); } } // end namespace CGAL #include #endif // CGAL_TRIANGULATION_CONFORMER_2_H