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.
296 lines
11 KiB
C++
296 lines
11 KiB
C++
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: vtkPointLocator.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.
|
|
|
|
=========================================================================*/
|
|
/**
|
|
* @class vtkPointLocator
|
|
* @brief quickly locate points in 3-space
|
|
*
|
|
* vtkPointLocator is a spatial search object to quickly locate points in 3D.
|
|
* vtkPointLocator works by dividing a specified region of space into a regular
|
|
* array of "rectangular" buckets, and then keeping a list of points that
|
|
* lie in each bucket. Typical operation involves giving a position in 3D
|
|
* and finding the closest point.
|
|
*
|
|
* vtkPointLocator has two distinct methods of interaction. In the first
|
|
* method, you supply it with a dataset, and it operates on the points in
|
|
* the dataset. In the second method, you supply it with an array of points,
|
|
* and the object operates on the array.
|
|
*
|
|
* @warning
|
|
* Many other types of spatial locators have been developed such as
|
|
* octrees and kd-trees. These are often more efficient for the
|
|
* operations described here.
|
|
*
|
|
* @sa
|
|
* vtkCellPicker vtkPointPicker vtkStaticPointLocator
|
|
*/
|
|
|
|
#ifndef vtkPointLocator_h
|
|
#define vtkPointLocator_h
|
|
|
|
#include "vtkCommonDataModelModule.h" // For export macro
|
|
#include "vtkIncrementalPointLocator.h"
|
|
|
|
class vtkCellArray;
|
|
class vtkIdList;
|
|
class vtkNeighborPoints;
|
|
class vtkPoints;
|
|
|
|
class VTKCOMMONDATAMODEL_EXPORT vtkPointLocator : public vtkIncrementalPointLocator
|
|
{
|
|
public:
|
|
/**
|
|
* Construct with automatic computation of divisions, averaging
|
|
* 25 points per bucket.
|
|
*/
|
|
static vtkPointLocator* New();
|
|
|
|
//@{
|
|
/**
|
|
* Standard methods for type management and printing.
|
|
*/
|
|
vtkTypeMacro(vtkPointLocator, vtkIncrementalPointLocator);
|
|
void PrintSelf(ostream& os, vtkIndent indent) override;
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Set the number of divisions in x-y-z directions.
|
|
*/
|
|
vtkSetVector3Macro(Divisions, int);
|
|
vtkGetVectorMacro(Divisions, int, 3);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Specify the average number of points in each bucket.
|
|
*/
|
|
vtkSetClampMacro(NumberOfPointsPerBucket, int, 1, VTK_INT_MAX);
|
|
vtkGetMacro(NumberOfPointsPerBucket, int);
|
|
//@}
|
|
|
|
// Re-use any superclass signatures that we don't override.
|
|
using vtkAbstractPointLocator::FindClosestPoint;
|
|
|
|
/**
|
|
* Given a position x, return the id of the point closest to it. Alternative
|
|
* method requires separate x-y-z values.
|
|
* These methods are thread safe if BuildLocator() is directly or
|
|
* indirectly called from a single thread first.
|
|
*/
|
|
vtkIdType FindClosestPoint(const double x[3]) override;
|
|
|
|
//@{
|
|
/**
|
|
* Given a position x and a radius r, return the id of the point
|
|
* closest to the point in that radius.
|
|
* These methods are thread safe if BuildLocator() is directly or
|
|
* indirectly called from a single thread first. dist2 returns the squared
|
|
* distance to the point.
|
|
*/
|
|
vtkIdType FindClosestPointWithinRadius(double radius, const double x[3], double& dist2) override;
|
|
virtual vtkIdType FindClosestPointWithinRadius(
|
|
double radius, const double x[3], double inputDataLength, double& dist2);
|
|
//@}
|
|
|
|
/**
|
|
* Initialize the point insertion process. The newPts is an object
|
|
* representing point coordinates into which incremental insertion methods
|
|
* place their data. Bounds are the box that the points lie in.
|
|
* Not thread safe.
|
|
*/
|
|
int InitPointInsertion(vtkPoints* newPts, const double bounds[6]) override;
|
|
|
|
/**
|
|
* Initialize the point insertion process. The newPts is an object
|
|
* representing point coordinates into which incremental insertion methods
|
|
* place their data. Bounds are the box that the points lie in.
|
|
* Not thread safe.
|
|
*/
|
|
int InitPointInsertion(vtkPoints* newPts, const double bounds[6], vtkIdType estSize) override;
|
|
|
|
/**
|
|
* Incrementally insert a point into search structure with a particular
|
|
* index value. You should use the method IsInsertedPoint() to see whether
|
|
* this point has already been inserted (that is, if you desire to prevent
|
|
* duplicate points). Before using this method you must make sure that
|
|
* newPts have been supplied, the bounds has been set properly, and that
|
|
* divs are properly set. (See InitPointInsertion().)
|
|
* Not thread safe.
|
|
*/
|
|
void InsertPoint(vtkIdType ptId, const double x[3]) override;
|
|
|
|
/**
|
|
* Incrementally insert a point into search structure. The method returns
|
|
* the insertion location (i.e., point id). You should use the method
|
|
* IsInsertedPoint() to see whether this point has already been
|
|
* inserted (that is, if you desire to prevent duplicate points).
|
|
* Before using this method you must make sure that newPts have been
|
|
* supplied, the bounds has been set properly, and that divs are
|
|
* properly set. (See InitPointInsertion().)
|
|
* Not thread safe.
|
|
*/
|
|
vtkIdType InsertNextPoint(const double x[3]) override;
|
|
|
|
//@{
|
|
/**
|
|
* Determine whether point given by x[3] has been inserted into points list.
|
|
* Return id of previously inserted point if this is true, otherwise return
|
|
* -1. This method is thread safe.
|
|
*/
|
|
vtkIdType IsInsertedPoint(double x, double y, double z) override
|
|
{
|
|
double xyz[3];
|
|
xyz[0] = x;
|
|
xyz[1] = y;
|
|
xyz[2] = z;
|
|
return this->IsInsertedPoint(xyz);
|
|
};
|
|
vtkIdType IsInsertedPoint(const double x[3]) override;
|
|
//@}
|
|
|
|
/**
|
|
* Determine whether point given by x[3] has been inserted into points list.
|
|
* Return 0 if point was already in the list, otherwise return 1. If the
|
|
* point was not in the list, it will be ADDED. In either case, the id of
|
|
* the point (newly inserted or not) is returned in the ptId argument.
|
|
* Note this combines the functionality of IsInsertedPoint() followed
|
|
* by a call to InsertNextPoint().
|
|
* This method is not thread safe.
|
|
*/
|
|
int InsertUniquePoint(const double x[3], vtkIdType& ptId) override;
|
|
|
|
/**
|
|
* Given a position x, return the id of the point closest to it. This method
|
|
* is used when performing incremental point insertion. Note that -1
|
|
* indicates that no point was found.
|
|
* This method is thread safe if BuildLocator() is directly or
|
|
* indirectly called from a single thread first.
|
|
*/
|
|
vtkIdType FindClosestInsertedPoint(const double x[3]) 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 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;
|
|
|
|
//@{
|
|
/**
|
|
* Find the closest points to a position such that each octant of
|
|
* space around the position contains at least N points. Loosely
|
|
* limit the search to a maximum number of points evaluated, M.
|
|
* These methods are thread safe if BuildLocator() is directly or
|
|
* indirectly called from a single thread first.
|
|
*/
|
|
virtual void FindDistributedPoints(int N, const double x[3], vtkIdList* result, int M);
|
|
virtual void FindDistributedPoints(int N, double x, double y, double z, vtkIdList* result, int M);
|
|
//@}
|
|
|
|
/**
|
|
* Find all points within a specified radius R of position x.
|
|
* The result is not sorted in any specific manner.
|
|
* These methods are thread safe if BuildLocator() is directly or
|
|
* indirectly called from a single thread first.
|
|
*/
|
|
void FindPointsWithinRadius(double R, const double x[3], vtkIdList* result) override;
|
|
|
|
/**
|
|
* Given a position x, return the list of points in the bucket that
|
|
* contains the point. It is possible that nullptr is returned. The user
|
|
* provides an ijk array that is the indices into the locator.
|
|
* This method is thread safe.
|
|
*/
|
|
virtual vtkIdList* GetPointsInBucket(const double x[3], int ijk[3]);
|
|
|
|
//@{
|
|
/**
|
|
* Provide an accessor to the points.
|
|
*/
|
|
vtkGetObjectMacro(Points, vtkPoints);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* See vtkLocator interface documentation.
|
|
* These methods are not thread safe.
|
|
*/
|
|
void Initialize() override;
|
|
void FreeSearchStructure() override;
|
|
void BuildLocator() override;
|
|
void GenerateRepresentation(int level, vtkPolyData* pd) override;
|
|
//@}
|
|
|
|
protected:
|
|
vtkPointLocator();
|
|
~vtkPointLocator() override;
|
|
|
|
// place points in appropriate buckets
|
|
void GetBucketNeighbors(
|
|
vtkNeighborPoints* buckets, const int ijk[3], const int ndivs[3], int level);
|
|
void GetOverlappingBuckets(
|
|
vtkNeighborPoints* buckets, const double x[3], const int ijk[3], double dist, int level);
|
|
void GetOverlappingBuckets(vtkNeighborPoints* buckets, const double x[3], double dist,
|
|
int prevMinLevel[3], int prevMaxLevel[3]);
|
|
void GenerateFace(int face, int i, int j, int k, vtkPoints* pts, vtkCellArray* polys);
|
|
double Distance2ToBucket(const double x[3], const int nei[3]);
|
|
double Distance2ToBounds(const double x[3], const double bounds[6]);
|
|
|
|
vtkPoints* Points; // Used for merging points
|
|
int Divisions[3]; // Number of sub-divisions in x-y-z directions
|
|
int NumberOfPointsPerBucket; // Used with previous boolean to control subdivide
|
|
vtkIdList** HashTable; // lists of point ids in buckets
|
|
double H[3]; // width of each bucket in x-y-z directions
|
|
|
|
double InsertionTol2;
|
|
vtkIdType InsertionPointId;
|
|
double InsertionLevel;
|
|
|
|
// These are inlined methods and data members for performance reasons
|
|
double HX, HY, HZ;
|
|
double FX, FY, FZ, BX, BY, BZ;
|
|
vtkIdType XD, YD, ZD, SliceSize;
|
|
|
|
void GetBucketIndices(const double* x, int ijk[3]) const
|
|
{
|
|
// Compute point index. Make sure it lies within range of locator.
|
|
vtkIdType tmp0 = static_cast<vtkIdType>(((x[0] - this->BX) * this->FX));
|
|
vtkIdType tmp1 = static_cast<vtkIdType>(((x[1] - this->BY) * this->FY));
|
|
vtkIdType tmp2 = static_cast<vtkIdType>(((x[2] - this->BZ) * this->FZ));
|
|
|
|
ijk[0] = tmp0 < 0 ? 0 : (tmp0 >= this->XD ? this->XD - 1 : tmp0);
|
|
ijk[1] = tmp1 < 0 ? 0 : (tmp1 >= this->YD ? this->YD - 1 : tmp1);
|
|
ijk[2] = tmp2 < 0 ? 0 : (tmp2 >= this->ZD ? this->ZD - 1 : tmp2);
|
|
}
|
|
|
|
vtkIdType GetBucketIndex(const double* x) const
|
|
{
|
|
int ijk[3];
|
|
this->GetBucketIndices(x, ijk);
|
|
return ijk[0] + ijk[1] * this->XD + ijk[2] * this->SliceSize;
|
|
}
|
|
|
|
void ComputePerformanceFactors();
|
|
|
|
private:
|
|
vtkPointLocator(const vtkPointLocator&) = delete;
|
|
void operator=(const vtkPointLocator&) = delete;
|
|
};
|
|
|
|
#endif
|