Skip to content

Commit aacf5bd

Browse files
authored
[operations] A new Operations class to enable point-in-element checks from the top level insertion algorithm (#85)
* [operations] Created a ContainsPoint operation * Checks whether a point is inside an element * Works with an element or a proximity type as input * [toolbox] Added a containsPoint function for point-in-tetra operation * [algorithm] Using containsPoint operations in the insertion algorithm class - no dynamic casts to elements * [operations] Use SOFA-like error messaging * [operations] Message warning in case input proximity is null in ContainsPointInProximity operation
1 parent 57df238 commit aacf5bd

File tree

7 files changed

+124
-13
lines changed

7 files changed

+124
-13
lines changed

src/sofa/collisionAlgorithm/algorithm/InsertionAlgorithm.h

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <sofa/collisionAlgorithm/operations/CreateCenterProximity.h>
77
#include <sofa/collisionAlgorithm/operations/FindClosestProximity.h>
88
#include <sofa/collisionAlgorithm/operations/Project.h>
9+
#include <sofa/collisionAlgorithm/operations/ContainsPoint.h>
910
#include <sofa/collisionAlgorithm/operations/NeedleOperations.h>
1011
#include <sofa/collisionAlgorithm/proximity/EdgeProximity.h>
1112
#include <sofa/collisionAlgorithm/proximity/TetrahedronProximity.h>
@@ -225,24 +226,17 @@ class InsertionAlgorithm : public BaseAlgorithm
225226
auto projectOnVol = Operations::Project::Operation::get(l_volGeom);
226227
const BaseProximity::SPtr volProx =
227228
findClosestProxOnVol(tipProx, l_volGeom.get(), projectOnVol, getFilterFunc());
229+
228230
// Proximity can be detected before the tip enters the tetra (e.g. near a boundary face)
229231
// Only accept proximities if the tip is inside the tetra during insertion
230232
if (volProx)
231233
{
232-
TetrahedronProximity::SPtr tetProx =
233-
dynamic_pointer_cast<TetrahedronProximity>(volProx);
234-
if (tetProx)
234+
auto containsPointInVol = Operations::ContainsPointInProximity::Operation::get(
235+
l_volGeom->getTypeInfo());
236+
if(containsPointInVol(tipProx->getPosition(), volProx))
235237
{
236-
double f0(tetProx->f0()), f1(tetProx->f1()), f2(tetProx->f2()),
237-
f3(tetProx->f3());
238-
bool isInTetra = toolbox::TetrahedronToolBox::isInTetra(
239-
tipProx->getPosition(), tetProx->element()->getTetrahedronInfo(), f0,
240-
f1, f2, f3);
241-
if (isInTetra)
242-
{
243-
volProx->normalize();
244-
m_couplingPts.push_back(volProx);
245-
}
238+
volProx->normalize();
239+
m_couplingPts.push_back(volProx);
246240
}
247241
}
248242
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#include <sofa/collisionAlgorithm/operations/ContainsPoint.h>
2+
#include <sofa/collisionAlgorithm/proximity/TetrahedronProximity.h>
3+
#include <sofa/collisionAlgorithm/proximity/TriangleProximity.h>
4+
5+
namespace sofa::collisionAlgorithm::Operations::ContainsPointInElement
6+
{
7+
8+
int register_ContainsPoint_Triangle =
9+
Operation::register_func<TriangleElement>(&toolbox::TriangleToolBox::containsPoint);
10+
11+
int register_ContainsPoint_Tetrahedron =
12+
Operation::register_func<TetrahedronElement>(&toolbox::TetrahedronToolBox::containsPoint);
13+
14+
} // namespace sofa::collisionAlgorithm::Operations::ContainsPointInElement
15+
16+
namespace sofa::collisionAlgorithm::Operations::ContainsPointInProximity
17+
{
18+
19+
int register_ContainsPointInProximity_Triangle =
20+
Operation::register_func<TriangleElement>(&containsPoint<TriangleProximity>);
21+
22+
int register_ContainsPointInProximity_Tetrahedron =
23+
Operation::register_func<TetrahedronElement>(&containsPoint<TetrahedronProximity>);
24+
25+
} // namespace sofa::collisionAlgorithm::Operations::ContainsPointInProximity
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#pragma once
2+
3+
#include <sofa/collisionAlgorithm/BaseElement.h>
4+
#include <sofa/collisionAlgorithm/BaseOperation.h>
5+
6+
namespace sofa::collisionAlgorithm::Operations::ContainsPointInElement
7+
{
8+
9+
typedef bool Result;
10+
11+
class Operation : public GenericOperation<Operation, // Type of the operation
12+
Result, // Default return type
13+
const type::Vec3&, const BaseElement::SPtr& // Parameters
14+
>
15+
{
16+
public:
17+
Result defaultFunc(const type::Vec3&, const BaseElement::SPtr&) const override { return false; }
18+
19+
void notFound(const std::type_info& id) const override
20+
{
21+
msg_error("ContainsPointInElement")
22+
<< "The operation ContainsPointInElementOperation is not registered with for type = "
23+
<< sofa::helper::NameDecoder::decodeFullName(id);
24+
}
25+
};
26+
27+
typedef Operation::FUNC FUNC;
28+
29+
} // namespace sofa::collisionAlgorithm::Operations::ContainsPointInElement
30+
31+
namespace sofa::collisionAlgorithm::Operations::ContainsPointInProximity
32+
{
33+
34+
typedef bool Result;
35+
36+
class Operation
37+
: public GenericOperation<Operation, // Type of the operation
38+
Result, // Default return type
39+
const type::Vec3&, const BaseProximity::SPtr& // Parameters
40+
>
41+
{
42+
public:
43+
Result defaultFunc(const type::Vec3&, const BaseProximity::SPtr&) const override
44+
{
45+
return false;
46+
}
47+
48+
void notFound(const std::type_info& id) const override
49+
{
50+
msg_error("ContainsPointInProximity")
51+
<< "The operation ContainsPointInProximityOperation is not registered with for type = "
52+
<< sofa::helper::NameDecoder::decodeFullName(id);
53+
}
54+
};
55+
56+
template <typename PROX>
57+
Result containsPoint(const type::Vec3& P, const typename std::shared_ptr<PROX>& prox)
58+
{
59+
if (!prox)
60+
{
61+
msg_warning("ContainsPointInProximity") << "Null proximity pointer in containsPoint"
62+
<< "Operation is disabled; returning false";
63+
return false;
64+
}
65+
66+
auto elem = prox->element();
67+
auto containsPointInElem =
68+
sofa::collisionAlgorithm::Operations::ContainsPointInElement::Operation::get(elem);
69+
return containsPointInElem(P, elem);
70+
}
71+
72+
typedef Operation::FUNC FUNC;
73+
74+
} // namespace sofa::collisionAlgorithm::Operations::ContainsPointInProximity

src/sofa/collisionAlgorithm/toolbox/TetrahedronToolBox.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ Operations::CreateCenterProximity::Result TetrahedronToolBox::createCenterProxim
1010
return TetrahedronProximity::create(tetra, 1.0/4.0,1.0/4.0,1.0/4.0,1.0/4.0);
1111
}
1212

13+
Operations::ContainsPointInElement::Result TetrahedronToolBox::containsPoint(const type::Vec3 & P, const TetrahedronElement::SPtr & tetra) {
14+
TetrahedronProximity::SPtr prox = TetrahedronProximity::create(tetra, 1.0/4.0,1.0/4.0,1.0/4.0,1.0/4.0);
15+
double f0(prox->f0()), f1(prox->f1()), f2(prox->f2()), f3(prox->f3());
16+
return isInTetra(P,tetra->getTetrahedronInfo(),f0,f1,f2,f3);
17+
}
18+
1319
Operations::Project::Result TetrahedronToolBox::project(const type::Vec3 & P, const TetrahedronElement::SPtr & tetra) {
1420
double fact[4];
1521
projectOnTetra(P, tetra->getTetrahedronInfo(),fact[0],fact[1],fact[2],fact[3]);

src/sofa/collisionAlgorithm/toolbox/TetrahedronToolBox.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <sofa/collisionAlgorithm/elements/TetrahedronElement.h>
55
#include <sofa/collisionAlgorithm/operations/Project.h>
66
#include <sofa/collisionAlgorithm/operations/CreateCenterProximity.h>
7+
#include <sofa/collisionAlgorithm/operations/ContainsPoint.h>
78

89
namespace sofa::collisionAlgorithm::toolbox {
910

@@ -12,6 +13,8 @@ class TetrahedronToolBox {
1213

1314
static Operations::CreateCenterProximity::Result createCenterProximity(const TetrahedronElement::SPtr & tetra);
1415

16+
static Operations::ContainsPointInElement::Result containsPoint(const type::Vec3 & P, const TetrahedronElement::SPtr & tetra);
17+
1518
static Operations::Project::Result project(const type::Vec3 & P, const TetrahedronElement::SPtr & tetra);
1619

1720
static void projectOnTetra(const type::Vec3d projectP, const TetrahedronElement::TetraInfo & teinfo, double & fact_u, double & fact_v, double & fact_w,double & fact_x);

src/sofa/collisionAlgorithm/toolbox/TriangleToolBox.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ Operations::CreateCenterProximity::Result TriangleToolBox::createCenterProximity
88
return TriangleProximity::create(tri, 1.0/3.0,1.0/3.0,1.0/3.0);
99
}
1010

11+
Operations::ContainsPointInElement::Result TriangleToolBox::containsPoint(const type::Vec3 & P, const TriangleElement::SPtr & tri) {
12+
TriangleProximity::SPtr prox = TriangleProximity::create(tri, 1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0);
13+
double f0(prox->f0()), f1(prox->f1()), f2(prox->f2());
14+
return isInTriangle(P,tri->getTriangleInfo(),f0,f1,f1);
15+
}
16+
1117
//Barycentric coordinates are computed according to
1218
//http://gamedev.stackexchange.com/questions/23743/whats-the-most-efficient-way-to-find-barycentric-coordinates
1319
Operations::Project::Result TriangleToolBox::project(const type::Vec3 & P, const TriangleElement::SPtr & tri) {

src/sofa/collisionAlgorithm/toolbox/TriangleToolBox.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <sofa/collisionAlgorithm/elements/TriangleElement.h>
55
#include <sofa/collisionAlgorithm/operations/Project.h>
66
#include <sofa/collisionAlgorithm/operations/CreateCenterProximity.h>
7+
#include <sofa/collisionAlgorithm/operations/ContainsPoint.h>
78

89
namespace sofa::collisionAlgorithm::toolbox {
910

@@ -12,6 +13,8 @@ class TriangleToolBox {
1213

1314
static Operations::CreateCenterProximity::Result createCenterProximity(const TriangleElement::SPtr & tri);
1415

16+
static Operations::ContainsPointInElement::Result containsPoint(const type::Vec3 & P, const TriangleElement::SPtr & tri);
17+
1518
static Operations::Project::Result project(const type::Vec3 & P, const TriangleElement::SPtr & tri);
1619

1720
static void computeTriangleBaryCoords(const type::Vec3d & proj_P, const TriangleElement::TriangleInfo & tinfo, double & fact_u, double & fact_v, double & fact_w);

0 commit comments

Comments
 (0)