From e22d328fa9d1682c00617a4cad0498c67a7512f4 Mon Sep 17 00:00:00 2001 From: "zhimin.zeng" Date: Fri, 16 May 2025 11:48:54 +0800 Subject: [PATCH] ENH: Optimizing the shape invalid condition for wipe tower of multi-extruder jira: none Change-Id: Ic80a83088f409f0c4d4444c085befb6a1817c85b --- src/libslic3r/PrintApply.cpp | 53 +++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/src/libslic3r/PrintApply.cpp b/src/libslic3r/PrintApply.cpp index 69f760d17..59c2adfd8 100644 --- a/src/libslic3r/PrintApply.cpp +++ b/src/libslic3r/PrintApply.cpp @@ -288,6 +288,51 @@ static t_config_option_keys full_print_config_diffs(const DynamicPrintConfig &cu return full_config_diff; } +static bool is_printable_filament_changed(const DynamicPrintConfig& new_full_config, const Polygon& old_poly, const Polygon& new_poly) +{ + if (old_poly != new_poly) { + auto map_mode_opt = new_full_config.option>("filament_map_mode"); + if (map_mode_opt && map_mode_opt->value == FilamentMapMode::fmmManual) + return false; + + Pointfs printable_area = new_full_config.option("printable_area")->values; + std::vector extruder_areas = new_full_config.option("extruder_printable_area")->values; + Points pts; + for (auto pt : printable_area) { pts.emplace_back(Point(scale_(pt.x()), scale_(pt.y()))); } + Polygon printable_poly(pts); + + std::vector extruder_polys; + for (auto extruder_area : extruder_areas) { + pts.clear(); + for (auto pt : extruder_area) { pts.emplace_back(Point(scale_(pt.x()), scale_(pt.y()))); } + extruder_polys.emplace_back(Polygon(pts)); + } + + std::vector split_polys; + for (const Polygon poly : extruder_polys) { + Polygons res = diff(printable_poly, poly); + if (!res.empty()) { split_polys.emplace_back(res[0]); } + } + + Polygons all_extruder_polys = intersection({printable_poly}, extruder_polys); + if (!all_extruder_polys.empty()) split_polys.emplace_back(all_extruder_polys[0]); + + auto find_intersections = [](const Polygon &poly, const std::vector &contours) -> std::set { + std::set result; + for (size_t i = 0; i < contours.size(); ++i) { + if (!intersection(poly, contours[i]).empty()) { result.insert(static_cast(i)); } + } + return result; + }; + + std::set old_poly_ids = find_intersections(old_poly, split_polys); + std::set new_poly_ids = find_intersections(new_poly, split_polys); + + return old_poly_ids != new_poly_ids; + } + return false; +} + // Repository for solving partial overlaps of ModelObject::layer_config_ranges. // Here the const DynamicPrintConfig* point to the config in ModelObject::layer_config_ranges. class LayerRanges @@ -1452,7 +1497,10 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ // Synchronize the content of instances. auto new_instance = model_object_new.instances.begin(); for (auto old_instance = model_object.instances.begin(); old_instance != model_object.instances.end(); ++ old_instance, ++ new_instance) { - (*old_instance)->set_transformation((*new_instance)->get_transformation()); + if (is_printable_filament_changed(new_full_config, (*old_instance)->convex_hull_2d(), (*new_instance)->convex_hull_2d())) { + update_apply_status(this->invalidate_steps({psWipeTower, psGCodeExport})); + } + (*old_instance)->set_transformation((*new_instance)->get_transformation()); (*old_instance)->print_volume_state = (*new_instance)->print_volume_state; (*old_instance)->printable = (*new_instance)->printable; } @@ -1515,9 +1563,6 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ PrintBase::ApplyStatus status = (*it_old)->print_object->set_instances(std::move(new_instances.instances)); if (status != PrintBase::APPLY_STATUS_UNCHANGED) { size_t extruder_num = new_full_config.option("nozzle_diameter")->size(); - if (extruder_num > 1) { - update_apply_status(this->invalidate_steps({ psWipeTower,psSkirtBrim, psGCodeExport })); - } update_apply_status(status == PrintBase::APPLY_STATUS_INVALIDATED); } print_objects_new.emplace_back((*it_old)->print_object);