ENH: Optimizing the shape invalid condition for wipe tower of multi-extruder

jira: none
Change-Id: Ic80a83088f409f0c4d4444c085befb6a1817c85b
This commit is contained in:
zhimin.zeng 2025-05-16 11:48:54 +08:00 committed by lane.wei
parent 2b8edfccc8
commit e22d328fa9

View File

@ -288,6 +288,51 @@ static t_config_option_keys full_print_config_diffs(const DynamicPrintConfig &cu
return full_config_diff; 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<ConfigOptionEnum<FilamentMapMode>>("filament_map_mode");
if (map_mode_opt && map_mode_opt->value == FilamentMapMode::fmmManual)
return false;
Pointfs printable_area = new_full_config.option<ConfigOptionPoints>("printable_area")->values;
std::vector<Pointfs> extruder_areas = new_full_config.option<ConfigOptionPointsGroups>("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<Polygon> 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<Polygon> 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<Polygon> &contours) -> std::set<int> {
std::set<int> result;
for (size_t i = 0; i < contours.size(); ++i) {
if (!intersection(poly, contours[i]).empty()) { result.insert(static_cast<int>(i)); }
}
return result;
};
std::set<int> old_poly_ids = find_intersections(old_poly, split_polys);
std::set<int> 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. // Repository for solving partial overlaps of ModelObject::layer_config_ranges.
// Here the const DynamicPrintConfig* point to the config in ModelObject::layer_config_ranges. // Here the const DynamicPrintConfig* point to the config in ModelObject::layer_config_ranges.
class LayerRanges class LayerRanges
@ -1452,6 +1497,9 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_
// Synchronize the content of instances. // Synchronize the content of instances.
auto new_instance = model_object_new.instances.begin(); 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) { for (auto old_instance = model_object.instances.begin(); old_instance != model_object.instances.end(); ++ old_instance, ++ new_instance) {
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)->set_transformation((*new_instance)->get_transformation());
(*old_instance)->print_volume_state = (*new_instance)->print_volume_state; (*old_instance)->print_volume_state = (*new_instance)->print_volume_state;
(*old_instance)->printable = (*new_instance)->printable; (*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)); PrintBase::ApplyStatus status = (*it_old)->print_object->set_instances(std::move(new_instances.instances));
if (status != PrintBase::APPLY_STATUS_UNCHANGED) { if (status != PrintBase::APPLY_STATUS_UNCHANGED) {
size_t extruder_num = new_full_config.option<ConfigOptionFloatsNullable>("nozzle_diameter")->size(); size_t extruder_num = new_full_config.option<ConfigOptionFloatsNullable>("nozzle_diameter")->size();
if (extruder_num > 1) {
update_apply_status(this->invalidate_steps({ psWipeTower,psSkirtBrim, psGCodeExport }));
}
update_apply_status(status == PrintBase::APPLY_STATUS_INVALIDATED); update_apply_status(status == PrintBase::APPLY_STATUS_INVALIDATED);
} }
print_objects_new.emplace_back((*it_old)->print_object); print_objects_new.emplace_back((*it_old)->print_object);