/*========================================================================= Program: Visualization Toolkit Module: vtkKdNode.h Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ /*---------------------------------------------------------------------------- Copyright (c) Sandia Corporation See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details. ----------------------------------------------------------------------------*/ /** * @class vtkKdNode * @brief This class represents a single spatial region * in an 3D axis aligned binary spatial partitioning. It is assumed * the region bounds some set of points. Regions are represented * as nodes in a binary tree. * * * * @sa * vtkKdTree vtkOBSPCuts */ #ifndef vtkKdNode_h #define vtkKdNode_h #include "vtkCommonDataModelModule.h" // For export macro #include "vtkObject.h" class vtkCell; class vtkPlanesIntersection; class VTKCOMMONDATAMODEL_EXPORT vtkKdNode : public vtkObject { public: vtkTypeMacro(vtkKdNode, vtkObject); void PrintSelf(ostream& os, vtkIndent indent) override; static vtkKdNode* New(); //@{ /** * Set/Get the dimension along which this region is divided. * (0 - x, 1 - y, 2 - z, 3 - leaf node (default)). */ vtkSetMacro(Dim, int); vtkGetMacro(Dim, int); //@} /** * Get the location of the division plane along the axis the region * is divided. See also GetDim(). The result is undertermined if * this node is not divided (a leaf node). */ virtual double GetDivisionPosition(); //@{ /** * Set/Get the number of points contained in this region. */ vtkSetMacro(NumberOfPoints, int); vtkGetMacro(NumberOfPoints, int); //@} //@{ /** * Set/Get the bounds of the spatial region represented by this node. * Caller allocates storage for 6-vector in GetBounds. */ void SetBounds(double x1, double x2, double y1, double y2, double z1, double z2); void SetBounds(const double b[6]) { this->SetBounds(b[0], b[1], b[2], b[3], b[4], b[5]); } void GetBounds(double* b) const; //@} //@{ /** * Set/Get the bounds of the points contained in this spatial region. * This may be smaller than the bounds of the region itself. * Caller allocates storage for 6-vector in GetDataBounds. */ void SetDataBounds(double x1, double x2, double y1, double y2, double z1, double z2); void GetDataBounds(double* b) const; //@} /** * Given a pointer to NumberOfPoints points, set the DataBounds of this * node to the bounds of these points. */ void SetDataBounds(float* v); /** * Get a pointer to the 3 bound minima (xmin, ymin and zmin) or the * 3 bound maxima (xmax, ymax, zmax). Don't free this pointer. */ double* GetMinBounds() VTK_SIZEHINT(3) { return this->Min; } double* GetMaxBounds() VTK_SIZEHINT(3) { return this->Max; } /** * Set the xmin, ymin and zmin value of the bounds of this region */ void SetMinBounds(const double* mb); /** * Set the xmax, ymax and zmax value of the bounds of this region */ void SetMaxBounds(const double* mb); /** * Get a pointer to the 3 data bound minima (xmin, ymin and zmin) or the * 3 data bound maxima (xmax, ymax, zmax). Don't free this pointer. */ double* GetMinDataBounds() VTK_SIZEHINT(3) { return this->MinVal; } double* GetMaxDataBounds() VTK_SIZEHINT(3) { return this->MaxVal; } /** * Set the xmin, ymin and zmin value of the bounds of this * data within this region */ void SetMinDataBounds(const double* mb); /** * Set the xmax, ymax and zmax value of the bounds of this * data within this region */ void SetMaxDataBounds(const double* mb); //@{ /** * Set/Get the ID associated with the region described by this node. If * this is not a leaf node, this value should be -1. */ vtkSetMacro(ID, int); vtkGetMacro(ID, int); //@} //@{ /** * If this node is not a leaf node, there are leaf nodes below it whose * regions represent a partitioning of this region. The IDs of these * leaf nodes form a contiguous set. Set/Get the range of the IDs of * the leaf nodes below this node. If this is already a leaf node, these * values should be the same as the ID. */ vtkGetMacro(MinID, int); vtkGetMacro(MaxID, int); vtkSetMacro(MinID, int); vtkSetMacro(MaxID, int); //@} /** * Add the left and right children. */ void AddChildNodes(vtkKdNode* left, vtkKdNode* right); /** * Delete the left and right children. */ void DeleteChildNodes(); //@{ /** * Set/Get a pointer to the left child of this node. */ vtkGetObjectMacro(Left, vtkKdNode); void SetLeft(vtkKdNode* left); //@} //@{ /** * Set/Get a pointer to the right child of this node. */ vtkGetObjectMacro(Right, vtkKdNode); void SetRight(vtkKdNode* right); //@} //@{ /** * Set/Get a pointer to the parent of this node. */ vtkGetObjectMacro(Up, vtkKdNode); void SetUp(vtkKdNode* up); //@} /** * Return 1 if this spatial region intersects the axis-aligned box given * by the bounds passed in. Use the possibly smaller bounds of the points * within the region if useDataBounds is non-zero. */ int IntersectsBox( double x1, double x2, double y1, double y2, double z1, double z2, int useDataBounds); /** * Return 1 if this spatial region intersects a sphere described by * it's center and the square of it's radius. Use the possibly smaller * bounds of the points within the region if useDataBounds is non-zero. */ int IntersectsSphere2(double x, double y, double z, double rSquared, int useDataBounds); /** * A vtkPlanesIntersection object represents a convex 3D region bounded * by planes, and it is capable of computing intersections of * boxes with itself. Return 1 if this spatial region intersects * the spatial region described by the vtkPlanesIntersection object. * Use the possibly smaller bounds of the points within the region * if useDataBounds is non-zero. */ int IntersectsRegion(vtkPlanesIntersection* pi, int useDataBounds); /** * Return 1 if the cell specified intersects this region. If you * already know the ID of the region containing the cell's centroid, * provide that as an argument. If you already know the bounds of the * cell, provide that as well, in the form of xmin,xmax,ymin,ymax,zmin, * zmax. Either of these may speed the calculation. * Use the possibly smaller bounds of the points within the region * if useDataBounds is non-zero. */ int IntersectsCell( vtkCell* cell, int useDataBounds, int cellRegion = -1, double* cellBounds = nullptr); /** * Return 1 if this spatial region entirely contains a box specified * by it's bounds. Use the possibly smaller * bounds of the points within the region if useDataBounds is non-zero. */ int ContainsBox( double x1, double x2, double y1, double y2, double z1, double z2, int useDataBounds); /** * Return 1 if this spatial region entirely contains the given point. * Use the possibly smaller bounds of the points within the region * if useDataBounds is non-zero. */ vtkTypeBool ContainsPoint(double x, double y, double z, int useDataBounds); /** * Calculate the distance squared from any point to the boundary of this * region. Use the boundary of the points within the region if useDataBounds * is non-zero. */ double GetDistance2ToBoundary(double x, double y, double z, int useDataBounds); /** * Calculate the distance squared from any point to the boundary of this * region. Use the boundary of the points within the region if useDataBounds * is non-zero. Set boundaryPt to the point on the boundary. */ double GetDistance2ToBoundary( double x, double y, double z, double* boundaryPt, int useDataBounds); /** * Calculate the distance from the specified point (which is required to * be inside this spatial region) to an interior boundary. An interior * boundary is one that is not also an boundary of the entire space * partitioned by the tree of vtkKdNode's. */ double GetDistance2ToInnerBoundary(double x, double y, double z); //@{ /** * For debugging purposes, print out this node. */ void PrintNode(int depth); void PrintVerboseNode(int depth); //@} protected: vtkKdNode(); ~vtkKdNode() override; private: double _GetDistance2ToBoundary( double x, double y, double z, double* boundaryPt, int innerBoundaryOnly, int useDataBounds); double Min[3]; // spatial bounds of node double Max[3]; // spatial bounds of node double MinVal[3]; // spatial bounds of data within node double MaxVal[3]; // spatial bounds of data within node int NumberOfPoints; vtkKdNode* Up; vtkKdNode* Left; vtkKdNode* Right; int Dim; int ID; // region id int MinID; int MaxID; vtkKdNode(const vtkKdNode&) = delete; void operator=(const vtkKdNode&) = delete; }; #endif