7 #include "NeedleRigidBodyCH.h" 8 #include "imstkLineMesh.h" 9 #include "imstkNeedle.h" 10 #include "imstkPuncturable.h" 11 #include "imstkRbdContactConstraint.h" 12 #include "imstkRigidBodyModel2.h" 13 #include "imstkRigidObject2.h" 14 #include "imstkVecDataArray.h" 15 #include "RbdLineToPointRotationConstraint.h" 16 #include "RbdLineToPointTranslationConstraint.h" 18 using namespace imstk;
22 const std::vector<CollisionElement>& elementsA,
23 const std::vector<CollisionElement>& elementsB)
30 std::shared_ptr<CollidingObject> needleObj = getInputObjectA();
31 auto needle = needleObj->getComponent<
Needle>();
32 std::shared_ptr<CollidingObject> tissueObj = getInputObjectB();
33 auto puncturable = tissueObj->getComponent<
Puncturable>();
36 Puncture::State state = needle->getState(punctureId);
37 if (elementsA.size() == 0)
39 if (state == Puncture::State::INSERTED)
41 needle->setState(punctureId, Puncture::State::REMOVED);
42 LOG(INFO) <<
"Unpuncture!\n";
44 else if (state == Puncture::State::TOUCHING)
46 needle->setState(punctureId, Puncture::State::REMOVED);
53 std::shared_ptr<RigidObject2> rbdObj,
54 const Vec3d& contactPt,
const Vec3d& contactNormal,
55 const double contactDepth)
57 auto needle = rbdObj->getComponent<
Needle>();
58 std::shared_ptr<CollidingObject> tissueObj = getInputObjectB();
59 auto puncturable = tissueObj->getComponent<
Puncturable>();
63 if (needle->getState(punctureId) == Puncture::State::REMOVED)
65 needle->setState(punctureId, Puncture::State::TOUCHING);
68 const Vec3d n = contactNormal.normalized();
69 if (needle->getState(punctureId) == Puncture::State::TOUCHING)
72 const Vec3d needleAxes = needle->getNeedleDirection();
73 const double fN = std::max(needleAxes.dot(rbdObj->getRigidBody()->getForce()), 0.0);
77 LOG(INFO) <<
"Puncture!\n";
78 needle->setState(punctureId, Puncture::State::INSERTED);
79 puncturable->setPuncture(punctureId, needle->getPuncture(punctureId));
82 m_initNeedleAxes = needleAxes;
83 m_initNeedleOrientation = Quatd::FromTwoVectors(Vec3d(0.0, -1.0, 0.0), needleAxes);
84 m_initContactPt = contactPt;
89 Puncture::State state = needle->getState(punctureId);
90 if (state == Puncture::State::TOUCHING)
92 auto contactConstraint = std::make_shared<RbdContactConstraint>(
93 rbdObj->getRigidBody(),
nullptr,
94 n, contactPt, contactDepth,
96 RbdConstraint::Side::A);
97 contactConstraint->compute(rbdObj->getRigidBodyModel2()->getTimeStep());
98 rbdObj->getRigidBodyModel2()->addConstraint(contactConstraint);
101 else if (state == Puncture::State::INSERTED)
103 auto lineMesh = std::dynamic_pointer_cast<
LineMesh>(rbdObj->getPhysicsGeometry());
104 Vec3d* p = &(*lineMesh->getVertexPositions())[0];
105 Vec3d* q = &(*lineMesh->getVertexPositions())[1];
108 auto translationConstraint = std::make_shared<RbdLineToPointTranslationConstraint>(
109 rbdObj->getRigidBody(), m_initContactPt, p, q, 0.1);
110 translationConstraint->compute(rbdObj->getRigidBodyModel2()->getTimeStep());
111 rbdObj->getRigidBodyModel2()->addConstraint(translationConstraint);
115 double x = contactDepth / 0.02;
120 rbdObj->getRigidBody()->m_intertiaTensor = Mat3d::Identity() *
121 (10000.0 + x * 10000.0);
122 rbdObj->getRigidBodyModel2()->updateMass();
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...
Base class for all volume mesh types.
virtual void handle(const std::vector< CollisionElement > &elementsA, const std::vector< CollisionElement > &elementsB) override
Add rigid body constraints according to contacts.
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...