Commit Graph
244 Commits
Author SHA1 Message Date
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
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
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
HanifKoh 8a6377f087 Add Missing Includes Across src/libslic3r (#16068)
* Add Missing Includes Across src/libslic3r

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

* Make the libslic3r Headers Compile on Their Own

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

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

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

* Keep Windows Setup Ahead of the Added libslic3r Includes

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

* Re-Add libslic3r Includes After the Clipper2 2.0.1 Migration

Rebasing onto main took main's version of the files the Clipper2 migration rewrote, so their added includes are restored here, along with includes for main's new code. Clipper2's individual headers are now ignored by clang-tidy: they only build the Z variant through clipper2_z.hpp, which defines USINGZ first, so including clipper.core.h and the like directly broke ClipperZUtils.cpp.
2026-10-03 15:31:11 +08:00
Ian BassiandRodrigo Faselli 222c6a2df5 Improve performance by migrating to Clipper2 2.0.1 (#15969)
Co-authored-by: Rodrigo Faselli <162915171+RF47@users.noreply.github.com>
2026-10-02 17:33:41 -03:00
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
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
Hanif Koh 5092831007 Apply the Belt Slicing Transform to Painted Supports and Seams
Painted support/seam facets, support volumes, seam occlusion, MMU and fuzzy skin painting (top/bottom
and side facets) and the adaptive infill octree used trafo_centered(), or trafo() with a centre-offset
shift, while the layers were sliced with the belt rotation, remap and Z lift; they now share
PrintObject::trafo_sliced().
2026-09-14 17:27:32 +08:00
Hanif Koh 8e330f951a Merge Main into Belt Printer
Merge origin/main (00429da739) into belt-printer.

Conflicts resolved:
- src/CMakeLists.txt: keep both wxInspector workarounds.
- GCodeProcessor.cpp: keep the belt compare_pos / z_for_height lines.
- PrintObjectSlice.cpp: the belt bbox-Z guard also covers main's
  printable_region_ids bookkeeping.
- TreeSupport.cpp: the belt-floor check runs before main's PendingNode
  queueing.
- Tab.hpp: keep the belt fields, drop the removed upload description
  fields.
- tests/libslic3r/CMakeLists.txt: keep both test files.

Also included:
- eSUN PLA belt presets declare their own filament_id (OFkrxQC4) and
  scripts/filament_id_snapshot.json is regenerated, as main's filament_id
  check requires.
- Custom.json version bumped to 02.04.00.05 so the belt entries reach
  existing installs.
- Fix the ambiguous WithinRel call in the belt apron width test, which
  otherwise breaks the fff_print build.
2026-09-14 16:33:08 +08:00
harrierpigeonandClaude Fable 5.1 1bcfe58064 Belt: stop the purge prism printing plastic no toolchange needs
Two independent leaks of filament on the belt purge prism, plus the
replan safety net the second one needs.

1. The early-truncation scan bounded itself with the prism's own
   toolchanges. ToolOrdering covers the whole print and the prism is a
   printed object in it, so the "last toolchange" the scan found was on
   the prism's own top layers -- it runs past every model object by
   design -- and the truncation cancelled nothing. Bound the scan at the
   tallest non-prism object (support layers included; on a belt they can
   top the object). On MCTEST5 that was 197 toolchanges over 39.4 mm of
   tower that no swap ever needed.

2. On a layer with no toolchange, the prism's entire fill printed as
   solid infill in its own filament. Drop the fills no toolchange
   claimed, right after the purge marking and before
   ensure_perimeters_infills_order() force-overrides whatever is left.
   Perimeters stay so the bar keeps a continuous wall. An earlier version
   of this deleted the entities and had to be reverted: psWipeTower can
   rerun without regenerating infill, and a later tool ordering may claim
   what this one did not. The entities are now stashed with their layer,
   region and index and put back exactly, the same reversibility contract
   layer truncation already had.

3. Both stashes go stale if an object step reruns: make_fills() clears
   and regenerates fills over m_layers only, so a stale stash would put
   old fills back next to new ones, and truncated layers would keep old
   perimeters/fills. Undo the plan's edits at the top of Print::process()
   whenever psWipeTower is not done. Every object-step invalidation also
   invalidates psWipeTower, so that condition is exactly "some object
   step may rerun"; when it is done nothing regenerates and the edits
   must stay. This also covers a prism left behind after belt mode is
   turned off, which previously stayed truncated forever.

WipingExtrusions::is_entity_overridden() becomes public so the prism can
tell claimed fills from unclaimed ones.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SsuY8Laiyh7q2zPVVKV3HZ
2026-09-12 22:23:14 -05:00
Kiss Lorand a49b892708 Fix bridge flow invalidation for zero-gap supports (#15626) 2026-09-10 18:23:31 -03:00
Kris Austin d127db4d99 build: clear 5 warning categories across 19 sites (#15628) 2026-09-10 18:15:39 -03:00
Valerii Bokhan e8d35fadd4 Fix internal bridges over Hilbert Curve/Octagram Spiral sparse infill (#15206)
* Fix internal bridges over Hilbert Curve/Octagram Spiral sparse infill

For patterns with curved/turning anchor lines (Hilbert Curve, Octagram
Spiral), the bridge_over_infill algorithm produced incorrect results:

1. determine_bridging_angle: sampling curved anchor orientations
   produced noise across all turning directions (0/90/180/270°)
   instead of a single dominant one, yielding unstable bridge angles
   with 180° spread. Fix: use the configured infill_direction + 90°
   directly, bypassing the noisy sampling. The old blind +0.25*PI
   (Hilbert) and +1/16*PI (Octagram) offsets are removed.

2. construct_anchored_polygon: curved Hilbert/Octagram anchors
   intersected each vertical scan line many times at wildly different
   Y positions, producing chaotic polygon sections — holes in random
   places, bridges over air, rotated bridges. Fix: replace the curved
   infill polylines with synthetic straight lines parallel to
   infill_direction, spaced at the real infill line spacing
   (flow_spacing / density). Lines are centered on the limiting_area
   bbox center so that after rotation they span the full bridged_area.
   Anchors are left at full bbox length (not clipped) to guarantee
   every scan line finds an anchor.

Rectilinear and other straight-line patterns are unaffected.

Known limitation: some bridge edges may still terminate over air in
edge cases where the nearest synthetic anchor line is more than one
infill spacing away from the bridge boundary. This will be addressed
in a follow-up.

* fix: anchor internal bridges to actual sparse infill

Preserve real anchors across regions and align plane-path anchor origins with printed infill. Respect lower-layer rotation templates and model alignment, and sample curved bridge boundaries more finely.

Add regression coverage for anchor alignment, bridge angles and region isolation, with Orca comments explaining the geometry constraints. Verified 175 FFF tests before the comment-only follow-up; preserve CRLF in modified files.

* Fix internal bridge support contacts and separated infill origins

Restore anchor contact after bridge smoothing and share per-body pattern origins between anchors and printed infill. Recompute origins when preparation settings change.

Cover multiline counts 1, 2 and 3 and add regressions for printed bridge support, separated infill alignment and reslicing.

* Add explicit standard headers to PrintObject tests

* test: cover surface centering when infill settings change

Verify top and bottom Archimedean Chords and Octagram Spiral paths after switching centering modes or toggling separated infills. Compare reslicing against fresh slicing and document dependent infill invalidation.

* test: preserve directional surface infill when settings change

* perf: index layer islands for connected-body detection

* test: use public print pipeline for body centering checks
2026-09-10 08:03:50 -03:00
Kris AustinandRodrigo Faselli 1749c293a6 build: clear 237 warnings - unused lambda captures (#15417)
* build: enable /Zc:lambda for MSVC

MSVC keeps its legacy lambda processor under /std:c++17, which rejects
reading a constexpr constant inside a lambda that does not capture it
(C3493). No other compiler requires that capture, and clang reports it as
an unused one, so the two cannot both be satisfied without the flag.

/Zc:lambda selects the conforming lambda parser that clang and GCC
already use. It is implied by /std:c++20 and /permissive-, so it is only
needed while we are on C++17. clang-cl is conforming already and does not
take the flag.

It requires VS2019 16.8, so build_release_vs.bat now says 16.8+.

* build: clear 237 unused lambda capture warnings

236 captures across 81 files, 142 of them `this`. Removing an unused
capture changes no behavior; clang does not report a capture whose type
has a non-trivial destructor, so nothing held only to extend an object's
lifetime is in this set.

Nine of them are the second half of the warning, "is not required to be
captured for this use", where the capture is a const or constexpr value
the body does read. Those depend on the /Zc:lambda change in the previous
commit. One of them, in FillRectilinear.cpp, had been worked around with
an #ifndef __APPLE__ guard around the capture list, which is now gone.

GUI_ObjectTableSettings.cpp captured its reset button only to read it
inside #ifdef __WXOSX_MAC__. That branch now takes the button from the
event it is already handling.

* build: fail configure on MSVC older than 19.28 instead of dropping /Zc:lambda

cl.exe answers an unrecognized /Zc: sub-option with warning D9002 and keeps
going, so on VS2019 before 16.8 the flag is silently ignored and the build
instead dies with C3493 in FillRectilinear.cpp, nowhere near the cause.

* fix: delete three locals that are now unused

Their only remaining use was the lambda capture this branch removed. The
Clang builds set -Wno-unused-variable, so the build never flagged them.

---------

Co-authored-by: Rodrigo Faselli <162915171+RF47@users.noreply.github.com>
2026-09-02 07:38:05 -03:00
harrierpigeon e5d4ad2aa7 Merge remote-tracking branch 'upstream/main' into haryr/aug25-rebase
# Conflicts:
#	src/libslic3r/Support/TreeSupport.cpp
2026-08-30 23:31:48 -05:00
Kris Austin db29f570bd build: clear 50 warnings - pessimizing moves and null checks that cannot fail (#15408)
* build: remove std::move that blocks copy elision

std::move wrapped around a temporary, or around a local being returned,
stops the compiler constructing it in place. Each edit is the fix clang
suggests, which is to delete the std::move call and keep its argument.

Three of the 39 sites save a move, the two return std::move(local) in
Print.cpp and TreeSupport.cpp:2749. The rest are equivalent either way
and match how the codebase already writes this elsewhere.

Clears 39 -Wpessimizing-move warnings.

* build: drop null checks on references and this

A reference cannot be bound to null and this cannot be null, so the
compiler folds these conditions to true and drops the guard. Seven are
if (&bitmap && bitmap.IsOk()), where IsOk() already does the work; two
test this directly. The guarded code runs either way, so removing the
dead operand changes nothing.

Clears 11 -Wundefined-bool-conversion warnings.
2026-08-28 08:05:59 -03:00
harrierpigeon d289478618 Merge remote-tracking branch 'upstream/main' into haryr/aug25-rebase
# Conflicts:
#	resources/profiles/Custom.json
#	src/libslic3r/Brim.cpp
#	src/libslic3r/GCode.cpp
#	src/libslic3r/GCode.hpp
#	src/libslic3r/Preset.cpp
#	src/slic3r/GUI/3DScene.cpp
#	src/slic3r/GUI/ConfigManipulation.cpp
#	src/slic3r/GUI/GLCanvas3D.cpp
#	src/slic3r/GUI/Plater.cpp
2026-08-25 06:50:46 -05:00
Kiss Lorand fd23b74b99 Fix single-value object overrides on multi-nozzle printers (#15221) 2026-08-13 17:09:10 -03:00
harrierpigeon 3d11b60e71 Harden belt purge tower replanning 2026-08-08 20:14:52 -05:00
harrierpigeon 88726d76e8 Purge tower part 1 2026-08-08 16:35:54 -05:00
harrierpigeon 1bd3404c03 Fix belt brim emission: dropped first-contact bands, tool selection, inner-only predicate (A,B,C,D)
- Emit coincident belt_brim_by_layer bands even when the leading object layer
  has no InstanceVisit (zero-extrusion lead-in / no coinciding support), so the
  brim at first belt contact is no longer dropped.
- Register each coincident band's brim filament in ToolOrdering and emit each
  band exactly once, in its brim-filament pass; emit ordinary-layer aprons in
  the brim pass before object extrusion (correct tool, brim-first) instead of
  with whatever tool was active.
- has_belt_brim(): inner-only brims need brim_width>0 (leading/extra produce no
  inner geometry), fixing spurious prime-tower/spiral rejection; mirror in
  wants_brim. Single-extruder/single-object output is unchanged except
  previously-dropped bands now print.
2026-08-06 15:40:04 -05:00
harrierpigeon b1905ebc20 Belt brim: fixes from review
Six issues found by reviewing the previous commit against belt-printer, two of
them release-blocking.

Data race (high).  Print::process() runs generate_support_material() for all
objects in a tbb::parallel_for, and make_belt_brim() runs at its tail, but
belt_brim_obstacles() read every OTHER object's support_layers() - which a
concurrent task may be inside clear_support_layers() deleting.  That is a
use-after-free, and even when it survives, the obstacle set depends on which
object finishes first.  Only this object's own supports are consulted now; they
are complete at that point.  Foreign objects still contribute their slices,
which are finished and immutable before the support phase.

Apron bands dropped (high), two separate causes.  An apron band prints below
its own object's first layer, but another object can already be printing at
that print_z, in which case process_layer() takes the ordinary path and never
emitted the band - the emission is now shared by both paths.  Separately, a
band whose print_z matched a support layer of the SAME object was overwritten
in the print-wide merge, which keeps one record per object per z and could not
detect the collision because LayerToPrint::layer() is null for a band.  The
per-object pairing loop is now a three-way merge over object, support and apron
streams, so each object contributes at most one record per z.

Multi-instance was far too strict (medium).  It refused belt brim for every
multi-instance object, killing plain brim width and inner brim too, and only
warned when a leading length was set.  Only movement ALONG the belt changes an
instance's belt-floor Z, so copies side by side ACROSS the belt share one set of
bands perfectly well; belt_brim_instances_compatible() now tests just that, and
the warning fires whenever the brim is actually suppressed.

Apron layer bookkeeping (medium).  Apron layers count toward m_layer_count and
advance m_layer_index, but emitted no Z/height tags, left m_last_layer_z,
m_max_layer_z and m_last_height stale - so the first object layer computed its
height against a pre-apron Z - and skipped before_layer_change_gcode and
layer_change_gcode entirely.  All of that now matches the ordinary path.

Obstacle cost (low).  belt_brim_obstacles() ran a full-plate union per band.
A bounding-box pre-filter drops non-overlapping objects before materialising any
polygon, and the union is skipped for trivial inputs.

Deliberately unchanged: every apron band still reports cooling layer_id 0.
CoolingBuffer uses it for the initial_layer_fan_speed override and the
close_fan_the_first_x_layers gate, and every band lies on the belt plane itself,
so it is all first-layer material by the only definition that means anything on
a belt.  Numbering the bands would ramp the fan up while still printing on the
belt.  Now documented at the assignment rather than left implicit.
2026-08-06 01:08:44 -05:00
harrierpigeon 55b4dca9bc Belt printers: brim laid onto the tilted belt, with a leading apron
A belt printer slices in a rotated frame, so the belt surface is a tilted
plane rather than the Z=0 bed plane.  Each slicing layer touches the belt
only along a narrow strip at its leading edge - about 0.2mm at 45 degrees -
so a part's first layer is really a first line, with almost no contact patch
to hold it down while the belt drags it forward.  Brim was hard-disabled on
belt printers, leaving no remedy at all.

Generate the brim on the belt plane instead.  The object's belt footprint is
the union over layers of each slice clipped to that layer's contact band; the
brim is offset from it in a "flattened" frame where the shear axis is
stretched by 1/cos(tilt), so ordinary Clipper offsets measure true on-belt
distance.  It is emitted as cross-belt lines, one per layer band, anchored to
a fixed fraction of the band so every line shares a nozzle-to-belt clearance
and therefore comes out the same width; flow is matched to the resulting band
pitch, keeping the sheet uniform and gap-free.

Three new controls, all belt-only:

  * Leading brim length - extends the brim ahead of the part along the belt,
    on every downhill-facing edge of its contact area.  This apron necessarily
    prints BELOW the object's first layer, since layer 0 is the part's leading
    contact, so it needs brim-only bands of its own.
  * Extra brim width - widens the brim sideways across the belt only.
  * Brim type "Leading edge only" - brim at the part's first belt contact and
    nothing after it.  Appended last in BrimType so no existing value shifts;
    degrades to an outer brim off belt printers, with a warning.

The apron bands are lightweight records rather than a Layer subclass, so no
fabricated Layer::id() can leak into initial-layer temperature selection, the
spiral vase probe, cooling or gradual interpolation.  They are generated in
posSupportMaterial because their print_z values must exist before ToolOrdering
is built at psWipeTower, and they are emitted from a short dedicated branch in
process_layer that runs before any layer pointer is dereferenced.

The footprint is closed before offsetting outwards: a belt contact patch is
often a broken-up strip, and the merged offset rings of two islands closer
than 2 x brim_width would otherwise fill the space between them - space that
lies under the part.

Also fixes a pre-existing bug where PrintObject::get_first_layer_bbox()
overwrote a valid bbox with an unassigned one on any belt printer with a brim
configured, because has_brim() was true while make_brim() returned early.

Belt brim is refused alongside the prime tower and spiral vase, and requires
one instance per PrintObject - translating an instance along the belt axis
changes its physical belt-floor Z.  Untilted belt printers are unchanged: they
still get no brim, since the plate brim is emitted out of skirt_brim_groups(),
which _make_skirt() never builds for a belt printer.
2026-08-06 01:08:44 -05:00
harrierpigeon 175075fd08 Merge upstream/main into belt-printer
Brings the belt-printer work up to date with 591 upstream commits.

Conflict resolutions (12 files, 42 hunks):

- GCode.cpp: adopted upstream's per-filament/per-nozzle config refactor
  (get_filament_config_index, NOZZLE_CONFIG), the extracted
  generate_timelapse_gcode + farthest-point timelapse, and the
  ConfigOptionFloatsNullable calibration options. Re-applied the belt
  hooks on top: init_belt_writer / axis remap / FirstLayerPlane setup,
  on_set_origin, the belt-corrected calib_z for the volumetric speed
  tower, and path_on_first_layer (belt's per-path first-layer test) in
  place of upstream's layer-index on_first_layer() in the acceleration,
  jerk and overhang-detection paths. Swept upstream's new m_writer.
  uses to m_writer-> since belt holds the writer by unique_ptr.
- interpolate_value_across_layers: kept upstream's banded stepping and
  belt's object-Z-span ratio; dropped upstream's duplicate ratio decl.
- Plater.cpp: took upstream's guarded add_model(...) early-returns and
  the VFA vfa_layer_height plumbing; kept the belt temp-tower path,
  _calib_apply_belt_mode and belt_calib_flip_ringing_tower. Dropped the
  VFA "cut upper" block, superseded upstream by model scaling.
- Brim.cpp: upstream's ObjectInstanceID-keyed brimAreaMap, keeping the
  belt early-return.
- 3DScene.cpp: kept both the belt build-plate tilt up_direction and
  upstream's per-extruder printable-height shading.
- GCodeViewer.cpp: kept upstream's dim-previous-layers setup and belt's
  exemption from the same-result early return.
- TreeSupport.cpp: upstream's >= 0 roof-layer fix inside belt's
  belt-floor branch.
- calib.cpp / GCode.hpp / GCodeWriter.{cpp,hpp} / Print.hpp: upstream's
  additions adapted to belt's pointer-held writer and helpers.
- Custom.json: kept profile version 02.04.00.03 (belt) over upstream's
  02.04.00.01; both bumped from 02.04.00.00.

Building this tree needs the wxInspector dependency, which upstream
added in the interim (python3 and wxWidgets 3.3.2 were already present
in the shared deps prefix).
2026-08-02 16:09:27 -05:00
maddavo 13ae3a1c90 Add outer-only mouse ears and align ear radius controls (#15015)
Improve mouse ear brim controls
2026-08-02 10:54:16 +08:00
Valerii Bokhan fb36d5e73b Feature: Smooth Factor for the Hilbert Curve sparse infill (#14969) 2026-08-01 17:58:04 -03:00
Ian Bassi 6489b4cad3 Fix: Only one wall top surfaces (#14929) 2026-07-29 09:23:35 -03:00
MqriusandIan Bassi c84d5c7943 Add top/bottom surface fill order control (Outward/Inward) for Concentric, Archimedean Chords and Octagram Spiral (#14179)
Co-authored-by: Ian Bassi <ian.bassi@outlook.com>
2026-07-14 15:34:13 -03:00
Ian BassiandRodrigo Faselli c4ea86041b Separated Infills enhancements (#14674)
Co-authored-by: Rodrigo Faselli <162915171+RF47@users.noreply.github.com>
2026-07-12 11:45:00 -03:00
93d5b65852 Fix per-obj multi-variant options handling (#14700)
* ENH: config: add logic to apply params to object/region config with multi-extruder

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

* FIX: X1C switch to H2D lose Highflow parameter

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

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

* Fix modified multi-variant per-obj option highlight

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

---------

Co-authored-by: lane.wei <lane.wei@bambulab.com>
Co-authored-by: weiting.ji <weiting.ji@bambulab.com>
2026-07-11 22:21:22 +08:00
bc6ffcfb31 Anisotropic surfaces + Separated Infills (remake) (#11682)
Co-authored-by: Rodrigo Faselli <162915171+RF47@users.noreply.github.com>
Co-authored-by: Ian Bassi <ian.bassi@outlook.com>
2026-07-08 15:40:19 -03:00
Ian BassiandRodrigo Faselli 20a66fa99b Top Surface Expansion (#14296)
Co-authored-by: Rodrigo Faselli <162915171+RF47@users.noreply.github.com>
2026-07-08 14:20:40 -03:00
FlorianandRodrigo Faselli 2d4f7a7437 added option to limit polyhole edges (#12349)
Co-authored-by: Rodrigo Faselli <162915171+RF47@users.noreply.github.com>
2026-07-04 23:03:36 -03:00
Valerii Bokhan 1882861a98 Feature: Small perimeters speed for supports (#13459) 2026-07-03 17:27:57 -03:00
Ian Bassi a6dd002fe7 Top and Bottom layer directions (#13631)
* Top layer direction

* Bottom layer direction

* comSimple
2026-07-03 17:27:05 -03:00
SoftFever ca388f2d9e Merge branch 'main' into pr/Noisyfox/13712 2026-06-22 10:56:11 +08:00
Joseph Robertson da3fee2dfa Merge branch 'main' into belt/baseChanges 2026-06-05 11:55:44 -05:00
Ian Bassiandigiannakas ea35b9ce68 Divided filament for features (#14042)
* Implement legacy key handling to address possible profile issues following semantic change of per feature filaments

* Reimport base

* Fix inner wall

* Profiles update

---------

Co-authored-by: igiannakas <ioannis@my-spot.co.uk>
2026-06-05 20:45:43 +08: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
ae16c76dd2 Bridge Line Width + Improve bridge density (#11255)
* Base

* Standarized

Co-Authored-By: Rodrigo Faselli <162915171+RF47@users.noreply.github.com>

* Wiki

* Improved descriptions based in RF47 Tests

Co-Authored-By: Rodrigo Faselli <162915171+RF47@users.noreply.github.com>

* Bridge Flow Wiki

* Removed CMATH

Co-Authored-By: Rodrigo Faselli <162915171+RF47@users.noreply.github.com>

* Default to 100

* Revert "TESTING BRIDGE DENSITY"

This reverts commit 8634f802311cd3877b0dd5651029b30b2d4eab60.

Removed desc change

* Minor changes

Co-Authored-By: Noisyfox <timemanager.rick@gmail.com>

* Update LayerRegion.cpp

* Missing ;

Co-authored-by: Rodrigo Faselli <162915171+RF47@users.noreply.github.com>

* Restrict bridge line width to nozzle diameter

* Clarification

* Increased both Bridge Densitys to 125

Co-Authored-By: Valerii Bokhan <80919135+valerii-bokhan@users.noreply.github.com>

* Valerii check

Co-Authored-By: Valerii Bokhan <80919135+valerii-bokhan@users.noreply.github.com>

* Fix error handling

* Clarify thick bridges documentation and tooltips

Updated the documentation and tooltips for 'thick_bridges' and 'thick_internal_bridges' to clarify that bridge extrusion uses a line height equal to the nozzle diameter, and to better explain the trade-offs between strength, reliability, and appearance.

* Partially restore bridge_flow description

* Suggestions

---------

Co-authored-by: Rodrigo Faselli <162915171+RF47@users.noreply.github.com>
Co-authored-by: Noisyfox <timemanager.rick@gmail.com>
Co-authored-by: Valerii Bokhan <80919135+valerii-bokhan@users.noreply.github.com>
2026-06-03 10:16:59 -03:00