MOAB: Mesh Oriented datABase  (version 5.2.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, void** array_ptr, int& array_allocated_space, int& array_size,
00123                        int count, int val_size, int* err )
00124         : arrayPtr( 0 )
00125     {
00126         if( !array_allocated_space || !*array_ptr )
00127         {
00128             *array_ptr            = std::malloc( val_size * count );
00129             array_allocated_space = array_size = count;
00130             if( !*array_ptr ) { ERROR( iBase_MEMORY_ALLOCATION_FAILED, "Couldn't allocate array." ); }
00131             arrayPtr = array_ptr;
00132         }
00133         else
00134         {
00135             array_size = count;
00136             if( array_allocated_space < count )
00137             { ERROR( iBase_BAD_ARRAY_SIZE, "Allocated array not large enough to hold returned contents." ); }
00138         }
00139         RETURN( iBase_SUCCESS );
00140     }
00141 
00142     ~iMeshArrayManager()
00143     {
00144         if( arrayPtr )
00145         {
00146             std::free( *arrayPtr );
00147             *arrayPtr = 0;
00148         }
00149     }
00150 
00151     void keep_array()
00152     {
00153         arrayPtr = 0;
00154     }
00155 };
00156 
00157 inline int compare_no_case( const char* str1, const char* str2, size_t n )
00158 {
00159     for( size_t i = 1; i != n && *str1 && toupper( *str1 ) == toupper( *str2 ); ++i, ++str1, ++str2 )
00160         ;
00161     return toupper( *str2 ) - toupper( *str1 );
00162 }
00163 
00164 // Filter out non-MOAB options and remove the "moab:" prefix
00165 inline std::string filter_options( const char* begin, const char* end )
00166 {
00167     const char* opt_begin = begin;
00168     const char* opt_end   = begin;
00169 
00170     std::string filtered;
00171     bool first = true;
00172 
00173     while( opt_end != end )
00174     {
00175         opt_end = std::find( opt_begin, end, ' ' );
00176 
00177         if( opt_end - opt_begin >= 5 && compare_no_case( opt_begin, "moab:", 5 ) == 0 )
00178         {
00179             if( !first ) filtered.push_back( ';' );
00180             first = false;
00181             filtered.append( opt_begin + 5, opt_end );
00182         }
00183 
00184         opt_begin = opt_end + 1;
00185     }
00186     return filtered;
00187 }
00188 
00189 #endif  // IMESH_MOAB_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines