1
15
16 #ifndef SCD_ELEMENT_DATA_HPP
17 #define SCD_ELEMENT_DATA_HPP
18
19
20
21
22
23
24
25
26
27
28
29
30 #include "SequenceData.hpp"
31 #include "moab/HomXform.hpp"
32 #include "moab/CN.hpp"
33 #include "ScdVertexData.hpp"
34 #include "Internals.hpp"
35 #include "moab/Range.hpp"
36
37 #include <vector>
38 #include <algorithm>
39
40 namespace moab
41 {
42
43 class ScdElementData : public SequenceData
44 {
45
46
47 class VertexDataRef
48 {
49 private:
50 HomCoord minmax[2];
51 HomXform xform, invXform;
52 ScdVertexData* srcSeq;
53
54 public:
55 friend class ScdElementData;
56
57 VertexDataRef( const HomCoord& min, const HomCoord& max, const HomXform& tmp_xform, ScdVertexData* this_seq );
58
59 bool contains( const HomCoord& coords ) const;
60 };
61
62 private:
63
64
65 HomCoord boxParams[3];
66
67
68
69 int dIJK[3];
70
71
72
73 int dIJKm1[3];
74
75
76 int isPeriodic[2];
77
78
79 ScdElementData();
80
81
82 std::vector< VertexDataRef > vertexSeqRefs;
83
84 public:
85
86 ScdElementData( EntityHandle start_handle,
87 const int imin,
88 const int jmin,
89 const int kmin,
90 const int imax,
91 const int jmax,
92 const int kmax,
93 int* is_periodic );
94
95 virtual ~ScdElementData();
96
97
98 inline EntityHandle get_vertex( const HomCoord& coords ) const;
99 inline EntityHandle get_vertex( int i, int j, int k ) const
100 {
101 return get_vertex( HomCoord( i, j, k ) );
102 }
103
104
105 EntityHandle get_element( const int i, const int j, const int k ) const;
106
107
108 const HomCoord& min_params() const;
109
110
111 const HomCoord& max_params() const;
112
113
114 void param_extents( int& di, int& dj, int& dk ) const;
115
116
117 ErrorCode get_params( const EntityHandle ehandle, int& i, int& j, int& k ) const;
118
119
120 inline int is_periodic_i() const
121 {
122 return isPeriodic[0];
123 };
124
125
126 inline int is_periodic_j() const
127 {
128 return isPeriodic[1];
129 };
130
131 inline void is_periodic( int is_p[2] ) const
132 {
133 is_p[0] = isPeriodic[0];
134 is_p[1] = isPeriodic[1];
135 }
136
137
138 int i_min() const
139 {
140 return ( boxParams[0].hom_coord() )[0];
141 }
142 int j_min() const
143 {
144 return ( boxParams[0].hom_coord() )[1];
145 }
146 int k_min() const
147 {
148 return ( boxParams[0].hom_coord() )[2];
149 }
150 int i_max() const
151 {
152 return ( boxParams[1].hom_coord() )[0];
153 }
154 int j_max() const
155 {
156 return ( boxParams[1].hom_coord() )[1];
157 }
158 int k_max() const
159 {
160 return ( boxParams[1].hom_coord() )[2];
161 }
162
163
164
165 bool boundary_complete() const;
166
167
168 inline bool contains( const HomCoord& coords ) const;
169
170
171 inline bool contains_vertex( const HomCoord& coords ) const;
172
173
174 inline ErrorCode get_params_connectivity( const int i,
175 const int j,
176 const int k,
177 std::vector< EntityHandle >& connectivity ) const;
178
179
180
181
182
183
184 ErrorCode add_vsequence( ScdVertexData* vseq,
185 const HomCoord& p1,
186 const HomCoord& q1,
187 const HomCoord& p2,
188 const HomCoord& q2,
189 const HomCoord& p3,
190 const HomCoord& q3,
191 bool bb_input = false,
192 const HomCoord& bb_min = HomCoord::unitv[0],
193 const HomCoord& bb_max = HomCoord::unitv[0] );
194
195 SequenceData* subset( EntityHandle start,
196 EntityHandle end,
197 const int* sequence_data_sizes,
198 const int* tag_data_sizes ) const;
199
200 static EntityID calc_num_entities( EntityHandle start_handle,
201 int irange,
202 int jrange,
203 int krange,
204 int* is_periodic = NULL );
205
206 unsigned long get_memory_use() const;
207 };
208
209 inline EntityHandle ScdElementData::get_element( const int i, const int j, const int k ) const
210 {
211 return start_handle() + ( i - i_min() ) + ( j - j_min() ) * dIJKm1[0] + ( k - k_min() ) * dIJKm1[0] * dIJKm1[1];
212 }
213
214 inline const HomCoord& ScdElementData::min_params() const
215 {
216 return boxParams[0];
217 }
218
219 inline const HomCoord& ScdElementData::max_params() const
220 {
221 return boxParams[1];
222 }
223
224
225 inline void ScdElementData::param_extents( int& di, int& dj, int& dk ) const
226 {
227 di = dIJK[0];
228 dj = dIJK[1];
229 dk = dIJK[2];
230 }
231
232 inline ErrorCode ScdElementData::get_params( const EntityHandle ehandle, int& i, int& j, int& k ) const
233 {
234 if( TYPE_FROM_HANDLE( ehandle ) != TYPE_FROM_HANDLE( start_handle() ) ) return MB_FAILURE;
235
236 int hdiff = ehandle - start_handle();
237
238
239
240 k = ( dIJKm1[1] > 0 ? hdiff / ( dIJKm1[1] > 0 ? dIJKm1[0] * dIJKm1[1] : 1 ) : 0 );
241 j = ( hdiff - ( k * dIJKm1[0] * dIJKm1[1] ) ) / dIJKm1[0];
242 i = hdiff % dIJKm1[0];
243
244 k += boxParams[0].k();
245 j += boxParams[0].j();
246 i += boxParams[0].i();
247
248 return ( ehandle >= start_handle() && ehandle < start_handle() + size() && i >= i_min() && i <= i_max() &&
249 j >= j_min() && j <= j_max() && k >= k_min() && k <= k_max() )
250 ? MB_SUCCESS
251 : MB_FAILURE;
252 }
253
254 inline bool ScdElementData::contains( const HomCoord& temp ) const
255 {
256
257
258 return ( ( dIJKm1[0] && temp.i() >= boxParams[0].i() && temp.i() < boxParams[0].i() + dIJKm1[0] ) &&
259 ( ( !dIJKm1[1] && temp.j() == boxParams[1].j() ) ||
260 ( dIJKm1[1] && temp.j() >= boxParams[0].j() && temp.j() < boxParams[0].j() + dIJKm1[1] ) ) &&
261 ( ( !dIJKm1[2] && temp.k() == boxParams[1].k() ) ||
262 ( dIJKm1[2] && temp.k() >= boxParams[0].k() && temp.k() < boxParams[0].k() + dIJKm1[2] ) ) );
263 }
264
265 inline bool ScdElementData::contains_vertex( const HomCoord& temp ) const
266 {
267
268
269 return ( ( dIJK[0] && temp.i() >= boxParams[0].i() && temp.i() < boxParams[0].i() + dIJK[0] ) &&
270 ( ( !dIJK[1] && temp.j() == boxParams[1].j() ) ||
271 ( dIJK[1] && temp.j() >= boxParams[0].j() && temp.j() < boxParams[0].j() + dIJK[1] ) ) &&
272 ( ( !dIJK[2] && temp.k() == boxParams[1].k() ) ||
273 ( dIJK[2] && temp.k() >= boxParams[0].k() && temp.k() < boxParams[0].k() + dIJK[2] ) ) );
274 }
275
276 inline bool ScdElementData::VertexDataRef::contains( const HomCoord& coords ) const
277 {
278 return ( minmax[0] <= coords && minmax[1] >= coords );
279 }
280
281 inline ScdElementData::VertexDataRef::VertexDataRef( const HomCoord& this_min,
282 const HomCoord& this_max,
283 const HomXform& tmp_xform,
284 ScdVertexData* this_seq )
285 : xform( tmp_xform ), invXform( tmp_xform.inverse() ), srcSeq( this_seq )
286 {
287 minmax[0] = HomCoord( this_min );
288 minmax[1] = HomCoord( this_max );
289 }
290
291 inline EntityHandle ScdElementData::get_vertex( const HomCoord& coords ) const
292 {
293 assert( boundary_complete() );
294 for( std::vector< VertexDataRef >::const_iterator it = vertexSeqRefs.begin(); it != vertexSeqRefs.end(); ++it )
295 {
296 if( ( *it ).minmax[0] <= coords && ( *it ).minmax[1] >= coords )
297 {
298
299 HomCoord local_coords = coords / ( *it ).xform;
300
301 assert( ( *it ).srcSeq->contains( local_coords ) );
302
303
304 return ( *it ).srcSeq->get_vertex( local_coords );
305 }
306 }
307
308
309 return 0;
310 }
311
312 inline ErrorCode ScdElementData::add_vsequence( ScdVertexData* vseq,
313 const HomCoord& p1,
314 const HomCoord& q1,
315 const HomCoord& p2,
316 const HomCoord& q2,
317 const HomCoord& p3,
318 const HomCoord& q3,
319 bool bb_input,
320 const HomCoord& bb_min,
321 const HomCoord& bb_max )
322 {
323
324
325 HomXform M;
326 M.three_pt_xform( p1, q1, p2, q2, p3, q3 );
327
328
329
330
331 HomCoord minmax[2];
332 if( bb_input )
333 {
334 minmax[0] = bb_min;
335 minmax[1] = bb_max;
336 }
337 else
338 {
339 minmax[0] = vseq->min_params() * M;
340 minmax[1] = vseq->max_params() * M;
341 }
342
343
344 for( std::vector< VertexDataRef >::const_iterator vsit = vertexSeqRefs.begin(); vsit != vertexSeqRefs.end();
345 ++vsit )
346 if( ( *vsit ).contains( minmax[0] ) || ( *vsit ).contains( minmax[1] ) ) return MB_FAILURE;
347
348 HomCoord tmp_min( std::min( minmax[0].i(), minmax[1].i() ), std::min( minmax[0].j(), minmax[1].j() ),
349 std::min( minmax[0].k(), minmax[1].k() ) );
350 HomCoord tmp_max( std::max( minmax[0].i(), minmax[1].i() ), std::max( minmax[0].j(), minmax[1].j() ),
351 std::max( minmax[0].k(), minmax[1].k() ) );
352
353
354 VertexDataRef tmp_seq_ref( tmp_min, tmp_max, M, vseq );
355
356
357 vertexSeqRefs.push_back( tmp_seq_ref );
358
359 return MB_SUCCESS;
360 }
361
362 inline ErrorCode ScdElementData::get_params_connectivity( const int i,
363 const int j,
364 const int k,
365 std::vector< EntityHandle >& connectivity ) const
366 {
367 if( contains( HomCoord( i, j, k ) ) == false ) return MB_FAILURE;
368
369 int ip1 = ( isPeriodic[0] ? ( i + 1 ) % dIJKm1[0] : i + 1 ),
370 jp1 = ( isPeriodic[1] ? ( j + 1 ) % dIJKm1[1] : j + 1 );
371
372 connectivity.push_back( get_vertex( i, j, k ) );
373 connectivity.push_back( get_vertex( ip1, j, k ) );
374 if( CN::Dimension( TYPE_FROM_HANDLE( start_handle() ) ) < 2 ) return MB_SUCCESS;
375 connectivity.push_back( get_vertex( ip1, jp1, k ) );
376 connectivity.push_back( get_vertex( i, jp1, k ) );
377 if( CN::Dimension( TYPE_FROM_HANDLE( start_handle() ) ) < 3 ) return MB_SUCCESS;
378 connectivity.push_back( get_vertex( i, j, k + 1 ) );
379 connectivity.push_back( get_vertex( ip1, j, k + 1 ) );
380 connectivity.push_back( get_vertex( ip1, jp1, k + 1 ) );
381 connectivity.push_back( get_vertex( i, jp1, k + 1 ) );
382 return MB_SUCCESS;
383 }
384
385 }
386
387 #endif