Commit Graph
31106 Commits
Author SHA1 Message Date
Tommaso BianchiandClaude Opus 5 ab15f386e4 CAD: type a sketch dimension without clicking the field first
On a Wayland session the in-canvas value field never took the keyboard focus, so
after drawing a rectangle the first keystrokes went nowhere and the field had to
be clicked before a number could be typed. open() already did Show, Raise,
SetFocus on both frame and control, SelectAll, and re-asserted all of it in a
CallAfter — none of it works here, and no amount of re-asserting would: under
Wayland a client cannot focus itself, and mutter ignores gtk_window_present()
without an activation token as focus-stealing prevention. The earlier fix
recorded in this file (dropping wxFRAME_FLOAT_ON_PARENT, whose GTK _UTILITY_
hint made an xrdp session refuse focus) addressed a different compositor.

Stop needing WM focus. The canvas keeps the focus and feeds the field:
SketchInlineEditor::feed_key() types into the control directly — Enter commits,
Esc cancels, Backspace/Delete edit, digits and '-' '.' ',' are accepted, and
anything else is handed back so a stray letter cannot vanish into a numeric
field. A m_fresh flag reproduces the SelectAll semantics the field already had,
so the first digit replaces the prefill. It returns false when the control
genuinely holds the focus, so X11 keeps wx's normal routing and no character is
typed twice.

The CHAR_HOOK gates on the editor's own is_open(), NOT on inline_busy().
inline_busy is a freeze flag for the sketch tool: cleared on commit, re-set only
when the next queued field opens, with a CallAfter between them. Gating on it
left a window where the field was on screen and the flag was false — typing
worked for a rectangle's Width and not its Height.

VERIFIED at the machine on behemoth: typing the first dimension directly, with
no click, works. NOT yet confirmed: the Width -> Height handover; the is_open()
gate is diagnosed from the handover code, not observed. The hook's
SNAPORCA_KEYTRACE=1 switch logs each key with the focused widget if it needs
chasing further.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-14 17:53:41 +02:00
Tommaso BianchiandClaude Opus 5 614824ce89 CAD: right-click in a sketch offers verbs for what is selected, instead of for nothing
Select a line in a sketch, right-click, and every sketch verb was greyed: Trim,
Extend, Fillet, Chamfer, Offset, Mirror, the arrays, Constrain. The menu was
right and the selection was gone — two independent faults, each of which hid
the other.

FIRST, the Select-mode RightDown branch called clear_selection() before handing
the click back. Handing it back is correct: the m_right_consumed flag means "the
tool USED this right-click", and a plain right-click is not a gesture
terminator, so the offer should open. Clearing first is not: the offer describes
WHAT IS SELECTED, so wiping the selection guaranteed it could only ever describe
nothing. Deselection keeps its own gesture — left-click on empty space, a few
lines above in the same handler.

SECOND, offer_selection_kind() returned SkNone for every sketch state. The offer
table has always carried verbs for a selected line, arc, point or pair, but
nothing ever RETURNED those kinds, so fourteen rows were gated on selection bits
no code path could set. Classify the selection instead: SkLine / SkArc / SkPoint
/ Sk2Ent, via a first_selected_type() accessor on the tool and two forwarders on
the canvas.

Either fix alone measures as a failure — the classification is handed an empty
selection, or the preserved selection has no kind to match — which is why both
land together.

This is the second half of the report behind 3eb6e5d608: a user comparing the
Design tab with Onshape said "adding constraints seems to be missing"
(OrcaSlicer PR #15238). Constrain was one of the fourteen dead rows, and the
gesture that would have shown it threw the selection away first.

Verified at the machine on behemoth by Tommaso: select a line of a rectangle,
right-click, and the sketch verbs are live.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-14 17:37:37 +02:00
NoisyfoxandClaude 9c7e6711c6 build: move FFmpeg media player sources to the common GUI list
wxMediaCtrl3 and AVVideoDecoder are platform-neutral C++ compiled on
all three platforms, so list them once in the common SLIC3R_GUI_SOURCES
instead of duplicating them in the APPLE and non-APPLE branches. The
else() branch is now empty and drops out entirely.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-14 23:06:16 +08:00
NoisyfoxandClaude adcbdddc12 refactor: remove dead GStreamer bambusrc plugin and its build dep
gstbambusrc was the GStreamer source element for the old wxMediaCtrl2
Wayland player, its only consumer (deleted in the previous commit).
The new FFmpeg player handles bambu:/// URIs through the Bambu C API
instead. Drop the plugin and the gstreamer-1.0 / gstreamer-base-1.0
REQUIRED pkg-config dependencies that existed solely for it.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-14 22:48:33 +08:00
NoisyfoxandClaude 7e3724b5f3 refactor: remove dead wxMediaCtrl2 player
wxMediaCtrl2 was never instantiated on any platform (USE_WX_MEDIA_CTRL_2
is 0 everywhere); wxMediaCtrl3 replaced it. Delete wxMediaCtrl2.cpp/h,
drop them from the Win/Linux source list and the gettext list.txt, and
collapse the preprocessor-dead #if USE_WX_MEDIA_CTRL_2 gate in
MediaPlayCtrl.h.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-14 22:30:14 +08:00
NoisyfoxandClaude dd910dcb85 build: drop redundant --enable-shared in FFmpeg deps configure
The literal --enable-shared was always overridden by ${_link_cmd}
(--enable-static --disable-shared on Apple, --enable-shared elsewhere)
and FFmpeg configure processes these flags in order, last one wins.
Remove it and the stale comment documenting the workaround.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-14 22:10:29 +08:00
Noisyfox bf40951a4f fix: add static FFmpeg NOTFOUND guard; drop dead wxMediaCtrl2.h include 2026-08-14 21:52:31 +08:00
NoisyfoxandClaude 97955dbab8 refactor: remove old BambuPlayer-based media player from macOS
Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-14 21:15:20 +08:00
NoisyfoxandClaude 4531dc2af1 build: build static-only FFmpeg for macOS deps
Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-14 21:10:26 +08:00
Noisyfox 2c8f56dd84 feat: use FFmpeg media player on macOS with static FFmpeg 2026-08-14 21:01:43 +08:00
NoisyfoxandClaude ec31750330 Add implementation plan for macOS FFmpeg player
Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-14 20:11:09 +08:00
Tommaso BianchiandClaude Opus 5 eb52972a8e CAD: the offer menu speaks one language, not two
On a non-English desktop the offer menu came out mixed: "Create / Add material /
Rimuovi / Fillet / chamfer / draft / Repeat / Transform / Reference / Modify",
and under Modify, "Elimina" beside "Constrain sketch".

Nothing was mistranslated. The row names went through a bare wxGetTranslation(),
which searches EVERY loaded catalogue — including wxWidgets' own wxstd. That
catalogue is loaded in the desktop's language whether or not the application has
one, and it happens to contain exactly two of our eight row names:

    wxstd it: 'Remove' -> 'Rimuovi', 'Delete' -> 'Elimina'

Create, Add material, Repeat, Transform, Reference and Modify are not wx
vocabulary, so they stayed English. Two words in one language, six in another,
in the same menu — and the same trap is set for every other locale wx ships:
Supprimer, Löschen, Eliminar.

Name the domain: wxGetTranslation(s, SLIC3R_APP_KEY). These strings are now
translated by our own catalogue or not at all, which is consistent either way.

Left deliberately alone: the accelerator still renders as "Canc" rather than
"Del" on an Italian system. That is wx naming the physical key, and on an
Italian keyboard the key really is marked Canc — telling that user to press
"Del" would name a key they do not have.

Verified on the rig with LANG=it_IT: the menu now reads Remove and Delete, and
the submenu shows "Delete    Canc" beside "Constrain sketch".

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-14 14:10:48 +02:00
NoisyfoxandClaude 111364d880 Add design doc for macOS FFmpeg player
Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-14 20:08:55 +08:00
Tommaso BianchiandClaude Opus 5 3eb6e5d608 CAD: constraints are reachable from the offer menu, not only from a toolbar icon
A user evaluating the Design tab against Onshape reported that "adding
constraints seems to be missing" — with nineteen constraint types and a solver
shipped behind it (OrcaSlicer PR #15238, exussum12).

They were not wrong about what they could see. The only ways in were an
icon-only toolbar button whose tooltip you have to hover to read, and an offer
row gated on sketch_mode with a sketch ENTITY selected, filed under "Reference".
Right after finishing a sketch — the moment you want to constrain it — neither
was in front of the user, so a shipped headline feature read as absent.

Add a model-mode row: "Constrain sketch", offered under Modify when a sketch
region is selected, routed through the new btn:constrain verb action.

on_begin_constrain() also gains a fallback to m_sel_sketch_feat. The offer
reaches it from a SkLoop selection, which carries no TREE selection, and the
function read only tree_selection() — so the new row would have answered
"Select a sketch in the tree first" about a sketch the user had visibly
selected. It now adopts the region's owning sketch and syncs the tree to match.

Verified on the rig: draw a rectangle, finish the sketch, click the region,
right-click -> Modify -> "Constrain sketch" enters Constrain mode with
"Pick 1-2 lines, then a constraint" and the Constraints (8) card listing the
sketch's inferred constraints. That path did not exist before.

Does NOT address the other half of the report: there is still no Pierce
constraint, so a sweep profile cannot be tied to its path. Tracked separately.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-14 14:00:30 +02:00
Tommaso BianchiandClaude Opus 5 9013f530fa CAD: a sheet body reports no volume, instead of a confident wrong one
mass_properties on an open shell returned volume 96000 with an inertia diagonal
of [-4.2e7, -4.2e7, -6.9e7] for a 60x60x40 four-walled box — negative principal
moments, which no real body can have. BRepGProp::VolumeProperties integrates the
divergence theorem over whatever faces exist; on an open shell that is not a
volume at all, and the old code hid the only obvious tell by taking std::abs()
of the mass. "valid: true" then asserted the number was trustworthy.

This matters because mass_properties is what an agent or a user reaches for to
confirm a cut removed the right material. Silent nonsense there means the check
passes on garbage.

MassProps gains is_solid. For a sheet we compute surface area only — that stays
exact — and report volume 0 with the inertia left zeroed. The MCP verb returns
is_solid plus a note saying volume and inertia are not defined for an open
shell; the GUI's Mass command says "sheet body — N cm² of surface, no volume"
rather than quoting material that is not there.

Verified on the rig: the sheet now returns volume 0.0, surface_area 9600.0
(exactly 4 x 60 x 40), is_solid false. The solid controls are unchanged and
exact — a 60 mm cube reports 216000.0 and 21600.0.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-14 13:35:03 +02:00
Tommaso BianchiandClaude Opus 5 1545fb7946 CAD: an armed Plane or Axis pick captures the face, instead of escalating to the body
Clicking a face that already happened to be selected, while a Plane or Axis pick
was armed, read as a repeat pick: the click escalated to "whole body", the
capture was lost, and the card's label stayed "(none)" with nothing on screen to
explain it. On a cube it is easy to hit — the face under the cursor is often the
one already selected from the previous step.

The capture path in on_solid_picked already restores the flag for all three
tools, and reset_plane_refs()/reset_axis_refs() restore it when a pick is
abandoned — both were written as if the arm side disabled escalation. Only
CoordSys actually did (that was snaporca-u0wd). Plane and Axis never had it.

Verified on the rig: Midplane on a 60 mm cube now captures Face A (#5, top) and
Face B (#3, side) on the FIRST click each, and the resulting plane renders as
the 45-degree bisector between them, which is what a midplane of two
perpendicular faces should be. Before this, the first pick escalated to the body
and Face A stayed "(none)".

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-14 12:45:25 +02:00
Tommaso BianchiandClaude Opus 5 f6f2edb906 CAD: the Plane card refuses a method it cannot build, instead of quietly building another one
Every method in CadDocument's plane dispatch falls back to offset_angle_plane()
when its references are missing. Picking Tangent and confirming with nothing
selected therefore produced an OFFSET plane, announced as "Plane added — pick it
as a sketch plane". The user asked for one construction and silently received a
different one, with nothing on screen to reveal the substitution.

Validate at the GUI boundary instead: Angle needs an edge, Midplane two faces
(and not the same face twice — that yields a plane coincident with the face,
which is well-defined and useless), Tangent a face, Two-edges two edges. Offset
and Coincident are unchanged: both are meaningful with no reference, since they
fall back to the base plane by design.

on_add_plane() now returns false when it refuses, and confirm_tool() skips
close_tool() in that case — a refusal that also threw away the picks the user
had already made would be worse than the bug.

The kernel keeps fallback_offset(): it must return something. It should just
never be reachable from a user gesture without a warning.

Verified on the Xvfb rig: Tangent with no pick refuses and creates no feature
(it created one before), the card stays open with the type preserved, Midplane
with no faces refuses with its own message, and Offset with no picks still
creates a plane as it always did.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-14 12:18:13 +02:00
Lam Wei Lun 92123cdc2c Add filament color next to tab button in filament setting 2026-08-14 16:50:33 +08:00
Tommaso Bianchi 9a5e9dfc36 CAD: the wheel scrolls the card panel, it does not edit the field under it
wxSpinCtrlDouble takes the mouse wheel whenever the pointer is over it. A card
taller than the panel therefore could not be scrolled past without silently
incrementing whatever field the cursor happened to be over — measured on the
rig: eight notches over the Coord Sys card turned an X hint from 1,00 into 6,00
while the panel did not move at all. The same gesture over an Extrude distance,
a Hole diameter or a mate Offset is a silent model change made by someone who
believed they were navigating, and nothing on screen reports it.

Every spin in this panel comes from one factory, so the guard goes there: an
unfocused spin hands the wheel to its parent, and the scrolled cards panel gets
it. A spin the user has deliberately focused still takes the wheel, which is the
one case where editing is what was meant.

Verified on the rig with an Extrude card: eight notches over an unfocused
Distance leave it at 10,00; clicking into it first and scrolling takes it to
13,00.
2026-08-14 10:33:28 +02:00
Lam Wei Lun 76ec2f10c6 Switch to a Tab layout for the Publish dialog 2026-08-14 16:19:46 +08:00
Tommaso Bianchi 03fb81020e CAD: picking a face for a Coord Sys must also make it a face-based frame
A mate between two connectors committed cleanly, recomputed without error, and
moved nothing. apply_mate was reached and computed a translation of exactly
(0, 0, 0).

The connectors were the cause, not the mate. Picking a face stores
coordsys_face and coordsys_body but left the Type combo on its default,
Point (world) — and datum_frame ignores the pick entirely for that type,
resolving the connector to coordsys_point, which is (0,0,0) unless the user
typed otherwise. Two connectors built that way share one frame, so the mate
between them is an identity transform: everything reports success and the
assembly never moves.

Capturing a face or an edge now switches the type to FaceAndDirection. Picking
a face IS the choice of a face-based frame; asking for it twice, with no hint
that the second half is required, is what made every mate a silent no-op.

Verified on the rig, two bodies with a face-based connector each:
  before  Extrude4 [-71.6, 402.6, 156.5] .. [-8.8, 412.6, 237.3]
  after   Extrude4 [-31.4, -40.4, -10.0] .. [ 31.4,  40.4,  -0.0]
with the mate transform now (40.19, -196.88, 402.56) instead of (0, 0, 0).
That is the first mate in this tree that assembles anything.

Not the kernel: recompute applies mates exactly as preview does, proven by an
A/B harness over all five kinds — the two paths give identical bounding boxes.
2026-08-14 10:01:28 +02:00
Ian Chua 58b17f08e0 Merge branch 'main' into feat/plugin-storage-api 2026-08-14 15:19:26 +08:00
Tommaso Bianchi c45f84edf4 CAD: three Design-tab fixes — consumed holed loop, constraint rows, hover ghost
1. A consumed loop WITH HOLES was never dropped from the sketch overlay.
   sync_sketch_display compares each region's entity list against what a per-loop
   extrude stored, but rebuilt the candidate from the region's OWN entities while
   the extrude stores the region's entities PLUS every hole's (see
   selected_loop_entities). For a plate with one bore that is 4 against 5, so the
   match never fired and the extruded rectangle stayed drawn on top of the solid
   it had become. Adds region_entity_indices_with_holes, which returns the same
   order the extrude uses, and compares against that; a matching region now drops
   its holes' entities too. Hole-less regions are unaffected.

   This is also the artefact that made a correct plate-with-a-bore read as a
   plate with a plug in it during rig testing.

2. The Constraints card drew its header and its first row on top of each other.
   The rows and the delete buttons were parented to m_form rather than m_cards,
   so they were laid out in the wrong window's coordinate space and started at
   the card's top edge. Re-parented; nothing else about the card changed.

3. The mate hover ghost never appeared. The highlight handler asked for a repaint
   with request_repaint(), which only queues a Refresh — and a wxMenu popup runs
   its own modal loop, so the paint was not serviced until the menu closed, by
   which time the ghost had been dropped. Adds DesignCanvas::repaint_now(), which
   flushes the paint immediately, mirroring the m_status->Update() the status line
   in the same function already needed for the same reason.

Delegated to opencode (DeepSeek V4 Pro) and reviewed by diff. Fix 1 needed an
accessor on DesignSketchTool because region_loops/RegionLoop are private — that
was outside the file list it was given, and it said so rather than working around
it.

Verified on the rig: a rectangle-plus-circle sketch extrudes to a plate with a
bore and NO overlay left on top of it, and the Constraints card shows its header
clear of eight readable rows.
2026-08-14 09:15:51 +02:00
Ian Chua 9d37ee4709 removed changes that are out of scope 2026-08-14 15:12:18 +08:00
Ian Chua 991c36d649 Merge branch 'feat/plugin-auditing' of https://github.com/OrcaSlicer/OrcaSlicer into feat/plugin-auditing 2026-08-14 14:49:54 +08:00
Ian Chua f6f68573b6 fix: add resources folder to the allowed roots as readonly 2026-08-14 14:48:57 +08:00
Tommaso Bianchi 9340d4c7dc CAD: the DoF readout comes back in Constrain mode
Leaving Sketch clears the "N degrees of freedom" line, which is right — it
describes a sketch's constraint state and means nothing in Feature mode. But
entering CONSTRAIN left it blank too, and Constrain is where the number is the
whole point: the readout is fed only by a live solve, and no solve fires merely
because the mode changed, so the line stayed empty until the user happened to
change something.

The solve callback now caches its last result and the labelling is split into
apply_dof_status(), which set_ui_mode re-applies on entry to Constrain.

Verified on the rig: a rectangle reports "4 degrees of freedom" in Sketch, and
the same line is there after K enters Constrain.
2026-08-14 08:36:19 +02:00
Tommaso Bianchi 1631963ba1 CAD: pick tolerances scale with the face, so a narrow face is reachable
The edge and vertex tolerances were fixed at 8 and 11 px. On a face that is
barely wider than that on screen — a thin plate, or any part once you zoom out —
every point on it lies within the edge budget, so the pick alternated edge and
whole body and the FACE level could never be reached at all. That is not just
awkward: a face pick is what gives a Coord Sys its owning body, and a mate needs
one, so thin parts could not be assembled.

Both tolerances are now capped at a third of the face's shorter on-screen side,
measured from the edge samples the picker already walks. They only ever shrink,
so a face with room keeps the full budget and nothing changes for ordinary
geometry; a narrow one keeps its middle for itself.

Verified on the rig on a 16.7 mm-wide plate at three zoom levels including one
far enough out to make the face a thin sliver: the middle reports "face 5
selected" every time, while points near the rim still take the edge.
2026-08-14 08:32:19 +02:00
Tommaso Bianchi 76d7dd6946 CAD: an armed face/edge pick must not lose its click to the body escalation
A card that asks for a face ("Click a solid FACE in the viewport") could not be
satisfied. Clicking the same sub-element twice deliberately escalates to the
whole body — right for free picking, wrong here: the user clicks the very face
the card is pointing at, the escalation turns it into a whole-body pick, and the
armed capture rejects it and leaves "(none)". Both orders failed, so a
face-based Coord Sys was reachable only by accident of ordering. That mattered
beyond the card: a mate needs a connector with an owning body, and a face or
edge pick is the only thing that sets one.

Adds DesignSketchTool::set_escalate_on_repick, off while the Plane, Axis or
CoordSys card has a pick armed and back on as soon as it is captured or
abandoned. While armed, clicking a face means "this face", which is what the
prompt already says.

Verified on the rig: arm Pick Face, click the face, and it reads "#5" on the
first click. With nothing armed the escalation still alternates whole <-> face
as before.
2026-08-14 08:26:24 +02:00
Lam Wei Lun 99db5cca38 Renamed to Publish instead of Publish Settings 2026-08-14 14:00:20 +08:00
Tommaso Bianchi d8103f794b CAD: a mate needs B to have a body, so stop offering one when it does not
The mate palette called all five kinds viable on connectors created as
Point(world), which belong to no body. Clicking one built the Mate feature and
the RECOMPUTE then failed with "mate: mate_cs_b has no associated body" — the
refusal arrived one step too late, after the feature was already in the tree,
and the user is told about it by an error line rather than by the palette that
offered the thing.

mate_options now checks the same two conditions the apply path throws on: B must
have a body (B is the connector whose body moves; A is the fixed reference and
needs none), and that body must still resolve. Either way all five kinds go
non-viable with a reason, so the offer and the kernel cannot disagree.

Verified on the rig: with two Point(world) connectors, every row is now dimmed
and reads "connector B is not attached to a body — a mate moves B's body". That
also exercises the dimmed-with-a-reason presentation for the first time, which
until now had nothing to show because every kind was always viable.

Tests: a new [mate] case covering no body, a body that no longer resolves, and
the revival once B is given one. One existing case needed its setup widened
rather than its assertion weakened: "an unrecorded fingerprint does not make a
type non-viable" built two body-less connectors, so it was asserting a side
effect of the old permissiveness instead of the property it is named for. Its
connectors now have a body, leaving the missing fingerprint as the only variable.
Full [CadDocument] suite: 2458 assertions in 185 cases.
2026-08-14 07:45:32 +02:00
Lam Wei Lun d124e1ccbc Update unit test 2026-08-14 13:41:38 +08:00
Tommaso Bianchi 08ef43fad8 CAD: the mate palette fired nothing — two menu handlers were shadowing it
Right-clicking a document with two coordinate systems builds the mate palette
exactly as designed: a separator, a disabled "Mate: A -> B" header, then five
rows in fixed order. Hovering a row showed no ghost and left the previous status
message on screen; clicking one created nothing at all. The palette enumerated
perfectly and fired nothing, which put the whole M8 mate epic out of reach from
the UI.

The mate handlers were never invoked. show_offer_menu binds two pairs of
handlers to the SAME wxMenu: the mate pair (by mate_base, at base + 500) and the
generic verb pair. wxWidgets pushes dynamic entries to the FRONT of the handler
list, so the pair bound LAST runs FIRST for every id — and the generic pair was
last. A mate id lands outside the verb table's range, so both generic lambdas
returned early WITHOUT e.Skip(), which wx reads as "handled", and the mate
handlers behind them never saw the event.

Binds the two generic handlers to the verb id range [base, base + 499] so each
half only sees its own ids regardless of bind order.

Verified on the rig with a purpose-built assembly (two bodies 60 mm apart, a
Coord Sys on each): before, clicking Fastened produced no feature and no status
change; after, it produces a Mate feature. The verb rows keep working — the same
run created both coordinate systems through Reference > Coord Sys.

Note the mate then fails its recompute with "mate: mate_cs_b has no associated
body", because a Point(world) coordinate system belongs to no body while the
palette still advertises all five kinds as viable. That is a separate defect and
is filed; this commit is about the palette being reachable at all.
2026-08-14 07:34:33 +02:00
NoisyfoxandClaude 73131735a2 Fix Linux unit tests loading deps-built FFmpeg libraries
The test executables that link libslic3r_gui (which links PkgConfig::LIBAV)
have a load-time dependency on the deps-built FFmpeg shared libraries. The CI
unit-test runner only receives the tests artifact, so those libraries were
unresolvable there (Ubuntu 24.04 ships libavcodec.so.60, not .61). Copy the
libraries next to each affected test executable and give it an $ORIGIN rpath,
mirroring the Windows branch that copies DLLs next to every test executable.
orcaslicer_copy_sos now places the copies in the per-config output directory
for multi-config generators, like orcaslicer_copy_dlls does.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-14 13:25:29 +08:00
Lam Wei Lun 96f5a23387 Only serialize selected published settings. Minor cleanup 2026-08-14 12:53:44 +08:00
Ian Chua 28d0d218ff Merge branch 'main' into feat/plugin-auditing 2026-08-14 12:33:35 +08:00
Ian Chua d99f4c8164 Merge branch 'main' into feat/plugin-auditing 2026-08-14 12:33:08 +08:00
Ian Chua 7580d8ef8c Merge branch 'main' into feat/plugin-pages 2026-08-14 12:20:34 +08:00
Noisyfox e9ca9d41d1 Attempt to fix Linux unit test 2026-08-14 10:58:43 +08:00
Lam Wei Lun b488067f82 Merge from main 2026-08-14 10:50:24 +08:00
Lam Wei Lun b280ab555c Initial Commit for Publish Settings workflow 2026-08-14 10:49:49 +08:00
d5dbd96dd6 Skip filament_colour_type in G-code config block to fix Anycubic Kobra 3 parse crash (#13507)
Co-authored-by: manzari <mail@manzari.dev>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Rodrigo Faselli <162915171+RF47@users.noreply.github.com>
2026-08-13 21:52:52 -03:00
Tommaso Bianchi 7b953d564d CAD: a project whose model is a recipe is not an empty file
Reopening a saved CAD design ended on a modal "The file does not contain any
geometry data." warning. A CAD project legitimately carries no mesh — the model
lives in the feature tree (Metadata/SnapOrca_cad.bin) until Commit to Plate — so
the warning is false for one, and it is the last thing the user sees after
opening a design they spent an hour on. It reads as "your work is gone" at the
exact moment the recipe HAS just loaded and the Design tab is about to rehydrate
it, and the main window sits disabled behind the dialog until it is dismissed.

Counts a non-empty model.cad_recipe as geometry.

Verified on the rig: save without Commit to Plate, reopen, and the Design tab
comes up with Sketch1 -> Extrude2 -> Body 1 editable, with no dialog at all.
2026-08-14 00:15:46 +02:00
TheLegendTubaGuy 0225cadff0 Fix PLA/PETG warning wiki link (#15172) 2026-08-13 18:57:08 -03:00
Tommaso Bianchi 5889f6640f CAD: extrude a sketch region with its holes, and stop crashing at startup
A rectangle with a circle inside it, drawn in ONE sketch, could not be extruded
to a plate with a bore from the GUI. Five defects were in the way. Each was
found by driving the app on a headless rig and measuring the result — the code
reads correctly at every one of these points, which is why they survived.

1. Wire orientation (kernel). SketchEngine::wires_to_face added every hole as
   wires[i].Reversed(), which is only right when the sketch happens to wind both
   loops the same way. A circle drawn clockwise inside a counter-clockwise
   rectangle came out matching the outer boundary, OCCT swept it as a SECOND
   contour, and the prism was the plate with its bore filled and the disc's
   volume counted twice. Measured: bbox 67.17 x 219.67 x 10 with volume
   152088 mm3 against a solid box of 147542 — a body larger than its own
   bounding box, which is the signature. Holes are now added as-is and
   ShapeFix_Face::FixOrientation() classifies them; that is winding-independent
   and is the idiom make_extrude_regions already used for imported glyphs, which
   is why holed TEXT always extruded correctly while a holed SKETCH never did.
   After the fix: 142996 mm3, implied bore radius 12.03 mm against the circle
   drawn.

2. The live-sketch click threw the picked region away. region_at() served only
   as a yes/no gate and on_face_selected() carried no argument, so Extrude fell
   back to whichever loop the resolver found first — clicking the material of a
   plate-with-a-hole extruded the disc. The region is now carried through, and
   DesignPanel also hands it to the tool with set_loop_pick(), AFTER open_tool()
   because that re-derives selection state, since extrude_uses_loop() reads
   selected_loop_entities() and that lives on the tool.

3. region_at() had no hole awareness and no innermost preference: it returned
   the first polygon containing the point. It now skips a region when the point
   lies inside one of that region's holes, and picks the smallest containing
   loop, so a click in the bore selects the disc and a click on the material
   selects the plate.

4. Startup segfault. DesignCanvas::request_repaint probed the GL backend via
   OpenGLManager::get_gl_info().get_renderer() before the canvas had initialised
   GL — glGetString with no context current and, before init_opengl(), no loaded
   function pointers. Anything that asked for a repaint while the panel was
   still being built landed there, with no window and nothing in the log. It now
   bails at the top on !is_initialized() and asks for a Refresh instead. Note
   the crash was in the PROBE, not in render(), which already guards itself.

5. A holed sketch on a plane whose normal points -Z came out as the full box PLUS
   a disc — 220274 mm3 where 163726 was due (192000 + 28274). wires_to_face took
   a SketchPlane parameter it never used and let OCCT infer a surface from the
   outer wire; when the inferred normal disagreed with the sketch's, the hole
   classification produced no hole. Every face is now built on the sketch's own
   gp_Pln.

Also in this change, from the same rig session:

- A right-click that only clears the sketch selection no longer reports itself
  as consumed, so it stops suppressing the offer menu. With any geometry in a
  live sketch there was no menu route left to add a second entity.
- Escape no longer discards a live sketch that holds drawn geometry; it says so
  and keeps the work (live_sketch_has_work()).
- The holed-region fill is an even-odd scanline instead of a keyhole bridge, so
  no corridor triangle leaks from the bore to the nearest corner.
- Cyan is reserved for the selection: an unselected region no longer wears a
  shade one step off the selected one.
- The origin planes follow the mode, so pressing Sketch on a document that
  already has a body offers them again instead of naming a plane you cannot see.

Tests: three [holes] cases over add_extrude_entities asserting the plate-with-bore
volume, solid and face counts on both a +Z and a -Z sketch plane, and the
by-name refusal of two disjoint regions. Full [CadDocument] suite green.
2026-08-13 23:43:36 +02:00
TheLegendTubaGuy c5aedd1cea Enable Snapmaker U1 bed type selector (#15174) 2026-08-13 18:25:52 -03:00
78eef79ffe Fix flushing-volume warning for single-filament plates (#14704)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Rodrigo Faselli <162915171+RF47@users.noreply.github.com>
2026-08-13 17:50:55 -03:00
Kiss Lorand 56d2c527cb Fix crashes from object-level small perimeter speed overrides (#15232) 2026-08-13 17:28:31 -03:00
Kiss Lorand fd23b74b99 Fix single-value object overrides on multi-nozzle printers (#15221) 2026-08-13 17:09:10 -03:00
Tommaso Bianchi e27a44e6ef Merge remote-tracking branch 'prfork/cad-mainline' into cad-mainline 2026-08-13 17:37:10 +02:00