// Copyright (c) 2006-2007 INRIA Sophia-Antipolis (France). // Copyright (c) 2008,2011 GeometryFactory Sarl (France) // All rights reserved. // // This file is part of CGAL (www.cgal.org). // // $URL$ // $Id$ // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // // Author(s) : Laurent Rineau, Stephane Tayeb, Andreas Fabri, Jane Tournois #ifndef CGAL_SIMPLICIAL_MESH_CELL_BASE_3_H #define CGAL_SIMPLICIAL_MESH_CELL_BASE_3_H #include #include #include #include #include #include #include #include #include #ifdef CGAL_LINKED_WITH_TBB # include #endif namespace CGAL { // Class Simplicial_mesh_cell_3 // Cell base class used for tetrahedral remeshing // Adds information to Cb about the cell of the input complex containing it template< class Subdomain_index_, class Surface_patch_index_, class TDS> class Simplicial_mesh_cell_3 { public: using Triangulation_data_structure = TDS; using Vertex_handle = typename TDS::Vertex_handle; using Cell_handle = typename TDS::Cell_handle; using Vertex = typename TDS::Vertex; using Cell = typename TDS::Cell; using TDS_data = typename TDS::Cell_data; // Index Type using Subdomain_index = Subdomain_index_; using Surface_patch_index = Surface_patch_index_; public: // Constructors Simplicial_mesh_cell_3() : time_stamp_(std::size_t(-1)) {} Simplicial_mesh_cell_3(const Simplicial_mesh_cell_3& rhs) : N(rhs.N) , V(rhs.V) , time_stamp_(rhs.time_stamp_) , subdomain_index_(rhs.subdomain_index_) { for(int i=0; i <4; i++){ surface_index_table_[i] = rhs.surface_index_table_[i]; } } Simplicial_mesh_cell_3(Vertex_handle v0, Vertex_handle v1, Vertex_handle v2, Vertex_handle v3) : V(CGAL::make_array(v0, v1, v2, v3)) { } Simplicial_mesh_cell_3(Vertex_handle v0, Vertex_handle v1, Vertex_handle v2, Vertex_handle v3, Cell_handle n0, Cell_handle n1, Cell_handle n2, Cell_handle n3) : N(CGAL::make_array(n0, n1, n2, n3)) , V(CGAL::make_array(v0, v1, v2, v3)) { } // ACCESS FUNCTIONS Vertex_handle vertex(int i) const { CGAL_precondition( i >= 0 && i <= 3 ); return V[i]; } bool has_vertex(Vertex_handle v) const { return (V[0] == v) || (V[1] == v) || (V[2]== v) || (V[3]== v); } bool has_vertex(Vertex_handle v, int & i) const { if (v == V[0]) { i = 0; return true; } if (v == V[1]) { i = 1; return true; } if (v == V[2]) { i = 2; return true; } if (v == V[3]) { i = 3; return true; } return false; } int index(Vertex_handle v) const { if (v == V[0]) { return 0; } if (v == V[1]) { return 1; } if (v == V[2]) { return 2; } CGAL_assertion( v == V[3] ); return 3; } Cell_handle neighbor(int i) const { CGAL_precondition( i >= 0 && i <= 3); return N[i]; } bool has_neighbor(Cell_handle n) const { return (N[0] == n) || (N[1] == n) || (N[2] == n) || (N[3] == n); } bool has_neighbor(Cell_handle n, int & i) const { if(n == N[0]){ i = 0; return true; } if(n == N[1]){ i = 1; return true; } if(n == N[2]){ i = 2; return true; } if(n == N[3]){ i = 3; return true; } return false; } int index(Cell_handle n) const { if (n == N[0]) return 0; if (n == N[1]) return 1; if (n == N[2]) return 2; CGAL_assertion( n == N[3] ); return 3; } // SETTING void set_neighbor(int i, Cell_handle n) { CGAL_precondition( i >= 0 && i <= 3); CGAL_precondition( this != n.operator->() ); N[i] = n; } void set_neighbors() { N[0] = N[1] = N[2] = N[3] = Cell_handle(); } void set_neighbors(Cell_handle n0, Cell_handle n1, Cell_handle n2, Cell_handle n3) { CGAL_precondition( this != n0.operator->() ); CGAL_precondition( this != n1.operator->() ); CGAL_precondition( this != n2.operator->() ); CGAL_precondition( this != n3.operator->() ); N[0] = n0; N[1] = n1; N[2] = n2; N[3] = n3; } // CHECKING // the following trivial is_valid allows // the user of derived cell base classes // to add their own purpose checking bool is_valid(bool = false, int = 0) const { return true; } // For use by Compact_container. void * for_compact_container() const { return N[0].for_compact_container(); } void for_compact_container(void *p) { N[0].for_compact_container(p); } // TDS internal data access functions. TDS_data& tds_data() { return _tds_data; } const TDS_data& tds_data() const { return _tds_data; } // We must override the functions that modify the vertices. // And if the point inside a vertex is modified, we fail, // but there's not much we can do for this now. void set_vertex(int i, Vertex_handle v) { CGAL_precondition( i >= 0 && i <= 3); V[i] = v; } void set_vertices() { V[0] = V[1] = V[2] = V[3] = Vertex_handle(); } void set_vertices(Vertex_handle v0, Vertex_handle v1, Vertex_handle v2, Vertex_handle v3) { V[0] = v0; V[1] = v1; V[2] = v2; V[3] = v3; } // Returns the index of the cell of the input complex that contains the cell Subdomain_index subdomain_index() const { return subdomain_index_; } // Sets the index of the cell of the input complex that contains the cell void set_subdomain_index(const Subdomain_index& index) { subdomain_index_ = index; } /// Set surface index of \c facet to \c index void set_surface_patch_index(const int facet, const Surface_patch_index& index) { CGAL_precondition(facet>=0 && facet<4); surface_index_table_[facet] = index; } /// Returns surface index of facet \c facet Surface_patch_index surface_patch_index(const int facet) const { CGAL_precondition(facet>=0 && facet<4); return surface_index_table_[facet]; } /// Returns true if facet lies on a surface patch bool is_facet_on_surface(const int facet) const { CGAL_precondition(facet>=0 && facet<4); return ( !( Surface_patch_index() == surface_index_table_[facet] )); } // ----------------------------------- // Backward Compatibility // ----------------------------------- #ifndef CGAL_MESH_3_NO_DEPRECATED_SURFACE_INDEX typedef Surface_patch_index Surface_index; void set_surface_index(const int facet, const Surface_index& index) { set_surface_patch_index(facet,index); } /// Returns surface index of facet \c facet Surface_index surface_index(const int facet) const { return surface_patch_index(facet); } #endif // CGAL_MESH_3_NO_DEPRECATED_SURFACE_INDEX // ----------------------------------- // End backward Compatibility // ----------------------------------- static std::string io_signature() { return Get_io_signature()() + "+(" + Get_io_signature()() + ")[4]"; } /// 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: /// Stores surface_index for each facet of the cell std::array surface_index_table_ = {}; std::array N; std::array V; std::size_t time_stamp_; // The index of the cell of the input complex that contains me Subdomain_index subdomain_index_ = {}; TDS_data _tds_data; public: friend std::istream& operator>>(std::istream &is, Simplicial_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); 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); } } return is; } friend std::ostream& operator<<(std::ostream &os, const Simplicial_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)); } return os; } }; // end class Simplicial_mesh_cell_3 /*! \ingroup PkgSMDS3Classes The class `Simplicial_mesh_cell_base_3` is a model of the concept `SimplicialMeshCellBase_3`. It is designed to serve as cell base class for.3D simplicial mesh data structures. It stores and gives access to data about the complex the cell belongs to, such as the subdomain it belongs to or surface it takes part to. \tparam Subdomain_index Type of indices for subdomains of the discretized geometric domain. Must be a model of `CopyConstructible`, `Assignable`, `DefaultConstructible` and `EqualityComparable`. The default constructed value must match the label of the exterior of the domain (which contains at least the unbounded component). It must match the `Subdomain_index` of the model of the `MeshDomain_3` concept when used for mesh generation. \tparam Surface_patch_index Type of indices for surface patches (boundaries and interfaces) of the discretized geometric domain. Must be a model of `CopyConstructible`, `Assignable`, `DefaultConstructible` and `EqualityComparable`. The default constructed value must be the index value assigned to a non surface facet. It must match the `Surface_patch_index` of the model of the `MeshDomain_3` concept when used for mesh generation. \cgalModels `SimplicialMeshCellBase_3` \sa `CGAL::Mesh_complex_3_in_triangulation_3` \sa \link Mesh_cell_base_3 `CGAL::Mesh_cell_base_3`\endlink \sa `MeshDomain_3` \sa `MeshDomainWithFeatures_3` */ template class Simplicial_mesh_cell_base_3 { public: template struct Rebind_TDS { typedef Simplicial_mesh_cell_3 Other; }; }; } // end namespace CGAL #endif // CGAL_SIMPLICIAL_MESH_CELL_BASE_3_H