Implement reduce outer surface texture mode

This commit is contained in:
sentientstardust
2026-05-08 17:29:49 +01:00
parent 3cc3cba664
commit 380cc025cd
4 changed files with 72 additions and 11 deletions

View File

@@ -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(),

View File

@@ -1427,10 +1427,8 @@ std::vector<unsigned int> 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);
}

View File

@@ -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<Model> 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<Model> preview_model = std::make_unique<Model>();
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<unsigned char> filament_ids;
unsigned char first_extruder_id = 1;
const std::vector<std::string> extruder_colours = wxGetApp().plater()->get_extruder_colors_from_plater_config();
std::unique_ptr<Model> preview_model = build_color_region_dialog_preview_model(object, input_colors.size());
const std::vector<std::string> 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<unsigned char> filament_ids;
unsigned char first_extruder_id = 1;
const std::vector<std::string> extruder_colours = wxGetApp().plater()->get_extruder_colors_from_plater_config();
const std::vector<std::string> 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;

View File

@@ -590,6 +590,17 @@ static std::vector<unsigned int> texture_mapping_selected_ids(const TextureMappi
return ids;
}
static std::vector<unsigned int> texture_mapping_checkbox_ordered_ids(const TextureMappingZone &zone, size_t num_physical)
{
const std::vector<unsigned int> selected = texture_mapping_selected_ids(zone, num_physical);
std::vector<unsigned int> ordered;
ordered.reserve(selected.size());
for (size_t id = 1; id <= std::min<size_t>(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<float> &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<unsigned int> 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<unsigned int> ids = texture_mapping_checkbox_ordered_ids(updated, palette.size());
if (ids.empty())
ids = texture_mapping_selected_ids(updated, palette.size());
return;
std::vector<float> strengths;
std::vector<float> offsets;
std::vector<float> 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();