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