A curved chamfer chain with straight planar ends can end across two earlier planar bevel faces, shortening their shared seam to where the new chamfer plane crosses it; picks on one tangent chain are applied once. Fixes#1303.
A fillet or chamfer on a cylindrical boss's bottom arc now builds with a closed display mesh: the seam-extension containment ray counts a shared curved-boundary endpoint once. Merging the split faces of a three-edge arc corner rebuilds the face on the original input face's full surface instead of a piece's restricted patch, and runs under the kernel's panic guard. Fixes#1262 and #1263.
Co-authored-by: Karl-VonRichter <20079846+Karl-VonRichter@users.noreply.github.com>
A round or chamfer whose edge chain runs on across a curved seam (the end circle of a lofted tube whose axis bends) is now built: the section solve keeps its contact on the seam through a plane taken afresh at the seam's nearest point at each step. Straight seams are unchanged. Robustness seed 41 is re-recorded: its second fillet, refused before, now builds. Fixes#1213.
Co-authored-by: gvocale <gvocale@users.noreply.github.com>
A fillet or chamfer that consumes both seams of a side, leaving its old boundary and the fitted contact on the same curve, now returns TooLarge ("the blend would consume a neighbouring face") instead of a zero-area face that doesn't mesh. Genuine two-edge faces are kept. Fixes#1113.
Co-authored-by: Karl-VonRichter <Karl-VonRichter@users.noreply.github.com>
* Action matrix regressions of #1255: knuckle rounds, thin holes, a 45° flange hole, an axis after an edit
- Curve blends: past the end of a curved edge the run of sections along the end
tangent wrapped round the ring of centres; it is shortened while it still
crosses the end face (the hinge knuckle's cap rounds at 0.728 mm).
- Boolean retry guard: each body's volume is measured finer than its smallest
radius, and a volume out of bounds is measured again ten times finer before
it refuses (a 0.133 mm drill measured -30272 mm³; a plastic part's coarse
mesh was off by more than the slack).
- Sheet metal: a drill cap's certificate allows the evaluation noise its fitted
tilt shows (a hole square to a 45° flange).
- Construction geometry on a named face uses the face found by name, not a
second pick at its nearest point (an axis through a corner round after a
parameter moved it).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Retry guard: measure the target, tool and result at one tolerance
Measured at different tolerances, the chords' error on the faces they share
didn't cancel: a blind hole in a long D-profile bar measured 20 mm³ more than
the bar.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Action matrix baseline from this branch's full run: 37 actions pass again, none fewer
Blessed with cargo xtask action-matrix --from DIR --bless from the 16 shards of
run 38673859774.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Fillets and chamfers meeting at corners on curved faces, on top of #935
What #935 and #926 leave of #851 and the matrix:
- Corner build for blends meeting on faces of any surface (curvecorner.rs):
the knife-edge tip's round with the arc's or the back edge's, edges
picked in any order, a round ending in an earlier round of its radius
(as a feature of its own), and chamfers meeting at the arc's corner.
Its end curves are fitted by chord length: a uniform parameter
through points clustered at the ends doubled back on itself there,
and the display planner refused the face.
- A straight edge ending at a curved face (the back edge into the
knife-edge tip): rolled, or cut by the face in the planar corner
build (blend_corner.rs).
- A rolling ball turning about a rounded corner of its own radius
(a pivot: a piece of sphere or cone).
- Seams that are an earlier blend's straight contact (fitted curves)
count as straight.
- No spline across a joint where the strip's curvature jumps (a line
into a small round): each strip ends on the joint's section.
- Sections at a chain's vertices on the faces of the edge from it
alone.
- Every new fillet path passes #949's check for openings.
Tests measure volumes through the display plan, as #935's do.
Action matrix: 51 more fillets and chamfers pass (sweep, tangent arc
chain, sheet-metal hem, bracket holes), none fewer. Robustness seed 33
recorded (its last fillet builds differently; display and measured
volumes now agree).
Co-Authored-By: bherbruck <brennen.herbruck@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015bV2ntwLfUHV4JnCMPSyRi
* Corner blend tests: scale, seed 33's volumes, tighter engine bounds
From the review of #854:
- seed_33_display_plan_and_measure_agree: seed 33's bodies measure
the same through the display plan and the measure (2e-5), which the
golden's re-record rests on.
- the_arc_rounded_after_the_back_edge_matches_both_together: the order
that still leaves 0.05 mm³ at the tip, as an ignored test.
- corner_blends_hold_at_any_scale: the cases this branch adds on the
#851 part, at 0.01x and 100x, take off what they take at full size
times k³ (within 5e-6, checked to 1e-4).
- The engine tests on the part as drawn measure through the display
plan; bounds are about twice what each reads (2e-4 to 3e-3), and the
front corner's sets are checked against the kernel's CSG grid.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015bV2ntwLfUHV4JnCMPSyRi
---------
Co-authored-by: bherbruck <brennen.herbruck@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Fillets and chamfers ending on a boss's pieced wall or beside it, on a face that runs along its seam twice, and loops the loop blend refuses
- A straight edge whose end meets one curved surface in several faces (a cylinder a join left
in pieces) ends on that surface: the section is cut where it crosses each seam, which is
shortened there; where no seam is crossed (the wall missing inside the other body) the
section lies on the bared surface and the rest of the side edge becomes a seam.
- Two end faces that aren't both planes meeting in lines: each face takes the section's points
on it, cut where it crosses the edge between them. Not where an end face runs on smoothly
from a side (an earlier round): the corner build takes those.
- Face boundaries close over several connector edges.
- A face on a periodic surface running along its seam twice (as a STEP file gives it) is
rebuilt the same way (#691).
- A curved chain ending square on a face that runs on past its side extends that face's seam.
- A smooth chain stops before an edge between faces that meet smoothly.
- A loop the loop blend refuses for its shape is blended edge by edge; refusals about its size
stand.
- Action matrix: ACTION_MATRIX_ACTIONS and ACTION_MATRIX_VALIDITY for quick local runs; the
fillets and chamfers that pass now recorded.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Rolling-ball blends now handle knife edges, where the two faces have opposite normals; an edge that runs out along an end face tangent to one side; and rounds that end in an earlier round on curved faces, picked together or one after another. The three edges at a vertex of smooth faces, rounded to one radius, end in a piece of sphere. When the given order of up to four edges is refused, or leaves a face boundary off its surface, other orders are tried.
Closes#851.
Co-authored-by: lasselian <22126420+lasselian@users.noreply.github.com>
A single edge's blend no longer needs a plane square to the edge at each end. Straight edges: each rail ends where it reaches the end face's surface, the side edges there are shortened or continued along their line or circle, and the blend ends where its cylinder or chamfer plane meets that surface (a fitted curve checked against both). A chamfer may end across two faces. Curved edges: at a slanted or curved end the rolling ball runs on past the end and the strip is cut back where it meets that face. A straight edge running smoothly into a bend or rounded corner is blended along its whole smooth chain. Rolling-ball fixes: smooth chains follow edges stored against their curve, the ball touches only the faces of the edges it rolls along, the seam normal at a joint comes from the face there, and each strip is fitted with neighbouring sections at its own spacing.
Action matrix: edge.fillet 83.6% -> 93.0%, edge.chamfer 82.6% -> 93.3% (697 new passes, no regressions); reference tests 76/76.
Fixes#556
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`fit: reduce` acts only on refusals marked too large. Three kinds weren't:
the corner build's contact lines leaving their faces or running backwards,
and a curved chain's contact reaching past the end of the seam it trims. Two
more were hidden: a later edge's too-large refusal lost to an earlier edge's
other error, and the corner build's lost to the local blend's in `fillet`.
The messages are unchanged.
Refs #293
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* fix: fillet fit review follow-ups
From the review of #388 (merged before these landed):
- The Fillet dialog's Applied Radius showed nothing when editing a fillet
that was already reduced: the preview found the radius by diffing the
states before and after. The engine's preview now keeps the command
replies, and the dialog reads the radius of the feature they name.
- Pattern copies of a reduced fillet try the radius the original was
reduced to first, instead of each searching again (up to 16 fillets).
- fit: reduce with a chord or variable radius is refused instead of being
silently ignored.
- One helper appends a note to a feature's warning; too_large is imported
like unsupported in the loop and curve blends.
Refs #293
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TWc1smHYwTSVrVc8SNvS44
* Use the solidcraft_doc crate name after the rename
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HWLPLy7ug7URSK5WybjRNa
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: bherbruck <brennen.herbruck@gmail.com>
* feat(kernel): typed TooLarge refusal and fillet_max search
Blend refusals caused only by the size (larger than the neighbouring faces,
taller than the walls, longer than the next edge, larger than a corner
radius) now return KernelError::TooLarge, displayed as before. fillet_max
finds the largest radius below a request at which the fillet of the edges
works, to three significant digits, by building candidates; it is an explicit
call (up to 16 fillets), not run on every refusal.
A corner edge that doesn't run square to the edge is now reported as such
instead of as a blend larger than the neighbouring faces.
Refs #293
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TWc1smHYwTSVrVc8SNvS44
* feat: fillet fit option reduces a radius too large for its edges
solid.fillet takes fit: exact (the default, as before: a radius too large
for the geometry around the edges is refused) or reduce: the radius is
reduced to the largest that works for all the picked edges (kernel
fillet_max, three significant digits, every candidate built). The feature
stores the requested radius, so it refits on every evaluation; when it
reduces, the feature's warning says so and the command returns
radius_applied. Pattern copies of the fillet use the same rule. The file
format writes fit only when it is reduce.
The Fillet dialog gets a Radius Fit row (Exact / Reduce to Fit, constant
radius) and, when the preview reduced the radius, an Applied Radius line;
editing the feature keeps the choice.
One radius for all edges for now; per-edge radii and taper follow.
Refs #293
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TWc1smHYwTSVrVc8SNvS44
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: bherbruck <brennen.herbruck@gmail.com>
Fillets (local, loop, rolling ball, corner, variable, chord), chamfers
(cutters, local corners, loops, two sides), shell, draft, offset faces,
split face/body, delete face, patch/copy/stitch/trim/extend and
transforms record their history over [body] while they build: faces
rebuilt from the body's, blends in place of edges (corner patches in
place of the edges at the corner), shell walls as offsets, edges as
pieces of the body's or where two faces meet. Multi-step operations
compose each step. The push-face offset fallback now has history, and
the bore union composes its narrowed tool.
A reflection reorders a body's edges, so transforms now match edges by
identity (mirrored copies reported the wrong edges).
Refs #136
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01J53sR6gEaVt56soFDpTck8
* Fillets along a straight edge between two cylinders: the rolling-ball blend trims curved cap edges to its contacts
The edge where two overlapping extruded arcs meet is a straight line between two cylinders
ending on planar caps. The rolling-ball blend built its sections and surface, but only
straight seams could be shortened to the contacts, so a circular cap edge was refused with
"a curved edge where the blend ends". Curved seams now keep the part of their curve between
the new ends, found from the nearest of a few samples (a search from the far end of a long
arc can settle on the opposite side of the circle).
The ball's surface projections start from each face's last answer instead of a cold search,
falling back to one when the warm answer leaves the surface's parameters or is farther than
the last point: about 4.5x faster per fillet (370 -> 80 ms), so dragging the radius is usable.
Fixes#237
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Curve blend: refuse a closed curved seam where the blend ends
A seam that starts and ends at the same vertex (a full circle) has no
"between" two contacts, so trimming it built a broken edge. Return
"not supported yet" instead. The curved-seam trim moves into
trim_curved_seam so it can be tested directly.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RjGw4gA5ZvKrU8MQP6sBgT
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: bherbruck <brennen.herbruck@gmail.com>