MOAB: Mesh Oriented datABase  (version 5.5.0)
iMesh_MOAB.hpp
Go to the documentation of this file.
1 #ifndef IMESH_MOAB_HPP
2 #define IMESH_MOAB_HPP
3 
4 #include "iMesh.h"
5 #include "MBiMesh.hpp"
6 #include "moab/Forward.hpp"
7 #include <cstring>
8 #include <cstdlib>
9 #include <cstdio>
10 
11 using namespace moab;
12 
13 /* map from MB's entity type to TSTT's entity topology */
15 
16 /* map from MB's entity type to TSTT's entity type */
18 
19 /* map to MB's entity type from TSTT's entity topology */
20 extern const EntityType mb_topology_table[MBMAXTYPE + 1];
21 
22 /* map from TSTT's tag types to MOAB's */
24 
25 /* map from MOAB's tag types to tstt's */
26 extern const iBase_TagValueType tstt_data_type_table[MB_MAX_DATA_TYPE + 1];
27 
28 /* map from MOAB's ErrorCode to tstt's */
29 extern "C" const iBase_ErrorType iBase_ERROR_MAP[MB_FAILURE + 1];
30 
31 #include "MBiMesh.hpp"
32 
33 static inline bool iMesh_isError( int code )
34 {
35  return ( iBase_SUCCESS != code );
36 }
37 static inline bool iMesh_isError( ErrorCode code )
38 {
39  return ( MB_SUCCESS != code );
40 }
41 
42 #define PP_CAT_( a, b ) a##b
43 #define PP_CAT( a, b ) PP_CAT_( a, b )
44 
45 #define RETURN( CODE ) \
46  do \
47  { \
48  *err = MBIMESHI->set_last_error( ( CODE ), "" ); \
49  return; \
50  } while( false )
51 
52 #define ERROR( CODE, MSG ) \
53  do \
54  { \
55  *err = MBIMESHI->set_last_error( ( CODE ), ( MSG ) ); \
56  return; \
57  } while( false )
58 
59 #define CHKERR( CODE, MSG ) \
60  do \
61  { \
62  if( iMesh_isError( ( CODE ) ) ) ERROR( ( CODE ), ( MSG ) ); \
63  } while( false )
64 
65 #define CHKENUM( VAL, TYPE, ERR ) \
66  do \
67  { \
68  if( ( VAL ) < PP_CAT( TYPE, _MIN ) || ( VAL ) > PP_CAT( TYPE, _MAX ) ) \
69  ERROR( ( ERR ), "Invalid enumeration value" ); \
70  } while( false )
71 
72 // Ensure that a tag's data type matches the expected data type (entity handle
73 // and entity set handle tags are compatible with one another).
74 #define CHKTAGTYPE( TAG, TYPE ) \
75  do \
76  { \
77  int type, result; \
78  iMesh_getTagType( instance, ( TAG ), &type, &result ); \
79  CHKERR( result, "Couldn't get tag data type" ); \
80  if( ( type == iBase_ENTITY_HANDLE && ( TYPE ) == iBase_ENTITY_SET_HANDLE ) || \
81  ( type == iBase_ENTITY_SET_HANDLE && ( TYPE ) == iBase_ENTITY_HANDLE ) ) \
82  break; \
83  if( type != ( TYPE ) ) ERROR( iBase_INVALID_TAG_HANDLE, "Invalid tag data type" ); \
84  } while( false )
85 
86 #define CHKNONEMPTY() \
87  do \
88  { \
89  int count, result; \
90  iMesh_getNumOfType( instance, 0, iBase_ALL_TYPES, &count, &result ); \
91  CHKERR( result, "Couldn't get number of entities" ); \
92  if( count == 0 ) ERROR( iBase_INVALID_ENTITY_HANDLE, "Invalid entity handle: mesh is empty" ); \
93  } while( false )
94 
95 // Check the array size, and allocate the array if necessary.
96 // Free the array upon leaving scope unless KEEP_ARRAY
97 // is invoked.
98 #define ALLOC_CHECK_ARRAY( array, this_size ) \
99  iMeshArrayManager array##_manager( instance, reinterpret_cast< void** >( array ), *( array##_allocated ), \
100  *( array##_size ), this_size, sizeof( **( array ) ), err ); \
101  if( iBase_SUCCESS != *err ) return
102 
103 #define ALLOC_CHECK_TAG_ARRAY( array, this_size ) \
104  iMeshArrayManager array##_manager( instance, reinterpret_cast< void** >( array ), *( array##_allocated ), \
105  *( array##_size ), this_size, 1, err ); \
106  if( iBase_SUCCESS != *err ) return
107 
108 #define KEEP_ARRAY( array ) array##_manager.keep_array()
109 
110 // Check the array size, and allocate the array if necessary.
111 // Do NOT free the array upon leaving scope.
112 #define ALLOC_CHECK_ARRAY_NOFAIL( array, this_size ) \
113  ALLOC_CHECK_ARRAY( array, this_size ); \
114  KEEP_ARRAY( array )
115 
116 // Implement RAII pattern for allocated arrays
118 {
119  void** arrayPtr;
120 
121  public:
123  void** array_ptr,
124  int& array_allocated_space,
125  int& array_size,
126  int count,
127  int val_size,
128  int* err )
129  : arrayPtr( 0 )
130  {
131  if( !array_allocated_space || !*array_ptr )
132  {
133  *array_ptr = std::malloc( val_size * count );
134  array_allocated_space = array_size = count;
135  if( !*array_ptr )
136  {
137  ERROR( iBase_MEMORY_ALLOCATION_FAILED, "Couldn't allocate array." );
138  }
139  arrayPtr = array_ptr;
140  }
141  else
142  {
143  array_size = count;
144  if( array_allocated_space < count )
145  {
146  ERROR( iBase_BAD_ARRAY_SIZE, "Allocated array not large enough to hold returned contents." );
147  }
148  }
150  }
151 
153  {
154  if( arrayPtr )
155  {
156  std::free( *arrayPtr );
157  *arrayPtr = 0;
158  }
159  }
160 
161  void keep_array()
162  {
163  arrayPtr = 0;
164  }
165 };
166 
167 inline int compare_no_case( const char* str1, const char* str2, size_t n )
168 {
169  for( size_t i = 1; i != n && *str1 && toupper( *str1 ) == toupper( *str2 ); ++i, ++str1, ++str2 )
170  ;
171  return toupper( *str2 ) - toupper( *str1 );
172 }
173 
174 // Filter out non-MOAB options and remove the "moab:" prefix
175 inline std::string filter_options( const char* begin, const char* end )
176 {
177  const char* opt_begin = begin;
178  const char* opt_end = begin;
179 
180  std::string filtered;
181  bool first = true;
182 
183  while( opt_end != end )
184  {
185  opt_end = std::find( opt_begin, end, ' ' );
186 
187  if( opt_end - opt_begin >= 5 && compare_no_case( opt_begin, "moab:", 5 ) == 0 )
188  {
189  if( !first ) filtered.push_back( ';' );
190  first = false;
191  filtered.append( opt_begin + 5, opt_end );
192  }
193 
194  opt_begin = opt_end + 1;
195  }
196  return filtered;
197 }
198 
199 #endif // IMESH_MOAB_HPP