diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 70e2723f0ff..c9f352f8bdf 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -9784,6 +9784,8 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, std::clamp(zone->tone_gamma, 0.5f, 3.f); const float texture_sagging_ratio = std::isfinite(zone->sagging_ratio) ? std::clamp(zone->sagging_ratio, 0.f, 6.f) : 0.f; + const bool reduce_outer_surface_texture = + vertex_color_match_mode && zone->reduce_outer_surface_texture && !compact_offset_mode; const bool raw_texture_mapping_mode = zone->texture_mapping_mode == int(TextureMappingZone::TextureMappingRawValues); @@ -10059,6 +10061,41 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, outer_wall_gradient_segment_mods.emplace_back(mod); } + if (reduce_outer_surface_texture && max_width_delta_limit_mm > EPSILON) { + double weighted_shift_mm = 0.0; + double weighted_length_mm = 0.0; + double weighted_balance_weight_mm = 0.0; + for (const OuterWallGradientSegmentMod &mod : outer_wall_gradient_segment_mods) { + if (mod.length_mm <= EPSILON || !std::isfinite(mod.centerline_shift_mm)) + continue; + weighted_shift_mm += double(mod.centerline_shift_mm) * mod.length_mm; + weighted_length_mm += mod.length_mm; + weighted_balance_weight_mm += double(mod.balance_weight) * mod.length_mm; + } + if (weighted_length_mm > EPSILON && weighted_balance_weight_mm > EPSILON) { + const float average_shift_mm = float(weighted_shift_mm / weighted_length_mm); + const float target_average_shift_mm = base_centerline_shift_mm + 0.25f * max_width_delta_limit_mm; + const float balance_weight_average = float(weighted_balance_weight_mm / weighted_length_mm); + const float balance_mm = + std::clamp((target_average_shift_mm - average_shift_mm) / + std::max(balance_weight_average, float(EPSILON)), + -0.5f * max_width_delta_limit_mm, + 0.5f * max_width_delta_limit_mm); + outer_wall_gradient_dynamic_ctx.centerline_shift_balance_mm = balance_mm; + outer_wall_gradient_dynamic_ctx.centerline_shift_balance_weight_scale = 1.f; + for (OuterWallGradientSegmentMod &mod : outer_wall_gradient_segment_mods) { + if (mod.length_mm <= EPSILON) + continue; + const float balanced_shift_mm = + std::clamp(mod.centerline_shift_mm + balance_mm * mod.balance_weight, + 0.f, + base_centerline_shift_mm + 0.5f * max_width_delta_limit_mm); + if (!apply_centerline_shift_to_mod(mod, balanced_shift_mm)) + mod = OuterWallGradientSegmentMod{}; + } + } + } + outer_wall_gradient_modulated_path = std::any_of( outer_wall_gradient_segment_mods.begin(), outer_wall_gradient_segment_mods.end(), diff --git a/src/libslic3r/TextureMapping.cpp b/src/libslic3r/TextureMapping.cpp index f8770f65e5c..7ef822ee605 100644 --- a/src/libslic3r/TextureMapping.cpp +++ b/src/libslic3r/TextureMapping.cpp @@ -1427,10 +1427,8 @@ std::vector TextureMappingManager::effective_texture_component_ids }; if (zone.force_sequential_filaments) { - for (const unsigned int id : selected) { - if (result.size() >= expected) - break; - if (id >= 1 && id <= num_physical && id < used.size() && !used[id]) { + for (unsigned int id = 1; result.size() < expected && id <= num_physical; ++id) { + if (std::find(selected.begin(), selected.end(), id) != selected.end() && id < used.size() && !used[id]) { used[id] = true; result.emplace_back(id); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp index 58b40e67beb..ae111ab3689 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp @@ -5246,6 +5246,17 @@ static bool apply_dialog_vertex_filaments_to_color_regions(ModelObject return changed && offset == vertex_filament_ids.size(); } +static std::unique_ptr build_color_region_dialog_preview_model(const ModelObject &object, size_t vertex_count) +{ + TriangleMesh mesh = object.raw_mesh(); + if (mesh.empty() || mesh.its.vertices.size() != vertex_count) + return nullptr; + + std::unique_ptr preview_model = std::make_unique(); + preview_model->add_object(object.name.c_str(), object.input_file.c_str(), std::move(mesh)); + return preview_model; +} + static bool convert_object_to_color_regions(ModelObject &object, const ManagedColorDataCreateSource &source, wxWindow *parent) { if (object_has_color_regions(object)) @@ -5271,13 +5282,15 @@ static bool convert_object_to_color_regions(ModelObject &object, const ManagedCo std::vector filament_ids; unsigned char first_extruder_id = 1; - const std::vector extruder_colours = wxGetApp().plater()->get_extruder_colors_from_plater_config(); + std::unique_ptr preview_model = build_color_region_dialog_preview_model(object, input_colors.size()); + const std::vector extruder_colours = wxGetApp().plater()->get_extruder_colors_from_plater_config(nullptr, false); ObjDialogInOut in_out; in_out.input_colors = input_colors; in_out.is_single_color = is_single_color; in_out.filament_ids = filament_ids; in_out.first_extruder_id = first_extruder_id; in_out.deal_vertex_color = true; + in_out.model = preview_model.get(); ObjColorDialog color_dlg(parent, in_out, extruder_colours); if (color_dlg.ShowModal() != wxID_OK) return false; @@ -6650,7 +6663,7 @@ void GLGizmoMmuSegmentation::open_obj_vertex_color_mapping_dialog() std::vector filament_ids; unsigned char first_extruder_id = 1; - const std::vector extruder_colours = wxGetApp().plater()->get_extruder_colors_from_plater_config(); + const std::vector extruder_colours = wxGetApp().plater()->get_extruder_colors_from_plater_config(nullptr, false); ObjDialogInOut in_out; in_out.input_colors = input_colors; in_out.is_single_color = is_single_color; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 300af2b2976..6f0cbe86ec5 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -590,6 +590,17 @@ static std::vector texture_mapping_selected_ids(const TextureMappi return ids; } +static std::vector texture_mapping_checkbox_ordered_ids(const TextureMappingZone &zone, size_t num_physical) +{ + const std::vector selected = texture_mapping_selected_ids(zone, num_physical); + std::vector ordered; + ordered.reserve(selected.size()); + for (size_t id = 1; id <= std::min(num_physical, 9); ++id) + if (std::find(selected.begin(), selected.end(), unsigned(id)) != selected.end()) + ordered.emplace_back(unsigned(id)); + return ordered.size() >= 2 ? ordered : selected; +} + static std::string encode_texture_mapping_float_values(const std::vector &values) { std::ostringstream ss; @@ -5742,18 +5753,15 @@ void Sidebar::update_texture_mapping_panel(bool sync_manager) zone_index, mgr_ptr, palette, - physical_colors, apply_zone, bundle, set_config_string](wxCommandEvent &) { if (zone_index >= mgr_ptr->zones().size()) return; TextureMappingZone updated = mgr_ptr->zones()[zone_index]; - std::vector ids = updated.is_image_texture() ? - TextureMappingManager::effective_texture_component_ids(updated, palette.size(), physical_colors) : - texture_mapping_selected_ids(updated, palette.size()); + const std::vector ids = texture_mapping_checkbox_ordered_ids(updated, palette.size()); if (ids.empty()) - ids = texture_mapping_selected_ids(updated, palette.size()); + return; std::vector strengths; std::vector offsets; std::vector transmission_distances; @@ -5807,6 +5815,11 @@ void Sidebar::update_texture_mapping_panel(bool sync_manager) updated.transmission_distance_calibration_mode = dlg.transmission_distance_calibration_mode(); updated.preview_opacity_pct = dlg.preview_opacity_pct(); updated.force_sequential_filaments = dlg.force_sequential_filaments(); + if (updated.force_sequential_filaments && ids.size() >= 2) { + updated.component_ids = encode_texture_mapping_component_ids(ids); + updated.component_a = ids[0]; + updated.component_b = ids[1]; + } updated.auto_adjust_filament_selection = dlg.auto_adjust_filament_selection(); updated.preview_limit_resolution = dlg.preview_limit_resolution(); updated.reduce_outer_surface_texture = dlg.reduce_outer_surface_texture();