iMSTK
Interactive Medical Simulation Toolkit
imstkGeometry.cpp
1 /*
2 ** This file is part of the Interactive Medical Simulation Toolkit (iMSTK)
3 ** iMSTK is distributed under the Apache License, Version 2.0.
4 ** See accompanying NOTICE for details.
5 */
6 
7 #include "imstkGeometry.h"
8 #include "imstkLogger.h"
9 #include "imstkParallelUtils.h"
10 
11 namespace imstk
12 {
13 std::atomic<size_t> Geometry::s_numGlobalIds = { 0 };
14 
15 void
17 {
18  LOG(INFO) << getTypeName();
19  LOG(INFO) << "Transform: " << m_transform;
20 }
21 
22 void
23 Geometry::computeBoundingBox(Vec3d& imstkNotUsed(min), Vec3d& imstkNotUsed(max), const double imstkNotUsed(padding))
24 {
25  LOG(WARNING) << "computeBoundingBox() must be called from an instance of a specific geometry class";
26 }
27 
28 void
29 Geometry::translate(const Vec3d& t, TransformType type)
30 {
31  if (t.isApprox(Vec3d::Zero()))
32  {
33  return;
34  }
35 
36  transform(AffineTransform3d(Eigen::Translation3d(t)).matrix(), type);
37 }
38 
39 void
40 Geometry::translate(double x, double y, double z, TransformType type)
41 {
42  this->translate(Vec3d(x, y, z), type);
43 }
44 
45 void
46 Geometry::rotate(const Mat3d& r, TransformType type)
47 {
48  if (r.isApprox(Mat3d::Identity()))
49  {
50  return;
51  }
52 
53  Mat4d m = Mat4d::Identity();
54  m.block<3, 3>(0, 0) = r;
55  transform(m, type);
56 }
57 
58 void
59 Geometry::rotate(const Quatd& q, TransformType type)
60 {
61  this->rotate(q.toRotationMatrix(), type);
62 }
63 
64 void
65 Geometry::rotate(const Vec3d& axis, double radians, TransformType type)
66 {
67  this->rotate(Rotd(radians, axis.normalized()).toRotationMatrix(), type);
68 }
69 
70 void
71 Geometry::scale(const Vec3d& s, TransformType type)
72 {
73  Mat4d m = Mat4d::Identity();
74  m(0, 0) = s[0];
75  m(1, 1) = s[1];
76  m(2, 2) = s[2];
77  transform(m, type);
78 }
79 
80 void
81 Geometry::scale(const double s, TransformType type)
82 {
83  Mat4d m = Mat4d::Identity();
84  m(0, 0) = s;
85  m(1, 1) = s;
86  m(2, 2) = s;
87  transform(m, type);
88 }
89 
90 void
91 Geometry::transform(const Mat4d& T, TransformType type)
92 {
93  if (type == TransformType::ConcatenateToTransform)
94  {
96  }
97  else
98  {
99  applyTransform(T);
100  this->postModified();
101  }
102  m_transformApplied = false;
103 }
104 
105 Vec3d
107 {
108  return m_transform.block<3, 1>(0, 3);
109 }
110 
111 void
112 Geometry::setTranslation(const Vec3d& t)
113 {
114  m_transform.block<3, 1>(0, 3) = t;
115  m_transformApplied = false;
116 }
117 
118 void
119 Geometry::setTranslation(const double x, const double y, const double z)
120 {
121  this->setTranslation(Vec3d(x, y, z));
122 }
123 
124 void
125 Geometry::setRotation(const Mat3d& m)
126 {
127  // Decompose trs, getRotation assumes no shear
128  const Vec3d s = getScaling();
129  const Vec3d t = getTranslation();
130  m_transform = Mat4d::Identity();
131  m_transform.block<3, 3>(0, 0) = m;
132  m_transform.block<3, 1>(0, 3) = t;
133  m_transform(0, 0) *= s[0];
134  m_transform(1, 1) *= s[1];
135  m_transform(2, 2) *= s[2];
136  m_transformApplied = false;
137 }
138 
139 void
140 Geometry::setRotation(const Quatd& q)
141 {
142  this->setRotation(q.toRotationMatrix());
143 }
144 
145 void
146 Geometry::setRotation(const Vec3d& axis, const double angle)
147 {
148  this->setRotation(Rotd(angle, axis).toRotationMatrix());
149 }
150 
151 void
152 Geometry::setScaling(const Vec3d& s)
153 {
154  // Applying 0 scales will destroy the basis, would need another transform
155  if (s == Vec3d::Zero())
156  {
157  LOG(WARNING) << "Cannot apply 0 scales";
158  return;
159  }
160  m_transform.block<3, 1>(0, 0) = m_transform.block<3, 1>(0, 0).normalized() * s[0];
161  m_transform.block<3, 1>(0, 1) = m_transform.block<3, 1>(0, 1).normalized() * s[1];
162  m_transform.block<3, 1>(0, 2) = m_transform.block<3, 1>(0, 2).normalized() * s[2];
163  m_transformApplied = false;
164 }
165 
166 void
167 Geometry::setScaling(const double s)
168 {
169  setScaling(Vec3d(s, s, s));
170 }
171 
172 Mat3d
174 {
175  // Assumes affine, no shear
176  const Vec3d& x = m_transform.block<3, 1>(0, 0);
177  const Vec3d& y = m_transform.block<3, 1>(0, 1);
178  const Vec3d& z = m_transform.block<3, 1>(0, 2);
179 
180  Mat3d r;
181  r.block<3, 1>(0, 0) = x.normalized();
182  r.block<3, 1>(0, 1) = y.normalized();
183  r.block<3, 1>(0, 2) = z.normalized();
184 
185  return r;
186 }
187 
188 Vec3d
190 {
191  return Vec3d(
192  m_transform.block<3, 1>(0, 0).norm(),
193  m_transform.block<3, 1>(0, 1).norm(),
194  m_transform.block<3, 1>(0, 2).norm());
195 }
196 } // namespace imstk
Mat4d m_transform
Transformation matrix.
static std::atomic< size_t > s_numGlobalIds
Total number of geometries that have been created in this program.
virtual void print() const
Print.
Vec3d getTranslation() const
Get/Set translation.
void rotate(const Quatd &q, TransformType type=TransformType::ConcatenateToTransform)
Rotate the geometry in Cartesian space.
virtual const std::string getTypeName() const =0
Returns the string representing the type name of the geometry.
virtual void computeBoundingBox(Vec3d &lowerCorner, Vec3d &upperCorner, const double paddingPercent=0.0)
Compute the bounding box for the geometry.
Compound Geometry.
Vec3d getScaling() const
Get/Set scaling.
void transform(const Mat4d &T, TransformType type=TransformType::ConcatenateToTransform)
Applies a rigid transform to the geometry.
void postModified()
Post modified event.
Mat3d getRotation() const
Get/Set rotation.
void scale(const Vec3d &scaling, TransformType type=TransformType::ConcatenateToTransform)
Scale in Cartesian directions.
void translate(const Vec3d &t, TransformType type=TransformType::ConcatenateToTransform)
Translate the geometry in Cartesian space.
TransformType
Enumeration for the transformation to apply ApplyToTransform to apply the transformation to the data...
Definition: imstkGeometry.h:30
virtual void applyTransform(const Mat4d &)
Directly apply transform to data.