moab
|
00001 00016 #ifndef SWEPT_ELEMENT_DATA_HPP 00017 #define SWEPT_ELEMENT_DATA_HPP 00018 00019 // 00020 // Class: SweptElementData 00021 // 00022 // Purpose: represent a rectangular element of mesh 00023 // 00024 // A SweptElement represents a rectangular element of mesh, including both vertices and 00025 // elements, and the parametric space used to address that element. Vertex data, 00026 // i.e. coordinates, may not be stored directly in the element, but the element returns 00027 // information about the vertex handles of vertices in the element. Vertex and element 00028 // handles associated with the element are each contiguous. 00029 00030 #include "SequenceData.hpp" 00031 #include "moab/HomXform.hpp" 00032 #include "moab/CN.hpp" 00033 #include "SweptVertexData.hpp" 00034 #include "Internals.hpp" 00035 #include "moab/Range.hpp" 00036 00037 #include <vector> 00038 #include <algorithm> 00039 00040 namespace moab { 00041 00042 class SweptElementData : public SequenceData 00043 { 00044 00046 class VertexDataRef 00047 { 00048 private: 00049 HomCoord minmax[2]; 00050 HomXform xform, invXform; 00051 SweptVertexData *srcSeq; 00052 public: 00053 friend class SweptElementData; 00054 00055 VertexDataRef(const HomCoord &min, const HomCoord &max, 00056 const HomXform &tmp_xform, SweptVertexData *this_seq); 00057 00058 bool contains(const HomCoord &coords) const; 00059 }; 00060 00061 private: 00062 00064 HomCoord elementParams[3]; 00065 00068 int dIJK[3]; 00069 00072 int dIJKm1[3]; 00073 00075 SweptElementData(); 00076 00078 std::vector<VertexDataRef> vertexSeqRefs; 00079 00080 public: 00081 00083 SweptElementData( EntityHandle start_handle, 00084 const int imin, const int jmin, const int kmin, 00085 const int imax, const int jmax, const int kmax, 00086 const int* Cq ); 00087 00088 virtual ~SweptElementData(); 00089 00091 inline EntityHandle get_vertex(const HomCoord &coords) const; 00092 inline EntityHandle get_vertex(int i, int j, int k) const 00093 { return get_vertex(HomCoord(i,j,k)); } 00094 00096 EntityHandle get_element(const int i, const int j, const int k) const; 00097 00099 const HomCoord &min_params() const; 00100 00102 const HomCoord &max_params() const; 00103 00105 void param_extents(int &di, int &dj, int &dk) const; 00106 00108 ErrorCode get_params(const EntityHandle ehandle, 00109 int &i, int &j, int &k) const; 00110 00112 int i_min() const {return (elementParams[0].hom_coord())[0];} 00113 int j_min() const {return (elementParams[0].hom_coord())[1];} 00114 int k_min() const {return (elementParams[0].hom_coord())[2];} 00115 int i_max() const {return (elementParams[1].hom_coord())[0];} 00116 int j_max() const {return (elementParams[1].hom_coord())[1];} 00117 int k_max() const {return (elementParams[1].hom_coord())[2];} 00118 00121 bool boundary_complete() const; 00122 00124 inline bool contains(const HomCoord &coords) const; 00125 00127 inline ErrorCode get_params_connectivity(const int i, const int j, const int k, 00128 std::vector<EntityHandle>& connectivity) const; 00129 00135 ErrorCode add_vsequence(SweptVertexData *vseq, 00136 const HomCoord &p1, const HomCoord &q1, 00137 const HomCoord &p2, const HomCoord &q2, 00138 const HomCoord &p3, const HomCoord &q3, 00139 bool bb_input = false, 00140 const HomCoord &bb_min = HomCoord::unitv[0], 00141 const HomCoord &bb_max = HomCoord::unitv[0]); 00142 00143 00144 SequenceData* subset( EntityHandle start, 00145 EntityHandle end, 00146 const int* sequence_data_sizes, 00147 const int* tag_data_sizes ) const; 00148 00149 static EntityID calc_num_entities( EntityHandle start_handle, 00150 int irange, 00151 int jrange, 00152 int krange ); 00153 00154 unsigned long get_memory_use() const; 00155 }; 00156 00157 inline EntityHandle SweptElementData::get_element(const int i, const int j, const int k) const 00158 { 00159 return start_handle() + (i-i_min()) + (j-j_min())*dIJKm1[0] + (k-k_min())*dIJKm1[0]*dIJKm1[1]; 00160 } 00161 00162 inline const HomCoord &SweptElementData::min_params() const 00163 { 00164 return elementParams[0]; 00165 } 00166 00167 inline const HomCoord &SweptElementData::max_params() const 00168 { 00169 return elementParams[1]; 00170 } 00171 00173 inline void SweptElementData::param_extents(int &di, int &dj, int &dk) const 00174 { 00175 di = dIJK[0]; 00176 dj = dIJK[1]; 00177 dk = dIJK[2]; 00178 } 00179 00180 inline ErrorCode SweptElementData::get_params(const EntityHandle ehandle, 00181 int &i, int &j, int &k) const 00182 { 00183 if (TYPE_FROM_HANDLE(ehandle) != TYPE_FROM_HANDLE(start_handle())) return MB_FAILURE; 00184 00185 int hdiff = ehandle - start_handle(); 00186 00187 // use double ?: test below because on some platforms, both sides of the : are 00188 // evaluated, and if dIJKm1[1] is zero, that'll generate a divide-by-zero 00189 k = (dIJKm1[1] > 0 ? hdiff / (dIJKm1[1] > 0 ? dIJKm1[0]*dIJKm1[1] : 1) : 0); 00190 j = (hdiff - (k*dIJKm1[0]*dIJKm1[1])) / dIJKm1[0]; 00191 i = hdiff % dIJKm1[0]; 00192 00193 k += elementParams[0].k(); 00194 j += elementParams[0].j(); 00195 i += elementParams[0].i(); 00196 00197 return (ehandle >= start_handle() && 00198 ehandle < start_handle()+size() && 00199 i >= i_min() && i <= i_max() && 00200 j >= j_min() && j <= j_max() && 00201 k >= k_min() && k <= k_max()) ? MB_SUCCESS : MB_FAILURE; 00202 } 00203 00204 inline bool SweptElementData::contains(const HomCoord &temp) const 00205 { 00206 // upper bound is < instead of <= because element params max is one less 00207 // than vertex params max 00208 return (temp >= elementParams[0] && temp < elementParams[1]); 00209 } 00210 00211 inline bool SweptElementData::VertexDataRef::contains(const HomCoord &coords) const 00212 { 00213 return (minmax[0] <= coords && minmax[1] >= coords); 00214 } 00215 00216 inline SweptElementData::VertexDataRef::VertexDataRef(const HomCoord &this_min, const HomCoord &this_max, 00217 const HomXform &tmp_xform, SweptVertexData *this_seq) 00218 : xform(tmp_xform), invXform(tmp_xform.inverse()), srcSeq(this_seq) 00219 { 00220 minmax[0] = HomCoord(this_min); 00221 minmax[1] = HomCoord(this_max); 00222 } 00223 00224 inline EntityHandle SweptElementData::get_vertex(const HomCoord &coords) const 00225 { 00226 assert(boundary_complete()); 00227 for (std::vector<VertexDataRef>::const_iterator it = vertexSeqRefs.begin(); 00228 it != vertexSeqRefs.end(); it++) { 00229 if ((*it).minmax[0] <= coords && (*it).minmax[1] >= coords) { 00230 // first get the vertex block-local parameters 00231 HomCoord local_coords = coords / (*it).xform; 00232 00233 // now get the vertex handle for those coords 00234 return (*it).srcSeq->get_vertex(local_coords); 00235 } 00236 } 00237 00238 // got here, it's an error 00239 return 0; 00240 } 00241 00242 inline ErrorCode SweptElementData::add_vsequence(SweptVertexData *vseq, 00243 const HomCoord &p1, const HomCoord &q1, 00244 const HomCoord &p2, const HomCoord &q2, 00245 const HomCoord &p3, const HomCoord &q3, 00246 bool bb_input, 00247 const HomCoord &bb_min, 00248 const HomCoord &bb_max) 00249 { 00250 // compute the transform given the vseq-local parameters and the mapping to 00251 // this element sequence's parameters passed in minmax 00252 HomXform M; 00253 M.three_pt_xform(p1, q1, p2, q2, p3, q3); 00254 00255 // min and max in element seq's parameter system may not be same as those in 00256 // vseq's system, so need to take min/max 00257 00258 HomCoord minmax[2]; 00259 if (bb_input) { 00260 minmax[0] = bb_min; 00261 minmax[1] = bb_max; 00262 } 00263 else { 00264 minmax[0] = vseq->min_params() * M; 00265 minmax[1] = vseq->max_params() * M; 00266 } 00267 00268 // check against other vseq's to make sure they don't overlap 00269 for (std::vector<VertexDataRef>::const_iterator vsit = vertexSeqRefs.begin(); 00270 vsit != vertexSeqRefs.end(); vsit++) 00271 if ((*vsit).contains(minmax[0]) || (*vsit).contains(minmax[1])) 00272 return MB_FAILURE; 00273 00274 HomCoord tmp_min(std::min(minmax[0].i(), minmax[1].i()), 00275 std::min(minmax[0].j(), minmax[1].j()), 00276 std::min(minmax[0].k(), minmax[1].k())); 00277 HomCoord tmp_max(std::max(minmax[0].i(), minmax[1].i()), 00278 std::max(minmax[0].j(), minmax[1].j()), 00279 std::max(minmax[0].k(), minmax[1].k())); 00280 00281 00282 // set up a new vertex sequence reference 00283 VertexDataRef tmp_seq_ref(tmp_min, tmp_max, M, vseq); 00284 00285 // add to the list 00286 vertexSeqRefs.push_back(tmp_seq_ref); 00287 00288 return MB_SUCCESS; 00289 } 00290 00291 inline ErrorCode SweptElementData::get_params_connectivity(const int i, const int j, const int k, 00292 std::vector<EntityHandle>& connectivity) const 00293 { 00294 if (contains(HomCoord(i, j, k)) == false) return MB_FAILURE; 00295 00296 connectivity.push_back(get_vertex(i, j, k)); 00297 connectivity.push_back(get_vertex(i+1, j, k)); 00298 if (CN::Dimension(TYPE_FROM_HANDLE(start_handle())) < 2) return MB_SUCCESS; 00299 connectivity.push_back(get_vertex(i+1, j+1, k)); 00300 connectivity.push_back(get_vertex(i, j+1, k)); 00301 if (CN::Dimension(TYPE_FROM_HANDLE(start_handle())) < 3) return MB_SUCCESS; 00302 connectivity.push_back(get_vertex(i, j, k+1)); 00303 connectivity.push_back(get_vertex(i+1, j, k+1)); 00304 connectivity.push_back(get_vertex(i+1, j+1, k+1)); 00305 connectivity.push_back(get_vertex(i, j+1, k+1)); 00306 return MB_SUCCESS; 00307 } 00308 00309 } // namespace moab 00310 00311 #endif