MOAB: Mesh Oriented datABase
(version 5.3.1)
|
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 }