iMSTK
Interactive Medical Simulation Toolkit
imstkCompoundGeometry.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 "imstkCompoundGeometry.h"
8 
9 #include "imstkAnalyticalGeometry.h"
10 #include "imstkLogger.h"
11 
12 #include <algorithm>
13 #include <numeric>
14 
15 namespace imstk
16 {
17 void
19 {
20  std::for_each(m_geometries.begin(), m_geometries.end(), [](const auto& geom) { geom.geometry->print(); });
21 }
22 
23 double
25 {
27  return std::accumulate(m_geometries.begin(), m_geometries.end(), 0.0, [](auto val, auto& geom)
28  { return val + geom.geometry->getVolume(); });
29 }
30 
31 void
32 CompoundGeometry::computeBoundingBox(Vec3d& lowerCorner, Vec3d& upperCorner, const double paddingPercent /*= 0.0*/)
33 {
34  Eigen::AlignedBox3d box;
35  box.setEmpty();
37  for (auto geom : m_geometries)
38  {
39  Vec3d localLowLeft;
40  Vec3d localUpRight;
41  geom.geometry->computeBoundingBox(localLowLeft, localUpRight, paddingPercent);
42  box.extend(Eigen::AlignedBox3d(localLowLeft, localUpRight));
43  }
44  lowerCorner = box.corner(Eigen::AlignedBox3d::BottomLeftFloor);
45  upperCorner = box.corner(Eigen::AlignedBox3d::TopRightCeil);
46 }
47 
48 Vec3d
50 {
52  return std::accumulate(m_geometries.begin(), m_geometries.end(), Vec3d(0, 0, 0), [](auto val, auto& geom)
53  { return val + geom.geometry->getCenter(); }) / m_geometries.size();
54 }
55 
56 bool
58 {
59  return false;
60 }
61 
62 void
64 {
65  // Take the current transform and offset each
66  if (!m_transformApplied)
67  {
68  std::for_each(m_geometries.begin(), m_geometries.end(), [this](auto& geom) {
69  auto transform = m_transform * geom.localTransform;
70  CHECK(!transform.hasNaN());
71  CHECK(geom.geometry != nullptr);
72  geom.geometry->setTransform(transform);
73  geom.geometry->updatePostTransformData();
74  });
75  }
76  m_transformApplied = true;
77 }
78 
79 void
81 {
82  std::for_each(m_geometries.begin(), m_geometries.end(), [&mat](auto& geom) {
83  auto transform = mat * geom.localTransform;
84  CHECK(!transform.hasNaN());
85  geom.geometry->setTransform(transform);
86  geom.geometry->updatePostTransformData();
87  });
88  m_transformApplied = true;
89 }
90 
91 void
93 {
94  if (index >= m_geometries.size())
95  {
96  return;
97  }
98  m_transformApplied = false;
99  m_geometries[index].localTransform = transform;
100 }
101 
102 std::shared_ptr<imstk::Geometry>
103 CompoundGeometry::get(size_t index) const
104 {
105  if (index < m_geometries.size())
106  {
107  return m_geometries[index].geometry;
108  }
109  else
110  {
111  return nullptr;
112  }
113 }
114 
115 void
116 CompoundGeometry::add(std::shared_ptr<AnalyticalGeometry> geometry)
117 {
118  if (std::find_if(m_geometries.begin(), m_geometries.end(), [this, geometry](auto& geom) { return geom.geometry == geometry; }) == m_geometries.end())
119  {
120  m_geometries.push_back({ geometry, Mat4d::Identity() });
121  }
122  else
123  {
124  LOG(WARNING) << "Added duplicate geometry to compound geometry, ignored " << geometry->getName();
125  }
126 }
127 
128 Geometry*
129 imstk::CompoundGeometry::cloneImplementation() const
130 {
131  throw std::logic_error("The method or operation is not implemented.");
132 }
133 } // namespace imstk
Mat4d m_transform
Transformation matrix.
void applyTransform(const Mat4d &) override
Directly apply transform to data.
void print() const override
Print.
Compound Geometry.
double getVolume() override
Returns the volume of the geometry (if valid)
void transform(const Mat4d &T, TransformType type=TransformType::ConcatenateToTransform)
Applies a rigid transform to the geometry.
Base class for any geometrical representation.
Definition: imstkGeometry.h:22
void setLocalTransform(size_t index, const Mat4d &transform)
void updatePostTransformData() const override
void add(std::shared_ptr< AnalyticalGeometry > geometry)
Adds a geometry to the compound geometry.
std::shared_ptr< Geometry > get(size_t index) const
void computeBoundingBox(Vec3d &lowerCorner, Vec3d &upperCorner, const double paddingPercent=0.0) override
Compute the bounding box for the geometry.
bool isMesh() const override
Returns true if the geometry is a mesh, else returns false.
Vec3d getCenter() override
Returns the bounding box center.