From 4662bc67bb39b978d110bba86477527522d93a5d Mon Sep 17 00:00:00 2001 From: ExPikaPaka Date: Thu, 15 Oct 2026 12:15:41 +0200 Subject: [PATCH] Treat an image with no colour spread as flat, not as a ramp The axis-coverage signal defaulted to 1, meaning "spans its range", which is what a ramp measures. An image of a single colour has no axis to measure, so it kept that default and stopped counting as flat - the most flat image there is. It broke the slic3rutils test that feeds mix_targets() a uniform 8x8. Zero is the right default: an unmeasurable axis leaves the flat-share test deciding on its own, exactly as before this signal existed. That also covers an image with too few pixels to fit an axis through. --- src/libslic3r/TextureDisplacement.cpp | 4 +++- src/libslic3r/TextureDisplacement.hpp | 6 +++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/libslic3r/TextureDisplacement.cpp b/src/libslic3r/TextureDisplacement.cpp index 264809d79c..8481583ea1 100644 --- a/src/libslic3r/TextureDisplacement.cpp +++ b/src/libslic3r/TextureDisplacement.cpp @@ -754,7 +754,9 @@ TextureDetail analyze_texture_detail(const TextureDisplacementLayer &layer) // Both signals, because either alone misreads a common case: the histogram calls a // two-colour gradient flat (measured 0.90 on a green-to-red ramp, and 0.96 on a painted - // model texture), while coverage alone would call a noisy two-colour logo a gradient. + // model texture), while coverage alone would call a noisy two-colour logo a gradient. An + // image whose axis could not be measured keeps coverage at 0, so the flat-share test decides + // alone - which is what an image of a single colour needs. out.flat_colors = out.flat_share >= 0.85f && out.axis_coverage < 0.25f; } std::lock_guard lock(g_texture_detail_cache.mutex); diff --git a/src/libslic3r/TextureDisplacement.hpp b/src/libslic3r/TextureDisplacement.hpp index e319515074..5cdc673806 100644 --- a/src/libslic3r/TextureDisplacement.hpp +++ b/src/libslic3r/TextureDisplacement.hpp @@ -508,7 +508,11 @@ struct TextureDetail // covers it end to end; a few flat colours sit in spikes with gaps between them. The histogram // above cannot tell those apart - a two-colour gradient occupies as few bins as the two colours // on their own - so both are needed before an image counts as flat. - float axis_coverage = 1.f; + // + // Zero when there was nothing to measure: an image of one colour, or too few pixels to fit an + // axis through. That is the right default, because it leaves the flat-share test deciding on its + // own, exactly as it did before this signal existed. + float axis_coverage = 0.f; bool flat_colors = false; }; TextureDetail analyze_texture_detail(const TextureDisplacementLayer &layer);