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