From e999e0acfc37084e540c986ee7038b16b5236e61 Mon Sep 17 00:00:00 2001
From: Yohann Bearzi <yohann.bearzi@kitware.com>
Date: Thu, 14 May 2020 13:53:34 -0400
Subject: [PATCH] Adding API to `vtkBoundingBox`

`vtkBoundingBox` can now test intersection with spheres
with `vtkBoundingBox::IntersectsSphere`.

Method `vtkBoundingBox::ComputeInnerDimension` tells
what is the inner dimension of itself.
---
 Common/DataModel/vtkBoundingBox.cxx | 32 +++++++++++++++++++++++++++++
 Common/DataModel/vtkBoundingBox.h   | 25 ++++++++++++++++++++++
 2 files changed, 57 insertions(+)

diff --git a/Common/DataModel/vtkBoundingBox.cxx b/Common/DataModel/vtkBoundingBox.cxx
index 298cda921d0..a0358c2a5be 100644
--- a/Common/DataModel/vtkBoundingBox.cxx
+++ b/Common/DataModel/vtkBoundingBox.cxx
@@ -628,6 +628,38 @@ bool vtkBoundingBox::IntersectPlane(double origin[3], double normal[3])
 }
 
 //------------------------------------------------------------------------------
+bool vtkBoundingBox::IntersectsSphere(double center[3], double radius) const
+{
+  return center[0] >= this->MinPnt[0] - radius && center[0] <= this->MaxPnt[0] + radius &&
+    center[1] >= this->MinPnt[1] - radius && center[1] <= this->MaxPnt[1] + radius &&
+    center[2] >= this->MinPnt[2] - radius && center[2] <= this->MaxPnt[2] + radius;
+}
+
+// ---------------------------------------------------------------------------
+int vtkBoundingBox::ComputeInnerDimension() const
+{
+  double thickness = this->MaxPnt[0] - this->MinPnt[0];
+  int dim = 3;
+  if (std::abs(thickness) <=
+    std::max(std::fabs(this->MaxPnt[0]), std::fabs(this->MinPnt[0])) * VTK_DBL_EPSILON)
+  {
+    --dim;
+  }
+  thickness = this->MaxPnt[1] - this->MinPnt[1];
+  if (std::abs(thickness) <=
+    std::max(std::fabs(this->MaxPnt[1]), std::fabs(this->MinPnt[1])) * VTK_DBL_EPSILON)
+  {
+    --dim;
+  }
+  thickness = this->MaxPnt[2] - this->MinPnt[2];
+  if (std::fabs(thickness) <=
+    std::max(std::fabs(this->MaxPnt[2]), std::fabs(this->MinPnt[2])) * VTK_DBL_EPSILON)
+  {
+    --dim;
+  }
+  return dim;
+}
+
 // Support ComputeBounds()
 namespace
 {
diff --git a/Common/DataModel/vtkBoundingBox.h b/Common/DataModel/vtkBoundingBox.h
index 5b14ed019e7..407e3080a79 100644
--- a/Common/DataModel/vtkBoundingBox.h
+++ b/Common/DataModel/vtkBoundingBox.h
@@ -143,6 +143,11 @@ public:
    */
   void AddBounds(const double bounds[]);
 
+  /**
+   * Returns true if this instance is entirely contained by bbox.
+   */
+  bool IsSubsetOf(const vtkBoundingBox& bbox) const;
+
   /**
    * Intersect this box with bbox. The method returns 1 if both boxes are
    * valid and they do have overlap else it will return 0.  If 0 is returned
@@ -162,6 +167,17 @@ public:
    */
   bool IntersectPlane(double origin[3], double normal[3]);
 
+  /**
+   * Intersect this box with a sphere.
+   * Parameters involve the center of the sphere and the squared radius.
+   */
+  bool IntersectsSphere(double center[3], double squaredRadius) const;
+
+  /**
+   * Returns the inner dimension of the bounding box.
+   */
+  int ComputeInnerDimension() const;
+
   /**
    * Returns 1 if the min and max points of bbox are contained
    * within the bounds of the specified box, else returns 0.
@@ -376,6 +392,15 @@ inline void vtkBoundingBox::GetCenter(double center[3]) const
   center[2] = 0.5 * (this->MaxPnt[2] + this->MinPnt[2]);
 }
 
+inline bool vtkBoundingBox::IsSubsetOf(const vtkBoundingBox& bbox) const
+{
+  const double* bboxMaxPnt = bbox.GetMaxPoint();
+  const double* bboxMinPnt = bbox.GetMinPoint();
+  return this->MaxPnt[0] < bboxMaxPnt[0] && this->MinPnt[0] > bboxMinPnt[0] &&
+    this->MaxPnt[1] < bboxMaxPnt[1] && this->MinPnt[1] > bboxMinPnt[1] &&
+    this->MaxPnt[2] < bboxMaxPnt[2] && this->MinPnt[2] > bboxMinPnt[2];
+}
+
 inline void vtkBoundingBox::SetBounds(const double bounds[6])
 {
   this->SetBounds(bounds[0], bounds[1], bounds[2], bounds[3], bounds[4], bounds[5]);
-- 
GitLab