1 #include "moab/MOABConfig.h"
2 #include "iMesh_extensions.h"
3 #include "moab/Core.hpp"
4 #include "moab/Range.hpp"
5 #include "moab/CN.hpp"
6 #include "moab/MeshTopoUtil.hpp"
7 #include "moab/ScdInterface.hpp"
8 #include "moab/FileOptions.hpp"
9 #include "iMesh_MOAB.hpp"
10 #include "MBIter.hpp"
11 #include "MBTagConventions.hpp"
12 #define IS_BUILDING_MB
13 #include "Internals.hpp"
14 #undef IS_BUILDING_MB
15 
16 #ifdef MOAB_HAVE_MPI
17 #include "moab_mpi.h"
18 #include "moab/ParallelComm.hpp"
19 #endif
20 
21 #define STRINGIFY_(X) #X
22 #define STRINGIFY(X) STRINGIFY_(X)
23 #ifdef MOAB_HAVE_UNORDERED_MAP
24 # include STRINGIFY(MOAB_HAVE_UNORDERED_MAP)
25 #else
26 # include <map>
27 #endif
28 
29 #include <iostream>
30 #include <cassert>
31 #include <cctype>
32 #include <cstring>
33 #include <stdarg.h>
34 #include <stdio.h>
35 #define MIN(a,b) (a < b ? a : b)
36 
37 #ifdef _MSC_VER
38 # define snprintf(A,B,C,D) _snprintf((A),(B),(C),(D))
39 #endif
40 
41 static ErrorCode create_int_ents(MBiMesh * mbimesh,
42 				 Range &from_ents,
43 				 const EntityHandle* in_set = 0);
44 #define HANDLE_ARRAY_PTR(array) reinterpret_cast<EntityHandle*>(array)
45 #define CONST_HANDLE_ARRAY_PTR(array) reinterpret_cast<const EntityHandle*>(array)
46 #define TAG_HANDLE(handle) reinterpret_cast<Tag>(handle)
47 #define CONST_TAG_HANDLE(handle) static_cast<const Tag>(handle)
48 #define ENTITY_HANDLE(handle) reinterpret_cast<EntityHandle>(handle)
49 #define CONST_ENTITY_HANDLE(handle) reinterpret_cast<const EntityHandle>(handle)
50 #define CAST_TO_VOID(ptr) reinterpret_cast<void*>(ptr)
51 
52 // map from MB's entity type to TSTT's entity topology
53 const iMesh_EntityTopology tstt_topology_table[] =
54 {
55   iMesh_POINT,          // MBVERTEX
56   iMesh_LINE_SEGMENT,   // MBEDGE
57   iMesh_TRIANGLE,       // MBTRI
58   iMesh_QUADRILATERAL,  // MBQUAD
59   iMesh_POLYGON,        // MBPOLYGON
60   iMesh_TETRAHEDRON,    // MBTET
61   iMesh_PYRAMID,        // MBPYRAMID
62   iMesh_PRISM,          // MBPRISM
63   iMesh_ALL_TOPOLOGIES, // MBKNIFE
64   iMesh_HEXAHEDRON,     // MBHEX
65   iMesh_POLYHEDRON,     // MBPOLYHEDRON
66   iMesh_ALL_TOPOLOGIES, // MBENTITYSET
67   iMesh_ALL_TOPOLOGIES, // MBMAXTYPE
68 };
69 
70 // map from MB's entity type to TSTT's entity type
71 const iBase_EntityType tstt_type_table[] =
72 {
73   iBase_VERTEX,         // MBVERTEX
74   iBase_EDGE,           // MBEDGE
75   iBase_FACE,           // MBTRI
76   iBase_FACE,           // MBQUAD
77   iBase_FACE,           // MBPOLYGON
78   iBase_REGION,         // MBTET
79   iBase_REGION,         // MBPYRAMID
80   iBase_REGION,         // MBPRISM
81   iBase_REGION,         // MBKNIFE
82   iBase_REGION,         // MBHEX
83   iBase_REGION,         // MBPOLYHEDRON
84   iBase_ALL_TYPES, // MBENTITYSET
85   iBase_ALL_TYPES  // MBMAXTYPE
86 };
87 
88 // map to MB's entity type from TSTT's entity topology
89 const EntityType mb_topology_table[] =
90 {
91   MBVERTEX,
92   MBEDGE,
93   MBPOLYGON,
94   MBTRI,
95   MBQUAD,
96   MBPOLYHEDRON,
97   MBTET,
98   MBHEX,
99   MBPRISM,
100   MBPYRAMID,
101   MBMAXTYPE,
102   MBMAXTYPE
103 };
104 
105 // map from TSTT's tag types to MOAB's
106 const DataType mb_data_type_table[] =
107 {
108   MB_TYPE_OPAQUE,
109   MB_TYPE_INTEGER,
110   MB_TYPE_DOUBLE ,
111   MB_TYPE_HANDLE ,
112   MB_TYPE_HANDLE
113 };
114 
115 // map from MOAB's tag types to tstt's
116 const iBase_TagValueType tstt_data_type_table[] =
117 {
118   iBase_BYTES,
119   iBase_INTEGER,
120   iBase_DOUBLE,
121   iBase_BYTES,
122   iBase_ENTITY_HANDLE
123 };
124 
125 const iBase_ErrorType iBase_ERROR_MAP[MB_FAILURE+1] =
126 {
127   iBase_SUCCESS, // MB_SUCCESS = 0,
128   iBase_INVALID_ENTITY_HANDLE, // MB_INDEX_OUT_OF_RANGE,
129   iBase_INVALID_ENTITY_TYPE, // MB_TYPE_OUT_OF_RANGE,
130   iBase_MEMORY_ALLOCATION_FAILED, // MB_MEMORY_ALLOCATION_FAILED,
131   iBase_INVALID_ENTITY_HANDLE, // MB_ENTITY_NOT_FOUND,
132   iBase_NOT_SUPPORTED, // MB_MULTIPLE_ENTITIES_FOUND,
133   iBase_TAG_NOT_FOUND, // MB_TAG_NOT_FOUND,
134   iBase_FILE_NOT_FOUND, // MB_FILE_DOES_NOT_EXIST,
135   iBase_FILE_WRITE_ERROR, // MB_FILE_WRITE_ERROR,
136   iBase_NOT_SUPPORTED, // MB_NOT_IMPLEMENTED,
137   iBase_TAG_ALREADY_EXISTS, // MB_ALREADY_ALLOCATED,
138   iBase_FAILURE, // MB_VARIABLE_DATA_LENGTH,
139   iBase_FAILURE, // MB_INVALID_SIZE,
140   iBase_NOT_SUPPORTED, // MB_UNSUPPORTED_OPERATION,
141   iBase_INVALID_ARGUMENT, // MB_UNHANDLED_OPTION
142   iBase_INVALID_ENTITY_TYPE, // MB_STRUCTURED_MESH
143   iBase_FAILURE // MB_FAILURE};
144 };
145 
146 // Return data about a list of handles for use in check_handle_tag_type.
147 // Set output arguments to true if the list contains the corresponding
148 // type of handle.  Leave them unmodified if it does not.
ht_content_type(const std::vector<EntityHandle> & h,bool & saw_ent,bool & saw_set,bool & saw_root)149 static inline void ht_content_type( const std::vector<EntityHandle>& h,
150                                     bool &saw_ent, bool &saw_set, bool &saw_root )
151 {
152   std::vector<EntityHandle>::const_iterator i;
153   for (i = h.begin(); i != h.end(); ++i) {
154     if (*i == 0)
155       saw_root = true;
156     else if (TYPE_FROM_HANDLE(*i) == MBENTITYSET)
157       saw_set = true;
158     else
159       saw_ent = true;
160   }
161 }
162 
163 // Scan all tag data to try to guess whether the MOAB tag with
164 // data of type MB_TYPE_HANDLE is iBase_ENTITY_HANDLE or
165 // iBase_ENTITY_SET_HANDLE.
check_handle_tag_type(Tag t,MBiMesh * mbi)166 static ErrorCode check_handle_tag_type( Tag t, MBiMesh* mbi )
167 {
168   Interface* mb = mbi->mbImpl;
169   ErrorCode rval;
170   int size;
171   DataType type;
172   rval = mb->tag_get_data_type( t, type );
173   if (MB_SUCCESS != rval) return rval;
174   if (MB_TYPE_HANDLE != type) return MB_TYPE_OUT_OF_RANGE;
175   rval = mb->tag_get_length( t, size );
176   if (MB_SUCCESS != rval) return rval;
177   std::vector<EntityHandle> data(size);
178 
179     // check for global/mesh value
180   bool saw_set = false, saw_ent = false, saw_root = false;
181   EntityHandle root = 0;
182   rval = mb->tag_get_data( t, &root, 1, &data[0] );
183   if (MB_SUCCESS == rval)
184     ht_content_type( data, saw_ent, saw_set, saw_root );
185 
186     // check default value
187   rval = mb->tag_get_default_value( t, &data[0] );
188   if (MB_SUCCESS == rval)
189     ht_content_type( data, saw_ent, saw_set, saw_root );
190 
191     // check all tagged entities
192   Range r;
193   rval = mb->get_entities_by_type_and_tag( 0, MBMAXTYPE, &t, 0, 1, r );
194   if (MB_SUCCESS != rval) return rval;
195   for (Range::iterator i = r.begin(); i != r.end(); ++i) {
196     rval = mb->tag_get_data( t, &*i, 1, &data[0] );
197     if (MB_SUCCESS != rval) return rval;
198     ht_content_type( data, saw_ent, saw_set, saw_root );
199   }
200 
201     // If tag values were only entities, note type accordingly.
202     // Similarly if all are entity sets, note accordingly.
203     // Because root set (zero handle) is sometimes used to mean NULL
204     // rather than the actual root set, treat that specially.  If
205     // all values are either root set or an entity handle, then
206     // treat as if all values were non-set handles.
207   if (saw_set && !saw_ent)
208     mbi->note_set_handle_tag( t );
209   else if (!saw_set && saw_ent)
210     mbi->note_ent_handle_tag( t );
211   else if (saw_root && !saw_ent)
212     mbi->note_set_handle_tag( t );
213 
214   return MB_SUCCESS;
215 }
216 
remove_var_len_tags(Interface * mb,std::vector<Tag> & tags)217 static void remove_var_len_tags( Interface* mb, std::vector<Tag>& tags )
218 {
219   int size;
220   size_t r, w = 0;
221   for (r = 0; r < tags.size(); ++r)
222     if (MB_SUCCESS == mb->tag_get_length( tags[r], size ))
223       tags[w++] = tags[r];
224   tags.resize(w);
225 }
226 
227 // modify the adjacency table to match the ITAPS spec's expectations
munge_adj_table(int * adjTable,int geom_dim)228 static void munge_adj_table(int *adjTable, int geom_dim)
229 {
230     // If geom_dim is 2, 3D adjacencies are unavailable. This may change!
231   if (geom_dim == 2) {
232     for (size_t i = 0; i < 16; ++i) {
233       if (i % 4 == 3 || i >= 12)
234         adjTable[i] = iBase_UNAVAILABLE;
235     }
236   }
237 
238     // Ensure that diagonal entries are only available/unavailable.
239   for (size_t i = 0; i < 16; i+=5) {
240     if (adjTable[i] != iBase_UNAVAILABLE)
241       adjTable[i] = iBase_AVAILABLE;
242   }
243 }
244 
245 #ifdef __cplusplus
246 extern "C" {
247 #endif
248 
249   static void eatwhitespace(std::string &this_string);
250 
iMesh_getErrorType(iMesh_Instance instance,int * error_type)251   void iMesh_getErrorType(iMesh_Instance instance, int *error_type)
252   {
253     if (instance == NULL)
254       *error_type = iBase_FAILURE;
255     else
256       *error_type = MBIMESHI->lastErrorType;
257   }
258 
iMesh_getDescription(iMesh_Instance instance,char * descr,int descr_len)259   void iMesh_getDescription(iMesh_Instance instance, char *descr, int descr_len)
260   {
261     if (instance == NULL) {
262       strcpy(descr, "iMesh_getDescription: Invalid instance");
263     }
264     else {
265       unsigned int len = MIN(strlen(MBIMESHI->lastErrorDescription),
266                              static_cast<unsigned int>(descr_len));
267       strncpy(descr, MBIMESHI->lastErrorDescription, len);
268       descr[len] = '\0';
269     }
270   }
271 
iMesh_newMesh(const char * options,iMesh_Instance * instance,int * err,int options_len)272   void iMesh_newMesh(const char *options,
273                      iMesh_Instance *instance, int *err, int options_len)
274   {
275     std::string tmp_options = filter_options(options, options+options_len);
276     FileOptions opts(tmp_options.c_str());
277 
278     MBiMesh **mbi = reinterpret_cast<MBiMesh**>(instance);
279     *mbi = NULL;
280 
281     ErrorCode result = opts.get_null_option("PARALLEL");
282     if (MB_SUCCESS == result) {
283 #ifdef MOAB_HAVE_MPI
284       int flag = 1;
285       int retval = MPI_Initialized(&flag);
286       if (MPI_SUCCESS != retval || !flag) {
287         int argc = 0;
288         char **argv = NULL;
289 
290           // mpi not initialized yet - initialize here
291         retval = MPI_Init(&argc, &argv);
292         assert(MPI_SUCCESS == retval);
293       }
294       *mbi = new (std::nothrow) MBiMesh(NULL);
295 #else
296         //mError->set_last_error( "PARALLEL option not valid, this instance"
297         //                        " compiled for serial execution.\n" );
298       *mbi = new (std::nothrow) MBiMesh(NULL);
299       *err = (*mbi)->set_last_error(MB_NOT_IMPLEMENTED,
300                                     "Not configured with parallel support");
301       return;
302 #endif
303     }
304     else {
305       *mbi = new (std::nothrow) MBiMesh(NULL);
306     }
307     if (NULL == *mbi) {
308       *err = iBase_FAILURE;
309       return;
310     }
311 
312     *err = iBase_SUCCESS;
313   }
314 
iMesh_dtor(iMesh_Instance instance,int * err)315   void iMesh_dtor(iMesh_Instance instance, int *err)
316   {
317     delete MBIMESHI;
318     *err = iBase_SUCCESS;
319   }
320 
iMesh_load(iMesh_Instance instance,const iBase_EntitySetHandle handle,const char * name,const char * options,int * err,int name_len,int options_len)321   void iMesh_load(iMesh_Instance instance,
322                   const iBase_EntitySetHandle handle,
323                   const char *name, const char *options,
324                   int *err, int name_len, int options_len)
325   {
326       // get filename, option & null-terminate
327     std::string filename(name, name_len);
328     eatwhitespace(filename);
329 
330     std::string opts = filter_options(options, options+options_len);
331 
332     Range orig_ents;
333     ErrorCode result = MOABI->get_entities_by_handle( 0, orig_ents );
334     CHKERR(result,"Internal error");
335 
336     const EntityHandle* file_set = 0;
337     if (handle != 0 /*root_set*/) {
338       const iBase_EntitySetHandle* ptr = &handle;
339       file_set = reinterpret_cast<const EntityHandle*>(ptr);
340     }
341 
342     result = MOABI->load_file(filename.c_str(), file_set, opts.c_str());
343 
344     CHKERR(result, "iMesh_load:ERROR loading a mesh.");
345 
346       // create interior edges/faces if requested
347     if (MBIMESHI->AdjTable[5] || MBIMESHI->AdjTable[10]) {
348       Range set_ents;
349       result = MOABI->get_entities_by_handle(0, set_ents);
350       CHKERR(result,"");
351       Range sets;
352       result = MOABI->get_entities_by_type(0, MBENTITYSET, sets);
353       CHKERR(result,"");
354       set_ents = subtract( set_ents, sets );
355       set_ents = subtract( set_ents, orig_ents );
356       result = create_int_ents(MBIMESHI, set_ents, file_set);
357       CHKERR(result,"");
358     }
359     RETURN(iBase_SUCCESS);
360   }
361 
iMesh_save(iMesh_Instance instance,const iBase_EntitySetHandle handle,const char * name,const char * options,int * err,const int name_len,int options_len)362   void iMesh_save(iMesh_Instance instance,
363                   const iBase_EntitySetHandle handle,
364                   const char *name, const char *options,
365                   int *err, const int name_len, int options_len)
366   {
367       // get filename & attempt to NULL-terminate
368     std::string filename( name, name_len );
369     eatwhitespace(filename);
370     std::string opts = filter_options(options, options+options_len);
371 
372     EntityHandle set = ENTITY_HANDLE(handle);
373     ErrorCode result = MOABI->write_file(filename.c_str(), NULL, opts.c_str(),
374                                        &set, 1);
375 
376     CHKERR(result, "iMesh_save:ERROR saving a mesh.");
377     RETURN(iBase_SUCCESS);
378   }
379 
iMesh_getRootSet(iMesh_Instance instance,iBase_EntitySetHandle * root_set,int * err)380   void iMesh_getRootSet(iMesh_Instance instance,
381                         iBase_EntitySetHandle *root_set, int *err)
382   {
383     *root_set = 0;
384       //return CAST_TO_VOID(MOABI->get_root_set());
385     RETURN(iBase_SUCCESS);
386   }
387 
iMesh_getGeometricDimension(iMesh_Instance instance,int * geom_dim,int * err)388   void iMesh_getGeometricDimension(iMesh_Instance instance,
389                                    int *geom_dim, int *err)
390   {
391     MOABI->get_dimension(*geom_dim);
392     RETURN(iBase_SUCCESS);
393   }
394 
iMesh_setGeometricDimension(iMesh_Instance instance,int geom_dim,int * err)395   void iMesh_setGeometricDimension(iMesh_Instance instance,
396                                    int geom_dim, int *err)
397   {
398     ErrorCode rval = MOABI->set_dimension(geom_dim);
399     CHKERR(rval,"iMesh_setGeometricDimension: failed");
400 
401     RETURN(iBase_SUCCESS);
402   }
403 
iMesh_getDfltStorage(iMesh_Instance instance,int * order,int * err)404   void iMesh_getDfltStorage(iMesh_Instance instance,
405                             int *order, int *err)
406   {
407     *order = iBase_BLOCKED;
408     RETURN(iBase_SUCCESS);
409   }
410 
iMesh_getAdjTable(iMesh_Instance instance,int ** adjacency_table,int * adjacency_table_allocated,int * adjacency_table_size,int * err)411   void iMesh_getAdjTable (iMesh_Instance instance,
412                           int** adjacency_table,
413                           /*inout*/ int* adjacency_table_allocated,
414                           /*out*/ int* adjacency_table_size, int *err)
415   {
416     int geom_dim;
417     iMesh_getGeometricDimension(instance, &geom_dim, err);
418 
419     ALLOC_CHECK_ARRAY_NOFAIL(adjacency_table, 16);
420     memcpy(*adjacency_table, MBIMESHI->AdjTable, 16*sizeof(int));
421     munge_adj_table(*adjacency_table, geom_dim);
422     RETURN(iBase_SUCCESS);
423   }
424 
iMesh_setAdjTable(iMesh_Instance instance,int * adj_table,int adj_table_size,int * err)425   void iMesh_setAdjTable (iMesh_Instance instance,
426                           int* adj_table,
427                           /*inout*/ int adj_table_size,
428                           int *err)
429   {
430     if (16 != adj_table_size) {
431       RETURN(iBase_INVALID_ARGUMENT);
432     }
433 
434     int geom_dim;
435     iMesh_getGeometricDimension(instance, &geom_dim, err);
436 
437     memcpy(MBIMESHI->AdjTable, adj_table, 16*sizeof(int));
438     munge_adj_table(adj_table, geom_dim);
439     RETURN(iBase_SUCCESS);
440   }
441 
iMesh_getNumOfType(iMesh_Instance instance,const iBase_EntitySetHandle entity_set_handle,const int entity_type,int * num_type,int * err)442   void iMesh_getNumOfType(iMesh_Instance instance,
443                           /*in*/ const iBase_EntitySetHandle entity_set_handle,
444                           /*in*/ const int entity_type,
445                           int *num_type, int *err)
446   {
447     iMesh_getNumOfTypeRec(instance, entity_set_handle, entity_type, false,
448                           num_type, err);
449   }
450 
iMesh_getNumOfTopo(iMesh_Instance instance,const iBase_EntitySetHandle entity_set_handle,const int entity_topology,int * num_topo,int * err)451   void iMesh_getNumOfTopo(iMesh_Instance instance,
452                           /*in*/ const iBase_EntitySetHandle entity_set_handle,
453                           /*in*/ const int entity_topology,
454                           int *num_topo, int *err)
455   {
456     iMesh_getNumOfTopoRec(instance, entity_set_handle, entity_topology,
457                           false, num_topo, err);
458   }
459 
iMesh_optimize(iMesh_Instance instance,int * handles_invalidated,int * err)460   void iMesh_optimize( iMesh_Instance instance,
461                        int* handles_invalidated,
462                        int* err )
463   {
464     // TODO: implement this for real
465     *handles_invalidated = 0;
466     RETURN(iBase_SUCCESS);
467   }
468 
iMesh_getEntities(iMesh_Instance instance,const iBase_EntitySetHandle entity_set_handle,const int entity_type,const int entity_topology,iBase_EntityHandle ** entity_handles,int * entity_handles_allocated,int * entity_handles_size,int * err)469   void iMesh_getEntities(iMesh_Instance instance,
470                          /*in*/ const iBase_EntitySetHandle entity_set_handle,
471                          /*in*/ const int entity_type,
472                          /*in*/ const int entity_topology,
473                          /*inout*/ iBase_EntityHandle** entity_handles,
474                          /*inout*/ int* entity_handles_allocated,
475                          /*out*/ int* entity_handles_size,
476                          int *err)
477   {
478     iMesh_getEntitiesRec(instance, entity_set_handle, entity_type,
479                          entity_topology, false,
480                          entity_handles, entity_handles_allocated, entity_handles_size,
481                          err);
482   }
483 
iMesh_getVtxArrCoords(iMesh_Instance instance,const iBase_EntityHandle * vertex_handles,const int vertex_handles_size,int storage_order,double ** coords,int * coords_allocated,int * coords_size,int * err)484   void iMesh_getVtxArrCoords (iMesh_Instance instance,
485                               /*in*/ const iBase_EntityHandle* vertex_handles,
486                               /*in*/ const int vertex_handles_size,
487                               /*inout*/ int storage_order,
488                               /*inout*/ double** coords,
489                               /*inout*/ int* coords_allocated,
490                               /*out*/ int* coords_size, int *err)
491   {
492     int geom_dim;
493     MOABI->get_dimension(geom_dim);
494 
495       // make sure we can hold them all
496     ALLOC_CHECK_ARRAY(coords, geom_dim*vertex_handles_size);
497 
498       // now get all the coordinates
499       // coords will come back interleaved by default
500     ErrorCode result;
501     if (storage_order == iBase_INTERLEAVED) {
502       if (3 == geom_dim) {
503         result = MOABI->get_coords(CONST_HANDLE_ARRAY_PTR(vertex_handles),
504                                  vertex_handles_size, *coords);
505       }
506       else {
507         std::vector<double> dum_coords(3*vertex_handles_size);
508         result = MOABI->get_coords(CONST_HANDLE_ARRAY_PTR(vertex_handles),
509                                  vertex_handles_size,
510                                  &dum_coords[0]);
511 
512         for (int i = 0; i < vertex_handles_size; i++) {
513           for (int j = 0; j < geom_dim; j++)
514             (*coords)[geom_dim*i + j] = dum_coords[3*i + j];
515         }
516       }
517     }
518     else {
519       std::vector<double> dum_coords(3*vertex_handles_size);
520       result = MOABI->get_coords(CONST_HANDLE_ARRAY_PTR(vertex_handles),
521                                vertex_handles_size,
522                                &dum_coords[0]);
523       CHKERR(result,"iMesh_getVtxArrCoords: problem getting vertex coords");
524 
525       for (int i = 0; i < vertex_handles_size; i++) {
526         for (int j = 0; j < geom_dim; j++)
527           (*coords)[i + vertex_handles_size*j] = dum_coords[3*i + j];
528       }
529     }
530 
531     KEEP_ARRAY(coords);
532     RETURN(iBase_SUCCESS);
533   }
534 
535 /**
536  * Method:  initEntArrIter[]
537  */
iMesh_initEntArrIter(iMesh_Instance instance,const iBase_EntitySetHandle entity_set_handle,const int requested_entity_type,const int requested_entity_topology,const int requested_array_size,const int resilient,iBase_EntityArrIterator * entArr_iterator,int * err)538   void iMesh_initEntArrIter (iMesh_Instance instance,
539                              /*in*/ const iBase_EntitySetHandle entity_set_handle,
540                              /*in*/ const int requested_entity_type,
541                              /*in*/ const int requested_entity_topology,
542                              /*in*/ const int requested_array_size,
543                              /*in*/ const int resilient,
544                              /*out*/ iBase_EntityArrIterator* entArr_iterator,
545                              int *err)
546   {
547     iMesh_initEntArrIterRec(instance, entity_set_handle, requested_entity_type,
548                             requested_entity_topology, requested_array_size, resilient, false,
549                             entArr_iterator, err);
550   }
551 
552 /**
553  * Method:  getEntArrNextIter[]
554  */
iMesh_getNextEntArrIter(iMesh_Instance instance,iBase_EntityArrIterator entArr_iterator,iBase_EntityHandle ** entity_handles,int * entity_handles_allocated,int * entity_handles_size,int * has_data,int * err)555   void iMesh_getNextEntArrIter (iMesh_Instance instance,
556                                 /*in*/ iBase_EntityArrIterator entArr_iterator,
557                                 /*inout*/ iBase_EntityHandle** entity_handles,
558                                 /*inout*/ int* entity_handles_allocated,
559                                 /*out*/ int* entity_handles_size,
560                                 int *has_data, int *err)
561   {
562       // check the size of the destination array
563     ALLOC_CHECK_ARRAY_NOFAIL(entity_handles, entArr_iterator->array_size());
564     entArr_iterator->get_entities( dynamic_cast<Core*>(MOABI),
565              (EntityHandle*)*entity_handles, *entity_handles_size );
566     *has_data = (*entity_handles_size != 0);
567     RETURN(iBase_SUCCESS);
568   }
569 
570 /**
571  * Method:  resetEntArrIter[]
572  */
iMesh_resetEntArrIter(iMesh_Instance instance,iBase_EntityArrIterator entArr_iterator,int * err)573   void iMesh_resetEntArrIter (iMesh_Instance instance,
574                               /*in*/ iBase_EntityArrIterator entArr_iterator, int *err)
575   {
576     ErrorCode result = entArr_iterator->reset( MOABI );
577     CHKERR(result,"Re-query of iterator data for iMesh_resetEntArrIter failed");
578     RETURN(iBase_SUCCESS);
579   }
580 
iMesh_endEntArrIter(iMesh_Instance instance,iBase_EntityArrIterator entArr_iterator,int * err)581   void iMesh_endEntArrIter (iMesh_Instance instance,
582                             /*in*/ iBase_EntityArrIterator entArr_iterator, int *err)
583   {
584     delete entArr_iterator;
585     RETURN(iBase_SUCCESS);
586   }
587 
iMesh_getEntArrTopo(iMesh_Instance instance,const iBase_EntityHandle * entity_handles,const int entity_handles_size,int ** topology,int * topology_allocated,int * topology_size,int * err)588   void iMesh_getEntArrTopo(iMesh_Instance instance,
589                            /*in*/ const iBase_EntityHandle* entity_handles,
590                            /*in*/ const int entity_handles_size,
591                            /*inout*/ int** topology,
592                            /*inout*/ int* topology_allocated,
593                            /*out*/ int* topology_size, int *err)
594   {
595       // go through each entity and look up its type
596     ALLOC_CHECK_ARRAY_NOFAIL(topology, entity_handles_size);
597 
598     for (int i = 0; i < entity_handles_size; i++)
599       (*topology)[i] =
600         tstt_topology_table[MOABI->type_from_handle(ENTITY_HANDLE(entity_handles[i]))];
601 
602     *topology_size = entity_handles_size;
603 
604     RETURN(iBase_SUCCESS);
605   }
606 
iMesh_getEntArrType(iMesh_Instance instance,const iBase_EntityHandle * entity_handles,const int entity_handles_size,int ** etype,int * etype_allocated,int * etype_size,int * err)607   void iMesh_getEntArrType(iMesh_Instance instance,
608                            /*in*/ const iBase_EntityHandle* entity_handles,
609                            /*in*/ const int entity_handles_size,
610                            /*inout*/ int** etype,
611                            /*inout*/ int* etype_allocated,
612                            /*out*/ int* etype_size, int *err)
613   {
614       // go through each entity and look up its type
615     ALLOC_CHECK_ARRAY_NOFAIL(etype, entity_handles_size);
616 
617     for (int i = 0; i < entity_handles_size; i++)
618       (*etype)[i] =
619         tstt_type_table[MOABI->type_from_handle(ENTITY_HANDLE(entity_handles[i]))];
620 
621     *etype_size = entity_handles_size;
622 
623     RETURN(iBase_SUCCESS);
624   }
625 
iMesh_getEntArrAdj(iMesh_Instance instance,const iBase_EntityHandle * entity_handles,const int entity_handles_size,const int entity_type_requested,iBase_EntityHandle ** adjacentEntityHandles,int * adjacentEntityHandles_allocated,int * adjacentEntityHandles_size,int ** offset,int * offset_allocated,int * offset_size,int * err)626   void iMesh_getEntArrAdj(iMesh_Instance instance,
627                           /*in*/ const iBase_EntityHandle* entity_handles,
628                           /*in*/ const int entity_handles_size,
629                           /*in*/ const int entity_type_requested,
630                           /*inout*/ iBase_EntityHandle** adjacentEntityHandles,
631                           /*inout*/ int* adjacentEntityHandles_allocated,
632                           /*out*/ int* adjacentEntityHandles_size,
633                           /*inout*/ int** offset,
634                           /*inout*/ int* offset_allocated,
635                           /*out*/ int* offset_size, int *err)
636   {
637     ErrorCode result = MB_SUCCESS;
638 
639     ALLOC_CHECK_ARRAY(offset, entity_handles_size+1);
640 
641     const EntityHandle* entity_iter = (const EntityHandle*)entity_handles;
642     const EntityHandle* const entity_end = entity_iter + entity_handles_size;
643     int* off_iter = *offset;
644     int prev_off = 0;
645 
646     std::vector<EntityHandle> conn_storage;
647     std::vector<EntityHandle> adj_ents;
648     const EntityHandle *connect;
649     int num_connect;
650 
651     EntityHandle* array; // ptr to working array of result handles
652     int array_alloc;       // allocated size of 'array'
653     const bool allocated_array = !*adjacentEntityHandles_allocated || !*adjacentEntityHandles;
654     if (allocated_array) {
655       array = 0;
656       array_alloc = 0;
657     }
658     else {
659       array = reinterpret_cast<EntityHandle*>(*adjacentEntityHandles);
660       array_alloc = *adjacentEntityHandles_allocated;
661     }
662 
663     for ( ; entity_iter != entity_end; ++entity_iter)
664     {
665       *off_iter = prev_off;
666       off_iter++;
667 
668       if (iBase_VERTEX == entity_type_requested &&
669           TYPE_FROM_HANDLE(*entity_iter) != MBPOLYHEDRON) {
670         if (CN::Dimension(TYPE_FROM_HANDLE(*entity_iter)) == 0)
671           continue;
672         result = MOABI->get_connectivity(*entity_iter, connect, num_connect, false, &conn_storage);
673         if (MB_SUCCESS != result) {
674           if (allocated_array)
675             free(array);
676           ERROR(result, "iMesh_getEntArrAdj: trouble getting adjacency list.");
677         }
678       }
679       else if (iBase_ALL_TYPES == entity_type_requested) {
680         adj_ents.clear();
681         for (int dim = 0; dim < 4; ++dim) {
682           if (CN::Dimension(TYPE_FROM_HANDLE(*entity_iter)) == dim)
683             continue;
684           result = MOABI->get_adjacencies( entity_iter, 1, dim, false, adj_ents, Interface::UNION );
685           if (MB_SUCCESS != result) {
686             if (allocated_array)
687               free(array);
688             ERROR(result, "iMesh_getEntArrAdj: trouble getting adjacency list.");
689           }
690         }
691         connect = &adj_ents[0];
692         num_connect = adj_ents.size();
693       }
694       else {
695         if (CN::Dimension(TYPE_FROM_HANDLE(*entity_iter)) == entity_type_requested)
696           continue;
697         adj_ents.clear();
698         result = MOABI->get_adjacencies( entity_iter, 1,
699                                        entity_type_requested, false, adj_ents );
700         if (MB_SUCCESS != result) {
701           if (allocated_array)
702             free(array);
703           ERROR(result, "iMesh_getEntArrAdj: trouble getting adjacency list.");
704         }
705         connect = &adj_ents[0];
706         num_connect = adj_ents.size();
707       }
708 
709       if (prev_off + num_connect <= array_alloc) {
710         std::copy(connect, connect+num_connect, array+prev_off);
711       }
712       else if (allocated_array) {
713           // if array is not allocated yet, guess at initial size
714           // as the number of adjacencies for the first entity times
715           // the number of input entities.  This will result in a single
716           // exact allocation if one input entity or typical queries
717           // such as connectivity of a non-mixed mesh or regions adjacent
718           // to faces.
719         if (!array_alloc)
720           array_alloc = entity_handles_size * num_connect;
721         else
722           array_alloc = std::max(array_alloc*2, prev_off+num_connect);
723         EntityHandle* new_array = (EntityHandle*)realloc( array, array_alloc*sizeof(EntityHandle) );
724         if (!new_array) {
725           free(array);
726           RETURN(iBase_MEMORY_ALLOCATION_FAILED);
727         }
728         else
729           array = new_array;
730         std::copy(connect, connect+num_connect, array+prev_off);
731       }
732       // else do nothing.  Will catch error later when comparing
733       //  occupied to allocated sizes.  Continue here because
734       //  must pass back required size.
735 
736       prev_off += num_connect;
737     }
738     *off_iter = prev_off;
739     *adjacentEntityHandles_size = prev_off;
740 
741     if (*adjacentEntityHandles_size > array_alloc) {
742       if (allocated_array)
743         free(array);
744       RETURN(iBase_BAD_ARRAY_SIZE);
745     }
746     else if (allocated_array) {
747       *adjacentEntityHandles = reinterpret_cast<iBase_EntityHandle*>(array);
748       *adjacentEntityHandles_allocated = array_alloc;
749     }
750 
751     KEEP_ARRAY(offset);
752     RETURN(iBase_SUCCESS);
753   }
754 
iMesh_getEntArr2ndAdj(iMesh_Instance instance,iBase_EntityHandle const * entity_handles,int entity_handles_size,int bridge_entity_type,int requested_entity_type,iBase_EntityHandle ** adj_entity_handles,int * adj_entity_handles_allocated,int * adj_entity_handles_size,int ** offset,int * offset_allocated,int * offset_size,int * err)755   void iMesh_getEntArr2ndAdj( iMesh_Instance instance,
756                               iBase_EntityHandle const* entity_handles,
757                               int entity_handles_size,
758                               int bridge_entity_type,
759                               int requested_entity_type,
760                               iBase_EntityHandle** adj_entity_handles,
761                               int* adj_entity_handles_allocated,
762                               int* adj_entity_handles_size,
763                               int** offset,
764                               int* offset_allocated,
765                               int* offset_size,
766                               int* err )
767   {
768     CHKENUM(bridge_entity_type, iBase_EntityType, iBase_INVALID_ENTITY_TYPE);
769     CHKENUM(requested_entity_type, iBase_EntityType, iBase_INVALID_ENTITY_TYPE);
770 
771     ErrorCode result = MB_SUCCESS;
772 
773     ALLOC_CHECK_ARRAY(offset, entity_handles_size+1);
774 
775     const EntityHandle* entity_iter = (const EntityHandle*)entity_handles;
776     const EntityHandle* const entity_end = entity_iter + entity_handles_size;
777     int* off_iter = *offset;
778     int prev_off = 0;
779 
780     std::vector<EntityHandle> all_adj_ents;
781     MeshTopoUtil mtu(MOABI);
782 
783     int min_bridge = iBase_VERTEX, max_bridge = iBase_REGION;
784     int min_req    = iBase_VERTEX, max_req    = iBase_REGION;
785     if (iBase_ALL_TYPES != bridge_entity_type)
786       min_bridge = max_bridge = bridge_entity_type;
787     if (iBase_ALL_TYPES != requested_entity_type)
788       min_req = max_req = requested_entity_type;
789 
790     for ( ; entity_iter != entity_end; ++entity_iter)
791     {
792       *off_iter = prev_off;
793       off_iter++;
794       Range adj_ents;
795 
796       int source = CN::Dimension(TYPE_FROM_HANDLE(*entity_iter));
797       for (int bridge = min_bridge; bridge <= max_bridge; ++bridge) {
798         if (source == bridge)
799           continue;
800         for (int requested = min_req; requested <= max_req; ++requested) {
801           if (bridge == requested)
802             continue;
803           result = mtu.get_bridge_adjacencies( *entity_iter,
804                                                bridge,
805                                                requested, adj_ents );
806           CHKERR(result, "iMesh_getEntArr2ndAdj: trouble getting adjacency list.");
807         }
808       }
809 
810       std::copy(adj_ents.begin(), adj_ents.end(), std::back_inserter(all_adj_ents));
811       prev_off += adj_ents.size();
812     }
813     *off_iter = prev_off;
814 
815     ALLOC_CHECK_ARRAY_NOFAIL(adj_entity_handles, all_adj_ents.size() );
816     memcpy(*adj_entity_handles, &all_adj_ents[0],
817            sizeof(EntityHandle)*all_adj_ents.size() );
818 
819     KEEP_ARRAY(offset);
820 
821       // Return an error if the bridge and requested entity types are different
822     if (iBase_ALL_TYPES != bridge_entity_type &&
823         bridge_entity_type == requested_entity_type)
824       ERROR(iBase_INVALID_ARGUMENT, "iMesh_getEntArr2ndAdj: bridge and "
825             "requested entity types must be different.");
826     else
827       RETURN(iBase_SUCCESS);
828   }
829 
iMesh_getAdjEntIndices(iMesh_Instance instance,iBase_EntitySetHandle entity_set_handle,int entity_type_requestor,int entity_topology_requestor,int entity_type_requested,iBase_EntityHandle ** entity_handles,int * entity_handles_allocated,int * entity_handles_size,iBase_EntityHandle ** adj_entity_handles,int * adj_entity_handles_allocated,int * adj_entity_handles_size,int ** adj_entity_indices,int * adj_entity_indices_allocated,int * adj_entity_indices_size,int ** offset,int * offset_allocated,int * offset_size,int * err)830   void iMesh_getAdjEntIndices(iMesh_Instance instance,
831                       /*in*/    iBase_EntitySetHandle entity_set_handle,
832                       /*in*/    int entity_type_requestor,
833                       /*in*/    int entity_topology_requestor,
834                       /*in*/    int entity_type_requested,
835                       /*inout*/ iBase_EntityHandle** entity_handles,
836                       /*inout*/ int* entity_handles_allocated,
837                       /*out*/   int* entity_handles_size,
838                       /*inout*/ iBase_EntityHandle** adj_entity_handles,
839                       /*inout*/ int* adj_entity_handles_allocated,
840                       /*out*/   int* adj_entity_handles_size,
841                       /*inout*/ int** adj_entity_indices,
842                       /*inout*/ int* adj_entity_indices_allocated,
843                       /*out*/   int* adj_entity_indices_size,
844                       /*inout*/ int** offset,
845                       /*inout*/ int* offset_allocated,
846                       /*out*/   int* offset_size,
847                       /*out*/   int *err)
848   {
849     const int allocated_entity_handles = (*entity_handles_allocated == 0);
850     const int allocated_indices = (*adj_entity_indices_allocated == 0);
851     const int allocated_offset = (*offset_allocated == 0);
852 
853     // get source entities
854     iMesh_getEntities( instance,
855                        entity_set_handle,
856                        entity_type_requestor,
857                        entity_topology_requestor,
858                        entity_handles,
859                        entity_handles_allocated,
860                        entity_handles_size,
861                        err );
862     if (iBase_SUCCESS != *err)
863       return;
864 
865     // get adjacencies
866     iBase_EntityHandle* all_adj_handles = 0;
867     int size = 0, alloc = 0;
868     iMesh_getEntArrAdj( instance,
869                         *entity_handles, *entity_handles_size,
870                         entity_type_requested,
871                         &all_adj_handles, &alloc, &size,
872                         offset, offset_allocated, offset_size,
873                         err );
874     if (*err != iBase_SUCCESS) {
875       if (allocated_entity_handles) {
876         free( *entity_handles );
877         *entity_handles = 0;
878         *entity_handles_allocated = 0;
879       }
880       return;
881     }
882 
883     // allocate or check size of adj_entity_indices
884     *adj_entity_indices_size = size;
885     if (allocated_indices) {
886       *adj_entity_indices = (int*)malloc(sizeof(iBase_EntityHandle)*size);
887       if (!*adj_entity_indices)
888         *err = iBase_MEMORY_ALLOCATION_FAILED;
889       else
890         *adj_entity_indices_allocated = size;
891     }
892     else if (*adj_entity_indices_allocated < size) {
893       *err = iBase_BAD_ARRAY_DIMENSION;
894     }
895     if (iBase_SUCCESS != *err) {
896       free( all_adj_handles );
897       if (allocated_entity_handles) {
898         free( *entity_handles );
899         *entity_handles = 0;
900         *entity_handles_allocated = 0;
901       }
902       if (allocated_offset) {
903         free( *offset );
904         *offset = 0;
905         *offset_allocated = 0;
906       }
907       return;
908     }
909 
910     // Now create an array of unique sorted handles from all_adj_handles.
911     // We need to create a copy because we still need all_adj_handles.  We
912     // will eventually need to copy the resulting unique list into
913     // adj_entity_handles, so if adj_entity_handles is already allocated and
914     // of sufficient size, use it rather than allocating another temporary.
915     iBase_EntityHandle* unique_adj = 0;
916     if (*adj_entity_handles_allocated >= size) {
917       unique_adj = *adj_entity_handles;
918     }
919     else {
920       unique_adj = (iBase_EntityHandle*)malloc(sizeof(iBase_EntityHandle) * size);
921     }
922     std::copy( all_adj_handles, all_adj_handles+size, unique_adj );
923     std::sort( unique_adj, unique_adj + size );
924     *adj_entity_handles_size = std::unique( unique_adj, unique_adj + size ) - unique_adj;
925 
926     // If we created a temporary array for unique_adj rather than using
927     // already allocated space in adj_entity_handles, allocate adj_entity_handles
928     // and copy the unique handle list into it
929     if (*adj_entity_handles != unique_adj) {
930       if (!*adj_entity_handles_allocated) {
931         *adj_entity_handles = (iBase_EntityHandle*)malloc(
932                               sizeof(iBase_EntityHandle) * *adj_entity_handles_size);
933         if (!*adj_entity_handles)
934           *err = iBase_MEMORY_ALLOCATION_FAILED;
935         else
936           *adj_entity_handles_allocated = *adj_entity_handles_size;
937       }
938       else if (*adj_entity_handles_allocated < *adj_entity_handles_size)
939         *err = iBase_BAD_ARRAY_DIMENSION;
940       if (iBase_SUCCESS != *err) {
941         free( unique_adj );
942         free( all_adj_handles );
943         if (allocated_entity_handles) {
944           free( *entity_handles );
945           *entity_handles = 0;
946           *entity_handles_allocated = 0;
947         }
948         if (allocated_offset) {
949           free( *offset );
950           *offset = 0;
951           *offset_allocated = 0;
952         }
953         if (allocated_indices) {
954           free( *adj_entity_indices );
955           *adj_entity_indices = 0;
956           *adj_entity_indices_allocated = 0;
957         }
958         return;
959       }
960 
961       std::copy( unique_adj, unique_adj + *adj_entity_handles_size, *adj_entity_handles );
962       free( unique_adj );
963       unique_adj = *adj_entity_handles;
964     }
965 
966     // convert from adjacency list to indices into unique_adj
967     for (int i = 0; i < *adj_entity_indices_size; ++i)
968       (*adj_entity_indices)[i] = std::lower_bound( unique_adj,
969         unique_adj + *adj_entity_handles_size, all_adj_handles[i] ) - unique_adj;
970     free( all_adj_handles );
971   }
972 
973 
iMesh_createEntSet(iMesh_Instance instance,const int isList,iBase_EntitySetHandle * entity_set_created,int * err)974   void iMesh_createEntSet(iMesh_Instance instance,
975                           /*in*/ const int isList,
976                           /*out*/ iBase_EntitySetHandle* entity_set_created, int *err)
977   {
978       // create the entity set
979     EntityHandle meshset;
980     ErrorCode result;
981 
982     if (isList)
983       result = MOABI->create_meshset(MESHSET_ORDERED, meshset);
984     else
985       result = MOABI->create_meshset(MESHSET_SET, meshset);
986 
987     CHKERR(result,"iMesh_createEntSet: ERROR creating a entityset instance");
988 
989       // return EntitySet_Handle
990     *entity_set_created = (iBase_EntitySetHandle)meshset;
991     RETURN(iBase_SUCCESS);
992   }
993 
iMesh_destroyEntSet(iMesh_Instance instance,iBase_EntitySetHandle entity_set,int * err)994   void iMesh_destroyEntSet (iMesh_Instance instance,
995                             /*in*/ iBase_EntitySetHandle entity_set, int *err)
996   {
997     EntityHandle set = ENTITY_HANDLE(entity_set);
998     ErrorCode result = MOABI->delete_entities(&set, 1);
999     CHKERR(result, "iMesh_destroyEntSet: couldn't delete the set.");
1000 
1001     RETURN(iBase_SUCCESS);
1002   }
1003 
iMesh_isList(iMesh_Instance instance,const iBase_EntitySetHandle entity_set,int * is_list,int * err)1004   void iMesh_isList (iMesh_Instance instance,
1005                      /*in*/ const iBase_EntitySetHandle entity_set,
1006                      int *is_list, int *err)
1007   {
1008     unsigned int options;
1009     ErrorCode result = MOABI->get_meshset_options(ENTITY_HANDLE(entity_set), options);
1010     CHKERR(result,"iMesh_isList: couldn't query set.");
1011     if (options & MESHSET_ORDERED)
1012       *is_list = true;
1013     else *is_list = false;
1014 
1015     RETURN(iBase_SUCCESS);
1016   }
1017 
iMesh_getNumEntSets(iMesh_Instance instance,const iBase_EntitySetHandle entity_set_handle,const int num_hops,int * num_sets,int * err)1018   void iMesh_getNumEntSets(iMesh_Instance instance,
1019                            /*in*/ const iBase_EntitySetHandle entity_set_handle,
1020                            /*in*/ const int num_hops,
1021                            int *num_sets, int *err)
1022   {
1023     ErrorCode rval = MOABI->num_contained_meshsets( ENTITY_HANDLE(entity_set_handle),
1024                                                     num_sets,
1025                                                     std::max(0,num_hops+1) );
1026     CHKERR(rval, "iMesh_entitysetGetNumberEntitySets:ERROR getting number of entitysets.");
1027 
1028     RETURN(iBase_SUCCESS);
1029   }
1030 
iMesh_getEntSets(iMesh_Instance instance,const iBase_EntitySetHandle entity_set_handle,const int num_hops,iBase_EntitySetHandle ** contained_entset_handles,int * contained_entset_handles_allocated,int * contained_entset_handles_size,int * err)1031   void iMesh_getEntSets(iMesh_Instance instance,
1032                         /*in*/ const iBase_EntitySetHandle entity_set_handle,
1033                         /*in*/ const int num_hops,
1034                         /*inout*/ iBase_EntitySetHandle** contained_entset_handles,
1035                         /*inout*/ int* contained_entset_handles_allocated,
1036                         /*inout*/ int* contained_entset_handles_size, int *err)
1037   {
1038     std::vector<EntityHandle> sets;
1039     ErrorCode rval = MOABI->get_contained_meshsets( ENTITY_HANDLE(entity_set_handle),
1040                                                     sets,
1041                                                     std::max( num_hops+1, 0 ) );
1042     CHKERR(rval, "iMesh_entitysetGetEntitySets: problem getting entities by type.");
1043     ALLOC_CHECK_ARRAY_NOFAIL(contained_entset_handles, sets.size() );
1044 
1045     std::copy( sets.begin(), sets.end(), (EntityHandle*)*contained_entset_handles );
1046     *contained_entset_handles_size = sets.size();
1047     RETURN(iBase_SUCCESS);
1048   }
1049 
iMesh_addEntArrToSet(iMesh_Instance instance,const iBase_EntityHandle * entity_handles,int entity_handles_size,iBase_EntitySetHandle entity_set,int * err)1050   void iMesh_addEntArrToSet(iMesh_Instance instance,
1051                             /*in*/ const iBase_EntityHandle* entity_handles,
1052                             /*in*/ int entity_handles_size,
1053                             /*in*/ iBase_EntitySetHandle entity_set,
1054                             int *err)
1055   {
1056     const EntityHandle *ents = CONST_HANDLE_ARRAY_PTR(entity_handles);
1057     ErrorCode result = MOABI->add_entities(ENTITY_HANDLE(entity_set),
1058                                            ents, entity_handles_size);
1059 
1060     CHKERR(result,"iMesh_addEntArrToSet:ERROR adding entities in EntitySet.");
1061     RETURN(iBase_SUCCESS);
1062   }
1063 
iMesh_addEntToSet(iMesh_Instance instance,iBase_EntityHandle entity_handle,iBase_EntitySetHandle entity_set,int * err)1064   void iMesh_addEntToSet(iMesh_Instance instance,
1065                          /*in*/ iBase_EntityHandle entity_handle,
1066                          /*in*/ iBase_EntitySetHandle entity_set, int *err)
1067   {
1068     iMesh_addEntArrToSet(instance, &entity_handle, 1, entity_set, err);
1069   }
1070 
iMesh_rmvEntArrFromSet(iMesh_Instance instance,const iBase_EntityHandle * entity_handles,int entity_handles_size,iBase_EntitySetHandle entity_set,int * err)1071   void iMesh_rmvEntArrFromSet(iMesh_Instance instance,
1072                               /*in*/ const iBase_EntityHandle* entity_handles,
1073                               /*in*/ int entity_handles_size,
1074                               /*in*/ iBase_EntitySetHandle entity_set, int *err)
1075   {
1076     const EntityHandle *ents = CONST_HANDLE_ARRAY_PTR(entity_handles);
1077 
1078     ErrorCode result = MOABI->remove_entities
1079       (ENTITY_HANDLE(entity_set), ents, entity_handles_size);
1080 
1081     CHKERR(result,"iMesh_rmvEntArrFromSet:ERROR removing entities in EntitySet.");
1082     RETURN(iBase_SUCCESS);
1083   }
1084 
iMesh_rmvEntFromSet(iMesh_Instance instance,iBase_EntityHandle entity_handle,iBase_EntitySetHandle entity_set,int * err)1085   void iMesh_rmvEntFromSet(iMesh_Instance instance,
1086                            /*in*/ iBase_EntityHandle entity_handle,
1087                            /*in*/ iBase_EntitySetHandle entity_set,
1088                            int *err)
1089   {
1090     iMesh_rmvEntArrFromSet(instance, &entity_handle, 1, entity_set, err);
1091   }
1092 
iMesh_addEntSet(iMesh_Instance instance,iBase_EntitySetHandle entity_set_to_add,iBase_EntitySetHandle entity_set_handle,int * err)1093   void iMesh_addEntSet(iMesh_Instance instance,
1094                        /*in*/ iBase_EntitySetHandle entity_set_to_add,
1095                        /*in*/ iBase_EntitySetHandle entity_set_handle,
1096                        int *err)
1097   {
1098     if (!entity_set_to_add || !entity_set_handle)
1099       ERROR(iBase_INVALID_ARGUMENT, "iMesh_addEntSet: ERROR invalid argument");
1100 
1101     EntityHandle to_add = ENTITY_HANDLE(entity_set_to_add);
1102     ErrorCode result = MOABI->add_entities(ENTITY_HANDLE(entity_set_handle), &to_add, 1);
1103 
1104     CHKERR(result,"iMesh_addEntSet:ERROR adding entitysets.");
1105     RETURN(iBase_SUCCESS);
1106   }
1107 
iMesh_rmvEntSet(iMesh_Instance instance,iBase_EntitySetHandle entity_set_to_remove,iBase_EntitySetHandle entity_set_handle,int * err)1108   void iMesh_rmvEntSet(iMesh_Instance instance,
1109                        /*in*/ iBase_EntitySetHandle entity_set_to_remove,
1110                        /*in*/ iBase_EntitySetHandle entity_set_handle,
1111                        int *err)
1112   {
1113     if (!entity_set_to_remove || !entity_set_handle)
1114       ERROR(iBase_INVALID_ARGUMENT, "iMesh_rmvEntSet: ERROR invalid argument");
1115 
1116     EntityHandle to_remove = ENTITY_HANDLE(entity_set_to_remove);
1117     ErrorCode result = MOABI->remove_entities
1118       (ENTITY_HANDLE(entity_set_handle), &to_remove, 1);
1119 
1120     CHKERR(result,"iMesh_rmvEntSet:ERROR removing entitysets in EntitySet.");
1121     RETURN(iBase_SUCCESS);
1122   }
1123 
iMesh_isEntContained(iMesh_Instance instance,iBase_EntitySetHandle containing_entity_set,iBase_EntityHandle contained_entity,int * is_contained,int * err)1124   void iMesh_isEntContained (iMesh_Instance instance,
1125                              /*in*/ iBase_EntitySetHandle containing_entity_set,
1126                              /*in*/ iBase_EntityHandle contained_entity,
1127                              int *is_contained, int *err)
1128   {
1129     int junk1 = 1, junk2 = 1;
1130     iMesh_isEntArrContained( instance, containing_entity_set,
1131                              &contained_entity, 1, &is_contained,
1132                              &junk1, &junk2, err );
1133   }
1134 
iMesh_isEntArrContained(iMesh_Instance instance,iBase_EntitySetHandle containing_set,const iBase_EntityHandle * entity_handles,int num_entity_handles,int ** is_contained,int * is_contained_allocated,int * is_contained_size,int * err)1135   void iMesh_isEntArrContained( iMesh_Instance instance,
1136                             /*in*/ iBase_EntitySetHandle containing_set,
1137                             /*in*/ const iBase_EntityHandle* entity_handles,
1138                             /*in*/ int num_entity_handles,
1139                          /*inout*/ int** is_contained,
1140                          /*inout*/ int* is_contained_allocated,
1141                            /*out*/ int* is_contained_size,
1142                            /*out*/ int* err )
1143 
1144   {
1145     EntityHandle set = ENTITY_HANDLE(containing_set);
1146     ALLOC_CHECK_ARRAY_NOFAIL(is_contained, num_entity_handles);
1147     *is_contained_size = num_entity_handles;
1148 
1149     if (containing_set) {
1150       for (int i = 0; i < num_entity_handles; ++i) {
1151         EntityHandle h = ENTITY_HANDLE(entity_handles[i]);
1152         (*is_contained)[i] = MOABI->contains_entities( set, &h, 1 );
1153       }
1154     }
1155     else {
1156       std::fill( *is_contained, (*is_contained)+num_entity_handles, 1 );
1157     }
1158     RETURN(iBase_SUCCESS);
1159   }
1160 
iMesh_isEntSetContained(iMesh_Instance instance,const iBase_EntitySetHandle containing_entity_set,const iBase_EntitySetHandle contained_entity_set,int * is_contained,int * err)1161   void iMesh_isEntSetContained (iMesh_Instance instance,
1162                                 /*in*/ const iBase_EntitySetHandle containing_entity_set,
1163                                 /*in*/ const iBase_EntitySetHandle contained_entity_set,
1164                                 int *is_contained, int *err)
1165   {
1166     iMesh_isEntContained(instance, containing_entity_set,
1167                          reinterpret_cast<iBase_EntityHandle>(contained_entity_set),
1168                          is_contained, err);
1169   }
1170 
iMesh_addPrntChld(iMesh_Instance instance,iBase_EntitySetHandle parent_entity_set,iBase_EntitySetHandle child_entity_set,int * err)1171   void iMesh_addPrntChld(iMesh_Instance instance,
1172                          /*inout*/ iBase_EntitySetHandle parent_entity_set,
1173                          /*inout*/ iBase_EntitySetHandle child_entity_set,
1174                          int *err)
1175   {
1176     ErrorCode result = MOABI->add_parent_child
1177       (ENTITY_HANDLE(parent_entity_set),
1178        ENTITY_HANDLE(child_entity_set));
1179 
1180     if (result == MB_ENTITY_NOT_FOUND)
1181       ERROR(iBase_INVALID_ENTITYSET_HANDLE,
1182             "iMesh_addPrntChld: ERROR invalid entity set.");
1183     CHKERR(result, "iMesh_addPrntChld: ERROR addParentChild failed.");
1184     RETURN(iBase_SUCCESS);
1185   }
1186 
iMesh_rmvPrntChld(iMesh_Instance instance,iBase_EntitySetHandle parent_entity_set,iBase_EntitySetHandle child_entity_set,int * err)1187   void iMesh_rmvPrntChld(iMesh_Instance instance,
1188                          /*inout*/ iBase_EntitySetHandle parent_entity_set,
1189                          /*inout*/ iBase_EntitySetHandle child_entity_set,
1190                          int *err)
1191   {
1192     ErrorCode result = MOABI->remove_parent_child
1193       (ENTITY_HANDLE(parent_entity_set),
1194        ENTITY_HANDLE(child_entity_set));
1195 
1196     if (result == MB_ENTITY_NOT_FOUND)
1197       ERROR(iBase_INVALID_ENTITYSET_HANDLE,
1198             "iMesh_rmvPrntChld: ERROR invalid entity set.");
1199     CHKERR(result,"iMesh_rmvPrntChld: ERROR RemoveParentChild failed.");
1200     RETURN(iBase_SUCCESS);
1201   }
1202 
iMesh_isChildOf(iMesh_Instance instance,const iBase_EntitySetHandle parent_entity_set,const iBase_EntitySetHandle child_entity_set,int * is_child,int * err)1203   void iMesh_isChildOf(iMesh_Instance instance,
1204                        /*in*/ const iBase_EntitySetHandle parent_entity_set,
1205                        /*in*/ const iBase_EntitySetHandle child_entity_set,
1206                        int *is_child, int *err)
1207   {
1208     if (!child_entity_set)
1209       ERROR(iBase_INVALID_ENTITYSET_HANDLE,
1210             "iMesh_isChildOf: ERROR invalid entity set.");
1211 
1212     std::vector<EntityHandle> children;
1213 
1214     ErrorCode result = MOABI->get_child_meshsets
1215       (ENTITY_HANDLE(parent_entity_set), children);
1216 
1217     if (result == MB_ENTITY_NOT_FOUND)
1218       ERROR(iBase_INVALID_ENTITYSET_HANDLE,
1219             "iMesh_rmvPrntChld: ERROR invalid entity set.");
1220     CHKERR(result,"iMesh_isChildOf: ERROR IsParentChildRelated failed.");
1221 
1222     if (std::find(children.begin(), children.end(), ENTITY_HANDLE(child_entity_set))
1223         != children.end())
1224       *is_child = true;
1225 
1226     else
1227       *is_child = false;
1228 
1229     RETURN(iBase_SUCCESS);
1230   }
1231 
iMesh_getNumChld(iMesh_Instance instance,const iBase_EntitySetHandle entity_set,const int num_hops,int * num_child,int * err)1232   void iMesh_getNumChld(iMesh_Instance instance,
1233                         /*in*/ const iBase_EntitySetHandle entity_set,
1234                         /*in*/ const int num_hops,
1235                         int *num_child, int *err)
1236   {
1237     *num_child = 0;
1238     ErrorCode result = MOABI->num_child_meshsets
1239       (ENTITY_HANDLE(entity_set), num_child, num_hops+1);
1240 
1241     if (result == MB_ENTITY_NOT_FOUND)
1242       ERROR(iBase_INVALID_ENTITYSET_HANDLE,
1243             "iMesh_getNumChld: ERROR invalid entity set.");
1244     CHKERR(result,"iMesh_getNumChld: ERROR GetNumChildren failed.");
1245 
1246     RETURN(iBase_SUCCESS);
1247   }
1248 
iMesh_getNumPrnt(iMesh_Instance instance,const iBase_EntitySetHandle entity_set,const int num_hops,int * num_parent,int * err)1249   void iMesh_getNumPrnt(iMesh_Instance instance,
1250                         /*in*/ const iBase_EntitySetHandle entity_set,
1251                         /*in*/ const int num_hops,
1252                         int *num_parent, int *err)
1253   {
1254     *num_parent = 0;
1255     ErrorCode result = MOABI->num_parent_meshsets
1256       (ENTITY_HANDLE(entity_set), num_parent, num_hops+1);
1257 
1258     if (result == MB_ENTITY_NOT_FOUND)
1259       ERROR(iBase_INVALID_ENTITYSET_HANDLE,
1260             "iMesh_getNumPrnt: ERROR invalid entity set.");
1261     CHKERR(result,"iMesh_getNumPrnt: ERROR GetNumParents failed.");
1262     RETURN(iBase_SUCCESS);
1263   }
1264 
iMesh_getChldn(iMesh_Instance instance,const iBase_EntitySetHandle from_entity_set,const int num_hops,iBase_EntitySetHandle ** entity_set_handles,int * entity_set_handles_allocated,int * entity_set_handles_size,int * err)1265   void iMesh_getChldn(iMesh_Instance instance,
1266                       /*in*/ const iBase_EntitySetHandle from_entity_set,
1267                       /*in*/ const int num_hops,
1268                       /*out*/ iBase_EntitySetHandle** entity_set_handles,
1269                       /*out*/ int* entity_set_handles_allocated,
1270                       /*out*/ int* entity_set_handles_size, int *err)
1271   {
1272     std::vector<EntityHandle> children;
1273 
1274     ErrorCode result = MOABI->get_child_meshsets
1275       (ENTITY_HANDLE(from_entity_set), children, num_hops+1);
1276 
1277     if (result == MB_ENTITY_NOT_FOUND)
1278       ERROR(iBase_INVALID_ENTITYSET_HANDLE,
1279             "iMesh_getChldn: ERROR invalid entity set.");
1280     CHKERR(result,"ERROR getChildren failed.");
1281     ALLOC_CHECK_ARRAY_NOFAIL(entity_set_handles, children.size());
1282 
1283     EntityHandle *ents = HANDLE_ARRAY_PTR(*entity_set_handles);
1284       // use a memcpy for efficiency
1285     memcpy(ents, &children[0], children.size()*sizeof(EntityHandle));
1286 
1287     RETURN(iBase_SUCCESS);
1288   }
1289 
iMesh_getPrnts(iMesh_Instance instance,const iBase_EntitySetHandle from_entity_set,const int num_hops,iBase_EntitySetHandle ** entity_set_handles,int * entity_set_handles_allocated,int * entity_set_handles_size,int * err)1290   void iMesh_getPrnts(iMesh_Instance instance,
1291                       /*in*/ const iBase_EntitySetHandle from_entity_set,
1292                       /*in*/ const int num_hops,
1293                       /*out*/ iBase_EntitySetHandle** entity_set_handles,
1294                       /*out*/ int* entity_set_handles_allocated,
1295                       /*out*/ int* entity_set_handles_size, int *err)
1296   {
1297     std::vector<EntityHandle> parents;
1298 
1299     ErrorCode result = MOABI->get_parent_meshsets
1300       (ENTITY_HANDLE(from_entity_set), parents, num_hops+1);
1301 
1302     if (result == MB_ENTITY_NOT_FOUND)
1303       ERROR(iBase_INVALID_ENTITYSET_HANDLE,
1304             "iMesh_getPrnts: ERROR invalid entity set.");
1305     CHKERR(result,"ERROR getParents failed.");
1306 
1307     ALLOC_CHECK_ARRAY_NOFAIL(entity_set_handles, parents.size());
1308 
1309     EntityHandle *ents = HANDLE_ARRAY_PTR(*entity_set_handles);
1310       // use a memcpy for efficiency
1311     memcpy(ents, &parents[0], parents.size()*sizeof(EntityHandle));
1312 
1313     RETURN(iBase_SUCCESS);
1314   }
1315 
iMesh_setVtxArrCoords(iMesh_Instance instance,const iBase_EntityHandle * vertex_handles,const int vertex_handles_size,const int storage_order,const double * new_coords,const int new_coords_size,int * err)1316   void iMesh_setVtxArrCoords (iMesh_Instance instance,
1317                               /*in*/ const iBase_EntityHandle* vertex_handles,
1318                               /*in*/ const int vertex_handles_size,
1319                               /*in*/ const int storage_order,
1320                               /*in*/ const double* new_coords,
1321                               /*in*/ const int new_coords_size, int *err)
1322   {
1323     CHKENUM(storage_order, iBase_StorageOrder, iBase_INVALID_ARGUMENT);
1324 
1325     int geom_dim;
1326     MOABI->get_dimension(geom_dim);
1327     if (new_coords_size != geom_dim*vertex_handles_size) {
1328       ERROR(iBase_INVALID_ARGUMENT, "iMesh_setVtxArrCoords: Didn't get the right # coordinates.");
1329     }
1330 
1331     ErrorCode result = MB_SUCCESS, tmp_result;
1332     if (storage_order == iBase_INTERLEAVED) {
1333       if (3 == geom_dim) {
1334         result = MOABI->set_coords(CONST_HANDLE_ARRAY_PTR(vertex_handles),
1335                                  vertex_handles_size, new_coords);
1336       }
1337       else {
1338         const EntityHandle *verts = CONST_HANDLE_ARRAY_PTR(vertex_handles);
1339         double dummy[3] = {0, 0, 0};
1340         for (int i = 0; i < vertex_handles_size; i++) {
1341           for (int j = 0; j < geom_dim; j++)
1342             dummy[j] = new_coords[geom_dim*i + j];
1343           tmp_result = MOABI->set_coords(&verts[i], 1, dummy);
1344           if (MB_SUCCESS != tmp_result) result = tmp_result;
1345         }
1346       }
1347     }
1348     else {
1349       const EntityHandle *verts = CONST_HANDLE_ARRAY_PTR(vertex_handles);
1350       double dummy[3] = {0, 0, 0};
1351       for (int i = 0; i < vertex_handles_size; i++) {
1352         for (int j = 0; j < geom_dim; j++)
1353           dummy[j] = new_coords[i + vertex_handles_size*j];
1354         tmp_result = MOABI->set_coords(&verts[i], 1, dummy);
1355         if (MB_SUCCESS != tmp_result) result = tmp_result;
1356       }
1357     }
1358 
1359     CHKERR(result, "iMesh_setVtxArrCoords: problem setting coordinates.");
1360 
1361     RETURN(iBase_SUCCESS);
1362   }
1363 
iMesh_createVtxArr(iMesh_Instance instance,const int num_verts,const int storage_order,const double * new_coords,const int new_coords_size,iBase_EntityHandle ** new_vertex_handles,int * new_vertex_handles_allocated,int * new_vertex_handles_size,int * err)1364   void iMesh_createVtxArr(iMesh_Instance instance,
1365                           /*in*/ const int num_verts,
1366                           /*in*/ const int storage_order,
1367                           /*in*/ const double* new_coords,
1368                           /*in*/ const int new_coords_size,
1369                           /*inout*/ iBase_EntityHandle** new_vertex_handles,
1370                           /*inout*/ int* new_vertex_handles_allocated,
1371                           /*inout*/ int* new_vertex_handles_size, int *err)
1372   {
1373     int geom_dim;
1374     MOABI->get_dimension(geom_dim);
1375     if (new_coords_size != geom_dim*num_verts) {
1376       ERROR(iBase_INVALID_ARGUMENT, "iMesh_createVtxArr: Didn't get the right # coordinates.");
1377     }
1378 
1379       // if there aren't any elements in the array, allocate it
1380     ALLOC_CHECK_ARRAY(new_vertex_handles, num_verts);
1381 
1382       // make the entities
1383     EntityHandle *new_verts = HANDLE_ARRAY_PTR(*new_vertex_handles);
1384 
1385     if (storage_order == iBase_INTERLEAVED) {
1386       if (3 == geom_dim) {
1387         for (int i = 0; i < num_verts; i++) {
1388           ErrorCode result = MOABI->create_vertex(&new_coords[3*i], new_verts[i]);
1389           CHKERR(result, "iMesh_createVtxArr: couldn't create vertex.");
1390         }
1391       }
1392       else {
1393         double tmp[3] = {0, 0, 0};
1394         for (int i = 0; i < num_verts; i++) {
1395           for (int j = 0; j < geom_dim; j++)
1396             tmp[j] = new_coords[geom_dim*i + j];
1397           ErrorCode result = MOABI->create_vertex(tmp, new_verts[i]);
1398           CHKERR(result, "iMesh_createVtxArr: couldn't create vertex.");
1399         }
1400       }
1401     }
1402     else {
1403       double tmp[3] = {0, 0, 0};
1404       for (int i = 0; i < num_verts; i++) {
1405         for (int j = 0; j < geom_dim; j++)
1406           tmp[j] = new_coords[j*num_verts + i];
1407 
1408         ErrorCode result = MOABI->create_vertex(tmp, new_verts[i]);
1409         CHKERR(result, "iMesh_createVtxArr: couldn't create vertex.");
1410       }
1411     }
1412 
1413     KEEP_ARRAY(new_vertex_handles);
1414     RETURN(iBase_SUCCESS);
1415   }
1416 
iMesh_createEntArr(iMesh_Instance instance,const int new_entity_topology,const iBase_EntityHandle * lower_order_entity_handles,const int lower_order_entity_handles_size,iBase_EntityHandle ** new_entity_handles,int * new_entity_handles_allocated,int * new_entity_handles_size,int ** status,int * status_allocated,int * status_size,int * err)1417   void iMesh_createEntArr(iMesh_Instance instance,
1418                           /*in*/ const int new_entity_topology,
1419                           /*in*/ const iBase_EntityHandle* lower_order_entity_handles,
1420                           /*in*/ const int lower_order_entity_handles_size,
1421                           /*out*/ iBase_EntityHandle** new_entity_handles,
1422                           /*out*/ int* new_entity_handles_allocated,
1423                           /*out*/ int* new_entity_handles_size,
1424                           /*inout*/  int** status,
1425                           /*inout*/ int* status_allocated,
1426                           /*out*/ int* status_size, int *err)
1427   {
1428       // for now, throw an error if lower order entity handles aren't vertices
1429     if (iMesh_POINT > new_entity_topology || iMesh_SEPTAHEDRON < new_entity_topology) {
1430       ERROR(iBase_INVALID_ARGUMENT, "iMesh_createEntArr: invalid topology.");
1431     }
1432     EntityType this_type = mb_topology_table[new_entity_topology];
1433     int num_ents = 0, num_verts;
1434     const EntityHandle *lower_ents;
1435     if (MBVERTEX != this_type) {
1436       num_verts = CN::VerticesPerEntity(this_type);
1437       num_ents = lower_order_entity_handles_size / num_verts;
1438       lower_ents = CONST_HANDLE_ARRAY_PTR(lower_order_entity_handles);
1439         // check that we have the right number of lower order entity handles
1440       if (lower_order_entity_handles_size % CN::VerticesPerEntity(this_type) != 0) {
1441         ERROR(iBase_INVALID_ENTITY_COUNT, "iMesh_createEntArr: wrong # vertices for this entity type.");
1442        }
1443     }
1444     else {
1445       ERROR(iBase_INVALID_ARGUMENT, "iMesh_createEntArr: can't create vertices with this function, use createVtxArr instead.");
1446     }
1447 
1448     if (num_ents == 0) {
1449       ERROR(iBase_INVALID_ENTITY_COUNT, "iMesh_createEntArr: called to create 0 entities.");
1450     }
1451 
1452       // if there aren't any elements in the array, allocate it
1453 
1454       // This function is poorly defined.  We have to return allocated
1455       // arrays even if we fail.
1456     ALLOC_CHECK_ARRAY_NOFAIL(new_entity_handles, num_ents);
1457     ALLOC_CHECK_ARRAY_NOFAIL(status, num_ents);
1458 
1459       // make the entities
1460     EntityHandle *new_ents = HANDLE_ARRAY_PTR(*new_entity_handles);
1461 
1462     ErrorCode tmp_result, result = MB_SUCCESS;
1463 
1464     for (int i = 0; i < num_ents; i++) {
1465       tmp_result = MOABI->create_element(this_type, lower_ents, num_verts,
1466                                        new_ents[i]);
1467       if (MB_SUCCESS != tmp_result) {
1468         (*status)[i] = iBase_CREATION_FAILED;
1469         result = tmp_result;
1470       }
1471       else
1472         (*status)[i] = iBase_NEW;
1473 
1474       lower_ents += num_verts;
1475     }
1476 
1477     CHKERR(result, "iMesh_createEntArr: couldn't create one of the entities.");
1478 
1479     *new_entity_handles_size = num_ents;
1480     *status_size = num_ents;
1481 
1482     if (MBIMESHI->AdjTable[5] || MBIMESHI->AdjTable[10]) {
1483       Range set_ents;
1484       std::copy(HANDLE_ARRAY_PTR(*new_entity_handles),
1485                 HANDLE_ARRAY_PTR(*new_entity_handles)+*new_entity_handles_size,
1486                 range_inserter(set_ents));
1487       result = create_int_ents(MBIMESHI, set_ents);
1488       CHKERR(result,"");
1489     }
1490 
1491     RETURN(iBase_SUCCESS);
1492   }
1493 
iMesh_deleteEntArr(iMesh_Instance instance,const iBase_EntityHandle * entity_handles,const int entity_handles_size,int * err)1494   void iMesh_deleteEntArr(iMesh_Instance instance,
1495                           /*in*/ const iBase_EntityHandle* entity_handles,
1496                           /*in*/ const int entity_handles_size, int *err)
1497   {
1498     if (0 == entity_handles_size) {
1499       RETURN(iBase_SUCCESS);
1500     }
1501 
1502     ErrorCode result = MOABI->delete_entities(CONST_HANDLE_ARRAY_PTR(entity_handles),
1503                                               entity_handles_size);
1504     CHKERR(result, "iMesh_deleteEntArr: trouble deleting entities.");
1505 
1506     RETURN(iBase_SUCCESS);
1507   }
1508 
iMesh_createTag(iMesh_Instance instance,const char * tag_name,const int tag_size,const int tag_type,iBase_TagHandle * tag_handle,int * err,const int tag_name_size)1509   void iMesh_createTag(iMesh_Instance instance,
1510                        /*in*/ const char* tag_name,
1511                        /*in*/ const int tag_size,
1512                        /*in*/ const int tag_type,
1513                        /*out*/ iBase_TagHandle* tag_handle,
1514                        int *err,
1515                        const int tag_name_size)
1516   {
1517     iMesh_createTagWithOptions(instance, tag_name, NULL, tag_size, tag_type, tag_handle, err, tag_name_size, 0);
1518   }
1519 
iMesh_destroyTag(iMesh_Instance instance,iBase_TagHandle tag_handle,const int forced,int * err)1520   void iMesh_destroyTag(iMesh_Instance instance,
1521                         /*in*/ iBase_TagHandle tag_handle,
1522                         /*in*/ const int forced, int *err)
1523   {
1524       // might need to check if it's used first
1525     if (false == forced) {
1526       Range ents;
1527       ErrorCode result;
1528       Tag this_tag = TAG_HANDLE(tag_handle);
1529       for (EntityType this_type = MBVERTEX; this_type != MBMAXTYPE; this_type++) {
1530         result = MOABI->get_entities_by_type_and_tag(0, this_type, &this_tag, NULL, 1,
1531                                                    ents, Interface::UNION);
1532         CHKERR(result,"iMesh_destroyTag: problem finding tag.");
1533         if (!ents.empty()) {
1534           ERROR(iBase_TAG_IN_USE, "iMesh_destroyTag: forced=false and entities"
1535                 " are still assigned this tag.");
1536         }
1537       }
1538         // check if tag value is set on mesh
1539       const void* data_ptr;
1540       EntityHandle root = 0;
1541       result = MOABI->tag_get_by_ptr( this_tag, &root, 1, &data_ptr );
1542       if (MB_SUCCESS == result)
1543         ERROR(iBase_TAG_IN_USE, "iMesh_destroyTag: forced=false and mesh"
1544               " is still assigned this tag.");
1545     }
1546 
1547       // ok, good to go - either forced or no entities with this tag
1548     ErrorCode result = MOABI->tag_delete(TAG_HANDLE(tag_handle));
1549     if (MB_SUCCESS != result && MB_TAG_NOT_FOUND != result)
1550       ERROR(result, "iMesh_destroyTag: problem deleting tag.");
1551 
1552     if (MB_SUCCESS == result)
1553       MBIMESHI->note_tag_destroyed( TAG_HANDLE(tag_handle) );
1554 
1555     RETURN(iBase_ERROR_MAP[result]);
1556   }
1557 
iMesh_getTagName(iMesh_Instance instance,const iBase_TagHandle tag_handle,char * out_data,int * err,int out_data_len)1558   void iMesh_getTagName(iMesh_Instance instance,
1559                         /*in*/ const iBase_TagHandle tag_handle,
1560                         char *out_data, int *err,
1561                         int out_data_len)
1562   {
1563     static ::std::string name;
1564     ErrorCode result = MOABI->tag_get_name(TAG_HANDLE(tag_handle), name);
1565     CHKERR(result, "iMesh_getTagName: problem getting name.");
1566 
1567     strncpy(out_data, name.c_str(), out_data_len);
1568     RETURN(iBase_SUCCESS);
1569   }
1570 
iMesh_getTagType(iMesh_Instance instance,const iBase_TagHandle tag_handle,int * value_type,int * err)1571   void iMesh_getTagType (iMesh_Instance instance,
1572                          /*in*/ const iBase_TagHandle tag_handle,
1573                          int *value_type, int *err)
1574   {
1575     DataType this_type;
1576     ErrorCode result = MOABI->tag_get_data_type(TAG_HANDLE(tag_handle),
1577                                                 this_type);
1578     CHKERR(result, "iMesh_getTagType: problem getting type.");
1579 
1580     if (this_type != MB_TYPE_HANDLE)
1581       *value_type = tstt_data_type_table[this_type];
1582     else if (MBIMESHI->is_set_handle_tag( TAG_HANDLE(tag_handle) ))
1583       *value_type = iBase_ENTITY_SET_HANDLE;
1584     else if (MBIMESHI->is_ent_handle_tag( TAG_HANDLE(tag_handle) ))
1585       *value_type = iBase_ENTITY_HANDLE;
1586     else {
1587       result = check_handle_tag_type(TAG_HANDLE(tag_handle), MBIMESHI );
1588       CHKERR(result, "iMesh_getTagType: problem guessing handle tag subtype");
1589       if (MBIMESHI->is_set_handle_tag( TAG_HANDLE(tag_handle) ))
1590         *value_type = iBase_ENTITY_SET_HANDLE;
1591       else
1592         *value_type = iBase_ENTITY_HANDLE;
1593     }
1594 
1595     RETURN(iBase_SUCCESS);
1596   }
1597 
iMesh_getTagSizeValues(iMesh_Instance instance,const iBase_TagHandle tag_handle,int * tag_size_val,int * err)1598   void iMesh_getTagSizeValues(iMesh_Instance instance,
1599                               /*in*/ const iBase_TagHandle tag_handle,
1600                               int *tag_size_val, int *err)
1601   {
1602     ErrorCode result = MOABI->tag_get_length(TAG_HANDLE(tag_handle), *tag_size_val);
1603     CHKERR(result, "iMesh_getTagSize: problem getting size.");
1604 
1605     RETURN(iBase_SUCCESS);
1606   }
1607 
iMesh_getTagSizeBytes(iMesh_Instance instance,const iBase_TagHandle tag_handle,int * tag_size_bytes,int * err)1608   void iMesh_getTagSizeBytes(iMesh_Instance instance,
1609                              /*in*/ const iBase_TagHandle tag_handle,
1610                              int *tag_size_bytes, int *err)
1611   {
1612     ErrorCode result = MOABI->tag_get_bytes(TAG_HANDLE(tag_handle), *tag_size_bytes);
1613     CHKERR(result, "iMesh_getTagSize: problem getting size.");
1614 
1615     RETURN(iBase_SUCCESS);
1616   }
1617 
iMesh_getTagHandle(iMesh_Instance instance,const char * tag_name,iBase_TagHandle * tag_handle,int * err,const int tag_name_len)1618   void iMesh_getTagHandle(iMesh_Instance instance,
1619                           /*in*/ const char* tag_name,
1620                           iBase_TagHandle *tag_handle, int *err,
1621                           const int tag_name_len)
1622   {
1623     std::string tmp_tagname(tag_name, tag_name_len);
1624     eatwhitespace(tmp_tagname);
1625 
1626     ErrorCode result = MOABI->tag_get_handle(tmp_tagname.c_str(), 0, MB_TYPE_OPAQUE,
1627                                              (Tag&)*tag_handle, MB_TAG_ANY);
1628 
1629     if (MB_SUCCESS != result) {
1630       std::string msg("iMesh_getTagHandle: problem getting handle for tag named '");
1631       msg += std::string(tag_name) + std::string("'");
1632       *tag_handle = 0;
1633       ERROR(result, msg.c_str());
1634     }
1635 
1636       // do not return variable-length tags through ITAPS API
1637     int size;
1638     if (MB_SUCCESS != MOABI->tag_get_length( TAG_HANDLE(*tag_handle), size ))
1639       RETURN(iBase_TAG_NOT_FOUND);
1640 
1641     RETURN(iBase_SUCCESS);
1642   }
1643 
iMesh_getAllIfaceTags(iMesh_Instance instance,iBase_TagHandle ** tag_handles,int * tag_handles_allocated,int * tag_handles_size,int * err)1644   void iMesh_getAllIfaceTags (iMesh_Instance instance,
1645                               /*inout*/ iBase_TagHandle** tag_handles,
1646                               /*inout*/ int* tag_handles_allocated,
1647                               /*out*/ int* tag_handles_size, int *err)
1648   {
1649     std::vector<Tag> all_tags;
1650 
1651     ErrorCode result = MOABI->tag_get_tags(all_tags);
1652     CHKERR(result, "iMesh_getAllIfaceTags failed.");
1653 
1654     remove_var_len_tags( MOABI, all_tags );
1655 
1656       // now put those tag handles into sidl array
1657     ALLOC_CHECK_ARRAY_NOFAIL(tag_handles, all_tags.size());
1658     memcpy(*tag_handles, &all_tags[0], all_tags.size()*sizeof(Tag));
1659     *tag_handles_size = all_tags.size();
1660 
1661     RETURN(iBase_SUCCESS);
1662   }
1663 
iMesh_setEntSetData(iMesh_Instance instance,iBase_EntitySetHandle entity_set_handle,const iBase_TagHandle tag_handle,const void * tag_value,const int,int * err)1664   void iMesh_setEntSetData (iMesh_Instance instance,
1665                             /*in*/ iBase_EntitySetHandle entity_set_handle,
1666                             /*in*/ const iBase_TagHandle tag_handle,
1667                             /*in*/ const void* tag_value,
1668                             /*in*/ const int , int *err)
1669   {
1670     ErrorCode result;
1671 
1672     EntityHandle set = ENTITY_HANDLE(entity_set_handle);
1673     result = MOABI->tag_set_data(TAG_HANDLE(tag_handle), &set, 1, tag_value);
1674     CHKERR(result, "iMesh_setEntSetData: error");
1675 
1676     RETURN(iBase_SUCCESS);
1677   }
1678 
iMesh_setEntSetIntData(iMesh_Instance instance,iBase_EntitySetHandle entity_set,const iBase_TagHandle tag_handle,const int tag_value,int * err)1679   void iMesh_setEntSetIntData (iMesh_Instance instance,
1680                                /*in*/ iBase_EntitySetHandle entity_set,
1681                                /*in*/ const iBase_TagHandle tag_handle,
1682                                /*in*/ const int tag_value, int *err)
1683   {
1684     CHKTAGTYPE(tag_handle, iBase_INTEGER);
1685     iMesh_setEntSetData(instance, entity_set, tag_handle,
1686                         &tag_value,
1687                         sizeof(int), err);
1688   }
1689 
iMesh_setEntSetDblData(iMesh_Instance instance,iBase_EntitySetHandle entity_set,const iBase_TagHandle tag_handle,const double tag_value,int * err)1690   void iMesh_setEntSetDblData (iMesh_Instance instance,
1691                                /*in*/ iBase_EntitySetHandle entity_set,
1692                                /*in*/ const iBase_TagHandle tag_handle,
1693                                /*in*/ const double tag_value, int *err)
1694   {
1695     CHKTAGTYPE(tag_handle, iBase_DOUBLE);
1696     iMesh_setEntSetData(instance, entity_set, tag_handle,
1697                         &tag_value,
1698                         sizeof(double), err);
1699   }
1700 
iMesh_setEntSetEHData(iMesh_Instance instance,iBase_EntitySetHandle entity_set,const iBase_TagHandle tag_handle,const iBase_EntityHandle tag_value,int * err)1701   void iMesh_setEntSetEHData (iMesh_Instance instance,
1702                               /*in*/ iBase_EntitySetHandle entity_set,
1703                               /*in*/ const iBase_TagHandle tag_handle,
1704                               /*in*/ const iBase_EntityHandle tag_value, int *err)
1705   {
1706       // XXX: decide how best to handle validating entity handles as tag data
1707     CHKNONEMPTY();
1708     CHKTAGTYPE(tag_handle, iBase_ENTITY_HANDLE);
1709     iMesh_setEntSetData(instance, entity_set, tag_handle,
1710                         &tag_value,
1711                         sizeof(iBase_EntityHandle), err);
1712   }
1713 
iMesh_setEntSetESHData(iMesh_Instance instance,iBase_EntitySetHandle entity_set,const iBase_TagHandle tag_handle,const iBase_EntitySetHandle tag_value,int * err)1714   void iMesh_setEntSetESHData (iMesh_Instance instance,
1715                                /*in*/ iBase_EntitySetHandle entity_set,
1716                                /*in*/ const iBase_TagHandle tag_handle,
1717                                /*in*/ const iBase_EntitySetHandle tag_value, int *err)
1718   {
1719     CHKTAGTYPE(tag_handle, iBase_ENTITY_SET_HANDLE);
1720     iMesh_setEntSetData(instance, entity_set, tag_handle,
1721                         &tag_value,
1722                         sizeof(iBase_EntitySetHandle), err);
1723   }
1724 
iMesh_getEntSetData(iMesh_Instance instance,const iBase_EntitySetHandle entity_set_handle,const iBase_TagHandle tag_handle,void * tag_value,int * tag_value_allocated,int * tag_value_size,int * err)1725   void iMesh_getEntSetData (iMesh_Instance instance,
1726                             /*in*/ const iBase_EntitySetHandle entity_set_handle,
1727                             /*in*/ const iBase_TagHandle tag_handle,
1728                             /*inout*/ void* tag_value,
1729                             /*inout*/ int* tag_value_allocated,
1730                             /*inout*/ int* tag_value_size, int *err)
1731   {
1732     EntityHandle eh = ENTITY_HANDLE(entity_set_handle);
1733     Tag tag = TAG_HANDLE(tag_handle);
1734 
1735     int tag_size;
1736     ErrorCode result = MOABI->tag_get_bytes(tag, tag_size);
1737     CHKERR(result, "iMesh_getEntSetData: couldn't get tag size.");
1738 
1739     ALLOC_CHECK_TAG_ARRAY(tag_value, tag_size);
1740 
1741     result = MOABI->tag_get_data(tag, &eh, 1,
1742                                  *static_cast<void**>(tag_value));
1743 
1744     CHKERR(result, "iMesh_getEntSetData didn't succeed.");
1745     KEEP_ARRAY(tag_value);
1746     RETURN(iBase_SUCCESS);
1747   }
1748 
iMesh_getEntSetIntData(iMesh_Instance instance,const iBase_EntitySetHandle entity_set,const iBase_TagHandle tag_handle,int * out_data,int * err)1749   void iMesh_getEntSetIntData (iMesh_Instance instance,
1750                                /*in*/ const iBase_EntitySetHandle entity_set,
1751                                /*in*/ const iBase_TagHandle tag_handle,
1752                                int *out_data, int *err)
1753   {
1754     CHKTAGTYPE(tag_handle, iBase_INTEGER);
1755     void *tag_ptr = out_data;
1756     int dum_size = sizeof(int);
1757     iMesh_getEntSetData(instance, entity_set, tag_handle, &tag_ptr,
1758                         &dum_size, &dum_size, err);
1759   }
1760 
iMesh_getEntSetDblData(iMesh_Instance instance,const iBase_EntitySetHandle entity_set,const iBase_TagHandle tag_handle,double * out_data,int * err)1761   void iMesh_getEntSetDblData (iMesh_Instance instance,
1762                                /*in*/ const iBase_EntitySetHandle entity_set,
1763                                /*in*/ const iBase_TagHandle tag_handle,
1764                                double *out_data, int *err)
1765   {
1766     CHKTAGTYPE(tag_handle, iBase_DOUBLE);
1767     void *tag_ptr = out_data;
1768     int tag_size = sizeof(double);
1769     iMesh_getEntSetData(instance, entity_set, tag_handle, &tag_ptr,
1770                         &tag_size, &tag_size, err);
1771   }
1772 
iMesh_getEntSetEHData(iMesh_Instance instance,const iBase_EntitySetHandle entity_set,const iBase_TagHandle tag_handle,iBase_EntityHandle * out_data,int * err)1773   void iMesh_getEntSetEHData (iMesh_Instance instance,
1774                               /*in*/ const iBase_EntitySetHandle entity_set,
1775                               /*in*/ const iBase_TagHandle tag_handle,
1776                               iBase_EntityHandle *out_data, int *err)
1777   {
1778     CHKTAGTYPE(tag_handle, iBase_ENTITY_HANDLE);
1779     void *tag_ptr = out_data;
1780     int tag_size = sizeof(EntityHandle);
1781     iMesh_getEntSetData(instance, entity_set, tag_handle, &tag_ptr,
1782                         &tag_size, &tag_size, err);
1783   }
1784 
iMesh_getEntSetESHData(iMesh_Instance instance,const iBase_EntitySetHandle entity_set,const iBase_TagHandle tag_handle,iBase_EntitySetHandle * out_data,int * err)1785   void iMesh_getEntSetESHData (iMesh_Instance instance,
1786                               /*in*/ const iBase_EntitySetHandle entity_set,
1787                               /*in*/ const iBase_TagHandle tag_handle,
1788                               iBase_EntitySetHandle *out_data, int *err)
1789   {
1790     CHKTAGTYPE(tag_handle, iBase_ENTITY_SET_HANDLE);
1791     void *tag_ptr = out_data;
1792     int tag_size = sizeof(EntityHandle);
1793     iMesh_getEntSetData(instance, entity_set, tag_handle, &tag_ptr,
1794                         &tag_size, &tag_size, err);
1795   }
1796 
iMesh_getAllEntSetTags(iMesh_Instance instance,const iBase_EntitySetHandle entity_set_handle,iBase_TagHandle ** tag_handles,int * tag_handles_allocated,int * tag_handles_size,int * err)1797   void iMesh_getAllEntSetTags (iMesh_Instance instance,
1798                                /*in*/ const iBase_EntitySetHandle entity_set_handle,
1799                                /*out*/ iBase_TagHandle** tag_handles,
1800                                /*out*/ int* tag_handles_allocated,
1801                                /*out*/ int* tag_handles_size, int *err)
1802   {
1803     EntityHandle eh = ENTITY_HANDLE(entity_set_handle);
1804     std::vector<Tag> all_tags;
1805 
1806     ErrorCode result = MOABI->tag_get_tags_on_entity(eh, all_tags);
1807     CHKERR(result, "iMesh_entitysetGetAllTagHandles failed.");
1808 
1809     remove_var_len_tags( MOABI, all_tags );
1810 
1811       // now put those tag handles into sidl array
1812     ALLOC_CHECK_ARRAY_NOFAIL(tag_handles, all_tags.size());
1813     memcpy(*tag_handles, &all_tags[0], all_tags.size()*sizeof(Tag));
1814 
1815     *tag_handles_size = (int) all_tags.size();
1816     RETURN(iBase_SUCCESS);
1817   }
1818 
iMesh_rmvEntSetTag(iMesh_Instance instance,iBase_EntitySetHandle entity_set_handle,const iBase_TagHandle tag_handle,int * err)1819   void iMesh_rmvEntSetTag (iMesh_Instance instance,
1820                            /*in*/ iBase_EntitySetHandle entity_set_handle,
1821                            /*in*/ const iBase_TagHandle tag_handle, int *err)
1822   {
1823     EntityHandle set = ENTITY_HANDLE(entity_set_handle);
1824     ErrorCode result = MOABI->tag_delete_data(TAG_HANDLE(tag_handle), &set, 1);
1825 
1826       // don't return an error if the tag simply wasn't set on the ent set
1827     if (MB_TAG_NOT_FOUND == result)
1828       RETURN(iBase_SUCCESS);
1829     else
1830       RETURN(iBase_ERROR_MAP[result]);
1831   }
1832 
iMesh_setVtxCoord(iMesh_Instance instance,iBase_EntityHandle vertex_handle,const double x,const double y,const double z,int * err)1833   void iMesh_setVtxCoord (iMesh_Instance instance,
1834                           /*in*/ iBase_EntityHandle vertex_handle,
1835                           /*in*/ const double x, /*in*/ const double y,
1836                           /*in*/ const double z, int *err)
1837 
1838   {
1839     const double xyz[3] = {x, y, z};
1840     int geom_dim;
1841     MOABI->get_dimension(geom_dim);
1842 
1843     iMesh_setVtxArrCoords(instance, &vertex_handle, 1, iBase_BLOCKED,
1844                           xyz, geom_dim, err);
1845   }
1846 
iMesh_createVtx(iMesh_Instance instance,const double x,const double y,const double z,iBase_EntityHandle * new_vertex_handle,int * err)1847   void iMesh_createVtx(iMesh_Instance instance,
1848                        /*in*/ const double x, /*in*/ const double y,
1849                        /*in*/ const double z,
1850                        /*out*/ iBase_EntityHandle* new_vertex_handle, int *err)
1851   {
1852     int dum = 1;
1853     const double xyz[3] = {x, y, z};
1854     int geom_dim;
1855     MOABI->get_dimension(geom_dim);
1856     iMesh_createVtxArr(instance, 1, iBase_BLOCKED,
1857                        xyz, geom_dim, &new_vertex_handle, &dum, &dum, err);
1858   }
1859 
iMesh_createEnt(iMesh_Instance instance,const int new_entity_topology,const iBase_EntityHandle * lower_order_entity_handles,const int lower_order_entity_handles_size,iBase_EntityHandle * new_entity_handle,int * status,int * err)1860   void iMesh_createEnt(iMesh_Instance instance,
1861                        /*in*/ const int new_entity_topology,
1862                        /*in*/ const iBase_EntityHandle* lower_order_entity_handles,
1863                        /*in*/ const int lower_order_entity_handles_size,
1864                        /*out*/ iBase_EntityHandle* new_entity_handle,
1865                        /*out*/ int* status, int *err)
1866   {
1867     if (0 == lower_order_entity_handles_size) {
1868       ERROR(iBase_INVALID_ENTITY_COUNT,
1869             "iMesh_createEnt: need more than zero lower order entities.");
1870     }
1871 
1872       // call  directly to allow creation of higher-order entities
1873       // directly from connectivity
1874     EntityType this_type = mb_topology_table[new_entity_topology];
1875     EntityHandle tmp_ent;
1876     ErrorCode result = MOABI->create_element(this_type,
1877                                              CONST_HANDLE_ARRAY_PTR(lower_order_entity_handles),
1878                                              lower_order_entity_handles_size,
1879                                              tmp_ent);
1880     if (MB_SUCCESS == result) {
1881       *new_entity_handle = reinterpret_cast<iBase_EntityHandle>(tmp_ent);
1882       *status = iBase_NEW;
1883 
1884       if (MBIMESHI->AdjTable[5] || MBIMESHI->AdjTable[10]) {
1885         Range set_ents;
1886         set_ents.insert( tmp_ent );
1887         create_int_ents(MBIMESHI, set_ents);
1888       }
1889 
1890       RETURN(iBase_SUCCESS);
1891     }
1892     else {
1893       *new_entity_handle = 0;
1894       *status = iBase_CREATION_FAILED;
1895       ERROR(result, "iMesh_createEnt: couldn't create entity");
1896     }
1897   }
1898 
iMesh_deleteEnt(iMesh_Instance instance,iBase_EntityHandle entity_handle,int * err)1899   void iMesh_deleteEnt(iMesh_Instance instance,
1900                        /*in*/ iBase_EntityHandle entity_handle, int *err)
1901   {
1902     iMesh_deleteEntArr(instance, &entity_handle, 1, err);
1903   }
1904 
iMesh_getArrData(iMesh_Instance instance,const iBase_EntityHandle * entity_handles,const int entity_handles_size,const iBase_TagHandle tag_handle,void * tag_values,int * tag_values_allocated,int * tag_values_size,int * err)1905   void iMesh_getArrData (iMesh_Instance instance,
1906                          /*in*/ const iBase_EntityHandle* entity_handles,
1907                          /*in*/ const int entity_handles_size,
1908                          /*in*/ const iBase_TagHandle tag_handle,
1909                          /*inout*/ void* tag_values,
1910                          /*inout*/int* tag_values_allocated,
1911                          /*out*/ int* tag_values_size, int *err)
1912   {
1913     if (0 == entity_handles_size)
1914       RETURN(iBase_SUCCESS);
1915     CHKNONEMPTY();
1916 
1917     const EntityHandle *ents = reinterpret_cast<const EntityHandle *>(entity_handles);
1918     Tag tag = TAG_HANDLE(tag_handle);
1919 
1920     int tag_size;
1921     ErrorCode result = MOABI->tag_get_bytes(tag, tag_size);
1922     if (MB_SUCCESS != result) {
1923       int nerr=-1; char tagn[64], msg[256];
1924       iMesh_getTagName(instance, tag_handle, tagn, &nerr, sizeof(tagn));
1925       snprintf(msg, sizeof(msg), "iMesh_getArrData: couldn't get size for tag \"%s\"",
1926                nerr==0?tagn:"unknown");
1927       ERROR(result, msg);
1928     }
1929 
1930     ALLOC_CHECK_TAG_ARRAY(tag_values, tag_size * entity_handles_size);
1931 
1932     result = MOABI->tag_get_data(tag, ents, entity_handles_size,
1933                                  *static_cast<void**>(tag_values));
1934 
1935     if (MB_SUCCESS != result) {
1936       std::string message("iMesh_getArrData: ");
1937       if (MB_TAG_NOT_FOUND == result)
1938         message += "tag not found";
1939       else
1940         message += "failed";
1941 
1942       std::string name;
1943       if (MB_SUCCESS == MOABI->tag_get_name( tag, name )) {
1944         message += "for tag \"";
1945         message += name;
1946         message += "\".";
1947       }
1948       ERROR(result, message.c_str());
1949     }
1950 
1951     KEEP_ARRAY(tag_values);
1952     RETURN(iBase_SUCCESS);
1953   }
1954 
iMesh_getIntArrData(iMesh_Instance instance,const iBase_EntityHandle * entity_handles,const int entity_handles_size,const iBase_TagHandle tag_handle,int ** tag_values,int * tag_values_allocated,int * tag_values_size,int * err)1955   void iMesh_getIntArrData (iMesh_Instance instance,
1956                             /*in*/ const iBase_EntityHandle* entity_handles,
1957                             /*in*/ const int entity_handles_size,
1958                             /*in*/ const iBase_TagHandle tag_handle,
1959                             /*inout*/ int** tag_values,
1960                             /*inout*/ int* tag_values_allocated,
1961                             /*out*/ int* tag_values_size, int *err)
1962   {
1963     CHKTAGTYPE(tag_handle, iBase_INTEGER);
1964     *tag_values_allocated *= sizeof(int);
1965     if (tag_values_size != tag_values_allocated) *tag_values_size *= sizeof(int);
1966     iMesh_getArrData(instance, entity_handles,
1967                      entity_handles_size, tag_handle,
1968                      tag_values,
1969                      tag_values_allocated,
1970                      tag_values_size, err);
1971     *tag_values_allocated /= sizeof(int);
1972     if (tag_values_size != tag_values_allocated) *tag_values_size /= sizeof(int);
1973   }
1974 
iMesh_getDblArrData(iMesh_Instance instance,const iBase_EntityHandle * entity_handles,const int entity_handles_size,const iBase_TagHandle tag_handle,double ** tag_values,int * tag_values_allocated,int * tag_values_size,int * err)1975   void iMesh_getDblArrData (iMesh_Instance instance,
1976                             /*in*/ const iBase_EntityHandle* entity_handles,
1977                             /*in*/ const int entity_handles_size,
1978                             /*in*/ const iBase_TagHandle tag_handle,
1979                             /*inout*/ double** tag_values,
1980                             /*inout*/ int* tag_values_allocated,
1981                             /*out*/ int* tag_values_size, int *err)
1982   {
1983     CHKTAGTYPE(tag_handle, iBase_DOUBLE);
1984     *tag_values_allocated *= sizeof(double);
1985     if (tag_values_size != tag_values_allocated) *tag_values_size *= sizeof(double);
1986     iMesh_getArrData(instance, entity_handles,
1987                      entity_handles_size, tag_handle,
1988                      tag_values,
1989                      tag_values_allocated, tag_values_size, err);
1990     *tag_values_allocated /= sizeof(double);
1991     if (tag_values_size != tag_values_allocated) *tag_values_size /= sizeof(double);
1992   }
1993 
iMesh_getEHArrData(iMesh_Instance instance,const iBase_EntityHandle * entity_handles,const int entity_handles_size,const iBase_TagHandle tag_handle,iBase_EntityHandle ** tag_value,int * tag_value_allocated,int * tag_value_size,int * err)1994   void iMesh_getEHArrData (iMesh_Instance instance,
1995                            /*in*/ const iBase_EntityHandle* entity_handles,
1996                            /*in*/ const int entity_handles_size,
1997                            /*in*/ const iBase_TagHandle tag_handle,
1998                            /*inout*/ iBase_EntityHandle** tag_value,
1999                            /*inout*/ int* tag_value_allocated,
2000                            /*out*/ int* tag_value_size, int *err)
2001   {
2002     CHKTAGTYPE(tag_handle, iBase_ENTITY_HANDLE);
2003     *tag_value_allocated *= sizeof(iBase_EntityHandle);
2004     if (tag_value_size != tag_value_allocated) *tag_value_size *= sizeof(iBase_EntityHandle);
2005     iMesh_getArrData(instance, entity_handles,
2006                      entity_handles_size, tag_handle,
2007                      reinterpret_cast<void**>(tag_value),
2008                      tag_value_allocated,
2009                      tag_value_size, err);
2010     *tag_value_allocated /= sizeof(iBase_EntityHandle);
2011     if (tag_value_size != tag_value_allocated) *tag_value_size /= sizeof(iBase_EntityHandle);
2012   }
2013 
iMesh_getESHArrData(iMesh_Instance instance,const iBase_EntityHandle * entity_handles,const int entity_handles_size,const iBase_TagHandle tag_handle,iBase_EntitySetHandle ** tag_value,int * tag_value_allocated,int * tag_value_size,int * err)2014   void iMesh_getESHArrData (iMesh_Instance instance,
2015                            /*in*/ const iBase_EntityHandle* entity_handles,
2016                            /*in*/ const int entity_handles_size,
2017                            /*in*/ const iBase_TagHandle tag_handle,
2018                            /*inout*/ iBase_EntitySetHandle** tag_value,
2019                            /*inout*/ int* tag_value_allocated,
2020                            /*out*/ int* tag_value_size, int *err)
2021   {
2022     CHKTAGTYPE(tag_handle, iBase_ENTITY_SET_HANDLE);
2023     *tag_value_allocated *= sizeof(iBase_EntityHandle);
2024     if (tag_value_size != tag_value_allocated) *tag_value_size *= sizeof(iBase_EntityHandle);
2025     iMesh_getArrData(instance, entity_handles,
2026                      entity_handles_size, tag_handle,
2027                      reinterpret_cast<void**>(tag_value),
2028                      tag_value_allocated,
2029                      tag_value_size, err);
2030     *tag_value_allocated /= sizeof(iBase_EntityHandle);
2031     if (tag_value_size != tag_value_allocated) *tag_value_size /= sizeof(iBase_EntityHandle);
2032   }
2033 
iMesh_setArrData(iMesh_Instance instance,const iBase_EntityHandle * entity_handles,const int entity_handles_size,const iBase_TagHandle tag_handle,const void * tag_values,const int tag_values_size,int * err)2034   void iMesh_setArrData (iMesh_Instance instance,
2035                          /*in*/ const iBase_EntityHandle* entity_handles,
2036                          /*in*/ const int entity_handles_size,
2037                          /*in*/ const iBase_TagHandle tag_handle,
2038                          /*in*/ const void* tag_values,
2039                          /*in*/ const int tag_values_size, int *err)
2040   {
2041     if (0 == entity_handles_size)
2042       RETURN(iBase_SUCCESS);
2043     CHKNONEMPTY();
2044 
2045     int tag_size;
2046     iMesh_getTagSizeBytes(instance, tag_handle, &tag_size, err);
2047     // Check err manually and just return if not iBase_SUCCESS to not step on
2048     // the error set in iMesh_getTagSizeBytes().
2049     if (iBase_SUCCESS != *err)
2050       return;
2051 
2052     if (tag_values_size != (tag_size * entity_handles_size)) {
2053       ERROR(iBase_BAD_ARRAY_SIZE, "iMesh_setArrData: bad tag_values_size passed.");
2054     }
2055 
2056     ErrorCode result = MOABI->tag_set_data(TAG_HANDLE(tag_handle),
2057                                            CONST_HANDLE_ARRAY_PTR(entity_handles),
2058                                            entity_handles_size,
2059                                            tag_values);
2060     CHKERR(result, "iMesh_setArrData didn't succeed.");
2061     RETURN(iBase_SUCCESS);
2062   }
2063 
iMesh_setIntArrData(iMesh_Instance instance,const iBase_EntityHandle * entity_handles,const int entity_handles_size,const iBase_TagHandle tag_handle,const int * tag_values,const int tag_values_size,int * err)2064   void iMesh_setIntArrData (iMesh_Instance instance,
2065                             /*in*/ const iBase_EntityHandle* entity_handles,
2066                             /*in*/ const int entity_handles_size,
2067                             /*in*/ const iBase_TagHandle tag_handle,
2068                             /*in*/ const int* tag_values,
2069                             /*in*/ const int tag_values_size, int *err)
2070   {
2071     CHKTAGTYPE(tag_handle, iBase_INTEGER);
2072     iMesh_setArrData(instance, entity_handles,
2073                      entity_handles_size, tag_handle,
2074                      reinterpret_cast<const char*>(tag_values),
2075                      sizeof(int)*tag_values_size, err);
2076   }
2077 
iMesh_setDblArrData(iMesh_Instance instance,const iBase_EntityHandle * entity_handles,const int entity_handles_size,const iBase_TagHandle tag_handle,const double * tag_values,const int tag_values_size,int * err)2078   void iMesh_setDblArrData (iMesh_Instance instance,
2079                             /*in*/ const iBase_EntityHandle* entity_handles,
2080                             /*in*/ const int entity_handles_size,
2081                             /*in*/ const iBase_TagHandle tag_handle,
2082                             /*in*/ const double* tag_values,
2083                             /*in*/ const int tag_values_size, int *err)
2084   {
2085     CHKTAGTYPE(tag_handle, iBase_DOUBLE);
2086     iMesh_setArrData(instance, entity_handles,
2087                      entity_handles_size, tag_handle,
2088                      reinterpret_cast<const char*>(tag_values),
2089                      sizeof(double)*tag_values_size, err);
2090   }
2091 
iMesh_setEHArrData(iMesh_Instance instance,const iBase_EntityHandle * entity_handles,const int entity_handles_size,const iBase_TagHandle tag_handle,const iBase_EntityHandle * tag_values,const int tag_values_size,int * err)2092   void iMesh_setEHArrData (iMesh_Instance instance,
2093                            /*in*/ const iBase_EntityHandle* entity_handles,
2094                            /*in*/ const int entity_handles_size,
2095                            /*in*/ const iBase_TagHandle tag_handle,
2096                            /*in*/ const iBase_EntityHandle* tag_values,
2097                            /*in*/ const int tag_values_size, int *err)
2098   {
2099     CHKTAGTYPE(tag_handle, iBase_ENTITY_HANDLE);
2100     iMesh_setArrData(instance, entity_handles,
2101                      entity_handles_size, tag_handle,
2102                      reinterpret_cast<const char*>(tag_values),
2103                      sizeof(iBase_EntityHandle)*tag_values_size, err);
2104   }
2105 
iMesh_setESHArrData(iMesh_Instance instance,const iBase_EntityHandle * entity_handles,const int entity_handles_size,const iBase_TagHandle tag_handle,const iBase_EntitySetHandle * tag_values,const int tag_values_size,int * err)2106   void iMesh_setESHArrData (iMesh_Instance instance,
2107                            /*in*/ const iBase_EntityHandle* entity_handles,
2108                            /*in*/ const int entity_handles_size,
2109                            /*in*/ const iBase_TagHandle tag_handle,
2110                            /*in*/ const iBase_EntitySetHandle* tag_values,
2111                            /*in*/ const int tag_values_size, int *err)
2112   {
2113     CHKTAGTYPE(tag_handle, iBase_ENTITY_SET_HANDLE);
2114     iMesh_setArrData(instance, entity_handles,
2115                      entity_handles_size, tag_handle,
2116                      reinterpret_cast<const char*>(tag_values),
2117                      sizeof(iBase_EntityHandle)*tag_values_size, err);
2118   }
2119 
iMesh_rmvArrTag(iMesh_Instance instance,const iBase_EntityHandle * entity_handles,const int entity_handles_size,const iBase_TagHandle tag_handle,int * err)2120   void iMesh_rmvArrTag (iMesh_Instance instance,
2121                         /*in*/ const iBase_EntityHandle* entity_handles,
2122                         /*in*/ const int entity_handles_size,
2123                         /*in*/ const iBase_TagHandle tag_handle, int *err)
2124   {
2125     if (0 == entity_handles_size)
2126       RETURN(iBase_SUCCESS);
2127     CHKNONEMPTY();
2128 
2129     ErrorCode result = MOABI->tag_delete_data(TAG_HANDLE(tag_handle),
2130                                               CONST_HANDLE_ARRAY_PTR(entity_handles),
2131                                               entity_handles_size);
2132 
2133       // don't return an error if the tag simply wasn't set on the entities
2134     if (MB_TAG_NOT_FOUND == result)
2135       RETURN(iBase_SUCCESS);
2136     else
2137       RETURN(iBase_ERROR_MAP[result]);
2138   }
2139 
iMesh_getData(iMesh_Instance instance,const iBase_EntityHandle entity_handle,const iBase_TagHandle tag_handle,void * tag_value,int * tag_value_allocated,int * tag_value_size,int * err)2140   void iMesh_getData (iMesh_Instance instance,
2141                       /*in*/ const iBase_EntityHandle entity_handle,
2142                       /*in*/ const iBase_TagHandle tag_handle,
2143                       /*out*/ void* tag_value,
2144                       /*inout*/ int *tag_value_allocated,
2145                       /*out*/ int *tag_value_size, int *err)
2146   {
2147     iMesh_getArrData(instance, &entity_handle, 1,
2148                      tag_handle, tag_value, tag_value_allocated,
2149                      tag_value_size, err);
2150   }
2151 
iMesh_getIntData(iMesh_Instance instance,const iBase_EntityHandle entity_handle,const iBase_TagHandle tag_handle,int * out_data,int * err)2152   void iMesh_getIntData (iMesh_Instance instance,
2153                          /*in*/ const iBase_EntityHandle entity_handle,
2154                          /*in*/ const iBase_TagHandle tag_handle,
2155                          int *out_data, int *err)
2156   {
2157     CHKTAGTYPE(tag_handle, iBase_INTEGER);
2158     void *val_ptr = out_data;
2159     int val_size = sizeof(int);
2160     iMesh_getArrData(instance, &entity_handle, 1,
2161                      tag_handle, &val_ptr, &val_size, &val_size, err);
2162   }
2163 
iMesh_getDblData(iMesh_Instance instance,const iBase_EntityHandle entity_handle,const iBase_TagHandle tag_handle,double * out_data,int * err)2164   void iMesh_getDblData (iMesh_Instance instance,
2165                          /*in*/ const iBase_EntityHandle entity_handle,
2166                          /*in*/ const iBase_TagHandle tag_handle,
2167                          double *out_data, int *err)
2168   {
2169     CHKTAGTYPE(tag_handle, iBase_DOUBLE);
2170     void *val_ptr = out_data;
2171     int val_size = sizeof(double);
2172     iMesh_getArrData(instance, &entity_handle, 1,
2173                      tag_handle, &val_ptr, &val_size, &val_size, err);
2174   }
2175 
iMesh_getEHData(iMesh_Instance instance,const iBase_EntityHandle entity_handle,const iBase_TagHandle tag_handle,iBase_EntityHandle * out_data,int * err)2176   void iMesh_getEHData (iMesh_Instance instance,
2177                         /*in*/ const iBase_EntityHandle entity_handle,
2178                         /*in*/ const iBase_TagHandle tag_handle,
2179                         iBase_EntityHandle *out_data, int *err)
2180   {
2181     CHKTAGTYPE(tag_handle, iBase_ENTITY_HANDLE);
2182     void *val_ptr = out_data;
2183     int dum = sizeof(iBase_EntityHandle);
2184     iMesh_getArrData(instance, &entity_handle, 1,
2185                      tag_handle, &val_ptr, &dum, &dum, err);
2186   }
2187 
iMesh_getESHData(iMesh_Instance instance,const iBase_EntityHandle entity_handle,const iBase_TagHandle tag_handle,iBase_EntitySetHandle * out_data,int * err)2188   void iMesh_getESHData (iMesh_Instance instance,
2189                         /*in*/ const iBase_EntityHandle entity_handle,
2190                         /*in*/ const iBase_TagHandle tag_handle,
2191                         iBase_EntitySetHandle *out_data, int *err)
2192   {
2193     CHKTAGTYPE(tag_handle, iBase_ENTITY_SET_HANDLE);
2194     void *val_ptr = out_data;
2195     int dum = sizeof(iBase_EntityHandle);
2196     iMesh_getArrData(instance, &entity_handle, 1,
2197                      tag_handle, &val_ptr, &dum, &dum, err);
2198   }
2199 
iMesh_setData(iMesh_Instance instance,iBase_EntityHandle entity_handle,const iBase_TagHandle tag_handle,const void * tag_value,const int tag_value_size,int * err)2200   void iMesh_setData (iMesh_Instance instance,
2201                       /*in*/ iBase_EntityHandle entity_handle,
2202                       /*in*/ const iBase_TagHandle tag_handle,
2203                       /*in*/ const void* tag_value,
2204                       /*in*/ const int tag_value_size, int *err)
2205   {
2206     iMesh_setArrData(instance, &entity_handle, 1,
2207                      tag_handle, tag_value, tag_value_size, err);
2208   }
2209 
iMesh_setIntData(iMesh_Instance instance,iBase_EntityHandle entity_handle,const iBase_TagHandle tag_handle,const int tag_value,int * err)2210   void iMesh_setIntData (iMesh_Instance instance,
2211                          /*in*/ iBase_EntityHandle entity_handle,
2212                          /*in*/ const iBase_TagHandle tag_handle,
2213                          /*in*/ const int tag_value, int *err)
2214   {
2215     CHKTAGTYPE(tag_handle, iBase_INTEGER);
2216     iMesh_setArrData(instance, &entity_handle, 1,
2217                      tag_handle,
2218                      reinterpret_cast<const char*>(&tag_value),
2219                      sizeof(int), err);
2220   }
2221 
iMesh_setDblData(iMesh_Instance instance,iBase_EntityHandle entity_handle,const iBase_TagHandle tag_handle,const double tag_value,int * err)2222   void iMesh_setDblData (iMesh_Instance instance,
2223 
2224                          /*in*/ iBase_EntityHandle entity_handle,
2225                          /*in*/ const iBase_TagHandle tag_handle,
2226                          /*in*/ const double tag_value, int *err)
2227   {
2228     CHKTAGTYPE(tag_handle, iBase_DOUBLE);
2229     iMesh_setArrData(instance, &entity_handle, 1,
2230                      tag_handle,
2231                      reinterpret_cast<const char*>(&tag_value),
2232                      sizeof(double), err);
2233   }
2234 
iMesh_setEHData(iMesh_Instance instance,iBase_EntityHandle entity_handle,const iBase_TagHandle tag_handle,const iBase_EntityHandle tag_value,int * err)2235   void iMesh_setEHData (iMesh_Instance instance,
2236                         /*in*/ iBase_EntityHandle entity_handle,
2237                         /*in*/ const iBase_TagHandle tag_handle,
2238                         /*in*/ const iBase_EntityHandle tag_value, int *err)
2239   {
2240     CHKTAGTYPE(tag_handle, iBase_ENTITY_HANDLE);
2241     iMesh_setArrData(instance, &entity_handle, 1,
2242                      tag_handle,
2243                      reinterpret_cast<const char*>(&tag_value),
2244                      sizeof(iBase_EntityHandle), err);
2245   }
2246 
iMesh_setESHData(iMesh_Instance instance,iBase_EntityHandle entity_handle,const iBase_TagHandle tag_handle,const iBase_EntitySetHandle tag_value,int * err)2247   void iMesh_setESHData (iMesh_Instance instance,
2248                         /*in*/ iBase_EntityHandle entity_handle,
2249                         /*in*/ const iBase_TagHandle tag_handle,
2250                         /*in*/ const iBase_EntitySetHandle tag_value, int *err)
2251   {
2252     CHKTAGTYPE(tag_handle, iBase_ENTITY_SET_HANDLE);
2253     iMesh_setArrData(instance, &entity_handle, 1,
2254                      tag_handle,
2255                      reinterpret_cast<const char*>(&tag_value),
2256                      sizeof(iBase_EntityHandle), err);
2257   }
2258 
iMesh_getAllTags(iMesh_Instance instance,const iBase_EntityHandle entity_handle,iBase_TagHandle ** tag_handles,int * tag_handles_allocated,int * tag_handles_size,int * err)2259   void iMesh_getAllTags (iMesh_Instance instance,
2260                          /*in*/ const iBase_EntityHandle entity_handle,
2261                          /*inout*/ iBase_TagHandle** tag_handles,
2262                          /*inout*/ int* tag_handles_allocated,
2263                          /*out*/ int* tag_handles_size, int *err)
2264   {
2265     std::vector<Tag> all_tags;
2266 
2267     ErrorCode result = MOABI->tag_get_tags_on_entity(ENTITY_HANDLE(entity_handle), all_tags);
2268     CHKERR(result, "iMesh_getAllTags failed.");
2269 
2270     remove_var_len_tags( MOABI, all_tags );
2271 
2272       // now put those tag handles into sidl array
2273     ALLOC_CHECK_ARRAY_NOFAIL(tag_handles, all_tags.size());
2274     memcpy(*tag_handles, &all_tags[0], all_tags.size()*sizeof(Tag));
2275     *tag_handles_size = all_tags.size();
2276 
2277     RETURN(iBase_SUCCESS);
2278   }
2279 
iMesh_rmvTag(iMesh_Instance instance,iBase_EntityHandle entity_handle,const iBase_TagHandle tag_handle,int * err)2280   void iMesh_rmvTag (iMesh_Instance instance,
2281                      /*in*/ iBase_EntityHandle entity_handle,
2282                      /*in*/ const iBase_TagHandle tag_handle, int *err)
2283   {
2284     iMesh_rmvArrTag(instance, &entity_handle, 1, tag_handle, err);
2285   }
2286 
iMesh_initEntIter(iMesh_Instance instance,const iBase_EntitySetHandle entity_set_handle,const int requested_entity_type,const int requested_entity_topology,const int resilient,iBase_EntityIterator * entity_iterator,int * err)2287   void iMesh_initEntIter (iMesh_Instance instance,
2288                           /*in*/ const iBase_EntitySetHandle entity_set_handle,
2289                           /*in*/ const int requested_entity_type,
2290                           /*in*/ const int requested_entity_topology,
2291                           /*in*/ const int resilient,
2292                           /*out*/ iBase_EntityIterator* entity_iterator,
2293                           int *err)
2294   {
2295     iMesh_initEntArrIterRec(instance, entity_set_handle, requested_entity_type,
2296                             requested_entity_topology, 1, resilient, false,
2297                             reinterpret_cast<iBase_EntityArrIterator*>(entity_iterator),
2298                             err);
2299   }
2300 
iMesh_getNextEntIter(iMesh_Instance instance,iBase_EntityIterator entity_iterator,iBase_EntityHandle * entity_handle,int * is_end,int * err)2301   void iMesh_getNextEntIter (iMesh_Instance instance,
2302                              /*in*/ iBase_EntityIterator entity_iterator,
2303                              /*out*/ iBase_EntityHandle* entity_handle,
2304                              int *is_end, int *err)
2305   {
2306     int eh_size = 1;
2307     iMesh_getNextEntArrIter(instance,
2308                             reinterpret_cast<iBase_EntityArrIterator>(entity_iterator),
2309                             &entity_handle, &eh_size, &eh_size, is_end, err);
2310 
2311   }
2312 
iMesh_resetEntIter(iMesh_Instance instance,iBase_EntityIterator entity_iterator,int * err)2313   void iMesh_resetEntIter (iMesh_Instance instance,
2314                            /*in*/ iBase_EntityIterator entity_iterator, int *err)
2315   {
2316     iMesh_resetEntArrIter(instance,
2317                           reinterpret_cast<iBase_EntityArrIterator>(entity_iterator),
2318                           err);
2319   }
2320 
iMesh_endEntIter(iMesh_Instance instance,iBase_EntityIterator entity_iterator,int * err)2321   void iMesh_endEntIter (iMesh_Instance instance,
2322                          /*in*/ iBase_EntityIterator entity_iterator, int *err)
2323   {
2324     iMesh_endEntArrIter(instance,
2325                         reinterpret_cast<iBase_EntityArrIterator>(entity_iterator),
2326                         err);
2327   }
2328 
iMesh_getEntTopo(iMesh_Instance instance,const iBase_EntityHandle entity_handle,int * out_topo,int * err)2329   void iMesh_getEntTopo (iMesh_Instance instance,
2330                          /*in*/ const iBase_EntityHandle entity_handle,
2331                          int *out_topo, int *err)
2332   {
2333     *out_topo = tstt_topology_table[MOABI->type_from_handle(ENTITY_HANDLE(entity_handle))];
2334     RETURN(iBase_SUCCESS);
2335   }
2336 
iMesh_getEntType(iMesh_Instance instance,const iBase_EntityHandle entity_handle,int * out_type,int * err)2337   void iMesh_getEntType (iMesh_Instance instance,
2338                          /*in*/ const iBase_EntityHandle entity_handle,
2339                          int *out_type, int *err)
2340   {
2341     *out_type = tstt_type_table[MOABI->type_from_handle(ENTITY_HANDLE(entity_handle))];
2342     RETURN(iBase_SUCCESS);
2343   }
2344 
iMesh_getVtxCoord(iMesh_Instance instance,const iBase_EntityHandle vertex_handle,double * x,double * y,double * z,int * err)2345   void iMesh_getVtxCoord (iMesh_Instance instance,
2346                           /*in*/ const iBase_EntityHandle vertex_handle,
2347                           /*out*/ double *x, /*out*/ double *y, /*out*/ double *z, int *err)
2348   {
2349     int order = iBase_BLOCKED;
2350     double xyz[3] = {0}, *tmp_xyz = xyz;
2351     int dum = 3;
2352 
2353     iMesh_getVtxArrCoords(instance,
2354                           &vertex_handle, 1, order,
2355                           &tmp_xyz, &dum, &dum, err);
2356     if (iBase_SUCCESS == *err) {
2357       *x = xyz[0]; *y = xyz[1]; *z = xyz[2];
2358     }
2359   }
2360 
iMesh_getEntAdj(iMesh_Instance instance,const iBase_EntityHandle entity_handle,const int entity_type_requested,iBase_EntityHandle ** adj_entity_handles,int * adj_entity_handles_allocated,int * adj_entity_handles_size,int * err)2361   void iMesh_getEntAdj(iMesh_Instance instance,
2362                        /*in*/ const iBase_EntityHandle entity_handle,
2363                        /*in*/ const int entity_type_requested,
2364                        /*inout*/ iBase_EntityHandle** adj_entity_handles,
2365                        /*inout*/ int* adj_entity_handles_allocated,
2366                        /*out*/ int* adj_entity_handles_size, int *err)
2367   {
2368     int offsets[2];
2369     int *offsets_ptr = offsets;
2370     int offset_size, offset_allocated = 2;
2371 
2372     iMesh_getEntArrAdj(instance,
2373                        &entity_handle, 1, entity_type_requested,
2374                        adj_entity_handles, adj_entity_handles_allocated,
2375                        adj_entity_handles_size, &offsets_ptr, &offset_allocated,
2376                        &offset_size, err);
2377   }
2378 
iMesh_getEnt2ndAdj(iMesh_Instance instance,iBase_EntityHandle entity_handle,int order_adjacent_key,int requested_entity_type,iBase_EntityHandle ** adj_entities,int * adj_entities_allocated,int * adj_entities_size,int * err)2379   void iMesh_getEnt2ndAdj( iMesh_Instance instance,
2380                            iBase_EntityHandle entity_handle,
2381                            int order_adjacent_key,
2382                            int requested_entity_type,
2383                            iBase_EntityHandle** adj_entities,
2384                            int* adj_entities_allocated,
2385                            int* adj_entities_size,
2386                            int* err )
2387   {
2388     int offsets[2];
2389     int *offsets_ptr = offsets;
2390     int offset_size, offset_allocated = 2;
2391 
2392     iMesh_getEntArr2ndAdj(instance,
2393                           &entity_handle, 1, order_adjacent_key,
2394                           requested_entity_type,
2395                           adj_entities, adj_entities_allocated,
2396                           adj_entities_size, &offsets_ptr, &offset_allocated,
2397                           &offset_size, err);
2398   }
2399 
iMesh_subtract(iMesh_Instance instance,const iBase_EntitySetHandle entity_set_1,const iBase_EntitySetHandle entity_set_2,iBase_EntitySetHandle * result_entity_set,int * err)2400   void iMesh_subtract(iMesh_Instance instance,
2401                       /*in*/ const iBase_EntitySetHandle entity_set_1,
2402                       /*in*/ const iBase_EntitySetHandle entity_set_2,
2403                       /*out*/ iBase_EntitySetHandle* result_entity_set, int *err)
2404   {
2405     EntityHandle temp_set;
2406     EntityHandle set1 = ENTITY_HANDLE(entity_set_1),
2407       set2 = ENTITY_HANDLE(entity_set_2);
2408 
2409     int isList1=0, isList2=0;
2410     iMesh_isList(instance, entity_set_1, &isList1, err);
2411     if (*err != iBase_SUCCESS) return;
2412     iMesh_isList(instance, entity_set_2, &isList2, err);
2413     if (*err != iBase_SUCCESS) return;
2414 
2415     ErrorCode result;
2416     if (isList1 && isList2)
2417       result = MOABI->create_meshset(MESHSET_ORDERED, temp_set);
2418     else
2419       result = MOABI->create_meshset(MESHSET_SET, temp_set);
2420 
2421     if (MB_SUCCESS != result)
2422       ERROR(result, "iMesh_subtract: couldn't create result set.");
2423 
2424       // if the second set is the root set, the result is always the empty set
2425     if (entity_set_2) {
2426       if (!entity_set_1) {
2427           // subtracting from the root set, so get everything first...
2428         Range entities;
2429         result = MOABI->get_entities_by_handle(0,entities);
2430         if (MB_SUCCESS == result)
2431           result = MOABI->add_entities(temp_set, entities);
2432           // ...but not the newly-created set!
2433         if (MB_SUCCESS == result)
2434           result = MOABI->remove_entities(temp_set, &temp_set, 1);
2435       }
2436       else
2437         result = MOABI->unite_meshset(temp_set, set1);
2438 
2439       if (MB_SUCCESS == result)
2440         result = MOABI->subtract_meshset(temp_set, set2);
2441     }
2442 
2443     CHKERR(result, "iMesh_subtract: ERROR subtract failed.");
2444     *result_entity_set = (iBase_EntitySetHandle)temp_set;
2445 
2446     RETURN(iBase_SUCCESS);
2447   }
2448 
iMesh_intersect(iMesh_Instance instance,const iBase_EntitySetHandle entity_set_1,const iBase_EntitySetHandle entity_set_2,iBase_EntitySetHandle * result_entity_set,int * err)2449   void iMesh_intersect(iMesh_Instance instance,
2450                        /*in*/ const iBase_EntitySetHandle entity_set_1,
2451                        /*in*/ const iBase_EntitySetHandle entity_set_2,
2452                        /*out*/ iBase_EntitySetHandle* result_entity_set, int *err)
2453   {
2454     EntityHandle temp_set;
2455     EntityHandle set1 = ENTITY_HANDLE(entity_set_1),
2456       set2 = ENTITY_HANDLE(entity_set_2);
2457 
2458     int isList1=0, isList2=0;
2459     iMesh_isList(instance, entity_set_1, &isList1, err);
2460     if (*err != iBase_SUCCESS) return;
2461     iMesh_isList(instance, entity_set_2, &isList2, err);
2462     if (*err != iBase_SUCCESS) return;
2463 
2464     ErrorCode result;
2465     if (isList1 && isList2)
2466       result = MOABI->create_meshset(MESHSET_ORDERED, temp_set);
2467     else
2468       result = MOABI->create_meshset(MESHSET_SET, temp_set);
2469 
2470     if (MB_SUCCESS != result)
2471       ERROR(result, "iMesh_intersect: couldn't create result set.");
2472 
2473     if (!entity_set_1 && !entity_set_2) {
2474         // intersecting the root set with itself, so get everything...
2475       Range entities;
2476       result = MOABI->get_entities_by_handle(0, entities);
2477       if (MB_SUCCESS == result)
2478         result = MOABI->add_entities(temp_set, entities);
2479         // ...but not the newly-created set!
2480       if (MB_SUCCESS == result)
2481         result = MOABI->remove_entities(temp_set, &temp_set, 1);
2482     }
2483     else if (!entity_set_1) {
2484       result = MOABI->unite_meshset(temp_set, set2);
2485     }
2486     else if (!entity_set_2) {
2487       result = MOABI->unite_meshset(temp_set, set1);
2488     }
2489     else {
2490       if (isList1 && isList2) {
2491           // ITAPS has very specific rules about the behavior of intersection on
2492           // list-type sets. Since MOAB doesn't (and likely will never) work
2493           // exactly this way, we implement our own algorithm here.
2494 
2495 #ifdef MOAB_HAVE_UNORDERED_MAP
2496         typedef MOAB_UNORDERED_MAP_NS::unordered_map<EntityHandle, size_t> lookup_t;
2497 #else
2498         typedef std::map<EntityHandle, size_t> lookup_t;
2499 #endif
2500 
2501           // First, build a lookup table for the second set.
2502         lookup_t lookup;
2503         {
2504           std::vector<EntityHandle> contents2;
2505           result = MOABI->get_entities_by_handle(set2, contents2);
2506           CHKERR(result,"iMesh_intersect: ERROR intersect failed.");
2507 
2508           for (std::vector<EntityHandle>::iterator i = contents2.begin();
2509                i != contents2.end(); ++i) {
2510 #ifdef MOAB_HAVE_UNORDERED_MAP
2511             lookup_t::iterator j = lookup.find(*i);
2512 #else
2513             lookup_t::iterator j = lookup.lower_bound(*i);
2514 #endif
2515             if (j != lookup.end() && j->first == *i)
2516               ++j->second;
2517             else
2518               lookup.insert(j, lookup_t::value_type(*i, 1));
2519           }
2520         }
2521 
2522           // Then, iterate over the contents of the first set and check for
2523           // their existence in the second set.
2524         std::vector<EntityHandle> contents1;
2525         result = MOABI->get_entities_by_handle(set1, contents1);
2526         CHKERR(result,"iMesh_intersect: ERROR intersect failed.");
2527 
2528         std::vector<EntityHandle>::iterator w = contents1.begin();
2529         for (std::vector<EntityHandle>::iterator i = contents1.begin();
2530              i != contents1.end(); ++i) {
2531           lookup_t::iterator j = lookup.find(*i);
2532           if (j != lookup.end() && j->second) {
2533             --j->second;
2534             *w = *i;
2535             ++w;
2536           }
2537         }
2538 
2539         result = MOABI->add_entities(temp_set, &contents1[0],
2540                                      w - contents1.begin());
2541       }
2542       else {
2543         result = MOABI->unite_meshset(temp_set, set1);
2544         if (MB_SUCCESS == result)
2545           result = MOABI->intersect_meshset(temp_set, set2);
2546       }
2547     }
2548 
2549     CHKERR(result,"iMesh_intersect: ERROR intersect failed.");
2550     *result_entity_set = (iBase_EntitySetHandle)temp_set;
2551 
2552     RETURN(iBase_SUCCESS);
2553   }
2554 
iMesh_unite(iMesh_Instance instance,const iBase_EntitySetHandle entity_set_1,const iBase_EntitySetHandle entity_set_2,iBase_EntitySetHandle * result_entity_set,int * err)2555   void iMesh_unite(iMesh_Instance instance,
2556                    /*in*/ const iBase_EntitySetHandle entity_set_1,
2557                    /*in*/ const iBase_EntitySetHandle entity_set_2,
2558                    /*out*/ iBase_EntitySetHandle* result_entity_set, int *err)
2559   {
2560     EntityHandle temp_set;
2561     EntityHandle set1 = ENTITY_HANDLE(entity_set_1),
2562       set2 = ENTITY_HANDLE(entity_set_2);
2563 
2564     int isList1=0, isList2=0;
2565     iMesh_isList(instance, entity_set_1, &isList1, err);
2566     if (*err != iBase_SUCCESS) return;
2567     iMesh_isList(instance, entity_set_2, &isList2, err);
2568     if (*err != iBase_SUCCESS) return;
2569 
2570     ErrorCode result;
2571     if (isList1 && isList2)
2572       result = MOABI->create_meshset(MESHSET_ORDERED, temp_set);
2573     else
2574       result = MOABI->create_meshset(MESHSET_SET, temp_set);
2575 
2576     if (MB_SUCCESS != result)
2577       ERROR(result, "iMesh_unite: couldn't create result set.");
2578 
2579 
2580     if (entity_set_1 && entity_set_2) {
2581       result = MOABI->unite_meshset(temp_set, set1);
2582       if (MB_SUCCESS == result)
2583         result = MOABI->unite_meshset(temp_set, set2);
2584     }
2585     else {
2586         // uniting with the root set, so get everything...
2587       Range entities;
2588       result = MOABI->get_entities_by_handle(0, entities);
2589       if (MB_SUCCESS == result)
2590         result = MOABI->add_entities(temp_set, entities);
2591         // ...but not the newly-created set!
2592       if (MB_SUCCESS == result)
2593         result = MOABI->remove_entities(temp_set, &temp_set, 1);
2594     }
2595 
2596     CHKERR(result,"iMesh_unite: ERROR unite failed.");
2597 
2598     *result_entity_set = (iBase_EntitySetHandle)temp_set;
2599 
2600     RETURN(iBase_SUCCESS);
2601   }
2602 
iMesh_getEntitiesRec(iMesh_Instance instance,const iBase_EntitySetHandle entity_set_handle,const int entity_type,const int entity_topology,const int recursive,iBase_EntityHandle ** entity_handles,int * entity_handles_allocated,int * entity_handles_size,int * err)2603   void iMesh_getEntitiesRec(iMesh_Instance instance,
2604                             /*in*/ const iBase_EntitySetHandle entity_set_handle,
2605                             /*in*/ const int entity_type,
2606                             /*in*/ const int entity_topology,
2607                             /*in*/ const int recursive,
2608                             /*out*/ iBase_EntityHandle** entity_handles,
2609                             /*out*/ int* entity_handles_allocated,
2610                             /*out*/ int* entity_handles_size,
2611                             /*out*/ int *err)
2612   {
2613     CHKENUM(entity_type, iBase_EntityType, iBase_INVALID_ENTITY_TYPE);
2614     CHKENUM(entity_topology, iMesh_EntityTopology,
2615             iBase_INVALID_ENTITY_TOPOLOGY);
2616 
2617     bool use_top = false;
2618       // initialize just to get rid of compiler warning
2619     EntityType type = mb_topology_table[iMesh_ALL_TOPOLOGIES];
2620     std::vector<EntityHandle> out_entities;
2621 
2622     if (entity_topology != iMesh_ALL_TOPOLOGIES) {
2623       type = mb_topology_table[entity_topology];
2624       use_top = true;
2625 
2626       if (entity_type != iBase_ALL_TYPES) {
2627         if (entity_topology != iMesh_SEPTAHEDRON &&
2628             entity_type != CN::Dimension(type))
2629           ERROR(iBase_BAD_TYPE_AND_TOPO, "type and topology are inconsistant");
2630 
2631           // Special-case handling for septahedra since we don't support them
2632         else if (entity_topology == iMesh_SEPTAHEDRON &&
2633                  entity_type != iBase_REGION)
2634           ERROR(iBase_BAD_TYPE_AND_TOPO, "type and topology are inconsistant");
2635       }
2636     }
2637 
2638     EntityHandle handle = ENTITY_HANDLE(entity_set_handle);
2639     ErrorCode result;
2640 
2641     if (use_top) {
2642       if (entity_topology == iMesh_SEPTAHEDRON)
2643         result = MB_SUCCESS;  // MOAB doesn't do septahedrons, so there are never any.
2644       else
2645         result = MOABI->get_entities_by_type(handle, type, out_entities, recursive);
2646     }
2647     else if (entity_type != iBase_ALL_TYPES)
2648       result = MOABI->get_entities_by_dimension(handle, entity_type, out_entities, recursive);
2649     else
2650       result = MOABI->get_entities_by_handle(handle, out_entities, recursive);
2651 
2652     CHKERR(result,"iMesh_GetEntities:ERROR getting entities.");
2653 
2654       // remove entity sets from the result list
2655     std::vector<EntityHandle>::iterator iter, end_iter;
2656     if (iBase_ALL_TYPES == entity_type && iMesh_ALL_TOPOLOGIES == entity_topology) {
2657       for (iter = out_entities.begin(); iter != out_entities.end() &&
2658            TYPE_FROM_HANDLE(*iter) != MBENTITYSET; ++iter);
2659       for (end_iter = iter; iter != out_entities.end(); ++iter)
2660         if (TYPE_FROM_HANDLE(*iter) != MBENTITYSET)
2661           *(end_iter++) = *iter;
2662       out_entities.erase( end_iter, out_entities.end() );
2663     }
2664 
2665     int num_ents = out_entities.size();
2666 
2667     ALLOC_CHECK_ARRAY_NOFAIL(entity_handles, num_ents);
2668 
2669     int k = 0;
2670 
2671       // filter out entity sets here
2672     for (iter = out_entities.begin(); iter != out_entities.end(); ++iter)
2673       (*entity_handles)[k++] = (iBase_EntityHandle)*iter;
2674 
2675       // now it's safe to set the size; set it to k, not out_entities.size(), to
2676       // account for sets which might have been removed
2677     *entity_handles_size = k;
2678 
2679     RETURN(iBase_SUCCESS);
2680   }
2681 
2682     /**\brief  Get the number of entities with the specified type in the instance or set, recursive
2683      *
2684      * Get the number of entities with the specified type in the instance
2685      * or set.  If recursive is passed in non-zero, includes entities in owned sets.
2686      * If entity set handle is zero, return information for instance,
2687      * otherwise for set.  Value of entity type must be from the
2688      * iBase_EntityType enumeration.  If iBase_ALL_TYPES is specified,
2689      * total number of entities (excluding entity sets) is returned.
2690      * \param instance iMesh instance handle
2691      * \param entity_set_handle Entity set being queried
2692      * \param entity_type Type of entity requested
2693      * \param recursive If non-zero, includes entities in owned sets too
2694      * \param num_type Pointer to number of entities, returned from function
2695      * \param *err Pointer to error type returned from function
2696      */
iMesh_getNumOfTypeRec(iMesh_Instance instance,const iBase_EntitySetHandle entity_set_handle,const int entity_type,const int recursive,int * num_type,int * err)2697   void iMesh_getNumOfTypeRec(iMesh_Instance instance,
2698                              /*in*/ const iBase_EntitySetHandle entity_set_handle,
2699                              /*in*/ const int entity_type,
2700                              /*in*/ const int recursive,
2701                              /*out*/ int *num_type,
2702                              /*out*/ int *err)
2703   {
2704     CHKENUM(entity_type, iBase_EntityType, iBase_INVALID_ENTITY_TYPE);
2705 
2706     *num_type = 0;
2707     ErrorCode result;
2708     if (entity_type == iBase_ALL_TYPES) {
2709       result = MOABI->get_number_entities_by_handle
2710         (ENTITY_HANDLE(entity_set_handle), *num_type, recursive);
2711       if (MB_SUCCESS == result && !recursive) {
2712         int num_sets = 0;
2713         result = MOABI->get_number_entities_by_type
2714           (ENTITY_HANDLE(entity_set_handle), MBENTITYSET, num_sets, recursive);
2715         *num_type -= num_sets;
2716       }
2717     } else {
2718       result = MOABI->get_number_entities_by_dimension
2719         (ENTITY_HANDLE(entity_set_handle), entity_type, *num_type, recursive);
2720     }
2721 
2722     CHKERR(result,"iMesh_entitysetGetNumberEntityOfType: "
2723                   "ERROR getting number of entities by type.");
2724 
2725     RETURN(iBase_SUCCESS);
2726   }
2727 
2728 
2729     /**\brief  Get the number of entities with the specified topology in the instance or set
2730      *
2731      * Get the number of entities with the specified topology in the instance
2732      * or set.  If recursive is passed in non-zero, includes entities in owned sets.
2733      * If entity set handle is zero, return information for instance,
2734      * otherwise for set.  Value of entity topology must be from the
2735      * iMesh_EntityTopology enumeration.  If iMesh_ALL_TOPOLOGIES is specified,
2736      * total number of entities (excluding entity sets) is returned.
2737      * \param instance iMesh instance handle
2738      * \param entity_set_handle Entity set being queried
2739      * \param entity_topology Topology of entity requested
2740      * \param recursive If non-zero, includes entities in owned sets too
2741      * \param num_topo Pointer to number of entities, returned from function
2742      * \param *err Pointer to error type returned from function
2743      */
iMesh_getNumOfTopoRec(iMesh_Instance instance,const iBase_EntitySetHandle entity_set_handle,const int entity_topology,const int recursive,int * num_topo,int * err)2744   void iMesh_getNumOfTopoRec(iMesh_Instance instance,
2745                              /*in*/ const iBase_EntitySetHandle entity_set_handle,
2746                              /*in*/ const int entity_topology,
2747                              /*in*/ const int recursive,
2748                              /*out*/ int *num_topo,
2749                              /*out*/ int *err)
2750   {
2751     CHKENUM(entity_topology, iMesh_EntityTopology,
2752             iBase_INVALID_ENTITY_TOPOLOGY);
2753 
2754     if (entity_topology == iMesh_SEPTAHEDRON) {
2755       *num_topo = 0;
2756       RETURN(iBase_SUCCESS);
2757     }
2758 
2759     *num_topo = 0;
2760     ErrorCode result;
2761     if (iMesh_ALL_TOPOLOGIES == entity_topology) {
2762       result = MOABI->get_number_entities_by_handle(ENTITY_HANDLE(entity_set_handle),
2763                                                   *num_topo, recursive);
2764 
2765       if (!recursive && MB_SUCCESS == result) { // remove entity sets from count
2766         int num_sets;
2767         result = MOABI->get_number_entities_by_type
2768           (ENTITY_HANDLE(entity_set_handle), MBENTITYSET, num_sets, recursive);
2769         *num_topo -= num_sets;
2770       }
2771     }
2772     else {
2773       result = MOABI->get_number_entities_by_type(ENTITY_HANDLE(entity_set_handle),
2774                                          mb_topology_table[entity_topology],
2775                                          *num_topo, recursive);
2776     }
2777 
2778     CHKERR(result,"iMesh_entitysetGetNumberEntityOfTopology: ERROR getting "
2779                       "number of entities by topology.");
2780     RETURN(iBase_SUCCESS);
2781   }
2782 
2783     /**\brief  Get entities with specified type, topology, tag(s) and (optionally) tag value(s)
2784      *
2785      * Get entities with the specified type, topology, tag(s), and optionally tag value(s).
2786      * If tag values pointer is input as zero, entities with specified tag(s) are returned,
2787      * regardless of their value.
2788      * \param instance iMesh instance handle
2789      * \param entity_set_handle Entity set being queried
2790      * \param entity_type Type of entities being requested
2791      * \param entity_topology Topology of entities being requested
2792      * \param tag_handles Array of tag handles
2793      * \param tag_vals Array of tag values (zero if values not requested)
2794      * \param num_tags_vals Number of tags and optionally values
2795      * \param recursive If non-zero, gets entities in owned sets too
2796      * \param *entity_handles Pointer to array of entity handles returned
2797      *        from function
2798      * \param *entity_handles_allocated Pointer to allocated size of
2799      *        entity_handles array
2800      * \param *entity_handles_size Pointer to occupied size of entity_handles array
2801      * \param *err Pointer to error type returned from function
2802      */
iMesh_getEntsByTagsRec(iMesh_Instance instance,const iBase_EntitySetHandle entity_set_handle,const int entity_type,const int entity_topology,const iBase_TagHandle * tag_handles,const char * const * tag_vals,const int num_tags_vals,const int recursive,iBase_EntityHandle ** entity_handles,int * entity_handles_allocated,int * entity_handles_size,int * err)2803   void iMesh_getEntsByTagsRec(iMesh_Instance instance,
2804                               /*in*/ const iBase_EntitySetHandle entity_set_handle,
2805                               /*in*/ const int entity_type,
2806                               /*in*/ const int entity_topology,
2807                               /*in*/ const iBase_TagHandle *tag_handles,
2808                               /*in*/ const char * const *tag_vals,
2809                               /*in*/ const int num_tags_vals,
2810                               /*in*/ const int recursive,
2811                               /*out*/ iBase_EntityHandle** entity_handles,
2812                               /*out*/ int* entity_handles_allocated,
2813                               /*out*/ int* entity_handles_size,
2814                               /*out*/ int *err)
2815   {
2816     CHKENUM(entity_type, iBase_EntityType, iBase_INVALID_ENTITY_TYPE);
2817     CHKENUM(entity_topology, iMesh_EntityTopology,
2818             iBase_INVALID_ENTITY_TOPOLOGY);
2819 
2820     bool use_top = false;
2821       // initialize just to get rid of compiler warning
2822     EntityType type = mb_topology_table[iMesh_ALL_TOPOLOGIES];
2823     Range out_entities;
2824 
2825     if (entity_topology != iMesh_ALL_TOPOLOGIES) {
2826       type = mb_topology_table[entity_topology];
2827       use_top = true;
2828 
2829       if (entity_type != iBase_ALL_TYPES) {
2830         if (entity_topology != iMesh_SEPTAHEDRON &&
2831             entity_type != CN::Dimension(type))
2832           ERROR(iBase_BAD_TYPE_AND_TOPO, "type and topology are inconsistant");
2833 
2834           // Special-case handling for septahedra since we don't support them
2835         else if (entity_topology == iMesh_SEPTAHEDRON &&
2836                  entity_type != iBase_REGION)
2837           ERROR(iBase_BAD_TYPE_AND_TOPO, "type and topology are inconsistant");
2838       }
2839     }
2840 
2841     EntityHandle handle = ENTITY_HANDLE(entity_set_handle);
2842     ErrorCode result = MB_SUCCESS;
2843 
2844     if (use_top) {
2845       if (entity_topology == iMesh_SEPTAHEDRON)
2846         result = MB_SUCCESS;  // MOAB doesn't do septahedrons, so there are never any.
2847       else
2848         result = MOABI->get_entities_by_type_and_tag(handle, type, (Tag*)tag_handles,
2849                                                    (const void* const *)tag_vals,
2850                                                    num_tags_vals, out_entities,
2851                                                    Interface::INTERSECT, recursive);
2852     }
2853     else if (entity_type != iBase_ALL_TYPES) {
2854         // need to loop over all types of this dimension
2855       for (EntityType tp = CN::TypeDimensionMap[entity_type].first;
2856            tp <= CN::TypeDimensionMap[entity_type].second; tp++) {
2857         Range tmp_range;
2858         ErrorCode tmp_result = MOABI->get_entities_by_type_and_tag(handle, type, (Tag*)tag_handles,
2859                                                                    (const void* const *)tag_vals,
2860                                                                    num_tags_vals, tmp_range,
2861                                                                    Interface::INTERSECT, recursive);
2862         if (MB_SUCCESS != tmp_result) result = tmp_result;
2863         else out_entities.merge(tmp_range);
2864       }
2865     }
2866     else
2867       result = MOABI->get_entities_by_type_and_tag(handle, type, (Tag*)tag_handles,
2868                                                  (const void* const *)tag_vals,
2869                                                  num_tags_vals, out_entities,
2870                                                  Interface::INTERSECT, recursive);
2871 
2872     CHKERR(result,"iMesh_GetEntities:ERROR getting entities.");
2873 
2874     ALLOC_CHECK_ARRAY_NOFAIL(entity_handles, out_entities.size());
2875 
2876     Range::iterator iter = out_entities.begin();
2877     Range::iterator end_iter = out_entities.end();
2878     int k = 0;
2879 
2880       // filter out entity sets here
2881     if (iBase_ALL_TYPES == entity_type && iMesh_ALL_TOPOLOGIES == entity_topology) {
2882       for (; iter != end_iter && MOABI->type_from_handle(*iter) != MBENTITYSET; ++iter)
2883         (*entity_handles)[k++] = (iBase_EntityHandle)*iter;
2884     }
2885     else {
2886       for (; iter != end_iter; ++iter)
2887         (*entity_handles)[k++] = (iBase_EntityHandle)*iter;
2888     }
2889 
2890       // now it's safe to set the size; set it to k, not out_entities.size(), to
2891       // account for sets which might have been removed
2892     *entity_handles_size = k;
2893 
2894     RETURN(iBase_SUCCESS);
2895   }
2896 
iMesh_getEntSetsByTagsRec(iMesh_Instance instance,const iBase_EntitySetHandle entity_set_handle,const iBase_TagHandle * tag_handles,const char * const * tag_vals,const int num_tags_vals,const int recursive,iBase_EntitySetHandle ** set_handles,int * set_handles_allocated,int * set_handles_size,int * err)2897   void iMesh_getEntSetsByTagsRec(iMesh_Instance instance,
2898                                  /*in*/ const iBase_EntitySetHandle entity_set_handle,
2899                                  /*in*/ const iBase_TagHandle *tag_handles,
2900                                  /*in*/ const char * const *tag_vals,
2901                                  /*in*/ const int num_tags_vals,
2902                                  /*in*/ const int recursive,
2903                                  /*out*/ iBase_EntitySetHandle** set_handles,
2904                                  /*out*/ int* set_handles_allocated,
2905                                  /*out*/ int* set_handles_size,
2906                                  /*out*/ int *err)
2907   {
2908     Range out_entities;
2909 
2910     EntityHandle handle = ENTITY_HANDLE(entity_set_handle);
2911     ErrorCode result;
2912 
2913     result = MOABI->get_entities_by_type_and_tag(handle, MBENTITYSET, (Tag*)tag_handles,
2914                                                (const void* const *)tag_vals,
2915                                                num_tags_vals, out_entities,
2916                                                Interface::INTERSECT, recursive);
2917     CHKERR(result,"ERROR getting entities.");
2918 
2919     ALLOC_CHECK_ARRAY_NOFAIL(set_handles, out_entities.size());
2920 
2921     std::copy(out_entities.begin(), out_entities.end(), ((EntityHandle*) *set_handles));
2922 
2923     RETURN(iBase_SUCCESS);
2924   }
2925 
iMesh_MBCNType(const int imesh_entity_topology,int * mbcn_type)2926   void iMesh_MBCNType(/*in*/ const int imesh_entity_topology,
2927                       /*out*/ int *mbcn_type)
2928   {
2929     if (iMesh_POINT > imesh_entity_topology ||
2930         iMesh_ALL_TOPOLOGIES <= imesh_entity_topology)
2931       *mbcn_type = -1;
2932     else
2933       *mbcn_type = mb_topology_table[imesh_entity_topology];
2934   }
2935 
iMesh_tagIterate(iMesh_Instance instance,const iBase_TagHandle tag_handle,iBase_EntityArrIterator entArr_iterator,void * data,int * count,int * err)2936   void iMesh_tagIterate(iMesh_Instance instance,
2937                         /*in*/ const iBase_TagHandle tag_handle,
2938                         iBase_EntityArrIterator entArr_iterator,
2939                           /**< [in] Iterator being queried */
2940                         void* data,
2941                           /**< [out] Pointer to pointer that will be set to tag data memory
2942                              \ref trio) */
2943                         int* count,
2944                           /**< [out] Number of contiguous entities in this subrange */
2945                         int* err
2946                           /**< [out] Returned Error status (see iBase_ErrorType) */
2947                         )
2948   {
2949     MBRangeIter *ri = dynamic_cast<MBRangeIter*>(entArr_iterator);
2950     if (!ri) CHKERR(MB_FAILURE,"Wrong type of iterator, need a range-based iterator for iMesh_tagIterate.");
2951 
2952     ErrorCode result = MOABI->tag_iterate(TAG_HANDLE(tag_handle),
2953                                           ri->position(), ri->end(), *count, *static_cast<void**>(data));
2954     CHKERR(result, "Problem getting tag iterator.");
2955 
2956     RETURN(iBase_SUCCESS);
2957   }
2958 
iMesh_connectIterate(iMesh_Instance instance,iBase_EntityArrIterator entArr_iterator,iBase_EntityHandle ** connect,int * verts_per_entity,int * count,int * err)2959   void iMesh_connectIterate(iMesh_Instance instance,
2960                             iBase_EntityArrIterator entArr_iterator,
2961                               /**< [in] Iterator being queried */
2962                             iBase_EntityHandle **connect,
2963                               /**< [out] Pointer to pointer that will be set to connectivity data memory */
2964                             int *verts_per_entity,
2965                               /**< [out] Pointer to integer set to number of vertices per entity */
2966                             int* count,
2967                               /**< [out] Number of contiguous entities in this subrange */
2968                             int* err
2969                               /**< [out] Returned Error status (see iBase_ErrorType) */
2970                             )
2971   {
2972     MBRangeIter *ri = dynamic_cast<MBRangeIter*>(entArr_iterator);
2973     if (!ri) CHKERR(MB_FAILURE,"Wrong type of iterator, need a range-based iterator for iMesh_connectIterate.");
2974 
2975     ErrorCode result = MOABI->connect_iterate(ri->position(), ri->end(),
2976                                               reinterpret_cast<EntityHandle*&>(*connect), *verts_per_entity, *count);
2977     CHKERR(result, "Problem getting connect iterator.");
2978 
2979     RETURN(iBase_SUCCESS);
2980   }
2981 
iMesh_coordsIterate(iMesh_Instance instance,iBase_EntityArrIterator entArr_iterator,double ** xcoords_ptr,double ** ycoords_ptr,double ** zcoords_ptr,int * count,int * err)2982   void iMesh_coordsIterate(iMesh_Instance instance,
2983                            iBase_EntityArrIterator entArr_iterator,
2984                               /**< [in] Iterator being queried */
2985                            double **xcoords_ptr,
2986                               /**< [out] Pointer to pointer that will be set to x coordinate data memory */
2987                            double **ycoords_ptr,
2988                               /**< [out] Pointer to pointer that will be set to y coordinate data memory */
2989                            double **zcoords_ptr,
2990                               /**< [out] Pointer to pointer that will be set to z coordinate data memory */
2991                             int* count,
2992                               /**< [out] Number of contiguous entities in this subrange */
2993                             int* err
2994                               /**< [out] Returned Error status (see iBase_ErrorType) */
2995                             )
2996   {
2997     MBRangeIter *ri = dynamic_cast<MBRangeIter*>(entArr_iterator);
2998     if (!ri) CHKERR(MB_FAILURE,"Wrong type of iterator, need a range-based iterator for iMesh_coordsIterate.");
2999 
3000     ErrorCode result = MOABI->coords_iterate(ri->position(), ri->end(),
3001                                              *xcoords_ptr, *ycoords_ptr, *zcoords_ptr, *count);
3002     CHKERR(result, "Problem getting coords iterator.");
3003 
3004     RETURN(iBase_SUCCESS);
3005   }
3006 
iMesh_stepEntIter(iMesh_Instance instance,iBase_EntityIterator ent_iterator,int step_length,int * at_end,int * err)3007   void iMesh_stepEntIter(
3008       iMesh_Instance instance,
3009         /**< [in] iMesh instance handle */
3010       iBase_EntityIterator ent_iterator,
3011         /**< [in] Iterator being queried */
3012       int step_length,
3013         /**< [in] Number of entities to step the iterator */
3014       int* at_end,
3015         /**< [out] Non-zero if iterator is at the end of the iteration */
3016       int* err
3017         /**< [out] Returned Error status (see iBase_ErrorType) */
3018                       )
3019   {
3020     iMesh_stepEntArrIter(instance, reinterpret_cast<iBase_EntityArrIterator>(ent_iterator),
3021                          step_length, at_end, err);
3022   }
3023 
iMesh_stepEntArrIter(iMesh_Instance instance,iBase_EntityArrIterator entArr_iterator,int step_length,int * at_end,int * err)3024   void iMesh_stepEntArrIter(
3025       iMesh_Instance instance,
3026         /**< [in] iMesh instance handle */
3027       iBase_EntityArrIterator entArr_iterator,
3028         /**< [in] Iterator being queried */
3029       int step_length,
3030         /**< [in] Number of entities to step the iterator */
3031       int* at_end,
3032         /**< [out] Non-zero if iterator is at the end of the iteration */
3033       int* err
3034         /**< [out] Returned Error status (see iBase_ErrorType) */
3035                       )
3036   {
3037     bool tmp;
3038     ErrorCode result = entArr_iterator->step(step_length, tmp);
3039     CHKERR(result, "Problem stepping iterator.");
3040     *at_end = tmp;
3041     RETURN(iBase_SUCCESS);
3042   }
3043 
3044 /**
3045  * Method:  initEntArrIter[]
3046  */
iMesh_initEntArrIterRec(iMesh_Instance instance,const iBase_EntitySetHandle entity_set_handle,const int requested_entity_type,const int requested_entity_topology,const int requested_array_size,const int resilient,const int recursive,iBase_EntityArrIterator * entArr_iterator,int * err)3047   void iMesh_initEntArrIterRec (iMesh_Instance instance,
3048                              /*in*/ const iBase_EntitySetHandle entity_set_handle,
3049                              /*in*/ const int requested_entity_type,
3050                              /*in*/ const int requested_entity_topology,
3051                              /*in*/ const int requested_array_size,
3052                              /*in*/ const int resilient,
3053                              /*in*/ const int recursive,
3054                              /*out*/ iBase_EntityArrIterator* entArr_iterator,
3055                              int *err)
3056   {
3057     CHKENUM(requested_entity_type, iBase_EntityType, iBase_INVALID_ENTITY_TYPE);
3058     CHKENUM(requested_entity_topology, iMesh_EntityTopology,
3059             iBase_INVALID_ENTITY_TOPOLOGY);
3060     if (resilient)
3061         ERROR(iBase_NOT_SUPPORTED, "reslient iterators not supported");
3062 
3063     EntityType req_type = mb_topology_table[requested_entity_topology];
3064 
3065     if (requested_entity_topology != iMesh_ALL_TOPOLOGIES) {
3066       if (requested_entity_type != iBase_ALL_TYPES) {
3067         if (requested_entity_topology != iMesh_SEPTAHEDRON &&
3068             requested_entity_type != CN::Dimension(req_type))
3069           ERROR(iBase_BAD_TYPE_AND_TOPO, "type and topology are inconsistant");
3070 
3071           // Special-case handling for septahedra since we don't support them
3072         else if (requested_entity_topology == iMesh_SEPTAHEDRON &&
3073                  requested_entity_type != iBase_REGION)
3074           ERROR(iBase_BAD_TYPE_AND_TOPO, "type and topology are inconsistant");
3075       }
3076     }
3077 
3078     ErrorCode result;
3079     unsigned flags;
3080     result = MOABI->get_meshset_options( ENTITY_HANDLE(entity_set_handle), flags );
3081     CHKERR(result,"Invalid entity set handle");
3082 
3083     if (flags & MESHSET_ORDERED)
3084       *entArr_iterator = new MBListIter( (iBase_EntityType)requested_entity_type,
3085                                          (iMesh_EntityTopology)requested_entity_topology,
3086                                          ENTITY_HANDLE(entity_set_handle),
3087                                          requested_array_size, recursive );
3088     else
3089       *entArr_iterator = new MBRangeIter( (iBase_EntityType)requested_entity_type,
3090                                           (iMesh_EntityTopology)requested_entity_topology,
3091                                           ENTITY_HANDLE(entity_set_handle),
3092                                           requested_array_size, recursive );
3093     result = (*entArr_iterator)->reset( MOABI );
3094     if (MB_SUCCESS != result)
3095       delete *entArr_iterator;
3096     CHKERR(result, "iMesh_initEntArrIter: ERROR getting entities of proper type or topology." );
3097     RETURN(iBase_SUCCESS);
3098   }
3099 
iMesh_createTagWithOptions(iMesh_Instance instance,const char * tag_name,const char * tmp_tag_options,const int tag_size,const int tag_type,iBase_TagHandle * tag_handle,int * err,const int tag_name_len,const int tag_options_len)3100   void iMesh_createTagWithOptions(iMesh_Instance instance,
3101                                   /*in*/ const char* tag_name,
3102                                   /*in*/ const char* tmp_tag_options,
3103                                   /*in*/ const int tag_size,
3104                                   /*in*/ const int tag_type,
3105                                   /*out*/ iBase_TagHandle* tag_handle,
3106                                   /*out*/ int *err,
3107                                   /*in*/ const int tag_name_len,
3108                                   /*in*/ const int tag_options_len)
3109   {
3110     if (tag_size < 0)
3111       ERROR(iBase_INVALID_ARGUMENT, "iMesh_createTag: invalid tag size");
3112     CHKENUM(tag_type, iBase_TagValueType, iBase_INVALID_ARGUMENT);
3113 
3114     std::string tmp_tagname(tag_name, tag_name_len);
3115     eatwhitespace(tmp_tagname);
3116 
3117     moab::TagType storage = MB_TAG_SPARSE;
3118     ErrorCode result;
3119 
3120       // declared here 'cuz might have to hold destination of a default value ptr
3121     std::string storage_type;
3122     const void *def_val = NULL;
3123     std::vector<int> def_int;
3124     std::vector<double> def_dbl;
3125     std::vector<moab::EntityHandle> def_handles;
3126     int dum_int;
3127     double dum_dbl;
3128 
3129     if (0 != tag_options_len) {
3130       std::string tag_options = filter_options(tmp_tag_options, tmp_tag_options+tag_options_len);
3131       FileOptions opts(tag_options.c_str());
3132       const char *option_vals[] = {"SPARSE", "DENSE", "BIT", "MESH"};
3133       const moab::TagType opt_types[] = {moab::MB_TAG_SPARSE, moab::MB_TAG_DENSE,
3134                                          moab::MB_TAG_BIT, moab::MB_TAG_MESH};
3135       int opt_num = -1;
3136       result = opts.match_option("TAG_STORAGE_TYPE", option_vals, opt_num);
3137       if (MB_FAILURE == result)
3138         ERROR(result, "iMesh_createTagWithOptions: option string not recognized.");
3139       else if (MB_SUCCESS == result) {
3140         assert(opt_num >= 0 && opt_num <= 3);
3141         storage = opt_types[opt_num];
3142       }
3143 
3144         // now look for default value option; reuse storage_type
3145       storage_type.clear();
3146       result = opts.get_option("TAG_DEFAULT_VALUE", storage_type);
3147       if (MB_SUCCESS == result) {
3148           // ok, need to parse the string into a proper default value
3149         switch (tag_type) {
3150           case iBase_INTEGER:
3151               result = opts.get_int_option("TAG_DEFAULT_VALUE", dum_int);
3152               def_int.resize(tag_size);
3153               std::fill(def_int.begin(), def_int.end(), dum_int);
3154               def_val = &def_int[0];
3155               break;
3156           case iBase_DOUBLE:
3157               result = opts.get_real_option("TAG_DEFAULT_VALUE", dum_dbl);
3158               def_dbl.resize(tag_size);
3159               std::fill(def_dbl.begin(), def_dbl.end(), dum_dbl);
3160               def_val = &def_dbl[0];
3161               break;
3162           case iBase_ENTITY_HANDLE:
3163                 // for default handle, will have to use int
3164               result = opts.get_int_option("TAG_DEFAULT_VALUE", dum_int);
3165               if (0 > dum_int)
3166                 ERROR(result, "iMesh_createTagWithOptions: for default handle-type tag, must use non-negative int on input.");
3167               def_handles.resize(tag_size);
3168               std::fill(def_handles.begin(), def_handles.end(), (moab::EntityHandle)dum_int);
3169               def_val = &def_handles[0];
3170               break;
3171           case iBase_BYTES:
3172               if ((int)storage_type.length() < tag_size)
3173                 ERROR(result, "iMesh_createTagWithOptions: default value for byte-type tag must be large enough to store tag value.");
3174               def_val = storage_type.c_str();
3175               break;
3176         }
3177       }
3178     }
3179 
3180     moab::Tag new_tag;
3181     result = MOABI->tag_get_handle(tmp_tagname.c_str(),
3182                                    tag_size,
3183                                    mb_data_type_table[tag_type],
3184                                    new_tag,
3185                                    storage|MB_TAG_EXCL, def_val);
3186 
3187     if (MB_SUCCESS != result) {
3188       std::string msg("iMesh_createTag: ");
3189       if (MB_ALREADY_ALLOCATED == result) {
3190         msg += "Tag already exists with name: \"";
3191         *tag_handle = (iBase_TagHandle) new_tag;
3192       }
3193       else
3194         msg += "Failed to create tag with name: \"";
3195       msg += tag_name;
3196       msg += "\".";
3197       ERROR(result,msg.c_str());
3198     }
3199 
3200     if (tag_type == iBase_ENTITY_HANDLE)
3201       MBIMESHI->note_ent_handle_tag( new_tag );
3202     else if (tag_type == iBase_ENTITY_SET_HANDLE)
3203       MBIMESHI->note_set_handle_tag( new_tag );
3204 
3205     *tag_handle = (iBase_TagHandle) new_tag;
3206 
3207     RETURN(iBase_SUCCESS);
3208 
3209 /* old implementation:
3210    Tag new_tag;
3211    int this_size = tag_size;
3212 
3213    ErrorCode result = MOABI->tag_get_handle(tmp_tagname.c_str(),
3214    this_size,
3215    mb_data_type_table[tag_type],
3216    new_tag,
3217    MB_TAG_SPARSE|MB_TAG_EXCL);
3218 
3219    if (MB_SUCCESS != result) {
3220    std::string msg("iMesh_createTag: ");
3221    if (MB_ALREADY_ALLOCATED == result) {
3222    msg += "Tag already exists with name: \"";
3223    *tag_handle = (iBase_TagHandle) new_tag;
3224    }
3225    else
3226    msg += "Failed to create tag with name: \"";
3227    msg += tag_name;
3228    msg += "\".";
3229    ERROR(result,msg.c_str());
3230    }
3231 
3232    if (tag_type == iBase_ENTITY_HANDLE)
3233    MBIMESHI->note_ent_handle_tag( new_tag );
3234    else if (tag_type == iBase_ENTITY_SET_HANDLE)
3235    MBIMESHI->note_set_handle_tag( new_tag );
3236 
3237    *tag_handle = (iBase_TagHandle) new_tag;
3238    */
3239   }
3240 
3241 #ifdef __cplusplus
3242 } // extern "C"
3243 #endif
3244 
create_int_ents(MBiMesh * mbimesh,Range & from_ents,const EntityHandle * in_set)3245 ErrorCode create_int_ents(MBiMesh* mbimesh,
3246                             Range &from_ents,
3247                             const EntityHandle* in_set)
3248 {
3249   //MBiMesh* mbimesh = dynamic_cast<MBiMesh*>(instance);
3250   assert(mbimesh);
3251   assert(mbimesh->AdjTable[10] || mbimesh->AdjTable[5]);
3252   Range int_ents;
3253   ErrorCode result;
3254   Interface * instance = mbimesh->mbImpl;
3255   if (mbimesh->AdjTable[10]) {
3256     result = instance->get_adjacencies(from_ents, 2, true, int_ents,
3257                                   Interface::UNION);
3258     if (MB_SUCCESS != result) return result;
3259     unsigned int old_size = from_ents.size();
3260     from_ents.merge(int_ents);
3261     if (old_size != from_ents.size() && in_set) {
3262       result = instance->add_entities(*in_set, int_ents);
3263       if (MB_SUCCESS != result) return result;
3264     }
3265   }
3266 
3267   if (mbimesh->AdjTable[5]) {
3268     int_ents.clear();
3269     result = instance->get_adjacencies(from_ents, 1, true, int_ents,
3270                                   Interface::UNION);
3271     if (MB_SUCCESS != result) return result;
3272     unsigned int old_size = from_ents.size();
3273     from_ents.merge(int_ents);
3274     if (old_size != from_ents.size() && in_set) {
3275       result = instance->add_entities(*in_set, int_ents);
3276       if (MB_SUCCESS != result) return result;
3277     }
3278   }
3279 
3280   return MB_SUCCESS;
3281 }
3282 
eatwhitespace(std::string & this_string)3283 void eatwhitespace(std::string &this_string)
3284 {
3285   std::string::size_type p = this_string.find_last_not_of(" ");
3286   if (p != this_string.npos)
3287     this_string.resize(p+1);
3288 }
3289 
iMesh_createStructuredMesh(iMesh_Instance instance,int * local_dims,int * global_dims,double * i_vals,double * j_vals,double * k_vals,int resolve_shared,int ghost_dim,int bridge_dim,int num_layers,int addl_ents,int vert_gids,int elem_gids,iBase_EntitySetHandle * set_handle,int * err)3290 void iMesh_createStructuredMesh(iMesh_Instance instance,
3291                                 /*in*/ int *local_dims,
3292                                 /*in*/ int *global_dims,
3293                                 /*in*/ double *i_vals,
3294                                 /*in*/ double *j_vals,
3295                                 /*in*/ double *k_vals,
3296                                 /*in*/ int resolve_shared,
3297                                 /*in*/ int ghost_dim,
3298                                 /*in*/ int bridge_dim,
3299                                 /*in*/ int num_layers,
3300                                 /*in*/ int addl_ents,
3301                                 /*in*/ int vert_gids,
3302                                 /*in*/ int elem_gids,
3303                                 /*inout*/ iBase_EntitySetHandle* set_handle,
3304                                 /*out*/ int *err)
3305 {
3306   ScdInterface *scdi = NULL;
3307   ErrorCode rval = MOABI->query_interface(scdi);
3308   CHKERR(rval, "Couldn't get structured mesh interface.");
3309 
3310   Range tmp_range;
3311   ScdBox *scd_box;
3312   rval = scdi->construct_box(HomCoord(local_dims[0], local_dims[1], (-1 != local_dims[2] ? local_dims[2] : 0), 1),
3313                              HomCoord(local_dims[3], local_dims[4], (-1 != local_dims[5] ? local_dims[5] : 0), 1),
3314                              NULL, 0, scd_box, NULL, NULL, (vert_gids ? true : false));
3315   CHKERR(rval, "Trouble creating scd vertex sequence.");
3316 
3317     // set the global box parameters
3318   if (global_dims) {
3319     for (int i = 0; i < 6; i++) scd_box->par_data().gDims[i] = global_dims[i];
3320   }
3321 
3322   tmp_range.insert(scd_box->start_vertex(), scd_box->start_vertex()+scd_box->num_vertices()-1);
3323   tmp_range.insert(scd_box->start_element(), scd_box->start_element()+scd_box->num_elements()-1);
3324   tmp_range.insert(scd_box->box_set());
3325 
3326   if (set_handle) {
3327     if (!(*set_handle)) {
3328         // return the new ScdBox's set
3329       *set_handle = reinterpret_cast<iBase_EntitySetHandle>(scd_box->box_set());
3330     }
3331     else{
3332       // add the new ScdBox's set to the given file set
3333       EntityHandle s = scd_box->box_set();
3334       rval = MOABI->add_entities(ENTITY_HANDLE(*set_handle), &s, 1 );
3335       CHKERR(rval, "Couldn't add box set to file set.");
3336     }
3337   }
3338 
3339     // get a ptr to global id memory
3340   void *data;
3341   int count;
3342   Range::const_iterator topv, bote, tope;
3343 
3344   Tag gid_tag = 0;
3345   int *v_gid_data = NULL, *e_gid_data = NULL;
3346   if (vert_gids || elem_gids) {
3347     rval = MOABI->tag_get_handle(GLOBAL_ID_TAG_NAME,
3348                                  1, MB_TYPE_INTEGER,
3349                                  gid_tag,
3350                                  MB_TAG_DENSE|MB_TAG_CREAT);
3351     CHKERR(rval, "Couldn't get GLOBAL_ID tag.");
3352   }
3353 
3354   if (vert_gids) {
3355     topv = tmp_range.upper_bound(tmp_range.begin(), tmp_range.end(),
3356                                  scd_box->start_vertex() + scd_box->num_vertices());
3357 
3358     rval = MOABI->tag_iterate(gid_tag, tmp_range.begin(), topv, count, data);
3359     CHKERR(rval, "Failed to get tag iterator.");
3360     assert(count == scd_box->num_vertices());
3361     v_gid_data = (int*)data;
3362   }
3363 
3364   if (elem_gids) {
3365     bote = tmp_range.lower_bound(tmp_range.begin(), tmp_range.end(),
3366                                  scd_box->start_element());
3367     tope = tmp_range.upper_bound(tmp_range.begin(), tmp_range.end(),
3368                                  *bote + scd_box->num_elements());
3369 
3370     rval = MOABI->tag_iterate(gid_tag, bote, tope, count, data);
3371     CHKERR(rval, "Failed to get tag iterator.");
3372     assert(count == scd_box->num_elements());
3373     e_gid_data = (int*)data;
3374   }
3375 
3376   if (i_vals || j_vals || k_vals || v_gid_data || e_gid_data) {
3377 
3378       // set the vertex coordinates
3379     double *xc, *yc, *zc;
3380     rval = scd_box->get_coordinate_arrays(xc, yc, zc);
3381     CHKERR(rval, "Couldn't get vertex coordinate arrays.");
3382 
3383     int i, j, k, il, jl, kl;
3384     int dil = local_dims[3] - local_dims[0] + 1;
3385     int djl = local_dims[4] - local_dims[1] + 1;
3386     int di = (global_dims ? global_dims[3] - global_dims[0] + 1 : dil);
3387     int dj = (global_dims ? global_dims[4] - global_dims[1] + 1 : djl);
3388     for (kl = local_dims[2]; kl <= local_dims[5]; kl++) {
3389       k = kl - local_dims[2];
3390       for (jl = local_dims[1]; jl <= local_dims[4]; jl++) {
3391         j = jl - local_dims[1];
3392         for (il = local_dims[0]; il <= local_dims[3]; il++) {
3393           i = il - local_dims[0];
3394           unsigned int pos = i + j*dil + k*dil*djl;
3395           xc[pos] = (i_vals ? i_vals[i] : -1.0);
3396           yc[pos] = (j_vals ? j_vals[j] : -1.0);
3397           zc[pos] = (-1 == local_dims[2] ? 0.0 : (k_vals ? k_vals[k] : -1.0));
3398           if (v_gid_data) {
3399             *v_gid_data = (-1 != kl ? kl*di*dj : 0) + jl*di + il + 1;
3400             v_gid_data++;
3401           }
3402           if (e_gid_data && kl < local_dims[5] && jl < local_dims[4] && il < local_dims[3]) {
3403             *e_gid_data = (-1 != kl ? kl*(di-1)*(dj-1) : 0) + jl*(di-1) + il + 1;
3404             e_gid_data++;
3405           }
3406         }
3407       }
3408     }
3409   }
3410 
3411 #ifdef MOAB_HAVE_MPI
3412     // do parallel stuff, if requested
3413   if (resolve_shared) {
3414     ParallelComm *pcomm = ParallelComm::get_pcomm(MOABI, 0);
3415     if (pcomm) {
3416 
3417       rval = pcomm->resolve_shared_ents(0, MOABI->dimension_from_handle(scd_box->start_element()), 0, &gid_tag);
3418       CHKERR(rval, "Trouble resolving shared vertices.");
3419 
3420       if (-1 != ghost_dim) {
3421         rval = pcomm->exchange_ghost_cells(ghost_dim, bridge_dim, num_layers, addl_ents, true);
3422         CHKERR(rval, "Trouble exchanging ghosts.");
3423       }
3424     }
3425   }
3426 #else
3427     // empty statement to remove compiler warning
3428   if (resolve_shared || ghost_dim || bridge_dim || num_layers || addl_ents) {}
3429 #endif
3430 
3431   RETURN(iBase_SUCCESS);
3432 }
3433 
iMesh_freeMemory(iMesh_Instance,void ** ptrToMem)3434 void iMesh_freeMemory(
3435     iMesh_Instance /*instance*/,
3436           /**< [in] iMesh instance handle */
3437          void ** ptrToMem)
3438 {
3439   free(*ptrToMem);
3440   *ptrToMem=0;
3441   return;
3442 }
3443 
3444