37     struct RINGMesh2CSMP {
    45     static RINGMesh2CSMP tet_descriptor = { 4,                  
    52     static RINGMesh2CSMP hex_descriptor = { 6,                         
    54         { 0, 4, 5, 1, 2, 6, 7, 3 },     
    59     static RINGMesh2CSMP prism_descriptor = { 12,                     
    66     static RINGMesh2CSMP pyramid_descriptor = { 18,                 
    73     static RINGMesh2CSMP* cell_type_to_cell_descriptor[4] = { &tet_descriptor,
    76                                                               &pyramid_descriptor };
    78     class CSMPIOHandler final: 
public GeoModelIOHandler< 3 > {
    85         void load( 
const std::string& filename, GeoModel3D& geomodel ) 
final    89             throw RINGMeshException( 
"I/O",
    90                 "Loading of a GeoModel from CSMP not implemented yet" );
    92         void save( 
const GeoModel3D& geomodel, 
const std::string& filename ) 
final    94             initialize( geomodel );
    96             std::string directory = GEO::FileSystem::dir_name( filename );
    97             std::string file = GEO::FileSystem::base_name( filename );
    99             std::ostringstream oss_ascii;
   100             oss_ascii << directory << 
"/" << file << 
".asc";
   101             std::ofstream ascii( oss_ascii.str().c_str() );
   102             ascii.precision( 16 );
   104             ascii << geomodel.name() << 
EOL;
   105             ascii << 
"Model generated from RINGMesh" << 
EOL;
   107             std::ostringstream oss_data;
   108             oss_data << directory << 
"/" << file << 
".dat";
   109             std::ofstream data( oss_data.str().c_str() );
   110             data.precision( 16 );
   112             std::ostringstream oss_regions;
   113             oss_regions << directory << 
"/" << file << 
"-regions.txt";
   114             std::ofstream regions( oss_regions.str().c_str() );
   115             regions << 
"'" << oss_regions.str() << 
EOL;
   116             regions << 
"no properties" << 
EOL;
   118             const GeoModelMesh3D& mesh = geomodel.mesh;
   119             const GeoModelMeshPolygons3D& polygons = mesh.polygons;
   122             signed_index_t conversion_sign[3] = { 1, 1, -1 };
   123             index_t conversion_axis[3] = { 0, 2, 1 };
   124             data << mesh.vertices.nb() << 
" # PX, PY, PZ" << 
EOL;
   125             for( 
auto dim : range( 3 ) ) {
   126                 for( 
auto v : range( mesh.vertices.nb() ) ) {
   128                         << conversion_sign[dim]
   129                             * mesh.vertices.vertex( v )[conversion_axis[dim]];
   130                     new_line( count, 5, data );
   132                 reset_line( count, data );
   134             reset_line( count, data );
   136             index_t nb_families = 0;
   137             index_t nb_interfaces = geomodel.nb_geological_entities(
   138                 Interface3D::type_name_static() );
   139             std::vector< index_t > nb_triangle_interface( nb_interfaces, 0 );
   140             std::vector< index_t > nb_quad_interface( nb_interfaces, 0 );
   141             for( 
auto i : range( nb_interfaces ) ) {
   142                 const GeoModelGeologicalEntity3D& interf =
   143                     geomodel.geological_entity( Interface3D::type_name_static(), i );
   144                 for( 
auto s : range( interf.nb_children() ) ) {
   145                     index_t s_id = interf.child_gmme( s ).index();
   146                     nb_triangle_interface[i] += polygons.nb_triangle( s_id );
   147                     nb_quad_interface[i] += polygons.nb_quad( s_id );
   149                 if( nb_triangle_interface[i] > 0 ) nb_families++;
   150                 if( nb_quad_interface[i] > 0 ) nb_families++;
   152             for( 
auto r : range( geomodel.nb_regions() ) ) {
   153                 if( mesh.cells.nb_tet( r ) > 0 ) nb_families++;
   154                 if( mesh.cells.nb_pyramid( r ) > 0 ) nb_families++;
   155                 if( mesh.cells.nb_prism( r ) > 0 ) nb_families++;
   156                 if( mesh.cells.nb_hex( r ) > 0 ) nb_families++;
   158             if( geomodel.wells() ) nb_families += geomodel.wells()->nb_wells();
   160             ascii << nb_families << 
" # Number of families" << 
EOL;
   161             ascii << 
"# Object name" << 
TAB << 
"Entity type" << 
TAB << 
"Material-ID"   162                 << 
TAB << 
"Number of entities" << 
EOL;
   163             for( 
const auto& region : geomodel.regions() ) {
   164                 regions << region.name() << 
EOL;
   165                 std::string entity_type[4] = { 
"TETRA_4", 
"HEXA_8", 
"PENTA_6",
   167                 for( 
auto type : range(
   171                     if( mesh.cells.nb_cells( region.index(), T ) > 0 ) {
   172                         ascii << region.name() << 
TAB << entity_type[type] << 
TAB   173                             << 0 << 
TAB << mesh.cells.nb_cells( region.index(), T )
   178             for( 
auto i : range( nb_interfaces ) ) {
   179                 regions << interface_csmp_name( i, geomodel ) << 
EOL;
   180                 if( nb_triangle_interface[i] > 0 ) {
   181                     ascii << interface_csmp_name( i, geomodel ) << 
TAB << 
"TRI_3"   182                         << 
TAB << 0 << 
TAB << nb_triangle_interface[i] << 
EOL;
   184                 if( nb_quad_interface[i] > 0 ) {
   185                     ascii << interface_csmp_name( i, geomodel ) << 
TAB << 
"QUAD_4"   186                         << 
TAB << 0 << 
TAB << nb_quad_interface[i] << 
EOL;
   189             if( geomodel.wells() ) {
   190                 for( 
auto w : range( geomodel.wells()->nb_wells() ) ) {
   191                     const Well3D& well = geomodel.wells()->well( w );
   192                     regions << well.name() << 
EOL;
   193                     ascii << well.name() << 
TAB << 
"BAR_2" << 
TAB << 0 << 
TAB   194                         << well.nb_edges() << 
EOL;
   198             data << 
"# PBFLAGS" << 
EOL;
   199             for( 
auto p : range( mesh.vertices.nb() ) ) {
   200                 data << 
" " << std::setw( 3 ) << point_boundary( p );
   201                 new_line( count, 20, data );
   203             reset_line( count, data );
   205             data << 
"# PBVALS" << 
EOL;
   206             for( 
auto p : range( mesh.vertices.nb() ) ) {
   208                 data << 
" " << std::setw( 3 ) << 0;
   209                 new_line( count, 20, data );
   211             reset_line( count, data );
   213             index_t nb_total_entities = mesh.cells.nb_cells()
   214                 + polygons.nb_polygons() + mesh.wells.nb_edges();
   215             data << nb_total_entities << 
" # PELEMENT" << 
EOL;
   216             for( 
auto r : range( geomodel.nb_regions() ) ) {
   217                 index_t entity_type[4] = { 4, 6, 12, 18 };
   218                 for( 
auto type : range(
   222                     for( 
auto el : range( mesh.cells.nb_cells( r, T ) ) ) {
   224                         data << 
" " << std::setw( 3 ) << entity_type[type];
   225                         new_line( count, 20, data );
   229             for( 
auto i : range( nb_interfaces ) ) {
   230                 for( 
auto el : range( nb_triangle_interface[i] ) ) {
   232                     data << 
" " << std::setw( 3 ) << 8;
   233                     new_line( count, 20, data );
   235                 for( 
auto el : range( nb_quad_interface[i] ) ) {
   237                     data << 
" " << std::setw( 3 ) << 14;
   238                     new_line( count, 20, data );
   241             if( geomodel.wells() ) {
   242                 for( 
auto w : range( geomodel.wells()->nb_wells() ) ) {
   243                     const Well3D& well = geomodel.wells()->well( w );
   244                     for( 
auto e : range( well.nb_edges() ) ) {
   246                         data << 
" " << std::setw( 3 ) << 2;
   247                         new_line( count, 20, data );
   251             reset_line( count, data );
   254                 << 
"# now the entities which make up each object are listed in sequence"   256             index_t cur_cell = 0;
   257             for( 
auto r : range( geomodel.nb_regions() ) ) {
   258                 const RINGMesh::GeoModelEntity3D& region = geomodel.region( r );
   259                 std::string entity_type[4] = { 
"TETRA_4", 
"HEXA_8", 
"PENTA_6",
   261                 for( 
auto type : range(
   265                     if( mesh.cells.nb_cells( r, T ) > 0 ) {
   266                         ascii << region.name() << 
" " << entity_type[type] << 
" "   267                             << mesh.cells.nb_cells( r, T ) << 
EOL;
   268                         for( 
auto el : range( mesh.cells.nb_cells( r, T ) ) ) {
   270                             ascii << cur_cell++ << 
" ";
   271                             new_line( count, 10, ascii );
   273                         reset_line( count, ascii );
   277             for( 
auto i : range( nb_interfaces ) ) {
   278                 if( nb_triangle_interface[i] > 0 ) {
   279                     ascii << interface_csmp_name( i, geomodel ) << 
" " << 
"TRI_3"   280                         << 
" " << nb_triangle_interface[i] << 
EOL;
   281                     for( 
auto el : range( nb_triangle_interface[i] ) ) {
   283                         ascii << cur_cell++ << 
" ";
   284                         new_line( count, 10, ascii );
   286                     reset_line( count, ascii );
   288                 if( nb_quad_interface[i] > 0 ) {
   289                     ascii << interface_csmp_name( i, geomodel ) << 
" " << 
"QUAD_4"   290                         << 
" " << nb_quad_interface[i] << 
EOL;
   291                     for( 
auto el : range( nb_quad_interface[i] ) ) {
   293                         ascii << cur_cell++ << 
" ";
   294                         new_line( count, 10, ascii );
   296                     reset_line( count, ascii );
   299             if( geomodel.wells() ) {
   300                 for( 
auto w : range( geomodel.wells()->nb_wells() ) ) {
   301                     const Well3D& well = geomodel.wells()->well( w );
   302                     ascii << well.name() << 
" " << 
"BAR_2" << 
" " << well.nb_edges()
   304                     for( 
auto e : range( well.nb_edges() ) ) {
   306                         ascii << cur_cell++ << 
" ";
   307                         new_line( count, 10, ascii );
   309                     reset_line( count, ascii );
   313             index_t nb_plist = 3 * polygons.nb_triangle() + 4 * polygons.nb_quad()
   314                 + 4 * mesh.cells.nb_tet() + 5 * mesh.cells.nb_pyramid()
   315                 + 6 * mesh.cells.nb_prism() + 8 * mesh.cells.nb_hex()
   316                 + 2 * mesh.wells.nb_edges();
   317             data << nb_plist << 
" # PLIST" << 
EOL;
   318             for( 
auto r : range( geomodel.nb_regions() ) ) {
   319                 for( 
auto type : range(
   323                     RINGMesh2CSMP& descriptor = *cell_type_to_cell_descriptor[type];
   324                     for( 
auto el : range( mesh.cells.nb_cells( r, T ) ) ) {
   325                         index_t cell = mesh.cells.cell( r, el, T );
   326                         for( 
auto p : range( descriptor.nb_vertices ) ) {
   327                             index_t csmp_p = descriptor.vertices[p];
   328                             index_t vertex_id = mesh.cells.vertex(
   329                                 ElementLocalVertex( cell, csmp_p ) );
   330                             data << 
" " << std::setw( 7 ) << vertex_id;
   331                             new_line( count, 10, data );
   336             for( 
auto i : range( nb_interfaces ) ) {
   337                 const GeoModelGeologicalEntity3D& interf =
   338                     geomodel.geological_entity( Interface3D::type_name_static(), i );
   339                 for( 
auto s : range( interf.nb_children() ) ) {
   340                     index_t s_id = interf.child_gmme( s ).index();
   341                     for( 
auto el : range( polygons.nb_triangle( s_id ) ) ) {
   342                         index_t tri = polygons.triangle( s_id, el );
   343                         for( 
auto p : range( polygons.nb_vertices( tri ) ) ) {
   344                             index_t vertex_id = polygons.vertex(
   345                                 ElementLocalVertex( tri, p ) );
   346                             data << 
" " << std::setw( 7 ) << vertex_id;
   347                             new_line( count, 10, data );
   350                     for( 
auto el : range( polygons.nb_quad( s_id ) ) ) {
   351                         index_t quad = polygons.quad( s_id, el );
   352                         for( 
auto p : range( polygons.nb_vertices( quad ) ) ) {
   353                             index_t vertex_id = polygons.vertex(
   354                                 ElementLocalVertex( quad, p ) );
   355                             data << 
" " << std::setw( 7 ) << vertex_id;
   356                             new_line( count, 10, data );
   361             for( 
auto w : range( mesh.wells.nb_wells() ) ) {
   362                 for( 
auto e : range( mesh.wells.nb_edges( w ) ) ) {
   363                     for( 
auto v : range( 2 ) ) {
   364                         index_t vertex_id = mesh.wells.vertex( w, e, v );
   365                         data << 
" " << std::setw( 7 ) << vertex_id;
   366                         new_line( count, 10, data );
   370             reset_line( count, data );
   372             index_t nb_polygons = 3 * polygons.nb_triangle() + 4 * polygons.nb_quad()
   373                 + 4 * mesh.cells.nb_tet() + 5 * mesh.cells.nb_pyramid()
   374                 + 5 * mesh.cells.nb_prism() + 6 * mesh.cells.nb_hex()
   375                 + 2 * mesh.wells.nb_edges();
   376             data << nb_polygons << 
" # PFVERTS" << 
EOL;
   377             for( 
auto r : range( geomodel.nb_regions() ) ) {
   378                 for( 
auto type : range(
   382                     RINGMesh2CSMP& descriptor = *cell_type_to_cell_descriptor[type];
   383                     for( 
auto el : range( mesh.cells.nb_cells( r, T ) ) ) {
   384                         index_t cell = mesh.cells.cell( r, el );
   385                         for( 
auto p : range( descriptor.nb_polygons ) ) {
   386                             index_t csmp_f = descriptor.polygon[p];
   387                             index_t adj = mesh.cells.adjacent( cell, csmp_f );
   388                             if( adj == GEO::NO_CELL ) {
   389                                 data << 
" " << std::setw( 7 ) << -28;
   391                                 data << 
" " << std::setw( 7 ) << adj;
   393                             new_line( count, 10, data );
   398             for( 
auto i : range( nb_interfaces ) ) {
   399                 const GeoModelGeologicalEntity3D& interf =
   400                     geomodel.geological_entity( Interface3D::type_name_static(), i );
   401                 for( 
auto s : range( interf.nb_children() ) ) {
   402                     index_t s_id = interf.child_gmme( s ).index();
   403                     for( 
auto el : range( polygons.nb_triangle( s_id ) ) ) {
   404                         index_t tri = polygons.triangle( s_id, el );
   405                         for( 
auto e : range( polygons.nb_vertices( tri ) ) ) {
   406                             index_t adj = polygons.adjacent(
   407                                 PolygonLocalEdge( tri, e ) );
   408                             if( adj == GEO::NO_FACET ) {
   409                                 data << 
" " << std::setw( 7 ) << -28;
   411                                 data << 
" " << std::setw( 7 ) << adj;
   413                             new_line( count, 10, data );
   416                     for( 
auto el : range( polygons.nb_quad( s_id ) ) ) {
   417                         index_t quad = polygons.quad( s_id, el );
   418                         for( 
auto e : range( polygons.nb_vertices( quad ) ) ) {
   419                             index_t adj = polygons.adjacent(
   420                                 PolygonLocalEdge( quad, e ) );
   421                             if( adj == GEO::NO_FACET ) {
   422                                 data << 
" " << std::setw( 7 ) << -28;
   424                                 data << 
" " << std::setw( 7 ) << adj;
   426                             new_line( count, 10, data );
   431             index_t edge_offset = polygons.nb() + mesh.cells.nb();
   432             index_t cur_edge = 0;
   433             for( 
auto w : range( mesh.wells.nb_wells() ) ) {
   434                 data << 
" " << std::setw( 7 ) << -28;
   435                 new_line( count, 10, data );
   436                 if( mesh.wells.nb_edges( w ) > 1 ) {
   437                     data << 
" " << std::setw( 7 ) << edge_offset + cur_edge + 1;
   439                     new_line( count, 10, data );
   440                     for( index_t e = 1; e < mesh.wells.nb_edges( w ) - 1;
   442                         data << 
" " << std::setw( 7 ) << edge_offset + cur_edge - 1;
   443                         new_line( count, 10, data );
   444                         data << 
" " << std::setw( 7 ) << edge_offset + cur_edge + 1;
   445                         new_line( count, 10, data );
   447                     data << 
" " << std::setw( 7 ) << edge_offset + cur_edge - 1;
   448                     new_line( count, 10, data );
   450                 data << 
" " << std::setw( 7 ) << -28;
   452                 new_line( count, 10, data );
   454             reset_line( count, data );
   456             data << nb_total_entities << 
" # PMATERIAL" << 
EOL;
   457             for( 
auto i : range( nb_total_entities ) ) {
   459                 data << 
" " << std::setw( 3 ) << 0;
   460                 new_line( count, 20, data );
   465             regions << std::flush;
   471             index_t number_of_counts,
   472             std::ofstream& out )
 const   475             if( count == number_of_counts ) {
   480         void reset_line( index_t& count, std::ofstream& out )
 const   489             point_boundaries_.clear();
   497             corner_boundary_flags_.clear();
   498             edge_boundary_flags_.clear();
   499             surface_boundary_flags_.clear();
   501         void initialize( 
const GeoModel3D& gm )
   505             const GeoModel3D& geomodel = gm;
   506             std::string cmsp_filename = GEO::CmdLine::get_arg( 
"out:csmp" );
   507             box_model_ = cmsp_filename != 
"";
   509                 GEO::LineInput parser( cmsp_filename );
   511                     throw RINGMeshException( 
"I/O", 
"Cannot open file: ",
   516                 while( !parser.eof() ) {
   517                     if( parser.nb_fields() == 0 ) 
continue;
   518                     if( parser.nb_fields() != 3 ) 
return;
   519                     std::string type = parser.field( 1 );
   520                     index_t interface_id = NO_ID;
   521                     if( type == 
"NAME" ) {
   522                         std::string name = parser.field( 2 );
   523                         GeologicalEntityType type = Interface3D::type_name_static();
   524                         for( 
auto& cur_interface : geomodel.geol_entities( type ) ) {
   525                             if( cur_interface.name() == name ) {
   526                                 interface_id = cur_interface.index();
   530                     } 
else if( type == 
"ID" ) {
   531                         interface_id = parser.field_as_uint( 2 );
   533                         throw RINGMeshException( 
"I/O", 
"Unknown type: ", type );
   536                     std::string keyword = parser.field( 0 );
   537                     if( keyword == 
"BACK" ) {
   538                         back_ = interface_id;
   539                     } 
else if( keyword == 
"TOP" ) {
   541                     } 
else if( keyword == 
"FRONT" ) {
   542                         front_ = interface_id;
   543                     } 
else if( keyword == 
"BOTTOM" ) {
   544                         bottom_ = interface_id;
   545                     } 
else if( keyword == 
"LEFT" ) {
   546                         left_ = interface_id;
   547                     } 
else if( keyword == 
"RIGHT" ) {
   548                         right_ = interface_id;
   550                         throw RINGMeshException( 
"I/O", 
"Unknown keyword: ",
   557                 if( back_ == NO_ID || top_ == NO_ID || front_ == NO_ID
   558                     || bottom_ == NO_ID || left_ == NO_ID || right_ == NO_ID ) {
   559                     throw RINGMeshException( 
"I/O",
   560                         "Missing box shape information" );
   563                 surface_boundary_flags_[back_] = -7;
   564                 surface_boundary_flags_[top_] = -5;
   565                 surface_boundary_flags_[front_] = -6;
   566                 surface_boundary_flags_[bottom_] = -4;
   567                 surface_boundary_flags_[left_] = -2;
   568                 surface_boundary_flags_[right_] = -3;
   570                 std::set< index_t > back_bottom;
   571                 back_bottom.insert( back_ );
   572                 back_bottom.insert( bottom_ );
   573                 edge_boundary_flags_[back_bottom] = -16;
   574                 std::set< index_t > back_right;
   575                 back_right.insert( back_ );
   576                 back_right.insert( right_ );
   577                 edge_boundary_flags_[back_right] = -17;
   578                 std::set< index_t > back_top;
   579                 back_top.insert( back_ );
   580                 back_top.insert( top_ );
   581                 edge_boundary_flags_[back_top] = -18;
   582                 std::set< index_t > back_left;
   583                 back_left.insert( back_ );
   584                 back_left.insert( left_ );
   585                 edge_boundary_flags_[back_left] = -19;
   586                 std::set< index_t > right_bottom;
   587                 right_bottom.insert( right_ );
   588                 right_bottom.insert( bottom_ );
   589                 edge_boundary_flags_[right_bottom] = -20;
   590                 std::set< index_t > right_top;
   591                 right_top.insert( right_ );
   592                 right_top.insert( top_ );
   593                 edge_boundary_flags_[right_top] = -21;
   594                 std::set< index_t > left_top;
   595                 left_top.insert( left_ );
   596                 left_top.insert( top_ );
   597                 edge_boundary_flags_[left_top] = -22;
   598                 std::set< index_t > left_bottom;
   599                 left_bottom.insert( left_ );
   600                 left_bottom.insert( bottom_ );
   601                 edge_boundary_flags_[left_bottom] = -23;
   602                 std::set< index_t > front_bottom;
   603                 front_bottom.insert( front_ );
   604                 front_bottom.insert( bottom_ );
   605                 edge_boundary_flags_[front_bottom] = -24;
   606                 std::set< index_t > front_right;
   607                 front_right.insert( front_ );
   608                 front_right.insert( right_ );
   609                 edge_boundary_flags_[front_right] = -25;
   610                 std::set< index_t > front_top;
   611                 front_top.insert( front_ );
   612                 front_top.insert( top_ );
   613                 edge_boundary_flags_[front_top] = -26;
   614                 std::set< index_t > front_left;
   615                 front_left.insert( front_ );
   616                 front_left.insert( left_ );
   617                 edge_boundary_flags_[front_left] = -27;
   619                 std::set< index_t > back_top_left;
   620                 back_top_left.insert( back_ );
   621                 back_top_left.insert( top_ );
   622                 back_top_left.insert( left_ );
   623                 corner_boundary_flags_[back_top_left] = -13;
   624                 std::set< index_t > back_top_right;
   625                 back_top_right.insert( back_ );
   626                 back_top_right.insert( top_ );
   627                 back_top_right.insert( right_ );
   628                 corner_boundary_flags_[back_top_right] = -14;
   629                 std::set< index_t > back_bottom_left;
   630                 back_bottom_left.insert( back_ );
   631                 back_bottom_left.insert( bottom_ );
   632                 back_bottom_left.insert( left_ );
   633                 corner_boundary_flags_[back_bottom_left] = -8;
   634                 std::set< index_t > back_bottom_right;
   635                 back_bottom_right.insert( back_ );
   636                 back_bottom_right.insert( bottom_ );
   637                 back_bottom_right.insert( right_ );
   638                 corner_boundary_flags_[back_bottom_right] = -10;
   639                 std::set< index_t > front_top_left;
   640                 front_top_left.insert( front_ );
   641                 front_top_left.insert( top_ );
   642                 front_top_left.insert( left_ );
   643                 corner_boundary_flags_[front_top_left] = -15;
   644                 std::set< index_t > front_top_right;
   645                 front_top_right.insert( front_ );
   646                 front_top_right.insert( top_ );
   647                 front_top_right.insert( right_ );
   648                 corner_boundary_flags_[front_top_right] = -9;
   649                 std::set< index_t > front_bottom_left;
   650                 front_bottom_left.insert( front_ );
   651                 front_bottom_left.insert( bottom_ );
   652                 front_bottom_left.insert( left_ );
   653                 corner_boundary_flags_[front_bottom_left] = -12;
   654                 std::set< index_t > front_bottom_right;
   655                 front_bottom_right.insert( front_ );
   656                 front_bottom_right.insert( bottom_ );
   657                 front_bottom_right.insert( right_ );
   658                 corner_boundary_flags_[front_bottom_right] = -11;
   661             point_boundaries_.resize( gm.mesh.vertices.nb() );
   662             for( 
const auto& surface : surface_range < 3 > ( gm ) ) {
   663                 index_t interface_id = surface.parent_gmge( 0 ).index();
   665                     gm.mesh.polygons.nb_polygons( surface.index() ) ) ) {
   666                     index_t p_id = gm.mesh.polygons.polygon( surface.index(), p );
   667                     for( 
auto v : range( gm.mesh.polygons.nb_vertices( p_id ) ) ) {
   668                         index_t vertex_id = gm.mesh.polygons.vertex(
   669                             ElementLocalVertex( p_id, v ) );
   670                         point_boundaries_[vertex_id].insert( interface_id );
   675         std::string interface_csmp_name(
   677             const GeoModel3D& geomodel )
 const   682                 } 
else if( i == top_ ) {
   684                 } 
else if( i == front_ ) {
   686                 } 
else if( i == bottom_ ) {
   688                 } 
else if( i == left_ ) {
   690                 } 
else if( i == right_ ) {
   694             return geomodel.geological_entity( Interface3D::type_name_static(), i ).name();
   696         signed_index_t point_boundary( index_t p )
 const   699             const std::set< unsigned int >& boundaries = point_boundaries_[p];
   701                 if( boundaries.size() == 1 ) {
   702                     auto it = surface_boundary_flags_.find( *boundaries.begin() );
   705                 } 
else if( boundaries.size() == 2 ) {
   706                     auto it = edge_boundary_flags_.find( boundaries );
   709                 } 
else if( boundaries.size() == 3 ) {
   710                     auto it = corner_boundary_flags_.find( boundaries );
   717                 if( boundaries.empty() )
   724         std::vector< std::set< index_t > > point_boundaries_;
   734         std::map< std::set< index_t >, signed_index_t > corner_boundary_flags_;
   735         std::map< std::set< index_t >, signed_index_t > edge_boundary_flags_;
   736         std::map< index_t, signed_index_t > surface_boundary_flags_;
 void ringmesh_unused(const T &)
 
auto to_underlying_type(Enum e) -> typename std::underlying_type< Enum >::type
 
#define ringmesh_assert(x)