MOAB: Mesh Oriented datABase  (version 5.4.0)
testgeom.cpp
Go to the documentation of this file.
00001 /**
00002  * This library is free software; you can redistribute it and/or
00003  * modify it under the terms of the GNU Lesser General Public
00004  * License as published by the Free Software Foundation; either
00005  * version 2.1 of the License, or (at your option) any later version.
00006  *
00007  */
00008 /**
00009  * \file testgeom.cc
00010  *
00011  * \brief testgeom, a unit test for the ITAPS geometry interface
00012  *
00013  */
00014 #include "FBiGeom.h"
00015 #include <iostream>
00016 #include <set>
00017 #include <algorithm>
00018 #include <vector>
00019 #include <iterator>
00020 #include <algorithm>
00021 #include <iomanip>
00022 #include <cassert>
00023 #include <cstring>
00024 #include <cmath>
00025 #define CHECK( STR ) \
00026     if( err != iBase_SUCCESS ) return print_error( STR, err, geom, __FILE__, __LINE__ )
00027 
00028 #define STRINGIFY( S )  XSTRINGIFY( S )
00029 #define XSTRINGIFY( S ) #S
00030 
00031 static bool print_error( const char* desc, int err, FBiGeom_Instance geom, const char* file, int line )
00032 {
00033     char buffer[1024];
00034     FBiGeom_getDescription( geom, buffer, sizeof( buffer ) );
00035     buffer[sizeof( buffer ) - 1] = '\0';
00036 
00037     std::cerr << "ERROR: " << desc << std::endl
00038               << "  Error code: " << err << std::endl
00039               << "  Error desc: " << buffer << std::endl
00040               << "  At        : " << file << ':' << line << std::endl;
00041 
00042     return false;  // must always return false or CHECK macro will break
00043 }
00044 
00045 typedef iBase_TagHandle TagHandle;
00046 typedef iBase_EntityHandle GentityHandle;
00047 typedef iBase_EntitySetHandle GentitysetHandle;
00048 
00049 /* Frees allocated arrays for us */
00050 template < typename T >
00051 class SimpleArray
00052 {
00053   private:
00054     T* arr;
00055     int arrSize;
00056     int arrAllocated;
00057 
00058   public:
00059     SimpleArray() : arr( 0 ), arrSize( 0 ), arrAllocated( 0 ) {}
00060     SimpleArray( unsigned s ) : arrSize( s ), arrAllocated( s )
00061     {
00062         arr = (T*)malloc( s * sizeof( T ) );
00063         for( unsigned i = 0; i < s; ++i )
00064             new( arr + i ) T();
00065     }
00066 
00067     ~SimpleArray()
00068     {
00069         for( int i = 0; i < size(); ++i )
00070             arr[i].~T();
00071         free( arr );
00072     }
00073 
00074     T** ptr()
00075     {
00076         return &arr;
00077     }
00078     int& size()
00079     {
00080         return arrSize;
00081     }
00082     int size() const
00083     {
00084         return arrSize;
00085     }
00086     int& capacity()
00087     {
00088         return arrAllocated;
00089     }
00090     int capacity() const
00091     {
00092         return arrAllocated;
00093     }
00094 
00095     typedef T* iterator;
00096     typedef const T* const_iterator;
00097     iterator begin()
00098     {
00099         return arr;
00100     }
00101     const_iterator begin() const
00102     {
00103         return arr;
00104     }
00105     iterator end()
00106     {
00107         return arr + arrSize;
00108     }
00109     const_iterator end() const
00110     {
00111         return arr + arrSize;
00112     }
00113 
00114     T& operator[]( unsigned idx )
00115     {
00116         return arr[idx];
00117     }
00118     T operator[]( unsigned idx ) const
00119     {
00120         return arr[idx];
00121     }
00122 };
00123 
00124 #define ARRAY_INOUT( A ) A.ptr(), &( A ).capacity(), &( A ).size()
00125 #define ARRAY_IN( A )    &( A )[0], ( A ).size()
00126 
00127 bool gLoad_test( const std::string& filename, FBiGeom_Instance );
00128 
00129 bool tags_test( FBiGeom_Instance geom );
00130 bool tag_get_set_test( FBiGeom_Instance geom );
00131 bool tag_info_test( FBiGeom_Instance geom );
00132 bool gentityset_test( FBiGeom_Instance geom, bool /*multiset*/, bool /*ordered*/ );
00133 bool topology_adjacencies_test( FBiGeom_Instance geom );
00134 bool geometry_evaluation_test( FBiGeom_Instance geom );
00135 bool construct_test( FBiGeom_Instance geom );
00136 bool primitives_test( FBiGeom_Instance geom );
00137 bool transforms_test( FBiGeom_Instance geom );
00138 bool booleans_test( FBiGeom_Instance geom );
00139 bool shutdown_test( FBiGeom_Instance geom, std::string& engine_opt );
00140 bool save_entset_test( FBiGeom_Instance geom );
00141 bool mesh_size_test( FBiGeom_Instance geom );
00142 
00143 void handle_error_code( const bool result, int& number_failed, int& /*number_not_implemented*/, int& number_successful )
00144 {
00145     if( result )
00146     {
00147         std::cout << "Success";
00148         number_successful++;
00149     }
00150     else
00151     {
00152         std::cout << "Failure";
00153         number_failed++;
00154     }
00155 }
00156 
00157 int main( int argc, char* argv[] )
00158 {
00159     std::string filename = STRINGIFY( MESHDIR ) "/shell.h5m";
00160     std::string engine_opt;
00161 
00162     if( argc == 1 )
00163     {
00164         std::cout << "Using default input file: " << filename << std::endl;
00165     }
00166     else if( argc == 2 )
00167     {
00168         filename = argv[1];
00169     }
00170     else
00171     {
00172         std::cerr << "Usage: " << argv[0] << " [geom_filename]" << std::endl;
00173         return 1;
00174     }
00175 
00176     bool result;
00177     int number_tests                 = 0;
00178     int number_tests_successful      = 0;
00179     int number_tests_not_implemented = 0;
00180     int number_tests_failed          = 0;
00181 
00182     // initialize the Mesh
00183     int err;
00184     FBiGeom_Instance geom;
00185     FBiGeom_newGeom( engine_opt.c_str(), &geom, &err, engine_opt.length() );
00186 
00187     // Print out Header information
00188     std::cout << "\n\nITAPS GEOMETRY INTERFACE TEST PROGRAM:\n\n";
00189     // gLoad test
00190     std::cout << "   gLoad: ";
00191     result = gLoad_test( filename, geom );
00192     handle_error_code( result, number_tests_failed, number_tests_not_implemented, number_tests_successful );
00193     number_tests++;
00194     std::cout << "\n";
00195 
00196     // tags test
00197     std::cout << "   tags: ";
00198     result = tags_test( geom );
00199     handle_error_code( result, number_tests_failed, number_tests_not_implemented, number_tests_successful );
00200     number_tests++;
00201     std::cout << "\n";
00202     /*
00203       // gentitysets test
00204     std::cout << "   gentity sets: ";
00205     result = gentityset_test(geom, false, false);
00206     handle_error_code(result, number_tests_failed,
00207                       number_tests_not_implemented,
00208                       number_tests_successful);
00209     number_tests++;
00210     std::cout << "\n";
00211     */
00212     // topology adjacencies test
00213     std::cout << "   topology adjacencies: ";
00214     result = topology_adjacencies_test( geom );
00215     handle_error_code( result, number_tests_failed, number_tests_not_implemented, number_tests_successful );
00216     number_tests++;
00217     std::cout << "\n";
00218 
00219     // geometry evaluation test
00220     std::cout << "   geometry evaluation: ";
00221     result = geometry_evaluation_test( geom );
00222     handle_error_code( result, number_tests_failed, number_tests_not_implemented, number_tests_successful );
00223     number_tests++;
00224     std::cout << "\n";
00225     /*
00226       // construct test
00227     std::cout << "   construct: ";
00228     result = construct_test(geom);
00229     handle_error_code(result, number_tests_failed,
00230                       number_tests_not_implemented,
00231                       number_tests_successful);
00232     number_tests++;
00233     std::cout << "\n";
00234 
00235       // primitives test
00236     std::cout << "   primitives: ";
00237     result = primitives_test(geom);
00238     handle_error_code(result, number_tests_failed,
00239                       number_tests_not_implemented,
00240                       number_tests_successful);
00241     number_tests++;
00242     std::cout << "\n";
00243 
00244       // transforms test
00245     std::cout << "   transforms: ";
00246     result = transforms_test(geom);
00247     handle_error_code(result, number_tests_failed,
00248                       number_tests_not_implemented,
00249                       number_tests_successful);
00250     number_tests++;
00251     std::cout << "\n";
00252 
00253       // booleans test
00254     std::cout << "   booleans: ";
00255     result = booleans_test(geom);
00256     handle_error_code(result, number_tests_failed,
00257                       number_tests_not_implemented,
00258                       number_tests_successful);
00259     number_tests++;
00260     std::cout << "\n";
00261 
00262   #if defined(HAVE_ACIS) && !defined(FORCE_OCC)
00263     std::cout << "   mesh size: ";
00264     result = mesh_size_test(geom);
00265     handle_error_code(result, number_tests_failed,
00266                       number_tests_not_implemented,
00267                       number_tests_successful);
00268     number_tests++;
00269     std::cout << "\n";
00270 
00271       // save entset test
00272     std::cout << "   save entset: ";
00273     result = save_entset_test(geom);
00274     handle_error_code(result, number_tests_failed,
00275                       number_tests_not_implemented,
00276                       number_tests_successful);
00277     number_tests++;
00278     std::cout << "\n";
00279   #endif
00280     */
00281     // shutdown test
00282     std::cout << "   shutdown: ";
00283     result = shutdown_test( geom, engine_opt );
00284     handle_error_code( result, number_tests_failed, number_tests_not_implemented, number_tests_successful );
00285     number_tests++;
00286     std::cout << "\n";
00287 
00288     // summary
00289 
00290     std::cout << "\nTSTT TEST SUMMARY: \n"
00291               << "   Number Tests:           " << number_tests << "\n"
00292               << "   Number Successful:      " << number_tests_successful << "\n"
00293               << "   Number Not Implemented: " << number_tests_not_implemented << "\n"
00294               << "   Number Failed:          " << number_tests_failed << "\n\n"
00295               << std::endl;
00296 
00297     return number_tests_failed;
00298 }
00299 
00300 /*!
00301   @test
00302   Load Mesh
00303   @li Load a mesh file
00304 */
00305 bool gLoad_test( const std::string& filename, FBiGeom_Instance geom )
00306 {
00307     int err;
00308     FBiGeom_load( geom, &filename[0], 0, &err, filename.length(), 0 );
00309     CHECK( "ERROR : can not load a geometry" );
00310 
00311     iBase_EntitySetHandle root_set;
00312     FBiGeom_getRootSet( geom, &root_set, &err );
00313     CHECK( "ERROR : getRootSet failed!" );
00314 
00315     // print out the number of entities
00316     std::cout << "Model contents: " << std::endl;
00317     const char* gtype[] = { "vertices: ", "edges: ", "faces: ", "regions: " };
00318     for( int i = 0; i <= 3; ++i )
00319     {
00320         int count;
00321         FBiGeom_getNumOfType( geom, root_set, i, &count, &err );
00322         CHECK( "Error: problem getting entities after gLoad." );
00323         std::cout << gtype[i] << count << std::endl;
00324     }
00325 
00326     return true;
00327 }
00328 
00329 /*!
00330   @test
00331   Test tag creating, reading, writing, deleting
00332   @li Load a mesh file
00333 */
00334 bool tags_test( FBiGeom_Instance geom )
00335 {
00336     bool success = tag_info_test( geom );
00337     if( !success ) return success;
00338 
00339     success = tag_get_set_test( geom );
00340     if( !success ) return success;
00341 
00342     return true;
00343 }
00344 
00345 bool tag_info_test( FBiGeom_Instance geom )
00346 {
00347     int err;
00348 
00349     iBase_EntitySetHandle root_set;
00350     FBiGeom_getRootSet( geom, &root_set, &err );
00351     CHECK( "ERROR : getRootSet failed!" );
00352 
00353     // create an arbitrary tag, size 4
00354     iBase_TagHandle this_tag, tmp_handle;
00355     std::string tag_name( "tag_info tag" ), tmp_name;
00356     FBiGeom_createTag( geom, &tag_name[0], 4, iBase_BYTES, &this_tag, &err, tag_name.length() );
00357     CHECK( "ERROR : can not create a tag." );
00358 
00359     // get information on the tag
00360 
00361     char name_buffer[256];
00362     FBiGeom_getTagName( geom, this_tag, name_buffer, &err, sizeof( name_buffer ) );
00363     CHECK( "ERROR : Couldn't get tag name." );
00364     if( tag_name != name_buffer )
00365     {
00366         std::cerr << "ERROR: getTagName returned '" << name_buffer << "' for tag created as '" << tag_name << "'"
00367                   << std::endl;
00368         return false;
00369     }
00370 
00371     FBiGeom_getTagHandle( geom, &tag_name[0], &tmp_handle, &err, tag_name.length() );
00372     CHECK( "ERROR : Couldn't get tag handle." );
00373     if( tmp_handle != this_tag )
00374     {
00375         std::cerr << "ERROR: getTagHandle didn't return consistent result." << std::endl;
00376         return false;
00377     }
00378 
00379     int tag_size;
00380     FBiGeom_getTagSizeBytes( geom, this_tag, &tag_size, &err );
00381     CHECK( "ERROR : Couldn't get tag size." );
00382     if( tag_size != 4 )
00383     {
00384         std::cerr << "ERROR: getTagSizeBytes: expected 4, got " << tag_size << std::endl;
00385         return false;
00386     }
00387 
00388     FBiGeom_getTagSizeValues( geom, this_tag, &tag_size, &err );
00389     CHECK( "ERROR : Couldn't get tag size." );
00390     if( tag_size != 4 )
00391     {
00392         std::cerr << "ERROR: getTagSizeValues: expected 4, got " << tag_size << std::endl;
00393         return false;
00394     }
00395 
00396     int tag_type;
00397     FBiGeom_getTagType( geom, this_tag, &tag_type, &err );
00398     CHECK( "ERROR : Couldn't get tag type." );
00399     if( tag_type != iBase_BYTES )
00400     {
00401         std::cerr << "ERROR: getTagType: expected " << iBase_BYTES << ", got " << tag_type << std::endl;
00402         return false;
00403     }
00404 
00405     FBiGeom_destroyTag( geom, this_tag, true, &err );
00406     CHECK( "ERROR : Couldn't delete a tag." );
00407 
00408     // print information about all the tags in the model
00409 
00410     std::set< iBase_TagHandle > tags;
00411     SimpleArray< iBase_EntityHandle > entities;
00412     FBiGeom_getEntities( geom, root_set, iBase_ALL_TYPES, ARRAY_INOUT( entities ), &err );
00413     CHECK( "getEntities( ..., iBase_ALL_TYPES, ... ) failed." );
00414     for( int i = 0; i < entities.size(); ++i )
00415     {
00416         SimpleArray< iBase_TagHandle > tag_arr;
00417         FBiGeom_getAllTags( geom, entities[i], ARRAY_INOUT( tag_arr ), &err );
00418         CHECK( "getAllTags failed." );
00419         std::copy( tag_arr.begin(), tag_arr.end(), std::inserter( tags, tags.begin() ) );
00420     }
00421 
00422     std::cout << "Tags defined on model: ";
00423     bool first = true;
00424     for( std::set< iBase_TagHandle >::iterator sit = tags.begin(); sit != tags.end(); ++sit )
00425     {
00426         FBiGeom_getTagName( geom, *sit, name_buffer, &err, sizeof( name_buffer ) );
00427         name_buffer[sizeof( name_buffer ) - 1] = '\0';  // mnake sure of NUL termination
00428         CHECK( "getTagName failed." );
00429 
00430         if( !first ) std::cout << ", ";
00431         std::cout << name_buffer;
00432         first = false;
00433     }
00434     if( first ) std::cout << "<none>";
00435     std::cout << std::endl;
00436 
00437     return true;
00438 }
00439 
00440 bool tag_get_set_test( FBiGeom_Instance geom )
00441 {
00442     int err;
00443 
00444     // create an arbitrary tag, size 4
00445     iBase_TagHandle this_tag;
00446     std::string tag_name( "tag_get_set tag" );
00447     FBiGeom_createTag( geom, &tag_name[0], sizeof( int ), iBase_BYTES, &this_tag, &err, tag_name.length() );
00448     CHECK( "ERROR : can not create a tag for get_set test." );
00449 
00450     iBase_EntitySetHandle root_set;
00451     FBiGeom_getRootSet( geom, &root_set, &err );
00452     CHECK( "ERROR : getRootSet failed!" );
00453 
00454     // set this tag to an integer on each entity; keep track of total sum
00455     int sum = 0, num = 0, dim;
00456     for( dim = 0; dim <= 3; dim++ )
00457     {
00458         SimpleArray< iBase_EntityHandle > gentity_handles;
00459         FBiGeom_getEntities( geom, root_set, dim, ARRAY_INOUT( gentity_handles ), &err );
00460         int num_ents = gentity_handles.size();
00461         std::vector< int > tag_vals( num_ents );
00462         for( int i = 0; i < num_ents; ++i )
00463         {
00464             tag_vals[i] = num;
00465             sum += num;
00466             ++num;
00467         }
00468 
00469         FBiGeom_setArrData( geom, ARRAY_IN( gentity_handles ), this_tag, (char*)&tag_vals[0],
00470                             tag_vals.size() * sizeof( int ), &err );
00471         CHECK( "ERROR : can't set tag on entities" );
00472     }
00473 
00474     // check tag values for entities now
00475     int get_sum = 0;
00476     for( dim = 0; dim <= 3; dim++ )
00477     {
00478         SimpleArray< iBase_EntityHandle > gentity_handles;
00479         FBiGeom_getEntities( geom, root_set, dim, ARRAY_INOUT( gentity_handles ), &err );
00480         int num_ents = gentity_handles.size();
00481 
00482         SimpleArray< char > tag_vals;
00483         FBiGeom_getArrData( geom, ARRAY_IN( gentity_handles ), this_tag, (void**)tag_vals.ptr(), &tag_vals.capacity(),
00484                             &tag_vals.size(), &err );
00485         CHECK( "ERROR : can't get tag on entities" );
00486 
00487         int* tag_ptr = (int*)( &tag_vals[0] );
00488         for( int i = 0; i < num_ents; ++i )
00489             get_sum += tag_ptr[i];
00490     }
00491 
00492     if( get_sum != sum )
00493     {
00494         std::cerr << "ERROR: getData didn't return consistent results." << std::endl;
00495         return false;
00496     }
00497 
00498     FBiGeom_destroyTag( geom, this_tag, true, &err );
00499     CHECK( "ERROR : couldn't delete tag." );
00500 
00501     return true;
00502 }
00503 
00504 /*!
00505   @test
00506   TSTT gentity sets test (just implemented parts for now)
00507   @li Check gentity sets
00508 */
00509 bool gentityset_test( FBiGeom_Instance geom, bool /*multiset*/, bool /*ordered*/ )
00510 {
00511     int num_type = 4;
00512     iBase_EntitySetHandle ges_array[4];
00513     int number_array[4];
00514     // int num_all_gentities_super = 0;
00515     int ent_type = iBase_VERTEX;
00516 
00517     int err;
00518     iBase_EntitySetHandle root_set;
00519     FBiGeom_getRootSet( geom, &root_set, &err );
00520     CHECK( "ERROR : getRootSet failed!" );
00521 
00522     // get the number of sets in the whole model
00523     int all_sets = 0;
00524     FBiGeom_getNumEntSets( geom, root_set, 0, &all_sets, &err );
00525     CHECK( "Problem getting the number of all gentity sets in whole model." );
00526 
00527     // add gentities to entitysets by type
00528     for( ; ent_type < num_type; ent_type++ )
00529     {
00530         // initialize the entityset
00531         FBiGeom_createEntSet( geom, true, &ges_array[ent_type], &err );
00532         CHECK( "Problem creating entityset." );
00533 
00534         // get entities by type in total "mesh"
00535         SimpleArray< iBase_EntityHandle > gentities;
00536         FBiGeom_getEntities( geom, root_set, ent_type, ARRAY_INOUT( gentities ), &err );
00537         CHECK( "Failed to get gentities by type in gentityset_test." );
00538 
00539         // add gentities into gentity set
00540         FBiGeom_addEntArrToSet( geom, ARRAY_IN( gentities ), ges_array[ent_type], &err );
00541         CHECK( "Failed to add gentities in entityset_test." );
00542 
00543         // Check to make sure entity set really has correct number of entities in it
00544         FBiGeom_getNumOfType( geom, ges_array[ent_type], ent_type, &number_array[ent_type], &err );
00545         CHECK( "Failed to get number of gentities by type in entityset_test." );
00546 
00547         // compare the number of entities by type
00548         int num_type_gentity = gentities.size();
00549 
00550         if( number_array[ent_type] != num_type_gentity )
00551         {
00552             std::cerr << "Number of gentities by type is not correct" << std::endl;
00553             return false;
00554         }
00555 
00556         // add to number of all entities in super set
00557         // num_all_gentities_super += num_type_gentity;
00558     }
00559 
00560     // make a super set having all entitysets
00561     iBase_EntitySetHandle super_set;
00562     FBiGeom_createEntSet( geom, true, &super_set, &err );
00563     CHECK( "Failed to create a super set in gentityset_test." );
00564 
00565     for( int i = 0; i < num_type; i++ )
00566     {
00567         FBiGeom_addEntSet( geom, ges_array[i], super_set, &err );
00568         CHECK( "Failed to create a super set in gentityset_test." );
00569     }
00570 
00571     //----------TEST BOOLEAN OPERATIONS----------------//
00572 
00573     iBase_EntitySetHandle temp_ges1;
00574     FBiGeom_createEntSet( geom, true, &temp_ges1, &err );
00575     CHECK( "Failed to create a super set in gentityset_test." );
00576 
00577     // Subtract
00578     // add all EDGEs and FACEs to temp_es1
00579     // get all EDGE entities
00580     SimpleArray< iBase_EntityHandle > gedges, gfaces, temp_gentities1;
00581     FBiGeom_getEntities( geom, ges_array[iBase_EDGE], iBase_EDGE, ARRAY_INOUT( gedges ), &err );
00582     CHECK( "Failed to get gedge gentities in gentityset_test." );
00583 
00584     // add EDGEs to ges1
00585     FBiGeom_addEntArrToSet( geom, ARRAY_IN( gedges ), temp_ges1, &err );
00586     CHECK( "Failed to add gedge gentities in gentityset_test." );
00587 
00588     // get all FACE gentities
00589     FBiGeom_getEntities( geom, ges_array[iBase_FACE], iBase_FACE, ARRAY_INOUT( gfaces ), &err );
00590     CHECK( "Failed to get gface gentities in gentityset_test." );
00591 
00592     // add FACEs to es1
00593     FBiGeom_addEntArrToSet( geom, ARRAY_IN( gfaces ), temp_ges1, &err );
00594     CHECK( "Failed to add gface gentities in gentityset_test." );
00595 
00596     // subtract EDGEs
00597     FBiGeom_subtract( geom, temp_ges1, ges_array[iBase_EDGE], &temp_ges1, &err );
00598     CHECK( "Failed to subtract gentitysets in gentityset_test." );
00599 
00600     FBiGeom_getEntities( geom, temp_ges1, iBase_FACE, ARRAY_INOUT( temp_gentities1 ), &err );
00601     CHECK( "Failed to get gface gentities in gentityset_test." );
00602 
00603     if( gfaces.size() != temp_gentities1.size() )
00604     {
00605         std::cerr << "Number of entitysets after subtraction not correct \
00606              in gentityset_test."
00607                   << std::endl;
00608         return false;
00609     }
00610 
00611     // check there's nothing but gfaces in temp_ges1
00612     int num_gents;
00613     FBiGeom_getNumOfType( geom, temp_ges1, iBase_EDGE, &num_gents, &err );
00614     CHECK( "Failed to get dimensions of gentities in gentityset_test." );
00615     if( 0 != num_gents )
00616     {
00617         std::cerr << "Subtraction failed to remove all edges" << std::endl;
00618         return false;
00619     }
00620 
00621     //------------Intersect------------
00622     //
00623 
00624     // clean out the temp_ges1
00625     FBiGeom_rmvEntArrFromSet( geom, ARRAY_IN( gfaces ), temp_ges1, &err );
00626     CHECK( "Failed to remove gface gentities in gentityset_test." );
00627 
00628     // check if it is really cleaned out
00629     FBiGeom_getNumOfType( geom, temp_ges1, iBase_FACE, &num_gents, &err );
00630     CHECK( "Failed to get number of gentities by type in gentityset_test." );
00631 
00632     if( num_gents != 0 )
00633     {
00634         std::cerr << "failed to remove correctly." << std::endl;
00635         return false;
00636     }
00637 
00638     // add EDGEs to temp ges1
00639     FBiGeom_addEntArrToSet( geom, ARRAY_IN( gedges ), temp_ges1, &err );
00640     CHECK( "Failed to add gedge gentities in gentityset_test." );
00641 
00642     // add FACEs to temp ges1
00643     FBiGeom_addEntArrToSet( geom, ARRAY_IN( gfaces ), temp_ges1, &err );
00644     CHECK( "Failed to add gface gentities in gentityset_test." );
00645 
00646     // intersect temp_ges1 with gedges set
00647     // temp_ges1 entityset is altered
00648     FBiGeom_intersect( geom, temp_ges1, ges_array[iBase_EDGE], &temp_ges1, &err );
00649     CHECK( "Failed to intersect in gentityset_test." );
00650 
00651     // try to get FACEs, but there should be nothing but EDGE
00652     FBiGeom_getNumOfType( geom, temp_ges1, iBase_FACE, &num_gents, &err );
00653     CHECK( "Failed to get gface gentities in gentityset_test." );
00654 
00655     if( num_gents != 0 )
00656     {
00657         std::cerr << "wrong number of gfaces." << std::endl;
00658         return false;
00659     }
00660 
00661     //-------------Unite--------------
00662 
00663     // get all regions
00664     iBase_EntitySetHandle temp_ges2;
00665     SimpleArray< iBase_EntityHandle > gregions;
00666 
00667     FBiGeom_createEntSet( geom, true, &temp_ges2, &err );
00668     CHECK( "Failed to create a temp gentityset in gentityset_test." );
00669 
00670     FBiGeom_getEntities( geom, ges_array[iBase_REGION], iBase_REGION, ARRAY_INOUT( gregions ), &err );
00671     CHECK( "Failed to get gregion gentities in gentityset_test." );
00672 
00673     // add REGIONs to temp es2
00674     FBiGeom_addEntArrToSet( geom, ARRAY_IN( gregions ), temp_ges2, &err );
00675     CHECK( "Failed to add gregion gentities in gentityset_test." );
00676 
00677     // unite temp_ges1 and temp_ges2
00678     // temp_ges1 gentityset is altered
00679     FBiGeom_unite( geom, temp_ges1, temp_ges2, &temp_ges1, &err );
00680     CHECK( "Failed to unite in gentityset_test." );
00681 
00682     // perform the check
00683     FBiGeom_getNumOfType( geom, temp_ges1, iBase_REGION, &num_gents, &err );
00684     CHECK( "Failed to get number of gregion gentities by type in gentityset_test." );
00685 
00686     if( num_gents != number_array[iBase_REGION] )
00687     {
00688         std::cerr << "different number of gregions in gentityset_test." << std::endl;
00689         return false;
00690     }
00691 
00692     //--------Test parent/child stuff in entiysets-----------
00693 
00694     // Add 2 sets as children to another
00695     iBase_EntitySetHandle parent_child;
00696     FBiGeom_createEntSet( geom, true, &parent_child, &err );
00697     CHECK( "Problem creating gentityset in gentityset_test." );
00698 
00699     FBiGeom_addPrntChld( geom, ges_array[iBase_VERTEX], parent_child, &err );
00700     CHECK( "Problem add parent in gentityset_test." );
00701 
00702     // check if parent is really added
00703     SimpleArray< iBase_EntitySetHandle > parents;
00704     FBiGeom_getPrnts( geom, parent_child, 1, ARRAY_INOUT( parents ), &err );
00705     CHECK( "Problem getting parents in gentityset_test." );
00706 
00707     if( parents.size() != 1 )
00708     {
00709         std::cerr << "number of parents is not correct in gentityset_test." << std::endl;
00710         return false;
00711     }
00712 
00713     // add parent and child
00714     // sidl::array<void*> parent_child_array = sidl::array<void*>::create1d(1);
00715     // int num_parent_child_array;
00716     // sidl::array<void*> temp_gedge_array = sidl::array<void*>::create1d(1);
00717     // int num_temp_gedge_array;
00718     // parent_child_array.set(0, parent_child);
00719     // temp_gedge_array.set(0, ges_array[TSTTG::EntityType_EDGE]);
00720     FBiGeom_addPrntChld( geom, ges_array[iBase_EDGE], parent_child, &err );
00721     CHECK( "Problem adding parent and child in gentityset_test." );
00722 
00723     // sidl::array<void*> temp_gface_array = sidl::array<void*>::create1d(1);
00724     // int num_temp_gface_array;
00725     // temp_gface_array.set(0, ges_array[TSTTG::EntityType_FACE]);
00726     FBiGeom_addPrntChld( geom, parent_child, ges_array[iBase_FACE], &err );
00727     CHECK( "Problem adding parent and child in gentityset_test." );
00728 
00729     // add child
00730     FBiGeom_addPrntChld( geom, parent_child, ges_array[iBase_REGION], &err );
00731     CHECK( "Problem adding child in gentityset_test." );
00732 
00733     // get the number of parent gentitysets
00734     num_gents = -1;
00735     FBiGeom_getNumPrnt( geom, parent_child, 1, &num_gents, &err );
00736     CHECK( "Problem getting number of parents in gentityset_test." );
00737 
00738     if( num_gents != 2 )
00739     {
00740         std::cerr << "number of parents is not correct in gentityset_test." << std::endl;
00741         return false;
00742     }
00743 
00744     // get the number of child gentitysets
00745     num_gents = -1;
00746     FBiGeom_getNumChld( geom, parent_child, 1, &num_gents, &err );
00747     CHECK( "Problem getting number of children in gentityset_test." );
00748 
00749     if( num_gents != 2 )
00750     {
00751         std::cerr << "number of children is not correct in gentityset_test." << std::endl;
00752         return false;
00753     }
00754 
00755     SimpleArray< iBase_EntitySetHandle > children;
00756     FBiGeom_getChldn( geom, parent_child, 1, ARRAY_INOUT( children ), &err );
00757     CHECK( "Problem getting children in gentityset_test." );
00758 
00759     if( children.size() != 2 )
00760     {
00761         std::cerr << "number of children is not correct in gentityset_test." << std::endl;
00762         return false;
00763     }
00764 
00765     // remove children
00766     FBiGeom_rmvPrntChld( geom, parent_child, ges_array[iBase_FACE], &err );
00767     CHECK( "Problem removing parent child in gentityset_test." );
00768 
00769     // get the number of child gentitysets
00770     FBiGeom_getNumChld( geom, parent_child, 1, &num_gents, &err );
00771     CHECK( "Problem getting number of children in gentityset_test." );
00772 
00773     if( num_gents != 1 )
00774     {
00775         std::cerr << "number of children is not correct in gentityset_test." << std::endl;
00776         return false;
00777     }
00778 
00779     // parent_child and ges_array[TSTTG::EntityType_EDGE] should be related
00780     int result = 0;
00781     FBiGeom_isChildOf( geom, ges_array[iBase_EDGE], parent_child, &result, &err );
00782     CHECK( "Problem checking relation in gentityset_test." );
00783     if( !result )
00784     {
00785         std::cerr << "parent_child and ges_array[TSTTG::EntityType_EDGE] should be related" << std::endl;
00786         return false;
00787     }
00788 
00789     // ges_array[TSTTG::EntityType_FACE] and ges_array[TSTTG::REGION] are not related
00790     result = 2;
00791     FBiGeom_isChildOf( geom, ges_array[iBase_FACE], ges_array[iBase_REGION], &result, &err );
00792     if( result )
00793     {
00794         std::cerr << "ges_array[TSTTG::REGION] and ges_array[TSTTG::EntityType_FACE] should not be "
00795                      "related"
00796                   << std::endl;
00797         return false;
00798     }
00799 
00800     //--------test modify and query functions-----------------------------
00801 
00802     // check the number of gentity sets in whole mesh
00803     SimpleArray< iBase_EntitySetHandle > gentity_sets;
00804     FBiGeom_getEntSets( geom, root_set, 1, ARRAY_INOUT( gentity_sets ), &err );
00805     CHECK( "Problem to get all gentity sets in mesh." );
00806 
00807     if( gentity_sets.size() != all_sets + 8 )
00808     {
00809         std::cerr << "the number of gentity sets in whole mesh should be 8 times of num_iter." << std::endl;
00810         return false;
00811     }
00812 
00813     // get all gentity sets in super set
00814     SimpleArray< iBase_EntitySetHandle > ges_array1;
00815     FBiGeom_getEntSets( geom, super_set, 1, ARRAY_INOUT( ges_array1 ), &err );
00816     CHECK( "Problem to get gentity sets in super set." );
00817 
00818     // get the number of gentity sets in super set
00819     int num_super;
00820     FBiGeom_getNumEntSets( geom, super_set, 1, &num_super, &err );
00821     CHECK( "Problem to get the number of all gentity sets in super set." );
00822 
00823     // the number of gentity sets in super set should be same
00824     if( num_super != ges_array1.size() )
00825     {
00826         std::cerr << "the number of gentity sets in super set should be same." << std::endl;
00827         return false;
00828     }
00829 
00830     // get all entities in super set
00831     SimpleArray< iBase_EntitySetHandle > all_gentities;
00832     FBiGeom_getEntSets( geom, super_set, 1, ARRAY_INOUT( all_gentities ), &err );
00833     CHECK( "Problem to get all gentities in super set." );
00834 
00835     // compare the number of all gentities in super set
00836     // HJK : num_hops is not implemented
00837     // if (num_all_gentities_super != ARRAY_SIZE(all_gentities)) {
00838     // std::cerr << "number of all gentities in super set should be same." << std::endl;
00839     // success = false;
00840     //}
00841 
00842     // test add, remove and get all entitiy sets using super set
00843     // check GetAllGentitysets works recursively and dosen't return
00844     // multi sets
00845     for( int k = 0; k < num_super; k++ )
00846     {
00847         // add gentity sets of super set to each gentity set of super set
00848         // make multiple child super sets
00849         iBase_EntitySetHandle ges_k = ges_array1[k];
00850 
00851         for( int a = 0; a < ges_array1.size(); a++ )
00852         {
00853             FBiGeom_addEntSet( geom, ges_array1[a], ges_k, &err );
00854             CHECK( "Problem to add entity set." );
00855         }
00856 
00857         // add super set to each entity set
00858         //    sidl::array<GentitysetHandle> superset_array
00859         //= sidl::array<GentitysetHandle>::create1d(1);
00860         // superset_array.set(0, super_set);
00861         // int num_superset_array;
00862 
00863         FBiGeom_addEntSet( geom, super_set, ges_k, &err );
00864         CHECK( "Problem to add super set to gentitysets." );
00865 
00866         // add one gentity sets multiple times
00867         // HJK: ??? how to deal this case?
00868         // sidl::array<GentitysetHandle> temp_array1
00869         //= sidl::array<GentitysetHandle>::create1d(1);
00870         // int num_temp_array1;
00871         // temp_array1.set(0, temp_ges1);
00872 
00873         // for (int l = 0; l < 3; l++) {
00874         FBiGeom_addEntSet( geom, temp_ges1, ges_k, &err );
00875         CHECK( "Problem to add temp set to gentitysets." );
00876         //}
00877     }
00878 
00879     return true;
00880 }
00881 
00882 /*!
00883 @test
00884 TSTTG topology adjacencies Test
00885 @li Check topology information
00886 @li Check adjacency
00887 */
00888 // make each topological entity vectors, check their topology
00889 // types, get interior and exterior faces of model
00890 bool topology_adjacencies_test( FBiGeom_Instance geom )
00891 {
00892     int i, err;
00893     iBase_EntitySetHandle root_set;
00894     FBiGeom_getRootSet( geom, &root_set, &err );
00895     CHECK( "ERROR : getRootSet failed!" );
00896 
00897     int top          = iBase_VERTEX;
00898     int num_test_top = iBase_ALL_TYPES;
00899     std::vector< std::vector< iBase_EntityHandle > > gentity_vectors( num_test_top );
00900 
00901     // fill the vectors of each topology entities
00902     // like lines vector, polygon vector, triangle vector,
00903     // quadrilateral, polyhedrron, tet, hex, prism, pyramid,
00904     // septahedron vectors
00905     for( i = top; i < num_test_top; i++ )
00906     {
00907         SimpleArray< iBase_EntityHandle > gentities;
00908         FBiGeom_getEntities( geom, root_set, i, ARRAY_INOUT( gentities ), &err );
00909         CHECK( "Failed to get gentities in adjacencies_test." );
00910 
00911         gentity_vectors[i].resize( gentities.size() );
00912         std::copy( gentities.begin(), gentities.end(), gentity_vectors[i].begin() );
00913     }
00914 
00915     // check number of entities for each topology
00916     for( i = top; i < num_test_top; i++ )
00917     {
00918         int num_tops = 0;
00919         FBiGeom_getNumOfType( geom, root_set, i, &num_tops, &err );
00920         CHECK( "Failed to get number of gentities in adjacencies_test." );
00921 
00922         if( static_cast< int >( gentity_vectors[i].size() ) != num_tops )
00923         {
00924             std::cerr << "Number of gentities doesn't agree with number returned for dimension " << i << std::endl;
00925             return false;
00926         }
00927     }
00928 
00929     // check adjacencies in both directions
00930     std::vector< iBase_EntityHandle >::iterator vit;
00931     for( i = iBase_REGION; i >= iBase_VERTEX; i-- )
00932     {
00933         for( vit = gentity_vectors[i].begin(); vit != gentity_vectors[i].end(); ++vit )
00934         {
00935             iBase_EntityHandle this_gent = *vit;
00936 
00937             // check downward adjacencies
00938             for( int j = iBase_VERTEX; j < i; j++ )
00939             {
00940 
00941                 SimpleArray< iBase_EntityHandle > lower_ents;
00942                 FBiGeom_getEntAdj( geom, this_gent, j, ARRAY_INOUT( lower_ents ), &err );
00943                 CHECK( "Bi-directional adjacencies test failed." );
00944 
00945                 // for each of them, make sure they are adjacent to the upward ones
00946                 int num_lower = lower_ents.size();
00947                 for( int k = 0; k < num_lower; k++ )
00948                 {
00949                     SimpleArray< iBase_EntityHandle > upper_ents;
00950                     FBiGeom_getEntAdj( geom, lower_ents[k], i, ARRAY_INOUT( upper_ents ), &err );
00951                     CHECK( "Bi-directional adjacencies test failed." );
00952                     if( std::find( upper_ents.begin(), upper_ents.end(), this_gent ) == upper_ents.end() )
00953                     {
00954                         std::cerr << "Didn't find lower-upper adjacency which was supposed to be "
00955                                      "there, dims = "
00956                                   << i << ", " << j << std::endl;
00957                         return false;
00958                     }
00959                 }
00960             }
00961         }
00962     }
00963 
00964     return true;
00965 }
00966 
00967 /*!
00968 @test
00969 FBiGeom_MOAB topology adjacencies Test
00970 @li Check topology information
00971 @li Check adjacency
00972 */
00973 // make each topological entity vectors, check their topology
00974 // types, get interior and exterior faces of model
00975 bool geometry_evaluation_test( FBiGeom_Instance geom )
00976 {
00977     int i, err;
00978     iBase_EntitySetHandle root_set;
00979     FBiGeom_getRootSet( geom, &root_set, &err );
00980     CHECK( "ERROR : getRootSet failed!" );
00981 
00982     int top          = iBase_VERTEX;
00983     int num_test_top = iBase_ALL_TYPES;
00984     std::vector< std::vector< iBase_EntityHandle > > gentity_vectors( num_test_top );
00985 
00986     // fill the vectors of each topology entities
00987     // like lines vector, polygon vector, triangle vector,
00988     // quadrilateral, polyhedrron, tet, hex, prism, pyramid,
00989     // septahedron vectors
00990     for( i = top; i < num_test_top; i++ )
00991     {
00992         SimpleArray< iBase_EntityHandle > gentities;
00993         FBiGeom_getEntities( geom, root_set, i, ARRAY_INOUT( gentities ), &err );
00994         CHECK( "Failed to get gentities in adjacencies_test." );
00995 
00996         gentity_vectors[i].resize( gentities.size() );
00997         std::copy( gentities.begin(), gentities.end(), gentity_vectors[i].begin() );
00998     }
00999 
01000     // check adjacencies in both directions
01001     double min[3], max[3], on[3];
01002     double near[3] = { .0, .0, .0 };
01003     std::vector< iBase_EntityHandle >::iterator vit;
01004     for( i = iBase_REGION; i >= iBase_VERTEX; i-- )
01005     {
01006         if( i != iBase_EDGE )
01007         {
01008             for( vit = gentity_vectors[i].begin(); vit != gentity_vectors[i].end(); ++vit )
01009             {
01010                 iBase_EntityHandle this_gent = *vit;
01011                 FBiGeom_getEntBoundBox( geom, this_gent, &min[0], &min[1], &min[2], &max[0], &max[1], &max[2], &err );
01012                 CHECK( "Failed to get bounding box of entity." );
01013 
01014                 FBiGeom_getEntClosestPt( geom, this_gent, near[0], near[1], near[2], &on[0], &on[1], &on[2], &err );
01015                 CHECK( "Failed to get closest point on entity." );
01016             }
01017         }
01018     }
01019 
01020     return true;
01021 }
01022 
01023 /*!
01024 @test
01025 TSTTG construct Test
01026 @li Check construction of geometry
01027 */
01028 bool construct_test( FBiGeom_Instance geom )
01029 {
01030     int err;
01031     iBase_EntityHandle new_body = 0;
01032 
01033     // construct a cylinder, sweep it about an axis, and delete the result
01034     iBase_EntityHandle cyl = 0;
01035     FBiGeom_createCylinder( geom, 1.0, 1.0, 0.0, &cyl, &err );
01036     // Is the minor radius really supposed to be zero??? - JK
01037     CHECK( "Creating cylinder failed." );
01038 
01039     // move it onto the y axis
01040     FBiGeom_moveEnt( geom, cyl, 0.0, 1.0, -0.5, &err );
01041     CHECK( "Problems moving surface." );
01042 
01043     // get the surface with max z
01044     iBase_EntityHandle max_surf = 0;
01045     SimpleArray< iBase_EntityHandle > surfs;
01046     FBiGeom_getEntAdj( geom, cyl, iBase_FACE, ARRAY_INOUT( surfs ), &err );
01047     CHECK( "Problems getting max surf for rotation." );
01048 
01049     SimpleArray< double > max_corn, min_corn;
01050     FBiGeom_getArrBoundBox( geom, ARRAY_IN( surfs ), iBase_INTERLEAVED, ARRAY_INOUT( min_corn ),
01051                             ARRAY_INOUT( max_corn ), &err );
01052     CHECK( "Problems getting max surf for rotation." );
01053     double dtol = 1.0e-6;
01054     for( int i = 0; i < surfs.size(); ++i )
01055     {
01056         if( ( max_corn[3 * i + 2] ) <= dtol && ( max_corn[3 * i + 2] ) >= -dtol && ( min_corn[3 * i + 2] ) <= dtol &&
01057             ( min_corn[3 * i + 2] ) >= -dtol )
01058         {
01059             max_surf = surfs[i];
01060             break;
01061         }
01062     }
01063 
01064     if( 0 == max_surf )
01065     {
01066         std::cerr << "Couldn't find max surf for rotation." << std::endl;
01067         return false;
01068     }
01069 
01070     // sweep it around the x axis
01071     FBiGeom_moveEnt( geom, cyl, 0.0, 1.0, 0.0, &err );
01072     CHECK( "Problems moving surface." );
01073 
01074     FBiGeom_sweepEntAboutAxis( geom, max_surf, 360.0, 1.0, 0.0, 0.0, &new_body, &err );
01075     CHECK( "Problems sweeping surface about axis." );
01076 
01077     // now delete
01078     FBiGeom_deleteEnt( geom, new_body, &err );
01079     CHECK( "Problems deleting cylinder or swept surface body." );
01080 
01081     // if we got here, we were successful
01082     return true;
01083 }
01084 
01085 static bool compare_box( const double* expected_min,
01086                          const double* expected_max,
01087                          const double* actual_min,
01088                          const double* actual_max )
01089 {
01090     bool same   = true;
01091     double dtol = 1.0e-6;
01092 
01093     for( int i = 0; i < 3; ++i )
01094     {
01095         if( expected_min[i] < actual_min[i] - dtol || expected_min[i] * 10 > actual_min[i] ||
01096             expected_max[i] > actual_max[i] + dtol || expected_max[i] * 10 < actual_max[i] )
01097             same = false;
01098     }
01099     return same;
01100 }
01101 
01102 bool primitives_test( FBiGeom_Instance geom )
01103 {
01104     int err;
01105     SimpleArray< iBase_EntityHandle > prims( 3 );
01106     iBase_EntityHandle prim;
01107 
01108     FBiGeom_createBrick( geom, 1.0, 2.0, 3.0, &prim, &err );
01109     CHECK( "createBrick failed." );
01110     prims[0] = prim;
01111 
01112     FBiGeom_createCylinder( geom, 1.0, 4.0, 2.0, &prim, &err );
01113     CHECK( "createCylinder failed." );
01114     prims[1] = prim;
01115 
01116     FBiGeom_createTorus( geom, 2.0, 1.0, &prim, &err );
01117     CHECK( "createTorus failed." );
01118     prims[2] = prim;
01119 
01120     // verify the bounding boxes for Acis based entities
01121     SimpleArray< double > max_corn, min_corn;
01122     FBiGeom_getArrBoundBox( geom, ARRAY_IN( prims ), iBase_INTERLEAVED, ARRAY_INOUT( min_corn ),
01123                             ARRAY_INOUT( max_corn ), &err );
01124 
01125     double preset_min_corn[] =
01126         // min brick corner xyz
01127         { -0.5, -1.0, -1.5,
01128           // min cyl corner xyz
01129           -4.0, -2.0, -0.5,
01130           // min torus corner xyz
01131           -3.0, -3.0, -1.0 };
01132 
01133     double preset_max_corn[] =
01134         // max brick corner xyz
01135         { 0.5, 1.0, 1.5,
01136           // max cyl corner xyz
01137           4.0, 2.0, 0.5,
01138           // max torus corner xyz
01139           3.0, 3.0, 1.0 };
01140 
01141     if( !compare_box( preset_min_corn, preset_max_corn, &min_corn[0], &max_corn[0] ) )
01142     {
01143         std::cerr << "Box check failed for brick" << std::endl;
01144         return false;
01145     }
01146 
01147     if( !compare_box( preset_min_corn + 3, preset_max_corn + 3, &min_corn[3], &max_corn[3] ) )
01148     {
01149         std::cerr << "Box check failed for cylinder" << std::endl;
01150         return false;
01151     }
01152 
01153     if( !compare_box( preset_min_corn + 6, preset_max_corn + 6, &min_corn[6], &max_corn[6] ) )
01154     {
01155         std::cerr << "Box check failed for torus" << std::endl;
01156         return false;
01157     }
01158     // must have worked; delete the entities then return
01159     for( int i = 0; i < 3; ++i )
01160     {
01161         FBiGeom_deleteEnt( geom, prims[i], &err );
01162         CHECK( "Problems deleting primitive after boolean check." );
01163     }
01164 
01165     return true;
01166 }
01167 
01168 bool transforms_test( FBiGeom_Instance geom )
01169 {
01170     int err;
01171 
01172     // construct a brick
01173     iBase_EntityHandle brick = 0;
01174     FBiGeom_createBrick( geom, 1.0, 2.0, 3.0, &brick, &err );
01175     CHECK( "Problems creating brick for transforms test." );
01176 
01177     // move it, then test bounding box
01178     FBiGeom_moveEnt( geom, brick, 0.5, 1.0, 1.5, &err );
01179     CHECK( "Problems moving brick for transforms test." );
01180 
01181     double bb_min[3], bb_max[3];
01182     FBiGeom_getEntBoundBox( geom, brick, bb_min, bb_min + 1, bb_min + 2, bb_max, bb_max + 1, bb_max + 2, &err );
01183     CHECK( "Problems getting bounding box after move." );
01184 
01185     double dtol = 1.0e-6;
01186     if( ( bb_min[0] ) >= dtol || ( bb_min[0] ) <= -dtol || ( bb_min[1] ) >= dtol || ( bb_min[1] ) <= -dtol ||
01187         ( bb_min[2] ) >= dtol || ( bb_min[2] ) <= -dtol || ( bb_max[0] - 1 ) >= dtol || 1 - bb_max[0] >= dtol ||
01188         ( bb_max[1] - 2 ) >= dtol || 2 - bb_max[1] >= dtol || ( bb_max[2] - 3 ) >= dtol || 3 - bb_max[2] >= dtol )
01189     {
01190         std::cerr << "Wrong bounding box after move." << std::endl;
01191         return false;
01192     }
01193 
01194     // now rotate it about +x, then test bounding box
01195     FBiGeom_rotateEnt( geom, brick, 90, 1.0, 0.0, 0.0, &err );
01196     CHECK( "Problems rotating brick for transforms test." );
01197 
01198     FBiGeom_getEntBoundBox( geom, brick, bb_min, bb_min + 1, bb_min + 2, bb_max, bb_max + 1, bb_max + 2, &err );
01199     CHECK( "Problems getting bounding box after rotate." );
01200 
01201     if( ( bb_min[0] ) >= dtol || -bb_min[0] >= dtol || ( bb_min[1] + 3 ) >= dtol || -( bb_min[1] + 3 ) >= dtol ||
01202         ( bb_min[2] ) >= dtol || -( bb_min[2] ) >= dtol || ( bb_max[0] - 1 ) >= dtol || 1 - bb_max[0] >= dtol ||
01203         ( bb_max[1] ) >= dtol || -( bb_max[1] ) >= dtol || ( bb_max[2] - 2 ) >= dtol || 2 - bb_max[2] >= dtol )
01204     {
01205         std::cerr << "Wrong bounding box after rotate." << std::endl;
01206         return false;
01207     }
01208 
01209     // now reflect through y plane; should recover original bb
01210     FBiGeom_reflectEnt( geom, brick, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, &err );
01211     CHECK( "Problems reflecting brick for transforms test." );
01212 
01213     FBiGeom_getEntBoundBox( geom, brick, bb_min, bb_min + 1, bb_min + 2, bb_max, bb_max + 1, bb_max + 2, &err );
01214     CHECK( "Problems getting bounding box after reflect." );
01215 
01216     if( ( bb_min[0] ) >= dtol || -( bb_min[0] ) >= dtol || ( bb_min[1] ) >= dtol || ( bb_min[2] ) >= dtol ||
01217         -( bb_min[1] ) >= dtol || -( bb_min[2] ) >= dtol || ( bb_max[0] - 1 ) >= dtol || 1 - bb_max[0] >= dtol ||
01218         ( bb_max[1] - 3 ) >= dtol || 3 - bb_max[1] >= dtol || ( bb_max[2] - 2 ) >= dtol || 2 - bb_max[2] >= dtol )
01219     {
01220         std::cerr << "Wrong bounding box after reflect." << std::endl;
01221         return false;
01222     }
01223 
01224     // must have worked; delete the entities then return
01225     FBiGeom_deleteEnt( geom, brick, &err );
01226     CHECK( "Problems deleting brick after transforms check." );
01227     return true;
01228 }
01229 
01230 bool booleans_test( FBiGeom_Instance geom )
01231 {
01232     int err;
01233 
01234     // construct a brick size 1, and a cylinder rad 0.25 height 2
01235     iBase_EntityHandle brick = 0, cyl = 0;
01236     FBiGeom_createBrick( geom, 1.0, 0.0, 0.0, &brick, &err );
01237     CHECK( "Problems creating brick for booleans test." );
01238     FBiGeom_createCylinder( geom, 1.0, 0.25, 0.0, &cyl, &err );
01239     CHECK( "Problems creating cylinder for booleans test." );
01240 
01241     // subtract the cylinder from the brick
01242     iBase_EntityHandle subtract_result = 0;
01243     FBiGeom_subtractEnts( geom, brick, cyl, &subtract_result, &err );
01244     CHECK( "Problems subtracting for booleans subtract test." );
01245 
01246     // section the brick
01247     iBase_EntityHandle section_result = 0;
01248     FBiGeom_sectionEnt( geom, subtract_result, 1.0, 0.0, 0.0, 0.25, true, &section_result, &err );
01249     CHECK( "Problems sectioning for booleans section test." );
01250 
01251     // unite the section result with a new cylinder
01252     FBiGeom_createCylinder( geom, 1.0, 0.25, 0.0, &cyl, &err );
01253     CHECK( "Problems creating cylinder for unite test." );
01254     iBase_EntityHandle unite_results;
01255     iBase_EntityHandle unite_input[] = { section_result, cyl };
01256     FBiGeom_uniteEnts( geom, unite_input, 2, &unite_results, &err );
01257     CHECK( "Problems uniting for booleans unite test." );
01258 
01259     FBiGeom_deleteEnt( geom, unite_results, &err );
01260     CHECK( "Problems deleting for booleans unite test." );
01261     return true;
01262 }
01263 
01264 static int get_entities( FBiGeom_Instance geom,
01265                          int entity_type,
01266                          std::vector< iBase_EntityHandle >& entities_out,
01267                          iBase_TagHandle id_tag      = 0,
01268                          std::vector< int >* ids_out = 0 )
01269 {
01270     int err, num;
01271     iBase_EntitySetHandle root;
01272     FBiGeom_getRootSet( geom, &root, &err );
01273     if( iBase_SUCCESS != err ) return err;
01274     FBiGeom_getNumOfType( geom, root, entity_type, &num, &err );
01275     if( iBase_SUCCESS != err ) return err;
01276 
01277     entities_out.resize( num );
01278     int junk1                    = entities_out.size(), junk2;
01279     iBase_EntityHandle* junk_ptr = &entities_out[0];
01280     ;
01281     FBiGeom_getEntities( geom, root, entity_type, &junk_ptr, &junk1, &junk2, &err );
01282     if( iBase_SUCCESS != err ) return err;
01283     assert( num == junk1 && num == junk2 );
01284 
01285     if( !ids_out ) return iBase_SUCCESS;
01286 
01287     ids_out->resize( num );
01288     int* int_ptr = &( *ids_out )[0];
01289     FBiGeom_getIntArrData( geom, &entities_out[0], num, id_tag, &int_ptr, &junk1, &junk2, &err );
01290     if( iBase_SUCCESS != err ) return err;
01291     assert( num == junk1 && num == junk2 );
01292 
01293     return iBase_SUCCESS;
01294 }
01295 
01296 static int check_firmness( FBiGeom_Instance geom,
01297                            const std::vector< iBase_EntityHandle >& entities,
01298                            const std::vector< int >& ids,
01299                            iBase_TagHandle firmness_tag,
01300                            const char* expected_value,
01301                            const char* ent_type_str )
01302 {
01303     const int firmness_size = 4;
01304     std::vector< char > firmness( firmness_size * entities.size() );
01305 
01306     char* byte_ptr = &firmness[0];
01307     int err, junk1 = firmness.size(), junk2 = entities.size() * firmness_size;
01308     FBiGeom_getArrData( geom, &entities[0], entities.size(), firmness_tag, (void**)&byte_ptr, &junk1, &junk2, &err );
01309     if( iBase_SUCCESS != err ) return err;
01310 
01311     bool all_correct = true;
01312     for( unsigned i = 0; i < entities.size(); ++i )
01313         if( std::string( &firmness[firmness_size * i], firmness_size ) != expected_value ) all_correct = false;
01314     if( !all_correct )
01315     {
01316         std::cout << "ERROR: Expected \"" << expected_value << "\" firmness "
01317                   << "for all " << ent_type_str << "." << std::endl;
01318         std::cout << "ID  Actual  " << std::endl;
01319         for( unsigned i = 0; i < entities.size(); ++i )
01320             std::cout << std::setw( 2 ) << ids[i] << "  " << std::string( &firmness[firmness_size * i], firmness_size )
01321                       << std::endl;
01322         return iBase_FAILURE;
01323     }
01324 
01325     return iBase_SUCCESS;
01326 }
01327 
01328 static int count_num_with_tag( FBiGeom_Instance geom,
01329                                const std::vector< iBase_EntityHandle >& ents,
01330                                iBase_TagHandle tag )
01331 {
01332     int err, bytes;
01333     FBiGeom_getTagSizeBytes( geom, tag, &bytes, &err );
01334     if( iBase_SUCCESS != err ) return -1;
01335     std::vector< char > data( bytes );
01336 
01337     int success_count = 0;
01338     for( size_t i = 0; i < ents.size(); ++i )
01339     {
01340         char* ptr = &data[0];
01341         int junk1 = bytes, junk2;
01342         FBiGeom_getData( geom, ents[i], tag, (void**)&ptr, &junk1, &junk2, &err );
01343         if( iBase_TAG_NOT_FOUND == err ) continue;
01344         if( iBase_SUCCESS != err ) return -1;
01345         ++success_count;
01346     }
01347 
01348     return success_count;
01349 }
01350 
01351 bool mesh_size_test( FBiGeom_Instance geom )
01352 {
01353     const char* filename = STRINGIFY( SRCDIR ) "/size.sat";
01354     int err, junk1, junk2;
01355     bool result = true;
01356 
01357     FBiGeom_deleteAll( geom, &err );
01358     CHECK( "" );
01359     FBiGeom_load( geom, filename, 0, &err, strlen( filename ), 0 );
01360     CHECK( "Failed to load input file: 'size.sat'" );
01361 
01362     // get tag handles
01363     iBase_TagHandle interval, size, firmness, id;
01364     FBiGeom_getTagHandle( geom, "MESH_INTERVAL", &interval, &err, strlen( "MESH_INTERVAL" ) );
01365     CHECK( "FBiGeom_getTagHandle(\"MESH_INTERVAL\")" );
01366     FBiGeom_getTagHandle( geom, "MESH_SIZE", &size, &err, strlen( "MESH_SIZE" ) );
01367     CHECK( "FBiGeom_getTagHandle(\"MESH_SIZE\")" );
01368     FBiGeom_getTagHandle( geom, "SIZE_FIRMNESS", &firmness, &err, strlen( "SIZE_FIRMNESS" ) );
01369     CHECK( "FBiGeom_getTagHandle(\"SIZE_FIRMNESS\")" );
01370     FBiGeom_getTagHandle( geom, "GLOBAL_ID", &id, &err, strlen( "GLOBAL_ID" ) );
01371     CHECK( "FBiGeom_getTagHandle(\"GLOBAL_ID\")" );
01372 
01373     // get entity lists
01374     std::vector< iBase_EntityHandle > verts, curves, surfs, vols;
01375     std::vector< int > vert_ids, curve_ids, surf_ids, vol_ids;
01376     err = get_entities( geom, iBase_VERTEX, verts, id, &vert_ids );
01377     CHECK( "" );
01378     err = get_entities( geom, iBase_EDGE, curves, id, &curve_ids );
01379     CHECK( "" );
01380     err = get_entities( geom, iBase_FACE, surfs, id, &surf_ids );
01381     CHECK( "" );
01382     err = get_entities( geom, iBase_REGION, vols, id, &vol_ids );
01383     CHECK( "" );
01384 
01385     // expect interval count to be the same as ID for every curve
01386     std::vector< int > intervals( curves.size() );
01387     int* int_ptr = &intervals[0];
01388     junk1 = junk2 = curves.size();
01389     FBiGeom_getIntArrData( geom, &curves[0], curves.size(), interval, &int_ptr, &junk1, &junk2, &err );
01390     CHECK( "Failed to get intervals for curves" );
01391     if( intervals != curve_ids )
01392     {
01393         std::cout << "ERROR: Incorrect curve intervals for one or more curves." << std::endl;
01394         std::cout << "ID  Expected  Actual" << std::endl;
01395         for( unsigned i = 0; i < curves.size(); ++i )
01396             std::cout << std::setw( 2 ) << curve_ids[i] << "  " << std::setw( 8 ) << curve_ids[i] << "  "
01397                       << std::setw( 6 ) << intervals[i] << std::endl;
01398         result = false;
01399     }
01400 
01401     // expect size to be the same as ID for every surface
01402     std::vector< double > sizes( surfs.size() );
01403     double* dbl_ptr = &sizes[0];
01404     junk1 = junk2 = surfs.size();
01405     FBiGeom_getDblArrData( geom, &surfs[0], surfs.size(), size, &dbl_ptr, &junk1, &junk2, &err );
01406     CHECK( "Failed to get sizes for surfaces" );
01407     bool all_correct = true;
01408     for( unsigned i = 0; i < surfs.size(); ++i )
01409         if( fabs( sizes[i] - (double)surf_ids[i] ) > 1e-8 ) all_correct = false;
01410     if( !all_correct )
01411     {
01412         std::cout << "ERROR: Incorrect mesh size for one or more surfaces." << std::endl;
01413         std::cout << "ID  Expected  Actual  " << std::endl;
01414         for( unsigned i = 0; i < surfs.size(); ++i )
01415             std::cout << std::setw( 2 ) << surf_ids[i] << "  " << std::setw( 8 ) << (double)surf_ids[i] << "  "
01416                       << std::setw( 8 ) << sizes[i] << std::endl;
01417         result = false;
01418     }
01419 
01420     err = result ? iBase_SUCCESS : iBase_FAILURE;
01421     CHECK( "Invalid size or interval data" );
01422 
01423     // expect "HARD" firmness on all curves
01424     err = check_firmness( geom, curves, curve_ids, firmness, "HARD", "curves" );
01425     CHECK( "Invalid curve firmness" );
01426     // expect "SOFT" firmness on all surfaces
01427     err = check_firmness( geom, surfs, surf_ids, firmness, "SOFT", "surfaces" );
01428     CHECK( "Invalid surface firmness" );
01429 
01430     // expect no firmnes on other entities
01431     err = count_num_with_tag( geom, verts, firmness ) ? iBase_FAILURE : iBase_SUCCESS;
01432     CHECK( "Got firmness for vertex." );
01433     err = count_num_with_tag( geom, vols, firmness ) ? iBase_FAILURE : iBase_SUCCESS;
01434     CHECK( "Got firmness for volume." );
01435 
01436     // expect no interval tag on any entities except curves
01437     err = count_num_with_tag( geom, verts, interval ) ? iBase_FAILURE : iBase_SUCCESS;
01438     CHECK( "Got interval count for vertex." );
01439     err = count_num_with_tag( geom, vols, interval ) ? iBase_FAILURE : iBase_SUCCESS;
01440     CHECK( "Got interval count for volume." );
01441 
01442     // expect no size tag on any entities except surfaces
01443     // curves should have size of one of their parent surfaces
01444     err = count_num_with_tag( geom, verts, size ) ? iBase_FAILURE : iBase_SUCCESS;
01445     CHECK( "Got mesh size for vertex." );
01446     err = count_num_with_tag( geom, vols, size ) ? iBase_FAILURE : iBase_SUCCESS;
01447     CHECK( "Got mesh size for volume." );
01448 
01449     return true;
01450 }
01451 
01452 bool shutdown_test( FBiGeom_Instance geom, std::string& engine_opt )
01453 {
01454     int err;
01455 
01456     // test shutdown & startup of interface
01457     FBiGeom_dtor( geom, &err );
01458     CHECK( "Interface destruction didn't work properly." );
01459 
01460     FBiGeom_newGeom( engine_opt.c_str(), &geom, &err, engine_opt.length() );
01461     CHECK( "Interface re-construction didn't work properly." );
01462 
01463     FBiGeom_dtor( geom, &err );
01464     CHECK( "2nd Interface destruction didn't work properly." );
01465 
01466     return true;
01467 }
01468 
01469 bool save_entset_test( FBiGeom_Instance geom )
01470 {
01471     int err;
01472 
01473 #ifdef FORCE_OCC
01474     std::string filename = "testout.brep";
01475 #elif defined( HAVE_ACIS )
01476     std::string filename = "testout.sat";
01477 #elif defined( HAVE_OCC )
01478     std::string filename = "testout.brep";
01479 #else
01480     std::string filename = "testout.sat";
01481 #endif
01482 
01483     // initialize number of ents and sets to compare with later
01484     int num_ents_bef, num_sets_bef;
01485     iBase_EntitySetHandle root;
01486     FBiGeom_getRootSet( geom, &root, &err );
01487     CHECK( "Failed to get root set." );
01488     FBiGeom_getNumEntSets( geom, root, 1, &num_sets_bef, &err );
01489     CHECK( "Failed to get number of ent sets." );
01490     FBiGeom_getNumOfType( geom, root, iBase_REGION, &num_ents_bef, &err );
01491     CHECK( "Failed to get number of entities." );
01492 
01493     // create set, and entity to add to set
01494     iBase_EntityHandle cyl;
01495     FBiGeom_createCylinder( geom, 1.0, 0.25, 0.0, &cyl, &err );
01496     CHECK( "Problems creating cylinder for save entset test." );
01497     iBase_EntitySetHandle seth;
01498     FBiGeom_createEntSet( geom, true, &seth, &err );
01499     CHECK( "Problems creating entity set for save entset test." );
01500 
01501     // add the entity
01502     FBiGeom_addEntToSet( geom, cyl, seth, &err );
01503     CHECK( "Problems adding entity to set for save entset test." );
01504 
01505     // save/restore the model, and see if the entity is there
01506     FBiGeom_save( geom, filename.c_str(), NULL, &err, filename.length(), 0 );
01507     CHECK( "Problems saving file for save entset test." );
01508 
01509     FBiGeom_destroyEntSet( geom, seth, &err );
01510     CHECK( "Failed to destroy entity set." );
01511     FBiGeom_deleteEnt( geom, cyl, &err );
01512     CHECK( "Failed to destroy entity." );
01513 
01514     // read the file back in
01515     FBiGeom_load( geom, filename.c_str(), NULL, &err, filename.length(), 0 );
01516     CHECK( "Problems reading file for save entset test." );
01517 
01518     // check number of sets and entities
01519     int num_ents_aft, num_sets_aft;
01520     FBiGeom_getNumEntSets( geom, root, 1, &num_sets_aft, &err );
01521     CHECK( "Failed to get number of ent sets." );
01522     FBiGeom_getNumOfType( geom, root, iBase_REGION, &num_ents_aft, &err );
01523     CHECK( "Failed to get number of entities." );
01524     bool success = true;
01525     if( num_ents_aft != 2 * num_ents_bef + 1 )
01526     {
01527         print_error( "Failed to get the right number of entities.", iBase_FAILURE, geom, __FILE__, __LINE__ );
01528         success = false;
01529     }
01530     else if( num_sets_aft != 2 * num_sets_bef + 1 )
01531     {
01532         print_error( "Failed to get the right number of entity sets.", iBase_FAILURE, geom, __FILE__, __LINE__ );
01533         success = false;
01534     }
01535 
01536     // otherwise, we succeeded
01537     return success;
01538 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines