Skip to content

Commit aa7174d

Browse files
th-skamepernod
andauthored
[algorithm] Enable optional collision-only functionality in the InsertionAlgorithm (#98)
* [algorithm] Remove projection operation on tip in the InsertionAlgorithm- completely unnecessary * [algorithm] Changed FindClosestProximityAlgorithm to find the closest proximity back on the from geometry * [algorithm] Auto-format code * [algorithm] Rewrite some comments * [algorithm] Place shared operations at the top * [algorithm] Add a bool to enable/disable the puncture sequence * [algorithm] Add a bool to enable/disable insertion sequence * [algorithm] Add a bool to enable/disable shaft collision sequence * [algorithm] auto format code * [algorithm] Absorb the FindClosestProximity for shaft collision * [algorithm] Add an experimental component in the algorithm * [algorithm] Remove FindClosestProximityAlgorithm * [cmake] Remove FindClosestProximityAlgorithm from CMakeLists * [algorithm] Make sanity checks happen only when appropriate for some data * [algorithm] Place geometry checks in InsertionAlgorithm when they make sense --------- Co-authored-by: epernod <[email protected]>
1 parent d15d64a commit aa7174d

File tree

5 files changed

+92
-165
lines changed

5 files changed

+92
-165
lines changed

CMakeLists.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ set(HEADER_FILES
2424
${COLLISIONALGORITHM_SRC}/InternalData.h
2525

2626
${COLLISIONALGORITHM_SRC}/algorithm/Find2DClosestProximityAlgorithm.h
27-
${COLLISIONALGORITHM_SRC}/algorithm/FindClosestProximityAlgorithm.h
2827
${COLLISIONALGORITHM_SRC}/algorithm/InsertionAlgorithm.h
2928

3029
${COLLISIONALGORITHM_SRC}/broadphase/AABBBroadPhase.h
@@ -69,7 +68,6 @@ set(SOURCE_FILES
6968
${COLLISIONALGORITHM_SRC}/CollisionPipeline.cpp
7069

7170
${COLLISIONALGORITHM_SRC}/algorithm/Find2DClosestProximityAlgorithm.cpp
72-
${COLLISIONALGORITHM_SRC}/algorithm/FindClosestProximityAlgorithm.cpp
7371
${COLLISIONALGORITHM_SRC}/algorithm/InsertionAlgorithm.cpp
7472

7573
${COLLISIONALGORITHM_SRC}/broadphase/AABBBroadPhase.cpp

src/CollisionAlgorithm/algorithm/FindClosestProximityAlgorithm.cpp

Lines changed: 0 additions & 13 deletions
This file was deleted.

src/CollisionAlgorithm/algorithm/FindClosestProximityAlgorithm.h

Lines changed: 0 additions & 87 deletions
This file was deleted.

src/CollisionAlgorithm/algorithm/InsertionAlgorithm.h

Lines changed: 92 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
#include <CollisionAlgorithm/BaseAlgorithm.h>
44
#include <CollisionAlgorithm/BaseGeometry.h>
55
#include <CollisionAlgorithm/BaseOperation.h>
6+
#include <CollisionAlgorithm/operations/ContainsPoint.h>
67
#include <CollisionAlgorithm/operations/CreateCenterProximity.h>
78
#include <CollisionAlgorithm/operations/FindClosestProximity.h>
8-
#include <CollisionAlgorithm/operations/Project.h>
9-
#include <CollisionAlgorithm/operations/ContainsPoint.h>
109
#include <CollisionAlgorithm/operations/NeedleOperations.h>
10+
#include <CollisionAlgorithm/operations/Project.h>
1111
#include <CollisionAlgorithm/proximity/EdgeProximity.h>
1212
#include <sofa/component/constraint/lagrangian/solver/ConstraintSolverImpl.h>
1313
#include <sofa/component/statecontainer/MechanicalObject.h>
@@ -29,7 +29,7 @@ class SOFA_COLLISIONALGORITHM_API InsertionAlgorithm : public BaseAlgorithm
2929

3030
GeomLink l_tipGeom, l_surfGeom, l_shaftGeom, l_volGeom;
3131
Data<AlgorithmOutput> d_collisionOutput, d_insertionOutput;
32-
Data<bool> d_projective;
32+
Data<bool> d_projective, d_enablePuncture, d_enableInsertion, d_enableShaftCollision;
3333
Data<SReal> d_punctureForceThreshold, d_tipDistThreshold;
3434
ConstraintSolver::SPtr m_constraintSolver;
3535
std::vector<BaseProximity::SPtr> m_couplingPts;
@@ -50,6 +50,12 @@ class SOFA_COLLISIONALGORITHM_API InsertionAlgorithm : public BaseAlgorithm
5050
d_projective(initData(
5151
&d_projective, false, "projective",
5252
"Projection of closest detected proximity back onto the needle tip element.")),
53+
d_enablePuncture(
54+
initData(&d_enablePuncture, true, "enablePuncture", "Enable puncture algorithm.")),
55+
d_enableInsertion(
56+
initData(&d_enableInsertion, true, "enableInsertion", "Enable insertion algorithm.")),
57+
d_enableShaftCollision(initData(&d_enableShaftCollision, true, "enableShaftCollision",
58+
"Enable shaft-surface collision.")),
5359
d_punctureForceThreshold(initData(&d_punctureForceThreshold, -1_sreal,
5460
"punctureForceThreshold",
5561
"Threshold for the force applied to the needle tip. "
@@ -70,24 +76,30 @@ class SOFA_COLLISIONALGORITHM_API InsertionAlgorithm : public BaseAlgorithm
7076
void init() override
7177
{
7278
BaseAlgorithm::init();
73-
this->getContext()->get<ConstraintSolver>(m_constraintSolver);
74-
msg_warning_when(!m_constraintSolver)
75-
<< "No constraint solver found in context. Insertion algorithm is disabled.";
7679

77-
if (d_punctureForceThreshold.getValue() < 0)
80+
if (d_enablePuncture.getValue())
7881
{
79-
msg_warning() << d_punctureForceThreshold.getName() +
80-
" parameter not defined or set to negative value." msgendl
81-
<< "Puncture will not function properly; provide a positive value";
82-
d_punctureForceThreshold.setValue(std::numeric_limits<double>::max());
82+
this->getContext()->get<ConstraintSolver>(m_constraintSolver);
83+
msg_warning_when(!m_constraintSolver)
84+
<< "No constraint solver found in context. Insertion algorithm is disabled.";
85+
if (d_punctureForceThreshold.getValue() < 0)
86+
{
87+
msg_warning() << d_punctureForceThreshold.getName() +
88+
" parameter not defined or set to negative value." msgendl
89+
<< "Puncture will not function properly; provide a positive value";
90+
d_punctureForceThreshold.setValue(std::numeric_limits<double>::max());
91+
}
8392
}
8493

85-
if (d_tipDistThreshold.getValue() < 0)
94+
if (d_enableInsertion.getValue())
8695
{
87-
msg_warning() << d_tipDistThreshold.getName() +
88-
" parameter not defined or set to negative value." msgendl
89-
<< "Needle-volume coupling is disabled; provide a positive value";
90-
d_tipDistThreshold.setValue(std::numeric_limits<double>::max());
96+
if (d_tipDistThreshold.getValue() < 0)
97+
{
98+
msg_warning() << d_tipDistThreshold.getName() +
99+
" parameter not defined or set to negative value." msgendl
100+
<< "Needle-volume coupling is disabled; provide a positive value";
101+
d_tipDistThreshold.setValue(std::numeric_limits<double>::max());
102+
}
91103
}
92104
}
93105

@@ -118,61 +130,64 @@ class SOFA_COLLISIONALGORITHM_API InsertionAlgorithm : public BaseAlgorithm
118130

119131
void doDetection()
120132
{
121-
if (!l_tipGeom || !l_surfGeom || !l_shaftGeom || !l_volGeom) return;
122-
123133
auto& collisionOutput = *d_collisionOutput.beginEdit();
124134
auto& insertionOutput = *d_insertionOutput.beginEdit();
125135

126136
insertionOutput.clear();
127137
collisionOutput.clear();
128138

129-
if (m_couplingPts.empty())
139+
if (m_couplingPts.empty() && l_surfGeom)
130140
{
131-
// 1. Puncture algorithm
132-
auto createTipProximity =
133-
Operations::CreateCenterProximity::Operation::get(l_tipGeom->getTypeInfo());
141+
// Operations on surface geometry
134142
auto findClosestProxOnSurf =
135143
Operations::FindClosestProximity::Operation::get(l_surfGeom);
136144
auto projectOnSurf = Operations::Project::Operation::get(l_surfGeom);
137-
auto projectOnTip = Operations::Project::Operation::get(l_tipGeom);
138145

139-
const SReal punctureForceThreshold = d_punctureForceThreshold.getValue();
140-
for (auto itTip = l_tipGeom->begin(); itTip != l_tipGeom->end(); itTip++)
146+
// Puncture sequence
147+
if (d_enablePuncture.getValue() && l_tipGeom)
141148
{
142-
BaseProximity::SPtr tipProx = createTipProximity(itTip->element());
143-
if (!tipProx) continue;
144-
const BaseProximity::SPtr surfProx = findClosestProxOnSurf(
145-
tipProx, l_surfGeom.get(), projectOnSurf, getFilterFunc());
146-
if (surfProx)
147-
{
148-
surfProx->normalize();
149+
auto createTipProximity =
150+
Operations::CreateCenterProximity::Operation::get(l_tipGeom->getTypeInfo());
151+
auto projectOnTip = Operations::Project::Operation::get(l_tipGeom);
149152

150-
// 1.1 Check whether puncture is happening - if so, create coupling point
151-
if (m_constraintSolver)
153+
const SReal punctureForceThreshold = d_punctureForceThreshold.getValue();
154+
for (auto itTip = l_tipGeom->begin(); itTip != l_tipGeom->end(); itTip++)
155+
{
156+
BaseProximity::SPtr tipProx = createTipProximity(itTip->element());
157+
if (!tipProx) continue;
158+
const BaseProximity::SPtr surfProx = findClosestProxOnSurf(
159+
tipProx, l_surfGeom.get(), projectOnSurf, getFilterFunc());
160+
if (surfProx)
152161
{
153-
const MechStateTipType::SPtr mstate =
154-
l_tipGeom->getContext()->get<MechStateTipType>();
155-
const auto& lambda =
156-
m_constraintSolver->getLambda()[mstate.get()].read()->getValue();
157-
SReal norm{0_sreal};
158-
for (const auto& l : lambda)
159-
{
160-
norm += l.norm();
161-
}
162-
if (norm > punctureForceThreshold)
162+
surfProx->normalize();
163+
164+
// Check whether puncture is happening - if so, create coupling point ...
165+
if (m_constraintSolver)
163166
{
164-
m_couplingPts.push_back(surfProx);
165-
continue;
167+
const MechStateTipType::SPtr mstate =
168+
l_tipGeom->getContext()->get<MechStateTipType>();
169+
const auto& lambda =
170+
m_constraintSolver->getLambda()[mstate.get()].read()->getValue();
171+
SReal norm{0_sreal};
172+
for (const auto& l : lambda)
173+
{
174+
norm += l.norm();
175+
}
176+
if (norm > punctureForceThreshold)
177+
{
178+
m_couplingPts.push_back(surfProx);
179+
continue;
180+
}
166181
}
167-
}
168182

169-
// ... if not, create a proximity pair for the tip-surface collision
170-
collisionOutput.add(tipProx, surfProx);
183+
// ... if not, create a proximity pair for the tip-surface collision
184+
collisionOutput.add(tipProx, surfProx);
185+
}
171186
}
172187
}
173188

174-
// 1.3 Collision with the shaft geometry
175-
if (m_couplingPts.empty())
189+
// Shaft collision sequence - Disable if coupling points have been added
190+
if (d_enableShaftCollision.getValue() && m_couplingPts.empty() && l_shaftGeom)
176191
{
177192
auto createShaftProximity =
178193
Operations::CreateCenterProximity::Operation::get(l_shaftGeom->getTypeInfo());
@@ -187,11 +202,17 @@ class SOFA_COLLISIONALGORITHM_API InsertionAlgorithm : public BaseAlgorithm
187202
{
188203
surfProx->normalize();
189204

190-
// 1.2 If not, create a proximity pair for the tip-surface collision
191205
if (d_projective.getValue())
192206
{
193-
shaftProx =
194-
projectOnShaft(surfProx->getPosition(), itShaft->element()).prox;
207+
//shaftProx =
208+
// projectOnShaft(surfProx->getPosition(), itShaft->element()).prox;
209+
//if (!shaftProx) continue;
210+
//shaftProx->normalize();
211+
// Experimental - This enables projection anywhere on the edge
212+
auto findClosestProxOnShaft =
213+
Operations::FindClosestProximity::Operation::get(l_shaftGeom);
214+
shaftProx = findClosestProxOnShaft(surfProx, l_shaftGeom,
215+
projectOnShaft, getFilterFunc());
195216
if (!shaftProx) continue;
196217
shaftProx->normalize();
197218
}
@@ -202,7 +223,9 @@ class SOFA_COLLISIONALGORITHM_API InsertionAlgorithm : public BaseAlgorithm
202223
}
203224
else
204225
{
205-
// 2. Needle insertion algorithm
226+
// Insertion sequence
227+
if (!d_enableInsertion.getValue() || !l_tipGeom || !l_volGeom || !l_shaftGeom) return;
228+
206229
ElementIterator::SPtr itTip = l_tipGeom->begin();
207230
auto createTipProximity =
208231
Operations::CreateCenterProximity::Operation::get(itTip->getTypeInfo());
@@ -256,7 +279,7 @@ class SOFA_COLLISIONALGORITHM_API InsertionAlgorithm : public BaseAlgorithm
256279

257280
const int numCPs = floor(lastCPToP1.norm() / tipDistThreshold);
258281

259-
for(int idCP = 0 ; idCP < numCPs ; idCP++)
282+
for (int idCP = 0; idCP < numCPs; idCP++)
260283
{
261284
// Candidate coupling point along shaft segment
262285
const type::Vec3 candidateCP = lastCP + tipDistThreshold * shaftEdgeDir;
@@ -270,7 +293,7 @@ class SOFA_COLLISIONALGORITHM_API InsertionAlgorithm : public BaseAlgorithm
270293
// Skip if candidate CP is outside current edge segment
271294
if (projPtOnEdge < 0_sreal || projPtOnEdge > edgeSegmentLength) break;
272295

273-
// Project candidate CP onto shaft geometry ...
296+
// Project candidate CP onto shaft geometry ...
274297
shaftProx = projectOnShaft(candidateCP, itShaft->element()).prox;
275298
if (!shaftProx) continue;
276299

@@ -279,8 +302,8 @@ class SOFA_COLLISIONALGORITHM_API InsertionAlgorithm : public BaseAlgorithm
279302
shaftProx, l_volGeom.get(), projectOnVol, getFilterFunc());
280303
if (!volProx) continue;
281304

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
305+
// Proximity can be detected before the tip enters the tetra (e.g. near a
306+
// boundary face) Only accept proximities if the tip is inside the tetra
284307
// during insertion
285308
if (containsPointInVol(shaftProx->getPosition(), volProx))
286309
{
@@ -291,11 +314,19 @@ class SOFA_COLLISIONALGORITHM_API InsertionAlgorithm : public BaseAlgorithm
291314
}
292315
}
293316
}
317+
else // Don't bother with removing the point that was just added
318+
{
319+
// Remove coupling points that are ahead of the tip in the insertion direction
320+
ElementIterator::SPtr itShaft = l_shaftGeom->begin(l_shaftGeom->getSize() - 2);
321+
auto prunePointsAheadOfTip =
322+
Operations::Needle::PrunePointsAheadOfTip::get(itShaft->getTypeInfo());
323+
prunePointsAheadOfTip(m_couplingPts, itShaft->element());
324+
}
294325
}
295326

296-
if (!m_couplingPts.empty())
327+
if (d_enableInsertion.getValue() && !m_couplingPts.empty() && l_shaftGeom)
297328
{
298-
// 3. Re-project proximities on the shaft geometry
329+
// Reprojection on shaft geometry sequence
299330
auto findClosestProxOnShaft =
300331
Operations::FindClosestProximity::Operation::get(l_shaftGeom);
301332
auto projectOnShaft = Operations::Project::Operation::get(l_shaftGeom);

src/CollisionAlgorithm/initCollisionAlgorithm.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ extern void registerCollisionLoop(sofa::core::ObjectFactory* factory);
2020

2121
// Algorithms
2222
extern void registerFind2DClosestProximityAlgorithm(sofa::core::ObjectFactory* factory);
23-
extern void registerFindClosestProximityAlgorithm(sofa::core::ObjectFactory* factory);
2423
extern void registerInsertionAlgorithm(sofa::core::ObjectFactory* factory);
2524

2625
// BroadPhase
@@ -90,7 +89,6 @@ void registerObjects(sofa::core::ObjectFactory* factory)
9089
registerCollisionLoop(factory);
9190
// Register Algorithms
9291
registerFind2DClosestProximityAlgorithm(factory);
93-
registerFindClosestProximityAlgorithm(factory);
9492
registerInsertionAlgorithm(factory);
9593
// Register BroadPhase
9694
registerAABBBroadPhase(factory);

0 commit comments

Comments
 (0)