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