40 #include <geogram/basic/algorithm.h> 51 template < index_t DIMENSION >
54 : builder_( builder ),
55 geomodel_( geomodel ),
56 geomodel_access_( geomodel )
60 template < index_t DIMENSION >
91 template < index_t DIMENSION >
105 geomodel_.mesh.remove_colocated_vertices();
116 template < index_t DIMENSION >
120 std::set< gmme_id > empty_mesh_entities;
121 std::set< gmge_id > empty_geological_entities;
124 if( !empty_mesh_entities.empty() )
126 builder_.topology.get_dependent_entities(
127 empty_mesh_entities, empty_geological_entities );
128 builder_.removal.remove_mesh_entities( empty_mesh_entities );
132 template < index_t DIMENSION >
136 std::set< gmme_id > empty_mesh_entities;
140 if( !empty_mesh_entities.empty() )
142 builder_.removal.remove_mesh_entities( empty_mesh_entities );
147 geomodel_.mesh.remove_colocated_vertices();
152 template < index_t DIMENSION >
155 for(
const auto& line :
geomodel_.lines() )
157 if( !line.is_first_corner_first_vertex() )
159 const auto first_boundary_index = line.boundary( 0 ).index();
160 builder_.topology.set_mesh_entity_boundary(
161 line.gmme(), 0, line.boundary_gmme( 1 ).index() );
162 builder_.topology.set_mesh_entity_boundary(
163 line.gmme(), 1, first_boundary_index );
172 for(
const auto& surface :
geomodel_.surfaces() )
176 for(
const auto& region :
geomodel_.regions() )
178 if( region.is_meshed() )
189 for(
const auto& surface :
geomodel_.surfaces() )
191 if( surface.is_meshed() )
198 template < index_t DIMENSION >
201 for(
const auto& line :
geomodel_.lines() )
207 template < index_t DIMENSION >
212 std::vector< bool > vertices_to_delete(
214 for(
auto mesh_element_index :
219 mesh_element_index ) ) )
221 vertices_to_delete[geomodel_mesh_entity
223 { mesh_element_index, vertex } )] =
227 builder_.geometry.delete_mesh_entity_vertices(
228 geomodel_mesh_entity.
gmme(), vertices_to_delete );
231 template < index_t DIMENSION >
235 std::vector< index_t >& colocated_vertices )
238 if( nb_vertices != 3 )
240 std::vector< index_t > vertices( nb_vertices );
241 for(
auto v :
range( nb_vertices ) )
248 return vertices.size() != nb_vertices;
251 { polygon_id, 0 } )];
253 { polygon_id, 1 } )];
255 { polygon_id, 2 } )];
256 return v1 == v2 || v2 == v3 || v3 == v1;
259 template < index_t DIMENSION >
260 std::vector< index_t >
263 std::vector< index_t >& colocated_vertices )
271 return f_is_degenerate;
274 template < index_t DIMENSION >
278 std::vector< index_t > colocated;
280 std::tie( std::ignore, colocated ) =
281 nn_search.get_colocated_index_mapping(
geomodel_.epsilon() );
285 return static_cast< index_t
>(
286 std::count( degenerate.begin(), degenerate.end(), 1 ) );
289 template < index_t DIMENSION >
293 std::vector< index_t >& colocated_vertices )
301 return e_is_degenerate;
304 template < index_t DIMENSION >
308 std::vector< index_t > colocated;
310 std::tie( std::ignore, colocated ) =
311 nn_search.get_colocated_index_mapping(
geomodel_.epsilon() );
314 auto nb =
static_cast< index_t
>(
315 std::count( degenerate.begin(), degenerate.end(), 1 ) );
318 builder_.geometry.delete_line_edges( line.
index(), degenerate, false );
322 template < index_t DIMENSION >
327 for(
const auto& line :
geomodel_.lines() )
333 " degenerated edges removed in LINE ", line.index() );
335 if( line.nb_mesh_elements() == 0 )
337 to_remove.insert( line.gmme() );
344 for(
const auto& surface :
geomodel_.surfaces() )
353 if( surface.nb_vertices() > 0 )
357 auto mode =
static_cast< GEO::MeshRepairMode
>( 2 );
358 auto builder =
builder_.geometry.create_surface_builder(
360 builder->repair( mode, 0.0 );
363 builder->remove_small_connected_components( epsilon_sq, 3 );
366 if( surface.nb_vertices() > 0 )
368 builder->repair( mode, 0.0 );
371 if( surface.nb_vertices() == 0
372 || surface.nb_mesh_elements() == 0 )
374 to_remove.insert( surface.gmme() );
380 template < index_t DIMENSION >
385 std::set< index_t > vertices;
390 const auto& mesh_entity =
geomodel_.mesh_entity( E_id );
393 if( mesh_entity.boundary( 0 ).is_inside_border( mesh_entity ) )
395 vertices.insert( mesh_entity.nb_vertices() - 1 );
399 std::vector< const GeoModelMeshEntity< DIMENSION >* > inside_border;
400 for(
auto i :
range( mesh_entity.nb_boundaries() ) )
402 if( mesh_entity.boundary( i ).is_inside_border( mesh_entity ) )
404 inside_border.push_back(
406 &mesh_entity.boundary( i ) ) );
409 if( !inside_border.empty() )
414 const auto& nn_search = mesh_entity.vertex_nn_search();
416 for(
const auto& entity : inside_border )
418 for(
auto v :
range( entity->nb_vertices() ) )
420 auto colocated_indices = nn_search.get_neighbors(
421 entity->vertex( v ),
geomodel_.epsilon() );
422 if( colocated_indices.size() > 1 )
424 std::sort( colocated_indices.begin(),
425 colocated_indices.end() );
428 vertices.insert( colocated_indices.begin() + 1,
429 colocated_indices.end() );
437 template < index_t DIMENSION >
439 std::set< gmme_id >& to_remove )
443 std::array< const MeshEntityType, 2 > types{
447 for(
const auto& type : types )
452 const auto& E =
geomodel_.mesh_entity( entity_id );
454 const auto& kdtree = E.vertex_nn_search();
455 std::vector< index_t > colocated;
456 std::tie( std::ignore, colocated ) =
457 kdtree.get_colocated_index_mapping(
geomodel_.epsilon() );
462 std::vector< bool > to_delete( colocated.size(), false );
463 index_t nb_todelete{ 0 };
464 for(
auto v :
range( colocated.size() ) )
466 if( colocated[v] == v
467 || inside_border.find( v ) != inside_border.end() )
480 if( nb_todelete == 0 )
485 if( nb_todelete == E.nb_vertices() )
488 to_remove.insert( E.gmme() );
494 builder_.geometry.create_surface_builder( e );
495 for(
auto p_itr :
range( E.nb_mesh_elements() ) )
498 range( E.nb_mesh_element_vertices( p_itr ) ) )
500 builder->set_polygon_vertex( { p_itr, fpv_itr },
501 colocated[E.mesh_element_vertex_index(
502 { p_itr, fpv_itr } )] );
505 builder->delete_vertices( to_delete );
507 " colocated vertices deleted in ", entity_id );
511 auto builder =
builder_.geometry.create_line_builder( e );
512 for(
auto e_itr :
range( E.nb_mesh_elements() ) )
514 builder->set_edge_vertex(
515 { e_itr, 0 }, colocated[E.mesh_element_vertex_index(
517 builder->set_edge_vertex(
518 { e_itr, 1 }, colocated[E.mesh_element_vertex_index(
521 builder->delete_vertices( to_delete );
523 " colocated vertices deleted in ", entity_id );
533 template < index_t DIMENSION >
537 const std::vector< index_t >& colocated_vertices )
546 template < index_t DIMENSION >
bool edge_is_degenerate(const Line< DIMENSION > &line, index_t edge, const std::vector< index_t > &colocated_vertices)
Checks if an edge is degenerate.
std::vector< bool > line_detect_degenerate_edges(const Line< DIMENSION > &line, std::vector< index_t > &colocated_vertices)
Abstract base class for GeoModelMeshEntity.
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.
index_t nb_mesh_element_vertices(index_t polygon_index) const final
bool polygon_is_degenerate(const Surface< DIMENSION > &surface, index_t polygon_id, std::vector< index_t > &colocated_vertices)
Tests whether a polygon is degenerate.
void remove_degenerate_polygons_and_edges(std::set< gmme_id > &to_remove)
Remove degenerate polygons and edges from the Surface and Line of the geomodel.
void remove_degenerate_polygons_and_edges_and_update_gm()
std::set< index_t > vertices_on_inside_boundary(const gmme_id &E_id)
const NNSearch< DIMENSION > & vertex_nn_search() const
Return the NNSearch for the Entity vertices.
virtual index_t nb_mesh_element_vertices(index_t mesh_element_index) const =0
Number of vertices of a constitutive element of the mesh.
static MeshEntityType type_name_static()
GeoModelBuilderRepair(GeoModelBuilder< DIMENSION > &builder, GeoModel< DIMENSION > &geomodel)
Entity_type_template type() const
index_t detect_degenerate_polygons(const Surface< DIMENSION > &surface)
Detect and remove degenerated polygons in a Surface.
std::vector< index_t > surface_detect_degenerate_polygons(const Surface< DIMENSION > &surface, std::vector< index_t > &colocated_vertices)
static MeshEntityType type_name_static()
void sort_unique(CONTAINER &container, const CMP &cmp)
Sorts a container and suppresses all duplicated entities.
index_t nb_mesh_elements() const final
index_t mesh_element_vertex_index(const ElementLocalVertex &element_local_vertex) const final
Get the index of a vertex in the Line from the.
static void out(const std::string &feature, const Args &... args)
static MeshEntityType type_name_static()
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.
void repair(RepairMode repair_mode)
Repair a GeoModel according a repair mode.
void remove_isolated_vertices_on_mesh_entity(const GeoModelMeshEntity< DIMENSION > &geomodel_mesh_entity)
remove isolated vertices on a GeoModelMeshEntity
void remove_colocated_entity_vertices_and_update_gm()
index_t repair_line_mesh(const Line< DIMENSION > &line)
Detect and remove degenerate edges in a.
virtual index_t nb_mesh_elements() const =0
Get the number constitutive elements of the mesh.
GeoModel< DIMENSION > & geomodel_
Classes to build GeoModel from various inputs.
Try repairing a supposedly invalid GeoModel.
A GeoModelEntity of type LINE.
index_t nb_mesh_elements() const final
GeoModelBuilder< DIMENSION > & builder_
This template is a specialization of a gme_id to the GeoModelMeshEntity.
index_t nb_vertices() const
void remove_isolated_vertices_base()
void remove_isolated_vertices()
remove isolated vertices on GeoModelMeshEntities
void remove_colocated_entity_vertices(std::set< gmme_id > &to_remove)
Remove colocated vertices of the geomodel.
void repair_line_boundary_vertex_order()
For all the lines in the geomodel, switch line boundaries if the way of their indices does not follow...
void geomodel_mesh_repair()
#define ringmesh_assert_not_reached