![]() |
Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
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
00016 #include
00017 #include
00018 #include
00019 #include
00020 #include
00021 #include
00022 #include
00023 #include
00024 #include
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 << "";
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 parent_child_array = sidl::array::create1d(1);
00737 // int num_parent_child_array;
00738 // sidl::array temp_gedge_array = sidl::array::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 temp_gface_array = sidl::array::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 superset_array
00881 //= sidl::array::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 temp_array1
00891 //= sidl::array::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, §ion_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 }