VTK  9.6.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
18
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
27VTK_ABI_NAMESPACE_BEGIN
28class vtkPoints;
29
30class VTKCOMMONDATAMODEL_EXPORT vtkBoundingBox
31{
32public:
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
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 }
120
121
123
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
208 static bool IntersectsSphere(
209 const double min[3], const double max[3], const double center[3], double r2)
210 {
211 double d2 = 0.0;
212 for (int i = 0; i < 3; ++i)
213 {
214 if (center[i] < min[i])
215 {
216 d2 += (center[i] - min[i]) * (center[i] - min[i]);
217 }
218 else if (center[i] > max[i])
219 {
220 d2 += (center[i] - max[i]) * (center[i] - max[i]);
221 }
222 }
223 return (d2 <= r2);
224 }
225
230 bool IntersectsSphere(double center[3], double radius) const;
231
236 bool IntersectsSphere2(double center[3], double radius2) const
237 {
238 return vtkBoundingBox::IntersectsSphere(this->MinPnt, this->MaxPnt, center, radius2);
239 }
240
246 static bool InsideSphere(
247 const double min[3], const double max[3], const double center[3], double r2)
248 {
249 double dmin = 0.0, dmax = 0.0;
250 for (int i = 0; i < 3; ++i)
251 {
252 double a = (center[i] - min[i]) * (center[i] - min[i]);
253 double b = (center[i] - max[i]) * (center[i] - max[i]);
254 dmax += std::max(a, b);
255 if (min[i] <= center[i] && center[i] <= max[i])
256 {
257 dmin += std::min(a, b);
258 }
259 }
260 return (!(dmin <= r2 && r2 <= dmax));
261 }
262
267 bool InsideSphere(double center[3], double radius2) const
268 {
269 return vtkBoundingBox::InsideSphere(this->MinPnt, this->MaxPnt, center, radius2);
270 }
271
276 bool IntersectsLine(const double p1[3], const double p2[3]) const;
277
282
287 int Contains(const vtkBoundingBox& bbox) const;
288
305 static bool ContainsLine(const double x[3], const double s[3], const double lineEnd[3], double& t,
306 double xInt[3], int& plane);
307
309
312 void GetBounds(double bounds[6]) const;
313 void GetBounds(
314 double& xMin, double& xMax, double& yMin, double& yMax, double& zMin, double& zMax) const;
316
320 double GetBound(int i) const;
321
323
326 const double* GetMinPoint() const VTK_SIZEHINT(3);
327 void GetMinPoint(double& x, double& y, double& z) const;
328 void GetMinPoint(double x[3]) const;
330
332
335 const double* GetMaxPoint() const VTK_SIZEHINT(3);
336 void GetMaxPoint(double& x, double& y, double& z) const;
337 void GetMaxPoint(double x[3]) const;
339
344 void GetCorner(int corner, double p[3]) const;
345
347
350 vtkTypeBool ContainsPoint(const double p[3]) const;
351 vtkTypeBool ContainsPoint(double px, double py, double pz) const;
352 template <class PointT>
353 bool ContainsPoint(const PointT& p) const;
355
359 void GetCenter(double center[3]) const;
360
364 void GetLengths(double lengths[3]) const;
365
369 double GetLength(int i) const;
370
374 double GetMaxLength() const;
375
377
381 double GetDiagonalLength2() const;
382 double GetDiagonalLength() const;
384
386
397 void Inflate(double delta);
398 void Inflate(double deltaX, double deltaY, double deltaZ);
399 void Inflate();
400 void InflateSlice(double delta);
402
404
410 void Scale(double s[3]);
411 void Scale(double sx, double sy, double sz);
413
415
420 void ScaleAboutCenter(double s);
421 void ScaleAboutCenter(double s[3]);
422 void ScaleAboutCenter(double sx, double sy, double sz);
424
435 vtkIdType ComputeDivisions(vtkIdType totalBins, double bounds[6], int divs[3]) const;
436
441 static void ClampDivisions(vtkIdType targetBins, int divs[3]);
442
446 void Reset();
447
452 void ClampPoint(double point[3]);
453
460 void GetDistance(double point[3], double distance[3]);
461
466 void Translate(double motion[3]);
467
468protected:
469 double MinPnt[3], MaxPnt[3];
470};
471
472inline void vtkBoundingBox::Reset()
473{
474 this->MinPnt[0] = this->MinPnt[1] = this->MinPnt[2] = VTK_DOUBLE_MAX;
475 this->MaxPnt[0] = this->MaxPnt[1] = this->MaxPnt[2] = VTK_DOUBLE_MIN;
476}
477
479 double& xMin, double& xMax, double& yMin, double& yMax, double& zMin, double& zMax) const
480{
481 xMin = this->MinPnt[0];
482 xMax = this->MaxPnt[0];
483 yMin = this->MinPnt[1];
484 yMax = this->MaxPnt[1];
485 zMin = this->MinPnt[2];
486 zMax = this->MaxPnt[2];
487}
488
489inline double vtkBoundingBox::GetBound(int i) const
490{
491 // If i is odd then when are returning a part of the max bounds
492 // else part of the min bounds is requested. The exact component
493 // needed is i /2 (or i right shifted by 1
494 return ((i & 0x1) ? this->MaxPnt[i >> 1] : this->MinPnt[i >> 1]);
495}
496
497inline const double* vtkBoundingBox::GetMinPoint() const
498{
499 return this->MinPnt;
500}
501
502inline void vtkBoundingBox::GetMinPoint(double x[3]) const
503{
504 x[0] = this->MinPnt[0];
505 x[1] = this->MinPnt[1];
506 x[2] = this->MinPnt[2];
507}
508
509inline const double* vtkBoundingBox::GetMaxPoint() const
510{
511 return this->MaxPnt;
512}
513
514inline void vtkBoundingBox::GetMaxPoint(double x[3]) const
515{
516 x[0] = this->MaxPnt[0];
517 x[1] = this->MaxPnt[1];
518 x[2] = this->MaxPnt[2];
519}
520
521inline int vtkBoundingBox::IsValid() const
522{
523 return ((this->MinPnt[0] <= this->MaxPnt[0]) && (this->MinPnt[1] <= this->MaxPnt[1]) &&
524 (this->MinPnt[2] <= this->MaxPnt[2]));
525}
526
527inline int vtkBoundingBox::IsValid(const double bounds[6])
528{
529 return (bounds[0] <= bounds[1] && bounds[2] <= bounds[3] && bounds[4] <= bounds[5]);
530}
531
532inline double vtkBoundingBox::GetLength(int i) const
533{
534 return this->MaxPnt[i] - this->MinPnt[i];
535}
536
537inline void vtkBoundingBox::GetLengths(double lengths[3]) const
538{
539 lengths[0] = this->GetLength(0);
540 lengths[1] = this->GetLength(1);
541 lengths[2] = this->GetLength(2);
542}
543
544inline void vtkBoundingBox::GetCenter(double center[3]) const
545{
546 center[0] = 0.5 * (this->MaxPnt[0] + this->MinPnt[0]);
547 center[1] = 0.5 * (this->MaxPnt[1] + this->MinPnt[1]);
548 center[2] = 0.5 * (this->MaxPnt[2] + this->MinPnt[2]);
549}
550
551inline bool vtkBoundingBox::IsSubsetOf(const vtkBoundingBox& bbox) const
552{
553 const double* bboxMaxPnt = bbox.GetMaxPoint();
554 const double* bboxMinPnt = bbox.GetMinPoint();
555 return this->MaxPnt[0] < bboxMaxPnt[0] && this->MinPnt[0] > bboxMinPnt[0] &&
556 this->MaxPnt[1] < bboxMaxPnt[1] && this->MinPnt[1] > bboxMinPnt[1] &&
557 this->MaxPnt[2] < bboxMaxPnt[2] && this->MinPnt[2] > bboxMinPnt[2];
558}
559
560inline void vtkBoundingBox::SetBounds(const double bounds[6])
561{
562 this->SetBounds(bounds[0], bounds[1], bounds[2], bounds[3], bounds[4], bounds[5]);
563}
564
565inline void vtkBoundingBox::GetBounds(double bounds[6]) const
566{
567 this->GetBounds(bounds[0], bounds[1], bounds[2], bounds[3], bounds[4], bounds[5]);
568}
569
571{
572 this->Reset();
573}
574
575inline vtkBoundingBox::vtkBoundingBox(const double bounds[6])
576{
577 this->Reset();
578 this->SetBounds(bounds);
579}
580
582 double xMin, double xMax, double yMin, double yMax, double zMin, double zMax)
583{
584 this->Reset();
585 this->SetBounds(xMin, xMax, yMin, yMax, zMin, zMax);
586}
587
589{
590 this->MinPnt[0] = bbox.MinPnt[0];
591 this->MinPnt[1] = bbox.MinPnt[1];
592 this->MinPnt[2] = bbox.MinPnt[2];
593
594 this->MaxPnt[0] = bbox.MaxPnt[0];
595 this->MaxPnt[1] = bbox.MaxPnt[1];
596 this->MaxPnt[2] = bbox.MaxPnt[2];
597}
598
599inline vtkBoundingBox::vtkBoundingBox(const double min[3], const double max[3])
600{
601 this->MinPnt[0] = min[0];
602 this->MinPnt[1] = min[1];
603 this->MinPnt[2] = min[2];
604
605 this->MaxPnt[0] = max[0];
606 this->MaxPnt[1] = max[1];
607 this->MaxPnt[2] = max[2];
608}
609
610inline vtkBoundingBox::vtkBoundingBox(double center[3], double delta)
611{
612 this->Reset();
613 this->AddPoint(center);
614 this->Inflate(delta);
615}
616
618{
619 this->MinPnt[0] = bbox.MinPnt[0];
620 this->MinPnt[1] = bbox.MinPnt[1];
621 this->MinPnt[2] = bbox.MinPnt[2];
622
623 this->MaxPnt[0] = bbox.MaxPnt[0];
624 this->MaxPnt[1] = bbox.MaxPnt[1];
625 this->MaxPnt[2] = bbox.MaxPnt[2];
626 return *this;
627}
628
629inline bool vtkBoundingBox::operator==(const vtkBoundingBox& bbox) const
630{
631 return ((this->MinPnt[0] == bbox.MinPnt[0]) && (this->MinPnt[1] == bbox.MinPnt[1]) &&
632 (this->MinPnt[2] == bbox.MinPnt[2]) && (this->MaxPnt[0] == bbox.MaxPnt[0]) &&
633 (this->MaxPnt[1] == bbox.MaxPnt[1]) && (this->MaxPnt[2] == bbox.MaxPnt[2]));
634}
635
636inline bool vtkBoundingBox::operator!=(const vtkBoundingBox& bbox) const
637{
638 return !((*this) == bbox);
639}
640
641inline void vtkBoundingBox::SetMinPoint(double p[3])
642{
643 this->SetMinPoint(p[0], p[1], p[2]);
644}
645
646inline void vtkBoundingBox::SetMaxPoint(double p[3])
647{
648 this->SetMaxPoint(p[0], p[1], p[2]);
649}
650
651inline void vtkBoundingBox::GetMinPoint(double& x, double& y, double& z) const
652{
653 x = this->MinPnt[0];
654 y = this->MinPnt[1];
655 z = this->MinPnt[2];
656}
657
658inline void vtkBoundingBox::GetMaxPoint(double& x, double& y, double& z) const
659{
660 x = this->MaxPnt[0];
661 y = this->MaxPnt[1];
662 z = this->MaxPnt[2];
663}
664
665inline vtkTypeBool vtkBoundingBox::ContainsPoint(double px, double py, double pz) const
666{
667 if ((px < this->MinPnt[0]) || (px > this->MaxPnt[0]))
668 {
669 return 0;
670 }
671 if ((py < this->MinPnt[1]) || (py > this->MaxPnt[1]))
672 {
673 return 0;
674 }
675 if ((pz < this->MinPnt[2]) || (pz > this->MaxPnt[2]))
676 {
677 return 0;
678 }
679 return 1;
680}
681
682inline vtkTypeBool vtkBoundingBox::ContainsPoint(const double p[3]) const
683{
684 return this->ContainsPoint(p[0], p[1], p[2]);
685}
686
687template <class PointT>
688inline bool vtkBoundingBox::ContainsPoint(const PointT& p) const
689{
690 return this->ContainsPoint(p[0], p[1], p[2]);
691}
692
693inline void vtkBoundingBox::GetCorner(int corner, double p[3]) const
694{
695 if ((corner < 0) || (corner > 7))
696 {
697 p[0] = VTK_DOUBLE_MAX;
698 p[1] = VTK_DOUBLE_MAX;
699 p[2] = VTK_DOUBLE_MAX;
700 return; // out of bounds
701 }
702
703 int ix = (corner & 1) ? 1 : 0; // 0,1,0,1,0,1,0,1
704 int iy = ((corner >> 1) & 1) ? 1 : 0; // 0,0,1,1,0,0,1,1
705 int iz = (corner >> 2) ? 1 : 0; // 0,0,0,0,1,1,1,1
706
707 const double* pts[2] = { this->MinPnt, this->MaxPnt };
708 p[0] = pts[ix][0];
709 p[1] = pts[iy][1];
710 p[2] = pts[iz][2];
711}
712
713VTK_ABI_NAMESPACE_END
714#endif
715// VTK-HeaderTest-Exclude: vtkBoundingBox.h
RealT r2
Definition PyrC2Basis.h:20
void ScaleAboutCenter(double s)
Scale each dimension of the box by some given factor, with the origin of the bounding box the center ...
static bool ContainsLine(const double x[3], const double s[3], const double lineEnd[3], double &t, double xInt[3], int &plane)
A specialized, performant method to compute the containment of a finite line emanating from the cente...
double GetDiagonalLength2() const
Return the length of the diagonal.
void Scale(double s[3])
Scale each dimension of the box by some given factor.
void ClampPoint(double point[3])
Clamp point so it is contained inside box.
void AddBounds(const double bounds[6])
Adjust the bounding box so it contains the specified bounds (defined by the VTK representation (xmin,...
vtkIdType ComputeDivisions(vtkIdType totalBins, double bounds[6], int divs[3]) const
Compute the number of divisions in the x-y-z directions given a psoitive, target number of total bins...
static void ComputeBounds(vtkPoints *pts, TIter ptIds, vtkIdType numPointIds, double bounds[6])
Compute the bounding box from an array of vtkPoints.
int IntersectBox(const vtkBoundingBox &bbox)
Intersect this box with bbox.
const double * GetMinPoint() const
Get the minimum point of the bounding box.
double GetDiagonalLength() const
Return the length of the diagonal.
bool InsideSphere(double center[3], double radius2) const
Determine if this bounding box is completely contained by a sphere.
void SetBounds(double xMin, double xMax, double yMin, double yMax, double zMin, double zMax)
Set the bounds explicitly of the box (using the VTK convention for representing a bounding box).
void AddBox(const vtkBoundingBox &bbox)
Change the bounding box to be the union of itself and the specified bbox.
int Contains(const vtkBoundingBox &bbox) const
Returns 1 if the min and max points of bbox are contained within the bounds of the specified 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...
int Intersects(const vtkBoundingBox &bbox) const
Returns 1 if the boxes intersect else returns 0.
double GetMaxLength() const
Return the maximum length of the box.
bool operator!=(const vtkBoundingBox &bbox) const
Equality operator.
void AddPoint(double px, double py, double pz)
Change bounding box so it includes the point p.
void GetDistance(double point[3], double distance[3])
For each axis, get the minimum distance to put the point inside the box.
int ComputeInnerDimension() const
Returns the inner dimension of the bounding box.
void GetCorner(int corner, double p[3]) const
Get the ith corner of the bounding box.
void ComputeBounds(vtkPoints *pts)
Compute the bounding box from an array of vtkPoints.
bool IsSubsetOf(const vtkBoundingBox &bbox) const
Returns true if this instance is entirely contained by bbox.
static void ComputeBounds(vtkPoints *pts, double bounds[6])
Compute the bounding box from an array of vtkPoints.
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 Reset()
Returns the box to its initialized state.
bool IntersectPlane(double origin[3], double normal[3])
Intersect this box with the half space defined by plane.
bool IntersectsLine(const double p1[3], const double p2[3]) const
Returns true if any part of segment [p1,p2] lies inside the bounding box, as well as on its boundarie...
static void ComputeLocalBounds(vtkPoints *points, double u[3], double v[3], double w[3], double outputBounds[6])
Compute local bounds.
void GetCenter(double center[3]) const
Get the center of the bounding box.
void AddPoint(double p[3])
Change bounding box so it includes the point p.
bool IntersectsSphere2(double center[3], double radius2) const
Intersect this box with a sphere.
double GetLength(int i) const
Return the length of the bounding box in the ith direction.
bool operator==(const vtkBoundingBox &bbox) const
Equality operator.
vtkTypeBool ContainsPoint(const double p[3]) const
Returns 1 if the point is contained in the box else 0.
static void ClampDivisions(vtkIdType targetBins, int divs[3])
Clamp the number of divisions to be less than or equal to a target number of bins,...
vtkBoundingBox()
Construct a bounding box with the min point set to VTK_DOUBLE_MAX and the max point set to VTK_DOUBLE...
bool IntersectsSphere(double center[3], double radius) const
Intersect this box with a sphere.
void GetLengths(double lengths[3]) const
Get the length of each side of the box.
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 Inflate(double delta)
Expand the bounding box.
void ComputeBounds(vtkPoints *pts, unsigned char *ptUses)
Compute the bounding box from an array of vtkPoints.
void InflateSlice(double delta)
Expand the bounding box.
static void ComputeBounds(vtkPoints *pts, const unsigned char *ptUses, double bounds[6])
Compute the bounding box from an array of vtkPoints.
void SetBounds(const double bounds[6])
Set the bounds explicitly of the box (using the VTK convention for representing a bounding box).
const double * GetMaxPoint() const
Get the maximum point of the bounding box.
double GetBound(int i) const
Return the ith bounds of the box (defined by VTK style).
static void ComputeBounds(vtkPoints *pts, const std::atomic< unsigned char > *ptUses, double bounds[6])
Compute the bounding box from an array of vtkPoints.
void GetBounds(double bounds[6]) const
Get the bounds of the box (defined by VTK style).
void Translate(double motion[3])
Translate box from motion.
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...
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.
vtkBoundingBox & operator=(const vtkBoundingBox &bbox)
Assignment Operator.
represent and manipulate 3D points
Definition vtkPoints.h:30
int vtkTypeBool
Definition vtkABI.h:64
void Reset()
Initializes the field list to empty.
virtual double * GetBounds()
Compute the bounding box of the current cell in `bounds' in global coordinates.
bool VTKCOMMONCORE_EXPORT operator==(const std::string &a, const vtkStringToken &b)
bool VTKCOMMONCORE_EXPORT operator!=(const std::string &a, const vtkStringToken &b)
virtual void SetBounds(double, double, double, double, double, double)
int vtkIdType
Definition vtkType.h:368
#define VTK_DOUBLE_MIN
Definition vtkType.h:206
#define VTK_DOUBLE_MAX
Definition vtkType.h:207
int Inflate(double dist) override
Inflates voxel by moving every faces by dist.
#define VTK_SIZEHINT(...)
#define max(a, b)