Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
00001 #ifndef IMESH_MOAB_HPP 00002 #define IMESH_MOAB_HPP 00003 00004 #include "iMesh.h" 00005 #include "MBiMesh.hpp" 00006 #include "moab/Forward.hpp" 00007 #include <cstring> 00008 #include <cstdlib> 00009 #include <cstdio> 00010 00011 using namespace moab; 00012 00013 /* map from MB's entity type to TSTT's entity topology */ 00014 extern const iMesh_EntityTopology tstt_topology_table[MBMAXTYPE + 1]; 00015 00016 /* map from MB's entity type to TSTT's entity type */ 00017 extern const iBase_EntityType tstt_type_table[MBMAXTYPE + 1]; 00018 00019 /* map to MB's entity type from TSTT's entity topology */ 00020 extern const EntityType mb_topology_table[MBMAXTYPE + 1]; 00021 00022 /* map from TSTT's tag types to MOAB's */ 00023 extern const DataType mb_data_type_table[iBase_TagValueType_MAX + 1]; 00024 00025 /* map from MOAB's tag types to tstt's */ 00026 extern const iBase_TagValueType tstt_data_type_table[MB_MAX_DATA_TYPE + 1]; 00027 00028 /* map from MOAB's ErrorCode to tstt's */ 00029 extern "C" const iBase_ErrorType iBase_ERROR_MAP[MB_FAILURE + 1]; 00030 00031 #include "MBiMesh.hpp" 00032 00033 static inline bool iMesh_isError( int code ) 00034 { 00035 return ( iBase_SUCCESS != code ); 00036 } 00037 static inline bool iMesh_isError( ErrorCode code ) 00038 { 00039 return ( MB_SUCCESS != code ); 00040 } 00041 00042 #define PP_CAT_( a, b ) a##b 00043 #define PP_CAT( a, b ) PP_CAT_( a, b ) 00044 00045 #define RETURN( CODE ) \ 00046 do \ 00047 { \ 00048 *err = MBIMESHI->set_last_error( ( CODE ), "" ); \ 00049 return; \ 00050 } while( false ) 00051 00052 #define ERROR( CODE, MSG ) \ 00053 do \ 00054 { \ 00055 *err = MBIMESHI->set_last_error( ( CODE ), ( MSG ) ); \ 00056 return; \ 00057 } while( false ) 00058 00059 #define CHKERR( CODE, MSG ) \ 00060 do \ 00061 { \ 00062 if( iMesh_isError( ( CODE ) ) ) ERROR( ( CODE ), ( MSG ) ); \ 00063 } while( false ) 00064 00065 #define CHKENUM( VAL, TYPE, ERR ) \ 00066 do \ 00067 { \ 00068 if( ( VAL ) < PP_CAT( TYPE, _MIN ) || ( VAL ) > PP_CAT( TYPE, _MAX ) ) \ 00069 ERROR( ( ERR ), "Invalid enumeration value" ); \ 00070 } while( false ) 00071 00072 // Ensure that a tag's data type matches the expected data type (entity handle 00073 // and entity set handle tags are compatible with one another). 00074 #define CHKTAGTYPE( TAG, TYPE ) \ 00075 do \ 00076 { \ 00077 int type, result; \ 00078 iMesh_getTagType( instance, ( TAG ), &type, &result ); \ 00079 CHKERR( result, "Couldn't get tag data type" ); \ 00080 if( ( type == iBase_ENTITY_HANDLE && ( TYPE ) == iBase_ENTITY_SET_HANDLE ) || \ 00081 ( type == iBase_ENTITY_SET_HANDLE && ( TYPE ) == iBase_ENTITY_HANDLE ) ) \ 00082 break; \ 00083 if( type != ( TYPE ) ) ERROR( iBase_INVALID_TAG_HANDLE, "Invalid tag data type" ); \ 00084 } while( false ) 00085 00086 #define CHKNONEMPTY() \ 00087 do \ 00088 { \ 00089 int count, result; \ 00090 iMesh_getNumOfType( instance, 0, iBase_ALL_TYPES, &count, &result ); \ 00091 CHKERR( result, "Couldn't get number of entities" ); \ 00092 if( count == 0 ) ERROR( iBase_INVALID_ENTITY_HANDLE, "Invalid entity handle: mesh is empty" ); \ 00093 } while( false ) 00094 00095 // Check the array size, and allocate the array if necessary. 00096 // Free the array upon leaving scope unless KEEP_ARRAY 00097 // is invoked. 00098 #define ALLOC_CHECK_ARRAY( array, this_size ) \ 00099 iMeshArrayManager array##_manager( instance, reinterpret_cast< void** >( array ), *( array##_allocated ), \ 00100 *( array##_size ), this_size, sizeof( **( array ) ), err ); \ 00101 if( iBase_SUCCESS != *err ) return 00102 00103 #define ALLOC_CHECK_TAG_ARRAY( array, this_size ) \ 00104 iMeshArrayManager array##_manager( instance, reinterpret_cast< void** >( array ), *( array##_allocated ), \ 00105 *( array##_size ), this_size, 1, err ); \ 00106 if( iBase_SUCCESS != *err ) return 00107 00108 #define KEEP_ARRAY( array ) array##_manager.keep_array() 00109 00110 // Check the array size, and allocate the array if necessary. 00111 // Do NOT free the array upon leaving scope. 00112 #define ALLOC_CHECK_ARRAY_NOFAIL( array, this_size ) \ 00113 ALLOC_CHECK_ARRAY( array, this_size ); \ 00114 KEEP_ARRAY( array ) 00115 00116 // Implement RAII pattern for allocated arrays 00117 class iMeshArrayManager 00118 { 00119 void** arrayPtr; 00120 00121 public: 00122 iMeshArrayManager( iMesh_Instance instance, 00123 void** array_ptr, 00124 int& array_allocated_space, 00125 int& array_size, 00126 int count, 00127 int val_size, 00128 int* err ) 00129 : arrayPtr( 0 ) 00130 { 00131 if( !array_allocated_space || !*array_ptr ) 00132 { 00133 *array_ptr = std::malloc( val_size * count ); 00134 array_allocated_space = array_size = count; 00135 if( !*array_ptr ) 00136 { 00137 ERROR( iBase_MEMORY_ALLOCATION_FAILED, "Couldn't allocate array." ); 00138 } 00139 arrayPtr = array_ptr; 00140 } 00141 else 00142 { 00143 array_size = count; 00144 if( array_allocated_space < count ) 00145 { 00146 ERROR( iBase_BAD_ARRAY_SIZE, "Allocated array not large enough to hold returned contents." ); 00147 } 00148 } 00149 RETURN( iBase_SUCCESS ); 00150 } 00151 00152 ~iMeshArrayManager() 00153 { 00154 if( arrayPtr ) 00155 { 00156 std::free( *arrayPtr ); 00157 *arrayPtr = 0; 00158 } 00159 } 00160 00161 void keep_array() 00162 { 00163 arrayPtr = 0; 00164 } 00165 }; 00166 00167 inline int compare_no_case( const char* str1, const char* str2, size_t n ) 00168 { 00169 for( size_t i = 1; i != n && *str1 && toupper( *str1 ) == toupper( *str2 ); ++i, ++str1, ++str2 ) 00170 ; 00171 return toupper( *str2 ) - toupper( *str1 ); 00172 } 00173 00174 // Filter out non-MOAB options and remove the "moab:" prefix 00175 inline std::string filter_options( const char* begin, const char* end ) 00176 { 00177 const char* opt_begin = begin; 00178 const char* opt_end = begin; 00179 00180 std::string filtered; 00181 bool first = true; 00182 00183 while( opt_end != end ) 00184 { 00185 opt_end = std::find( opt_begin, end, ' ' ); 00186 00187 if( opt_end - opt_begin >= 5 && compare_no_case( opt_begin, "moab:", 5 ) == 0 ) 00188 { 00189 if( !first ) filtered.push_back( ';' ); 00190 first = false; 00191 filtered.append( opt_begin + 5, opt_end ); 00192 } 00193 00194 opt_begin = opt_end + 1; 00195 } 00196 return filtered; 00197 } 00198 00199 #endif // IMESH_MOAB_HPP