testgeom.cc 50.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13
/**
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 */
/**
 * \file testgeom.cc
 *
 * \brief testgeom, a unit test for the ITAPS geometry interface
 *
 */
14
#include "FBiGeom.h"
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
#include <iostream>
#include <set>
#include <algorithm>
#include <vector>
#include <iterator>
#include <algorithm>
#include <iomanip>
#include <assert.h>
#include <string.h>
#include <math.h>
#define CHECK( STR ) if (err != iBase_SUCCESS) return print_error( STR, err, geom, __FILE__, __LINE__ )

#define STRINGIFY(S) XSTRINGIFY(S)
#define XSTRINGIFY(S) #S

static bool print_error( const char* desc, 
                         int err,
32
                         FBiGeom_Instance geom,
33 34 35 36
                         const char* file,
                         int line )
{
  char buffer[1024];
37
  FBiGeom_getDescription( geom, buffer, sizeof(buffer) );
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
  buffer[sizeof(buffer)-1] = '\0';
  
  std::cerr << "ERROR: " << desc << std::endl
            << "  Error code: " << err << std::endl
            << "  Error desc: " << buffer << std::endl
            << "  At        : " << file << ':' << line << std::endl
            ;
  
  return false; // must always return false or CHECK macro will break
}

typedef iBase_TagHandle TagHandle;
typedef iBase_EntityHandle GentityHandle;
typedef iBase_EntitySetHandle GentitysetHandle;

/* Frees allocated arrays for us */
template <typename T> class SimpleArray
{
  private:
    T* arr;
    int arrSize;
    int arrAllocated;
     
  public:
    SimpleArray() : arr(0) , arrSize(0), arrAllocated(0) {}
    SimpleArray( unsigned s ) :arrSize(s), arrAllocated(s) {
      arr = (T*)malloc(s*sizeof(T));
      for (unsigned i = 0; i < s; ++i)
        new (arr+i) T();
    }
    
    ~SimpleArray() {
      for (int i = 0; i < size(); ++i)
        arr[i].~T();
      free(arr);
    }

    T**  ptr()            { return &arr; }
    int& size()           { return arrSize; }
    int  size()     const { return arrSize; }
    int& capacity()       { return arrAllocated; }
    int  capacity() const { return arrAllocated; }
    
    typedef T* iterator;
    typedef const T* const_iterator;
    iterator       begin()       { return arr; }
    const_iterator begin() const { return arr; }
    iterator         end()       { return arr + arrSize; }
    const_iterator   end() const { return arr + arrSize; }
    
    
    T& operator[]( unsigned idx )       { return arr[idx]; }
    T  operator[]( unsigned idx ) const { return arr[idx]; }
};

#define ARRAY_INOUT( A ) A.ptr(), &A.capacity(), &A.size()
#define ARRAY_IN( A ) &A[0], A.size()

96
bool gLoad_test(const std::string &filename, FBiGeom_Instance);
97 98 99 100 101 102 103 104 105 106 107 108 109 110

bool tags_test(FBiGeom_Instance geom);
bool tag_get_set_test(FBiGeom_Instance geom);
bool tag_info_test(FBiGeom_Instance geom);
bool gentityset_test(FBiGeom_Instance geom, bool /*multiset*/, bool /*ordered*/);
bool topology_adjacencies_test(FBiGeom_Instance geom);
bool geometry_evaluation_test(FBiGeom_Instance geom);
bool construct_test(FBiGeom_Instance geom);
bool primitives_test(FBiGeom_Instance geom);
bool transforms_test(FBiGeom_Instance geom);
bool booleans_test(FBiGeom_Instance geom);
bool shutdown_test(FBiGeom_Instance geom, std::string &engine_opt);
bool save_entset_test(FBiGeom_Instance geom);
bool mesh_size_test(FBiGeom_Instance geom);
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128

void handle_error_code(const bool result,
                       int &number_failed,
                       int &/*number_not_implemented*/,
                       int &number_successful)
{
  if (result) {
    std::cout << "Success";
    number_successful++;
  }
  else {
    std::cout << "Failure";    
    number_failed++;
  }
}

int main( int argc, char *argv[] )
{
129
    std::string filename = STRINGIFY(MESHDIR) "/shell.h5m";
130
    std::string engine_opt;
Iulian Grindeanu's avatar
Iulian Grindeanu committed
131

132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
  if (argc == 1) {
    std::cout << "Using default input file: " << filename << std::endl;
  }
  else if (argc == 2) {
    filename = argv[1];
  }
  else {
    std::cerr << "Usage: " << argv[0] << " [geom_filename]" << std::endl;
    return 1;
  }

  bool result;
  int number_tests = 0;
  int number_tests_successful = 0;
  int number_tests_not_implemented = 0;
  int number_tests_failed = 0;

    // initialize the Mesh
  int err;
151 152
  FBiGeom_Instance geom;
  FBiGeom_newGeom( engine_opt.c_str(), &geom, &err, engine_opt.length() );
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282

    // Print out Header information
  std::cout << "\n\nITAPS GEOMETRY INTERFACE TEST PROGRAM:\n\n";
    // gLoad test
  std::cout << "   gLoad: ";
  result = gLoad_test(filename, geom);
  handle_error_code(result, number_tests_failed,
                    number_tests_not_implemented,
                    number_tests_successful);
  number_tests++;
  std::cout << "\n";
  
    // tags test
  std::cout << "   tags: ";
  result = tags_test(geom);
  handle_error_code(result, number_tests_failed,
                    number_tests_not_implemented,
                    number_tests_successful);
  number_tests++;
  std::cout << "\n";
  /*
    // gentitysets test
  std::cout << "   gentity sets: ";
  result = gentityset_test(geom, false, false);
  handle_error_code(result, number_tests_failed,
                    number_tests_not_implemented,
                    number_tests_successful);
  number_tests++;
  std::cout << "\n";
  */
    // topology adjacencies test
  std::cout << "   topology adjacencies: ";
  result = topology_adjacencies_test(geom);
  handle_error_code(result, number_tests_failed,
                    number_tests_not_implemented,
                    number_tests_successful);
  number_tests++;
  std::cout << "\n";

    // geometry evaluation test
  std::cout << "   geometry evaluation: ";
  result = geometry_evaluation_test(geom);
  handle_error_code(result, number_tests_failed,
                    number_tests_not_implemented,
                    number_tests_successful);
  number_tests++;
  std::cout << "\n";
  /*
    // construct test
  std::cout << "   construct: ";
  result = construct_test(geom);
  handle_error_code(result, number_tests_failed,
                    number_tests_not_implemented,
                    number_tests_successful);
  number_tests++;
  std::cout << "\n";
  
    // primitives test
  std::cout << "   primitives: ";
  result = primitives_test(geom);
  handle_error_code(result, number_tests_failed,
                    number_tests_not_implemented,
                    number_tests_successful);
  number_tests++;
  std::cout << "\n";

    // transforms test
  std::cout << "   transforms: ";
  result = transforms_test(geom);
  handle_error_code(result, number_tests_failed,
                    number_tests_not_implemented,
                    number_tests_successful);
  number_tests++;
  std::cout << "\n";

    // booleans test
  std::cout << "   booleans: ";
  result = booleans_test(geom);
  handle_error_code(result, number_tests_failed,
                    number_tests_not_implemented,
                    number_tests_successful);
  number_tests++;
  std::cout << "\n";
  
#if defined(HAVE_ACIS) && !defined(FORCE_OCC)
  std::cout << "   mesh size: ";
  result = mesh_size_test(geom);
  handle_error_code(result, number_tests_failed,
                    number_tests_not_implemented,
                    number_tests_successful);
  number_tests++;
  std::cout << "\n";

    // save entset test
  std::cout << "   save entset: ";
  result = save_entset_test(geom);
  handle_error_code(result, number_tests_failed,
                    number_tests_not_implemented,
                    number_tests_successful);
  number_tests++;
  std::cout << "\n";
#endif  
  */  
    // shutdown test
  std::cout << "   shutdown: ";
  result = shutdown_test(geom, engine_opt);
  handle_error_code(result, number_tests_failed,
                    number_tests_not_implemented,
                    number_tests_successful);
  number_tests++;
  std::cout << "\n";
  

    // summary

  std::cout << "\nTSTT TEST SUMMARY: \n"
            << "   Number Tests:           " << number_tests << "\n"
            << "   Number Successful:      " << number_tests_successful << "\n"
            << "   Number Not Implemented: " << number_tests_not_implemented << "\n"
            << "   Number Failed:          " << number_tests_failed 
            << "\n\n" << std::endl;
  
  return number_tests_failed;
}

/*!
  @test 
  Load Mesh
  @li Load a mesh file
*/
283
bool gLoad_test(const std::string &filename, FBiGeom_Instance geom)
284 285
{
  int err;
286
  FBiGeom_load( geom, &filename[0], 0, &err, filename.length(), 0 );
287 288 289
  CHECK( "ERROR : can not load a geometry" );
  
  iBase_EntitySetHandle root_set;
290
  FBiGeom_getRootSet( geom, &root_set, &err );
291 292 293 294 295 296 297
  CHECK( "ERROR : getRootSet failed!" );
  
    // print out the number of entities
  std::cout << "Model contents: " << std::endl;
  const char *gtype[] = {"vertices: ", "edges: ", "faces: ", "regions: "};
  for (int i = 0; i <= 3; ++i) {
    int count;
298
    FBiGeom_getNumOfType( geom, root_set, i, &count, &err );
299 300 301 302 303 304 305 306 307 308 309 310
    CHECK( "Error: problem getting entities after gLoad." );
    std::cout << gtype[i] << count << std::endl;
  }

  return true;
}

/*!
  @test 
  Test tag creating, reading, writing, deleting
  @li Load a mesh file
*/
311
bool tags_test(FBiGeom_Instance geom)
312
{
313
  bool success = tag_info_test(geom);
314 315 316 317 318 319 320 321
  if (!success) return success;
  
  success = tag_get_set_test(geom);
  if (!success) return success;

  return true;
}

322
bool tag_info_test(FBiGeom_Instance geom) 
323 324 325 326
{
  int err;
  
  iBase_EntitySetHandle root_set;
327
  FBiGeom_getRootSet( geom, &root_set, &err );
328 329 330 331 332
  CHECK( "ERROR : getRootSet failed!" );

    // create an arbitrary tag, size 4
  iBase_TagHandle this_tag, tmp_handle;
  std::string tag_name("tag_info tag"), tmp_name;
333
  FBiGeom_createTag( geom, &tag_name[0], 4, iBase_BYTES, &this_tag, &err, tag_name.length() );
334 335 336 337 338
  CHECK( "ERROR : can not create a tag." );

    // get information on the tag
  
  char name_buffer[256];
339
  FBiGeom_getTagName( geom, this_tag, name_buffer, &err, sizeof(name_buffer) );
340 341 342 343 344 345 346 347
  CHECK( "ERROR : Couldn't get tag name." );
  if (tag_name != name_buffer) {
    std::cerr << "ERROR: getTagName returned '" << name_buffer 
              << "' for tag created as '" << tag_name << "'" << std::endl;
    return false;
  }
  
  
348
  FBiGeom_getTagHandle( geom, &tag_name[0], &tmp_handle, &err, tag_name.length() );
349 350 351 352 353 354 355
  CHECK( "ERROR : Couldn't get tag handle." );
  if (tmp_handle != this_tag) {
    std::cerr << "ERROR: getTagHandle didn't return consistent result." << std::endl;
    return false;
  }  

  int tag_size;
356
  FBiGeom_getTagSizeBytes( geom, this_tag, &tag_size, &err );
357 358 359 360 361 362
  CHECK( "ERROR : Couldn't get tag size." );
  if (tag_size != 4) {
    std::cerr << "ERROR: getTagSizeBytes: expected 4, got " << tag_size << std::endl;
    return false;
  }

363
  FBiGeom_getTagSizeValues( geom, this_tag, &tag_size, &err );
364 365 366 367 368 369 370
  CHECK( "ERROR : Couldn't get tag size." );
  if (tag_size != 4) {
    std::cerr << "ERROR: getTagSizeValues: expected 4, got " << tag_size << std::endl;
    return false;
  }

  int tag_type;
371
  FBiGeom_getTagType( geom, this_tag, &tag_type, &err );
372 373 374 375 376 377 378
  CHECK( "ERROR : Couldn't get tag type." );
  if (tag_type != iBase_BYTES) {
    std::cerr << "ERROR: getTagType: expected " << iBase_BYTES 
              << ", got " << tag_type << std::endl;
    return false;
  }
  
379
  FBiGeom_destroyTag( geom, this_tag, true, &err );
380 381 382 383 384 385
  CHECK( "ERROR : Couldn't delete a tag." );

    // print information about all the tags in the model

  std::set<iBase_TagHandle> tags;
  SimpleArray<iBase_EntityHandle> entities;
386
  FBiGeom_getEntities( geom, root_set, iBase_ALL_TYPES, 
387 388 389 390
                     ARRAY_INOUT(entities),  &err );
  CHECK( "getEntities( ..., iBase_ALL_TYPES, ... ) failed." );
  for (int i = 0; i < entities.size(); ++i) {
    SimpleArray<iBase_TagHandle> tag_arr;
391
    FBiGeom_getAllTags( geom, entities[i], ARRAY_INOUT(tag_arr), &err);
392 393 394 395 396 397 398
    CHECK( "getAllTags failed." );
    std::copy( tag_arr.begin(), tag_arr.end(), std::inserter( tags, tags.begin() ) );
  }
  
  std::cout << "Tags defined on model: ";
  bool first = true;
  for (std::set<iBase_TagHandle>::iterator sit = tags.begin(); sit != tags.end(); ++sit) {
399
    FBiGeom_getTagName( geom, *sit, name_buffer, &err, sizeof(name_buffer) );
400 401 402 403 404 405 406 407 408 409 410 411 412
    name_buffer[sizeof(name_buffer)-1] = '\0'; // mnake sure of NUL termination
    CHECK( "getTagName failed." );
    
    if (!first) std::cout << ", ";
    std::cout << name_buffer;
    first = false;
  }
  if (first) std::cout << "<none>";
  std::cout << std::endl;

  return true;
}

413
bool tag_get_set_test(FBiGeom_Instance geom) 
414 415 416 417 418 419
{
  int err;
  
    // create an arbitrary tag, size 4
  iBase_TagHandle this_tag;
  std::string tag_name("tag_get_set tag");
420
  FBiGeom_createTag( geom, &tag_name[0], sizeof(int), iBase_BYTES, &this_tag, &err, tag_name.length() );
421 422 423
  CHECK( "ERROR : can not create a tag for get_set test." );
  
  iBase_EntitySetHandle root_set;
424
  FBiGeom_getRootSet( geom, &root_set, &err );
425 426 427 428 429 430
  CHECK( "ERROR : getRootSet failed!" );
  
    // set this tag to an integer on each entity; keep track of total sum
  int sum = 0, num = 0, dim;
  for (dim = 0; dim <= 3; dim++) {
    SimpleArray<iBase_EntityHandle> gentity_handles;
431
    FBiGeom_getEntities( geom, root_set, dim, ARRAY_INOUT( gentity_handles ), &err );
432 433 434 435 436 437 438 439
    int num_ents = gentity_handles.size();
    std::vector<int> tag_vals( num_ents );
    for (int i = 0; i < num_ents; ++i) {
      tag_vals[i] = num;
      sum += num;
      ++num;
    }
    
440
    FBiGeom_setArrData( geom, ARRAY_IN( gentity_handles ),
441 442 443 444 445 446 447 448 449 450
                      this_tag, 
                      (char*)&tag_vals[0], tag_vals.size()*sizeof(int),
                      &err );
    CHECK( "ERROR : can't set tag on entities" );
  }
  
    // check tag values for entities now
  int get_sum = 0;
  for (dim = 0; dim <= 3; dim++) {
    SimpleArray<iBase_EntityHandle> gentity_handles;
451
    FBiGeom_getEntities( geom, root_set, dim, ARRAY_INOUT( gentity_handles ), &err );
452 453 454
    int num_ents = gentity_handles.size();
    
    SimpleArray<char> tag_vals;
455
    FBiGeom_getArrData( geom, ARRAY_IN( gentity_handles ), this_tag, 
456
        (void**)tag_vals.ptr(), &tag_vals.capacity(), &tag_vals.size(), &err );
457 458 459 460 461 462 463 464 465 466 467 468
    CHECK( "ERROR : can't get tag on entities" );
    
    int* tag_ptr = (int*)(&tag_vals[0]);
    for (int i = 0; i < num_ents; ++i)
      get_sum += tag_ptr[i];
  }
  
  if (get_sum != sum) {
    std::cerr << "ERROR: getData didn't return consistent results." << std::endl;
    return false;
  }
  
469
  FBiGeom_destroyTag( geom, this_tag, true, &err );
470 471 472 473 474 475 476 477 478 479
  CHECK( "ERROR : couldn't delete tag." );

  return true;
}

/*!
  @test
  TSTT gentity sets test (just implemented parts for now)
  @li Check gentity sets
*/
480
bool gentityset_test(FBiGeom_Instance geom, bool /*multiset*/, bool /*ordered*/)
481 482 483 484
{
  int num_type = 4;
  iBase_EntitySetHandle ges_array[4];
  int number_array[4];
485
  //int num_all_gentities_super = 0;
486 487 488 489
  int ent_type = iBase_VERTEX;

  int err;
  iBase_EntitySetHandle root_set;
490
  FBiGeom_getRootSet( geom, &root_set, &err );
491 492 493 494
  CHECK( "ERROR : getRootSet failed!" );
  
    // get the number of sets in the whole model
  int all_sets = 0;
495
  FBiGeom_getNumEntSets( geom, root_set, 0, &all_sets, &err );
496 497 498 499 500
  CHECK( "Problem getting the number of all gentity sets in whole model." );

    // add gentities to entitysets by type
  for (; ent_type < num_type; ent_type++) {
      // initialize the entityset
501
    FBiGeom_createEntSet( geom, true, &ges_array[ent_type], &err );
502 503 504 505
    CHECK( "Problem creating entityset." );

      // get entities by type in total "mesh"
    SimpleArray<iBase_EntityHandle> gentities;
506
    FBiGeom_getEntities( geom, root_set, ent_type, ARRAY_INOUT(gentities), &err );
507 508 509
    CHECK( "Failed to get gentities by type in gentityset_test." );
    
      // add gentities into gentity set
510
    FBiGeom_addEntArrToSet( geom, ARRAY_IN( gentities ), ges_array[ent_type], &err );
511 512 513
    CHECK( "Failed to add gentities in entityset_test." );
    
      // Check to make sure entity set really has correct number of entities in it
514
    FBiGeom_getNumOfType( geom, ges_array[ent_type], ent_type, &number_array[ent_type], &err );
515 516 517 518 519 520 521 522 523 524 525 526 527
    CHECK( "Failed to get number of gentities by type in entityset_test." );

      // compare the number of entities by type
    int num_type_gentity = gentities.size();

    if (number_array[ent_type] != num_type_gentity)
    {
      std::cerr << "Number of gentities by type is not correct"
                << std::endl;
      return false;
    }

      // add to number of all entities in super set
528
    //num_all_gentities_super += num_type_gentity;
529 530 531 532
  }

    // make a super set having all entitysets
  iBase_EntitySetHandle super_set;
533
  FBiGeom_createEntSet( geom, true, &super_set, &err );
534 535 536
  CHECK( "Failed to create a super set in gentityset_test." );

  for (int i = 0; i < num_type; i++) {
537
    FBiGeom_addEntSet( geom, ges_array[i], super_set, &err );
538 539 540 541 542 543
    CHECK( "Failed to create a super set in gentityset_test." );
  }

    //----------TEST BOOLEAN OPERATIONS----------------//

  iBase_EntitySetHandle temp_ges1;
544
  FBiGeom_createEntSet( geom, true, &temp_ges1, &err );
545 546 547 548 549 550
  CHECK( "Failed to create a super set in gentityset_test." );

    // Subtract
    // add all EDGEs and FACEs to temp_es1
    // get all EDGE entities
  SimpleArray<iBase_EntityHandle> gedges, gfaces, temp_gentities1;
551
  FBiGeom_getEntities( geom, ges_array[iBase_EDGE], iBase_EDGE, ARRAY_INOUT(gedges), &err );
552 553 554
  CHECK( "Failed to get gedge gentities in gentityset_test." );

    // add EDGEs to ges1
555
  FBiGeom_addEntArrToSet( geom, ARRAY_IN(gedges), temp_ges1, &err );
556 557 558
  CHECK( "Failed to add gedge gentities in gentityset_test." );

    // get all FACE gentities
559
  FBiGeom_getEntities( geom, ges_array[iBase_FACE], iBase_FACE, ARRAY_INOUT(gfaces), &err );
560 561 562
  CHECK( "Failed to get gface gentities in gentityset_test." );

    // add FACEs to es1
563
  FBiGeom_addEntArrToSet( geom, ARRAY_IN(gfaces), temp_ges1, &err );
564 565 566
  CHECK( "Failed to add gface gentities in gentityset_test." );

    // subtract EDGEs
567
  FBiGeom_subtract( geom, temp_ges1, ges_array[iBase_EDGE], &temp_ges1, &err );
568 569
  CHECK( "Failed to subtract gentitysets in gentityset_test." );
  
570
  FBiGeom_getEntities( geom, temp_ges1, iBase_FACE, ARRAY_INOUT(temp_gentities1), &err );
571 572 573 574 575 576 577 578 579 580
  CHECK( "Failed to get gface gentities in gentityset_test." );

  if (gfaces.size() != temp_gentities1.size()) {
    std::cerr << "Number of entitysets after subtraction not correct \
             in gentityset_test." << std::endl;
    return false;
  }

    // check there's nothing but gfaces in temp_ges1
  int num_gents;
581
  FBiGeom_getNumOfType( geom, temp_ges1, iBase_EDGE, &num_gents, &err );
582 583 584 585 586 587 588 589 590 591
  CHECK( "Failed to get dimensions of gentities in gentityset_test." );
  if (0 != num_gents) {
    std::cerr << "Subtraction failed to remove all edges" << std::endl;
    return false;
  }

    //------------Intersect------------
    //

    // clean out the temp_ges1
592
  FBiGeom_rmvEntArrFromSet( geom, ARRAY_IN(gfaces), temp_ges1, &err );
593 594 595
  CHECK( "Failed to remove gface gentities in gentityset_test." );

    // check if it is really cleaned out
596
  FBiGeom_getNumOfType( geom, temp_ges1, iBase_FACE, &num_gents, &err );
597 598 599 600 601 602 603 604
  CHECK( "Failed to get number of gentities by type in gentityset_test." );

  if (num_gents != 0) {
    std::cerr << "failed to remove correctly." << std::endl;
    return false;
  }
  
    // add EDGEs to temp ges1
605
  FBiGeom_addEntArrToSet( geom, ARRAY_IN(gedges), temp_ges1, &err );
606 607 608
  CHECK( "Failed to add gedge gentities in gentityset_test." );

    // add FACEs to temp ges1
609
  FBiGeom_addEntArrToSet( geom, ARRAY_IN(gfaces), temp_ges1, &err );
610 611 612 613
  CHECK( "Failed to add gface gentities in gentityset_test." );

    // intersect temp_ges1 with gedges set 
    // temp_ges1 entityset is altered
614
  FBiGeom_intersect( geom, temp_ges1, ges_array[iBase_EDGE], &temp_ges1, &err );
615 616 617
  CHECK( "Failed to intersect in gentityset_test." );
  
    // try to get FACEs, but there should be nothing but EDGE
618
  FBiGeom_getNumOfType( geom, temp_ges1, iBase_FACE, &num_gents, &err );
619 620 621 622 623 624 625 626 627 628 629 630 631 632
  CHECK( "Failed to get gface gentities in gentityset_test." );

  if (num_gents != 0) {
    std::cerr << "wrong number of gfaces." << std::endl;
    return false;
  }


    //-------------Unite--------------

    // get all regions
  iBase_EntitySetHandle temp_ges2;
  SimpleArray<iBase_EntityHandle> gregions;

633
  FBiGeom_createEntSet( geom, true, &temp_ges2, &err );
634 635
  CHECK( "Failed to create a temp gentityset in gentityset_test." );
  
636
  FBiGeom_getEntities( geom, ges_array[iBase_REGION], iBase_REGION, ARRAY_INOUT(gregions), &err );
637 638 639
  CHECK( "Failed to get gregion gentities in gentityset_test." );
  
    // add REGIONs to temp es2
640
  FBiGeom_addEntArrToSet( geom, ARRAY_IN(gregions), temp_ges2, &err );
641 642 643 644
  CHECK( "Failed to add gregion gentities in gentityset_test." );

    // unite temp_ges1 and temp_ges2
    // temp_ges1 gentityset is altered
645
  FBiGeom_unite( geom, temp_ges1, temp_ges2, &temp_ges1, &err );
646 647 648
  CHECK( "Failed to unite in gentityset_test." );

    // perform the check
649
  FBiGeom_getNumOfType( geom, temp_ges1, iBase_REGION, &num_gents, &err );
650 651 652 653 654 655 656 657 658 659 660 661
  CHECK( "Failed to get number of gregion gentities by type in gentityset_test." );
  
  if (num_gents != number_array[iBase_REGION]) {
    std::cerr << "different number of gregions in gentityset_test." << std::endl;
    return false;
  }


    //--------Test parent/child stuff in entiysets-----------

    // Add 2 sets as children to another
  iBase_EntitySetHandle parent_child;
662
  FBiGeom_createEntSet( geom, true, &parent_child, &err );
663 664
  CHECK( "Problem creating gentityset in gentityset_test." );

665
  FBiGeom_addPrntChld( geom, ges_array[iBase_VERTEX], parent_child, &err );
666 667 668 669
  CHECK( "Problem add parent in gentityset_test." );

    // check if parent is really added
  SimpleArray<iBase_EntitySetHandle> parents;
670
  FBiGeom_getPrnts( geom, parent_child, 1, ARRAY_INOUT(parents), &err );
671 672 673 674 675 676 677 678 679 680 681 682 683 684 685
  CHECK( "Problem getting parents in gentityset_test." );

  if (parents.size() != 1) {
    std::cerr << "number of parents is not correct in gentityset_test."
              << std::endl;
    return false;
  }

    // add parent and child
  //sidl::array<void*> parent_child_array = sidl::array<void*>::create1d(1);
  //int num_parent_child_array;
  //sidl::array<void*> temp_gedge_array = sidl::array<void*>::create1d(1);
  //int num_temp_gedge_array;
  //parent_child_array.set(0, parent_child);
  //temp_gedge_array.set(0, ges_array[TSTTG::EntityType_EDGE]);
686
  FBiGeom_addPrntChld( geom, ges_array[iBase_EDGE], parent_child, &err );
687 688 689 690 691
  CHECK( "Problem adding parent and child in gentityset_test." );

  //sidl::array<void*> temp_gface_array = sidl::array<void*>::create1d(1);
  //int num_temp_gface_array;
  //temp_gface_array.set(0, ges_array[TSTTG::EntityType_FACE]);
692
  FBiGeom_addPrntChld( geom, parent_child, ges_array[iBase_FACE], &err );
693 694 695
  CHECK( "Problem adding parent and child in gentityset_test." );

    // add child
696
  FBiGeom_addPrntChld( geom, parent_child, ges_array[iBase_REGION], &err );
697 698 699 700
  CHECK( "Problem adding child in gentityset_test." );

    // get the number of parent gentitysets
  num_gents = -1;
701
  FBiGeom_getNumPrnt( geom, parent_child, 1, &num_gents, &err );
702 703 704 705 706 707 708 709 710 711
  CHECK( "Problem getting number of parents in gentityset_test." );

  if (num_gents != 2) {
    std::cerr << "number of parents is not correct in gentityset_test."
              << std::endl;
    return false;
  }

    // get the number of child gentitysets
  num_gents = -1;
712
  FBiGeom_getNumChld( geom, parent_child, 1, &num_gents, &err );
713 714 715 716 717 718 719 720 721
  CHECK( "Problem getting number of children in gentityset_test." );

  if (num_gents != 2) {
    std::cerr << "number of children is not correct in gentityset_test."
              << std::endl;
    return false;
  }

  SimpleArray<iBase_EntitySetHandle> children;
722
  FBiGeom_getChldn( geom, parent_child, 1, ARRAY_INOUT(children), &err );
723 724 725 726 727 728 729 730 731
  CHECK( "Problem getting children in gentityset_test." );

  if (children.size() != 2) {
    std::cerr << "number of children is not correct in gentityset_test."
              << std::endl;
    return false;
  }

    // remove children
732
  FBiGeom_rmvPrntChld( geom, parent_child, ges_array[iBase_FACE], &err );
733 734 735
  CHECK( "Problem removing parent child in gentityset_test." );

    // get the number of child gentitysets
736
  FBiGeom_getNumChld( geom, parent_child, 1, &num_gents, &err );
737 738 739 740 741 742 743 744 745 746
  CHECK( "Problem getting number of children in gentityset_test." );

  if (num_gents != 1) {
    std::cerr << "number of children is not correct in gentityset_test."
              << std::endl;
    return false;
  }

    // parent_child and ges_array[TSTTG::EntityType_EDGE] should be related
  int result = 0;
747
  FBiGeom_isChildOf( geom, ges_array[iBase_EDGE], parent_child, &result, &err );
748 749 750 751 752 753 754 755
  CHECK( "Problem checking relation in gentityset_test." );
  if (!result) {
    std::cerr << "parent_child and ges_array[TSTTG::EntityType_EDGE] should be related" << std::endl;
    return false;
  }

    // ges_array[TSTTG::EntityType_FACE] and ges_array[TSTTG::REGION] are not related
  result = 2;
756
  FBiGeom_isChildOf( geom, ges_array[iBase_FACE], ges_array[iBase_REGION], &result, &err );
757 758 759 760 761 762 763 764 765 766
  if (result) {
    std::cerr << "ges_array[TSTTG::REGION] and ges_array[TSTTG::EntityType_FACE] should not be related" << std::endl;
    return false;
  }
  

    //--------test modify and query functions-----------------------------
  
    // check the number of gentity sets in whole mesh
  SimpleArray<iBase_EntitySetHandle> gentity_sets;
767
  FBiGeom_getEntSets( geom, root_set, 1, ARRAY_INOUT( gentity_sets ), &err );
768 769 770 771 772 773 774 775 776 777
  CHECK( "Problem to get all gentity sets in mesh." );
  
  if (gentity_sets.size() != all_sets + 8) {
    std::cerr << "the number of gentity sets in whole mesh should be 8 times of num_iter."
              << std::endl;
    return false;
  }

    // get all gentity sets in super set
  SimpleArray<iBase_EntitySetHandle> ges_array1;
778
  FBiGeom_getEntSets( geom, super_set, 1, ARRAY_INOUT( ges_array1 ), &err );
779 780 781 782
  CHECK( "Problem to get gentity sets in super set." );

    // get the number of gentity sets in super set
  int num_super;
783
  FBiGeom_getNumEntSets( geom, super_set, 1, &num_super, &err );
784 785 786 787 788 789 790 791 792 793
  CHECK( "Problem to get the number of all gentity sets in super set." );
  
    // the number of gentity sets in super set should be same
  if (num_super != ges_array1.size()) {
    std::cerr << "the number of gentity sets in super set should be same." << std::endl;
    return false;
  }

    // get all entities in super set
  SimpleArray<iBase_EntitySetHandle> all_gentities;
794
  FBiGeom_getEntSets( geom, super_set, 1, ARRAY_INOUT( all_gentities ), &err );
795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812
  CHECK( "Problem to get all gentities in super set." );
  
    // compare the number of all gentities in super set
  // HJK : num_hops is not implemented
  //if (num_all_gentities_super != ARRAY_SIZE(all_gentities)) {
  //std::cerr << "number of all gentities in super set should be same." << std::endl;
  //success = false;
  //}

    // test add, remove and get all entitiy sets using super set
    // check GetAllGentitysets works recursively and dosen't return
    // multi sets
  for (int k = 0; k < num_super; k++) {
      // add gentity sets of super set to each gentity set of super set
      // make multiple child super sets
    iBase_EntitySetHandle ges_k = ges_array1[k];

    for (int a = 0; a < ges_array1.size(); a++) {
813
      FBiGeom_addEntSet( geom, ges_array1[a], ges_k, &err );
814 815 816 817 818 819 820 821 822
      CHECK( "Problem to add entity set." );
    }
    
      // add super set to each entity set
    //    sidl::array<GentitysetHandle> superset_array
    //= sidl::array<GentitysetHandle>::create1d(1);
    //superset_array.set(0, super_set);
    //int num_superset_array;
    
823
    FBiGeom_addEntSet( geom, super_set, ges_k, &err );
824 825 826 827 828 829 830 831 832 833
    CHECK( "Problem to add super set to gentitysets." );

      // add one gentity sets multiple times
    // HJK: ??? how to deal this case?
    //sidl::array<GentitysetHandle> temp_array1
    //= sidl::array<GentitysetHandle>::create1d(1);
    //int num_temp_array1;
    //temp_array1.set(0, temp_ges1);

    //for (int l = 0; l < 3; l++) {
834
    FBiGeom_addEntSet( geom, temp_ges1, ges_k, &err );
835 836 837 838 839 840 841 842 843 844 845 846 847 848 849
    CHECK( "Problem to add temp set to gentitysets." );
      //}
  }

  return true;
}
  
/*!
@test
TSTTG topology adjacencies Test
@li Check topology information
@li Check adjacency
*/
// make each topological entity vectors, check their topology
// types, get interior and exterior faces of model
850
bool topology_adjacencies_test(FBiGeom_Instance geom)
851 852 853
{
  int i, err;
  iBase_EntitySetHandle root_set;
854
  FBiGeom_getRootSet( geom, &root_set, &err );
855 856 857 858 859 860 861 862 863 864 865 866
  CHECK( "ERROR : getRootSet failed!" );

  int top = iBase_VERTEX;
  int num_test_top = iBase_ALL_TYPES;
  std::vector< std::vector<iBase_EntityHandle> > gentity_vectors(num_test_top);

  // fill the vectors of each topology entities
  // like lines vector, polygon vector, triangle vector,
  // quadrilateral, polyhedrron, tet, hex, prism, pyramid,
  // septahedron vectors
  for (i = top; i < num_test_top; i++) {
    SimpleArray<iBase_EntityHandle> gentities;
867
    FBiGeom_getEntities( geom, root_set, i, ARRAY_INOUT( gentities ), &err );
868 869 870 871 872 873 874 875 876
    CHECK("Failed to get gentities in adjacencies_test.");
  
    gentity_vectors[i].resize( gentities.size() );
    std::copy( gentities.begin(), gentities.end(), gentity_vectors[i].begin() );
  }

  // check number of entities for each topology
  for (i = top; i < num_test_top; i++) {
    int num_tops = 0;
877
    FBiGeom_getNumOfType( geom, root_set, i, &num_tops, &err );
878 879 880 881 882 883 884 885 886 887 888 889
    CHECK( "Failed to get number of gentities in adjacencies_test." );
    
    if (static_cast<int>(gentity_vectors[i].size()) != num_tops) {
      std::cerr << "Number of gentities doesn't agree with number returned for dimension " 
                << i << std::endl;
      return false;
    }
  }

  // check adjacencies in both directions
  std::vector<iBase_EntityHandle>::iterator vit;
  for (i = iBase_REGION; i >= iBase_VERTEX; i--) {
890
    for (vit = gentity_vectors[i].begin(); vit != gentity_vectors[i].end(); ++vit) {
891 892 893 894 895 896
      iBase_EntityHandle this_gent = *vit;

        // check downward adjacencies
      for (int j = iBase_VERTEX; j < i; j++) {

        SimpleArray<iBase_EntityHandle> lower_ents;
897
        FBiGeom_getEntAdj( geom, this_gent, j, ARRAY_INOUT(lower_ents), &err );
898 899 900 901 902 903
        CHECK( "Bi-directional adjacencies test failed." );

          // for each of them, make sure they are adjacent to the upward ones
        int num_lower = lower_ents.size();
        for (int k = 0; k < num_lower; k++) {
          SimpleArray<iBase_EntityHandle> upper_ents;
904
          FBiGeom_getEntAdj( geom, lower_ents[k], i, ARRAY_INOUT(upper_ents), &err );
905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921
          CHECK( "Bi-directional adjacencies test failed." );
          if (std::find(upper_ents.begin(),upper_ents.end(), this_gent) ==
              upper_ents.end()) {
            std::cerr << "Didn't find lower-upper adjacency which was supposed to be there, dims = "
                 << i << ", " << j << std::endl;
            return false;
          }
        }
      }
    }
  }

  return true;
}

/*!
@test
922
FBiGeom_MOAB topology adjacencies Test
923 924 925 926 927
@li Check topology information
@li Check adjacency
*/
// make each topological entity vectors, check their topology
// types, get interior and exterior faces of model
928
bool geometry_evaluation_test(FBiGeom_Instance geom)
929 930 931
{
  int i, err;
  iBase_EntitySetHandle root_set;
932
  FBiGeom_getRootSet( geom, &root_set, &err );
933 934 935 936 937 938 939 940 941 942 943 944
  CHECK( "ERROR : getRootSet failed!" );

  int top = iBase_VERTEX;
  int num_test_top = iBase_ALL_TYPES;
  std::vector< std::vector<iBase_EntityHandle> > gentity_vectors(num_test_top);

  // fill the vectors of each topology entities
  // like lines vector, polygon vector, triangle vector,
  // quadrilateral, polyhedrron, tet, hex, prism, pyramid,
  // septahedron vectors
  for (i = top; i < num_test_top; i++) {
    SimpleArray<iBase_EntityHandle> gentities;
945
    FBiGeom_getEntities( geom, root_set, i, ARRAY_INOUT( gentities ), &err );
946 947 948 949 950 951 952 953 954 955 956 957
    CHECK("Failed to get gentities in adjacencies_test.");
  
    gentity_vectors[i].resize( gentities.size() );
    std::copy( gentities.begin(), gentities.end(), gentity_vectors[i].begin() );
  }
 
  // check adjacencies in both directions
  double min[3], max[3], on[3];
  double near[3] = {.0, .0, .0};
  std::vector<iBase_EntityHandle>::iterator vit;
  for (i = iBase_REGION; i >= iBase_VERTEX; i--) {
    if (i != iBase_EDGE) {
958
      for (vit = gentity_vectors[i].begin(); vit != gentity_vectors[i].end(); ++vit) {
959
	iBase_EntityHandle this_gent = *vit;
960
	FBiGeom_getEntBoundBox(geom, this_gent, &min[0], &min[1], &min[2],
961 962 963
			     &max[0], &max[1], &max[2], &err);
	CHECK("Failed to get bounding box of entity.");
	
964
	FBiGeom_getEntClosestPt(geom, this_gent, near[0], near[1], near[2],
965 966 967 968 969 970 971 972 973 974 975 976 977 978
			      &on[0], &on[1], &on[2], &err);
	CHECK("Failed to get closest point on entity.");
      }
    }
  }

  return true;
}

/*!
@test
TSTTG construct Test
@li Check construction of geometry
*/
979
bool construct_test(FBiGeom_Instance geom)
980 981 982 983 984 985
{
  int err;
  iBase_EntityHandle new_body = 0;

    // construct a cylinder, sweep it about an axis, and delete the result
  iBase_EntityHandle cyl = 0;
986
  FBiGeom_createCylinder( geom, 1.0, 1.0, 0.0, &cyl, &err );
987 988 989 990
    // Is the minor radius really supposed to be zero??? - JK
  CHECK( "Creating cylinder failed." );
  
    // move it onto the y axis
991
  FBiGeom_moveEnt( geom, cyl, 0.0, 1.0, -0.5, &err );
992 993 994 995 996
  CHECK( "Problems moving surface." );

      // get the surface with max z
  iBase_EntityHandle max_surf = 0;
  SimpleArray<iBase_EntityHandle> surfs;
997
  FBiGeom_getEntAdj( geom, cyl, iBase_FACE, ARRAY_INOUT(surfs), &err );
998 999 1000
  CHECK( "Problems getting max surf for rotation." );
  
  SimpleArray<double> max_corn, min_corn;
1001
  FBiGeom_getArrBoundBox( geom, ARRAY_IN(surfs), iBase_INTERLEAVED, 
1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020
                        ARRAY_INOUT( min_corn ),
                        ARRAY_INOUT( max_corn ),
                        &err );
  CHECK( "Problems getting max surf for rotation." );
  double dtol = 1.0e-6;
  for (int i = 0; i < surfs.size(); ++i) {
    if ((max_corn[3*i+2]) <= dtol && (max_corn[3*i+2]) >= -dtol &&
        (min_corn[3*i+2]) <= dtol && (min_corn[3*i+2]) >= -dtol) {
      max_surf = surfs[i];
      break;
    }
  }  
  
  if (0 == max_surf) {
    std::cerr << "Couldn't find max surf for rotation." << std::endl;
    return false;
  }
  
    // sweep it around the x axis
1021
  FBiGeom_moveEnt( geom, cyl, 0.0, 1.0, 0.0, &err );
1022 1023
  CHECK( "Problems moving surface." );

1024
  FBiGeom_sweepEntAboutAxis( geom, max_surf, 360.0, 1.0, 0.0, 0.0, &new_body, &err );
1025 1026 1027
  CHECK( "Problems sweeping surface about axis." );
  
    // now delete
1028
  FBiGeom_deleteEnt( geom, new_body, &err );
1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053
  CHECK( "Problems deleting cylinder or swept surface body." );
  
    // if we got here, we were successful
  return true;
}

static bool compare_box( const double* expected_min,
                         const double* expected_max,
                         const double* actual_min,
                         const double* actual_max )
{
  bool same = true;
  double dtol = 1.0e-6;
  
  for (int i = 0; i < 3; ++i)
  {
    if (expected_min[i] < actual_min[i] - dtol || 
        expected_min[i]*10 >  actual_min[i] ||
        expected_max[i] > actual_max[i] + dtol ||
        expected_max[i]*10 < actual_max[i])  
      same = false;
  } 
  return same;
}

1054
bool primitives_test(FBiGeom_Instance geom) 
1055 1056 1057 1058 1059
{
  int err;
  SimpleArray<iBase_EntityHandle> prims(3);
  iBase_EntityHandle prim;
 
1060
  FBiGeom_createBrick( geom, 1.0, 2.0, 3.0, &prim, &err );
1061 1062 1063
  CHECK( "createBrick failed." );
  prims[0] = prim;
  
1064
  FBiGeom_createCylinder( geom, 1.0, 4.0, 2.0, &prim, &err );
1065 1066 1067
  CHECK( "createCylinder failed." );
  prims[1] = prim;
  
1068
  FBiGeom_createTorus( geom, 2.0, 1.0, &prim, &err );
1069 1070 1071 1072 1073
  CHECK( "createTorus failed." );
  prims[2] = prim;
  
    // verify the bounding boxes for Acis based entities
  SimpleArray<double> max_corn, min_corn;
1074
  FBiGeom_getArrBoundBox( geom, ARRAY_IN(prims), iBase_INTERLEAVED, 
1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113
                        ARRAY_INOUT(min_corn), ARRAY_INOUT(max_corn), &err );

  double preset_min_corn[] = 
      // min brick corner xyz
    {-0.5, -1.0, -1.5, 
      // min cyl corner xyz
     -4.0, -2.0, -0.5,
      // min torus corner xyz
     -3.0, -3.0, -1.0
    };
  
  double preset_max_corn[] = 
      // max brick corner xyz
    {0.5, 1.0, 1.5, 
      // max cyl corner xyz
     4.0, 2.0, 0.5,
      // max torus corner xyz
     3.0, 3.0, 1.0
    };
  
  if (!compare_box( preset_min_corn, preset_max_corn,
                    &min_corn[0], &max_corn[0] )) {
    std::cerr << "Box check failed for brick" << std::endl;
    return false;
  }
  
  if (!compare_box( preset_min_corn+3, preset_max_corn+3,
                    &min_corn[3], &max_corn[3] )) {
    std::cerr << "Box check failed for cylinder" << std::endl;
    return false;
  }
  
  if (!compare_box( preset_min_corn+6, preset_max_corn+6,
                    &min_corn[6], &max_corn[6] )) {
    std::cerr << "Box check failed for torus" << std::endl;
    return false;
  }
    // must have worked; delete the entities then return
  for (int i = 0; i < 3; ++i) {
1114
    FBiGeom_deleteEnt( geom, prims[i], &err );
1115 1116 1117 1118 1119 1120
    CHECK( "Problems deleting primitive after boolean check." );
  }
  
  return true;
}
  
1121
bool transforms_test(FBiGeom_Instance geom) 
1122 1123 1124 1125 1126
{
  int err;
  
    // construct a brick
  iBase_EntityHandle brick = 0;
1127
  FBiGeom_createBrick( geom, 1.0, 2.0, 3.0, &brick, &err );
1128 1129 1130
  CHECK( "Problems creating brick for transforms test." );
  
    // move it, then test bounding box
1131
  FBiGeom_moveEnt( geom, brick, 0.5, 1.0, 1.5, &err );
1132 1133 1134
  CHECK( "Problems moving brick for transforms test." );
  
  double bb_min[3], bb_max[3];
1135
  FBiGeom_getEntBoundBox( geom, brick, bb_min, bb_min+1, bb_min+2, bb_max, bb_max+1, bb_max+2, &err );
1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149
  CHECK( "Problems getting bounding box after move." );

  double dtol = 1.0e-6;
  if ((bb_min[0]) >= dtol || (bb_min[0]) <= -dtol || 
      (bb_min[1]) >= dtol || (bb_min[1]) <= -dtol || 
      (bb_min[2]) >= dtol || (bb_min[2]) <= -dtol ||
      (bb_max[0]-1) >= dtol || 1-bb_max[0] >=dtol ||
      (bb_max[1]-2) >= dtol || 2 - bb_max[1] >=dtol||
      (bb_max[2]-3) >= dtol || 3 - bb_max[2] >= dtol) {
    std::cerr << "Wrong bounding box after move." << std::endl;
    return false;
  }
  
    // now rotate it about +x, then test bounding box
1150
  FBiGeom_rotateEnt( geom, brick, 90, 1.0, 0.0, 0.0, &err );
1151 1152
  CHECK( "Problems rotating brick for transforms test." );
  
1153
  FBiGeom_getEntBoundBox( geom, brick, bb_min, bb_min+1, bb_min+2, bb_max, bb_max+1, bb_max+2, &err );
1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166
  CHECK( "Problems getting bounding box after rotate." );

  if ((bb_min[0]) >= dtol || -bb_min[0] >= dtol ||
      (bb_min[1]+3) >= dtol || -(bb_min[1]+3) >= dtol ||
      (bb_min[2]) >= dtol || -(bb_min[2]) >= dtol ||
      (bb_max[0]-1) >= dtol || 1-bb_max[0] >= dtol ||
      (bb_max[1]) >= dtol || -(bb_max[1]) >= dtol ||
      (bb_max[2]-2) >= dtol || 2-bb_max[2] >=dtol) {
    std::cerr << "Wrong bounding box after rotate." << std::endl;
    return false;
  }
  
    // now reflect through y plane; should recover original bb
1167
  FBiGeom_reflectEnt( geom, brick, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, &err );
1168 1169
  CHECK( "Problems reflecting brick for transforms test." );
  
1170
  FBiGeom_getEntBoundBox( geom, brick, bb_min, bb_min+1, bb_min+2, bb_max, bb_max+1, bb_max+2, &err );
1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182
  CHECK( "Problems getting bounding box after reflect." );
  
  if ((bb_min[0]) >= dtol || -(bb_min[0]) >= dtol ||(bb_min[1]) >= dtol || 
      (bb_min[2]) >= dtol || -(bb_min[1]) >= dtol || -(bb_min[2]) >= dtol ||
      (bb_max[0]-1) >= dtol || 1- bb_max[0] >= dtol ||
      (bb_max[1]-3) >= dtol || 3 - bb_max[1] >= dtol ||
      (bb_max[2]-2) >= dtol || 2 - bb_max[2] >= dtol) {
    std::cerr << "Wrong bounding box after reflect." << std::endl;
    return false;
  }

    // must have worked; delete the entities then return
1183
  FBiGeom_deleteEnt( geom, brick, &err );
1184 1185 1186 1187 1188
  CHECK( "Problems deleting brick after transforms check." );
  return true;
}


1189
bool booleans_test(FBiGeom_Instance geom) 
1190 1191 1192 1193 1194
{
  int err;

    // construct a brick size 1, and a cylinder rad 0.25 height 2
  iBase_EntityHandle brick = 0, cyl = 0;
1195
  FBiGeom_createBrick( geom, 1.0, 0.0, 0.0, &brick, &err );
1196
  CHECK( "Problems creating brick for booleans test." );
1197
  FBiGeom_createCylinder( geom, 1.0, 0.25, 0.0, &cyl, &err );
1198 1199 1200 1201
  CHECK( "Problems creating cylinder for booleans test." );

    // subtract the cylinder from the brick
  iBase_EntityHandle subtract_result = 0;
1202
  FBiGeom_subtractEnts( geom, brick, cyl, &subtract_result, &err );
1203 1204 1205 1206
  CHECK( "Problems subtracting for booleans subtract test." );

    // section the brick
  iBase_EntityHandle section_result = 0;
1207
  FBiGeom_sectionEnt( geom, subtract_result, 1.0, 0.0, 0.0, 0.25, true, &section_result, &err );
1208 1209 1210
  CHECK( "Problems sectioning for booleans section test." );

    // unite the section result with a new cylinder
1211
  FBiGeom_createCylinder( geom, 1.0, 0.25, 0.0, &cyl, &err );
1212 1213 1214
  CHECK( "Problems creating cylinder for unite test." );
  iBase_EntityHandle unite_results;
  iBase_EntityHandle unite_input[] = { section_result, cyl };