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>
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.
* 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.
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.
- 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
1. fix hybrid tree support may go outside plate
github: #4769
2. fix false alarm of empty layer warning
jira: STUDIO-8178
Change-Id: I7bcc3959b06184901cbec946e8840c7a94bc1cab
(cherry picked from commit 647bd4213c363eff6258992f5f607c1f03cbc482)
Previously painting support enforces on vertical faces doesn't work, as projecting the facets downwards will give empty polygons.
Now we use a different mechanism to enable vertical paint-on enforces, by directly adding contact nodes.
Note: this feature only works with tree support as only tree support has contact nodes.
jira: none
Change-Id: Id171b1665566d142a6427285baccb40c0aa00949
(cherry picked from commit 9c882f61eb37350a4486df58de48f0ae489f2d15)
(cherry picked from commit 68625a6e601e2feef8e56693da1f58372b27b560)
1. do not add interface for small overhangs so supports are easier to
remove
2. calculate avoidance more accurately using real layer height
jira: STUDIO-6285
3. hybrid nodes won't collide with lower layers
4. calculate max move more accurately
5. do not increase radius if next layer has collision
jira: STUDIO-2296, STUDIO-7883
6. rewrite plan_layer_heights to prevent support layers overlap.
Now the tree support layers are completely independent to object layers.
6. increase collision areas for interface. The top layers may be too
close to interface with adaptive layer heights and very small overhang angle
Change-Id: I052c3f66e68afb7663e2d70c846dd09ed7086071
(cherry picked from commit aca511caebfdeec270d4fc0ec6bbbadde77cddc9)
(cherry picked from commit f2fc996652b3b204b4e554f57afed8519feb0397)
1. add rectilinear interface pattern for organic support
jira: STUDIO-7181
2. add tree support optgroup
Change-Id: I94882bc34a61c6adc06b8ecbc9f2323f9b039aac
(cherry picked from commit a8142ab3f37e0bd140a31a7e635b8475f471d7e3)
(cherry picked from commit 69cf816b9431bc21ca0187c7db1148e2d2e898ab)
1. sharp tails are supported by a sparse set of contact points which are
easier to remove than previously dense surrounding support.
Organic tree support also has this feature, including all other smart
overhang detection techniques (small overhang and cantilever detection),
with the cost of slightly longer time to detect overhangs.
2. improve supporting overhang contours by adding contact points along
contours.
jira: STUDIO-3876
2. remove some redundant data structure.
Change-Id: If7f595348506a14aba2d0132d23f97d3539c1e1f
(cherry picked from commit e3cce09b9db12ced2841045ffd337b1f35494e6c)
(cherry picked from commit 507345deb193d895d0813fc913f00b0def7e62f9)
1. speedup detect_overhangs by skipping sharp tail and cantilever detection if there are too many overhangs.
jira: STUDIO-3584, STUDIO-2592
2. drop_nodes with precalculation of avoidance and tbb parallel_for_each for all nodes in each layer.
jira: STUDIO-1814, STUDIO-2381, STUDIO-2639, STUDIO-5020,
3. don't show too many progress messages
Change-Id: Ia4897089c69c235fb7cd8e5fdcf4690086048b31
(cherry picked from commit 9c08e28b5b5342dfdde2c939fc953f143a42a59b)
(cherry picked from commit 9de69035a029374be477b74e67c96dd8235daafa)
1. reduce unnecessary small parts of tree supports
jira: STUDIO-6506
2. fix the bug that zero height tree support may be generated with synced support layer height.
3. fix the bug that tree nodes' radii may change abruptly
jira: STUDIO-6326
Change-Id: I38153d136e46bf9d797881cc6ca8803767f46736
(cherry picked from commit 59af0a6c2643169463cf18010ffd75f3aa19b704)
(cherry picked from commit 47440f040cae70f79e430b02d44f6093208ac066)
Only early stop detect_overhangs if support is disabled AND not checking support necessity.
jira: STUDIO-6158
Change-Id: I2d9662231d941827d6392d57344f7d911f641e09
(cherry picked from commit b811a6031d1afe0e7b1cb73050fe6391a65411ef)
(cherry picked from commit fa61ee6abdb4b04a2141b3f8ea9e2e8a789b7881)
1. accurate top z distance for tree support
Also fix a bug that bottom z and top z distances are misused.
jira: STUDIO-3000, STUDIO-5990
github: #1827
2. Change interface pattern to interlaced rectilinear when using
support material.
2. clean up tree support code
Change-Id: Icc8ce1b6844c841a6fbd1d623df707fdc8ed0f7b
(cherry picked from commit da7412a48dfb5767918ef125b9d0fb9718c03a61)
(cherry picked from commit 39ae64fc53abec794d740e36baaa13fd6fb35849)
First layer support can't be top interface, and
min brim width of auto mode should be larger
than 0.
Jira: STUDIO-5010
Change-Id: I02f8b017b535f8a47965387e8679f692b1966e04
(cherry picked from commit 3e7d54abe352e8ab5f9d6492b5a86a96f9067f94)
(cherry picked from commit 7efebe6bc6)
1. Improve generation speed by removing unnecessary get_avoidance.
2. Fix a bug of hybrid support's interface (Jira: STUDIO-4878,
STUDIO-4726, Github#2614)
3. Fix a bug of tree support pass through objects (Jira: STUDIO-4252, STUDIO-4608
STUDIO-4298)
4. Fix a bug with first layer + Arachne (Jira: STUDIO-4281, Github #2423)
Change-Id: I40978c93ab93fa6964483514dad552d73a66c710
(cherry picked from commit 2ccbbe49c74d4aab4f086e79a6f8262b7fc80f15)
(cherry picked from commit bambulab/BambuStudio@d7a4623380)
Co-authored-by: Arthur <arthur.tang@bambulab.com>
1. add a hook inside tree branches for improved strength
2. fix the issue that interface may fly as a mess (delete the logic
where gap nodes can skip dropping down)
3. fix the issue that base nodes may fly as a mess (smoothing should
skip polygon nodes, see Jira:STUDIO-4403)
Change-Id: Ie9f2039813c2ca3127ed8913304cc455fec8e7ee
(cherry picked from commit 83cef5f91d49ff3d275a89ec3df8b5f0fd573f8c)
(cherry picked from commit bambulab/BambuStudio@76f876a3c6)
Co-authored-by: Arthur <arthur.tang@bambulab.com>
* Initial port of organic tree support from PrusaSlicer
* Port missing Organic support parameters from PrusaSlicer
* Update parameter naming
* Reorganize the `raft_first_layer_expansion` and `raft_first_layer_density` parameters as they are not only used by rafts
* Reset support style only in simple mode
* Sync latest update from PrusaSlicer & copyrights
* Fix organic tree support crash with invalid parameters
---------
Co-authored-by: Vojtech Bubnik <bubnikv@gmail.com>