Skip to content

Port of #13906 (WIP): a flat 3D print that folds, from the derived flat - #27

Draft
raykholo wants to merge 8 commits into
h0witzer:fix-6748-developfrom
raykholo:port/13906-print-fold
Draft

raykholo wants to merge 8 commits into
h0witzer:fix-6748-developfrom
raykholo:port/13906-print-fold

Conversation

@raykholo

Copy link
Copy Markdown

Port of tangency-labs#13906 (Unfold for Printing / foldable 3D print, by @cvengels) onto the surfaces-first develop in tangency-labs#9245. Draft: the original was a WIP, and the gaps below are still open.

What it does

  • Unfold for Printing wizard: splits a solid into flat printable parts that fold back up along film hinges. It has V-grooves, bevels, filament channels, press fits and carved hole walls.
  • sheet.convert takes print_* parameters: wall, film, clearance, split edges, filament edges, press-fit edges, and swap start face.

How it maps onto the surfaces

  • New SurfaceSheet::print_layout(&Development) (crates/doc/src/sheet_print_layout.rs):
    • Each piece of the development is a part.
    • Panels hang on each other along the bend joints.
    • Each child panel is translated so its sharp line lies on its parent's. That takes the zone width out, which is the hinge on the film at the outer skin.
  • Rip cut-backs are set through the sheet's own Lap before develop():
    • butt joints: Cut(0, (t+c−min(t·cosφ,0))/sinφ)
    • mitres: Cut(s, s), with s = c/2/sin(half)
    • filament edges: Cut(0,0)
  • Split edges are joins that stay cut open, so the faces past them become their own pieces.
  • The sheet stays the definition: the flat is never written back. Unfold and Refold toggle between the flat print and the folded print. Other sheet features are refused on a print.

Commits

  • The five original commits are cherry-picked with authorship kept. Their old-model hunks were dropped where Sheet metal: one model, the part's surfaces; the flat pattern is derived (#6748) tangency-labs/solidcraft#9245 deletes that code, and the wizard commit's body says how.
  • 6f34cc7: the layout and the solid now come from the surface sheet.
  • 14531f1: the tests are rewritten in closed forms. Old and new assertions:
    • v_grooves: V = t·(6000+2·100·30+2·60·30−4·30·(t+c)) − (2(100+60)−4(t+c))·groove
    • butt and mitre formulas for c = 0 and c = 0.2
    • filament: butt − five ≈ 4·30·1.85²
    • The rest are listed in the commit body.
  • Hexagonal prism, every edge pressed: folded is 0.40 % below flat (23556.16 vs 23650.32 mm³). On the old model the loss was under 0.3 %. Folding can only lose the corner material that two sides' fingers share, so the test asserts folded < flat, with the loss under 0.42 %.

Open gaps

  1. The wizard's interactive steps still use their own B-rep unfolder (UnfoldGraph/FlatLayout, generator 2's wall_solids). They run before any sheet exists. Generator 1 (sheet.convert) uses the surface sheet.
  2. print_wall is always required: a shelled body's own walls are not read.
  3. Hole mitres and sockets assume the hole wall is square to its face.
  4. Corner fills and channels that run out through a folded-over face are not ported. The old corner-film assertions are dropped, not replaced.
  5. Further gaps:
    • Curved or multi-point rip edges get no bevel or joints.
    • Inside corners use Miter{max(c, 0.8)}.
    • Convert's folded-overlap check is skipped for prints.
    • Cuts made after the convert are not guarded.
    • There is no print-specific DXF or bend-table handling.

Tests (buildq)

  • engine foldable: 10 passed. engine print_unfold: 10 passed.
  • engine convert_tests: all pass apart from two failures that already fail on fix-6748-develop.
  • engine schema: 719 passed.
  • ui-egui dialogs_sheet: 46 passed. ui-egui prefs: passes apart from the stand-up failure that also fails on the base.

Credit: @cvengels (C. Vengels) for the wizard, the print joints and the original PR.

cvengels and others added 8 commits November 15, 2026 03:49
Work in progress, not ready for review. A new wizard in the Sheet Metal tab,
"Unfold for Printing", in six steps: pick the base face, set bend and cut
edges, unfold flat against a printer bed, split at bends, choose wall and
joints, and build the printable solid. Steps 1 to 4 are tested by hand,
steps 5 and 6 on a box. Known gaps: carving out faces into groups, per-wall
thickness, saved custom printers. Some tests in the full suite fail on main
as well and are not caused by this change.

Port onto the surface-sheet refactor (tangency-labs#9245), what this commit leaves out
or changes (the rest of the diff is the original):
- crates/doc/src/sheet_convert.rs and the SheetBody changes in
  crates/doc/src/sheet.rs are not brought over: the old flat model is deleted
  on this branch. Of sheet_print_fold.rs only the part that does not read a
  SheetBody is kept (the print's values, joint kinds, filament, press-fit and
  fold-core types and their pure helpers); the geometry that cut the flat
  print out of a SheetBody comes back, built from the surface sheet, in a
  later commit of this branch.
- sheet.convert's print_* parameters and the FeatureKind::SheetConvert fields
  are merged into the new picked-faces form of Convert (the first face picked
  is the fixed face the print lies on). The dialog's print inputs follow the
  new inputs of Convert as rows 5 to 8. Evaluating a print is refused until
  the surface-sheet implementation lands.
- Icon and SVG paths follow the move to crates/look/icons.
…ers (tangency-labs#13905)

The wizard and the print wall hints called functions that moved to the
shared ui-text and theme crates and to ui_kit on main; they use the new
places now. No change in behaviour.
…gency-labs#13905)

Faces that can't fold with the rest of the pattern (the walls of a hole)
are carved out into a part of their own in step 2. The part folds at the
inside corners of the body, on the film, and its border follows what the
cuts get: fingers that stand in sockets of the faces it meets (press fit
or filament), a mitre, or a butt end.

Also: a chamfer's straight spline edges count as straight, the new tab
hides the origin, printers of one's own are kept in the preferences, and
the fingers of two walls that lie side by side in the flat end short of
the line halfway between them.

Port onto the surface-sheet refactor (tangency-labs#9245): the changes this commit made
to the old flat model (sheet_convert.rs, the SheetBody half of
sheet_print_fold.rs, the old evaluation of print_mitres and print_sockets in
eval_more.rs) are not brought over, those files being deleted or rebuilt on
this branch. The print_mitres and print_sockets values, the FINGER_FLAT_GAP,
CRUMB and FIN constants, PrintSocket and socket_fingers are kept.
…ngency-labs#13905)

Generator 2 makes the printable parts from the body's own walls: each
face's outline taken into the material by the wall thickness, mitred
where two faces meet round the outside of the body, then turned flat
with a film under each bend. Folded up, the walls are the body's shell.

A cut can be a press fit: the corner two walls share is dealt out along
the edge in fingers, a nub on each finger's end face and a dimple in
what stands next to it. Bends are never press fits, the ends of a cut
stay mitred, and a cut gets no fingers where another wall lies beside it
in the flat pattern.

Step 1 of the wizard chooses the generator (1 stays the default); step 5
offers mitre or press fit for the cuts of generator 2.

Not run yet: cargo xtask ci, the wasm build.

Port onto the surface-sheet refactor (tangency-labs#9245): the one-line change to the old
flat model's sheet.rs is not brought over.
…angency-labs#6748, tangency-labs#13905)

The folded sheet's faces (`SurfaceSheet`) are the print's definition and its flat is derived from
them, never written back: no second unfolding, and nothing maps the flat back into 3D.

- `sheet_print_layout.rs`: the print's parts and panels, taken from the sheet's joints and its
  development (`solidcraft_develop::develop`). Which panels hang on which, which joints are
  bends (all must turn toward the material, as the faces of a solid do round its outside) and
  by how much, and where each panel lies in the flat come from the sheet; a panel that hangs on
  another is moved, with everything on it, until its sharp line lies on its parent's (the
  zone's width the development lays between them taken out, as a print hinges on a film at the
  outer skin where Datum::Sharp anchors the bend). The open edges are the rips' edges on their
  panels.
- `sheet_print_fold.rs`: the solid from that layout: the flat as one body with a V-groove and a
  film at each bend, a rip's cut-back as its joint says (butt: the panel reached first whole, the
  other a wall and the clearance short; mitre: the sheet's own cut-back at the outer skin and a
  slope at the inner; inside corners as the sheet cuts them but never nearer than a nozzle's
  line), filament channels and press fits on open edges and on bends, mitres and sockets on the
  edges of holes whose walls print as a part of their own, and the print folded back up.
  Moved here from the old SheetBody code, rewritten on the layout: the groove, the fingers on
  open edges and on bends, the nubs and dimples, the folded pieces. Not carried over: the corner
  fills (the layout's panels reach their sharps, so the corners the old zones left open are
  not open) and the channels that run out through a face folded over their ends.
- `SurfaceSheet::print` keeps what a print is made with; `build` makes the print instead of the
  folded sheet. Unfold and Refold are the flat print and the print folded back up; no other sheet
  metal feature works on it.
- `convert_surfaces_joined`: Convert with edges that join the faces on either side to the sheet
  and stay cut open (the print's split edges: the faces past one print as a part of their own),
  and without the check that the folded sheet's material does not meet (a print hinges at the
  outer skin, whatever the rule's radius would do to walls shorter than twice the wall).
- `sheet.convert` with `print_fold` (the first face picked is the one the print lies on) is
  evaluated by `convert_to_print`.

Claude-Session: https://claude.ai/code/session_01DmVrHV7g8BrZkapg5Nm4eD
…in closed forms (tangency-labs#13905)

The PR's tests of Convert's print (it came with its tests, written on the old flat model) now
check the same behaviours through the surface sheet. Each derives its expected numbers in a doc
comment from the layout the sheet gives: the faces' outlines, the rips' cut-backs, the grooves'
section. Ported: lies flat on its fixed face and folds back; grooves take the film and the
clearance; refused values; butt and mitre corners; an end edge picked in the middle of a face;
overlapping faces and split edges; filament and press fits on open edges and on bends (the
hexagonal prism's too); the walls of a hole fold into it.

Claude-Session: https://claude.ai/code/session_01DmVrHV7g8BrZkapg5Nm4eD
…t is

The port had widened the flat-vs-folded volume bound from 0.3 % to
0.6 %. Measured on the surface sheet's layout the folded print is
94 mm3 of 23650 mm3 (0.40 %) below the flat: two sides' fingers share
each 60 degree corner, and the folded print holds it once. Folding can
only lose material, so assert folded < flat and a loss under 0.42 %.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants