Repository navigation
Add self-intersection tests for triangle meshes - #125
Merged
Merged
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #125 +/- ##
==========================================
+ Coverage 61.84% 62.67% +0.82%
==========================================
Files 16 17 +1
Lines 3182 3287 +105
Branches 417 429 +12
==========================================
+ Hits 1968 2060 +92
- Misses 1046 1053 +7
- Partials 168 174 +6
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Single-point contacts and differently scaled triangles can produce incorrect intersection results.
1 open finding
What changed in this PR
Adds triangle-mesh self-intersection detection and local rollback support.
Changes:
- Implements vectorized triangle and mesh intersection tests.
- Adds vertex rollback for newly introduced intersections.
- Adds API documentation and tests.
| File | Description |
|---|---|
lapy/intersect.py |
Implements detection and rollback algorithms. |
lapy/utils/tests/test_intersect.py |
Tests intersection and rollback behavior. |
doc/api/lapy.modules.rst |
Lists the new module. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

LaPy had no way to tell whether a triangle mesh intersects itself. That matters after anything that moves vertices, like
smoothing, mean curvature flow or a surface repair: a surface that crosses itself is still a valid manifold for
is_manifold(), but it is not an embedded surface anymore. This PR adds a modulelapy.intersectwith a vectorizedself-intersection test and a function to undo vertex moves that create intersections.
Changes
New module
lapy/intersect.py, listed on the API page under Modules:triangles_intersect(a, b)tests pairs of triangles, given as corner arrays of shape (k, 3, 3), with the intervaltest of Moeller (1997). Triangles that only touch in a point, and coplanar triangles, do not count as intersecting.
self_intersections(tria, subset=None)returns the pairs of triangles that intersect and share no vertex, sortedwithin each row and lexicographically. Candidate pairs come from a KD-tree on the triangle centroids; the few much
larger triangles are searched one by one, so that they do not inflate the search radius for all others. With
subset,only pairs involving those triangles are tested, and only triangles in their bounding box are searched, which is much
faster after a local change.
undo_intersections(tria, v_new, rings=2, max_rounds=10)takes new vertex positions, for example after smoothing, andmoves the vertices of intersecting triangles and
ringsrings of their neighbors back to their positions intria.It repeats on the triangles that changed until nothing intersects, and returns the positions and the number of
vertices moved back. The mesh itself is not modified.
The functions follow the other analysis modules (
diffgeo,conformal) and take the mesh as their first argument.Everything is vectorized over candidate pairs with numpy and scipy, so no new dependency. On a 286k triangle cortical
surface
self_intersectionstakes about 3.5 s.Tests
New tests in
lapy/utils/tests/test_intersect.py:apart;
finds the same pairs as the full search;
undo_intersectionson that torus, which moves back only the vertices near the crossing, keeps a small changeelsewhere and leaves the mesh unchanged.
The docs build with
-Wand numpydoc validation passes with the new module.