moab
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   { 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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines