AACubeTree.hpp
Go to the documentation of this file.
1namespace GfxTL
2{
3
4 //-- AACubeCell
5
6 template <class Point, class Base>
7 AACubeCell<Point, Base>::AACubeCell() : _parent(NULL)
8 {
9 memset(_children, 0, sizeof(_children));
10 }
11
12 template <class Point, class Base>
13 AACubeCell<Point, Base>::AACubeCell(ThisType* parent, const CubeType& cube) :
14 _parent(parent), _cube(cube)
15 {
16 memset(_children, 0, sizeof(_children));
17 }
18
19 template <class Point, class Base>
20 AACubeCell<Point, Base>::~AACubeCell()
21 {
22 for (int i = 0; i < NChildren; ++i)
23 {
24 if (_children[i])
25 {
26 delete _children[i];
27 }
28 }
29 }
30
31 template <class Point, class Base>
32 const AACubeCell<Point, Base>*
33 AACubeCell<Point, Base>::operator[](unsigned int index) const
34 {
35 return _children[index];
36 }
37
38 template <class Point, class Base>
39 AACubeCell<Point, Base>*
40 AACubeCell<Point, Base>::operator[](unsigned int index)
41 {
42 return _children[index];
43 }
44
45 template <class Point, class Base>
46 void
47 AACubeCell<Point, Base>::Child(unsigned int index, ThisType* child)
48 {
49 _children[index] = child;
50 }
51
52 template <class Point, class Base>
53 typename AACubeCell<Point, Base>::CubeType&
54 AACubeCell<Point, Base>::Cube()
55 {
56 return _cube;
57 }
58
59 template <class Point, class Base>
60 const typename AACubeCell<Point, Base>::CubeType&
61 AACubeCell<Point, Base>::Cube() const
62 {
63 return _cube;
64 }
65
66 template <class Point, class Base>
67 AACubeCell<Point, Base>*
68 AACubeCell<Point, Base>::Parent()
69 {
70 return _parent;
71 }
72
73 template <class Point, class Base>
74 const AACubeCell<Point, Base>*
75 AACubeCell<Point, Base>::Parent() const
76 {
77 return _parent;
78 }
79
80 template <class Point, class Base>
81 void
82 AACubeCell<Point, Base>::Parent(ThisType* parent)
83 {
84 _parent = parent;
85 }
86
87 template <class Point, class Base>
88 AACubeCell<Point, Base>*
89 AACubeCell<Point, Base>::FaceNeighborIndexed(unsigned int index, unsigned int* level)
90 {
91 int axis = index >> 1;
92 ++axis;
93 if (index & 1)
94 {
95 axis = -axis;
96 }
97 return FaceNeighbor(axis, level);
98 }
99
100 template <class Point, class Base>
101 const AACubeCell<Point, Base>*
102 AACubeCell<Point, Base>::FaceNeighborIndexed(unsigned int index, unsigned int* level) const
103 {
104 int axis = index >> 1;
105 ++axis;
106 if (index & 1)
107 {
108 axis = -axis;
109 }
110 return FaceNeighbor(axis, level);
111 }
112
113 template <class Point, class Base>
114 AACubeCell<Point, Base>*
115 AACubeCell<Point, Base>::FaceNeighbor(int axis, unsigned int* level)
116 {
117 int box = SubBox();
118 if (box < 0)
119 {
120 return NULL;
121 }
122 int a = axis;
123 if (a > 0)
124 {
125 a -= 1;
126 if (box & (1 << a))
127 {
128 return (*_parent)[box & ~(1 << a)];
129 }
130 }
131 if (a < 0)
132 {
133 a = (-a) - 1;
134 if (!(box & (1 << a)))
135 {
136 return (*_parent)[box | (1 << a)];
137 }
138 }
139 unsigned int l = *level;
140 ++(*level);
141 ThisType* c = _parent->FaceNeighbor(axis, level);
142 if (!c)
143 {
144 return NULL;
145 }
146 int invBox = box;
147 if (invBox & (1 << a))
148 {
149 invBox &= ~(1 << a);
150 }
151 else
152 {
153 invBox |= 1 << a;
154 }
155 if (*level == l + 1 && (*c)[invBox])
156 {
157 --(*level);
158 c = (*c)[invBox];
159 }
160 return c;
161 }
162
163 template <class Point, class Base>
164 const AACubeCell<Point, Base>*
165 AACubeCell<Point, Base>::FaceNeighbor(int axis, unsigned int* level) const
166 {
167 return const_cast<ThisType*>(this)->FaceNeighbor(axis, level);
168 }
169
170 template <class Point, class Base>
171 int
172 AACubeCell<Point, Base>::SubBox() const
173 {
174 unsigned int box;
175 if (!_parent)
176 {
177 return -1;
178 }
179 if (!(_parent->Cube().IsSubCube(&box, Cube())))
180 {
181 assert(false);
182 return -1;
183 }
184 return (int)box;
185 }
186
187 //-- AACubeTree
188
189 template <class Strategies>
190 void
191 AACubeTree<Strategies>::Clear()
192 {
193 StrategyBaseType::Clear();
194 _cellCount = 0;
195 }
196
197 template <class Strategies>
198 void
199 AACubeTree<Strategies>::Build()
200 {
201 AABox<PointType> bbox;
202 BoundingVolume(&bbox);
204 bbox.Center(&center);
205 ScalarType w = (bbox.Max() - bbox.Min()).Length();
206 PointType bbl;
207 for (unsigned int i = 0; i < PointType::Dim; ++i)
208 {
209 bbl[i] = center[i] - (w / 2);
210 }
211 CubeType bc(bbl, w);
212 /*CubeType bc;
213 BoundingCube(&bc);*/
214 CubeType cc(bc[CubeType::NCorners - 1] * (ScalarType)1.2, bc.Width() * (ScalarType)1.2);
215 Build(cc);
216 }
217
218 template <class Strategies>
219 void
220 AACubeTree<Strategies>::Build(const CubeType& bc)
221 {
222 Clear();
223
224 std::queue<CellType*>* q;
225 std::queue<CellType*>* qq;
226 std::queue<CellType*> q1, q2, level;
227
228 CellType* c = new CellType(NULL, bc);
229 RootCellData(bc, c); // implemented by TreeData
230 q1.push(c);
231 Root(c); // implemented by BaseTree
232 InitCellData(c); // implemented by Strategies
233 q = &q1;
234 qq = &q2;
235
236 do
237 {
238 while (q->size())
239 {
240 c = q->front();
241 level.push(c);
242 q->pop();
243 //InitCellData(c); // implemented by Strategies
244 if (ShouldSubdivide(*c)) // implemented by Strategies
245 {
246 Subdivide(c);
247 for (int i = 0; i < CellType::NChildren; ++i)
248 {
249 qq->push((*c)[i]);
250 }
251 _cellCount += CellType::NChildren;
252 }
253 }
254 std::queue<CellType*>* qqq = q;
255 q = qq;
256 qq = qqq;
257
258 while (level.size())
259 {
260 c = level.front();
261 level.pop();
262 InitLevelDependentCellData(c); // implemented by Strategies
263 }
264 } while (q->size());
265 }
266
267 template <class Strategies>
268 void
269 AACubeTree<Strategies>::Subdivide(CellType* cell)
270 {
271 Subdivide(cell, 0, 0, cell);
272 for (unsigned int i = 0; i < CellType::NChildren; ++i)
273 {
274 InitCellData((*cell)[i]); // implemented by Strategies
275 }
276 }
277
278 template <class Strategies>
279 void
280 AACubeTree<Strategies>::RefreshWithNewTreeData(const CubeType& bc)
281 {
282 // iterate over all cells and readjust cell data
283 CellType* c = Root();
284 if (!c)
285 {
286 return;
287 }
288 RootCellData(c->Cube(), c);
289 std::list<CellType*> stack;
290 stack.push_back(c);
291 while (stack.size())
292 {
293 c = stack.back();
294 stack.pop_back();
295 if (!IsLeaf(c))
296 {
297 ReadjustChildrenData(c, 0, 0, c);
298 for (unsigned int i = 0; i < CellType::NChildren; ++i)
299 {
300 stack.push_back((*c)[i]);
301 }
302 }
303 }
304 StrategyBaseType::RefreshWithNewTreeData(bc);
305 }
306
307 template <class Strategies>
308 void
309 AACubeTree<Strategies>::ReadjustChildrenData(CellType* cell,
310 unsigned int axis,
311 unsigned int box,
312 CellType* data)
313 {
314 if (axis == Dim)
315 {
316 (*cell)[box]->Data(*data);
317 }
318 else
319 {
320 ScalarType s;
321 cell->Cube().DividingPlane(axis, &s);
322 CellType left, right;
323 SplitAlongAxis(*data, axis, s, &left, &right); // implemented by TreeData
324
325 ReadjustChildrenData(cell, axis + 1, box | (1 << axis), &left);
326 ReadjustChildrenData(cell, axis + 1, box & (~(1 << axis)), &right);
327 }
328 }
329
330 template <class Strategies>
331 void
332 AACubeTree<Strategies>::Subdivide(CellType* cell,
333 unsigned int axis,
334 unsigned int box,
335 CellType* data)
336 {
337 if (axis == Dim)
338 {
339 CellType* child = new CellType;
340 child->Data(*data);
341 child->Parent(cell);
342 child->Cube() = CubeType(box, cell->Cube());
343 cell->Child(box, child);
344 }
345 else
346 {
347 ScalarType s;
348 cell->Cube().DividingPlane(axis, &s);
349 CellType left, right;
350 SplitAlongAxis(*data, axis, s, &left, &right); // implemented by TreeData
351
352 Subdivide(cell, axis + 1, box | (1 << axis), &left);
353 Subdivide(cell, axis + 1, box & (~(1 << axis)), &right);
354 }
355 }
356
357}; // namespace GfxTL
uint8_t data[1]
uint8_t index
constexpr T c
#define q
Definition AABox.h:10
double s(double t, double s0, double v0, double a0, double j)
Definition CtrlUtil.h:33
double a(double t, double a0, double j)
Definition CtrlUtil.h:45