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)