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