MOAB: Mesh Oriented datABase
(version 5.4.1)
|
00001 #include "moab/Interface.hpp" 00002 #include "TestUtil.hpp" 00003 #include "moab/Core.hpp" 00004 #include "moab/Types.hpp" 00005 #include "MBTagConventions.hpp" 00006 #include "moab/GeomTopoTool.hpp" 00007 #include <iostream> 00008 #include <map> 00009 #include <set> 00010 00011 using namespace moab; 00012 00013 Tag category_tag; 00014 Tag geom_tag; 00015 Tag name_tag; 00016 Tag obj_name_tag; 00017 Tag dim_tag, id_tag; 00018 00019 bool check_tree( Interface* mbi, GeomTopoTool* GTT, std::map< int, std::set< int > >& ref_map ); 00020 ErrorCode get_all_handles( Interface* mbi ); 00021 Range get_children_by_dimension( Interface* mbi, EntityHandle parent, int desired_dimension ); 00022 void heappermute( Interface* mbi, int v[], int n, std::map< int, std::set< int > > ref_map, int len ); 00023 void swap( int* x, int* y ); 00024 void get_cube_info( int cube_id, std::vector< double >& scale, std::vector< double >& trans ); 00025 void test_two_cubes(); 00026 void test_three_cubes(); 00027 void test_four_cubes(); 00028 00029 ErrorCode build_cube( Interface* mbi, 00030 std::vector< double > scale_vec, 00031 std::vector< double > trans_vec, 00032 int object_id, 00033 EntityHandle& volume ) 00034 { 00035 GeomTopoTool* GTT = new GeomTopoTool( mbi ); 00036 00037 ErrorCode rval; 00038 00039 // Define a 1x1x1 cube centered at orgin 00040 00041 // coordinates of each corner 00042 const double coords[] = { 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 00043 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5 }; 00044 00045 // connectivity of 2 triangles per 00046 // each face of the cube 00047 const int connectivity[] = { 00048 0, 3, 1, 3, 2, 1, // -Z 00049 0, 1, 4, 5, 4, 1, // +X 00050 1, 2, 6, 6, 5, 1, // +Y 00051 6, 2, 3, 7, 6, 3, // -X 00052 0, 4, 3, 7, 3, 4, // -Y 00053 4, 5, 7, 5, 6, 7 // +Z 00054 }; 00055 00056 // Create the geometry 00057 const int num_verts = 8; 00058 const int num_tris = 12; 00059 EntityHandle verts[num_verts], tris[num_tris], surf; 00060 00061 rval = mbi->create_meshset( MESHSET_SET, surf );MB_CHK_ERR( rval ); 00062 /* 00063 // scale coords 00064 int i; 00065 double scaled_coords[24]; 00066 for ( i = 0; i < num_verts; i++ ) 00067 { 00068 scaled_coords[3*i] = coords[3*i]*scale_vec[0]; 00069 scaled_coords[3*i+1] = coords[3*i+1]*scale_vec[1]; 00070 scaled_coords[3*i+2] = coords[3*i+2]*scale_vec[2]; 00071 } 00072 00073 // translate coords 00074 double trans_coords[24]; 00075 for ( i = 0; i < num_verts; i++ ) 00076 { 00077 trans_coords[3*i] = scaled_coords[3*i] + trans_vec[0]; 00078 trans_coords[3*i+1] = scaled_coords[3*i+1] + trans_vec[1]; 00079 trans_coords[3*i+2] = scaled_coords[3*i+2] + trans_vec[2]; 00080 } 00081 */ 00082 // transform coords-- scale and translate 00083 double trans_coords[24]; 00084 for( int i = 0; i < num_verts; i++ ) 00085 { 00086 trans_coords[3 * i] = coords[3 * i] * scale_vec[0] + trans_vec[0]; 00087 trans_coords[3 * i + 1] = coords[3 * i + 1] * scale_vec[1] + trans_vec[1]; 00088 trans_coords[3 * i + 2] = coords[3 * i + 2] * scale_vec[2] + trans_vec[2]; 00089 } 00090 00091 // create vertices and add to meshset 00092 for( int i = 0; i < num_verts; ++i ) 00093 { 00094 rval = mbi->create_vertex( trans_coords + 3 * i, verts[i] );MB_CHK_ERR( rval ); 00095 00096 rval = mbi->add_entities( surf, &verts[i], 1 );MB_CHK_ERR( rval ); 00097 } 00098 00099 // create triangles and add to meshset 00100 for( int i = 0; i < num_tris; ++i ) 00101 { 00102 const EntityHandle conn[] = { verts[connectivity[3 * i]], verts[connectivity[3 * i + 1]], 00103 verts[connectivity[3 * i + 2]] }; 00104 rval = mbi->create_element( MBTRI, conn, 3, tris[i] );MB_CHK_ERR( rval ); 00105 00106 rval = mbi->add_entities( surf, &tris[i], 1 );MB_CHK_ERR( rval ); 00107 } 00108 00109 // set name, id, geom, and category tags for SURFACE 00110 rval = mbi->tag_set_data( name_tag, &surf, 1, "Surface\0" );MB_CHK_ERR( rval ); 00111 std::string object_name; 00112 rval = mbi->tag_set_data( obj_name_tag, &surf, 1, object_name.c_str() );MB_CHK_ERR( rval ); 00113 rval = mbi->tag_set_data( id_tag, &surf, 1, &object_id );MB_CHK_ERR( rval ); 00114 int two = 2; 00115 rval = mbi->tag_set_data( geom_tag, &surf, 1, &( two ) );MB_CHK_ERR( rval ); 00116 rval = mbi->tag_set_data( category_tag, &surf, 1, "Surface\0" );MB_CHK_ERR( rval ); 00117 00118 // create volume meshset associated with surface meshset 00119 // EntityHandle volume; 00120 rval = mbi->create_meshset( MESHSET_SET, volume );MB_CHK_ERR( rval ); 00121 00122 // set name, id, geom, and category tags for VOLUME 00123 rval = mbi->tag_set_data( name_tag, &volume, 1, "Volume\0" );MB_CHK_ERR( rval ); 00124 rval = mbi->tag_set_data( obj_name_tag, &surf, 1, object_name.c_str() );MB_CHK_ERR( rval ); 00125 rval = mbi->tag_set_data( id_tag, &volume, 1, &( object_id ) );MB_CHK_ERR( rval ); 00126 int three = 3; 00127 rval = mbi->tag_set_data( geom_tag, &volume, 1, &( three ) );MB_CHK_ERR( rval ); 00128 rval = mbi->tag_set_data( category_tag, &volume, 1, "Volume\0" );MB_CHK_ERR( rval ); 00129 00130 // set surface as child of volume 00131 rval = mbi->add_parent_child( volume, surf );MB_CHK_ERR( rval ); 00132 00133 // set sense tag 00134 rval = GTT->set_sense( surf, volume, SENSE_FORWARD );MB_CHK_ERR( rval ); 00135 00136 delete GTT; 00137 00138 return MB_SUCCESS; 00139 } 00140 00141 int main() 00142 { 00143 int result = 0; 00144 00145 result += RUN_TEST( test_two_cubes ); 00146 result += RUN_TEST( test_three_cubes ); 00147 result += RUN_TEST( test_four_cubes ); 00148 00149 return result; 00150 } 00151 00152 ErrorCode get_all_handles( Interface* mbi ) 00153 { 00154 ErrorCode rval; 00155 00156 rval = mbi->tag_get_handle( NAME_TAG_NAME, NAME_TAG_SIZE, MB_TYPE_OPAQUE, name_tag, MB_TAG_SPARSE | MB_TAG_CREAT );MB_CHK_ERR( rval ); 00157 00158 rval = mbi->tag_get_handle( "OBJECT_NAME", 32, MB_TYPE_OPAQUE, obj_name_tag, MB_TAG_SPARSE | MB_TAG_CREAT );MB_CHK_ERR( rval ); 00159 00160 int negone = -1; 00161 rval = mbi->tag_get_handle( GEOM_DIMENSION_TAG_NAME, 1, MB_TYPE_INTEGER, geom_tag, MB_TAG_SPARSE | MB_TAG_CREAT, 00162 &negone );MB_CHK_ERR( rval ); 00163 00164 id_tag = mbi->globalId_tag(); 00165 00166 rval = mbi->tag_get_handle( CATEGORY_TAG_NAME, CATEGORY_TAG_SIZE, MB_TYPE_OPAQUE, category_tag, 00167 MB_TAG_SPARSE | MB_TAG_CREAT ); 00168 00169 MB_CHK_ERR( rval ); 00170 return MB_SUCCESS; 00171 } 00172 00173 /* This function tests that the tree built by generate_hierarchy is the same 00174 as the reference tree 00175 */ 00176 bool check_tree( Interface* mbi, GeomTopoTool* GTT, std::map< int, std::set< int > >& ref_map ) 00177 { 00178 ErrorCode rval; 00179 int vol_id; 00180 std::set< int > test_set; 00181 00182 Range vols; 00183 rval = GTT->get_gsets_by_dimension( 3, vols ); 00184 if( ref_map.size() != vols.size() ) 00185 { 00186 return false; 00187 } 00188 00189 // go through volumes, create sets of children 00190 for( Range::iterator it = vols.begin(); it != vols.end(); ++it ) 00191 { 00192 // get vol id 00193 rval = mbi->tag_get_data( id_tag, &( *it ), 1, &vol_id );MB_CHK_ERR( rval ); 00194 00195 // check if test vol in ref map 00196 if( ref_map.find( vol_id ) == ref_map.end() ) 00197 { 00198 return false; 00199 } 00200 00201 // put range of child surfaces into set 00202 Range child_surfs; 00203 test_set.clear(); 00204 child_surfs = get_children_by_dimension( mbi, *it, 2 ); 00205 00206 for( Range::iterator j = child_surfs.begin(); j != child_surfs.end(); ++j ) 00207 { 00208 int child_id; 00209 00210 rval = mbi->tag_get_data( id_tag, &( *j ), 1, &child_id );MB_CHK_ERR( rval ); 00211 test_set.insert( child_id ); 00212 } 00213 00214 // compare sets 00215 if( test_set != ref_map[vol_id] ) 00216 { 00217 return false; 00218 } 00219 } 00220 00221 return true; 00222 } 00223 00224 Range get_children_by_dimension( Interface* mbi, EntityHandle parent, int desired_dimension ) 00225 { 00226 ErrorCode rval; 00227 Range all_children, desired_children; 00228 Range::iterator it; 00229 int actual_dimension; 00230 00231 all_children.clear(); 00232 rval = mbi->get_child_meshsets( parent, all_children );MB_CHK_SET_ERR_RET_VAL( rval, "Failed to get child meshsets", all_children ); 00233 00234 for( it = all_children.begin(); it != all_children.end(); ++it ) 00235 { 00236 rval = mbi->tag_get_data( geom_tag, &( *it ), 1, &actual_dimension );MB_CHK_SET_ERR_RET_VAL( rval, "Failed to get geom tag from child meshset", all_children ); 00237 if( actual_dimension == desired_dimension ) 00238 { 00239 desired_children.insert( *it ); 00240 } 00241 } 00242 00243 return desired_children; 00244 } 00245 00246 /* This function contains info for the scale and translation vectors of 00247 four different cubes that will be used in the hierarchy testing 00248 */ 00249 void get_cube_info( int cube_id, std::vector< double >& scale, std::vector< double >& trans ) 00250 { 00251 scale.clear(); 00252 trans.clear(); 00253 00254 if( cube_id == 1 ) 00255 { 00256 scale.push_back( 1 ); 00257 scale.push_back( 1 ); 00258 scale.push_back( 1 ); 00259 trans.push_back( 0 ); 00260 trans.push_back( 0 ); 00261 trans.push_back( 0 ); 00262 } 00263 if( cube_id == 2 ) 00264 { 00265 scale.push_back( 4 ); 00266 scale.push_back( 4 ); 00267 scale.push_back( 4 ); 00268 trans.push_back( 0 ); 00269 trans.push_back( 0 ); 00270 trans.push_back( 0 ); 00271 } 00272 if( cube_id == 3 ) 00273 { 00274 scale.push_back( 8 ); 00275 scale.push_back( 8 ); 00276 scale.push_back( 8 ); 00277 trans.push_back( 0 ); 00278 trans.push_back( 0 ); 00279 trans.push_back( 0 ); 00280 } 00281 if( cube_id == 4 ) 00282 { 00283 scale.push_back( 40 ); 00284 scale.push_back( 40 ); 00285 scale.push_back( 40 ); 00286 trans.push_back( 0 ); 00287 trans.push_back( 0 ); 00288 trans.push_back( 0 ); 00289 } 00290 } 00291 00292 /* 00293 * One large cube that contains a smaller one. 00294 */ 00295 void test_two_cubes() 00296 { 00297 ErrorCode rval; 00298 00299 Interface* mbi = new Core(); 00300 00301 // get all handles (dimension, id, sense) 00302 rval = get_all_handles( mbi );MB_CHK_ERR_RET( rval ); 00303 00304 int len = 2; 00305 int num[2] = { 1, 2 }; 00306 00307 // build reference map 00308 std::map< int, std::set< int > > ref_map; 00309 ref_map[1].insert( 1 ); 00310 ref_map[2].insert( 2 ); 00311 ref_map[2].insert( 1 ); 00312 00313 heappermute( mbi, num, len, ref_map, len ); 00314 00315 delete mbi; 00316 } 00317 00318 /* 00319 * One large cube that contains two others. 00320 * The two inner cubes are siblings. 00321 */ 00322 void test_three_cubes() 00323 { 00324 ErrorCode rval; 00325 00326 Interface* mbi = new Core(); 00327 00328 // get all handles (dimension, id, sense) 00329 rval = get_all_handles( mbi );MB_CHK_ERR_RET( rval ); 00330 00331 int len = 3; 00332 int num[3] = { 1, 2, 3 }; 00333 00334 // build reference map 00335 std::map< int, std::set< int > > ref_map; 00336 ref_map[1].insert( 1 ); 00337 ref_map[2].insert( 2 ); 00338 ref_map[2].insert( 1 ); 00339 ref_map[3].insert( 3 ); 00340 ref_map[3].insert( 2 ); 00341 00342 heappermute( mbi, num, len, ref_map, len ); 00343 00344 delete mbi; 00345 } 00346 00347 /* 00348 * Four nested cubes of decreasing size; one placed inside the next 00349 */ 00350 void test_four_cubes() 00351 { 00352 ErrorCode rval; 00353 00354 Interface* mbi = new Core(); 00355 00356 // get all handles (dimension, id, sense) 00357 rval = get_all_handles( mbi );MB_CHK_ERR_RET( rval ); 00358 00359 int len = 4; 00360 int num[4] = { 1, 2, 3, 4 }; 00361 00362 // build reference map 00363 std::map< int, std::set< int > > ref_map; 00364 ref_map[1].insert( 1 ); 00365 ref_map[2].insert( 2 ); 00366 ref_map[2].insert( 1 ); 00367 ref_map[3].insert( 3 ); 00368 ref_map[3].insert( 2 ); 00369 ref_map[4].insert( 4 ); 00370 ref_map[4].insert( 3 ); 00371 00372 heappermute( mbi, num, len, ref_map, len ); 00373 00374 delete mbi; 00375 } 00376 00377 /* Heap's algorithm generates all possible permutations of n objects 00378 This function is a modification of code found here: 00379 http://www.sanfoundry.com/c-program-implement-heap-algorithm-permutation-n-numbers 00380 */ 00381 void heappermute( Interface* mbi, int v[], int n, std::map< int, std::set< int > > ref_map, int len ) 00382 { 00383 00384 ErrorCode rval; 00385 std::vector< double > scale, trans; 00386 EntityHandle vol; 00387 Range flat_vols; 00388 00389 if( n == 1 ) 00390 { 00391 // build cubes 00392 flat_vols.clear(); 00393 for( int i = 0; i < len; i++ ) 00394 { 00395 get_cube_info( v[i], scale, trans ); 00396 build_cube( mbi, scale, trans, v[i], vol ); 00397 flat_vols.insert( vol ); 00398 } 00399 00400 // construct the topology 00401 GeomTopoTool* GTT = new GeomTopoTool( mbi ); 00402 // first build obbs-- necessary for topology construction 00403 rval = GTT->construct_obb_trees();MB_CHK_ERR_RET( rval ); 00404 rval = GTT->restore_topology_from_geometric_inclusion( flat_vols );MB_CHK_ERR_RET( rval ); 00405 00406 // test the topology 00407 bool result = check_tree( mbi, GTT, ref_map ); 00408 CHECK_EQUAL( 1, result ); 00409 delete GTT; 00410 00411 // delete the geometry so new one can be built; 00412 rval = mbi->delete_mesh();MB_CHK_ERR_RET( rval ); 00413 } 00414 00415 else 00416 { 00417 for( int i = 0; i < n; i++ ) 00418 { 00419 heappermute( mbi, v, n - 1, ref_map, len ); 00420 if( n % 2 == 1 ) 00421 { 00422 swap( &v[0], &v[n - 1] ); 00423 } 00424 00425 else 00426 { 00427 swap( &v[i], &v[n - 1] ); 00428 } 00429 } 00430 } 00431 } 00432 00433 void swap( int* x, int* y ) 00434 { 00435 int temp; 00436 00437 temp = *x; 00438 *x = *y; 00439 *y = temp; 00440 }