Compare commits

...

142 Commits

Author SHA1 Message Date
Joseph Robertson
2ca843a38e Belt Printing: Bugfix: Solid Organic Tree Base, Slim Tree Skirt, Renderer (#14395)
* fix tree support brim
* treesupport3d part 1: more diagnostic logging.  (todo once things are fixed: remove this / gate it properly)
* make area under Z=0 in rotated slice pipeline not solid
* fix solid Z=0 layer for belt printers
* fix renderer
* clean up logging
* final review pass
2026-06-24 22:01:29 -05:00
Joseph Robertson
0ef7c6d581 Belt Printing: Update (#14393)
# Description

<!--
> Please provide a summary of the changes made in this PR. Include
details such as:
  > * What issue does this PR address or fix?
  > * What new features or enhancements does this PR introduce?
> * Are there any breaking changes or dependencies that need to be
considered?
-->

# 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-06-24 21:34:53 -05:00
Joseph Robertson
34b0d36cda Belt Printer Initial Push (#14385)
# Description

Initial push - documentation available at #12998 

[How to Download Pull Requests Artifacts for
Testing](https://www.orcaslicer.com/wiki/how_to_download_pr_artifacts)
2026-06-24 09:42:40 -05:00
Joseph Robertson
d619c7e19c Merge branch 'belt-printer' into belt/baseChanges 2026-06-24 09:42:25 -05:00
SoftFever
4e03983426 build belt parallel branch and publish the nightly release 2026-06-24 21:02:57 +08:00
dependabot[bot]
d3ac5ab98e Bump actions/github-script from 7 to 9 (#13431)
Bumps [actions/github-script](https://github.com/actions/github-script) from 7 to 9.
- [Release notes](https://github.com/actions/github-script/releases)
- [Commits](https://github.com/actions/github-script/compare/v7...v9)

---
updated-dependencies:
- dependency-name: actions/github-script
  dependency-version: '9'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-24 20:35:21 +08:00
SoftFever
0b77321d3a bump flashforge profile version 2026-06-24 19:16:15 +08:00
Markus K.
a6816d8c0d Fix hyperlink for flow ratio calibration wiki (#14378) 2026-06-24 12:23:55 +03:00
Kiss Lorand
045179150f Refactor skirt/brim + bugfixes related to them (#14333)
Refactor skirt and brim ownership and emission flow

Refactor skirt and brim generation around a common object/group
ownership model.

Skirts and brims are now emitted as a coordinated preamble
(skirt -> brim -> object) instead of being generated and emitted
through multiple independent code paths.

Changes:
- Fix repeated skirt emission caused by the previous skirt state
  tracking logic.
- Restore local skirt/brim ordering for per-object skirts in
  By Layer mode.
- Emit brims together with their owning object or object group.
- Handle combined brims independently from skirt grouping.
- Handle draft shields through the same ownership model as skirts.
- Fix draft shield generation when skirt height is zero.
- Generate draft shields after brim geometry is known, preventing
  draft shields from overlapping brims.
- Reject unsafe grouped per-object skirt configurations in
  By Object mode.
- Remove legacy skirt emission paths and state-management
  workarounds.

Support brim generation remains unchanged.

Co-authored-by: SoftFever <softfeverever@gmail.com>
2026-06-24 15:48:31 +08:00
SoftFever
4c3e30144d Show a warning dialog about profile sync changes. (#14377) 2026-06-24 14:58:33 +08:00
Indy Jones
ff83aa41ef Fix duplicate Flashforge filaments in system filament list (#14316)
The `@FF AD5M 0.25 nozzle` filament variants carried the base profile's
full printer list (AD5M/AD5M Pro/AD5X 0.4/0.6/0.8) instead of the 0.25
nozzle printers. Combined with base profiles that also listed the AD5X
0.4/0.6/0.8 printers already covered by dedicated `@FF AD5X` variants,
multiple presets with the same alias became compatible with the same
printer. The filament combobox keys presets by full name but displays
them by alias, so these surfaced as duplicate entries (e.g. "Flashforge
PLA Silk", "Flashforge ASA Basic" shown twice).

Fix the `compatible_printers` lists (data only, no settings changed):
- Repoint the 15 `@FF AD5M 0.25 nozzle` variants to the actual 0.25
  nozzle printers (Adventurer 5M 0.25 + Adventurer 5M Pro 0.25).
- Remove the redundant AD5X 0.4/0.6/0.8 entries from the base profiles
  where dedicated AD5X variants already exist.
- Bump Flashforge profile version to 02.04.00.02.

Each affected filament now resolves to exactly one preset per printer,
and the previously uncovered AD5M 0.25 nozzle printers gain coverage.
2026-06-24 14:20:11 +08:00
NM
91b712a237 feat(profiles): Snapmaker U1, add 0.2mm & 0.8mm nozzle profiles, complete 0.6mm process lineup (#14305)
* Snapmaker U1: add 0.2mm and 0.8mm nozzle profiles

Add machine and process profiles for the Snapmaker U1's 0.2mm and
0.8mm nozzles, and complete the 0.6mm process lineup. Follows the
same data-only pattern used to add the 0.6 / 0.4+0.6 nozzles in
commit afc3756.

The U1 ships with 0.4, 0.4+0.6 and 0.6 nozzle options today; the 0.2
and 0.8 nozzles are supported hardware but have no profiles, so they
cannot be selected. This adds them the Orca-native way: per-nozzle
machine presets plus a model-file dropdown entry, with their process
profiles filtered in via compatible_printers.

Machine (2): lean presets inheriting fdm_U1, mirroring the existing
SM_U1_06 (0.6) preset and overriding only the per-nozzle values;
setting_ids SM_U1_02 / SM_U1_08.

Process (21): 2 per-nozzle commons (fdm_process_U1_0.2_common,
_0.8_common) holding the nozzle line widths, plus 19 profiles
(0.2: 8, 0.6: 6, 0.8: 5) that inherit their per-nozzle common and
carry their own layer height, matching upstream's factoring. The two
0.24 Standard profiles that shared id GP029 are split into
GP029_06_024 / GP029_08_024.

Model dropdown: machine/Snapmaker U1.json nozzle_diameter
"0.4;0.4+0.6;0.6" -> "0.2;0.4;0.4+0.6;0.6;0.8".
Vendor index: register the new presets in Snapmaker.json.

The existing 0.4 / 0.6 / 0.4+0.6 presets resolve identically before
and after. scripts/orca_extra_profile_check.py and the profile
validator both pass.

* chore(profiles): bump Snapmaker vendor version to 02.04.00.04

Bump the Snapmaker vendor config_version so existing installs pick up the new 0.2mm and 0.8mm U1 nozzle profiles. PresetUpdater only re-imports a vendor bundle when the shipped version is strictly greater than the cached one.

---------

Co-authored-by: ni4223 <ni4223@users.noreply.github.com>
2026-06-24 14:18:38 +08:00
TheLegendTubaGuy
8491f87ddb Set Qidi X-Max 4 printer agent (#14334)
* Set Qidi X-Max 4 printer agent

* bump version

---------

Co-authored-by: SoftFever <softfeverever@gmail.com>
2026-06-24 14:16:20 +08:00
Sandmann
99fde4a24e fix(CrealityPrint): avoid false 'End of file' error when K1 closes the WS after start (#14344)
K1C: corrige erro 'End of file' ao enviar impressao (start_print)

A K1-family fecha o WebSocket 9999 assim que aceita o comando de iniciar
impressao. O start_print fazia um ws.read() bloqueante logo apos o write, que
estourava 'End of file [asio.misc:2]' e era reportado como erro -- embora a
impressao ja tivesse iniciado (o comando e entregue no write). Torna o read e o
close best-effort (overloads com error_code), eliminando o falso erro. Mesmo
padrao ja usado em feed_filament; cobre os caminhos single-color e multicor.
2026-06-24 14:13:45 +08:00
Joseph Robertson
31b44cb731 Merge pull request #66 from HarrierPigeon/belt/tommyb-rendererChanges
Clean up and implement @tommasobbianchi's belt renderer changes
2026-06-23 00:27:39 -05:00
harrierpigeon
ddbee84e68 render the G-code preview upright (designed view) + toggle UI 2026-06-23 00:14:17 -05:00
Joseph Robertson
bf6cce1f40 Merge pull request #45 from tommasobbianchi/feat/belt-gcode-cartesian-preview
belt: render the G-code preview upright (model/Cartesian space)
2026-06-22 19:59:27 -05:00
Joseph Robertson
8bdf0df00a Merge branch 'main' into belt/baseChanges 2026-06-22 19:36:17 -05:00
Joseph Robertson
d6c9187c71 Merge branch 'main' into belt/baseChanges 2026-06-22 19:36:17 -05:00
Ian Bassi
5538bf6463 Lang: Gettext update (#14361) 2026-06-22 20:16:55 -03:00
Ian Bassi
0cdfb88357 Lang: Gettext update (#14361) 2026-06-22 20:16:55 -03:00
foXaCe
fdf4a493cb i18n(fr): translate strings added after the post-refactor sync (#14304) 2026-06-22 20:13:19 -03:00
foXaCe
14cec7239b i18n(fr): translate strings added after the post-refactor sync (#14304) 2026-06-22 20:13:19 -03:00
Heiko Liebscher
932410e06b Improve German (de) translation (#14352)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 15:40:14 -03:00
Heiko Liebscher
86c6a1a66f Improve German (de) translation (#14352)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 15:40:14 -03:00
SoftFever
a409791826 bump version to 2.5.0-dev 2026-06-22 00:50:51 +08:00
SoftFever
07f08dfe40 bump version to 2.5.0-dev 2026-06-22 00:50:51 +08:00
Noisyfox
ba12608e4a Don't allow adding more colors for non-semm printers on obj import color remapping dialog (#14275) 2026-06-21 18:20:58 +08:00
Noisyfox
a4fb5af9e1 Don't allow adding more colors for non-semm printers on obj import color remapping dialog (#14275) 2026-06-21 18:20:58 +08:00
Tommaso Bianchi
8593d66a39 belt: correct the designed-view preview's belt-Z origin and reject mis-mapped outliers
The Cartesian designed-view preview over-extended the toolpaths past the model
shell by a height-proportional amount (up to ~20mm tall parts), most visibly on
long multi-part prints; compact parts like a calibration cube looked fine.

Two coupled causes:
- Belt start G-code that primes with a Z advance and a 'G92 Z0' reset leaves a
  constant machine-Z origin in the GCodeProcessor, so move positions are stored as
  gcode_Z + origin. The linear back-transform mixes that constant with the
  gantry-Y term, leaving a per-move designed-Y error that min-corner anchoring
  cannot cancel when an elevated move (e.g. a bridge) happens to cancel it at the
  bbox minimum. Expose GCodeProcessorResult::belt_z_origin (the m_origin[Z] left by
  the start G-code) and subtract it before the back-transform.
- Elevated features (bridges/overhangs) are mis-mapped by the linear inverse to
  outside the model body; build the anchor bbox only from moves within model_bb +/-
  10mm, with a fallback to the full bbox when the clip would drop the bulk (object
  placed away from the belt entry) so the gross-offset case still anchors.

Preview-only; G-code output is unchanged.
2026-06-21 06:48:44 +02:00
Tommaso Bianchi
3fc3b8a8ae belt: anchor the designed-view G-code preview onto the model bounding box
The belt designed (upright) preview back-transforms the machine-frame G-code
into model space with the linear belt inverse. That inverse recovers the
print's shape and orientation, but not the per-object placement/lift
translation: the object's position on the belt, the BeltSliceStrategy min-Z
lift, and the centering pre-translate are applied OUTSIDE
build_forward_transform() (see PrintObjectSlice.cpp), so its linear inverse
cannot undo them. The result was a constant offset (~20 mm on the belt-advance
axis) of the toolpaths from the model shell, on every model.

Recover the missing translation generally — independent of the offset's exact
source or the axis remap — by anchoring the back-transformed object body
(extrusions on layer_id >= 1, i.e. excluding the layer-0 prime/skirt) onto the
upright model bounding box, the same space the shells render in, and folding
that translation into the belt inverse before converting to libvgcode.

Replaces the previous Y=0 anchoring in LibVGCodeWrapper, which pinned the
toolpaths to the belt entry rather than to the model and so left the offset in
place for any object not sitting at the origin.
2026-06-21 06:48:44 +02:00
Tommaso Bianchi
695a1f897a belt: render the G-code preview in model (Cartesian) space
On a belt printer the emitted G-code is in the machine frame (45-deg sheared,
axis-remapped, scaled), so the toolpath preview shows the print as a sheared
slab floating off the bed. Map each toolpath vertex back to model/Cartesian
space for the "designed" view.

The back-transform is the inverse of the full G-code forward pipeline
(BeltGCodeWriter::to_machine_coords):
  model = [BeltForward^-1 if !gcode_back_transform] . AxisRemap^-1 . MachineFrame^-1
built from config, so it handles any rotation / shear / scale / axis-remap
combination, not just plain 45-deg belt slicing. Computed in load_as_gcode()
from print.config() and applied per-vertex inside libvgcode::convert (display
position only; layer_id, times and the volumetric/flow math keep the raw
machine values, so the layer slider and stats are unaffected).

- Toggle with the existing "Show designed view" checkbox / hotkey B; off shows
  the raw machine-frame G-code (useful for debugging the transform itself).
  Defaults to on.
- Belt printers skip the same-result-id load cache so the upright view applies
  and the toggle takes effect even when the G-code is unchanged.
- The object extrusions (layer_id >= 1) are anchored to the belt entry to drop
  the constant machine-origin offset (start-G-code belt advance) that the linear
  back-transform alone does not capture; start-G-code prime lines are excluded
  so they don't steal the anchor.
2026-06-21 06:48:44 +02:00
Tommaso Bianchi
2d69f6e17c belt: expose MachineFrameTransform's composed matrix
Add a const accessor for the shear*scale transform so the G-code viewer can
build the machine->model back-transform for the upright belt preview.
2026-06-21 06:48:44 +02:00
Joseph Robertson
340ce575e2 Merge branch 'main' into belt/baseChanges 2026-06-20 15:56:59 -05:00
Indy Jones
b8dd2d3ca8 Fix start G-code: wait for nozzle temperature before purge line (#14120)
Several Artillery and Flashforge machine profiles set the first-layer nozzle temperature with M104 (set, no wait) immediately before the purge/prime line. The purge then runs before the nozzle reaches temperature, so filament is extruded through a nozzle that is not yet hot enough to melt it. Changed M104 to M109 so the printer waits for the target temperature before purging.

Affected profiles:
- Artillery Sidewinder X3 Plus / X3 Pro / X4 Plus / X4 Pro (0.4 nozzle)
- Flashforge AD5X (0.25/0.4/0.6/0.8)
- Flashforge Adventurer 5M / 5M Pro (0.25/0.8 overrides + shared fdm_adventurer5m_common, which also covers the 0.4/0.6 variants via inheritance)

Refs #4337
2026-06-20 20:16:37 +08:00
Alexandre Folle de Menezes
0335d76d30 Update and complement ptBR translation (#14302) 2026-06-20 13:15:28 +08:00
Mykola Nahirnyi
3e56d25f64 Allow presets without parent 2026-06-20 13:14:46 +08:00
Tobias Gloth
4c149b69eb can build boost, draco, opencv as debug with msvc (#13921)
* can build boost, draco, opencv as debug with msvc

* only forward build configuration for MSVC and in Debug mode
2026-06-20 12:39:08 +08:00
Terasit Juntarasombut
57cb60e20f l10n: Update Thai (th) localization after gettext refactor (#14288) 2026-06-19 20:40:09 -03:00
Surfoo
8ffe84b1dd i18n(fr): improve French localization quality and consistency. (#14293) 2026-06-19 17:09:39 -03:00
Ian Bassi
f4268a0eec Adaptive Pressure Advance Validation (#14198)
Co-authored-by: Wegerich <23041237+Wegerich@users.noreply.github.com>
2026-06-19 15:46:00 -03:00
SoftFever
17e2adc283 CI(macOS): retry flaky hdiutil DMG creation; delete per-arch bundles only on success 2026-06-20 01:15:31 +08:00
Ian Bassi
d87f7e462c Localization fixes (#14291)
* Restore text

* Restore english fuzzys

* Gettext

* Fuzzy for comment

* Gettext
2026-06-19 11:54:53 -03:00
SoftFever
0a6a42ecb5 Add Linux ARM64 (aarch64) AppImage build
Build the Linux AppImage for ARM64 (aarch64) alongside x86_64: the Linux CI
job now matrixes over both architectures, with arch-aware deps caching and
artifact/asset names (amd64 keeps its existing names). The aarch64 AppImage is
published to the nightly and release pages like the x86_64 one.

Run the unit-test suite on the aarch64 runner (faster GitHub arm runner); the
tests are built on that leg. Self-hosted keeps tests on the amd64 server.
2026-06-19 15:57:20 +08:00
Kiss Lorand
762e474433 Skirt overhaul (#14130)
Co-authored-by: Rodrigo Faselli <162915171+RF47@users.noreply.github.com>
2026-06-19 10:43:46 +08:00
Rodrigo Faselli
115d6dde46 ENABLE_SMOOTH_NORMALS (#14080)
* ENABLE_SMOOTH_NORMALS

* Remove definition of macro L if defined

* Update GLModel.cpp

* suavizado ajustado en 5 grados

5 grados

3,5 grados

* Ajuste de brillo menos intenso

* opcion smooth normals

Update GLModel.cpp

test

test 3

* cleaning macros

* tooltip

* Apply suggestion from @RF47

* Apply suggestion from @RF47

* Apply suggestions from code review

Co-authored-by: Rodrigo Faselli <162915171+RF47@users.noreply.github.com>
2026-06-19 09:42:12 +08:00
foXaCe
9da2975424 i18n(fr): complete French catalog after the localization refactor (#14277) 2026-06-18 16:19:24 -03:00
raistlin7447
7b3228d10d Cover the libnest2d nesting engine and fix an NfpPlacer crash (#14267)
* fix(libnest2d): skip the excluded-region alignment pass when there are none

NfpPlacer::finalAlign(), run from clearItems() and the destructor, always
ran the "find a best position inside the NFP of fixed items" pass even when
no items are fixed. With nothing to avoid, calcnfp() computes the inner-fit
NFP of the pile and can feed clipper a coordinate outside its allowed range.
On Linux/clang the value stays in range so it went unnoticed; on MSVC the
clipper "Coordinate outside allowed range" exception escapes the noexcept
destructor and aborts the process (exit 0xC0000409).

Build the excluded set up front and only run the pass when it is non-empty.
The block exists solely to keep the pile clear of fixed items (excluded
regions / wipe tower), so it is a no-op when there are none and the
wipe-tower behaviour is unchanged.

* test(libnest2d): remove dead nesting tests and split the suite by feature

Seven of the suite's hidden [.] test cases drove code paths Orca abandoned
at the BambuStudio fork: BottomLeftPlacer (used nowhere in src/) and the
stock default NfpPlacer backend, which returns zero bins in Orca. They have
been red since the fork and are never registered with ctest. Remove them.

Split the 1,000-line libnest2d_tests_main.cpp into per-feature files, per the
repo convention, sharing a header for the no-fit-polygon backend setup that
every translation unit must agree on (ODR):

  libnest2d_tests.cpp       Item and nest() basics
  test_geometry.cpp         geometry primitives
  test_nfp.cpp              no-fit-polygon machinery
  libnest2d_test_utils.hpp  shared includes and the NFP backend specialisation

Along the way: drop a debug exportSVG() helper that only wrote a file on test
failure (so the suite never leaves stray assets), convert the deprecated
Catch::Approx to WithinRel/WithinAbs matchers, and give the tests descriptive
names.

* test(libnest2d): add NfpPlacer unit tests

NfpPlacer is the placement engine the arranger drives, but the suite only
covered the geometry primitives. Add a fixture and five tests that exercise
pack()/accept() directly: a single item lands in the bin, an oversized item
is rejected, the first item is seeded for every starting point, many items
pack without overlap, and the rotation candidates are searched. This lifts
nfpplacer.hpp line coverage from 42% to 87% in the libnest2d suite.

* test(libslic3r): add arrangement::arrange() integration coverage

The libnest2d suite cannot reach Orca's real nesting entry point because it
does not link libslic3r. Add test_arrange.cpp driving arrangement::arrange():
items land on the bed and within bounds, do not overlap, are spaced by their
inflation, an oversized item stays unplaced, overflow spills onto virtual beds,
an empty input is a no-op, and the DONT_ALIGN and USER_DEFINED final-alignment
paths are exercised. A self-test guards the overlap check the other cases use.
2026-06-18 23:40:37 +08:00
Joseph Robertson
d795900fcf Merge pull request #64 from tommasobbianchi/feat/esun-pla-maxvolspeed-tuning
IdeaFormer IR3 V2: tune eSUN PLA white speed from HW max-vol-speed calibration
2026-06-18 09:42:19 -05:00
Joseph Robertson
9b1fb2217a Merge branch 'main' into belt/baseChanges 2026-06-18 09:41:14 -05:00
Ian Bassi
2de58e557b Lozalization Update after refactor (#14272) 2026-06-18 09:22:31 -03:00
Ian Bassi
514ab02525 Localizations refactor (#14254) 2026-06-18 09:13:51 -03:00
Wegerich
d7688a27d0 APA for overhangs - Prusa incompatibility warning (#14271)
* APA for overhangs - Prusa incompatibility warning

Added a sentence explicitly stating that APA for overhangs is not compatible with prusa printers

* whitespace
2026-06-18 11:46:51 +01:00
Wegerich
c2965a1336 Clarify that "network plugin" now means *bambu* only (#14265)
Clarify that "network plugin" now means *bambu* only and doesn't refer to orca cloud

fully differentiate the two offerings to avoid confusion especially for non Bambu users
2026-06-18 15:10:56 +08:00
Tommaso Bianchi
ef6f65eacc IdeaFormer IR3 V2: tune eSUN PLA white speed from HW max-vol-speed calibration
Physical max-volumetric-speed test (belt #62 v4 asset) on the IR3 V2 with eSUN
PLA white: the wall stayed clean up to ~100 mm/s = ~20 mm3/s before
under-extrusion. The shipped cap of 10 mm3/s was ~half the real ceiling and
was silently throttling infill.

- eSUN PLA @IdeaFormer IR3 V2: filament_max_volumetric_speed 10 -> 20
- 0.20mm Standard @IdeaFormer IR3 V2: sparse_infill_speed 200 (~18 mm3/s at the
  new cap, no longer throttled). Outer wall (45), PA (0.12), accel (1000)
  unchanged — accuracy preserved.
- IdeaFormer.json version bump for profile-cache refresh.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 07:13:59 +02:00
raistlin7447
a587859e84 Fix: show all print validation warnings instead of only the last (#14112) 2026-06-18 12:45:26 +08:00
SoftFever
3ffb9585d2 flatpak: OrcaSlicer was trying to migrate old configs from an io.github.orcaslicer.OrcaSlicer folder — a bundle ID used only in nightly builds between the 2.3.1 and 2.3.2 releases.
The correct old config folder, widely used in pre-2.3.2 releases, is io.github.softfever.OrcaSlicer.
2026-06-18 00:40:22 +08:00
Alexandre Folle de Menezes
af854f3242 Improve and complement the pt-BR translation (#14252) 2026-06-17 23:57:11 +08:00
Noisyfox
9b60b9cd5d Fix wrong variant index is used on motion ability setting tab (#14253)
Fix wrong variant index is used on motion ability setting tab (OrcaSlicer/OrcaSlicer#13308)
2026-06-17 23:54:27 +08:00
SoftFever
927c5efb8c add Chinese translations 2026-06-17 20:53:01 +08:00
SoftFever
81951fddb5 Fix locale errors 2026-06-17 19:10:29 +08:00
Alexandre Folle de Menezes
4535f19501 Misc fixes to GUI strings (#14047)
* Degrees symbol don't need localization

* The Z when referring to the axis should be uppercase

* Fix the spelling of "GitHub" to camelcase

* Unify the casing of mouse button shortcuts

* Always use G-code with an hyphen

* Fix the spelling of "restricted"

* More grammar fixes

* add missing modifications

---------

Co-authored-by: SoftFever <softfeverever@gmail.com>
2026-06-17 17:55:32 +08:00
Jakub Hencl
ee9a796f14 Improve Czech localization translations (#13666)
* Improve Czech localization translations

Updated and improved Czech translations for OrcaSlicer UI strings.

- Fixed untranslated entries
- Improved terminology consistency
- Adjusted wording to better match PrusaSlicer style
- Fixed plural forms and formatting placeholders
- Remaining untranslated strings will be completed later

* fix errors

* reformat

---------

Co-authored-by: SoftFever <softfeverever@gmail.com>
2026-06-17 17:45:16 +08:00
Heiko Liebscher
3bce4bb197 feat: update German localization for various features and error messages (#14201) 2026-06-17 17:18:08 +08:00
Noisyfox
dcee299909 Allow use offline when logged in to Orca Cloud (#14235)
* Store user session information along with refresh token, to allow offline use once user is logged in

* Don't bother with avatar because we won't see it when offline anyway

* Fix offline Sync Presets freezing the UI on repeat clicks

Ignore restart_sync_user_preset() while a manual sync's progress dialog is on screen, so a second app-modal dialog can't stack on the first. Offline the dialog blocks on a long, uncancellable HTTP timeout; on macOS the global menu stays live while the window is disabled, so a second click otherwise wedges the app (force-quit only).

* Skip redundant user-secret re-write on startup

set_user_session() always re-encrypts and writes the secret to disk; on the startup restore path that just rewrites the bytes it was loaded from. Add a persist flag so the restore path skips it. Also drop an unused catch binding and a stray blank line.

---------

Co-authored-by: SoftFever <softfeverever@gmail.com>
2026-06-17 17:15:09 +08:00
SoftFever
9eeb73b68b feat: Support 3MF as g-code (use_3mf option) (#14238)
* feat: add support for 3MF file format in printer configurations and export options

* fix file extension

* enable 3mf for X Max 4

* disable use_3mf for X Plus 4

* Fixed an issue where `label_object_enabled` was not properly propagated to 3mf

* enable exclude object for Max 4

* remove hardcoded use 3mf for flashforge, move them to the new printer profiles config
2026-06-17 15:39:40 +08:00
hamham999
7ab3174f7c Fixing the volumetric speed setting for some Creality filaments (#14237) 2026-06-16 18:16:01 -03:00
Vovodroid
5a6e31ac5b Allow drop of sunken objects (#14243) 2026-06-16 18:13:10 -03:00
Kiss Lorand
e700113b39 Fix non-organic tree support base clearance above object surfaces (#14128) 2026-06-16 15:50:09 -03:00
Grant Harkness
5ed8f5ef25 perf(GCodeProcessor): stop recompiling std::regex on every g-code line (up to 2.9x faster slicing) (#14166)
perf(GCodeProcessor): stop recompiling std::regex on every g-code line

process_SET_VELOCITY_LIMIT() constructed three std::regex objects from
scratch on every call, and Klipper-flavor g-code contains
SET_VELOCITY_LIMIT on a large share of lines (8,834 of 103,549 lines for
a single 3DBenchy sliced for a Creality K2). perf attributes 6.4% of the
whole slicing run to this one function, almost all of it regex
compilation and the allocator traffic it generates.
process_SET_PRESSURE_ADVANCE() and the External_Purge_Tag handler had
the same per-call construction.

Hoist all five patterns to function-local static const std::regex so
they compile once. Generated g-code is byte-identical (modulo the
timestamp header); slicing a 16x Benchy plate for a K2 drops from
78.5s to 27.3s wall (2.9x) on a 16-core Linux box, single Benchy from
8.9s to 5.6s.

Co-authored-by: grant0013 <grant@harktech.co.uk>
2026-06-16 23:51:27 +08:00
raistlin7447
454335dba6 Correct tests/CLAUDE.md: testing framework is Catch2 v3, not v2 (#14231)
The testing guide stated OrcaSlicer uses Catch2 v2 and advised the v2
`<catch2/catch.hpp>` include, but the vendored framework is v3.11.0
(tests/catch2/) and every test file includes `<catch2/catch_all.hpp>`.

The wrong version drove several incorrect claims: that SKIP() is
unavailable (it is, v3.3.0+), that the string matcher is "Contains"
rather than "ContainsSubstring", and that thread-safe assertions,
multiple reporters, STATIC_CHECK and built-in sharding do not exist.

Correct all version statements, the example include, and the
former "Version-Specific Limitations" section to reflect v3.11.0.
2026-06-16 23:00:30 +08:00
Allyn Malventano
b0c1887f40 fix: persist user-selected preview view mode after first load (#13625)
fix: apply smart preview defaults per extruder count session

- Track last extruder count (1=single, 2+=multi) instead of boolean flag
- Apply appropriate default (ColorPrint/FeatureType) when count changes
- User selections persist within same extruder count
- Symmetric behavior: both single and multi actively apply defaults
- Delete duplicate dead code block (uncommented TODO scaffolding)

Behavior:
- First slice (any type) → appropriate default
- User changes view → persists on re-slice
- Switch single→single or multi→multi → persists
- Switch single↔multi → appropriate default applies
2026-06-16 22:15:00 +08:00
raistlin7447
e6f917d7c5 Re-enable [OrcaCloudServiceAgent] headless tests now that the crash is fixed (#14236)
Re-enable [OrcaCloudServiceAgent] tests now that the headless crash is fixed

The two OrcaCloudServiceAgent display-name tests were tagged [NotWorking]
in #14175 because the agent constructor dereferenced a null wxTheApp when
run headless (no wxApp is created in the unit-test binary), crashing before
any assertion ran. That null dereference was fixed in 14d2dfdd4c, which
guards wxTheApp in compute_fallback_path() and skips file persistence when
no fallback path is available.

With the fix in place both tests build and pass headless, so drop the
[NotWorking] tag and the stale explanatory comments. Verified on Linux
clang-18 (the CI compiler), headless: 20 assertions in 2 test cases pass.

Closes #14193
2026-06-16 22:14:13 +08:00
Joseph Robertson
0add523e1b Merge branch 'main' into belt/baseChanges 2026-06-13 08:23:47 -05:00
Joseph Robertson
375036f330 Merge pull request #44 from tommasobbianchi/feat/belt-skip-height-check
belt: don't reject long objects (skip build-height check on belt printers)
2026-06-13 08:23:26 -05:00
Joseph Robertson
fbbeb1fab0 Merge pull request #58 from HarrierPigeon/belt/tempTower-TommyB
Belt/temp tower tommy b
2026-06-12 05:53:32 -05:00
harrierpigeon
0bca3fd2e5 make belt printer specific temp tower only accessible to belt printers 2026-06-12 05:13:08 -05:00
Tommaso Bianchi
85fd613cf7 feat(belt/calib): add Overhang temperature-tower model (selectable) (#48)
Belt printers can't slice a tall vertical temperature tower. This adds a
belt-specific temperature-tower model — a row of discrete, individually
engraved provini laid along the belt, each printed at one temperature via
custom per-layer M104. Each provino is an inverted-L overhang that stresses
print quality, so the operator reads the best temperature off overhang
quality rather than a continuous ramp.

It is offered as a "Test model" choice in the temperature calibration dialog
(mirroring the Cornering test's selector), so users keep Joe's counter-rotated
sectioned tower as "Standard" and can pick this one as "Overhang":
- Calib_Params::test_model (existing field) carries the choice.
- Temp_Calibration_Dlg gets a Standard/Overhang radio.
- Plater::calib_temp belt branch: test_model 0 -> _calib_temp_belt_sectioned
  (unchanged Standard path), 1 -> the discrete-provini Overhang path.

Assets: belt_temp_provino_unit.stl + belt_temp_tower_<start>_<end>.stl (6
ranges) + gen_belt_temp_tower.py (manifold engraving). Based on
belt/generic-calibrations. The Overhang path is HW-validated on the IdeaFormer
IR3 V2 (discrete M104 + engraved numbers); not re-validated since the rebase.
2026-06-12 05:13:07 -05:00
Joseph Robertson
0da24cd38b Belt/Standard calibrations (#54)
Enables supported printing of standard Orcaslicer calibration profiles.

* Build 2 Checkpoint

* fix support generation wedge, ghost layers

* flip cornering tests 180 deg to waste less supports

* fix row spacing on the flow ratio calibrations

* more testing, this didn't fix anything

* switched rotation tools, same issue

* fixed Z-offset issues

* add rest of PA features, may look a bit weird on a belt

* make temp towers work

* re-enable spiral on calibrations that want it

* Final cleanup pre-PR and community testing
2026-06-12 03:14:12 -05:00
Rodrigo Faselli
d7b75540d0 Merge branch 'main' into belt/baseChanges 2026-06-11 11:59:53 -03:00
Tommaso Bianchi
b7bda9912b belt: fix IR3 V2 end G-code reversing the belt into the part (#56)
The IdeaFormer IR3 V2 End G-code ran `G28 ; home all`, which homes the
Z (belt) and Y (gantry) axes. On a belt printer Z is the conveyor, so
homing it runs the belt all the way back to origin, dragging the finished
part back under the gantry that G28 has just lowered — the head knocks the
print (reported by an IR3 V2 user; the `G1 Y50` lift came after the G28,
too late).

Replace the end sequence with a belt-safe one: switch to relative mode
(G91), lift the gantry for clearance, advance the belt forward one full
machine-depth (Z676, the 676 mm product depth) to eject the part and cycle
the belt surface clean, then home X only — never the Z/belt axis.
2026-06-11 09:30:35 -05:00
Tommaso Bianchi
4f3a608009 belt: don't flag the lead-in as an empty-layer error on belt printers (#47)
collect_layers_to_print() warns (CRITICAL) when an extrusion layer sits above
the previous one with an empty gap below — the fixed-bed assumption that
material with nothing under it is floating and unprintable. On a belt printer a
*leading* empty range (the gap starts at Z=0, no prior extrusion layer) is not
floating: it is the conveyor lead-in, and the part rests on the advancing belt
as the first material is laid down well above Z=0. A part not designed for a
belt (e.g. a flat test model tilted into the belt frame) then trips this as a
false "Object can't be printed for empty layer between 0 and N" error.

Suppress only the leading case (belt_printer && last_extrusion_layer == null);
genuine internal gaps are still flagged, since on a belt those can be an
over-angle overhang printing into air. Non-belt output is unchanged.
2026-06-10 23:54:02 -05:00
Tommaso Bianchi
f682ab5cd3 belt: replace height-check skip with a belt-correct vertical-clearance check
The original PR skipped the max-print-height check entirely on belt printers
because the sliced (virtual) Z is belt travel, not build height. As the reviewer
noted, that removed the only working height guard. Restore a correct guard:

- Print::validate: on belt printers, compare the upright object height
  (max over instances of the scene-space bbox) against printable_height directly.
  printable_height is the usable VERTICAL clearance above the belt: the gantry
  travels up the tilted plane (reach = height/cos(tilt)) and its axis range is
  sized for that (IR3 V2: ~354 mm gantry travel = 250 mm vertical at 45deg, and
  printable_height = 250). Hardware-confirmed 250 mm vertical clearance, so no
  cos(tilt) factor is applied.
- BuildVolume::set_belt_printer: drop the diagonal Z scaling; the build-volume Z
  already equals printable_height, keeping the live 'outside build volume'
  highlight in agreement with validate().

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 21:41:18 +02:00
harrierpigeon
2bcb775b90 update IdeaFormer profiles to new generic belt printer config 2026-06-10 05:10:20 -05:00
Joseph Robertson
e29a82c672 add attribution and design notes 2026-06-10 05:10:20 -05:00
Joseph Robertson
5b243eec92 Relocate Pre-Slice remap logic 2026-06-10 05:10:20 -05:00
Joseph Robertson
fee6be98b2 unify frame tilt work 2026-06-10 05:10:20 -05:00
Joseph Robertson
9405ac5976 remove mesh origin snapping 2026-06-10 05:10:20 -05:00
Tommaso Bianchi
6ed2437848 Add IdeaFormer IR3 V2 belt printer profile - credit: tommasobbianchi (#43)
* Add IdeaFormer IR3 V2 belt printer profile

Self-contained vendor profile for the IdeaFormer IR3 V2 (45 deg belt printer):
machine (0.4 nozzle) + 0.20mm process + Generic PLA/PETG filaments, with the
belt machine-frame transforms set explicitly on the machine preset
(belt_printer, belt_slice_rotation x/45/global, build_plate_tilt_x=45,
gcode_remap_x/y/z, gcode_shear_z=pos_tan, gcode_scale_y=inv_cos).

The vendor bundles its own machine/process commons (fdm_belt_common,
fdm_klipper_common, fdm_machine_common, fdm_process_common) on purpose:
OrcaSlicer resolves system-preset inheritance per-vendor, so a profile that
inherits the Custom vendor's commons cross-vendor fails to resolve its parent
and the whole IdeaFormer vendor silently fails to load. Bundling the commons
(and listing them in IdeaFormer.json in dependency order) keeps the vendor
self-contained, matching how every other vendor folder is structured.

Machine limits, bed temperature (75 C for belt PLA) and start/end G-code are
taken from a working IdeaFormer IR3 V2.



* feat(belt/profile): eSUN PLA @IdeaFormer IR3 V2 — HW-calibrated belt filament

Add an eSUN PLA belt profile for the IR3 V2, inheriting Generic PLA @IdeaFormer
IR3 V2 (self-contained: parent is in the same IdeaFormer vendor, registered
after it in filament_list). HW-calibrated on the IR3 V2:
- nozzle_temperature 200/200 (temp-tower calibration)
- pressure_advance 0.12 (PA calibration)
- filament_max_volumetric_speed 10 mm³/s (max-vol-speed calibration: wall
  failed at 126 mm/s → 126 × 0.0798 mm³/mm ≈ 10 mm³/s)
2026-06-10 04:13:56 -05:00
Joseph Robertson
da3fee2dfa Merge branch 'main' into belt/baseChanges 2026-06-05 11:55:44 -05:00
Joseph Robertson
c0d6ae8540 Merge branch 'main' into belt/baseChanges 2026-06-05 03:12:27 -05:00
Joseph Robertson
573e1c6544 Belt/fix profiles and minor oopsies (#42)
* fix duplicate printer, bump version

* clean up extra tab in space

* fix generic defaults
2026-06-05 03:11:38 -05:00
Rodrigo Faselli
20be78a96e Merge branch 'main' into belt/baseChanges 2026-06-04 17:32:35 -03:00
Joseph Robertson
02d45c3258 Finish Fixes from Copilot Review (#39)
* fix: restore BuildVolume bounds when toggling belt mode

set_belt_printer() mutated m_bboxf when enabling but never restored
the original extents on disable or when switching infinite_y true->false,
leaving stale max.y/max.z values that broke collision and object_state
checks. Recompute m_bboxf from m_bed_shape + m_max_print_height at the
top of each call, then apply belt-specific adjustments on top.

Addresses Copilot review comment on PR #12998 (BuildVolume.cpp:196).

* chore: drop [BELT-DEBUG] to_machine_coords log to trace

Was emitting at warning level once per 0.2mm Z bucket during every belt
print export, polluting default user logs. Trace level matches the rest
of the belt diagnostics and is silent in production.

Addresses Copilot review comment on PR #12998 (BeltGCodeWriter.cpp:86).

* chore: drop [BELTRACE] make_perimeters/support logs to trace

Eight warning-level traces around make_perimeters and
generate_support_material were emitting on every call/exit during normal
slicing, cluttering default logs. They're concurrency-debug breadcrumbs
not user-facing diagnostics, so drop them to trace.

Addresses Copilot review comment on PR #12998 (PrintObject.cpp:438).

* perf: gate BeltSliceStrategy diagnostic bbox tracking behind compile flag

apply_to_trafo() walked every model vertex twice (once for min_z, once
for per-volume mesh/slicer bboxes) and emitted seven trace logs per
call. The bboxes and logs are diagnostic only; min_z is the load-bearing
output. Wrap the bbox accumulation, logging, and supporting headers in
SLIC3R_BELT_DIAGNOSTIC_LOG so production builds do the bare min_z scan.

Addresses Copilot review comment on PR #12998 (BeltSliceStrategy.cpp:95).

* fix: apply part_cooling_fan_min_pwm to first-layer plane fan crossings

apply_first_layer_plane_fan_eval emitted band-crossing M106 commands
through GCodeWriter::set_fan() without the per-printer PWM floor that
every other set_fan call in CoolingBuffer applies. On printers with a
non-zero part_cooling_fan_min_pwm, fans could fail to spin up at low
requested speeds near the belt surface.

Addresses Copilot review comment on PR #12998 (CoolingBuffer.cpp:1227).
2026-06-04 14:40:45 -05:00
harrierpigeon
f9888c7d7a Merge remote-tracking branch 'upstream/main' into belt/baseChanges 2026-05-31 05:17:32 -05:00
Joseph Robertson
0bda684dd7 delete mesh transforms (#37)
* delete mesh shear, scale and refactor logger

* clean up config options

* reorder UI elements
2026-05-31 05:08:42 -05:00
Joseph Robertson
8a578cdf00 Merge branch 'main' into belt/baseChanges 2026-05-30 21:39:03 -05:00
Rodrigo Faselli
6b256db012 Merge branch 'main' into belt/baseChanges 2026-05-28 07:44:43 -03:00
Joseph Robertson
2dc4900292 Copilot review fixes & upstream code interaction fix (#34)
* first pass at review issue 8
* delete detritus
* fix build compile error due to upstream changes
2026-05-27 21:53:04 -05:00
Joseph Robertson
0f75d6bc4e Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-05-27 19:25:02 -05:00
Joseph Robertson
e913621369 Merge branch 'main' into belt/baseChanges 2026-05-27 11:50:16 -05:00
Joseph Robertson
48b6db93b8 Belt/slice rotate (#33)
* initial commit
* fix upper bounds for assemblies
* significantly less Z shift issues, still not quite tamped down yet though
* add instrumentation to logs
* finally found the issue
* update printer defaults
2026-05-27 11:45:38 -05:00
Joseph Robertson
72cafcbe06 Merge branch 'main' into belt/baseChanges 2026-05-22 15:23:07 -05:00
Joseph Robertson
a9bae54f20 Rotate instead of shear for slicing stage (#30)
* initial commit

* fix upper bounds for assemblies

* significantly less Z shift issues, still not quite tamped down yet though

* add instrumentation to logs

* finally found the issue

* update printer defaults
2026-05-22 15:21:33 -05:00
Joseph Robertson
218881c6f6 fix assembly bounding box truncation problems noticed by hotcubcar (#28) 2026-05-20 02:46:41 -05:00
Joseph Robertson
cd5fb68d38 Merge branch 'main' into belt/baseChanges 2026-05-19 23:00:14 -05:00
Joseph Robertson
f87a46ec6e fix X mirroring (#26)
Thanks to @hotcubcar for catching this!
2026-05-19 22:54:50 -05:00
Rodrigo Faselli
8dc91d8b1d Merge branch 'main' into belt/baseChanges 2026-05-19 08:06:57 -03:00
Joseph Robertson
da8b11b8ab HOTFIX: update generic belt printer profile (#23)
oops
2026-05-19 01:06:39 -05:00
Joseph Robertson
c79970bedb Clean Up Settings Interface, Update Generic Profile (#22)
* clean up UI elements

* further cleaning

* final cleanup for first round of settings UI streamlining

* update generic belt printer settings

* fix generic again
2026-05-19 00:56:08 -05:00
harrierpigeon
7252f6acb7 Merge upstream/main into belt/rebase/may-18
Reconciles the belt-printer branch with upstream PRs through #13723. Six
files had conflicts; three additional files needed manual follow-up fixes
where the auto-merge produced code that referenced upstream-renamed fields
or changed function signatures.

Notable reconciliations:
- TreeSupport.cpp: kept belt-floor early-exit branches around HEAD's
  drop-down logic, folded upstream's `(distance_to_top > 0 ? 1 : 0)`
  formula into the non-belt-floor path (upstream PR #11812). Dropped dead
  `roof_enabled`/`force_tip_to_roof` locals.
- TreeSupport3D.cpp: combined upstream's safety-offset + remove_small
  changes with HEAD's belt-floor clip in the per-slice trim loop. Dropped
  HEAD's `else` block (superseded by upstream's rewritten bottom-contact
  propagation) and re-added the belt-floor clip into the new propagation
  loop. Gated the propagation on belt printers to prevent OOM when
  belt-floor clipping produces empty initial slices.
- TriangleSelector.{cpp,hpp}: merged both new `select_patch` parameters
  (HEAD's `up_direction` and upstream's `select_partially`); body uses
  `dot(up_direction)` for the overhang angle check and forwards
  `select_partially` to `select_triangle`.
- SupportMaterial.cpp: `slicing_params.soluble_interface` →
  `zero_gap_interface_bottom` in HEAD's `detect_belt_floor_bottom_contacts`,
  matching upstream's same-purpose rename at line 2495.
- Custom.json, GCodeWriter.cpp: simple additive merges (kept entries /
  includes from both sides).

Verified by building OrcaSlicer (RelWithDebInfo) after a full deps
rebuild (Eigen v5.0.1, libigl v2.6.0 are now managed deps) and slicing
a scaled Benchy on the NORMALIZER belt-printer profile without OOM.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-18 21:53:24 -05:00
Joseph Robertson
6a2d690f45 Decouple Slicing From Machine Frame Logic (#21)
* minor logic swap

* first attempt, has a race condition

* fixed the offset issue

* found a solution, I think things work now (at least once I quash this race condition)

* still chasing down race conditions

* add manual shear / scale order strategy swap

* tweak manual shear, fix ui uninitialization crash

* fix z height / g-code desync issue

* fix shear then scale cutoff planes

* getting closer

* fix support termination planes

* fix incorrect offsets in shear-then-scale mode

* test - fix overextrusion due to model/layer scale
2026-05-18 19:01:43 -05:00
RF47
8fa6a4602b fix profile indentation 2026-05-09 19:51:18 -03:00
harrierpigeon
0f29437135 Merge remote-tracking branch 'upstream/main' into belt/baseChanges
Conflicts resolved in src/libslic3r/GCode.cpp and src/slic3r/GUI/GUI_Factories.cpp.

GCode.cpp: combined upstream's air-filtration per-extruder gating
(activate_air_filtration_during_print / _on_completion), the new
extrusion-role-change gcode lambda, ZAA's path.z_contoured arc-fit
disable, raft-aware slow_down_layers branch, and Vec3d/Line3 ZAA
plumbing with the local belt-printer changes (path_on_first_layer,
effective_layer_index_for_point, should_disable_arc_fitting). All
auto-merged m_writer.X() calls converted to m_writer->X() to match
the local unique_ptr<GCodeWriter> refactor.

GUI_Factories.cpp: inserted brim_flow_ratio in the Support category
list and renumbered around the local build_plate_tilt_x/y entries.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 16:23:41 -05:00
SoftFever
75cc0de071 Merge branch 'main' into belt/baseChanges 2026-04-17 15:44:03 +08:00
Joseph Robertson
bc6d0ef0fb Add first layer detection and fan control - prototype 2026-04-13 22:29:23 -05:00
Joseph Robertson
c17ae25bbc Merge branch 'main' into belt/baseChanges 2026-04-13 21:34:34 -05:00
harrierpigeon
e981a517cd Merge branch 'belt/global-mesh-transform' into temp-pr19-merge 2026-04-10 11:49:37 -05:00
harrierpigeon
0703728e56 add global mesh transform option 2026-04-10 11:39:08 -05:00
SoftFever
1e9ee0c120 add a generic belt printer 2026-04-09 23:07:08 -05:00
harrierpigeon
e9a579b604 switch default shear axis, swap to tan(a) instead of cot(a) 2026-04-09 23:07:07 -05:00
harrierpigeon
783acd932a revert CLAUDE.md 2026-04-09 23:07:07 -05:00
harrierpigeon
c8a1bf3a99 Part 3.2: decouple axis remapping, enable viewing settings in Developer mode or when Belt mode is active 2026-04-09 23:07:07 -05:00
harrierpigeon
2facaac9e8 Part 3.1: refactor BeltTransform pipeline
add BeltGCodeWriter

add BeltGCode

consolidate changes into shared classes for BeltGcode
2026-04-09 23:07:07 -05:00
harrierpigeon
9bbac19de4 Part 2.7: Add G-code back-transform and tree support belt floor clipping
- Add BeltBackTransform class that inverts the shear/scale matrix and
  applies it in GCodeWriter::to_machine_coords() so G-code outputs in
  the machine's physical coordinate space, gated by new
  belt_gcode_back_transform config option
- Extend belt floor clipping to all three tree support pipelines
  (Prusa-style, Orca organic, TreeModelVolumes) with per-layer polygon
  clipping, anti-overhang integration, and belt raft extension layers
- Fix tree drop_nodes() belt termination, organic support global Z
  offset, collision calculation index bug, and first-layer brim/empty
  layer checks for belt printers

two-shot - first build built but didn't plumb to UI.  Woah.

add pre-slice axis remap, because Y needs to be Z

going to change tactic and move based on bbox min

switch to per axis snapping

per axis swap snap now per object

build plate tilt wasn't invalidating slicer settings

support upper bound now correct, need to get lower bound corrected

axis swapped support termination corrected

Z Shear works with and without pre-slice remap now
2026-04-09 23:07:07 -05:00
harrierpigeon
ea5c6776b3 Part 2.6: Add belt floor support clipping for all support types
- Fix support clipping z-shift calculation by removing coordinate-space
  mismatch and sync belt_floor_z_shift with global_z_offset; fix
  invalidation so posSupportMaterial no longer resets slicing params
- Add belt floor polygon clipping to non-organic tree support
  (slim/strong/hybrid) with collision surface integration in
  TreeSupportData, belt extension layers, and first-layer brim
  suppression
- Add belt floor clipping to organic tree support pipeline with virtual
  belt raft layers, per-layer polygons in TreeModelVolumes, and
  post-generation layer trimming; fix pre-existing processing_last_mesh
  bug in calculateCollision()

Fix belt floor support clipping: z-shift, invalidation, and global offset

- Fix support clipping z-shift calculation by removing coordinate-space
  mismatch (raw_bounding_box min.z vs trafo_centered m_belt_min_z) and
  sync belt_floor_z_shift with global_z_offset in global shear mode
- Fix invalidation so posSupportMaterial no longer resets slicing params,
  preventing the exact posSlice z-shift from being overwritten by the
  bounding-box approximation on support-only setting changes
- Remove double-counting of global z_offset on support layers — support
  already inherits the offset from object layers during generation

This Work Was Co-Authored-By Claude Opus 4.6 (1M context) <noreply@anthropic.com>

UI: gray out inactive belt sub-options, rename to mesh transforms, move to Advanced

Fix mesh clipping through build plate after belt shear/scale transform

Generalize G-code viewer designed-view toggle for full belt transform

Clip support layers to transformed belt floor plane

Supports below the tilted build plate (Z = shear_factor * from_axis - min_z)
are now clipped via half-plane intersection after generation. Belt floor
parameters stored in SlicingParameters and populated in both update_slicing_parameters()
and the static slicing_parameters() overload.

Make belt G-code viewer toggle more prominent, add B keyboard shortcut

- Add separator + teal "Belt Printer" header in legend panel
- Append [B] hint to checkbox label
- Add B key shortcut in GLCanvas3D to toggle designed/machine view
- Read belt_printer_angle from loaded G-code headers to enable belt view

Add per-axis global transform option for belt printer shear

New belt_shear_{x,y,z}_global bool configs. When enabled, shear incorporates
instance shift so objects at different bed positions get position-aware
transform (Z += factor * instance_shift_on_from_axis).

Fix global shear: use layer Z offset instead of mesh transform, add config invalidation

- Global shear offset applied as post-slicing layer print_z adjustment
  instead of mesh transform (which was absorbed by min_z normalization
  or shifted mesh out of slice range)
- Register all belt transform options in Print::invalidate_state_by_config_options
  to trigger posSlice re-slicing (the fallback only invalidated Print steps,
  not PrintObject steps — belt changes had no effect without manual re-slice)
- Belt gcode remap options added to steps_gcode (gcode-export only)
- Skip empty-first-layer check for belt objects with global Z offset

WIP: split instances for global shear, relative Z offsets, debug logging

- PrintApply: when belt global mode active, prevent instance grouping by
  adding unique Z perturbation to trafo — each copy becomes its own
  PrintObject with independent layers
- PrintObjectSlice: compute global Z offset relative to minimum Y shift
  across all PrintObjects (lowest-Y object stays at Z=0)
- Debug logging (warning level) for belt global shift values and offsets

Known issues:
- Cached posSlice results cause stale offsets when mixing copies with
  individually-added objects — need to compute min baseline outside slice()
- Supports still generate to Z=0 instead of object's global Z offset

Fix global shear for copied objects: disable shared-object layer optimization

When belt global Z shear is active, each object needs unique layer Z
values based on its bed position. The shared-object optimization was
causing copies to reuse the source object's layers (and its Z offset)
instead of computing their own position-based offset.

started work on getting supports to work properly

one step forward, one step back

this version didn't quite work.  Getting somewhere though

about to add UI controllable tests

added configuration options for supports

tweak CLAUDE.md to be more aggressive for my machine.  This commit should probably be pulled out before contributing upstream

still chasing down some bugs

moving objects between slices no longer results in improper Z-height because of caching

added more data to the debug logs

Z offset is getting more global again

still not quite there, I think there's a fundamental logic flaw?

hunting for bugs

finally have a functional fix

Add belt floor clipping to tree supports (organic and non-organic)

- Add belt floor polygon clipping to non-organic tree support
  (slim/strong/hybrid) in draw_circles() and terminate nodes at the
  belt surface instead of the horizontal build plate
- Add belt floor clipping to organic tree support pipeline with virtual
  belt raft layers for sub-floor branch generation, per-layer belt
  floor polygons in TreeModelVolumes, and post-generation layer trimming
- Fix pre-existing processing_last_mesh bug in TreeModelVolumes that
  prevented m_anti_overhang (support blockers) from ever being applied;
  skip empty first layer check for belt printers

Commits:

current approach: make a face surface to build supports to

closer!

supports now terminate on shear plane, now need to get shear plane to correct Z height

nearly there

chasing down logic issues still

committing for checkpoint, this still does not work

still got logic problems...

cull support clipping

stashing changes for now.  Going to focus on getting the global shear OFF support generation dialed first.

beginning per object shear calcs

Local shear transform is on correct Z offset now

local shear finally works now and needs more testing

global shear works now, needs thorough testing

debugging non-45 degree angles

debugging part 2

supports at all angles work now

remove debug logging

Add belt floor collision to non-organic tree support pipeline

- Integrate belt floor as a collision surface in TreeSupportData so
  branches route around the belt naturally, replacing the explicit
  termination checks in drop_nodes()
- Add belt extension layers below the object after draw_circles() to
  allow support geometry to extend to the diagonal belt surface instead
  of terminating at a horizontal first layer
- Fix coordinate overflow in belt floor polygons (scale_(1e4) exceeds
  int32), skip first-layer brim expansion for belt printers, and
  extend empty first layer check bypass to all belt modes

add debug logging, Z translate for tree supports

still not seeing any cutoff surface yet

adding debug options

attempt #2 at trees

if hit Z buildplate stop but don't set to_buildplate true

getting closer

tree support almost there, just need to get rid of the circles at the beginning

getting closer

belt / shear plane clip works, need to figure out the buidlplate plane issues

more logic, added debugging logs

supports now extend somewhat below Z=0 in global shear mode

fix bad alloc, add 10mm below build plate

fully works now

shear transform + prusa tree support generation works now.

pull out debug logging
2026-04-09 23:07:07 -05:00
harrierpigeon
98f4d34dcb Part 2.5: Add global shear transform, support clipping, and belt UI improvements
- Implement per-object global shear transform in PrintObject with
  layer Z-offset calculation, config invalidation, and fix for
  shared-object layer optimization breaking copied objects
- Clip support layers to the transformed belt floor plane and begin
  work on tree support adaptation for sheared coordinate space
- Improve belt UI: gray out inactive sub-options, add B keyboard
  shortcut for G-code viewer design-view toggle, fix mesh clipping
  through build plate after shear/scale transform

y' = y + z·cot(α),
  while x' = x and z' = z

getting closer to customizable variant

getting closer

X/Y/Z shear initial

clean up UI

add 1/sin(a) transform, idea taken from blackbelt cura plugin

Things work now (turns out I've been using the wrong set of  transforms)
2026-04-09 23:07:07 -05:00
harrierpigeon
501aff7e53 Part 2: Replace belt rotation w/ per-axis shear transforms and G-code axis remap
- Replace monolithic belt rotation transform with independent per-axis
    shear controls (mode/angle/source-axis for X, Y, Z) and G-code axis
    remapping, giving full flexibility to match any belt printer's
    coordinate system
  - Remove all rotation mode logic and intermediate type+axes dropdowns,
    simplifying the pipeline to pure shear matrices while preserving the
    default behavior (Y += Z*cot(45deg) with identity remap)
  - Clean up GCodeWriter, GCodeProcessor, and GCodeViewer for the new
    shear-only model; expose 12 new settings in printer UI via
    Tab.cpp/Preset.cpp

Implement belt printer tilted slicing

Implement the core belt slicing pipeline that makes the slicer
tilt-aware:

Step 1: GCodeWriter::to_machine_coords() - R(+alpha, X) rotation
  from slicing frame to machine frame
Step 2: PrintObject - belt-rotated object height calculation
  (y*sin(a) + z*cos(a)) for correct layer count
Step 3: PrintObjectSlice - apply R(-alpha, X) rotation trafo so
  horizontal slice planes correspond to belt-parallel planes,
  with Z-shift computed from model volumes
Step 4: GCodeProcessor - machine-frame preview (no transform needed)
Step 5: 3DBed - rotate bed visualization about X by belt angle

Fix: belt surface IS the build plate, no mesh rotation

Currently still slicing perpendicular to the belt normal.  Need to figure out why.

Fix G-code Z sign: use R(-alpha, X) so Z+ is away from belt

The previous R(+alpha, X) transform produced negative Z values
(-y*sin(a) term dominated). Changed to R(-alpha, X) which gives
machine_z = y*sin(a) + z*cos(a), always positive for points
above the belt surface. Z increases with each layer as expected.

reverting and changing slice methodology

Add pink slicing direction arrow from origin

Shows the effective slicing direction (gantry normal) as a pink
arrow from the origin. Shorter and wider than the gravity arrow.
Direction: R(+alpha, X) * Z = (0, -sin(a), cos(a)), which is
the layer stacking direction in the original mesh frame.

Fix slicing arrow visibility and add raw G-code toggle

- Disable depth test for pink slicing arrow so it renders on top of
  the tilted bed geometry (was being occluded)
- Remove unnecessary 5mm Z-offset from arrow position
- Add m_belt_show_raw toggle to GCodeViewer
- Add "Show raw G-code (slicing frame)" checkbox in legend when
  belt mode is active

Implement to_machine_coords inverse rotation for belt printer G-code

The slicing pipeline rotates the mesh by R(-alpha, X) and shifts Z to
start at 0. The G-code output now undoes this transform via
to_machine_coords: R(+alpha, X) * T(0,0,+z_shift), recovering the
original machine-frame coordinates where Y is horizontal and Z is
vertical.

Changes:
- GCodeWriter: implement to_machine_coords with inverse rotation + Z-shift
- GCodeWriter: add belt_z_shift member and setter/getter
- GCode.cpp: compute Z-shift from print objects (same logic as
  PrintObjectSlice) and pass to writer; write z_shift to G-code header
- GCodeProcessor: parse belt_z_shift from G-code header
- GCodeViewer: store belt_z_shift from processor result

Wire raw G-code toggle to apply slicing-frame view transform

When "Show raw G-code (slicing frame)" is checked in the preview
legend, the view matrix is modified to apply R(-alpha, X) * T(0,0,-z_shift)
to the toolpath rendering. This shows the G-code as it was during
slicing: rotated part with horizontal layers.

Default (unchecked): machine-frame view — upright part with tilted layers.

Remove belt printer placeholder comment from GCodeProcessor

The preview now correctly displays machine-frame G-code with the
optional raw view toggle. No transform is needed in the processor.
2026-04-09 23:07:06 -05:00
harrierpigeon
c808653565 Add belt printer transform pipeline: slicing rotation, G-code coords, preview
- Implement core belt slicing pipeline: R(-alpha, X) mesh rotation in PrintObjectSlice with corrected object height calculation for proper layer count
Add to_machine_coords() in GCodeWriter to convert slicing-frame coordinates back to machine-frame, propagated through GCode,
GCodeProcessor, and GCodeViewer
Add belt-mode UI: tilted bed visualization, slicing-direction arrow, and raw G-code toggle to switch between machine-frame and slicing-frame views

This is a combination of 6 commits.

checkpoint 1: initial MVP.  Slicing functions, but rotates instead of skews are happening and a lot of other stuff too

getting somewhere, getting to the point where I need to figure out how to verify this stuff

this appears to be a dead end.

getting somewhere I think maybe

I'm pretty sure we've completely lost the plot at this point and need to restart this process...

remove slice logic in preparation for new, more invasive plan
2026-04-09 23:07:06 -05:00
harrierpigeon
a7441c7f48 stage in changes from off-plate-gravity and remove stuff I didn't need 2026-04-09 23:07:06 -05:00
SoftFever
3bc13e5cfd add a generic belt printer 2026-04-07 10:37:34 +08:00
SoftFever
141749a6f2 Merge branch 'main' into belt/baseChanges 2026-04-06 22:52:31 +08:00
harrierpigeon
4634a5dfd7 switch default shear axis, swap to tan(a) instead of cot(a) 2026-03-30 13:25:40 -05:00
harrierpigeon
372139c770 revert CLAUDE.md 2026-03-30 13:25:40 -05:00
harrierpigeon
44eebdb8ad Part 3.2: decouple axis remapping, enable viewing settings in Developer mode or when Belt mode is active 2026-03-30 13:25:40 -05:00
harrierpigeon
c7aa4ca3ef Part 3.1: refactor BeltTransform pipeline
add BeltGCodeWriter

add BeltGCode

consolidate changes into shared classes for BeltGcode
2026-03-30 13:25:40 -05:00
harrierpigeon
b297f68921 Part 2.7: Add G-code back-transform and tree support belt floor clipping
- Add BeltBackTransform class that inverts the shear/scale matrix and
  applies it in GCodeWriter::to_machine_coords() so G-code outputs in
  the machine's physical coordinate space, gated by new
  belt_gcode_back_transform config option
- Extend belt floor clipping to all three tree support pipelines
  (Prusa-style, Orca organic, TreeModelVolumes) with per-layer polygon
  clipping, anti-overhang integration, and belt raft extension layers
- Fix tree drop_nodes() belt termination, organic support global Z
  offset, collision calculation index bug, and first-layer brim/empty
  layer checks for belt printers

two-shot - first build built but didn't plumb to UI.  Woah.

add pre-slice axis remap, because Y needs to be Z

going to change tactic and move based on bbox min

switch to per axis snapping

per axis swap snap now per object

build plate tilt wasn't invalidating slicer settings

support upper bound now correct, need to get lower bound corrected

axis swapped support termination corrected

Z Shear works with and without pre-slice remap now
2026-03-30 13:25:40 -05:00
harrierpigeon
7ff6bc42b1 Part 2.6: Add belt floor support clipping for all support types
- Fix support clipping z-shift calculation by removing coordinate-space
  mismatch and sync belt_floor_z_shift with global_z_offset; fix
  invalidation so posSupportMaterial no longer resets slicing params
- Add belt floor polygon clipping to non-organic tree support
  (slim/strong/hybrid) with collision surface integration in
  TreeSupportData, belt extension layers, and first-layer brim
  suppression
- Add belt floor clipping to organic tree support pipeline with virtual
  belt raft layers, per-layer polygons in TreeModelVolumes, and
  post-generation layer trimming; fix pre-existing processing_last_mesh
  bug in calculateCollision()

Fix belt floor support clipping: z-shift, invalidation, and global offset

- Fix support clipping z-shift calculation by removing coordinate-space
  mismatch (raw_bounding_box min.z vs trafo_centered m_belt_min_z) and
  sync belt_floor_z_shift with global_z_offset in global shear mode
- Fix invalidation so posSupportMaterial no longer resets slicing params,
  preventing the exact posSlice z-shift from being overwritten by the
  bounding-box approximation on support-only setting changes
- Remove double-counting of global z_offset on support layers — support
  already inherits the offset from object layers during generation

This Work Was Co-Authored-By Claude Opus 4.6 (1M context) <noreply@anthropic.com>

UI: gray out inactive belt sub-options, rename to mesh transforms, move to Advanced

Fix mesh clipping through build plate after belt shear/scale transform

Generalize G-code viewer designed-view toggle for full belt transform

Clip support layers to transformed belt floor plane

Supports below the tilted build plate (Z = shear_factor * from_axis - min_z)
are now clipped via half-plane intersection after generation. Belt floor
parameters stored in SlicingParameters and populated in both update_slicing_parameters()
and the static slicing_parameters() overload.

Make belt G-code viewer toggle more prominent, add B keyboard shortcut

- Add separator + teal "Belt Printer" header in legend panel
- Append [B] hint to checkbox label
- Add B key shortcut in GLCanvas3D to toggle designed/machine view
- Read belt_printer_angle from loaded G-code headers to enable belt view

Add per-axis global transform option for belt printer shear

New belt_shear_{x,y,z}_global bool configs. When enabled, shear incorporates
instance shift so objects at different bed positions get position-aware
transform (Z += factor * instance_shift_on_from_axis).

Fix global shear: use layer Z offset instead of mesh transform, add config invalidation

- Global shear offset applied as post-slicing layer print_z adjustment
  instead of mesh transform (which was absorbed by min_z normalization
  or shifted mesh out of slice range)
- Register all belt transform options in Print::invalidate_state_by_config_options
  to trigger posSlice re-slicing (the fallback only invalidated Print steps,
  not PrintObject steps — belt changes had no effect without manual re-slice)
- Belt gcode remap options added to steps_gcode (gcode-export only)
- Skip empty-first-layer check for belt objects with global Z offset

WIP: split instances for global shear, relative Z offsets, debug logging

- PrintApply: when belt global mode active, prevent instance grouping by
  adding unique Z perturbation to trafo — each copy becomes its own
  PrintObject with independent layers
- PrintObjectSlice: compute global Z offset relative to minimum Y shift
  across all PrintObjects (lowest-Y object stays at Z=0)
- Debug logging (warning level) for belt global shift values and offsets

Known issues:
- Cached posSlice results cause stale offsets when mixing copies with
  individually-added objects — need to compute min baseline outside slice()
- Supports still generate to Z=0 instead of object's global Z offset

Fix global shear for copied objects: disable shared-object layer optimization

When belt global Z shear is active, each object needs unique layer Z
values based on its bed position. The shared-object optimization was
causing copies to reuse the source object's layers (and its Z offset)
instead of computing their own position-based offset.

started work on getting supports to work properly

one step forward, one step back

this version didn't quite work.  Getting somewhere though

about to add UI controllable tests

added configuration options for supports

tweak CLAUDE.md to be more aggressive for my machine.  This commit should probably be pulled out before contributing upstream

still chasing down some bugs

moving objects between slices no longer results in improper Z-height because of caching

added more data to the debug logs

Z offset is getting more global again

still not quite there, I think there's a fundamental logic flaw?

hunting for bugs

finally have a functional fix

Add belt floor clipping to tree supports (organic and non-organic)

- Add belt floor polygon clipping to non-organic tree support
  (slim/strong/hybrid) in draw_circles() and terminate nodes at the
  belt surface instead of the horizontal build plate
- Add belt floor clipping to organic tree support pipeline with virtual
  belt raft layers for sub-floor branch generation, per-layer belt
  floor polygons in TreeModelVolumes, and post-generation layer trimming
- Fix pre-existing processing_last_mesh bug in TreeModelVolumes that
  prevented m_anti_overhang (support blockers) from ever being applied;
  skip empty first layer check for belt printers

Commits:

current approach: make a face surface to build supports to

closer!

supports now terminate on shear plane, now need to get shear plane to correct Z height

nearly there

chasing down logic issues still

committing for checkpoint, this still does not work

still got logic problems...

cull support clipping

stashing changes for now.  Going to focus on getting the global shear OFF support generation dialed first.

beginning per object shear calcs

Local shear transform is on correct Z offset now

local shear finally works now and needs more testing

global shear works now, needs thorough testing

debugging non-45 degree angles

debugging part 2

supports at all angles work now

remove debug logging

Add belt floor collision to non-organic tree support pipeline

- Integrate belt floor as a collision surface in TreeSupportData so
  branches route around the belt naturally, replacing the explicit
  termination checks in drop_nodes()
- Add belt extension layers below the object after draw_circles() to
  allow support geometry to extend to the diagonal belt surface instead
  of terminating at a horizontal first layer
- Fix coordinate overflow in belt floor polygons (scale_(1e4) exceeds
  int32), skip first-layer brim expansion for belt printers, and
  extend empty first layer check bypass to all belt modes

add debug logging, Z translate for tree supports

still not seeing any cutoff surface yet

adding debug options

attempt #2 at trees

if hit Z buildplate stop but don't set to_buildplate true

getting closer

tree support almost there, just need to get rid of the circles at the beginning

getting closer

belt / shear plane clip works, need to figure out the buidlplate plane issues

more logic, added debugging logs

supports now extend somewhat below Z=0 in global shear mode

fix bad alloc, add 10mm below build plate

fully works now

shear transform + prusa tree support generation works now.

pull out debug logging
2026-03-30 13:25:40 -05:00
harrierpigeon
719af2d81d Part 2.5: Add global shear transform, support clipping, and belt UI improvements
- Implement per-object global shear transform in PrintObject with
  layer Z-offset calculation, config invalidation, and fix for
  shared-object layer optimization breaking copied objects
- Clip support layers to the transformed belt floor plane and begin
  work on tree support adaptation for sheared coordinate space
- Improve belt UI: gray out inactive sub-options, add B keyboard
  shortcut for G-code viewer design-view toggle, fix mesh clipping
  through build plate after shear/scale transform

y' = y + z·cot(α),
  while x' = x and z' = z

getting closer to customizable variant

getting closer

X/Y/Z shear initial

clean up UI

add 1/sin(a) transform, idea taken from blackbelt cura plugin

Things work now (turns out I've been using the wrong set of  transforms)
2026-03-30 13:25:40 -05:00
harrierpigeon
cb13a22e57 Part 2: Replace belt rotation w/ per-axis shear transforms and G-code axis remap
- Replace monolithic belt rotation transform with independent per-axis
    shear controls (mode/angle/source-axis for X, Y, Z) and G-code axis
    remapping, giving full flexibility to match any belt printer's
    coordinate system
  - Remove all rotation mode logic and intermediate type+axes dropdowns,
    simplifying the pipeline to pure shear matrices while preserving the
    default behavior (Y += Z*cot(45deg) with identity remap)
  - Clean up GCodeWriter, GCodeProcessor, and GCodeViewer for the new
    shear-only model; expose 12 new settings in printer UI via
    Tab.cpp/Preset.cpp

Implement belt printer tilted slicing

Implement the core belt slicing pipeline that makes the slicer
tilt-aware:

Step 1: GCodeWriter::to_machine_coords() - R(+alpha, X) rotation
  from slicing frame to machine frame
Step 2: PrintObject - belt-rotated object height calculation
  (y*sin(a) + z*cos(a)) for correct layer count
Step 3: PrintObjectSlice - apply R(-alpha, X) rotation trafo so
  horizontal slice planes correspond to belt-parallel planes,
  with Z-shift computed from model volumes
Step 4: GCodeProcessor - machine-frame preview (no transform needed)
Step 5: 3DBed - rotate bed visualization about X by belt angle

Fix: belt surface IS the build plate, no mesh rotation

Currently still slicing perpendicular to the belt normal.  Need to figure out why.

Fix G-code Z sign: use R(-alpha, X) so Z+ is away from belt

The previous R(+alpha, X) transform produced negative Z values
(-y*sin(a) term dominated). Changed to R(-alpha, X) which gives
machine_z = y*sin(a) + z*cos(a), always positive for points
above the belt surface. Z increases with each layer as expected.

reverting and changing slice methodology

Add pink slicing direction arrow from origin

Shows the effective slicing direction (gantry normal) as a pink
arrow from the origin. Shorter and wider than the gravity arrow.
Direction: R(+alpha, X) * Z = (0, -sin(a), cos(a)), which is
the layer stacking direction in the original mesh frame.

Fix slicing arrow visibility and add raw G-code toggle

- Disable depth test for pink slicing arrow so it renders on top of
  the tilted bed geometry (was being occluded)
- Remove unnecessary 5mm Z-offset from arrow position
- Add m_belt_show_raw toggle to GCodeViewer
- Add "Show raw G-code (slicing frame)" checkbox in legend when
  belt mode is active

Implement to_machine_coords inverse rotation for belt printer G-code

The slicing pipeline rotates the mesh by R(-alpha, X) and shifts Z to
start at 0. The G-code output now undoes this transform via
to_machine_coords: R(+alpha, X) * T(0,0,+z_shift), recovering the
original machine-frame coordinates where Y is horizontal and Z is
vertical.

Changes:
- GCodeWriter: implement to_machine_coords with inverse rotation + Z-shift
- GCodeWriter: add belt_z_shift member and setter/getter
- GCode.cpp: compute Z-shift from print objects (same logic as
  PrintObjectSlice) and pass to writer; write z_shift to G-code header
- GCodeProcessor: parse belt_z_shift from G-code header
- GCodeViewer: store belt_z_shift from processor result

Wire raw G-code toggle to apply slicing-frame view transform

When "Show raw G-code (slicing frame)" is checked in the preview
legend, the view matrix is modified to apply R(-alpha, X) * T(0,0,-z_shift)
to the toolpath rendering. This shows the G-code as it was during
slicing: rotated part with horizontal layers.

Default (unchecked): machine-frame view — upright part with tilted layers.

Remove belt printer placeholder comment from GCodeProcessor

The preview now correctly displays machine-frame G-code with the
optional raw view toggle. No transform is needed in the processor.
2026-03-30 13:25:40 -05:00
harrierpigeon
ed6ea086a2 Add belt printer transform pipeline: slicing rotation, G-code coords, preview
- Implement core belt slicing pipeline: R(-alpha, X) mesh rotation in PrintObjectSlice with corrected object height calculation for proper layer count
Add to_machine_coords() in GCodeWriter to convert slicing-frame coordinates back to machine-frame, propagated through GCode,
GCodeProcessor, and GCodeViewer
Add belt-mode UI: tilted bed visualization, slicing-direction arrow, and raw G-code toggle to switch between machine-frame and slicing-frame views

This is a combination of 6 commits.

checkpoint 1: initial MVP.  Slicing functions, but rotates instead of skews are happening and a lot of other stuff too

getting somewhere, getting to the point where I need to figure out how to verify this stuff

this appears to be a dead end.

getting somewhere I think maybe

I'm pretty sure we've completely lost the plot at this point and need to restart this process...

remove slice logic in preparation for new, more invasive plan
2026-03-30 13:25:40 -05:00
harrierpigeon
08aa277974 stage in changes from off-plate-gravity and remove stuff I didn't need 2026-03-30 13:25:40 -05:00
373 changed files with 89868 additions and 189339 deletions

View File

@@ -5,6 +5,7 @@ on:
branches:
- main
- release/*
- belt-printer
paths:
- 'deps/**'
- 'src/**'
@@ -55,11 +56,23 @@ jobs:
build_linux:
strategy:
fail-fast: false
# Build both arches on every event (PRs included), through the same
# build_check_cache -> build_deps -> build_orca chain (the AppImage).
# aarch64 always uses the GitHub-hosted arm runner (there is no arm
# self-hosted server). amd64's empty arch is load-bearing: it keeps the
# historical 'linux-clang' deps cache key and the unsuffixed asset names.
matrix:
include:
- arch: ""
os: ${{ vars.SELF_HOSTED && 'orca-lnx-server' || 'ubuntu-24.04' }}
- arch: "aarch64"
os: ubuntu-24.04-arm
# Don't run scheduled builds on forks:
if: ${{ !cancelled() && (github.event_name != 'schedule' || github.repository == 'OrcaSlicer/OrcaSlicer') }}
uses: ./.github/workflows/build_check_cache.yml
with:
os: ${{ vars.SELF_HOSTED && 'orca-lnx-server' || 'ubuntu-24.04' }}
os: ${{ matrix.os }}
arch: ${{ matrix.arch }}
build-deps-only: ${{ inputs.build-deps-only || false }}
secrets: inherit
build_windows:
@@ -99,7 +112,9 @@ jobs:
secrets: inherit
unit_tests:
name: Unit Tests
runs-on: ${{ vars.SELF_HOSTED && 'orca-lnx-server' || 'ubuntu-24.04' }}
# Tests are built on the aarch64 leg by default (faster GitHub arm runner),
# so run them there; self-hosted builds them on the amd64 server instead.
runs-on: ${{ vars.SELF_HOSTED && 'orca-lnx-server' || 'ubuntu-24.04-arm' }}
needs: build_linux
if: ${{ !cancelled() && success() }}
steps:
@@ -170,6 +185,9 @@ jobs:
date:
ver:
ver_pure:
# Belt-printer nightlies share the main nightly release but carry a `_belt`
# suffix so they never overwrite the main assets.
nightly_suffix: ${{ github.ref == 'refs/heads/belt-printer' && '_belt' || '' }}
steps:
- name: "Remove unneeded stuff to free disk space"
run:
@@ -228,13 +246,12 @@ jobs:
name: OrcaSlicer-Linux-flatpak_${{ env.ver }}_${{ matrix.variant.arch }}.flatpak
path: '/__w/OrcaSlicer/OrcaSlicer/OrcaSlicer-Linux-flatpak_${{ env.ver }}_${{ matrix.variant.arch }}.flatpak'
- name: Deploy Flatpak to nightly release
if: github.repository == 'OrcaSlicer/OrcaSlicer' && github.ref == 'refs/heads/main'
if: github.repository == 'OrcaSlicer/OrcaSlicer' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/belt-printer')
uses: WebFreak001/deploy-nightly@v3.2.0
with:
upload_url: https://uploads.github.com/repos/OrcaSlicer/OrcaSlicer/releases/137995723/assets{?name,label}
release_id: 137995723
asset_path: /__w/OrcaSlicer/OrcaSlicer/OrcaSlicer-Linux-flatpak_${{ env.ver }}_${{ matrix.variant.arch }}.flatpak
asset_name: OrcaSlicer-Linux-flatpak_nightly_${{ matrix.variant.arch }}.flatpak
asset_name: OrcaSlicer-Linux-flatpak_nightly${{ env.nightly_suffix }}_${{ matrix.variant.arch }}.flatpak
asset_content_type: application/octet-stream
max_releases: 1 # optional, if there are more releases than this matching the asset_name, the oldest ones are going to be deleted

View File

@@ -33,8 +33,10 @@ jobs:
- name: set outputs
id: set_outputs
env:
# Keep macOS cache keys and paths architecture-specific.
cache-os: ${{ runner.os == 'macOS' && format('macos-{0}', inputs.arch) || (runner.os == 'Windows' && 'windows' || 'linux-clang') }}
# Keep macOS/Linux cache keys architecture-specific. amd64 Linux passes
# no arch (key stays 'linux-clang', preserving the existing cache);
# aarch64 gets its own 'linux-clang-aarch64' key.
cache-os: ${{ runner.os == 'macOS' && format('macos-{0}', inputs.arch) || (runner.os == 'Windows' && 'windows' || format('linux-clang{0}', inputs.arch && format('-{0}', inputs.arch) || '')) }}
dep-folder-name: ${{ runner.os == 'macOS' && format('/{0}', inputs.arch) || '/OrcaSlicer_dep' }}
output-cmd: ${{ runner.os == 'Windows' && '$env:GITHUB_OUTPUT' || '"$GITHUB_OUTPUT"'}}
run: |

View File

@@ -29,6 +29,11 @@ jobs:
ubuntu-ver: '2404'
ubuntu-ver-str: '_Ubuntu2404'
ORCA_UPDATER_SIG_KEY: ${{ secrets.ORCA_UPDATER_SIG_KEY }}
# Branches whose builds are published to the nightly release. The
# belt-printer branch ships alongside main but its assets carry a `_belt`
# suffix (nightly_suffix) so they never overwrite the main nightly assets.
deploy_nightly: ${{ github.ref == 'refs/heads/main' || github.ref == 'refs/heads/belt-printer' }}
nightly_suffix: ${{ github.ref == 'refs/heads/belt-printer' && '_belt' || '' }}
steps:
- name: Checkout
@@ -65,6 +70,11 @@ jobs:
echo "ver_pure=$ver_pure" >> $GITHUB_ENV
echo "date=$(date +'%Y%m%d')" >> $GITHUB_ENV
echo "git_commit_hash=$git_commit_hash" >> $GITHUB_ENV
# Per-arch Linux AppImage naming: amd64 keeps the historical unsuffixed
# name (arch_suffix empty). Unused on macOS/Windows.
if [ '${{ inputs.arch }}' = 'aarch64' ]; then
echo "arch_suffix=_aarch64" >> $GITHUB_ENV
fi
shell: bash
- name: Get the version and date on Windows
@@ -153,17 +163,9 @@ jobs:
run: |
./build_release_macos.sh -u -x ${{ !vars.SELF_HOSTED && '-1' || '' }} -a universal -t 10.15
- name: Delete intermediate per-arch artifacts
if: runner.os == 'macOS' && inputs.macos-combine-only
uses: geekyeggo/delete-artifact@v6
with:
name: |
OrcaSlicer_Mac_bundle_arm64_${{ github.sha }}
OrcaSlicer_Mac_bundle_x86_64_${{ github.sha }}
# Thanks to RaySajuuk, it's working now
- name: Sign app and notary
if: github.repository == 'OrcaSlicer/OrcaSlicer' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release/')) && runner.os == 'macOS' && inputs.macos-combine-only
if: github.repository == 'OrcaSlicer/OrcaSlicer' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/belt-printer' || startsWith(github.ref, 'refs/heads/release/')) && runner.os == 'macOS' && inputs.macos-combine-only
working-directory: ${{ github.workspace }}
env:
BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }}
@@ -171,6 +173,8 @@ jobs:
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
CERTIFICATE_ID: ${{ secrets.MACOS_CERTIFICATE_ID }}
run: |
# Load the `retry` helper (retries flaky commands such as `hdiutil create`).
source ${{ github.workspace }}/scripts/retry.sh
CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode --output $CERTIFICATE_PATH
@@ -193,7 +197,7 @@ jobs:
rm -rf ${{ github.workspace }}/build/universal/OrcaSlicer_dmg/*
cp -R ${{ github.workspace }}/build/universal/OrcaSlicer/OrcaSlicer.app ${{ github.workspace }}/build/universal/OrcaSlicer_dmg/
ln -sfn /Applications ${{ github.workspace }}/build/universal/OrcaSlicer_dmg/Applications
hdiutil create -volname "OrcaSlicer" -srcfolder ${{ github.workspace }}/build/universal/OrcaSlicer_dmg -ov -format UDZO OrcaSlicer_Mac_universal_${{ env.ver }}.dmg
retry hdiutil create -volname "OrcaSlicer" -srcfolder ${{ github.workspace }}/build/universal/OrcaSlicer_dmg -ov -format UDZO OrcaSlicer_Mac_universal_${{ env.ver }}.dmg
codesign --deep --force --verbose --options runtime --timestamp --entitlements ${{ github.workspace }}/scripts/disable_validation.entitlements --sign "$CERTIFICATE_ID" OrcaSlicer_Mac_universal_${{ env.ver }}.dmg
# Create separate OrcaSlicer_profile_validator DMG if the app exists
@@ -202,7 +206,7 @@ jobs:
rm -rf ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg/*
cp -R ${{ github.workspace }}/build/universal/OrcaSlicer/OrcaSlicer_profile_validator.app ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg/
ln -sfn /Applications ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg/Applications
hdiutil create -volname "OrcaSlicer Profile Validator" -srcfolder ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg -ov -format UDZO OrcaSlicer_profile_validator_Mac_universal_${{ env.ver }}.dmg
retry hdiutil create -volname "OrcaSlicer Profile Validator" -srcfolder ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg -ov -format UDZO OrcaSlicer_profile_validator_Mac_universal_${{ env.ver }}.dmg
codesign --deep --force --verbose --options runtime --timestamp --entitlements ${{ github.workspace }}/scripts/disable_validation.entitlements --sign "$CERTIFICATE_ID" OrcaSlicer_profile_validator_Mac_universal_${{ env.ver }}.dmg
fi
@@ -217,14 +221,16 @@ jobs:
fi
- name: Create DMG without notary
if: github.ref != 'refs/heads/main' && runner.os == 'macOS' && inputs.macos-combine-only
if: github.ref != 'refs/heads/main' && github.ref != 'refs/heads/belt-printer' && runner.os == 'macOS' && inputs.macos-combine-only
working-directory: ${{ github.workspace }}
run: |
# Load the `retry` helper (retries flaky commands such as `hdiutil create`).
source ${{ github.workspace }}/scripts/retry.sh
mkdir -p ${{ github.workspace }}/build/universal/OrcaSlicer_dmg
rm -rf ${{ github.workspace }}/build/universal/OrcaSlicer_dmg/*
cp -R ${{ github.workspace }}/build/universal/OrcaSlicer/OrcaSlicer.app ${{ github.workspace }}/build/universal/OrcaSlicer_dmg/
ln -sfn /Applications ${{ github.workspace }}/build/universal/OrcaSlicer_dmg/Applications
hdiutil create -volname "OrcaSlicer" -srcfolder ${{ github.workspace }}/build/universal/OrcaSlicer_dmg -ov -format UDZO OrcaSlicer_Mac_universal_${{ env.ver }}.dmg
retry hdiutil create -volname "OrcaSlicer" -srcfolder ${{ github.workspace }}/build/universal/OrcaSlicer_dmg -ov -format UDZO OrcaSlicer_Mac_universal_${{ env.ver }}.dmg
# Create separate OrcaSlicer_profile_validator DMG if the app exists
if [ -f "${{ github.workspace }}/build/universal/OrcaSlicer/OrcaSlicer_profile_validator.app/Contents/MacOS/OrcaSlicer_profile_validator" ]; then
@@ -232,9 +238,19 @@ jobs:
rm -rf ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg/*
cp -R ${{ github.workspace }}/build/universal/OrcaSlicer/OrcaSlicer_profile_validator.app ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg/
ln -sfn /Applications ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg/Applications
hdiutil create -volname "OrcaSlicer Profile Validator" -srcfolder ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg -ov -format UDZO OrcaSlicer_profile_validator_Mac_universal_${{ env.ver }}.dmg
retry hdiutil create -volname "OrcaSlicer Profile Validator" -srcfolder ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg -ov -format UDZO OrcaSlicer_profile_validator_Mac_universal_${{ env.ver }}.dmg
fi
# Delete the per-arch bundles only after signing/DMG creation succeeded, so a
# failed run keeps them available for a re-run instead of forcing a full rebuild.
- name: Delete intermediate per-arch artifacts
if: success() && runner.os == 'macOS' && inputs.macos-combine-only
uses: geekyeggo/delete-artifact@v6
with:
name: |
OrcaSlicer_Mac_bundle_arm64_${{ github.sha }}
OrcaSlicer_Mac_bundle_x86_64_${{ github.sha }}
- name: Upload artifacts mac
if: runner.os == 'macOS' && inputs.macos-combine-only
uses: actions/upload-artifact@v7
@@ -251,13 +267,13 @@ jobs:
if-no-files-found: ignore
- name: Deploy Mac release
if: github.repository == 'OrcaSlicer/OrcaSlicer' && github.ref == 'refs/heads/main' && runner.os == 'macOS' && inputs.macos-combine-only && !vars.SELF_HOSTED
if: github.repository == 'OrcaSlicer/OrcaSlicer' && env.deploy_nightly == 'true' && runner.os == 'macOS' && inputs.macos-combine-only && !vars.SELF_HOSTED
uses: WebFreak001/deploy-nightly@v3.2.0
with:
upload_url: https://uploads.github.com/repos/OrcaSlicer/OrcaSlicer/releases/137995723/assets{?name,label}
release_id: 137995723
asset_path: ${{ github.workspace }}/OrcaSlicer_Mac_universal_${{ env.ver }}.dmg
asset_name: OrcaSlicer_Mac_universal_nightly.dmg
asset_name: OrcaSlicer_Mac_universal_nightly${{ env.nightly_suffix }}.dmg
asset_content_type: application/octet-stream
max_releases: 1 # optional, if there are more releases than this matching the asset_name, the oldest ones are going to be deleted
@@ -339,24 +355,24 @@ jobs:
path: ${{ github.workspace }}/build/src/Release/OrcaSlicer_profile_validator.exe
- name: Deploy Windows release portable
if: github.repository == 'OrcaSlicer/OrcaSlicer' && github.ref == 'refs/heads/main' && runner.os == 'Windows' && !vars.SELF_HOSTED
if: github.repository == 'OrcaSlicer/OrcaSlicer' && env.deploy_nightly == 'true' && runner.os == 'Windows' && !vars.SELF_HOSTED
uses: WebFreak001/deploy-nightly@v3.2.0
with:
upload_url: https://uploads.github.com/repos/OrcaSlicer/OrcaSlicer/releases/137995723/assets{?name,label}
release_id: 137995723
asset_path: ${{ github.workspace }}/build/OrcaSlicer_Windows_${{ env.ver }}_portable.zip
asset_name: OrcaSlicer_Windows_nightly_portable.zip
asset_name: OrcaSlicer_Windows_nightly${{ env.nightly_suffix }}_portable.zip
asset_content_type: application/x-zip-compressed
max_releases: 1
- name: Deploy Windows release installer
if: github.repository == 'OrcaSlicer/OrcaSlicer' && github.ref == 'refs/heads/main' && runner.os == 'Windows' && !vars.SELF_HOSTED
if: github.repository == 'OrcaSlicer/OrcaSlicer' && env.deploy_nightly == 'true' && runner.os == 'Windows' && !vars.SELF_HOSTED
uses: WebFreak001/deploy-nightly@v3.2.0
with:
upload_url: https://uploads.github.com/repos/OrcaSlicer/OrcaSlicer/releases/137995723/assets{?name,label}
release_id: 137995723
asset_path: ${{ github.workspace }}/build/OrcaSlicer_Windows_Installer_${{ env.ver }}.exe
asset_name: OrcaSlicer_Windows_Installer_nightly.exe
asset_name: OrcaSlicer_Windows_Installer_nightly${{ env.nightly_suffix }}.exe
asset_content_type: application/x-msdownload
max_releases: 1
@@ -401,16 +417,23 @@ jobs:
if: runner.os == 'Linux'
shell: bash
run: |
./build_linux.sh -istrlL
# Build + tar the unit tests (-t) only on the leg that runs them: the
# aarch64 leg by default (faster GitHub arm runner), or amd64 when using
# self-hosted runners (no arm self-hosted server). unit_tests downloads
# this tarball. The profile validator is built with -s, so amd64 keeps it.
tests=${{ (!vars.SELF_HOSTED && inputs.arch == 'aarch64') || (vars.SELF_HOSTED && inputs.arch != 'aarch64') }}
if $tests; then flags=-istrlL; else flags=-isrlL; fi
./build_linux.sh "$flags"
./scripts/check_appimage_libs.sh ./build/package ./build/package/bin/orca-slicer
mv -n ./build/OrcaSlicer_Linux_V${{ env.ver_pure }}.AppImage ./build/OrcaSlicer_Linux_AppImage${{ env.ubuntu-ver-str }}_${{ env.ver }}.AppImage
chmod +x ./build/OrcaSlicer_Linux_AppImage${{ env.ubuntu-ver-str }}_${{ env.ver }}.AppImage
tar -cvpf build_tests.tar build/tests
appimage=./build/OrcaSlicer_Linux_AppImage${{ env.ubuntu-ver-str }}${{ env.arch_suffix }}_${{ env.ver }}.AppImage
mv -n ./build/OrcaSlicer_Linux_V${{ env.ver_pure }}.AppImage "$appimage"
chmod +x "$appimage"
if $tests; then tar -cvpf build_tests.tar build/tests; fi
# Use tar because upload-artifacts won't always preserve directory structure
# and doesn't preserve file permissions
- name: Upload Test Artifact
if: runner.os == 'Linux'
if: runner.os == 'Linux' && ((!vars.SELF_HOSTED && inputs.arch == 'aarch64') || (vars.SELF_HOSTED && inputs.arch != 'aarch64'))
uses: actions/upload-artifact@v7
with:
name: ${{ github.sha }}-tests
@@ -420,7 +443,7 @@ jobs:
if-no-files-found: error
- name: Run external slicer regression tests
if: runner.os == 'Linux'
if: runner.os == 'Linux' && inputs.arch != 'aarch64'
timeout-minutes: 20
shell: bash
run: |
@@ -430,7 +453,7 @@ jobs:
python3 "$test_repo_dir/run_test.py" "${{ github.workspace }}/build/package/bin/orca-slicer"
- name: Build orca_custom_preset_tests
if: github.ref == 'refs/heads/main' && runner.os == 'Linux' && !vars.SELF_HOSTED
if: github.ref == 'refs/heads/main' && runner.os == 'Linux' && !vars.SELF_HOSTED && inputs.arch != 'aarch64'
working-directory: ${{ github.workspace }}/build/src/Release
shell: bash
run: |
@@ -442,28 +465,28 @@ jobs:
if: ${{ ! env.ACT && runner.os == 'Linux' }}
uses: actions/upload-artifact@v7
with:
name: OrcaSlicer_Linux_ubuntu_${{ env.ubuntu-ver }}_${{ env.ver }}
path: './build/OrcaSlicer_Linux_AppImage${{ env.ubuntu-ver-str }}_${{ env.ver }}.AppImage'
name: OrcaSlicer_Linux_ubuntu_${{ env.ubuntu-ver }}${{ env.arch_suffix }}_${{ env.ver }}
path: "./build/OrcaSlicer_Linux_AppImage${{ env.ubuntu-ver-str }}${{ env.arch_suffix }}_${{ env.ver }}.AppImage"
- name: Upload OrcaSlicer_profile_validator Ubuntu
if: ${{ ! env.ACT && runner.os == 'Linux' && !vars.SELF_HOSTED }}
if: ${{ ! env.ACT && runner.os == 'Linux' && !vars.SELF_HOSTED && inputs.arch != 'aarch64' }}
uses: actions/upload-artifact@v7
with:
name: OrcaSlicer_profile_validator_Linux_ubuntu_${{ env.ubuntu-ver }}_${{ env.ver }}
path: './build/src/Release/OrcaSlicer_profile_validator'
- name: Deploy Ubuntu release
if: ${{ github.repository == 'OrcaSlicer/OrcaSlicer' && ! env.ACT && github.ref == 'refs/heads/main' && runner.os == 'Linux' && !vars.SELF_HOSTED }}
if: ${{ github.repository == 'OrcaSlicer/OrcaSlicer' && ! env.ACT && env.deploy_nightly == 'true' && runner.os == 'Linux' && !vars.SELF_HOSTED }}
uses: WebFreak001/deploy-nightly@v3.2.0
with:
upload_url: https://uploads.github.com/repos/OrcaSlicer/OrcaSlicer/releases/137995723/assets{?name,label}
release_id: 137995723
asset_path: ./build/OrcaSlicer_Linux_AppImage${{ env.ubuntu-ver-str }}_${{ env.ver }}.AppImage
asset_name: OrcaSlicer_Linux_AppImage${{ env.ubuntu-ver-str }}_nightly.AppImage
asset_path: ./build/OrcaSlicer_Linux_AppImage${{ env.ubuntu-ver-str }}${{ env.arch_suffix }}_${{ env.ver }}.AppImage
asset_name: OrcaSlicer_Linux_AppImage${{ env.ubuntu-ver-str }}${{ env.arch_suffix }}_nightly${{ env.nightly_suffix }}.AppImage
asset_content_type: application/octet-stream
max_releases: 1 # optional, if there are more releases than this matching the asset_name, the oldest ones are going to be deleted
- name: Deploy Ubuntu release
if: ${{ github.repository == 'OrcaSlicer/OrcaSlicer' && ! env.ACT && github.ref == 'refs/heads/main' && runner.os == 'Linux' && !vars.SELF_HOSTED }}
if: ${{ github.repository == 'OrcaSlicer/OrcaSlicer' && ! env.ACT && github.ref == 'refs/heads/main' && runner.os == 'Linux' && !vars.SELF_HOSTED && inputs.arch != 'aarch64' }}
uses: rickstaa/action-create-tag@v1
with:
tag: "nightly-builds"
@@ -472,7 +495,7 @@ jobs:
message: "nightly-builds"
- name: Deploy Ubuntu OrcaSlicer_profile_validator release
if: ${{ github.repository == 'OrcaSlicer/OrcaSlicer' && ! env.ACT && github.ref == 'refs/heads/main' && runner.os == 'Linux' && !vars.SELF_HOSTED }}
if: ${{ github.repository == 'OrcaSlicer/OrcaSlicer' && ! env.ACT && github.ref == 'refs/heads/main' && runner.os == 'Linux' && !vars.SELF_HOSTED && inputs.arch != 'aarch64' }}
uses: WebFreak001/deploy-nightly@v3.2.0
with:
upload_url: https://uploads.github.com/repos/OrcaSlicer/OrcaSlicer/releases/137995723/assets{?name,label}
@@ -483,7 +506,7 @@ jobs:
max_releases: 1
- name: Deploy orca_custom_preset_tests
if: ${{ github.repository == 'OrcaSlicer/OrcaSlicer' && ! env.ACT && github.ref == 'refs/heads/main' && runner.os == 'Linux' && !vars.SELF_HOSTED }}
if: ${{ github.repository == 'OrcaSlicer/OrcaSlicer' && ! env.ACT && github.ref == 'refs/heads/main' && runner.os == 'Linux' && !vars.SELF_HOSTED && inputs.arch != 'aarch64' }}
uses: WebFreak001/deploy-nightly@v3.2.0
with:
upload_url: https://uploads.github.com/repos/OrcaSlicer/OrcaSlicer/releases/137995723/assets{?name,label}

View File

@@ -24,7 +24,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Ask PR author for label
uses: actions/github-script@v7
uses: actions/github-script@v9
with:
script: |
function isPermissionDenied(error) {
@@ -88,7 +88,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Apply label command from PR author
uses: actions/github-script@v7
uses: actions/github-script@v9
with:
script: |
function isPermissionDenied(error) {

View File

@@ -161,6 +161,8 @@ It can also be installed through graphical software managers (KDE Discover, GNOM
### AppImage
AppImages are published for both **x86_64** and **aarch64** (ARM64). Pick the file matching your CPU — the ARM64 build has `aarch64` in its name (e.g. `OrcaSlicer_Linux_AppImage_Ubuntu2404_aarch64_*.AppImage`).
1. Download App image from the [releases page](https://github.com/OrcaSlicer/OrcaSlicer/releases).
2. Double click the downloaded file to run it.

View File

@@ -10,7 +10,13 @@ if (APPLE AND CMAKE_OSX_ARCHITECTURES)
set(_context_arch_line "-DBOOST_CONTEXT_ARCHITECTURE:STRING=${CMAKE_OSX_ARCHITECTURES}")
endif ()
set(_options "")
if (MSVC AND DEP_DEBUG)
set(_options "FORWARD_CONFIG")
endif ()
orcaslicer_add_cmake_project(Boost
${_options}
URL "https://github.com/boostorg/boost/releases/download/boost-1.84.0/boost-1.84.0.tar.gz"
URL_HASH SHA256=4d27e9efed0f6f152dc28db6430b9d3dfb40c0345da7342eaa5a987dde57bd95
LIST_SEPARATOR |

20
deps/CMakeLists.txt vendored
View File

@@ -155,17 +155,25 @@ if (NOT _is_multi AND NOT CMAKE_BUILD_TYPE)
endif ()
function(orcaslicer_add_cmake_project projectname)
cmake_parse_arguments(P_ARGS "" "INSTALL_DIR;BUILD_COMMAND;INSTALL_COMMAND" "CMAKE_ARGS" ${ARGN})
cmake_parse_arguments(P_ARGS "FORWARD_CONFIG" "INSTALL_DIR;BUILD_COMMAND;INSTALL_COMMAND" "CMAKE_ARGS" ${ARGN})
set(_configs_line -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE})
if (_is_multi OR MSVC)
if (ORCA_INCLUDE_DEBUG_INFO AND NOT DEP_DEBUG)
if (P_ARGS_FORWARD_CONFIG)
set(_configs_line -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE})
elseif (ORCA_INCLUDE_DEBUG_INFO AND NOT DEP_DEBUG)
set(_configs_line "-DCMAKE_C_FLAGS_RELEASE:STRING=${CMAKE_C_FLAGS_RELWITHDEBINFO} -DCMAKE_CXX_FLAGS_RELEASE:STRING=${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
else ()
set(_configs_line "")
endif ()
endif ()
if (P_ARGS_FORWARD_CONFIG)
set(_target_config "$<CONFIG>")
else()
set(_target_config "Release")
endif()
if (MSVC)
set(_gen CMAKE_GENERATOR "${DEP_MSVC_GEN}" CMAKE_GENERATOR_PLATFORM "${DEP_PLATFORM}")
else()
@@ -208,8 +216,8 @@ if (NOT IS_CROSS_COMPILE OR NOT APPLE)
${DEP_CMAKE_OPTS}
${P_ARGS_CMAKE_ARGS}
${P_ARGS_UNPARSED_ARGUMENTS}
BUILD_COMMAND ${CMAKE_COMMAND} --build . --config Release -- ${_build_j}
INSTALL_COMMAND ${CMAKE_COMMAND} --build . --target install --config Release
BUILD_COMMAND ${CMAKE_COMMAND} --build . --config ${_target_config} -- ${_build_j}
INSTALL_COMMAND ${CMAKE_COMMAND} --build . --target install --config ${_target_config}
)
if (FLATPAK)
@@ -251,8 +259,8 @@ else()
${DEP_CMAKE_OPTS}
${P_ARGS_CMAKE_ARGS}
${P_ARGS_UNPARSED_ARGUMENTS}
BUILD_COMMAND ${CMAKE_COMMAND} --build . --config Release -- ${_build_j}
INSTALL_COMMAND ${CMAKE_COMMAND} --build . --target install --config Release
BUILD_COMMAND ${CMAKE_COMMAND} --build . --config ${_target_config} -- ${_build_j}
INSTALL_COMMAND ${CMAKE_COMMAND} --build . --target install --config ${_target_config}
)
endif()

View File

@@ -1,4 +1,10 @@
set(_options "")
if (MSVC AND DEP_DEBUG)
set(_options "FORWARD_CONFIG")
endif ()
orcaslicer_add_cmake_project(Draco
${_options}
URL https://github.com/google/draco/archive/refs/tags/1.5.7.zip
URL_HASH SHA256=27b72ba2d5ff3d0a9814ad40d4cb88f8dc89a35491c0866d952473f8f9416b77
)

View File

@@ -1,7 +1,11 @@
if (MSVC)
set(_use_IPP "-DWITH_IPP=ON")
if (DEP_DEBUG)
set(_options "FORWARD_CONFIG")
endif ()
else ()
set(_use_IPP "-DWITH_IPP=OFF")
set(_options "")
endif ()
if (IN_GIT_REPO)
@@ -9,6 +13,7 @@ if (IN_GIT_REPO)
endif ()
orcaslicer_add_cmake_project(OpenCV
${_options}
URL https://github.com/opencv/opencv/archive/refs/tags/4.6.0.tar.gz
URL_HASH SHA256=1ec1cba65f9f20fe5a41fda1586e01c70ea0c9a6d7b67c9e13edf0cfe2239277
PATCH_COMMAND git apply ${OpenCV_DIRECTORY_FLAG} --verbose --ignore-space-change --whitespace=fix ${CMAKE_CURRENT_LIST_DIR}/0001-vs.patch ${CMAKE_CURRENT_LIST_DIR}/0002-clang19-macos.patch

View File

@@ -1123,18 +1123,17 @@ private:
std::vector<RawShape> objs,excludes;
for (const Item &item : items_) {
if (item.isFixed()) continue;
objs.push_back(item.transformedShape());
if (item.isFixed())
excludes.push_back(item.transformedShape());
else
objs.push_back(item.transformedShape());
}
if (objs.empty())
return;
// Without fixed items this inner-fit NFP can exceed clipper's range and crash MSVC.
if (!excludes.empty())
{ // find a best position inside NFP of fixed items (excluded regions), so the center of pile is cloest to bed center
RawShape objs_convex_hull = sl::convexHull(objs);
for (const Item &item : items_) {
if (item.isFixed()) {
excludes.push_back(item.transformedShape());
}
}
auto nfps = calcnfp(objs_convex_hull, excludes, bbin, Lvl<MaxNfpLevel::value>());
if (nfps.empty()) {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,79 @@
#!/usr/bin/env python3
"""Belt temperature-tower asset generator (discrete-provini design).
A vertical temperature tower cannot be sliced on a belt printer, so lay a row of
DISCRETE provini (one per temperature) along the belt (designed Y) with a fixed
surface gap. Each provino is the chevron+arc unit (belt_temp_provino_unit.stl,
keel-first); its temperature is ENGRAVED upright into the 50 mm face — a raised
number would be an unsupported overhang on the belt. The C++ calib_temp belt branch
(Plater.cpp) injects one M104 per zone 70 layers INTO provino i:
print_z[i] = i * PITCH * cos(theta) + 70 * layer_height (theta = 45)
inside the body, not in the empty inter-provino gap (which has no sliced layers for
the event to attach to). PITCH below is the shared geometry contract with that code —
keep them in sync.
Generates one STL per filament temp range used by Temp_Calibration_Dlg.
"""
import numpy as np, trimesh, os
from matplotlib.textpath import TextPath
from matplotlib.font_manager import FontProperties
from shapely.geometry import Polygon as ShPoly
from shapely.ops import unary_union
HERE = os.path.dirname(os.path.abspath(__file__))
UNIT = os.path.join(HERE, 'belt_temp_provino_unit.stl') # single provino, keel-first
SURF_GAP = 25.0 # surface-to-surface gap between provini (mm) — user spec
TEXT_H = 9.0
TEXT_DEPTH = 0.8 # engraving depth (numbers are CUT into the face, not raised:
# a raised number is an unsupported Y-overhang on the belt)
TEXT_OVERSHOOT = 0.6 # extra height poking out of the face for a clean boolean cut
# Temperature ranges (start, end) per filament family, 5 C step. File name encodes them.
RANGES = [(230,190),(270,230),(250,230),(280,240),(240,210),(320,280)]
unit = trimesh.load(UNIT)
dY = unit.bounds[1,1] - unit.bounds[0,1]
PITCH = dY + SURF_GAP # designed-Y pitch == C++ contract constant
print(f"unit dY={dY:.2f} PITCH={PITCH:.3f} (C++ contract: print_z[i]=i*{PITCH:.3f}*cos45)")
# 50 mm face normal (0,-1,1)/sqrt2 ; UPRIGHT basis u=+X det(+1) (verified non-mirrored)
n = np.array([0,-1,1.])/np.sqrt(2)
u = np.array([1,0,0.]); v = np.array([0,1,1.])/np.sqrt(2)
R = np.column_stack([u,v,n])
fn = unit.face_normals; fc = unit.triangles_center; fa = unit.area_faces
sel = (fn@n) > 0.9
face_c = (fc[sel]*fa[sel,None]).sum(0)/fa[sel].sum()
def text_mesh(s):
tp = TextPath((0,0), s, size=TEXT_H, prop=FontProperties(family='DejaVu Sans'))
rings = [ShPoly(p) for p in tp.to_polygons() if len(p)>=3]
rings.sort(key=lambda r:r.area, reverse=True)
used=[False]*len(rings); parts=[]
for i,o in enumerate(rings):
if used[i]: continue
holes=[]
for j in range(i+1,len(rings)):
if not used[j] and o.contains(rings[j]): holes.append(rings[j].exterior.coords); used[j]=True
parts.append(ShPoly(o.exterior.coords,holes)); used[i]=True
poly = unary_union(parts)
geoms = list(poly.geoms) if poly.geom_type=='MultiPolygon' else [poly]
m = trimesh.util.concatenate([trimesh.creation.extrude_polygon(g,height=TEXT_DEPTH+TEXT_OVERSHOOT) for g in geoms])
c = m.bounds.mean(axis=0); m.apply_translation([-c[0],-c[1],0]); return m
for t_start, t_end in RANGES:
temps = list(range(t_start, t_end-1, -5))
parts=[]
for i,T in enumerate(temps):
c = unit.copy(); c.apply_translation([0, i*PITCH, 0])
t = text_mesh(str(T)); M=np.eye(4); M[:3,:3]=R; t.apply_transform(M)
# place the text spanning from TEXT_DEPTH inside the face to TEXT_OVERSHOOT outside,
# then CUT it out of the provino (engrave) — no raised material, no Y-overhang.
t.apply_translation(face_c - n*TEXT_DEPTH + np.array([0,i*PITCH,0]))
c = trimesh.boolean.difference([c, t], engine='manifold')
parts.append(c)
asset = trimesh.util.concatenate(parts)
out = os.path.join(HERE, f"belt_temp_tower_{t_start}_{t_end}.stl")
asset.export(out)
dims = np.round(asset.bounds[1]-asset.bounds[0],1)
wt = all(p.is_watertight for p in parts)
print(f" {t_start}->{t_end}: {len(temps)} zones bbox={dims} watertight={wt} -> {os.path.basename(out)}")

View File

@@ -146,16 +146,16 @@ text = Fine-tuning for flow rate\nDid you know that flow rate can be fine-tuned
text = Split your prints into plates\nDid you know that you can split a model that has a lot of parts into individual plates ready to print? This will simplify the process of keeping track of all the parts.
[hint:Speed up your print with Adaptive Layer Height]
text = Speed up your print with Adaptive Layer Height\nDid you know that you can print a model even faster, by using the Adaptive Layer Height option? Check it out!
text = Speed up your print with Adaptive Layer Height\nDid you know that you can print a model even faster by using the Adaptive Layer Height option? Check it out!
[hint:Support painting]
text = Support painting\nDid you know that you can paint the location of your supports? This feature makes it easy to place the support material only on the sections of the model that actually need it.
[hint:Different types of supports]
text = Different types of supports\nDid you know that you can choose from multiple types of supports? Tree supports work great for organic models, while saving filament and improving print speed. Check them out!
text = Different types of supports\nDid you know that you can choose from multiple types of supports? Tree supports work great for organic models while saving filament and improving print speed. Check them out!
[hint:Printing Silk Filament]
text = Printing Silk Filament\nDid you know that Silk filament needs special consideration to print it successfully? Higher temperature and lower speed are always recommended for the best results.
text = Printing Silk Filament\nDid you know that Silk filament needs special consideration to print successfully? A higher temperature and lower speed are always recommended for the best results.
[hint:Brim for better adhesion]
text = Brim for better adhesion\nDid you know that when printed models have a small contact interface with the printing surface, it's recommended to use a brim?
@@ -167,13 +167,13 @@ text = Set parameters for multiple objects\nDid you know that you can set slicin
text = Stack objects\nDid you know that you can stack objects as a whole one?
[hint:Flush into support/objects/infill]
text = Flush into support/objects/infill\nDid you know that you can reduce wasted filament by flushing it into support/objects/infill during filament change?
text = Flush into support/objects/infill\nDid you know that you can reduce wasted filament by flushing it into support/objects/infill during filament changes?
[hint:Improve strength]
text = Improve strength\nDid you know that you can use more wall loops and higher sparse infill density to improve the strength of the model?
[hint:When do you need to print with the printer door opened]
text = When do you need to print with the printer door opened?\nDid you know that opening the printer door can reduce the probability of extruder/hotend clogging when printing lower temperature filament with a higher enclosure temperature? More info about this in the Wiki.
text = When do you need to print with the printer door opened?\nDid you know that opening the printer door can reduce the probability of extruder/hotend clogging when printing lower temperature filament with a higher enclosure temperature? There is more info about this in the Wiki.
[hint:Avoid warping]
text = Avoid warping\nDid you know that when printing materials that are prone to warping such as ABS, appropriately increasing the heatbed temperature can reduce the probability of warping?

View File

@@ -123,7 +123,7 @@
"0"
],
"machine_pause_gcode": "M600",
"machine_start_gcode": "M140 S60\nM104 S140\nM190 S[first_layer_bed_temperature]\nM109 S{temperature_vitrification[0]}\nG28;\nNOZZLE_WIPE\nM140 S[first_layer_bed_temperature];\nM104 S[first_layer_temperature];\nDRAW_LINE_ONLY",
"machine_start_gcode": "M140 S60\nM104 S140\nM190 S[first_layer_bed_temperature]\nM109 S{temperature_vitrification[0]}\nG28;\nNOZZLE_WIPE\nM140 S[first_layer_bed_temperature];\nM109 S[first_layer_temperature];\nDRAW_LINE_ONLY",
"machine_unload_filament_time": "0",
"manual_filament_change": "0",
"max_layer_height": [

View File

@@ -126,7 +126,7 @@
"0"
],
"machine_pause_gcode": "M600",
"machine_start_gcode": "M140 S60\nM104 S140\nM190 S[first_layer_bed_temperature]\nM109 S{temperature_vitrification[0]}\nG28;\nNOZZLE_WIPE\nM140 S[first_layer_bed_temperature];\nM104 S[first_layer_temperature];\nDRAW_LINE_ONLY",
"machine_start_gcode": "M140 S60\nM104 S140\nM190 S[first_layer_bed_temperature]\nM109 S{temperature_vitrification[0]}\nG28;\nNOZZLE_WIPE\nM140 S[first_layer_bed_temperature];\nM109 S[first_layer_temperature];\nDRAW_LINE_ONLY",
"machine_unload_filament_time": "0",
"manual_filament_change": "0",
"max_layer_height": [

View File

@@ -126,7 +126,7 @@
"0"
],
"machine_pause_gcode": "M600",
"machine_start_gcode": "M104 S140\nM190 S[first_layer_bed_temperature]\nM109 S{temperature_vitrification[0]}\nG28;\nG1 X230 Y300 Z10 F5000\nSET_KINEMATIC_POSITION Y=0\nG1 Y20 F4000\nG1 X230 F4000\nG1 Z-1 F600 \nG1 X270 F4000\nG1 Y25 F4000\nG1 X230 F4000\nG92 E0\nG1 Z10 F1200\nG1 Y0 F5000\nG1 E-1 F3000\nM400\nSET_KINEMATIC_POSITION Y=300\nG92 E-1\nM140 S[first_layer_bed_temperature];\nM104 S[first_layer_temperature];\nG1 X0 Y0.8 Z0.8 F18000\nG92 E0\nG1 X0 Y0.8 Z0.3 E8 F600\nG92 E0\nG1 X200 Y0.8 Z0.3 F1800.0 E20.0;draw line\nG92 E0\nG1 X200 Y0 Z0.3 F1800.0 E0.08;draw line\nG92 E0\nG1 X100 Y0 Z0.3 F1800.0 E10.0;draw line\nG92 E0\nG1 X100 Y1.6 Z0.3 F1800.0 E0.16;draw line\nG92 E0\nG1 X180 Y1.6 Z0.3 F1800.0 E8;draw line\nG92 E0\nG1 X180 Y0 Z0.3 F1800.0 E0.16;draw line\nG92 E0\nG1 E-1 Z5 F18000\nG92 E0",
"machine_start_gcode": "M104 S140\nM190 S[first_layer_bed_temperature]\nM109 S{temperature_vitrification[0]}\nG28;\nG1 X230 Y300 Z10 F5000\nSET_KINEMATIC_POSITION Y=0\nG1 Y20 F4000\nG1 X230 F4000\nG1 Z-1 F600 \nG1 X270 F4000\nG1 Y25 F4000\nG1 X230 F4000\nG92 E0\nG1 Z10 F1200\nG1 Y0 F5000\nG1 E-1 F3000\nM400\nSET_KINEMATIC_POSITION Y=300\nG92 E-1\nM140 S[first_layer_bed_temperature];\nM109 S[first_layer_temperature];\nG1 X0 Y0.8 Z0.8 F18000\nG92 E0\nG1 X0 Y0.8 Z0.3 E8 F600\nG92 E0\nG1 X200 Y0.8 Z0.3 F1800.0 E20.0;draw line\nG92 E0\nG1 X200 Y0 Z0.3 F1800.0 E0.08;draw line\nG92 E0\nG1 X100 Y0 Z0.3 F1800.0 E10.0;draw line\nG92 E0\nG1 X100 Y1.6 Z0.3 F1800.0 E0.16;draw line\nG92 E0\nG1 X180 Y1.6 Z0.3 F1800.0 E8;draw line\nG92 E0\nG1 X180 Y0 Z0.3 F1800.0 E0.16;draw line\nG92 E0\nG1 E-1 Z5 F18000\nG92 E0",
"machine_unload_filament_time": "0",
"manual_filament_change": "0",
"max_layer_height": [

View File

@@ -126,7 +126,7 @@
"0"
],
"machine_pause_gcode": "M600",
"machine_start_gcode": "M104 S140\nM190 S[first_layer_bed_temperature]\nM109 S{temperature_vitrification[0]}\nG28;\nG1 X180 Y247 Z10 F5000\nSET_KINEMATIC_POSITION Y=0\nG1 Y11 F4000\nG1 X180 F4000\nG1 Z-1 F600 \nG1 X230 F4000\nG1 Y15 F4000\nG1 X180 F4000\nG92 E0\nG1 Z10 F1200\nG1 Y0 F5000\nG1 E-1 F3000\nM400\nSET_KINEMATIC_POSITION Y=247\nG92 E-1\nM140 S[first_layer_bed_temperature];\nM104 S[first_layer_temperature];\nG1 X0 Y0.8 Z0.8 F18000\nG92 E0\nG1 X0 Y0.8 Z0.3 E8 F600\nG92 E0\nG1 X170 Y0.8 Z0.3 F1800.0 E17.0;draw line\nG92 E0\nG1 X170 Y0 Z0.3 F1800.0 E0.08;draw line\nG92 E0\nG1 X70 Y0 Z0.3 F1800.0 E10.0;draw line\nG92 E0\nG1 X70 Y1.6 Z0.3 F1800.0 E0.16;draw line\nG92 E0\nG1 X150 Y1.6 Z0.3 F1800.0 E8;draw line\nG92 E0\nG1 X150 Y0 Z0.3 F1800.0 E0.16;draw line\nG92 E0\nG1 E-1 Z5 F18000\nG92 E0\n",
"machine_start_gcode": "M104 S140\nM190 S[first_layer_bed_temperature]\nM109 S{temperature_vitrification[0]}\nG28;\nG1 X180 Y247 Z10 F5000\nSET_KINEMATIC_POSITION Y=0\nG1 Y11 F4000\nG1 X180 F4000\nG1 Z-1 F600 \nG1 X230 F4000\nG1 Y15 F4000\nG1 X180 F4000\nG92 E0\nG1 Z10 F1200\nG1 Y0 F5000\nG1 E-1 F3000\nM400\nSET_KINEMATIC_POSITION Y=247\nG92 E-1\nM140 S[first_layer_bed_temperature];\nM109 S[first_layer_temperature];\nG1 X0 Y0.8 Z0.8 F18000\nG92 E0\nG1 X0 Y0.8 Z0.3 E8 F600\nG92 E0\nG1 X170 Y0.8 Z0.3 F1800.0 E17.0;draw line\nG92 E0\nG1 X170 Y0 Z0.3 F1800.0 E0.08;draw line\nG92 E0\nG1 X70 Y0 Z0.3 F1800.0 E10.0;draw line\nG92 E0\nG1 X70 Y1.6 Z0.3 F1800.0 E0.16;draw line\nG92 E0\nG1 X150 Y1.6 Z0.3 F1800.0 E8;draw line\nG92 E0\nG1 X150 Y0 Z0.3 F1800.0 E0.16;draw line\nG92 E0\nG1 E-1 Z5 F18000\nG92 E0\n",
"machine_unload_filament_time": "0",
"manual_filament_change": "0",
"max_layer_height": [

View File

@@ -45,7 +45,7 @@
"0"
],
"filament_max_volumetric_speed": [
"1"
"10"
],
"filament_minimal_purge_on_wipe_tower": [
"15"

View File

@@ -54,7 +54,7 @@
"0"
],
"filament_max_volumetric_speed": [
"2"
"12"
],
"filament_minimal_purge_on_wipe_tower": [
"15"

View File

@@ -51,7 +51,7 @@
"0"
],
"filament_max_volumetric_speed": [
"1"
"12"
],
"filament_retraction_length": [
"0.8"

View File

@@ -48,7 +48,7 @@
"0"
],
"filament_max_volumetric_speed": [
"1"
"12"
],
"filament_retraction_length": [
"0.8"

View File

@@ -48,7 +48,7 @@
"0"
],
"filament_max_volumetric_speed": [
"2"
"12"
],
"filament_type": [
"PETG"

View File

@@ -39,7 +39,7 @@
"0"
],
"filament_max_volumetric_speed": [
"1"
"16"
],
"filament_minimal_purge_on_wipe_tower": [
"15"

View File

@@ -45,7 +45,7 @@
"0"
],
"filament_max_volumetric_speed": [
"1"
"16"
],
"filament_minimal_purge_on_wipe_tower": [
"15"

View File

@@ -45,7 +45,7 @@
"0"
],
"filament_max_volumetric_speed": [
"1"
"16"
],
"filament_minimal_purge_on_wipe_tower": [
"15"

View File

@@ -48,7 +48,7 @@
"0"
],
"filament_max_volumetric_speed": [
"1"
"12"
],
"filament_minimal_purge_on_wipe_tower": [
"15"

View File

@@ -54,7 +54,7 @@
"0"
],
"filament_max_volumetric_speed": [
"2"
"12"
],
"filament_minimal_purge_on_wipe_tower": [
"15"

View File

@@ -48,7 +48,7 @@
"0"
],
"filament_max_volumetric_speed": [
"1"
"12"
],
"filament_minimal_purge_on_wipe_tower": [
"15"

View File

@@ -54,7 +54,7 @@
"0"
],
"filament_max_volumetric_speed": [
"1.8"
"12"
],
"filament_minimal_purge_on_wipe_tower": [
"15"

View File

@@ -48,7 +48,7 @@
"0"
],
"filament_max_volumetric_speed": [
"2"
"16"
],
"filament_minimal_purge_on_wipe_tower": [
"15"

View File

@@ -45,7 +45,7 @@
"1"
],
"filament_max_volumetric_speed": [
"3"
"6"
],
"filament_retract_before_wipe": [
"100%"

View File

@@ -54,7 +54,7 @@
"0"
],
"filament_max_volumetric_speed": [
"4"
"10"
],
"filament_retract_before_wipe": [
"100%"

View File

@@ -54,7 +54,7 @@
"0"
],
"filament_max_volumetric_speed": [
"4"
"10"
],
"filament_retract_before_wipe": [
"100%"

View File

@@ -54,7 +54,7 @@
"0"
],
"filament_max_volumetric_speed": [
"4"
"10"
],
"filament_retract_before_wipe": [
"100%"

View File

@@ -54,7 +54,7 @@
"0"
],
"filament_max_volumetric_speed": [
"4"
"10"
],
"filament_retract_before_wipe": [
"100%"

View File

@@ -48,7 +48,7 @@
"0"
],
"filament_max_volumetric_speed": [
"2"
"16"
],
"filament_minimal_purge_on_wipe_tower": [
"15"

View File

@@ -48,7 +48,7 @@
"1"
],
"filament_max_volumetric_speed": [
"3"
"6"
],
"filament_retract_before_wipe": [
"100"

View File

@@ -57,7 +57,7 @@
"0"
],
"filament_max_volumetric_speed": [
"1"
"10"
],
"filament_minimal_purge_on_wipe_tower": [
"15"

View File

@@ -51,7 +51,7 @@
"0"
],
"filament_max_volumetric_speed": [
"2"
"23"
],
"filament_minimal_purge_on_wipe_tower": [
"15"

View File

@@ -54,7 +54,7 @@
"0"
],
"filament_max_volumetric_speed": [
"2"
"18"
],
"filament_minimal_purge_on_wipe_tower": [
"15"

View File

@@ -51,7 +51,7 @@
"0"
],
"filament_max_volumetric_speed": [
"2"
"18"
],
"filament_retract_before_wipe": [
"100"

View File

@@ -39,7 +39,7 @@
"0"
],
"filament_max_volumetric_speed": [
"2"
"21"
],
"filament_minimal_purge_on_wipe_tower": [
"15"

View File

@@ -45,7 +45,7 @@
"0"
],
"filament_max_volumetric_speed": [
"2"
"21"
],
"filament_minimal_purge_on_wipe_tower": [
"15"

View File

@@ -51,7 +51,7 @@
"0"
],
"filament_max_volumetric_speed": [
"2"
"21"
],
"filament_minimal_purge_on_wipe_tower": [
"15"

View File

@@ -1,9 +1,13 @@
{
"name": "Custom Printer",
"version": "02.04.00.00",
"version": "02.04.00.03",
"force_update": "0",
"description": "My configurations",
"machine_model_list": [
{
"name": "Generic Belt Printer",
"sub_path": "machine/MyBeltPrinter.json"
},
{
"name": "Generic Klipper Printer",
"sub_path": "machine/MyKlipper.json"
@@ -262,18 +266,38 @@
"name": "MyKlipper 0.8 nozzle",
"sub_path": "machine/MyKlipper 0.8 nozzle.json"
},
{
"name": "fdm_belt_common",
"sub_path": "machine/fdm_belt_common.json"
},
{
"name": "fdm_toolchanger_common",
"sub_path": "machine/fdm_toolchanger_common.json"
},
{
"name": "MyRepetier 0.4 nozzle",
"sub_path": "machine/MyRepetier 0.4 nozzle.json"
},
{
"name": "MyRRF 0.4 nozzle",
"sub_path": "machine/MyRRF 0.4 nozzle.json"
},
{
"name": "MyBeltPrinter 0.2 nozzle",
"sub_path": "machine/MyBeltPrinter 0.2 nozzle.json"
},
{
"name": "MyBeltPrinter 0.4 nozzle",
"sub_path": "machine/MyBeltPrinter 0.4 nozzle.json"
},
{
"name": "MyBeltPrinter 0.6 nozzle",
"sub_path": "machine/MyBeltPrinter 0.6 nozzle.json"
},
{
"name": "MyBeltPrinter 0.8 nozzle",
"sub_path": "machine/MyBeltPrinter 0.8 nozzle.json"
},
{
"name": "MyRepetier 0.4 nozzle",
"sub_path": "machine/MyRepetier 0.4 nozzle.json"
},
{
"name": "MyToolChanger 0.2 nozzle",
"sub_path": "machine/MyToolChanger 0.2 nozzle.json"

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

@@ -0,0 +1,26 @@
{
"type": "machine",
"name": "MyBeltPrinter 0.2 nozzle",
"inherits": "fdm_belt_common",
"from": "system",
"setting_id": "GM_BELT_001",
"instantiation": "true",
"printer_model": "Generic Belt Printer",
"nozzle_diameter": [
"0.2"
],
"max_layer_height": [
"0.16"
],
"min_layer_height": [
"0.04"
],
"printer_variant": "0.2",
"printable_area": [
"0x0",
"350x0",
"350x350",
"0x350"
],
"printable_height": "300"
}

View File

@@ -0,0 +1,20 @@
{
"type": "machine",
"name": "MyBeltPrinter 0.4 nozzle",
"inherits": "fdm_belt_common",
"from": "system",
"setting_id": "GM_BELT_002",
"instantiation": "true",
"printer_model": "Generic Belt Printer",
"nozzle_diameter": [
"0.4"
],
"printer_variant": "0.4",
"printable_area": [
"0x0",
"350x0",
"350x350",
"0x350"
],
"printable_height": "300"
}

View File

@@ -0,0 +1,26 @@
{
"type": "machine",
"name": "MyBeltPrinter 0.6 nozzle",
"inherits": "fdm_belt_common",
"from": "system",
"setting_id": "GM_BELT_003",
"instantiation": "true",
"printer_model": "Generic Belt Printer",
"nozzle_diameter": [
"0.6"
],
"max_layer_height": [
"0.4"
],
"min_layer_height": [
"0.12"
],
"printer_variant": "0.6",
"printable_area": [
"0x0",
"350x0",
"350x350",
"0x350"
],
"printable_height": "300"
}

View File

@@ -0,0 +1,26 @@
{
"type": "machine",
"name": "MyBeltPrinter 0.8 nozzle",
"inherits": "fdm_belt_common",
"from": "system",
"setting_id": "GM_BELT_004",
"instantiation": "true",
"printer_model": "Generic Belt Printer",
"nozzle_diameter": [
"0.8"
],
"max_layer_height": [
"0.6"
],
"min_layer_height": [
"0.2"
],
"printer_variant": "0.8",
"printable_area": [
"0x0",
"350x0",
"350x350",
"0x350"
],
"printable_height": "300"
}

View File

@@ -0,0 +1,12 @@
{
"type": "machine_model",
"name": "Generic Belt Printer",
"model_id": "my_belt_01",
"nozzle_diameter": "0.4;0.2;0.6;0.8",
"machine_tech": "FFF",
"family": "MyPrinter",
"bed_model": "Custom_350_bed.stl",
"bed_texture": "orcaslicer_bed_texture.svg",
"hotend_model": "",
"default_materials": "Generic PLA @System;Generic PLA-CF @System;Generic PETG @System;Generic TPU @System;Generic PC @System;Generic PVA @System;Generic PA @System;Generic PA-CF @System"
}

View File

@@ -0,0 +1,99 @@
{
"type": "machine",
"name": "fdm_belt_common",
"inherits": "fdm_klipper_common",
"from": "system",
"instantiation": "false",
"gcode_flavor": "klipper",
"single_extruder_multi_material": "0",
"default_filament_profile": [
"Generic PLA @System"
],
"default_print_profile": "0.20mm Standard @System",
"max_layer_height": [
"0.32"
],
"min_layer_height": [
"0.08"
],
"deretraction_speed": [
"30"
],
"extruder_colour": [
"#FCE94F"
],
"extruder_offset": [
"0x0"
],
"long_retractions_when_cut": [
"0"
],
"nozzle_diameter": [
"0.4"
],
"retract_before_wipe": [
"70%"
],
"retract_length_toolchange": [
"2"
],
"retract_lift_above": [
"0"
],
"retract_lift_below": [
"0"
],
"retract_lift_enforce": [
"All Surfaces"
],
"retract_restart_extra": [
"0"
],
"retract_restart_extra_toolchange": [
"0"
],
"retract_when_changing_layer": [
"1"
],
"retraction_distances_when_cut": [
"18"
],
"retraction_length": [
"0.8"
],
"retraction_minimum_travel": [
"1"
],
"retraction_speed": [
"30"
],
"travel_slope": [
"3"
],
"wipe": [
"1"
],
"wipe_distance": [
"1"
],
"z_hop": [
"0.4"
],
"z_hop_types": [
"Normal Lift"
],
"gcode_remap_x": "rev_x",
"gcode_remap_y": "pos_z",
"gcode_remap_z": "pos_y",
"printer_extruder_id": [
"1"
],
"belt_printer": "1",
"belt_slice_rotation": "x",
"belt_slice_rotation_angle": "45",
"belt_slice_rotation_global": "1",
"build_plate_tilt_x": "45",
"purge_in_prime_tower": "0",
"scan_first_layer": "0",
"auxiliary_fan": "0"
}

View File

@@ -1,7 +1,7 @@
{
"name": "Flashforge",
"url": "",
"version": "02.04.00.01",
"version": "02.04.00.03",
"force_update": "0",
"description": "Flashforge configurations",
"machine_model_list": [

View File

@@ -9,14 +9,7 @@
"Flashforge ABS Basic @FF AD5M 0.25 nozzle"
],
"compatible_printers": [
"Flashforge Adventurer 5M 0.4 Nozzle",
"Flashforge Adventurer 5M 0.6 Nozzle",
"Flashforge Adventurer 5M 0.8 Nozzle",
"Flashforge Adventurer 5M Pro 0.4 Nozzle",
"Flashforge Adventurer 5M Pro 0.6 Nozzle",
"Flashforge Adventurer 5M Pro 0.8 Nozzle",
"Flashforge AD5X 0.4 nozzle",
"Flashforge AD5X 0.6 nozzle",
"Flashforge AD5X 0.8 nozzle"
"Flashforge Adventurer 5M 0.25 Nozzle",
"Flashforge Adventurer 5M Pro 0.25 Nozzle"
]
}

View File

@@ -14,9 +14,6 @@
"Flashforge Adventurer 5M 0.8 Nozzle",
"Flashforge Adventurer 5M Pro 0.4 Nozzle",
"Flashforge Adventurer 5M Pro 0.6 Nozzle",
"Flashforge Adventurer 5M Pro 0.8 Nozzle",
"Flashforge AD5X 0.4 nozzle",
"Flashforge AD5X 0.6 nozzle",
"Flashforge AD5X 0.8 nozzle"
"Flashforge Adventurer 5M Pro 0.8 Nozzle"
]
}

View File

@@ -9,14 +9,7 @@
"Flashforge ASA Basic @FF AD5M 0.25 nozzle"
],
"compatible_printers": [
"Flashforge Adventurer 5M 0.4 Nozzle",
"Flashforge Adventurer 5M 0.6 Nozzle",
"Flashforge Adventurer 5M 0.8 Nozzle",
"Flashforge Adventurer 5M Pro 0.4 Nozzle",
"Flashforge Adventurer 5M Pro 0.6 Nozzle",
"Flashforge Adventurer 5M Pro 0.8 Nozzle",
"Flashforge AD5X 0.4 nozzle",
"Flashforge AD5X 0.6 nozzle",
"Flashforge AD5X 0.8 nozzle"
"Flashforge Adventurer 5M 0.25 Nozzle",
"Flashforge Adventurer 5M Pro 0.25 Nozzle"
]
}

View File

@@ -14,9 +14,6 @@
"Flashforge Adventurer 5M 0.8 Nozzle",
"Flashforge Adventurer 5M Pro 0.4 Nozzle",
"Flashforge Adventurer 5M Pro 0.6 Nozzle",
"Flashforge Adventurer 5M Pro 0.8 Nozzle",
"Flashforge AD5X 0.4 nozzle",
"Flashforge AD5X 0.6 nozzle",
"Flashforge AD5X 0.8 nozzle"
"Flashforge Adventurer 5M Pro 0.8 Nozzle"
]
}

View File

@@ -9,14 +9,7 @@
"Flashforge HS PETG @FF AD5M 0.25 nozzle"
],
"compatible_printers": [
"Flashforge Adventurer 5M 0.4 Nozzle",
"Flashforge Adventurer 5M 0.6 Nozzle",
"Flashforge Adventurer 5M 0.8 Nozzle",
"Flashforge Adventurer 5M Pro 0.4 Nozzle",
"Flashforge Adventurer 5M Pro 0.6 Nozzle",
"Flashforge Adventurer 5M Pro 0.8 Nozzle",
"Flashforge AD5X 0.4 nozzle",
"Flashforge AD5X 0.6 nozzle",
"Flashforge AD5X 0.8 nozzle"
"Flashforge Adventurer 5M 0.25 Nozzle",
"Flashforge Adventurer 5M Pro 0.25 Nozzle"
]
}

View File

@@ -14,9 +14,6 @@
"Flashforge Adventurer 5M 0.8 Nozzle",
"Flashforge Adventurer 5M Pro 0.4 Nozzle",
"Flashforge Adventurer 5M Pro 0.6 Nozzle",
"Flashforge Adventurer 5M Pro 0.8 Nozzle",
"Flashforge AD5X 0.4 nozzle",
"Flashforge AD5X 0.6 nozzle",
"Flashforge AD5X 0.8 nozzle"
"Flashforge Adventurer 5M Pro 0.8 Nozzle"
]
}

View File

@@ -9,14 +9,7 @@
"Flashforge PETG Basic @FF AD5M 0.25 nozzle"
],
"compatible_printers": [
"Flashforge Adventurer 5M 0.4 Nozzle",
"Flashforge Adventurer 5M 0.6 Nozzle",
"Flashforge Adventurer 5M 0.8 Nozzle",
"Flashforge Adventurer 5M Pro 0.4 Nozzle",
"Flashforge Adventurer 5M Pro 0.6 Nozzle",
"Flashforge Adventurer 5M Pro 0.8 Nozzle",
"Flashforge AD5X 0.4 nozzle",
"Flashforge AD5X 0.6 nozzle",
"Flashforge AD5X 0.8 nozzle"
"Flashforge Adventurer 5M 0.25 Nozzle",
"Flashforge Adventurer 5M Pro 0.25 Nozzle"
]
}

View File

@@ -9,14 +9,7 @@
"Flashforge PETG Pro @FF AD5M 0.25 nozzle"
],
"compatible_printers": [
"Flashforge Adventurer 5M 0.4 Nozzle",
"Flashforge Adventurer 5M 0.6 Nozzle",
"Flashforge Adventurer 5M 0.8 Nozzle",
"Flashforge Adventurer 5M Pro 0.4 Nozzle",
"Flashforge Adventurer 5M Pro 0.6 Nozzle",
"Flashforge Adventurer 5M Pro 0.8 Nozzle",
"Flashforge AD5X 0.4 nozzle",
"Flashforge AD5X 0.6 nozzle",
"Flashforge AD5X 0.8 nozzle"
"Flashforge Adventurer 5M 0.25 Nozzle",
"Flashforge Adventurer 5M Pro 0.25 Nozzle"
]
}

View File

@@ -32,9 +32,6 @@
"Flashforge Adventurer 5M 0.8 Nozzle",
"Flashforge Adventurer 5M Pro 0.4 Nozzle",
"Flashforge Adventurer 5M Pro 0.6 Nozzle",
"Flashforge Adventurer 5M Pro 0.8 Nozzle",
"Flashforge AD5X 0.4 nozzle",
"Flashforge AD5X 0.6 nozzle",
"Flashforge AD5X 0.8 nozzle"
"Flashforge Adventurer 5M Pro 0.8 Nozzle"
]
}

View File

@@ -9,14 +9,7 @@
"Flashforge PETG Transparent @FF AD5M 0.25 nozzle"
],
"compatible_printers": [
"Flashforge Adventurer 5M 0.4 Nozzle",
"Flashforge Adventurer 5M 0.6 Nozzle",
"Flashforge Adventurer 5M 0.8 Nozzle",
"Flashforge Adventurer 5M Pro 0.4 Nozzle",
"Flashforge Adventurer 5M Pro 0.6 Nozzle",
"Flashforge Adventurer 5M Pro 0.8 Nozzle",
"Flashforge AD5X 0.4 nozzle",
"Flashforge AD5X 0.6 nozzle",
"Flashforge AD5X 0.8 nozzle"
"Flashforge Adventurer 5M 0.25 Nozzle",
"Flashforge Adventurer 5M Pro 0.25 Nozzle"
]
}

View File

@@ -32,9 +32,6 @@
"Flashforge Adventurer 5M 0.8 Nozzle",
"Flashforge Adventurer 5M Pro 0.4 Nozzle",
"Flashforge Adventurer 5M Pro 0.6 Nozzle",
"Flashforge Adventurer 5M Pro 0.8 Nozzle",
"Flashforge AD5X 0.4 nozzle",
"Flashforge AD5X 0.6 nozzle",
"Flashforge AD5X 0.8 nozzle"
"Flashforge Adventurer 5M Pro 0.8 Nozzle"
]
}

View File

@@ -9,14 +9,7 @@
"Flashforge PLA Basic @FF AD5M 0.25 nozzle"
],
"compatible_printers": [
"Flashforge Adventurer 5M 0.4 Nozzle",
"Flashforge Adventurer 5M 0.6 Nozzle",
"Flashforge Adventurer 5M 0.8 Nozzle",
"Flashforge Adventurer 5M Pro 0.4 Nozzle",
"Flashforge Adventurer 5M Pro 0.6 Nozzle",
"Flashforge Adventurer 5M Pro 0.8 Nozzle",
"Flashforge AD5X 0.4 nozzle",
"Flashforge AD5X 0.6 nozzle",
"Flashforge AD5X 0.8 nozzle"
"Flashforge Adventurer 5M 0.25 Nozzle",
"Flashforge Adventurer 5M Pro 0.25 Nozzle"
]
}

View File

@@ -14,9 +14,6 @@
"Flashforge Adventurer 5M 0.8 Nozzle",
"Flashforge Adventurer 5M Pro 0.4 Nozzle",
"Flashforge Adventurer 5M Pro 0.6 Nozzle",
"Flashforge Adventurer 5M Pro 0.8 Nozzle",
"Flashforge AD5X 0.4 nozzle",
"Flashforge AD5X 0.6 nozzle",
"Flashforge AD5X 0.8 nozzle"
"Flashforge Adventurer 5M Pro 0.8 Nozzle"
]
}

View File

@@ -9,14 +9,7 @@
"Flashforge PLA Color Change @FF AD5M 0.25 nozzle"
],
"compatible_printers": [
"Flashforge Adventurer 5M 0.4 Nozzle",
"Flashforge Adventurer 5M 0.6 Nozzle",
"Flashforge Adventurer 5M 0.8 Nozzle",
"Flashforge Adventurer 5M Pro 0.4 Nozzle",
"Flashforge Adventurer 5M Pro 0.6 Nozzle",
"Flashforge Adventurer 5M Pro 0.8 Nozzle",
"Flashforge AD5X 0.4 nozzle",
"Flashforge AD5X 0.6 nozzle",
"Flashforge AD5X 0.8 nozzle"
"Flashforge Adventurer 5M 0.25 Nozzle",
"Flashforge Adventurer 5M Pro 0.25 Nozzle"
]
}

View File

@@ -14,9 +14,6 @@
"Flashforge Adventurer 5M 0.8 Nozzle",
"Flashforge Adventurer 5M Pro 0.4 Nozzle",
"Flashforge Adventurer 5M Pro 0.6 Nozzle",
"Flashforge Adventurer 5M Pro 0.8 Nozzle",
"Flashforge AD5X 0.4 nozzle",
"Flashforge AD5X 0.6 nozzle",
"Flashforge AD5X 0.8 nozzle"
"Flashforge Adventurer 5M Pro 0.8 Nozzle"
]
}

View File

@@ -9,14 +9,7 @@
"Flashforge PLA Galaxy @FF AD5M 0.25 nozzle"
],
"compatible_printers": [
"Flashforge Adventurer 5M 0.4 Nozzle",
"Flashforge Adventurer 5M 0.6 Nozzle",
"Flashforge Adventurer 5M 0.8 Nozzle",
"Flashforge Adventurer 5M Pro 0.4 Nozzle",
"Flashforge Adventurer 5M Pro 0.6 Nozzle",
"Flashforge Adventurer 5M Pro 0.8 Nozzle",
"Flashforge AD5X 0.4 nozzle",
"Flashforge AD5X 0.6 nozzle",
"Flashforge AD5X 0.8 nozzle"
"Flashforge Adventurer 5M 0.25 Nozzle",
"Flashforge Adventurer 5M Pro 0.25 Nozzle"
]
}

View File

@@ -14,9 +14,6 @@
"Flashforge Adventurer 5M 0.8 Nozzle",
"Flashforge Adventurer 5M Pro 0.4 Nozzle",
"Flashforge Adventurer 5M Pro 0.6 Nozzle",
"Flashforge Adventurer 5M Pro 0.8 Nozzle",
"Flashforge AD5X 0.4 nozzle",
"Flashforge AD5X 0.6 nozzle",
"Flashforge AD5X 0.8 nozzle"
"Flashforge Adventurer 5M Pro 0.8 Nozzle"
]
}

View File

@@ -9,14 +9,7 @@
"Flashforge PLA Luminous @FF AD5M 0.25 nozzle"
],
"compatible_printers": [
"Flashforge Adventurer 5M 0.4 Nozzle",
"Flashforge Adventurer 5M 0.6 Nozzle",
"Flashforge Adventurer 5M 0.8 Nozzle",
"Flashforge Adventurer 5M Pro 0.4 Nozzle",
"Flashforge Adventurer 5M Pro 0.6 Nozzle",
"Flashforge Adventurer 5M Pro 0.8 Nozzle",
"Flashforge AD5X 0.4 nozzle",
"Flashforge AD5X 0.6 nozzle",
"Flashforge AD5X 0.8 nozzle"
"Flashforge Adventurer 5M 0.25 Nozzle",
"Flashforge Adventurer 5M Pro 0.25 Nozzle"
]
}

Some files were not shown because too many files have changed in this diff Show More