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