![]() |
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
00008 #include
00009 #include
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