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