Repository navigation
Conversation
|
@bherbruck could you add |
…angency-labs#6748: two files still named the record through solidcraft_geom main at dc38349 fails to compile: crates/smlib/src/trace.rs and apps/solidcraft-cli/src/kernel_cases_export.rs name `solidcraft_geom::brep::Brep`, which moved to solidcore_record. Drop this commit once main has its own fix. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…solidcore fix-6748-develop (d7ac9223) brought onto main at dc38349: crates/develop, the sheet made from surfaces (Convert, Thicken, its features, cuts read back onto the flat), brep::query and the tests, on solidcore and the record types main now takes from solidcore-record (`solidcore_record::{Vec2, Vec3, Seg2, Loop2, Region2, Plane}`, the record's brep types, the geometry through `solidcraft_geom::prelude`). Taken from main where both changed: the Hem and Fold commands' typed contracts (Hem's gap described as the space between its leg and the face, twice the bend's inner radius), main's layer comment for solidcore, the geom tests' imports. The flat pattern's DXF keeps main's writing order and loose pieces, in the one writer flat-first and surface-first sheets share. main's new cut test converts with Thicken and counts the surface sheet's holes. The old flat-first sheet_convert.rs goes, as on develop. main's tray round trip (tangency-labs#7529) is restored and FAILS here: Convert keeps a bend modelled with its radius as a roll, so the tray converts with the right solid and flat but no bends. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-record's types Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`sheet.perforate` takes a `shape`: round (default), hex (a regular hexagon `diameter` across its flats, a corner up, so a staggered field is a honeycomb) or slot (`diameter` wide, `length` long overall, along the rows), and a `row_pitch` for rows closer or further apart than the pattern's own. Each hole keeps `margin` clear of the edges, cut-outs, bends and outline by its own outline, from a first row and column half its width (or height) in. Holes that would meet their neighbours, a slot no longer than it is wide, and a length without a slot are refused. The flat pattern reports each field's shape, row pitch, area (the outline on the material, else the flat), its open share of that and the grid's nominal open share (Ø5 on 6 staggered: 62.98 %). The DXF draws a hexagon as six LINEs and a slot as two LINEs and two ARCs on PERFORATION, and the measured volume and area take each shape's area and perimeter. The Perforate dialog gets Shape, Slot length and Row pitch, and the flat view draws hexagons and slots as their outlines. The feature saves `shape`, `length` and `row_pitch`, a sheet's perforation `shape` and `row_pitch`: one pending format note, no migration. The holes stay marks on the flat pattern; cutting them into the solid is left for the surface model (tangency-labs#9245). Assisted-by: LLM
…a bend, a roll past DIN 6935's limit, and rolls have lines in the flat Convert and Thicken tell a cylinder modelled between two planes by its inside radius in thicknesses. Short of 10^0.7 (about 5), where DIN 6935's k(R/T) = 0.65 + 0.5 lg(R/T) reaches 1 and the neutral fiber lies halfway through the sheet, it is a bend: the cylinder is no panel, the two planes run on to their virtual sharp (each end carried along the line beside it, or stepped out square where the face runs on past the bend), and they bend there with the cylinder's own inside radius, so the sheet is the part as modelled. From there on it is a roll, as before. A bend picked on a modelled bend's cylinder or on one of its edges is on the sheet. A roll's flat has its lines, as a bend's has: along its rulings where it starts and ends, and halfway between (`roll_lines` in sheet.flat_pattern); the DXF draws them on a ROLL layer, so a reader of the bend layers doesn't take a roll for bends. The tests that had a modelled corner of one or one and a half thicknesses as a roll have it as a bend of its radius; the flat-pattern test's channel is rolled six thicknesses inside to stay a roll. main's tray round trip (tangency-labs#7529) converts its bends now: the notched tray of one feature comes back exactly; the others differ at their corners' reliefs (round -4 mm2 of flat, notched and round in two features -2, torn +4.1 with its bends 0.58 longer), which is still to do. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…lines, dotted where a roll starts and ends and dashed halfway Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…the tooling would: its thickness, its bends' radius and its reliefs A vendor's file with other radii or another thickness converts to the sheet the rule makes. The sheet takes the rule's thickness from the side picked, whatever the body's, and a bend modelled with its radius (short of DIN 6935's 10^0.7 thicknesses) bends at the rule's radius at its virtual sharp. The body's own thickness only tells its sides apart and whether a modelled corner is a bend or a roll; a roll keeps its own radius. Engravings are read against the sheet as the body has it (its thickness and its corners' radii), and kept on the rule's sheet each as deep from its face. Convert notes where the rule changes the body: its thickness, or a corner's radius. main's 1092 case (an L modelled R 2 under an R 3 rule: one bend at the rule's radius at the legs' virtual sharp, V = 9000 + 200 pi) is back in place of this branch's rename; its recipe keeps Thicken and the quarter arc. Tests whose plates are not about thickness convert under a rule of their stock; the parametric shell's stock is its thickness parameter; the shell, L, block and threshold tests expect the rule's thickness and radius. The guide says the rule wins. The tray round trip (tangency-labs#7529) still fails: the rule's reliefs as Convert cuts them differ from the ones the edge flange cut under the same rule. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… as it reports each bend A roll's row in sheet.flat_pattern (`roll_table`) and in the Flat Pattern dialog: how far it turns, its inside radius (none for a cone, whose radius runs along it), its length along its rulings and how wide it lies in the flat, read from its start, end and middle lines. The bend table CSV keeps its bend rows only, as press-brake readers take it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… sheets (tangency-labs#6748) Base Flange and Contour Flange build sheets made from surfaces; Fold, Path Flange, further bends and perforation fields work on them. The flat reads from the sheet's surface side (up bends toward the reader); a cut that parts pieces holding no joint keeps them in place, as flat-first did. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@h0witzer thanks for the second round. I checked c429118 against my review of 11-12, and the items are settled:
Two checks fail on this head. Both are small:
On jyviko's item 5: the certified outline from Written by Claude Code (Anthropic) on behalf of @brett19. |
…tests (tangency-labs#6748) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ts run again (tangency-labs#6748) - ladder/12-sheet-metal/006 and 007 re-recorded: the corner-relief trays have the relief walls of each bend, flange and panel as faces of their own (006: 73 faces, 181 edges, 110 vertices; 007: 132 edges, 88 vertices). Volume and area are unchanged and every check passes. - The two ball-on-roll cuts are no longer ignored: tangency-labs#15886's trim fix is on main (merged here), and both pass. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@brett19, a regression report for #15475 (SolidCraft's planar region booleans on solidcore-ops), found merging Five sheet tests on
All five involve arcs in the regions the sheet passes to |
|
@h0witzer thanks, that's a clean bisect. It's ours: #15475 moved the planar region booleans onto solidcore-ops, and all five of your cases have arcs in the regions. The sheet passes what We're reproducing it now on c429118 with your five tests. Then we'll write minimal repros that run on If something you pass in does turn out to be the cause, we'll say so with the trace before asking you to change anything. Written by Claude Code (Anthropic) on behalf of @brett19. |
…d rim hole is as deep as drilled (tangency-labs#6748) - main's index face names on a sheet (`F2:face:1`): a sheet feature names its faces after what made each and numbers none, so the name found nothing. It now finds the one face of a sheet body the same feature made that the saved point lies on (`numbered_sheet_face`, as tangency-labs#16661 finds a replaced line's side face); the index is not read. Holes main saved on a base's bottom, in its rim and through a flange rebuild as main built them. - Convert: a modelled bend picked on its cylinder across the thickness from the faces picked is the bend on their side (the coaxial cylinder of another radius that runs smoothly into what they reach), as main's Convert took it. Before, that cylinder and its faces became panels too and overlapped the faces picked. - sheet-edge-names: a flange's `base:<line>:<side>` maps where no copy comes before the flange; a mirror after it (a part mirrored once its flanges are on) no longer leaves the names unmapped. - A bore lying in a panel runs a hair past an end only where the panel's material ends: a blind hole into a rim was T/100 deeper than drilled (10.04 for 10 in a 4 mm rim). Test change: four tests added (`holes_main_saved_on_a_sheets_numbered_faces_open_on_those_faces`, `a_part_main_mirrored_after_its_flanges_rebuilds_both_copies`, `a_bend_picked_on_the_cylinder_across_from_the_face_converts_as_the_face_sides`, `a_blind_hole_into_a_rim_is_as_deep_as_drilled`) and one case in the sheet-edge-names unit test; none changed or removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Pushed 55fdc95 to
Parity, rerun on this head: 71 designs saved by Gate on this tree: The certified cut outlines (#16938) and the #15475 regression (brett19's fix to come) are unchanged by this push. |
|
@h0witzer, a status update on the five #15475 engine tests that still fail on this branch (relief wall naming, the tray outline, the round notch, and the two others in the list above). The cause is in solidcore, on Cause.
The sheet data is valid as it stands. Switching only that arc branch back to the old construction makes all five tests pass on this branch, with no SolidCraft change. Fix (#17061). Each arc gets its own circle, starting at the arc's start, trimmed [0, sweep], with no re-parameterisation. It adds solidcore tests that fail on
It is in its gate now. It then gets an independent review, and we'll mark it ready and post here when it does. Once it merges, merging Written by Claude Code (Anthropic) on behalf of @brett19. |
|
@h0witzer thanks for the report: it's on the ops side, and the fix is #17061; nothing changes in what the sheet passes in. solidcore-ops built every arc on one shared circle per centre (angle 0 on the frame's x axis), so two arcs of one circle became one curve and the 2D boolean dropped the point where they meet, and an arc starting past π got a trim past 360° (the 0.5 mm hole's Written by Claude Code (Anthropic) on behalf of @brett19. |
…ntour's bend (tangency-labs#6748) The full suite's `design_corpus` and `action_matrix` found three faces of the corpus's `modern-sheet-metal` (a contour flange of three legs) that no sketch could stay attached to: the first leg's far end and its two ends were named by their place among the faces (`F2:face:2`), which is no identity (tangency-labs#7990). A later leg's rims are named after the bend that makes it (`far`, `end0`, `end1`); the first leg is made by no bend, and a contour's sketch line draws none of its rims, so nothing said what made them. They are now read from the contour's bend into the next leg, as that leg's are: `far:l1`, `end0:l1`, `end1:l1`, at the same ends as the next leg's. A flange added on the leg later never counts, so the names hold when one is. Test change: one test added (`a_contour_flanges_first_leg_names_its_rims_as_the_others_do`); none changed or removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The section of a B-spline extrusion by a plane parallel to its profile (tangency-labs#6748) came without UV curves, as upstream's analytic special cases do. The general intersection it replaces gave them, and the offset's mate proves a curve without them only on analytic surfaces, so moving a cylinder's top was refused with ExactCurveUncut (local_operation a_raised_cylinder_top_mates_on_its_exact_circle_within_the_derived_reach). extrusion_section_uv_curves fills both, exactly: on the B-spline the iso line at the sweep parameter where the plane cuts (sigma = f / (c - f (c - 1)), c the weight ratio across the sweep), on the plane the section's control net in the plane's parameters. The unit test checks both lift onto the section to 1e-12. Result that changes: WR-450 with analytic_copy_keeps_parameterization off (upstream's defect) now has trims 0.78 off on the arcs at z = -14 and z = 14 as well as the line at x = -14 (3 edges and 4 vertices, was 1 and 2): the box's top and bottom now cut the cylinder in its exact section. With the fix on, the result is valid as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Pushed 5c10d98 to
The full suite on Linux still waits for |
|
A tab cut free by a U-shaped slot still can't be folded on this branch. This is the Fold case from #11903, and I'd like to help with it. The part. A 120 × 80 mm plate, 2 mm thick. A U-shaped slot leaves a 35 × 40 mm tongue joined to the plate along one side. The fold line runs across the tongue's root, 2 mm into the tongue. [{"command":"sheet.manage_rules","params":{"name":"AL2","thickness":"2","bend_radius":"2","k_factor":"0.43","active":true}},
{"command":"sketch.create","params":{"plane":"XY","name":"Base"}},
{"command":"sketch.line","params":{"points":[[-60,-40],[60,-40],[60,40],[-60,40]],"closed":true}},
{"command":"sketch.line","params":{"points":[[-10,-25],[30,-25],[30,25],[-10,25],[-10,20],[25,20],[25,-20],[-10,-20]],"closed":true}},
{"command":"sketch.finish","params":{}},
{"command":"sheet.flange","params":{"sketch":"Base","profiles":[0]}},
{"command":"sheet.fold","params":{"points":[[-8,-15,2],[-8,15,2]],"angle":"45 deg"}}]What happens.
Expected. Only the tongue folds. The plate around the slot stays flat, and the flat pattern keeps its size. The line's points pick the stretch of the bend that folds, as they already do for collinear tabs on an edge (#264). What I have. I made this work on
All existing sheet tests in This PR replaces the model that branch changes, so I won't open a PR against |
|
@artem-nerel thanks, yes please. This should land as a follow-up after #9245, which is under a scope freeze (fixes only) while it waits for CI. Please build it now against What it is on the surface model. A folded tongue needs nothing new in the model: it is two panels (the plate and the tongue) joined by one bend, whose zone ends lie on the slot. Develop, settle, the flat pattern, the DXF and naming already handle that. The change is in how a fold picks the material it bends: The rule, in four steps:
This replaces the outline-band pieces and three refusals: "a fold whose bend zone holds two pieces beyond it", "the fold cuts its panel into more than one piece on its fixed side" and "folding tabs that join again beyond the bend". In their place is the one parting test, and the #264 drawn-stretch path becomes step 2. Everything else stays as it is: the bend allowance and fold position, bend ends following the outline, the corner check when a zone reaches a corner of the outline, and the flat pattern. Cases. The rule is AL2 (T 2, R 2, K 0.43). Each row uses your 120 × 80 plate unless it says otherwise, and "Today" is #9245 at 5c10d98.
Your four tests are the right ones; please port them as written, and add the rows above as tests too. The "Same" rows guard today's results, and the last three rows with your slot pin step 3. Please don't port the selection condition from your This also covers the Fold route of #11903, since each collar tab's root runs from slit to slit. An edge flange on a hole's edge is still refused on #9245; that is a separate change. I'll review the draft against the repository's rules before it merges into the fork. |
Change
Sheet metal on one model, the part's surfaces (RFC #6748; direction confirmed by @jyviko on #6748). A sheet is its panels (flat, rolled or conical surfaces) and the bends, seams and rips between them; the folded body and the flat pattern are both built from that, so they always agree. The flat-pattern
SheetBodyis deleted (crates/doc/src/sheet.rs10,961 → 825 lines;sheet_convert.rsandsheet_flat_lineage.rsgone), and every sheet feature builds from surfaces: Base, Contour, Edge and Path Flange, Hem, Fold, Unfold/Refold, Perforate, Convert, Recognize, cuts and holes read back onto the sheet, the flat pattern, DXF and bend table.Where the geometry lives. The development engine is in solidcore (h0witzer#20 by @brett19, merged into this branch):
solidcore::develop(charts, layout, fold, rigid motions, andhermite: cubic pieces proved within a tolerance of a curve carried into the flat),solidcore::eval::{query, folded}(exact record queries; the folded pcurve moved out ofcrates/kernel/src/sew.rs, which is now 198 lines shorter thanmain's), record types insolidcore-record::develop, calls insolidcore-ops::{develop, query}.crates/developis a thin adapter that words the kernel's typed refusals.crates/geomismain's apart from the flux quadrature, whose pieces come from solidcore. What is still computed app-side is listed in #16938.Developments are closed form and refused otherwise. Plane, right circular cylinder and right circular cone panels develop exactly; a free-form panel is refused with a typed reason pointing at #15743 (jyviko's conditions 1 and 2). Bends develop at the rule's K-factor; rolls and rolled cones at K 0.5 (the neutral fiber at mid-thickness, DIN 6935).
Landing. One PR, as discussed with @brett19: the engine moved into solidcore here rather than in a separate PR 1, and the flat model is already deleted, so a harness that runs both models can't exist. Parity is shown instead by
main's sheet tests ported onto surfaces as the spec, and by designs saved onmainand rebuilt here (below). The scope is frozen: only fixes go in from here; new sheet features (fork PRs h0witzer#8, #12, #13, #14) go tomainafter this lands.Intentional behavior changes
Every user-visible change from
main, with the test that pins it and the reason. "R" is a changed result of the same input (Changes a default: noper CONTRIBUTING); "T" is a change of what a tool does with its default inputs, or of what a saved value means.main→ this branch)mainrefused the flat pattern ("can't includeFillet1"), and the next sheet feature dropped the round with a warningsheet_testsa_fillet_on_a_sheet_corner_is_an_arc_of_its_outline_kept_by_a_later_flange;kc/3324-flat-pattern-refused-after-a-fillet-on-the-sheet(expectation rewritten; the directory name still says "refused");cut_testsa_corner_rounded_through_the_sheet_is_an_arc_of_its_outlinemainrefused it ("intersects a folded bend")sheet_testsa_cut_grazing_a_bend_near_its_edge_takes_every_fiber_it_meets_and_one_clear_of_it_cuts_the_base;cut_testsa_hole_through_a_plate_that_runs_into_its_bend_is_cut_from_both,a_drill_through_a_bend_is_cut_as_its_shadowmainrefused itsheet_testsholes_in_a_contour_flanges_end_panels_are_cut_outs_or_notches_of_its_flat_pattern(its last part; the volume bound T × outline length × the shadow's sag is derived in the test)maindropped the holes that fell in a later bend's zone. A field made after a bend still keeps clear of itsheet_testsperforation_runs_through_bends_and_survives_fold_unfold_and_reopen;props_testsperforated_sheet_hole_a_later_fold_runs_through_weighs_as_the_same_hole_cut_and_folded;kc/cov-perforate-keeps-clear-of-a-bend-zone(unchanged, passes)mainmade it one bend of the rule's radius at the virtual sharpconvert_testsa_bend_picked_on_a_chamfer_is_refusedmain(#15288) built a sharp bend with its outer face onlysheet_testsa_bend_radius_of_0_is_refused_wherever_it_is_given,a_refused_rule_names_the_value_at_fault,a_tiny_bend_radius_keeps_both_cylindrical_facessheet.manage_rulesand when a saved rule is evaluated.mainleft those corners open with a warning ("left open")sheet_testsreturns_follow_the_rules_gap_and_a_gap_of_zero_is_refused,a_design_whose_rule_has_no_gap_says_so_on_its_flanges(a saved gap of 0 errors on the base flange until it is set)brett19's item 6. No format stepmainbuilt it as a low wallconvert_testsa_bend_ends_where_its_wall_ends_with_the_rules_bend_relief_beside_it(last part; now run throughsheet.recognize)mainrefused one deeper than half the plate, recesses in both faces, and a recess leaving a raised rim. Convert keeps a recess as a pocket only where its faces are given inengrave; without that, the recess's opening is a hole of the panelconvert_testsa_plates_recesses_are_the_sheets_at_any_depth_from_either_face,a_hole_reaching_into_a_bend_is_refused_and_a_deep_pocket_kept,an_engraving_is_converted_only_where_its_faces_are_pickedmain,facewas required: a plate kept its own thickness, a shell kept its wall thickness, and a solid took the rule's inward. Herebodyalone converts every face (lessskip);faceandfacestake the faces picked and every face a bend joins to them;directionandengraveare new. A rod picked on its end is a disc of the rule's thickness (main: a plate as thick as the rod is long), and a block thicker at one end converts (mainrefused it).modewas never onmain: it existed only on this branch (added in057ef5f82, removed inbbac52e3f)surface_convert_testsa_thin_block_converts_to_six_panels_parted_by_rips,a_solid_converts_whole_with_its_material_inside_or_outside,a_surface_body_converts_with_the_rules_thickness_on_either_side,a_whole_thin_block_under_a_thick_rule_is_refused_naming_its_sides;convert_testsone_face_of_a_bent_part_thickens_alone,the_sheet_follows_the_solid_through_parameter_changes_undo_and_reopening;sheet_testsunfold_cut_refold_and_convertbrett19's item 6. A saved plate conversion opens as Recognize of that plate under its rule (format/pending/sheet-surface-convert.rs); a saved conversion of a shelled body opens at the rule's thickness, with a notenew_rulemakes a rule from the body.main's Convert of a plate or shell kept the body's thicknessrecognize_testsa_recognized_body_takes_the_rules_thickness_and_radius,a_new_rule_from_the_body_gives_the_body_back;convert_testsa_converted_shell_takes_the_rules_thickness_and_radiussheet.converttosheet.recognize(10, each with a rule at the body's own thickness; expectations unchanged but for the method text):1040-convert-a-1200-mm-strip-1-mm-thick,1040-convert-a-990-mm-strip-keeps-its-1-mm-hole,1092-convert-a-channel-with-its-bends-modelled,1092-convert-an-L-with-a-modelled-bend-to-the-rules-radius,1092-convert-an-engraved-plate,1285-convert-a-bracket-whose-wall-covers-part-of-an-edge,3316-convert-a-plate-keeps-its-place,4328-convert-l-section-with-modelled-bend,725-convert-a-shelled-tray-and-unfold-it,774-convert-a-plate-with-nine-round-holes.tests/kernel-cases/EXEMPTnow listssheet.convert, so no kernel case runs Convertmaincalled Convert of a thin body is Recognize heremainmade every modelled bend one bend of the rule's radiusconvert_testsa_modelled_corner_is_a_bend_short_of_about_five_thicknesses_and_a_roll_from_there;surface_convert_testsa_roll_keeps_its_modeled_radiussheet_surface_convert.rs,up: !b.toward_material). Base and edge flanges still read "up". The same rule swaps POCKET_TOP and POCKET_BOTTOM for a plate recognized from its engraved face, and mirrors the #14616 hat's flat (v = 20 − y)convert_testsa_shelled_tray_keeps_its_walls_and_unfolds_by_the_k_factor(BEND_DOWN ×4),bends_picked_inside_and_a_fixed_face_inside_give_the_same_sheet,a_trapezoid_section_unfolds_through_72_and_108_degree_bends,a_tapered_tray_converts_with_72_degree_walls_and_slanted_corners,bend_edges_changed_in_an_edit_are_the_ones_bent,holes_and_a_slot_in_a_channels_faces_land_where_the_bends_put_them,a_bend_ends_where_its_wall_ends_with_the_rules_bend_relief_beside_it,a_plate_with_an_engraving_converts_with_the_engraving_as_a_pocket;sheet_testsbase_and_edge_flange_follow_the_k_factor("up", unchanged)057ef5f82gave no reason; the reason above is the code's commentbrett19's item 6. DXF layers BEND_UP and BEND_DOWN change for such partsmaingave a feature's relief only to corners between two of its own bends. The test's tear request also moved from the near feature to the far one. In the same way, a feature's rectangular relief now covers its shared corners (and the test's size went 3 → 8 mm, because a 3 mm relief at the new center takes nothing)sheet_testsan_edge_flange_feature_can_tear_its_corners_under_a_notch_rule,each_edge_flange_feature_chooses_the_corner_relief_of_its_own_corners,an_edge_flange_feature_follows_the_rule_for_the_relief_it_leaves_outc = s0 − BA/2), and cut from every piece of the flat it reaches.maincut it from the base at the corner of the bends (s0in) and shortened both bends by rsheet_testscorner_reliefs_of_the_rule_reach_the_part_the_flat_pattern_and_the_dxf,corner_reliefs_at_non_orthogonal_corners_reach_the_flat_pattern_and_the_dxf,side_edge_flanges_across_a_bend_keep_their_relief_through_rebuild_and_reopen,thickness_in_a_rule_is_the_rules_even_beside_a_parameter_of_that_name;convert_testsa_converted_trays_corners_are_closed_and_relieved_as_a_flanged_trays_are,a_wall_on_part_of_an_edge_meets_a_wall_at_a_relieved_corner_and_is_relieved_at_its_end;ladder/006,ladder/007;kc/3417; scenarios51(107.640745 → 110.154019);develop_testsa_corner_relief_is_centered_where_the_bends_crossmainlet the later flange trim the base under the first bend, and the earlier flange's panel ran on, so the result depended on the orderoracle/75-sm-bracket-holes/expected.json(KNOWN_FAILURES = {}intools/oracle-analytic/cases_sheet_metal.py;mainhad"75-sm-bracket-holes": "#296");surface_convert_testsflanges_meeting_at_a_corner_close_it_as_converting_the_same_metal_doeskc/296-hole-in-a-base-with-two-adjacent-edge-flangesis re-derived for the mitred cornergapis the space between the leg and the face it folds over, so the bend's inside radius is gap/2. Onmainthe gap was the inside radius. Saved designs migrate (format/pending/sheet-hem-gap.rsdoubles saved values, and a rule without one gets 0.02). The defaulthem_gapis still "0.01 mm", so a new default hem has inside radius 0.005 (main: 0.01)format/pending/sheet-hem-gap.rstestsaved_hem_gaps_double_and_a_rule_without_one_gets_twice_the_old_default;oracle/73-sm-hem(21334.723 → 21332.046);ladder/009;kc/cov-hem-open-with-a-gap-flipped,kc/cov-export-bend-table-csv-flange-and-hem;sheet_testscontour_flange_hem_and_tray;convert_testsdesigns_from_before_bend_edges_open_unchangedbrett19checked this)gap: 1now gets R 0.5roll_tablelists it.mainlisted it as a bend (R 8, 90°), developed at the rule's K; a roll develops at K 0.5 (row 30)sheet_testscontour_flange_takes_tangent_arcs_and_develops_their_bends(bends0,roll_table1)mainsaid "1 piece ofBody1is no longer joined to its base … it is kept". Now each piece is a sheet with its own flatsheet_testsa_slot_across_a_flange_beside_its_bend_leaves_two_pieces_folded_or_flat,a_hole_across_a_flanges_width_leaves_two_pieces,a_ring_over_a_flange_keeps_the_piece_of_its_inside,cuts_that_split_a_sheet_leave_its_pieces_each_with_its_flatmainit ended square acrosssheet_testsa_cut_out_with_a_corner_on_a_bend_line_refolds(1.0 mm² vs 2.0)mainbuilt itsheet_testsa_fold_across_a_flanges_slanted_end_foldsmainit stopped at 97sheet_testsan_edge_flange_beside_a_ledge_as_tall_as_its_setback_or_a_little_taller_foldsmain(#15346) built every offsetsheet_testsa_cut_passing_a_hair_off_a_flange_corner_buildsmain14), #15566's sharp tabs 18 (main26), and an unfolded body keeps the folded body's facessheet_testsbase_and_edge_flange_follow_the_k_factor,fold_across_two_rounded_tabs_keeps_one_face_per_arc,elliptic_cut_out_stays_exact_in_the_flat_pattern_and_follows_arcs_when_foldedmain:sheet:<body>:<panel>:<side>inmodel.faces'ssheet_face, sketches attached assheet_face, and flangeedge_nameslikebase:l2:top. Here: names likeF12:top:F3:side:l1,sheet_facealways empty, sketches attached asexact_face, and flangeedge_nameslikeF3:side:l2|F3:topnames_tests(8);sheet_testsflange_edges_are_named_and_follow_the_base_sketch,a_sketch_on_a_flange_face_attaches_to_its_panel,every_flat_face_of_a_sheet_takes_an_attached_sketchformat/pending/sheet-face-names.rs,sheet-edge-names.rs);main's index face name on a sheet (F2:face:1) finds the one face of that feature its saved point lies on; another oldsheet:name reports a lost attachment, to be picked againdialogs_testsconvert_takes_the_faces_picked_and_the_bend_edges,convert_takes_the_body_its_bends_and_the_faces_it_skips,recognize_makes_the_bodys_rule_and_convert_points_to_itstays), decided once.maindecided it again on every rebuild (the larger side, or the fixed point). Older designs get the side once, as they opensheet_testsa_fold_keeps_the_side_its_fixed_point_picked_when_its_line_moves_past_the_point,an_older_designs_fold_gets_its_side_once_as_it_opens_and_keeps_it;names_testsa_fold_keeps_its_side_and_that_sides_names_when_its_line_movesstays: left|rightinput is not passed by any testslitsin the flat JSON (two OUTLINE lines in the DXF), not spliced into the outline loopdxf_testsjunction tests (read throughjunction_cuts)maindeveloped every bend at the rule's K and had no rollssurface_convert_testsa_conversion_shows_in_the_flat_pattern(rule K 0.4),a_roll_keeps_its_modeled_radius,a_pipe_rolls_out_from_its_surface_alone;sheet_testsa_contour_flange_rolls_a_tangent_arc_at_its_own_radius(its folded volume is then the flat's area × T exactly),a_contour_flange_of_one_half_turn_is_a_half_pipe;cut_testsa_rolls_flat_has_lines_where_it_starts_and_ends_and_halfway_betweenbrett19's roll-threshold pointmaincut it straight across in the flat (a helix when folded). Flat area +1.5 to +3.4 mm² on the torn trays; bend lengths unchangedkc/723-tray-with-torn-corners-folded,kc/723-unfold-a-tray-with-torn-corners,kc/1797-tray-with-torn-corners-at-72-degrees-folded;sheet_testsa_tear_of_the_rule_reaches_the_part_the_flat_pattern_and_the_dxfParity with
mainSaved designs. Each sheet-metal kernel case's recipe was run by
main's build (1843e1f,main's own copy of the recipe), saved, and the saved file rebuilt bymain's build and by this one, comparing every body's volume and area and each sheet's flat size, flat area and bend table. Of 71 saved designs: 46 rebuild identically; 17 differ as rows of the table predict (thickness from the rule, bend labels, relief placement, corners closed across features); 3 where this branch hits the closed form exactly andmainwas a hair under (an ellipse cut-out, 0.013 to 0.016 mm³); 3 differ by the torn corner's shape (row 31); 1 asks for a face to be picked again (a sketch on an edge flange's panel by itssheet:name, row 26); and 1 is refused: a Convert of an L whose recipe draws the inner arc three quarters of a turn, so its inside corner is a bump, not a bend (maindropped the bump's material).main's index face names (F2:face:1), a Convert picked on the bend's other cylinder, and a mirrored sheet's flange edge names were fixed in 55fdc95. The case-by-case tables are in the comments below.Capabilities. Every sheet capability on
main, each with the test here that covers it, is in the parity comment (#9245 (comment)).Validation
Locally on the pushed head (3fd02c8; Windows, GNU toolchain, dev profile):
cargo test -p solidcraft-engine --lib -- sheet convert loft: 488 pass, 0 fail, 3 ignored (a benchmark, and the two ball-on-roll cuts waiting on solidcore: a ball cut whose poles lie on a cylinder's face builds; the trace steps to the pole at its seam corner #15886's fix, now onmain; un-ignoring them follows).cargo test -p solidcraft-doc --lib: 691 pass.develop::,eval::folded,eval::query,eval::pcurve68 pass; solidcore-opsquery,develop,pcurve,curve_knots20 pass;solidcraft-kernel --lib sew15 pass.cargo clippy -D warningsclean on solidcore, solidcore-ops, doc, engine, develop, kernel and geom;cargo check --workspace --all-targetsclean;Cargo.lockpasses--locked; fmt clean on every changed file.hostile_params_never_panic: the hang reported here wasfile.slicerssearching this machine's programs on each of ~5,600 calls on Windows, whichmainfixed in Tests: the hostile-parameter test lists made-up slicers instead of searching the machine 5,600 times #15825 (merged in).Known, with follow-ups
solidcore::develop::hermite, is in this PR with its tests; wiring it into the shadow reader is the follow-up in Sheet metal: geometry still computed app-side, and certified cut outlines (follow-up to #9245) #16938 (a draft does it, and one case, a 30° hole through a plate, fails the planar boolean and needs finding first).sheet_surface::on_grid(1 nm grid for shared flat corners) stays until each shared corner is computed once.Changes a default: yes — no preference keeps the old behaviour; the T rows above are the user-facing changes, each listed with its reason for a maintainer's OK, and older designs are converted once as they open where the geometry can be kept (hem gaps, plate conversions, sheet face and edge names).
Test change: kernel cases, the ladder and oracles 73 and 75 changed only where this PR changes the result, each row of the table above pointing at its test, with the number derived by hand in the expected file.
🤖 Generated with Claude Code