feat(fold): fold scope — flap-typed moving, up to, @fold #67
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/fold-scope"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Implements the fold-scope design (ADR 0016): every fold has axis / anchor / scope / direction.
movingis now flap-typed: a point (the flap carrying it), a line (usually a multi-match, per ADR 0016), or#(…)incidence constraints. Map folds keep their implied anchor.up to <flap>scopes the fold to a contiguous some-layers range [demaine2007, §14] — the outer prefix of the stack over the crease region from anchor through target, computed as a closure inFold_state.select_scope. Non-moving faces stay whole and uncut.@fold <crease> moving … [up to …]folds along existing material; new segments join the same bundle (ADR 0014). Bare bind +@fold … up tocomposes into crease-all-fold-some: non-moving layers keep their flatUmark.One amendment to the design surfaced during verification: the outer-prefix rule alone admits folds that tear the paper — a moving flap still hinged off-axis to a stationary one. Renders of the first drafted examples exposed it (bowtie faces in the FOLD output). The fold now also enforces hinge-closure — every mover↔stayer crease must lie on the fold axis — and errors with a tear message; design doc and spec §4.6 carry the rule now. The all-layers default cannot tear, so existing behavior is untouched.
Spec §4.6 is rewritten around the four-ingredient model, grammar and Landed list bumped to v0.18-dev. All pre-existing goldens byte-identical.
Examples
Each example: the scoped program on the left, the same program with the
up toclause dropped (all-layers status quo) on the right. Crease patterns show which layers got creased; folded views show the resulting stack outline.up tothe anchor — fold only the top flap (fold-top-flap.bel)up to .d(scoped)up to(all-layers)The scoped fold creases only the top layer's paper (material
y=3/4); all-layers also scores the bottom layer (y=1/4, third CP line). Folded: the scoped bottom layer stays put, keeping the full half-height outline; all-layers tucks everything up into a quarter-height strip. The fold axis runs parallel to the--hhinge — an axis crossing the hinge of a partially-moving flap is the new tear error.up toa range — fold the top two of four (fold-top-two.bel)moving .d up to .c(top two)up to(all four)CP: roof (two quadrants creased) vs diamond (all four). Folded: the scoped fold keeps the full quarter outline — the two lower layers still fill the corner under the moved triangles; all-layers folds the corner away entirely.
select_scopewalks the stack over the crease region from the anchor flap (.d, top) through the target (.c, second layer) inclusive. A line-construction fold like@throughhas no implied anchor, somovingis required.Crease all layers,
@foldsome (crease-all-fold-some.bel)up to .d(scoped)up to(all-layers)This was the motivating composition. The two crease patterns are geometrically identical —
--mscored both layers either way, which is the point: the difference is the assignment. Scoped, only the top flap's segment upgrades to a live fold; the bottom layer's segment stays a flatUmark (Ucount 1 vs 0 in the FOLD output). The folded views make it visible: scoped keeps the bottom layer down (full outline), all-layers folds both up (strip).Precrease →
@fold(fold-along.bel)@fold --dReplaces the axiom re-statement idiom (
precrease-fold.belrestates@map .b onto .a):@foldreferences the material crease, theUupgrades toV(#27), and any new segments cut by the fold would join--d's bundle (ADR 0014). Byte-equal faces/assignments to the re-statement version, minus the duplicated construction.