VTK  9.7.1
vtkBoundingBox.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
2 // SPDX-License-Identifier: BSD-3-Clause
19 #ifndef vtkBoundingBox_h
20 #define vtkBoundingBox_h
21 #include "vtkCommonDataModelModule.h" // For export macro
22 #include "vtkSystemIncludes.h"
23 
24 #include <algorithm> // For std::min, std::max
25 #include <atomic> // For threaded bounding box computation
26 
27 VTK_ABI_NAMESPACE_BEGIN
28 class vtkPoints;
29 
30 class VTKCOMMONDATAMODEL_EXPORT vtkBoundingBox
31 {
32 public:
34 
42  vtkBoundingBox(const double bounds[6]);
46  vtkBoundingBox(double xMin, double xMax, double yMin, double yMax, double zMin, double zMax);
50  vtkBoundingBox(const double min[3], const double max[3]);
54  vtkBoundingBox(double center[3], double delta);
56 
60  vtkBoundingBox(const vtkBoundingBox& bbox);
61 
65  vtkBoundingBox& operator=(const vtkBoundingBox& bbox);
66 
68 
71  bool operator==(const vtkBoundingBox& bbox) const;
72  bool operator!=(const vtkBoundingBox& bbox) const;
74 
76 
80  void SetBounds(const double bounds[6]);
81  void SetBounds(double xMin, double xMax, double yMin, double yMax, double zMin, double zMax);
83 
85 
92  static void ComputeBounds(vtkPoints* pts, double bounds[6]);
93  static void ComputeBounds(vtkPoints* pts, const unsigned char* ptUses, double bounds[6]);
94  static void ComputeBounds(
95  vtkPoints* pts, const std::atomic<unsigned char>* ptUses, double bounds[6]);
96  template <typename TIter>
97  static void ComputeBounds(vtkPoints* pts, TIter ptIds, vtkIdType numPointIds, double bounds[6]);
99  {
100  double bds[6];
102  this->MinPnt[0] = bds[0];
103  this->MinPnt[1] = bds[2];
104  this->MinPnt[2] = bds[4];
105  this->MaxPnt[0] = bds[1];
106  this->MaxPnt[1] = bds[3];
107  this->MaxPnt[2] = bds[5];
108  }
109  void ComputeBounds(vtkPoints* pts, unsigned char* ptUses)
110  {
111  double bds[6];
112  vtkBoundingBox::ComputeBounds(pts, ptUses, bds);
113  this->MinPnt[0] = bds[0];
114  this->MinPnt[1] = bds[2];
115  this->MinPnt[2] = bds[4];
116  this->MaxPnt[0] = bds[1];
117  this->MaxPnt[1] = bds[3];
118  this->MaxPnt[2] = bds[5];
119  }
121 
123 
127  static void ComputeLocalBounds(
128  vtkPoints* points, double u[3], double v[3], double w[3], double outputBounds[6]);
130 
132 
136  void SetMinPoint(double x, double y, double z);
137  void SetMinPoint(double p[3]);
139 
141 
145  void SetMaxPoint(double x, double y, double z);
146  void SetMaxPoint(double p[3]);
148 
150 
154  int IsValid() const;
155  static int IsValid(const double bounds[6]);
157 
159 
163  void AddPoint(double p[3]);
164  void AddPoint(double px, double py, double pz);
166 
171  void AddBox(const vtkBoundingBox& bbox);
172 
177  void AddBounds(const double bounds[6]);
178 
182  bool IsSubsetOf(const vtkBoundingBox& bbox) const;
183 
189  int IntersectBox(const vtkBoundingBox& bbox);
190 
194  int Intersects(const vtkBoundingBox& bbox) const;
195 
201  bool IntersectPlane(double origin[3], double normal[3]);
202 
210  static bool IntersectsSphere(
211  const double min[3], const double max[3], const double center[3], double r2)
212  {
213  double d2 = 0.0;
214  for (int i = 0; i < 3; ++i)
215  {
216  if (center[i] < min[i])
217  {
218  d2 += (center[i] - min[i]) * (center[i] - min[i]);
219  }
220  else if (center[i] > max[i])
221  {
222  d2 += (center[i] - max[i]) * (center[i] - max[i]);
223  }
224  }
225  return (d2 <= r2);
226  }
227 
232  bool IntersectsSphere(double center[3], double radius) const;
233 
238  bool IntersectsSphere2(double center[3], double radius2) const
239  {
240  return vtkBoundingBox::IntersectsSphere(this->MinPnt, this->MaxPnt, center, radius2);
241  }
242 
249  static bool InsideSphere(
250  const double min[3], const double max[3], const double center[3], double r2)
251  {
252  double dmax = 0.0;
253  for (int i = 0; i < 3; ++i)
254  {
255  double a = (center[i] - min[i]) * (center[i] - min[i]);
256  double b = (center[i] - max[i]) * (center[i] - max[i]);
257  dmax += std::max(a, b);
258  }
259  return dmax <= r2;
260  }
261 
266  bool InsideSphere(double center[3], double radius2) const
267  {
268  return vtkBoundingBox::InsideSphere(this->MinPnt, this->MaxPnt, center, radius2);
269  }
270 
275  bool IntersectsLine(const double p1[3], const double p2[3]) const;
276 
280  int ComputeInnerDimension() const;
281 
286  int Contains(const vtkBoundingBox& bbox) const;
287 
304  static bool ContainsLine(const double x[3], const double s[3], const double lineEnd[3], double& t,
305  double xInt[3], int& plane);
306 
308 
311  void GetBounds(double bounds[6]) const;
312  void GetBounds(
313  double& xMin, double& xMax, double& yMin, double& yMax, double& zMin, double& zMax) const;
315 
319  double GetBound(int i) const;
320 
322 
325  const double* GetMinPoint() const VTK_SIZEHINT(3);
326  void GetMinPoint(double& x, double& y, double& z) const;
327  void GetMinPoint(double x[3]) const;
329 
331 
334  const double* GetMaxPoint() const VTK_SIZEHINT(3);
335  void GetMaxPoint(double& x, double& y, double& z) const;
336  void GetMaxPoint(double x[3]) const;
338 
343  void GetCorner(int corner, double p[3]) const;
344 
346 
349  vtkTypeBool ContainsPoint(const double p[3]) const;
350  vtkTypeBool ContainsPoint(double px, double py, double pz) const;
351  template <class PointT>
352  bool ContainsPoint(const PointT& p) const;
354 
358  void GetCenter(double center[3]) const;
359 
363  void GetLengths(double lengths[3]) const;
364 
368  double GetLength(int i) const;
369 
373  double GetMaxLength() const;
374 
376 
380  double GetDiagonalLength2() const;
381  double GetDiagonalLength() const;
383 
385 
396  void Inflate(double delta);
397  void Inflate(double deltaX, double deltaY, double deltaZ);
398  void Inflate();
399  void InflateSlice(double delta);
401 
403 
409  void Scale(double s[3]);
410  void Scale(double sx, double sy, double sz);
412 
414 
419  void ScaleAboutCenter(double s);
420  void ScaleAboutCenter(double s[3]);
421  void ScaleAboutCenter(double sx, double sy, double sz);
423 
434  vtkIdType ComputeDivisions(vtkIdType totalBins, double bounds[6], int divs[3]) const;
435 
440  static void ClampDivisions(vtkIdType targetBins, int divs[3]);
441 
445  void Reset();
446 
451  void ClampPoint(double point[3]);
452 
459  void GetDistance(double point[3], double distance[3]);
460 
465  void Translate(double motion[3]);
466 
467 protected:
468  double MinPnt[3], MaxPnt[3];
469 };
470 
471 inline void vtkBoundingBox::Reset()
472 {
473  this->MinPnt[0] = this->MinPnt[1] = this->MinPnt[2] = VTK_DOUBLE_MAX;
474  this->MaxPnt[0] = this->MaxPnt[1] = this->MaxPnt[2] = VTK_DOUBLE_MIN;
475 }
476 
478  double& xMin, double& xMax, double& yMin, double& yMax, double& zMin, double& zMax) const
479 {
480  xMin = this->MinPnt[0];
481  xMax = this->MaxPnt[0];
482  yMin = this->MinPnt[1];
483  yMax = this->MaxPnt[1];
484  zMin = this->MinPnt[2];
485  zMax = this->MaxPnt[2];
486 }
487 
488 inline double vtkBoundingBox::GetBound(int i) const
489 {
490  // If i is odd then when are returning a part of the max bounds
491  // else part of the min bounds is requested. The exact component
492  // needed is i /2 (or i right shifted by 1
493  return ((i & 0x1) ? this->MaxPnt[i >> 1] : this->MinPnt[i >> 1]);
494 }
495 
496 inline const double* vtkBoundingBox::GetMinPoint() const
497 {
498  return this->MinPnt;
499 }
500 
501 inline void vtkBoundingBox::GetMinPoint(double x[3]) const
502 {
503  x[0] = this->MinPnt[0];
504  x[1] = this->MinPnt[1];
505  x[2] = this->MinPnt[2];
506 }
507 
508 inline const double* vtkBoundingBox::GetMaxPoint() const
509 {
510  return this->MaxPnt;
511 }
512 
513 inline void vtkBoundingBox::GetMaxPoint(double x[3]) const
514 {
515  x[0] = this->MaxPnt[0];
516  x[1] = this->MaxPnt[1];
517  x[2] = this->MaxPnt[2];
518 }
519 
520 inline int vtkBoundingBox::IsValid() const
521 {
522  return ((this->MinPnt[0] <= this->MaxPnt[0]) && (this->MinPnt[1] <= this->MaxPnt[1]) &&
523  (this->MinPnt[2] <= this->MaxPnt[2]));
524 }
525 
526 inline int vtkBoundingBox::IsValid(const double bounds[6])
527 {
528  return (bounds[0] <= bounds[1] && bounds[2] <= bounds[3] && bounds[4] <= bounds[5]);
529 }
530 
531 inline double vtkBoundingBox::GetLength(int i) const
532 {
533  return this->MaxPnt[i] - this->MinPnt[i];
534 }
535 
536 inline void vtkBoundingBox::GetLengths(double lengths[3]) const
537 {
538  lengths[0] = this->GetLength(0);
539  lengths[1] = this->GetLength(1);
540  lengths[2] = this->GetLength(2);
541 }
542 
543 inline void vtkBoundingBox::GetCenter(double center[3]) const
544 {
545  center[0] = 0.5 * (this->MaxPnt[0] + this->MinPnt[0]);
546  center[1] = 0.5 * (this->MaxPnt[1] + this->MinPnt[1]);
547  center[2] = 0.5 * (this->MaxPnt[2] + this->MinPnt[2]);
548 }
549 
550 inline bool vtkBoundingBox::IsSubsetOf(const vtkBoundingBox& bbox) const
551 {
552  const double* bboxMaxPnt = bbox.GetMaxPoint();
553  const double* bboxMinPnt = bbox.GetMinPoint();
554  return this->MaxPnt[0] < bboxMaxPnt[0] && this->MinPnt[0] > bboxMinPnt[0] &&
555  this->MaxPnt[1] < bboxMaxPnt[1] && this->MinPnt[1] > bboxMinPnt[1] &&
556  this->MaxPnt[2] < bboxMaxPnt[2] && this->MinPnt[2] > bboxMinPnt[2];
557 }
558 
559 inline void vtkBoundingBox::SetBounds(const double bounds[6])
560 {
561  this->SetBounds(bounds[0], bounds[1], bounds[2], bounds[3], bounds[4], bounds[5]);
562 }
563 
564 inline void vtkBoundingBox::GetBounds(double bounds[6]) const
565 {
566  this->GetBounds(bounds[0], bounds[1], bounds[2], bounds[3], bounds[4], bounds[5]);
567 }
568 
570 {
571  this->Reset();
572 }
573 
574 inline vtkBoundingBox::vtkBoundingBox(const double bounds[6])
575 {
576  this->Reset();
577  this->SetBounds(bounds);
578 }
579 
581  double xMin, double xMax, double yMin, double yMax, double zMin, double zMax)
582 {
583  this->Reset();
584  this->SetBounds(xMin, xMax, yMin, yMax, zMin, zMax);
585 }
586 
588 {
589  this->MinPnt[0] = bbox.MinPnt[0];
590  this->MinPnt[1] = bbox.MinPnt[1];
591  this->MinPnt[2] = bbox.MinPnt[2];
592 
593  this->MaxPnt[0] = bbox.MaxPnt[0];
594  this->MaxPnt[1] = bbox.MaxPnt[1];
595  this->MaxPnt[2] = bbox.MaxPnt[2];
596 }
597 
598 inline vtkBoundingBox::vtkBoundingBox(const double min[3], const double max[3])
599 {
600  this->MinPnt[0] = min[0];
601  this->MinPnt[1] = min[1];
602  this->MinPnt[2] = min[2];
603 
604  this->MaxPnt[0] = max[0];
605  this->MaxPnt[1] = max[1];
606  this->MaxPnt[2] = max[2];
607 }
608 
609 inline vtkBoundingBox::vtkBoundingBox(double center[3], double delta)
610 {
611  this->Reset();
612  this->AddPoint(center);
613  this->Inflate(delta);
614 }
615 
617 {
618  this->MinPnt[0] = bbox.MinPnt[0];
619  this->MinPnt[1] = bbox.MinPnt[1];
620  this->MinPnt[2] = bbox.MinPnt[2];
621 
622  this->MaxPnt[0] = bbox.MaxPnt[0];
623  this->MaxPnt[1] = bbox.MaxPnt[1];
624  this->MaxPnt[2] = bbox.MaxPnt[2];
625  return *this;
626 }
627 
628 inline bool vtkBoundingBox::operator==(const vtkBoundingBox& bbox) const
629 {
630  return ((this->MinPnt[0] == bbox.MinPnt[0]) && (this->MinPnt[1] == bbox.MinPnt[1]) &&
631  (this->MinPnt[2] == bbox.MinPnt[2]) && (this->MaxPnt[0] == bbox.MaxPnt[0]) &&
632  (this->MaxPnt[1] == bbox.MaxPnt[1]) && (this->MaxPnt[2] == bbox.MaxPnt[2]));
633 }
634 
635 inline bool vtkBoundingBox::operator!=(const vtkBoundingBox& bbox) const
636 {
637  return !((*this) == bbox);
638 }
639 
640 inline void vtkBoundingBox::SetMinPoint(double p[3])
641 {
642  this->SetMinPoint(p[0], p[1], p[2]);
643 }
644 
645 inline void vtkBoundingBox::SetMaxPoint(double p[3])
646 {
647  this->SetMaxPoint(p[0], p[1], p[2]);
648 }
649 
650 inline void vtkBoundingBox::GetMinPoint(double& x, double& y, double& z) const
651 {
652  x = this->MinPnt[0];
653  y = this->MinPnt[1];
654  z = this->MinPnt[2];
655 }
656 
657 inline void vtkBoundingBox::GetMaxPoint(double& x, double& y, double& z) const
658 {
659  x = this->MaxPnt[0];
660  y = this->MaxPnt[1];
661  z = this->MaxPnt[2];
662 }
663 
664 inline vtkTypeBool vtkBoundingBox::ContainsPoint(double px, double py, double pz) const
665 {
666  if ((px < this->MinPnt[0]) || (px > this->MaxPnt[0]))
667  {
668  return 0;
669  }
670  if ((py < this->MinPnt[1]) || (py > this->MaxPnt[1]))
671  {
672  return 0;
673  }
674  if ((pz < this->MinPnt[2]) || (pz > this->MaxPnt[2]))
675  {
676  return 0;
677  }
678  return 1;
679 }
680 
681 inline vtkTypeBool vtkBoundingBox::ContainsPoint(const double p[3]) const
682 {
683  return this->ContainsPoint(p[0], p[1], p[2]);
684 }
685 
686 template <class PointT>
687 inline bool vtkBoundingBox::ContainsPoint(const PointT& p) const
688 {
689  return this->ContainsPoint(p[0], p[1], p[2]);
690 }
691 
692 inline void vtkBoundingBox::GetCorner(int corner, double p[3]) const
693 {
694  if ((corner < 0) || (corner > 7))
695  {
696  p[0] = VTK_DOUBLE_MAX;
697  p[1] = VTK_DOUBLE_MAX;
698  p[2] = VTK_DOUBLE_MAX;
699  return; // out of bounds
700  }
701 
702  int ix = (corner & 1) ? 1 : 0; // 0,1,0,1,0,1,0,1
703  int iy = ((corner >> 1) & 1) ? 1 : 0; // 0,0,1,1,0,0,1,1
704  int iz = (corner >> 2) ? 1 : 0; // 0,0,0,0,1,1,1,1
705 
706  const double* pts[2] = { this->MinPnt, this->MaxPnt };
707  p[0] = pts[ix][0];
708  p[1] = pts[iy][1];
709  p[2] = pts[iz][2];
710 }
711 
712 VTK_ABI_NAMESPACE_END
713 #endif
714 // VTK-HeaderTest-Exclude: vtkBoundingBox.h
RealT r2
Definition: PyrC2Basis.h:20
void GetBounds(double bounds[6]) const
Get the bounds of the box (defined by VTK style).
void GetBounds(T a, double bds[6])
const double * GetMinPoint() const
Get the minimum point of the bounding box.
#define VTK_DOUBLE_MAX
Definition: vtkType.h:202
void SetMaxPoint(double x, double y, double z)
Set the maximum point of the bounding box - if the max point is less than the min point then the min ...
void ComputeBounds(vtkPoints *pts)
Compute the bounding box from an array of vtkPoints.
bool operator!=(const vtkBoundingBox &bbox) const
Equality operator.
static void ComputeBounds(vtkPoints *pts, double bounds[6])
Compute the bounding box from an array of vtkPoints.
int vtkIdType
Definition: vtkType.h:363
bool VTKCOMMONCORE_EXPORT operator==(const std::string &a, const vtkStringToken &b)
void GetCorner(int corner, double p[3]) const
Get the ith corner of the bounding box.
int vtkTypeBool
Definition: vtkABI.h:64
bool operator==(const vtkBoundingBox &bbox) const
Equality operator.
void GetCenter(double center[3]) const
Get the center of the bounding box.
int IsValid() const
Returns 1 if the bounds have been set and 0 if the box is in its initialized state which is an invert...
double GetBound(int i) const
Return the ith bounds of the box (defined by VTK style).
void GetLengths(double lengths[3]) const
Get the length of each side of the box.
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.
vtkBoundingBox & operator=(const vtkBoundingBox &bbox)
Assignment Operator.
bool VTKCOMMONCORE_EXPORT operator!=(const std::string &a, const vtkStringToken &b)
vtkTypeBool ContainsPoint(const double p[3]) const
Returns 1 if the point is contained in the box else 0.
#define VTK_SIZEHINT(...)
bool IsSubsetOf(const vtkBoundingBox &bbox) const
Returns true if this instance is entirely contained by bbox.
void SetMinPoint(double x, double y, double z)
Set the minimum point of the bounding box - if the min point is greater than the max point then the m...
#define VTK_DOUBLE_MIN
Definition: vtkType.h:201
double GetLength(int i) const
Return the length of the bounding box in the ith direction.
bool IntersectsSphere2(double center[3], double radius2) const
Intersect this box with a sphere.
void SetBounds(const double bounds[6])
Set the bounds explicitly of the box (using the VTK convention for representing a bounding box)...
vtkBoundingBox()
Construct a bounding box with the min point set to VTK_DOUBLE_MAX and the max point set to VTK_DOUBLE...
double MaxPnt[3]
static bool IntersectsSphere(const double min[3], const double max[3], const double center[3], double r2)
Performant method to intersect box with a sphere.
void ComputeBounds(vtkPoints *pts, unsigned char *ptUses)
Compute the bounding box from an array of vtkPoints.
const double * GetMaxPoint() const
Get the maximum point of the bounding box.
#define max(a, b)
represent and manipulate 3D points
Definition: vtkPoints.h:30
Fast, simple class for representing and operating on 3D bounds.
double MinPnt[3]
bool InsideSphere(double center[3], double radius2) const
Determine if this bounding box is completely contained by a sphere.