|
MOAB: Mesh Oriented datABase
(version 5.4.1)
|
#include "moab/Core.hpp"#include "moab/CartVect.hpp"#include "moab/AdaptiveKDTree.hpp"#include "moab/GeomUtil.hpp"#include "Internals.hpp"#include "moab/Range.hpp"#include "moab/FileOptions.hpp"#include <iostream>#include <iomanip>#include <cstdio>#include <limits>#include <sstream>#include <cstdlib>#include <ctime>#include <unistd.h>#include <sys/stat.h>#include <fcntl.h>
Include dependency graph for kd_tree_tool.cpp:Go to the source code of this file.
Functions | |
| std::string | clock_to_string (clock_t t) |
| std::string | mem_to_string (unsigned long mem) |
| void | build_tree (Interface *interface, const Range &elems, FileOptions &opts) |
| void | build_grid (Interface *iface, const double dims[3]) |
| void | delete_existing_tree (Interface *interface) |
| void | print_stats (Interface *interface) |
| void | tag_elements (Interface *interface) |
| void | tag_vertices (Interface *interface) |
| void | write_tree_blocks (Interface *interface, const char *file) |
| static void | usage (bool err=true) |
| static int | parseint (int &i, int argc, char *argv[]) |
| static void | parsedims (int &i, int argc, char *argv[], double dims[3]) |
| int | main (int argc, char *argv[]) |
| static int | hash_handle (EntityHandle handle) |
Variables | |
| const int | MAX_TAG_VALUE = 32 |
| const char * | TAG_NAME = "TREE_CELL" |
| void build_grid | ( | Interface * | iface, |
| const double | dims[3] | ||
| ) |
Definition at line 386 of file kd_tree_tool.cpp.
References moab::AdaptiveKDTreeIter::box_max(), moab::AdaptiveKDTreeIter::box_min(), moab::AdaptiveKDTree::Plane::coord, moab::Tree::create_root(), moab::AdaptiveKDTreeIter::depth(), ErrorCode, moab::Tree::get_max_depth(), moab::AdaptiveKDTree::get_tree_iterator(), MB_ENTITY_NOT_FOUND, MB_SUCCESS, moab::AdaptiveKDTree::Plane::norm, moab::AdaptiveKDTree::split_leaf(), and moab::AdaptiveKDTreeIter::step().
Referenced by main().
{
ErrorCode rval;
EntityHandle root = 0;
AdaptiveKDTree tool( interface );
AdaptiveKDTreeIter iter;
AdaptiveKDTree::Plane plane;
double min[3] = { -0.5 * dims[0], -0.5 * dims[1], -0.5 * dims[2] };
double max[3] = { 0.5 * dims[0], 0.5 * dims[1], 0.5 * dims[2] };
rval = tool.create_root( min, max, root );
if( MB_SUCCESS != rval || !root )
{
std::cerr << "Failed to create tree root." << std::endl;
exit( 4 );
}
rval = tool.get_tree_iterator( root, iter );
if( MB_SUCCESS != rval )
{
std::cerr << "Failed to get tree iterator." << std::endl;
}
do
{
while( iter.depth() < tool.get_max_depth() )
{
plane.norm = iter.depth() % 3;
plane.coord = 0.5 * ( iter.box_min()[plane.norm] + iter.box_max()[plane.norm] );
rval = tool.split_leaf( iter, plane );
if( MB_SUCCESS != rval )
{
std::cerr << "Failed to split tree leaf at depth " << iter.depth() << std::endl;
exit( 4 );
}
}
} while( ( rval = iter.step() ) == MB_SUCCESS );
if( rval != MB_ENTITY_NOT_FOUND )
{
std::cerr << "Error stepping KDTree iterator." << std::endl;
exit( 4 );
}
}
| void build_tree | ( | Interface * | interface, |
| const Range & | elems, | ||
| FileOptions & | opts | ||
| ) |
Definition at line 373 of file kd_tree_tool.cpp.
References moab::Range::empty().
{
EntityHandle root = 0;
if( elems.empty() )
{
std::cerr << "No elements from which to build tree." << std::endl;
exit( 4 );
}
AdaptiveKDTree tool( interface, elems, &root, &opts );
}
| std::string clock_to_string | ( | clock_t | t | ) |
Definition at line 431 of file kd_tree_tool.cpp.
References buffer, and moab::unit().
Referenced by main().
{
char unit[5] = "s";
char buffer[256];
double dt = t / (double)CLOCKS_PER_SEC;
// if (dt > 300) {
// dt /= 60;
// strcpy( unit, "min" );
//}
// if (dt > 300) {
// dt /= 60;
// strcpy( unit, "hr" );
//}
// if (dt > 100) {
// dt /= 24;
// strcpy( unit, "days" );
//}
sprintf( buffer, "%0.2f%s", dt, unit );
return buffer;
}
| void delete_existing_tree | ( | Interface * | interface | ) |
Definition at line 354 of file kd_tree_tool.cpp.
References moab::Range::begin(), moab::Range::clear(), moab::Range::empty(), moab::Range::end(), moab::Tree::find_all_trees(), and moab::AdaptiveKDTree::reset_tree().
Referenced by main().
{
Range trees;
AdaptiveKDTree tool( interface );
tool.find_all_trees( trees );
if( !trees.empty() ) std::cout << "Destroying existing tree(s) contained in file" << std::endl;
for( Range::iterator i = trees.begin(); i != trees.end(); ++i )
tool.reset_tree();
trees.clear();
tool.find_all_trees( trees );
if( !trees.empty() )
{
std::cerr << "Failed to destroy existing trees. Aborting" << std::endl;
exit( 5 );
}
}
| static int hash_handle | ( | EntityHandle | handle | ) | [static] |
Definition at line 452 of file kd_tree_tool.cpp.
References moab::ID_FROM_HANDLE(), and MAX_TAG_VALUE.
Referenced by tag_elements(), tag_vertices(), and write_tree_blocks().
{
EntityID h = ID_FROM_HANDLE( handle );
return (int)( ( h * 13 + 7 ) % MAX_TAG_VALUE ) + 1;
}
| int main | ( | int | argc, |
| char * | argv[] | ||
| ) |
Definition at line 155 of file kd_tree_tool.cpp.
References build_grid(), build_time, build_tree(), clock_to_string(), delete_existing_tree(), moab::Range::empty(), ErrorCode, moab::Tree::find_all_trees(), input_file, load_time, MB_SUCCESS, moab::Range::merge(), parsedims(), parseint(), moab::AdaptiveKDTree::print(), moab::Range::size(), moab::AdaptiveKDTree::SUBDIVISION, moab::AdaptiveKDTree::SUBDIVISION_SNAP, tag_elements(), tag_time(), tag_vertices(), usage, moab::AdaptiveKDTree::VERTEX_MEDIAN, moab::AdaptiveKDTree::VERTEX_SAMPLE, and write_tree_blocks().
{
bool surf_elems = false, vol_elems = false;
const char* input_file = 0;
const char* output_file = 0;
const char* tree_file = 0;
std::ostringstream options;
bool tag_elems = false;
clock_t load_time, build_time, stat_time, tag_time, write_time, block_time;
bool make_grid = false;
double dims[3];
for( int i = 1; i < argc; ++i )
{
if( argv[i][0] != '-' )
{
if( !input_file )
input_file = argv[i];
else if( !output_file )
output_file = argv[i];
else
usage();
continue;
}
if( !argv[i][1] || argv[i][2] ) usage();
switch( argv[i][1] )
{
case '2':
surf_elems = true;
break;
case '3':
vol_elems = true;
break;
case 'S':
options << "MESHSET_FLAGS=" << MESHSET_ORDERED << ";";
break;
case 's':
break;
case 'd':
options << "MAX_DEPTH=" << parseint( i, argc, argv ) << ";";
break;
case 'n':
options << "MAX_PER_LEAF=" << parseint( i, argc, argv ) << ";";
break;
case 'u':
options << "CANDIDATE_PLANE_SET=" << AdaptiveKDTree::SUBDIVISION << ";";
break;
case 'p':
options << "CANDIDATE_PLANE_SET=" << AdaptiveKDTree::SUBDIVISION_SNAP << ";";
break;
case 'm':
options << "CANDIDATE_PLANE_SET=" << AdaptiveKDTree::VERTEX_MEDIAN << ";";
break;
case 'v':
options << "CANDIDATE_PLANE_SET=" << AdaptiveKDTree::VERTEX_SAMPLE << ";";
break;
case 'N':
options << "SPLITS_PER_DIR=" << parseint( i, argc, argv ) << ";";
break;
case 't':
tag_elems = true;
break;
case 'T':
tree_file = argv[++i];
break;
case 'G':
make_grid = true;
parsedims( i, argc, argv, dims );
break;
case 'h':
usage( false );
break;
default:
usage();
}
}
// this test relies on not cleaning up trees
options << "CLEAN_UP=false;";
if( make_grid != !output_file ) usage();
// default to both
if( !surf_elems && !vol_elems ) surf_elems = vol_elems = true;
ErrorCode rval;
Core moab_core;
Interface* interface = &moab_core;
FileOptions opts( options.str().c_str() );
if( make_grid )
{
load_time = 0;
output_file = input_file;
input_file = 0;
build_time = clock();
build_grid( interface, dims );
build_time = clock() - build_time;
}
else
{
load_time = clock();
rval = interface->load_mesh( input_file );
if( MB_SUCCESS != rval )
{
std::cerr << "Error reading file: " << input_file << std::endl;
exit( 2 );
}
load_time = clock() - load_time;
delete_existing_tree( interface );
std::cout << "Building tree..." << std::endl;
build_time = clock();
Range elems;
if( !surf_elems )
{
interface->get_entities_by_dimension( 0, 3, elems );
}
else
{
interface->get_entities_by_dimension( 0, 2, elems );
if( vol_elems )
{
Range tmp;
interface->get_entities_by_dimension( 0, 3, tmp );
elems.merge( tmp );
}
}
build_tree( interface, elems, opts );
build_time = clock() - build_time;
}
std::cout << "Calculating stats..." << std::endl;
AdaptiveKDTree tool( interface );
Range range;
tool.find_all_trees( range );
if( range.size() != 1 )
{
if( range.empty() )
std::cerr << "Internal error: Failed to retreive tree." << std::endl;
else
std::cerr << "Internal error: Multiple tree roots." << std::endl;
exit( 5 );
}
tool.print();
stat_time = clock() - build_time;
if( tag_elems )
{
std::cout << "Tagging tree..." << std::endl;
tag_elements( interface );
tag_vertices( interface );
}
tag_time = clock() - stat_time;
std::cout << "Writing file... ";
std::cout.flush();
rval = interface->write_mesh( output_file );
if( MB_SUCCESS != rval )
{
std::cerr << "Error writing file: " << output_file << std::endl;
exit( 3 );
}
write_time = clock() - tag_time;
std::cout << "Wrote " << output_file << std::endl;
if( tree_file )
{
std::cout << "Writing tree block rep...";
std::cout.flush();
write_tree_blocks( interface, tree_file );
std::cout << "Wrote " << tree_file << std::endl;
}
block_time = clock() - write_time;
std::cout << "Times: "
<< " Load"
<< " Build"
<< " Stats"
<< " Write";
if( tag_elems ) std::cout << "Tag Sets";
if( tree_file ) std::cout << "Block ";
std::cout << std::endl;
std::cout << " " << std::setw( 8 ) << clock_to_string( load_time ) << std::setw( 8 )
<< clock_to_string( build_time ) << std::setw( 8 ) << clock_to_string( stat_time ) << std::setw( 8 )
<< clock_to_string( write_time );
if( tag_elems ) std::cout << std::setw( 8 ) << clock_to_string( tag_time );
if( tree_file ) std::cout << std::setw( 8 ) << clock_to_string( block_time );
std::cout << std::endl;
return 0;
}
| std::string mem_to_string | ( | unsigned long | mem | ) |
Definition at line 360 of file obb_tree_tool.cpp.
References buffer, and moab::unit().
{
char unit[3] = "B";
if( mem > 9 * 1024 )
{
mem = ( mem + 512 ) / 1024;
strcpy( unit, "kB" );
}
if( mem > 9 * 1024 )
{
mem = ( mem + 512 ) / 1024;
strcpy( unit, "MB" );
}
if( mem > 9 * 1024 )
{
mem = ( mem + 512 ) / 1024;
strcpy( unit, "GB" );
}
char buffer[256];
sprintf( buffer, "%lu %s", mem, unit );
return buffer;
}
| static void parsedims | ( | int & | i, |
| int | argc, | ||
| char * | argv[], | ||
| double | dims[3] | ||
| ) | [static] |
Definition at line 116 of file kd_tree_tool.cpp.
References moab::error(), and usage.
Referenced by main().
{
char* end;
++i;
if( i == argc )
{
std::cerr << "Expected value following '" << argv[i - 1] << "'" << std::endl;
usage();
}
dims[0] = strtod( argv[i], &end );
if( *end == '\0' )
{
dims[2] = dims[1] = dims[0];
return;
}
else if( *end != 'x' && *end != 'X' )
goto error;
++end;
dims[1] = strtod( end, &end );
if( *end == '\0' )
{
dims[2] = dims[1];
return;
}
else if( *end != 'x' && *end != 'X' )
goto error;
++end;
dims[2] = strtod( end, &end );
if( *end != '\0' ) goto error;
return;
error:
std::cerr << "Invaild dimension specification." << std::endl;
usage();
}
| static int parseint | ( | int & | i, |
| int | argc, | ||
| char * | argv[] | ||
| ) | [static] |
Definition at line 96 of file kd_tree_tool.cpp.
References usage.
Referenced by main().
{
char* end;
++i;
if( i == argc )
{
std::cerr << "Expected value following '" << argv[i - 1] << "'" << std::endl;
usage();
}
int result = strtol( argv[i], &end, 0 );
if( result < 0 || *end )
{
std::cerr << "Expected positive integer following '" << argv[i - 1] << "'" << std::endl;
usage();
}
return result;
}
| void print_stats | ( | Interface * | interface | ) |
Definition at line 410 of file obb_tree_tool.cpp.
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, moab::mem_to_string(), memory_use(), moab::Range::merge(), and moab::OrientedBoxTreeTool::stats().
{
EntityHandle root;
Range range;
ErrorCode rval;
rval = get_root( interface, root );
if( MB_SUCCESS != rval )
{
std::cerr << "Internal error: Failed to retrieve root." << std::endl;
exit( 5 );
}
OrientedBoxTreeTool tool( interface );
Range tree_sets, triangles, verts;
// interface->get_child_meshsets( root, tree_sets, 0 );
interface->get_entities_by_type( 0, MBENTITYSET, tree_sets );
tree_sets.erase( tree_sets.begin(), Range::lower_bound( tree_sets.begin(), tree_sets.end(), root ) );
interface->get_entities_by_type( 0, MBTRI, triangles );
interface->get_entities_by_type( 0, MBVERTEX, verts );
triangles.merge( verts );
tree_sets.insert( root );
unsigned long long set_used, set_amortized, set_store_used, set_store_amortized, set_tag_used, set_tag_amortized,
tri_used, tri_amortized;
interface->estimated_memory_use( tree_sets, &set_used, &set_amortized, &set_store_used, &set_store_amortized, 0, 0,
0, 0, &set_tag_used, &set_tag_amortized );
interface->estimated_memory_use( triangles, &tri_used, &tri_amortized );
int num_tri = 0;
interface->get_number_entities_by_type( 0, MBTRI, num_tri );
tool.stats( root, std::cout );
unsigned long long real_rss, real_vsize;
memory_use( real_vsize, real_rss );
printf( "------------------------------------------------------------------\n" );
printf( "\nmemory: used amortized\n" );
printf( " ---------- ----------\n" );
printf( "triangles %10s %10s\n", mem_to_string( tri_used ).c_str(), mem_to_string( tri_amortized ).c_str() );
printf( "sets (total)%10s %10s\n", mem_to_string( set_used ).c_str(), mem_to_string( set_amortized ).c_str() );
printf( "sets %10s %10s\n", mem_to_string( set_store_used ).c_str(),
mem_to_string( set_store_amortized ).c_str() );
printf( "set tags %10s %10s\n", mem_to_string( set_tag_used ).c_str(),
mem_to_string( set_tag_amortized ).c_str() );
printf( "total real %10s %10s\n", mem_to_string( real_rss ).c_str(), mem_to_string( real_vsize ).c_str() );
printf( "------------------------------------------------------------------\n" );
}
| void tag_elements | ( | Interface * | interface | ) |
Definition at line 458 of file kd_tree_tool.cpp.
References moab::Range::begin(), moab::Range::clear(), moab::Range::empty(), moab::Tree::find_all_trees(), moab::Interface::get_entities_by_handle(), moab::AdaptiveKDTree::get_tree_iterator(), moab::AdaptiveKDTreeIter::handle(), hash_handle(), MB_SUCCESS, MB_TAG_CREAT, MB_TAG_DENSE, MB_TYPE_INTEGER, moab::Range::size(), moab::AdaptiveKDTreeIter::step(), moab::Interface::tag_get_handle(), TAG_NAME, and moab::Interface::tag_set_data().
Referenced by main().
{
EntityHandle root;
Range range;
AdaptiveKDTree tool( moab );
tool.find_all_trees( range );
if( range.size() != 1 )
{
if( range.empty() )
std::cerr << "Internal error: Failed to retreive tree." << std::endl;
else
std::cerr << "Internal error: Multiple tree roots." << std::endl;
exit( 5 );
}
root = *range.begin();
range.clear();
Tag tag;
int zero = 0;
moab->tag_get_handle( TAG_NAME, 1, MB_TYPE_INTEGER, tag, MB_TAG_DENSE | MB_TAG_CREAT, &zero );
AdaptiveKDTreeIter iter;
tool.get_tree_iterator( root, iter );
std::vector< int > tag_vals;
do
{
range.clear();
moab->get_entities_by_handle( iter.handle(), range );
tag_vals.clear();
tag_vals.resize( range.size(), hash_handle( iter.handle() ) );
moab->tag_set_data( tag, range, &tag_vals[0] );
} while( MB_SUCCESS == iter.step() );
}
| void tag_vertices | ( | Interface * | interface | ) |
Definition at line 495 of file kd_tree_tool.cpp.
References moab::CartVect::array(), moab::Range::begin(), moab::AdaptiveKDTreeIter::box_max(), moab::AdaptiveKDTreeIter::box_min(), moab::GeomUtil::box_point_overlap(), moab::Range::clear(), moab::Range::empty(), moab::Tree::find_all_trees(), moab::Interface::get_adjacencies(), moab::Interface::get_coords(), moab::Interface::get_entities_by_handle(), moab::AdaptiveKDTree::get_tree_iterator(), moab::AdaptiveKDTreeIter::handle(), hash_handle(), MB_SUCCESS, MB_TAG_CREAT, MB_TAG_DENSE, MB_TYPE_INTEGER, moab::Range::size(), moab::AdaptiveKDTreeIter::step(), moab::Interface::tag_get_handle(), TAG_NAME, moab::Interface::tag_set_data(), and moab::Interface::UNION.
Referenced by main().
{
EntityHandle root;
Range range;
AdaptiveKDTree tool( moab );
tool.find_all_trees( range );
if( range.size() != 1 )
{
if( range.empty() )
std::cerr << "Internal error: Failed to retreive tree." << std::endl;
else
std::cerr << "Internal error: Multiple tree roots." << std::endl;
exit( 5 );
}
root = *range.begin();
range.clear();
Tag tag;
int zero = 0;
moab->tag_get_handle( TAG_NAME, 1, MB_TYPE_INTEGER, tag, MB_TAG_DENSE | MB_TAG_CREAT, &zero );
AdaptiveKDTreeIter iter;
tool.get_tree_iterator( root, iter );
do
{
range.clear();
moab->get_entities_by_handle( iter.handle(), range );
int tag_val = hash_handle( iter.handle() );
Range verts;
moab->get_adjacencies( range, 0, false, verts, Interface::UNION );
for( Range::iterator i = verts.begin(); i != verts.end(); ++i )
{
CartVect coords;
moab->get_coords( &*i, 1, coords.array() );
if( GeomUtil::box_point_overlap( CartVect( iter.box_min() ), CartVect( iter.box_max() ), coords, 1e-7 ) )
moab->tag_set_data( tag, &*i, 1, &tag_val );
}
} while( MB_SUCCESS == iter.step() );
}
| static void usage | ( | bool | err = true | ) | [static] |
Definition at line 37 of file kd_tree_tool.cpp.
{
std::ostream& s = err ? std::cerr : std::cout;
s << "kd_tree_tool [-d <int>] [-2|-3] [-n <int>] [-u|-p|-m|-v] [-N <int>] [-s|-S] <input file> "
"<output file>"
<< std::endl
<< "kd_tree_tool [-d <int>] -G <dims> [-s|-S] <output file>" << std::endl
<< "kd_tree_tool [-h]" << std::endl;
if( !err )
{
s << "Tool to build adaptive kd-Tree" << std::endl;
s << " -d <int> Specify maximum depth for tree. Default: 30" << std::endl
<< " -n <int> Specify maximum entities per leaf. Default: 6" << std::endl
<< " -2 Build tree from surface elements. Default: yes" << std::endl
<< " -3 Build tree from volume elements. Default: yes" << std::endl
<< " -u Use 'SUBDIVISION' scheme for tree construction" << std::endl
<< " -p Use 'SUBDIVISION_SNAP' tree construction algorithm." << std::endl
<< " -m Use 'VERTEX_MEDIAN' tree construction algorithm." << std::endl
<< " -v Use 'VERTEX_SAMPLE' tree construction algorithm." << std::endl
<< " -N <int> Specify candidate split planes per axis. Default: 3" << std::endl
<< " -t Tag elements will tree cell number." << std::endl
<< " -T Write tree boxes to file." << std::endl
<< " -G <dims> Generate grid - no input elements. Dims must be " << std::endl
<< " HxWxD or H." << std::endl
<< " -s Use range-based sets for tree nodes" << std::endl
<< " -S Use vector-based sets for tree nodes" << std::endl
<< std::endl;
}
exit( err );
}
| void write_tree_blocks | ( | Interface * | interface, |
| const char * | file | ||
| ) |
Definition at line 539 of file kd_tree_tool.cpp.
References moab::Range::begin(), moab::AdaptiveKDTreeIter::box_max(), moab::AdaptiveKDTreeIter::box_min(), moab::Range::clear(), moab::Core::create_element(), moab::Core::create_vertex(), moab::Range::empty(), moab::Tree::find_all_trees(), moab::AdaptiveKDTree::get_tree_iterator(), moab::AdaptiveKDTreeIter::handle(), hash_handle(), MB_SUCCESS, MB_TAG_CREAT, MB_TAG_DENSE, MB_TYPE_INTEGER, MBHEX, moab::Range::size(), moab::AdaptiveKDTreeIter::step(), moab::Core::tag_get_handle(), TAG_NAME, moab::Core::tag_set_data(), and moab::Core::write_mesh().
Referenced by main().
{
EntityHandle root;
Range range;
AdaptiveKDTree tool( interface );
tool.find_all_trees( range );
if( range.size() != 1 )
{
if( range.empty() )
std::cerr << "Internal error: Failed to retreive tree." << std::endl;
else
std::cerr << "Internal error: Multiple tree roots." << std::endl;
exit( 5 );
}
root = *range.begin();
range.clear();
Core moab2;
Tag tag;
int zero = 0;
moab2.tag_get_handle( TAG_NAME, 1, MB_TYPE_INTEGER, tag, MB_TAG_DENSE | MB_TAG_CREAT, &zero );
AdaptiveKDTreeIter iter;
tool.get_tree_iterator( root, iter );
do
{
double x1 = iter.box_min()[0];
double y1 = iter.box_min()[1];
double z1 = iter.box_min()[2];
double x2 = iter.box_max()[0];
double y2 = iter.box_max()[1];
double z2 = iter.box_max()[2];
double coords[24] = { x1, y1, z1, x2, y1, z1, x2, y2, z1, x1, y2, z1,
x1, y1, z2, x2, y1, z2, x2, y2, z2, x1, y2, z2 };
EntityHandle verts[8], elem;
for( int i = 0; i < 8; ++i )
moab2.create_vertex( coords + 3 * i, verts[i] );
moab2.create_element( MBHEX, verts, 8, elem );
int tag_val = hash_handle( iter.handle() );
moab2.tag_set_data( tag, &elem, 1, &tag_val );
} while( MB_SUCCESS == iter.step() );
moab2.write_mesh( file );
}
| const int MAX_TAG_VALUE = 32 |
Definition at line 23 of file kd_tree_tool.cpp.
Referenced by hash_handle().
| const char* TAG_NAME = "TREE_CELL" |
Definition at line 24 of file kd_tree_tool.cpp.