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++
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
|