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