From 76b40c9636c39b9c707235d20c86b6c69bf596b7 Mon Sep 17 00:00:00 2001 From: "yifan.wu" Date: Wed, 19 Oct 2022 16:30:08 +0800 Subject: [PATCH] FIX: fix an flush_into_object bug for copied objects Copied objects share extrusion paths but they should be treated seperately. Thanks hisptoot for the fix. Signed-off-by: yifan.wu Change-Id: I24d3050df7d284e92fc50a0213023a43ee8c529c --- src/libslic3r/GCode.cpp | 2 +- src/libslic3r/GCode/ToolOrdering.cpp | 24 ++++++++++++------------ src/libslic3r/GCode/ToolOrdering.hpp | 10 +++++----- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 65fba12a7..433cbf1b0 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -2791,7 +2791,7 @@ GCode::LayerResult GCode::process_layer( } printing_extruders.clear(); if (is_anything_overridden) { - entity_overrides = const_cast(layer_tools).wiping_extrusions().get_extruder_overrides(extrusions, correct_extruder_id, layer_to_print.object()->instances().size()); + entity_overrides = const_cast(layer_tools).wiping_extrusions().get_extruder_overrides(extrusions, layer_to_print.original_object, correct_extruder_id, layer_to_print.object()->instances().size()); if (entity_overrides == nullptr) { printing_extruders.emplace_back(correct_extruder_id); } else { diff --git a/src/libslic3r/GCode/ToolOrdering.cpp b/src/libslic3r/GCode/ToolOrdering.cpp index a99d100bf..d2e05ccfc 100644 --- a/src/libslic3r/GCode/ToolOrdering.cpp +++ b/src/libslic3r/GCode/ToolOrdering.cpp @@ -864,11 +864,11 @@ const LayerTools& ToolOrdering::tools_for_layer(coordf_t print_z) const } // This function is called from Print::mark_wiping_extrusions and sets extruder this entity should be printed with (-1 .. as usual) -void WipingExtrusions::set_extruder_override(const ExtrusionEntity* entity, size_t copy_id, int extruder, size_t num_of_copies) +void WipingExtrusions::set_extruder_override(const ExtrusionEntity* entity, const PrintObject* object, size_t copy_id, int extruder, size_t num_of_copies) { something_overridden = true; - auto entity_map_it = (entity_map.emplace(entity, ExtruderPerCopy())).first; // (add and) return iterator + auto entity_map_it = (entity_map.emplace(std::make_tuple(entity, object), ExtruderPerCopy())).first; // (add and) return iterator ExtruderPerCopy& copies_vector = entity_map_it->second; copies_vector.resize(num_of_copies, -1); @@ -1019,9 +1019,9 @@ float WipingExtrusions::mark_wiping_extrusions(const Print& print, unsigned int if (!lt.is_extruder_order(lt.wall_filament(region), new_extruder)) continue; - if ((!is_entity_overridden(fill, copy) && fill->total_volume() > min_infill_volume)) + if ((!is_entity_overridden(fill, object, copy) && fill->total_volume() > min_infill_volume)) { // this infill will be used to wipe this extruder - set_extruder_override(fill, copy, new_extruder, num_of_copies); + set_extruder_override(fill, object, copy, new_extruder, num_of_copies); if ((volume_to_wipe -= float(fill->total_volume())) <= 0.f) // More material was purged already than asked for. return 0.f; @@ -1034,8 +1034,8 @@ float WipingExtrusions::mark_wiping_extrusions(const Print& print, unsigned int { for (const ExtrusionEntity* ee : layerm->perimeters.entities) { auto* fill = dynamic_cast(ee); - if (is_overriddable(*fill, print.config(), *object, region) && !is_entity_overridden(fill, copy) && fill->total_volume() > min_infill_volume) { - set_extruder_override(fill, copy, new_extruder, num_of_copies); + if (is_overriddable(*fill, print.config(), *object, region) && !is_entity_overridden(fill, object, copy) && fill->total_volume() > min_infill_volume) { + set_extruder_override(fill, object, copy, new_extruder, num_of_copies); if ((volume_to_wipe -= float(fill->total_volume())) <= 0.f) // More material was purged already than asked for. return 0.f; @@ -1125,7 +1125,7 @@ void WipingExtrusions::ensure_perimeters_infills_order(const Print& print) auto* fill = dynamic_cast(ee); if (!is_overriddable(*fill, print.config(), *object, region) - || is_entity_overridden(fill, copy) ) + || is_entity_overridden(fill, object, copy) ) continue; // This infill could have been overridden but was not - unless we do something, it could be @@ -1138,7 +1138,7 @@ void WipingExtrusions::ensure_perimeters_infills_order(const Print& print) //|| object->config().flush_into_objects // in this case the perimeter is overridden, so we can override by the last one safely || lt.is_extruder_order(lt.wall_filament(region), last_nonsoluble_extruder // !infill_first, but perimeter is already printed when last extruder prints || ! lt.has_extruder(lt.sparse_infill_filament(region)))) // we have to force override - this could violate infill_first (FIXME) - set_extruder_override(fill, copy, (is_infill_first ? first_nonsoluble_extruder : last_nonsoluble_extruder), num_of_copies); + set_extruder_override(fill, object, copy, (is_infill_first ? first_nonsoluble_extruder : last_nonsoluble_extruder), num_of_copies); else { // In this case we can (and should) leave it to be printed normally. // Force overriding would mean it gets printed before its perimeter. @@ -1148,8 +1148,8 @@ void WipingExtrusions::ensure_perimeters_infills_order(const Print& print) // Now the same for perimeters - see comments above for explanation: for (const ExtrusionEntity* ee : layerm->perimeters.entities) { // iterate through all perimeter Collections auto* fill = dynamic_cast(ee); - if (is_overriddable(*fill, print.config(), *object, region) && ! is_entity_overridden(fill, copy)) - set_extruder_override(fill, copy, (is_infill_first ? last_nonsoluble_extruder : first_nonsoluble_extruder), num_of_copies); + if (is_overriddable(*fill, print.config(), *object, region) && ! is_entity_overridden(fill, object, copy)) + set_extruder_override(fill, object, copy, (is_infill_first ? last_nonsoluble_extruder : first_nonsoluble_extruder), num_of_copies); } } } @@ -1162,10 +1162,10 @@ void WipingExtrusions::ensure_perimeters_infills_order(const Print& print) // so -1 was used as "print as usual"). // The resulting vector therefore keeps track of which extrusions are the ones that were overridden and which were not. If the extruder used is overridden, // its number is saved as is (zero-based index). Regular extrusions are saved as -number-1 (unfortunately there is no negative zero). -const WipingExtrusions::ExtruderPerCopy* WipingExtrusions::get_extruder_overrides(const ExtrusionEntity* entity, int correct_extruder_id, size_t num_of_copies) +const WipingExtrusions::ExtruderPerCopy* WipingExtrusions::get_extruder_overrides(const ExtrusionEntity* entity, const PrintObject* object, int correct_extruder_id, size_t num_of_copies) { ExtruderPerCopy *overrides = nullptr; - auto entity_map_it = entity_map.find(entity); + auto entity_map_it = entity_map.find(std::make_tuple(entity, object)); if (entity_map_it != entity_map.end()) { overrides = &entity_map_it->second; overrides->resize(num_of_copies, -1); diff --git a/src/libslic3r/GCode/ToolOrdering.hpp b/src/libslic3r/GCode/ToolOrdering.hpp index 34fdbf49c..53c6603c6 100644 --- a/src/libslic3r/GCode/ToolOrdering.hpp +++ b/src/libslic3r/GCode/ToolOrdering.hpp @@ -31,7 +31,7 @@ public: typedef boost::container::small_vector ExtruderPerCopy; // This is called from GCode::process_layer - see implementation for further comments: - const ExtruderPerCopy* get_extruder_overrides(const ExtrusionEntity* entity, int correct_extruder_id, size_t num_of_copies); + const ExtruderPerCopy* get_extruder_overrides(const ExtrusionEntity* entity, const PrintObject* object, int correct_extruder_id, size_t num_of_copies); int get_support_extruder_overrides(const PrintObject* object); int get_support_interface_extruder_overrides(const PrintObject* object); @@ -71,18 +71,18 @@ private: int last_nonsoluble_extruder_on_layer(const PrintConfig& print_config) const; // This function is called from mark_wiping_extrusions and sets extruder that it should be printed with (-1 .. as usual) - void set_extruder_override(const ExtrusionEntity* entity, size_t copy_id, int extruder, size_t num_of_copies); + void set_extruder_override(const ExtrusionEntity* entity, const PrintObject* object, size_t copy_id, int extruder, size_t num_of_copies); // BBS void set_support_extruder_override(const PrintObject* object, size_t copy_id, int extruder, size_t num_of_copies); void set_support_interface_extruder_override(const PrintObject* object, size_t copy_id, int extruder, size_t num_of_copies); // Returns true in case that entity is not printed with its usual extruder for a given copy: - bool is_entity_overridden(const ExtrusionEntity* entity, size_t copy_id) const { - auto it = entity_map.find(entity); + bool is_entity_overridden(const ExtrusionEntity* entity, const PrintObject *object, size_t copy_id) const { + auto it = entity_map.find(std::make_tuple(entity, object)); return it == entity_map.end() ? false : it->second[copy_id] != -1; } - std::map entity_map; // to keep track of who prints what + std::map, ExtruderPerCopy> entity_map; // to keep track of who prints what // BBS std::map support_map; std::map support_intf_map;