iMSTK
Interactive Medical Simulation Toolkit
imstkNeedlePbdCH.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 "imstkMacros.h"
10 #include "imstkPbdCollisionHandling.h"
11 #include "imstkPbdPointTriangleConstraint.h"
12 #include "imstkSurfaceMesh.h"
13 
14 #include "imstkSurfaceInsertionConstraint.h"
15 #include "imstkThreadInsertionConstraint.h"
16 
17 // using namespace imstk;
18 namespace imstk
19 {
20 class PbdObject;
22 class LineMesh;
23 class TetrahedralMesh;
24 
33 {
34 public:
35  NeedlePbdCH() = default;
36  ~NeedlePbdCH() override = default;
37 
38  IMSTK_TYPE_NAME(NeedlePbdCH)
39 
40  // Stores data for penetration points, both for the needle and the thread
41  struct PuncturePoint // Note, this needs to be public
42  {
43  // Triangle ID on Surface mesh used for suture
44  int triId = -1;
45 
46  // Triangle vertices on Physics mesh used for suture (found via map from surface -> physics mesh)
47  Vec3i triVertIds = { -1, -1, -1 };
48  // Puncture barycentric coordinate on triangle
49  Vec3d baryCoords = { 0.0, 0.0, 0.0 };
50  // Line segment ID of needle or thread
51  int segId = -1;
52  };
53 
54  struct PunctureData
55  {
56  std::vector<PuncturePoint> thread;
57  std::vector<PuncturePoint> needle;
58  std::vector<std::vector<PuncturePoint>> stitch;
59  };
60 
64  void init(std::shared_ptr<PbdObject> threadObj);
65 
69  void stitch();
70 
74  void handle(
75  const std::vector<CollisionElement>& elementsA,
76  const std::vector<CollisionElement>& elementsB) override;
77 
78  void generateNewPunctureData();
79  void addPunctureConstraints();
80 
81  void setNeedleToSurfaceStiffness(double stiffness) { m_needleToSurfaceStiffness = stiffness; }
82  double getNeedleToSurfaceStiffness() { return m_needleToSurfaceStiffness; }
83 
84  void setSurfaceToNeedleStiffness(double stiffness) { m_surfaceToNeedleStiffness = stiffness; }
85  double getSurfaceToNeedleStiffness() { return m_surfaceToNeedleStiffness; }
86 
87  void setThreadToSurfaceStiffness(double stiffness) { m_needleToSurfaceStiffness = stiffness; }
88  double getThreadToSurfaceStiffness() { return m_needleToSurfaceStiffness; }
89 
90  void setSurfaceToThreadStiffness(double stiffness) { m_surfaceToThreadStiffness = stiffness; }
91  double getSurfaceToThreadStiffness() { return m_surfaceToThreadStiffness; }
92 
93  void setPunctureDotThreshold(double threshold) { m_threshold = threshold; }
94  double getPunctureDotThreshold() { return m_threshold; }
95 
96  // Add getters for all puncture data
97  const PunctureData& getPunctureData() { return pData; };
98 
99 protected:
100 
101  // Flags for which entity is puncturing a triangle
102  std::vector<bool> m_isThreadPunctured;
103 
104  // Vector of needle-triangle constraints (one sided, force triangle to follow needle)
105  std::vector<std::shared_ptr<SurfaceInsertionConstraint>> pointTriangleConstraints;
106 
107  // Vector of thread-triangle constraints (one sided, force thread to follow triangle)
108  std::vector<std::shared_ptr<PbdBaryPointToPointConstraint>> m_stitchConstraints;
109 
110  // All constraints
111  std::vector<std::shared_ptr<PbdConstraint>> m_constraints;
112  std::vector<PbdConstraint*> m_solverConstraints;
113 
114  // Penetration data for needle, thread, and stitch
115  PunctureData pData;
116 
117  // Bool to activate stitching constraint
118  bool m_stitch = false;
119 
120  // Center of puncture points for stitching constraint
121  std::vector<Vec3d> m_stitchPoints;
122 
123  // Thread Data
124  std::shared_ptr<PbdObject> m_threadObj;
125  std::shared_ptr<LineMesh> m_threadMesh;
126 
127  // PBD Tissue Mesh Data
128  std::shared_ptr<PbdObject> m_pbdTissueObj;
129  std::shared_ptr<SurfaceMesh> m_tissueSurfMesh;
130 
131  std::shared_ptr<PbdObject> m_needleObj;
132  std::shared_ptr<LineMesh> m_needleMesh;
133 
134  // Stiffnesses
135  // NOTE: for now, this stiffness times the iteration count needs to be one
136  // TODO: Reformat constraints with reprojection step
137  double m_needleToSurfaceStiffness = 0.2;
138  double m_surfaceToNeedleStiffness = 0.2;
139  double m_threadToSurfaceStiffness = 0.2;
140  double m_surfaceToThreadStiffness = 0.2;
141 
142  bool m_needlePunctured = false;
143  bool m_threadPunctured = false;
144 
145  // Puncture angle dot product threshold
146  double m_threshold = 0.8;
147 
148 private:
149 
150  std::vector<PbdParticleId> m_particles;
151  std::vector<std::shared_ptr<PbdConstraint>> m_threadConstraints;
152 
153  bool didPuncture(const std::vector<CollisionElement>& elementsA, const std::vector<CollisionElement>& elementsB);
154 };
155 } // end iMSTK namespace
void handle(const std::vector< CollisionElement > &elementsA, const std::vector< CollisionElement > &elementsB) override
Handles puncture constraints for both the needle and the thread.
Implements PBD based collision handling. Given an input PbdObject and CollisionData it creates & adds...
Compound Geometry.
Represents a set of tetrahedrons & vertices via an array of Vec3d double vertices & Vec4i integer ind...
Base class for all volume mesh types.
Definition: imstkLineMesh.h:18
void init(std::shared_ptr< PbdObject > threadObj)
Initialize interaction data.
Base class for scene objects that move and/or deform under position based dynamics formulation...
Constrains two points from two separate cells/elements given via barycentric coordinates to be coinci...
Handles penetration constraints for the needle and the thread by creating a set of puncture points th...