7 #include "imstkBoneDrillingCH.h" 8 #include "imstkCollidingObject.h" 9 #include "imstkCollisionData.h" 10 #include "imstkParallelFor.h" 11 #include "imstkRbdConstraint.h" 12 #include "imstkRigidObject2.h" 13 #include "imstkTetrahedralMesh.h" 20 setInputObjectB(drillObject);
23 std::shared_ptr<RigidObject2>
24 BoneDrillingCH::getDrillObj()
const 26 return std::dynamic_pointer_cast<
RigidObject2>(getInputObjectB());
31 const std::vector<CollisionElement>& elementsA,
32 const std::vector<CollisionElement>& elementsB)
34 auto boneTetMesh = std::dynamic_pointer_cast<
TetrahedralMesh>(getBoneObj()->getCollidingGeometry());
37 ParallelUtils::parallelFor(elementsA.size(),
43 if ((elementB.m_type != CollisionElementType::PointDirection && elementB.m_type != CollisionElementType::PointIndexDirection)
44 || elementA.m_type != CollisionElementType::CellIndex || elementA.m_element.m_CellIndexElement.cellType != IMSTK_TETRAHEDRON)
49 if (elementA.m_element.m_CellIndexElement.idCount != 1)
54 const int tetIndex = elementA.m_element.m_CellIndexElement.ids[0];
56 if (elementB.m_type == CollisionElementType::PointDirection)
58 depth = elementB.m_element.m_PointDirectionElement.penetrationDepth;
60 else if (elementB.m_type == CollisionElementType::PointIndexDirection)
62 depth = elementB.m_element.m_PointIndexDirectionElement.penetrationDepth;
65 if (m_nodeRemovalStatus[tetIndex])
70 m_nodalDensity[tetIndex] -= 0.001 * (m_angularSpeed / m_BoneHardness) * m_stiffness * depth * 0.001;
72 if (m_nodalDensity[tetIndex] <= 0.)
78 m_nodeRemovalStatus[tetIndex] =
true;
81 for (
auto& tetId : m_nodalCardinalSet[tetIndex])
83 boneTetMesh->setTetrahedraAsRemoved(static_cast<unsigned int>(tetId));
91 const std::vector<CollisionElement>& elementsA,
92 const std::vector<CollisionElement>& elementsB)
94 std::shared_ptr<CollidingObject> bone = getBoneObj();
95 std::shared_ptr<RigidObject2> drill = getDrillObj();
97 auto boneMesh = std::dynamic_pointer_cast<
TetrahedralMesh>(bone->getCollidingGeometry());
99 if (m_nodalDensity.size() != boneMesh->getNumVertices())
102 m_nodalDensity.reserve(boneMesh->getNumVertices());
103 for (
size_t i = 0; i < boneMesh->getNumVertices(); ++i)
105 m_nodalDensity.push_back(m_initialBoneDensity);
108 m_nodeRemovalStatus.reserve(boneMesh->getNumVertices());
109 for (
size_t i = 0; i < boneMesh->getNumVertices(); ++i)
111 m_nodeRemovalStatus.push_back(
false);
114 m_nodalCardinalSet.reserve(boneMesh->getNumVertices());
115 for (
size_t i = 0; i < boneMesh->getNumVertices(); ++i)
117 std::vector<size_t> row;
118 m_nodalCardinalSet.push_back(row);
122 for (
size_t tetId = 0; tetId < boneMesh->getNumCells(); ++tetId)
124 const Vec4i& indices = (*boneMesh->getCells())[tetId];
125 for (
int i = 0; i < 4; i++)
127 m_nodalCardinalSet[indices[i]].push_back(tetId);
133 if (elementsA.size() != elementsB.size())
139 const auto devicePosition = drill->getCollidingGeometry()->getTranslation();
140 if (elementsA.empty() && elementsB.empty())
143 drill->getVisualGeometry()->setTranslation(devicePosition);
150 Vec3d t = Vec3d::Zero();
151 double maxDepthSqr = MIN_D;
152 for (
size_t i = 0; i < elementsB.size(); i++)
157 if ((elementB.m_type != CollisionElementType::PointDirection && elementB.m_type != CollisionElementType::PointIndexDirection)
158 || elementA.m_type != CollisionElementType::CellIndex || elementA.m_element.m_CellIndexElement.cellType != IMSTK_TETRAHEDRON)
163 if (elementA.m_element.m_CellIndexElement.idCount != 1)
168 const int tetIndex = elementA.m_element.m_CellIndexElement.ids[0];
170 Vec3d dir = Vec3d::Zero();
171 if (elementB.m_type == CollisionElementType::PointDirection)
173 depth = elementB.m_element.m_PointDirectionElement.penetrationDepth;
174 dir = elementB.m_element.m_PointDirectionElement.dir;
176 else if (elementB.m_type == CollisionElementType::PointIndexDirection)
178 depth = elementB.m_element.m_PointIndexDirectionElement.penetrationDepth;
179 dir = elementB.m_element.m_PointIndexDirectionElement.dir;
182 if (m_nodeRemovalStatus[tetIndex])
187 const double dSqr = depth * depth;
188 if (dSqr > maxDepthSqr)
194 drill->getVisualGeometry()->setTranslation(devicePosition + t);
197 Vec3d force = m_stiffness * (drill->getVisualGeometry()->getTranslation() - devicePosition);
200 const double dt = 0.1;
201 force += m_initialStep ? Vec3d(0.0, 0.0, 0.0) : m_damping * (devicePosition - m_prevPos) / dt;
204 (*drill->getRigidBody()->m_force) = force;
210 m_initialStep =
false;
211 m_prevPos = devicePosition;
void erodeBone(const std::vector< CollisionElement > &elementsA, const std::vector< CollisionElement > &elementsB)
Decrease the density at the nodal points and remove if the density goes below 0.
virtual void handle(const std::vector< CollisionElement > &elementsA, const std::vector< CollisionElement > &elementsB) override
Does the bone drilling.
void setInputObjectDrill(std::shared_ptr< RigidObject2 > drillObject)
Set the input drill.
Union of collision elements. We use a union to avoid polymorphism. There may be many elements and acc...
Represents a set of tetrahedrons & vertices via an array of Vec3d double vertices & Vec4i integer ind...
Scene objects that are governed by rigid body dynamics under the RigidBodyModel2. ...