MOAB: Mesh Oriented datABase  (version 5.4.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,
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines