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