9 #include "imstkMacros.h" 10 #include "imstkNeedle.h" 11 #include "imstkPuncturable.h" 12 #include "imstkRbdContactConstraint.h" 13 #include "imstkRigidBodyCH.h" 14 #include "imstkRigidBodyModel2.h" 15 #include "imstkRigidObject2.h" 17 #include "RbdAxesLockingConstraint.h" 18 #include "RbdAngularLockingConstraint.h" 20 using namespace imstk;
30 void setNeedleForceThreshold(
double needleForceThreshold) { m_needleForceThreshold = needleForceThreshold; }
31 double getNeedleForceThrehsold()
const {
return m_needleForceThreshold; }
38 const std::vector<CollisionElement>& elementsA,
39 const std::vector<CollisionElement>& elementsB)
override 41 std::shared_ptr<CollidingObject> needleObj = getInputObjectA();
42 m_needle = needleObj->getComponent<
Needle>();
43 std::shared_ptr<CollidingObject> tissueObj = getInputObjectB();
44 m_puncturable = tissueObj->getComponent<
Puncturable>();
50 if (elementsA.size() == 0)
52 m_needle->setState(
getPunctureId(m_needle, m_puncturable), Puncture::State::REMOVED);
60 std::shared_ptr<RigidObject2> rbdObj,
61 const Vec3d& contactPt,
const Vec3d& contactNormal,
62 const double contactDepth)
override 67 const Vec3d n = contactNormal.normalized();
68 if (m_needle->getState(punctureId) == Puncture::State::TOUCHING)
71 const Vec3d needleAxes = m_needle->getNeedleDirection();
72 const double fN = std::max(needleAxes.dot(rbdObj->getRigidBody()->getForce()), 0.0);
74 if (fN > m_needleForceThreshold)
76 LOG(INFO) <<
"Puncture!\n";
77 m_needle->setState(punctureId, Puncture::State::INSERTED);
80 m_initNeedleAxes = needleAxes;
81 m_initNeedleOrientation = Quatd::FromTwoVectors(Vec3d(0.0, -1.0, 0.0), needleAxes);
82 m_initContactPt = contactPt;
87 if (m_needle->getState(punctureId) == Puncture::State::TOUCHING)
89 auto contactConstraint = std::make_shared<RbdContactConstraint>(
90 rbdObj->getRigidBody(),
nullptr,
91 n, contactPt, contactDepth,
93 RbdConstraint::Side::A);
94 contactConstraint->compute(rbdObj->getRigidBodyModel2()->getTimeStep());
95 rbdObj->getRigidBodyModel2()->addConstraint(contactConstraint);
98 else if (m_needle->getState(punctureId) == Puncture::State::INSERTED)
100 auto needleLockConstraint = std::make_shared<RbdAxesLockingConstraint>(
101 rbdObj->getRigidBody(),
102 m_initContactPt, m_initNeedleAxes,
104 needleLockConstraint->compute(rbdObj->getRigidBodyModel2()->getTimeStep());
105 rbdObj->getRigidBodyModel2()->addConstraint(needleLockConstraint);
107 auto needleLockConstraint2 = std::make_shared<RbdAngularLockingConstraint>(
108 rbdObj->getRigidBody(), m_initNeedleOrientation, 0.05);
109 needleLockConstraint2->compute(rbdObj->getRigidBodyModel2()->getTimeStep());
110 rbdObj->getRigidBodyModel2()->addConstraint(needleLockConstraint2);
115 double m_needleForceThreshold = 250.0;
117 std::shared_ptr<Needle> m_needle;
118 std::shared_ptr<Puncturable> m_puncturable;
119 Vec3d m_initContactPt = Vec3d::Zero();
120 Vec3d m_initNeedleAxes = Vec3d::Zero();
121 Quatd m_initNeedleOrientation = Quatd::Identity();
PunctureId getPunctureId(std::shared_ptr< Needle > needle, std::shared_ptr< Puncturable > puncturable, const int supportId)
Get puncture id between needle and puncturable.
Place this on an object to make it puncturable by a needle. This allows puncturables to know they've ...
void handle(const std::vector< CollisionElement > &elementsA, const std::vector< CollisionElement > &elementsB) override
Handle the collision/contact data.
Base for all needles in imstk it supports global puncture state, per object puncture state...
virtual void handle(const std::vector< CollisionElement > &elementsA, const std::vector< CollisionElement > &elementsB) override
Add rigid body constraints according to contacts.
Creates rigid body contact and frictional constraints given collision data then adds them to the rigi...
void addConstraint(std::shared_ptr< RigidObject2 > rbdObj, const Vec3d &contactPt, const Vec3d &contactNormal, const double contactDepth) override
Add constraint for the rigid body given contact.
std::tuple< int, int, int > PunctureId
Punctures are identified via three ints. The needle id, the puncturable id, and a local id that allow...