Let texture bakes create a chosen number of mixed colours

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.
This commit is contained in:
SoftFever
2026-10-09 22:23:07 +08:00
parent 62b829d1cb
commit 0473da4ef8
17 changed files with 888 additions and 320 deletions
@@ -4,6 +4,7 @@
#include <functional>
#include <utility>
#include <string>
#include <vector>
#include "libslic3r/TextureDisplacement.hpp"
#include <exception>
#include <cstddef>
@@ -114,6 +115,17 @@ void TextureDisplacementBakeJob::finalize(bool canceled, std::exception_ptr &ept
if (volume == nullptr)
return;
// The filament each palette entry prints in. This is where a mix becomes a mixed filament slot,
// and only a mix the bake actually painted with: the preview never creates one, so the project
// gains only the slots this result needs. Done before anything below names them - adding a slot
// runs ModelVolume::update_extruder_count(), which clamps paint above the old filament count.
Sidebar &sidebar = plater->sidebar();
const std::vector<int> filament_of = GLGizmoTextureDisplacement::palette_filaments(
m_input.color.palette, m_triangle_color, [&sidebar](const PrintableColor &mix) {
return sidebar.ensure_mixed_filament({ unsigned(mix.a + 1), unsigned(mix.b + 1) },
{ mix.a_percent(), 100 - mix.a_percent() });
});
volume->set_mesh(std::move(m_result));
volume->set_new_unique_id();
volume->calculate_convex_hull();
@@ -129,9 +141,11 @@ void TextureDisplacementBakeJob::finalize(bool canceled, std::exception_ptr &ept
const TriangleSelector::TriangleSplittingData &existing = volume->mmu_segmentation_facets.get_data();
if (!existing.bitstream.empty())
selector.deserialize(existing, false);
for (size_t i = 0; i < m_triangle_color.size(); ++i)
if (m_triangle_color[i] > 0)
selector.set_facet(int(i), EnforcerBlockerType(m_triangle_color[i]));
for (size_t i = 0; i < m_triangle_color.size(); ++i) {
const size_t entry = size_t(m_triangle_color[i]);
if (entry > 0 && entry <= filament_of.size() && filament_of[entry - 1] >= 0)
selector.set_facet(int(i), EnforcerBlockerType(filament_of[entry - 1] + 1));
}
volume->mmu_segmentation_facets.set(selector);
}