38 #include <geogram/basic/attributes.h> 48 template < index_t DIMENSION >
49 std::set< index_t > get_internal_borders(
52 std::set< index_t > internal_borders;
59 internal_borders.insert( border.
index() );
62 return internal_borders;
75 template < index_t DIMENSION >
76 std::tuple< bool, index_t, index_t > find_polygon_from_edge_vertices(
81 index_t polygon = NO_ID;
86 [&surface, &v0, &v1, &result, &edge, &polygon]( index_t i ) {
93 index_t j_next = surface.
mesh()
100 v1, surface.
geomodel().epsilon() ) )
111 return std::make_tuple( result, polygon, edge );
114 template < index_t DIMENSION >
121 index_t nb_cell_facet_vertices =
123 index_t nb_polygon_vertices =
125 if( nb_cell_facet_vertices != nb_polygon_vertices )
129 vec3 cell_facet_barycenter = region.
mesh().cell_facet_barycenter(
132 return inexact_equal( cell_facet_barycenter, polygon_barycenter,
136 template < index_t DIMENSION >
137 std::tuple< bool, index_t, index_t > find_cell_facet_from_polygon(
142 index_t cell = NO_ID;
143 index_t cell_facet = NO_ID;
147 v_bary, [®ion, &surface, polygon, &result, &cell_facet, &cell](
151 if( are_cell_facet_and_polygon_equal(
152 region, i, cell_facet_i, surface, polygon ) )
154 cell_facet = cell_facet_i;
162 return std::make_tuple( result, cell, cell_facet );
165 template < index_t DIMENSION >
173 v, [&surface, &v, &result, &vertex_id, &element_id]( index_t i ) {
192 template < index_t DIMENSION >
193 index_t edge_index_from_polygon_and_edge_vertex_indices(
225 template < index_t DIMENSION >
226 index_t cell_facet_index_from_cell_and_polygon(
236 vec3 cell_facet_barycenter =
238 if(
inexact_equal( cell_facet_barycenter, polygon_barycenter,
247 template < index_t DIMENSION >
248 void check_and_initialize_corner_vertex(
251 if( geomodel.
corner( corner_id ).nb_vertices() == 0 )
254 builder.geometry.create_mesh_entity_vertices(
263 template < index_t DIMENSION >
266 : builder_( builder ),
267 geomodel_( geomodel ),
268 geomodel_access_( geomodel )
272 template < index_t DIMENSION >
275 geomodel_.mesh.vertices.clear();
278 template < index_t DIMENSION >
287 template < index_t DIMENSION >
295 geomodel_access_.modifiable_mesh_entity( t );
297 geomodel_.mesh.vertices;
307 std::unique_ptr< MeshBaseBuilder< DIMENSION > > builder =
314 template < index_t DIMENSION >
316 const gmme_id& entity_id, index_t v, index_t geomodel_vertex )
319 geomodel_.mesh.vertices;
320 set_mesh_entity_vertex(
321 entity_id, v, geomodel_vertices.
vertex( geomodel_vertex ), false );
323 ringmesh_assert( v < geomodel_.mesh_entity( entity_id ).nb_vertices() );
325 entity_id, v, geomodel_vertex );
328 template < index_t DIMENSION >
335 geomodel_access_.modifiable_mesh_entity(
id );
337 std::unique_ptr< MeshBaseBuilder< DIMENSION > > builder =
343 builder->
clear(
true,
true );
345 if( !points.empty() )
347 auto nb_points =
static_cast< index_t
>( points.size() );
348 index_t start = builder->create_vertices( nb_points );
349 for(
auto v :
range( nb_points ) )
351 builder->set_vertex( start + v, points[v] );
356 template < index_t DIMENSION >
359 const gmme_id& entity_id, index_t nb_vertices )
362 geomodel_access_.modifiable_mesh_entity( entity_id );
364 std::unique_ptr< MeshBaseBuilder< DIMENSION > > builder =
370 template < index_t DIMENSION >
373 const std::vector< index_t >& geomodel_vertices,
377 geomodel_access_.modifiable_mesh_entity( entity_id );
379 std::unique_ptr< MeshBaseBuilder< DIMENSION > > builder =
385 builder->
clear(
true,
true );
387 auto nb_model_vertices =
388 static_cast< index_t
>( geomodel_vertices.size() );
389 index_t start = builder->create_vertices( nb_model_vertices );
390 for(
auto v :
range( nb_model_vertices ) )
392 set_mesh_entity_vertex(
393 entity_id, start + v, geomodel_vertices[v] );
397 template < index_t DIMENSION >
401 check_and_initialize_corner_vertex( geomodel_, corner_id );
402 set_mesh_entity_vertex(
407 template < index_t DIMENSION >
411 set_mesh_entity_vertices(
416 geomodel_access_.modifiable_mesh_entity(
418 std::unique_ptr< LineMeshBuilder< DIMENSION > > builder =
419 create_line_builder( line_id );
420 for(
auto e :
range( 1, line.nb_vertices() ) )
422 builder->create_edge( e - 1, e );
426 template < index_t DIMENSION >
430 const std::vector< index_t >& surface_polygons,
431 const std::vector< index_t >& surface_polygon_ptr )
433 set_mesh_entity_vertices(
435 surface_vertices,
true );
436 set_surface_geometry(
437 surface_id, surface_polygons, surface_polygon_ptr );
440 template < index_t DIMENSION >
443 const std::vector< index_t >& polygons,
444 const std::vector< index_t >& polygon_ptr )
446 std::unique_ptr< SurfaceMeshBuilder< DIMENSION > > builder =
447 create_surface_builder( surface_id );
448 builder->create_polygons( polygons, polygon_ptr );
449 compute_surface_adjacencies( surface_id );
452 template < index_t DIMENSION >
454 index_t corner_id, index_t geomodel_vertex_id )
456 check_and_initialize_corner_vertex( geomodel_, corner_id );
457 set_mesh_entity_vertex(
459 geomodel_vertex_id );
462 template < index_t DIMENSION >
464 index_t line_id,
const std::vector< index_t >& unique_vertices )
466 bool clear_vertices =
false;
468 geomodel_access_.modifiable_mesh_entity(
475 set_mesh_entity_vertices( E.
gmme(), unique_vertices, clear_vertices );
477 std::unique_ptr< LineMeshBuilder< DIMENSION > > builder =
478 create_line_builder( line_id );
481 builder->create_edge( e - 1, e );
485 template < index_t DIMENSION >
489 const std::vector< index_t >& corners )
491 std::unique_ptr< SurfaceMeshBuilder< DIMENSION > > builder =
492 create_surface_builder( surface_id );
493 for(
auto polygon_vertex :
range( corners.size() ) )
495 builder->set_polygon_vertex(
497 corners[polygon_vertex] );
501 template < index_t DIMENSION >
503 index_t surface_id,
const std::vector< index_t >& vertex_indices )
505 std::unique_ptr< SurfaceMeshBuilder< DIMENSION > > builder =
506 create_surface_builder( surface_id );
507 return builder->create_polygon( vertex_indices );
510 template < index_t DIMENSION >
515 geomodel_access_.modifiable_mesh_entity( E_id ) );
516 std::unique_ptr< MeshBaseBuilder< DIMENSION > > builder =
518 *gmme_access.modifiable_mesh() );
519 builder->clear(
true,
false );
522 template < index_t DIMENSION >
526 if( geomodel_.entity_type_manager().mesh_entity_manager.is_line(
529 std::unique_ptr< LineMeshBuilder< DIMENSION > > builder =
530 create_line_builder( E_id.
index() );
531 builder->remove_isolated_vertices();
533 else if( geomodel_.entity_type_manager().mesh_entity_manager.is_surface(
536 std::unique_ptr< SurfaceMeshBuilder< DIMENSION > > builder =
537 create_surface_builder( E_id.
index() );
538 builder->remove_isolated_vertices();
540 else if( geomodel_.entity_type_manager().mesh_entity_manager.is_corner(
543 std::unique_ptr< PointSetMeshBuilder< DIMENSION > > builder =
544 create_corner_builder( E_id.
index() );
545 builder->remove_isolated_vertices();
553 template < index_t DIMENSION >
555 const gmme_id& E_id,
const std::vector< bool >& to_delete )
558 geomodel_access_.modifiable_mesh_entity( E_id ) );
559 std::unique_ptr< MeshBaseBuilder< DIMENSION > > builder =
561 *gmme_access.modifiable_mesh() );
562 builder->delete_vertices( to_delete );
565 template < index_t DIMENSION >
570 std::vector< bool > to_delete;
571 to_delete.push_back(
true );
572 delete_mesh_entity_vertices( corner, to_delete );
574 template < index_t DIMENSION >
577 const std::vector< bool >& to_delete,
578 bool remove_isolated_vertices )
580 std::unique_ptr< LineMeshBuilder< DIMENSION > > builder =
581 create_line_builder( line_id );
582 builder->delete_edges( to_delete, remove_isolated_vertices );
584 template < index_t DIMENSION >
587 const std::vector< bool >& to_delete,
588 bool remove_isolated_vertices )
590 std::unique_ptr< SurfaceMeshBuilder< DIMENSION > > builder =
591 create_surface_builder( surface_id );
592 builder->delete_polygons( to_delete, remove_isolated_vertices );
595 template < index_t DIMENSION >
600 const std::vector< index_t >& adjacents )
602 std::unique_ptr< SurfaceMeshBuilder< DIMENSION > > builder =
603 create_surface_builder( surface_id );
604 for(
auto polygon_edge :
range( adjacents.size() ) )
606 builder->set_polygon_adjacent(
608 adjacents[polygon_edge] );
612 template < index_t DIMENSION >
614 index_t surface_id,
bool recompute_adjacency )
617 std::unique_ptr< SurfaceMeshBuilder< DIMENSION > > builder =
618 create_surface_builder( surface_id );
620 if( recompute_adjacency )
626 builder->set_polygon_adjacent(
631 builder->connect_polygons();
634 template < index_t DIMENSION >
638 for(
const auto& surface : geomodel_.surfaces() )
640 std::set< index_t > cutting_lines = get_internal_borders( surface );
641 for(
auto line_id : cutting_lines )
643 cut_surface_by_line( surface.
index(), line_id );
645 if( !cutting_lines.empty() )
647 std::unique_ptr< SurfaceMeshBuilder< DIMENSION > >
648 surface_mesh_builder =
649 create_surface_builder( surface.
index() );
650 surface_mesh_builder->remove_isolated_vertices();
655 template < index_t DIMENSION >
657 index_t surface_id, index_t line_id )
659 index_t nb_disconnected_edges =
660 disconnect_surface_polygons_along_line_edges( surface_id, line_id );
661 if( nb_disconnected_edges > 0 )
663 duplicate_surface_vertices_along_line( surface_id, line_id );
673 template < index_t DIMENSION >
676 index_t surface_id, index_t line_id )
686 std::vector< ElementVertex > polygon_vertices( line.
nb_vertices() );
691 index_t& polygon_vertex = polygon_vertices[v].vertex_;
692 index_t& polygon = polygon_vertices[v].element_;
694 find_polygon_from_vertex( surface, p, polygon, polygon_vertex );
697 found && polygon != NO_ID && polygon_vertex != NO_ID );
701 create_mesh_entity_vertices( surface_gme, line.
nb_vertices() );
702 std::unique_ptr< SurfaceMeshBuilder< DIMENSION > >
703 surface_mesh_builder = create_surface_builder( surface_id );
708 const index_t& polygon_vertex = polygon_vertices[v].vertex_;
709 const index_t& polygon = polygon_vertices[v].element_;
711 std::vector< index_t > polygons =
713 update_polygon_vertex(
714 surface_id, polygons, polygon_vertex, vertex_id );
715 surface_mesh_builder->set_vertex( vertex_id, p );
720 template < index_t DIMENSION >
723 index_t surface_id, index_t line_id )
730 std::unique_ptr< SurfaceMeshBuilder< DIMENSION > > builder =
731 create_surface_builder( surface_id );
732 index_t nb_disconnected_edges{ 0 };
741 std::tie( found, p, e ) =
742 find_polygon_from_edge_vertices( surface, p0, p1 );
750 index_t adj_e = edge_index_from_polygon_and_edge_vertex_indices(
751 surface, adj_f, p0, p1 );
753 builder->set_polygon_adjacent(
755 builder->set_polygon_adjacent(
757 nb_disconnected_edges++;
760 return nb_disconnected_edges;
762 template < index_t DIMENSION >
765 const std::vector< index_t >& polygons,
770 std::unique_ptr< SurfaceMeshBuilder< DIMENSION > > builder =
771 create_surface_builder( surface_id );
772 for(
auto cur_p : polygons )
781 builder->set_polygon_vertex(
787 template < index_t DIMENSION >
791 for(
auto i :
range( geomodel_.nb_mesh_entities( entity_type ) ) )
793 copy_mesh( from,
gmme_id( entity_type, i ) );
797 template < index_t DIMENSION >
803 assign_mesh_to_entity( *from_E_const_access.mesh(), mesh_entity );
806 template < index_t DIMENSION >
811 geomodel_access_.modifiable_mesh_entity( to );
813 std::unique_ptr< MeshBaseBuilder< DIMENSION > > builder =
816 builder->
copy( mesh,
true );
820 const std::vector< index_t >& cells,
824 const Region3D& region = geomodel_.region( region_id );
825 std::unique_ptr< VolumeMeshBuilder3D > builder =
826 create_region_builder( region_id );
827 for(
auto cur_c : cells )
830 range( region.nb_mesh_element_vertices( cur_c ) ) )
832 if( region.mesh_element_vertex_index(
836 builder->set_cell_vertex(
844 index_t region_id,
const std::vector< index_t >& tet_vertices )
846 std::unique_ptr< VolumeMeshBuilder3D > builder =
847 create_region_builder( region_id );
848 builder->assign_cell_tet_mesh( tet_vertices );
849 builder->connect_cells();
854 index_t region_id, index_t surface_id )
859 const Region3D& region = geomodel_.region( region_id );
860 const Surface3D& surface = geomodel_.surface( surface_id );
861 std::unique_ptr< VolumeMeshBuilder3D > builder =
862 create_region_builder( region_id );
863 index_t nb_disconnected_polygons{ 0 };
864 for(
auto polygon :
range( surface.nb_mesh_elements() ) )
867 index_t cell = NO_ID;
868 index_t cell_facet = NO_ID;
869 std::tie( found, cell, cell_facet ) =
870 find_cell_facet_from_polygon( region, surface, polygon );
874 index_t adj_cell = region.cell_adjacent_index( cell, cell_facet );
875 if( adj_cell != NO_ID )
877 index_t adj_cell_facet = cell_facet_index_from_cell_and_polygon(
878 region, adj_cell, surface, polygon );
880 builder->set_cell_adjacent(
882 builder->set_cell_adjacent(
884 nb_disconnected_polygons++;
887 return nb_disconnected_polygons;
891 index_t region_id, index_t surface_id )
896 gmme_id region_gme( Region3D::type_name_static(), region_id );
897 const Region3D& region = geomodel_.region( region_id );
898 const Surface3D& surface = geomodel_.surface( surface_id );
900 std::vector< ElementVertex > cell_vertices( surface.nb_vertices() );
901 for(
auto v :
range( surface.nb_vertices() ) )
905 index_t& cell = cell_vertices[v].element_;
906 index_t& cell_vertex = cell_vertices[v].vertex_;
908 region.find_cell_from_colocated_vertex_if_any( p );
915 GEO::vector< std::string > names;
916 geomodel_.region( region_id )
917 .vertex_attribute_manager()
918 .list_attribute_names( names );
920 GeoModelMeshEntity3D& E =
921 geomodel_access_.modifiable_mesh_entity( region_gme );
922 index_t vertices_nb = E.nb_vertices();
925 create_mesh_entity_vertices( region_gme, surface.nb_vertices() );
927 std::unique_ptr< VolumeMeshBuilder3D > region_mesh_builder =
928 create_region_builder( region_id );
930 for(
auto v :
range( surface.nb_vertices() ) )
933 const index_t& cell = cell_vertices[v].element_;
934 const index_t& cell_vertex = cell_vertices[v].vertex_;
936 std::vector< index_t > cells =
938 update_cell_vertex( region_id, cells, cell_vertex, vertex_id );
939 region_mesh_builder->set_vertex( vertex_id, p );
942 for(
const auto& name : names )
944 if( name !=
"model_vertex_map" && name !=
"point" )
946 GEO::Attribute< double > attr(
947 geomodel_.region( region_id )
948 .vertex_attribute_manager(),
950 index_t dim_nb = attr.dimension();
951 for(
auto dim :
range( dim_nb ) )
953 attr[( vertices_nb + v ) * dim_nb + dim] =
954 attr[cell_vertex * dim_nb + dim];
962 index_t region_id, index_t surface_id )
964 index_t nb_disconnected_polygons =
965 disconnect_region_cells_along_surface_polygons(
966 region_id, surface_id );
967 if( nb_disconnected_polygons > 0 )
969 duplicate_region_vertices_along_surface( region_id, surface_id );
975 for(
const auto& region : geomodel_.regions() )
981 std::set< index_t > cutting_surfaces =
982 get_internal_borders( region );
983 for(
auto surface_id : cutting_surfaces )
985 cut_region_by_surface( region.
index(), surface_id );
987 if( !cutting_surfaces.empty() )
989 std::unique_ptr< VolumeMeshBuilder3D > region_mesh_builder =
990 create_region_builder( region.
index() );
991 region_mesh_builder->remove_isolated_vertices();
997 const std::vector< vec3 >& points,
998 const std::vector< index_t >& tetras )
1000 set_mesh_entity_vertices(
1001 gmme_id( Region3D::type_name_static(), region_id ), points,
true );
1002 assign_region_tet_mesh( region_id, tetras );
1006 index_t region_id,
bool recompute_adjacency )
1008 const Region3D& region = geomodel_.region( region_id );
1009 std::unique_ptr< VolumeMeshBuilder3D > builder =
1010 create_region_builder( region_id );
1011 if( recompute_adjacency )
1013 for(
auto c :
range( region.nb_mesh_elements() ) )
1015 for(
auto f :
range( region.nb_cell_facets( c ) ) )
1021 builder->connect_cells();
1025 const std::vector< bool >& to_delete,
1026 bool remove_isolated_vertices )
1028 std::unique_ptr< VolumeMeshBuilder3D > builder =
1029 create_region_builder( region_id );
1030 builder->delete_cells( to_delete, remove_isolated_vertices );
1034 index_t region_id,
CellType type, index_t nb_cells )
1036 std::unique_ptr< VolumeMeshBuilder3D > builder =
1037 create_region_builder( region_id );
1038 return builder->create_cells( nb_cells, type );
1044 const std::vector< index_t >& corners )
1046 std::unique_ptr< VolumeMeshBuilder3D > builder =
1047 create_region_builder( region_id );
1048 for(
auto cell_vertex :
range( corners.size() ) )
1050 builder->set_cell_vertex(
1052 corners[cell_vertex] );
1058 if( geomodel_.entity_type_manager().mesh_entity_manager.is_region(
1061 std::unique_ptr< VolumeMeshBuilder3D > builder =
1062 create_region_builder( E_id.
index() );
1063 builder->remove_isolated_vertices();
1074 const std::vector< index_t >& vertex_indices )
1076 index_t cell_id = create_region_cells( region_id, type, 1 );
1077 set_region_element_geometry( region_id, cell_id, vertex_indices );
1083 GeoModelBuilderGeometryBase3D::copy_meshes( geomodel );
1084 GeoModelBuilderGeometryBase3D::copy_meshes(
1085 geomodel, Region3D::type_name_static() );
const GeoModel< DIMENSION > & geomodel() const
const VolumeMesh< DIMENSION > & mesh() const
Get the low level mesh data structure.
void update_point(index_t v, const vecn< DIMENSION > &point)
Set the point coordinates of all the vertices that share this unique vertex, including the unique ver...
Abstract base class for GeoModelMeshEntity.
GEO::vecng< DIMENSION, double > vecn
const NNSearch< DIMENSION > & polygon_nn_search() const
Return the NNSearch for the polygons of the surface.
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.
void update_vertex_mapping(const gmme_id &entity_id, index_t entity_vertex_index, index_t geomodel_vertex_index)
bool is_inside_border(const GeoModelMeshEntity &rhs) const
Check if this entity is an inside border of rhs.
virtual const vecn< DIMENSION > & vertex(index_t v_id) const =0
Gets a point.
const vecn< DIMENSION > & vertex(index_t vertex_index) const
Coordinates of the vertex_index.
index_t nb_cell_facets(index_t cell_index) const
index_t nb_mesh_element_vertices(index_t polygon_index) const final
virtual const GeoModelMeshEntity< DIMENSION > & mesh_entity(const gmme_id &id) const
Generic access to a meshed entity.
void ringmesh_unused(const T &)
A GeoModelEntity of type CORNER.
const Corner< DIMENSION > & corner(index_t index) const
index_t nb_boundaries() const
std::vector< index_t > polygons_around_vertex(index_t vertex_id, bool border_only, index_t first_polygon) const
Determines the polygons around a vertex.
void copy(const MeshBase< DIMENSION > &rhs, bool copy_attributes)
Copy a mesh into this one.
Entity_type_template type() const
const SurfaceMesh< DIMENSION > & mesh() const
Get the low level mesh data structure.
vecn< DIMENSION > mesh_element_barycenter(index_t polygon_index) const final
index_t nb_mesh_elements() const final
index_t nb_mesh_elements() const final
const NNSearch< DIMENSION > & cell_nn_search() const
Return the NNSearch for the cells of the region.
index_t create_vertices(index_t nb)
Creates a contiguous chunk of vertices.
void set_vertex(index_t v_id, const vecn< DIMENSION > &vertex)
Sets a point.
const vecn< DIMENSION > & vertex(index_t v) const
Coordinates of a vertex of the GeoModel.
encapsulate adimensional mesh functionalities in order to provide an API on which we base the RINGMes...
ElementLocalVertex prev_polygon_vertex(const ElementLocalVertex &polygon_local_vertex) const
Gets the previous vertex index in the polygon.
GeoModelBuilderGeometryBase(GeoModelBuilder< DIMENSION > &builder, GeoModel< DIMENSION > &geomodel)
index_t nb_cell_facet_vertices(index_t cell_index, index_t facet_index) const
index_t geomodel_vertex_id(const gmme_id &mesh_entity, index_t entity_vertex_index=0) const
Get the GeoModelMesh index of a GeoModelMeshEntity vertex from its index in that GeoModelMeshEntity.
#define ringmesh_assert(x)
vecn< DIMENSION > cell_facet_barycenter(const CellLocalFacet &cell_local_facet) const
A GeoModelEntity of type REGION.
The MeshEntityType described the type of the meshed entities There are 4 MeshEntityTypes correspondin...
Classes to build GeoModel from various inputs.
ElementLocalVertex next_polygon_vertex(const ElementLocalVertex &polygon_local_vertex) const
Gets the next vertex index in the polygon vertex.
A GeoModelEntity of type LINE.
const vecn< DIMENSION > & mesh_element_vertex(const ElementLocalVertex &element_local_vertex) const
Coordinates of a vertex of a mesh element.
index_t nb_mesh_elements() const final
std::vector< index_t > cells_around_vertex(index_t vertex_id, index_t cell_hint) const
This template is a specialization of a gme_id to the GeoModelMeshEntity.
bool inexact_equal(const vecn< DIMENSION > &v1, const vecn< DIMENSION > &v2, double epsilon)
index_t nb_vertices() const
void clear(bool keep_attributes, bool keep_memory)
Removes all the entities and attributes of this mesh.
#define ringmesh_assert_not_reached
const GeoModelMeshEntity< DIMENSION > & boundary(index_t x) const
std::shared_ptr< MeshBase< DIMENSION > > & modifiable_mesh()