You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

302 lines
9.0 KiB
C++

/*=========================================================================
Program: Visualization Toolkit
Module: vtkOctreePointLocatorNode.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 vtkOctreePointLocatorNode
* @brief Octree node that has 8 children each of equal size
*
*
* This class represents a single spatial region in a 3D axis octant
* partitioning. It is intended to work efficiently with the
* vtkOctreePointLocator and is not meant for general use. It is assumed
* the region bounds some set of points. The ordering of the children is
* (-x,-y,-z),(+x,-y,-z),(-x,+y,-z),(+x,+y,-z),(-x,-y,+z),(+x,-y,+z),
* (-x,+y,+z),(+x,+y,+z). The portion of the domain assigned to an
* octant is Min < x <= Max.
*
* @sa
* vtkOctreePointLocator
*/
#ifndef vtkOctreePointLocatorNode_h
#define vtkOctreePointLocatorNode_h
#include "vtkCommonDataModelModule.h" // For export macro
#include "vtkObject.h"
class vtkCell;
class vtkPlanesIntersection;
class VTKCOMMONDATAMODEL_EXPORT vtkOctreePointLocatorNode : public vtkObject
{
public:
vtkTypeMacro(vtkOctreePointLocatorNode, vtkObject);
void PrintSelf(ostream& os, vtkIndent indent) override;
static vtkOctreePointLocatorNode* New();
//@{
/**
* Set/Get the number of points contained in this region.
*/
void SetNumberOfPoints(int numberOfPoints) { this->NumberOfPoints = numberOfPoints; }
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 xMin, double xMax, double yMin, double yMax, double zMin, double zMax);
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 xMin, double xMax, double yMin, double yMax, double zMin, double zMax);
void GetDataBounds(double* b) const;
//@}
//@{
/**
* 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.
*/
vtkGetMacro(MinBounds, double*);
vtkGetMacro(MaxBounds, double*);
//@}
//@{
/**
* Set the xmin, ymin and zmin value of the bounds of this region
*/
void SetMinBounds(double minBounds[3])
{
this->MinBounds[0] = minBounds[0];
this->MinBounds[1] = minBounds[1];
this->MinBounds[2] = minBounds[2];
}
//@}
//@{
/**
* Set the xmax, ymax and zmax value of the bounds of this region
*/
void SetMaxBounds(double maxBounds[3])
{
this->MaxBounds[0] = maxBounds[0];
this->MaxBounds[1] = maxBounds[1];
this->MaxBounds[2] = maxBounds[2];
}
//@}
//@{
/**
* 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.
*/
vtkGetMacro(MinDataBounds, double*);
vtkGetMacro(MaxDataBounds, double*);
//@}
//@{
/**
* Set the xmin, ymin and zmin value of the bounds of this
* data within this region.
*/
void SetMinDataBounds(double minDataBounds[3])
{
this->MinDataBounds[0] = minDataBounds[0];
this->MinDataBounds[1] = minDataBounds[1];
this->MinDataBounds[2] = minDataBounds[2];
}
//@}
//@{
/**
* Set the xmax, ymax and zmax value of the bounds of this
* data within this region.
*/
void SetMaxDataBounds(double maxDataBounds[3])
{
this->MaxDataBounds[0] = maxDataBounds[0];
this->MaxDataBounds[1] = maxDataBounds[1];
this->MaxDataBounds[2] = maxDataBounds[2];
}
//@}
//@{
/**
* Get the ID associated with the region described by this node. If
* this is not a leaf node, this value should be -1.
*/
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. Get the first of the first point's
* ID that is contained in this node.
*/
vtkGetMacro(MinID, int);
//@}
/**
* Add the 8 children.
*/
void CreateChildNodes();
/**
* Delete the 8 children.
*/
void DeleteChildNodes();
/**
* Get a pointer to the ith child of this node.
*/
vtkOctreePointLocatorNode* GetChild(int i);
/**
* 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 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, vtkOctreePointLocatorNode* top, 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,
vtkOctreePointLocatorNode* top, 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 vtkOctreePointLocatorNode's.
*/
double GetDistance2ToInnerBoundary(double x, double y, double z, vtkOctreePointLocatorNode* top);
/**
* Return the id of the suboctant that a given point is in.
* If CheckContainment is non-zero then it checks whether
* the point is in the actual bounding box of the suboctant,
* otherwise it only checks which octant the point is in
* that is created from the axis-aligned partitioning of
* the domain at this octant's center.
*/
int GetSubOctantIndex(double* point, int CheckContainment);
/**
* Recursive function to compute ID, MinVal, MaxVal, and MinID.
* Parent is used for MinVal and MaxVal in the case that no
* points are in the leaf node.
*/
void ComputeOctreeNodeInformation(
vtkOctreePointLocatorNode* Parent, int& NextLeafId, int& NextMinId, float* coordinates);
protected:
vtkOctreePointLocatorNode();
~vtkOctreePointLocatorNode() override;
private:
double _GetDistance2ToBoundary(double x, double y, double z, double* boundaryPt,
int innerBoundaryOnly, vtkOctreePointLocatorNode* top, int useDataBounds);
/**
* The minimum coordinate location of the node.
*/
double MinBounds[3];
/**
* The maximum coordinate location of the node.
*/
double MaxBounds[3];
/**
* The minimum coordinate location of the points contained
* within this node.
*/
double MinDataBounds[3];
/**
* The maximum coordinate location of the points contained
* within this node.
*/
double MaxDataBounds[3];
/**
* Get the number of points associated with this octant.
* The octant does not have to be a leaf octant. For example,
* for the root octant NumberOfPoints is equal to the number
* of points in the dataset.
*/
int NumberOfPoints;
/**
* A pointer to the 8 children of this node.
*/
vtkOctreePointLocatorNode** Children;
/**
* The ID of this octant. If it is not a leaf octant then ID=-1.
*/
int ID;
/**
* The minimum Id of the ordered points in this octant (note that
* this Id is different than the vtkIdType used for referencing
* the point in the data set.
*/
int MinID;
vtkOctreePointLocatorNode(const vtkOctreePointLocatorNode&) = delete;
void operator=(const vtkOctreePointLocatorNode&) = delete;
};
#endif