Commit Graph
442 Commits
Author SHA1 Message Date
David Eccles (gringer)andRodrigo Faselli 1dcbb2c02a Fill in truncated octahedron tops (optional setting) (#12541)
Co-authored-by: Rodrigo Faselli <162915171+RF47@users.noreply.github.com>
2026-10-05 20:32:18 -03:00
Kris Austin 90ac58d3cd perf: skip the unused curled wall estimate to speed up slicing by up to 9% (#16113)
perf: skip estimating curled walls when nothing reads them

The curled extrusion estimate ran whenever a region had overhang speed on,
which is the default, but only the slowdown for curled perimeters reads the
curled lines it produces, and that slowdown is off by default. The step now
also requires a region with the slowdown on, and clears the curled lines
when it skips the estimate, so none are left from an earlier slice. 
Also fixes stale fan commands due to the stale curled lines on the reused layers.
2026-10-04 09:45:19 +01:00
HanifKoh 8a6377f087 Add Missing Includes Across src/libslic3r (#16068)
* Add Missing Includes Across src/libslic3r

Every libslic3r source and header now directly includes the headers declaring what it uses, rather than relying on the precompiled header or transitive includes. Generated with clang-tidy misc-include-cleaner, with libslic3r headers spelled libslic3r/... so they resolve outside the library's private include paths. MultiMaterialSegmentation.hpp, Support/SupportParameters.hpp and Format/STEP.hpp are made self-contained by hand.

* Make the libslic3r Headers Compile on Their Own

Each now includes, or forward-declares, what it uses instead of relying on what its includers happened to include first. Left out: I18N.hpp, which errors on purpose when included from GUI code, and VoxelizeCSGMesh.hpp and SLA/bicubic.h, which nothing includes and which no longer compile at all.

* Add the Includes Missing From the Hand-Fixed libslic3r Headers

clang-tidy would not edit these headers while they failed to compile on their own, so the first pass skipped them. With the headers now self-contained, a second pass adds the rest.

* Keep Windows Setup Ahead of the Added libslic3r Includes

Print.cpp and Thread.cpp open with a _WIN32 block that has to come first; without the precompiled header, Print.cpp otherwise reaches windows.h through OCCT with NONLS defined and boost/regex fails. OpenVDBUtils.cpp and SLA/SupportTreeBuilder.cpp had includes inside #ifndef NOMINMAX, which libslic3r defines on Windows, so those were skipped there. .clang-tidy also ignores the MSVC STL and UCRT internals, Boost.Multiprecision's fwd.hpp and CPython's Windows include directory.

* Re-Add libslic3r Includes After the Clipper2 2.0.1 Migration

Rebasing onto main took main's version of the files the Clipper2 migration rewrote, so their added includes are restored here, along with includes for main's new code. Clipper2's individual headers are now ignored by clang-tidy: they only build the Z variant through clipper2_z.hpp, which defines USINGZ first, so including clipper.core.h and the like directly broke ClipperZUtils.cpp.
2026-10-03 15:31:11 +08:00
Ian BassiandRodrigo Faselli 222c6a2df5 Improve performance by migrating to Clipper2 2.0.1 (#15969)
Co-authored-by: Rodrigo Faselli <162915171+RF47@users.noreply.github.com>
2026-10-02 17:33:41 -03:00
HanifKohandSoftFever 205de9ce63 Keep User Preset Values on Extruder Variants They Don't List (#16046)
* Keep User Preset Values on Extruder Variants They Don't List

A user preset stores the variant list its parent had when it was saved.
When the parent later gains variants, update_diff_values_to_child_config
matched variants by name only and left the new ones at the parent's
value, so the user's settings were silently replaced there, and a
re-save wrote the system values into the user's file.

An unmatched parent variant now takes the child's first variant of the
same extruder, the rule slicing already uses in get_config_index_base.
A child without a variant list covers the parent's first extruder. The
name match also no longer indexes the child's extruder ids when it has
none.

* Share One Variant Column Rule Between Slicing, User Presets and Projects

Three places chose which variant column a value comes from, each with
its own copy of "the same variant and owner, else the owner's first
column": get_config_index_base when slicing, the user preset merge in
update_diff_values_to_child_config, and normalize_filament_values_to_variants
for projects and the CLI.

find_variant_column now holds that rule and map_variant_columns applies
it to a variant list, so a change to how missing variants are filled
reaches all three. Each caller keeps its own copy step. There is no
behaviour change: G-code is identical before and after. The one
relaxation is that get_config_index_base no longer reads past a short
id list when its two lists differ in length, which its assert already
rules out.

* Rename variant column helpers to variant index

---------

Co-authored-by: SoftFever <softfeverever@gmail.com>
2026-10-02 20:13:06 +08:00
HanifKoh 92d30fbc55 Clamp Ironing Line Spacing to a Usable Minimum (#15949)
An ironing line spacing of 0 reached the fillers from a 3MF, the CLI or
the per-filament override, which has no GUI guard. Concentric ironing
then never finished slicing, because a zero inset never shrinks the
region, and rectilinear ironing was silently dropped. Tiny positive
values produced an unprintable number of lines.

Top surface and support ironing now clamp the spacing to the 0.05 mm
floor the process GUI guard already enforces, so these configurations
iron at that spacing. Spacings at or above the floor, including every
shipped profile, are unchanged. The concentric filler also returns early
on a non-positive step so no other caller can hang it, and the filament
settings page now resets a too-small override the same way the process
page does.
2026-10-01 16:53:16 +08:00
Kris Austin 865e9963c3 perf: speed up G-code export by 7-26% via typed config apply (#16026) 2026-09-30 18:58:22 -03:00
SoftFever 1504bd7153 Fix command-line slicing when a filament leaves out a per-variant setting 2026-09-29 21:09:20 +08:00
SoftFever 7a2daaa351 Make all vendor profiles pass the updated profile checks 2026-09-28 23:02:04 +08:00
SoftFever 71bb400e46 Add multi-variant support to the app 2026-09-28 19:08:35 +08:00
Ian Bassi ea280ba6f6 Wipe tower sparse layers combination (#15841) 2026-09-26 16:27:15 -03:00
Ian BassiandRodrigo Faselli 8c03985818 Add Cubic Non-crossing multiline strategy (#15887)
Co-authored-by: Rodrigo Faselli <162915171+RF47@users.noreply.github.com>
2026-09-26 11:40:49 -03:00
SoftFever b535a81064 Fix: support per-nozzle top_solid_infill_flow_ratio 2026-09-24 23:52:55 +08:00
Drew WingfieldandSoftFever 6e4be42a04 UltiMaker S5 Profile + Local API Support (#14062)
* Add Ultimaker S5 Profile - WIP

* Add Ultimaker physical printer base

* Ultimaker API WIP for base update.

* Fix undefined reference error.

* Add UMS5 profile, add placeholders for testAuth stuff.

* Fix non-const func definitions, make func names align with style guide.

* Localization stuff? IDK if this does anything or is required.

* Add cover image

* Auth code cleanup, add UI button for auth cred generation, implement various auth checks and tests.

* Fix auth stuff

* Clean up code

* Get upload code sort-of working, fix typo

* Update printer settings and start/end gcodes

* Add makeGriffinCompatible preprocessor script to prevent machine crash, update machine profile.

* Fix buildplate size, fix time missing bug, add S5 buildplate model

* Correct capitalization to UltiMaker

* Fix display bug, fix capitalization bug

* Implement credential generation button and logic

* Fix generate auth creds button, add todos, fix capitalization.

* Actually fix generate auth credentials.

* Fix generate auth creds message.

* Update UM S5 machine limits

* Revert accidental commit.

* Fix postprocessor, clean up code.

* Update presets for multi-extruder printing.

* Add Single Extruder and Fast profiles.

* Code cleanup

* Register and validate the UltiMaker S5 presets

* Show the Generate API Key button only for UltiMaker print hosts

The PR added it to the Physical Printer dialog for every host type, where pressing it runs an ordinary connection test and reports "API Key created". Gate it on the selected host type instead.

* Drop unused lambda captures in the UltiMaker host code

clang promotes -Wunused-lambda-capture to an error under the project's -Werror, so the file failed to build on macOS; the five callbacks do not touch this.

* Fix the Windows build of the UltiMaker print host

---------

Co-authored-by: SoftFever <softfeverever@gmail.com>
2026-09-21 01:00:55 +08:00
Ian Bassi 59e40a2c2e Print unsupported walls last (#15411) 2026-09-17 09:14:20 -03:00
Ian Bassi 82e91bd472 Port wipe tower BBS improvements (#15485) 2026-09-17 09:08:50 -03:00
Ian BassiandRodrigo Faselli 72774e5398 Toolchange Cyclic Order (#14868)
* Toolchange Cyclic Order

* Apply cyclic order to first layer

* Unit test

* Copilot fixes

---------

Co-authored-by: Rodrigo Faselli <162915171+RF47@users.noreply.github.com>
2026-09-16 12:19:03 -03:00
Valerii Bokhan 3e1daccd7c Feature: Add inward wipe for external perimeters (#15407) 2026-09-15 20:01:39 -03:00
Kris Austin d643b10ac4 build: expand PrintConfig.hpp option lists twice per class instead of five times (#15658) 2026-09-13 17:46:03 -03:00
Rodrigo FaselliandIan Bassi 85dc866425 Spiral Inset infill (spiral-concentric infill) (#15085)
Co-authored-by: Ian Bassi <ian.bassi@outlook.com>
2026-09-06 11:36:23 -03:00
Ian Bassi 8fea099d99 BBL Port Color Mix Base 2026-08-23 22:11:48 +08:00
ExPikaPakaandSoftFever 5ed56eb876 Cache system presets to eliminate startup and wizard load times (#14217)
* Add caching system for presets

* Removing user\bundle serialization and keeping it only for system presets

* Integrate caching into WebGuideDialog which speeds up time of SetupWizzard and PrinterSelection dialog

* Add CI\CD step to prepare cache file in ahead of time so user does not need to wait

* Add partial cache generation when only one of the vendros is changed to speed up recalculation time

* Handle corrupted files

* Add cache to GuideDialog as previos version didn't work as expected

* Add inspecting tool and fix CI cache generation

* Generate cache per vendor

* Simplify code by mergin it in PresetBundle

* Simplify code a bit more

* Add cereal serialize() to VendorProfile, PrinterModel, Preset, and Semver

* Remove CachedPrinterModel/VendorProfile/Preset mirror structs from VendorCache

* Fix use-after-free in CallAfter lambda; replace raw thread pointer with unique_ptr

* Use get_vendor_cache_key() to match cache keys written by the app

* Remove BOM added by VSC

* Skip invalid vendors

* Remove leftover cache file

* Fix build for windows arm64

* Revert json cache back

* Update check for stale cache

* Serealize all value fields for Preset class to minimize regression later

* Minimize field duplication by moving Cache thing into PresetBundle

* Add tests for Cache system

* Add a bit more tests

* Merge branch 'main' into feature/cache_profiles_and_optimize_loading_speed

* Rvert from per-verndor to single cache file

Replace N per-vendor .cache files with a single system_presets.cache
that holds all vendors and presets in one serialized blob.

Cache load is now all-or-nothing: on hit all vendors are applied from
the bundle (sub-second); on miss all vendors are parsed from JSON and
a fresh bundle is written to the user cache dir.

Invalidation is driven by bundle_key - a sorted concatenation of all
vendor JSON version strings. Any vendor update invalidates the whole
cache and triggers re-parse on next launch.

Guide wizard (WebGuideDialog) loads the bundled cache into a plain
PresetBundle instead of a separate VendorGuideData struct, removing
the duplicate data model.

generate_system_cache simplified from a per-vendor loop to a single
save_system_presets_cache() call producing one output file.

* Transfer all Preset fields from cache via move assignmet

apply_vendor_preset_group was copying fields manually and missed
bundle_id, user_id, base_id, sync_info, updated_time, key_values,
ini_str. Replace field-by-field copy with move assignment of the
fully-deserialized Preset, then restore the vendor pointer which
is excluded from serialization.

* Ignore cache for future

* Remove not used files

* Ship one preset cache per vendor in place of the profile JSONs

Each vendor's system presets serialize into a single <vendor>.opc built at
package time, and a shipped build carries that file alone — the profile JSON
and its sub-file tree are pruned. The vendor loader, the setup wizard's profile
list and the resource installer all read a vendor through its cache, falling
back to parsing whenever one is absent, stale or unreadable, so the cache stays
an optimization and never a source of truth. Caches hold presets in source form
and resolve inheritance at load, through the same code the JSON path uses.

* Make the preset cache self-describing and load each vendor from the system folder alone

The cached DynamicPrintConfig is keyed by name, through a per-file dictionary of the
distinct opt_keys, the type each was written as, and the distinct enum value names,
instead of by serialization_key_ordinal — a position assigned by declaration order at
static init, where inserting one option shifts every later ordinal and the lookup then
succeeds on the wrong option. Because a name-keyed payload drops the options this build
cannot place rather than being rejected wholesale, the schema fingerprint goes, and with
it the two fallbacks that existed only because an installed cache died on every app
upgrade: the second lookup tier into resources/profiles and the parse fallback to the
same place. A vendor is loaded from <data_dir>/system/ and nowhere else, as on main —
which is what makes the app write its .opc files there again.

* Simplify the preset cache internals after review

* Use the shared temp-dir helper in the preset bundle loading test

* Bound stamp string reads in the preset cache

* Speed up the setup wizard with a profile-data cache

The wizard's per-vendor fast path threw on vendors present only in
resources, falling back to a ~29 s raw JSON scan on every open. Each
vendor now loads from the directory it was found in, and the derived
model/machine/filament/process catalog is cached whole in
<data_dir>/cache/wizard_profile_data.json, stamped by each vendor's
name and version - a fresh cache makes an open one file read, with no
bundle built and no presets installed (~0.2 s vs ~2 s).

* Remove debug SVG dump from a geometry test

* Move the per-vendor cache file format into PresetCacheFormat

* Move the vendor install helpers from PresetBundle into Utils

* rename

* fix flatpak

* change cache version to 1

---------

Co-authored-by: SoftFever <softfeverever@gmail.com>
2026-08-21 16:56:52 +08:00
Ian Bassi 322dc9b6a6 Smooth more patterns (#15205) 2026-08-18 12:19:27 -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 fd23b74b99 Fix single-value object overrides on multi-nozzle printers (#15221) 2026-08-13 17:09:10 -03:00
SoftFever 408db4b3b0 Wait for the toolchange temperature on the wipe tower
Adds a printer option that picks up the new tool without a blocking temperature
wait, travels to the wipe tower, and waits there right before purging, parked
beside the tower so the ooze from the heat-up lands next to it rather than on the
model. The incoming filament's target is raised ahead of the tool change, so the
heat-up overlaps both the change itself and the travel to the tower.

Off by default, and only offered for multi-extruder printers using a Type 2 wipe
tower; the generic toolchanger profile enables it.
2026-08-06 12:24:00 +08:00
Mikhail f. Shiryaev 7b404596e9 Add Skip G-code config block to exclude the config comments from G-code files (#12455)
Add feature to skip CONFIG_BLOCK in G-code files
2026-08-03 15:10:01 -03:00
maddavo 13ae3a1c90 Add outer-only mouse ears and align ear radius controls (#15015)
Improve mouse ear brim controls
2026-08-02 10:54:16 +08:00
Valerii Bokhan fb36d5e73b Feature: Smooth Factor for the Hilbert Curve sparse infill (#14969) 2026-08-01 17:58:04 -03:00
Maksym PyrozhokandIan Bassi ef7bfeda9c Cyclic ordering (#13578)
Co-authored-by: Ian Bassi <ian.bassi@outlook.com>
2026-07-27 19:52:29 -03:00
SoftFever 9a72dda79a Fix plugin configuration not taking effect, and improve the plugin config UI (#14944)
# Description

Changing a slicing plugin's configuration had no effect on the sliced
result until you forced a re-slice some other way; it now applies
immediately. Print, printer and filament presets also keep their plugin
configuration separately, so configuring a plugin on one no longer wipes
out what you set on another.

A plugin's custom configuration page gets the same round of improvements
in both the Plugins dialog and the per-preset dialog: it follows the
app's light/dark theme, keeps its state while you edit instead of
resetting under the cursor, and can tell whether it is being edited
globally or for a preset, so "Restore defaults" can be labeled for what
it will actually do. The two bundled examples show this off — Twistify
now ships a custom configuration UI, and Inspector is themed, groups

# Screenshots/Recordings/Graphs



https://github.com/user-attachments/assets/02ca062a-5143-49a3-abe0-a2a040b3a928



## 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-07-25 20:00:56 +08:00
SoftFever 9b5eb76478 Misc updates and clean up
- WipeTower: use filament_ramming_volumetric_speed(_nc) for ramming, falling back to
  max_vol_speed only when nil; gate precool temps on enable_pre_heating
- ToolOrderUtils: disable the inter-layer forecast in the per-nozzle base reorder so
  H2D/H2C ordering is unchanged
- PrintConfig: stop stripping filament_prime_volume in handle_legacy; document that
  prime_volume drives the Type2 wipe tower and filament_prime_volume the Type1 one
- GCodeProcessor: exclude post-print end-gcode M400 dwells from the M73 estimate and
  drop the dead air-filtration state
- Trim verbose BambuStudio source-location comments across the port
2026-07-20 17:34:13 +08:00
SoftFever 65ab9b61a8 Merge branch 'main' into feature/h2c_support_clean_fixes 2026-07-20 00:02:43 +08:00
SoftFever b663f851fe Merge branch 'main' into feat/plugin-feature 2026-07-17 11:30:34 +08:00
denis svinarchuk 407c78fb30 fix: port BBS NozzleStatusRecorder pattern for per-carousel-slot purge tracking
The upstream _make_wipe_tower() tracked purge volumes per-extruder (2 slots),
which collapsed all H2C carousel filaments into one slot and caused massive
redundant AMS flushing (~40g instead of ~0.4g).

Changes:
- Print.cpp: Replace per-extruder nozzle_cur_filament_ids with BBS
  NozzleStatusRecorder that tracks per group_id (carousel slot 0..6).
  Use get_nozzle_for_filament() to resolve physical slot per layer.
  Select filament_prime_volume_nc for nozzle changes, filament_prime_volume
  for filament changes (BBS pattern).
- PrintConfig.hpp/cpp: Register filament_prime_volume (per-filament EC prime
  volume, default 45mm³) matching BBS PrintConfig.
- Preset.cpp: Add filament_prime_volume to preset keys list.

Safe for non-carousel printers: group_id == extruder_id when each extruder
has one nozzle, so NozzleStatusRecorder behaves identically to the original
per-extruder tracking.

Reference to BBS: BambuStudio/src/libslic3r/Print.cpp _make_wipe_tower() L3341-3392
2026-07-16 14:54:46 +01:00
Mqrius 6d1974a662 Restore flow calibration special order, overridable via fill order (#14786) 2026-07-16 09:10:15 -03:00
SoftFever 0849c44ae0 Merge branch 'main' into dev/ams-heat 2026-07-15 19:45:27 +08:00
SoftFever 8cb0cb7693 Merge branch 'main' into feat/plugin-feature
Resolve five conflicts, all of which needed both sides rather than a pick:

- BackgroundSlicingProcess: ours was a pure tabs->spaces reformat of base, so
  keep main's per-filament volume/nozzle map read-back (its only change here).
- GUI_App: main's #12506 else-if attached to an `if` this branch deleted;
  re-expressed onto the same-agent early-return path (the agent factory caches
  per id, so pointer equality is the same predicate).
- MainFrame: both sides relocated Sync Presets independently; keep main's
  push_notification plus the branch's Plugins menu items.
- Tab: the "TODO: Orca: Support hybrid" blocks were unchanged base, not a branch
  decision; take main's enabled Hybrid to match the already auto-merged siblings.
- test_config: union of both sides' cases (6 plugin + 9 multi-nozzle).
2026-07-15 17:18:46 +08:00
MqriusandIan Bassi c84d5c7943 Add top/bottom surface fill order control (Outward/Inward) for Concentric, Archimedean Chords and Octagram Spiral (#14179)
Co-authored-by: Ian Bassi <ian.bassi@outlook.com>
2026-07-14 15:34:13 -03:00
Valerii BokhanandIan Bassi 50768e0716 Feature: Retract amount after wipe (#11015)
Co-authored-by: Ian Bassi <ian.bassi@outlook.com>
2026-07-14 14:42:16 -03:00
Noisyfox 246f2d32bf Merge branch 'main' into dev/ams-heat
# Conflicts:
#	src/libslic3r/Preset.cpp
#	src/libslic3r/PrintConfig.hpp
#	src/slic3r/GUI/DeviceCore/CMakeLists.txt
#	src/slic3r/GUI/DeviceCore/DevDefs.h
#	src/slic3r/GUI/DeviceCore/DevFilaSystem.cpp
#	src/slic3r/GUI/DeviceCore/DevFilaSystem.h
#	src/slic3r/GUI/DeviceCore/DevUtilBackend.cpp
#	src/slic3r/GUI/DeviceCore/DevUtilBackend.h
#	src/slic3r/GUI/DeviceManager.cpp
#	src/slic3r/GUI/DeviceManager.hpp
#	src/slic3r/GUI/SelectMachine.cpp
#	src/slic3r/GUI/SelectMachine.hpp
2026-07-14 10:10:19 +08:00
Noisyfox 49282858a4 Merge branch 'main' into dev/ams-heat 2026-07-13 14:43:45 +08:00
Rodrigo Faselli 79aa0bd4a2 Merge branch 'main' into feature/h2c_support_clean 2026-07-12 22:00:40 -03:00
Ian BassiandRodrigo Faselli c4ea86041b Separated Infills enhancements (#14674)
Co-authored-by: Rodrigo Faselli <162915171+RF47@users.noreply.github.com>
2026-07-12 11:45:00 -03:00
SoftFever abbd420f2a feat(engine): write per-variant filament values back for selector regroups
When the per-layer filament selector (enable_filament_dynamic_map)
migrates a filament across nozzle variants (e.g. Standard -> High Flow),
the config write-back only stored the derived extruder map; every
per-variant filament value (retraction, nozzle temperature, flow,
flush...) kept the numbers resolved from the pre-slice static mapping.

Now both dynamic write-back sites (the by-layer branch and the
sequential stitch) branch on the result's dynamic support. Migrating
results run a mixed-filament expansion that regathers every
filament_options_with_variant key from the pristine per-variant
superset, giving a migrating filament one config slot per (extruder
type x nozzle volume type) it lands on - filament_self_index,
filament_extruder_variant, and all value arrays grow in lockstep - and
recompute the retract overrides with per-slot machine indices so a nil
slot falls back to its own variant's machine value. Non-migrating
dynamic results take the merged three-map write-back so re-applies
reproduce from the written maps. Unrouted filaments resolve from the
result's own default map, so slot resolution never depends on
filament_map round-tripping through the plate config.

Print::apply reproduces the identical expansion from the persisted
group result (shared dedupe helper, expansion function, and slot
indices on both sides): the expanded keys sit in the psWipeTower /
psGCodeExport invalidate lists, so without the reproduction every
re-apply after a selector slice would diff non-empty and permanently
invalidate. cal_non_support_filaments now resolves the extruder per
layer from the published result for dynamic groupings.

filament_map_2 keeps its apply-time static derivation; nothing on the
dynamic path reads it (the per-slot machine indices key the override
merge), and per-(extruder x volume-type) machine limits in the g-code
processor remain a documented follow-up.

Every change is gated behind is_dynamic_group_reorder() or a persisted
result with dynamic support; no profile sets the flag, so the static
fleet's instruction stream is unchanged (20/20 pinned-slice byte gate
identical, incl. the sequential repro sliced twice, deterministic).

Tests: expansion unit coverage (migrating slots, unrouted fallback via
the default map, mis-sized volume map ignored, nullable retract keys in
lockstep, slot machine index layout), an end-to-end stub-driven
write-back asserting expanded slots, per-layer config-index resolution,
the override merge incl. the nil-slot variant fallback, and re-apply
stability, plus a real selector slice staying valid across re-apply.
Suites green (libslic3r 48987/168, fff_print 633/60).
2026-07-12 11:15:58 +08:00
SoftFever c65b0540a3 Merge remote-tracking branch 'origin/main' into feature/h2c_support_clean
# Conflicts:
#	src/libslic3r/PrintApply.cpp
#	src/libslic3r/PrintConfig.cpp
#	src/libslic3r/PrintConfig.hpp
#	tests/libslic3r/test_config.cpp
2026-07-11 23:10:54 +08:00
93d5b65852 Fix per-obj multi-variant options handling (#14700)
* ENH: config: add logic to apply params to object/region config with multi-extruder

JIRA: no-jira
Change-Id: Ieab98cd8d031e5ca82a3aad2d0b89d8ae4a794f1
(cherry picked from commit 3179fd416e68ca8bc2d746f859508d07db18fe5b)

* FIX: X1C switch to H2D lose Highflow parameter

Jira: STUDIO-15272
Change-Id: Id8cf5d93a49d5542ac82f9554974b458e15c1193
(cherry picked from commit 15d9f072ff658a3beb4f916d978dfea12c2d9f16)

* Fix mishandling of `stride` param and add unit test for it

* Fix modified multi-variant per-obj option highlight

* Fix issue that per-obj FloatsOrPercents options are marked as dirty incorrectly when lost focus

---------

Co-authored-by: lane.wei <lane.wei@bambulab.com>
Co-authored-by: weiting.ji <weiting.ji@bambulab.com>
2026-07-11 22:21:22 +08:00
SoftFever 18b9279c26 feat(print): add per-filament config-index resolvers and filament_map_2
- Print::get_nozzle_config_index / get_filament_config_indx resolve a
  filament's variant slot per layer from the nozzle group result, with
  hashed index caches; when no group result is published (sequential
  prints), they fall back to the static filament->extruder mapping so
  behavior is unchanged
- filament_map_2 caches each filament's resolved print-variant slot;
  rebuilt in Print::apply after the filament_map diff handling and in
  the filament-map write-back
- filament retract overrides now key by slot indices: apply_override
  fallback indexing flips to 0-based, Print::apply passes
  filament_map/extruder indices, the write-back passes filament_map_2
  (identical resolution while slots equal extruders)
- filament_volume_map/filament_nozzle_map/filament_map_2/
  filament_self_index become PrintConfig static members (required for
  member access); grouping input guards tightened so their registered
  1-element defaults are never mistaken for real per-filament maps
  (single-filament manual mode keeps the mix-marker fallback)
- update_filament_self_index_cache refreshed at every full-config
  assignment
- tests: 0-based apply_override fallback, get_config_index_base
  hit/miss/mixed-type cases

The resolvers are not consumed by the g-code writer yet. Non-Hybrid
g-code is unchanged except the config header, which now serializes the
three new static keys (defaults until the per-filament producer lands);
verified by the 19-fixture byte gate: 3 added header lines per fixture,
zero motion changes.
2026-07-11 02:29:40 +08:00
SoftFever 13cd8d4864 feat(config): keep per-(extruder x volume-type) slots in variant expansion
- get_extruder_nozzle_volume_count derives per-extruder volume-type slot
  lists from extruder_nozzle_stats (absent stats = one slot per extruder)
- update_values_to_printer_extruders learns the slot layout: when any
  extruder mixes volume types, option arrays keep one slot per
  (extruder x volume type), extruder-ascending then volume-ascending;
  single-slot resolution takes the filament's volume type on mixed
  extruders
- update_values_to_printer_extruders_for_multiple_filaments applies a
  per-filament nozzle_volume_type override from filament_volume_map
  (when sized to the filament count) and remaps filament_self_index
  through the same pipeline as every other filament key
- get_config_index_base + is_auto_filament_map_mode helpers (consumers
  land with the per-filament config-index resolvers)
- callers updated: PresetBundle composition paths, PrintApply (counts
  hoisted above the extruder_applied guard), Print write-back
- new tests: slot counting, Hybrid slot expansion incl. stride 2,
  per-filament override, non-Hybrid degeneracy

Non-Hybrid printers keep their variant layout and values (proven by a
19-fixture byte gate; the only header delta is filament_self_index now
flowing through the same variant pipeline as its sibling filament
keys). Hybrid slices grow the config-block variant arrays to one entry
per sub-nozzle volume type; motion g-code is unchanged until the
g-code writer consumes the new slots.
2026-07-11 00:51:10 +08:00
SoftFever 19352215da feat(plugin)!: merge G-code post-processing into the slicing pipeline as psGCodePostProcess
G-code post-processing is now a step of the slicing-pipeline plugin rather than a
separate capability type. One capability class can transform slices at the geometry
seams AND edit the final G-code, behind a single picker/option.

- Add SlicingPipelineStepPlugin::psGCodePostProcess (bound as
  orca.slicing.Step.psGCodePostProcess). Unlike the geometry steps it fires from the
  GUI export path in PostProcessor.cpp, not from Print::process(): ctx.print/ctx.object
  are None and the plugin edits the file at ctx.gcode_path in place. It may run more
  than once per slice (file export and/or upload) and its output is not shown in the
  preview.
- Extend SlicingPipelineContext with gcode_path/host/output_name and a C++-only
  full_config; config_value() falls back to it when there is no live Print.
- PostProcessor.cpp dispatches SlicingPipelinePluginCapability at psGCodePostProcess,
  driven by the existing slicing_pipeline_plugin option.
- The exported G-code lives outside data_dir(), so the plugin audit sandbox would
  block the write; the trampoline's audit setup grants ctx.gcode_path's folder as a
  scoped allowed root, gated on a non-empty gcode_path so the geometry-step hooks gain
  no extra filesystem access.

BREAKING CHANGE: the separate G-code post-processing capability type is removed.
- orca.gcode.GCodePluginCapabilityBase and orca.PluginType.PostProcessing are gone;
  post-processing plugins migrate to orca.slicing.SlicingPipelineCapabilityBase +
  Step.psGCodePostProcess (and gain ctx.params / ctx.config_value()).
- The post_process_plugin config option is removed; use slicing_pipeline_plugin.
  Presets carrying the old key degrade to the standard unknown-key warning.
- Manifest type = "post-processing" now maps to Unknown (advisory only; the loader
  dispatches on the C++ get_type()).

Also repairs two latent build breaks the branch carried: stale Step enum value usages
in test_slicing_pipeline_hook.cpp and a reference to the removed
ConfigOptionDef::PluginType::None in Tab::on_value_change (now is_plugin_backed()).
Adds the orca_gcode_stamp sample plugin and a psGCodePostProcess binding test.
2026-07-10 19:57:35 +08:00