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