9 #if !defined( _MSC_VER ) && !defined( __MINGW32__ )
11 #include <sys/types.h>
25 static void get_time_mem(
double& tot_time,
double& tot_mem );
28 #if !defined( _MSC_VER ) && !defined( __MINGW32__ )
29 #include <sys/resource.h>
32 extern "C" int getrusage(
int,
struct rusage* );
34 #include </usr/ucbinclude/sys/rusage.h>
41 #define CHKERROR( A ) \
44 if( MB_SUCCESS != ( A ) ) \
46 std::cerr << "Internal error at line " << __LINE__ << std::endl; \
54 static void usage(
const char* argv0,
bool help =
false )
56 std::ostream& str =
help ? std::cout : std::cerr;
58 str <<
"Usage: " << argv0
59 <<
" [-b <block_num> [-b ...] ] [-l] [-m] [-M <n>] [-p] [-s <sideset_num>] [-S] [-t|-T "
60 "<name>] [-w] [-v|-V <n>]"
61 <<
" <input_file> [<output_file>]" << std::endl;
62 str <<
"Help : " << argv0 <<
" -h" << std::endl;
63 if( !
help ) exit( 1 );
65 str <<
"Options: " << std::endl;
66 str <<
"-a : Compute skin using vert-elem adjacencies (more memory, less time)." << std::endl;
67 str <<
"-b <block_num> : Compute skin only for material set/block <block_num>." << std::endl;
68 str <<
"-p : Print cpu & memory performance." << std::endl;
69 str <<
"-s <sideset_num> : Put skin in neumann set/sideset <sideset_num>." << std::endl;
70 str <<
"-S : Look for and use structured mesh information to speed up skinning." << std::endl;
71 str <<
"-t : Set '" <<
DEFAULT_FIXED_TAG <<
"' tag on skin vertices." << std::endl;
72 str <<
"-T <name> : Create tag with specified name and set to 1 on skin vertices." << std::endl;
73 str <<
"-w : Write out whole mesh (otherwise just writes skin)." << std::endl;
74 str <<
"-m : consolidate duplicate vertices" << std::endl;
75 str <<
"-M <n> : consolidate duplicate vertices with specified tolerance. "
76 "(Default: min_edge_length/"
78 str <<
"-l : List total numbers of entities and vertices in skin." << std::endl;
82 int main(
int argc,
char* argv[] )
85 std::vector< int > matsets;
87 bool write_tag =
false, write_whole_mesh =
false;
88 bool print_perf =
false;
89 bool use_vert_elem_adjs =
false;
90 bool merge_vertices =
false;
91 double merge_epsilon = -1;
92 bool list_skin =
false;
97 bool no_more_flags =
false;
102 if( !no_more_flags && argv[i][0] ==
'-' )
105 for(
int j = 1; argv[f][j]; ++j )
110 use_vert_elem_adjs =
true;
119 write_whole_mesh =
true;
122 merge_vertices =
true;
125 no_more_flags =
true;
128 usage( argv[0],
true );
137 if( i == argc || 0 >= ( block = strtol( argv[i], &endptr, 0 ) ) || *endptr )
139 std::cerr <<
"Expected positive integer following '-b' flag" << std::endl;
142 matsets.push_back( (
int)block );
146 if( i == argc || 0 >= ( neuset_num = strtol( argv[i], &endptr, 0 ) ) || *endptr )
148 std::cerr <<
"Expected positive integer following '-s' flag" << std::endl;
154 if( i == argc || argv[i][0] ==
'-' )
156 std::cerr <<
"Expected tag name following '-T' flag" << std::endl;
159 fixed_tag = argv[i++];
162 if( i == argc || 0.0 > ( merge_epsilon = strtod( argv[i], &endptr ) ) || *endptr )
164 std::cerr <<
"Expected positive numeric value following '-M' flag" << std::endl;
167 merge_vertices =
true;
171 std::cerr <<
"Unrecognized flag: '" << argv[f][j] <<
"'" << std::endl;
179 std::cerr <<
"Extra argument: " << argv[i] << std::endl;
184 output_file = argv[i++];
194 std::cerr <<
"No input file specified" << std::endl;
204 double tmp_time1, tmp_mem1;
206 std::cout <<
"Before reading: cpu time = " << tmp_time1 <<
", memory = " << tmp_mem1 / 1.0e6 <<
"MB."
214 std::cerr <<
"Failed to load \"" <<
input_file <<
"\"." << std::endl;
217 std::cerr <<
"Read \"" <<
input_file <<
"\"" << std::endl;
220 double tmp_time2, tmp_mem2;
222 std::cout <<
"After reading: cpu time = " << tmp_time2 <<
", memory = " << tmp_mem2 / 1.0e6 <<
"MB."
228 if( merge_epsilon < 0.0 )
232 std::cerr <<
"Error determining minimum edge length" << std::endl;
239 std::cerr <<
"Error merging duplicate vertices" << std::endl;
254 Tag matset_tag = 0, neuset_tag = 0;
260 if( matsets.empty() )
265 if( 0 == matset_tag )
267 std::cerr <<
"Couldn't find any material sets in this mesh." << std::endl;
271 for( std::vector< int >::iterator vit = matsets.begin(); vit != matsets.end(); ++vit )
273 int this_matset = *vit;
274 const void* this_matset_ptr = &this_matset;
275 Range this_range, ent_range;
280 std::cerr <<
"Trouble getting material set #" << *vit << std::endl;
283 else if( this_range.
empty() )
285 std::cerr <<
"Warning: couldn't find material set " << *vit << std::endl;
291 skin_ents.
merge( ent_range );
295 if( skin_ents.
empty() )
297 std::cerr <<
"No entities for which to compute skin; exiting." << std::endl;
301 if( use_vert_elem_adjs )
309 double tmp_time = 0.0, tmp_mem = 0.0;
313 std::cout <<
"Before skinning: cpu time = " << tmp_time <<
", memory = " << tmp_mem / 1.0e6 <<
"MB."
318 Range forward_lower, reverse_lower;
321 result = tool.
find_skin( 0, skin_ents,
false, forward_lower, NULL,
false,
true,
true );
323 result = tool.
find_skin( 0, skin_ents,
false, forward_lower, &reverse_lower );
325 boundary.
merge( forward_lower );
326 boundary.
merge( reverse_lower );
329 std::cerr <<
"Mesh skinning failed." << std::endl;
337 std::cout <<
"Skin has ";
342 std::cout << skin_verts.
size() <<
" vertices." << std::endl;
352 std::vector< int > ones;
357 std::cerr <<
"Trouble getting vertices on boundary." << std::endl;
360 ones.resize( bverts.
size(), 1 );
364 if( -1 != neuset_num )
367 if( 0 == neuset_tag )
371 if(
MB_SUCCESS != result || 0 == neuset_tag )
return 1;
377 if(
MB_SUCCESS != result || 0 == forward_neuset )
return 1;
381 if( !forward_lower.
empty() )
386 if( !reverse_lower.
empty() )
390 if(
MB_SUCCESS != result || 0 == forward_neuset )
return 1;
407 if( NULL != output_file && write_whole_mesh )
414 std::cerr <<
"Failed to write \"" << output_file <<
"\"." << std::endl;
417 std::cerr <<
"Wrote \"" << output_file <<
"\"" << std::endl;
419 else if( NULL != output_file )
437 std::cerr <<
"Failed to write \"" << output_file <<
"\"." << std::endl;
440 std::cerr <<
"Wrote \"" << output_file <<
"\"" << std::endl;
445 double tot_time, tot_mem;
447 std::cout <<
"Total cpu time = " << tot_time <<
" seconds." << std::endl;
448 std::cout <<
"Total skin cpu time = " << tot_time - tmp_time <<
" seconds." << std::endl;
449 std::cout <<
"Total memory = " << tot_mem / 1024 <<
" MB." << std::endl;
450 std::cout <<
"Total skin memory = " << ( tot_mem - tmp_mem ) / 1024 <<
" MB." << std::endl;
451 std::cout <<
"Entities: " << std::endl;
458 #if defined( _MSC_VER ) || defined( __MINGW32__ )
461 tot_time = (double)clock() / CLOCKS_PER_SEC;
467 struct rusage r_usage;
468 getrusage( RUSAGE_SELF, &r_usage );
469 double utime = (double)r_usage.ru_utime.tv_sec + ( (
double)r_usage.ru_utime.tv_usec / 1.e6 );
470 double stime = (double)r_usage.ru_stime.tv_sec + ( (
double)r_usage.ru_stime.tv_usec / 1.e6 );
471 tot_time = utime + stime;
473 if( 0 != r_usage.ru_maxrss )
475 tot_mem = (double)r_usage.ru_maxrss;
481 char file_str[4096], dum_str[4096];
482 int file_ptr = open(
"/proc/self/stat", O_RDONLY );
483 int file_len = read( file_ptr, file_str,
sizeof( file_str ) - 1 );
491 file_str[file_len] =
'\0';
494 unsigned int dum_uint, vm_size, rss;
495 int num_fields = sscanf( file_str,
505 &dum_int, dum_str, dum_str, &dum_int, &dum_int, &dum_int, &dum_int, &dum_int,
506 &dum_uint, &dum_uint, &dum_uint, &dum_uint, &dum_uint, &dum_int, &dum_int, &dum_int,
507 &dum_int, &dum_int, &dum_int, &dum_uint, &dum_uint, &dum_int, &vm_size, &rss );
508 if( num_fields == 24 ) tot_mem = ( (double)vm_size );
515 double sqr_result = std::numeric_limits< double >::max();
526 std::vector< EntityHandle > storage;
529 EntityType t =
moab.type_from_handle( *i );
531 int conn_len, indices[2];
532 rval =
moab.get_connectivity( *i, conn, conn_len,
true, &storage );
536 for(
int j = 0; j < num_edges; ++j )
539 EntityHandle v[2] = { conn[indices[0]], conn[indices[1]] };
540 if( v[0] == v[1] )
continue;
543 rval =
moab.get_coords( v, 2, c );
549 double len_sqr = c[0] * c[0] + c[1] * c[1] + c[2] * c[2];
550 if( len_sqr < sqr_result ) sqr_result = len_sqr;
554 result = sqrt( sqr_result );
570 fprintf( stderr,
"Failed to build kD-tree.\n" );
574 std::set< EntityHandle > dead_verts;
575 std::vector< EntityHandle > leaves;
579 rval =
moab.get_coords( &*i, 1, coords );
584 rval = tree.
distance_search( coords, epsilon, leaves, epsilon, epsilon );
588 for( std::vector< EntityHandle >::iterator j = leaves.begin(); j != leaves.end(); ++j )
597 assert( v != near.
end() );
603 if( *j < *i && dead_verts.find( *j ) != dead_verts.end() )
continue;
606 rval =
moab.get_coords( &*j, 1, coords2 );
609 coords2[0] -= coords[0];
610 coords2[1] -= coords[1];
611 coords2[2] -= coords[2];
612 double dsqr = coords2[0] * coords2[0] + coords2[1] * coords2[1] + coords2[2] * coords2[2];
613 if( dsqr <= epsilon * epsilon )
622 dead_verts.insert( *i );
623 rval =
moab.merge_entities( merge, *i,
false,
true );
628 if( dead_verts.empty() )
629 std::cout <<
"No duplicate/coincident vertices." << std::endl;
631 std::cout <<
"Merged and deleted " << dead_verts.size() <<
" vertices "
632 <<
"coincident within " << epsilon << std::endl;