From 0664e47a70fde5a3e40bc31a0fe838a9019a1ca2 Mon Sep 17 00:00:00 2001 From: sentientstardust Date: Fri, 8 May 2026 03:34:12 +0100 Subject: [PATCH] Recognize when extruder IDs are texture mapping zones --- src/libslic3r/MultiMaterialSegmentation.cpp | 16 +++++++++------- src/libslic3r/PrintApply.cpp | 17 +++++++++++------ src/libslic3r/PrintObjectSlice.cpp | 15 ++++++++++----- 3 files changed, 30 insertions(+), 18 deletions(-) diff --git a/src/libslic3r/MultiMaterialSegmentation.cpp b/src/libslic3r/MultiMaterialSegmentation.cpp index 571299b5135..0a8717c593e 100644 --- a/src/libslic3r/MultiMaterialSegmentation.cpp +++ b/src/libslic3r/MultiMaterialSegmentation.cpp @@ -1848,15 +1848,14 @@ static std::vector> merge_segmented_layers(const std::ve { const size_t num_layers = segmented_regions.size(); std::vector> segmented_regions_merged(num_layers); - segmented_regions_merged.assign(num_layers, std::vector(num_facets_states - 1)); + segmented_regions_merged.assign(num_layers, std::vector(num_facets_states)); assert(!top_and_bottom_layers.size() || num_facets_states == top_and_bottom_layers.size()); BOOST_LOG_TRIVIAL(debug) << "Print object segmentation - Merging segmented layers in parallel - Begin"; tbb::parallel_for(tbb::blocked_range(0, num_layers), [&segmented_regions, &top_and_bottom_layers, &segmented_regions_merged, &num_facets_states, &throw_on_cancel_callback](const tbb::blocked_range &range) { for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++layer_idx) { assert(segmented_regions[layer_idx].size() == num_facets_states); - // Zero is skipped because it is the default color of the volume - for (size_t extruder_id = 1; extruder_id < num_facets_states; ++extruder_id) { + for (size_t extruder_id = 0; extruder_id < num_facets_states; ++extruder_id) { throw_on_cancel_callback(); if (!segmented_regions[layer_idx][extruder_id].empty()) { ExPolygons segmented_regions_trimmed = segmented_regions[layer_idx][extruder_id]; @@ -1868,16 +1867,19 @@ static std::vector> merge_segmented_layers(const std::ve } } - segmented_regions_merged[layer_idx][extruder_id - 1] = std::move(segmented_regions_trimmed); + segmented_regions_merged[layer_idx][extruder_id] = std::move(segmented_regions_trimmed); } if (!top_and_bottom_layers.empty() && !top_and_bottom_layers[extruder_id][layer_idx].empty()) { - bool was_top_and_bottom_empty = segmented_regions_merged[layer_idx][extruder_id - 1].empty(); - append(segmented_regions_merged[layer_idx][extruder_id - 1], top_and_bottom_layers[extruder_id][layer_idx]); + bool was_top_and_bottom_empty = segmented_regions_merged[layer_idx][extruder_id].empty(); + append(segmented_regions_merged[layer_idx][extruder_id], top_and_bottom_layers[extruder_id][layer_idx]); // Remove dimples (#7235) appearing after merging side segmentation of the model with tops and bottoms painted layers. if (!was_top_and_bottom_empty) - segmented_regions_merged[layer_idx][extruder_id - 1] = offset2_ex(union_ex(segmented_regions_merged[layer_idx][extruder_id - 1]), float(SCALED_EPSILON), -float(SCALED_EPSILON)); + segmented_regions_merged[layer_idx][extruder_id] = + offset2_ex(union_ex(segmented_regions_merged[layer_idx][extruder_id]), + float(SCALED_EPSILON), + -float(SCALED_EPSILON)); } } } diff --git a/src/libslic3r/PrintApply.cpp b/src/libslic3r/PrintApply.cpp index ef14d3bff3f..63b5354fbc6 100644 --- a/src/libslic3r/PrintApply.cpp +++ b/src/libslic3r/PrintApply.cpp @@ -1893,12 +1893,17 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ for (size_t state_idx = static_cast(EnforcerBlockerType::Extruder1); state_idx < used_facet_states.size(); ++state_idx) { if (!used_facet_states[state_idx] || state_idx > num_total_filaments) continue; - painting_extruders.emplace_back(state_idx); - append_texture_mapping_component_extruders(m_texture_mapping_mgr, - static_cast(state_idx), - num_extruders, - physical_filament_colors, - painting_extruders); + const unsigned int state_id = static_cast(state_idx); + if (state_idx <= num_extruders) { + painting_extruders.emplace_back(state_id); + } else if (m_texture_mapping_mgr.is_texture_mapping_zone_id(state_id)) { + painting_extruders.emplace_back(state_id); + append_texture_mapping_component_extruders(m_texture_mapping_mgr, + state_id, + num_extruders, + physical_filament_colors, + painting_extruders); + } } std::sort(painting_extruders.begin(), painting_extruders.end()); painting_extruders.erase(std::unique(painting_extruders.begin(), painting_extruders.end()), painting_extruders.end()); diff --git a/src/libslic3r/PrintObjectSlice.cpp b/src/libslic3r/PrintObjectSlice.cpp index 6148533a5ae..0fa8e2c4fa7 100644 --- a/src/libslic3r/PrintObjectSlice.cpp +++ b/src/libslic3r/PrintObjectSlice.cpp @@ -1069,8 +1069,10 @@ static inline void apply_mm_segmentation(PrintObject &print_object, ThrowOnCance const auto &layer_ranges = print_object.shared_regions()->layer_ranges; double z = print_object.get_layer(int(range.begin()))->slice_z; auto it_layer_range = layer_range_first(layer_ranges, z); - // BBS - const size_t num_extruders = print_object.print()->config().filament_diameter.size(); + const size_t num_physical = print_object.print()->config().filament_diameter.size(); + const TextureMappingManager &texture_mgr = print_object.print()->texture_mapping_manager(); + const size_t num_channels = segmentation.empty() ? 0 : segmentation.front().size(); + const size_t num_extruders = num_channels > 0 ? num_channels - 1 : 0; struct ByExtruder { ExPolygons expolygons; @@ -1090,12 +1092,15 @@ static inline void apply_mm_segmentation(PrintObject &print_object, ThrowOnCance it_layer_range = layer_range_next(layer_ranges, it_layer_range, layer.slice_z); const PrintObjectRegions::LayerRangeRegions &layer_range = *it_layer_range; // Gather per extruder expolygons. + assert(segmentation[layer_id].size() == num_channels); by_extruder.assign(num_extruders, ByExtruder()); by_region.assign(layer.region_count(), ByRegion()); bool layer_split = false; - for (size_t extruder_id = 0; extruder_id < num_extruders; ++ extruder_id) { - ByExtruder ®ion = by_extruder[extruder_id]; - append(region.expolygons, std::move(segmentation[layer_id][extruder_id])); + for (size_t channel_idx = 1; channel_idx < num_channels; ++ channel_idx) { + if (channel_idx > num_physical && !texture_mgr.is_texture_mapping_zone_id(unsigned(channel_idx))) + continue; + ByExtruder ®ion = by_extruder[channel_idx - 1]; + append(region.expolygons, std::move(segmentation[layer_id][channel_idx])); if (! region.expolygons.empty()) { region.bbox = get_extents(region.expolygons); layer_split = true;