MOAB: Mesh Oriented datABase  (version 5.5.0)
obb_tree_tool.cpp File Reference
#include "moab/Core.hpp"
#include "moab/CartVect.hpp"
#include "moab/OrientedBoxTreeTool.hpp"
#include "moab/OrientedBox.hpp"
#include "Internals.hpp"
#include "moab/Range.hpp"
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <limits>
#include <cstdlib>
#include <ctime>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
+ Include dependency graph for obb_tree_tool.cpp:

Go to the source code of this file.

Classes

struct  SimpleStat< T >
 
class  TriTagger
 
class  VtxTagger
 
class  LeafHexer
 

Macros

#define IS_BUILDING_MB
 

Functions

std::string clock_to_string (clock_t t)
 
std::string mem_to_string (unsigned long mem)
 
ErrorCode get_root (Interface *moab, EntityHandle &root)
 
EntityHandle build_tree (Interface *interface, OrientedBoxTreeTool::Settings settings)
 
void delete_existing_tree (Interface *interface)
 
void print_stats (Interface *interface)
 
void tag_triangles (Interface *interface)
 
void tag_vertices (Interface *interface)
 
void write_tree_blocks (Interface *interface, const char *file)
 
static void usage (bool err=true)
 
static void memory_use (unsigned long long &vsize, unsigned long long &rss)
 
static int parseint (int &i, int argc, char *argv[])
 
static double parsedouble (int &i, int argc, char *argv[])
 
int main (int argc, char *argv[])
 
static int hash_handle (EntityHandle handle)
 

Variables

const int MAX_TAG_VALUE = 20
 
const char *const TAG_NAME = "OBB_ID"
 
const char *const TREE_TAG = "OBB_ROOT"
 
const char * root_tag = TREE_TAG
 

Macro Definition Documentation

◆ IS_BUILDING_MB

#define IS_BUILDING_MB

Definition at line 1 of file obb_tree_tool.cpp.

Function Documentation

◆ build_tree()

EntityHandle build_tree ( Interface interface,
OrientedBoxTreeTool::Settings  settings 
)

Definition at line 299 of file obb_tree_tool.cpp.

300 {
301  ErrorCode rval;
302  EntityHandle root = 0;
303  Range triangles;
304 
305  rval = interface->get_entities_by_type( 0, MBTRI, triangles );
306  if( MB_SUCCESS != rval || triangles.empty() )
307  {
308  std::cerr << "No triangles from which to build tree." << std::endl;
309  exit( 4 );
310  }
311 
312  OrientedBoxTreeTool tool( interface );
313  rval = tool.build( triangles, root, &settings );
314  if( MB_SUCCESS != rval || !root )
315  {
316  std::cerr << "Tree construction failed." << std::endl;
317  exit( 4 );
318  }
319 
320  // store tree root
321  Tag roottag;
322  rval = interface->tag_get_handle( root_tag, 1, MB_TYPE_HANDLE, roottag, MB_TAG_CREAT | MB_TAG_SPARSE );
323  if( MB_SUCCESS != rval )
324  {
325  std::cout << "Failed to create root tag: \"" << root_tag << '"' << std::endl;
326  exit( 2 );
327  }
328  const EntityHandle mesh = 0;
329  rval = interface->tag_set_data( roottag, &mesh, 1, &root );
330  if( MB_SUCCESS != rval )
331  {
332  std::cout << "Failed to set root tag: \"" << root_tag << '"' << std::endl;
333  exit( 2 );
334  }
335 
336  return root;
337 }

References moab::OrientedBoxTreeTool::build(), moab::Range::empty(), ErrorCode, moab::Interface::get_entities_by_type(), MB_SUCCESS, MB_TAG_CREAT, MB_TAG_SPARSE, MB_TYPE_HANDLE, MBTRI, mesh, root_tag, settings, moab::Interface::tag_get_handle(), and moab::Interface::tag_set_data().

Referenced by main().

◆ clock_to_string()

std::string clock_to_string ( clock_t  t)

Definition at line 339 of file obb_tree_tool.cpp.

340 {
341  char unit[5] = "s";
342  char buffer[256];
343  double dt = t / (double)CLOCKS_PER_SEC;
344  // if (dt > 300) {
345  // dt /= 60;
346  // strcpy( unit, "min" );
347  //}
348  // if (dt > 300) {
349  // dt /= 60;
350  // strcpy( unit, "hr" );
351  //}
352  // if (dt > 100) {
353  // dt /= 24;
354  // strcpy( unit, "days" );
355  //}
356  sprintf( buffer, "%0.2f%s", dt, unit );
357  return buffer;
358 }

References buffer, t, and moab::unit().

Referenced by main().

◆ delete_existing_tree()

void delete_existing_tree ( Interface interface)

Definition at line 283 of file obb_tree_tool.cpp.

284 {
285  EntityHandle root;
286  ErrorCode rval = get_root( interface, root );
287  if( MB_SUCCESS == rval )
288  {
289  OrientedBoxTreeTool tool( interface );
290  rval = tool.delete_tree( root );
291  if( MB_SUCCESS != rval )
292  {
293  std::cerr << "Failed to destroy existing trees. Aborting" << std::endl;
294  exit( 5 );
295  }
296  }
297 }

References moab::OrientedBoxTreeTool::delete_tree(), ErrorCode, get_root(), and MB_SUCCESS.

Referenced by main().

◆ get_root()

ErrorCode get_root ( Interface moab,
EntityHandle root 
)

Definition at line 271 of file obb_tree_tool.cpp.

272 {
273  Tag tag;
274  ErrorCode rval;
275 
276  rval = moab->tag_get_handle( root_tag, 1, MB_TYPE_HANDLE, tag );
277  if( MB_SUCCESS != rval ) return rval;
278 
279  const EntityHandle mesh = 0;
280  return moab->tag_get_data( tag, &mesh, 1, &root );
281 }

References ErrorCode, MB_SUCCESS, MB_TYPE_HANDLE, mesh, and root_tag.

Referenced by delete_existing_tree(), print_stats(), tag_triangles(), tag_vertices(), and write_tree_blocks().

◆ hash_handle()

static int hash_handle ( EntityHandle  handle)
static

Definition at line 458 of file obb_tree_tool.cpp.

459 {
460  EntityID h = ID_FROM_HANDLE( handle );
461  return (int)( ( h * 13 + 7 ) % MAX_TAG_VALUE ) + 1;
462 }

References moab::ID_FROM_HANDLE(), and MAX_TAG_VALUE.

Referenced by TriTagger::leaf(), VtxTagger::leaf(), and LeafHexer::leaf().

◆ main()

int main ( int  argc,
char *  argv[] 
)

Definition at line 135 of file obb_tree_tool.cpp.

136 {
137  const char* input_file = 0;
138  const char* output_file = 0;
139  const char* tree_file = 0;
141  bool tag_tris = false;
142  clock_t load_time, build_time, stat_time, tag_time, write_time, block_time;
143 
144  for( int i = 1; i < argc; ++i )
145  {
146  if( argv[i][0] != '-' )
147  {
148  if( !input_file )
149  input_file = argv[i];
150  else if( !output_file )
151  output_file = argv[i];
152  else
153  usage();
154  continue;
155  }
156 
157  if( !argv[i][1] || argv[i][2] ) usage();
158 
159  switch( argv[i][1] )
160  {
161  case 's':
163  break;
164  case 'S':
165  settings.set_options = MESHSET_ORDERED;
166  break;
167  case 'd':
168  settings.max_depth = parseint( i, argc, argv );
169  break;
170  case 'n':
171  settings.max_leaf_entities = parseint( i, argc, argv );
172  break;
173  case 'm':
174  settings.worst_split_ratio = parsedouble( i, argc, argv );
175  break;
176  case 'M':
177  settings.best_split_ratio = parsedouble( i, argc, argv );
178  break;
179  case 't':
180  tag_tris = true;
181  break;
182  case 'T':
183  if( ++i == argc ) usage();
184  tree_file = argv[i];
185  break;
186  case 'N':
187  if( ++i == argc ) usage();
188  root_tag = argv[i];
189  break;
190  case 'h':
191  usage( false );
192  break;
193  default:
194  usage();
195  }
196  }
197 
198  if( !output_file ) usage();
199 
200  ErrorCode rval;
201  Core moab_core;
202  Interface* interface = &moab_core;
203 
204  load_time = clock();
205  rval = interface->load_mesh( input_file );
206  if( MB_SUCCESS != rval )
207  {
208  std::cerr << "Error reading file: " << input_file << std::endl;
209  exit( 2 );
210  }
211  load_time = clock() - load_time;
212 
213  delete_existing_tree( interface );
214 
215  std::cout << "Building tree..." << std::endl;
216  build_time = clock();
217  build_tree( interface, settings );
218  build_time = clock() - build_time;
219 
220  std::cout << "Calculating stats..." << std::endl;
221  print_stats( interface );
222  stat_time = clock() - build_time;
223 
224  if( tag_tris )
225  {
226  std::cout << "Tagging tree..." << std::endl;
227  tag_triangles( interface );
228  tag_vertices( interface );
229  }
230  tag_time = clock() - stat_time;
231 
232  std::cout << "Writing file... ";
233  std::cout.flush();
234  rval = interface->write_mesh( output_file );
235  if( MB_SUCCESS != rval )
236  {
237  std::cerr << "Error writing file: " << output_file << std::endl;
238  exit( 3 );
239  }
240  write_time = clock() - tag_time;
241  std::cout << "Wrote " << output_file << std::endl;
242 
243  if( tree_file )
244  {
245  std::cout << "Writing tree block rep...";
246  std::cout.flush();
247  write_tree_blocks( interface, tree_file );
248  std::cout << "Wrote " << tree_file << std::endl;
249  }
250  block_time = clock() - write_time;
251 
252  std::cout << "Times: "
253  << " Load"
254  << " Build"
255  << " Stats"
256  << " Write";
257  if( tag_tris ) std::cout << "Tag Sets";
258  if( tree_file ) std::cout << "Block ";
259  std::cout << std::endl;
260 
261  std::cout << " " << std::setw( 8 ) << clock_to_string( load_time ) << std::setw( 8 )
262  << clock_to_string( build_time ) << std::setw( 8 ) << clock_to_string( stat_time ) << std::setw( 8 )
263  << clock_to_string( write_time );
264  if( tag_tris ) std::cout << std::setw( 8 ) << clock_to_string( tag_time );
265  if( tree_file ) std::cout << std::setw( 8 ) << clock_to_string( block_time );
266  std::cout << std::endl;
267 
268  return 0;
269 }

References moab::OrientedBoxTreeTool::Settings::best_split_ratio, build_time, build_tree(), clock_to_string(), delete_existing_tree(), ErrorCode, input_file, load_time, moab::OrientedBoxTreeTool::Settings::max_depth, moab::OrientedBoxTreeTool::Settings::max_leaf_entities, MB_SUCCESS, MESHSET_SET, parsedouble(), parseint(), print_stats(), root_tag, moab::OrientedBoxTreeTool::Settings::set_options, settings, tag_time(), tag_triangles(), tag_vertices(), usage(), moab::OrientedBoxTreeTool::Settings::worst_split_ratio, and write_tree_blocks().

◆ mem_to_string()

std::string mem_to_string ( unsigned long  mem)

Definition at line 360 of file obb_tree_tool.cpp.

361 {
362  char unit[3] = "B";
363  if( mem > 9 * 1024 )
364  {
365  mem = ( mem + 512 ) / 1024;
366  strcpy( unit, "kB" );
367  }
368  if( mem > 9 * 1024 )
369  {
370  mem = ( mem + 512 ) / 1024;
371  strcpy( unit, "MB" );
372  }
373  if( mem > 9 * 1024 )
374  {
375  mem = ( mem + 512 ) / 1024;
376  strcpy( unit, "GB" );
377  }
378  char buffer[256];
379  sprintf( buffer, "%lu %s", mem, unit );
380  return buffer;
381 }

References buffer, and moab::unit().

Referenced by print_stats().

◆ memory_use()

static void memory_use ( unsigned long long &  vsize,
unsigned long long &  rss 
)
static

Definition at line 68 of file obb_tree_tool.cpp.

69 {
70  char buffer[512];
71  unsigned long lvsize;
72  long lrss;
73  int filp = open( "/proc/self/stat", O_RDONLY );
74  ssize_t r = read( filp, buffer, sizeof( buffer ) - 1 );
75  close( filp );
76  if( r < 0 ) r = 0;
77  lvsize = lrss = 0;
78  buffer[r] = '\0';
79  sscanf( buffer,
80  "%*d %*s %*c " // pid command state
81  "%*d %*d " // ppid pgrp
82  "%*d %*d %*d " // session tty_nr tpgid
83  "%*u " // flags
84  "%*u %*u %*u %*u " // minflt cminflt majflt cmajflt
85  "%*u %*u %*d %*d " // utime stime cutime cstime
86  "%*d %*d %*d " // priority nice (unused)
87  "%*d %*u " // itrealval starttime
88  "%lu %ld",
89  &lvsize, &lrss );
90  rss = lrss * getpagesize();
91  vsize = lvsize;
92 }

References buffer.

Referenced by print_stats().

◆ parsedouble()

static double parsedouble ( int &  i,
int  argc,
char *  argv[] 
)
static

Definition at line 115 of file obb_tree_tool.cpp.

116 {
117  char* end;
118  ++i;
119  if( i == argc )
120  {
121  std::cerr << "Expected value following '" << argv[i - 1] << "'" << std::endl;
122  usage();
123  }
124 
125  double result = strtod( argv[i], &end );
126  if( result < 0 || *end )
127  {
128  std::cerr << "Expected positive real number following '" << argv[i - 1] << "'" << std::endl;
129  usage();
130  }
131 
132  return result;
133 }

References usage().

Referenced by main().

◆ parseint()

static int parseint ( int &  i,
int  argc,
char *  argv[] 
)
static

Definition at line 95 of file obb_tree_tool.cpp.

96 {
97  char* end;
98  ++i;
99  if( i == argc )
100  {
101  std::cerr << "Expected value following '" << argv[i - 1] << "'" << std::endl;
102  usage();
103  }
104 
105  int result = strtol( argv[i], &end, 0 );
106  if( result < 0 || *end )
107  {
108  std::cerr << "Expected positive integer following '" << argv[i - 1] << "'" << std::endl;
109  usage();
110  }
111 
112  return result;
113 }

References usage().

Referenced by main().

◆ print_stats()

void print_stats ( Interface interface)

Definition at line 410 of file obb_tree_tool.cpp.

411 {
412  EntityHandle root;
413  Range range;
414  ErrorCode rval;
415  rval = get_root( interface, root );
416  if( MB_SUCCESS != rval )
417  {
418  std::cerr << "Internal error: Failed to retrieve root." << std::endl;
419  exit( 5 );
420  }
421  OrientedBoxTreeTool tool( interface );
422 
423  Range tree_sets, triangles, verts;
424  // interface->get_child_meshsets( root, tree_sets, 0 );
425  interface->get_entities_by_type( 0, MBENTITYSET, tree_sets );
426  tree_sets.erase( tree_sets.begin(), Range::lower_bound( tree_sets.begin(), tree_sets.end(), root ) );
427  interface->get_entities_by_type( 0, MBTRI, triangles );
428  interface->get_entities_by_type( 0, MBVERTEX, verts );
429  triangles.merge( verts );
430  tree_sets.insert( root );
431  unsigned long long set_used, set_amortized, set_store_used, set_store_amortized, set_tag_used, set_tag_amortized,
432  tri_used, tri_amortized;
433  interface->estimated_memory_use( tree_sets, &set_used, &set_amortized, &set_store_used, &set_store_amortized, 0, 0,
434  0, 0, &set_tag_used, &set_tag_amortized );
435  interface->estimated_memory_use( triangles, &tri_used, &tri_amortized );
436 
437  int num_tri = 0;
438  interface->get_number_entities_by_type( 0, MBTRI, num_tri );
439 
440  tool.stats( root, std::cout );
441 
442  unsigned long long real_rss, real_vsize;
443  memory_use( real_vsize, real_rss );
444 
445  printf( "------------------------------------------------------------------\n" );
446  printf( "\nmemory: used amortized\n" );
447  printf( " ---------- ----------\n" );
448  printf( "triangles %10s %10s\n", mem_to_string( tri_used ).c_str(), mem_to_string( tri_amortized ).c_str() );
449  printf( "sets (total)%10s %10s\n", mem_to_string( set_used ).c_str(), mem_to_string( set_amortized ).c_str() );
450  printf( "sets %10s %10s\n", mem_to_string( set_store_used ).c_str(),
451  mem_to_string( set_store_amortized ).c_str() );
452  printf( "set tags %10s %10s\n", mem_to_string( set_tag_used ).c_str(),
453  mem_to_string( set_tag_amortized ).c_str() );
454  printf( "total real %10s %10s\n", mem_to_string( real_rss ).c_str(), mem_to_string( real_vsize ).c_str() );
455  printf( "------------------------------------------------------------------\n" );
456 }

References moab::Range::begin(), moab::Range::end(), moab::Range::erase(), ErrorCode, moab::Interface::estimated_memory_use(), moab::Interface::get_entities_by_type(), moab::Interface::get_number_entities_by_type(), get_root(), moab::Range::insert(), MB_SUCCESS, MBENTITYSET, MBTRI, MBVERTEX, mem_to_string(), memory_use(), moab::Range::merge(), and moab::OrientedBoxTreeTool::stats().

Referenced by main().

◆ tag_triangles()

void tag_triangles ( Interface interface)

Definition at line 492 of file obb_tree_tool.cpp.

493 {
494  EntityHandle root;
495  ErrorCode rval = get_root( moab, root );
496  if( MB_SUCCESS != rval )
497  {
498  std::cerr << "Internal error: Failed to retrieve tree." << std::endl;
499  exit( 5 );
500  }
501 
502  Tag tag;
503  int zero = 0;
504  moab->tag_get_handle( TAG_NAME, 1, MB_TYPE_INTEGER, tag, MB_TAG_DENSE | MB_TAG_CREAT, &zero );
505  TriTagger op( tag, moab );
506 
507  OrientedBoxTreeTool tool( moab );
508  rval = tool.preorder_traverse( root, op );
509  if( MB_SUCCESS != rval )
510  {
511  std::cerr << "Internal error tagging triangles" << std::endl;
512  exit( 5 );
513  }
514 }

References ErrorCode, get_root(), MB_SUCCESS, MB_TAG_CREAT, MB_TAG_DENSE, MB_TYPE_INTEGER, moab::OrientedBoxTreeTool::preorder_traverse(), and TAG_NAME.

Referenced by main().

◆ tag_vertices()

void tag_vertices ( Interface interface)

Definition at line 547 of file obb_tree_tool.cpp.

548 {
549  EntityHandle root;
550  ErrorCode rval = get_root( moab, root );
551  if( MB_SUCCESS != rval )
552  {
553  std::cerr << "Internal error: Failed to retrieve tree." << std::endl;
554  exit( 5 );
555  }
556 
557  Tag tag;
558  int zero = 0;
559  moab->tag_get_handle( TAG_NAME, 1, MB_TYPE_INTEGER, tag, MB_TAG_DENSE | MB_TAG_CREAT, &zero );
560  VtxTagger op( tag, moab );
561 
562  OrientedBoxTreeTool tool( moab );
563  rval = tool.preorder_traverse( root, op );
564  if( MB_SUCCESS != rval )
565  {
566  std::cerr << "Internal error tagging vertices" << std::endl;
567  exit( 5 );
568  }
569 }

References ErrorCode, get_root(), MB_SUCCESS, MB_TAG_CREAT, MB_TAG_DENSE, MB_TYPE_INTEGER, moab::OrientedBoxTreeTool::preorder_traverse(), and TAG_NAME.

Referenced by main().

◆ usage()

static void usage ( bool  err = true)
static

Definition at line 39 of file obb_tree_tool.cpp.

40 {
41  std::ostream& s = err ? std::cerr : std::cout;
42  s << "obb_tree_tool [-s|-S] [-d <int>] [-n <int>] <input file> <output file>" << std::endl
43  << "obb_tree_tool [-h]" << std::endl;
44  if( !err )
45  {
47  s << "Tool to build adaptive kd-Tree from triangles" << std::endl;
48  s << " -s Use range-based sets for tree nodes" << std::endl
49  << " -S Use vector-based sets for tree nodes" << std::endl
50  << " -d <int> Specify maximum depth for tree. Default: " << st.max_depth << std::endl
51  << " -n <int> Specify maximum entities per leaf. Default: " << st.max_leaf_entities << std::endl
52  << " -m <real> Specify worst split ratio. Default: " << st.worst_split_ratio << std::endl
53  << " -M <real> Specify best split ratio. Default: " << st.best_split_ratio << std::endl
54  << " -t Tag triangles will tree cell number." << std::endl
55  << " -T Write tree boxes to file." << std::endl
56  << " -N Specify mesh tag containing tree root. Default: \"" << TREE_TAG << '"' << std::endl
57  << std::endl;
58  }
59  exit( err );
60 }

References moab::OrientedBoxTreeTool::Settings::best_split_ratio, moab::OrientedBoxTreeTool::Settings::max_depth, moab::OrientedBoxTreeTool::Settings::max_leaf_entities, TREE_TAG, and moab::OrientedBoxTreeTool::Settings::worst_split_ratio.

Referenced by main(), parsedouble(), and parseint().

◆ write_tree_blocks()

void write_tree_blocks ( Interface interface,
const char *  file 
)

Definition at line 603 of file obb_tree_tool.cpp.

604 {
605  EntityHandle root;
606  ErrorCode rval = get_root( interface, root );
607  if( MB_SUCCESS != rval )
608  {
609  std::cerr << "Internal error: Failed to retrieve tree." << std::endl;
610  exit( 5 );
611  }
612 
613  Core moab2;
614  Tag tag;
615  int zero = 0;
617 
618  OrientedBoxTreeTool tool( interface );
619  LeafHexer op( &tool, &moab2, tag );
620  rval = tool.preorder_traverse( root, op );
621  if( MB_SUCCESS != rval )
622  {
623  std::cerr << "Internal error: failed to construct leaf hexes" << std::endl;
624  exit( 5 );
625  }
626 
627  moab2.write_mesh( file );
628 }

References ErrorCode, get_root(), MB_SUCCESS, MB_TAG_CREAT, MB_TAG_DENSE, MB_TYPE_INTEGER, moab::OrientedBoxTreeTool::preorder_traverse(), moab::Core::tag_get_handle(), TAG_NAME, and moab::Core::write_mesh().

Referenced by main().

Variable Documentation

◆ MAX_TAG_VALUE

const int MAX_TAG_VALUE = 20

Definition at line 26 of file obb_tree_tool.cpp.

Referenced by hash_handle().

◆ root_tag

const char* root_tag = TREE_TAG

Definition at line 29 of file obb_tree_tool.cpp.

Referenced by build_tree(), get_root(), and main().

◆ TAG_NAME

const char* const TAG_NAME = "OBB_ID"

Definition at line 27 of file obb_tree_tool.cpp.

Referenced by tag_triangles(), tag_vertices(), and write_tree_blocks().

◆ TREE_TAG

const char* const TREE_TAG = "OBB_ROOT"

Definition at line 28 of file obb_tree_tool.cpp.

Referenced by usage().