Branch data Line data Source code
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 */
14 : : extern const iMesh_EntityTopology tstt_topology_table[MBMAXTYPE + 1];
15 : :
16 : : /* map from MB's entity type to TSTT's entity type */
17 : : extern const iBase_EntityType tstt_type_table[MBMAXTYPE + 1];
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 */
23 : : extern const DataType mb_data_type_table[iBase_TagValueType_MAX + 1];
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 : 239 : static inline bool iMesh_isError( int code )
34 : : {
35 : 239 : return ( iBase_SUCCESS != code );
36 : : }
37 : 3103 : static inline bool iMesh_isError( ErrorCode code )
38 : : {
39 : 3103 : 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
117 : : class iMeshArrayManager
118 : : {
119 : : void** arrayPtr;
120 : :
121 : : public:
122 : 56947 : iMeshArrayManager( iMesh_Instance instance, void** array_ptr, int& array_allocated_space, int& array_size,
123 : : int count, int val_size, int* err )
124 : 56947 : : arrayPtr( 0 )
125 : : {
126 [ + + ][ + + ]: 56947 : if( !array_allocated_space || !*array_ptr )
127 : : {
128 : 321 : *array_ptr = std::malloc( val_size * count );
129 : 321 : array_allocated_space = array_size = count;
130 [ - + ]: 321 : if( !*array_ptr ) { ERROR( iBase_MEMORY_ALLOCATION_FAILED, "Couldn't allocate array." ); }
131 : 321 : arrayPtr = array_ptr;
132 : : }
133 : : else
134 : : {
135 : 56626 : array_size = count;
136 [ + + ]: 56626 : if( array_allocated_space < count )
137 : 2 : { ERROR( iBase_BAD_ARRAY_SIZE, "Allocated array not large enough to hold returned contents." ); }
138 : : }
139 : 56945 : RETURN( iBase_SUCCESS );
140 : : }
141 : :
142 : 56947 : ~iMeshArrayManager()
143 : : {
144 [ - + ]: 56947 : if( arrayPtr )
145 : : {
146 : 0 : std::free( *arrayPtr );
147 : 0 : *arrayPtr = 0;
148 : : }
149 : 56947 : }
150 : :
151 : 56939 : void keep_array()
152 : : {
153 : 56939 : arrayPtr = 0;
154 : 56939 : }
155 : : };
156 : :
157 : 100 : inline int compare_no_case( const char* str1, const char* str2, size_t n )
158 : : {
159 [ + + ][ + - ]: 500 : for( size_t i = 1; i != n && *str1 && toupper( *str1 ) == toupper( *str2 ); ++i, ++str1, ++str2 )
[ + - ]
160 : : ;
161 : 100 : return toupper( *str2 ) - toupper( *str1 );
162 : : }
163 : :
164 : : // Filter out non-MOAB options and remove the "moab:" prefix
165 : 102 : inline std::string filter_options( const char* begin, const char* end )
166 : : {
167 : 102 : const char* opt_begin = begin;
168 : 102 : const char* opt_end = begin;
169 : :
170 : 102 : std::string filtered;
171 : 102 : bool first = true;
172 : :
173 [ + + ]: 204 : while( opt_end != end )
174 : : {
175 [ + - ]: 102 : opt_end = std::find( opt_begin, end, ' ' );
176 : :
177 [ + + ][ + - ]: 102 : if( opt_end - opt_begin >= 5 && compare_no_case( opt_begin, "moab:", 5 ) == 0 )
[ + - ][ + + ]
178 : : {
179 [ + + ][ + - ]: 100 : if( !first ) filtered.push_back( ';' );
180 : 100 : first = false;
181 [ + - ]: 100 : filtered.append( opt_begin + 5, opt_end );
182 : : }
183 : :
184 : 102 : opt_begin = opt_end + 1;
185 : : }
186 : 102 : return filtered;
187 : : }
188 : :
189 : : #endif // IMESH_MOAB_HPP
|