Commit Graph
30379 Commits
Author SHA1 Message Date
Clifford GarwoodandClaude Opus 5 1aa9bb8d93 fix(imex): make the plate badge count filaments the way validate does
The badge is meant to predict whether slicing will be refused, and it delegates
to the same helper for that reason. It was feeding that helper a different
filament list. get_extruders(true) resolves a mixed slot into its physical
components -- right for AMS mapping, which has to know what is actually loaded
-- while Print::validate counts the slot itself.

So a plate holding one two-component blend reads as two filaments to the badge
and one to validate. The badge sees two, decides the plate is fine, and stays
silent; the slice is then refused. It also runs the other way: a plate the user
sees as a single colour draws a multi-material warning, because the expansion
made it look like two.

Give get_extruders an expand_mixed flag, defaulted so every existing caller
keeps the resolved list, and have the badge ask for the authored one.

The badge was also only mirroring validate's multi-color rule, not its first
one -- a mixed filament is unsupported in a parallel mode outright. Without it
the badge stays quiet on exactly the plate validate refuses first.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-27 10:36:15 -04:00
Clifford GarwoodandClaude Opus 5 2473ca7496 docs(imex): record that the primary-routing refusal is a scope choice
The rule's comment claimed the plate "is not printable as configured: the
primary tool executes the toolpaths while the flow and temperatures were
computed for a filament it cannot load". That is not what the emitter does. It
never uses the declared primary -- it re-derives an effective one from the
filament actually in use -- so a plate whose only filament sits on a Span tool
sharing the primary's gantry produces coherent G-code and would print.

The refusal is still correct, but it rests on intent rather than physics: a
parallel mode exists to run carriages in parallel, and a single-colour plate
riding one span lane is not that. Left as a physical-impossibility claim, the
rule reads as a false positive to anyone who checks it against the emitter --
a review already flagged it as one -- and the obvious "fix" is to relax it.

Say which it is, and keep the genuinely-broken case distinct: a filament routed
to a head outside the mode's active tools still yields a stuck-hot nozzle, and
that one is not a matter of taste.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-27 09:04:50 -04:00
Clifford GarwoodandClaude Opus 5 018091f43b fix(imex): let the mixed-filament refusal outrank the multi-color rule
A mixed filament is unsupported in a parallel mode outright, but the rule saying
so ran third. A plate carrying a blend plus any second filament tripped the
multi-color rule's used > 1 gate first and was told its active tools all sit on
one gantry -- a diagnosis of a multi-color print the user never configured,
whose remedy is to go rework the mode's tool roster. The blend was never
mentioned. Move the check ahead of both rules below it; being unsupported
regardless of routing or topology, it dominates them.

Nothing is masked that leads anywhere else: every branch of
imex_multicolor_block_reason is itself confined to non-primary modes, so the
mixed message's remedy -- switch this plate to Primary -- silences those too.

Say "Mixed filaments", not "Blended". Every other string in the app calls these
mixed, including the button that creates one and the sibling refusal for the
wipe tower filament, so the user had no way to connect the message to the
feature it names.

Three comments in the block were wrong, and two of them were newly wrong. The
routing rule's bounds-check note still said "Blended slots are out of range by
construction, but they never reach here -- the rule above returns first": the
rule above is now the multi-color one, which does not return first for a single
mixed filament, and out-of-range is not guaranteed at all. Mixed slots are kept
at the tail of the filament arrays by convention, not by enforcement --
PresetBundle::set_num_filaments grows filament_is_mixed with resize(), so
raising a printer's extruder count with a blend present lands physical slots
after the mixed one. The scan is position-agnostic and stays correct; only the
stated reason was wrong.

The same discovery makes the empty-routed_list guard live rather than the dead
code it was described as. Print::apply() normalises physical_extruder_map before
validate() runs, so an unauthored map is never the cause -- but a printer with
more filaments than logical extruders leaves the tail slots outside the map, and
raising the extruder count does exactly that.

The new test validates the plate twice. The first pass, with no blend, asserts
the multi-color rule is armed at all; without it the second proves nothing,
because the rule only fires here thanks to a degenerate fixture mode whose two
tools share a gantry. Give that mode a Span tool and the whole test would pass
under either ordering while appearing to guard it. It also pins err.object,
which the mixed path sets and the multi-color path leaves null -- a discriminator
that survives the next wording change. Verified by reverting the order: the test
fails on both the message and the object.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-27 08:48:14 -04:00
Clifford GarwoodandClaude Opus 5 2e883df7d9 fix(imex): name the physical head in M104/M109 tool indices
M104/M109 address a heater, but every caller of the instance
GCodeWriter::set_temperature overload addresses filaments by logical id, so on a
printer whose physical_extruder_map is not the identity the emitted T named the
wrong head -- or, where the logical id exceeds the head count, no head at all.
With a map of 0,0,0,0,1,2,3 a toolchange to filament 5 emitted "M109 S265 T4"
and "M104 S190 T4 ;cooldown" while the head it meant was T1.

Upstream already treats these commands as physical: the preheat it injects in
GCodeProcessor maps through the same map before emitting, and BBS's own wipe
tower does likewise. Emitting logical is the half that never got the memo.

That mismatch also disabled the cooldown suppression beside the preheat, which
compares the line's T against pem[tool_number] and so never matched a logical
one -- 171 cooldowns survived in a two-head print where none should have. Worse,
it could match the wrong line: a cooldown for filament 1 emitted T1, and a
toolchange to filament 5 gives pem[4] == 1, so a legitimate cooldown for head 0
was deleted because the incoming head happened to be numbered 1.

Translate once, in the instance overload every logical-space caller passes
through. The static overload is already physical-in and is left alone.

Gated on is_imex. physical_extruder_map carries two readings in this tree: the
BBS paths index it by extruder id, the IMEX paths by filament id, and the two
coincide only when the filament and nozzle counts match. Mapping unconditionally
would impose the IMEX reading on profiles that mean the other one --
fdm_bbl_3dp_002_common ships a non-identity [1,0], spared today only because
single_extruder_multi_material suppresses the T qualifier entirely.

The wipe tower's interface-temperature pass has to move with it. It strips the
M109 that post_toolchange emits by searching for that filament's tool index, so
it now searches for the mapped one; left alone it would have stopped matching,
and the surviving blocking M109 would have silently defeated the interface
temperature. Its sibling pass reads WipeTower2 output, which emits no T at all,
and is deliberately unchanged.

The bare T<n> toolchange stays logical -- it selects an AFC lane, not a heater.

Test slices two objects across a head boundary, the only case that reaches this
emission: the same-physical short-circuit in set_extruder suppresses the
cooldown entirely for lane swaps within one head. It scans every M104/M109
rather than matching fixed strings, so it catches any unmapped emission and not
just the two sites changed here. With the mapping neutered it reports 101
offending lines; with it in place, none.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-26 22:04:23 -04:00
Clifford GarwoodandClaude Opus 5 f0778ef5fa fix(imex): shorten the off-primary message and block blended filaments
The routing error ran to roughly 450 characters and explained the mechanism
before it got to the remedy. It also offered to "edit the mode in Printer
Settings so its Primary tool is one of %3%", which on a plate whose filaments
resolve to no head at all rendered as "one of no configured extruder". Cut it
to the mode, the tool it prints with, where the plate's filaments actually are,
and the two things the user can do about it.

The second msgid that named candidate modes went with it. It could only suggest
a mode whose primary is among the routed heads, and every mode on the printers
this fires for declares 0:P, so it had nothing to offer.

Blended filaments now return before that check rather than falling through it.
A blend is mixed at the nozzle by its component toolheads, and a parallel mode
is already using those toolheads to print copies or mirrors, so the two cannot
run at once regardless of where the components route -- including when a
component sits on the declared primary. Reaching the routing rule would also
have described them wrongly: mixed slots sit past the end of
physical_extruder_map, so they resolve to no head and read as merely unrouted.

Keeps the empty-list guard the shortening first dropped. validate() reads the
raw physical_extruder_map, whose registered default is a single entry, so a
profile that declares IMEX modes without authoring a map leaves every slot past
the first outside it -- and the sentence ended in a dangling "on .".

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-26 22:04:02 -04:00
Clifford GarwoodandClaude Opus 5 b24733cea8 Merge the color mixing subsystem into the IMEX work
Brings the upstream color-mixing feature and its follow-ups onto the branch so the
IMEX placement and primary-routing checks are built and tested against them for the
first time.

Merged clean, no conflicts. Not yet exercised together: a mixed filament is a virtual
slot no nozzle carries, while physical_extruder_map routes logical slots to physical
heads, so the IMEX pem lookups have no defined answer for one. Print::extruders()
lists mixed slots under their own id while tool_ordering.all_extruders() lists them
post-expansion, and the IMEX code reads both.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-26 09:25:41 -04:00
Clifford GarwoodandClaude Opus 5 008d13a59e fix(imex): keep the placement error across every validation path
Plater::validate_current_plate() runs the same background_process.validate() as
update_background_process(), and on success clears update_apply_result_invalid(false)
and closes the ValidateError notification -- but it never consulted
imex_placement_violation(). Any event reaching it wiped a live IMEX placement error
and re-enabled the Slice button on a plate the slicer still refused; pressing Slice
then hit the check in reslice() and returned early, so the job simply never started.

Reproduce by clicking the bed with the prime tower overlapping a reserved area.
Plater::select_plate_by_hover_id() -> select_plate() calls validate_current_plate()
unconditionally, even when the clicked plate is already current, and deselects as a
side effect -- which makes it look as though deselecting the tower cleared the error.
Escape and clicks off the bed go through selection_changed(), which only renders and
clears nothing.

Extract the violation-to-message mapping into one helper and call it from both paths.
model_fits is set alongside err.string in validate_current_plate, mirroring the
missing-plugin block below it: the slice is already gated by m_apply_invalid, but
leaving m_ready_for_slice true would trap a future consumer that reads it alone.

These are the only two sites that matter. NotificationType::ValidateError has exactly
three references in the tree and update_apply_result_invalid exactly four; the other
slice-ready writers can only touch m_ready_for_slice, never m_apply_invalid, so they
cannot re-enable Slice on their own.

Three adjacent gaps are left alone, all pre-existing: "Slice all" is hard-coded
always-enabled regardless of plate state; a slice-all batch halts silently at a
violating plate because reslice() returns above the line that queues the advance; and
object_list_changed() computes its own can_slice from geometry, harmless only because
the result is ANDed with PartPlate::can_slice().

This is a hole in the shipped tower-zone check rather than a regression from rotating
the tower hull -- it was simply invisible until a tower could be placed in violation.

No automated gate: Plater is GUI-only, the helper is file-local and unlinkable, and
imex_placement_violation() needs a live wxApp and preset bundle. "Both call sites
consult it" is a call-graph property no unit test can express. The grep for a single
imex_placement_violation reference is a future regression tripwire, not evidence this
refactor happened -- it already returned 1 beforehand.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-26 08:25:25 -04:00
Clifford GarwoodandClaude Opus 5 ba07716ddb Merge upstream main: color mixing feature and related fixes
Brings in 54 upstream commits, the bulk of them the BambuStudio-ported color
mixing / mixed filament subsystem (#15347) plus its follow-ups, along with the
Assimp-backed colored OBJ import, warning-policy build changes, and assorted
profile and localization updates.

Two conflicts, both "each side added at the same point", resolved by keeping
both:

- Print::validate() -- our IMEX multi-color block and upstream's new gradient
  mixed filament warning were inserted at the same spot after the empty
  extruders check. They test unrelated conditions, so both are kept, each with
  its own closing brace.
- tests/libslic3r/test_3mf.cpp -- our three IMEX per-plate round-trip scenarios
  and upstream's mixed-filament round-trip scenario both append to the end of
  the file, and each side added one include. All four scenarios and both
  includes are kept.

Everything else merged cleanly, including GCode.cpp, ToolOrdering.cpp,
PartPlate.cpp and PrintConfig.cpp. Upstream left the is_extruder_used block
untouched, so the IMEX supplement still applies, and estimate_wipe_tower_polygon
is unchanged, so the prime tower hull work is unaffected.

Not addressed here, and worth its own change: a mixed filament is a virtual slot
that no nozzle carries, while physical_extruder_map routes logical slots to
physical heads. Print::extruders() lists mixed slots under their own id whereas
tool_ordering.all_extruders() lists them post-expansion, so the IMEX pem lookups
have no defined answer for a mixed slot. Upstream's own guards reject a mixed
filament where a physical slot is required; IMEX likely wants the same.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-25 13:07:26 -04:00
Clifford GarwoodandClaude Opus 5 baef398ee3 fix(imex): refuse a plate whose filament cannot reach the mode's primary tool
The IMEX primary tool prints the sliced paths directly, so it can only load a
filament that physical_extruder_map routes to it. The ghost filament picker
enforces that for the secondary tools -- it offers only lanes whose pem entry
equals that head -- but the primary's filament comes from the ordinary object
filament selector, which has no IMEX awareness. Nothing detected the mismatch:
collect_imex_warnings() computes the same condition and discards it into a
display fallback, and the multi-color rule never examines it.

Block it in Print::validate() via the existing imex_primary_tool_for_mode and
imex_primary_logical_from_objects helpers. The message names the declared
primary, the heads the plate's filaments actually live on, and any configured
modes whose primary would work, and carries the object so the notification can
offer a jump to it.

Blocks rather than warns, matching the multi-color rule: the plate is not
printable as configured, and where the routed head is also absent from the
mode's active tools the 1st->2nd layer temperature branch skips it too, leaving
that head at its initial-layer temperature for the whole job.

The multi-color check now runs first. Its constraints -- an MMU manifold sharing
one head, a single-gantry mode -- cannot be fixed by switching mode, so the more
specific error should win rather than be masked by routing advice that leads
straight back to it. The extruders().size() > 1 gate moved onto that call, since
the routing check must also see single-filament plates, which is its common case.

The copy-mode guard-rail test printed on a filament routed off the primary, so
it asserted a plate this rule now refuses; retargeted to a well-formed plate.
Its replacement pins the object's own extruder, because ModelVolume reports its
extruder_id and would otherwise put a primary-routed slot on the plate.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-25 12:58:52 -04:00
Ian Bassi a5223279ac Fix uneven corner rounding in multiline infill (#15352)
* Skip straight-run splits in corner smoothing

Teach `CornerSmoother` to treat vertices that only continue a straight segment as part of the same leg instead of rounding them as corners. The smoother now keeps a three-point window so it can emit a corner only once both adjoining legs are known, which avoids unnecessary corner processing while preserving real turns such as hairpins.

* Add regression test for split-leg smoothing

Adds a FillCornerSmoothing regression test covering polylines with an extra collinear vertex in a straight run. The test ensures corner smoothing treats split and unsplit geometry identically, preventing inconsistent rounding radii in triangular/grid infill paths.
2026-08-25 12:46:34 -03:00
Kris Austin 265ae16160 chore: ignore CMakeUserPresets.json (#15354)
CMake reads CMakeUserPresets.json for developer-local presets, and its
documentation states the file should not be checked into version control:
https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html#introduction

It is the preset equivalent of CMakeLists.txt.user, ignored on the line
above.
2026-08-25 12:13:45 -03:00
SoftFever 9e34dde632 Color mixing feature (#15347)
# Description

This PR ports the color mixing feature from BambuStudio.
The port is based on the previous work by @ianalexis in #15231.
This PR completes the port and fixes various bugs.

Several improvements were also made during the porting process.

WIP


# Screenshots/Recordings/Graphs

<!--
> Please attach relevant screenshots to showcase the UI changes.
> Please attach images that can help explain the changes.
-->

## Tests

<!--
> Please describe the tests that you have conducted to verify the
changes made in this PR.
-->

<!--
> A guide for users on how to download the artifacts from this PR.
-->

[How to Download Pull Requests Artifacts for
Testing](https://www.orcaslicer.com/wiki/how_to_download_pr_artifacts)
2026-08-25 22:10:49 +08:00
SoftFever bfe5f7e63c fix text error 2026-08-25 21:35:43 +08:00
Kris Austin 56f9edc572 build: mark missing overrides and drop unused lambda captures (1,156 clang warnings) (#15334)
* chore: mark every declaration that overrides a base virtual

clang-cl reports 42 member functions across 28 files that override a
base virtual without being marked `override`, inside classes that
already mark their other overrides. That is every occurrence of
-Winconsistent-missing-override in the tree, so the category drops to
zero and -Werror=inconsistent-missing-override becomes available as a
guard against it coming back.

Behaviour is unchanged. Each keyword goes only where clang had already
resolved the declaration to a base virtual, so it records what the
compiler already worked out and cannot affect overload resolution or
dispatch. If any of these signatures had not really overridden a base
method, the build would have failed rather than warned.

Where a declaration already carried `virtual` it is left alone and the
keyword appended, matching the surrounding declarations. Plain
`override` is used rather than the wxWidgets `wxOVERRIDE` macro, which
wx/defs.h defines as `override` beneath a comment marking it obsolete,
and which the rest of src/slic3r already avoids by 1742 occurrences to
113.

A full clang-cl build takes -Winconsistent-missing-override from 1,146
warning lines to 0. Those 42 declarations produce that many lines
because a header is re-diagnosed in every translation unit that
includes it. CalibrationWizardStartPage.hpp alone accounts for 336 of
them from 4 declarations.

* chore: drop unused lambda captures in GUI/Widgets

clang-cl reports 10 lambda captures in src/slic3r/GUI/Widgets that are
never read. Removing them changes nothing at runtime.

Every capture removed is `this` or a raw pointer. clang does not report
a capture whose type has a non-trivial destructor, since such a capture
can be held purely for its effect on an object's lifetime, so nothing
that owns or extends a lifetime is touched. The std::weak_ptr captured
beside the removed `this` in MultiNozzleSync.cpp stays.

This clears the category in GUI/Widgets only. A full clang-cl build
takes -Wunused-lambda-capture from 312 warning lines to 302, leaving
235 sites in other directories for a follow-up.
2026-08-25 08:18:48 -03:00
yw4z 2f9ef86e97 match style of dialog buttons 2026-08-25 00:04:14 +03:00
yw4z fbe4cdff23 fix mixed filaments area cannot be hidden 2026-08-24 23:07:11 +03:00
yw4z a3231aa723 rebuild menus from scratch to remove duplicate item check and match "delete" item order 2026-08-24 22:02:47 +03:00
yw4z ce75a66e7c fix duplicate decompose menu item 2026-08-24 21:38:51 +03:00
Valerii Bokhan 524fd5e9c0 Fix: resolve 23 MSVC compiler warnings (#15280)
* fix: resolve MSVC compiler warnings and build error

C4101 - unreferenced local variables:
  - STEP.cpp, FilamentGroup.cpp: remove unused catch variable 'e'
  - GLGizmoMeasure.cpp: remove unused 'direction_on_model'
  - PartPlate.cpp: remove unused 'origin1, origin2'
  - DevStatus.cpp: suppress unused 'e' via (void)e

C4005 - macro redefinition:
  - Wrap NOMINMAX defines in #ifndef guards (OrcaSlicer.cpp, Preset.cpp,
    SupportTreeBuilder.cpp, OpenVDBUtils.cpp, GUI.cpp)
  - Remove conflicting DESIGN_INPUT_SIZE redefine in DownloadProgressDialog.cpp

C4172 - return address of local/temporary:
  - Config.cpp: return static const double instead of temporary 0

C4996 - deprecated API usage:
  - ImGuiWrapper.cpp: use GetText().Length() instead of GetTextLength()
  - OrcaCloudServiceAgent.cpp: replace deprecated wxPATH_NORM_ALL with
    explicit flags matching old default behavior
  - ASCIIFolding.cpp: replace deprecated std::wstring_convert/codecvt_utf8
    with boost::locale::conv::utf_to_utf (already used in same function)

C2440 - build error from deprecated wxTipWindow constructor:
  - Button.hpp/cpp: replace raw wxTipWindow* with wxTipWindow::Ref (weak
    reference). Ref auto-nulls when the tip window closes, eliminating
    the manual Bind(wxEVT_DESTROY) handler. delete uses operator->() to
    access the raw pointer since Ref is non-owning

* fix: avoid duplicate GetText() call in ImGuiWrapper clipboard handler

Capture wxTextDataObject::GetText() result in a local variable instead
of calling it twice (for .Length() check and into_u8()). GetText()
returns wxString by value, so this avoids an extra allocation/copy.

* fix: resolve MSVC compiler warnings (code review fixes)

* fix: resolve MSVC compiler warnings (code review fixes)
2026-08-24 15:37:47 -03:00
SoftFever 0fa25acda8 Match OrcaSlicer's color theme in the color-mixing UI 2026-08-25 00:47:25 +08:00
SoftFever 1631d3cf01 fix flatpak build 2026-08-24 17:30:39 +08:00
SoftFever 55812a7a8d Merge branch 'main' into color-mixing 2026-08-24 16:26:33 +08:00
SoftFever e342698d8e Update sublayer option check. Add validation warning for gradient mixed filament without sublayer mixing 2026-08-24 15:30:02 +08:00
Kris Austin d61e0cb7bf build: unify the warning policy across compilers (clang-cl: 124k warnings -> 2.7k, 21% faster) (#15328) 2026-08-23 19:55:48 -03:00
TheLegendTubaGuy 07b81cfdc9 Fix Qidi X-Max 4 chamber heating profiles (#15244) 2026-08-23 13:10:41 -03:00
Valentin d7fed95390 Fix Ukrainian translation typo (#15333) 2026-08-23 12:42:30 -03:00
GlauTechandIan Bassi c72908e377 Update OrcaSlicer_tr.po (#15309)
* Update OrcaSlicer_tr.po

* Update OrcaSlicer_tr.po

Fixed inaccurate AI-generated text and updated missing translations.

* REmoive # AI Translated

* Update OrcaSlicer_tr.po

The following changes were made in this version:
- The term "Instance" was changed to "Eş kopya".
- The term "Jerk" was changed to "sarsıntı".
- Semantic discrepancies regarding certain words were corrected.

* Update OrcaSlicer_tr.po

The necessary arrangements have been made.

* Update OrcaSlicer_tr.po

* Update OrcaSlicer_tr.po

The necessary updates have been made.

* G-kodu to G-code

---------

Co-authored-by: Ian Bassi <ian.bassi@outlook.com>
2026-08-23 12:34:51 -03:00
Ian Bassi ea376e858c Show move length in Previewr panel (#15326)
Adds a new "Length" row to the sequential marker position popup in GCodeViewer and updates row capacity accordingly.
For arc commands (G2/G3) that are split into multiple vertices, it now sums segment distances across vertices with the same gcode_id so the displayed value reflects the full move length instead of a single chord.
2026-08-23 12:18:22 -03:00
Ian Bassi 877180829c Unify colinear simplify tolerance in Arachne (#15314)
Introduced a shared `colinear_vertex_tolerance()` helper in `ExtrusionLine.hpp` and updated both simplify paths (`ExtrusionLine.cpp` and `WallToolPaths.cpp`) to use it instead of duplicated hardcoded `0.005` scaled thresholds. This keeps the near-colinear early-out tied to `SCALED_EPSILON` (rounding-noise scale) and avoids unintended curve decimation from larger tolerances, while documenting the geometric impact in code.
2026-08-23 12:18:06 -03:00
SoftFever 2b1499a087 clean up comments 2026-08-23 22:43:41 +08:00
SoftFever 7934814077 fix wrong size of the last swatch of each row in Mixing Recommendations 2026-08-23 22:11:49 +08:00
SoftFever 4a32a9e066 Match mixed filament swatches to the editor's gradient preview
The sidebar Mixed Filament list, the extruder icons, the color painting
gizmo and the canvas filament bar now show the same bottom-to-top fade the
Edit Mixed Filament preview shows, custom gradient curves included, instead
of a horizontal fade between the two component colours. Ordinary and vendor
multi-colour filaments are drawn exactly as before.
2026-08-23 22:11:49 +08:00
SoftFever ff35dacf4c Fix UI hanging on Mac 2026-08-23 22:11:49 +08:00
SoftFever 6f32d59997 Fixed an issue that gradient color button in color painting gizmo don't have number 2026-08-23 22:11:49 +08:00
SoftFever f02423074c Warn about mixed color sublayer when adding height ranges 2026-08-23 22:11:49 +08:00
SoftFever 38d51783ae Refresh the mixed filament list when a component preset changes 2026-08-23 22:11:49 +08:00
SoftFever af5397d678 Close the single-extruder mixed filament warning by type 2026-08-23 22:11:49 +08:00
SoftFever 9985688b5b Blend mixed slots in the machine-send and AMS-sync thumbnails 2026-08-23 22:11:49 +08:00
SoftFever d27766aff0 Reject a mixed filament as the wipe tower filament 2026-08-23 22:11:49 +08:00
SoftFever cfeca9b9ff Hide mixed slots from the support and wipe tower filament dropdowns 2026-08-23 22:11:49 +08:00
SoftFever 716bba53df Refuse to slice a broken mixed filament 2026-08-23 22:11:49 +08:00
SoftFever 8965b0be21 Skip mixed slots in flush volume auto-calculation
Mixed-colour slots are virtual and never flushed. Guard auto_calc_flushing_volumes_internal against them as BambuStudio does, and make the flushing dialog's default matrix and the sidebar 'modified' comparison physical-only so the untouched mixed rows no longer count as a user edit and the Re-calculate result matches the physical-only table.
2026-08-23 22:11:49 +08:00
SoftFever 0c3d7c6ed1 Expand mixed slots in by-object filament bookkeeping 2026-08-23 22:11:49 +08:00
SoftFever 2131ef0560 Keep mixed filaments across app restarts 2026-08-23 22:11:49 +08:00
SoftFever 6745a33d53 Fix deleting mixed filaments from the sidebar 2026-08-23 22:11:49 +08:00
SoftFever b2e1870a14 Restore sublayer prompt when enabling gradient mixing 2026-08-23 22:11:49 +08:00
SoftFever 6e52c091f3 Initialize parse output in string_to_double_decimal_point 2026-08-23 22:11:49 +08:00
SoftFever 1b5b8fce54 Port mixed filament dialog fixes from BambuStudio 2026-08-23 22:11:49 +08:00
SoftFever b1e3cdc666 Port colored OBJ import pipeline from BambuStudio 2026-08-23 22:11:49 +08:00
SoftFever 94a1cd6c93 Port color decompose recipe data and interpolation from BambuStudio 2026-08-23 22:11:49 +08:00