Skip to content

[Geometry] Bugfixes and add unit tests#5987

Open
fredroy wants to merge 9 commits intosofa-framework:masterfrom
fredroy:add_tests_geometry
Open

[Geometry] Bugfixes and add unit tests#5987
fredroy wants to merge 9 commits intosofa-framework:masterfrom
fredroy:add_tests_geometry

Conversation

@fredroy
Copy link
Copy Markdown
Contributor

@fredroy fredroy commented Mar 3, 2026

Fix various Edge and triangles functions

  • intersectionWith* (test against abs value to check both sides) and collinearity
  • fix 2d and 3d cases
  • isPointInTriangle: add checks if the point is in the triangle plane but also add a boolean to bypass this check (as it was before the "fix")
  • mat_LCP (used for proximity): the solver returned true even it fails to converge (max iterations reached)

and more unit tests for Sofa.Geometry module

[with-all-tests]


By submitting this pull request, I acknowledge that
I have read, understand, and agree SOFA Developer Certificate of Origin (DCO).


Reviewers will merge this pull-request only if

  • it builds with SUCCESS for all platforms on the CI.
  • it does not generate new warnings.
  • it does not generate new unit test failures.
  • it does not generate new scene test failures.
  • it does not break API compatibility.
  • it is more than 1 week old (or has fast-merge label).

@fredroy fredroy added pr: fix Fix a bug pr: status to review To notify reviewers to review this pull-request pr: test PR adding test(s) in SOFA pr: AI-aided Label notifying the reviewers that part or all of the PR has been generated with the help of an AI labels Mar 3, 2026
@fredroy
Copy link
Copy Markdown
Contributor Author

fredroy commented Mar 3, 2026

[ci-build][with-all-tests]

@fredroy fredroy force-pushed the add_tests_geometry branch from ae273ee to 69cba4f Compare March 3, 2026 06:55
@hugtalbot hugtalbot requested review from bakpaul and epernod March 12, 2026 09:33
return false;

const auto Ln0p0 = sofa::type::dot(AB, AC);
if (Ln0p0 < 0 || Ln0p0 > Ln0n1) // out of bounds [n0; n1]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Funny that the AI didn't catch this, but here because AB is not normalized the check is wrong.

Suggested change
if (Ln0p0 < 0 || Ln0p0 > std::pow(Ln0n1,2) ) // out of bounds [n0; n1]

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but Ln0n1 = sofa::type::dot(AB, AB); so I dont see why you do std::pow(Ln0n1,2)....

Comment on lines +94 to +113
// In 3D, use signed areas via dot product with triangle normal
// to get correct sign for outside-triangle points
const auto N = sofa::type::cross(n1 - n0, n2 - n0);
const auto NdotN = sofa::type::dot(N, N);

if (NdotN < std::numeric_limits<T>::epsilon() * std::numeric_limits<T>::epsilon()) // triangle is flat
{
return sofa::type::Vec<3, T>(-1, -1, -1);
}

sofa::type::Vec<3, T> baryCoefs(type::NOINIT);
baryCoefs[0] = sofa::type::dot(N, sofa::type::cross(n2 - n1, p0 - n1)) / NdotN;
baryCoefs[1] = sofa::type::dot(N, sofa::type::cross(n0 - n2, p0 - n2)) / NdotN;
baryCoefs[2] = 1 - baryCoefs[0] - baryCoefs[1];

if (fabs(baryCoefs[2]) <= std::numeric_limits<T>::epsilon()){
baryCoefs[2] = 0;
}

return baryCoefs;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, before this the barycentric mapping was a bit wrong when the point wasn't on the triangle. Because of 104, the value of the third barycentric coordinate was always underestimated because the other ones where overestimated.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@epernod this fix the cases when the point is not on the same plane as the triangle. But does it ever happen ? Anyway I think that the api should not expect anything and check because otherwise we would rely on the user to make the check before.

@fredroy fredroy force-pushed the add_tests_geometry branch from fcc869f to 9cd1ebb Compare March 30, 2026 00:36
fredroy and others added 9 commits March 31, 2026 16:14
if (denominator < EQUALITY_THRESHOLD)  the denominator is a signed dot product. When negative (edge crosses plane from the "back"), this is always true,
  so the function rejects ~half of all valid intersections.
1-The 2D path computes alpha (parameter on edge AB) and checks 0 <= alpha <= 1, but never computes or checks beta (parameter on edge CD). Reports false
  intersections when the infinite line CD crosses segment AB but outside segment CD.
2-if (alphaDenom < std::numeric_limits<T>::epsilon())  same pattern as Bug 1. The cross product alphaDenom is signed. When negative (non-collinear edges in
  one orientation), incorrectly reports them as collinear.
solveLCP returns true when solver fails to converge (max iterations reached)
While isPointInTriangle still works (it only checks sign pattern),
  any code that uses the returned coordinates for interpolation, projection to the nearest point on the triangle, or distance computation gets wrong values.
  This is a public utility function likely consumed by many parts of the codebase.
…or for beta)

Co-authored-by: Paul Baksic <30337881+bakpaul@users.noreply.github.com>
@fredroy fredroy force-pushed the add_tests_geometry branch from 9cd1ebb to 5a274e4 Compare March 31, 2026 07:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr: AI-aided Label notifying the reviewers that part or all of the PR has been generated with the help of an AI pr: fix Fix a bug pr: status to review To notify reviewers to review this pull-request pr: test PR adding test(s) in SOFA

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants