iMSTK
Interactive Medical Simulation Toolkit
EmbeddingConstraint.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 "EmbeddingConstraint.h"
8 #include "imstkCollisionUtils.h"
9 
10 namespace imstk
11 {
12 void
14  PbdState& bodies,
15  const PbdParticleId& ptA1,
16  const PbdParticleId& ptB1, const PbdParticleId& ptB2, const PbdParticleId& ptB3,
17  Vec3d* p, Vec3d* q,
18  const double compliance)
19 {
20  // Set the triangle
21  m_particles[0] = ptB1;
22  m_particles[1] = ptB2;
23  m_particles[2] = ptB3;
24  const Vec3d& x1 = bodies.getPosition(m_particles[0]);
25  const Vec3d& x2 = bodies.getPosition(m_particles[1]);
26  const Vec3d& x3 = bodies.getPosition(m_particles[2]);
27 
28  // Compute intersection point & interpolant on triangle
29  CollisionUtils::testSegmentTriangle(*p, *q, x1, x2, x3, m_uvw);
30  m_iPt = x1 * m_uvw[0] + x2 * m_uvw[1] + x3 * m_uvw[2];
31 
32  m_particles[3] = ptA1;
33  // Compute local untransformed position on needle (the iPt will move with the needle)
34  m_r[3] = bodies.getOrientation(ptA1).inverse()._transformVector(m_iPt - bodies.getPosition(ptA1));
35 
36  // Compute the interpolant on the line
37  {
38  m_p = p;
39  m_q = q;
40  const Vec3d pq = (*p - *q).normalized();
41  const Vec3d d = m_iPt - *q;
42  t = pq.dot(d);
43  m_uv[0] = t = pq.dot(d) / pq.norm();
44  m_uv[1] = 1.0 - m_uv[0];
45  }
46 
47  setCompliance(compliance);
48 }
49 
50 Vec3d
52 {
53  const Vec3d& x1 = bodies.getPosition(m_particles[0]);
54  const Vec3d& x2 = bodies.getPosition(m_particles[1]);
55  const Vec3d& x3 = bodies.getPosition(m_particles[2]);
56 
57  Vec3d* p = m_p;
58  Vec3d* q = m_q;
59  const Vec3d pq = (*p - *q);
60  const Vec3d pq_n = pq.normalized();
61 
62  // Compute the location of the intersection point on both elements
63  const Vec3d triPos = x1 * m_uvw[0] + x2 * m_uvw[1] + x3 * m_uvw[2];
64  const Vec3d linePos = (*q) * m_uv[0] + (*p) * m_uv[1];
65  //const Vec3d linePos = (*q) + pq_n * t;
66 
67  // Compute the transform to align the triangle to the line
68  return triPos - linePos;
69 }
70 
71 bool
73  std::vector<Vec3d>& dcdx)
74 {
75  // Triangle
76  const Vec3d& x0 = bodies.getPosition(m_particles[0]);
77  const Vec3d& x1 = bodies.getPosition(m_particles[1]);
78  const Vec3d& x2 = bodies.getPosition(m_particles[2]);
79  // Body center of mass
80  const Vec3d& x3 = bodies.getPosition(m_particles[3]);
81  //const Quatd& q3 = bodies.getOrientation(m_particles[3]);
82 
83  // Compute the normal/axes of the line
84  const Vec3d pq = *m_p - *m_q;
85  const Vec3d pq_n = pq.normalized();
86 
87  // Compute the difference between the two interpolated points on the elements
88  Vec3d diff = computeInterpolantDifference(bodies);
89 
90  // Remove any normal movement (remove only fraction for sort of friction)
91  // Frees normal movement
92  diff = diff - diff.dot(pq_n) * pq_n * (1.0 - m_normalFriction);
93  const Vec3d ortho = diff.normalized(); // Constrain only orthogonal movement
94 
95  // Puncture point
96  const Vec3d triPos = m_iPt = x0 * m_uvw[0] + x1 * m_uvw[1] + x2 * m_uvw[2];
97 
98  dcdx[0] = -ortho;
99  dcdx[1] = -ortho;
100  dcdx[2] = -ortho;
101  dcdx[3] = ortho;
102  //m_r[3] = triPos - x3;
103 
104  c = -diff.norm();
105 
106  return true;
107 }
108 } // 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.
bool computeValueAndGradient(PbdState &bodies, double &c, std::vector< Vec3d > &dcdx) override
Compute value and gradient of the constraint.
Vec3d computeInterpolantDifference(const PbdState &bodies) const
Given two interpolants on the two elements, compute the difference between them and use for resolutio...
void initConstraint(PbdState &bodies, const PbdParticleId &ptA1, const PbdParticleId &ptB1, const PbdParticleId &ptB2, const PbdParticleId &ptB3, Vec3d *p, Vec3d *q, const double compliance=0.0)
Initializes both PBD and RBD constraint.
Provides interface for accessing particles from a 2d array of PbdBody,Particles.
Definition: imstkPbdBody.h:229