Four changes to the image-adjustment panel, all from using it:
Entry point. The panel is now opened by an icon in the layer's header row,
between the image name and the order arrows, rather than by a button buried
under "More settings". It acts on the image the name refers to, so it belongs
beside the name. Disabled for a layer with no image.
Only "Save as copy". Overwrite is gone, and with it the one path that edited
a layer's stored image in place. Writing the result to the texture library and
pointing the layer at it is the single way an adjustment becomes permanent,
which also means an adjusted texture is always a file the user can find and
reuse. encode_texture_image_data() had no other caller and is removed.
A window, not a popup. A popup dimmed the canvas and closed on any click
outside itself, which between them made it impossible to watch the model
while adjusting it. An ordinary floating window leaves the 3D view live,
clickable and orbitable, and stays put until Cancel, Save as copy or its
close button.
The displacement follows the sliders. TextureDisplacementLayer gains a
transient preview_adjust that decode_height_texture() applies on top of the
decoded image, before smoothing. Everything downstream of the decode then
sees the adjusted image without being told the panel exists: the relief, the
colour, the thumbnails, the UV backdrop and the bake. It is not serialized by
cereal or the .3mf, because it is the state of an open editor rather than a
property of the layer; the panel reverts it on every exit that is not a
commit, and a commit clears it before pointing the layer at the file that
already carries the edit, so the adjustment is never applied twice.
Two caches had to learn about it or they would have gone on serving the
pixels from before the slider moved, since neither the image_data pointer nor
the smoothing value changes while a slider is dragged: the new adjusted-copy
cache keys on (image, adjustments), the smoothed cache now keys on both, and
the GPU thumbnail, height and colour textures and the UV editor backdrop
carry the adjustment in their keys alongside smoothing. Two tests cover
exactly that: the same image_data with two different adjustments must decode
to two different images, with and without smoothing on.
The recompute is lazy. A slider move marks the preview dirty and the existing
"rebuild once the mouse is released" rule in the panel consumes it, so a drag
recomputes the displacement once, on release, instead of once per frame. The
panel's own image still updates continuously, from a background pass over a
384 px copy, so the photo tracks the slider while the model catches up after.
Adds brightness, contrast, sharpness, blur and hue over one layer's image,
shown on the image itself and updating as the sliders move. Reached from an
"Adjust image" button in the layer card, beside Smoothing.
What the panel produces is not a set of layer parameters: it replaces the
layer's image, so the adjusted pixels feed the colour and the displacement
together and a brightness change moves the relief too. That is deliberate,
and the panel says so. It is also why brightness is a lift toward white
rather than an additive offset: an offset drives everything above mid-grey
to a flat 255, and since the image is the height map, that region would bake
as flat relief instead of bright relief.
Three exits: Cancel discards, Overwrite replaces the layer's image_data, and
Save as copy writes a new PNG into the user's texture library and points the
layer at it. Overwrite and Save as copy both hand the layer a brand new
allocation, which is what invalidates decode_height_texture()'s cache,
analyze_texture_detail()'s, and the GPU thumbnail and height/colour
textures, all of them keyed by that pointer.
Grayscale in, grayscale out: a grey image is not promoted to RGB, since that
would offer the colour feature a row of identical greys and triple the
stored PNG for it. Hue is disabled for a grayscale source, with the reason
shown, because grey has no hue to turn.
The live preview runs on its own thread over a 384 px downscale, one pass in
flight at a time so a drag coalesces to wherever the sliders stop. Measured
on a 1024x1024 with every knob engaged, a full-size pass costs 13-19 ms
grayscale and 40-60 ms in colour (130-190 ms at 2048 in colour), which is
far too much to repeat per slider frame; the same pass on the downscale is
3-4 ms and 9-12 ms. Not the plater's job worker either: that is a single
FIFO shared with Bake, where a per-frame image filter would queue behind
multi-second mesh work. The full-size pass runs once, on commit, on the UI
thread, because the rebuild_preview() immediately after it is an order of
magnitude more work synchronously already.
The image maths lands in libslic3r as apply_texture_adjustments() and
downscale_height_texture(), so it is testable without a GUI, and the blur
reuses the same smooth_height_pixels() the Smoothing slider drives.
The green highlight and tint no longer cover a colour preview, and return while a stroke is
painted. The Fast view also keeps the other parts of a multi-part object.
The new Mixed colors setting caps how many mixed filaments a bake adds. They are picked from the
texture's colours, and only the ones the bake paints with are created. Previewing no longer creates
filament slots, both previews show a mix in its slot's colour, and the bake paints each mix with the
slot it actually got.
* 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
* 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.
Meeting the triangle budget by merging flat faces alone no longer raises the warning, and the
warning now quotes the budget instead of the triangle count left after the flat faces were merged.
Relief preserved from an earlier bake is counted on top of the budget
instead of eating into it: baking a second area went from ~214 k
triangles to the ~1000 k it was given.
When the resolution needs more triangles than the budget allows, it is
said before the bake under Resolution and again afterwards.
- Bake: each layer is sampled only on its own painted area; analytic
projections used to stack every layer over every painted region, so the
top layer's texture showed on all of them (colour sampler too)
- Auto resolution follows the texture's texel size and sharpness again
- Unwrap: charts cut by each face's own normal (a cube gives 6 islands, not
12 triangles); non-disk charts (tubes, closed shells) are split until they
flatten; connected nets test real triangle overlap, grow from the largest
chart and are packed side by side
- UV edits are stored per unwrapped copy, so dragging a seam vertex no
longer moves its copies in neighbouring islands
- UV pane: tool strip with unwrap settings moved in from the panel, sharp
HiDPI icons, clearer island/edge/selection drawing with hover, texture
picker from the thumbnail, texture no longer lost on reopen (GL state
from the 3D view, background upload retries)
- Panel: whole-model select/erase as icons in the tools row; inactive
layers' paint shown muted; colour textures shown in colour in the picker
- Built-in displacement texture library
- Tests for unwrap segmentation, connected nets, UV edits and per-layer
sampling