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