1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkKdNode.h
5 
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10      This software is distributed WITHOUT ANY WARRANTY; without even
11      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12      PURPOSE.  See the above copyright notice for more information.
13 
14 =========================================================================*/
15 /*----------------------------------------------------------------------------
16  Copyright (c) Sandia Corporation
17  See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
18 ----------------------------------------------------------------------------*/
19 
20 // .NAME vtkKdNode - This class represents a single spatial region
21 //     in an 3D axis aligned binary spatial partitioning.  It is assumed
22 //     the region bounds some set of points.  Regions are represented
23 //     as nodes in a binary tree.
24 //
25 // .SECTION Description
26 //
27 // .SECTION See Also
28 //      vtkKdTree vtkOBSPCuts
29 
30 #ifndef vtkKdNode_h
31 #define vtkKdNode_h
32 
33 #include "vtkCommonDataModelModule.h" // For export macro
34 #include "vtkObject.h"
35 
36 class vtkCell;
37 class vtkPlanesIntersection;
38 
39 class VTKCOMMONDATAMODEL_EXPORT vtkKdNode : public vtkObject
40 {
41 public:
42   vtkTypeMacro(vtkKdNode, vtkObject);
43   void PrintSelf(ostream& os, vtkIndent indent);
44 
45   static vtkKdNode *New();
46 
47   // Description:
48   // Set/Get the dimension along which this region is divided.
49   // (0 - x, 1 - y, 2 - z, 3 - leaf node (default)).
50   vtkSetMacro(Dim, int);
51   vtkGetMacro(Dim, int);
52 
53   // Description:
54   // Get the location of the division plane along the axis the region
55   // is divided.  See also GetDim().  The result is undertermined if
56   // this node is not divided (a leaf node).
57   virtual double GetDivisionPosition();
58 
59   // Description:
60   // Set/Get the number of points contained in this region.
61   vtkSetMacro(NumberOfPoints, int);
62   vtkGetMacro(NumberOfPoints, int);
63 
64   // Description:
65   //   Set/Get the bounds of the spatial region represented by this node.
66   //   Caller allocates storage for 6-vector in GetBounds.
67   void SetBounds(double x1,double x2,double y1,double y2,double z1,double z2);
SetBounds(const double b[6])68   void SetBounds(const double b[6])
69     {
70     this->SetBounds(b[0], b[1], b[2], b[3], b[4], b[5]);
71     }
72   void GetBounds(double *b) const;
73 
74   // Description:
75   //   Set/Get the bounds of the points contained in this spatial region.
76   //   This may be smaller than the bounds of the region itself.
77   //   Caller allocates storage for 6-vector in GetDataBounds.
78   void SetDataBounds(double x1,double x2,double y1,double y2,double z1,double z2);
79   void GetDataBounds(double *b) const;
80 
81   // Description:
82   //   Given a pointer to NumberOfPoints points, set the DataBounds of this
83   //   node to the bounds of these points.
84   void SetDataBounds(float *v);
85 
86   // Description:
87   //   Get a pointer to the 3 bound minima (xmin, ymin and zmin) or the
88   //   3 bound maxima (xmax, ymax, zmax).  Don't free this pointer.
GetMinBounds()89   double *GetMinBounds() {return this->Min;}
GetMaxBounds()90   double *GetMaxBounds() {return this->Max;}
91 
92   // Description:
93   //   Set the xmin, ymin and zmin value of the bounds of this region
94   void SetMinBounds(const double *mb);
95 
96   // Description:
97   //   Set the xmax, ymax and zmax value of the bounds of this region
98   void SetMaxBounds(const double *mb);
99 
100   // Description:
101   //   Get a pointer to the 3 data bound minima (xmin, ymin and zmin) or the
102   //   3 data bound maxima (xmax, ymax, zmax).  Don't free this pointer.
GetMinDataBounds()103   double *GetMinDataBounds() {return this->MinVal;}
GetMaxDataBounds()104   double *GetMaxDataBounds() {return this->MaxVal;}
105 
106   // Description:
107   //   Set the xmin, ymin and zmin value of the bounds of this
108   //   data within this region
109   void SetMinDataBounds(const double *mb);
110 
111   // Description:
112   //   Set the xmax, ymax and zmax value of the bounds of this
113   //   data within this region
114   void SetMaxDataBounds(const double *mb);
115 
116   // Description:
117   //   Set/Get the ID associated with the region described by this node.  If
118   //   this is not a leaf node, this value should be -1.
119   vtkSetMacro(ID, int);
120   vtkGetMacro(ID, int);
121 
122   // Description:
123   //   If this node is not a leaf node, there are leaf nodes below it whose
124   //   regions represent a partitioning of this region.  The IDs of these
125   //   leaf nodes form a contigous set.  Set/Get the range of the IDs of
126   //   the leaf nodes below this node.  If this is already a leaf node, these
127   //   values should be the same as the ID.
128   vtkGetMacro(MinID, int);
129   vtkGetMacro(MaxID, int);
130   vtkSetMacro(MinID, int);
131   vtkSetMacro(MaxID, int);
132 
133   // Description:
134   //   Add the left and right children.
135   void AddChildNodes(vtkKdNode *left, vtkKdNode *right);
136 
137   // Description:
138   //   Delete the left and right children.
139   void DeleteChildNodes();
140 
141   // Description:
142   //   Set/Get a pointer to the left child of this node.
143   vtkGetObjectMacro(Left, vtkKdNode);
144   void SetLeft(vtkKdNode* left);
145 
146   // Description:
147   //   Set/Get a pointer to the right child of this node.
148   vtkGetObjectMacro(Right, vtkKdNode);
149   void SetRight(vtkKdNode *right);
150 
151   // Description:
152   //   Set/Get a pointer to the parent of this node.
153   vtkGetObjectMacro(Up, vtkKdNode);
154   void SetUp(vtkKdNode* up);
155 
156   // Description:
157   //   Return 1 if this spatial region intersects the axis-aligned box given
158   //   by the bounds passed in.  Use the possibly smaller bounds of the points
159   //   within the region if useDataBounds is non-zero.
160   int IntersectsBox(double x1,double x2,double y1,double y2,double z1,double z2,
161                     int useDataBounds);
162 
163   // Description:
164   //   Return 1 if this spatial region intersects a sphere described by
165   //   it's center and the square of it's radius. Use the possibly smaller
166   //   bounds of the points within the region if useDataBounds is non-zero.
167   int IntersectsSphere2(double x, double y, double z, double rSquared,
168                         int useDataBounds);
169 
170   // Description:
171   //   A vtkPlanesIntersection object represents a convex 3D region bounded
172   //   by planes, and it is capable of computing intersections of
173   //   boxes with itself.  Return 1 if this spatial region intersects
174   //   the spatial region described by the vtkPlanesIntersection object.
175   //   Use the possibly smaller bounds of the points within the region
176   //   if useDataBounds is non-zero.
177   int IntersectsRegion(vtkPlanesIntersection *pi, int useDataBounds);
178 
179   // Description:
180   //   Return 1 if the cell specified intersects this region.  If you
181   //   already know the ID of the region containing the cell's centroid,
182   //   provide that as an argument.  If you already know the bounds of the
183   //   cell, provide that as well, in the form of xmin,xmax,ymin,ymax,zmin,
184   //   zmax.  Either of these may speed the calculation.
185   //   Use the possibly smaller bounds of the points within the region
186   //   if useDataBounds is non-zero.
187   int IntersectsCell(vtkCell *cell, int useDataBounds,
188                      int cellRegion=-1, double *cellBounds=NULL);
189 
190   // Description:
191   //   Return 1 if this spatial region entirely contains a box specified
192   //   by it's bounds. Use the possibly smaller
193   //   bounds of the points within the region if useDataBounds is non-zero.
194   int ContainsBox(double x1,double x2,double y1,double y2,double z1,double z2,
195                   int useDataBounds);
196 
197   // Description:
198   //   Return 1 if this spatial region entirely contains the given point.
199   //   Use the possibly smaller bounds of the points within the region
200   //   if useDataBounds is non-zero.
201   int ContainsPoint(double x, double y, double z, int useDataBounds);
202 
203   // Description:
204   //   Calculate the distance squared from any point to the boundary of this
205   //   region.  Use the boundary of the points within the region if useDataBounds
206   //   is non-zero.
207   double GetDistance2ToBoundary(double x, double y, double z, int useDataBounds);
208 
209   // Description:
210   //   Calculate the distance squared from any point to the boundary of this
211   //   region.  Use the boundary of the points within the region if useDataBounds
212   //   is non-zero.  Set boundaryPt to the point on the boundary.
213   double GetDistance2ToBoundary(double x, double y, double z, double *boundaryPt,
214                                 int useDataBounds);
215 
216   // Description:
217   //   Calculate the distance from the specified point (which is required to
218   //   be inside this spatial region) to an interior boundary.  An interior
219   //   boundary is one that is not also an boundary of the entire space
220   //   partitioned by the tree of vtkKdNode's.
221   double GetDistance2ToInnerBoundary(double x, double y, double z);
222 
223   // Description:
224   //   For debugging purposes, print out this node.
225   void PrintNode(int depth);
226   void PrintVerboseNode(int depth);
227 
228 protected:
229 
230   vtkKdNode();
231   ~vtkKdNode();
232 
233 private:
234 
235   double _GetDistance2ToBoundary(
236     double x, double y, double z, double *boundaryPt,
237     int innerBoundaryOnly, int useDataBounds);
238 
239   double Min[3];       // spatial bounds of node
240   double Max[3];       // spatial bounds of node
241   double MinVal[3];    // spatial bounds of data within node
242   double MaxVal[3];    // spatial bounds of data within node
243   int NumberOfPoints;
244 
245   vtkKdNode *Up;
246 
247   vtkKdNode *Left;
248   vtkKdNode *Right;
249 
250   int Dim;
251 
252   int ID;        // region id
253 
254   int MinID;
255   int MaxID;
256 
257   vtkKdNode(const vtkKdNode&); // Not implemented
258   void operator=(const vtkKdNode&); // Not implemented
259 };
260 
261 #endif
262