58 template < index_t DIMENSION >
59 bool check_range_model_vertex_ids(
62 const auto& geomodel_vertices = E.
geomodel().mesh.vertices;
67 if( geomodel_vertices.geomodel_vertex_id(
id, i ) == NO_ID
68 && geomodel_vertices.geomodel_vertex_id(
id, i )
72 "GeoModelEntity",
"Invalid geomodel vertex index in ",
id );
82 template < index_t DIMENSION >
83 index_t compute_nb_surface_connected_components(
86 index_t nb_connected_components;
87 std::tie( nb_connected_components, std::ignore ) =
88 surface.
mesh().connected_components();
89 return nb_connected_components;
95 template < index_t DIMENSION >
96 index_t compute_nb_volume_connected_components(
99 index_t nb_connected_components;
100 std::tie( nb_connected_components, std::ignore ) =
101 region.
mesh().connected_components();
102 return nb_connected_components;
113 template < index_t DIMENSION >
114 std::vector< index_t > count_vertex_occurences(
124 { mesh_element_index, vertex } )];
130 bool check_mesh_entity_vertices_are_different(
131 std::vector< index_t >& vertices,
132 std::vector< index_t >& vertices_global )
135 std::count( vertices.begin(), vertices.end(), NO_ID ) == 0 );
137 std::count( vertices_global.begin(), vertices_global.end(), NO_ID )
144 static_cast< index_t >( std::count(
145 vertices_global.begin(), vertices_global.end(), 0 ) )
146 != vertices_global.size() );
148 std::sort( vertices.begin(), vertices.end() );
149 std::sort( vertices_global.begin(), vertices_global.end() );
150 return std::unique( vertices.begin(), vertices.end() ) != vertices.end()
151 || std::unique( vertices_global.begin(), vertices_global.end() )
152 != vertices_global.end();
159 template < index_t DIMENSION >
160 bool polygon_is_degenerate(
164 std::vector< index_t > corners( nb_polygon_vertices, NO_ID );
165 std::vector< index_t > corners_global( nb_polygon_vertices, NO_ID );
167 const auto& geomodel_vertices = S.
geomodel().mesh.vertices;
172 corners[v] = polygon_vertex_index;
174 geomodel_vertices.geomodel_vertex_id(
id, { p, v } );
178 return check_mesh_entity_vertices_are_different(
179 corners, corners_global )
188 template < index_t DIMENSION >
189 bool cell_is_degenerate(
194 std::vector< index_t > vertices( nb_vertices_in_cell, NO_ID );
195 std::vector< index_t > vertices_global( nb_vertices_in_cell, NO_ID );
196 auto id = region.
gmme();
197 const auto& geomodel_vertices = region.
geomodel().mesh.vertices;
198 for(
auto v :
range( nb_vertices_in_cell ) )
202 geomodel_vertices.geomodel_vertex_id(
id, { cell_index, v } );
205 return check_mesh_entity_vertices_are_different(
206 vertices, vertices_global )
207 || volume < region.
geomodel().epsilon3();
213 template < index_t DIMENSION >
218 auto rhs_id = rhs.
gmme();
219 const auto& manager =
220 this->geomodel().entity_type_manager().relationship_manager;
221 return std::count_if( incident_entities_.begin(),
222 incident_entities_.end(),
223 [&rhs_id, &manager]( index_t i ) {
224 return manager.incident_entity_gmme( i ) == rhs_id;
229 template < index_t DIMENSION >
232 for(
auto i :
range( nb_boundaries() ) )
234 if( boundary( i ).is_inside_border( *
this ) )
242 template < index_t DIMENSION >
245 #ifdef RINGMESH_DEBUG 247 mesh_->print_mesh_bounded_attributes();
251 template < index_t DIMENSION >
255 auto& modifiable_model =
257 modifiable_model.
mesh.vertices.unbind_geomodel_vertex_map( gmme() );
260 template < index_t DIMENSION >
263 auto& modifiable_model =
265 modifiable_model.
mesh.vertices.bind_geomodel_vertex_map( gmme() );
268 template < index_t DIMENSION >
276 const auto& geomodel_vertices = this->geomodel().mesh.vertices;
278 for(
auto v :
range( nb_vertices() ) )
280 index_t geomodel_v{ geomodel_vertices.geomodel_vertex_id(
id, v ) };
282 if( geomodel_v == NO_ID )
285 " is not mapped to the related global geomodel vertex " 290 auto backward_vertices =
291 geomodel_vertices.mesh_entity_vertex_id(
id, geomodel_v );
292 bool found_in_backward{
false };
293 for(
auto bv : backward_vertices )
297 found_in_backward =
true;
300 if( !found_in_backward )
302 Logger::warn(
"GeoModelEntity",
"Error in mapping of ",
id,
304 " to the related global geomodel vertex indices." );
311 template < index_t DIMENSION >
314 return this->index() < this->geomodel().nb_mesh_entities( type_name() );
317 template < index_t DIMENSION >
321 this->geomodel().entity_type_manager().mesh_entity_manager;
322 const auto entity_type = type_name();
323 const auto& boundary_type = family.boundary_entity_type( entity_type );
327 if( family.is_valid_type( boundary_type ) )
329 for(
auto i :
range( nb_boundaries() ) )
331 const auto& E = boundary( i );
345 "Inconsistency boundary-incident_entity between ",
id,
354 template < index_t DIMENSION >
360 this->geomodel().entity_type_manager().mesh_entity_manager;
361 const auto entity_type = type_name();
362 const auto& incident_entity_type =
363 family.incident_entity_type( entity_type );
367 if( family.is_valid_type( incident_entity_type ) )
369 if( nb_incident_entities() == 0 )
372 "GeoModelEntity",
id,
" is in the boundary of no entity " );
375 for(
auto i :
range( nb_incident_entities() ) )
377 const auto& E = incident_entity( i );
391 "Inconsistency incident_entity-boundary between ",
id,
400 template < index_t DIMENSION >
404 this->geomodel().entity_type_manager().relationship_manager;
405 const auto entity_type = type_name();
408 const auto parent_types = family.parent_types( entity_type );
410 for(
const auto& parent_type : parent_types )
412 index_t nb_parent_entities_in_geomodel{
413 this->geomodel_.nb_geological_entities( parent_type )
415 if( nb_parent_entities_in_geomodel == 0 )
421 index_t nb_found_parents{ 0 };
422 for(
auto i :
range( nb_parents() ) )
424 const auto& E = parent( i );
432 while( !found && j < E.nb_children() )
434 if( E.child_gmme( j ) == id )
443 "Inconsistency parent-child between ",
id,
" and ",
449 if( nb_found_parents != 1 )
451 Logger::warn(
"GeoModelEntity",
id,
" has ", nb_found_parents,
452 " geological parent entity of type ", parent_type,
460 template < index_t DIMENSION >
463 return is_boundary_connectivity_valid()
464 && is_incident_entity_connectivity_valid();
467 template < index_t DIMENSION >
471 auto parent = parent_gmge( parent_index );
473 return this->geomodel().geological_entity( parent );
476 template < index_t DIMENSION >
481 auto id = parent_gmge( parent_type );
483 return this->geomodel().geological_entity(
id );
486 template < index_t DIMENSION >
490 return defined_parent_gmge( parent_type );
493 template < index_t DIMENSION >
497 for(
auto i :
range( nb_parents() ) )
499 if( parent_gmge( i ).type() == parent_type )
501 return parent_gmge( i );
508 template < index_t DIMENSION >
512 const auto parent_gmge = could_be_undefined_parent_gmge( parent_type );
517 template < index_t DIMENSION >
522 return this->geomodel()
523 .entity_type_manager()
524 .relationship_manager.boundary_gmme( boundaries_[x] );
527 template < index_t DIMENSION >
531 return this->geomodel().mesh_entity( boundary_gmme( x ) );
534 template < index_t DIMENSION >
538 return this->geomodel().mesh_entity( incident_entity_gmme( x ) );
541 template < index_t DIMENSION >
546 return this->geomodel()
547 .entity_type_manager()
548 .relationship_manager.incident_entity_gmme( incident_entities_[x] );
551 template < index_t DIMENSION >
556 return this->geomodel()
557 .entity_type_manager()
558 .relationship_manager.parent_of_gmme( parents_[
id] );
562 template < index_t DIMENSION >
566 for(
auto i :
range( this->nb_incident_entities() ) )
568 if( incident_entity( i ).is_on_voi() )
576 template < index_t DIMENSION >
580 if( this->nb_vertices() != 1 )
582 Logger::err(
"GeoModelEntity", this->gmme(),
" mesh has ",
583 point_set_mesh_->nb_vertices(),
" vertices " );
586 if( !point_set_mesh_->is_mesh_valid() )
588 Logger::err(
"GeoModelEntity", this->gmme(),
" mesh is invalid" );
594 template < index_t DIMENSION >
604 template < index_t DIMENSION >
609 if( !line_mesh_->is_mesh_valid() )
611 Logger::err(
"GeoModelEntity", this->gmme(),
" mesh is invalid" );
616 valid = check_range_model_vertex_ids( *
this ) && valid;
618 if( this->nb_vertices() > 1 )
621 auto nb = count_vertex_occurences( *
this );
642 if( nb.front() != 1 || nb.back() != 1 )
644 Logger::err(
"GeoModelEntity",
"Invalid extremity points in ",
651 Logger::warn(
"GeoModelEntity", nb0,
" isolated vertices in ",
660 "More than one connected component for ", this->gmme() );
665 if( nb2 != nb.size() - 2 )
668 "GeoModelEntity",
"Non-manifold entity", this->gmme() );
674 index_t nb_degenerated{ 0 };
675 for(
auto e :
range( nb_mesh_elements() ) )
677 double l = ( this->mesh_element_vertex( { e, 1 } )
678 - this->mesh_element_vertex( { e, 0 } ) )
680 if( l < this->geomodel().epsilon() )
685 if( nb_degenerated > 0 )
688 " degenerated edges in ", this->gmme() );
691 if( !is_first_corner_first_vertex() )
693 Logger::warn(
"GeoModelEntity",
"First and last vertex of Line",
695 " do not match first and second Corner respectively" );
701 template < index_t DIMENSION >
709 if( this->nb_boundaries() != 2 )
712 "Connectivity", this->gmme(),
" does not have 2 corners" );
718 template < index_t DIMENSION >
721 if( this->nb_boundaries() != 2 || this->nb_vertices() < 2 )
726 return this->boundary( 0 ).vertex( 0 ) == this->vertex( 0 )
727 && this->boundary( 1 ).vertex( 0 )
728 == this->vertex( this->nb_vertices() - 1 );
731 template < index_t DIMENSION >
742 || this->nb_incident_entities() == 2 );
743 return this->nb_incident_entities() == 1;
750 for(
auto i :
range( this->nb_incident_entities() ) )
752 if( this->incident_entity( i ).is_on_voi() )
762 template < index_t DIMENSION >
766 auto id = this->gmme();
768 if( !surface_mesh_->is_mesh_valid() )
770 Logger::err(
"GeoModelEntity", this->gmme(),
" mesh is invalid" );
776 index_t nb_degenerate{ 0 };
777 for(
auto p :
range( surface_mesh_->nb_polygons() ) )
779 if( polygon_is_degenerate( *
this,
id, p ) )
784 if( nb_degenerate != 0 )
786 Logger::warn(
"GeoModelEntity",
id,
" mesh has ", nb_degenerate,
787 " degenerate polygons " );
792 index_t cc{ compute_nb_surface_connected_components( *
this ) };
796 " connected components " );
802 template < index_t DIMENSION >
824 return static_cast< const Region3D&
>(
825 GeoModelMeshEntity3D::incident_entity( x ) );
830 template < index_t DIMENSION >
837 template < index_t DIMENSION >
843 template < index_t DIMENSION >
849 " boundary sides are invalid " );
858 region_valid =
false;
863 template < index_t DIMENSION >
872 if( !volume_mesh_->is_mesh_valid() )
880 index_t nb_degenerate{ 0 };
881 for(
auto c :
range( volume_mesh_->nb_cells() ) )
883 if( cell_is_degenerate( *
this, c ) )
888 if( nb_degenerate != 0 )
891 nb_degenerate,
" degenerate cells " );
896 index_t cc{ compute_nb_volume_connected_components( *
this ) };
900 " connected components " );
906 template < index_t DIMENSION >
910 if( gmme_.mesh_->type_name() != type )
912 gmme_.unbind_vertex_mapping_attribute();
913 gmme_.change_mesh_data_structure( type );
914 gmme_.bind_vertex_mapping_attribute();
918 template < index_t DIMENSION >
924 builder->copy( *point_set_mesh_,
true );
928 template < index_t DIMENSION >
934 builder->copy( *line_mesh_,
true );
938 template < index_t DIMENSION >
949 template < index_t DIMENSION >
955 volume_mesh_->find_cell_from_colocated_vertex_within_distance_if_any(
958 return cell_local_vertex;
961 template < index_t DIMENSION >
967 builder->copy( *volume_mesh_,
true );
974 return dynamic_cast< Surface2D&
>( gmme_ ).sides_;
981 return dynamic_cast< Region3D&
>( gmme_ ).sides_;
void change_mesh_data_structure(const MeshType &type) final
index_t nb_incident_entities() const
std::vector< bool > & modifiable_sides()
void change_mesh_data_structure(const MeshType &type) final
static std::unique_ptr< PointSetMesh< DIMENSION > > create_mesh(const MeshType type="")
const GeoModel< DIMENSION > & geomodel() const
virtual MeshEntityType type_name() const =0
const VolumeMesh< DIMENSION > & mesh() const
Get the low level mesh data structure.
GeoModelMesh< DIMENSION > mesh
Abstract base class for GeoModelMeshEntity.
GEO::vecng< DIMENSION, double > vecn
static std::unique_ptr< LineMeshBuilder > create_builder(LineMesh< DIMENSION > &mesh)
index_t mesh_element_vertex_index(const ElementLocalVertex &element_local_vertex) const final
Index of the vertex in the Surface from its index in a polygon of the mesh.
static std::unique_ptr< LineMesh< DIMENSION > > create_mesh(const MeshType type="")
bool is_inside_border(const GeoModelMeshEntity &rhs) const
Check if this entity is an inside border of rhs.
double mesh_element_size(index_t polygon_index) const final
index_t nb_mesh_element_vertices(index_t polygon_index) const final
The GeologicalEntityType described the type of the Geological entities User can defined there own Geo...
static std::unique_ptr< PointSetMeshBuilder< DIMENSION > > create_builder(PointSetMesh< DIMENSION > &mesh)
static ForbiddenGeologicalEntityType & type_name_static()
virtual bool is_connectivity_valid() const
index_t mesh_element_vertex_index(const ElementLocalVertex &element_local_vertex) const final
Index of a vertex in the Region from its index in a cell.
const Region< DIMENSION > & incident_entity(index_t x) const
bool is_first_corner_first_vertex() const
A GeoModelEntity of type CORNER.
ElementLocalVertex find_cell_from_colocated_vertex_if_any(const vecn< DIMENSION > &vertex_vec) const
bool is_parent_connectivity_valid() const
virtual bool is_on_voi() const =0
virtual index_t nb_mesh_element_vertices(index_t mesh_element_index) const =0
Number of vertices of a constitutive element of the mesh.
const GeoModelGeologicalEntity< DIMENSION > & parent(index_t parent_index) const
static void warn(const std::string &feature, const Args &... args)
std::shared_ptr< SurfaceMesh< DIMENSION > > surface_mesh_
const Surface< DIMENSION > & boundary(index_t x) const
index_t nb_boundaries() const
const gmme_id & boundary_gmme(index_t x) const
gmge_id defined_parent_gmge(const GeologicalEntityType &parent_type) const
bool is_on_voi() const final
Checks if this entity define the geomodel external boundary.
const SurfaceMesh< DIMENSION > & mesh() const
Get the low level mesh data structure.
void change_mesh_data_structure(const MeshType &type)
const gmge_id & parent_gmge(index_t id) const
static std::unique_ptr< VolumeMeshBuilder< DIMENSION > > create_builder(VolumeMesh< DIMENSION > &mesh)
A GeoModelEntity of type SURFACE.
index_t nb_mesh_element_vertices(index_t cell_index) const final
bool is_mesh_valid() const final
static void err(const std::string &feature, const Args &... args)
gmge_id could_be_undefined_parent_gmge(const GeologicalEntityType &parent_type) const
void bind_vertex_mapping_attribute() const
const Corner< DIMENSION > & boundary(index_t x) const
void update_mesh_storage_type(std::unique_ptr< SurfaceMesh< DIMENSION > > mesh)
bool is_mesh_valid() const final
Check that the mesh of the Surface is valid.
const gmme_id & incident_entity_gmme(index_t x) const
bool has_inside_border() const
Check if one entity is twice in the boundary.
virtual index_t mesh_element_vertex_index(const ElementLocalVertex &element_local_vertex) const =0
Convert the index in a mesh element to an index in the Entity.
bool is_on_voi() const final
const GeoModel< DIMENSION > & geomodel_
Reference to the GeoModel owning this entity.
virtual bool is_index_valid() const final
bool is_mesh_valid() const final
Check that the Corner mesh is a unique point.
virtual ~GeoModelMeshEntity()
#define ringmesh_assert(x)
const GeoModelMeshEntity< DIMENSION > & incident_entity(index_t x) const
virtual index_t nb_mesh_elements() const =0
Get the number constitutive elements of the mesh.
static std::unique_ptr< SurfaceMesh< DIMENSION > > create_mesh(const MeshType type="")
A GeoModelEntity of type REGION.
bool is_incident_entity_connectivity_valid() const
void unbind_vertex_mapping_attribute() const
const Line< DIMENSION > & boundary(index_t x) const
const Line< DIMENSION > & incident_entity(index_t x) const
This template is a specialization of a gme_id to the GeoModelGeologicalEntity.
void change_mesh_data_structure(const MeshType &type) final
Classes to build GeoModel from various inputs.
bool is_connectivity_valid() const final
void change_mesh_data_structure(const MeshType &type) final
A GeoModelEntity of type LINE.
bool is_on_voi() const final
bool are_geomodel_vertex_indices_valid() const
Check that geomodel vertex indices are consistent with what is stored at the GeoModel level...
bool is_boundary_connectivity_valid() const
bool is_mesh_valid() const final
Check that the mesh of the Line is valid.
static std::unique_ptr< VolumeMesh< DIMENSION > > create_mesh(const MeshType type="")
static std::unique_ptr< SurfaceMeshBuilder< DIMENSION > > create_builder(SurfaceMesh< DIMENSION > &mesh)
This template is a specialization of a gme_id to the GeoModelMeshEntity.
bool is_connectivity_valid() const final
index_t nb_vertices() const
double mesh_element_size(index_t cell_index) const final
Volume of a cell.
const GeoModelMeshEntity< DIMENSION > & boundary(index_t x) const