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, §ion_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