MOAB: Mesh Oriented datABase  (version 5.5.0)
gttool_test.cpp
Go to the documentation of this file.
1 /**
2  * This library is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU Lesser General Public
4  * License as published by the Free Software Foundation; either
5  * version 2.1 of the License, or (at your option) any later version.
6  *
7  */
8 /**
9  * \file gttool_test.cpp
10  *
11  * \brief test geometrize method from GeomTopoTool
12  *
13  */
14 #include "moab/Core.hpp"
15 #include <iostream>
16 
17 #include <cassert>
18 #include <cstring>
19 #include <cstdio>
20 
21 #include "TestUtil.hpp"
22 #include "moab/GeomTopoTool.hpp"
23 #include "MBTagConventions.hpp"
24 
25 using namespace moab;
26 
27 std::string filename;
28 std::string filename2;
29 std::string ofile;
30 std::string ofile2;
31 std::string ofile3;
32 std::string ofile4;
33 std::string ofile5;
34 
35 const char OBB_ROOT_TAG_NAME[] = "OBB_ROOT";
37 
40 
42 
44 
46 
48 
50 
52 
53 void handle_error_code( ErrorCode rv, int& number_failed, int& number_successful )
54 {
55  if( rv == MB_SUCCESS )
56  {
57  std::cout << "Success";
58  number_successful++;
59  }
60  else
61  {
62  std::cout << "Failure";
63  number_failed++;
64  }
65 }
66 
67 int main( int argc, char* argv[] )
68 {
69  filename = TestDir + "unittest/partBed.smf";
70  filename2 = TestDir + "unittest/test_geom.h5m";
71  ofile = "output.h5m";
72  ofile2 = "shell.h5m";
73  ofile3 = "shellCopy.h5m";
74  ofile4 = "geom_w_obbs.h5m";
75  ofile5 = "geom_missing_obb.h5m";
76 
77  remove_output_file = true;
78  bool only_check = false;
79  bool only_geometrize = false;
80 
81  if( argc == 1 )
82  {
83  std::cout << "Using default input file and output files " << filename << " " << ofile << " " << ofile2 << " "
84  << ofile3 << std::endl;
85  }
86  else if( argc == 5 )
87  {
88  filename = argv[1];
89  ofile = argv[2];
90  ofile2 = argv[3];
91  ofile3 = argv[4];
92  remove_output_file = false;
93  }
94  else if( argc == 2 )
95  {
96  ofile3 = argv[1]; // check model only from file
97  only_check = true;
98  remove_output_file = false; // this is input now, do not delete it
99  }
100  else if( argc == 3 )
101  {
102  filename = argv[1];
103  ofile = argv[2];
104  only_geometrize = true;
105  remove_output_file = false;
106  }
107  else
108  {
109  std::cerr << "Usage: " << argv[0] << " [surface_mesh] [mbgeo_file] [shellfile] [copyshellfile] " << std::endl;
110  return 1;
111  }
112 
113  int number_tests_successful = 0;
114  int number_tests_failed = 0;
115 
116  Core mbcore;
117  Interface* mb = &mbcore;
118 
119  // use this as a tool to check a model
120  if( only_check )
121  {
122  if( MB_SUCCESS == check_model_test( mb ) ) std::cout << ofile3 << " passed gtt check\n";
123  return 0;
124  }
125 
126  mb->load_file( filename.c_str() );
127 
128  // FBEngine * pFacet = new FBEngine(mb, NULL, true);// smooth facetting, no OBB tree passed
129 
130  std::cout << "geometrize test: ";
131  ErrorCode rval = geometrize_test( mb, 0 ); // just pass the root set
133  std::cout << "\n";
134 
135  if( only_geometrize )
136  {
137  return number_tests_failed;
138  }
139  std::cout << "create shell test: ";
140  rval = create_shell_test( mb );
142  std::cout << "\n";
143 
144  std::cout << "duplicate model test: ";
145  rval = duplicate_model_test( mb );
147  std::cout << "\n";
148 
149  std::cout << "check_model test: ";
150  rval = check_model_test( mb );
152  std::cout << "\n";
153 
154  std::cout << "test_rootsets_resize: ";
155  Interface* mb2 = new Core();
156  rval = test_root_sets_resize( mb2 );
158  delete mb2;
159  std::cout << "\n";
160 
161  std::cout << "test_delete_obb_tree: ";
162  Interface* mb3 = new Core();
163  rval = test_delete_obb_tree( mb3 );
165  delete mb3;
166  std::cout << "\n";
167 
168  std::cout << "test_restore_obb_trees: ";
169  Interface* mb4 = new Core();
170  Interface* mb5 = new Core();
171  Interface* mb6 = new Core();
172  rval = test_restore_obb_trees( mb4, mb5, mb6 );
174  delete mb4;
175  delete mb5;
176  delete mb6;
177  std::cout << "\n";
178 
179  return number_tests_failed;
180 }
182 {
183  GeomTopoTool gtt( mb );
184  EntityHandle outSet;
185  ErrorCode rval = gtt.geometrize_surface_set( inputSet, outSet );MB_CHK_SET_ERR( rval, "Can't geometrize the set\n" );
186 
187  std::cout << "writing output file: " << ofile.c_str() << " ";
188  rval = mb->write_file( ofile.c_str(), 0, 0, &outSet, 1 );MB_CHK_SET_ERR( rval, "Can't write output file\n" );
189  if( remove_output_file )
190  {
191  remove( ofile.c_str() );
192  }
193  return MB_SUCCESS;
194 }
195 
197 {
198  // we should be able to delete mesh and create a model from scratch
199 
200  ErrorCode rval = mb->delete_mesh();MB_CHK_SET_ERR( rval, "Can't delete existing mesh\n" );
201 
202  // create some vertices
203  double coords[] = { 0, 0, 0, 1, 0, 0.1, 2, 0, 0, 3, 0, -0.1, 0, 1, 0, 1, 1, 0, 2, 1, 0,
204  3, 1, -0.1, 0, 2, 0, 1, 2, -0.1, 2, 2, -0.1, 3, 2, -0.2, 0, 0, 1, 1, 0, 0.9,
205  2, 0.1, 0.85, 3, 0.2, 0.8, 0, 0.1, 2, 1, 0.1, 2, 2.1, 0.2, 2.1, 3.1, 0.2, 2.1 };
206 
207  int nvert = 20;
208  Range verts;
209  rval = mb->create_vertices( coords, nvert, verts );MB_CHK_SET_ERR( rval, "Can't create vertices\n" );
210 
211  EntityHandle connec[] = {
212  1, 2, 5, 5, 2, 6, 2, 3, 6, 6, 3, 7, 3, 4, 7, 7, 4, 8,
213  5, 6, 9, 9, 6, 10, 6, 7, 10, 10, 7, 11, 7, 8, 11, 11, 8, 12, // first face, 1-12
214  13, 14, 1, 1, 14, 2, 14, 15, 2, 2, 15, 3, 15, 16, 3, 3, 16, 4,
215  17, 18, 13, 13, 18, 14, 18, 19, 14, 14, 19, 15, 19, 20, 15, 15, 20, 16 // second face, 13-24
216  };
217  EntityHandle elem;
218  int nbTri = sizeof( connec ) / 3 / sizeof( EntityHandle );
219  int i = 0;
220  std::vector< EntityHandle > tris;
221  for( i = 0; i < nbTri; i++ )
222  {
223  mb->create_element( MBTRI, &connec[3 * i], 3, elem );
224  tris.push_back( elem );
225  }
226 
227  // create some edges too
228  EntityHandle edges[] = {
229  1, 2, 2, 3, 3, 4, // geo edge 1 1:3
230  4, 8, 8, 12, // geo 2 4:5
231  12, 11, 11, 10, 10, 9, // geo 3 6:8
232  9, 5, 5, 1, // geo 4 9:10
233  1, 13, 13, 17, // geo 5 11:12
234  17, 18, 18, 19, 19, 20, // geo 6 13:15
235  20, 16, 16, 4 // geo 7 16:17
236  };
237  int nbEdges = sizeof( edges ) / 2 / sizeof( EntityHandle );
238  std::vector< EntityHandle > edgs;
239  for( i = 0; i < nbEdges; i++ )
240  {
241  mb->create_element( MBEDGE, &edges[2 * i], 2, elem );
242  edgs.push_back( elem );
243  }
244  // create some sets, and create some ordered sets for edges
245  EntityHandle face1, face2;
246  rval = mb->create_meshset( MESHSET_SET, face1 );MB_CHK_ERR( rval );
247  rval = mb->add_entities( face1, &tris[0], 12 );MB_CHK_ERR( rval );
248 
249  rval = mb->create_meshset( MESHSET_SET, face2 );MB_CHK_ERR( rval );
250  // next 12 triangles
251  rval = mb->add_entities( face2, &tris[12], 12 );MB_CHK_ERR( rval );
252 
253  // the orientation and senses need to be set for face edges
254  moab::GeomTopoTool gTopoTool( mb, false );
255 
256  rval = gTopoTool.add_geo_set( face1, 2 );MB_CHK_ERR( rval );
257 
258  rval = gTopoTool.add_geo_set( face2, 2 );MB_CHK_ERR( rval );
259 
260  // create some edges
261  EntityHandle edge[7]; // edge[0] has EH 1...
262  ;
263  for( i = 0; i < 7; i++ )
264  {
265  rval = mb->create_meshset( MESHSET_ORDERED, edge[i] );MB_CHK_ERR( rval );
266  rval = gTopoTool.add_geo_set( edge[i], 1 );MB_CHK_ERR( rval );
267  }
268 
269  // first 3 mesh edges...
270  rval = mb->add_entities( edge[0], &edgs[0], 3 );MB_CHK_ERR( rval );
271  rval = mb->add_entities( edge[1], &edgs[3], 2 );MB_CHK_ERR( rval );
272  rval = mb->add_entities( edge[2], &edgs[5], 3 );MB_CHK_ERR( rval );
273  rval = mb->add_entities( edge[3], &edgs[8], 2 );MB_CHK_ERR( rval );
274  rval = mb->add_entities( edge[4], &edgs[10], 2 );MB_CHK_ERR( rval );
275  rval = mb->add_entities( edge[5], &edgs[12], 3 );MB_CHK_ERR( rval );
276  rval = mb->add_entities( edge[6], &edgs[15], 2 );MB_CHK_ERR( rval );
277 
278  // create some sets for vertices; also need to create some for parent/child relationships
279  EntityHandle vertSets[6]; // start from 0
280 
281  for( i = 0; i < 6; i++ )
282  {
283  rval = mb->create_meshset( MESHSET_SET, vertSets[i] );MB_CHK_ERR( rval );
284  rval = gTopoTool.add_geo_set( vertSets[i], 0 );MB_CHK_ERR( rval );
285  }
286 
287  EntityHandle v( 1 ); // first vertex;
288  rval = mb->add_entities( vertSets[0], &v, 1 );MB_CHK_ERR( rval );
289  v = EntityHandle( 4 );
290  rval = mb->add_entities( vertSets[1], &v, 1 );MB_CHK_ERR( rval );
291  v = EntityHandle( 9 );
292  rval = mb->add_entities( vertSets[2], &v, 1 );MB_CHK_ERR( rval );
293  v = EntityHandle( 12 );
294  rval = mb->add_entities( vertSets[3], &v, 1 );MB_CHK_ERR( rval );
295  v = EntityHandle( 17 );
296  rval = mb->add_entities( vertSets[4], &v, 1 );MB_CHK_ERR( rval );
297  v = EntityHandle( 20 );
298  rval = mb->add_entities( vertSets[5], &v, 1 );MB_CHK_ERR( rval );
299 
300  // need to add parent-child relations between sets
301  // edge 1 : 1-2
302  rval = mb->add_parent_child( edge[0], vertSets[0] );MB_CHK_ERR( rval );
303  rval = mb->add_parent_child( edge[0], vertSets[1] );MB_CHK_ERR( rval );
304  // edge 2 : 2-4
305  rval = mb->add_parent_child( edge[1], vertSets[1] );MB_CHK_ERR( rval );
306  rval = mb->add_parent_child( edge[1], vertSets[3] );MB_CHK_ERR( rval );
307 
308  // edge 3 : 4-3
309  rval = mb->add_parent_child( edge[2], vertSets[3] );MB_CHK_ERR( rval );
310  rval = mb->add_parent_child( edge[2], vertSets[2] );MB_CHK_ERR( rval );
311 
312  // edge 4 : 4-1
313  rval = mb->add_parent_child( edge[3], vertSets[2] );MB_CHK_ERR( rval );
314  rval = mb->add_parent_child( edge[3], vertSets[0] );MB_CHK_ERR( rval );
315 
316  // edge 5 : 1-5
317  rval = mb->add_parent_child( edge[4], vertSets[0] );MB_CHK_ERR( rval );
318  rval = mb->add_parent_child( edge[4], vertSets[4] );MB_CHK_ERR( rval );
319 
320  // edge 6 : 5-6
321  rval = mb->add_parent_child( edge[5], vertSets[4] );MB_CHK_ERR( rval );
322  rval = mb->add_parent_child( edge[5], vertSets[5] );MB_CHK_ERR( rval );
323 
324  // edge 7 : 6-2
325  rval = mb->add_parent_child( edge[6], vertSets[5] );MB_CHK_ERR( rval );
326  rval = mb->add_parent_child( edge[6], vertSets[1] );MB_CHK_ERR( rval );
327 
328  // face 1: edges 1, 2, 3, 4
329  rval = mb->add_parent_child( face1, edge[0] );MB_CHK_ERR( rval );
330  rval = mb->add_parent_child( face1, edge[1] );MB_CHK_ERR( rval );
331  rval = mb->add_parent_child( face1, edge[2] );MB_CHK_ERR( rval );
332  rval = mb->add_parent_child( face1, edge[3] );MB_CHK_ERR( rval );
333 
334  // face 2: edges 1, 5, 6, 7
335  rval = mb->add_parent_child( face2, edge[0] );MB_CHK_ERR( rval );
336  rval = mb->add_parent_child( face2, edge[4] );MB_CHK_ERR( rval );
337  rval = mb->add_parent_child( face2, edge[5] );MB_CHK_ERR( rval );
338  rval = mb->add_parent_child( face2, edge[6] );MB_CHK_ERR( rval );
339 
340  // set senses !!
341  std::vector< EntityHandle > faces;
342  faces.push_back( face1 ); // the face1 has all edges oriented positively
343  std::vector< int > senses;
344  senses.push_back( moab::SENSE_FORWARD ); //
345 
346  // faces.push_back(face1);
347  // faces.push_back(face2);
348  gTopoTool.set_senses( edge[1], faces, senses );
349  gTopoTool.set_senses( edge[2], faces, senses );
350  gTopoTool.set_senses( edge[3], faces, senses );
351 
352  faces[0] = face2; // set senses for edges for face2
353  gTopoTool.set_senses( edge[4], faces, senses );
354  gTopoTool.set_senses( edge[5], faces, senses );
355  gTopoTool.set_senses( edge[6], faces, senses );
356 
357  // the only complication is edge1 (edge[0]), that has face1 forward and face 2 reverse
358  faces[0] = face1;
359  faces.push_back( face2 );
360  senses.push_back( moab::SENSE_REVERSE ); // -1 is reverse; face 2 is reverse for edge1 (0)
361  // forward == 0, reverse ==1
362  gTopoTool.set_senses( edge[0], faces, senses );
363 
364  rval = mb->write_mesh( ofile2.c_str() );MB_CHK_ERR( rval );
365 
366  rval = mb->delete_mesh();MB_CHK_ERR( rval );
367 
368  // now test loading it up
369  rval = mb->load_file( ofile2.c_str() );MB_CHK_ERR( rval );
370 
371  if( remove_output_file )
372  {
373  remove( ofile2.c_str() );
374  }
375  // do some tests on geometry
376 
377  // it would be good to have a method on updating the geom topo tool
378  // so we do not have to create another one
379  moab::GeomTopoTool gTopoTool2( mb, true ); // to find the geomsets
380  Range ranges[5];
381  rval = gTopoTool2.find_geomsets( ranges );
382 
383  assert( MB_SUCCESS == rval );
384  assert( ranges[0].size() == 6 );
385  assert( ranges[1].size() == 7 );
386  assert( ranges[2].size() == 2 );
387  assert( ranges[3].size() == 0 );
388  assert( ranges[4].size() == 0 );
389 
390  return MB_SUCCESS;
391 }
392 
394 {
395  moab::GeomTopoTool gTopoTool2( mb, true ); // to find the geomsets
396 
397  GeomTopoTool* newModel = NULL;
398  ErrorCode rval = gTopoTool2.duplicate_model( newModel );
399  if( NULL == newModel || rval != MB_SUCCESS ) return MB_FAILURE;
400 
401  Range ranges[5];
402  rval = newModel->find_geomsets( ranges );MB_CHK_ERR( rval );
403 
404  assert( ranges[0].size() == 6 );
405  assert( ranges[1].size() == 7 );
406  assert( ranges[2].size() == 2 );
407  assert( ranges[3].size() == 0 );
408 
409  // write the model to a test file
410  EntityHandle rootModelSet = newModel->get_root_model_set();
411  std::cout << "writing duplicated model file: " << ofile3.c_str() << " ";
412  rval = mb->write_file( ofile3.c_str(), 0, 0, &rootModelSet, 1 );MB_CHK_SET_ERR( rval, "Can't write output files\n" );
413 
414  delete newModel; // we are done with the new geom topo tool
415  // do not delete yet the output file, delay after the next test
416  /*if (remove_output_file)
417  {
418  remove(ofile3.c_str());
419  }*/
420 
421  return MB_SUCCESS;
422 }
423 
425 {
426  ErrorCode rval = mb->delete_mesh();MB_CHK_SET_ERR( rval, "Can't delete existing mesh\n" );
427 
428  rval = mb->load_file( ofile3.c_str() );MB_CHK_ERR( rval );
429 
430  // do some tests on geometry
431  // it would be good to have a method on updating the geom topo tool
432  // so we do not have to create another one
433  if( remove_output_file )
434  {
435  remove( ofile3.c_str() );
436  }
437  moab::GeomTopoTool gTopoTool( mb, true );
438 
439  if( !gTopoTool.check_model() ) return MB_FAILURE;
440 
441  return MB_SUCCESS;
442 }
443 
445 {
446 
447  // load the test file
448  ErrorCode rval = mb->load_file( filename2.c_str() );MB_CHK_SET_ERR( rval, "Failed to load input file" );
449 
450  // create a GTT with all default settings
451  moab::GeomTopoTool* gTopoTool = new GeomTopoTool( mb );
452 
453  Tag geomTag;
454 
455  rval = mb->tag_get_handle( GEOM_DIMENSION_TAG_NAME, 1, MB_TYPE_INTEGER, geomTag, MB_TAG_CREAT | MB_TAG_SPARSE );MB_CHK_SET_ERR( rval, "Error: Failed to create geometry dimension tag" );
456 
457  Range surfs;
458 
459  const int dim = 2;
460  const void* const dim_val[] = { &dim };
461  rval = mb->get_entities_by_type_and_tag( 0, MBENTITYSET, &geomTag, dim_val, 1, surfs );MB_CHK_SET_ERR( rval, "Failed to get entity sets by type and tag" );
462 
463  // in reverse order, add surfaces and construct their trees
464  for( Range::reverse_iterator rit = surfs.rbegin(); rit != surfs.rend(); rit++ )
465  {
466 
467  rval = gTopoTool->add_geo_set( *rit, 2 );MB_CHK_SET_ERR( rval, "Failed to add geometry set to GTT" );
468 
469  rval = gTopoTool->construct_obb_tree( *rit );MB_CHK_SET_ERR( rval, "Failed to construct obb tree for surf " << *rit );
470  }
471 
472  for( Range::iterator it = surfs.begin(); it != surfs.end(); it++ )
473  {
474  EntityHandle obb_root_set;
475  rval = gTopoTool->get_root( *it, obb_root_set );MB_CHK_SET_ERR( rval, "Failed to get obb tree root from GTT" );
476 
477  // make sure the returned root is valid
478  CHECK( obb_root_set );
479  }
480 
481  // clean up GTT
482  delete gTopoTool;
483 
484  // create a GTT with all default settings
485  gTopoTool = new moab::GeomTopoTool( mb, false, 0, false );
486 
487  // in reverse order, add surfaces and construct their trees
488  for( Range::reverse_iterator rit = surfs.rbegin(); rit != surfs.rend(); rit++ )
489  {
490 
491  rval = gTopoTool->add_geo_set( *rit, 2 );MB_CHK_SET_ERR( rval, "Failed to add geometry set to GTT" );
492 
493  rval = gTopoTool->construct_obb_tree( *rit );MB_CHK_SET_ERR( rval, "Failed to construct obb tree for surf " << *rit );
494  }
495 
496  for( Range::iterator it = surfs.begin(); it != surfs.end(); it++ )
497  {
498  EntityHandle obb_root_set;
499  rval = gTopoTool->get_root( *it, obb_root_set );MB_CHK_SET_ERR( rval, "Failed to get obb tree root from GTT" );
500 
501  // make sure the returned root is valid
502  CHECK( obb_root_set );
503  }
504 
505  delete gTopoTool;
506 
507  rval = mb->delete_mesh();MB_CHK_SET_ERR( rval, "Failed to delete mesh in MOAB instance." );
508 
509  return MB_SUCCESS;
510 }
511 
513 {
514 
515  // Load the test file
516  ErrorCode rval = mb->load_file( filename2.c_str() );MB_CHK_SET_ERR( rval, "Failed to load input file" );
517 
518  // Create a GTT with all default settings
519  moab::GeomTopoTool* gTopoTool = new GeomTopoTool( mb );
520 
521  // Get all volumes and surfaces
522  Range vols, surfs;
523  rval = gTopoTool->get_gsets_by_dimension( 3, vols );MB_CHK_SET_ERR( rval, "Failed to get volume gsets" );
524  rval = gTopoTool->get_gsets_by_dimension( 2, surfs );MB_CHK_SET_ERR( rval, "Failed to get surface gsets" );
525 
526  // Build obb tree for volume
527  EntityHandle test_vol = vols.front();
528  rval = gTopoTool->construct_obb_tree( test_vol );MB_CHK_SET_ERR( rval, "Error constructing all trees." );
529 
530  // Get the obbRootTag for vol
531  rval = mb->tag_get_handle( OBB_ROOT_TAG_NAME, 1, MB_TYPE_HANDLE, obbRootTag, MB_TAG_CREAT | MB_TAG_SPARSE );MB_CHK_SET_ERR_CONT( rval, "Error: Failed to create obb root tag" );
532  EntityHandle gbroot;
533  rval = mb->tag_get_data( obbRootTag, &test_vol, 1, &gbroot );MB_CHK_SET_ERR( rval, "Failed to get the obb root tag" );
534 
535  // Test if obb tree in ModelSet
536  EntityHandle test_vol_root;
537  rval = gTopoTool->get_root( test_vol, test_vol_root );MB_CHK_SET_ERR( rval, "Obb root not in ModelSet" );
538 
539  // CASE 1: Delete vol obb tree including all child surface trees
540  rval = gTopoTool->delete_obb_tree( test_vol, false );MB_CHK_SET_ERR( rval, "Error deleting volume tree." );
541 
542  // Make sure vol tree is gone
543  EntityHandle newroot;
544  rval = mb->tag_get_data( obbRootTag, &test_vol, 1, &newroot );
545  if( MB_SUCCESS == rval )
546  {
547  return MB_FAILURE;
548  }
549 
550  // Make sure its child surf trees also gone
551  Range::iterator surf_it;
552  for( surf_it = surfs.begin(); surf_it != surfs.end(); ++surf_it )
553  {
554  EntityHandle test_surf_root_gone;
555  rval = mb->tag_get_data( obbRootTag, &( *surf_it ), 1, &test_surf_root_gone );
556  if( MB_SUCCESS == rval )
557  {
558  return MB_FAILURE;
559  }
560  }
561 
562  // Rebuild vol tree
563  rval = gTopoTool->construct_obb_tree( test_vol );MB_CHK_SET_ERR( rval, "Error constructing all trees." );
564 
565  // CASE 2: Delete just vol, not surf trees
566  rval = gTopoTool->delete_obb_tree( test_vol, true );MB_CHK_SET_ERR( rval, "Error deleting volume tree." );
567 
568  // Make sure vol tree is gone
569  rval = mb->tag_get_data( obbRootTag, &test_vol, 1, &gbroot );
570  if( MB_SUCCESS == rval )
571  {
572  return MB_FAILURE;
573  }
574 
575  // Make sure its child surf trees remain
576  for( surf_it = surfs.begin(); surf_it != surfs.end(); ++surf_it )
577  {
578  EntityHandle test_surf_root;
579  rval = mb->tag_get_data( obbRootTag, &( *surf_it ), 1, &test_surf_root );MB_CHK_SET_ERR( rval, "Problem getting obb root of surface." );
580  }
581 
582  // CASE 3: Delete surf tree
583  EntityHandle test_surf = surfs.front();
584  rval = gTopoTool->delete_obb_tree( test_surf, false );MB_CHK_SET_ERR( rval, "Error deleting surface tree." );
585 
586  // Make sure surf tree is gone
587  rval = mb->tag_get_data( obbRootTag, &test_surf, 1, &gbroot );
588  if( MB_SUCCESS == rval )
589  {
590  return MB_FAILURE;
591  }
592 
593  delete gTopoTool;
594 
595  return MB_SUCCESS;
596 }
597 
599 {
600 
601  // Load the test file
602  ErrorCode rval = mb->load_file( filename2.c_str() );MB_CHK_SET_ERR( rval, "Failed to load input file" );
603 
604  // Create a GTT with all default settings
605  moab::GeomTopoTool* gTopoTool = new GeomTopoTool( mb );
606 
607  // Build all obb trees
608  rval = gTopoTool->construct_obb_trees();MB_CHK_SET_ERR( rval, "Error constructing all trees" );
609  // Write the file with all obbs
610  rval = mb->write_file( ofile4.c_str() );MB_CHK_SET_ERR( rval, "Can't write output file" );
611 
612  // Delete a vol obb tree
613  Range vols;
614  rval = gTopoTool->get_gsets_by_dimension( 3, vols );MB_CHK_SET_ERR( rval, "Failed to get volume gsets" );
615  EntityHandle test_vol = vols.front();
616  rval = gTopoTool->delete_obb_tree( test_vol, false );MB_CHK_SET_ERR( rval, "Error deleting volume tree" );
617  // Write the file missing an obb
618  rval = mb->write_file( ofile5.c_str() );MB_CHK_SET_ERR( rval, "Can't write output file" );
619 
620  // Load file containing obbs
621  rval = mb2->load_file( ofile4.c_str() );MB_CHK_SET_ERR( rval, "Failed to load file containing obbs" );
622 
623  // 1) Check that roots are NOT restored by default GTT settings
624  // GeomTopoTool(Interface *impl, bool find_geoments = false, EntityHandle modelRootSet = 0,
625  // bool p_rootSets_vector = true, bool restore_rootSets = true);
626  moab::GeomTopoTool* gTopoTool2 = new GeomTopoTool( mb2, false, 0, true, true );
627 
628  vols.clear();
629  Range surfs;
630  rval = gTopoTool2->get_gsets_by_dimension( 3, vols );MB_CHK_SET_ERR( rval, "Failed to get volume gsets" );
631  rval = gTopoTool2->get_gsets_by_dimension( 2, surfs );MB_CHK_SET_ERR( rval, "Failed to get volume gsets" );
632 
633  Range gsets;
634  gsets.insert_list( surfs.begin(), surfs.end() );
635  gsets.insert_list( vols.begin(), vols.end() );
636  EntityHandle test_root2;
637  for( Range::iterator rit = gsets.begin(); rit != gsets.end(); ++rit )
638  {
639  rval = gTopoTool2->get_root( *rit, test_root2 );
640  if( MB_SUCCESS == rval )
641  {
642  return MB_FAILURE;
643  }
644  }
645 
646  // 2) Check that roots ARE restored by setting find_geoments and restore_rootSets to true
647  moab::GeomTopoTool* gTopoTool3 = new GeomTopoTool( mb2, true, 0, true, true );
648 
649  vols.clear();
650  rval = gTopoTool3->get_gsets_by_dimension( 3, vols );MB_CHK_SET_ERR( rval, "Failed to get volume gsets" );
651  surfs.clear();
652  rval = gTopoTool3->get_gsets_by_dimension( 2, surfs );MB_CHK_SET_ERR( rval, "Failed to get volume gsets" );
653 
654  gsets.clear();
655  gsets.insert_list( surfs.begin(), surfs.end() );
656  gsets.insert_list( vols.begin(), vols.end() );
657  EntityHandle test_root3;
658  for( Range::iterator rit = gsets.begin(); rit != gsets.end(); ++rit )
659  {
660  rval = gTopoTool3->get_root( *rit, test_root3 );MB_CHK_SET_ERR( rval, "Failed to get obb tree root from GTT" );
661  CHECK( test_root3 );
662  }
663 
664  // 3) Check that roots are deleted and then rebuilt if an obb tree is missing
665 
666  // Load file missing obb
667  rval = mb3->load_file( ofile5.c_str() );MB_CHK_SET_ERR( rval, "Failed to load file containing obbs" );
668 
669  // Create GTT and try to restore OBBs
670  moab::GeomTopoTool* gTopoTool4 = new GeomTopoTool( mb3, true, 0, true, true );
671 
672  // Check that roots still exist
673  vols.clear();
674  rval = gTopoTool4->get_gsets_by_dimension( 3, vols );MB_CHK_SET_ERR( rval, "Failed to get volume gsets" );
675  surfs.clear();
676  rval = gTopoTool4->get_gsets_by_dimension( 2, surfs );MB_CHK_SET_ERR( rval, "Failed to get volume gsets" );
677 
678  gsets.clear();
679  gsets.insert_list( surfs.begin(), surfs.end() );
680  gsets.insert_list( vols.begin(), vols.end() );
681  EntityHandle test_root4;
682  for( Range::iterator rit = gsets.begin(); rit != gsets.end(); ++rit )
683  {
684  rval = gTopoTool4->get_root( *rit, test_root4 );MB_CHK_SET_ERR( rval, "Failed to get obb tree root from GTT" );
685  CHECK( test_root4 );
686  }
687 
688  // 4) Check that roots exist but rootSets is NOT repopulated when find_geoments = true and
689  // restore_rootSets = false
690  moab::GeomTopoTool* gTopoTool5 = new GeomTopoTool( mb2, true, 0, true, false );
691 
692  // Get the obbRootTag for vol
693  rval = mb2->tag_get_handle( OBB_ROOT_TAG_NAME, 1, MB_TYPE_HANDLE, obbRootTag, MB_TAG_CREAT | MB_TAG_SPARSE );MB_CHK_SET_ERR_CONT( rval, "Error: Failed to create obb root tag" );
694 
695  vols.clear();
696  rval = gTopoTool5->get_gsets_by_dimension( 3, vols );MB_CHK_SET_ERR( rval, "Failed to get volume gsets" );
697  surfs.clear();
698  rval = gTopoTool5->get_gsets_by_dimension( 2, surfs );MB_CHK_SET_ERR( rval, "Failed to get volume gsets" );
699 
700  gsets.clear();
701  gsets.insert_list( surfs.begin(), surfs.end() );
702  gsets.insert_list( vols.begin(), vols.end() );
703  EntityHandle test_root5, tagged_root;
704  for( Range::iterator rit = gsets.begin(); rit != gsets.end(); ++rit )
705  {
706  // Check that root still exits, but not in rootSet
707  rval = mb2->tag_get_data( obbRootTag, &( *rit ), 1, &tagged_root );MB_CHK_SET_ERR( rval, "Failed to get root from tag" );
708  CHECK( tagged_root );
709  rval = gTopoTool5->get_root( *rit, test_root5 );
710  if( MB_SUCCESS == rval ) return MB_FAILURE;
711  }
712 
713  delete gTopoTool;
714  delete gTopoTool2;
715  delete gTopoTool3;
716  delete gTopoTool4;
717  delete gTopoTool5;
718 
719  return MB_SUCCESS;
720 }