Commit Graph
278 Commits
Author SHA1 Message Date
raistlin7447 17c3bbb7b6 Merge branch 'main' into perf/slicing-optimizations 2026-10-19 11:33:03 -05:00
Ian Bassi 9f6a344162 Make the adaptive infill settings pattern-neutral (#16654) 2026-10-19 12:05:55 -03:00
Ian BassiandRodrigo Faselli 0acf1e6680 Fix wall order on narrow tube walls and under outer brims, and test wall order and direction (#16421)
Co-authored-by: Rodrigo Faselli <162915171+RF47@users.noreply.github.com>
2026-10-16 18:56:55 -03:00
Arthur Porto 6aa613ccf0 Fix Z contouring failing on objects with several instances (#16461)
* Let Z contouring slice objects that have several instances

The contouring step refused any object with more than one instance. The
instances of a PrintObject differ only by their XY shift, so the mesh is now
placed with the first instance of the PrintObject being contoured.

* Say in the Z contouring comment how instances map to print objects

* Check that Z contouring follows each instance as it is turned
2026-10-15 07:30:57 -03:00
Ian Bassi e821665e4b Add orca-translations Claude skill and PO tool (#16436)
* Add orca-translations Claude skill and PO tool

Add a .claude skill that guides translation passes over the localization/i18n gettext catalogs. It covers the workflow: run gettext, settle new glossary terms, translate in batches, verify, and report.

Includes translation-rules.md, which condenses the placeholder, line-break and glossary rules plus the guidance on review notes.

Also adds scripts/po_tool.py (standard library only). It lists pending entries with glossary hints, validates and applies translations, adding '# AI Translated' and '# Needs human review' comments, and rewrites only the entries it changes. It can also check catalogs, look up existing translations, suggest glossary candidates and update the wiki glossary TSV.

* Let po_tool apply translations by entry id

pending now gives each entry a short id, so a translation file can name
entries by id instead of repeating the English msgid. apply accepts either.

A "review": "" item clears an earlier review note when overwriting an
entry, and check gives each msgfmt run its own temporary output file so
parallel checks do not collide.

* Fill all empty translations

Regenerate the template with run_gettext --full and translate every empty
entry in the 22 catalogs (7,089 entries) with the orca-translations skill,
following the localization glossary, including the new belt printer,
IDEX/IQEX and plugin terms. Every new entry is marked "# AI Translated";
122 also carry "# Needs human review" with what to check.

* Show entry ids in po_tool lookup and search translations

lookup now prints each entry's id, so an entry found there can be
rewritten with apply --overwrite without repeating the English, and
--msgstr searches the translations instead of the msgids, which finds
every entry that still uses a term being changed.

SKILL.md describes how to change an established term: check the
catalog's usage first, update the glossary cell, then rewrite only the
entries where the term has that meaning.

* Fix mistranslated terms and align catalogs with the glossary

Correct labels that the glossary had copied, and the entries that used
them:
- ca: Raft was rendered as the Brim term; it is now "Rai". Exhaust fan,
  Monotonic line, Unretract, Slice, Lateral Honeycomb and PA Tower
  labels fixed.
- cs: Lightning infill is "Blesk", not "Osvětlení" (illumination).
- sv: Retraction is "Retraktion", not "Reduktion"; Unretract,
  Lagerhöjd, Delkylningsfläkt, Utsugsfläkt, Aligned Rectilinear and the
  Preset label fixed.
- de: Brim is "Rand" and Skirt is "Umrandung", as most entries already
  had them.
- lt: brim entries used the Skirt word "apvadas"; they now use "kraštas".
- es: Sparse infill is "relleno de baja densidad", the catalog majority.
- eu: nozzle wipe is "garbiketa", not purge.
- th: the project plate is "เพลต", distinct from the bed.
- uk: Quarter Cubic, Latin "PA" in PA Tower, and Belt purge tower.
- pl: Cross Hatch, Tri-hexagon, Volumetric speed and Raft labels.
- zh_TW: Brim stays "Brim", as the existing labels have it.
- tr: "Prime Tower" read "Prime Minister Tower".
- ko: the plugin "Capabilities" label read "performance".
- Build Volume labels fixed in tr, de, cs and eu.

All 242 rewritten entries are marked "# AI Translated".

* Make more UI text translatable and fix pluralization and context

Audit the sources for text that translators could not translate
correctly and fix it.

Mark text that reached users in English only: IDEX/IQEX role names,
plugin permission prompts and errors, 3MF/preset loading errors, G-code
placeholder parser errors, calibration and device messages, notification
texts, file dialog filters, and the config validation messages.

Replace sentences built from translated fragments, such as the prime
tower warnings, "left"/"right" nozzle names, and "Filament " + number,
with single msgids that have placeholders, so translators can reorder
and inflect them.

Use plural forms for texts with a count ("%1% mixed filaments",
"%d objects", "%1% triangles") instead of "(s)" and mismatched verbs.
Fix the swapped singular/plural pair in "The following presets inherit
this preset".

Add translation contexts where one English word has several meanings
(Subscribed/Local, Standard, Pause, View, Step, Model, Camera, Flow,
Filter, Others, Prepare, the Design tools). Show "Size" instead of
"Build Volume" in the Cut tool, which displays the object size.

Fix code that compared translated text with English (the Edit G-code
dialog group, the plugin registration failure check), and add the
bundled web pages' missing string-table entries. Use the single
character for degrees Celsius, say "G-code", and describe the head
filament map without internal jargon.

Install the libslic3r translate callback before the presets load, so
their load errors are translated, and list the 28 source files that had
marked strings but were never extracted into localization/i18n/list.txt.

* Suggest earlier translations and list fuzzy entries in po_tool pending

pending now attaches the closest earlier translation of a similar
English text (from obsolete or translated entries), so a reworded or
split string keeps its wording, and it lists fuzzy entries by default,
since users never see them. A fuzzy entry also carries its stale
translation as previous_translation.

* Fix wording of the non-boolean operands error

The logical operation error said "operators" where it means the
operands the operation was applied to.

* Translate the newly translatable strings in all languages

Regenerate the template after the translatability changes and fill every
new or changed entry in the 22 catalogs (about 12,800 entries): the
strings that became translatable, the plural forms, the entries split by
context, and the previously fuzzy singular entries that became plurals.

Every new entry is marked "# AI Translated", and about 360 also carry a
"# Needs human review" note saying what to check. Terms follow the
localization glossary. Earlier translations of reworded strings were
reused where the meaning was unchanged. Existing entries were not
changed, and obsolete entries are kept.

* Document the source translatability audit in the orca-translations skill

Add a reference describing how strings reach translators, what to look
for (untranslated text, spliced sentences, missing plurals, ambiguous
words), what not to translate, where a context cannot be carried, and
what to do after the edits, plus a scanner that lists untranslated
user-facing string literals.

* Document how to write translatable strings in AGENTS.md

Tell developers to keep each message complete in one msgid: use
placeholders instead of concatenating translated fragments, plural forms
for counts, and contexts for ambiguous words, and to list new source
files in localization/i18n/list.txt. Add a matching code review item.

* Translate the strings added since the rebase

Regenerate the template against the current main and translate the 26
new entries per language: the Fix Model commands and messages, and the
texture displacement image adjustment panel. Each new entry is marked
"# AI Translated"; existing entries are unchanged.

* tidy
2026-10-13 10:53:57 -03:00
SoftFever c57b5dc6c5 Merge branch 'main' into perf/slicing-core-memory 2026-10-12 22:16:10 +08:00
Rodrigo Faselli 0f48982b78 Merge branch 'main' into perf/slicing-optimizations 2026-10-11 15:00:58 -03:00
0f3e8fbf27 Add center of mass markers to Prepare and Preview (#16291)
Co-authored-by: Rodrigo Faselli <162915171+RF47@users.noreply.github.com>
Co-authored-by: Kris Austin <kris.austin@gmail.com>
2026-10-09 16:48:48 -03:00
SoftFever f6e8821b13 Merge branch 'main' into perf/slicing-optimizations 2026-10-10 01:09:46 +08:00
Ian BassiandRodrigo Faselli b5f5b50157 Adaptive TPMS (#16005)
Co-authored-by: Rodrigo Faselli <162915171+RF47@users.noreply.github.com>
2026-10-09 12:36:09 -03:00
SoftFever 7f554fde04 Restore the internal bridge expansion from #16056 lost in the main merge 2026-10-09 22:11:47 +08:00
SoftFever d704ee5538 Merge branch 'main' into perf/slicing-optimizations
# Conflicts:
#	src/libslic3r/PerimeterGenerator.cpp
#	src/libslic3r/PrintObject.cpp
#	src/libslic3r/Support/TreeSupport.cpp
2026-10-09 19:48:26 +08:00
SoftFever a5d21b9922 Merge branch 'main' into belt-printer 2026-10-09 13:28:39 +08:00
Ian Bassi 785a1946a6 Fix Adaptive and Support Cubic infill density with modifiers (#16295) 2026-10-08 18:28:56 -03:00
SoftFever 5072f6b614 Merge branch 'main' into belt-printer 2026-10-08 23:03:56 +08:00
Ian Bassi 59fc97fb28 Extend Separated Infills (#16274) 2026-10-08 09:43:46 -03:00
LixNix 7d44b60ae4 H2D X2D Multi Nozzle Size Printing Support (#14125) 2026-10-08 20:28:32 +08:00
harrierpigeonandClaude Fable 5.1 9289fc4dd3 Leading-edge brim takes part in the outer-wall-first rule
The first-layer rule that prints the outer wall first when a brim is
attached to it, and the brim_type change rule that regenerates the
perimeters for it, only knew btOuterOnly.  btLeadingEdgeOnly, the belt
brim at the part's first contact, is an outer brim too.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 19:08:58 -05:00
harrierpigeonandClaude Fable 5.1 b2fb552e32 PrintObject: a re-slice invalidates posDetectOverhangsForLift
posSlice's invalidation list did not include posDetectOverhangsForLift.
A re-slice starts the layers over with empty overhang regions while the
step stayed done, so GCode::needs_retraction() had no overhangs to test
against until something else invalidated it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 19:08:58 -05:00
harrierpigeonandClaude Fable 5.1 a2f5a8ce2b Belt printer: size the layer range from the on-bed box
The belt object height is estimated from a bounding box swept through
the tilt rotation.  raw_bounding_box() has the instance's Z offset
removed, which did not matter while the estimate was the box's rotated
Z extent (a Z shift moves every corner alike), but the frame now starts
at the lowest belt-floor point under the footprint, and a point's
rotated z and the floor under it move in opposite directions under a Z
shift: the offset box under-estimated the height by twice the object's
height above the bed, so the layers stopped at the part's diagonal and
every part came out as a wedge (GUI and CLI alike; the unit tests never
checked the top).  Use the box of the mesh in the frame it is sliced in
(trafo_centered(), Z as placed on the bed), and have the leading
overhang test check that the whole part is sliced.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 00:10:29 -05:00
harrierpigeonandClaude Fable 5.1 dda58b07cd Belt printer: supports reach the belt under a leading overhang
The slicing frame of a belt object started at its lowest vertex, but the
belt under the leading end of an overhang lies below that, by the
overhang's length times the tilt's shear.  Every support generator works
in layers at z >= 0, so none of them could reach it: normal supports
stopped at the object's own lowest layer, and the two tree generators
each carried a stack of hacks to extend themselves below it (a post-hoc
copy of the lowest base area in TreeSupport, "virtual belt raft layers"
in TreeSupport3D/TreeModelVolumes), sized from the pre-rotation bbox
and capped at global z = 0, which is only right for the trailing half
of the belt.

Start the frame at the lowest belt-floor point under the footprint
instead, less a 10 mm margin along the belt for the base of a support
column (BeltSliceStrategy::apply_preslice_transforms and
BeltTransformPipeline::compute_belt_height_and_floor agree on it).  The
layers between it and the first vertex come out empty, which belt
slicing already tolerates, and the generators need no extension at all:

- normal supports: the generator anchors its layer grid at the frame
  origin, so run it in the object frame and shift the global belt Z
  offset onto the result afterwards, as organic supports already did.
  With the offset on the object layers a top contact at negative z
  turned the intermediate-layer count negative and the generator
  allocated layers until the kernel killed it (any overhang in the
  leading half of the belt).  Drop the first-layer flange expansion on a
  belt: the first support layer is the leading tip of the support, not
  a flange, and inflating it put lines in the air ahead of the belt.
- classic tree: a node now keeps dropping until its whole circle is in
  the belt, so the branch tapers to a tip on the belt instead of
  stopping, a radius above it, when its centre crosses.
- organic: the belt is no longer a support blocker.  A blocker is a
  collision, and a branch descending onto one slides off it, down the
  tilted belt and ahead of the part; the belt is where branches end,
  which the per-layer m_belt_floor clipping already does.

The belt brim is generated after the parallel support step instead of
inside it: belt_brim_obstacles() reads every object's layers and support
layers, which another object's support step rebuilds (and, now, shifts)
at the same time.  This is the race behind the Windows arm64 segfault
in "Belt brim of each object precedes its perimeters on its own
filament".

Also: the belt tilt axis moves to Developer mode as its own row (a
shared line is shown by its first option's mode), first_layer_plane
band thickness, belt_support_floor_mode, belt_preslice_global and
gcode_back_transform are retired and presumed on, the gravity arrow is
a plain line along the up direction, and the "Show raw G-code (belt
only)" preview toggle is gone.

Regression test: "Belt supports reach the belt under a leading
overhang" slices a cube with a fin whose underside is parallel to the
layers, 20 mm ahead of the cube and up to 41 mm of slicing Z above the
belt, for normal, organic and classic tree supports, and checks that
the lowest support layer sits on the belt beneath its own lines.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-06 22:14:25 -05:00
harrierpigeonandClaude Fable 5.1 8039d4d2ac Belt printer: retire the redundant and unused options
Removed, with the keys added to handle_legacy()'s ignore list so saved
profiles and 3MFs keep loading:

- belt_slice_rotation_global and preslice_remap_global. Both were only
  consulted when belt_preslice_global ("Global mesh transforms") was off,
  which no profile does; belt_preslice_global is now the single global
  mode and is presumed on everywhere the old flags were ORed in
  (PrintObjectSlice, BeltBackTransform, BeltGCode, Print::process,
  PrintApply). The Belt tilt row is axis + angle only.
- preslice_remap_x/y/z. No profile used the pre-slice axis remap; the belt
  tilt axis plus the G-code axis remap cover the machines that exist, and
  its implementation only agreed with itself for a plain swap (matrix
  columns vs remap_bbox rows). BeltTransformPipeline::build_preslice_remap,
  remap_bbox and has_preslice_remap are gone, the forward transform is the
  rotation, and the G-code header no longer carries the remap.
- belt_support_z_offset_mode. Saved and invalidated steps, but no support
  generator read it.
- first_layer_plane and first_layer_plane_offset, with FirstLayerPlane.cpp.
  On every shipped configuration the band is measured from the belt
  surface (GCode::belt_height_above_floor) and the evaluator was only
  reached for an explicit XY/YZ/XZ choice or a non-zero offset, which
  nobody set. first_layer_plane_thickness stays as the band unit,
  relabelled "First layer band thickness".

UI: the Machine frame transforms group is five single-option rows (G-code
remap X / Y / Z, Decouple machine-frame tilt, Machine-frame tilt angle;
the angle row is shown only when decoupled) instead of two multi-column
lines, and the remap fields carry full labels.

Also carries the phong.fs struct fix from #16226 so the worktree build
links its shaders.

libslic3r_tests and fff_print_tests pass; clang-tidy diff check clean;
orca_profile_tool.py check clean.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-06 18:14:34 -05:00
Joseph Robertson d2aa937ad7 Merge branch 'main' into belt-printer 2026-10-05 23:20:23 -05:00
harrierpigeonandClaude Fable 5.1 61a0db4a87 Belt printer: address the review on #14394
Code review items (raistlin7447):

1. PrintObject::slice() zeroes m_belt_min_z, m_belt_global_z_offset and
   m_belt_global_xy_correction before slicing. They were only written in belt
   mode, so a project switched to a normal printer, or whose tilt axis was set
   to None, kept the old offsets and shifted the adaptive infill octree and the
   organic support layers by them.
2. TreeModelVolumes shifts the support blockers into the raft-offset index
   space; a test now pins the index the blocker lands on.
3. The final-alignment clamp in libnest2d is opt-in (NfpPConfig::clamp_to_bin)
   and arrange sets it for belt printers only. Printers with an off-centre
   best_object_pos keep their alignment; a flat-bed test pins that.
4. The preview's belt view follows the loaded G-code, not the selected printer:
   GCodeProcessor carries the file's belt keys (and, for a belt file, its bed)
   into export_config_for_render(), and GCodeViewer enables the belt view from
   the header tilt.
5. belt_shift_layer_grid() also shifts the cached belt floor and the global Z
   offset, so a support-only or brim-only change after the purge-prism snap
   matches a fresh slice.
6. update_print_fff_config() resets raft_layers and draft_shield on a belt
   printer instead of only greying out the fields Print::validate() rejects.
7. GCodeWriter takes a first-layer point test instead of the FirstLayerPlane;
   GCode installs one that measures from the belt surface, like its
   extrusions, so the first-layer travel speed and the second-layer
   temperature change no longer depend on the gcode_remap_* convention.
8. belt_brim_clip_leading_edge() is exported and called by both the generator
   and the test.
9. Both phong.vs shaders use slope.up_direction for the overhang highlight.

The pre-slice and G-code axis remaps are gated on belt_printer through
BeltTransformPipeline::axis_remap_enabled(), so belt keys left in a profile
cannot change a non-belt print.

Tests requested in the review: belt-only keys at non-default values leave
non-belt G-code unchanged; switching a sliced project from belt to non-belt
(and tilt axis None) matches a fresh slice; a support-only change on a belt
purge print matches a fresh slice; non-belt start G-code moves keep the
first-layer Z in the processor; the belt brim's segment count catches a band
emitted twice.

The belt-to-non-belt test exposed an unrelated gap: invalidate_step(posSlice)
re-invalidated posSupportMaterial but not posSimplifySupportPath, so after
any re-slice the regenerated support paths were exported unsimplified.
posSimplifySupportPath is now in that list.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-05 23:06:01 -05:00
harrierpigeonandClaude Fable 5.1 9dbd0307f8 Add the includes clang-tidy's include cleaner asks for on the belt files
The clang-tidy job on #14394 fails on 129 misc-include-cleaner findings:
the belt sources and tests use std::, Eigen, Point/PrintConfig and
BeltBrim symbols without including the header that provides them, which
only compiled because the precompiled header supplied it. Every include
the job names is added, in each file's existing include style ("../" in
the GCode/ and Support/ subdirectories, quoted libslic3r/ paths in the
GUI and tests). No code changes.

Verified with scripts/clang_tidy_diff.py -p build-tidy --base eb5b9a77b9
(SLIC3R_PCH=OFF compile database, clang-tidy 22.1.8): no findings left.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L6Kg5igmmMU2YLoK6HrsWV
2026-10-05 20:43:18 -05:00
Kiss Lorand fefedb66c4 Fix overlapping internal bridges (#16177) 2026-10-05 21:17:20 -03:00
Hanif Koh 325ecdda10 Merge Main into Belt Printer 2026-10-05 17:27:52 +08:00
HanifKoh 4895bc03b4 Remove Unused Project Includes and Forward-Declare Where a Type Is Only Referenced (#16099)
* Remove Unused Project Includes and Forward-Declare Where a Type Is Only Referenced

Generated with include-what-you-use and applied conservatively. Only OrcaSlicer's own headers, the ones under src/ and tests/, are removed or forward-declared; standard-library and third-party includes are left alone. An include is removed only when both the Release and the Debug configuration leave it unused, never from inside a conditional block, and never from a file with platform-specific blocks, which only gain includes. Files whose only use of a header sits behind a feature or debug macro (libvgcode's OpenGL ES and marker code, the ARACHNE/TESTS_EXPORT_SVGS debug output) keep their includes.

clonable_ptr.hpp gains #pragma once; it had no include guard and was only safe while Config.hpp was its sole includer.

* Remove Unused Project Includes From Files With Platform-Specific Code

A Linux include-what-you-use run cannot see the code inside _WIN32, __APPLE__ or __linux__ blocks, so its verdict is only taken where nothing the removed header declares, directly or through what it includes, is named inside those blocks. Removals also have to hold in both the Release and Debug configuration and never touch a line inside a conditional block.

* Restore the libslic3r Precompiled Header and Direct Includes Lost in the Platform Pass

The platform-file pass treated pchheader.hpp as an ordinary header and
emptied it, and left GUI_Preview.hpp and 14 other files relying on
headers they no longer reached directly.

* Restore MainFrame.hpp in ParamsDialog.cpp for the Windows-Only Reparent Call

* Include Headers That Files Reached Through Ones the Cleanup Removed

* Drop Includes Duplicated by the Cleanup or by Main's Own Additions

* Leave PreciseSeam.cpp as Main Has It After the Precise Seam Rework
2026-10-05 16:47:17 +08:00
harrierpigeon bbb94724ba Merge upstream/main into belt-printer
Brings belt-printer up to main 4b4a261787. Resolutions:

- G-code header (#15897, #15915): main moved the header, config and
  thumbnail block later in _do_export; write_belt_header() moves with it,
  still after the thumbnails and outside the BTT_TFT gate.
- _extrude: first-layer acceleration keeps the per-path first-layer plane
  test with main's cached nozzle index (#16028); main's set_speed out-param
  form (#16108) everywhere else.
- GCodeWriter (#16108): the arc-to-polyline fallback for machine mappings
  that cannot express G2/G3 now runs in the out-param extrude_arc_to_xy,
  which is the overload GCode calls, and appends to the caller's string.
- GCodeProcessorResult: the belt fields join main's forwarding assign.
- Clipper2 (#15969): belt arrange helpers take Slic3r::Point; the tree
  support join types lose their ClipperLib qualifier.
- CLI arrange (#15837): belt printers still reserve no wipe tower.
- Wipe tower options (#15841): the two new sparse-layer toggles are hidden
  for belt printers like the rest of the tower options.
- Keyboard shortcuts (#15706): main's registry replaces the old key switch;
  the belt view toggle is re-registered in the next commit.
- Print::process: the belt purge-plan undo runs before main's SliceStarted
  event.
- scripts/filament_id_snapshot.json: deleted on main (a77209af8f).
- Includes and appended tests: union of both sides.
2026-10-04 19:20:33 -05:00
Rodrigo Faselli 7de1dc1548 Merge branch 'main' into perf/slicing-optimizations 2026-10-04 13:26:02 -03:00
Kris Austin 90ac58d3cd perf: skip the unused curled wall estimate to speed up slicing by up to 9% (#16113)
perf: skip estimating curled walls when nothing reads them

The curled extrusion estimate ran whenever a region had overhang speed on,
which is the default, but only the slowdown for curled perimeters reads the
curled lines it produces, and that slowdown is off by default. The step now
also requires a region with the slowdown on, and clears the curled lines
when it skips the estimate, so none are left from an earlier slice. 
Also fixes stale fan commands due to the stale curled lines on the reused layers.
2026-10-04 09:45:19 +01:00
Kiss Lorand 674308f691 Fix internal bridge limiting area expansion units (#16056) 2026-10-03 20:31:38 -03:00
Rodrigo Faselli b6140110f2 Merge branch 'main' into perf/slicing-optimizations 2026-10-03 10:57:31 -03:00
HanifKoh 8a6377f087 Add Missing Includes Across src/libslic3r (#16068)
* Add Missing Includes Across src/libslic3r

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

* Make the libslic3r Headers Compile on Their Own

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

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

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

* Keep Windows Setup Ahead of the Added libslic3r Includes

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

* Re-Add libslic3r Includes After the Clipper2 2.0.1 Migration

Rebasing onto main took main's version of the files the Clipper2 migration rewrote, so their added includes are restored here, along with includes for main's new code. Clipper2's individual headers are now ignored by clang-tidy: they only build the Z variant through clipper2_z.hpp, which defines USINGZ first, so including clipper.core.h and the like directly broke ClipperZUtils.cpp.
2026-10-03 15:31:11 +08:00
Ian Bassi 7b0e2f3ce5 Keep the G-code identical to main on Clipper2
Since main moved to Clipper2, parts of this branch no longer gave the same
G-code as main:

- bridge_over_infill dropped expand(limiting_area, 0.3 * flow.spacing()) as
  a no-op. The offset is below one unit, but Clipper2 still unites its
  result, which splits and merges touching polygons and so changes the
  anchor lines. Running it on the polygons next to the bridge gives main's
  anchors without the whole-layer pass.
- tsp_remove_crossings stopped at the first repeated ordering, where main
  runs on to its pn * pn cap. The loop is periodic from that point, so it
  now takes only the steps to the ordering main stops on.
- With a single tile, the tiled booleans now make the plain call instead of
  cutting the clip to the tile first.

The tiled boolean test compared rings exactly. With the safety offset a tile
unites only the clip polygons near it, and Clipper2 can then round a
crossing 1 unit differently, so that case allows 1 unit.

Comments that named ClipperLib now say Clipper, and
docs/HLSD/polygon-clipping.md describes the tiled booleans.

G-code of the five handy models in four configurations and of a baked
texture relief is byte-identical to main. Colour-painted models still
differ: segmenting each island on its own splits a colour's region into
different pieces than one diagram over the layer, which on one model also
changes the first layer's tool order.
2026-10-02 20:26:59 -03:00
ExPikaPaka 82f37ddb3a Fix the Windows build: near and far are macros there
bridge_over_infill's helper for splitting polygons by proximity named
its locals near and far. The Windows headers define both as macros that
expand to nothing, so "Polygons near;" declared nothing and the uses of
it did not compile. Renamed; no behaviour change.
2026-10-02 18:13:37 -03:00
ExPikaPaka 2b4bdead73 Run a layer's regions in parallel where they are independent
detect_surfaces_type, process_external_surfaces and the vertical shells
each waited on their own heaviest layer in turn. The LOTR map plate
slices in ~10.5 min at 0.1 mm / 2000k, was ~11.5; ~87 s at normal
settings, was ~97.
2026-10-02 18:13:37 -03:00
ExPikaPaka 9a86d79038 Tile the booleans on layers of many pieces
ClipperLib slows down with the number of edges on a scan line, and a
layer cut through a fine relief has tens of thousands of pieces.
detect_surfaces_type ~50 s at 0.1 mm / 2000k, was ~145.
2026-10-02 18:13:05 -03:00
ExPikaPaka d905f1a39b Merge colour and top/bottom regions per island
The merge took anything from 3 to 38 minutes at 0.1 mm / 2000k, now
~2.5. Every region is grouped with the islands it overlaps, so the
result is the same.
2026-10-02 18:12:41 -03:00
ExPikaPaka 3167c3665a Run colour segmentation and vertical shells in parallel
Same output, ~2.6 min for the LOTR map plate, was ~2.9.
2026-10-02 18:12:40 -03:00
ExPikaPaka 6d34d83e78 Faster slicing of colour-painted layers
A layer split into ~1000 colour fragments (a colour texture baked over a
large top face) made several per-fragment loops redo whole-layer ClipperLib
work, so slicing took ~33 min; it now takes ~3 min with the same output.

- make_fills: clip the layer's no-overlap area to each expolygon's box
  before intersecting
- discover_vertical_shells: small-piece filter compares only against the
  nearby part of the layer
- bridge_over_infill: whole-layer union/diff/intersections restricted to the
  candidate's neighbourhood; fill boundary expanded once per spacing; anchor
  tree built only from lines crossing the scan range; bbox pre-check in the
  collision test; limiting outline taken directly instead of through
  expand(..., 0.3 * flow.spacing()), which offsets by 0.135 scaled units
  (flow.spacing() is in mm) and only cost a whole-layer pass per candidate
2026-10-02 18:11:17 -03:00
Ian BassiandRodrigo Faselli 222c6a2df5 Improve performance by migrating to Clipper2 2.0.1 (#15969)
Co-authored-by: Rodrigo Faselli <162915171+RF47@users.noreply.github.com>
2026-10-02 17:33:41 -03:00
harrierpigeon f7b822abb7 Belt: remove the unused clip_support_fills()
It had no caller besides its own recursion.

Raised in Hanif Koh's review of #14394.
2026-10-02 01:07:45 -05:00
harrierpigeon c0ba2c8c44 Belt brim: read the belt axis from the config in the instance check
belt_brim_instances_compatible() runs while the slicing parameters can be
stale, like the rest of the brim predicates, which read the print config.

Raised in Hanif Koh's review of #14394.
2026-10-02 01:07:44 -05:00
harrierpigeon 97034b22f6 Belt: remove the tagged diagnostic logging
Drops the [BELT-DEBUG], [BELTRACE], [BELT-CALIB] and [BELT-PREVIEW] log
lines, the SLIC3R_BELT_DIAGNOSTIC_LOG blocks, and the counters and
temporaries that existed only to feed them. Six of the purge tower lines
logged at warning level, which is Orca's default, on every plan. Raised in
Hanif Koh's review of #14394.
2026-10-02 01:04:33 -05:00
harrierpigeon d755580c99 Belt brim: the purge prism never gets a brim, whatever its config says
The prism's generator already sets no_brim; PrintObject::has_belt_brim() now also ignores
any brim setting on the prism (belt_purge_tower_object), so a brim on the parts beside it
never blocks purging.
2026-10-02 01:00:36 -05:00
ExPikaPaka 391c53a8da Take the print config by reference while simplifying extrusions
simplify_path, simplify_multi_path and simplify_loop each copied the whole
PrintConfig, 10520 bytes with around 200 heap owning members, once per extrusion
entity, from inside the parallel_for over all layers. LayerRegion.cpp already
binds a reference a few hundred lines above. Three more sites in Layer.cpp do the
same thing.

The tree support changes in the same area: draw_circles() dropped layers from an
owning vector without deleting them, so every re-slice leaked the layers above
the topmost overhang. std::stable_partition rather than std::remove_if, because
remove_if leaves moved-from duplicates of kept pointers in the tail and deleting
those would be a double free. The collision and avoidance accessors returned
ExPolygons by value out of a cache that hands them out by reference, several
times per node per layer. The preview cache is released when the support step
finishes instead of at the start of the next slice; nothing reads it in between.

set_shared_object() now releases the layers the object still owns before it
starts aliasing another object's. Both clear functions are no-ops once the alias
is set, so this cannot free the sharee's layers.

PrintObjectSlice.cpp: eps was a function local static inside a parallel_for, so
slice_closing_radius was latched once per process. This one changes output for
projects that override it per object, or on a re-slice after editing it. The old
behaviour was undefined: whichever object won the race set it for the session.
2026-10-01 09:15:15 +02:00
harrierpigeon ad6afce67b Merge upstream/hanif/belt-printer-fixes into belt/final-round
Brings in upstream/belt-printer (the Sept 14 main merge) plus Hanif Koh's
21 review-fix commits from PR #15685, on top of the MachineKinematics
refactor and the purge-prism / tree-support / first-layer-speed fixes.

Conflict resolution:
- BeltGCodeWriter is gone (kinematics refactor), so Hanif's plate-offset
  fix for it is ported into GCodeWriter: the first-layer-plane checks in
  travel_to_xy / travel_to_xyz / _travel_to_z now evaluate the plate-local
  point, and BeltGCode::init_belt_writer hands the stored plate origin to
  the writer it installs.
- init_belt_writer(Print&) takes Hanif's signature; the BBL flag is set on
  the surviving writer by GCode::_do_export.
- The shared emit_belt_brim_bands() loop keeps the BeltFloorObjectGuard the
  local branch added, so apron bands classify first-layer height against
  their own object.
- eager_lift keeps effective_type: it now carries set_force_normal_lift().
- GCodeWriter's initializer list follows Hanif's member order with
  m_kinematics in its declared position.
- TreeSupport::detect_overhangs uses Hanif's clamped build_plate_tilt_slope()
  for the non-belt path and the belt shear for the belt path.
2026-09-30 15:22:19 -05:00
Ian Bassi 59e40a2c2e Print unsupported walls last (#15411) 2026-09-17 09:14:20 -03:00
Valerii Bokhan 3e1daccd7c Feature: Add inward wipe for external perimeters (#15407) 2026-09-15 20:01:39 -03:00