iMSTK
Interactive Medical Simulation Toolkit
All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Pages
imstkPbdBaryPointToPointConstraint.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 "imstkPbdBaryPointToPointConstraint.h"
8 
9 namespace imstk
10 {
11 Vec3d
13 {
14  Vec3d p1 = Vec3d::Zero();
15  Vec3d p2 = Vec3d::Zero();
16  for (size_t i = 0; i < m_particles.size(); i++)
17  {
18  if (m_bodiesSides[i])
19  {
20  p2 += bodies.getPosition(m_particles[i]) * m_weights[i];
21  }
22  else
23  {
24  p1 += bodies.getPosition(m_particles[i]) * m_weights[i];
25  }
26  }
27  return p2 - p1;
28 }
29 
30 void
32  PbdState& bodies,
33  const std::vector<PbdParticleId>& ptIdsA,
34  const std::vector<double>& weightsA,
35  const std::vector<PbdParticleId>& ptIdsB,
36  const std::vector<double>& weightsB,
37  const double stiffnessA, const double stiffnessB)
38 {
39  initConstraint(ptIdsA, weightsA, ptIdsB, weightsB, stiffnessA, stiffnessB, 0.0);
40  setRestLength(computeInterpolantDifference(bodies).norm());
41 }
42 
43 void
45  const std::vector<PbdParticleId>& ptIdsA,
46  const std::vector<double>& weightsA,
47  const std::vector<PbdParticleId>& ptIdsB,
48  const std::vector<double>& weightsB,
49  const double stiffnessA, const double stiffnessB,
50  const double restLength)
51 {
52  m_particles.resize(ptIdsA.size() + ptIdsB.size());
53  m_dcdx.resize(m_particles.size());
54  m_weights.resize(m_dcdx.size());
55  m_bodiesSides.resize(m_dcdx.size());
56 
57  for (size_t i = 0; i < ptIdsA.size(); i++)
58  {
59  m_particles[i] = ptIdsA[i];
60  m_weights[i] = weightsA[i];
61  m_bodiesSides[i] = false;
62  }
63  for (size_t i = 0, j = ptIdsA.size(); i < ptIdsB.size(); i++, j++)
64  {
65  m_particles[j] = ptIdsB[i];
66  m_weights[j] = weightsB[i];
67  m_bodiesSides[j] = true;
68  }
69 
70  m_restLength = restLength;
71  m_stiffness[0] = stiffnessA;
72  m_stiffness[1] = stiffnessB;
73 }
74 
75 bool
77  double& c, std::vector<Vec3d>& dcdx)
78 {
79  // Compute the difference between the interpolant points (points in the two cells)
80  Vec3d diff = computeInterpolantDifference(bodies);
81 
82  const double length = diff.norm();
83  c = length - m_restLength;
84 
85  // Save constraint value
86  m_C = c;
87 
88  if (length < 1.0e-16)
89  {
90  diff = Vec3d::Zero();
91  return false;
92  }
93  diff /= length;
94 
95  for (size_t i = 0; i < dcdx.size(); i++)
96  {
97  if (m_bodiesSides[i])
98  {
99  dcdx[i] = -diff * m_weights[i];
100  }
101  else
102  {
103  dcdx[i] = diff * m_weights[i];
104  }
105  }
106 
107  return true;
108 }
109 } // namespace imstk
std::vector< Vec3d > m_dcdx
Normalized constraint gradients (per particle)
std::vector< PbdParticleId > m_particles
body, particle index
Compound Geometry.
void initConstraint(const std::vector< PbdParticleId > &ptIdsA, const std::vector< double > &weightsA, const std::vector< PbdParticleId > &ptIdsB, const std::vector< double > &weightsB, const double stiffnessA, const double stiffnessB, const double restLength=0.0)
Initialize the constraint.
std::vector< bool > m_bodiesSides
Stores 0 or 1 to indicate side of particle.
bool computeValueAndGradient(PbdState &bodies, double &c, std::vector< Vec3d > &dcdx) override
Compute value and gradient of constraint function.
double m_C
Constraint Value.
Provides interface for accessing particles from a 2d array of PbdBody,Particles.
Definition: imstkPbdBody.h:229
void initConstraintToRest(PbdState &bodies, const std::vector< PbdParticleId > &ptIdsA, const std::vector< double > &weightsA, const std::vector< PbdParticleId > &ptIdsB, const std::vector< double > &weightsB, const double stiffnessA, const double stiffnessB)
initialize constraint with current distance between the points as the resting length ...