RINGMesh  Version 5.0.0
A programming library for geological model meshes
test-geomodel-from-surface.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012-2017, Association Scientifique pour la Geologie et ses
3  * Applications (ASGA). All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of ASGA nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ASGA BE LIABLE FOR ANY DIRECT,
20  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  * http://www.ring-team.org
28  *
29  * RING Project
30  * Ecole Nationale Superieure de Geologie - GeoRessources
31  * 2 Rue du Doyen Marcel Roubault - TSA 70605
32  * 54518 VANDOEUVRE-LES-NANCY
33  * FRANCE
34  */
35 
36 #include <ringmesh/ringmesh_tests_config.h>
37 
38 #include <future>
39 
40 #include <geogram/basic/command_line.h>
41 
42 #include <geogram/mesh/mesh_io.h>
43 
47 
48 #include <ringmesh/io/io.h>
49 
56 int main()
57 {
58  using namespace RINGMesh;
59 
60  try
61  {
63 
64  Logger::out( "TEST", "Test GeoModel building from Surface" );
65 
66  std::vector< std::future< void > > futures;
67 
68  GEO::Mesh in;
69  GEO::mesh_load( ringmesh_test_data_path + "modelA6.mesh", in );
70  GeoModel3D geomodel;
71 
72  GeoModelBuilderSurfaceMesh builder( geomodel, in );
76  builder.end_geomodel();
77  print_geomodel( geomodel );
78 
79 // Checking the validity of loaded model
80 #ifdef RINGMESH_DEBUG
81  GEO::CmdLine::set_arg( "in:intersection_check", true );
82 #else
83  GEO::CmdLine::set_arg( "in:intersection_check", false );
84 #endif
85 
86  futures.emplace_back( std::async( std::launch::async, [&geomodel] {
87  if( !is_geomodel_valid( geomodel ) )
88  {
89  throw RINGMeshException( "RINGMesh Test",
90  "Failed when loading model ", geomodel.name(),
91  ": the loaded model is not valid." );
92  }
93  } ) );
94 
95  futures.emplace_back( std::async( std::launch::async, [&geomodel] {
96  // Save and reload the model
97  std::string output_file( ringmesh_test_output_path );
98  output_file += "saved_modelA6.gm";
99  geomodel_save( geomodel, output_file );
100  } ) );
101 
102  GEO::Mesh surface_meshes;
103  // Compute mesh with duplicated points to compares number
104  // of mesh elements and mesh entities
105  for( const auto& surface : geomodel.surfaces() )
106  {
107  index_t vertex_it{ surface_meshes.vertices.create_vertices(
108  surface.nb_vertices() ) };
109  for( index_t v : range( surface.nb_vertices() ) )
110  {
111  surface_meshes.vertices.point( vertex_it + v ) =
112  surface.vertex( v );
113  }
114  index_t facet_it{ surface_meshes.facets.create_triangles(
115  surface.nb_mesh_elements() ) };
116  for( index_t f : range( surface.nb_mesh_elements() ) )
117  {
118  for( index_t v :
119  range( surface.nb_mesh_element_vertices( f ) ) )
120  {
121  surface_meshes.facets.set_vertex( facet_it + f, v,
122  vertex_it
123  + surface.mesh_element_vertex_index( { f, v } ) );
124  }
125  }
126  }
127  surface_meshes.facets.connect();
128 
129  futures.emplace_back(
130  std::async( std::launch::async, [&surface_meshes] {
131  // Save computed mesh
132  std::string output_file2( ringmesh_test_output_path );
133  output_file2 += "saved_modelA6_dupl_points.mesh";
134  GEO::mesh_save( surface_meshes, output_file2 );
135  } ) );
136 
137  GeoModel3D reloaded_model;
138  GeoModelBuilderSurfaceMesh builder2( reloaded_model, surface_meshes );
142  builder2.end_geomodel();
143  print_geomodel( reloaded_model );
144 
145  futures.emplace_back(
146  std::async( std::launch::async, [&reloaded_model] {
147  // Checking if building has been successfully done
148  if( !is_geomodel_valid( reloaded_model ) )
149  {
150  throw RINGMeshException( "RINGMesh Test",
151  "Failed when reloading model ", reloaded_model.name(),
152  ": the reloaded model is not valid." );
153  }
154  } ) );
155 
156  // Checking number of mesh elements
157  if( surface_meshes.vertices.nb() != in.vertices.nb() )
158  {
159  throw RINGMeshException( "RINGMesh Test",
160  "Error when building model: not same number of vertices ",
161  "than input mesh." );
162  }
163  if( surface_meshes.facets.nb() != in.facets.nb() )
164  {
165  throw RINGMeshException( "RINGMesh Test",
166  "Error when building model: not same number of facets ",
167  "than input mesh." );
168  }
169  if( surface_meshes.cells.nb() != in.cells.nb() )
170  {
171  throw RINGMeshException( "RINGMesh Test",
172  "Error when building model: not same number of cells ",
173  "than input mesh." );
174  }
175 
176  // Checking number of GeoModelMeshEntities
177  if( reloaded_model.nb_corners() != geomodel.nb_corners() )
178  {
179  throw RINGMeshException( "RINGMesh Test",
180  "Error when reload model: not same number of corners ",
181  "between saved model and reload model." );
182  }
183  if( reloaded_model.nb_lines() != geomodel.nb_lines() )
184  {
185  throw RINGMeshException( "RINGMesh Test",
186  "Error when reload model: not same number of lines ",
187  "between saved model and reload model." );
188  }
189  if( reloaded_model.nb_surfaces() != geomodel.nb_surfaces() )
190  {
191  throw RINGMeshException( "RINGMesh Test",
192  "Error when reload model: not same number of surfaces ",
193  "between saved model and reload model." );
194  }
195  if( reloaded_model.nb_regions() != geomodel.nb_regions() )
196  {
197  throw RINGMeshException( "RINGMesh Test",
198  "Error when reload model: not same number of regions ",
199  "between saved model and reload model." );
200  }
201 
202  for( auto& future : futures )
203  {
204  future.get();
205  }
206  }
207  catch( const RINGMeshException& e )
208  {
209  Logger::err( e.category(), e.what() );
210  return 1;
211  }
212  catch( const std::exception& e )
213  {
214  Logger::err( "Exception", e.what() );
215  return 1;
216  }
217  Logger::out( "TEST", "SUCCESS" );
218  return 0;
219 }
bool is_geomodel_valid(const GeoModel< DIMENSION > &geomodel, ValidityCheckMode validity_check_mode=ValidityCheckMode::ALL)
Check global geomodel validity.
void end_geomodel()
Finish up geomodel building and complete missing information.
void print_geomodel(const GeoModel< DIMENSION > &geomodel)
Print in the console the geomodel statistics.
static void err(const std::string &feature, const Args &... args)
Definition: logger.h:68
static void out(const std::string &feature, const Args &... args)
Definition: logger.h:61
void geomodel_save(const GeoModel< DIMENSION > &geomodel, const std::string &filename)
Definition: io.cpp:146
const std::string & category() const
Definition: common.h:165
Classes to build GeoModel from various inputs.
Definition: algorithm.h:48
To build a GeoModel from a set of disconnected polygonal surfaces.
void RINGMESH_API default_configure()
Definition: common.cpp:99