iMSTK
Interactive Medical Simulation Toolkit
imstkPbdPointTriangleConstraint.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 "imstkPbdPointTriangleConstraint.h"
8 
9 namespace imstk
10 {
11 void
13  const PbdParticleId& ptB1, const PbdParticleId& ptB2, const PbdParticleId& ptB3,
14  double stiffnessA, double stiffnessB)
15 {
16  m_particles[0] = ptA;
17  m_particles[1] = ptB1;
18  m_particles[2] = ptB2;
19  m_particles[3] = ptB3;
20 
21  m_stiffness[0] = stiffnessA;
22  m_stiffness[1] = stiffnessB;
23 }
24 
25 bool
27  PbdState& bodies,
28  double& c, std::vector<Vec3d>& dcdx)
29 {
30  const Vec3d& x0 = bodies.getPosition(m_particles[0]);
31  const Vec3d& x1 = bodies.getPosition(m_particles[1]);
32  const Vec3d& x2 = bodies.getPosition(m_particles[2]);
33  const Vec3d& x3 = bodies.getPosition(m_particles[3]);
34 
35  // Compute barycentric coordinates u,v,w
36  const Vec3d bary = baryCentric(x0, x1, x2, x3);
37 
38  // This constraint becomes invalid if moved out of the triangle
39  if (bary[0] < 0.0 || bary[1] < 0.0 || bary[2] < 0.0)
40  {
41  c = 0.0;
42  return false;
43  }
44 
45  // If contacting point near a boundary ignore constraint
47  {
48  int maxId = 0;
49  bary.maxCoeff(&maxId);
50  // +1 as first particle is from other body (vertex)
51  if (bodies.getInvMass(m_particles[maxId + 1]) == 0.0)
52  {
53  c = 0.0;
54  return false;
55  }
56  }
57 
58  // Triangle normal (pointing up on counter clockwise triangle)
59  const Vec3d n = (x2 - x1).cross(x3 - x1).normalized();
60  // Point could be on either side of triangle, we want to resolve to the triangles plane
61  const double l = (x0 - x1).dot(n);
62 
63  // A
64  dcdx[0] = -n;
65  // B
66  dcdx[1] = bary[0] * n;
67  dcdx[2] = bary[1] * n;
68  dcdx[3] = bary[2] * n;
69 
70  c = l;
71 
72  return true;
73 }
74 } // namespace imstk
std::pair< int, int > PbdParticleId
Index pair that refers to a particle in a PbdState. Index 0 is the body id, Index 1 is the particle i...
std::vector< PbdParticleId > m_particles
body, particle index
Compound Geometry.
void initConstraint(const PbdParticleId &ptA, const PbdParticleId &ptB1, const PbdParticleId &ptB2, const PbdParticleId &ptB3, double stiffnessA, double stiffnessB)
Initialize the constraint.
Provides interface for accessing particles from a 2d array of PbdBody,Particles.
Definition: imstkPbdBody.h:229
bool computeValueAndGradient(PbdState &bodies, double &c, std::vector< Vec3d > &dcdx) override
Compute value and gradient of constraint function.