VTK  9.7.1
vtkStaticPointLocator2DPrivate.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
2 // SPDX-FileCopyrightText: Copyright 2011 Sandia Corporation
3 // SPDX-License-Identifier: LicenseRef-BSD-3-Clause-Sandia-USGov
13 #ifndef vtkStaticPointLocator2DPrivate_h
14 #define vtkStaticPointLocator2DPrivate_h
15 
16 #include "vtkArrayDispatch.h"
18 #include "vtkCellArray.h"
19 #include "vtkDataArrayRange.h"
20 #include "vtkDataSet.h"
21 #include "vtkDoubleArray.h"
22 #include "vtkMath.h"
23 #include "vtkMathUtilities.h" // for SafeCastFromDouble
24 #include "vtkPoints.h"
26 #include "vtkSMPTools.h"
28 #include "vtkStructuredData.h"
29 
30 VTK_ABI_NAMESPACE_BEGIN
31 
32 #define Distance2BetweenPoints2D(p1, p2) \
33  ((p1[0] - p2[0]) * (p1[0] - p2[0]) + (p1[1] - p2[1]) * (p1[1] - p2[1]))
34 
40 inline bool IntersectsCircle(
41  const double min[2], const double max[2], const double center[2], double r2)
42 {
43  double d2 = 0.0;
44  for (int i = 0; i < 2; ++i)
45  {
46  if (center[i] < min[i])
47  {
48  d2 += (center[i] - min[i]) * (center[i] - min[i]);
49  }
50  else if (center[i] > max[i])
51  {
52  d2 += (center[i] - max[i]) * (center[i] - max[i]);
53  }
54  }
55  return (d2 <= r2);
56 }
57 
63 inline bool InsideCircle(
64  const double min[2], const double max[2], const double center[2], double r2)
65 {
66  double dmin = 0.0, dmax = 0.0;
67  for (int i = 0; i < 2; ++i)
68  {
69  double a = (center[i] - min[i]) * (center[i] - min[i]);
70  double b = (center[i] - max[i]) * (center[i] - max[i]);
71  dmax += std::max(a, b);
72  if (min[i] <= center[i] && center[i] <= max[i])
73  {
74  dmin += std::min(a, b);
75  }
76  }
77  return (!(dmin <= r2 && r2 <= dmax));
78 }
79 
80 //------------------------------------------------------------------------------
81 // The following code supports threaded point locator construction. The locator
82 // is assumed to be constructed once (i.e., it does not allow incremental point
83 // insertion). The algorithm proceeds in three steps:
84 // 1) All points are assigned a bucket index (combined i-j bucket location).
85 // The index is computed in parallel. This requires a one time allocation of an
86 // index array (which is also associated with the originating point ids).
87 // 2) vtkSMPTools::Sort() is used to sort the index array. Note that the sort
88 // carries along the point ids as well. This creates contiguous runs of points
89 // all resident in the same bucket.
90 // 3) The bucket offsets are updated to refer to the right entry location into
91 // the sorted point ids array. This enables quick access, and an indirect count
92 // of the number of points in each bucket.
93 
94 struct NeighborBuckets2D;
95 
96 //------------------------------------------------------------------------------
97 // The bucketed points, including the sorted map. This is just a PIMPLd
98 // wrapper around the classes that do the real work.
100 {
102  vtkIdType NumPts; // the number of points to bucket
105 
106  // These are internal data members used for performance reasons
108  int Divisions[3];
109  double Bounds[6];
110  double H[3];
111  double hX, hY, hX2, hY2;
112  double fX, fY, bX, bY;
114 
115  // Used for accelerated performance for certain methods
116  double* FastPoints; // fast path for accessing points
117  double BinRadius; // circumradius of a single bin/bucket
118  int MaxLevel; // the maximum possible level searches can proceed
119 
120  // Construction
121  vtkBucketList2D(vtkStaticPointLocator2D* loc, vtkIdType numPts, int numBuckets)
122  {
123  this->Locator = loc;
124  this->NumPts = numPts;
125  this->NumBuckets = numBuckets;
126  this->BatchSize = 10000; // building the offset array
127  this->DataSet = loc->GetDataSet();
128 
129  // Setup internal data members for more efficient processing. Remember this is
130  // a 2D locator so just processing (x,y) points.
131  double spacing[3], bounds[6];
132  loc->GetDivisions(this->Divisions);
133  loc->GetSpacing(spacing);
134  loc->GetBounds(bounds);
135  this->hX = this->H[0] = spacing[0];
136  this->hY = this->H[1] = spacing[1];
137  this->hX2 = this->hX / 2.0;
138  this->hY2 = this->hY / 2.0;
139  this->fX = 1.0 / spacing[0];
140  this->fY = 1.0 / spacing[1];
141  this->bX = this->Bounds[0] = bounds[0];
142  this->Bounds[1] = bounds[1];
143  this->bY = this->Bounds[2] = bounds[2];
144  this->Bounds[3] = bounds[3];
145  this->xD = this->Divisions[0];
146  this->yD = this->Divisions[1];
147  this->zD = 1;
148 
149  this->FastPoints = nullptr;
150  this->BinRadius = sqrt(hX * hX + hY * hY) / 2.0;
151  this->MaxLevel = std::max({ this->xD, this->yD, this->zD });
152  }
153 
154  // Virtuals for templated subclasses
155  virtual ~vtkBucketList2D() = default;
156  virtual void BuildLocator() = 0;
157 
158  // place points in appropriate buckets
159  void GetBucketNeighbors(
160  NeighborBuckets2D* buckets, const int ij[2], const int ndivs[2], int level);
161  void GenerateFace(int face, int i, int j, int k, vtkPoints* pts, vtkCellArray* polys);
162  double Distance2ToBucket(const double x[3], const int nei[3]);
163  double Distance2ToBounds(const double x[3], const double bounds[6]);
164 
165  //-----------------------------------------------------------------------------
166  // Inlined for performance. These function invocations must be called after
167  // BuildLocator() is invoked, otherwise the output is indeterminate.
168  void GetBucketIndices(const double* x, int ij[2]) const
169  {
170  // Compute point index. SafeCastFromDouble clamps to the integer type limits
171  // (mapping NaN to 0) so casting a coordinate far outside the locator bounds
172  // (e.g. VTK_DOUBLE_MAX) is not undefined behavior. Make sure it then lies
173  // within the range of the locator.
174  vtkIdType tmp0 = vtkMathUtilities::SafeCastFromDouble<vtkIdType>((x[0] - bX) * fX);
175  vtkIdType tmp1 = vtkMathUtilities::SafeCastFromDouble<vtkIdType>((x[1] - bY) * fY);
176 
177  ij[0] = std::min(std::max<vtkIdType>(tmp0, 0), xD - 1);
178  ij[1] = std::min(std::max<vtkIdType>(tmp1, 0), yD - 1);
179  }
180 
181  //-----------------------------------------------------------------------------
182  vtkIdType GetBucketIndex(const double* x) const
183  {
184  int ij[2];
185  this->GetBucketIndices(x, ij);
186  return ij[0] + ij[1] * xD;
187  }
188 
189  //-----------------------------------------------------------------------------
190  // Return the center of the bucket/bin at (i,j). Note, returns a 2D point
191  // center[2].
192  void GetBucketCenter(int i, int j, double center[3])
193  {
194  center[0] = this->bX + this->hX2 + i * this->hX;
195  center[1] = this->bY + this->hY2 + j * this->hY;
196  center[2] = 0.0;
197  }
198 
199  //-----------------------------------------------------------------------------
200  // Return the bounding box (min,max) of a specified bucket (i,j,k).
201  void GetBucketBounds(int i, int j, double min[3], double max[3])
202  {
203  min[0] = this->bX + i * this->hX;
204  min[1] = this->bY + j * this->hY;
205  min[2] = 0.0;
206  max[0] = min[0] + this->hX;
207  max[1] = min[1] + this->hY;
208  max[2] = 0.0;
209  }
210 
211  //-----------------------------------------------------------------------------
212  // Determine whether a bin/bucket specified by i,j is completely contained
213  // inside the circle (center,r2). Return true if contained; false otherwise.
214  bool BucketInsideCircle(int i, int j, const double center[3], double r2)
215  {
216  double xMin = this->bX + i * this->hX;
217  double xMax = xMin + this->hX;
218  double yMin = this->bY + j * this->hY;
219  double yMax = yMin + this->hY;
220  double dx0 = center[0] - xMin, dx1 = center[0] - xMax;
221  double dy0 = center[1] - yMin, dy1 = center[1] - yMax;
222  double dmax2 = std::max(dx0 * dx0, dx1 * dx1) + std::max(dy0 * dy0, dy1 * dy1);
223  return dmax2 <= r2;
224  }
225 }; // vtkBucketList2D
226 
227 //------------------------------------------------------------------------------
228 // This templated class manages the creation of the static locator
229 // structures. It also implements the operator() functors which are supplied
230 // to vtkSMPTools for threaded processesing.
231 template <typename TIds>
233 {
234  // Okay the various ivars
235  vtkLocatorTuple<TIds>* Map; // the map to be sorted
236  TIds* Offsets; // offsets for each bucket into the map
237 
238  // Construction
239  BucketList2D(vtkStaticPointLocator2D* loc, vtkIdType numPts, int numBuckets)
240  : vtkBucketList2D(loc, numPts, numBuckets)
241  {
242  // one extra to simplify traversal
243  this->Map = new vtkLocatorTuple<TIds>[numPts + 1];
244  this->Map[numPts].Bucket = numBuckets;
245  this->Offsets = new TIds[numBuckets + 1];
246  this->Offsets[numBuckets] = numPts;
247  }
248 
249  // Release allocated memory
250  ~BucketList2D() override
251  {
252  delete[] this->Map;
253  delete[] this->Offsets;
254  }
255 
256  // The number of point ids in a bucket is determined by computing the
257  // difference between the offsets into the sorted points array.
259  {
260  if (bucketNum < 0 || bucketNum >= this->NumBuckets)
261  {
262  return 0;
263  }
264  return (this->Offsets[bucketNum + 1] - this->Offsets[bucketNum]);
265  }
266 
267  // Given a bucket number, return the point ids in that bucket.
269  {
270  return this->Map + this->Offsets[bucketNum];
271  }
272 
273  // Given a bucket number, return the point ids in that bucket.
274  void GetIds(vtkIdType bucketNum, vtkIdList* bList)
275  {
276  const vtkLocatorTuple<TIds>* ids = this->GetIds(bucketNum);
277  vtkIdType numIds = this->GetNumberOfIds(bucketNum);
278  bList->SetNumberOfIds(numIds);
279  for (int i = 0; i < numIds; i++)
280  {
281  bList->SetId(i, ids[i].PtId);
282  }
283  }
284 
285  // Templated implementations of the locator
286  vtkIdType FindClosestPoint(const double x[3]);
288  double radius, const double x[3], double inputDataLength, double& dist2);
289  void FindClosestNPoints(int N, const double x[3], vtkIdList* result);
290  double FindNPointsInAnnulus(int N, const double x[3], vtkDist2TupleArray& results,
291  double minDist2 = (-0.1), bool sort = true, vtkDoubleArray* petals = nullptr);
292  void FindPointsWithinRadius(double R, const double x[3], vtkIdList* result);
293  int IntersectWithLine(double a0[3], double a1[3], double tol, double& t, double lineX[3],
294  double ptX[3], vtkIdType& ptId);
295  double FindCloseNBoundedPoints(int N, const double x[3], vtkIdList* result);
296 
297  void MergePoints(double tol, vtkIdType* pointMap);
298  void GenerateRepresentation(int vtkNotUsed(level), vtkPolyData* pd);
299 
300  // Internal methods
301  bool BucketIntersectsCircle(int i, int j, const double center[3], double R2);
303  NeighborBuckets2D* buckets, const double x[3], const int ij[2], double dist, int level);
304  void GetOverlappingBuckets(NeighborBuckets2D* buckets, const double x[3], double dist,
305  int prevMinLevel[2], int prevMaxLevel[2]);
306 
307  // Implicit point representation, slower path
308  template <typename T>
309  struct MapDataSet
310  {
313 
315  : BList(blist)
316  , DataSet(ds)
317  {
318  }
319 
321  {
322  double p[3];
323  vtkLocatorTuple<T>* t = this->BList->Map + ptId;
324  for (; ptId < end; ++ptId, ++t)
325  {
326  this->DataSet->GetPoint(ptId, p);
327  t->PtId = ptId;
328  t->Bucket = this->BList->GetBucketIndex(p);
329  } // for all points in this batch
330  }
331  };
332 
333  template <typename T, typename TPointsArray>
335  {
337  TPointsArray* Points;
338 
339  MapPointsArray(BucketList2D<T>* blist, TPointsArray* pts)
340  : BList(blist)
341  , Points(pts)
342  {
343  }
344 
346  {
347  double p[3];
348  auto x = vtk::DataArrayTupleRange<3>(this->Points, ptId, end).begin();
349  vtkLocatorTuple<T>* t = this->BList->Map + ptId;
350  for (; ptId < end; ++ptId, ++x, ++t)
351  {
352  x->GetTuple(p);
353  t->PtId = ptId;
354  t->Bucket = this->BList->GetBucketIndex(p);
355  } // for all points in this batch
356  }
357  };
358 
360  {
361  template <typename TPointsArray>
362  void operator()(TPointsArray* points, BucketList2D* blist)
363  {
364  MapPointsArray<TIds, TPointsArray> mapper(blist, points);
365  vtkSMPTools::For(0, blist->NumPts, mapper);
366  }
367  };
368 
369  // A clever way to build offsets in parallel. Basically each thread builds
370  // offsets across a range of the sorted map. Recall that offsets are an
371  // integral value referring to the locations of the sorted points that
372  // reside in each bucket.
373  template <typename T>
374  struct MapOffsets
375  {
379 
381  : BList(blist)
382  {
383  this->NumPts = this->BList->NumPts;
384  this->NumBuckets = this->BList->NumBuckets;
385  }
386 
387  // Traverse sorted points (i.e., tuples) and update bucket offsets.
388  void operator()(vtkIdType batch, vtkIdType batchEnd)
389  {
390  T* offsets = this->BList->Offsets;
391  const vtkLocatorTuple<T>* curPt = this->BList->Map + batch * this->BList->BatchSize;
392  const vtkLocatorTuple<T>* endBatchPt = this->BList->Map + batchEnd * this->BList->BatchSize;
393  const vtkLocatorTuple<T>* endPt = this->BList->Map + this->NumPts;
394  const vtkLocatorTuple<T>* prevPt;
395  endBatchPt = (endBatchPt > endPt ? endPt : endBatchPt);
396 
397  // Special case at the very beginning of the mapped points array. If
398  // the first point is in bucket# N, then all buckets up and including
399  // N must refer to the first point.
400  if (curPt == this->BList->Map)
401  {
402  prevPt = this->BList->Map;
403  std::fill_n(offsets, curPt->Bucket + 1, 0); // point to the first points
404  } // at the very beginning of the map (sorted points array)
405 
406  // We are entering this functor somewhere in the interior of the
407  // mapped points array. All we need to do is point to the entry
408  // position because we are interested only in prevPt->Bucket.
409  else
410  {
411  prevPt = curPt;
412  } // else in the middle of a batch
413 
414  // Okay we have a starting point for a bucket run. Now we can begin
415  // filling in the offsets in this batch. A previous thread should
416  // have/will have completed the previous and subsequent runs outside
417  // of the [batch,batchEnd) range
418  for (curPt = prevPt; curPt < endBatchPt;)
419  {
420  for (; curPt->Bucket == prevPt->Bucket && curPt <= endBatchPt; ++curPt)
421  {
422  // advance
423  }
424  // Fill in any gaps in the offset array
425  std::fill_n(
426  offsets + prevPt->Bucket + 1, curPt->Bucket - prevPt->Bucket, curPt - this->BList->Map);
427  prevPt = curPt;
428  } // for all batches in this range
429  } // operator()
430  };
431 
432  // Merge points that are pecisely coincident. Operates in parallel on
433  // locator buckets. Does not need to check neighbor buckets.
434  template <typename T>
436  {
440 
442  : BList(blist)
443  , MergeMap(mergeMap)
444  {
445  this->DataSet = blist->DataSet;
446  }
447 
448  void operator()(vtkIdType bucket, vtkIdType endBucket)
449  {
450  BucketList2D<T>* bList = this->BList;
451  vtkIdType* mergeMap = this->MergeMap;
452  int i, j;
453  const vtkLocatorTuple<TIds>* ids;
454  double p[3], p2[3];
455  vtkIdType ptId, ptId2, numIds;
456 
457  for (; bucket < endBucket; ++bucket)
458  {
459  if ((numIds = bList->GetNumberOfIds(bucket)) > 0)
460  {
461  ids = bList->GetIds(bucket);
462  for (i = 0; i < numIds; i++)
463  {
464  ptId = ids[i].PtId;
465  if (mergeMap[ptId] < 0)
466  {
467  mergeMap[ptId] = ptId;
468  this->DataSet->GetPoint(ptId, p);
469  for (j = i + 1; j < numIds; j++)
470  {
471  ptId2 = ids[j].PtId;
472  if (mergeMap[ptId2] < 0)
473  {
474  this->DataSet->GetPoint(ptId2, p2);
475  if (p[0] == p2[0] && p[1] == p2[1])
476  {
477  mergeMap[ptId2] = ptId;
478  }
479  }
480  }
481  } // if point not yet visited
482  }
483  }
484  }
485  }
486  };
487 
488  // Merge points that are coincident within a tolerance. Operates in
489  // parallel on points. Needs to check neighbor buckets which slows it down
490  // considerably. Note that merging is one direction: larger ids are merged
491  // to lower.
492  template <typename T>
493  struct MergeClose
494  {
498  double Tol;
499 
501 
502  MergeClose(BucketList2D<T>* blist, double tol, vtkIdType* mergeMap)
503  : BList(blist)
504  , MergeMap(mergeMap)
505  , Tol(tol)
506  {
507  this->DataSet = blist->DataSet;
508  }
509 
510  // Just allocate a little bit of memory to get started.
511  void Initialize()
512  {
513  vtkIdList*& pIds = this->PIds.Local();
514  pIds->Reserve(128); // allocate some memory
515  }
516 
517  void operator()(vtkIdType ptId, vtkIdType endPtId)
518  {
519  BucketList2D<T>* bList = this->BList;
520  vtkIdType* mergeMap = this->MergeMap;
521  int i;
522  double p[3];
523  vtkIdType nearId, numIds;
524  vtkIdList*& nearby = this->PIds.Local();
525 
526  for (; ptId < endPtId; ++ptId)
527  {
528  if (mergeMap[ptId] < 0)
529  {
530  mergeMap[ptId] = ptId;
531  this->DataSet->GetPoint(ptId, p);
532  bList->FindPointsWithinRadius(this->Tol, p, nearby);
533  if ((numIds = nearby->GetNumberOfIds()) > 0)
534  {
535  for (i = 0; i < numIds; i++)
536  {
537  nearId = nearby->GetId(i);
538  if (ptId < nearId && (mergeMap[nearId] < 0 || ptId < mergeMap[nearId]))
539  {
540  mergeMap[nearId] = ptId;
541  }
542  }
543  }
544  } // if point not yet processed
545  } // for all points in this batch
546  }
547 
548  void Reduce() {}
549  };
550 
551  // Build the map and other structures to support locator operations
552  void BuildLocator() override
553  {
554  // Place each point in a bucket
555  auto points = this->DataSet->GetPoints()->GetData();
556  MapPointsArrayWorker worker;
558  points, worker, this))
559  {
560  worker(points, this);
561  }
562 
563  // Provide accelerated access to points. Needed for Voronoi bin iterators.
565  {
566  this->FastPoints = static_cast<double*>(vtkDoubleArray::SafeDownCast(points)->GetPointer(0));
567  }
568 
569  // Now gather the points into contiguous runs in buckets
570  //
571  vtkSMPTools::Sort(this->Map, this->Map + this->NumPts);
572 
573  // Build the offsets into the Map. The offsets are the positions of
574  // each bucket into the sorted list. They mark the beginning of the
575  // list of points in each bucket. Amazingly, this can be done in
576  // parallel.
577  //
578  int numBatches = static_cast<int>(ceil(static_cast<double>(this->NumPts) / this->BatchSize));
579  MapOffsets<TIds> offMapper(this);
580  vtkSMPTools::For(0, numBatches, offMapper);
581  }
582 }; // BucketList2D
583 
584 VTK_ABI_NAMESPACE_END
585 #endif // vtkStaticPointLocator2DPrivate_h
586 // VTK-HeaderTest-Exclude: vtkStaticPointLocator2DPrivate.h
RealT r2
Definition: PyrC2Basis.h:20
void FindClosestNPoints(int N, const double x[3], vtkIdList *result)
void operator()(vtkIdType batch, vtkIdType batchEnd)
virtual vtkPoints * GetPoints()
If the subclass has (implicit/explicit) points, then return them.
void operator()(vtkIdType ptId, vtkIdType end)
bool BucketInsideCircle(int i, int j, const double center[3], double r2)
void GetOverlappingBuckets(NeighborBuckets2D *buckets, const double x[3], const int ij[2], double dist, int level)
const vtkLocatorTuple< TIds > * GetIds(vtkIdType bucketNum)
virtual ~vtkBucketList2D()=default
void GetBucketCenter(int i, int j, double center[3])
void GenerateFace(int face, int i, int j, int k, vtkPoints *pts, vtkCellArray *polys)
void GetIds(vtkIdType bucketNum, vtkIdList *bList)
abstract class to specify dataset behavior
Definition: vtkDataSet.h:56
ValueType * GetPointer(vtkIdType valueIdx)
Get the address of a particular data index.
MapDataSet(BucketList2D< T > *blist, vtkDataSet *ds)
vtkIdType GetNumberOfIds(vtkIdType bucketNum)
virtual double * GetSpacing()
Provide an accessor to the bucket spacing.
bool IntersectsCircle(const double min[2], const double max[2], const double center[2], double r2)
Performant method to intersect a box with a circle.
bool BucketIntersectsCircle(int i, int j, const double center[3], double R2)
int vtkIdType
Definition: vtkType.h:363
concrete dataset represents vertices, lines, polygons, and triangle strips
Definition: vtkPolyData.h:71
MapOffsets(BucketList2D< T > *blist)
vtkIdType FindClosestPointWithinRadius(double radius, const double x[3], double inputDataLength, double &dist2)
static vtkDoubleArray * SafeDownCast(vtkObjectBase *o)
dynamic, self-adjusting array of double
MergeClose(BucketList2D< T > *blist, double tol, vtkIdType *mergeMap)
virtual int * GetDivisions()
Set the number of divisions in x-y directions.
bool InsideCircle(const double min[2], const double max[2], const double center[2], double r2)
Performant method to determine if a box if fully inside a circle.
void GetBucketIndices(const double *x, int ij[2]) const
vtkIdType GetId(vtkIdType i)
Return the id at location i.
Definition: vtkIdList.h:81
void SetId(vtkIdType i, vtkIdType id)
Set the id at location i.
Definition: vtkIdList.h:113
virtual vtkDataSet * GetDataSet()
Build the locator from the points/cells defining this dataset.
int IntersectWithLine(double a0[3], double a1[3], double tol, double &t, double lineX[3], double ptX[3], vtkIdType &ptId)
vtkIdType GetBucketIndex(const double *x) const
list of point or cell ids
Definition: vtkIdList.h:25
void MergePoints(double tol, vtkIdType *pointMap)
void GetBucketNeighbors(NeighborBuckets2D *buckets, const int ij[2], const int ndivs[2], int level)
static void Sort(RandomAccessIterator begin, RandomAccessIterator end)
A convenience method for sorting data.
Definition: vtkSMPTools.h:615
vtkLocatorTuple< TIds > * Map
vtkIdType GetNumberOfIds() const noexcept
Return the number of id's in the list.
Definition: vtkIdList.h:76
vtkSMPThreadLocalObject< vtkIdList > PIds
static void For(vtkIdType first, vtkIdType last, vtkIdType grain, Functor &f)
Execute a for operation in parallel.
Definition: vtkSMPTools.h:238
void GetBounds(double *bounds) override
Provide an accessor to the bounds.
Private declarations for 2D binned spatial locator.
double Distance2ToBucket(const double x[3], const int nei[3])
void GenerateRepresentation(int level, vtkPolyData *pd)
vtkStaticPointLocator2D * Locator
vtkTypeBool Reserve(vtkIdType size)
Reserve the id list to the requested number of ids and preserve data.
object to represent cell connectivity
Definition: vtkCellArray.h:177
double FindNPointsInAnnulus(int N, const double x[3], vtkDist2TupleArray &results, double minDist2=(-0.1), bool sort=true, vtkDoubleArray *petals=nullptr)
Represent an array of vtkDist2Tuples.
double Distance2ToBounds(const double x[3], const double bounds[6])
BucketList2D(vtkStaticPointLocator2D *loc, vtkIdType numPts, int numBuckets)
vtkIdType FindClosestPoint(const double x[3])
void GetBucketBounds(int i, int j, double min[3], double max[3])
void FindPointsWithinRadius(double R, const double x[3], vtkIdList *result)
virtual double * GetPoint(vtkIdType ptId)=0
Get point coordinates with ptId such that: 0 <= ptId < NumberOfPoints.
double FindCloseNBoundedPoints(int N, const double x[3], vtkIdList *result)
MergePrecise(BucketList2D< T > *blist, vtkIdType *mergeMap)
vtkDataArray * GetData()
Definition: vtkPoints.h:60
T *& Local()
Returns an object local to the current thread.
void operator()(vtkIdType bucket, vtkIdType endBucket)
void operator()(vtkIdType ptId, vtkIdType end)
void operator()(vtkIdType ptId, vtkIdType endPtId)
MapPointsArray(BucketList2D< T > *blist, TPointsArray *pts)
void SetNumberOfIds(vtkIdType number)
Specify the number of ids for this object to hold.
#define max(a, b)
represent and manipulate 3D points
Definition: vtkPoints.h:30
Dispatch a single array against all array types mentioned in the ArrayList template parameter...
vtkBucketList2D(vtkStaticPointLocator2D *loc, vtkIdType numPts, int numBuckets)
quickly locate points in 2-space
virtual void BuildLocator()=0
STL-compatible iterable ranges that provide access to vtkDataArray elements.
void operator()(TPointsArray *points, BucketList2D *blist)