moab
iMesh_MOAB.cpp
Go to the documentation of this file.
00001 #include "iMesh_extensions.h"
00002 #include "moab/Core.hpp"
00003 #include "moab/Range.hpp"
00004 #include "moab/CN.hpp"
00005 #include "moab/MeshTopoUtil.hpp"
00006 #include "moab/ScdInterface.hpp"
00007 #include "moab/FileOptions.hpp"
00008 #include "iMesh_MOAB.hpp"
00009 #include "MBIter.hpp"
00010 #include "MBTagConventions.hpp"
00011 #define IS_BUILDING_MB
00012 #include "Internals.hpp"
00013 #undef IS_BUILDING_MB
00014 
00015 #ifdef USE_MPI
00016 #include "moab_mpi.h"
00017 #include "moab/ParallelComm.hpp"
00018 #endif
00019 
00020 #define STRINGIFY_(X) #X
00021 #define STRINGIFY(X) STRINGIFY_(X)
00022 #ifdef HAVE_UNORDERED_MAP
00023 # include STRINGIFY(HAVE_UNORDERED_MAP)
00024 #else
00025 # include <map>
00026 #endif
00027 
00028 #include <iostream>
00029 #include <cassert>
00030 #include <cctype>
00031 #include <cstring>
00032 #include <stdarg.h>
00033 #include <stdio.h>
00034 #define MIN(a,b) (a < b ? a : b)
00035 
00036 static ErrorCode create_int_ents(MBiMesh * mbimesh,
00037                  Range &from_ents,
00038                  const EntityHandle* in_set = 0);
00039 #define HANDLE_ARRAY_PTR(array) reinterpret_cast<EntityHandle*>(array)
00040 #define CONST_HANDLE_ARRAY_PTR(array) reinterpret_cast<const EntityHandle*>(array)
00041 #define TAG_HANDLE(handle) reinterpret_cast<Tag>(handle)
00042 #define CONST_TAG_HANDLE(handle) static_cast<const Tag>(handle)
00043 #define ENTITY_HANDLE(handle) reinterpret_cast<EntityHandle>(handle)
00044 #define CONST_ENTITY_HANDLE(handle) reinterpret_cast<const EntityHandle>(handle)
00045 #define CAST_TO_VOID(ptr) reinterpret_cast<void*>(ptr)
00046 
00047 // map from MB's entity type to TSTT's entity topology
00048 const iMesh_EntityTopology tstt_topology_table[] =
00049 {
00050   iMesh_POINT,          // MBVERTEX
00051   iMesh_LINE_SEGMENT,   // MBEDGE
00052   iMesh_TRIANGLE,       // MBTRI
00053   iMesh_QUADRILATERAL,  // MBQUAD
00054   iMesh_POLYGON,        // MBPOLYGON
00055   iMesh_TETRAHEDRON,    // MBTET
00056   iMesh_PYRAMID,        // MBPYRAMID
00057   iMesh_PRISM,          // MBPRISM
00058   iMesh_ALL_TOPOLOGIES, // MBKNIFE
00059   iMesh_HEXAHEDRON,     // MBHEX
00060   iMesh_POLYHEDRON,     // MBPOLYHEDRON
00061   iMesh_ALL_TOPOLOGIES, // MBENTITYSET
00062   iMesh_ALL_TOPOLOGIES, // MBMAXTYPE
00063 };
00064 
00065 // map from MB's entity type to TSTT's entity type
00066 const iBase_EntityType tstt_type_table[] =
00067 {
00068   iBase_VERTEX,         // MBVERTEX
00069   iBase_EDGE,           // MBEDGE
00070   iBase_FACE,           // MBTRI
00071   iBase_FACE,           // MBQUAD
00072   iBase_FACE,           // MBPOLYGON
00073   iBase_REGION,         // MBTET
00074   iBase_REGION,         // MBPYRAMID
00075   iBase_REGION,         // MBPRISM
00076   iBase_REGION,         // MBKNIFE
00077   iBase_REGION,         // MBHEX
00078   iBase_REGION,         // MBPOLYHEDRON
00079   iBase_ALL_TYPES, // MBENTITYSET
00080   iBase_ALL_TYPES  // MBMAXTYPE
00081 };
00082 
00083 // map to MB's entity type from TSTT's entity topology
00084 const EntityType mb_topology_table[] =
00085 {
00086   MBVERTEX,
00087   MBEDGE,
00088   MBPOLYGON,
00089   MBTRI,
00090   MBQUAD,
00091   MBPOLYHEDRON,
00092   MBTET,
00093   MBHEX,
00094   MBPRISM,
00095   MBPYRAMID,
00096   MBMAXTYPE,
00097   MBMAXTYPE
00098 };
00099 
00100 // map from TSTT's tag types to MOAB's
00101 const DataType mb_data_type_table[] =
00102 {
00103   MB_TYPE_OPAQUE,
00104   MB_TYPE_INTEGER,
00105   MB_TYPE_DOUBLE ,
00106   MB_TYPE_HANDLE ,
00107   MB_TYPE_HANDLE
00108 };
00109 
00110 // map from MOAB's tag types to tstt's
00111 const iBase_TagValueType tstt_data_type_table[] =
00112 {
00113   iBase_BYTES,
00114   iBase_INTEGER,
00115   iBase_DOUBLE,
00116   iBase_BYTES,
00117   iBase_ENTITY_HANDLE
00118 };
00119 
00120 const iBase_ErrorType iBase_ERROR_MAP[MB_FAILURE+1] =
00121 {
00122   iBase_SUCCESS, // MB_SUCCESS = 0,
00123   iBase_INVALID_ENTITY_HANDLE, // MB_INDEX_OUT_OF_RANGE,
00124   iBase_INVALID_ENTITY_TYPE, // MB_TYPE_OUT_OF_RANGE,
00125   iBase_MEMORY_ALLOCATION_FAILED, // MB_MEMORY_ALLOCATION_FAILED,
00126   iBase_INVALID_ENTITY_HANDLE, // MB_ENTITY_NOT_FOUND,
00127   iBase_NOT_SUPPORTED, // MB_MULTIPLE_ENTITIES_FOUND,
00128   iBase_TAG_NOT_FOUND, // MB_TAG_NOT_FOUND,
00129   iBase_FILE_NOT_FOUND, // MB_FILE_DOES_NOT_EXIST,
00130   iBase_FILE_WRITE_ERROR, // MB_FILE_WRITE_ERROR,
00131   iBase_NOT_SUPPORTED, // MB_NOT_IMPLEMENTED,
00132   iBase_TAG_ALREADY_EXISTS, // MB_ALREADY_ALLOCATED,
00133   iBase_FAILURE, // MB_VARIABLE_DATA_LENGTH,
00134   iBase_FAILURE, // MB_INVALID_SIZE,
00135   iBase_NOT_SUPPORTED, // MB_UNSUPPORTED_OPERATION,
00136   iBase_INVALID_ARGUMENT, // MB_UNHANDLED_OPTION
00137   iBase_INVALID_ENTITY_TYPE, // MB_STRUCTURED_MESH
00138   iBase_FAILURE // MB_FAILURE};
00139 };
00140 
00141 // Return data about a list of handles for use in check_handle_tag_type.
00142 // Set output arguments to true if the list contains the corresponding
00143 // type of handle.  Leave them unmodified if it does not.
00144 static inline void ht_content_type( const std::vector<EntityHandle>& h,
00145                                     bool &saw_ent, bool &saw_set, bool &saw_root )
00146 {
00147   std::vector<EntityHandle>::const_iterator i;
00148   for (i = h.begin(); i != h.end(); ++i) {
00149     if (*i == 0)
00150       saw_root = true;
00151     else if (TYPE_FROM_HANDLE(*i) == MBENTITYSET)
00152       saw_set = true;
00153     else
00154       saw_ent = true;
00155   }
00156 }
00157 
00158 // Scan all tag data to try to guess whether the MOAB tag with
00159 // data of type MB_TYPE_HANDLE is iBase_ENTITY_HANDLE or
00160 // iBase_ENTITY_SET_HANDLE.
00161 static ErrorCode check_handle_tag_type( Tag t, MBiMesh* mbi )
00162 {
00163   Interface* mb = mbi->mbImpl;
00164   ErrorCode rval;
00165   int size;
00166   DataType type;
00167   rval = mb->tag_get_data_type( t, type );
00168   if (MB_SUCCESS != rval) return rval;
00169   if (MB_TYPE_HANDLE != type) return MB_TYPE_OUT_OF_RANGE;
00170   rval = mb->tag_get_length( t, size );
00171   if (MB_SUCCESS != rval) return rval;
00172   std::vector<EntityHandle> data(size);
00173 
00174     // check for global/mesh value
00175   bool saw_set = false, saw_ent = false, saw_root = false;
00176   EntityHandle root = 0;
00177   rval = mb->tag_get_data( t, &root, 1, &data[0] );
00178   if (MB_SUCCESS == rval)
00179     ht_content_type( data, saw_ent, saw_set, saw_root );
00180 
00181     // check default value
00182   rval = mb->tag_get_default_value( t, &data[0] );
00183   if (MB_SUCCESS == rval)
00184     ht_content_type( data, saw_ent, saw_set, saw_root );
00185 
00186     // check all tagged entities
00187   Range r;
00188   rval = mb->get_entities_by_type_and_tag( 0, MBMAXTYPE, &t, 0, 1, r );
00189   if (MB_SUCCESS != rval) return rval;
00190   for (Range::iterator i = r.begin(); i != r.end(); ++i) {
00191     rval = mb->tag_get_data( t, &*i, 1, &data[0] );
00192     if (MB_SUCCESS != rval) return rval;
00193     ht_content_type( data, saw_ent, saw_set, saw_root );
00194   }
00195 
00196     // If tag values were only entities, note type accordingly.
00197     // Similarly if all are entity sets, note accordingly.
00198     // Because root set (zero handle) is sometimes used to mean NULL
00199     // rather than the actual root set, treat that specially.  If
00200     // all values are either root set or an entity handle, then
00201     // treat as if all values were non-set handles.
00202   if (saw_set && !saw_ent)
00203     mbi->note_set_handle_tag( t );
00204   else if (!saw_set && saw_ent)
00205     mbi->note_ent_handle_tag( t );
00206   else if (saw_root && !saw_ent)
00207     mbi->note_set_handle_tag( t );
00208 
00209   return MB_SUCCESS;
00210 }
00211 
00212 static void remove_var_len_tags( Interface* mb, std::vector<Tag>& tags )
00213 {
00214   int size;
00215   size_t r, w = 0;
00216   for (r = 0; r < tags.size(); ++r)
00217     if (MB_SUCCESS == mb->tag_get_length( tags[r], size ))
00218       tags[w++] = tags[r];
00219   tags.resize(w);
00220 }
00221 
00222 // modify the adjacency table to match the ITAPS spec's expectations
00223 static void munge_adj_table(int *adjTable, int geom_dim)
00224 {
00225     // If geom_dim is 2, 3D adjacencies are unavailable. This may change!
00226   if (geom_dim == 2) {
00227     for (size_t i = 0; i < 16; ++i) {
00228       if (i % 4 == 3 || i >= 12)
00229         adjTable[i] = iBase_UNAVAILABLE;
00230     }
00231   }
00232 
00233     // Ensure that diagonal entries are only available/unavailable.
00234   for (size_t i = 0; i < 16; i+=5) {
00235     if (adjTable[i] != iBase_UNAVAILABLE)
00236       adjTable[i] = iBase_AVAILABLE;
00237   }
00238 }
00239 
00240 #ifdef __cplusplus
00241 extern "C" {
00242 #endif
00243 
00244   static void eatwhitespace(std::string &this_string);
00245 
00246   void iMesh_getErrorType(iMesh_Instance instance, int *error_type)
00247   {
00248     if (instance == NULL)
00249       *error_type = iBase_FAILURE;
00250     else
00251       *error_type = MBIMESHI->lastErrorType;
00252   }
00253 
00254   void iMesh_getDescription(iMesh_Instance instance, char *descr, int descr_len)
00255   {
00256     if (instance == NULL) {
00257       strcpy(descr, "iMesh_getDescription: Invalid instance");
00258     }
00259     else {
00260       unsigned int len = MIN(strlen(MBIMESHI->lastErrorDescription),
00261                              static_cast<unsigned int>(descr_len));
00262       strncpy(descr, MBIMESHI->lastErrorDescription, len);
00263       descr[len] = '\0';
00264     }
00265   }
00266 
00267   void iMesh_newMesh(const char *options,
00268                      iMesh_Instance *instance, int *err, int options_len)
00269   {
00270     std::string tmp_options = filter_options(options, options+options_len);
00271     FileOptions opts(tmp_options.c_str());
00272 
00273     MBiMesh **mbi = reinterpret_cast<MBiMesh**>(instance);
00274     *mbi = NULL;
00275 
00276     ErrorCode result = opts.get_null_option("PARALLEL");
00277     if (MB_SUCCESS == result) {
00278 #ifdef USE_MPI
00279       int flag = 1;
00280       int retval = MPI_Initialized(&flag);
00281       if (MPI_SUCCESS != retval || !flag) {
00282         int argc = 0;
00283         char **argv = NULL;
00284 
00285           // mpi not initialized yet - initialize here
00286         retval = MPI_Init(&argc, &argv);
00287       }
00288       *mbi = new MBiMesh(NULL);
00289 #else
00290         //mError->set_last_error( "PARALLEL option not valid, this instance"
00291         //                        " compiled for serial execution.\n" );
00292       *err = (*mbi)->set_last_error(MB_NOT_IMPLEMENTED,
00293                                     "Not configured with parallel support");
00294       return;
00295 #endif
00296     }
00297     else {
00298       *mbi = new MBiMesh(NULL);
00299     }
00300     if (NULL == *mbi) {
00301       *err = iBase_FAILURE;
00302       return;
00303     }
00304 
00305     *err = iBase_SUCCESS;
00306   }
00307 
00308   void iMesh_dtor(iMesh_Instance instance, int *err)
00309   {
00310     delete MBIMESHI;
00311     *err = iBase_SUCCESS;
00312   }
00313 
00314   void iMesh_load(iMesh_Instance instance,
00315                   const iBase_EntitySetHandle handle,
00316                   const char *name, const char *options,
00317                   int *err, int name_len, int options_len)
00318   {
00319       // get filename, option & null-terminate
00320     std::string filename(name, name_len);
00321     eatwhitespace(filename);
00322 
00323     std::string opts = filter_options(options, options+options_len);
00324 
00325     Range orig_ents;
00326     ErrorCode result = MOABI->get_entities_by_handle( 0, orig_ents );
00327     CHKERR(result,"Internal error");
00328 
00329     const EntityHandle* file_set = 0;
00330     if (handle != 0 /*root_set*/) {
00331       const iBase_EntitySetHandle* ptr = &handle;
00332       file_set = reinterpret_cast<const EntityHandle*>(ptr);
00333     }
00334 
00335     result = MOABI->load_file(filename.c_str(), file_set, opts.c_str());
00336 
00337     CHKERR(result, "iMesh_load:ERROR loading a mesh.");
00338 
00339       // create interior edges/faces if requested
00340     if (MBIMESHI->AdjTable[5] || MBIMESHI->AdjTable[10]) {
00341       Range set_ents;
00342       result = MOABI->get_entities_by_handle(0, set_ents);
00343       CHKERR(result,"");
00344       Range sets;
00345       result = MOABI->get_entities_by_type(0, MBENTITYSET, sets);
00346       CHKERR(result,"");
00347       set_ents = subtract( set_ents, sets );
00348       set_ents = subtract( set_ents, orig_ents );
00349       result = create_int_ents(MBIMESHI, set_ents, file_set);
00350       CHKERR(result,"");
00351     }
00352     RETURN(iBase_SUCCESS);
00353   }
00354 
00355   void iMesh_save(iMesh_Instance instance,
00356                   const iBase_EntitySetHandle handle,
00357                   const char *name, const char *options,
00358                   int *err, const int name_len, int options_len)
00359   {
00360       // get filename & attempt to NULL-terminate
00361     std::string filename( name, name_len );
00362     eatwhitespace(filename);
00363     std::string opts = filter_options(options, options+options_len);
00364 
00365     EntityHandle set = ENTITY_HANDLE(handle);
00366     ErrorCode result = MOABI->write_file(filename.c_str(), NULL, opts.c_str(),
00367                                        &set, 1);
00368 
00369     CHKERR(result, "iMesh_save:ERROR saving a mesh.");
00370     RETURN(iBase_SUCCESS);
00371   }
00372 
00373   void iMesh_getRootSet(iMesh_Instance instance,
00374                         iBase_EntitySetHandle *root_set, int *err)
00375   {
00376     *root_set = 0;
00377       //return CAST_TO_VOID(MOABI->get_root_set());
00378     RETURN(iBase_SUCCESS);
00379   }
00380 
00381   void iMesh_getGeometricDimension(iMesh_Instance instance,
00382                                    int *geom_dim, int *err)
00383   {
00384     MOABI->get_dimension(*geom_dim);
00385     RETURN(iBase_SUCCESS);
00386   }
00387 
00388   void iMesh_setGeometricDimension(iMesh_Instance instance,
00389                                    int geom_dim, int *err)
00390   {
00391     ErrorCode rval = MOABI->set_dimension(geom_dim);
00392     CHKERR(rval,"iMesh_setGeometricDimension: failed");
00393 
00394     RETURN(iBase_SUCCESS);
00395   }
00396 
00397   void iMesh_getDfltStorage(iMesh_Instance instance,
00398                             int *order, int *err)
00399   {
00400     *order = iBase_BLOCKED;
00401     RETURN(iBase_SUCCESS);
00402   }
00403 
00404   void iMesh_getAdjTable (iMesh_Instance instance,
00405                           int** adjacency_table,
00406                           /*inout*/ int* adjacency_table_allocated,
00407                           /*out*/ int* adjacency_table_size, int *err)
00408   {
00409     int geom_dim;
00410     iMesh_getGeometricDimension(instance, &geom_dim, err);
00411 
00412     ALLOC_CHECK_ARRAY_NOFAIL(adjacency_table, 16);
00413     memcpy(*adjacency_table, MBIMESHI->AdjTable, 16*sizeof(int));
00414     munge_adj_table(*adjacency_table, geom_dim);
00415     RETURN(iBase_SUCCESS);
00416   }
00417 
00418   void iMesh_setAdjTable (iMesh_Instance instance,
00419                           int* adj_table,
00420                           /*inout*/ int adj_table_size,
00421                           int *err)
00422   {
00423     if (16 != adj_table_size) {
00424       RETURN(iBase_INVALID_ARGUMENT);
00425     }
00426 
00427     int geom_dim;
00428     iMesh_getGeometricDimension(instance, &geom_dim, err);
00429 
00430     memcpy(MBIMESHI->AdjTable, adj_table, 16*sizeof(int));
00431     munge_adj_table(adj_table, geom_dim);
00432     RETURN(iBase_SUCCESS);
00433   }
00434 
00435   void iMesh_getNumOfType(iMesh_Instance instance,
00436                           /*in*/ const iBase_EntitySetHandle entity_set_handle,
00437                           /*in*/ const int entity_type,
00438                           int *num_type, int *err)
00439   {
00440     iMesh_getNumOfTypeRec(instance, entity_set_handle, entity_type, false,
00441                           num_type, err);
00442   }
00443 
00444   void iMesh_getNumOfTopo(iMesh_Instance instance,
00445                           /*in*/ const iBase_EntitySetHandle entity_set_handle,
00446                           /*in*/ const int entity_topology,
00447                           int *num_topo, int *err)
00448   {
00449     iMesh_getNumOfTopoRec(instance, entity_set_handle, entity_topology,
00450                           false, num_topo, err);
00451   }
00452 
00453   void iMesh_optimize( iMesh_Instance instance,
00454                        int* handles_invalidated,
00455                        int* err )
00456   {
00457     // TODO: implement this for real
00458     *handles_invalidated = 0;
00459     RETURN(iBase_SUCCESS);
00460   }
00461 
00462   void iMesh_getEntities(iMesh_Instance instance,
00463                          /*in*/ const iBase_EntitySetHandle entity_set_handle,
00464                          /*in*/ const int entity_type,
00465                          /*in*/ const int entity_topology,
00466                          /*inout*/ iBase_EntityHandle** entity_handles,
00467                          /*inout*/ int* entity_handles_allocated,
00468                          /*out*/ int* entity_handles_size,
00469                          int *err)
00470   {
00471     iMesh_getEntitiesRec(instance, entity_set_handle, entity_type,
00472                          entity_topology, false,
00473                          entity_handles, entity_handles_allocated, entity_handles_size,
00474                          err);
00475   }
00476 
00477   void iMesh_getVtxArrCoords (iMesh_Instance instance,
00478                               /*in*/ const iBase_EntityHandle* vertex_handles,
00479                               /*in*/ const int vertex_handles_size,
00480                               /*inout*/ int storage_order,
00481                               /*inout*/ double** coords,
00482                               /*inout*/ int* coords_allocated,
00483                               /*out*/ int* coords_size, int *err)
00484   {
00485     int geom_dim;
00486     MOABI->get_dimension(geom_dim);
00487 
00488       // make sure we can hold them all
00489     ALLOC_CHECK_ARRAY(coords, geom_dim*vertex_handles_size);
00490 
00491       // now get all the coordinates
00492       // coords will come back interleaved by default
00493     ErrorCode result;
00494     if (storage_order == iBase_INTERLEAVED) {
00495       if (3 == geom_dim) {
00496         result = MOABI->get_coords(CONST_HANDLE_ARRAY_PTR(vertex_handles),
00497                                  vertex_handles_size, *coords);
00498       }
00499       else {
00500         std::vector<double> dum_coords(3*vertex_handles_size);
00501         result = MOABI->get_coords(CONST_HANDLE_ARRAY_PTR(vertex_handles),
00502                                  vertex_handles_size,
00503                                  &dum_coords[0]);
00504 
00505         for (int i = 0; i < vertex_handles_size; i++) {
00506           for (int j = 0; j < geom_dim; j++)
00507             (*coords)[geom_dim*i + j] = dum_coords[3*i + j];
00508         }
00509       }
00510     }
00511     else {
00512       std::vector<double> dum_coords(3*vertex_handles_size);
00513       result = MOABI->get_coords(CONST_HANDLE_ARRAY_PTR(vertex_handles),
00514                                vertex_handles_size,
00515                                &dum_coords[0]);
00516       CHKERR(result,"iMesh_getVtxArrCoords: problem getting vertex coords");
00517 
00518       for (int i = 0; i < vertex_handles_size; i++) {
00519         for (int j = 0; j < geom_dim; j++)
00520           (*coords)[i + vertex_handles_size*j] = dum_coords[3*i + j];
00521       }
00522     }
00523 
00524     KEEP_ARRAY(coords);
00525     RETURN(iBase_SUCCESS);
00526   }
00527 
00531   void iMesh_initEntArrIter (iMesh_Instance instance,
00532                              /*in*/ const iBase_EntitySetHandle entity_set_handle,
00533                              /*in*/ const int requested_entity_type,
00534                              /*in*/ const int requested_entity_topology,
00535                              /*in*/ const int requested_array_size,
00536                              /*in*/ const int resilient,
00537                              /*out*/ iBase_EntityArrIterator* entArr_iterator,
00538                              int *err)
00539   {
00540     iMesh_initEntArrIterRec(instance, entity_set_handle, requested_entity_type, 
00541                             requested_entity_topology, requested_array_size, resilient, false,
00542                             entArr_iterator, err);
00543   }
00544 
00548   void iMesh_getNextEntArrIter (iMesh_Instance instance,
00549                                 /*in*/ iBase_EntityArrIterator entArr_iterator,
00550                                 /*inout*/ iBase_EntityHandle** entity_handles,
00551                                 /*inout*/ int* entity_handles_allocated,
00552                                 /*out*/ int* entity_handles_size,
00553                                 int *has_data, int *err)
00554   {
00555       // check the size of the destination array
00556     ALLOC_CHECK_ARRAY_NOFAIL(entity_handles, entArr_iterator->array_size());
00557     entArr_iterator->get_entities( dynamic_cast<Core*>(MOABI), 
00558              (EntityHandle*)*entity_handles, *entity_handles_size );
00559     *has_data = (*entity_handles_size != 0);
00560     RETURN(iBase_SUCCESS);
00561   }
00562 
00566   void iMesh_resetEntArrIter (iMesh_Instance instance,
00567                               /*in*/ iBase_EntityArrIterator entArr_iterator, int *err)
00568   {
00569     ErrorCode result = entArr_iterator->reset( MOABI );
00570     CHKERR(result,"Re-query of iterator data for iMesh_resetEntArrIter failed");
00571     RETURN(iBase_SUCCESS);
00572   }
00573 
00574   void iMesh_endEntArrIter (iMesh_Instance instance,
00575                             /*in*/ iBase_EntityArrIterator entArr_iterator, int *err)
00576   {
00577     delete entArr_iterator;
00578     RETURN(iBase_SUCCESS);
00579   }
00580 
00581   void iMesh_getEntArrTopo(iMesh_Instance instance,
00582                            /*in*/ const iBase_EntityHandle* entity_handles,
00583                            /*in*/ const int entity_handles_size,
00584                            /*inout*/ int** topology,
00585                            /*inout*/ int* topology_allocated,
00586                            /*out*/ int* topology_size, int *err)
00587   {
00588       // go through each entity and look up its type
00589     ALLOC_CHECK_ARRAY_NOFAIL(topology, entity_handles_size);
00590 
00591     for (int i = 0; i < entity_handles_size; i++)
00592       (*topology)[i] =
00593         tstt_topology_table[MOABI->type_from_handle(ENTITY_HANDLE(entity_handles[i]))];
00594 
00595     *topology_size = entity_handles_size;
00596 
00597     RETURN(iBase_SUCCESS);
00598   }
00599 
00600   void iMesh_getEntArrType(iMesh_Instance instance,
00601                            /*in*/ const iBase_EntityHandle* entity_handles,
00602                            /*in*/ const int entity_handles_size,
00603                            /*inout*/ int** etype,
00604                            /*inout*/ int* etype_allocated,
00605                            /*out*/ int* etype_size, int *err)
00606   {
00607       // go through each entity and look up its type
00608     ALLOC_CHECK_ARRAY_NOFAIL(etype, entity_handles_size);
00609 
00610     for (int i = 0; i < entity_handles_size; i++)
00611       (*etype)[i] =
00612         tstt_type_table[MOABI->type_from_handle(ENTITY_HANDLE(entity_handles[i]))];
00613 
00614     *etype_size = entity_handles_size;
00615 
00616     RETURN(iBase_SUCCESS);
00617   }
00618 
00619   void iMesh_getEntArrAdj(iMesh_Instance instance,
00620                           /*in*/ const iBase_EntityHandle* entity_handles,
00621                           /*in*/ const int entity_handles_size,
00622                           /*in*/ const int entity_type_requested,
00623                           /*inout*/ iBase_EntityHandle** adjacentEntityHandles,
00624                           /*inout*/ int* adjacentEntityHandles_allocated,
00625                           /*out*/ int* adjacentEntityHandles_size,
00626                           /*inout*/ int** offset,
00627                           /*inout*/ int* offset_allocated,
00628                           /*out*/ int* offset_size, int *err)
00629   {
00630     ErrorCode result = MB_SUCCESS;
00631 
00632     ALLOC_CHECK_ARRAY(offset, entity_handles_size+1);
00633 
00634     const EntityHandle* entity_iter = (const EntityHandle*)entity_handles;
00635     const EntityHandle* const entity_end = entity_iter + entity_handles_size;
00636     int* off_iter = *offset;
00637     int prev_off = 0;
00638 
00639     std::vector<EntityHandle> conn_storage;
00640     std::vector<EntityHandle> adj_ents;
00641     const EntityHandle *connect;
00642     int num_connect;
00643 
00644     EntityHandle* array; // ptr to working array of result handles
00645     int array_alloc;       // allocated size of 'array'
00646     const bool allocated_array = !*adjacentEntityHandles_allocated || !*adjacentEntityHandles;
00647     if (allocated_array) {
00648       array = 0;
00649       array_alloc = 0;
00650     }
00651     else {
00652       array = reinterpret_cast<EntityHandle*>(*adjacentEntityHandles);
00653       array_alloc = *adjacentEntityHandles_allocated;
00654     }
00655 
00656     for ( ; entity_iter != entity_end; ++entity_iter)
00657     {
00658       *off_iter = prev_off;
00659       off_iter++;
00660 
00661       if (iBase_VERTEX == entity_type_requested &&
00662           TYPE_FROM_HANDLE(*entity_iter) != MBPOLYHEDRON) {
00663         if (CN::Dimension(TYPE_FROM_HANDLE(*entity_iter)) == 0)
00664           continue;
00665         result = MOABI->get_connectivity(*entity_iter, connect, num_connect, false, &conn_storage);
00666         if (MB_SUCCESS != result) {
00667           if (allocated_array)
00668             free(array);
00669           ERROR(result, "iMesh_getEntArrAdj: trouble getting adjacency list.");
00670         }
00671       }
00672       else if (iBase_ALL_TYPES == entity_type_requested) {
00673         adj_ents.clear();
00674         for (int dim = 0; dim < 4; ++dim) {
00675           if (CN::Dimension(TYPE_FROM_HANDLE(*entity_iter)) == dim)
00676             continue;
00677           result = MOABI->get_adjacencies( entity_iter, 1, dim, false, adj_ents, Interface::UNION );
00678           if (MB_SUCCESS != result) {
00679             if (allocated_array)
00680               free(array);
00681             ERROR(result, "iMesh_getEntArrAdj: trouble getting adjacency list.");
00682           }
00683         }
00684         connect = &adj_ents[0];
00685         num_connect = adj_ents.size();
00686       }
00687       else {
00688         if (CN::Dimension(TYPE_FROM_HANDLE(*entity_iter)) == entity_type_requested)
00689           continue;
00690         adj_ents.clear();
00691         result = MOABI->get_adjacencies( entity_iter, 1,
00692                                        entity_type_requested, false, adj_ents );
00693         if (MB_SUCCESS != result) {
00694           if (allocated_array)
00695             free(array);
00696           ERROR(result, "iMesh_getEntArrAdj: trouble getting adjacency list.");
00697         }
00698         connect = &adj_ents[0];
00699         num_connect = adj_ents.size();
00700       }
00701 
00702       if (prev_off + num_connect <= array_alloc) {
00703         std::copy(connect, connect+num_connect, array+prev_off);
00704       }
00705       else if (allocated_array) {
00706           // if array is not allocated yet, guess at initial size
00707           // as the number of adjacencies for the first entity times
00708           // the number of input entities.  This will result in a single
00709           // exact allocation if one input entity or typical queries
00710           // such as connectivity of a non-mixed mesh or regions adjacent
00711           // to faces.
00712         if (!array_alloc)
00713           array_alloc = entity_handles_size * num_connect;
00714         else
00715           array_alloc = std::max(array_alloc*2, prev_off+num_connect);
00716         array = (EntityHandle*)realloc( array, array_alloc*sizeof(EntityHandle) );
00717         if (!array) {
00718           RETURN(iBase_MEMORY_ALLOCATION_FAILED);
00719         }
00720         std::copy(connect, connect+num_connect, array+prev_off);
00721       }
00722       // else do nothing.  Will catch error later when comparing
00723       //  occupied to allocated sizes.  Continue here because
00724       //  must pass back required size.
00725 
00726       prev_off += num_connect;
00727     }
00728     *off_iter = prev_off;
00729     *adjacentEntityHandles_size = prev_off;
00730 
00731     if (*adjacentEntityHandles_size > array_alloc) {
00732       RETURN(iBase_BAD_ARRAY_SIZE);
00733     }
00734     else if (allocated_array) {
00735       *adjacentEntityHandles = reinterpret_cast<iBase_EntityHandle*>(array);
00736       *adjacentEntityHandles_allocated = array_alloc;
00737     }
00738 
00739     KEEP_ARRAY(offset);
00740     RETURN(iBase_SUCCESS);
00741   }
00742 
00743   void iMesh_getEntArr2ndAdj( iMesh_Instance instance,
00744                               iBase_EntityHandle const* entity_handles,
00745                               int entity_handles_size,
00746                               int bridge_entity_type,
00747                               int requested_entity_type,
00748                               iBase_EntityHandle** adj_entity_handles,
00749                               int* adj_entity_handles_allocated,
00750                               int* adj_entity_handles_size,
00751                               int** offset,
00752                               int* offset_allocated,
00753                               int* offset_size,
00754                               int* err )
00755   {
00756     CHKENUM(bridge_entity_type, iBase_EntityType, iBase_INVALID_ENTITY_TYPE);
00757     CHKENUM(requested_entity_type, iBase_EntityType, iBase_INVALID_ENTITY_TYPE);
00758 
00759     ErrorCode result = MB_SUCCESS;
00760 
00761     ALLOC_CHECK_ARRAY(offset, entity_handles_size+1);
00762 
00763     const EntityHandle* entity_iter = (const EntityHandle*)entity_handles;
00764     const EntityHandle* const entity_end = entity_iter + entity_handles_size;
00765     int* off_iter = *offset;
00766     int prev_off = 0;
00767 
00768     std::vector<EntityHandle> all_adj_ents;
00769     MeshTopoUtil mtu(MOABI);
00770 
00771     int min_bridge = iBase_VERTEX, max_bridge = iBase_REGION;
00772     int min_req    = iBase_VERTEX, max_req    = iBase_REGION;
00773     if (iBase_ALL_TYPES != bridge_entity_type)
00774       min_bridge = max_bridge = bridge_entity_type;
00775     if (iBase_ALL_TYPES != requested_entity_type)
00776       min_req = max_req = requested_entity_type;
00777 
00778     for ( ; entity_iter != entity_end; ++entity_iter)
00779     {
00780       *off_iter = prev_off;
00781       off_iter++;
00782       Range adj_ents;
00783 
00784       int source = CN::Dimension(TYPE_FROM_HANDLE(*entity_iter));
00785       for (int bridge = min_bridge; bridge <= max_bridge; ++bridge) {
00786         if (source == bridge)
00787           continue;
00788         for (int requested = min_req; requested <= max_req; ++requested) {
00789           if (bridge == requested)
00790             continue;
00791           result = mtu.get_bridge_adjacencies( *entity_iter,
00792                                                bridge,
00793                                                requested, adj_ents );
00794           CHKERR(result, "iMesh_getEntArr2ndAdj: trouble getting adjacency list.");
00795         }
00796       }
00797 
00798       std::copy(adj_ents.begin(), adj_ents.end(), std::back_inserter(all_adj_ents));
00799       prev_off += adj_ents.size();
00800     }
00801     *off_iter = prev_off;
00802 
00803     ALLOC_CHECK_ARRAY_NOFAIL(adj_entity_handles, all_adj_ents.size() );
00804     memcpy(*adj_entity_handles, &all_adj_ents[0],
00805            sizeof(EntityHandle)*all_adj_ents.size() );
00806 
00807     KEEP_ARRAY(offset);
00808 
00809       // Return an error if the bridge and requested entity types are different
00810     if (iBase_ALL_TYPES != bridge_entity_type &&
00811         bridge_entity_type == requested_entity_type)
00812       ERROR(iBase_INVALID_ARGUMENT, "iMesh_getEntArr2ndAdj: bridge and "
00813             "requested entity types must be different.");
00814     else
00815       RETURN(iBase_SUCCESS);
00816   }
00817 
00818   void iMesh_getAdjEntIndices(iMesh_Instance instance,
00819                       /*in*/    iBase_EntitySetHandle entity_set_handle,
00820                       /*in*/    int entity_type_requestor,
00821                       /*in*/    int entity_topology_requestor,
00822                       /*in*/    int entity_type_requested,
00823                       /*inout*/ iBase_EntityHandle** entity_handles,
00824                       /*inout*/ int* entity_handles_allocated,
00825                       /*out*/   int* entity_handles_size,
00826                       /*inout*/ iBase_EntityHandle** adj_entity_handles,
00827                       /*inout*/ int* adj_entity_handles_allocated,
00828                       /*out*/   int* adj_entity_handles_size,
00829                       /*inout*/ int** adj_entity_indices,
00830                       /*inout*/ int* adj_entity_indices_allocated,
00831                       /*out*/   int* adj_entity_indices_size,
00832                       /*inout*/ int** offset,
00833                       /*inout*/ int* offset_allocated,
00834                       /*out*/   int* offset_size,
00835                       /*out*/   int *err)
00836   {
00837     const int allocated_entity_handles = (*entity_handles_allocated == 0);
00838     const int allocated_indices = (*adj_entity_indices_allocated == 0);
00839     const int allocated_offset = (*offset_allocated == 0);
00840 
00841     // get source entities
00842     iMesh_getEntities( instance,
00843                        entity_set_handle,
00844                        entity_type_requestor,
00845                        entity_topology_requestor,
00846                        entity_handles,
00847                        entity_handles_allocated,
00848                        entity_handles_size,
00849                        err );
00850     if (iBase_SUCCESS != *err)
00851       return;
00852 
00853     // get adjacencies
00854     iBase_EntityHandle* all_adj_handles = 0;
00855     int size = 0, alloc = 0;
00856     iMesh_getEntArrAdj( instance,
00857                         *entity_handles, *entity_handles_size,
00858                         entity_type_requested,
00859                         &all_adj_handles, &alloc, &size,
00860                         offset, offset_allocated, offset_size,
00861                         err );
00862     if (*err != iBase_SUCCESS) {
00863       if (allocated_entity_handles) {
00864         free( *entity_handles );
00865         *entity_handles = 0;
00866         *entity_handles_allocated = 0;
00867       }
00868       return;
00869     }
00870 
00871     // allocate or check size of adj_entity_indices
00872     *adj_entity_indices_size = size;
00873     if (allocated_indices) {
00874       *adj_entity_indices = (int*)malloc(sizeof(iBase_EntityHandle)*size);
00875       if (!*adj_entity_indices)
00876         *err = iBase_MEMORY_ALLOCATION_FAILED;
00877       else
00878         *adj_entity_indices_allocated = size;
00879     }
00880     else if (*adj_entity_indices_allocated < size) {
00881       *err = iBase_BAD_ARRAY_DIMENSION;
00882     }
00883     if (iBase_SUCCESS != *err) {
00884       free( all_adj_handles );
00885       if (allocated_entity_handles) {
00886         free( *entity_handles );
00887         *entity_handles = 0;
00888         *entity_handles_allocated = 0;
00889       }
00890       if (allocated_offset) {
00891         free( *offset );
00892         *offset = 0;
00893         *offset_allocated = 0;
00894       }
00895       return;
00896     }
00897 
00898     // Now create an array of unique sorted handles from all_adj_handles.
00899     // We need to create a copy because we still need all_adj_handles.  We
00900     // will eventually need to copy the resulting unique list into
00901     // adj_entity_handles, so if adj_entity_handles is already allocated and
00902     // of sufficient size, use it rather than allocating another temporary.
00903     iBase_EntityHandle* unique_adj = 0;
00904     if (*adj_entity_handles_allocated >= size) {
00905       unique_adj = *adj_entity_handles;
00906     }
00907     else {
00908       unique_adj = (iBase_EntityHandle*)malloc(sizeof(iBase_EntityHandle) * size);
00909     }
00910     std::copy( all_adj_handles, all_adj_handles+size, unique_adj );
00911     std::sort( unique_adj, unique_adj + size );
00912     *adj_entity_handles_size = std::unique( unique_adj, unique_adj + size ) - unique_adj;
00913 
00914     // If we created a temporary array for unique_adj rather than using
00915     // already allocated space in adj_entity_handles, allocate adj_entity_handles
00916     // and copy the unique handle list into it
00917     if (*adj_entity_handles != unique_adj) {
00918       if (!*adj_entity_handles_allocated) {
00919         *adj_entity_handles = (iBase_EntityHandle*)malloc(
00920                               sizeof(iBase_EntityHandle) * *adj_entity_handles_size);
00921         if (!*adj_entity_handles)
00922           *err = iBase_MEMORY_ALLOCATION_FAILED;
00923         else
00924           *adj_entity_handles_allocated = *adj_entity_handles_size;
00925       }
00926       else if (*adj_entity_handles_allocated < *adj_entity_handles_size)
00927         *err = iBase_BAD_ARRAY_DIMENSION;
00928       if (iBase_SUCCESS != *err) {
00929         free( unique_adj );
00930         free( all_adj_handles );
00931         if (allocated_entity_handles) {
00932           free( *entity_handles );
00933           *entity_handles = 0;
00934           *entity_handles_allocated = 0;
00935         }
00936         if (allocated_offset) {
00937           free( *offset );
00938           *offset = 0;
00939           *offset_allocated = 0;
00940         }
00941         if (allocated_indices) {
00942           free( *adj_entity_indices );
00943           *adj_entity_indices = 0;
00944           *adj_entity_indices_allocated = 0;
00945         }
00946         return;
00947       }
00948 
00949       std::copy( unique_adj, unique_adj + *adj_entity_handles_size, *adj_entity_handles );
00950       free( unique_adj );
00951       unique_adj = *adj_entity_handles;
00952     }
00953 
00954     // convert from adjacency list to indices into unique_adj
00955     for (int i = 0; i < *adj_entity_indices_size; ++i)
00956       (*adj_entity_indices)[i] = std::lower_bound( unique_adj,
00957         unique_adj + *adj_entity_handles_size, all_adj_handles[i] ) - unique_adj;
00958     free( all_adj_handles );
00959   }
00960 
00961 
00962   void iMesh_createEntSet(iMesh_Instance instance,
00963                           /*in*/ const int isList,
00964                           /*out*/ iBase_EntitySetHandle* entity_set_created, int *err)
00965   {
00966       // create the entity set
00967     EntityHandle meshset;
00968     ErrorCode result;
00969 
00970     if (isList)
00971       result = MOABI->create_meshset(MESHSET_ORDERED, meshset);
00972     else
00973       result = MOABI->create_meshset(MESHSET_SET, meshset);
00974 
00975     CHKERR(result,"iMesh_createEntSet: ERROR creating a entityset instance");
00976 
00977       // return EntitySet_Handle
00978     *entity_set_created = (iBase_EntitySetHandle)meshset;
00979     RETURN(iBase_SUCCESS);
00980   }
00981 
00982   void iMesh_destroyEntSet (iMesh_Instance instance,
00983                             /*in*/ iBase_EntitySetHandle entity_set, int *err)
00984   {
00985     EntityHandle set = ENTITY_HANDLE(entity_set);
00986     ErrorCode result = MOABI->delete_entities(&set, 1);
00987     CHKERR(result, "iMesh_destroyEntSet: couldn't delete the set.");
00988 
00989     RETURN(iBase_SUCCESS);
00990   }
00991 
00992   void iMesh_isList (iMesh_Instance instance,
00993                      /*in*/ const iBase_EntitySetHandle entity_set,
00994                      int *is_list, int *err)
00995   {
00996     unsigned int options;
00997     ErrorCode result = MOABI->get_meshset_options(ENTITY_HANDLE(entity_set), options);
00998     CHKERR(result,"iMesh_isList: couldn't query set.");
00999     if (options & MESHSET_ORDERED)
01000       *is_list = true;
01001     else *is_list = false;
01002 
01003     RETURN(iBase_SUCCESS);
01004   }
01005 
01006   void iMesh_getNumEntSets(iMesh_Instance instance,
01007                            /*in*/ const iBase_EntitySetHandle entity_set_handle,
01008                            /*in*/ const int num_hops,
01009                            int *num_sets, int *err)
01010   {
01011     ErrorCode rval = MOABI->num_contained_meshsets( ENTITY_HANDLE(entity_set_handle),
01012                                                     num_sets,
01013                                                     std::max(0,num_hops+1) );
01014     CHKERR(rval, "iMesh_entitysetGetNumberEntitySets:ERROR getting number of entitysets.");
01015 
01016     RETURN(iBase_SUCCESS);
01017   }
01018 
01019   void iMesh_getEntSets(iMesh_Instance instance,
01020                         /*in*/ const iBase_EntitySetHandle entity_set_handle,
01021                         /*in*/ const int num_hops,
01022                         /*inout*/ iBase_EntitySetHandle** contained_entset_handles,
01023                         /*inout*/ int* contained_entset_handles_allocated,
01024                         /*inout*/ int* contained_entset_handles_size, int *err)
01025   {
01026     std::vector<EntityHandle> sets;
01027     ErrorCode rval = MOABI->get_contained_meshsets( ENTITY_HANDLE(entity_set_handle),
01028                                                     sets,
01029                                                     std::max( num_hops+1, 0 ) );
01030     CHKERR(rval, "iMesh_entitysetGetEntitySets: problem getting entities by type.");
01031     ALLOC_CHECK_ARRAY_NOFAIL(contained_entset_handles, sets.size() );
01032 
01033     std::copy( sets.begin(), sets.end(), (EntityHandle*)*contained_entset_handles );
01034     *contained_entset_handles_size = sets.size();
01035     RETURN(iBase_SUCCESS);
01036   }
01037 
01038   void iMesh_addEntArrToSet(iMesh_Instance instance,
01039                             /*in*/ const iBase_EntityHandle* entity_handles,
01040                             /*in*/ int entity_handles_size,
01041                             /*in*/ iBase_EntitySetHandle entity_set,
01042                             int *err)
01043   {
01044     const EntityHandle *ents = CONST_HANDLE_ARRAY_PTR(entity_handles);
01045     ErrorCode result = MOABI->add_entities(ENTITY_HANDLE(entity_set),
01046                                            ents, entity_handles_size);
01047 
01048     CHKERR(result,"iMesh_addEntArrToSet:ERROR adding entities in EntitySet.");
01049     RETURN(iBase_SUCCESS);
01050   }
01051 
01052   void iMesh_addEntToSet(iMesh_Instance instance,
01053                          /*in*/ iBase_EntityHandle entity_handle,
01054                          /*in*/ iBase_EntitySetHandle entity_set, int *err)
01055   {
01056     iMesh_addEntArrToSet(instance, &entity_handle, 1, entity_set, err);
01057   }
01058 
01059   void iMesh_rmvEntArrFromSet(iMesh_Instance instance,
01060                               /*in*/ const iBase_EntityHandle* entity_handles,
01061                               /*in*/ int entity_handles_size,
01062                               /*in*/ iBase_EntitySetHandle entity_set, int *err)
01063   {
01064     const EntityHandle *ents = CONST_HANDLE_ARRAY_PTR(entity_handles);
01065 
01066     ErrorCode result = MOABI->remove_entities
01067       (ENTITY_HANDLE(entity_set), ents, entity_handles_size);
01068 
01069     CHKERR(result,"iMesh_rmvEntArrFromSet:ERROR removing entities in EntitySet.");
01070     RETURN(iBase_SUCCESS);
01071   }
01072 
01073   void iMesh_rmvEntFromSet(iMesh_Instance instance,
01074                            /*in*/ iBase_EntityHandle entity_handle,
01075                            /*in*/ iBase_EntitySetHandle entity_set,
01076                            int *err)
01077   {
01078     iMesh_rmvEntArrFromSet(instance, &entity_handle, 1, entity_set, err);
01079   }
01080 
01081   void iMesh_addEntSet(iMesh_Instance instance,
01082                        /*in*/ iBase_EntitySetHandle entity_set_to_add,
01083                        /*in*/ iBase_EntitySetHandle entity_set_handle,
01084                        int *err)
01085   {
01086     if (!entity_set_to_add || !entity_set_handle)
01087       ERROR(iBase_INVALID_ARGUMENT, "iMesh_addEntSet: ERROR invalid argument");
01088 
01089     EntityHandle to_add = ENTITY_HANDLE(entity_set_to_add);
01090     ErrorCode result = MOABI->add_entities(ENTITY_HANDLE(entity_set_handle), &to_add, 1);
01091 
01092     CHKERR(result,"iMesh_addEntSet:ERROR adding entitysets.");
01093     RETURN(iBase_SUCCESS);
01094   }
01095 
01096   void iMesh_rmvEntSet(iMesh_Instance instance,
01097                        /*in*/ iBase_EntitySetHandle entity_set_to_remove,
01098                        /*in*/ iBase_EntitySetHandle entity_set_handle,
01099                        int *err)
01100   {
01101     if (!entity_set_to_remove || !entity_set_handle)
01102       ERROR(iBase_INVALID_ARGUMENT, "iMesh_rmvEntSet: ERROR invalid argument");
01103 
01104     EntityHandle to_remove = ENTITY_HANDLE(entity_set_to_remove);
01105     ErrorCode result = MOABI->remove_entities
01106       (ENTITY_HANDLE(entity_set_handle), &to_remove, 1);
01107 
01108     CHKERR(result,"iMesh_rmvEntSet:ERROR removing entitysets in EntitySet.");
01109     RETURN(iBase_SUCCESS);
01110   }
01111 
01112   void iMesh_isEntContained (iMesh_Instance instance,
01113                              /*in*/ iBase_EntitySetHandle containing_entity_set,
01114                              /*in*/ iBase_EntityHandle contained_entity,
01115                              int *is_contained, int *err)
01116   {
01117     int junk1 = 1, junk2 = 1;
01118     iMesh_isEntArrContained( instance, containing_entity_set,
01119                              &contained_entity, 1, &is_contained,
01120                              &junk1, &junk2, err );
01121   }
01122 
01123   void iMesh_isEntArrContained( iMesh_Instance instance,
01124                             /*in*/ iBase_EntitySetHandle containing_set,
01125                             /*in*/ const iBase_EntityHandle* entity_handles,
01126                             /*in*/ int num_entity_handles,
01127                          /*inout*/ int** is_contained,
01128                          /*inout*/ int* is_contained_allocated,
01129                            /*out*/ int* is_contained_size,
01130                            /*out*/ int* err )
01131 
01132   {
01133     EntityHandle set = ENTITY_HANDLE(containing_set);
01134     ALLOC_CHECK_ARRAY_NOFAIL(is_contained, num_entity_handles);
01135     *is_contained_size = num_entity_handles;
01136 
01137     if (containing_set) {
01138       for (int i = 0; i < num_entity_handles; ++i) {
01139         EntityHandle h = ENTITY_HANDLE(entity_handles[i]);
01140         (*is_contained)[i] = MOABI->contains_entities( set, &h, 1 );
01141       }
01142     }
01143     else {
01144       std::fill( *is_contained, (*is_contained)+num_entity_handles, 1 );
01145     }
01146     RETURN(iBase_SUCCESS);
01147   }
01148 
01149   void iMesh_isEntSetContained (iMesh_Instance instance,
01150                                 /*in*/ const iBase_EntitySetHandle containing_entity_set,
01151                                 /*in*/ const iBase_EntitySetHandle contained_entity_set,
01152                                 int *is_contained, int *err)
01153   {
01154     iMesh_isEntContained(instance, containing_entity_set,
01155                          reinterpret_cast<iBase_EntityHandle>(contained_entity_set),
01156                          is_contained, err);
01157   }
01158 
01159   void iMesh_addPrntChld(iMesh_Instance instance,
01160                          /*inout*/ iBase_EntitySetHandle parent_entity_set,
01161                          /*inout*/ iBase_EntitySetHandle child_entity_set,
01162                          int *err)
01163   {
01164     ErrorCode result = MOABI->add_parent_child
01165       (ENTITY_HANDLE(parent_entity_set),
01166        ENTITY_HANDLE(child_entity_set));
01167 
01168     if (result == MB_ENTITY_NOT_FOUND)
01169       ERROR(iBase_INVALID_ENTITYSET_HANDLE,
01170             "iMesh_addPrntChld: ERROR invalid entity set.");
01171     CHKERR(result, "iMesh_addPrntChld: ERROR addParentChild failed.");
01172     RETURN(iBase_SUCCESS);
01173   }
01174 
01175   void iMesh_rmvPrntChld(iMesh_Instance instance,
01176                          /*inout*/ iBase_EntitySetHandle parent_entity_set,
01177                          /*inout*/ iBase_EntitySetHandle child_entity_set,
01178                          int *err)
01179   {
01180     ErrorCode result = MOABI->remove_parent_child
01181       (ENTITY_HANDLE(parent_entity_set),
01182        ENTITY_HANDLE(child_entity_set));
01183 
01184     if (result == MB_ENTITY_NOT_FOUND)
01185       ERROR(iBase_INVALID_ENTITYSET_HANDLE,
01186             "iMesh_rmvPrntChld: ERROR invalid entity set.");
01187     CHKERR(result,"iMesh_rmvPrntChld: ERROR RemoveParentChild failed.");
01188     RETURN(iBase_SUCCESS);
01189   }
01190 
01191   void iMesh_isChildOf(iMesh_Instance instance,
01192                        /*in*/ const iBase_EntitySetHandle parent_entity_set,
01193                        /*in*/ const iBase_EntitySetHandle child_entity_set,
01194                        int *is_child, int *err)
01195   {
01196     if (!child_entity_set)
01197       ERROR(iBase_INVALID_ENTITYSET_HANDLE,
01198             "iMesh_isChildOf: ERROR invalid entity set.");
01199 
01200     std::vector<EntityHandle> children;
01201 
01202     ErrorCode result = MOABI->get_child_meshsets
01203       (ENTITY_HANDLE(parent_entity_set), children);
01204 
01205     if (result == MB_ENTITY_NOT_FOUND)
01206       ERROR(iBase_INVALID_ENTITYSET_HANDLE,
01207             "iMesh_rmvPrntChld: ERROR invalid entity set.");
01208     CHKERR(result,"iMesh_isChildOf: ERROR IsParentChildRelated failed.");
01209 
01210     if (std::find(children.begin(), children.end(), ENTITY_HANDLE(child_entity_set))
01211         != children.end())
01212       *is_child = true;
01213 
01214     else
01215       *is_child = false;
01216 
01217     RETURN(iBase_SUCCESS);
01218   }
01219 
01220   void iMesh_getNumChld(iMesh_Instance instance,
01221                         /*in*/ const iBase_EntitySetHandle entity_set,
01222                         /*in*/ const int num_hops,
01223                         int *num_child, int *err)
01224   {
01225     *num_child = 0;
01226     ErrorCode result = MOABI->num_child_meshsets
01227       (ENTITY_HANDLE(entity_set), num_child, num_hops+1);
01228 
01229     if (result == MB_ENTITY_NOT_FOUND)
01230       ERROR(iBase_INVALID_ENTITYSET_HANDLE,
01231             "iMesh_getNumChld: ERROR invalid entity set.");
01232     CHKERR(result,"iMesh_getNumChld: ERROR GetNumChildren failed.");
01233 
01234     RETURN(iBase_SUCCESS);
01235   }
01236 
01237   void iMesh_getNumPrnt(iMesh_Instance instance,
01238                         /*in*/ const iBase_EntitySetHandle entity_set,
01239                         /*in*/ const int num_hops,
01240                         int *num_parent, int *err)
01241   {
01242     *num_parent = 0;
01243     ErrorCode result = MOABI->num_parent_meshsets
01244       (ENTITY_HANDLE(entity_set), num_parent, num_hops+1);
01245 
01246     if (result == MB_ENTITY_NOT_FOUND)
01247       ERROR(iBase_INVALID_ENTITYSET_HANDLE,
01248             "iMesh_getNumPrnt: ERROR invalid entity set.");
01249     CHKERR(result,"iMesh_getNumPrnt: ERROR GetNumParents failed.");
01250     RETURN(iBase_SUCCESS);
01251   }
01252 
01253   void iMesh_getChldn(iMesh_Instance instance,
01254                       /*in*/ const iBase_EntitySetHandle from_entity_set,
01255                       /*in*/ const int num_hops,
01256                       /*out*/ iBase_EntitySetHandle** entity_set_handles,
01257                       /*out*/ int* entity_set_handles_allocated,
01258                       /*out*/ int* entity_set_handles_size, int *err)
01259   {
01260     std::vector<EntityHandle> children;
01261 
01262     ErrorCode result = MOABI->get_child_meshsets
01263       (ENTITY_HANDLE(from_entity_set), children, num_hops+1);
01264 
01265     if (result == MB_ENTITY_NOT_FOUND)
01266       ERROR(iBase_INVALID_ENTITYSET_HANDLE,
01267             "iMesh_getChldn: ERROR invalid entity set.");
01268     CHKERR(result,"ERROR getChildren failed.");
01269     ALLOC_CHECK_ARRAY_NOFAIL(entity_set_handles, children.size());
01270 
01271     EntityHandle *ents = HANDLE_ARRAY_PTR(*entity_set_handles);
01272       // use a memcpy for efficiency
01273     memcpy(ents, &children[0], children.size()*sizeof(EntityHandle));
01274 
01275     RETURN(iBase_SUCCESS);
01276   }
01277 
01278   void iMesh_getPrnts(iMesh_Instance instance,
01279                       /*in*/ const iBase_EntitySetHandle from_entity_set,
01280                       /*in*/ const int num_hops,
01281                       /*out*/ iBase_EntitySetHandle** entity_set_handles,
01282                       /*out*/ int* entity_set_handles_allocated,
01283                       /*out*/ int* entity_set_handles_size, int *err)
01284   {
01285     std::vector<EntityHandle> parents;
01286 
01287     ErrorCode result = MOABI->get_parent_meshsets
01288       (ENTITY_HANDLE(from_entity_set), parents, num_hops+1);
01289 
01290     if (result == MB_ENTITY_NOT_FOUND)
01291       ERROR(iBase_INVALID_ENTITYSET_HANDLE,
01292             "iMesh_getPrnts: ERROR invalid entity set.");
01293     CHKERR(result,"ERROR getParents failed.");
01294 
01295     ALLOC_CHECK_ARRAY_NOFAIL(entity_set_handles, parents.size());
01296 
01297     EntityHandle *ents = HANDLE_ARRAY_PTR(*entity_set_handles);
01298       // use a memcpy for efficiency
01299     memcpy(ents, &parents[0], parents.size()*sizeof(EntityHandle));
01300 
01301     RETURN(iBase_SUCCESS);
01302   }
01303 
01304   void iMesh_setVtxArrCoords (iMesh_Instance instance,
01305                               /*in*/ const iBase_EntityHandle* vertex_handles,
01306                               /*in*/ const int vertex_handles_size,
01307                               /*in*/ const int storage_order,
01308                               /*in*/ const double* new_coords,
01309                               /*in*/ const int new_coords_size, int *err)
01310   {
01311     CHKENUM(storage_order, iBase_StorageOrder, iBase_INVALID_ARGUMENT);
01312 
01313     int geom_dim;
01314     MOABI->get_dimension(geom_dim);
01315     if (new_coords_size != geom_dim*vertex_handles_size) {
01316       ERROR(iBase_INVALID_ARGUMENT, "iMesh_setVtxArrCoords: Didn't get the right # coordinates.");
01317     }
01318 
01319     ErrorCode result = MB_SUCCESS, tmp_result;
01320     if (storage_order == iBase_INTERLEAVED) {
01321       if (3 == geom_dim) {
01322         result = MOABI->set_coords(CONST_HANDLE_ARRAY_PTR(vertex_handles),
01323                                  vertex_handles_size, new_coords);
01324       }
01325       else {
01326         const EntityHandle *verts = CONST_HANDLE_ARRAY_PTR(vertex_handles);
01327         double dummy[3] = {0, 0, 0};
01328         for (int i = 0; i < vertex_handles_size; i++) {
01329           for (int j = 0; j < geom_dim; j++)
01330             dummy[j] = new_coords[geom_dim*i + j];
01331           tmp_result = MOABI->set_coords(&verts[i], 1, dummy);
01332           if (MB_SUCCESS != tmp_result) result = tmp_result;
01333         }
01334       }
01335     }
01336     else {
01337       const EntityHandle *verts = CONST_HANDLE_ARRAY_PTR(vertex_handles);
01338       double dummy[3] = {0, 0, 0};
01339       for (int i = 0; i < vertex_handles_size; i++) {
01340         for (int j = 0; j < geom_dim; j++)
01341           dummy[j] = new_coords[i + vertex_handles_size*j];
01342         tmp_result = MOABI->set_coords(&verts[i], 1, dummy);
01343         if (MB_SUCCESS != tmp_result) result = tmp_result;
01344       }
01345     }
01346 
01347     CHKERR(result, "iMesh_setVtxArrCoords: problem setting coordinates.");
01348 
01349     RETURN(iBase_SUCCESS);
01350   }
01351 
01352   void iMesh_createVtxArr(iMesh_Instance instance,
01353                           /*in*/ const int num_verts,
01354                           /*in*/ const int storage_order,
01355                           /*in*/ const double* new_coords,
01356                           /*in*/ const int new_coords_size,
01357                           /*inout*/ iBase_EntityHandle** new_vertex_handles,
01358                           /*inout*/ int* new_vertex_handles_allocated,
01359                           /*inout*/ int* new_vertex_handles_size, int *err)
01360   {
01361     int geom_dim;
01362     MOABI->get_dimension(geom_dim);
01363     if (new_coords_size != geom_dim*num_verts) {
01364       ERROR(iBase_INVALID_ARGUMENT, "iMesh_createVtxArr: Didn't get the right # coordinates.");
01365     }
01366 
01367       // if there aren't any elements in the array, allocate it
01368     ALLOC_CHECK_ARRAY(new_vertex_handles, num_verts);
01369 
01370       // make the entities
01371     EntityHandle *new_verts = HANDLE_ARRAY_PTR(*new_vertex_handles);
01372 
01373     if (storage_order == iBase_INTERLEAVED) {
01374       if (3 == geom_dim) {
01375         for (int i = 0; i < num_verts; i++) {
01376           ErrorCode result = MOABI->create_vertex(&new_coords[3*i], new_verts[i]);
01377           CHKERR(result, "iMesh_createVtxArr: couldn't create vertex.");
01378         }
01379       }
01380       else {
01381         double tmp[3] = {0, 0, 0};
01382         for (int i = 0; i < num_verts; i++) {
01383           for (int j = 0; j < geom_dim; j++)
01384             tmp[j] = new_coords[geom_dim*i + j];
01385           ErrorCode result = MOABI->create_vertex(tmp, new_verts[i]);
01386           CHKERR(result, "iMesh_createVtxArr: couldn't create vertex.");
01387         }
01388       }
01389     }
01390     else {
01391       double tmp[3] = {0, 0, 0};
01392       for (int i = 0; i < num_verts; i++) {
01393         for (int j = 0; j < geom_dim; j++)
01394           tmp[j] = new_coords[j*num_verts + i];
01395 
01396         ErrorCode result = MOABI->create_vertex(tmp, new_verts[i]);
01397         CHKERR(result, "iMesh_createVtxArr: couldn't create vertex.");
01398       }
01399     }
01400 
01401     KEEP_ARRAY(new_vertex_handles);
01402     RETURN(iBase_SUCCESS);
01403   }
01404 
01405   void iMesh_createEntArr(iMesh_Instance instance,
01406                           /*in*/ const int new_entity_topology,
01407                           /*in*/ const iBase_EntityHandle* lower_order_entity_handles,
01408                           /*in*/ const int lower_order_entity_handles_size,
01409                           /*out*/ iBase_EntityHandle** new_entity_handles,
01410                           /*out*/ int* new_entity_handles_allocated,
01411                           /*out*/ int* new_entity_handles_size,
01412                           /*inout*/  int** status,
01413                           /*inout*/ int* status_allocated,
01414                           /*out*/ int* status_size, int *err)
01415   {
01416       // for now, throw an error if lower order entity handles aren't vertices
01417     if (iMesh_POINT > new_entity_topology || iMesh_SEPTAHEDRON < new_entity_topology) {
01418       ERROR(iBase_INVALID_ARGUMENT, "iMesh_createEntArr: invalid topology.");
01419     }
01420     EntityType this_type = mb_topology_table[new_entity_topology];
01421     int num_ents = 0, num_verts;
01422     const EntityHandle *lower_ents;
01423     if (MBVERTEX != this_type) {
01424       num_verts = CN::VerticesPerEntity(this_type);
01425       num_ents = lower_order_entity_handles_size / num_verts;
01426       lower_ents = CONST_HANDLE_ARRAY_PTR(lower_order_entity_handles);
01427         // check that we have the right number of lower order entity handles
01428       if (lower_order_entity_handles_size % CN::VerticesPerEntity(this_type) != 0) {
01429         ERROR(iBase_INVALID_ENTITY_COUNT, "iMesh_createEntArr: wrong # vertices for this entity type.");
01430        }
01431     }
01432     else {
01433       ERROR(iBase_INVALID_ARGUMENT, "iMesh_createEntArr: can't create vertices with this function, use createVtxArr instead.");
01434     }
01435 
01436     if (num_ents == 0) {
01437       ERROR(iBase_INVALID_ENTITY_COUNT, "iMesh_createEntArr: called to create 0 entities.");
01438     }
01439 
01440       // if there aren't any elements in the array, allocate it
01441 
01442       // This function is poorly defined.  We have to return allocated
01443       // arrays even if we fail.
01444     ALLOC_CHECK_ARRAY_NOFAIL(new_entity_handles, num_ents);
01445     ALLOC_CHECK_ARRAY_NOFAIL(status, num_ents);
01446 
01447       // make the entities
01448     EntityHandle *new_ents = HANDLE_ARRAY_PTR(*new_entity_handles);
01449 
01450     ErrorCode tmp_result, result = MB_SUCCESS;
01451 
01452     for (int i = 0; i < num_ents; i++) {
01453       tmp_result = MOABI->create_element(this_type, lower_ents, num_verts,
01454                                        new_ents[i]);
01455       if (MB_SUCCESS != tmp_result) {
01456         (*status)[i] = iBase_CREATION_FAILED;
01457         result = tmp_result;
01458       }
01459       else
01460         (*status)[i] = iBase_NEW;
01461 
01462       lower_ents += num_verts;
01463     }
01464 
01465     CHKERR(result, "iMesh_createEntArr: couldn't create one of the entities.");
01466 
01467     *new_entity_handles_size = num_ents;
01468     *status_size = num_ents;
01469 
01470     if (MBIMESHI->AdjTable[5] || MBIMESHI->AdjTable[10]) {
01471       Range set_ents;
01472       std::copy(HANDLE_ARRAY_PTR(*new_entity_handles),
01473                 HANDLE_ARRAY_PTR(*new_entity_handles)+*new_entity_handles_size,
01474                 range_inserter(set_ents));
01475       result = create_int_ents(MBIMESHI, set_ents);
01476       CHKERR(result,"");
01477     }
01478 
01479     RETURN(iBase_SUCCESS);
01480   }
01481 
01482   void iMesh_deleteEntArr(iMesh_Instance instance,
01483                           /*in*/ const iBase_EntityHandle* entity_handles,
01484                           /*in*/ const int entity_handles_size, int *err)
01485   {
01486     if (0 == entity_handles_size) {
01487       RETURN(iBase_SUCCESS);
01488     }
01489 
01490     ErrorCode result = MOABI->delete_entities(CONST_HANDLE_ARRAY_PTR(entity_handles),
01491                                               entity_handles_size);
01492     CHKERR(result, "iMesh_deleteEntArr: trouble deleting entities.");
01493 
01494     RETURN(iBase_SUCCESS);
01495   }
01496 
01497   void iMesh_createTag(iMesh_Instance instance,
01498                        /*in*/ const char* tag_name,
01499                        /*in*/ const int tag_size,
01500                        /*in*/ const int tag_type,
01501                        /*out*/ iBase_TagHandle* tag_handle,
01502                        int *err,
01503                        const int tag_name_size)
01504   {
01505     iMesh_createTagWithOptions(instance, tag_name, NULL, tag_size, tag_type, tag_handle, err, tag_name_size, 0);
01506   }
01507 
01508   void iMesh_destroyTag(iMesh_Instance instance,
01509                         /*in*/ iBase_TagHandle tag_handle,
01510                         /*in*/ const int forced, int *err)
01511   {
01512       // might need to check if it's used first
01513     if (false == forced) {
01514       Range ents;
01515       ErrorCode result;
01516       Tag this_tag = TAG_HANDLE(tag_handle);
01517       for (EntityType this_type = MBVERTEX; this_type != MBMAXTYPE; this_type++) {
01518         result = MOABI->get_entities_by_type_and_tag(0, this_type, &this_tag, NULL, 1,
01519                                                    ents, Interface::UNION);
01520         CHKERR(result,"iMesh_destroyTag: problem finding tag.");
01521         if (!ents.empty()) {
01522           ERROR(iBase_TAG_IN_USE, "iMesh_destroyTag: forced=false and entities"
01523                 " are still assigned this tag.");
01524         }
01525       }
01526         // check if tag value is set on mesh
01527       const void* data_ptr;
01528       EntityHandle root = 0;
01529       result = MOABI->tag_get_by_ptr( this_tag, &root, 1, &data_ptr );
01530       if (MB_SUCCESS == result)
01531         ERROR(iBase_TAG_IN_USE, "iMesh_destroyTag: forced=false and mesh"
01532               " is still assigned this tag.");
01533     }
01534 
01535       // ok, good to go - either forced or no entities with this tag
01536     ErrorCode result = MOABI->tag_delete(TAG_HANDLE(tag_handle));
01537     if (MB_SUCCESS != result && MB_TAG_NOT_FOUND != result)
01538       ERROR(result, "iMesh_destroyTag: problem deleting tag.");
01539 
01540     if (MB_SUCCESS == result)
01541       MBIMESHI->note_tag_destroyed( TAG_HANDLE(tag_handle) );
01542 
01543     RETURN(iBase_ERROR_MAP[result]);
01544   }
01545 
01546   void iMesh_getTagName(iMesh_Instance instance,
01547                         /*in*/ const iBase_TagHandle tag_handle,
01548                         char *out_data, int *err,
01549                         int out_data_len)
01550   {
01551     static ::std::string name;
01552     ErrorCode result = MOABI->tag_get_name(TAG_HANDLE(tag_handle), name);
01553     CHKERR(result, "iMesh_getTagName: problem getting name.");
01554 
01555     strncpy(out_data, name.c_str(), out_data_len);
01556     RETURN(iBase_SUCCESS);
01557   }
01558 
01559   void iMesh_getTagType (iMesh_Instance instance,
01560                          /*in*/ const iBase_TagHandle tag_handle,
01561                          int *value_type, int *err)
01562   {
01563     DataType this_type;
01564     ErrorCode result = MOABI->tag_get_data_type(TAG_HANDLE(tag_handle),
01565                                                 this_type);
01566     CHKERR(result, "iMesh_getTagType: problem getting type.");
01567 
01568     if (this_type != MB_TYPE_HANDLE)
01569       *value_type = tstt_data_type_table[this_type];
01570     else if (MBIMESHI->is_set_handle_tag( TAG_HANDLE(tag_handle) ))
01571       *value_type = iBase_ENTITY_SET_HANDLE;
01572     else if (MBIMESHI->is_ent_handle_tag( TAG_HANDLE(tag_handle) ))
01573       *value_type = iBase_ENTITY_HANDLE;
01574     else {
01575       result = check_handle_tag_type(TAG_HANDLE(tag_handle), MBIMESHI );
01576       CHKERR(result, "iMesh_getTagType: problem guessing handle tag subtype");
01577       if (MBIMESHI->is_set_handle_tag( TAG_HANDLE(tag_handle) ))
01578         *value_type = iBase_ENTITY_SET_HANDLE;
01579       else
01580         *value_type = iBase_ENTITY_HANDLE;
01581     }
01582 
01583     RETURN(iBase_SUCCESS);
01584   }
01585 
01586   void iMesh_getTagSizeValues(iMesh_Instance instance,
01587                               /*in*/ const iBase_TagHandle tag_handle,
01588                               int *tag_size_val, int *err)
01589   {
01590     ErrorCode result = MOABI->tag_get_length(TAG_HANDLE(tag_handle), *tag_size_val);
01591     CHKERR(result, "iMesh_getTagSize: problem getting size.");
01592 
01593     RETURN(iBase_SUCCESS);
01594   }
01595 
01596   void iMesh_getTagSizeBytes(iMesh_Instance instance,
01597                              /*in*/ const iBase_TagHandle tag_handle,
01598                              int *tag_size_bytes, int *err)
01599   {
01600     ErrorCode result = MOABI->tag_get_bytes(TAG_HANDLE(tag_handle), *tag_size_bytes);
01601     CHKERR(result, "iMesh_getTagSize: problem getting size.");
01602 
01603     RETURN(iBase_SUCCESS);
01604   }
01605 
01606   void iMesh_getTagHandle(iMesh_Instance instance,
01607                           /*in*/ const char* tag_name,
01608                           iBase_TagHandle *tag_handle, int *err,
01609                           const int tag_name_len)
01610   {
01611     std::string tmp_tagname(tag_name, tag_name_len);
01612     eatwhitespace(tmp_tagname);
01613 
01614     ErrorCode result = MOABI->tag_get_handle(tmp_tagname.c_str(), 0, MB_TYPE_OPAQUE,
01615                                              (Tag&)*tag_handle, MB_TAG_ANY);
01616 
01617     if (MB_SUCCESS != result) {
01618       std::string msg("iMesh_getTagHandle: problem getting handle for tag named '");
01619       msg += std::string(tag_name) + std::string("'");
01620       *tag_handle = 0;
01621       ERROR(result, msg.c_str());
01622     }
01623 
01624       // do not return variable-length tags through ITAPS API
01625     int size;
01626     if (MB_SUCCESS != MOABI->tag_get_length( TAG_HANDLE(*tag_handle), size ))
01627       RETURN(iBase_TAG_NOT_FOUND);
01628 
01629     RETURN(iBase_SUCCESS);
01630   }
01631 
01632   void iMesh_getAllIfaceTags (iMesh_Instance instance,
01633                               /*inout*/ iBase_TagHandle** tag_handles,
01634                               /*inout*/ int* tag_handles_allocated,
01635                               /*out*/ int* tag_handles_size, int *err)
01636   {
01637     std::vector<Tag> all_tags;
01638 
01639     ErrorCode result = MOABI->tag_get_tags(all_tags);
01640     CHKERR(result, "iMesh_getAllIfaceTags failed.");
01641 
01642     remove_var_len_tags( MOABI, all_tags );
01643 
01644       // now put those tag handles into sidl array
01645     ALLOC_CHECK_ARRAY_NOFAIL(tag_handles, all_tags.size());
01646     memcpy(*tag_handles, &all_tags[0], all_tags.size()*sizeof(Tag));
01647     *tag_handles_size = all_tags.size();
01648 
01649     RETURN(iBase_SUCCESS);
01650   }
01651 
01652   void iMesh_setEntSetData (iMesh_Instance instance,
01653                             /*in*/ iBase_EntitySetHandle entity_set_handle,
01654                             /*in*/ const iBase_TagHandle tag_handle,
01655                             /*in*/ const void* tag_value,
01656                             /*in*/ const int , int *err)
01657   {
01658     ErrorCode result;
01659 
01660     EntityHandle set = ENTITY_HANDLE(entity_set_handle);
01661     result = MOABI->tag_set_data(TAG_HANDLE(tag_handle), &set, 1, tag_value);
01662     CHKERR(result, "iMesh_setEntSetData: error");
01663 
01664     RETURN(iBase_SUCCESS);
01665   }
01666 
01667   void iMesh_setEntSetIntData (iMesh_Instance instance,
01668                                /*in*/ iBase_EntitySetHandle entity_set,
01669                                /*in*/ const iBase_TagHandle tag_handle,
01670                                /*in*/ const int tag_value, int *err)
01671   {
01672     CHKTAGTYPE(tag_handle, iBase_INTEGER);
01673     iMesh_setEntSetData(instance, entity_set, tag_handle,
01674                         &tag_value,
01675                         sizeof(int), err);
01676   }
01677 
01678   void iMesh_setEntSetDblData (iMesh_Instance instance,
01679                                /*in*/ iBase_EntitySetHandle entity_set,
01680                                /*in*/ const iBase_TagHandle tag_handle,
01681                                /*in*/ const double tag_value, int *err)
01682   {
01683     CHKTAGTYPE(tag_handle, iBase_DOUBLE);
01684     iMesh_setEntSetData(instance, entity_set, tag_handle,
01685                         &tag_value,
01686                         sizeof(double), err);
01687   }
01688 
01689   void iMesh_setEntSetEHData (iMesh_Instance instance,
01690                               /*in*/ iBase_EntitySetHandle entity_set,
01691                               /*in*/ const iBase_TagHandle tag_handle,
01692                               /*in*/ const iBase_EntityHandle tag_value, int *err)
01693   {
01694       // XXX: decide how best to handle validating entity handles as tag data
01695     CHKNONEMPTY();
01696     CHKTAGTYPE(tag_handle, iBase_ENTITY_HANDLE);
01697     iMesh_setEntSetData(instance, entity_set, tag_handle,
01698                         &tag_value,
01699                         sizeof(iBase_EntityHandle), err);
01700   }
01701 
01702   void iMesh_setEntSetESHData (iMesh_Instance instance,
01703                                /*in*/ iBase_EntitySetHandle entity_set,
01704                                /*in*/ const iBase_TagHandle tag_handle,
01705                                /*in*/ const iBase_EntitySetHandle tag_value, int *err)
01706   {
01707     CHKTAGTYPE(tag_handle, iBase_ENTITY_SET_HANDLE);
01708     iMesh_setEntSetData(instance, entity_set, tag_handle,
01709                         &tag_value,
01710                         sizeof(iBase_EntitySetHandle), err);
01711   }
01712 
01713   void iMesh_getEntSetData (iMesh_Instance instance,
01714                             /*in*/ const iBase_EntitySetHandle entity_set_handle,
01715                             /*in*/ const iBase_TagHandle tag_handle,
01716                             /*inout*/ void* tag_value,
01717                             /*inout*/ int* tag_value_allocated,
01718                             /*inout*/ int* tag_value_size, int *err)
01719   {
01720     EntityHandle eh = ENTITY_HANDLE(entity_set_handle);
01721     Tag tag = TAG_HANDLE(tag_handle);
01722 
01723     int tag_size;
01724     ErrorCode result = MOABI->tag_get_bytes(tag, tag_size);
01725     CHKERR(result, "iMesh_getEntSetData: couldn't get tag size.");
01726 
01727     ALLOC_CHECK_TAG_ARRAY(tag_value, tag_size);
01728 
01729     result = MOABI->tag_get_data(tag, &eh, 1,
01730                                  *static_cast<void**>(tag_value));
01731 
01732     CHKERR(result, "iMesh_getEntSetData didn't succeed.");
01733     KEEP_ARRAY(tag_value);
01734     RETURN(iBase_SUCCESS);
01735   }
01736 
01737   void iMesh_getEntSetIntData (iMesh_Instance instance,
01738                                /*in*/ const iBase_EntitySetHandle entity_set,
01739                                /*in*/ const iBase_TagHandle tag_handle,
01740                                int *out_data, int *err)
01741   {
01742     CHKTAGTYPE(tag_handle, iBase_INTEGER);
01743     void *tag_ptr = out_data;
01744     int dum_size = sizeof(int);
01745     iMesh_getEntSetData(instance, entity_set, tag_handle, &tag_ptr,
01746                         &dum_size, &dum_size, err);
01747   }
01748 
01749   void iMesh_getEntSetDblData (iMesh_Instance instance,
01750                                /*in*/ const iBase_EntitySetHandle entity_set,
01751                                /*in*/ const iBase_TagHandle tag_handle,
01752                                double *out_data, int *err)
01753   {
01754     CHKTAGTYPE(tag_handle, iBase_DOUBLE);
01755     void *tag_ptr = out_data;
01756     int tag_size = sizeof(double);
01757     iMesh_getEntSetData(instance, entity_set, tag_handle, &tag_ptr,
01758                         &tag_size, &tag_size, err);
01759   }
01760 
01761   void iMesh_getEntSetEHData (iMesh_Instance instance,
01762                               /*in*/ const iBase_EntitySetHandle entity_set,
01763                               /*in*/ const iBase_TagHandle tag_handle,
01764                               iBase_EntityHandle *out_data, int *err)
01765   {
01766     CHKTAGTYPE(tag_handle, iBase_ENTITY_HANDLE);
01767     void *tag_ptr = out_data;
01768     int tag_size = sizeof(EntityHandle);
01769     iMesh_getEntSetData(instance, entity_set, tag_handle, &tag_ptr,
01770                         &tag_size, &tag_size, err);
01771   }
01772 
01773   void iMesh_getEntSetESHData (iMesh_Instance instance,
01774                               /*in*/ const iBase_EntitySetHandle entity_set,
01775                               /*in*/ const iBase_TagHandle tag_handle,
01776                               iBase_EntitySetHandle *out_data, int *err)
01777   {
01778     CHKTAGTYPE(tag_handle, iBase_ENTITY_SET_HANDLE);
01779     void *tag_ptr = out_data;
01780     int tag_size = sizeof(EntityHandle);
01781     iMesh_getEntSetData(instance, entity_set, tag_handle, &tag_ptr,
01782                         &tag_size, &tag_size, err);
01783   }
01784 
01785   void iMesh_getAllEntSetTags (iMesh_Instance instance,
01786                                /*in*/ const iBase_EntitySetHandle entity_set_handle,
01787                                /*out*/ iBase_TagHandle** tag_handles,
01788                                /*out*/ int* tag_handles_allocated,
01789                                /*out*/ int* tag_handles_size, int *err)
01790   {
01791     EntityHandle eh = ENTITY_HANDLE(entity_set_handle);
01792     std::vector<Tag> all_tags;
01793 
01794     ErrorCode result = MOABI->tag_get_tags_on_entity(eh, all_tags);
01795     CHKERR(result, "iMesh_entitysetGetAllTagHandles failed.");
01796 
01797     remove_var_len_tags( MOABI, all_tags );
01798 
01799       // now put those tag handles into sidl array
01800     ALLOC_CHECK_ARRAY_NOFAIL(tag_handles, all_tags.size());
01801     memcpy(*tag_handles, &all_tags[0], all_tags.size()*sizeof(Tag));
01802 
01803     *tag_handles_size = (int) all_tags.size();
01804     RETURN(iBase_SUCCESS);
01805   }
01806 
01807   void iMesh_rmvEntSetTag (iMesh_Instance instance,
01808                            /*in*/ iBase_EntitySetHandle entity_set_handle,
01809                            /*in*/ const iBase_TagHandle tag_handle, int *err)
01810   {
01811     EntityHandle set = ENTITY_HANDLE(entity_set_handle);
01812     ErrorCode result = MOABI->tag_delete_data(TAG_HANDLE(tag_handle), &set, 1);
01813 
01814       // don't return an error if the tag simply wasn't set on the ent set
01815     if (MB_TAG_NOT_FOUND == result)
01816       RETURN(iBase_SUCCESS);
01817     else
01818       RETURN(iBase_ERROR_MAP[result]);
01819   }
01820 
01821   void iMesh_setVtxCoord (iMesh_Instance instance,
01822                           /*in*/ iBase_EntityHandle vertex_handle,
01823                           /*in*/ const double x, /*in*/ const double y,
01824                           /*in*/ const double z, int *err)
01825 
01826   {
01827     const double xyz[3] = {x, y, z};
01828     int geom_dim;
01829     MOABI->get_dimension(geom_dim);
01830 
01831     iMesh_setVtxArrCoords(instance, &vertex_handle, 1, iBase_BLOCKED,
01832                           xyz, geom_dim, err);
01833   }
01834 
01835   void iMesh_createVtx(iMesh_Instance instance,
01836                        /*in*/ const double x, /*in*/ const double y,
01837                        /*in*/ const double z,
01838                        /*out*/ iBase_EntityHandle* new_vertex_handle, int *err)
01839   {
01840     int dum = 1;
01841     const double xyz[3] = {x, y, z};
01842     int geom_dim;
01843     MOABI->get_dimension(geom_dim);
01844     iMesh_createVtxArr(instance, 1, iBase_BLOCKED,
01845                        xyz, geom_dim, &new_vertex_handle, &dum, &dum, err);
01846   }
01847 
01848   void iMesh_createEnt(iMesh_Instance instance,
01849                        /*in*/ const int new_entity_topology,
01850                        /*in*/ const iBase_EntityHandle* lower_order_entity_handles,
01851                        /*in*/ const int lower_order_entity_handles_size,
01852                        /*out*/ iBase_EntityHandle* new_entity_handle,
01853                        /*out*/ int* status, int *err)
01854   {
01855     if (0 == lower_order_entity_handles_size) {
01856       ERROR(iBase_INVALID_ENTITY_COUNT,
01857             "iMesh_createEnt: need more than zero lower order entities.");
01858     }
01859 
01860       // call  directly to allow creation of higher-order entities
01861       // directly from connectivity
01862     EntityType this_type = mb_topology_table[new_entity_topology];
01863     EntityHandle tmp_ent;
01864     ErrorCode result = MOABI->create_element(this_type,
01865                                              CONST_HANDLE_ARRAY_PTR(lower_order_entity_handles),
01866                                              lower_order_entity_handles_size,
01867                                              tmp_ent);
01868     if (MB_SUCCESS == result) {
01869       *new_entity_handle = reinterpret_cast<iBase_EntityHandle>(tmp_ent);
01870       *status = iBase_NEW;
01871 
01872       if (MBIMESHI->AdjTable[5] || MBIMESHI->AdjTable[10]) {
01873         Range set_ents;
01874         set_ents.insert( tmp_ent );
01875         create_int_ents(MBIMESHI, set_ents);
01876       }
01877 
01878       RETURN(iBase_SUCCESS);
01879     }
01880     else {
01881       *new_entity_handle = 0;
01882       *status = iBase_CREATION_FAILED;
01883       ERROR(result, "iMesh_createEnt: couldn't create entity");
01884     }
01885   }
01886 
01887   void iMesh_deleteEnt(iMesh_Instance instance,
01888                        /*in*/ iBase_EntityHandle entity_handle, int *err)
01889   {
01890     iMesh_deleteEntArr(instance, &entity_handle, 1, err);
01891   }
01892 
01893   void iMesh_getArrData (iMesh_Instance instance,
01894                          /*in*/ const iBase_EntityHandle* entity_handles,
01895                          /*in*/ const int entity_handles_size,
01896                          /*in*/ const iBase_TagHandle tag_handle,
01897                          /*inout*/ void* tag_values,
01898                          /*inout*/int* tag_values_allocated,
01899                          /*out*/ int* tag_values_size, int *err)
01900   {
01901     if (0 == entity_handles_size)
01902       RETURN(iBase_SUCCESS);
01903     CHKNONEMPTY();
01904 
01905     const EntityHandle *ents = reinterpret_cast<const EntityHandle *>(entity_handles);
01906     Tag tag = TAG_HANDLE(tag_handle);
01907 
01908     int tag_size;
01909     ErrorCode result = MOABI->tag_get_bytes(tag, tag_size);
01910     if (MB_SUCCESS != result) {
01911       int nerr=-1; char tagn[64], msg[256];
01912       iMesh_getTagName(instance, tag_handle, tagn, &nerr, sizeof(tagn));
01913       snprintf(msg, sizeof(msg), "iMesh_getArrData: couldn't get size for tag \"%s\"",
01914                nerr==0?tagn:"unknown");
01915       ERROR(result, msg);
01916     }
01917 
01918     ALLOC_CHECK_TAG_ARRAY(tag_values, tag_size * entity_handles_size);
01919 
01920     result = MOABI->tag_get_data(tag, ents, entity_handles_size,
01921                                  *static_cast<void**>(tag_values));
01922 
01923     if (MB_SUCCESS != result) {
01924       std::string message("iMesh_getArrData: ");
01925       if (MB_TAG_NOT_FOUND == result)
01926         message += "tag not found";
01927       else
01928         message += "failed";
01929 
01930       std::string name;
01931       if (MB_SUCCESS == MOABI->tag_get_name( tag, name )) {
01932         message += "for tag \"";
01933         message += name;
01934         message += "\".";
01935       }
01936       ERROR(result, message.c_str());
01937     }
01938 
01939     KEEP_ARRAY(tag_values);
01940     RETURN(iBase_SUCCESS);
01941   }
01942 
01943   void iMesh_getIntArrData (iMesh_Instance instance,
01944                             /*in*/ const iBase_EntityHandle* entity_handles,
01945                             /*in*/ const int entity_handles_size,
01946                             /*in*/ const iBase_TagHandle tag_handle,
01947                             /*inout*/ int** tag_values,
01948                             /*inout*/ int* tag_values_allocated,
01949                             /*out*/ int* tag_values_size, int *err)
01950   {
01951     CHKTAGTYPE(tag_handle, iBase_INTEGER);
01952     *tag_values_allocated *= sizeof(int);
01953     if (tag_values_size != tag_values_allocated) *tag_values_size *= sizeof(int);
01954     iMesh_getArrData(instance, entity_handles,
01955                      entity_handles_size, tag_handle,
01956                      tag_values,
01957                      tag_values_allocated,
01958                      tag_values_size, err);
01959     *tag_values_allocated /= sizeof(int);
01960     if (tag_values_size != tag_values_allocated) *tag_values_size /= sizeof(int);
01961   }
01962 
01963   void iMesh_getDblArrData (iMesh_Instance instance,
01964                             /*in*/ const iBase_EntityHandle* entity_handles,
01965                             /*in*/ const int entity_handles_size,
01966                             /*in*/ const iBase_TagHandle tag_handle,
01967                             /*inout*/ double** tag_values,
01968                             /*inout*/ int* tag_values_allocated,
01969                             /*out*/ int* tag_values_size, int *err)
01970   {
01971     CHKTAGTYPE(tag_handle, iBase_DOUBLE);
01972     *tag_values_allocated *= sizeof(double);
01973     if (tag_values_size != tag_values_allocated) *tag_values_size *= sizeof(double);
01974     iMesh_getArrData(instance, entity_handles,
01975                      entity_handles_size, tag_handle,
01976                      tag_values,
01977                      tag_values_allocated, tag_values_size, err);
01978     *tag_values_allocated /= sizeof(double);
01979     if (tag_values_size != tag_values_allocated) *tag_values_size /= sizeof(double);
01980   }
01981 
01982   void iMesh_getEHArrData (iMesh_Instance instance,
01983                            /*in*/ const iBase_EntityHandle* entity_handles,
01984                            /*in*/ const int entity_handles_size,
01985                            /*in*/ const iBase_TagHandle tag_handle,
01986                            /*inout*/ iBase_EntityHandle** tag_value,
01987                            /*inout*/ int* tag_value_allocated,
01988                            /*out*/ int* tag_value_size, int *err)
01989   {
01990     CHKTAGTYPE(tag_handle, iBase_ENTITY_HANDLE);
01991     *tag_value_allocated *= sizeof(iBase_EntityHandle);
01992     if (tag_value_size != tag_value_allocated) *tag_value_size *= sizeof(iBase_EntityHandle);
01993     iMesh_getArrData(instance, entity_handles,
01994                      entity_handles_size, tag_handle,
01995                      reinterpret_cast<void**>(tag_value),
01996                      tag_value_allocated,
01997                      tag_value_size, err);
01998     *tag_value_allocated /= sizeof(iBase_EntityHandle);
01999     if (tag_value_size != tag_value_allocated) *tag_value_size /= sizeof(iBase_EntityHandle);
02000   }
02001 
02002   void iMesh_getESHArrData (iMesh_Instance instance,
02003                            /*in*/ const iBase_EntityHandle* entity_handles,
02004                            /*in*/ const int entity_handles_size,
02005                            /*in*/ const iBase_TagHandle tag_handle,
02006                            /*inout*/ iBase_EntitySetHandle** tag_value,
02007                            /*inout*/ int* tag_value_allocated,
02008                            /*out*/ int* tag_value_size, int *err)
02009   {
02010     CHKTAGTYPE(tag_handle, iBase_ENTITY_SET_HANDLE);
02011     *tag_value_allocated *= sizeof(iBase_EntityHandle);
02012     if (tag_value_size != tag_value_allocated) *tag_value_size *= sizeof(iBase_EntityHandle);
02013     iMesh_getArrData(instance, entity_handles,
02014                      entity_handles_size, tag_handle,
02015                      reinterpret_cast<void**>(tag_value),
02016                      tag_value_allocated,
02017                      tag_value_size, err);
02018     *tag_value_allocated /= sizeof(iBase_EntityHandle);
02019     if (tag_value_size != tag_value_allocated) *tag_value_size /= sizeof(iBase_EntityHandle);
02020   }
02021 
02022   void iMesh_setArrData (iMesh_Instance instance,
02023                          /*in*/ const iBase_EntityHandle* entity_handles,
02024                          /*in*/ const int entity_handles_size,
02025                          /*in*/ const iBase_TagHandle tag_handle,
02026                          /*in*/ const void* tag_values,
02027                          /*in*/ const int tag_values_size, int *err)
02028   {
02029     if (0 == entity_handles_size)
02030       RETURN(iBase_SUCCESS);
02031     CHKNONEMPTY();
02032 
02033     int tag_size;
02034     iMesh_getTagSizeBytes(instance, tag_handle, &tag_size, err);
02035     // Check err manually and just return if not iBase_SUCCESS to not step on
02036     // the error set in iMesh_getTagSizeBytes().
02037     if (iBase_SUCCESS != *err)
02038       return;
02039 
02040     if (tag_values_size != (tag_size * entity_handles_size)) {
02041       ERROR(iBase_BAD_ARRAY_SIZE, "iMesh_setArrData: bad tag_values_size passed.");
02042     }
02043 
02044     ErrorCode result = MOABI->tag_set_data(TAG_HANDLE(tag_handle),
02045                                            CONST_HANDLE_ARRAY_PTR(entity_handles),
02046                                            entity_handles_size,
02047                                            tag_values);
02048     CHKERR(result, "iMesh_setArrData didn't succeed.");
02049     RETURN(iBase_SUCCESS);
02050   }
02051 
02052   void iMesh_setIntArrData (iMesh_Instance instance,
02053                             /*in*/ const iBase_EntityHandle* entity_handles,
02054                             /*in*/ const int entity_handles_size,
02055                             /*in*/ const iBase_TagHandle tag_handle,
02056                             /*in*/ const int* tag_values,
02057                             /*in*/ const int tag_values_size, int *err)
02058   {
02059     CHKTAGTYPE(tag_handle, iBase_INTEGER);
02060     iMesh_setArrData(instance, entity_handles,
02061                      entity_handles_size, tag_handle,
02062                      reinterpret_cast<const char*>(tag_values),
02063                      sizeof(int)*tag_values_size, err);
02064   }
02065 
02066   void iMesh_setDblArrData (iMesh_Instance instance,
02067                             /*in*/ const iBase_EntityHandle* entity_handles,
02068                             /*in*/ const int entity_handles_size,
02069                             /*in*/ const iBase_TagHandle tag_handle,
02070                             /*in*/ const double* tag_values,
02071                             /*in*/ const int tag_values_size, int *err)
02072   {
02073     CHKTAGTYPE(tag_handle, iBase_DOUBLE);
02074     iMesh_setArrData(instance, entity_handles,
02075                      entity_handles_size, tag_handle,
02076                      reinterpret_cast<const char*>(tag_values),
02077                      sizeof(double)*tag_values_size, err);
02078   }
02079 
02080   void iMesh_setEHArrData (iMesh_Instance instance,
02081                            /*in*/ const iBase_EntityHandle* entity_handles,
02082                            /*in*/ const int entity_handles_size,
02083                            /*in*/ const iBase_TagHandle tag_handle,
02084                            /*in*/ const iBase_EntityHandle* tag_values,
02085                            /*in*/ const int tag_values_size, int *err)
02086   {
02087     CHKTAGTYPE(tag_handle, iBase_ENTITY_HANDLE);
02088     iMesh_setArrData(instance, entity_handles,
02089                      entity_handles_size, tag_handle,
02090                      reinterpret_cast<const char*>(tag_values),
02091                      sizeof(iBase_EntityHandle)*tag_values_size, err);
02092   }
02093 
02094   void iMesh_setESHArrData (iMesh_Instance instance,
02095                            /*in*/ const iBase_EntityHandle* entity_handles,
02096                            /*in*/ const int entity_handles_size,
02097                            /*in*/ const iBase_TagHandle tag_handle,
02098                            /*in*/ const iBase_EntitySetHandle* tag_values,
02099                            /*in*/ const int tag_values_size, int *err)
02100   {
02101     CHKTAGTYPE(tag_handle, iBase_ENTITY_SET_HANDLE);
02102     iMesh_setArrData(instance, entity_handles,
02103                      entity_handles_size, tag_handle,
02104                      reinterpret_cast<const char*>(tag_values),
02105                      sizeof(iBase_EntityHandle)*tag_values_size, err);
02106   }
02107 
02108   void iMesh_rmvArrTag (iMesh_Instance instance,
02109                         /*in*/ const iBase_EntityHandle* entity_handles,
02110                         /*in*/ const int entity_handles_size,
02111                         /*in*/ const iBase_TagHandle tag_handle, int *err)
02112   {
02113     if (0 == entity_handles_size)
02114       RETURN(iBase_SUCCESS);
02115     CHKNONEMPTY();
02116 
02117     ErrorCode result = MOABI->tag_delete_data(TAG_HANDLE(tag_handle),
02118                                               CONST_HANDLE_ARRAY_PTR(entity_handles),
02119                                               entity_handles_size);
02120 
02121       // don't return an error if the tag simply wasn't set on the entities
02122     if (MB_TAG_NOT_FOUND == result)
02123       RETURN(iBase_SUCCESS);
02124     else
02125       RETURN(iBase_ERROR_MAP[result]);
02126   }
02127 
02128   void iMesh_getData (iMesh_Instance instance,
02129                       /*in*/ const iBase_EntityHandle entity_handle,
02130                       /*in*/ const iBase_TagHandle tag_handle,
02131                       /*out*/ void* tag_value,
02132                       /*inout*/ int *tag_value_allocated,
02133                       /*out*/ int *tag_value_size, int *err)
02134   {
02135     iMesh_getArrData(instance, &entity_handle, 1,
02136                      tag_handle, tag_value, tag_value_allocated,
02137                      tag_value_size, err);
02138   }
02139 
02140   void iMesh_getIntData (iMesh_Instance instance,
02141                          /*in*/ const iBase_EntityHandle entity_handle,
02142                          /*in*/ const iBase_TagHandle tag_handle,
02143                          int *out_data, int *err)
02144   {
02145     CHKTAGTYPE(tag_handle, iBase_INTEGER);
02146     void *val_ptr = out_data;
02147     int val_size = sizeof(int);
02148     iMesh_getArrData(instance, &entity_handle, 1,
02149                      tag_handle, &val_ptr, &val_size, &val_size, err);
02150   }
02151 
02152   void iMesh_getDblData (iMesh_Instance instance,
02153                          /*in*/ const iBase_EntityHandle entity_handle,
02154                          /*in*/ const iBase_TagHandle tag_handle,
02155                          double *out_data, int *err)
02156   {
02157     CHKTAGTYPE(tag_handle, iBase_DOUBLE);
02158     void *val_ptr = out_data;
02159     int val_size = sizeof(double);
02160     iMesh_getArrData(instance, &entity_handle, 1,
02161                      tag_handle, &val_ptr, &val_size, &val_size, err);
02162   }
02163 
02164   void iMesh_getEHData (iMesh_Instance instance,
02165                         /*in*/ const iBase_EntityHandle entity_handle,
02166                         /*in*/ const iBase_TagHandle tag_handle,
02167                         iBase_EntityHandle *out_data, int *err)
02168   {
02169     CHKTAGTYPE(tag_handle, iBase_ENTITY_HANDLE);
02170     void *val_ptr = out_data;
02171     int dum = sizeof(iBase_EntityHandle);
02172     iMesh_getArrData(instance, &entity_handle, 1,
02173                      tag_handle, &val_ptr, &dum, &dum, err);
02174   }
02175 
02176   void iMesh_getESHData (iMesh_Instance instance,
02177                         /*in*/ const iBase_EntityHandle entity_handle,
02178                         /*in*/ const iBase_TagHandle tag_handle,
02179                         iBase_EntitySetHandle *out_data, int *err)
02180   {
02181     CHKTAGTYPE(tag_handle, iBase_ENTITY_SET_HANDLE);
02182     void *val_ptr = out_data;
02183     int dum = sizeof(iBase_EntityHandle);
02184     iMesh_getArrData(instance, &entity_handle, 1,
02185                      tag_handle, &val_ptr, &dum, &dum, err);
02186   }
02187 
02188   void iMesh_setData (iMesh_Instance instance,
02189                       /*in*/ iBase_EntityHandle entity_handle,
02190                       /*in*/ const iBase_TagHandle tag_handle,
02191                       /*in*/ const void* tag_value,
02192                       /*in*/ const int tag_value_size, int *err)
02193   {
02194     iMesh_setArrData(instance, &entity_handle, 1,
02195                      tag_handle, tag_value, tag_value_size, err);
02196   }
02197 
02198   void iMesh_setIntData (iMesh_Instance instance,
02199                          /*in*/ iBase_EntityHandle entity_handle,
02200                          /*in*/ const iBase_TagHandle tag_handle,
02201                          /*in*/ const int tag_value, int *err)
02202   {
02203     CHKTAGTYPE(tag_handle, iBase_INTEGER);
02204     iMesh_setArrData(instance, &entity_handle, 1,
02205                      tag_handle,
02206                      reinterpret_cast<const char*>(&tag_value),
02207                      sizeof(int), err);
02208   }
02209 
02210   void iMesh_setDblData (iMesh_Instance instance,
02211 
02212                          /*in*/ iBase_EntityHandle entity_handle,
02213                          /*in*/ const iBase_TagHandle tag_handle,
02214                          /*in*/ const double tag_value, int *err)
02215   {
02216     CHKTAGTYPE(tag_handle, iBase_DOUBLE);
02217     iMesh_setArrData(instance, &entity_handle, 1,
02218                      tag_handle,
02219                      reinterpret_cast<const char*>(&tag_value),
02220                      sizeof(double), err);
02221   }
02222 
02223   void iMesh_setEHData (iMesh_Instance instance,
02224                         /*in*/ iBase_EntityHandle entity_handle,
02225                         /*in*/ const iBase_TagHandle tag_handle,
02226                         /*in*/ const iBase_EntityHandle tag_value, int *err)
02227   {
02228     CHKTAGTYPE(tag_handle, iBase_ENTITY_HANDLE);
02229     iMesh_setArrData(instance, &entity_handle, 1,
02230                      tag_handle,
02231                      reinterpret_cast<const char*>(&tag_value),
02232                      sizeof(iBase_EntityHandle), err);
02233   }
02234 
02235   void iMesh_setESHData (iMesh_Instance instance,
02236                         /*in*/ iBase_EntityHandle entity_handle,
02237                         /*in*/ const iBase_TagHandle tag_handle,
02238                         /*in*/ const iBase_EntitySetHandle tag_value, int *err)
02239   {
02240     CHKTAGTYPE(tag_handle, iBase_ENTITY_SET_HANDLE);
02241     iMesh_setArrData(instance, &entity_handle, 1,
02242                      tag_handle,
02243                      reinterpret_cast<const char*>(&tag_value),
02244                      sizeof(iBase_EntityHandle), err);
02245   }
02246 
02247   void iMesh_getAllTags (iMesh_Instance instance,
02248                          /*in*/ const iBase_EntityHandle entity_handle,
02249                          /*inout*/ iBase_TagHandle** tag_handles,
02250                          /*inout*/ int* tag_handles_allocated,
02251                          /*out*/ int* tag_handles_size, int *err)
02252   {
02253     std::vector<Tag> all_tags;
02254 
02255     ErrorCode result = MOABI->tag_get_tags_on_entity(ENTITY_HANDLE(entity_handle), all_tags);
02256     CHKERR(result, "iMesh_getAllTags failed.");
02257 
02258     remove_var_len_tags( MOABI, all_tags );
02259 
02260       // now put those tag handles into sidl array
02261     ALLOC_CHECK_ARRAY_NOFAIL(tag_handles, all_tags.size());
02262     memcpy(*tag_handles, &all_tags[0], all_tags.size()*sizeof(Tag));
02263     *tag_handles_size = all_tags.size();
02264 
02265     RETURN(iBase_SUCCESS);
02266   }
02267 
02268   void iMesh_rmvTag (iMesh_Instance instance,
02269                      /*in*/ iBase_EntityHandle entity_handle,
02270                      /*in*/ const iBase_TagHandle tag_handle, int *err)
02271   {
02272     iMesh_rmvArrTag(instance, &entity_handle, 1, tag_handle, err);
02273   }
02274 
02275   void iMesh_initEntIter (iMesh_Instance instance,
02276                           /*in*/ const iBase_EntitySetHandle entity_set_handle,
02277                           /*in*/ const int requested_entity_type,
02278                           /*in*/ const int requested_entity_topology,
02279                           /*in*/ const int resilient,
02280                           /*out*/ iBase_EntityIterator* entity_iterator,
02281                           int *err)
02282   {
02283     iMesh_initEntArrIterRec(instance, entity_set_handle, requested_entity_type,
02284                             requested_entity_topology, 1, resilient, false,
02285                             reinterpret_cast<iBase_EntityArrIterator*>(entity_iterator),
02286                             err);
02287   }
02288 
02289   void iMesh_getNextEntIter (iMesh_Instance instance,
02290                              /*in*/ iBase_EntityIterator entity_iterator,
02291                              /*out*/ iBase_EntityHandle* entity_handle,
02292                              int *is_end, int *err)
02293   {
02294     int eh_size = 1;
02295     iMesh_getNextEntArrIter(instance,
02296                             reinterpret_cast<iBase_EntityArrIterator>(entity_iterator),
02297                             &entity_handle, &eh_size, &eh_size, is_end, err);
02298 
02299   }
02300 
02301   void iMesh_resetEntIter (iMesh_Instance instance,
02302                            /*in*/ iBase_EntityIterator entity_iterator, int *err)
02303   {
02304     iMesh_resetEntArrIter(instance,
02305                           reinterpret_cast<iBase_EntityArrIterator>(entity_iterator),
02306                           err);
02307   }
02308 
02309   void iMesh_endEntIter (iMesh_Instance instance,
02310                          /*in*/ iBase_EntityIterator entity_iterator, int *err)
02311   {
02312     iMesh_endEntArrIter(instance,
02313                         reinterpret_cast<iBase_EntityArrIterator>(entity_iterator),
02314                         err);
02315   }
02316 
02317   void iMesh_getEntTopo (iMesh_Instance instance,
02318                          /*in*/ const iBase_EntityHandle entity_handle,
02319                          int *out_topo, int *err)
02320   {
02321     *out_topo = tstt_topology_table[MOABI->type_from_handle(ENTITY_HANDLE(entity_handle))];
02322     RETURN(iBase_SUCCESS);
02323   }
02324 
02325   void iMesh_getEntType (iMesh_Instance instance,
02326                          /*in*/ const iBase_EntityHandle entity_handle,
02327                          int *out_type, int *err)
02328   {
02329     *out_type = tstt_type_table[MOABI->type_from_handle(ENTITY_HANDLE(entity_handle))];
02330     RETURN(iBase_SUCCESS);
02331   }
02332 
02333   void iMesh_getVtxCoord (iMesh_Instance instance,
02334                           /*in*/ const iBase_EntityHandle vertex_handle,
02335                           /*out*/ double *x, /*out*/ double *y, /*out*/ double *z, int *err)
02336   {
02337     int order = iBase_BLOCKED;
02338     double xyz[3] = {0}, *tmp_xyz = xyz;
02339     int dum = 3;
02340 
02341     iMesh_getVtxArrCoords(instance,
02342                           &vertex_handle, 1, order,
02343                           &tmp_xyz, &dum, &dum, err);
02344     if (iBase_SUCCESS == *err) {
02345       *x = xyz[0]; *y = xyz[1]; *z = xyz[2];
02346     }
02347   }
02348 
02349   void iMesh_getEntAdj(iMesh_Instance instance,
02350                        /*in*/ const iBase_EntityHandle entity_handle,
02351                        /*in*/ const int entity_type_requested,
02352                        /*inout*/ iBase_EntityHandle** adj_entity_handles,
02353                        /*inout*/ int* adj_entity_handles_allocated,
02354                        /*out*/ int* adj_entity_handles_size, int *err)
02355   {
02356     int offsets[2];
02357     int *offsets_ptr = offsets;
02358     int offset_size, offset_allocated = 2;
02359 
02360     iMesh_getEntArrAdj(instance,
02361                        &entity_handle, 1, entity_type_requested,
02362                        adj_entity_handles, adj_entity_handles_allocated,
02363                        adj_entity_handles_size, &offsets_ptr, &offset_allocated,
02364                        &offset_size, err);
02365   }
02366 
02367   void iMesh_getEnt2ndAdj( iMesh_Instance instance,
02368                            iBase_EntityHandle entity_handle,
02369                            int order_adjacent_key,
02370                            int requested_entity_type,
02371                            iBase_EntityHandle** adj_entities,
02372                            int* adj_entities_allocated,
02373                            int* adj_entities_size,
02374                            int* err )
02375   {
02376     int offsets[2];
02377     int *offsets_ptr = offsets;
02378     int offset_size, offset_allocated = 2;
02379 
02380     iMesh_getEntArr2ndAdj(instance,
02381                           &entity_handle, 1, order_adjacent_key,
02382                           requested_entity_type,
02383                           adj_entities, adj_entities_allocated,
02384                           adj_entities_size, &offsets_ptr, &offset_allocated,
02385                           &offset_size, err);
02386   }
02387 
02388   void iMesh_subtract(iMesh_Instance instance,
02389                       /*in*/ const iBase_EntitySetHandle entity_set_1,
02390                       /*in*/ const iBase_EntitySetHandle entity_set_2,
02391                       /*out*/ iBase_EntitySetHandle* result_entity_set, int *err)
02392   {
02393     EntityHandle temp_set;
02394     EntityHandle set1 = ENTITY_HANDLE(entity_set_1),
02395       set2 = ENTITY_HANDLE(entity_set_2);
02396 
02397     int isList1, isList2;
02398     iMesh_isList(instance, entity_set_1, &isList1, err);
02399     if (*err != iBase_SUCCESS) return;
02400     iMesh_isList(instance, entity_set_2, &isList2, err);
02401     if (*err != iBase_SUCCESS) return;
02402 
02403     ErrorCode result;
02404     if (isList1 && isList2)
02405       result = MOABI->create_meshset(MESHSET_ORDERED, temp_set);
02406     else
02407       result = MOABI->create_meshset(MESHSET_SET, temp_set);
02408 
02409     if (MB_SUCCESS != result)
02410       ERROR(result, "iMesh_subtract: couldn't create result set.");
02411 
02412       // if the second set is the root set, the result is always the empty set
02413     if (entity_set_2) {
02414       if (!entity_set_1) {
02415           // subtracting from the root set, so get everything first...
02416         Range entities;
02417         result = MOABI->get_entities_by_handle(0,entities);
02418         if (MB_SUCCESS == result)
02419           result = MOABI->add_entities(temp_set, entities);
02420           // ...but not the newly-created set!
02421         if (MB_SUCCESS == result)
02422           result = MOABI->remove_entities(temp_set, &temp_set, 1);
02423       }
02424       else
02425         result = MOABI->unite_meshset(temp_set, set1);
02426 
02427       if (MB_SUCCESS == result)
02428         result = MOABI->subtract_meshset(temp_set, set2);
02429     }
02430 
02431     CHKERR(result, "iMesh_subtract: ERROR subtract failed.");
02432     *result_entity_set = (iBase_EntitySetHandle)temp_set;
02433 
02434     RETURN(iBase_SUCCESS);
02435   }
02436 
02437   void iMesh_intersect(iMesh_Instance instance,
02438                        /*in*/ const iBase_EntitySetHandle entity_set_1,
02439                        /*in*/ const iBase_EntitySetHandle entity_set_2,
02440                        /*out*/ iBase_EntitySetHandle* result_entity_set, int *err)
02441   {
02442     EntityHandle temp_set;
02443     EntityHandle set1 = ENTITY_HANDLE(entity_set_1),
02444       set2 = ENTITY_HANDLE(entity_set_2);
02445 
02446     int isList1, isList2;
02447     iMesh_isList(instance, entity_set_1, &isList1, err);
02448     if (*err != iBase_SUCCESS) return;
02449     iMesh_isList(instance, entity_set_2, &isList2, err);
02450     if (*err != iBase_SUCCESS) return;
02451 
02452     ErrorCode result;
02453     if (isList1 && isList2)
02454       result = MOABI->create_meshset(MESHSET_ORDERED, temp_set);
02455     else
02456       result = MOABI->create_meshset(MESHSET_SET, temp_set);
02457 
02458     if (MB_SUCCESS != result)
02459       ERROR(result, "iMesh_intersect: couldn't create result set.");
02460 
02461     if (!entity_set_1 && !entity_set_2) {
02462         // intersecting the root set with itself, so get everything...
02463       Range entities;
02464       result = MOABI->get_entities_by_handle(0, entities);
02465       if (MB_SUCCESS == result)
02466         result = MOABI->add_entities(temp_set, entities);
02467         // ...but not the newly-created set!
02468       if (MB_SUCCESS == result)
02469         result = MOABI->remove_entities(temp_set, &temp_set, 1);
02470     }
02471     else if (!entity_set_1) {
02472       result = MOABI->unite_meshset(temp_set, set2);
02473     }
02474     else if (!entity_set_2) {
02475       result = MOABI->unite_meshset(temp_set, set1);
02476     }
02477     else {
02478       if (isList1 && isList2) {
02479           // ITAPS has very specific rules about the behavior of intersection on
02480           // list-type sets. Since MOAB doesn't (and likely will never) work
02481           // exactly this way, we implement our own algorithm here.
02482 
02483 #ifdef HAVE_UNORDERED_MAP
02484         typedef UNORDERED_MAP_NS::unordered_map<EntityHandle, size_t> lookup_t;
02485 #else
02486         typedef std::map<EntityHandle, size_t> lookup_t;
02487 #endif
02488 
02489           // First, build a lookup table for the second set.
02490         lookup_t lookup;
02491         {
02492           std::vector<EntityHandle> contents2;
02493           result = MOABI->get_entities_by_handle(set2, contents2);
02494           CHKERR(result,"iMesh_intersect: ERROR intersect failed.");
02495 
02496           for (std::vector<EntityHandle>::iterator i = contents2.begin();
02497                i != contents2.end(); ++i) {
02498 #ifdef HAVE_UNORDERED_MAP
02499             lookup_t::iterator j = lookup.find(*i);
02500 #else
02501             lookup_t::iterator j = lookup.lower_bound(*i);
02502 #endif
02503             if (j != lookup.end() && j->first == *i)
02504               ++j->second;
02505             else
02506               lookup.insert(j, lookup_t::value_type(*i, 1));
02507           }
02508         }
02509 
02510           // Then, iterate over the contents of the first set and check for
02511           // their existence in the second set.
02512         std::vector<EntityHandle> contents1;
02513         result = MOABI->get_entities_by_handle(set1, contents1);
02514         CHKERR(result,"iMesh_intersect: ERROR intersect failed.");
02515 
02516         std::vector<EntityHandle>::iterator w = contents1.begin();
02517         for (std::vector<EntityHandle>::iterator i = contents1.begin();
02518              i != contents1.end(); ++i) {
02519           lookup_t::iterator j = lookup.find(*i);
02520           if (j != lookup.end() && j->second) {
02521             --j->second;
02522             *w = *i;
02523             ++w;
02524           }
02525         }
02526 
02527         result = MOABI->add_entities(temp_set, &contents1[0],
02528                                      w - contents1.begin());
02529       }
02530       else {
02531         result = MOABI->unite_meshset(temp_set, set1);
02532         if (MB_SUCCESS == result)
02533           result = MOABI->intersect_meshset(temp_set, set2);
02534       }
02535     }
02536 
02537     CHKERR(result,"iMesh_intersect: ERROR intersect failed.");
02538     *result_entity_set = (iBase_EntitySetHandle)temp_set;
02539 
02540     RETURN(iBase_SUCCESS);
02541   }
02542 
02543   void iMesh_unite(iMesh_Instance instance,
02544                    /*in*/ const iBase_EntitySetHandle entity_set_1,
02545                    /*in*/ const iBase_EntitySetHandle entity_set_2,
02546                    /*out*/ iBase_EntitySetHandle* result_entity_set, int *err)
02547   {
02548     EntityHandle temp_set;
02549     EntityHandle set1 = ENTITY_HANDLE(entity_set_1),
02550       set2 = ENTITY_HANDLE(entity_set_2);
02551 
02552     int isList1, isList2;
02553     iMesh_isList(instance, entity_set_1, &isList1, err);
02554     if (*err != iBase_SUCCESS) return;
02555     iMesh_isList(instance, entity_set_2, &isList2, err);
02556     if (*err != iBase_SUCCESS) return;
02557 
02558     ErrorCode result;
02559     if (isList1 && isList2)
02560       result = MOABI->create_meshset(MESHSET_ORDERED, temp_set);
02561     else
02562       result = MOABI->create_meshset(MESHSET_SET, temp_set);
02563 
02564     if (MB_SUCCESS != result)
02565       ERROR(result, "iMesh_unite: couldn't create result set.");
02566 
02567 
02568     if (entity_set_1 && entity_set_2) {
02569       result = MOABI->unite_meshset(temp_set, set1);
02570       if (MB_SUCCESS == result)
02571         result = MOABI->unite_meshset(temp_set, set2);
02572     }
02573     else {
02574         // uniting with the root set, so get everything...
02575       Range entities;
02576       result = MOABI->get_entities_by_handle(0, entities);
02577       if (MB_SUCCESS == result)
02578         result = MOABI->add_entities(temp_set, entities);
02579         // ...but not the newly-created set!
02580       if (MB_SUCCESS == result)
02581         result = MOABI->remove_entities(temp_set, &temp_set, 1);
02582     }
02583 
02584     CHKERR(result,"iMesh_unite: ERROR unite failed.");
02585 
02586     *result_entity_set = (iBase_EntitySetHandle)temp_set;
02587 
02588     RETURN(iBase_SUCCESS);
02589   }
02590 
02591   void iMesh_getEntitiesRec(iMesh_Instance instance,
02592                             /*in*/ const iBase_EntitySetHandle entity_set_handle,
02593                             /*in*/ const int entity_type,
02594                             /*in*/ const int entity_topology,
02595                             /*in*/ const int recursive,
02596                             /*out*/ iBase_EntityHandle** entity_handles,
02597                             /*out*/ int* entity_handles_allocated,
02598                             /*out*/ int* entity_handles_size,
02599                             /*out*/ int *err)
02600   {
02601     CHKENUM(entity_type, iBase_EntityType, iBase_INVALID_ENTITY_TYPE);
02602     CHKENUM(entity_topology, iMesh_EntityTopology,
02603             iBase_INVALID_ENTITY_TOPOLOGY);
02604 
02605     bool use_top = false;
02606       // initialize just to get rid of compiler warning
02607     EntityType type = mb_topology_table[iMesh_ALL_TOPOLOGIES];
02608     std::vector<EntityHandle> out_entities;
02609 
02610     if (entity_topology != iMesh_ALL_TOPOLOGIES) {
02611       type = mb_topology_table[entity_topology];
02612       use_top = true;
02613 
02614       if (entity_type != iBase_ALL_TYPES) {
02615         if (entity_topology != iMesh_SEPTAHEDRON &&
02616             entity_type != CN::Dimension(type))
02617           ERROR(iBase_BAD_TYPE_AND_TOPO, "type and topology are inconsistant");
02618 
02619           // Special-case handling for septahedra since we don't support them
02620         else if (entity_topology == iMesh_SEPTAHEDRON &&
02621                  entity_type != iBase_REGION)
02622           ERROR(iBase_BAD_TYPE_AND_TOPO, "type and topology are inconsistant");
02623       }
02624     }
02625 
02626     EntityHandle handle = ENTITY_HANDLE(entity_set_handle);
02627     ErrorCode result;
02628 
02629     if (use_top) {
02630       if (entity_topology == iMesh_SEPTAHEDRON)
02631         result = MB_SUCCESS;  // MOAB doesn't do septahedrons, so there are never any.
02632       else
02633         result = MOABI->get_entities_by_type(handle, type, out_entities, recursive);
02634     }
02635     else if (entity_type != iBase_ALL_TYPES)
02636       result = MOABI->get_entities_by_dimension(handle, entity_type, out_entities, recursive);
02637     else
02638       result = MOABI->get_entities_by_handle(handle, out_entities, recursive);
02639 
02640     CHKERR(result,"iMesh_GetEntities:ERROR getting entities.");
02641 
02642       // remove entity sets from the result list
02643     std::vector<EntityHandle>::iterator iter, end_iter;
02644     if (iBase_ALL_TYPES == entity_type && iMesh_ALL_TOPOLOGIES == entity_topology) {
02645       for (iter = out_entities.begin(); iter != out_entities.end() &&
02646            TYPE_FROM_HANDLE(*iter) != MBENTITYSET; ++iter);
02647       for (end_iter = iter; iter != out_entities.end(); ++iter)
02648         if (TYPE_FROM_HANDLE(*iter) != MBENTITYSET)
02649           *(end_iter++) = *iter;
02650       out_entities.erase( end_iter, out_entities.end() );
02651     }
02652 
02653     int num_ents = out_entities.size();
02654 
02655     ALLOC_CHECK_ARRAY_NOFAIL(entity_handles, num_ents);
02656 
02657     int k = 0;
02658 
02659       // filter out entity sets here
02660     for (iter = out_entities.begin(); iter != out_entities.end(); iter++)
02661       (*entity_handles)[k++] = (iBase_EntityHandle)*iter;
02662 
02663       // now it's safe to set the size; set it to k, not out_entities.size(), to
02664       // account for sets which might have been removed
02665     *entity_handles_size = k;
02666 
02667     RETURN(iBase_SUCCESS);
02668   }
02669 
02685   void iMesh_getNumOfTypeRec(iMesh_Instance instance,
02686                              /*in*/ const iBase_EntitySetHandle entity_set_handle,
02687                              /*in*/ const int entity_type,
02688                              /*in*/ const int recursive,
02689                              /*out*/ int *num_type,
02690                              /*out*/ int *err)
02691   {
02692     CHKENUM(entity_type, iBase_EntityType, iBase_INVALID_ENTITY_TYPE);
02693 
02694     *num_type = 0;
02695     ErrorCode result;
02696     if (entity_type == iBase_ALL_TYPES) {
02697       result = MOABI->get_number_entities_by_handle
02698         (ENTITY_HANDLE(entity_set_handle), *num_type, recursive);
02699       if (MB_SUCCESS == result && !recursive) {
02700         int num_sets = 0;
02701         result = MOABI->get_number_entities_by_type
02702           (ENTITY_HANDLE(entity_set_handle), MBENTITYSET, num_sets, recursive);
02703         *num_type -= num_sets;
02704       }
02705     } else {
02706       result = MOABI->get_number_entities_by_dimension
02707         (ENTITY_HANDLE(entity_set_handle), entity_type, *num_type, recursive);
02708     }
02709 
02710     CHKERR(result,"iMesh_entitysetGetNumberEntityOfType: "
02711                   "ERROR getting number of entities by type.");
02712 
02713     RETURN(iBase_SUCCESS);
02714   }
02715 
02716 
02732   void iMesh_getNumOfTopoRec(iMesh_Instance instance,
02733                              /*in*/ const iBase_EntitySetHandle entity_set_handle,
02734                              /*in*/ const int entity_topology,
02735                              /*in*/ const int recursive,
02736                              /*out*/ int *num_topo,
02737                              /*out*/ int *err)
02738   {
02739     CHKENUM(entity_topology, iMesh_EntityTopology,
02740             iBase_INVALID_ENTITY_TOPOLOGY);
02741 
02742     if (entity_topology == iMesh_SEPTAHEDRON) {
02743       *num_topo = 0;
02744       RETURN(iBase_SUCCESS);
02745     }
02746 
02747     *num_topo = 0;
02748     ErrorCode result;
02749     if (iMesh_ALL_TOPOLOGIES == entity_topology) {
02750       result = MOABI->get_number_entities_by_handle(ENTITY_HANDLE(entity_set_handle),
02751                                                   *num_topo, recursive);
02752 
02753       if (!recursive && MB_SUCCESS == result) { // remove entity sets from count
02754         int num_sets;
02755         result = MOABI->get_number_entities_by_type
02756           (ENTITY_HANDLE(entity_set_handle), MBENTITYSET, num_sets, recursive);
02757         *num_topo -= num_sets;
02758       }
02759     }
02760     else if (iMesh_SEPTAHEDRON == entity_topology) {
02761       result = MB_SUCCESS;
02762       *num_topo = 0;
02763     }
02764     else {
02765       result = MOABI->get_number_entities_by_type(ENTITY_HANDLE(entity_set_handle),
02766                                          mb_topology_table[entity_topology],
02767                                          *num_topo, recursive);
02768     }
02769 
02770     CHKERR(result,"iMesh_entitysetGetNumberEntityOfTopology: ERROR getting "
02771                       "number of entities by topology.");
02772     RETURN(iBase_SUCCESS);
02773   }
02774 
02795   void iMesh_getEntsByTagsRec(iMesh_Instance instance,
02796                               /*in*/ const iBase_EntitySetHandle entity_set_handle,
02797                               /*in*/ const int entity_type,
02798                               /*in*/ const int entity_topology,
02799                               /*in*/ const iBase_TagHandle *tag_handles,
02800                               /*in*/ const char * const *tag_vals,
02801                               /*in*/ const int num_tags_vals,
02802                               /*in*/ const int recursive,
02803                               /*out*/ iBase_EntityHandle** entity_handles,
02804                               /*out*/ int* entity_handles_allocated,
02805                               /*out*/ int* entity_handles_size,
02806                               /*out*/ int *err)
02807   {
02808     CHKENUM(entity_type, iBase_EntityType, iBase_INVALID_ENTITY_TYPE);
02809     CHKENUM(entity_topology, iMesh_EntityTopology,
02810             iBase_INVALID_ENTITY_TOPOLOGY);
02811 
02812     bool use_top = false;
02813       // initialize just to get rid of compiler warning
02814     EntityType type = mb_topology_table[iMesh_ALL_TOPOLOGIES];
02815     Range out_entities;
02816 
02817     if (entity_topology != iMesh_ALL_TOPOLOGIES) {
02818       type = mb_topology_table[entity_topology];
02819       use_top = true;
02820 
02821       if (entity_type != iBase_ALL_TYPES) {
02822         if (entity_topology != iMesh_SEPTAHEDRON &&
02823             entity_type != CN::Dimension(type))
02824           ERROR(iBase_BAD_TYPE_AND_TOPO, "type and topology are inconsistant");
02825 
02826           // Special-case handling for septahedra since we don't support them
02827         else if (entity_topology == iMesh_SEPTAHEDRON &&
02828                  entity_type != iBase_REGION)
02829           ERROR(iBase_BAD_TYPE_AND_TOPO, "type and topology are inconsistant");
02830       }
02831     }
02832 
02833     EntityHandle handle = ENTITY_HANDLE(entity_set_handle);
02834     ErrorCode result = MB_SUCCESS;
02835 
02836     if (use_top) {
02837       if (entity_topology == iMesh_SEPTAHEDRON)
02838         result = MB_SUCCESS;  // MOAB doesn't do septahedrons, so there are never any.
02839       else
02840         result = MOABI->get_entities_by_type_and_tag(handle, type, (Tag*)tag_handles,
02841                                                    (const void* const *)tag_vals,
02842                                                    num_tags_vals, out_entities,
02843                                                    Interface::INTERSECT, recursive);
02844     }
02845     else if (entity_type != iBase_ALL_TYPES) {
02846         // need to loop over all types of this dimension
02847       for (EntityType tp = CN::TypeDimensionMap[entity_type].first;
02848            tp <= CN::TypeDimensionMap[entity_type].second; tp++) {
02849         Range tmp_range;
02850         ErrorCode tmp_result = MOABI->get_entities_by_type_and_tag(handle, type, (Tag*)tag_handles,
02851                                                                    (const void* const *)tag_vals,
02852                                                                    num_tags_vals, tmp_range,
02853                                                                    Interface::INTERSECT, recursive);
02854         if (MB_SUCCESS != tmp_result) result = tmp_result;
02855         else out_entities.merge(tmp_range);
02856       }
02857     }
02858     else
02859       result = MOABI->get_entities_by_type_and_tag(handle, type, (Tag*)tag_handles,
02860                                                  (const void* const *)tag_vals,
02861                                                  num_tags_vals, out_entities,
02862                                                  Interface::INTERSECT, recursive);
02863 
02864     CHKERR(result,"iMesh_GetEntities:ERROR getting entities.");
02865 
02866     ALLOC_CHECK_ARRAY_NOFAIL(entity_handles, out_entities.size());
02867 
02868     Range::iterator iter = out_entities.begin();
02869     Range::iterator end_iter = out_entities.end();
02870     int k = 0;
02871 
02872       // filter out entity sets here
02873     if (iBase_ALL_TYPES == entity_type && iMesh_ALL_TOPOLOGIES == entity_topology) {
02874       for (; iter != end_iter && MOABI->type_from_handle(*iter) != MBENTITYSET; iter++)
02875         (*entity_handles)[k++] = (iBase_EntityHandle)*iter;
02876     }
02877     else {
02878       for (; iter != end_iter; iter++)
02879         (*entity_handles)[k++] = (iBase_EntityHandle)*iter;
02880     }
02881 
02882       // now it's safe to set the size; set it to k, not out_entities.size(), to
02883       // account for sets which might have been removed
02884     *entity_handles_size = k;
02885 
02886     RETURN(iBase_SUCCESS);
02887   }
02888 
02889   void iMesh_getEntSetsByTagsRec(iMesh_Instance instance,
02890                                  /*in*/ const iBase_EntitySetHandle entity_set_handle,
02891                                  /*in*/ const iBase_TagHandle *tag_handles,
02892                                  /*in*/ const char * const *tag_vals,
02893                                  /*in*/ const int num_tags_vals,
02894                                  /*in*/ const int recursive,
02895                                  /*out*/ iBase_EntitySetHandle** set_handles,
02896                                  /*out*/ int* set_handles_allocated,
02897                                  /*out*/ int* set_handles_size,
02898                                  /*out*/ int *err)
02899   {
02900     Range out_entities;
02901 
02902     EntityHandle handle = ENTITY_HANDLE(entity_set_handle);
02903     ErrorCode result;
02904 
02905     result = MOABI->get_entities_by_type_and_tag(handle, MBENTITYSET, (Tag*)tag_handles,
02906                                                (const void* const *)tag_vals,
02907                                                num_tags_vals, out_entities,
02908                                                Interface::INTERSECT, recursive);
02909     CHKERR(result,"ERROR getting entities.");
02910 
02911     ALLOC_CHECK_ARRAY_NOFAIL(set_handles, out_entities.size());
02912 
02913     std::copy(out_entities.begin(), out_entities.end(), ((EntityHandle*) *set_handles));
02914 
02915     RETURN(iBase_SUCCESS);
02916   }
02917 
02918   void iMesh_MBCNType(/*in*/ const int imesh_entity_topology,
02919                       /*out*/ int *mbcn_type)
02920   {
02921     if (iMesh_POINT > imesh_entity_topology ||
02922         iMesh_ALL_TOPOLOGIES <= imesh_entity_topology)
02923       *mbcn_type = -1;
02924     else
02925       *mbcn_type = mb_topology_table[imesh_entity_topology];
02926   }
02927 
02928   void iMesh_tagIterate(iMesh_Instance instance,
02929                         /*in*/ const iBase_TagHandle tag_handle,
02930                         iBase_EntityArrIterator entArr_iterator, 
02932                         void* data, 
02935                         int* count,
02937                         int* err  
02939                         ) 
02940   {
02941     MBRangeIter *ri = dynamic_cast<MBRangeIter*>(entArr_iterator);
02942     if (!ri) CHKERR(MB_FAILURE,"Wrong type of iterator, need a range-based iterator for iMesh_tagIterate.");
02943   
02944     ErrorCode result = MOABI->tag_iterate(TAG_HANDLE(tag_handle), 
02945                                           ri->position(), ri->end(), *count, *static_cast<void**>(data));
02946     CHKERR(result, "Problem getting tag iterator.");
02947 
02948     RETURN(iBase_SUCCESS);
02949   }
02950 
02951   void iMesh_connectIterate(iMesh_Instance instance,
02952                             iBase_EntityArrIterator entArr_iterator, 
02954                             iBase_EntityHandle **connect,
02956                             int *verts_per_entity,
02958                             int* count,
02960                             int* err  
02962                             ) 
02963   {
02964     MBRangeIter *ri = dynamic_cast<MBRangeIter*>(entArr_iterator);
02965     if (!ri) CHKERR(MB_FAILURE,"Wrong type of iterator, need a range-based iterator for iMesh_connectIterate.");
02966   
02967     ErrorCode result = MOABI->connect_iterate(ri->position(), ri->end(), 
02968                                               reinterpret_cast<EntityHandle*&>(*connect), *verts_per_entity, *count);
02969     CHKERR(result, "Problem getting connect iterator.");
02970 
02971     RETURN(iBase_SUCCESS);
02972   }
02973 
02974   void iMesh_coordsIterate(iMesh_Instance instance,
02975                            iBase_EntityArrIterator entArr_iterator, 
02977                            double **xcoords_ptr,
02979                            double **ycoords_ptr,
02981                            double **zcoords_ptr,
02983                             int* count,
02985                             int* err  
02987                             ) 
02988   {
02989     MBRangeIter *ri = dynamic_cast<MBRangeIter*>(entArr_iterator);
02990     if (!ri) CHKERR(MB_FAILURE,"Wrong type of iterator, need a range-based iterator for iMesh_coordsIterate.");
02991   
02992     ErrorCode result = MOABI->coords_iterate(ri->position(), ri->end(), 
02993                                              *xcoords_ptr, *ycoords_ptr, *zcoords_ptr, *count);
02994     CHKERR(result, "Problem getting coords iterator.");
02995 
02996     RETURN(iBase_SUCCESS);
02997   }
02998 
02999   void iMesh_stepEntIter(
03000       iMesh_Instance instance, 
03002       iBase_EntityIterator ent_iterator, 
03004       int step_length, 
03006       int* at_end, 
03008       int* err  
03010                       ) 
03011   {
03012     iMesh_stepEntArrIter(instance, reinterpret_cast<iBase_EntityArrIterator>(ent_iterator),
03013                          step_length, at_end, err);
03014   }
03015 
03016   void iMesh_stepEntArrIter(
03017       iMesh_Instance instance, 
03019       iBase_EntityArrIterator entArr_iterator, 
03021       int step_length, 
03023       int* at_end, 
03025       int* err  
03027                       ) 
03028   {
03029     bool tmp;
03030     ErrorCode result = entArr_iterator->step(step_length, tmp);
03031     CHKERR(result, "Problem stepping iterator.");
03032     *at_end = tmp;
03033     RETURN(iBase_SUCCESS);
03034   }
03035 
03039   void iMesh_initEntArrIterRec (iMesh_Instance instance,
03040                              /*in*/ const iBase_EntitySetHandle entity_set_handle,
03041                              /*in*/ const int requested_entity_type,
03042                              /*in*/ const int requested_entity_topology,
03043                              /*in*/ const int requested_array_size,
03044                              /*in*/ const int resilient,
03045                              /*in*/ const int recursive,
03046                              /*out*/ iBase_EntityArrIterator* entArr_iterator,
03047                              int *err)
03048   {
03049     CHKENUM(requested_entity_type, iBase_EntityType, iBase_INVALID_ENTITY_TYPE);
03050     CHKENUM(requested_entity_topology, iMesh_EntityTopology,
03051             iBase_INVALID_ENTITY_TOPOLOGY);
03052     if (resilient)
03053         ERROR(iBase_NOT_SUPPORTED, "reslient iterators not supported");
03054 
03055     EntityType req_type = mb_topology_table[requested_entity_topology];
03056 
03057     if (requested_entity_topology != iMesh_ALL_TOPOLOGIES) {
03058       if (requested_entity_type != iBase_ALL_TYPES) {
03059         if (requested_entity_topology != iMesh_SEPTAHEDRON &&
03060             requested_entity_type != CN::Dimension(req_type))
03061           ERROR(iBase_BAD_TYPE_AND_TOPO, "type and topology are inconsistant");
03062 
03063           // Special-case handling for septahedra since we don't support them
03064         else if (requested_entity_topology == iMesh_SEPTAHEDRON &&
03065                  requested_entity_type != iBase_REGION)
03066           ERROR(iBase_BAD_TYPE_AND_TOPO, "type and topology are inconsistant");
03067       }
03068     }
03069 
03070     ErrorCode result;
03071     unsigned flags;
03072     result = MOABI->get_meshset_options( ENTITY_HANDLE(entity_set_handle), flags );
03073     CHKERR(result,"Invalid entity set handle");
03074     
03075     if (flags & MESHSET_ORDERED) 
03076       *entArr_iterator = new MBListIter( (iBase_EntityType)requested_entity_type, 
03077                                          (iMesh_EntityTopology)requested_entity_topology, 
03078                                          ENTITY_HANDLE(entity_set_handle), 
03079                                          requested_array_size, recursive );
03080     else
03081       *entArr_iterator = new MBRangeIter( (iBase_EntityType)requested_entity_type, 
03082                                           (iMesh_EntityTopology)requested_entity_topology, 
03083                                           ENTITY_HANDLE(entity_set_handle), 
03084                                           requested_array_size, recursive );
03085     result = (*entArr_iterator)->reset( MOABI );
03086     if (MB_SUCCESS != result)
03087       delete *entArr_iterator;
03088     CHKERR(result, "iMesh_initEntArrIter: ERROR getting entities of proper type or topology." );
03089     RETURN(iBase_SUCCESS);
03090   }
03091 
03092   void iMesh_createTagWithOptions(iMesh_Instance instance,
03093                                   /*in*/ const char* tag_name,
03094                                   /*in*/ const char* tmp_tag_options,
03095                                   /*in*/ const int tag_size,
03096                                   /*in*/ const int tag_type,
03097                                   /*out*/ iBase_TagHandle* tag_handle, 
03098                                   /*out*/ int *err,
03099                                   /*in*/ const int tag_name_len,
03100                                   /*in*/ const int tag_options_len) 
03101   {
03102     if (tag_size < 0)
03103       ERROR(iBase_INVALID_ARGUMENT, "iMesh_createTag: invalid tag size");
03104     CHKENUM(tag_type, iBase_TagValueType, iBase_INVALID_ARGUMENT);
03105 
03106     std::string tmp_tagname(tag_name, tag_name_len);
03107     eatwhitespace(tmp_tagname);
03108 
03109     moab::TagType storage = MB_TAG_SPARSE;
03110     ErrorCode result;
03111 
03112       // declared here 'cuz might have to hold destination of a default value ptr
03113     std::string storage_type;
03114     const void *def_val = NULL;
03115     std::vector<int> def_int;
03116     std::vector<double> def_dbl;
03117     std::vector<moab::EntityHandle> def_handles;
03118     int dum_int;
03119     double dum_dbl;
03120   
03121     if (0 != tag_options_len) {
03122       std::string tag_options = filter_options(tmp_tag_options, tmp_tag_options+tag_options_len);
03123       FileOptions opts(tag_options.c_str());
03124       const char *option_vals[] = {"SPARSE", "DENSE", "BIT", "MESH"};
03125       const moab::TagType opt_types[] = {moab::MB_TAG_SPARSE, moab::MB_TAG_DENSE,
03126                                          moab::MB_TAG_BIT, moab::MB_TAG_MESH};
03127       int opt_num = -1;
03128       result = opts.match_option("TAG_STORAGE_TYPE", option_vals, opt_num);
03129       if (MB_FAILURE == result)
03130         ERROR(result, "iMesh_createTagWithOptions: option string not recognized.");
03131       else if (MB_SUCCESS == result) {
03132         assert(opt_num >= 0 && opt_num <= 3);
03133         storage = opt_types[opt_num];
03134       }
03135 
03136         // now look for default value option; reuse storage_type
03137       storage_type.clear();
03138       result = opts.get_option("TAG_DEFAULT_VALUE", storage_type);
03139       if (MB_SUCCESS == result) {
03140           // ok, need to parse the string into a proper default value
03141         switch (tag_type) {
03142           case iBase_INTEGER:
03143               result = opts.get_int_option("TAG_DEFAULT_VALUE", dum_int);
03144               def_int.resize(tag_size);
03145               std::fill(def_int.begin(), def_int.end(), dum_int);
03146               def_val = &def_int[0];
03147               break;
03148           case iBase_DOUBLE:
03149               result = opts.get_real_option("TAG_DEFAULT_VALUE", dum_dbl);
03150               def_dbl.resize(tag_size);
03151               std::fill(def_dbl.begin(), def_dbl.end(), dum_dbl);
03152               def_val = &def_dbl[0];
03153               break;
03154           case iBase_ENTITY_HANDLE:
03155                 // for default handle, will have to use int
03156               result = opts.get_int_option("TAG_DEFAULT_VALUE", dum_int);
03157               if (0 > dum_int)
03158                 ERROR(result, "iMesh_createTagWithOptions: for default handle-type tag, must use non-negative int on input.");
03159               def_handles.resize(tag_size);
03160               std::fill(def_handles.begin(), def_handles.end(), (moab::EntityHandle)dum_int);
03161               def_val = &def_handles[0];
03162               break;
03163           case iBase_BYTES:
03164               if ((int)storage_type.length() < tag_size) 
03165                 ERROR(result, "iMesh_createTagWithOptions: default value for byte-type tag must be large enough to store tag value.");
03166               def_val = storage_type.c_str();
03167               break;
03168         }
03169       }
03170     }
03171 
03172     moab::Tag new_tag;
03173     result = MOABI->tag_get_handle(tmp_tagname.c_str(), 
03174                                    tag_size,
03175                                    mb_data_type_table[tag_type],
03176                                    new_tag,
03177                                    storage|MB_TAG_EXCL, def_val);
03178 
03179     if (MB_SUCCESS != result) {
03180       std::string msg("iMesh_createTag: ");
03181       if (MB_ALREADY_ALLOCATED == result) {
03182         msg += "Tag already exists with name: \"";
03183         *tag_handle = (iBase_TagHandle) new_tag;
03184       }
03185       else
03186         msg += "Failed to create tag with name: \"";
03187       msg += tag_name;
03188       msg += "\".";
03189       ERROR(result,msg.c_str());
03190     }
03191 
03192     if (tag_type == iBase_ENTITY_HANDLE)
03193       MBIMESHI->note_ent_handle_tag( new_tag );
03194     else if (tag_type == iBase_ENTITY_SET_HANDLE)
03195       MBIMESHI->note_set_handle_tag( new_tag );
03196 
03197     *tag_handle = (iBase_TagHandle) new_tag;
03198 
03199     RETURN(iBase_SUCCESS);
03200 
03201 /* old implementation:
03202    Tag new_tag;
03203    int this_size = tag_size;
03204 
03205    ErrorCode result = MOABI->tag_get_handle(tmp_tagname.c_str(), 
03206    this_size,
03207    mb_data_type_table[tag_type],
03208    new_tag,
03209    MB_TAG_SPARSE|MB_TAG_EXCL);
03210 
03211    if (MB_SUCCESS != result) {
03212    std::string msg("iMesh_createTag: ");
03213    if (MB_ALREADY_ALLOCATED == result) {
03214    msg += "Tag already exists with name: \"";
03215    *tag_handle = (iBase_TagHandle) new_tag;
03216    }
03217    else
03218    msg += "Failed to create tag with name: \"";
03219    msg += tag_name;
03220    msg += "\".";
03221    ERROR(result,msg.c_str());
03222    }
03223 
03224    if (tag_type == iBase_ENTITY_HANDLE)
03225    MBIMESHI->note_ent_handle_tag( new_tag );
03226    else if (tag_type == iBase_ENTITY_SET_HANDLE)
03227    MBIMESHI->note_set_handle_tag( new_tag );
03228 
03229    *tag_handle = (iBase_TagHandle) new_tag;
03230    */
03231   }
03232 
03233 #ifdef __cplusplus
03234 } // extern "C"
03235 #endif
03236 
03237 ErrorCode create_int_ents(MBiMesh* mbimesh,
03238                             Range &from_ents,
03239                             const EntityHandle* in_set)
03240 {
03241   //MBiMesh* mbimesh = dynamic_cast<MBiMesh*>(instance);
03242   assert(mbimesh);
03243   assert(mbimesh->AdjTable[10] || mbimesh->AdjTable[5]);
03244   Range int_ents;
03245   ErrorCode result;
03246   Interface * instance = mbimesh->mbImpl;
03247   if (mbimesh->AdjTable[10]) {
03248     result = instance->get_adjacencies(from_ents, 2, true, int_ents,
03249                                   Interface::UNION);
03250     if (MB_SUCCESS != result) return result;
03251     unsigned int old_size = from_ents.size();
03252     from_ents.merge(int_ents);
03253     if (old_size != from_ents.size() && in_set) {
03254       result = instance->add_entities(*in_set, int_ents);
03255       if (MB_SUCCESS != result) return result;
03256     }
03257   }
03258 
03259   if (mbimesh->AdjTable[5]) {
03260     int_ents.clear();
03261     result = instance->get_adjacencies(from_ents, 1, true, int_ents,
03262                                   Interface::UNION);
03263     if (MB_SUCCESS != result) return result;
03264     unsigned int old_size = from_ents.size();
03265     from_ents.merge(int_ents);
03266     if (old_size != from_ents.size() && in_set) {
03267       result = instance->add_entities(*in_set, int_ents);
03268       if (MB_SUCCESS != result) return result;
03269     }
03270   }
03271 
03272   return MB_SUCCESS;
03273 }
03274 
03275 void eatwhitespace(std::string &this_string)
03276 {
03277   std::string::size_type p = this_string.find_last_not_of(" ");
03278   if (p != this_string.npos)
03279     this_string.resize(p+1);
03280 }
03281 
03282 void iMesh_createStructuredMesh(iMesh_Instance instance,
03283                                 /*in*/ int *local_dims,
03284                                 /*in*/ int *global_dims,
03285                                 /*in*/ double *i_vals,
03286                                 /*in*/ double *j_vals,
03287                                 /*in*/ double *k_vals,
03288                                 /*in*/ int resolve_shared,
03289                                 /*in*/ int ghost_dim,
03290                                 /*in*/ int bridge_dim,
03291                                 /*in*/ int num_layers,
03292                                 /*in*/ int addl_ents,
03293                                 /*in*/ int vert_gids,
03294                                 /*in*/ int elem_gids,
03295                                 /*inout*/ iBase_EntitySetHandle* set_handle, 
03296                                 /*out*/ int *err) 
03297 {
03298   ScdInterface *scdi = NULL;
03299   ErrorCode rval = MOABI->query_interface(scdi);
03300   CHKERR(rval, "Couldn't get structured mesh interface.");
03301   
03302   Range tmp_range;
03303   ScdBox *scd_box;
03304   rval = scdi->construct_box(HomCoord(local_dims[0], local_dims[1], (-1 != local_dims[2] ? local_dims[2] : 0), 1),
03305                              HomCoord(local_dims[3], local_dims[4], (-1 != local_dims[5] ? local_dims[5] : 0), 1),
03306                              NULL, 0, scd_box, NULL, NULL, (vert_gids ? true : false));
03307   CHKERR(rval, "Trouble creating scd vertex sequence.");
03308 
03309     // set the global box parameters
03310   if (global_dims) {
03311     for (int i = 0; i < 6; i++) scd_box->par_data().gDims[i] = global_dims[i];
03312   }
03313 
03314   tmp_range.insert(scd_box->start_vertex(), scd_box->start_vertex()+scd_box->num_vertices()-1);
03315   tmp_range.insert(scd_box->start_element(), scd_box->start_element()+scd_box->num_elements()-1);
03316   tmp_range.insert(scd_box->box_set());
03317 
03318   if (set_handle) {
03319     if (!(*set_handle)) {
03320         // return the new ScdBox's set
03321       *set_handle = reinterpret_cast<iBase_EntitySetHandle>(scd_box->box_set());
03322     }
03323     else{
03324       // add the new ScdBox's set to the given file set
03325       EntityHandle s = scd_box->box_set();
03326       rval = MOABI->add_entities(ENTITY_HANDLE(*set_handle), &s, 1 );
03327       CHKERR(rval, "Couldn't add box set to file set.");
03328     }
03329   }
03330   
03331     // get a ptr to global id memory
03332   void *data;
03333   int count;
03334   Range::const_iterator topv, bote, tope;
03335 
03336   Tag gid_tag = 0;
03337   int *v_gid_data = NULL, *e_gid_data = NULL;
03338   if (vert_gids || elem_gids) {
03339     rval = MOABI->tag_get_handle(GLOBAL_ID_TAG_NAME,
03340                                  1, MB_TYPE_INTEGER,
03341                                  gid_tag,
03342                                  MB_TAG_DENSE|MB_TAG_CREAT);
03343     CHKERR(rval, "Couldn't get GLOBAL_ID tag.");
03344   }
03345   
03346   if (vert_gids) {
03347     topv = tmp_range.upper_bound(tmp_range.begin(), tmp_range.end(),
03348                                  scd_box->start_vertex() + scd_box->num_vertices());
03349 
03350     rval = MOABI->tag_iterate(gid_tag, tmp_range.begin(), topv, count, data);
03351     CHKERR(rval, "Failed to get tag iterator.");
03352     assert(count == scd_box->num_vertices());
03353     v_gid_data = (int*)data;
03354   }
03355   
03356   if (elem_gids) {
03357     bote = tmp_range.lower_bound(tmp_range.begin(), tmp_range.end(),
03358                                  scd_box->start_element());
03359     tope = tmp_range.upper_bound(tmp_range.begin(), tmp_range.end(),
03360                                  *bote + scd_box->num_elements());
03361 
03362     rval = MOABI->tag_iterate(gid_tag, bote, tope, count, data);
03363     CHKERR(rval, "Failed to get tag iterator.");
03364     assert(count == scd_box->num_elements());
03365     e_gid_data = (int*)data;
03366   }
03367   
03368   if (i_vals || j_vals || k_vals || v_gid_data || e_gid_data) {
03369     
03370       // set the vertex coordinates
03371     double *xc, *yc, *zc;
03372     rval = scd_box->get_coordinate_arrays(xc, yc, zc);
03373     CHKERR(rval, "Couldn't get vertex coordinate arrays.");
03374 
03375     int i, j, k, il, jl, kl;
03376     int dil = local_dims[3] - local_dims[0] + 1;
03377     int djl = local_dims[4] - local_dims[1] + 1;
03378     int di = (global_dims ? global_dims[3] - global_dims[0] + 1 : dil);
03379     int dj = (global_dims ? global_dims[4] - global_dims[1] + 1 : djl);
03380     for (kl = local_dims[2]; kl <= local_dims[5]; kl++) {
03381       k = kl - local_dims[2];
03382       for (jl = local_dims[1]; jl <= local_dims[4]; jl++) {
03383         j = jl - local_dims[1];
03384         for (il = local_dims[0]; il <= local_dims[3]; il++) {
03385           i = il - local_dims[0];
03386           unsigned int pos = i + j*dil + k*dil*djl;
03387           xc[pos] = (i_vals ? i_vals[i] : -1.0);
03388           yc[pos] = (j_vals ? j_vals[j] : -1.0);
03389           zc[pos] = (-1 == local_dims[2] ? 0.0 : (k_vals ? k_vals[k] : -1.0));
03390           if (v_gid_data) {
03391             *v_gid_data = (-1 != kl ? kl*di*dj : 0) + jl*di + il + 1;
03392             v_gid_data++;
03393           }
03394           if (e_gid_data && kl < local_dims[5] && jl < local_dims[4] && il < local_dims[3]) {
03395             *e_gid_data = (-1 != kl ? kl*(di-1)*(dj-1) : 0) + jl*(di-1) + il + 1;
03396             e_gid_data++;
03397           }
03398         }
03399       }
03400     }
03401   }
03402 
03403 #ifdef USE_MPI  
03404     // do parallel stuff, if requested
03405   if (resolve_shared) {
03406     ParallelComm *pcomm = ParallelComm::get_pcomm(MOABI, 0);
03407     if (pcomm) {
03408 
03409       rval = pcomm->resolve_shared_ents(0, MOABI->dimension_from_handle(scd_box->start_element()), 0, &gid_tag);
03410       CHKERR(rval, "Trouble resolving shared vertices.");
03411     
03412       if (-1 != ghost_dim) {
03413         rval = pcomm->exchange_ghost_cells(ghost_dim, bridge_dim, num_layers, addl_ents, true);
03414         CHKERR(rval, "Trouble exchanging ghosts.");
03415       }
03416     }    
03417   }
03418 #else
03419     // empty statement to remove compiler warning
03420   if (resolve_shared || ghost_dim || bridge_dim || num_layers || addl_ents) {}
03421 #endif
03422   
03423   RETURN(iBase_SUCCESS);
03424 }
03425 
03426 void iMesh_freeMemory(
03427     iMesh_Instance /*instance*/,
03429          void ** ptrToMem)
03430 {
03431   free(*ptrToMem);
03432   *ptrToMem=0;
03433   return;
03434 }
03435 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines