MOAB: Mesh Oriented datABase  (version 5.4.1)
iMesh_MOAB.hpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines