13#ifndef vtkStaticPointLocatorPrivate_h
14#define vtkStaticPointLocatorPrivate_h
30VTK_ABI_NAMESPACE_BEGIN
47struct NeighborBuckets;
77 this->NumPts = numPts;
78 this->NumBuckets = numBuckets;
79 this->BatchSize = 10000;
84 double spacing[3], bounds[6];
88 this->hX = this->H[0] = spacing[0];
89 this->hY = this->H[1] = spacing[1];
90 this->hZ = this->H[2] = spacing[2];
91 this->hX2 = this->hX / 2.0;
92 this->hY2 = this->hY / 2.0;
93 this->hZ2 = this->hZ / 2.0;
94 this->fX = 1.0 / spacing[0];
95 this->fY = 1.0 / spacing[1];
96 this->fZ = 1.0 / spacing[2];
97 this->bX = this->Bounds[0] = bounds[0];
98 this->Bounds[1] = bounds[1];
99 this->bY = this->Bounds[2] = bounds[2];
100 this->Bounds[3] = bounds[3];
101 this->bZ = this->Bounds[4] = bounds[4];
102 this->Bounds[5] = bounds[5];
103 this->xD = this->Divisions[0];
104 this->yD = this->Divisions[1];
105 this->zD = this->Divisions[2];
106 this->xyD = this->Divisions[0] * this->Divisions[1];
108 this->FastPoints =
nullptr;
109 this->BinRadius = sqrt(
hX *
hX +
hY *
hY +
hZ *
hZ) / 2.0;
110 this->MaxLevel = std::max({ this->xD, this->yD, this->zD });
119 NeighborBuckets* buckets,
const int ijk[3],
const int ndivs[3],
int level);
134 ijk[0] = tmp0 < 0 ? 0 : std::min(
xD - 1, tmp0);
135 ijk[1] = tmp1 < 0 ? 0 : std::min(
yD - 1, tmp1);
136 ijk[2] = tmp2 < 0 ? 0 : std::min(
zD - 1, tmp2);
144 return ijk[0] + ijk[1] *
xD + ijk[2] *
xyD;
151 center[0] = this->bX + this->hX2 + i * this->hX;
152 center[1] = this->bY + this->hY2 + j * this->hY;
153 center[2] = this->bZ + this->hZ2 + k * this->hZ;
160 min[0] = this->bX + i * this->hX;
161 min[1] = this->bY + j * this->hY;
162 min[2] = this->bZ + k * this->hZ;
163 max[0] = min[0] + this->hX;
164 max[1] = min[1] + this->hY;
165 max[2] = min[2] + this->hZ;
173 double min[3],
max[3];
174 min[0] = this->bX + i * this->hX;
175 min[1] = this->bY + j * this->hY;
176 min[2] = this->bZ + k * this->hZ;
188template <
typename TIds>
201 this->Map[numPts].
Bucket = numBuckets;
202 this->Offsets =
new TIds[numBuckets + 1];
203 this->Offsets[numBuckets] = numPts;
210 delete[] this->Offsets;
217 return (this->Offsets[bucketNum + 1] - this->Offsets[bucketNum]);
223 return this->Map + this->Offsets[bucketNum];
232 for (
int i = 0; i < numIds; i++)
234 bList->
SetId(i, ids[i].PtId);
241 double radius,
const double x[3],
double inputDataLength,
double& dist2);
244 double minDist2 = (-0.1),
bool sort =
true,
vtkDoubleArray* petals =
nullptr);
254 NeighborBuckets* buckets,
const double x[3],
const int ijk[3],
double dist,
int level);
256 int prevMinLevel[3],
int prevMaxLevel[3]);
259 template <
typename T>
276 for (; ptId < end; ++ptId, ++t)
285 template <
typename T,
typename TPo
intsArray>
303 for (; ptId < end; ++ptId, ++x, ++t)
314 template <
typename TPo
intsArray>
326 template <
typename T>
337 this->NumPts = this->BList->
NumPts;
343 T* offsets = this->BList->
Offsets;
348 endBatchPt = (endBatchPt > endPt ? endPt : endBatchPt);
353 if (curPt == this->BList->
Map)
355 prevPt = this->BList->
Map;
356 std::fill_n(offsets, curPt->
Bucket + 1, 0);
371 for (curPt = prevPt; curPt < endBatchPt;)
373 for (; curPt->
Bucket == prevPt->
Bucket && curPt <= endBatchPt; ++curPt)
379 offsets + prevPt->
Bucket + 1, curPt->
Bucket - prevPt->
Bucket, curPt - this->BList->Map);
387 template <
typename T>
398 this->DataSet = blist->
DataSet;
410 for (; bucket < endBucket; ++bucket)
414 ids = bList->
GetIds(bucket);
415 for (i = 0; i < numIds; i++)
418 if (mergeMap[ptId] < 0)
420 mergeMap[ptId] = ptId;
422 for (j = i + 1; j < numIds; j++)
425 if (mergeMap[ptId2] < 0)
428 if (p[0] == p2[0] && p[1] == p2[1] && p[2] == p2[2])
430 mergeMap[ptId2] = ptId;
448 template <
typename T>
463 this->DataSet = blist->
DataSet;
472 if (mergeMap[ptId] < 0)
474 mergeMap[ptId] = ptId;
481 for (
auto i = 0; i < numIds; ++i)
484 if (mergeMap[nearId] < 0)
486 mergeMap[nearId] = ptId;
506 template <
typename T>
522 for (
vtkIdType ptId = 0; ptId < numPts; ++ptId)
546 template <
typename T>
561 double hMin = std::min({ bl->
hX, bl->
hY, bl->
hZ });
562 this->CheckerboardDimension =
568 for (
auto i = 0; i < 3; ++i)
571 static_cast<double>(bl->
Divisions[i]) /
static_cast<double>(this->CheckerboardDimension);
573 this->NumBlocks *= this->BlockDims[i];
583 this->CheckerboardIndex[0] = 0;
584 this->CheckerboardIndex[1] = 0;
585 this->CheckerboardIndex[2] = 0;
586 return this->CheckerboardIndex;
600 for (
auto i = 0; i < 3; ++i)
602 ijk[i] = ijk[i] * this->CheckerboardDimension + cIdx[i];
603 if (ijk[i] >= this->
BList->Divisions[i])
610 return (ijk[0] + ijk[1] * this->
BList->Divisions[0] +
611 ijk[2] * this->BList->Divisions[0] * this->BList->Divisions[1]);
620 for (; blockId < endBlockId; ++blockId)
625 if (bin >= 0 && (numIds = this->
BList->GetNumberOfIds(bin)) > 0)
628 for (
auto i = 0; i < numIds; ++i)
648 int cDim = this->CheckerboardDimension;
653 for (cIdx[2] = 0; cIdx[2] < cDim; ++cIdx[2])
655 for (cIdx[1] = 0; cIdx[1] < cDim; ++cIdx[1])
657 for (cIdx[0] = 0; cIdx[0] < cDim; ++cIdx[0])
670 template <
typename T>
685 this->DataSet = blist->
DataSet;
690 for (
auto i = 0; i < tupleSize; ++i)
703 this->Tuple.
Local().resize(numComp);
704 this->Tuple2.
Local().resize(numComp);
715 int tupleSize =
static_cast<int>(this->Tuple.
Local().size());
716 double* t = this->Tuple.
Local().data();
717 double*
t2 = this->Tuple2.
Local().data();
719 for (; bucket < endBucket; ++bucket)
723 ids = bList->
GetIds(bucket);
724 for (i = 0; i < numIds; i++)
727 if (mergeMap[ptId] < 0)
729 mergeMap[ptId] = ptId;
732 for (j = i + 1; j < numIds; j++)
735 if (mergeMap[ptId2] < 0)
738 if (p[0] == p2[0] && p[1] == p2[1] && p[2] == p2[2])
743 mergeMap[ptId2] = ptId;
761 auto points = this->
DataSet->GetPoints()->GetData();
764 points, worker,
this))
766 worker(points,
this);
777 int numBatches =
static_cast<int>(ceil(
static_cast<double>(this->
NumPts) / this->
BatchSize));
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)
Performant method to determine if box if 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
list of point or cell ids
void SetNumberOfIds(vtkIdType number)
Specify the number of ids for this object to hold.
int Allocate(vtkIdType sz, int strategy=0)
Allocate a capacity for sz ids in the list and set the number of stored ids in the list to 0.
vtkIdType GetNumberOfIds() const noexcept
Return the number of id's in the list.
void SetId(vtkIdType i, vtkIdType vtkid)
Set the id at location i.
vtkIdType GetId(vtkIdType i)
Return the id at location i.
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).
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, 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.