CustusX  2021.09.21-dev+develop.e3cd0
An IGT application
cxBoundingBox3D.cpp
Go to the documentation of this file.
1 /*=========================================================================
2 This file is part of CustusX, an Image Guided Therapy Application.
3 
4 Copyright (c) SINTEF Department of Medical Technology.
5 All rights reserved.
6 
7 CustusX is released under a BSD 3-Clause license.
8 
9 See Lisence.txt (https://github.com/SINTEFMedtek/CustusX/blob/master/License.txt) for details.
10 =========================================================================*/
11 
12 #include "cxBoundingBox3D.h"
13 #include "cxUtilHelpers.h"
14 #include "cxTypeConversions.h"
15 
16 // --------------------------------------------------------
17 namespace cx
18 {
19 //namespace utils
20 //{
22 
23 
24 // --------------------------------------------------------
25 // IntBoundingBox3D
27 {
28 }
29 IntBoundingBox3D::IntBoundingBox3D(int x0, int x1, int y0, int y1, int z0, int z1)
30 {
31  elems[0] = x0;
32  elems[1] = x1;
33  elems[2] = y0;
34  elems[3] = y1;
35  elems[4] = z0;
36  elems[5] = z1;
37 }
41 {
42  Vector3D bl, tr;
43  for (unsigned i = 0; i < a.size(); ++i)
44  {
45  bl[i] = std::min(a[i], b[i]);
46  tr[i] = std::max(a[i], b[i]);
47  }
48 
49  elems[0] = static_cast<int> (bl[0]);
50  elems[1] = static_cast<int> (tr[0]);
51  elems[2] = static_cast<int> (bl[1]);
52  elems[3] = static_cast<int> (tr[1]);
53  elems[4] = static_cast<int> (bl[2]);
54  elems[5] = static_cast<int> (tr[2]);
55 }
56 
57 IntBoundingBox3D::IntBoundingBox3D(const Eigen::Vector3i& a, const Eigen::Vector3i& b)
58 {
59  Eigen::Vector3i bl, tr;
60  for (unsigned i = 0; i < a.size(); ++i)
61  {
62  bl[i] = std::min(a[i], b[i]);
63  tr[i] = std::max(a[i], b[i]);
64  }
65 
66  elems[0] = static_cast<int> (bl[0]);
67  elems[1] = static_cast<int> (tr[0]);
68  elems[2] = static_cast<int> (bl[1]);
69  elems[3] = static_cast<int> (tr[1]);
70  elems[4] = static_cast<int> (bl[2]);
71  elems[5] = static_cast<int> (tr[2]);
72 }
73 
75 {
76  for (unsigned i = 0; i < size(); ++i)
77  elems[i] = static_cast<int> (data[i]);
78  // std::copy(data, data+size(), elems);
79 }
81 {
82  std::copy(data, data + size(), elems);
83 }
84 // --------------------------------------------------------
85 Eigen::Vector3i IntBoundingBox3D::bottomLeft() const
86 {
87  return Eigen::Vector3i(elems[0], elems[2], elems[4]);
88 }
89 Eigen::Vector3i IntBoundingBox3D::topRight() const
90 {
91  return Eigen::Vector3i(elems[1], elems[3], elems[5]);
92 }
93 Eigen::Vector3i IntBoundingBox3D::center() const
94 {
95  return (bottomLeft() + topRight()) / 2;
96 }
97 Eigen::Vector3i IntBoundingBox3D::range() const
98 {
99  return topRight() - bottomLeft();
100 }
105 Eigen::Vector3i IntBoundingBox3D::corner(int x, int y, int z) const
106 {
107  Eigen::Vector3i c;
108  c[0] = x ? elems[1] : elems[0];
109  c[1] = y ? elems[3] : elems[2];
110  c[2] = z ? elems[5] : elems[4];
111  return c;
112 }
113 // --------------------------------------------------------
114 
117 bool IntBoundingBox3D::contains(const Eigen::Vector3i& p) const
118 {
119  bool inside = true;
120  for (unsigned i = 0; i < 3; ++i)
121  inside &= ((elems[2 * i] <= p[i]) && (p[i] <= elems[2 * i + 1]));
122  return inside;
123 }
124 
125 std::ostream& operator<<(std::ostream& s, const IntBoundingBox3D& data)
126 {
127  return stream_range(s, data.begin(), data.end());
128 }
129 // --------------------------------------------------------
130 
131 // --------------------------------------------------------
132 // DoubleBoundingBox3D
134 {
135 }
136 DoubleBoundingBox3D::DoubleBoundingBox3D(double x0, double x1, double y0, double y1, double z0, double z1)
137 {
138  elems[0] = x0;
139  elems[1] = x1;
140  elems[2] = y0;
141  elems[3] = y1;
142  elems[4] = z0;
143  elems[5] = z1;
144 }
148 {
149  Vector3D bl, tr;
150  for (unsigned i = 0; i < a.size(); ++i)
151  {
152  bl[i] = std::min(a[i], b[i]);
153  tr[i] = std::max(a[i], b[i]);
154  }
155 
156  elems[0] = bl[0];
157  elems[1] = tr[0];
158  elems[2] = bl[1];
159  elems[3] = tr[1];
160  elems[4] = bl[2];
161  elems[5] = tr[2];
162 }
164 {
165  std::copy(data, data + size(), elems);
166 }
168 {
169  std::copy(data, data + size(), elems);
170 }
172 {
173  for (unsigned i = 0; i < size(); ++i)
174  {
175  elems[i] = bb.elems[i];
176  }
177 }
178 // --------------------------------------------------------
179 
183 {
184  return DoubleBoundingBox3D(data[0], data[2], data[1], data[3], 0, 0);
185 }
186 // --------------------------------------------------------
187 
189 {
190  return Vector3D(elems[0], elems[2], elems[4]);
191 }
193 {
194  return Vector3D(elems[1], elems[3], elems[5]);
195 }
197 {
198  return (bottomLeft() + topRight()) / 2.0;
199 }
201 {
202  return topRight() - bottomLeft();
203 }
208 Vector3D DoubleBoundingBox3D::corner(int x, int y, int z) const
209 {
210  Vector3D c;
211  c[0] = x ? elems[1] : elems[0];
212  c[1] = y ? elems[3] : elems[2];
213  c[2] = z ? elems[5] : elems[4];
214  return c;
215 }
216 // --------------------------------------------------------
217 
221 {
222  bool inside = true;
223  for (unsigned i = 0; i < 3; ++i)
224  inside &= ((elems[2 * i] <= p[i]) && (p[i] <= elems[2 * i + 1]));
225  return inside;
226 }
227 
228 bool similar(const DoubleBoundingBox3D& a, const DoubleBoundingBox3D& b, double tol)
229 {
230  return similar(a.bottomLeft(), b.bottomLeft(), tol) && similar(a.topRight(), b.topRight(), tol);
231 }
232 // --------------------------------------------------------
233 std::ostream& operator<<(std::ostream& s, const DoubleBoundingBox3D& data)
234 {
235  return stream_range(s, data.begin(), data.end());
236 }
237 // --------------------------------------------------------
238 
240 {
241  if (cloud.empty())
242  return DoubleBoundingBox3D::zero();
243 
244  Vector3D a = cloud[0]; // min
245  Vector3D b = cloud[0]; // max
246 
247  for (unsigned int i = 0; i < cloud.size(); ++i)
248  {
249  for (unsigned int j = 0; j < 3; ++j)
250  {
251  a[j] = std::min(a[j], cloud[i][j]);
252  b[j] = std::max(b[j], cloud[i][j]);
253  }
254  }
255  return DoubleBoundingBox3D(a, b);
256 }
257 
259 {
260  std::vector<double> raw = convertQString2DoubleVector(text);
261  if (raw.size() != 6)
262  return DoubleBoundingBox3D(0, 1, 0, 1, 0, 1);
263  return DoubleBoundingBox3D((double*) &(*raw.begin()));
264 }
265 
267 {
268  std::vector<Vector3D> cloud;
269  cloud.push_back(corner(0,0,0));
270  cloud.push_back(other.corner(0,0,0));
271  cloud.push_back(corner(0,0,1));
272  cloud.push_back(other.corner(0,0,1));
273  cloud.push_back(corner(0,1,0));
274  cloud.push_back(other.corner(0,1,0));
275  cloud.push_back(corner(0,1,1));
276  cloud.push_back(other.corner(0,1,1));
277  cloud.push_back(corner(1,0,0));
278  cloud.push_back(other.corner(1,0,0));
279  cloud.push_back(corner(1,0,1));
280  cloud.push_back(other.corner(1,0,1));
281  cloud.push_back(corner(1,1,0));
282  cloud.push_back(other.corner(1,1,0));
283  cloud.push_back(corner(1,1,1));
284  cloud.push_back(other.corner(1,1,1));
285  return fromCloud(cloud);
286 }
287 
289 {
290  DoubleBoundingBox3D bb = a;
291 
292  for (int i=0; i<3; ++i)
293  {
294  bb[2*i] = std::max(a[2*i], b[2*i]);
295  bb[2*i+1] = std::min(a[2*i+1], b[2*i+1]);
296  }
297 
298  // check for no intersection
299  Vector3D range = bb.range();
300  for (int i=0; i<3; ++i)
301  if (range[i]<0.0)
302  return DoubleBoundingBox3D::zero();
303 
304  return bb;
305 }
306 
307 // --------------------------------------------------------
308 //} // namespace utils
309 } // namespace cx
310 // --------------------------------------------------------
DoubleBoundingBox3D unionWith(const DoubleBoundingBox3D &other) const
Vector3D topRight() const
Vector3D corner(int x, int y, int z) const
static DoubleBoundingBox3D fromViewport(const double *data)
Vector3D bottomLeft() const
static DoubleBoundingBox3D fromString(const QString &text)
construct a bb from a string containing 6 whitespace-separated numbers
std::ostream & stream_range(std::ostream &s, ITER begin, ITER end, char separator=' ')
Definition: cxUtilHelpers.h:32
static DoubleBoundingBox3D fromCloud(std::vector< Vector3D > cloud)
Eigen::Vector3i topRight() const
Eigen::Vector3i bottomLeft() const
Eigen::Vector3i range() const
static DoubleBoundingBox3D zero()
Representation of an integer bounding box in 3D. The data are stored as {xmin,xmax,ymin,ymax,zmin,zmax}, in order to simplify communication with vtk.
Representation of a floating-point bounding box in 3D. The data are stored as {xmin,xmax,ymin,ymax,zmin,zmax}, in order to simplify communication with vtk.
std::ostream & operator<<(std::ostream &s, const IntBoundingBox3D &data)
bool contains(const Eigen::Vector3i &p) const
Eigen::Vector3d Vector3D
Vector3D is a representation of a point or vector in 3D.
Definition: cxVector3D.h:42
Eigen::Vector3i corner(int x, int y, int z) const
Vector3D center() const
bool similar(const CameraInfo &lhs, const CameraInfo &rhs, double tol)
DoubleBoundingBox3D intersection(DoubleBoundingBox3D a, DoubleBoundingBox3D b)
Eigen::Vector3i center() const
std::vector< double > convertQString2DoubleVector(const QString &input, bool *ok)
bool contains(const Vector3D &p) const
Namespace for all CustusX production code.