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