You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Found while responding to review on #545. Distinct from the fix in that PR, and more consequential than the stale-geometry finding it was raised alongside.
What happens
pull_vertex_onto(dm, targets) moves a vertex onto each target in turn. Nothing prevents two targets from selecting the same vertex: the second write wins, and the first target silently ends up with no vertex on it.
add_fault calls it with every control point of a trace at once, so this is reachable from ordinary use. The resulting state — a control point that should carry a vertex and does not — is exactly what cut_along_lines reports as
N triangle(s) are entered but not left, which means a line ends inside the mesh
which is the failure #542/#545 exists to fix, arriving by a different route.
Measured
Unstructured box, h = 0.06, straight-ish trace, sweeping control-point spacing. "Collisions" is the number of targets whose chosen vertex was already claimed:
Resolving against the updated coordinates does not help. It is marginally worse (25 against 22 at 0.25 h). So the arr-versus-X question and this one are independent, and fixing the former would not touch this.
On the real listric trace that motivated #545 — 22 control points at roughly cell spacing — there are no collisions and both schemes pick identical vertices, which is why this has not bitten yet.
The fix
Exclude already-claimed vertices when selecting for each subsequent target: carry a claimed set, drop those candidates, and refuse (or warn, naming the target) when a target's minimal face has no unclaimed vertex left. That last case is real information — it means the trace is sampled more finely than the mesh can represent, and the honest response is to say so rather than to quietly place fewer vertices than were asked for.
Related: line_cut.resample already exists to thin a trace to cell spacing, with a docstring noting that "a trace sampled far finer than the cell size lands several points on one vertex and the facet chain fragments" — so the failure mode is known; it is simply not guarded at the point where the vertices are placed.
Practical limit until then
Keep fault control-point spacing at or above 0.5 h.
Underworld development team with AI support from Claude Code
Found while responding to review on #545. Distinct from the fix in that PR, and more consequential than the stale-geometry finding it was raised alongside.
What happens
pull_vertex_onto(dm, targets)moves a vertex onto each target in turn. Nothing prevents two targets from selecting the same vertex: the second write wins, and the first target silently ends up with no vertex on it.add_faultcalls it with every control point of a trace at once, so this is reachable from ordinary use. The resulting state — a control point that should carry a vertex and does not — is exactly whatcut_along_linesreports aswhich is the failure #542/#545 exists to fix, arriving by a different route.
Measured
Unstructured box,
h = 0.06, straight-ish trace, sweeping control-point spacing. "Collisions" is the number of targets whose chosen vertex was already claimed:Two points worth noting:
0.5 hspacing — one step coarser than the stale-geometry effect raised in review on Place a tip vertex from the face that holds it, not from the mesh at large #545, which needs sub-0.25 hbefore it changes any selection.0.25 h). So thearr-versus-Xquestion and this one are independent, and fixing the former would not touch this.On the real listric trace that motivated #545 — 22 control points at roughly cell spacing — there are no collisions and both schemes pick identical vertices, which is why this has not bitten yet.
The fix
Exclude already-claimed vertices when selecting for each subsequent target: carry a claimed set, drop those candidates, and refuse (or warn, naming the target) when a target's minimal face has no unclaimed vertex left. That last case is real information — it means the trace is sampled more finely than the mesh can represent, and the honest response is to say so rather than to quietly place fewer vertices than were asked for.
Related:
line_cut.resamplealready exists to thin a trace to cell spacing, with a docstring noting that "a trace sampled far finer than the cell size lands several points on one vertex and the facet chain fragments" — so the failure mode is known; it is simply not guarded at the point where the vertices are placed.Practical limit until then
Keep fault control-point spacing at or above
0.5 h.Underworld development team with AI support from Claude Code