source: GTP/trunk/Lib/Vis/Preprocessing/src/havran/ktb8b.h @ 2582

Revision 2582, 12.1 KB checked in by bittner, 17 years ago (diff)

Havran Ray Caster compiles and links, but still does not work

Line 
1// ===================================================================
2// $Id: $
3//
4// ktb.h
5//      definition of classes for CKTB tree building up and traversal
6//
7// Class: CKTBNodeAbstract, SKTBNode, CKTBAllocMan, CKTBNodeIterator
8//
9// REPLACEMENT_STRING
10//
11// Copyright by Vlastimil Havran, 2007 - email to "vhavran AT seznam.cz"
12// Initial coding by Vlasta Havran, February 2007
13
14#ifndef __KTB8B_H__
15#define __KTB8B_H__
16
17// GOLEM headers
18#include "configh.h"
19#include "AxisAlignedBox3.h"
20#include "Intersectable.h"
21#include "Containers.h"
22#include "allocgo2.h"
23#include "ktbconf.h"
24#include "sbbox.h"
25#include "Ray.h"
26
27// standard headers
28#include <vector>
29
30
31namespace GtpVisibilityPreprocessor {
32
33// Forward declarations
34
35// Use 8 Bytes representation
36#undef  SKTBNodeT
37#define SKTBNodeT CKTB8BNodeAbstract::SKTBNode
38
39//===============================================
40// Representation of one node of CKTB
41class CKTB8BNodeAbstract
42{
43public:
44  // maximal height of the CKTB tree
45  enum { MAX_HEIGHT = 32, MaskForOffset = 0xFFFFFFF8 };
46
47  // the basic element of CKTB tree .. node of tree
48  // it must be accessible by more classes
49
50  // but must be declared because of compilation
51  struct SKTBNode {
52    // SKTBNode *left; // pointer to the left child is implict in DFS order
53    union {
54      // here is the compressed version of the axis
55      unsigned char *pointer;
56      unsigned int offset;
57      int depth;
58    };
59    union {
60      float splitPlane; // the position of splitting plane
61      ObjectContainer *objlist; // object list for a leaf or tagged interior node
62      Intersectable *object; // the pointer to the object, if only one object
63      SBBox     *encbox; // enclosing bounding box for this node
64      SBBox     *minbox; // minimum bounding box for this node
65      SKTBNodeT *linkedNode; // the linked node
66      SKTBNodeT *parentBoxNode; // the pointer to the same node type
67    };
68
69    bool IsLeaf() const {
70      return ( CKTBAxes::Axes(offset & CKTBAxes::EE_Mask) == CKTBAxes::EE_Leaf);
71    }
72    bool IsEmptyLeaf() const {
73      return (this == 0);
74    }
75  }; // struct SKTBNode
76
77public:
78
79  // It was _KTB_R2
80  // default constructor
81  CKTB8BNodeAbstract() { }
82  // default destructor
83  ~CKTB8BNodeAbstract() {}
84
85  bool IsEmptyLeaf_(const SKTBNodeT *p) const {
86    assert(( CKTBAxes::Axes(p->offset & CKTBAxes::EE_Mask) == CKTBAxes::EE_Leaf));
87    return (p->objlist == NULL);
88  }
89
90  bool IsFullLeaf_(const SKTBNodeT *p) const {
91    return (( CKTBAxes::Axes(p->offset & CKTBAxes::EE_Mask) == CKTBAxes::EE_Leaf) &&
92            (p->objlist != NULL));
93  }
94 
95  bool IsLeaf_(const SKTBNodeT *p) const
96  { return ( CKTBAxes::Axes(p->offset & CKTBAxes::EE_Mask) == CKTBAxes::EE_Leaf); }
97 
98  bool HasMinBox_(const SKTBNodeT *p) const
99  { return (CKTBAxes::Axes(p->offset & CKTBAxes::EE_Mask) >= CKTBAxes::EE_X_axisBox); }
100
101  // ------------------------------------------------------
102  // Common functions for iterator and allocator
103
104  float GetSplitValue(const SKTBNodeT *nodep) const {
105    return nodep->splitPlane;
106  }
107 
108  CKTBAxes::Axes GetNodeType(const SKTBNodeT *nodep) const {
109    return (CKTBAxes::Axes)(nodep->offset & 0x7);
110  }
111  SKTBNodeT* GetLeft(const SKTBNode *nodep) const {
112    return (SKTBNodeT*)(nodep+1); // We assume linking in DFS order
113  }
114  SKTBNodeT* GetRight(const SKTBNodeT *nodep) const {
115    // We assume 8-Bytes aligned nodes in memory in 32-Bits environment
116    // This has to be checked during node linking.
117    return (SKTBNodeT*)(nodep->offset & MaskForOffset);
118  }
119
120  SKTBNodeT* GetLinkNode(const SKTBNodeT *nodep) const {
121    // We assume 8-Bytes aligned nodes in memory in 32-Bits environment
122    // This has to be checked during node linking.
123    return (SKTBNodeT*)(nodep->linkedNode);
124  }
125  // We assume linking in DFS order, this is for EncBox
126  SKTBNodeT* GetLeftLong(const SKTBNodeT *nodep) const {
127    return (SKTBNodeT*)(((char*)nodep) + 4*sizeof(SKTBNode));
128  }
129  SKTBNode* GetParentBoxNode(const SKTBNode *nodep) const {
130    return (SKTBNode*)(nodep+1)->parentBoxNode;
131  }
132 
133#ifdef _SHORT_FORM_MINBOX
134  SKTBNode* GetLeftMinBox(const SKTBNode *nodep) const {
135    return (SKTBNode*)(nodep+2);
136  }
137  int GetDepth(const SKTBNode * /*nodep*/) const {
138    return 0; // depth was not stored
139  }
140#else
141  SKTBNode* GetLeftMinBox(const SKTBNode *nodep) const {
142    return (SKTBNode*)(((char*)nodep) + 5*sizeof(SKTBNode));
143  } 
144  int GetDepth(const SKTBNode *nodep) const {
145    return (int)((nodep+1)->depth);
146  }
147#endif // _SHORT_FORM_MINBOX
148 
149}; // CKTBNodeAbstract
150
151//----------------------------------------------------------------
152// this class should be used as the base class for allocating
153// and connecting the nodes in the CKTB tree and for
154// for manipulating the nodes during building up
155class CKTB8BAllocMan:
156  public CKTB8BNodeAbstract
157{
158protected:
159#ifdef LEAVES_ARRAYS
160  CObjectArray arrayAlloc;
161#endif
162 
163  // init the stack of auxiliary variables from min to max
164  void InitAux(int min, int max, int maxItemsAtOnce);
165
166  // the direction of traversal through CKTB tree
167  enum EDirection { LEFT = 0, RIGHT = 1, NOWHERE = 2 };
168
169  //#ifdef _KTB_R2
170  SKTBNodeT* _AllocEmptyLeaf() {
171#ifdef _KTB_CONSTR_STATS
172    _stats_emptyLeftNodeCount++;
173#endif
174    return (SKTBNodeT*)0;
175  }
176protected:
177  // data required as the input parameter for construction of CKTB tree
178  int maxDepthAllowed; // maximal depth of CKTB tree
179  int maxListLength; // maximal list length of CKTB tree 
180public:
181  // default constructor
182  CKTB8BAllocMan() { InitForConstructor(); }
183
184  // default destructor
185  ~CKTB8BAllocMan() { }
186
187  // forget the content that is created by previous kd-tree construction
188  // or just init for the first use.
189  void InitForConstructor();
190
191  // the function, which reads the parameters from envinroment/commandline
192  void InitPars();
193
194  // -------------------------------------------------------
195  // allocate and free functions for SKTBNode
196  CAllocContinuous *alloc2; // the allocator saving space
197  SKTBNodeT *root; // this is the root node of the whole tree
198
199  // This is the node to return from the allocation functions
200  // Here it can be implemented some linking when DFS order allocation,
201  // so the node can be different than the representation of the real
202  // node with the information
203  SKTBNodeT *nodeToLink;
204
205  // Create the representation of the interior node
206  SKTBNodeT* AllocInteriorNode(int axis, float position,
207                               int cntLeft, int cntRight);
208
209  // Create the representation of the interior node with box, where box
210  // can be used during the traversal
211  SKTBNodeT* AllocInteriorNodeWithBox(int axis, float position,
212                                      int cntLeft, int cntRight,
213                                      const SBBox &tsbox, SKTBNodeT* prevMinBoxNode,
214                                      int depthStore);
215 
216  // Create the representation of the node with the bounding box
217  SKTBNodeT* AllocEncBoxNode(const SBBox &sbox);
218
219  // Create the representation of the leaf. Note that possibly there
220  // can be special cases, such as 0, 1, 2, or 3 objects, or in general
221  // N objects.
222  SKTBNodeT* AllocLeaf(int cntObjects);
223
224  ObjectContainer* GetObjList(const SKTBNodeT *nodep) const {
225    return nodep->objlist;
226  }
227
228  // -------------------------------------------------------
229  // linking and setting functions for CKTB tree
230
231  // Set the pointers to children for the interior node
232  void SetInteriorNodeLinks(SKTBNodeT *node,
233                            SKTBNodeT *leftChild,
234                            SKTBNodeT *rightChild);
235
236  // Set the objects list to the leaf. The object list is used as it is
237  // ... it is not copied !!
238  int SetFullLeaf(SKTBNodeT *node, const ObjectContainer *objlist);
239
240  // -------------------------------------------------------
241  // inquiry functions for CKTB tree nodes for current node
242
243  // returns the pointer to the root node of tree
244  SKTBNodeT* GetRootNode() { return root;}
245
246  // postprocessing of CKTB tree after its initial construction
247  virtual void PostBuild();
248
249  // provides the information on the method used for CKTB tree
250  // and some setting parameters to given stream
251  virtual void ProvideID(ostream &app) = 0;
252 
253  // ---- Get Statistical Data ---------------------------------
254  void GetKTBTreeStats(int &nodes, int &leaves, int &emptyLeaves)
255  {
256#ifdef _KTB_CONSTR_STATS
257    nodes = _stats_interiorCount + _stats_bboxCount + _stats_minbboxCount +
258      + _stats_leafNodeCount + _stats_emptyLeftNodeCount;
259    leaves = _stats_leafNodeCount + _stats_emptyLeftNodeCount;
260    emptyLeaves = _stats_emptyLeftNodeCount;
261#endif
262  }
263
264  // constructs the CKTB tree for given objectlist and given bounding box
265  virtual SKTBNodeT* BuildUp(ObjectContainer &objlist,
266                             const AxisAlignedBox3 &box,
267                             bool verbose = true) = 0;
268
269  // deletes all the structure starting from the root node
270  virtual void Remove();
271
272  // The current depth in the tree
273  inline int GetDepth() const {return _currDepth;}
274  void IncDepth() {_currDepth++;}
275  void DecDepth() {_currDepth--;}
276
277  // --------------------------------------------------------------
278  // Statistics
279public:
280#ifdef _KTB_CONSTR_STATS
281  int _stats_interiorCount;
282  int _stats_bboxCount;
283  int _stats_minbboxCount;
284  int _stats_leafNodeCount;
285  int _stats_emptyLeftNodeCount;
286
287  // maximal depth of the currently built path during building up
288  int _maxDepth; 
289  // Sum of depths of leaf nodes (empty + full)
290  unsigned long int _sumLeafDepth;
291  // Sum of depths of empty leaves
292  unsigned long int _sumFullLeafDepth;
293  // The count of object references in leaves
294  unsigned long int _sumObjectRefCount;
295  // The maximum number of object references in a leaf
296  unsigned long int _maxObjectRefInLeaf;
297  // Surface area of leaves and interior nodes
298  float _sumSurfaceAreaLeaves;
299  float _sumSurfaceAreaMULcntLeaves;
300  float _sumSurfaceAreaInteriorNodes;
301#endif
302
303  // General statistics on the depth of current node
304  // the depth of the currently accessed node during building up
305  int _currDepth;
306};
307
308//------------------------------------------------------
309// class which enables to use some functions with direct
310// access to the members of the tree
311// traversal classes should be derived from this class
312class CKTB8BNodeIterator:
313  public CKTB8BNodeAbstract
314{
315protected:
316  int rayOffset; 
317public:
318  // default constructor
319  CKTB8BNodeIterator();
320  // default destructor
321  ~CKTB8BNodeIterator() { }
322
323  float GetSplitValue(const SKTBNodeT *nodep) const {
324    return nodep->splitPlane;
325  }
326   
327  ObjectContainer* GetObjList(const SKTBNodeT *nodep) const {
328    return nodep->objlist;
329  }
330  SBBox* GetEncBox(const SKTBNodeT *nodep) const {
331    // Here is the overlapping to save some memory !!!
332    return (SBBox*)(((char*)nodep)+8);
333  }
334
335#ifdef _SHORT_FORM_MINBOX
336  SBBox* GetMinBox(const SKTBNodeT *nodep) const {
337    return (SBBox*)((nodep+1)->pointer);
338  } 
339#else // _SHORT_FORM_MINBOX
340  SBBox* GetMinBox(const SKTBNodeT *nodep) const {
341    // Here is the overlapping to save some memory !!!
342    return (SBBox*)(((char*)nodep)+16);
343  }
344#endif // _SHORT_FORM_MINBOX
345 
346  // test the objects in the full leaf p and if finds the closest intersection
347  // with object so tmin<= t <= tmax, returns the pointer to that
348  // object, t is returned in tmax
349  int TestFullLeaf(const SimpleRay &ray, const SKTBNodeT *p);
350  int TestFullLeaf(const SimpleRay &ray, const SKTBNode *p, int rayIndex);
351
352  // test the objects in the full leaf and finds out any intersection
353  // in this case returns the pointer to the object, otherwise NULL
354  int HitAnyObj(const SimpleRay &ray, const SKTBNodeT *p);
355
356  // ------------------------------------------------------------------------
357  // Only abstract functions to simplify the interface
358
359  // this resets the nesting to start from the zero depth (root)
360  virtual void ResetTraversalDepth() = 0;
361
362  // sets the bbox and the root node for this traversal class
363  virtual void Setup(const AxisAlignedBox3 &box, SKTBNodeT *Nroot) = 0;
364
365  // Find a leaf or the minimum box containg a point.
366  virtual const SKTBNode* Locate(const Vector3& /*position*/);
367}; // class CKTBNodeIterator
368
369}
370
371#endif // __KTB8B_H__
372
Note: See TracBrowser for help on using the repository browser.