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

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