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.

277 lines
9.0 KiB
C

/*=========================================================================
Program: Visualization Toolkit
Module: vtkOctreePointLocator.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 vtkOctreePointLocator
* @brief an octree spatial decomposition of a set of points
*
*
* Given a vtkDataSet, create an octree that is locally refined
* such that all leaf octants contain less than a certain
* amount of points. Note that there is no size constraint that
* a leaf octant in relation to any of its neighbors.
*
* This class can also generate a PolyData representation of
* the boundaries of the spatial regions in the decomposition.
*
* @sa
* vtkLocator vtkPointLocator vtkOctreePointLocatorNode
*/
#ifndef vtkOctreePointLocator_h
#define vtkOctreePointLocator_h
#include "vtkAbstractPointLocator.h"
#include "vtkCommonDataModelModule.h" // For export macro
class vtkCellArray;
class vtkIdTypeArray;
class vtkOctreePointLocatorNode;
class vtkPoints;
class vtkPolyData;
class VTKCOMMONDATAMODEL_EXPORT vtkOctreePointLocator : public vtkAbstractPointLocator
{
public:
vtkTypeMacro(vtkOctreePointLocator, vtkAbstractPointLocator);
void PrintSelf(ostream& os, vtkIndent indent) override;
static vtkOctreePointLocator* New();
//@{
/**
* Maximum number of points per spatial region. Default is 100.
*/
vtkSetMacro(MaximumPointsPerRegion, int);
vtkGetMacro(MaximumPointsPerRegion, int);
//@}
//@{
/**
* Get/Set macro for CreateCubicOctants.
*/
vtkSetMacro(CreateCubicOctants, int);
vtkGetMacro(CreateCubicOctants, int);
//@}
//@{
/**
* Some algorithms on octrees require a value that is a very
* small distance relative to the diameter of the entire space
* divided by the octree. This factor is the maximum axis-aligned
* width of the space multiplied by 10e-6.
*/
vtkGetMacro(FudgeFactor, double);
vtkSetMacro(FudgeFactor, double);
//@}
//@{
/**
* Get the spatial bounds of the entire octree space. Sets
* bounds array to xmin, xmax, ymin, ymax, zmin, zmax.
*/
double* GetBounds() override;
void GetBounds(double* bounds) override;
//@}
//@{
/**
* The number of leaf nodes of the tree, the spatial regions
*/
vtkGetMacro(NumberOfLeafNodes, int);
//@}
/**
* Get the spatial bounds of octree region
*/
void GetRegionBounds(int regionID, double bounds[6]);
/**
* Get the bounds of the data within the leaf node
*/
void GetRegionDataBounds(int leafNodeID, double bounds[6]);
/**
* Get the id of the leaf region containing the specified location.
*/
int GetRegionContainingPoint(double x, double y, double z);
/**
* Create the octree decomposition of the cells of the data set
* or data sets. Cells are assigned to octree spatial regions
* based on the location of their centroids.
*/
void BuildLocator() override;
//@{
/**
* Return the Id of the point that is closest to the given point.
* Set the square of the distance between the two points.
*/
vtkIdType FindClosestPoint(const double x[3]) override;
vtkIdType FindClosestPoint(double x, double y, double z, double& dist2);
//@}
/**
* Given a position x and a radius r, return the id of the point
* closest to the point in that radius.
* dist2 returns the squared distance to the point.
*/
vtkIdType FindClosestPointWithinRadius(double radius, const double x[3], double& dist2) override;
//@{
/**
* Find the Id of the point in the given leaf region which is
* closest to the given point. Return the ID of the point,
* and set the square of the distance of between the points.
*/
vtkIdType FindClosestPointInRegion(int regionId, double* x, double& dist2);
vtkIdType FindClosestPointInRegion(int regionId, double x, double y, double z, double& dist2);
//@}
/**
* Find all points within a specified radius of position x.
* The result is not sorted in any specific manner.
*/
void FindPointsWithinRadius(double radius, const double x[3], vtkIdList* result) override;
/**
* Find the closest N points to a position. This returns the closest
* N points to a position. A faster method could be created that returned
* N close points to a position, but not necessarily the exact N closest.
* The returned points are sorted from closest to farthest.
* These methods are thread safe if BuildLocator() is directly or
* indirectly called from a single thread first.
*/
void FindClosestNPoints(int N, const double x[3], vtkIdList* result) override;
/**
* Get a list of the original IDs of all points in a leaf node.
*/
vtkIdTypeArray* GetPointsInRegion(int leafNodeId);
/**
* Delete the octree data structure.
*/
void FreeSearchStructure() override;
/**
* Create a polydata representation of the boundaries of
* the octree regions.
*/
void GenerateRepresentation(int level, vtkPolyData* pd) override;
/**
* Fill ids with points found in area. The area is a 6-tuple containing
* (xmin, xmax, ymin, ymax, zmin, zmax).
* This method will clear the array by default. To append ids to an array,
* set clearArray to false.
*/
void FindPointsInArea(double* area, vtkIdTypeArray* ids, bool clearArray = true);
protected:
vtkOctreePointLocator();
~vtkOctreePointLocator() override;
vtkOctreePointLocatorNode* Top;
vtkOctreePointLocatorNode** LeafNodeList; // indexed by region/node ID
void BuildLeafNodeList(vtkOctreePointLocatorNode* node, int& index);
//@{
/**
* Given a point and a node return the leaf node id that contains the
* point. The function returns -1 if no nodes contain the point.
*/
int FindRegion(vtkOctreePointLocatorNode* node, float x, float y, float z);
int FindRegion(vtkOctreePointLocatorNode* node, double x, double y, double z);
//@}
static void SetDataBoundsToSpatialBounds(vtkOctreePointLocatorNode* node);
static void DeleteAllDescendants(vtkOctreePointLocatorNode* octant);
/**
* Recursive helper for public FindPointsWithinRadius. radiusSquared
* is the square of the radius and is used in order to avoid the
* expensive square root calculation.
*/
void FindPointsWithinRadius(
vtkOctreePointLocatorNode* node, double radiusSquared, const double x[3], vtkIdList* ids);
// Recursive helper for public FindPointsWithinRadius
void AddAllPointsInRegion(vtkOctreePointLocatorNode* node, vtkIdList* ids);
// Recursive helper for public FindPointsInArea
void FindPointsInArea(vtkOctreePointLocatorNode* node, double* area, vtkIdTypeArray* ids);
// Recursive helper for public FindPointsInArea
void AddAllPointsInRegion(vtkOctreePointLocatorNode* node, vtkIdTypeArray* ids);
void DivideRegion(vtkOctreePointLocatorNode* node, int* ordering, int level);
int DivideTest(int size, int level);
void AddPolys(vtkOctreePointLocatorNode* node, vtkPoints* pts, vtkCellArray* polys);
/**
* Given a leaf node id and point, return the local id and the squared distance
* between the closest point and the given point.
*/
int _FindClosestPointInRegion(int leafNodeId, double x, double y, double z, double& dist2);
/**
* Given a location and a radiues, find the closest point within
* this radius. The function does not examine the region with Id
* equal to skipRegion (do not set skipRegion to -1 as all non-leaf
* octants have -1 as their Id). The Id is returned along with
* the distance squared for success and -1 is returned for failure.
*/
int FindClosestPointInSphere(
double x, double y, double z, double radius, int skipRegion, double& dist2);
//@{
/**
* The maximum number of points in a region/octant before it is subdivided.
*/
int MaximumPointsPerRegion;
int NumberOfLeafNodes;
//@}
double FudgeFactor; // a very small distance, relative to the dataset's size
int NumberOfLocatorPoints;
float* LocatorPoints;
int* LocatorIds;
float MaxWidth;
/**
* If CreateCubicOctants is non-zero, the bounding box of the points will
* be expanded such that all octants that are created will be cube-shaped
* (e.g. have equal lengths on each side). This may make the tree deeper
* but also results in better shaped octants for doing searches. The
* default is to have this set on.
*/
int CreateCubicOctants;
vtkOctreePointLocator(const vtkOctreePointLocator&) = delete;
void operator=(const vtkOctreePointLocator&) = delete;
};
#endif