39 template< index_t >
class GeoModelBuilderGM;
43 if( type == Corner3D::type_name_static() )
return true;
44 if( type == Line3D::type_name_static() )
return true;
45 if( type == Surface3D::type_name_static() )
return true;
46 if( type == Region3D::type_name_static() )
return true;
50 template< index_t DIMENSION >
51 class GeoModelBuilderGMImpl {
53 GeoModelBuilderGMImpl(
54 GeoModelBuilderGM< DIMENSION >& builder,
56 : builder_( builder ), geomodel_( geomodel )
59 virtual ~GeoModelBuilderGMImpl() =
default;
61 virtual void read_mesh_entity_line( GEO::LineInput& file_line ) = 0;
64 GeoModelBuilderGM< DIMENSION >& builder_;
68 template< index_t DIMENSION >
69 class GeoModelBuilderGMImpl_0:
public GeoModelBuilderGMImpl< DIMENSION > {
71 GeoModelBuilderGMImpl_0(
72 GeoModelBuilderGM< DIMENSION >& builder,
74 : GeoModelBuilderGMImpl< DIMENSION >( builder, geomodel )
77 virtual ~GeoModelBuilderGMImpl_0() =
default;
79 void read_mesh_entity_line( GEO::LineInput& file_line )
override 82 if( file_line.nb_fields() < 4 ) {
84 file_line.line_number(),
85 ", 4 fields are expected, the type, id, name, and geological feature" );
87 auto entity = read_first_line( file_line );
88 read_second_line( file_line, entity );
92 virtual gmme_id read_first_line( GEO::LineInput& file_line )
95 file_line.field_as_uint( 1 ) };
96 this->builder_.info.set_mesh_entity_name( cur_gmme,
97 file_line.field( 2 ) );
100 void read_second_line( GEO::LineInput& file_line,
const gmme_id& entity );
102 template<
template< index_t >
class ENTITY >
103 void add_relation_for_entities_with_sides(
105 GEO::LineInput& file_line )
107 for(
auto c :
range( file_line.nb_fields() ) ) {
109 if( std::strncmp( file_line.field( c ),
"+", 1 ) == 0 ) {
113 GEO::String::from_string( &file_line.field( c )[1], s );
115 this->builder_.topology.add_mesh_entity_boundary_relation( entity, {
116 ENTITY< DIMENSION >::type_name_static(), s }, side );
120 void add_relation_for_entities_with_no_side(
122 GEO::LineInput& file_line )
124 const auto& manager =
125 this->geomodel_.entity_type_manager().mesh_entity_manager;
126 auto type = manager.boundary_entity_type( entity.
type() );
128 for(
auto c :
range( 1, file_line.nb_fields() ) ) {
129 gmme_id boundary { type, file_line.field_as_uint( c ) };
130 this->builder_.topology.add_mesh_entity_boundary_relation( entity,
137 void GeoModelBuilderGMImpl_0< 2 >::read_second_line(
138 GEO::LineInput& file_line,
141 file_line.get_line();
142 file_line.get_fields();
143 const auto& manager =
144 this->geomodel_.entity_type_manager().mesh_entity_manager;
145 if( manager.is_surface( entity.
type() ) ) {
146 add_relation_for_entities_with_sides< Line >( entity, file_line );
148 add_relation_for_entities_with_no_side( entity, file_line );
153 void GeoModelBuilderGMImpl_0< 3 >::read_second_line(
154 GEO::LineInput& file_line,
157 file_line.get_line();
158 file_line.get_fields();
159 const auto& manager =
160 this->geomodel_.entity_type_manager().mesh_entity_manager;
161 if( manager.is_region( entity.
type() ) ) {
162 add_relation_for_entities_with_sides< Surface >( entity, file_line );
164 add_relation_for_entities_with_no_side( entity, file_line );
168 template< index_t DIMENSION >
169 class GeoModelBuilderGMImpl_1:
public GeoModelBuilderGMImpl_0< DIMENSION > {
171 GeoModelBuilderGMImpl_1(
172 GeoModelBuilderGM< DIMENSION >& builder,
174 : GeoModelBuilderGMImpl_0< DIMENSION >( builder, geomodel )
177 virtual ~GeoModelBuilderGMImpl_1() =
default;
179 void read_mesh_entity_line( GEO::LineInput& file_line )
override 183 if( file_line.nb_fields() < 5 ) {
185 file_line.line_number(),
186 ", 5 fields are expected, the type, id, name, ",
187 "geological feature, and mesh type" );
189 auto entity = this->read_first_line( file_line );
191 const auto mesh_type = file_line.field( 4 );
192 if( GEO::String::string_starts_with( mesh_type,
"Geogram" ) ) {
193 this->builder_.geometry.change_mesh_data_structure( entity,
194 old_2_new_name( mesh_type ) );
196 this->builder_.geometry.change_mesh_data_structure( entity,
200 this->read_second_line( file_line, entity );
203 const std::string& old_2_new_name(
const std::string& old_name )
205 auto new_name_pos = GEO::String::to_uint(
206 GEO::String::to_string( old_name.at( old_name.length() - 2 ) ) );
207 return new_names[new_name_pos];
210 static const std::string new_names[4];
213 template< index_t DIMENSION >
214 const std::string GeoModelBuilderGMImpl_1< DIMENSION >::new_names[4] = {
215 std::string(
"GeogramPointSetMesh" ), std::string(
"GeogramLineMesh" ),
216 std::string(
"GeogramSurfaceMesh" ), std::string(
"GeogramVolumeMesh" ) };
218 template< index_t DIMENSION >
219 class GeoModelBuilderGMImpl_2:
public GeoModelBuilderGMImpl_1< DIMENSION > {
221 GeoModelBuilderGMImpl_2(
222 GeoModelBuilderGM< DIMENSION >& builder,
224 : GeoModelBuilderGMImpl_1< DIMENSION >( builder, geomodel )
227 virtual ~GeoModelBuilderGMImpl_2() =
default;
229 void read_mesh_entity_line( GEO::LineInput& file_line )
override 233 if( file_line.nb_fields() < 4 ) {
235 file_line.line_number(),
236 ", 4 fields are expected, the type, id, name, ",
237 "geological feature, and mesh type" );
239 auto entity = this->read_first_line( file_line );
241 const auto mesh_type = file_line.field( 3 );
242 this->builder_.geometry.change_mesh_data_structure( entity, mesh_type );
244 this->read_second_line( file_line, entity );
248 template< index_t DIMENSION >
251 static const index_t NB_VERSION = 3;
255 version_impl_[0].reset(
256 new GeoModelBuilderGMImpl_0< DIMENSION >( *
this, geomodel ) );
257 version_impl_[1].reset(
258 new GeoModelBuilderGMImpl_1< DIMENSION >( *
this, geomodel ) );
259 version_impl_[2].reset(
260 new GeoModelBuilderGMImpl_2< DIMENSION >( *
this, geomodel ) );
262 virtual ~GeoModelBuilderGM() =
default;
265 void load_geological_entities(
const std::string& geological_entity_file )
267 GEO::LineInput file_line { geological_entity_file };
268 while( !file_line.eof() && file_line.get_line() ) {
269 file_line.get_fields();
270 if( file_line.nb_fields() > 0 ) {
272 if( file_line.field_matches( 0,
"No" )
273 && file_line.field_matches( 1,
"geological" )
274 && file_line.field_matches( 2,
"entity" ) ) {
278 if( file_line.field_matches( 0,
"Nb" ) ) {
280 this->geology.create_geological_entities(
282 file_line.field_as_uint( 2 ) );
285 auto id = file_line.field_as_uint( 1 );
287 this->info.set_geological_entity_name( entity,
288 file_line.field( 2 ) );
289 this->geology.set_geological_entity_geol_feature( entity,
291 file_line.field( 3 ) ) );
292 file_line.get_line();
293 file_line.get_fields();
294 for(
auto in_b :
range( file_line.nb_fields() ) ) {
295 this->geology.add_parent_children_relation( entity,
296 { this->geomodel_.entity_type_manager().relationship_manager.child_type(
298 file_line.field_as_uint( in_b ) } );
314 std::vector< std::future< void > > files;
317 if( GEO::FileSystem::extension( file_name ) ==
"txt" ) {
323 std::async( std::launch::deferred,
325 auto file_without_extension = GEO::FileSystem::base_name(
327 std::string entity_type, entity_id;
328 GEO::String::split_string( file_without_extension,
'_', entity_type,
330 index_t
id { NO_ID };
331 GEO::String::from_string( entity_id,
id );
333 GEO::FileSystem::delete_file( file_name );
337 for(
auto& file : files ) {
343 void load_mesh_entity(
345 const std::string& file_name,
348 bool load_mesh_entity_base(
350 const std::string& file_name,
353 const auto& manager =
354 this->geomodel_.entity_type_manager().mesh_entity_manager;
355 if( manager.is_corner( entity_type ) ) {
356 auto builder = this->geometry.create_corner_builder(
id );
357 builder->load_mesh( file_name );
359 }
else if( manager.is_line( entity_type ) ) {
360 auto builder = this->geometry.create_line_builder(
id );
361 builder->load_mesh( file_name );
363 }
else if( manager.is_surface( entity_type ) ) {
364 auto builder = this->geometry.create_surface_builder(
id );
365 builder->load_mesh( file_name );
371 void load_file() final
375 const std::string mesh_entity_file(
"mesh_entities.txt" );
377 load_mesh_entities( mesh_entity_file );
378 auto ok = GEO::FileSystem::delete_file( mesh_entity_file );
383 const std::string geological_entity_file {
"geological_entities.txt" };
384 uz.
get_file( geological_entity_file );
385 load_geological_entities( geological_entity_file );
386 ok = GEO::FileSystem::delete_file( geological_entity_file );
390 void load_mesh_entities(
const std::string& mesh_entity_file )
392 GEO::LineInput file_line { mesh_entity_file };
393 while( !file_line.eof() && file_line.get_line() ) {
395 file_line.get_fields();
396 if( file_line.nb_fields() > 0 ) {
397 if( file_line.field_matches( 0,
"Version" ) ) {
398 file_version_ = file_line.field_as_uint( 1 );
401 else if( file_line.field_matches( 0,
"GeoModel" ) ) {
402 if( file_line.nb_fields() > 2 ) {
403 this->info.set_geomodel_name( file_line.field( 2 ) );
407 else if( file_line.field_matches( 0,
"Nb" ) ) {
409 this->topology.create_mesh_entities(
411 file_line.field_as_uint( 2 ) );
414 else if( match_mesh_entity_type(
416 version_impl_[file_version_]->read_mesh_entity_line(
423 void load_region_if_entity_is_region(
424 const std::string& entity_type,
426 const std::string& file_name,
429 index_t file_version_ { 0 };
430 std::unique_ptr< GeoModelBuilderGMImpl< DIMENSION > > version_impl_[NB_VERSION];
434 void GeoModelBuilderGM< 2 >::load_mesh_entity(
436 const std::string& file_name,
439 load_mesh_entity_base( entity_type, file_name,
id );
443 void GeoModelBuilderGM< 3 >::load_mesh_entity(
445 const std::string& file_name,
448 if( !load_mesh_entity_base( entity_type, file_name,
id ) ) {
449 const auto& manager =
450 this->geomodel_.entity_type_manager().mesh_entity_manager;
451 if( manager.is_region( entity_type ) ) {
452 auto builder = geometry.create_region_builder(
id );
453 builder->load_mesh( file_name );
461 template< index_t DIMENSION >
462 void save_geological_entity(
467 out << E.
gmge() <<
" " << E.
name() <<
" ";
484 template< index_t DIMENSION >
485 void save_geological_entities(
487 const std::string& file_name )
489 std::ofstream out { file_name.c_str() };
498 out <<
"No geological entity in the geomodel" <<
EOL;
504 out <<
"Nb " << type <<
" " << nb <<
EOL;
509 for(
auto j :
range( nb ) ) {
516 template<
typename ENTITY, index_t DIMENSION >
517 void save_mesh_entities_of_type(
523 const ENTITY& cur_mesh_entity =
524 dynamic_cast< const ENTITY&
>( geomodel.
mesh_entity( type, e ) );
525 out << type <<
" " << e <<
" " << cur_mesh_entity.name() <<
" " 526 << cur_mesh_entity.mesh().type_name() <<
EOL;
528 for(
auto b :
range( cur_mesh_entity.nb_boundaries() ) ) {
529 out << cur_mesh_entity.boundary_gmme( b ).index() <<
" ";
535 void save_dimension( index_t dimension, std::ofstream& out )
537 out <<
"Dimension " << dimension <<
EOL;
540 template< index_t DIMENSION >
541 void save_version_and_name(
545 out <<
"Version 2" <<
EOL;
546 out <<
"GeoModel name " << geomodel.
name() <<
EOL;
549 template< index_t DIMENSION >
550 void save_number_of_mesh_entities_base(
563 template< index_t DIMENSION >
564 void save_number_of_mesh_entities(
566 std::ofstream& out );
569 void save_number_of_mesh_entities(
570 const GeoModel2D& geomodel,
573 save_number_of_mesh_entities_base( geomodel, out );
577 void save_number_of_mesh_entities(
578 const GeoModel3D& geomodel,
581 save_number_of_mesh_entities_base( geomodel, out );
582 out <<
"Nb " <<
Region < 3
583 > ::type_name_static() <<
" " << geomodel.nb_regions() <<
EOL;
586 template< index_t DIMENSION >
587 void save_mesh_entities_topology_and_sides(
589 std::ofstream& out );
591 template<
template< index_t >
class ENTITY, index_t DIMENSION >
592 void save_mesh_entities_topology_and_sides_impl(
598 const ENTITY< DIMENSION >& E =
599 static_cast< const ENTITY< DIMENSION >&
>( geomodel.
mesh_entity(
600 ENTITY< DIMENSION >::type_name_static(), i ) );
602 out << E.gmme() <<
" " << E.
name() <<
" " << E.mesh().type_name() <<
EOL;
604 for(
auto j :
range( E.nb_boundaries() ) ) {
610 out << E.boundary_gmme( j ).index() <<
" ";
617 void save_mesh_entities_topology_and_sides(
618 const GeoModel2D& geomodel,
621 save_mesh_entities_topology_and_sides_impl< Surface >( geomodel, out );
625 void save_mesh_entities_topology_and_sides(
626 const GeoModel3D& geomodel,
629 save_mesh_entities_topology_and_sides_impl< Region >( geomodel, out );
633 template< index_t DIMENSION >
634 void save_mesh_entities_topology_base(
638 save_mesh_entities_of_type< Corner< DIMENSION > >( geomodel, out );
639 save_mesh_entities_of_type< Line< DIMENSION > >( geomodel, out );
642 template< index_t DIMENSION >
643 void save_mesh_entities_topology(
645 std::ofstream& out );
648 void save_mesh_entities_topology(
649 const GeoModel2D& geomodel,
652 save_mesh_entities_topology_base( geomodel, out );
656 void save_mesh_entities_topology(
657 const GeoModel3D& geomodel,
660 save_mesh_entities_topology_base( geomodel, out );
661 save_mesh_entities_of_type< Surface3D >( geomodel, out );
669 template< index_t DIMENSION >
670 void save_mesh_entities(
672 const std::string& file_name )
674 std::ofstream out( file_name.c_str() );
680 save_dimension( DIMENSION, out );
681 save_version_and_name( geomodel, out );
682 save_number_of_mesh_entities( geomodel, out );
683 save_mesh_entities_topology( geomodel, out );
684 save_mesh_entities_topology_and_sides( geomodel, out );
688 template< index_t DIMENSION >
691 const std::string& name );
695 const GeoModelMeshEntity3D& geomodel_entity_mesh,
696 const std::string& name )
698 if( geomodel_entity_mesh.type_name() == Region3D::type_name_static() ) {
699 const auto& region = geomodel_entity_mesh.geomodel().region(
700 geomodel_entity_mesh.index() );
701 if( !region.is_meshed() ) {
706 geomodel_entity_mesh.save( name );
712 const GeoModelMeshEntity2D& geomodel_entity_mesh,
713 const std::string& name )
715 if( geomodel_entity_mesh.type_name() == Surface2D::type_name_static() ) {
716 const auto& surface = geomodel_entity_mesh.geomodel().surface(
717 geomodel_entity_mesh.index() );
718 if( !surface.is_meshed() ) {
722 geomodel_entity_mesh.save( name );
726 template<
typename ENTITY >
727 std::string build_string_for_geomodel_entity_export(
const ENTITY& entity )
729 const auto&
id = entity.gmme();
730 std::string base_name =
id.type().string() +
"_" 731 + std::to_string(
id.index() );
732 return base_name +
"." + entity.mesh().default_extension();
740 template<
typename ENTITY >
741 void save_geomodel_mesh_entity(
742 const ENTITY& geomodel_entity_mesh,
743 std::vector< std::string >& filenames )
745 static std::mutex lock;
746 auto name = build_string_for_geomodel_entity_export( geomodel_entity_mesh );
747 if( save_mesh( geomodel_entity_mesh, name ) ) {
748 std::lock_guard< std::mutex > locking( lock );
749 filenames.push_back( name );
753 void zip_files(
const std::vector< std::string >& filenames,
ZipFile& zf )
755 for(
const std::string& name : filenames ) {
757 GEO::FileSystem::delete_file( name );
761 template<
template< index_t >
class ENTITY, index_t DIMENSION >
762 void save_geomodel_mesh_entities(
764 std::vector< std::string >& filenames )
766 const auto& type = ENTITY< DIMENSION >::type_name_static();
768 auto logger_status = logger->is_quiet();
769 logger->set_quiet(
true );
771 [&geomodel, &type, &filenames]( index_t i ) {
773 dynamic_cast< const ENTITY< DIMENSION >&
>( geomodel.
mesh_entity(
775 save_geomodel_mesh_entity< ENTITY< DIMENSION > >( entity, filenames );
777 logger->set_quiet( logger_status );
780 template< index_t DIMENSION >
781 void save_all_geomodel_mesh_entities_base(
783 std::vector< std::string >& filenames )
785 save_geomodel_mesh_entities< Corner, DIMENSION >( geomodel, filenames );
786 save_geomodel_mesh_entities< Line, DIMENSION >( geomodel, filenames );
787 save_geomodel_mesh_entities< Surface, DIMENSION >( geomodel, filenames );
790 template< index_t DIMENSION >
791 void save_all_geomodel_mesh_entities(
793 std::vector< std::string >& filenames );
796 void save_all_geomodel_mesh_entities(
797 const GeoModel2D& geomodel,
798 std::vector< std::string >& filenames )
800 save_all_geomodel_mesh_entities_base( geomodel, filenames );
803 void save_all_geomodel_mesh_entities(
804 const GeoModel3D& geomodel,
805 std::vector< std::string >& filenames )
807 save_all_geomodel_mesh_entities_base( geomodel, filenames );
808 save_geomodel_mesh_entities< Region, 3 >( geomodel, filenames );
811 template< index_t DIMENSION >
815 index_t nb_mesh_entities(
const GeoModel2D& geomodel )
817 return geomodel.nb_corners() + geomodel.nb_lines() + geomodel.nb_surfaces();
821 index_t nb_mesh_entities(
const GeoModel3D& geomodel )
823 return geomodel.nb_corners() + geomodel.nb_lines() + geomodel.nb_surfaces()
824 + geomodel.nb_regions();
827 index_t find_dimension(
const std::string& mesh_entities_filename )
829 GEO::LineInput file_line { mesh_entities_filename };
830 while( !file_line.eof() && file_line.get_line() ) {
831 file_line.get_fields();
832 if( file_line.nb_fields() == 2 ) {
833 if( file_line.field_matches( 0,
"Dimension" ) ) {
834 return file_line.field_as_uint( 1 );
841 template< index_t DIMENSION >
846 auto pwd = GEO::FileSystem::get_current_working_directory();
847 GEO::FileSystem::set_current_working_directory(
848 GEO::FileSystem::dir_name( filename ) );
849 GeoModelBuilderGM< DIMENSION > builder { geomodel,
850 GEO::FileSystem::base_name(
852 builder.build_geomodel();
853 GEO::FileSystem::set_current_working_directory( pwd );
858 const std::string& filename )
final 862 const std::string mesh_entity_file {
"mesh_entities.txt" };
863 save_mesh_entities( geomodel, mesh_entity_file );
865 GEO::FileSystem::delete_file( mesh_entity_file );
867 const std::string geological_entity_file {
"geological_entities.txt" };
868 save_geological_entities( geomodel, geological_entity_file );
869 zf.
add_file( geological_entity_file );
870 GEO::FileSystem::delete_file( geological_entity_file );
872 auto nb_mesh_entites = nb_mesh_entities( geomodel );
873 std::vector< std::string > filenames;
874 filenames.reserve( nb_mesh_entites );
876 save_all_geomodel_mesh_entities( geomodel, filenames );
878 std::sort( filenames.begin(), filenames.end() );
879 zip_files( filenames, zf );
882 index_t dimension(
const std::string& filename )
const final 885 const std::string mesh_entity_file(
"mesh_entities.txt" );
887 auto dimension = find_dimension( mesh_entity_file );
888 auto ok = GEO::FileSystem::delete_file( mesh_entity_file );
893 virtual ~GeoModelHandlerGM() =
default;
895 void save_geomodel_regions(
897 std::vector< std::string >& filenames );
Abstract base class for GeoModelMeshEntity.
void get_file(const std::string &filename)
static std::string geol_name(GEOL_FEATURE feature)
The GeologicalEntityType described the type of the Geological entities User can defined there own Geo...
virtual const GeoModelMeshEntity< DIMENSION > & mesh_entity(const gmme_id &id) const
Generic access to a meshed entity.
GEOL_FEATURE geological_feature() const
void ringmesh_unused(const T &)
void add_file(const std::string &filename)
static MeshEntityType type_name_static()
Abstract interface class to load and build GeoModels from files.
Entity_type_template type() const
index_t nb_geological_entity_types() const
Returns the index of the geological entity type storage.
std::string get_current_filename()
const std::string & name() const
Gets the name of the GeoModel.
static MeshEntityType type_name_static()
const std::string & name() const
static GEO::Logger * instance()
static MeshEntityType type_name_static()
const gmme_id & child_gmme(index_t x) const
const GeologicalEntityType & geological_entity_type(index_t index) const
index_t nb_corners() const
#define ringmesh_assert(x)
index_t nb_surfaces() const
index_t nb_children() const
A GeoModelEntity of type REGION.
The MeshEntityType described the type of the meshed entities There are 4 MeshEntityTypes correspondin...
This template is a specialization of a gme_id to the GeoModelGeologicalEntity.
Classes to build GeoModel from various inputs.
const GeoModelGeologicalEntity< DIMENSION > & geological_entity(gmge_id id) const
Returns a const reference the identified GeoModelGeologicalEntity.
virtual index_t nb_mesh_entities(const MeshEntityType &type) const
Returns the number of mesh entities of the given type.
This template is a specialization of a gme_id to the GeoModelMeshEntity.
index_t nb_geological_entities(const GeologicalEntityType &type) const
Returns the number of geological entities of the given type.
void parallel_for(index_t size, const ACTION &action)