13#ifndef vtkStaticPointLocatorPrivate_h
14#define vtkStaticPointLocatorPrivate_h
31VTK_ABI_NAMESPACE_BEGIN
48struct NeighborBuckets;
78 this->NumPts = numPts;
79 this->NumBuckets = numBuckets;
80 this->BatchSize = 10000;
85 double spacing[3], bounds[6];
89 this->hX = this->H[0] = spacing[0];
90 this->hY = this->H[1] = spacing[1];
91 this->hZ = this->H[2] = spacing[2];
92 this->hX2 = this->hX / 2.0;
93 this->hY2 = this->hY / 2.0;
94 this->hZ2 = this->hZ / 2.0;
95 this->fX = 1.0 / spacing[0];
96 this->fY = 1.0 / spacing[1];
97 this->fZ = 1.0 / spacing[2];
98 this->bX = this->Bounds[0] = bounds[0];
99 this->Bounds[1] = bounds[1];
100 this->bY = this->Bounds[2] = bounds[2];
101 this->Bounds[3] = bounds[3];
102 this->bZ = this->Bounds[4] = bounds[4];
103 this->Bounds[5] = bounds[5];
104 this->xD = this->Divisions[0];
105 this->yD = this->Divisions[1];
106 this->zD = this->Divisions[2];
107 this->xyD = this->Divisions[0] * this->Divisions[1];
109 this->FastPoints =
nullptr;
110 this->BinRadius = sqrt(
hX *
hX +
hY *
hY +
hZ *
hZ) / 2.0;
111 this->MaxLevel = std::max({ this->xD, this->yD, this->zD });
120 NeighborBuckets* buckets,
const int ijk[3],
const int ndivs[3],
int level);
138 ijk[0] = tmp0 < 0 ? 0 : std::min(
xD - 1, tmp0);
139 ijk[1] = tmp1 < 0 ? 0 : std::min(
yD - 1, tmp1);
140 ijk[2] = tmp2 < 0 ? 0 : std::min(
zD - 1, tmp2);
148 return ijk[0] + ijk[1] *
xD + ijk[2] *
xyD;
155 center[0] = this->bX + this->hX2 + i * this->hX;
156 center[1] = this->bY + this->hY2 + j * this->hY;
157 center[2] = this->bZ + this->hZ2 + k * this->hZ;
164 min[0] = this->bX + i * this->hX;
165 min[1] = this->bY + j * this->hY;
166 min[2] = this->bZ + k * this->hZ;
167 max[0] = min[0] + this->hX;
168 max[1] = min[1] + this->hY;
169 max[2] = min[2] + this->hZ;
177 double min[3],
max[3];
178 min[0] = this->bX + i * this->hX;
179 min[1] = this->bY + j * this->hY;
180 min[2] = this->bZ + k * this->hZ;
181 max[0] = min[0] + this->hX;
182 max[1] = min[1] + this->hY;
183 max[2] = min[2] + this->hZ;
192template <
typename TIds>
205 this->Map[numPts].
Bucket = numBuckets;
206 this->Offsets =
new TIds[numBuckets + 1];
207 this->Offsets[numBuckets] = numPts;
214 delete[] this->Offsets;
221 return (this->Offsets[bucketNum + 1] - this->Offsets[bucketNum]);
227 return this->Map + this->Offsets[bucketNum];
236 for (
int i = 0; i < numIds; i++)
238 bList->
SetId(i, ids[i].PtId);
245 double radius,
const double x[3],
double inputDataLength,
double& dist2);
248 double minDist2 = (-0.1),
bool sort =
true,
vtkDoubleArray* petals =
nullptr);
258 NeighborBuckets* buckets,
const double x[3],
const int ijk[3],
double dist,
int level);
260 int prevMinLevel[3],
int prevMaxLevel[3]);
263 template <
typename T>
280 for (; ptId < end; ++ptId, ++t)
289 template <
typename T,
typename TPo
intsArray>
307 for (; ptId < end; ++ptId, ++x, ++t)
318 template <
typename TPo
intsArray>
330 template <
typename T>
341 this->NumPts = this->BList->
NumPts;
347 T* offsets = this->BList->
Offsets;
352 endBatchPt = (endBatchPt > endPt ? endPt : endBatchPt);
357 if (curPt == this->BList->
Map)
359 prevPt = this->BList->
Map;
360 std::fill_n(offsets, curPt->
Bucket + 1, 0);
375 for (curPt = prevPt; curPt < endBatchPt;)
377 for (; curPt->
Bucket == prevPt->
Bucket && curPt <= endBatchPt; ++curPt)
383 offsets + prevPt->
Bucket + 1, curPt->
Bucket - prevPt->
Bucket, curPt - this->BList->Map);
391 template <
typename T>
402 this->DataSet = blist->
DataSet;
414 for (; bucket < endBucket; ++bucket)
418 ids = bList->
GetIds(bucket);
419 for (i = 0; i < numIds; i++)
422 if (mergeMap[ptId] < 0)
424 mergeMap[ptId] = ptId;
426 for (j = i + 1; j < numIds; j++)
429 if (mergeMap[ptId2] < 0)
432 if (p[0] == p2[0] && p[1] == p2[1] && p[2] == p2[2])
434 mergeMap[ptId2] = ptId;
452 template <
typename T>
467 this->DataSet = blist->
DataSet;
476 if (mergeMap[ptId] < 0)
478 mergeMap[ptId] = ptId;
485 for (
auto i = 0; i < numIds; ++i)
488 if (mergeMap[nearId] < 0)
490 mergeMap[nearId] = ptId;
510 template <
typename T>
526 for (
vtkIdType ptId = 0; ptId < numPts; ++ptId)
550 template <
typename T>
565 double hMin = std::min({ bl->
hX, bl->
hY, bl->
hZ });
566 this->CheckerboardDimension =
572 for (
auto i = 0; i < 3; ++i)
575 static_cast<double>(bl->
Divisions[i]) /
static_cast<double>(this->CheckerboardDimension);
577 this->NumBlocks *= this->BlockDims[i];
587 this->CheckerboardIndex[0] = 0;
588 this->CheckerboardIndex[1] = 0;
589 this->CheckerboardIndex[2] = 0;
590 return this->CheckerboardIndex;
604 for (
auto i = 0; i < 3; ++i)
606 ijk[i] = ijk[i] * this->CheckerboardDimension + cIdx[i];
607 if (ijk[i] >= this->
BList->Divisions[i])
614 return (ijk[0] + ijk[1] * this->
BList->Divisions[0] +
615 ijk[2] * this->BList->Divisions[0] * this->BList->Divisions[1]);
624 for (; blockId < endBlockId; ++blockId)
629 if (bin >= 0 && (numIds = this->
BList->GetNumberOfIds(bin)) > 0)
632 for (
auto i = 0; i < numIds; ++i)
652 int cDim = this->CheckerboardDimension;
657 for (cIdx[2] = 0; cIdx[2] < cDim; ++cIdx[2])
659 for (cIdx[1] = 0; cIdx[1] < cDim; ++cIdx[1])
661 for (cIdx[0] = 0; cIdx[0] < cDim; ++cIdx[0])
674 template <
typename T>
689 this->DataSet = blist->
DataSet;
694 for (
auto i = 0; i < tupleSize; ++i)
707 this->Tuple.
Local().resize(numComp);
708 this->Tuple2.
Local().resize(numComp);
719 int tupleSize =
static_cast<int>(this->Tuple.
Local().size());
720 double* t = this->Tuple.
Local().data();
721 double*
t2 = this->Tuple2.
Local().data();
723 for (; bucket < endBucket; ++bucket)
727 ids = bList->
GetIds(bucket);
728 for (i = 0; i < numIds; i++)
731 if (mergeMap[ptId] < 0)
733 mergeMap[ptId] = ptId;
736 for (j = i + 1; j < numIds; j++)
739 if (mergeMap[ptId2] < 0)
742 if (p[0] == p2[0] && p[1] == p2[1] && p[2] == p2[2])
747 mergeMap[ptId2] = ptId;
765 auto points = this->
DataSet->GetPoints()->GetData();
768 points, worker,
this))
770 worker(points,
this);
787 int numBatches =
static_cast<int>(ceil(
static_cast<double>(this->
NumPts) / this->
BatchSize));
ValueType * GetPointer(vtkIdType valueIdx)
Get the address of a particular data index.
int GetNumberOfComponents() const
Set/Get the dimension (n) of the components.
static bool InsideSphere(const double min[3], const double max[3], const double center[3], double r2)
Determine if a box is fully inside a sphere.
object to represent cell connectivity
virtual double * GetTuple(vtkIdType tupleIdx)=0
Get the data tuple at tupleIdx.
abstract class to specify dataset behavior
virtual double * GetPoint(vtkIdType ptId)=0
Get point coordinates with ptId such that: 0 <= ptId < NumberOfPoints.
dynamic, self-adjusting array of double
static vtkDoubleArray * SafeDownCast(vtkObjectBase *o)
list of point or cell ids
void SetNumberOfIds(vtkIdType number)
Specify the number of ids for this object to hold.
vtkIdType GetNumberOfIds() const noexcept
Return the number of id's in the list.
vtkIdType GetId(vtkIdType i)
Return the id at location i.
void SetId(vtkIdType i, vtkIdType id)
Set the id at location i.
vtkTypeBool Reserve(vtkIdType size)
Reserve the id list to the requested number of ids and preserve data.
virtual vtkDataSet * GetDataSet()
Build the locator from the points/cells defining this dataset.
static int Ceil(double x)
Rounds a double to the nearest integer not less than itself.
static int Floor(double x)
Rounds a double to the nearest integer not greater than itself.
represent and manipulate 3D points
concrete dataset represents vertices, lines, polygons, and triangle strips
Thread local storage for VTK objects.
T *& Local()
Returns an object local to the current thread.
Thread local storage for VTK objects.
T & Local()
This needs to be called mainly within a threaded execution path.
quickly locate points in 3-space
virtual double * GetBounds()
Provide an accessor to the bounds.
virtual double * GetSpacing()
Provide an accessor to the bucket spacing.
virtual int * GetDivisions()
Set the number of divisions in x-y-z directions.
static void ComputePointStructuredCoords(vtkIdType ptId, const int dim[3], int ijk[3], int dataDescription=vtkStructuredData::VTK_STRUCTURED_EMPTY)
Given a pointId and grid dimensions 'dim', get the structured coordinates (i-j-k).
A SafeCastFromDouble(double value)
Cast from double, and clamp to output type limits to avoid overlow.
VTK_ITER_INLINE auto DataArrayTupleRange(const ArrayTypePtr &array, TupleIdType start=-1, TupleIdType end=-1) -> typename detail::SelectTupleRange< ArrayTypePtr, TupleSize >::type
Generate an stl and for-range compatible range of tuple iterators from a vtkDataArray.
MapDataSet(BucketList< T > *blist, vtkDataSet *ds)
void operator()(vtkIdType ptId, vtkIdType end)
void operator()(vtkIdType batch, vtkIdType batchEnd)
MapOffsets(BucketList< T > *blist)
void operator()(TPointsArray *points, BucketList *blist)
void operator()(vtkIdType ptId, vtkIdType end)
MapPointsArray(BucketList< T > *blist, TPointsArray *pts)
void operator()(vtkIdType blockId, vtkIdType endBlockId)
MergeBinOrder(BucketList< T > *blist, double tol, vtkIdType *mergeMap)
int * InitializeCheckerboardIndex()
vtkIdType GetCurrentBin(int blockId, int cIdx[3])
int CheckerboardDimension
vtkSMPThreadLocalObject< vtkIdList > PIds
void MergePoint(vtkIdType ptId, vtkIdList *nearby)
MergeClose(BucketList< T > *blist, double tol, vtkIdType *mergeMap)
void operator()(vtkIdType numPts)
MergePointOrder(BucketList< T > *blist, double tol, vtkIdType *mergeMap)
MergePointsAndData(BucketList< T > *blist, vtkDataArray *da, vtkIdType *mergeMap)
bool TuplesEqual(int tupleSize, double *t1, double *t2)
vtkSMPThreadLocal< std::vector< double > > Tuple
void operator()(vtkIdType bucket, vtkIdType endBucket)
vtkSMPThreadLocal< std::vector< double > > Tuple2
MergePrecise(BucketList< T > *blist, vtkIdType *mergeMap)
void operator()(vtkIdType bucket, vtkIdType endBucket)
void GetIds(vtkIdType bucketNum, vtkIdList *bList)
BucketList(vtkStaticPointLocator *loc, vtkIdType numPts, int numBuckets)
void GetOverlappingBuckets(NeighborBuckets *buckets, const double x[3], double dist, int prevMinLevel[3], int prevMaxLevel[3])
double FindNPointsInShell(int N, const double x[3], vtkDist2TupleArray &results, double minDist2=(-0.1), bool sort=true, vtkDoubleArray *petals=nullptr)
void GenerateRepresentation(int level, vtkPolyData *pd)
void MergePointsWithData(vtkDataArray *data, vtkIdType *pointMap)
vtkIdType FindClosestPoint(const double x[3])
vtkIdType GetNumberOfIds(vtkIdType bucketNum)
void FindPointsWithinRadius(double R, const double x[3], vtkIdList *result)
vtkLocatorTuple< TIds > * Map
void BuildLocator() override
const vtkLocatorTuple< TIds > * GetIds(vtkIdType bucketNum)
vtkIdType FindClosestPointWithinRadius(double radius, const double x[3], double inputDataLength, double &dist2)
int IntersectWithLine(double a0[3], double a1[3], double tol, double &t, double lineX[3], double ptX[3], vtkIdType &ptId)
void GetOverlappingBuckets(NeighborBuckets *buckets, const double x[3], const int ijk[3], double dist, int level)
void MergePoints(double tol, vtkIdType *pointMap, int orderingMode)
void FindClosestNPoints(int N, const double x[3], vtkIdList *result)
Dispatch a single array against all array types mentioned in the ArrayList template parameter.
void GenerateFace(int face, int i, int j, int k, vtkPoints *pts, vtkCellArray *polys)
vtkIdType GetBucketIndex(const double *x) const
virtual void BuildLocator()=0
void GetBucketNeighbors(NeighborBuckets *buckets, const int ijk[3], const int ndivs[3], int level)
vtkBucketList(vtkStaticPointLocator *loc, vtkIdType numPts, int numBuckets)
double Distance2ToBucket(const double x[3], const int nei[3])
virtual ~vtkBucketList()=default
vtkStaticPointLocator * Locator
double Distance2ToBounds(const double x[3], const double bounds[6])
bool BucketInsideSphere(int i, int j, int k, const double center[3], double r2)
void GetBucketIndices(const double *x, int ijk[3]) const
void GetBucketBounds(int i, int j, int k, double min[3], double max[3])
void GetBucketCenter(int i, int j, int k, double center[3])
Represent an array of vtkDist2Tuples.
STL-compatible iterable ranges that provide access to vtkDataArray elements.