RINGMesh  Version 5.0.0
A programming library for geological model meshes
test-transfer-attributes-gm-gmm.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/attributes.h>
41 
45 #include <ringmesh/io/io.h>
46 
51 namespace
52 {
53  using namespace RINGMesh;
54 
55  const std::string attribute_names[6] = { "long_int_attr", "bool_attr",
56  "double_attr", "vec3_attr", "dim_6_double_attr", "char_attr" };
57 
58  std::mutex lock;
59 
60  void load_geomodel( GeoModel3D& in, const std::string& filename )
61  {
62  std::string input_model_file_name( ringmesh_test_data_path );
63  input_model_file_name += filename;
64 
65  bool loaded_model_is_valid = geomodel_load( in, input_model_file_name );
66 
67  if( !loaded_model_is_valid )
68  {
69  throw RINGMeshException( "RINGMesh Test",
70  "Failed when loading model ", in.name(),
71  ": the loaded model is not valid." );
72  }
73  }
74 
75  void assign_vertex_attribute_values( index_t vertex_i,
76  const vec3& cur_vertex,
77  GEO::Attribute< long int >& vertex_long_int_attr,
78  GEO::Attribute< bool >& vertex_bool_attr,
79  GEO::Attribute< double >& vertex_double_attr,
80  GEO::Attribute< vec3 >& vertex_vec3_attr,
81  GEO::Attribute< double >& vertex_dim_6_double_attr,
82  GEO::Attribute< char >& vertex_char_attr )
83  {
84  const long int rounded_vertex_xy =
85  std::lrint( cur_vertex.x * cur_vertex.y );
86  vertex_long_int_attr[vertex_i] = rounded_vertex_xy;
87  vertex_bool_attr[vertex_i] = ( rounded_vertex_xy % 2 == 0 );
88  vertex_double_attr[vertex_i] = cur_vertex.x;
89  vertex_vec3_attr[vertex_i] = cur_vertex;
90  vertex_dim_6_double_attr[vertex_i * 6 + 0] = cur_vertex.x;
91  vertex_dim_6_double_attr[vertex_i * 6 + 1] = cur_vertex.y;
92  vertex_dim_6_double_attr[vertex_i * 6 + 2] = cur_vertex.z;
93  vertex_dim_6_double_attr[vertex_i * 6 + 3] = cur_vertex.x;
94  vertex_dim_6_double_attr[vertex_i * 6 + 4] = cur_vertex.y;
95  vertex_dim_6_double_attr[vertex_i * 6 + 5] = cur_vertex.z;
96  vertex_char_attr[vertex_i] = std::to_string( cur_vertex.y ).data()[0];
97  }
98 
99  void set_vertex_attributes_on_geomodel_regions( const GeoModel3D& geomodel )
100  {
101  for( index_t reg_i = 0; reg_i < geomodel.nb_regions(); ++reg_i )
102  {
103  const Region3D& cur_reg = geomodel.region( reg_i );
104 
105  GEO::AttributesManager& reg_attr_mgr =
106  cur_reg.vertex_attribute_manager();
107  GEO::Attribute< long int > vertex_long_int_attr(
108  reg_attr_mgr, attribute_names[0] );
109  GEO::Attribute< bool > vertex_bool_attr(
110  reg_attr_mgr, attribute_names[1] );
111  GEO::Attribute< double > vertex_double_attr(
112  reg_attr_mgr, attribute_names[2] );
113  GEO::Attribute< vec3 > vertex_vec3_attr(
114  reg_attr_mgr, attribute_names[3] );
115  GEO::Attribute< double > vertex_dim_6_double_attr;
116  vertex_dim_6_double_attr.create_vector_attribute(
117  reg_attr_mgr, attribute_names[4], 6 );
118  GEO::Attribute< char > vertex_char_attr(
119  reg_attr_mgr, attribute_names[5] );
120 
121  for( index_t vertex_i = 0; vertex_i < cur_reg.nb_vertices();
122  ++vertex_i )
123  {
124  const vec3& cur_vertex = cur_reg.vertex( vertex_i );
125  assign_vertex_attribute_values( vertex_i, cur_vertex,
126  vertex_long_int_attr, vertex_bool_attr, vertex_double_attr,
127  vertex_vec3_attr, vertex_dim_6_double_attr,
128  vertex_char_attr );
129  }
130  }
131  }
132 
133  void set_vertex_attributes_on_geomodelmesh( const GeoModel3D& geomodel )
134  {
135  const GeoModelMesh3D& gmm = geomodel.mesh;
136  const GeoModelMeshVertices3D& gmmv = gmm.vertices;
137  GEO::AttributesManager& gmmv_attr_mgr = gmmv.attribute_manager();
138 
139  GEO::Attribute< long int > vertex_long_int_attr(
140  gmmv_attr_mgr, attribute_names[0] );
141  GEO::Attribute< bool > vertex_bool_attr(
142  gmmv_attr_mgr, attribute_names[1] );
143  GEO::Attribute< double > vertex_double_attr(
144  gmmv_attr_mgr, attribute_names[2] );
145  GEO::Attribute< vec3 > vertex_vec3_attr(
146  gmmv_attr_mgr, attribute_names[3] );
147  GEO::Attribute< double > vertex_dim_6_double_attr;
148  vertex_dim_6_double_attr.create_vector_attribute(
149  gmmv_attr_mgr, attribute_names[4], 6 );
150  GEO::Attribute< char > vertex_char_attr(
151  gmmv_attr_mgr, attribute_names[5] );
152 
153  for( index_t v_i = 0; v_i < gmmv.nb(); ++v_i )
154  {
155  const vec3& cur_vertex = gmmv.vertex( v_i );
156  assign_vertex_attribute_values( v_i, cur_vertex,
157  vertex_long_int_attr, vertex_bool_attr, vertex_double_attr,
158  vertex_vec3_attr, vertex_dim_6_double_attr, vertex_char_attr );
159  }
160  }
161 
162  void assign_cell_attribute_values( index_t cell_i,
163  double cell_volume,
164  const vec3& cell_barycenter,
165  GEO::Attribute< long int >& cell_long_int_attr,
166  GEO::Attribute< bool >& cell_bool_attr,
167  GEO::Attribute< double >& cell_double_attr,
168  GEO::Attribute< vec3 >& cell_vec3_attr,
169  GEO::Attribute< double >& cell_dim_6_double_attr,
170  GEO::Attribute< char >& cell_char_attr )
171  {
172  const long int rounded_volume = std::lrint( cell_volume );
173  cell_long_int_attr[cell_i] = rounded_volume;
174  cell_bool_attr[cell_i] = ( rounded_volume % 2 == 0 );
175  cell_double_attr[cell_i] = cell_volume;
176  cell_vec3_attr[cell_i] = cell_barycenter;
177  cell_dim_6_double_attr[cell_i * 6 + 0] = cell_vec3_attr[cell_i].x;
178  cell_dim_6_double_attr[cell_i * 6 + 1] = cell_vec3_attr[cell_i].y;
179  cell_dim_6_double_attr[cell_i * 6 + 2] = cell_vec3_attr[cell_i].z;
180  cell_dim_6_double_attr[cell_i * 6 + 3] = cell_vec3_attr[cell_i].x;
181  cell_dim_6_double_attr[cell_i * 6 + 4] = cell_vec3_attr[cell_i].y;
182  cell_dim_6_double_attr[cell_i * 6 + 5] = cell_vec3_attr[cell_i].z;
183  cell_char_attr[cell_i] =
184  std::to_string( cell_vec3_attr[cell_i].y ).data()[0];
185  }
186 
187  void set_cell_attributes_on_geomodel_regions( const GeoModel3D& geomodel )
188  {
189  for( index_t reg_i = 0; reg_i < geomodel.nb_regions(); ++reg_i )
190  {
191  const Region3D& cur_reg = geomodel.region( reg_i );
192 
193  GEO::AttributesManager& reg_attr_mgr =
194  cur_reg.cell_attribute_manager();
195  GEO::Attribute< long int > cell_long_int_attr(
196  reg_attr_mgr, attribute_names[0] );
197  GEO::Attribute< bool > cell_bool_attr(
198  reg_attr_mgr, attribute_names[1] );
199  GEO::Attribute< double > cell_double_attr(
200  reg_attr_mgr, attribute_names[2] );
201  GEO::Attribute< vec3 > cell_vec3_attr(
202  reg_attr_mgr, attribute_names[3] );
203  GEO::Attribute< double > cell_dim_6_double_attr;
204  cell_dim_6_double_attr.create_vector_attribute(
205  reg_attr_mgr, attribute_names[4], 6 );
206  GEO::Attribute< char > cell_char_attr(
207  reg_attr_mgr, attribute_names[5] );
208 
209  for( index_t cell_i = 0; cell_i < cur_reg.nb_mesh_elements();
210  ++cell_i )
211  {
212  const double cell_volume = cur_reg.mesh_element_size( cell_i );
213  assign_cell_attribute_values( cell_i, cell_volume,
214  cur_reg.mesh_element_barycenter( cell_i ),
215  cell_long_int_attr, cell_bool_attr, cell_double_attr,
216  cell_vec3_attr, cell_dim_6_double_attr, cell_char_attr );
217  }
218  }
219  }
220 
221  void set_cell_attributes_on_geomodelmesh( const GeoModel3D& geomodel )
222  {
223  const GeoModelMesh3D& gmm = geomodel.mesh;
224  const GeoModelMeshCells3D& gmmc = gmm.cells;
225  GEO::AttributesManager& gmmc_attr_mgr = gmmc.attribute_manager();
226 
227  GEO::Attribute< long int > cell_long_int_attr(
228  gmmc_attr_mgr, attribute_names[0] );
229  GEO::Attribute< bool > cell_bool_attr(
230  gmmc_attr_mgr, attribute_names[1] );
231  GEO::Attribute< double > cell_double_attr(
232  gmmc_attr_mgr, attribute_names[2] );
233  GEO::Attribute< vec3 > cell_vec3_attr(
234  gmmc_attr_mgr, attribute_names[3] );
235  GEO::Attribute< double > cell_dim_6_double_attr;
236  cell_dim_6_double_attr.create_vector_attribute(
237  gmmc_attr_mgr, attribute_names[4], 6 );
238  GEO::Attribute< char > cell_char_attr(
239  gmmc_attr_mgr, attribute_names[5] );
240 
241  for( index_t cell_i = 0; cell_i < gmmc.nb(); ++cell_i )
242  {
243  const double cell_volume = gmmc.volume( cell_i );
244  assign_cell_attribute_values( cell_i, cell_volume,
245  gmmc.barycenter( cell_i ), cell_long_int_attr, cell_bool_attr,
246  cell_double_attr, cell_vec3_attr, cell_dim_6_double_attr,
247  cell_char_attr );
248  }
249  }
250 
251  void check_attribute_exists( GEO::AttributesManager& attr_mgr,
252  const std::string& attr_name,
253  const std::string& on_mesh,
254  const std::string& stored_on )
255  {
256  if( !attr_mgr.is_defined( attr_name ) )
257  {
258  throw RINGMeshException( "RINGMesh Test", "Attribute ", attr_name,
259  " does not exist on ", on_mesh, " stored on ",
260  stored_on + "." );
261  }
262  }
263 
264  void check_attributes_exist_on_mesh( GEO::AttributesManager& attr_mgr,
265  const std::string& on_mesh,
266  const std::string& stored_on )
267  {
268  for( index_t i = 0; i < 6; ++i )
269  check_attribute_exists(
270  attr_mgr, attribute_names[i], on_mesh, stored_on );
271  }
272 
273  void check_vertex_attr_transfer_from_geomodel_regions_to_geomodelmesh(
274  const GeoModel3D& geomodel )
275  {
276  const GeoModelMesh3D& gmm = geomodel.mesh;
277  const GeoModelMeshVertices3D& gmmv = gmm.vertices;
278  GEO::AttributesManager& gmmv_attr_mgr = gmmv.attribute_manager();
279  check_attributes_exist_on_mesh(
280  gmmv_attr_mgr, "geomodelmesh", "vertices" );
281 
282  GEO::Attribute< long int > vertex_long_int_attr(
283  gmmv_attr_mgr, attribute_names[0] );
284  GEO::Attribute< bool > vertex_bool_attr(
285  gmmv_attr_mgr, attribute_names[1] );
286  GEO::Attribute< double > vertex_double_attr(
287  gmmv_attr_mgr, attribute_names[2] );
288  GEO::Attribute< vec3 > vertex_vec3_attr(
289  gmmv_attr_mgr, attribute_names[3] );
290  GEO::Attribute< double > vertex_dim_6_double_attr(
291  gmmv_attr_mgr, attribute_names[4] );
292  GEO::Attribute< char > vertex_char_attr(
293  gmmv_attr_mgr, attribute_names[5] );
294 
295  for( index_t vertex_i = 0; vertex_i < gmmv.nb(); ++vertex_i )
296  {
297  const vec3& cur_vertex = gmmv.vertex( vertex_i );
298  const long int rounded_vertex_xy =
299  std::lrint( cur_vertex.x * cur_vertex.y );
300 
301  if( rounded_vertex_xy != vertex_long_int_attr[vertex_i] )
302  {
303  throw RINGMeshException(
304  "RINGMesh Test", "Bad vertex transfer from geomodel region "
305  "to geomodelmesh for long int." );
306  }
307 
308  bool is_pair = ( rounded_vertex_xy % 2 == 0 );
309  if( is_pair != vertex_bool_attr[vertex_i] )
310  {
311  throw RINGMeshException(
312  "RINGMesh Test", "Bad vertex transfer from geomodel region "
313  "to geomodelmesh for bool." );
314  }
315 
316  if( std::abs( cur_vertex.x - vertex_double_attr[vertex_i] )
317  > geomodel.epsilon() )
318  {
319  throw RINGMeshException(
320  "RINGMesh Test", "Bad vertex transfer from geomodel region "
321  "to geomodelmesh for double." );
322  }
323 
324  const vec3 diff = cur_vertex - vertex_vec3_attr[vertex_i];
325  if( std::abs( diff.x ) > geomodel.epsilon()
326  || std::abs( diff.y ) > geomodel.epsilon()
327  || std::abs( diff.z ) > geomodel.epsilon() )
328  {
329  throw RINGMeshException(
330  "RINGMesh Test", "Bad vertex transfer from geomodel region "
331  "to geomodelmesh for vec3." );
332  }
333 
334  if( std::abs(
335  cur_vertex.x - vertex_dim_6_double_attr[6 * vertex_i + 0] )
336  > geomodel.epsilon()
337  || std::abs( cur_vertex.y
338  - vertex_dim_6_double_attr[6 * vertex_i + 1] )
339  > geomodel.epsilon()
340  || std::abs( cur_vertex.z
341  - vertex_dim_6_double_attr[6 * vertex_i + 2] )
342  > geomodel.epsilon()
343  || std::abs( cur_vertex.x
344  - vertex_dim_6_double_attr[6 * vertex_i + 3] )
345  > geomodel.epsilon()
346  || std::abs( cur_vertex.y
347  - vertex_dim_6_double_attr[6 * vertex_i + 4] )
348  > geomodel.epsilon()
349  || std::abs( cur_vertex.z
350  - vertex_dim_6_double_attr[6 * vertex_i + 5] )
351  > geomodel.epsilon() )
352  {
353  throw RINGMeshException(
354  "RINGMesh Test", "Bad vertex transfer from geomodel region "
355  "to geomodelmesh for double dim 6." );
356  }
357 
358  const char char_vec3_y = std::to_string( cur_vertex.y ).data()[0];
359  if( char_vec3_y != vertex_char_attr[vertex_i] )
360  {
361  throw RINGMeshException(
362  "RINGMesh Test", "Bad vertex transfer from geomodel region "
363  "to geomodelmesh for char." );
364  }
365  }
366  }
367 
368  void check_vertex_attr_transfer_from_geomodelmesh_to_geomodel_regions(
369  const GeoModel3D& geomodel )
370  {
371  for( index_t reg_i = 0; reg_i < geomodel.nb_regions(); ++reg_i )
372  {
373  const Region3D& cur_reg = geomodel.region( reg_i );
374  GEO::AttributesManager& reg_v_attr_mgr =
375  cur_reg.vertex_attribute_manager();
376  check_attributes_exist_on_mesh(
377  reg_v_attr_mgr, "geomodel region", "vertices" );
378 
379  GEO::Attribute< long int > vertex_long_int_attr(
380  reg_v_attr_mgr, attribute_names[0] );
381  GEO::Attribute< bool > vertex_bool_attr(
382  reg_v_attr_mgr, attribute_names[1] );
383  GEO::Attribute< double > vertex_double_attr(
384  reg_v_attr_mgr, attribute_names[2] );
385  GEO::Attribute< vec3 > vertex_vec3_attr(
386  reg_v_attr_mgr, attribute_names[3] );
387  GEO::Attribute< double > vertex_dim_6_double_attr(
388  reg_v_attr_mgr, attribute_names[4] );
389  GEO::Attribute< char > vertex_char_attr(
390  reg_v_attr_mgr, attribute_names[5] );
391 
392  for( index_t vertex_i = 0; vertex_i < cur_reg.nb_vertices();
393  ++vertex_i )
394  {
395  const vec3& cur_vertex = cur_reg.vertex( vertex_i );
396  const long int rounded_vertex_xy =
397  std::lrint( cur_vertex.x * cur_vertex.y );
398 
399  if( rounded_vertex_xy != vertex_long_int_attr[vertex_i] )
400  {
401  throw RINGMeshException( "RINGMesh Test",
402  "Bad vertex transfer from geomodelmesh to geomodel "
403  "region for long int." );
404  }
405 
406  bool is_pair = ( rounded_vertex_xy % 2 == 0 );
407  if( is_pair != vertex_bool_attr[vertex_i] )
408  {
409  throw RINGMeshException( "RINGMesh Test",
410  "Bad vertex transfer from geomodelmesh to geomodel "
411  "region for bool." );
412  }
413 
414  if( std::abs( cur_vertex.x - vertex_double_attr[vertex_i] )
415  > geomodel.epsilon() )
416  {
417  throw RINGMeshException( "RINGMesh Test",
418  "Bad vertex transfer from geomodelmesh to geomodel "
419  "region for double." );
420  }
421 
422  const vec3 diff = cur_vertex - vertex_vec3_attr[vertex_i];
423  if( std::abs( diff.x ) > geomodel.epsilon()
424  || std::abs( diff.y ) > geomodel.epsilon()
425  || std::abs( diff.z ) > geomodel.epsilon() )
426  {
427  throw RINGMeshException( "RINGMesh Test",
428  "Bad vertex transfer from geomodelmesh to geomodel "
429  "region for vec3." );
430  }
431 
432  if( std::abs( cur_vertex.x
433  - vertex_dim_6_double_attr[6 * vertex_i + 0] )
434  > geomodel.epsilon()
435  || std::abs( cur_vertex.y
436  - vertex_dim_6_double_attr[6 * vertex_i + 1] )
437  > geomodel.epsilon()
438  || std::abs( cur_vertex.z
439  - vertex_dim_6_double_attr[6 * vertex_i + 2] )
440  > geomodel.epsilon()
441  || std::abs( cur_vertex.x
442  - vertex_dim_6_double_attr[6 * vertex_i + 3] )
443  > geomodel.epsilon()
444  || std::abs( cur_vertex.y
445  - vertex_dim_6_double_attr[6 * vertex_i + 4] )
446  > geomodel.epsilon()
447  || std::abs( cur_vertex.z
448  - vertex_dim_6_double_attr[6 * vertex_i + 5] )
449  > geomodel.epsilon() )
450  {
451  throw RINGMeshException( "RINGMesh Test",
452  "Bad vertex transfer from geomodelmesh to geomodel "
453  "region for double dim 6." );
454  }
455 
456  const char char_vec3_y =
457  std::to_string( cur_vertex.y ).data()[0];
458  if( char_vec3_y != vertex_char_attr[vertex_i] )
459  {
460  throw RINGMeshException( "RINGMesh Test",
461  "Bad vertex transfer from geomodelmesh to geomodel "
462  "region for char." );
463  }
464  }
465  }
466  }
467 
468  void check_cell_attr_transfer_from_geomodel_regions_to_geomodelmesh(
469  const GeoModel3D& geomodel )
470  {
471  const GeoModelMesh3D& gmm = geomodel.mesh;
472  const GeoModelMeshCells3D& gmmc = gmm.cells;
473  GEO::AttributesManager& gmmc_attr_mgr = gmmc.attribute_manager();
474  check_attributes_exist_on_mesh(
475  gmmc_attr_mgr, "geomodelmesh", "cells" );
476 
477  GEO::Attribute< long int > cell_long_int_attr(
478  gmmc_attr_mgr, attribute_names[0] );
479  GEO::Attribute< bool > cell_bool_attr(
480  gmmc_attr_mgr, attribute_names[1] );
481  GEO::Attribute< double > cell_double_attr(
482  gmmc_attr_mgr, attribute_names[2] );
483  GEO::Attribute< vec3 > cell_vec3_attr(
484  gmmc_attr_mgr, attribute_names[3] );
485  GEO::Attribute< double > cell_dim_6_double_attr(
486  gmmc_attr_mgr, attribute_names[4] );
487  GEO::Attribute< char > cell_char_attr(
488  gmmc_attr_mgr, attribute_names[5] );
489 
490  for( index_t cell_i = 0; cell_i < gmmc.nb_cells(); ++cell_i )
491  {
492  const double cell_volume = gmmc.volume( cell_i );
493  const long int rounded_volume = std::lrint( cell_volume );
494 
495  if( rounded_volume != cell_long_int_attr[cell_i] )
496  {
497  throw RINGMeshException(
498  "RINGMesh Test", "Bad cell transfer from geomodel region "
499  "to geomodelmesh for long int." );
500  }
501 
502  bool is_pair = ( rounded_volume % 2 == 0 );
503  if( is_pair != cell_bool_attr[cell_i] )
504  {
505  throw RINGMeshException(
506  "RINGMesh Test", "Bad cell transfer from geomodel region "
507  "to geomodelmesh for bool." );
508  }
509 
510  if( std::abs( cell_volume - cell_double_attr[cell_i] )
511  > geomodel.epsilon3() )
512  {
513  throw RINGMeshException(
514  "RINGMesh Test", "Bad cell transfer from geomodel region "
515  "to geomodelmesh for double." );
516  }
517 
518  const vec3 cell_barycenter = gmmc.barycenter( cell_i );
519  const vec3 diff = cell_barycenter - cell_vec3_attr[cell_i];
520  if( std::abs( diff.x ) > geomodel.epsilon()
521  || std::abs( diff.y ) > geomodel.epsilon()
522  || std::abs( diff.z ) > geomodel.epsilon() )
523  {
524  throw RINGMeshException(
525  "RINGMesh Test", "Bad cell transfer from geomodel region "
526  "to geomodelmesh for vec3." );
527  }
528 
529  if( std::abs(
530  cell_barycenter.x - cell_dim_6_double_attr[6 * cell_i + 0] )
531  > geomodel.epsilon()
532  || std::abs( cell_barycenter.y
533  - cell_dim_6_double_attr[6 * cell_i + 1] )
534  > geomodel.epsilon()
535  || std::abs( cell_barycenter.z
536  - cell_dim_6_double_attr[6 * cell_i + 2] )
537  > geomodel.epsilon()
538  || std::abs( cell_barycenter.x
539  - cell_dim_6_double_attr[6 * cell_i + 3] )
540  > geomodel.epsilon()
541  || std::abs( cell_barycenter.y
542  - cell_dim_6_double_attr[6 * cell_i + 4] )
543  > geomodel.epsilon()
544  || std::abs( cell_barycenter.z
545  - cell_dim_6_double_attr[6 * cell_i + 5] )
546  > geomodel.epsilon() )
547  {
548  throw RINGMeshException(
549  "RINGMesh Test", "Bad cell transfer from geomodel region "
550  "to geomodelmesh for double dim 6." );
551  }
552 
553  const char char_vec3_y =
554  std::to_string( cell_barycenter.y ).data()[0];
555  if( char_vec3_y != cell_char_attr[cell_i] )
556  {
557  throw RINGMeshException(
558  "RINGMesh Test", "Bad cell transfer from geomodel region "
559  "to geomodelmesh for char." );
560  }
561  }
562  }
563 
564  void check_cell_attr_transfer_from_geomodelmesh_to_geomodel_regions(
565  const GeoModel3D& geomodel )
566  {
567  for( index_t reg_i = 0; reg_i < geomodel.nb_regions(); ++reg_i )
568  {
569  const Region3D& cur_reg = geomodel.region( reg_i );
570  GEO::AttributesManager& reg_c_attr_mgr =
571  cur_reg.cell_attribute_manager();
572  check_attributes_exist_on_mesh(
573  reg_c_attr_mgr, "geomodel region", "cells" );
574 
575  GEO::Attribute< long int > cell_long_int_attr(
576  reg_c_attr_mgr, attribute_names[0] );
577  GEO::Attribute< bool > cell_bool_attr(
578  reg_c_attr_mgr, attribute_names[1] );
579  GEO::Attribute< double > cell_double_attr(
580  reg_c_attr_mgr, attribute_names[2] );
581  GEO::Attribute< vec3 > cell_vec3_attr(
582  reg_c_attr_mgr, attribute_names[3] );
583  GEO::Attribute< double > cell_dim_6_double_attr(
584  reg_c_attr_mgr, attribute_names[4] );
585  GEO::Attribute< char > cell_char_attr(
586  reg_c_attr_mgr, attribute_names[5] );
587 
588  for( index_t cell_i = 0; cell_i < cur_reg.nb_mesh_elements();
589  ++cell_i )
590  {
591  const double cell_volume = cur_reg.mesh_element_size( cell_i );
592  const long int rounded_volume = std::lrint( cell_volume );
593 
594  if( rounded_volume != cell_long_int_attr[cell_i] )
595  {
596  throw RINGMeshException(
597  "RINGMesh Test", "Bad cell transfer from geomodelmesh "
598  "to geomodel region for long int." );
599  }
600 
601  bool is_pair = ( rounded_volume % 2 == 0 );
602  if( is_pair != cell_bool_attr[cell_i] )
603  {
604  throw RINGMeshException(
605  "RINGMesh Test", "Bad cell transfer from geomodelmesh "
606  "to geomodel region for bool." );
607  }
608 
609  if( std::abs( cell_volume - cell_double_attr[cell_i] )
610  > geomodel.epsilon3() )
611  {
612  throw RINGMeshException(
613  "RINGMesh Test", "Bad cell transfer from geomodelmesh "
614  "to geomodel region for double." );
615  }
616 
617  const vec3 cell_barycenter =
618  cur_reg.mesh_element_barycenter( cell_i );
619  const vec3 diff = cell_barycenter - cell_vec3_attr[cell_i];
620  if( std::abs( diff.x ) > geomodel.epsilon()
621  || std::abs( diff.y ) > geomodel.epsilon()
622  || std::abs( diff.z ) > geomodel.epsilon() )
623  {
624  throw RINGMeshException(
625  "RINGMesh Test", "Bad cell transfer from geomodelmesh "
626  "to geomodel region for vec3." );
627  }
628 
629  if( std::abs( cell_barycenter.x
630  - cell_dim_6_double_attr[6 * cell_i + 0] )
631  > geomodel.epsilon()
632  || std::abs( cell_barycenter.y
633  - cell_dim_6_double_attr[6 * cell_i + 1] )
634  > geomodel.epsilon()
635  || std::abs( cell_barycenter.z
636  - cell_dim_6_double_attr[6 * cell_i + 2] )
637  > geomodel.epsilon()
638  || std::abs( cell_barycenter.x
639  - cell_dim_6_double_attr[6 * cell_i + 3] )
640  > geomodel.epsilon()
641  || std::abs( cell_barycenter.y
642  - cell_dim_6_double_attr[6 * cell_i + 4] )
643  > geomodel.epsilon()
644  || std::abs( cell_barycenter.z
645  - cell_dim_6_double_attr[6 * cell_i + 5] )
646  > geomodel.epsilon() )
647  {
648  throw RINGMeshException( "RINGMesh Test",
649  "Bad cell transfer from geomodelmesh to geomodel "
650  "region for double dim 6." );
651  }
652 
653  const char char_vec3_y =
654  std::to_string( cell_barycenter.y ).data()[0];
655  if( char_vec3_y != cell_char_attr[cell_i] )
656  {
657  throw RINGMeshException(
658  "RINGMesh Test", "Bad cell transfer from geomodelmesh "
659  "to geomodel region for char." );
660  }
661  }
662  }
663  }
664 
665  void check_attr_transfer_from_geomodel_regions_to_geomodelmesh(
666  const GeoModel3D& geomodel )
667  {
668  check_vertex_attr_transfer_from_geomodel_regions_to_geomodelmesh(
669  geomodel );
670  check_cell_attr_transfer_from_geomodel_regions_to_geomodelmesh(
671  geomodel );
672  }
673 
674  void check_attr_transfer_from_geomodelmesh_to_geomodel_regions(
675  const GeoModel3D& geomodel )
676  {
677  check_vertex_attr_transfer_from_geomodelmesh_to_geomodel_regions(
678  geomodel );
679  check_cell_attr_transfer_from_geomodelmesh_to_geomodel_regions(
680  geomodel );
681  }
682 
683  void load_file( GeoModel3D& geomodel )
684  {
685  std::lock_guard< std::mutex > locking( lock );
686  load_geomodel( geomodel, "modelA1_volume_meshed.gm" );
687  }
688 
689  void tests_transfer_from_geomodel_regions_to_geomodelmesh()
690  {
691  GeoModel3D geomodel;
692  load_file( geomodel );
693 
694  set_vertex_attributes_on_geomodel_regions( geomodel );
695  set_cell_attributes_on_geomodel_regions( geomodel );
696  const GeoModelMesh3D& gmm = geomodel.mesh;
697  gmm.transfer_attributes_from_gm_regions_to_gmm();
698  check_attr_transfer_from_geomodel_regions_to_geomodelmesh( geomodel );
699  }
700 
701  void tests_transfer_from_geomodelmesh_to_geomodel_regions()
702  {
703  GeoModel3D geomodel;
704  load_file( geomodel );
705 
706  set_vertex_attributes_on_geomodelmesh( geomodel );
707  set_cell_attributes_on_geomodelmesh( geomodel );
708  const GeoModelMesh3D& gmm = geomodel.mesh;
709  gmm.transfer_attributes_from_gmm_to_gm_regions();
710  check_attr_transfer_from_geomodelmesh_to_geomodel_regions( geomodel );
711  }
712 
713  void run_tests()
714  {
715  // long int is not a default attribute type in geogram.
716  GEO::geo_register_attribute_type< long int >( "long int" );
717 
718  std::vector< std::future< void > > futures;
719 
720  futures.emplace_back( std::async( std::launch::async,
721  &tests_transfer_from_geomodel_regions_to_geomodelmesh ) );
722  futures.emplace_back( std::async( std::launch::async,
723  &tests_transfer_from_geomodelmesh_to_geomodel_regions ) );
724 
725  for( auto& future : futures )
726  {
727  future.get();
728  }
729  }
730 }
731 
732 int main()
733 {
734  using namespace RINGMesh;
735 
736  try
737  {
739 
740  Logger::out( "TEST", "Tests of attribute transfer between the geomodel "
741  "and the geomodelmesh" );
742  run_tests();
743  }
744  catch( const RINGMeshException& e )
745  {
746  Logger::err( e.category(), e.what() );
747  return 1;
748  }
749  catch( const std::exception& e )
750  {
751  Logger::err( "Exception", e.what() );
752  return 1;
753  }
754  Logger::out( "TEST", "SUCCESS" );
755  return 0;
756 }
void run_tests(GeoModel3D &geomodel)
vecn< 3 > vec3
Definition: types.h:76
bool geomodel_load(GeoModel< DIMENSION > &geomodel, const std::string &filename)
Definition: io.cpp:131
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 load_geomodel(GeoModel3D &geomodel)
const std::string & category() const
Definition: common.h:165
Classes to build GeoModel from various inputs.
Definition: algorithm.h:48
void RINGMESH_API default_configure()
Definition: common.cpp:99