66#include < sofa/collisionAlgorithm/operations/CreateCenterProximity.h>
77#include < sofa/collisionAlgorithm/operations/FindClosestProximity.h>
88#include < sofa/collisionAlgorithm/operations/Project.h>
9- #include < sofa/colliisonAlgorithm/operations/ContainsPoint.h>
9+ #include < sofa/collisionAlgorithm/operations/ContainsPoint.h>
10+ #include < sofa/collisionAlgorithm/operations/NeedleOperations.h>
1011#include < sofa/collisionAlgorithm/proximity/EdgeProximity.h>
1112#include < sofa/collisionAlgorithm/proximity/TetrahedronProximity.h>
1213#include < sofa/component/constraint/lagrangian/solver/ConstraintSolverImpl.h>
@@ -225,6 +226,7 @@ class InsertionAlgorithm : public BaseAlgorithm
225226 // Only add a new coupling point if the needle tip has advanced far enough
226227 if (tipToLastCP.norm () > tipDistThreshold)
227228 {
229+ // Prepare the operations before entering the loop
228230 auto createShaftProximity =
229231 Operations::CreateCenterProximity::Operation::get (l_shaftGeom->getTypeInfo ());
230232 auto projectOnShaft = Operations::Project::Operation::get (l_shaftGeom);
@@ -268,15 +270,18 @@ class InsertionAlgorithm : public BaseAlgorithm
268270 // Skip if candidate CP is outside current edge segment
269271 if (projPtOnEdge < 0_sreal || projPtOnEdge > edgeSegmentLength) break ;
270272
271- // Project candidate CP onto shaft geometry and then find nearest volume
272- // proximity
273+ // Project candidate CP onto shaft geometry ...
273274 shaftProx = projectOnShaft (candidateCP, itShaft->element ()).prox ;
274275 if (!shaftProx) continue ;
275276
277+ // ... then find nearest volume proximity
276278 const BaseProximity::SPtr volProx = findClosestProxOnVol (
277279 shaftProx, l_volGeom.get (), projectOnVol, getFilterFunc ());
278280 if (!volProx) continue ;
279281
282+ // Proximity can be detected before the tip enters the tetra (e.g. near a
283+ // boundary face) Only accept proximities if the tip is inside the tetra
284+ // during insertion
280285 if (containsPointInVol (shaftProx->getPosition (), volProx))
281286 {
282287 volProx->normalize ();
@@ -288,38 +293,11 @@ class InsertionAlgorithm : public BaseAlgorithm
288293 }
289294 else // Don't bother with removing the point that was just added
290295 {
291- // 2.2. Check whether coupling point should be removed
296+ // Remove coupling points that are ahead of the tip in the insertion direction
292297 ElementIterator::SPtr itShaft = l_shaftGeom->begin (l_shaftGeom->getSize () - 2 );
293- auto createShaftProximity =
294- Operations::CreateCenterProximity::Operation::get (itShaft->getTypeInfo ());
295- const BaseProximity::SPtr shaftProx = createShaftProximity (itShaft->element ());
296- if (shaftProx)
297- {
298- const EdgeProximity::SPtr edgeProx =
299- dynamic_pointer_cast<EdgeProximity>(shaftProx);
300- if (edgeProx)
301- {
302- const type::Vec3 normal = (edgeProx->element ()->getP1 ()->getPosition () -
303- edgeProx->element ()->getP0 ()->getPosition ())
304- .normalized ();
305- // If the (last) coupling point lies ahead of the tip (positive dot
306- // product), the needle is retreating. Thus, that point is removed.
307- if (dot (tipToLastCP, normal) > 0_sreal)
308- {
309- m_couplingPts.pop_back ();
310- }
311- }
312- else
313- {
314- msg_warning () << " shaftGeom: " << l_shaftGeom->getName ()
315- << " is not an EdgeGeometry. Point removal is disabled" ;
316- }
317- }
318- else
319- {
320- msg_warning () << " Cannot create proximity from shaftGeom: "
321- << l_shaftGeom->getName () << " - point removal is disabled" ;
322- }
298+ auto prunePointsAheadOfTip =
299+ Operations::Needle::PrunePointsAheadOfTip::get (itShaft->getTypeInfo ());
300+ prunePointsAheadOfTip (m_couplingPts, itShaft->element ());
323301 }
324302 }
325303
0 commit comments