From 11b55ccd73097ee151ec2197d02851bbbf2c297e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hejl?= Date: Fri, 1 Sep 2023 11:27:35 +0800 Subject: [PATCH] ENH: Added option for enabling interlocking between segmented regions by the multimaterial painting. This commit is cherry pick from Prusa, the commit number is 9bce0fcf9bb479c289c396e7e23ce95841a61628 Thanks to Prusa. Jira: XXXX Change-Id: I29ad1fa9ab3ccc393a1e2affde1ae869d0a33afa --- src/libslic3r/MultiMaterialSegmentation.cpp | 27 ++++++++++++--------- src/libslic3r/Preset.cpp | 2 +- src/libslic3r/PrintConfig.cpp | 21 ++++++++++++++++ src/libslic3r/PrintConfig.hpp | 2 ++ src/libslic3r/PrintObject.cpp | 2 ++ src/slic3r/GUI/Tab.cpp | 3 +++ 6 files changed, 45 insertions(+), 12 deletions(-) diff --git a/src/libslic3r/MultiMaterialSegmentation.cpp b/src/libslic3r/MultiMaterialSegmentation.cpp index 2d3710878..275ecf47a 100644 --- a/src/libslic3r/MultiMaterialSegmentation.cpp +++ b/src/libslic3r/MultiMaterialSegmentation.cpp @@ -1372,18 +1372,23 @@ static void remove_multiple_edges_in_vertices(MMU_Graph &graph, const std::vecto static void cut_segmented_layers(const std::vector &input_expolygons, std::vector> &segmented_regions, const float cut_width, + const float interlocking_depth, const std::function &throw_on_cancel_callback) { BOOST_LOG_TRIVIAL(debug) << "MMU segmentation - cutting segmented layers in parallel - begin"; - tbb::parallel_for(tbb::blocked_range(0, segmented_regions.size()),[&segmented_regions, &input_expolygons, &cut_width, &throw_on_cancel_callback](const tbb::blocked_range& range) { + tbb::parallel_for(tbb::blocked_range(0, segmented_regions.size()), + [&segmented_regions, &input_expolygons, &cut_width, &interlocking_depth, &throw_on_cancel_callback](const tbb::blocked_range &range) { for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++layer_idx) { throw_on_cancel_callback(); - const size_t num_extruders_plus_one = segmented_regions[layer_idx].size(); - std::vector segmented_regions_cuts(num_extruders_plus_one); // Indexed by extruder_id - for (size_t extruder_idx = 0; extruder_idx < num_extruders_plus_one; ++extruder_idx) - if (const ExPolygons &ex_polygons = segmented_regions[layer_idx][extruder_idx]; !ex_polygons.empty()) - segmented_regions_cuts[extruder_idx] = diff_ex(ex_polygons, offset_ex(input_expolygons[layer_idx], cut_width)); - segmented_regions[layer_idx] = std::move(segmented_regions_cuts); + const float region_cut_width = ((layer_idx % 2 == 0) && (interlocking_depth != 0.f)) ? interlocking_depth : cut_width; + const size_t num_extruders_plus_one = segmented_regions[layer_idx].size(); + if (region_cut_width > 0.f) { + std::vector segmented_regions_cuts(num_extruders_plus_one); // Indexed by extruder_id + for (size_t extruder_idx = 0; extruder_idx < num_extruders_plus_one; ++extruder_idx) + if (const ExPolygons &ex_polygons = segmented_regions[layer_idx][extruder_idx]; !ex_polygons.empty()) + segmented_regions_cuts[extruder_idx] = diff_ex(ex_polygons, offset_ex(input_expolygons[layer_idx], -region_cut_width)); + segmented_regions[layer_idx] = std::move(segmented_regions_cuts); + } } }); // end of parallel_for BOOST_LOG_TRIVIAL(debug) << "MMU segmentation - cutting segmented layers in parallel - end"; @@ -2040,10 +2045,10 @@ std::vector> multi_material_segmentation_by_painting(con BOOST_LOG_TRIVIAL(debug) << "MMU segmentation - layers segmentation in parallel - end"; throw_on_cancel_callback(); - //if (auto w = print_object.config().mmu_segmented_region_max_width; w > 0.f) { - // cut_segmented_layers(input_expolygons, segmented_regions, float(-scale_(w)), throw_on_cancel_callback); - // throw_on_cancel_callback(); - //} + if (auto max_width = print_object.config().mmu_segmented_region_max_width, interlocking_depth = print_object.config().mmu_segmented_region_interlocking_depth; max_width > 0.f || interlocking_depth > 0.f) { + cut_segmented_layers(input_expolygons, segmented_regions, float(scale_(max_width)), float(scale_(interlocking_depth)), throw_on_cancel_callback); + throw_on_cancel_callback(); + } // The first index is extruder number (includes default extruder), and the second one is layer number std::vector> top_and_bottom_layers = mmu_segmentation_top_and_bottom_layers(print_object, input_expolygons, throw_on_cancel_callback); diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 7d50ec1ea..9a8e27f39 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -802,7 +802,7 @@ static std::vector s_Preset_print_options { "wall_distribution_count", "min_feature_size", "min_bead_width", "post_process", "seam_gap", "wipe_speed", "top_solid_infill_flow_ratio", "initial_layer_flow_ratio", "default_jerk", "outer_wall_jerk", "inner_wall_jerk", "infill_jerk", "top_surface_jerk", "initial_layer_jerk", "travel_jerk", - "filter_out_gap_fill", + "filter_out_gap_fill", "mmu_segmented_region_max_width", "mmu_segmented_region_interlocking_depth", // calib "print_flow_ratio", //Orca diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index e238a7655..671135fe2 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -1966,6 +1966,27 @@ void PrintConfigDef::init_fff_params() def->mode = comDevelop; def->set_default_value(new ConfigOptionBool(false)); + def = this->add("mmu_segmented_region_max_width", coFloat); + def->label = L("Maximum width of a segmented region"); + def->tooltip = L("Maximum width of a segmented region. Zero disables this feature."); + def->sidetext = L("mm"); + def->min = 0; + def->category = L("Advanced"); + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloat(0.)); + + def = this->add("mmu_segmented_region_interlocking_depth", coFloat); + def->label = L("Interlocking depth of a segmented region"); + //def->tooltip = L("Interlocking depth of a segmented region. It will be ignored if " + // "\"mmu_segmented_region_max_width\" is zero or if \"mmu_segmented_region_interlocking_depth\"" + // "is bigger then \"mmu_segmented_region_max_width\". Zero disables this feature."); + def->tooltip = L("Interlocking depth of a segmented region. Zero disables this feature."); + def->sidetext = L("mm"); //(zero to disable) + def->min = 0; + def->category = L("Advanced"); + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloat(0.)); + def = this->add("ironing_type", coEnum); def->label = L("Ironing Type"); def->category = L("Quality"); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index bf808569a..74da46ce9 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -656,6 +656,8 @@ PRINT_CONFIG_CLASS_DEFINE( // Force the generation of solid shells between adjacent materials/volumes. ((ConfigOptionBool, interface_shells)) ((ConfigOptionFloat, layer_height)) + ((ConfigOptionFloat, mmu_segmented_region_max_width)) + ((ConfigOptionFloat, mmu_segmented_region_interlocking_depth)) ((ConfigOptionFloat, raft_contact_distance)) ((ConfigOptionFloat, raft_expansion)) ((ConfigOptionPercent, raft_first_layer_density)) diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index f086510ac..bb6ac4169 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -740,6 +740,8 @@ bool PrintObject::invalidate_state_by_config_options( steps.emplace_back(posPerimeters); } else if ( opt_key == "layer_height" + || opt_key == "mmu_segmented_region_max_width" + || opt_key == "mmu_segmented_region_interlocking_depth" || opt_key == "raft_layers" || opt_key == "raft_contact_distance" || opt_key == "slice_closing_radius" diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 1ea1e7e2b..e7fde7481 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -2050,6 +2050,9 @@ void TabPrint::build() optgroup->append_single_option_line("fuzzy_skin_point_distance"); optgroup->append_single_option_line("fuzzy_skin_thickness"); + optgroup = page->new_optgroup(L("Advanced"), L"advanced"); + // optgroup->append_single_option_line("mmu_segmented_region_max_width"); + optgroup->append_single_option_line("mmu_segmented_region_interlocking_depth"); optgroup = page->new_optgroup(L("G-code output"), L"param_gcode"); optgroup->append_single_option_line("reduce_infill_retraction");