iMSTK
Interactive Medical Simulation Toolkit
imstkPbdBody.h
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 #pragma once
8 
9 #include "imstkMath.h"
10 #include "imstkVecDataArray.h"
11 
12 #include <unordered_map>
13 
14 namespace
15 {
19 template<typename T>
20 void
21 copyAndAllocate(const std::shared_ptr<T>& src, std::shared_ptr<T>& dest)
22 {
23  if (src != nullptr)
24  {
25  if (dest == nullptr)
26  {
27  dest = std::make_shared<T>();
28  }
29  *dest = *src;
30  }
31 }
32 } // namespace
33 
34 namespace imstk
35 {
36 class PbdConstraint;
53 struct PbdBody
54 {
55  public:
56  enum class Type
57  {
58  DEFORMABLE,
59  DEFORMABLE_ORIENTED,
60  RIGID
61  };
62 
63  PbdBody() : bodyHandle(-1) { }
64  PbdBody(const int handle) : bodyHandle(handle) { }
65 
69  void deepCopy(const PbdBody& src)
70  {
72  bodyHandle = src.bodyHandle;
73 
74  copyAndAllocate(src.prevVertices, prevVertices);
75  copyAndAllocate(src.vertices, vertices);
76  copyAndAllocate(src.velocities, velocities);
77  copyAndAllocate(src.masses, masses);
78  copyAndAllocate(src.invMasses, invMasses);
79 
80  bodyType = src.bodyType;
81  if (getOriented())
82  {
83  copyAndAllocate(src.prevOrientations, prevOrientations);
84  copyAndAllocate(src.orientations, orientations);
85  copyAndAllocate(src.angularVelocities, angularVelocities);
86  copyAndAllocate(src.inertias, inertias);
87  copyAndAllocate(src.invInertias, invInertias);
88  }
89 
92 
93  externalForce = src.externalForce;
94  externalTorque = src.externalTorque;
95  }
96 
100  bool getOriented() const
101  {
102  return (bodyType == Type::DEFORMABLE_ORIENTED || bodyType == Type::RIGID);
103  }
104 
105  void setRigid(const Vec3d& pos,
106  const double mass = 1.0,
107  const Quatd& orientation = Quatd::Identity(),
108  const Mat3d& inertia = Mat3d::Identity())
109  {
110  bodyType = PbdBody::Type::RIGID;
111 
112  if (vertices == nullptr)
113  {
114  vertices = std::make_shared<VecDataArray<double, 3>>();
115  }
116  * vertices = { pos };
117 
118  uniformMassValue = mass;
119 
120  if (orientations == nullptr)
121  {
122  orientations = std::make_shared<StdVectorOfQuatd>();
123  }
124  * orientations = { orientation };
125 
126  if (inertias == nullptr)
127  {
128  inertias = std::make_shared<StdVectorOfMat3d>();
129  }
130  * inertias = { inertia };
131  }
132 
133  void setRigidVelocity(const Vec3d& velocity,
134  const Vec3d& angularVelocity = Vec3d::Zero())
135  {
136  bodyType = PbdBody::Type::RIGID;
137 
138  if (velocities == nullptr)
139  {
140  velocities = std::make_shared<VecDataArray<double, 3>>();
141  }
142  * velocities = { velocity };
143 
144  if (angularVelocities == nullptr)
145  {
146  angularVelocities = std::make_shared<VecDataArray<double, 3>>();
147  }
148  * angularVelocities = { angularVelocity };
149  }
150 
151  Vec3d getRigidPosition()
152  {
153  CHECK(bodyType == Type::RIGID) << "Body is not a rigid.";
154  return vertices->at(0);
155  }
156 
157  Quatd getRigidOrientation()
158  {
159  CHECK(bodyType == Type::RIGID) << "Body is not a rigid.";
160  return orientations->at(0);
161  }
162 
167  void overrideRigidPositionAndOrientation(const Vec3d& pos, const Quatd& orientation)
168  {
169  CHECK(bodyType == Type::RIGID) << "Body is not a rigid.";
170  (*vertices)[0] = (*prevVertices)[0] = pos;
171  (*orientations)[0] = (*prevOrientations)[0] = orientation;
172  }
173 
178  void overrideLinearAndAngularVelocity(const Vec3d& velocity, const Vec3d& angularVelocity)
179  {
180  CHECK(bodyType == Type::RIGID) << "Body is not a rigid.";
181  (*velocities)[0] = velocity;
182  (*angularVelocities)[0] = angularVelocity;
183  }
184 
185  // Struct Data
187  Type bodyType = Type::DEFORMABLE;
188 
189  std::shared_ptr<VecDataArray<double, 3>> prevVertices;
190  std::shared_ptr<VecDataArray<double, 3>> vertices;
191 
192  std::shared_ptr<VecDataArray<double, 3>> velocities;
193 
194  std::shared_ptr<DataArray<double>> masses;
195  std::shared_ptr<DataArray<double>> invMasses;
196 
197  std::shared_ptr<StdVectorOfQuatd> prevOrientations;
198  std::shared_ptr<StdVectorOfQuatd> orientations;
199 
200  std::shared_ptr<VecDataArray<double, 3>> angularVelocities;
201 
202  std::shared_ptr<StdVectorOfMat3d> inertias;
203  std::shared_ptr<StdVectorOfMat3d> invInertias;
204 
206  std::vector<int> fixedNodeIds;
208  double uniformMassValue = 1.0;
209 
211  bool bodyGravity = true;
212 
213  Vec3d externalForce = Vec3d::Zero();
214  Vec3d externalTorque = Vec3d::Zero();
215 
217  std::unordered_map<int, double> fixedNodeInvMass;
218 
221  std::unordered_map<int, std::vector<std::shared_ptr<PbdConstraint>>> cellConstraintMap;
222 };
223 
229 struct PbdState
230 {
231  public:
232  PbdState() { }
233 
234  void deepCopy(const PbdState& src)
235  {
236  // Copy by value not reference
237  m_bodies.resize(src.m_bodies.size());
238  for (size_t i = 0; i < m_bodies.size(); i++)
239  {
240  if (m_bodies[i] == nullptr)
241  {
242  m_bodies[i] = std::make_shared<PbdBody>();
243  }
244  m_bodies[i]->deepCopy(*src.m_bodies[i]);
245  }
246  }
247 
248  inline Vec3d& getPosition(const std::pair<int, int>& bodyParticleId) const { return (*m_bodies[bodyParticleId.first]->vertices)[bodyParticleId.second]; }
249  inline Vec3d& getVelocity(const std::pair<int, int>& bodyParticleId) const { return (*m_bodies[bodyParticleId.first]->velocities)[bodyParticleId.second]; }
250  inline Quatd& getOrientation(const std::pair<int, int>& bodyParticleId) const { return (*m_bodies[bodyParticleId.first]->orientations)[bodyParticleId.second]; }
251  inline Vec3d& getAngularVelocity(const std::pair<int, int>& bodyParticleId) const { return (*m_bodies[bodyParticleId.first]->angularVelocities)[bodyParticleId.second]; }
252 
253  inline double getInvMass(const std::pair<int, int>& bodyParticleId) const { return (*m_bodies[bodyParticleId.first]->invMasses)[bodyParticleId.second]; }
254  inline Mat3d& getInvInertia(const std::pair<int, int>& bodyParticleId) const { return (*m_bodies[bodyParticleId.first]->invInertias)[bodyParticleId.second]; }
255 
256  inline PbdBody::Type getBodyType(const std::pair<int, int>& bodyParticleId) const { return m_bodies[bodyParticleId.first]->bodyType; }
257 
258  std::vector<std::shared_ptr<PbdBody>> m_bodies;
259 };
260 } // namespace imstk
Represents a pbd body in the model. This is a data only object. It does no function. PbdBody can be of different types. The types effect what properties it has.
Definition: imstkPbdBody.h:53
int bodyHandle
Id in the system.
Definition: imstkPbdBody.h:186
Compound Geometry.
void deepCopy(const PbdBody &src)
Deep copy from src, copying dynamic allocations by value.
Definition: imstkPbdBody.h:69
std::unordered_map< int, double > fixedNodeInvMass
Map for archiving fixed nodes&#39; mass.
Definition: imstkPbdBody.h:217
std::unordered_map< int, std::vector< std::shared_ptr< PbdConstraint > > > cellConstraintMap
Definition: imstkPbdBody.h:221
bool bodyGravity
Switch to activate/deactivate gravity for this Pbd Body. 1 is gravity on, 0 is gravity off...
Definition: imstkPbdBody.h:211
std::vector< int > fixedNodeIds
Nodal/vertex IDs of the nodes that are fixed.
Definition: imstkPbdBody.h:206
void overrideRigidPositionAndOrientation(const Vec3d &pos, const Quatd &orientation)
Override the current position and orientation this can be used to handle pauses, switching of tools o...
Definition: imstkPbdBody.h:167
double uniformMassValue
Mass properties, not used if per vertex masses are given in geometry attributes.
Definition: imstkPbdBody.h:208
Provides interface for accessing particles from a 2d array of PbdBody,Particles.
Definition: imstkPbdBody.h:229
bool getOriented() const
The body should have orientations if its DEFORMABLE_ORIENTED or RIGID.
Definition: imstkPbdBody.h:100
void overrideLinearAndAngularVelocity(const Vec3d &velocity, const Vec3d &angularVelocity)
Override the current linear and angular velocity this can be used to handle pauses, switching of tools or other action that need to transform the body without running through the physics. Can only be used on Rigid bodies.
Definition: imstkPbdBody.h:178