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