MOAB: Mesh Oriented datABase  (version 5.5.0)
testSmooth2.cpp
Go to the documentation of this file.
1 /**
2  * This library is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU Lesser General Public
4  * License as published by the Free Software Foundation; either
5  * version 2.1 of the License, or (at your option) any later version.
6  *
7  */
8 /**
9  * \file testgeom.cc
10  *
11  * \brief testgeom, a unit test for the ITAPS geometry interface
12  *
13  */
14 #include "FBiGeom.h"
15 #include "FBiGeom_MOAB.hpp"
16 #include "iMesh.h"
17 #include <iostream>
18 #include <set>
19 #include <algorithm>
20 #include <vector>
21 #include <iterator>
22 #include <algorithm>
23 #include <iomanip>
24 #include <cassert>
25 #include <cstring>
26 #include <cmath>
27 #define CHECK( STR ) \
28  if( err != iBase_SUCCESS ) return print_error( STR, err, geom, __FILE__, __LINE__ )
29 
30 #define STRINGIFY( S ) XSTRINGIFY( S )
31 #define XSTRINGIFY( S ) #S
32 
33 static bool print_error( const char* desc, int err, FBiGeom_Instance geom, const char* file, int line )
34 {
35  char buffer[1024];
37  buffer[sizeof( buffer ) - 1] = '\0';
38 
39  std::cerr << "ERROR: " << desc << std::endl
40  << " Error code: " << err << std::endl
41  << " Error desc: " << buffer << std::endl
42  << " At : " << file << ':' << line << std::endl;
43 
44  return false; // must always return false or CHECK macro will break
45 }
46 
50 
53  const char* options,
55  int* err,
56  int options_len );
57 // the second destructor
58 extern void FBiGeom_dtor2( FBiGeom_Instance instance, int* err );
59 /* Frees allocated arrays for us */
60 template < typename T >
61 class SimpleArray
62 {
63  private:
64  T* arr;
65  int arrSize;
66  int arrAllocated;
67 
68  public:
69  SimpleArray() : arr( 0 ), arrSize( 0 ), arrAllocated( 0 ) {}
70  SimpleArray( unsigned s ) : arrSize( s ), arrAllocated( s )
71  {
72  arr = (T*)malloc( s * sizeof( T ) );
73  for( unsigned i = 0; i < s; ++i )
74  new( arr + i ) T();
75  }
76 
78  {
79  for( int i = 0; i < size(); ++i )
80  arr[i].~T();
81  free( arr );
82  }
83 
84  T** ptr()
85  {
86  return &arr;
87  }
88  int& size()
89  {
90  return arrSize;
91  }
92  int size() const
93  {
94  return arrSize;
95  }
96  int& capacity()
97  {
98  return arrAllocated;
99  }
100  int capacity() const
101  {
102  return arrAllocated;
103  }
104 
105  typedef T* iterator;
106  typedef const T* const_iterator;
108  {
109  return arr;
110  }
112  {
113  return arr;
114  }
116  {
117  return arr + arrSize;
118  }
120  {
121  return arr + arrSize;
122  }
123 
124  T& operator[]( unsigned idx )
125  {
126  return arr[idx];
127  }
128  T operator[]( unsigned idx ) const
129  {
130  return arr[idx];
131  }
132 };
133 
134 #define ARRAY_INOUT( A ) A.ptr(), &( A ).capacity(), &( A ).size()
135 #define ARRAY_IN( A ) &( A )[0], ( A ).size()
136 
137 bool smooth_test( const std::string& filename, FBiGeom_Instance );
138 
142 bool gentityset_test( FBiGeom_Instance geom, bool /*multiset*/, bool /*ordered*/ );
149 bool shutdown_test2( FBiGeom_Instance geom, std::string& engine_opt );
153 
155 
156 void handle_error_code( const bool result, int& number_failed, int& /*number_not_implemented*/, int& number_successful )
157 {
158  if( result )
159  {
160  std::cout << "Success";
161  number_successful++;
162  }
163  else
164  {
165  std::cout << "Failure";
166  number_failed++;
167  }
168 }
169 
170 int main( int argc, char* argv[] )
171 {
172  std::string filename = STRINGIFY( MESHDIR ) "/shell.h5m";
173 
174  if( argc == 1 )
175  {
176  std::cout << "Using default input file: " << filename << std::endl;
177  }
178  else if( argc == 2 )
179  {
180  filename = argv[1];
181  }
182  else
183  {
184  std::cerr << "Usage: " << argv[0] << " [geom_filename]" << std::endl;
185  return 1;
186  }
187 
188  int err;
189  int number_tests = 0;
190  int number_tests_successful = 0;
191  int number_tests_not_implemented = 0;
192  int number_tests_failed = 0;
193 
194  // initialize the FBiGeom, in a different way
195  iMesh_Instance mesh = NULL;
197  iMesh_newMesh( NULL, &mesh, &err, 0 );
198  if( err != iBase_SUCCESS )
199  std::cerr << " Error code: " << err << " At : " << __FILE__ << ':' << __LINE__ << std::endl;
200 
202  iMesh_createEntSet( mesh, 0, &root_set, &err );
203  if( err != iBase_SUCCESS )
204  std::cerr << " Error code: " << err << " failed to create a model set"
205  << " At : " << __FILE__ << ':' << __LINE__ << std::endl;
206 
207  iMesh_load( mesh, root_set, filename.c_str(), NULL, &err, filename.length(), 0 );
208  if( err != iBase_SUCCESS )
209  std::cerr << " Error code: " << err << " failed load the file"
210  << " At : " << __FILE__ << ':' << __LINE__ << std::endl;
211 
212  std::string opts( "SMOOTH;" );
213  // new constructor
214  FBiGeom_newGeomFromMesh( mesh, root_set, opts.c_str(), &geom, &err, opts.length() );
215 
216  CHECK( "Interface initialization didn't work properly." );
217 
218  // Print out Header information
219  std::cout << "\n\nITAPS GEOMETRY INTERFACE TEST PROGRAM:\n\n";
220  // gLoad test
221 
222  bool result;
223  std::cout << " Smooth faceting load and initialization: \n";
224  result = smooth_test( filename, geom );
225  handle_error_code( result, number_tests_failed, number_tests_not_implemented, number_tests_successful );
226 
227  number_tests++;
228  std::cout << "\n";
229 
230  // tags test
231  std::cout << " tags: ";
232  result = tags_test( geom );
233  handle_error_code( result, number_tests_failed, number_tests_not_implemented, number_tests_successful );
234  number_tests++;
235  std::cout << "\n";
236  /*
237  // gentitysets test
238  std::cout << " gentity sets: ";
239  result = gentityset_test(geom, false, false);
240  handle_error_code(result, number_tests_failed,
241  number_tests_not_implemented,
242  number_tests_successful);
243  number_tests++;
244  std::cout << "\n";
245  */
246  // topology adjacencies test
247  std::cout << " topology adjacencies: ";
248  result = topology_adjacencies_test( geom );
249  handle_error_code( result, number_tests_failed, number_tests_not_implemented, number_tests_successful );
250  number_tests++;
251  std::cout << "\n";
252 
253  // geometry evaluation test
254  std::cout << " geometry evaluation: \n";
255  result = geometry_evaluation_test( geom );
256  handle_error_code( result, number_tests_failed, number_tests_not_implemented, number_tests_successful );
257  number_tests++;
258  std::cout << "\n";
259 
260  // normals evaluation test
261  std::cout << " normals geometry evaluation: \n";
262  result = normals_test( geom );
263  handle_error_code( result, number_tests_failed, number_tests_not_implemented, number_tests_successful );
264  number_tests++;
265  std::cout << "\n";
266 
267  // ray tracing test
268  std::cout << " ray intersection test: \n";
269  result = ray_test( geom );
270  handle_error_code( result, number_tests_failed, number_tests_not_implemented, number_tests_successful );
271  number_tests++;
272  std::cout << "\n";
273  /*
274  // construct test
275  std::cout << " construct: ";
276  result = construct_test(geom);
277  handle_error_code(result, number_tests_failed,
278  number_tests_not_implemented,
279  number_tests_successful);
280  number_tests++;
281  std::cout << "\n";
282 
283  // primitives test
284  std::cout << " primitives: ";
285  result = primitives_test(geom);
286  handle_error_code(result, number_tests_failed,
287  number_tests_not_implemented,
288  number_tests_successful);
289  number_tests++;
290  std::cout << "\n";
291 
292  // transforms test
293  std::cout << " transforms: ";
294  result = transforms_test(geom);
295  handle_error_code(result, number_tests_failed,
296  number_tests_not_implemented,
297  number_tests_successful);
298  number_tests++;
299  std::cout << "\n";
300 
301  // booleans test
302  std::cout << " booleans: ";
303  result = booleans_test(geom);
304  handle_error_code(result, number_tests_failed,
305  number_tests_not_implemented,
306  number_tests_successful);
307  number_tests++;
308  std::cout << "\n";
309 
310  #if defined(HAVE_ACIS) && !defined(FORCE_OCC)
311  std::cout << " mesh size: ";
312  result = mesh_size_test(geom);
313  handle_error_code(result, number_tests_failed,
314  number_tests_not_implemented,
315  number_tests_successful);
316  number_tests++;
317  std::cout << "\n";
318 
319  // save entset test
320  std::cout << " save entset: ";
321  result = save_entset_test(geom);
322  handle_error_code(result, number_tests_failed,
323  number_tests_not_implemented,
324  number_tests_successful);
325  number_tests++;
326  std::cout << "\n";
327  #endif
328  */
329  // shutdown test
330  std::cout << " shutdown: ";
331  std::string engine_opt;
332  result = shutdown_test2( geom, engine_opt );
333  handle_error_code( result, number_tests_failed, number_tests_not_implemented, number_tests_successful );
334  number_tests++;
335  std::cout << "\n";
336 
337  // shutdown imesh instance too
338  iMesh_dtor( mesh, &err );
339  CHECK( "shutdown imesh error" );
340  // summary
341 
342  std::cout << "\nTSTT TEST SUMMARY: \n"
343  << " Number Tests: " << number_tests << "\n"
344  << " Number Successful: " << number_tests_successful << "\n"
345  << " Number Not Implemented: " << number_tests_not_implemented << "\n"
346  << " Number Failed: " << number_tests_failed << "\n\n"
347  << std::endl;
348 
349  return number_tests_failed;
350 }
351 
352 /*!
353  @test
354  Load Mesh
355  @li Load a mesh file
356  */
357 
358 bool smooth_test( const std::string& filename, FBiGeom_Instance geom )
359 {
360  int err;
361  char opts[] = "SMOOTH;";
362  FBiGeom_load( geom, &filename[0], opts, &err, filename.length(), 8 );
363  // FBiGeom_load( geom, &filename[0], 0, &err, filename.length(), 0 );
364  CHECK( "ERROR : can not load a geometry" );
365 
367  FBiGeom_getRootSet( geom, &root_set, &err );
368  CHECK( "ERROR : getRootSet failed!" );
369 
370  // print out the number of entities
371  std::cout << "Model contents: " << std::endl;
372  const char* gtype[] = { "vertices: ", "edges: ", "faces: ", "regions: " };
373  for( int i = 0; i <= 3; ++i )
374  {
375  int count;
376  FBiGeom_getNumOfType( geom, root_set, i, &count, &err );
377  CHECK( "Error: problem getting entities after gLoad." );
378  std::cout << gtype[i] << count << std::endl;
379  }
380 
381  return true;
382 }
383 /*!
384  @test
385  Test tag creating, reading, writing, deleting
386  @li Load a mesh file
387  */
389 {
390  bool success = tag_info_test( geom );
391  if( !success ) return success;
392 
393  success = tag_get_set_test( geom );
394  if( !success ) return success;
395 
396  return true;
397 }
398 
400 {
401  int err;
402 
404  FBiGeom_getRootSet( geom, &root_set, &err );
405  CHECK( "ERROR : getRootSet failed!" );
406 
407  // create an arbitrary tag, size 4
408  iBase_TagHandle this_tag, tmp_handle;
409  std::string tag_name( "tag_info tag" ), tmp_name;
410  FBiGeom_createTag( geom, &tag_name[0], 4, iBase_BYTES, &this_tag, &err, tag_name.length() );
411  CHECK( "ERROR : can not create a tag." );
412 
413  // get information on the tag
414 
415  char name_buffer[256];
416  FBiGeom_getTagName( geom, this_tag, name_buffer, &err, sizeof( name_buffer ) );
417  CHECK( "ERROR : Couldn't get tag name." );
418  if( tag_name != name_buffer )
419  {
420  std::cerr << "ERROR: getTagName returned '" << name_buffer << "' for tag created as '" << tag_name << "'"
421  << std::endl;
422  return false;
423  }
424 
425  FBiGeom_getTagHandle( geom, &tag_name[0], &tmp_handle, &err, tag_name.length() );
426  CHECK( "ERROR : Couldn't get tag handle." );
427  if( tmp_handle != this_tag )
428  {
429  std::cerr << "ERROR: getTagHandle didn't return consistent result." << std::endl;
430  return false;
431  }
432 
433  int tag_size;
434  FBiGeom_getTagSizeBytes( geom, this_tag, &tag_size, &err );
435  CHECK( "ERROR : Couldn't get tag size." );
436  if( tag_size != 4 )
437  {
438  std::cerr << "ERROR: getTagSizeBytes: expected 4, got " << tag_size << std::endl;
439  return false;
440  }
441 
442  FBiGeom_getTagSizeValues( geom, this_tag, &tag_size, &err );
443  CHECK( "ERROR : Couldn't get tag size." );
444  if( tag_size != 4 )
445  {
446  std::cerr << "ERROR: getTagSizeValues: expected 4, got " << tag_size << std::endl;
447  return false;
448  }
449 
450  int tag_type;
451  FBiGeom_getTagType( geom, this_tag, &tag_type, &err );
452  CHECK( "ERROR : Couldn't get tag type." );
453  if( tag_type != iBase_BYTES )
454  {
455  std::cerr << "ERROR: getTagType: expected " << iBase_BYTES << ", got " << tag_type << std::endl;
456  return false;
457  }
458 
459  FBiGeom_destroyTag( geom, this_tag, true, &err );
460  CHECK( "ERROR : Couldn't delete a tag." );
461 
462  // print information about all the tags in the model
463 
464  std::set< iBase_TagHandle > tags;
467  CHECK( "getEntities( ..., iBase_ALL_TYPES, ... ) failed." );
468  for( int i = 0; i < entities.size(); ++i )
469  {
471  FBiGeom_getAllTags( geom, entities[i], ARRAY_INOUT( tag_arr ), &err );
472  CHECK( "getAllTags failed." );
473  std::copy( tag_arr.begin(), tag_arr.end(), std::inserter( tags, tags.begin() ) );
474  }
475 
476  std::cout << "Tags defined on model: ";
477  bool first = true;
478  for( std::set< iBase_TagHandle >::iterator sit = tags.begin(); sit != tags.end(); ++sit )
479  {
480  FBiGeom_getTagName( geom, *sit, name_buffer, &err, sizeof( name_buffer ) );
481  name_buffer[sizeof( name_buffer ) - 1] = '\0'; // mnake sure of NUL termination
482  CHECK( "getTagName failed." );
483 
484  if( !first ) std::cout << ", ";
485  std::cout << name_buffer;
486  first = false;
487  }
488  if( first ) std::cout << "<none>";
489  std::cout << std::endl;
490 
491  return true;
492 }
493 
495 {
496  int err;
497 
498  // create an arbitrary tag, size 4
499  iBase_TagHandle this_tag;
500  std::string tag_name( "tag_get_set tag" );
501  FBiGeom_createTag( geom, &tag_name[0], sizeof( int ), iBase_BYTES, &this_tag, &err, tag_name.length() );
502  CHECK( "ERROR : can not create a tag for get_set test." );
503 
505  FBiGeom_getRootSet( geom, &root_set, &err );
506  CHECK( "ERROR : getRootSet failed!" );
507 
508  // set this tag to an integer on each entity; keep track of total sum
509  int sum = 0, num = 0, dim;
510  for( dim = 0; dim <= 3; dim++ )
511  {
512  SimpleArray< iBase_EntityHandle > gentity_handles;
513  FBiGeom_getEntities( geom, root_set, dim, ARRAY_INOUT( gentity_handles ), &err );
514  int num_ents = gentity_handles.size();
515  std::vector< int > tag_vals( num_ents );
516  for( int i = 0; i < num_ents; ++i )
517  {
518  tag_vals[i] = num;
519  sum += num;
520  ++num;
521  }
522 
523  FBiGeom_setArrData( geom, ARRAY_IN( gentity_handles ), this_tag, (char*)&tag_vals[0],
524  tag_vals.size() * sizeof( int ), &err );
525  CHECK( "ERROR : can't set tag on entities" );
526  }
527 
528  // check tag values for entities now
529  int get_sum = 0;
530  for( dim = 0; dim <= 3; dim++ )
531  {
532  SimpleArray< iBase_EntityHandle > gentity_handles;
533  FBiGeom_getEntities( geom, root_set, dim, ARRAY_INOUT( gentity_handles ), &err );
534  int num_ents = gentity_handles.size();
535 
536  SimpleArray< char > tag_vals;
537  FBiGeom_getArrData( geom, ARRAY_IN( gentity_handles ), this_tag, (void**)tag_vals.ptr(), &tag_vals.capacity(),
538  &tag_vals.size(), &err );
539  CHECK( "ERROR : can't get tag on entities" );
540 
541  int* tag_ptr = (int*)( &tag_vals[0] );
542  for( int i = 0; i < num_ents; ++i )
543  get_sum += tag_ptr[i];
544  }
545 
546  if( get_sum != sum )
547  {
548  std::cerr << "ERROR: getData didn't return consistent results." << std::endl;
549  return false;
550  }
551 
552  FBiGeom_destroyTag( geom, this_tag, true, &err );
553  CHECK( "ERROR : couldn't delete tag." );
554 
555  return true;
556 }
557 
558 /*!
559  @test
560  TSTT gentity sets test (just implemented parts for now)
561  @li Check gentity sets
562  */
563 bool gentityset_test( FBiGeom_Instance geom, bool /*multiset*/, bool /*ordered*/ )
564 {
565  int num_type = 4;
566  iBase_EntitySetHandle ges_array[4];
567  int number_array[4];
568  // int num_all_gentities_super = 0;
569  int ent_type = iBase_VERTEX;
570 
571  int err;
573  FBiGeom_getRootSet( geom, &root_set, &err );
574  CHECK( "ERROR : getRootSet failed!" );
575 
576  // get the number of sets in the whole model
577  int all_sets = 0;
578  FBiGeom_getNumEntSets( geom, root_set, 0, &all_sets, &err );
579  CHECK( "Problem getting the number of all gentity sets in whole model." );
580 
581  // add gentities to entitysets by type
582  for( ; ent_type < num_type; ent_type++ )
583  {
584  // initialize the entityset
585  FBiGeom_createEntSet( geom, true, &ges_array[ent_type], &err );
586  CHECK( "Problem creating entityset." );
587 
588  // get entities by type in total "mesh"
590  FBiGeom_getEntities( geom, root_set, ent_type, ARRAY_INOUT( gentities ), &err );
591  CHECK( "Failed to get gentities by type in gentityset_test." );
592 
593  // add gentities into gentity set
594  FBiGeom_addEntArrToSet( geom, ARRAY_IN( gentities ), ges_array[ent_type], &err );
595  CHECK( "Failed to add gentities in entityset_test." );
596 
597  // Check to make sure entity set really has correct number of entities in it
598  FBiGeom_getNumOfType( geom, ges_array[ent_type], ent_type, &number_array[ent_type], &err );
599  CHECK( "Failed to get number of gentities by type in entityset_test." );
600 
601  // compare the number of entities by type
602  int num_type_gentity = gentities.size();
603 
604  if( number_array[ent_type] != num_type_gentity )
605  {
606  std::cerr << "Number of gentities by type is not correct" << std::endl;
607  return false;
608  }
609 
610  // add to number of all entities in super set
611  // num_all_gentities_super += num_type_gentity;
612  }
613 
614  // make a super set having all entitysets
615  iBase_EntitySetHandle super_set;
616  FBiGeom_createEntSet( geom, true, &super_set, &err );
617  CHECK( "Failed to create a super set in gentityset_test." );
618 
619  for( int i = 0; i < num_type; i++ )
620  {
621  FBiGeom_addEntSet( geom, ges_array[i], super_set, &err );
622  CHECK( "Failed to create a super set in gentityset_test." );
623  }
624 
625  //----------TEST BOOLEAN OPERATIONS----------------//
626 
627  iBase_EntitySetHandle temp_ges1;
628  FBiGeom_createEntSet( geom, true, &temp_ges1, &err );
629  CHECK( "Failed to create a super set in gentityset_test." );
630 
631  // Subtract
632  // add all EDGEs and FACEs to temp_es1
633  // get all EDGE entities
634  SimpleArray< iBase_EntityHandle > gedges, gfaces, temp_gentities1;
635  FBiGeom_getEntities( geom, ges_array[iBase_EDGE], iBase_EDGE, ARRAY_INOUT( gedges ), &err );
636  CHECK( "Failed to get gedge gentities in gentityset_test." );
637 
638  // add EDGEs to ges1
639  FBiGeom_addEntArrToSet( geom, ARRAY_IN( gedges ), temp_ges1, &err );
640  CHECK( "Failed to add gedge gentities in gentityset_test." );
641 
642  // get all FACE gentities
643  FBiGeom_getEntities( geom, ges_array[iBase_FACE], iBase_FACE, ARRAY_INOUT( gfaces ), &err );
644  CHECK( "Failed to get gface gentities in gentityset_test." );
645 
646  // add FACEs to es1
647  FBiGeom_addEntArrToSet( geom, ARRAY_IN( gfaces ), temp_ges1, &err );
648  CHECK( "Failed to add gface gentities in gentityset_test." );
649 
650  // subtract EDGEs
651  FBiGeom_subtract( geom, temp_ges1, ges_array[iBase_EDGE], &temp_ges1, &err );
652  CHECK( "Failed to subtract gentitysets in gentityset_test." );
653 
654  FBiGeom_getEntities( geom, temp_ges1, iBase_FACE, ARRAY_INOUT( temp_gentities1 ), &err );
655  CHECK( "Failed to get gface gentities in gentityset_test." );
656 
657  if( gfaces.size() != temp_gentities1.size() )
658  {
659  std::cerr << "Number of entitysets after subtraction not correct \
660  in gentityset_test."
661  << std::endl;
662  return false;
663  }
664 
665  // check there's nothing but gfaces in temp_ges1
666  int num_gents;
667  FBiGeom_getNumOfType( geom, temp_ges1, iBase_EDGE, &num_gents, &err );
668  CHECK( "Failed to get dimensions of gentities in gentityset_test." );
669  if( 0 != num_gents )
670  {
671  std::cerr << "Subtraction failed to remove all edges" << std::endl;
672  return false;
673  }
674 
675  //------------Intersect------------
676  //
677 
678  // clean out the temp_ges1
679  FBiGeom_rmvEntArrFromSet( geom, ARRAY_IN( gfaces ), temp_ges1, &err );
680  CHECK( "Failed to remove gface gentities in gentityset_test." );
681 
682  // check if it is really cleaned out
683  FBiGeom_getNumOfType( geom, temp_ges1, iBase_FACE, &num_gents, &err );
684  CHECK( "Failed to get number of gentities by type in gentityset_test." );
685 
686  if( num_gents != 0 )
687  {
688  std::cerr << "failed to remove correctly." << std::endl;
689  return false;
690  }
691 
692  // add EDGEs to temp ges1
693  FBiGeom_addEntArrToSet( geom, ARRAY_IN( gedges ), temp_ges1, &err );
694  CHECK( "Failed to add gedge gentities in gentityset_test." );
695 
696  // add FACEs to temp ges1
697  FBiGeom_addEntArrToSet( geom, ARRAY_IN( gfaces ), temp_ges1, &err );
698  CHECK( "Failed to add gface gentities in gentityset_test." );
699 
700  // intersect temp_ges1 with gedges set
701  // temp_ges1 entityset is altered
702  FBiGeom_intersect( geom, temp_ges1, ges_array[iBase_EDGE], &temp_ges1, &err );
703  CHECK( "Failed to intersect in gentityset_test." );
704 
705  // try to get FACEs, but there should be nothing but EDGE
706  FBiGeom_getNumOfType( geom, temp_ges1, iBase_FACE, &num_gents, &err );
707  CHECK( "Failed to get gface gentities in gentityset_test." );
708 
709  if( num_gents != 0 )
710  {
711  std::cerr << "wrong number of gfaces." << std::endl;
712  return false;
713  }
714 
715  //-------------Unite--------------
716 
717  // get all regions
718  iBase_EntitySetHandle temp_ges2;
720 
721  FBiGeom_createEntSet( geom, true, &temp_ges2, &err );
722  CHECK( "Failed to create a temp gentityset in gentityset_test." );
723 
724  FBiGeom_getEntities( geom, ges_array[iBase_REGION], iBase_REGION, ARRAY_INOUT( gregions ), &err );
725  CHECK( "Failed to get gregion gentities in gentityset_test." );
726 
727  // add REGIONs to temp es2
728  FBiGeom_addEntArrToSet( geom, ARRAY_IN( gregions ), temp_ges2, &err );
729  CHECK( "Failed to add gregion gentities in gentityset_test." );
730 
731  // unite temp_ges1 and temp_ges2
732  // temp_ges1 gentityset is altered
733  FBiGeom_unite( geom, temp_ges1, temp_ges2, &temp_ges1, &err );
734  CHECK( "Failed to unite in gentityset_test." );
735 
736  // perform the check
737  FBiGeom_getNumOfType( geom, temp_ges1, iBase_REGION, &num_gents, &err );
738  CHECK( "Failed to get number of gregion gentities by type in gentityset_test." );
739 
740  if( num_gents != number_array[iBase_REGION] )
741  {
742  std::cerr << "different number of gregions in gentityset_test." << std::endl;
743  return false;
744  }
745 
746  //--------Test parent/child stuff in entiysets-----------
747 
748  // Add 2 sets as children to another
749  iBase_EntitySetHandle parent_child;
750  FBiGeom_createEntSet( geom, true, &parent_child, &err );
751  CHECK( "Problem creating gentityset in gentityset_test." );
752 
753  FBiGeom_addPrntChld( geom, ges_array[iBase_VERTEX], parent_child, &err );
754  CHECK( "Problem add parent in gentityset_test." );
755 
756  // check if parent is really added
758  FBiGeom_getPrnts( geom, parent_child, 1, ARRAY_INOUT( parents ), &err );
759  CHECK( "Problem getting parents in gentityset_test." );
760 
761  if( parents.size() != 1 )
762  {
763  std::cerr << "number of parents is not correct in gentityset_test." << std::endl;
764  return false;
765  }
766 
767  // add parent and child
768  // sidl::array<void*> parent_child_array = sidl::array<void*>::create1d(1);
769  // int num_parent_child_array;
770  // sidl::array<void*> temp_gedge_array = sidl::array<void*>::create1d(1);
771  // int num_temp_gedge_array;
772  // parent_child_array.set(0, parent_child);
773  // temp_gedge_array.set(0, ges_array[TSTTG::EntityType_EDGE]);
774  FBiGeom_addPrntChld( geom, ges_array[iBase_EDGE], parent_child, &err );
775  CHECK( "Problem adding parent and child in gentityset_test." );
776 
777  // sidl::array<void*> temp_gface_array = sidl::array<void*>::create1d(1);
778  // int num_temp_gface_array;
779  // temp_gface_array.set(0, ges_array[TSTTG::EntityType_FACE]);
780  FBiGeom_addPrntChld( geom, parent_child, ges_array[iBase_FACE], &err );
781  CHECK( "Problem adding parent and child in gentityset_test." );
782 
783  // add child
784  FBiGeom_addPrntChld( geom, parent_child, ges_array[iBase_REGION], &err );
785  CHECK( "Problem adding child in gentityset_test." );
786 
787  // get the number of parent gentitysets
788  num_gents = -1;
789  FBiGeom_getNumPrnt( geom, parent_child, 1, &num_gents, &err );
790  CHECK( "Problem getting number of parents in gentityset_test." );
791 
792  if( num_gents != 2 )
793  {
794  std::cerr << "number of parents is not correct in gentityset_test." << std::endl;
795  return false;
796  }
797 
798  // get the number of child gentitysets
799  num_gents = -1;
800  FBiGeom_getNumChld( geom, parent_child, 1, &num_gents, &err );
801  CHECK( "Problem getting number of children in gentityset_test." );
802 
803  if( num_gents != 2 )
804  {
805  std::cerr << "number of children is not correct in gentityset_test." << std::endl;
806  return false;
807  }
808 
810  FBiGeom_getChldn( geom, parent_child, 1, ARRAY_INOUT( children ), &err );
811  CHECK( "Problem getting children in gentityset_test." );
812 
813  if( children.size() != 2 )
814  {
815  std::cerr << "number of children is not correct in gentityset_test." << std::endl;
816  return false;
817  }
818 
819  // remove children
820  FBiGeom_rmvPrntChld( geom, parent_child, ges_array[iBase_FACE], &err );
821  CHECK( "Problem removing parent child in gentityset_test." );
822 
823  // get the number of child gentitysets
824  FBiGeom_getNumChld( geom, parent_child, 1, &num_gents, &err );
825  CHECK( "Problem getting number of children in gentityset_test." );
826 
827  if( num_gents != 1 )
828  {
829  std::cerr << "number of children is not correct in gentityset_test." << std::endl;
830  return false;
831  }
832 
833  // parent_child and ges_array[TSTTG::EntityType_EDGE] should be related
834  int result = 0;
835  FBiGeom_isChildOf( geom, ges_array[iBase_EDGE], parent_child, &result, &err );
836  CHECK( "Problem checking relation in gentityset_test." );
837  if( !result )
838  {
839  std::cerr << "parent_child and ges_array[TSTTG::EntityType_EDGE] should be related" << std::endl;
840  return false;
841  }
842 
843  // ges_array[TSTTG::EntityType_FACE] and ges_array[TSTTG::REGION] are not related
844  result = 2;
845  FBiGeom_isChildOf( geom, ges_array[iBase_FACE], ges_array[iBase_REGION], &result, &err );
846  if( result )
847  {
848  std::cerr << "ges_array[TSTTG::REGION] and ges_array[TSTTG::EntityType_FACE] should not be "
849  "related"
850  << std::endl;
851  return false;
852  }
853 
854  //--------test modify and query functions-----------------------------
855 
856  // check the number of gentity sets in whole mesh
858  FBiGeom_getEntSets( geom, root_set, 1, ARRAY_INOUT( gentity_sets ), &err );
859  CHECK( "Problem to get all gentity sets in mesh." );
860 
861  if( gentity_sets.size() != all_sets + 8 )
862  {
863  std::cerr << "the number of gentity sets in whole mesh should be 8 times of num_iter." << std::endl;
864  return false;
865  }
866 
867  // get all gentity sets in super set
869  FBiGeom_getEntSets( geom, super_set, 1, ARRAY_INOUT( ges_array1 ), &err );
870  CHECK( "Problem to get gentity sets in super set." );
871 
872  // get the number of gentity sets in super set
873  int num_super;
874  FBiGeom_getNumEntSets( geom, super_set, 1, &num_super, &err );
875  CHECK( "Problem to get the number of all gentity sets in super set." );
876 
877  // the number of gentity sets in super set should be same
878  if( num_super != ges_array1.size() )
879  {
880  std::cerr << "the number of gentity sets in super set should be same." << std::endl;
881  return false;
882  }
883 
884  // get all entities in super set
886  FBiGeom_getEntSets( geom, super_set, 1, ARRAY_INOUT( all_gentities ), &err );
887  CHECK( "Problem to get all gentities in super set." );
888 
889  // compare the number of all gentities in super set
890  // HJK : num_hops is not implemented
891  // if (num_all_gentities_super != ARRAY_SIZE(all_gentities)) {
892  // std::cerr << "number of all gentities in super set should be same." << std::endl;
893  // success = false;
894  //}
895 
896  // test add, remove and get all entitiy sets using super set
897  // check GetAllGentitysets works recursively and dosen't return
898  // multi sets
899  for( int k = 0; k < num_super; k++ )
900  {
901  // add gentity sets of super set to each gentity set of super set
902  // make multiple child super sets
903  iBase_EntitySetHandle ges_k = ges_array1[k];
904 
905  for( int a = 0; a < ges_array1.size(); a++ )
906  {
907  FBiGeom_addEntSet( geom, ges_array1[a], ges_k, &err );
908  CHECK( "Problem to add entity set." );
909  }
910 
911  // add super set to each entity set
912  // sidl::array<GentitysetHandle> superset_array
913  //= sidl::array<GentitysetHandle>::create1d(1);
914  // superset_array.set(0, super_set);
915  // int num_superset_array;
916 
917  FBiGeom_addEntSet( geom, super_set, ges_k, &err );
918  CHECK( "Problem to add super set to gentitysets." );
919 
920  // add one gentity sets multiple times
921  // HJK: ??? how to deal this case?
922  // sidl::array<GentitysetHandle> temp_array1
923  //= sidl::array<GentitysetHandle>::create1d(1);
924  // int num_temp_array1;
925  // temp_array1.set(0, temp_ges1);
926 
927  // for (int l = 0; l < 3; l++) {
928  FBiGeom_addEntSet( geom, temp_ges1, ges_k, &err );
929  CHECK( "Problem to add temp set to gentitysets." );
930  //}
931  }
932 
933  return true;
934 }
935 
936 /*!
937  @test
938  TSTTG topology adjacencies Test
939  @li Check topology information
940  @li Check adjacency
941  */
942 // make each topological entity vectors, check their topology
943 // types, get interior and exterior faces of model
945 {
946  int i, err;
948  FBiGeom_getRootSet( geom, &root_set, &err );
949  CHECK( "ERROR : getRootSet failed!" );
950 
951  int top = iBase_VERTEX;
952  int num_test_top = iBase_ALL_TYPES;
953  std::vector< std::vector< iBase_EntityHandle > > gentity_vectors( num_test_top );
954 
955  // fill the vectors of each topology entities
956  // like lines vector, polygon vector, triangle vector,
957  // quadrilateral, polyhedrron, tet, hex, prism, pyramid,
958  // septahedron vectors
959  for( i = top; i < num_test_top; i++ )
960  {
962  FBiGeom_getEntities( geom, root_set, i, ARRAY_INOUT( gentities ), &err );
963  CHECK( "Failed to get gentities in adjacencies_test." );
964 
965  gentity_vectors[i].resize( gentities.size() );
966  std::copy( gentities.begin(), gentities.end(), gentity_vectors[i].begin() );
967  }
968 
969  // check number of entities for each topology
970  for( i = top; i < num_test_top; i++ )
971  {
972  int num_tops = 0;
973  FBiGeom_getNumOfType( geom, root_set, i, &num_tops, &err );
974  CHECK( "Failed to get number of gentities in adjacencies_test." );
975 
976  if( static_cast< int >( gentity_vectors[i].size() ) != num_tops )
977  {
978  std::cerr << "Number of gentities doesn't agree with number returned for dimension " << i << std::endl;
979  return false;
980  }
981  }
982 
983  // check adjacencies in both directions
984  std::vector< iBase_EntityHandle >::iterator vit;
985  for( i = iBase_REGION; i >= iBase_VERTEX; i-- )
986  {
987  for( vit = gentity_vectors[i].begin(); vit != gentity_vectors[i].end(); ++vit )
988  {
989  iBase_EntityHandle this_gent = *vit;
990 
991  // check downward adjacencies
992  for( int j = iBase_VERTEX; j < i; j++ )
993  {
994 
996  FBiGeom_getEntAdj( geom, this_gent, j, ARRAY_INOUT( lower_ents ), &err );
997  CHECK( "Bi-directional adjacencies test failed." );
998 
999  // for each of them, make sure they are adjacent to the upward ones
1000  int num_lower = lower_ents.size();
1001  for( int k = 0; k < num_lower; k++ )
1002  {
1004  FBiGeom_getEntAdj( geom, lower_ents[k], i, ARRAY_INOUT( upper_ents ), &err );
1005  CHECK( "Bi-directional adjacencies test failed." );
1006  if( std::find( upper_ents.begin(), upper_ents.end(), this_gent ) == upper_ents.end() )
1007  {
1008  std::cerr << "Didn't find lower-upper adjacency which was supposed to be "
1009  "there, dims = "
1010  << i << ", " << j << std::endl;
1011  return false;
1012  }
1013  }
1014  }
1015  }
1016  }
1017 
1018  return true;
1019 }
1020 
1021 /*!
1022  @test
1023  FBiGeom_MOAB topology adjacencies Test
1024  @li Check topology information
1025  @li Check adjacency
1026  */
1027 // make each topological entity vectors, check their topology
1028 // types, get interior and exterior faces of model
1030 {
1031  int i, err;
1033  FBiGeom_getRootSet( geom, &root_set, &err );
1034  CHECK( "ERROR : getRootSet failed!" );
1035 
1036  int top = iBase_VERTEX;
1037  int num_test_top = iBase_ALL_TYPES;
1038  std::vector< std::vector< iBase_EntityHandle > > gentity_vectors( num_test_top );
1039 
1040  // fill the vectors of each topology entities
1041  // like lines vector, polygon vector, triangle vector,
1042  // quadrilateral, polyhedrron, tet, hex, prism, pyramid,
1043  // septahedron vectors
1044  for( i = top; i < num_test_top; i++ )
1045  {
1047  FBiGeom_getEntities( geom, root_set, i, ARRAY_INOUT( gentities ), &err );
1048  CHECK( "Failed to get gentities in adjacencies_test." );
1049 
1050  gentity_vectors[i].resize( gentities.size() );
1051  std::copy( gentities.begin(), gentities.end(), gentity_vectors[i].begin() );
1052  }
1053 
1054  // check adjacencies in both directions
1055  double min[3], max[3], on[3];
1056  double near[3] = { .0, .0, .0 };
1057  std::vector< iBase_EntityHandle >::iterator vit;
1058  for( i = iBase_REGION; i >= iBase_VERTEX; i-- )
1059  {
1060  if( i != iBase_EDGE )
1061  {
1062  for( vit = gentity_vectors[i].begin(); vit != gentity_vectors[i].end(); ++vit )
1063  {
1064  iBase_EntityHandle this_gent = *vit;
1065  FBiGeom_getEntBoundBox( geom, this_gent, &min[0], &min[1], &min[2], &max[0], &max[1], &max[2], &err );
1066  CHECK( "Failed to get bounding box of entity." );
1067 
1068  for( int j = 0; j < 3; j++ )
1069  near[j] = ( min[j] + max[j] ) / 2;
1070  FBiGeom_getEntClosestPt( geom, this_gent, near[0], near[1], near[2], &on[0], &on[1], &on[2], &err );
1071  CHECK( "Failed to get closest point on entity." );
1072  std::cout << " entity of type " << i << " closest point to \n " << near[0] << " " << near[1] << " "
1073  << near[2] << "\n is " << on[0] << " " << on[1] << " " << on[2] << "\n";
1074  }
1075  }
1076  }
1077 
1078  return true;
1079 }
1080 //
1081 // test normals evaluations on the surface only
1083 {
1084  int i, err;
1086  FBiGeom_getRootSet( geom, &root_set, &err );
1087  CHECK( "ERROR : getRootSet failed!" );
1088 
1089  int top = iBase_VERTEX;
1090  int num_test_top = iBase_ALL_TYPES;
1091  std::vector< std::vector< iBase_EntityHandle > > gentity_vectors( num_test_top );
1092 
1093  // fill the vectors of each topology entities
1094  // like lines vector, polygon vector, triangle vector,
1095  // quadrilateral, polyhedrron, tet, hex, prism, pyramid,
1096  // septahedron vectors
1097  for( i = top; i < num_test_top; i++ )
1098  {
1100  FBiGeom_getEntities( geom, root_set, i, ARRAY_INOUT( gentities ), &err );
1101  CHECK( "Failed to get gentities in adjacencies_test." );
1102 
1103  gentity_vectors[i].resize( gentities.size() );
1104  std::copy( gentities.begin(), gentities.end(), gentity_vectors[i].begin() );
1105  }
1106 
1107  // check adjacencies in both directions
1108  double min[3], max[3];
1109  double normal[3] = { .0, .0, .0 };
1110  std::vector< iBase_EntityHandle >::iterator vit;
1111  for( i = iBase_REGION; i > iBase_EDGE; i-- )
1112  {
1113  for( vit = gentity_vectors[i].begin(); vit != gentity_vectors[i].end(); ++vit )
1114  {
1115  iBase_EntityHandle this_gent = *vit;
1116  FBiGeom_getEntBoundBox( geom, this_gent, &min[0], &min[1], &min[2], &max[0], &max[1], &max[2], &err );
1117  CHECK( "Failed to get bounding box of entity." );
1118 
1119  FBiGeom_getEntNrmlXYZ( geom, this_gent, ( max[0] + min[0] ) / 2, ( max[1] + min[1] ) / 2,
1120  ( max[2] + min[2] ) / 2, &normal[0], &normal[1], &normal[2], &err );
1121 
1122  CHECK( "Failed to get normal to the closest point." );
1123  std::cout << " entity of type " << i << " closest normal to center:\n " << normal[0] << " " << normal[1]
1124  << " " << normal[2] << "\n";
1125  }
1126  }
1127 
1128  return true;
1129 }
1130 
1131 // test normals evaluations on the surface only
1133 {
1134  int err;
1136  FBiGeom_getRootSet( geom, &root_set, &err );
1137  CHECK( "ERROR : getRootSet failed!" );
1138 
1139  int top = iBase_FACE;
1140 
1142  FBiGeom_getEntities( geom, root_set, top, ARRAY_INOUT( faces ), &err );
1143  CHECK( "Failed to get gentities in adjacencies_test." );
1144 
1145  // check only the first face
1146 
1147  // check adjacencies in both directions
1148  double min[3], max[3];
1149 
1150  iBase_EntityHandle first_face = faces[0];
1151 
1152  FBiGeom_getEntBoundBox( geom, first_face, &min[0], &min[1], &min[2], &max[0], &max[1], &max[2], &err );
1153  CHECK( "Failed to get bounding box of entity." );
1154 
1155  // assume that the ray shot from the bottom of the box (middle) is a pretty good candidate
1156  // in z direction
1157  double x = ( min[0] + max[0] ) / 2, y = ( min[1] + max[1] ) / 2, z = min[2];
1158  SimpleArray< iBase_EntityHandle > intersect_entity_handles;
1159  SimpleArray< double > intersect_coords;
1160  SimpleArray< double > param_coords;
1161  FBiGeom_getPntRayIntsct( geom, x, y, z, // shot from
1162  0., 0., 1., // direction
1163  ARRAY_INOUT( intersect_entity_handles ), iBase_INTERLEAVED,
1164  ARRAY_INOUT( intersect_coords ), ARRAY_INOUT( param_coords ), &err );
1165 
1166  CHECK( "Failed to find ray intersections points " );
1167  for( int i = 0; i < intersect_entity_handles.size(); i++ )
1168  {
1169  int j;
1170  FBiGeom_getEntType( geom, intersect_entity_handles[i], &j, &err );
1171  CHECK( "Failed to get type of entity." );
1172 
1173  std::cout << " entity of type " << j << " n: " << intersect_entity_handles[i] << "\n"
1174  << intersect_coords[3 * i] << " " << intersect_coords[3 * i + 1] << " " << intersect_coords[3 * i + 2]
1175  << "\n"
1176  << " distance: " << param_coords[i] << "\n";
1177  }
1178 
1179  return true;
1180 }
1181 
1182 /*!
1183  @test
1184  TSTTG construct Test
1185  @li Check construction of geometry
1186  */
1188 {
1189  int err;
1190  iBase_EntityHandle new_body = 0;
1191 
1192  // construct a cylinder, sweep it about an axis, and delete the result
1193  iBase_EntityHandle cyl = 0;
1194  FBiGeom_createCylinder( geom, 1.0, 1.0, 0.0, &cyl, &err );
1195  // Is the minor radius really supposed to be zero??? - JK
1196  CHECK( "Creating cylinder failed." );
1197 
1198  // move it onto the y axis
1199  FBiGeom_moveEnt( geom, cyl, 0.0, 1.0, -0.5, &err );
1200  CHECK( "Problems moving surface." );
1201 
1202  // get the surface with max z
1203  iBase_EntityHandle max_surf = 0;
1205  FBiGeom_getEntAdj( geom, cyl, iBase_FACE, ARRAY_INOUT( surfs ), &err );
1206  CHECK( "Problems getting max surf for rotation." );
1207 
1208  SimpleArray< double > max_corn, min_corn;
1210  ARRAY_INOUT( max_corn ), &err );
1211  CHECK( "Problems getting max surf for rotation." );
1212  double dtol = 1.0e-6;
1213  for( int i = 0; i < surfs.size(); ++i )
1214  {
1215  if( ( max_corn[3 * i + 2] ) <= dtol && ( max_corn[3 * i + 2] ) >= -dtol && ( min_corn[3 * i + 2] ) <= dtol &&
1216  ( min_corn[3 * i + 2] ) >= -dtol )
1217  {
1218  max_surf = surfs[i];
1219  break;
1220  }
1221  }
1222 
1223  if( 0 == max_surf )
1224  {
1225  std::cerr << "Couldn't find max surf for rotation." << std::endl;
1226  return false;
1227  }
1228 
1229  // sweep it around the x axis
1230  FBiGeom_moveEnt( geom, cyl, 0.0, 1.0, 0.0, &err );
1231  CHECK( "Problems moving surface." );
1232 
1233  FBiGeom_sweepEntAboutAxis( geom, max_surf, 360.0, 1.0, 0.0, 0.0, &new_body, &err );
1234  CHECK( "Problems sweeping surface about axis." );
1235 
1236  // now delete
1237  FBiGeom_deleteEnt( geom, new_body, &err );
1238  CHECK( "Problems deleting cylinder or swept surface body." );
1239 
1240  // if we got here, we were successful
1241  return true;
1242 }
1243 
1244 static bool compare_box( const double* expected_min,
1245  const double* expected_max,
1246  const double* actual_min,
1247  const double* actual_max )
1248 {
1249  bool same = true;
1250  double dtol = 1.0e-6;
1251 
1252  for( int i = 0; i < 3; ++i )
1253  {
1254  if( expected_min[i] < actual_min[i] - dtol || expected_min[i] * 10 > actual_min[i] ||
1255  expected_max[i] > actual_max[i] + dtol || expected_max[i] * 10 < actual_max[i] )
1256  same = false;
1257  }
1258  return same;
1259 }
1260 
1262 {
1263  int err;
1265  iBase_EntityHandle prim;
1266 
1267  FBiGeom_createBrick( geom, 1.0, 2.0, 3.0, &prim, &err );
1268  CHECK( "createBrick failed." );
1269  prims[0] = prim;
1270 
1271  FBiGeom_createCylinder( geom, 1.0, 4.0, 2.0, &prim, &err );
1272  CHECK( "createCylinder failed." );
1273  prims[1] = prim;
1274 
1275  FBiGeom_createTorus( geom, 2.0, 1.0, &prim, &err );
1276  CHECK( "createTorus failed." );
1277  prims[2] = prim;
1278 
1279  // verify the bounding boxes for Acis based entities
1280  SimpleArray< double > max_corn, min_corn;
1282  ARRAY_INOUT( max_corn ), &err );
1283 
1284  double preset_min_corn[] =
1285  // min brick corner xyz
1286  { -0.5, -1.0, -1.5,
1287  // min cyl corner xyz
1288  -4.0, -2.0, -0.5,
1289  // min torus corner xyz
1290  -3.0, -3.0, -1.0 };
1291 
1292  double preset_max_corn[] =
1293  // max brick corner xyz
1294  { 0.5, 1.0, 1.5,
1295  // max cyl corner xyz
1296  4.0, 2.0, 0.5,
1297  // max torus corner xyz
1298  3.0, 3.0, 1.0 };
1299 
1300  if( !compare_box( preset_min_corn, preset_max_corn, &min_corn[0], &max_corn[0] ) )
1301  {
1302  std::cerr << "Box check failed for brick" << std::endl;
1303  return false;
1304  }
1305 
1306  if( !compare_box( preset_min_corn + 3, preset_max_corn + 3, &min_corn[3], &max_corn[3] ) )
1307  {
1308  std::cerr << "Box check failed for cylinder" << std::endl;
1309  return false;
1310  }
1311 
1312  if( !compare_box( preset_min_corn + 6, preset_max_corn + 6, &min_corn[6], &max_corn[6] ) )
1313  {
1314  std::cerr << "Box check failed for torus" << std::endl;
1315  return false;
1316  }
1317  // must have worked; delete the entities then return
1318  for( int i = 0; i < 3; ++i )
1319  {
1320  FBiGeom_deleteEnt( geom, prims[i], &err );
1321  CHECK( "Problems deleting primitive after boolean check." );
1322  }
1323 
1324  return true;
1325 }
1326 
1328 {
1329  int err;
1330 
1331  // construct a brick
1332  iBase_EntityHandle brick = 0;
1333  FBiGeom_createBrick( geom, 1.0, 2.0, 3.0, &brick, &err );
1334  CHECK( "Problems creating brick for transforms test." );
1335 
1336  // move it, then test bounding box
1337  FBiGeom_moveEnt( geom, brick, 0.5, 1.0, 1.5, &err );
1338  CHECK( "Problems moving brick for transforms test." );
1339 
1340  double bb_min[3], bb_max[3];
1341  FBiGeom_getEntBoundBox( geom, brick, bb_min, bb_min + 1, bb_min + 2, bb_max, bb_max + 1, bb_max + 2, &err );
1342  CHECK( "Problems getting bounding box after move." );
1343 
1344  double dtol = 1.0e-6;
1345  if( ( bb_min[0] ) >= dtol || ( bb_min[0] ) <= -dtol || ( bb_min[1] ) >= dtol || ( bb_min[1] ) <= -dtol ||
1346  ( bb_min[2] ) >= dtol || ( bb_min[2] ) <= -dtol || ( bb_max[0] - 1 ) >= dtol || 1 - bb_max[0] >= dtol ||
1347  ( bb_max[1] - 2 ) >= dtol || 2 - bb_max[1] >= dtol || ( bb_max[2] - 3 ) >= dtol || 3 - bb_max[2] >= dtol )
1348  {
1349  std::cerr << "Wrong bounding box after move." << std::endl;
1350  return false;
1351  }
1352 
1353  // now rotate it about +x, then test bounding box
1354  FBiGeom_rotateEnt( geom, brick, 90, 1.0, 0.0, 0.0, &err );
1355  CHECK( "Problems rotating brick for transforms test." );
1356 
1357  FBiGeom_getEntBoundBox( geom, brick, bb_min, bb_min + 1, bb_min + 2, bb_max, bb_max + 1, bb_max + 2, &err );
1358  CHECK( "Problems getting bounding box after rotate." );
1359 
1360  if( ( bb_min[0] ) >= dtol || -bb_min[0] >= dtol || ( bb_min[1] + 3 ) >= dtol || -( bb_min[1] + 3 ) >= dtol ||
1361  ( bb_min[2] ) >= dtol || -( bb_min[2] ) >= dtol || ( bb_max[0] - 1 ) >= dtol || 1 - bb_max[0] >= dtol ||
1362  ( bb_max[1] ) >= dtol || -( bb_max[1] ) >= dtol || ( bb_max[2] - 2 ) >= dtol || 2 - bb_max[2] >= dtol )
1363  {
1364  std::cerr << "Wrong bounding box after rotate." << std::endl;
1365  return false;
1366  }
1367 
1368  // now reflect through y plane; should recover original bb
1369  FBiGeom_reflectEnt( geom, brick, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, &err );
1370  CHECK( "Problems reflecting brick for transforms test." );
1371 
1372  FBiGeom_getEntBoundBox( geom, brick, bb_min, bb_min + 1, bb_min + 2, bb_max, bb_max + 1, bb_max + 2, &err );
1373  CHECK( "Problems getting bounding box after reflect." );
1374 
1375  if( ( bb_min[0] ) >= dtol || -( bb_min[0] ) >= dtol || ( bb_min[1] ) >= dtol || ( bb_min[2] ) >= dtol ||
1376  -( bb_min[1] ) >= dtol || -( bb_min[2] ) >= dtol || ( bb_max[0] - 1 ) >= dtol || 1 - bb_max[0] >= dtol ||
1377  ( bb_max[1] - 3 ) >= dtol || 3 - bb_max[1] >= dtol || ( bb_max[2] - 2 ) >= dtol || 2 - bb_max[2] >= dtol )
1378  {
1379  std::cerr << "Wrong bounding box after reflect." << std::endl;
1380  return false;
1381  }
1382 
1383  // must have worked; delete the entities then return
1384  FBiGeom_deleteEnt( geom, brick, &err );
1385  CHECK( "Problems deleting brick after transforms check." );
1386  return true;
1387 }
1388 
1390 {
1391  int err;
1392 
1393  // construct a brick size 1, and a cylinder rad 0.25 height 2
1394  iBase_EntityHandle brick = 0, cyl = 0;
1395  FBiGeom_createBrick( geom, 1.0, 0.0, 0.0, &brick, &err );
1396  CHECK( "Problems creating brick for booleans test." );
1397  FBiGeom_createCylinder( geom, 1.0, 0.25, 0.0, &cyl, &err );
1398  CHECK( "Problems creating cylinder for booleans test." );
1399 
1400  // subtract the cylinder from the brick
1401  iBase_EntityHandle subtract_result = 0;
1402  FBiGeom_subtractEnts( geom, brick, cyl, &subtract_result, &err );
1403  CHECK( "Problems subtracting for booleans subtract test." );
1404 
1405  // section the brick
1406  iBase_EntityHandle section_result = 0;
1407  FBiGeom_sectionEnt( geom, subtract_result, 1.0, 0.0, 0.0, 0.25, true, &section_result, &err );
1408  CHECK( "Problems sectioning for booleans section test." );
1409 
1410  // unite the section result with a new cylinder
1411  FBiGeom_createCylinder( geom, 1.0, 0.25, 0.0, &cyl, &err );
1412  CHECK( "Problems creating cylinder for unite test." );
1413  iBase_EntityHandle unite_results;
1414  iBase_EntityHandle unite_input[] = { section_result, cyl };
1415  FBiGeom_uniteEnts( geom, unite_input, 2, &unite_results, &err );
1416  CHECK( "Problems uniting for booleans unite test." );
1417 
1418  FBiGeom_deleteEnt( geom, unite_results, &err );
1419  CHECK( "Problems deleting for booleans unite test." );
1420  return true;
1421 }
1422 
1424  int entity_type,
1425  std::vector< iBase_EntityHandle >& entities_out,
1426  iBase_TagHandle id_tag = 0,
1427  std::vector< int >* ids_out = 0 )
1428 {
1429  int err, num;
1430  iBase_EntitySetHandle root;
1431  FBiGeom_getRootSet( geom, &root, &err );
1432  if( iBase_SUCCESS != err ) return err;
1433  FBiGeom_getNumOfType( geom, root, entity_type, &num, &err );
1434  if( iBase_SUCCESS != err ) return err;
1435 
1436  entities_out.resize( num );
1437  int junk1 = entities_out.size(), junk2;
1438  iBase_EntityHandle* junk_ptr = &entities_out[0];
1439  ;
1440  FBiGeom_getEntities( geom, root, entity_type, &junk_ptr, &junk1, &junk2, &err );
1441  if( iBase_SUCCESS != err ) return err;
1442  assert( num == junk1 && num == junk2 );
1443 
1444  if( !ids_out ) return iBase_SUCCESS;
1445 
1446  ids_out->resize( num );
1447  int* int_ptr = &( *ids_out )[0];
1448  FBiGeom_getIntArrData( geom, &entities_out[0], num, id_tag, &int_ptr, &junk1, &junk2, &err );
1449  if( iBase_SUCCESS != err ) return err;
1450  assert( num == junk1 && num == junk2 );
1451 
1452  return iBase_SUCCESS;
1453 }
1454 
1456  const std::vector< iBase_EntityHandle >& entities,
1457  const std::vector< int >& ids,
1458  iBase_TagHandle firmness_tag,
1459  const char* expected_value,
1460  const char* ent_type_str )
1461 {
1462  const int firmness_size = 4;
1463  std::vector< char > firmness( firmness_size * entities.size() );
1464 
1465  char* byte_ptr = &firmness[0];
1466  int err, junk1 = firmness.size(), junk2 = entities.size() * firmness_size;
1467  FBiGeom_getArrData( geom, &entities[0], entities.size(), firmness_tag, (void**)&byte_ptr, &junk1, &junk2, &err );
1468  if( iBase_SUCCESS != err ) return err;
1469 
1470  bool all_correct = true;
1471  for( unsigned i = 0; i < entities.size(); ++i )
1472  if( std::string( &firmness[firmness_size * i], firmness_size ) != expected_value ) all_correct = false;
1473  if( !all_correct )
1474  {
1475  std::cout << "ERROR: Expected \"" << expected_value << "\" firmness "
1476  << "for all " << ent_type_str << "." << std::endl;
1477  std::cout << "ID Actual " << std::endl;
1478  for( unsigned i = 0; i < entities.size(); ++i )
1479  std::cout << std::setw( 2 ) << ids[i] << " " << std::string( &firmness[firmness_size * i], firmness_size )
1480  << std::endl;
1481  return iBase_FAILURE;
1482  }
1483 
1484  return iBase_SUCCESS;
1485 }
1486 
1488  const std::vector< iBase_EntityHandle >& ents,
1489  iBase_TagHandle tag )
1490 {
1491  int err, bytes;
1492  FBiGeom_getTagSizeBytes( geom, tag, &bytes, &err );
1493  if( iBase_SUCCESS != err ) return -1;
1494  std::vector< char > data( bytes );
1495 
1496  int success_count = 0;
1497  for( size_t i = 0; i < ents.size(); ++i )
1498  {
1499  char* ptr = &data[0];
1500  int junk1 = bytes, junk2;
1501  FBiGeom_getData( geom, ents[i], tag, (void**)&ptr, &junk1, &junk2, &err );
1502  if( iBase_TAG_NOT_FOUND == err ) continue;
1503  if( iBase_SUCCESS != err ) return -1;
1504  ++success_count;
1505  }
1506 
1507  return success_count;
1508 }
1509 
1511 {
1512  const char* filename = STRINGIFY( SRCDIR ) "/size.sat";
1513  int err, junk1, junk2;
1514  bool result = true;
1515 
1516  FBiGeom_deleteAll( geom, &err );
1517  CHECK( "" );
1518  FBiGeom_load( geom, filename, 0, &err, strlen( filename ), 0 );
1519  CHECK( "Failed to load input file: 'size.sat'" );
1520 
1521  // get tag handles
1522  iBase_TagHandle interval, size, firmness, id;
1523  FBiGeom_getTagHandle( geom, "MESH_INTERVAL", &interval, &err, strlen( "MESH_INTERVAL" ) );
1524  CHECK( "FBiGeom_getTagHandle(\"MESH_INTERVAL\")" );
1525  FBiGeom_getTagHandle( geom, "MESH_SIZE", &size, &err, strlen( "MESH_SIZE" ) );
1526  CHECK( "FBiGeom_getTagHandle(\"MESH_SIZE\")" );
1527  FBiGeom_getTagHandle( geom, "SIZE_FIRMNESS", &firmness, &err, strlen( "SIZE_FIRMNESS" ) );
1528  CHECK( "FBiGeom_getTagHandle(\"SIZE_FIRMNESS\")" );
1529  FBiGeom_getTagHandle( geom, "GLOBAL_ID", &id, &err, strlen( "GLOBAL_ID" ) );
1530  CHECK( "FBiGeom_getTagHandle(\"GLOBAL_ID\")" );
1531 
1532  // get entity lists
1533  std::vector< iBase_EntityHandle > verts, curves, surfs, vols;
1534  std::vector< int > vert_ids, curve_ids, surf_ids, vol_ids;
1535  err = get_entities( geom, iBase_VERTEX, verts, id, &vert_ids );
1536  CHECK( "" );
1537  err = get_entities( geom, iBase_EDGE, curves, id, &curve_ids );
1538  CHECK( "" );
1539  err = get_entities( geom, iBase_FACE, surfs, id, &surf_ids );
1540  CHECK( "" );
1541  err = get_entities( geom, iBase_REGION, vols, id, &vol_ids );
1542  CHECK( "" );
1543 
1544  // expect interval count to be the same as ID for every curve
1545  std::vector< int > intervals( curves.size() );
1546  int* int_ptr = &intervals[0];
1547  junk1 = junk2 = curves.size();
1548  FBiGeom_getIntArrData( geom, &curves[0], curves.size(), interval, &int_ptr, &junk1, &junk2, &err );
1549  CHECK( "Failed to get intervals for curves" );
1550  if( intervals != curve_ids )
1551  {
1552  std::cout << "ERROR: Incorrect curve intervals for one or more curves." << std::endl;
1553  std::cout << "ID Expected Actual" << std::endl;
1554  for( unsigned i = 0; i < curves.size(); ++i )
1555  std::cout << std::setw( 2 ) << curve_ids[i] << " " << std::setw( 8 ) << curve_ids[i] << " "
1556  << std::setw( 6 ) << intervals[i] << std::endl;
1557  result = false;
1558  }
1559 
1560  // expect size to be the same as ID for every surface
1561  std::vector< double > sizes( surfs.size() );
1562  double* dbl_ptr = &sizes[0];
1563  junk1 = junk2 = surfs.size();
1564  FBiGeom_getDblArrData( geom, &surfs[0], surfs.size(), size, &dbl_ptr, &junk1, &junk2, &err );
1565  CHECK( "Failed to get sizes for surfaces" );
1566  bool all_correct = true;
1567  for( unsigned i = 0; i < surfs.size(); ++i )
1568  if( fabs( sizes[i] - (double)surf_ids[i] ) > 1e-8 ) all_correct = false;
1569  if( !all_correct )
1570  {
1571  std::cout << "ERROR: Incorrect mesh size for one or more surfaces." << std::endl;
1572  std::cout << "ID Expected Actual " << std::endl;
1573  for( unsigned i = 0; i < surfs.size(); ++i )
1574  std::cout << std::setw( 2 ) << surf_ids[i] << " " << std::setw( 8 ) << (double)surf_ids[i] << " "
1575  << std::setw( 8 ) << sizes[i] << std::endl;
1576  result = false;
1577  }
1578 
1579  err = result ? iBase_SUCCESS : iBase_FAILURE;
1580  CHECK( "Invalid size or interval data" );
1581 
1582  // expect "HARD" firmness on all curves
1583  err = check_firmness( geom, curves, curve_ids, firmness, "HARD", "curves" );
1584  CHECK( "Invalid curve firmness" );
1585  // expect "SOFT" firmness on all surfaces
1586  err = check_firmness( geom, surfs, surf_ids, firmness, "SOFT", "surfaces" );
1587  CHECK( "Invalid surface firmness" );
1588 
1589  // expect no firmnes on other entities
1590  err = count_num_with_tag( geom, verts, firmness ) ? iBase_FAILURE : iBase_SUCCESS;
1591  CHECK( "Got firmness for vertex." );
1592  err = count_num_with_tag( geom, vols, firmness ) ? iBase_FAILURE : iBase_SUCCESS;
1593  CHECK( "Got firmness for volume." );
1594 
1595  // expect no interval tag on any entities except curves
1596  err = count_num_with_tag( geom, verts, interval ) ? iBase_FAILURE : iBase_SUCCESS;
1597  CHECK( "Got interval count for vertex." );
1598  err = count_num_with_tag( geom, vols, interval ) ? iBase_FAILURE : iBase_SUCCESS;
1599  CHECK( "Got interval count for volume." );
1600 
1601  // expect no size tag on any entities except surfaces
1602  // curves should have size of one of their parent surfaces
1604  CHECK( "Got mesh size for vertex." );
1606  CHECK( "Got mesh size for volume." );
1607 
1608  return true;
1609 }
1610 
1611 bool shutdown_test2( FBiGeom_Instance geom, std::string& /*engine_opt*/ )
1612 {
1613  int err;
1614 
1615  // test shutdown2
1616  FBiGeom_dtor2( geom, &err );
1617  CHECK( "Interface destruction didn't work properly." );
1618 
1619  // FBiGeom_newGeom(engine_opt.c_str(), &geom, &err, engine_opt.length());
1620  // CHECK( "Interface re-construction didn't work properly." );
1621  //
1622  // FBiGeom_dtor(geom, &err);
1623  // CHECK( "2nd Interface destruction didn't work properly." );
1624 
1625  return true;
1626 }
1627 
1629 {
1630  int err;
1631 
1632 #ifdef FORCE_OCC
1633  std::string filename = "testout.brep";
1634 #elif defined( HAVE_ACIS )
1635  std::string filename = "testout.sat";
1636 #elif defined( HAVE_OCC )
1637  std::string filename = "testout.brep";
1638 #else
1639  std::string filename = "testout.sat";
1640 #endif
1641 
1642  // initialize number of ents and sets to compare with later
1643  int num_ents_bef, num_sets_bef;
1644  iBase_EntitySetHandle root;
1645  FBiGeom_getRootSet( geom, &root, &err );
1646  CHECK( "Failed to get root set." );
1647  FBiGeom_getNumEntSets( geom, root, 1, &num_sets_bef, &err );
1648  CHECK( "Failed to get number of ent sets." );
1649  FBiGeom_getNumOfType( geom, root, iBase_REGION, &num_ents_bef, &err );
1650  CHECK( "Failed to get number of entities." );
1651 
1652  // create set, and entity to add to set
1653  iBase_EntityHandle cyl;
1654  FBiGeom_createCylinder( geom, 1.0, 0.25, 0.0, &cyl, &err );
1655  CHECK( "Problems creating cylinder for save entset test." );
1656  iBase_EntitySetHandle seth;
1657  FBiGeom_createEntSet( geom, true, &seth, &err );
1658  CHECK( "Problems creating entity set for save entset test." );
1659 
1660  // add the entity
1661  FBiGeom_addEntToSet( geom, cyl, seth, &err );
1662  CHECK( "Problems adding entity to set for save entset test." );
1663 
1664  // save/restore the model, and see if the entity is there
1665  FBiGeom_save( geom, filename.c_str(), NULL, &err, filename.length(), 0 );
1666  CHECK( "Problems saving file for save entset test." );
1667 
1668  FBiGeom_destroyEntSet( geom, seth, &err );
1669  CHECK( "Failed to destroy entity set." );
1670  FBiGeom_deleteEnt( geom, cyl, &err );
1671  CHECK( "Failed to destroy entity." );
1672 
1673  // read the file back in
1674  FBiGeom_load( geom, filename.c_str(), NULL, &err, filename.length(), 0 );
1675  CHECK( "Problems reading file for save entset test." );
1676 
1677  // check number of sets and entities
1678  int num_ents_aft, num_sets_aft;
1679  FBiGeom_getNumEntSets( geom, root, 1, &num_sets_aft, &err );
1680  CHECK( "Failed to get number of ent sets." );
1681  FBiGeom_getNumOfType( geom, root, iBase_REGION, &num_ents_aft, &err );
1682  CHECK( "Failed to get number of entities." );
1683  bool success = true;
1684  if( num_ents_aft != 2 * num_ents_bef + 1 )
1685  {
1686  print_error( "Failed to get the right number of entities.", iBase_FAILURE, geom, __FILE__, __LINE__ );
1687  success = false;
1688  }
1689  else if( num_sets_aft != 2 * num_sets_bef + 1 )
1690  {
1691  print_error( "Failed to get the right number of entity sets.", iBase_FAILURE, geom, __FILE__, __LINE__ );
1692  success = false;
1693  }
1694 
1695  // otherwise, we succeeded
1696  return success;
1697 }