moab
|
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 { return (iBase_SUCCESS != code); } 00035 static inline bool iMesh_isError(ErrorCode code) 00036 { return (MB_SUCCESS != code); } 00037 00038 #define PP_CAT_(a,b) a ## b 00039 #define PP_CAT(a,b) PP_CAT_(a,b) 00040 00041 #define RETURN(CODE) \ 00042 do { \ 00043 *err = MBIMESHI->set_last_error((CODE), ""); \ 00044 return; \ 00045 } while(false) 00046 00047 #define ERROR(CODE,MSG) \ 00048 do { \ 00049 *err = MBIMESHI->set_last_error((CODE), (MSG)); \ 00050 return; \ 00051 } while(false) 00052 00053 #define CHKERR(CODE,MSG) \ 00054 do { \ 00055 if (iMesh_isError((CODE))) \ 00056 ERROR((CODE),(MSG)); \ 00057 } while(false) 00058 00059 #define CHKENUM(VAL,TYPE,ERR) \ 00060 do { \ 00061 if ((VAL) < PP_CAT(TYPE, _MIN) || (VAL) > PP_CAT(TYPE, _MAX)) \ 00062 ERROR((ERR), "Invalid enumeration value"); \ 00063 } while(false) 00064 00065 // Ensure that a tag's data type matches the expected data type (entity handle 00066 // and entity set handle tags are compatible with one another). 00067 #define CHKTAGTYPE(TAG,TYPE) \ 00068 do { \ 00069 int type, result; \ 00070 iMesh_getTagType(instance, (TAG), &type, &result); \ 00071 CHKERR(result, "Couldn't get tag data type"); \ 00072 if ((type == iBase_ENTITY_HANDLE && \ 00073 (TYPE) == iBase_ENTITY_SET_HANDLE) || \ 00074 (type == iBase_ENTITY_SET_HANDLE && \ 00075 (TYPE) == iBase_ENTITY_HANDLE)) \ 00076 break; \ 00077 if (type != (TYPE)) \ 00078 ERROR(iBase_INVALID_TAG_HANDLE, "Invalid tag data type"); \ 00079 } while(false) 00080 00081 #define CHKNONEMPTY() \ 00082 do { \ 00083 int count, result; \ 00084 iMesh_getNumOfType(instance, 0, iBase_ALL_TYPES, &count, &result); \ 00085 CHKERR(result, "Couldn't get number of entities"); \ 00086 if (count == 0) \ 00087 ERROR(iBase_INVALID_ENTITY_HANDLE, \ 00088 "Invalid entity handle: mesh is empty"); \ 00089 } while(false) 00090 00091 // Check the array size, and allocate the array if necessary. 00092 // Free the array upon leaving scope unless KEEP_ARRAY 00093 // is invoked. 00094 #define ALLOC_CHECK_ARRAY(array, this_size) \ 00095 iMeshArrayManager array ## _manager ( instance, reinterpret_cast<void**>(array), *(array ## _allocated), *(array ## _size), this_size, sizeof(**array), err ); \ 00096 if (iBase_SUCCESS != *err) return 00097 00098 #define ALLOC_CHECK_TAG_ARRAY(array, this_size) \ 00099 iMeshArrayManager array ## _manager ( instance, reinterpret_cast<void**>(array), *(array ## _allocated), *(array ## _size), this_size, 1, err ); \ 00100 if (iBase_SUCCESS != *err) return 00101 00102 #define KEEP_ARRAY(array) \ 00103 array ## _manager .keep_array() 00104 00105 // Check the array size, and allocate the array if necessary. 00106 // Do NOT free the array upon leaving scope. 00107 #define ALLOC_CHECK_ARRAY_NOFAIL(array, this_size) \ 00108 ALLOC_CHECK_ARRAY(array, this_size); KEEP_ARRAY(array) 00109 00110 00111 // Implement RAII pattern for allocated arrays 00112 class iMeshArrayManager 00113 { 00114 void** arrayPtr; 00115 00116 public: 00117 00118 00119 iMeshArrayManager( iMesh_Instance instance, 00120 void** array_ptr, 00121 int& array_allocated_space, 00122 int& array_size, 00123 int count, 00124 int val_size, 00125 int* err ) : arrayPtr(0) 00126 { 00127 if (!array_allocated_space || !*array_ptr) { 00128 *array_ptr = std::malloc(val_size * count); 00129 array_allocated_space = array_size = count; 00130 if (!*array_ptr) { 00131 ERROR(iBase_MEMORY_ALLOCATION_FAILED, "Couldn't allocate array."); 00132 } 00133 arrayPtr = array_ptr; 00134 } 00135 else { 00136 array_size = count; 00137 if (array_allocated_space < count) { 00138 ERROR(iBase_BAD_ARRAY_SIZE, 00139 "Allocated array not large enough to hold returned contents."); 00140 } 00141 } 00142 RETURN(iBase_SUCCESS); 00143 } 00144 00145 ~iMeshArrayManager() 00146 { 00147 if (arrayPtr) { 00148 std::free(*arrayPtr); 00149 *arrayPtr = 0; 00150 } 00151 } 00152 00153 void keep_array() 00154 { arrayPtr = 0; } 00155 }; 00156 00157 inline int compare_no_case(const char *str1, const char *str2, size_t n) { 00158 for (size_t i = 1; i != n && *str1 && toupper(*str1) == toupper(*str2); 00159 ++i, ++str1, ++str2); 00160 return toupper(*str2) - toupper(*str1); 00161 } 00162 00163 // Filter out non-MOAB options and remove the "moab:" prefix 00164 inline std::string filter_options(const char *begin, const char *end) 00165 { 00166 const char *opt_begin = begin; 00167 const char *opt_end = begin; 00168 00169 std::string filtered; 00170 bool first = true; 00171 00172 while (opt_end != end) { 00173 opt_end = std::find(opt_begin, end, ' '); 00174 00175 if (opt_end-opt_begin >= 5 && compare_no_case(opt_begin, "moab:", 5) == 0) { 00176 if (!first) 00177 filtered.push_back(';'); 00178 first = false; 00179 filtered.append(opt_begin+5, opt_end); 00180 } 00181 00182 opt_begin = opt_end+1; 00183 } 00184 return filtered; 00185 } 00186 00187 #endif // IMESH_MOAB_HPP