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