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