mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-18 14:32:36 +00:00
8f3f8356366404a7214ec108508ee95b268a5474
5
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
8f3f835636 |
Constrain while you sketch, and stop losing work to Esc and to invisible points
Five defects from ten minutes of real use, and the mode split behind the worst of them. One commit because the changes overlap in the same functions; the pieces are separable in the diff, not in the file. CONSTRAINING NO LONGER NEEDS A COMMITTED SKETCH. A constraint could only be applied by committing the sketch, selecting it in the feature tree, pressing the padlock, and only then picking. While drawing, the CONSTRAIN toolbar was not even on screen (set_ui_mode showed it in UiMode::Constrain alone) and apply_constraint answered "Press Constrain on a sketch first" -- in a status line nobody looks at. Draw two lines, press Parallel, get nothing: that is what a user reported as "the UX is a mess", and they were right. apply_constraint now takes the live session first, reading the picks from the selection model the sketch tool already had (click, ctrl-click to extend, double-click for the loop) and applying through try_add_constraints, which already did append -> solve -> keep-or-rollback. The committed Constrain path stays for editing an old sketch; it is no longer the only way in. The twenty constraint buttons now show in Sketch mode as well. The discriminator is is_sketching() && !is_constraining() && !is_constraining_entities(). Both begin_constrain and begin_constrain_entities set m_active, so is_sketching() alone is true DURING a constrain session and the new path would hijack the old one -- compiling perfectly and failing in behaviour. ONE PLANNER, NOT TWO. A second caller meant duplicating the logic that decides whether a constraint is legal, which roles it binds and whether it needs a typed value. That duplication is how today's Coincident bug survived: fixed in one branch, alive in the next one down. plan_entity_constraint() now lives in the kernel -- pure, no wx, no translation -- and both UI paths call it. DesignPanel loses 304 lines and gains 155. Being in the kernel makes it TESTABLE. The Parallel defect existed because a constraint type met an entity type nobody had tried, and the only instrument was a 13-minute GUI ladder. 19 new kernel cases cover the matrix: 264 -> 283 cases, 7648 -> 7867 assertions. Parallel, Perpendicular and EqualLength gain the two-line guard they never had. On non-lines they used to emit a def the solver silently dropped -- the sketch reported itself constrained when it was not, the same class as Horizontal on a Point. EqualLength on two rounds still promotes to EqualRadius first. Symmetric is planned completely, including its axis pick: the plan carries a VECTOR of defs because Symmetric on two lines is two constraints (P0/P0 and P1/P1). A single def would have half-applied it -- one end pinned, one free, looking correct until something moves. A PLACED POINT SURVIVES THE COMMIT. Type::Point was created correctly and never drawn once committed: both renderers skip it, correctly, since entity_polyline gives a point nothing. What was missing is the vertex-marker path the live session already used. rung_point passed throughout because it asserts the document, and the point was always in the document -- the pixels lied. ESC STOPS EATING AN UNSAVED SKETCH. The third press reached cancel_sketch(), clearing m_entities with no warning and nothing to undo. live_sketch_has_work() existed and was never consulted. The exit layer refuses once when there is work and lets a second consecutive Esc through; the refusal re-arms on a button press, never on mouse motion, or Esc could never exit while the hand moves. TWO NEW RUNGS. D10 drives Parallel through the committed path -- it passes on the PRE-fix binary, which is how we know the user's failure was the mode and not the constraint. D11 is the acceptance for the collapse: draw, pick both, press Parallel, no commit and no padlock. Ladder 126 -> 135 properties, all holding. CON_BTN_SKETCH is measured, not derived: in Sketch mode the group renders after the sketch toolbar, so the first button is at 677, not 449. Pitch 42, twenty buttons, read off a screenshot. Deriving it by offset is how that table drifted the last time. Known limit, commented at the call site: a constraint added to a LIVE sketch is not on the document undo stack, so Ctrl+Z will not take it back until the sketch is committed. snaporca-itp4, snaporca-oyhx, snaporca-l2vm |
||
|
|
942f6c28c7 |
Port: mirror emits a half that continues the chain
Carries snaporca 0231bd5b68. Parity holds: 17 files identical, 8 diverging as expected. A reflection reverses orientation, so mirror_entities now hands the reflected half back reversed in ORDER and flipped per ENTITY — an arc swapping its angles as well as its ends, a spline reversing its control points. Appending it to the source then yields one walkable chain instead of two halves meeting head-to-head, and a mirrored CCW loop stays CCW. This is the producer half of the confusion that cost three defects; the consumers (offset, and the exact loop area) keep their defensive handling, because that is what makes them correct for hand-built and imported sketches rather than only for geometry this function produced. Contract change, carried with the reason: a mirrored line's p0 is the reflection of the SOURCE's p1, and a mirrored CCW arc keeps a POSITIVE sweep — the reflection negates it, walking it the other way negates it again. Both [SketchEdit] cases updated, and a new [SketchProfile] case "a mirrored half continues the original chain" pins the property directly. Kernel here: all tests passed, 2687 assertions in 232 test cases. GUI target builds and links. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
cbbd24dcb4 |
Port the exact loop area, the offset traversal fix, and the 2D sketch ladder
Carries snaporca 572f794c84, d0f9a0052a, 9f7e4e3627 and 3974f8a170. Parity holds: 17 files identical, 8 diverging by their expected counts. EXACT AREA. A loop's area is now integrated entity by entity in traversal order — Green's theorem — instead of being shoelaced over the render polyline, which faceted every arc into 24 chords and lost 2.02 mm2 on a 3706.86 mm2 stadium. 0.054%, invisible on screen, and wrong in a number reported as "the area". OFFSET FOLLOWS THE TRAVERSAL. Offsetting a mirrored profile put one half on the wrong side and split the loop in two, because the chainer only followed p1->p0 links and each entity's offset side was taken from its stored direction. Chains are now orientation-aware, seeded at a free end, offset by `reversed ? -d : d`, and normalised head-to-tail on the way out — so offset is correct for any input ordering and its own output cannot reintroduce the problem. Both are the same underlying lesson, which has now cost three separate defects: an entity's STORED direction is not its direction of TRAVEL around the loop. THE LADDER. scripts/sketch-ladder.py is a graded suite of 2D sketches judged the way a person judges them — VERTEX, LENGTH, ARC, TANGENT, SYMMETRY, CLOSED — with area only as a cross-check, because area is derived and nobody can confirm it by eye. Eight rungs from a rectangle up to MPD5 from the StudyCadCam corpus, a dia 27 x 95 pin reproduced as its revolve half-profile with the R5 fillet tangency solved exactly. Entirely 2D: no extrude or any solid feature. Kernel here: all tests passed, 2681 assertions in 231 test cases, including the new "profile: a mirrored half offsets as one loop, not two". GUI target builds and links. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
5d7fc8c545 |
Port the sketch layer work from snaporca: offset chains, right-click, MCP verbs
Carries snaporca 971320e129, 6b049f0dc6, 4aae782029, 444d59f212, 74cf3d7e54 and the build guards from 597557a6e4. Parity re-verified after every hunk: 17 files identical, 8 diverging by their expected counts — DesignPanel.cpp still 32, DesignCanvas.cpp still 16, which is the proof each hunk landed on the right side rather than being copied over a real divergence. OFFSET OFFSETS THE CHAIN. Per-entity offsetting returned a closed rectangle as four parallel segments that no longer touch, so entities_to_wires gave four OPEN wires and nothing could be extruded. offset_entities now chains by shared endpoints and repairs each seam by mitering the neighbours to their intersection. Second bug, invisible to any single-entity test: +d meant "left of travel" for a line but "radius + d" for an arc regardless of sweep, so a slot outline offset with its straights going one way and its caps the other. The convention is now written on the declaration and pinned by a test. tests/libslic3r/test_sketchprofile.cpp is new and asserts the LOOP rather than coordinates — the property that decides whether a profile can be built, and the one the existing single-entity [SketchEdit] cases cannot see. Its include is catch2/catch_all.hpp here: this fork ships Catch2 v3 while snaporca is on v2, which is why the test files are a tolerated divergence. RIGHT-CLICK PICKS WHAT YOU POINTED AT, so a line's own verbs are offered instead of the empty-selection vocabulary; sk_delete stops sharing btn:delete with the feature tree; and an element's defining number (length / radius / diameter / angle / distance) can be typed, from the menu or from V. TWELVE MCP SKETCH VERBS. The socket had ~40 verbs and none touched a sketch, so the 2D layer could only be exercised by driving a GUI with synthetic clicks. sketch_describe reports each closed loop, the loops it encloses as voids, exact areas, and where a chain is still open; sketch_validate/sketch_heal are FreeCAD's ValidateSketch — find vertices that overlap within a tolerance but carry no coincidence, then weld them AND record the constraint, so a loop closed by floating-point luck becomes one closed by construction. scripts/mcp-sketch-smoke.py is the loop that asserts all of it. Kernel suite on this fork: all tests passed, 2677 assertions in 230 test cases. The GUI target links against the rebuilt deps image (the wxInspector blockage is gone) and the binary carries the new verbs. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
2b02a8e3dd |
Design tab: move the CAD sources into their own folder
Review request on PR #15238: "Place CAD-related files (e.g. CadDocument/ GeometryEngine) into a separate folder." src/libslic3r/CAD/ the kernel — CadDocument, GeometryEngine, the four Sketch* units, SketchSolver, ThreadStandards src/slic3r/GUI/CAD/ the tab — DesignPanel, DesignCanvas, DesignSketchTool, SketchInlineEditor, McpControl, generated DesignOffer Pure relocation: no line of logic changes. Two include rewrites follow from it — files that moved re-spell their own neighbours against src/ (already on the include path), and files that did not move pick up the new folder. docs and docs/ux/mockups/gen_offer_table.py follow the same paths. Verified: libslic3r, libslic3r_gui and libslic3r_tests all build, CAD suite green at 2518 assertions in 194 test cases, and the sibling fork builds identically — 17 shared sources still byte-identical, 8 diverging by their expected counts. |