FaceNeighborAACubeTreeStrategy.h
Go to the documentation of this file.
1#ifndef GfxTL__FACENEIGHBORAACUBETREESTRATEGY_HEADER__
2#define GfxTL__FACENEIGHBORAACUBETREESTRATEGY_HEADER__
3
4namespace GfxTL
5{
6
7 // requires that InheritedStrategyT supports StrategyBase::CellParent() and CellType::Center()
8 template <class InheritedStrategyT>
10 {
11 typedef typename InheritedStrategyT::value_type value_type;
12
13 class CellData : public InheritedStrategyT::CellData
14 {
15 };
16
17 template <class BaseT>
18 class StrategyBase : public InheritedStrategyT::template StrategyBase<BaseT>
19 {
20 public:
21 typedef typename InheritedStrategyT::template StrategyBase<BaseT> BaseType;
22 typedef typename BaseType::CellType CellType;
23
24 enum
25 {
26 Dim = CellType::Dim
27 };
28
29 // returns the face neighbor along axis in direction (0 = left, 1 = right)
30 // returns in level the level of the neighbor relative to the input cell (upwards)
31 // returns NULL if the cell is on the boundary
32 // This function does not return all face neighbors in the given direction
33 // in the case that the neighbors live on a deeper level than the input cell.
34 // In such a case the face neighbor on the same level as the input cell is
35 // return. All face neighbors on that side are children of the returned cell.
36 const CellType*
38 unsigned int axis,
39 unsigned int dir,
40 size_t* level) const
41 {
42 const CellType* parent = BaseType::CellParent(cell);
43 if (!parent)
44 {
45 return NULL; // root cell does not have any face neighbors
46 }
47 unsigned int childRelation = CellChildRelation(cell, *parent);
48 // check if face neighbor is another child of parent
49 // this is the case if dir is opposite to the childRelation
50 if (((childRelation >> (Dim - 1 - axis)) & 1) ^ (dir & 1)) // cell on opposite side?
51 {
52 unsigned int faceNeighborRelation =
53 childRelation ^ (1 << (Dim - 1 - axis)); // flip the respective bit
54 if (BaseType::ExistChild(*parent, faceNeighborRelation))
55 {
56 *level = 0;
57 return &(*parent)[faceNeighborRelation];
58 }
59 *level = 1;
60 return parent; // degenerate case -> cell does not have an actual face neighbor
61 }
62 // otherwise the face neighbor is a neighbor of the parent
63 size_t l;
64 const CellType* n = CellFaceNeighbor(*parent, axis, dir, &l);
65 if (!n)
66 {
67 return NULL;
68 }
69 if (l >
70 0) // if the face neighbor of the parent does not live on the same level as the parent
71 // we are unable to find any deeper face neighbor
72 {
73 *level = l + 1;
74 return n;
75 }
76 // otherwise try to find the child of n that is our face neighbor
77 // our face neighbor is the child that has the opposite side than us on axis
78 unsigned int faceNeighborRelation =
79 childRelation ^ (1 << (Dim - 1 - axis)); // flip the respective bit
80 if (BaseType::ExistChild(*n, faceNeighborRelation))
81 {
82 *level = 0;
83 return &(*n)[faceNeighborRelation];
84 }
85 *level = 1;
86 return n;
87 }
88
89 // non-const version
91 CellFaceNeighbor(CellType& cell, unsigned int axis, unsigned int dir, size_t* level)
92 {
93 return const_cast<CellType*>(CellFaceNeighbor(cell, axis, dir, level));
94 }
95
96 unsigned int
97 CellChildRelation(const CellType& cell, const CellType& parent) const
98 {
99 unsigned int childRelation = 0;
100 for (unsigned int i = 0; i < Dim; ++i)
101 {
102 if (cell.Center()[i] > parent.Center()[i])
103 {
104 childRelation |= 1 << (Dim - 1 - i);
105 }
106 }
107 return childRelation;
108 }
109 };
110 };
111
112}; // namespace GfxTL
113
114#endif
const CellType * CellFaceNeighbor(const CellType &cell, unsigned int axis, unsigned int dir, size_t *level) const
InheritedStrategyT::template StrategyBase< BaseT > BaseType
unsigned int CellChildRelation(const CellType &cell, const CellType &parent) const
CellType * CellFaceNeighbor(CellType &cell, unsigned int axis, unsigned int dir, size_t *level)
Definition AABox.h:10