7 #include "imstkPortHoleInteraction.h" 8 #include "imstkCapsule.h" 9 #include "imstkLineMesh.h" 10 #include "imstkPbdContactConstraint.h" 11 #include "imstkPbdModel.h" 12 #include "imstkPbdObject.h" 13 #include "imstkPbdSolver.h" 14 #include "imstkTaskGraph.h" 15 #include "imstkTaskNode.h" 19 PortHoleInteraction::PortHoleInteraction(
const std::string& name) :
SceneBehaviour(true, name),
20 m_portConstraint(
std::make_shared<PbdRigidLineToPointConstraint>())
22 m_portHoleHandleNode = std::make_shared<TaskNode>([&]()
26 m_collisionGeometryUpdateNode = std::make_shared<TaskNode>([&]()
28 m_toolObject->updateGeometries();
29 },
"CollisionGeometryUpdate");
31 m_constraints.resize(1);
32 m_constraints[0] = m_portConstraint.get();
38 CHECK(m_toolObject !=
nullptr) <<
"PortHoleInteraction requires a input tool object," 39 "please provide it with PortHoleInteraction::setTool";
40 CHECK(m_toolGeom !=
nullptr) <<
"PortHoleInteraction requires a tool geometry," 41 "please provide it with PortHoleInteraction::setToolGeometry";
43 m_taskGraph->addNode(m_portHoleHandleNode);
44 m_taskGraph->addNode(m_collisionGeometryUpdateNode);
45 m_taskGraph->addNode(m_toolObject->getPbdModel()->getIntegratePositionNode());
46 m_taskGraph->addNode(m_toolObject->getPbdModel()->getSolveNode());
50 PortHoleInteraction::setTool(std::shared_ptr<PbdObject> toolObject)
52 CHECK(m_toolObject ==
nullptr) <<
"PortHoleInteraction does not yet support changing" 53 "the tool at runtime, please set before initialization of the scene";
54 m_toolObject = toolObject;
58 PortHoleInteraction::setToolGeometry(std::shared_ptr<Geometry> toolGeom)
60 CHECK(std::dynamic_pointer_cast<LineMesh>(toolGeom) !=
nullptr 61 || std::dynamic_pointer_cast<Capsule>(toolGeom) !=
nullptr) <<
62 "PortHoleInteraction only works with capsule or line tool geometry";
63 m_toolGeom = toolGeom;
67 PortHoleInteraction::handlePortHole()
70 CHECK(m_toolGeom !=
nullptr) <<
71 "PortHoleInteraction requires a tool geometry";
74 p = q = Vec3d::Zero();
75 if (
auto lineMesh = std::dynamic_pointer_cast<LineMesh>(m_toolGeom))
77 CHECK(lineMesh->getNumVertices() == 2) <<
78 "PortHoleInteraction currently only works with straight single segment lines";
80 p = (*lineMesh->getVertexPositions())[0];
81 q = (*lineMesh->getVertexPositions())[1];
83 else if (
auto capsule = std::dynamic_pointer_cast<Capsule>(m_toolGeom))
85 const Vec3d capsule1Pos = capsule->getPosition();
86 const Vec3d capsule1Axis = capsule->getOrientation().toRotationMatrix().col(1).normalized();
87 const double capsule1HalfLength = capsule->getLength() * 0.5;
88 const Vec3d diff1 = capsule1Axis * capsule1HalfLength;
90 p = capsule1Pos - diff1;
91 q = capsule1Pos + diff1;
94 std::shared_ptr<PbdModel> pbdModel = m_toolObject->getPbdModel();
95 const PbdParticleId vid = pbdModel->addVirtualParticle(m_portHoleLocation, 0.0);
97 m_portConstraint->initConstraint(m_toolObject->getPbdModel()->getBodies(),
98 { m_toolObject->getPbdBody()->bodyHandle, 0 },
102 pbdModel->getSolver()->addConstraints(&m_constraints);
106 PortHoleInteraction::initGraphEdges(std::shared_ptr<TaskNode> source, std::shared_ptr<TaskNode> sink)
110 m_taskGraph->addEdge(source, m_toolObject->getPbdModel()->getSolveNode());
112 m_taskGraph->addEdge(m_toolObject->getPbdModel()->getIntegratePositionNode(), m_collisionGeometryUpdateNode);
113 m_taskGraph->addEdge(m_collisionGeometryUpdateNode, m_portHoleHandleNode);
114 m_taskGraph->addEdge(m_portHoleHandleNode, m_toolObject->getPbdModel()->getSolveNode());
116 m_taskGraph->addEdge(m_portHoleHandleNode, sink);
void init() override
Initialize the component, called at a later time after all component construction is complete...
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...