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 <yifan.wu@bambulab.com>
Change-Id: I24d3050df7d284e92fc50a0213023a43ee8c529c
This commit is contained in:
yifan.wu 2022-10-19 16:30:08 +08:00 committed by Lane.Wei
parent 65f57882b9
commit 76b40c9636
3 changed files with 18 additions and 18 deletions

View File

@ -2791,7 +2791,7 @@ GCode::LayerResult GCode::process_layer(
} }
printing_extruders.clear(); printing_extruders.clear();
if (is_anything_overridden) { if (is_anything_overridden) {
entity_overrides = const_cast<LayerTools&>(layer_tools).wiping_extrusions().get_extruder_overrides(extrusions, correct_extruder_id, layer_to_print.object()->instances().size()); entity_overrides = const_cast<LayerTools&>(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) { if (entity_overrides == nullptr) {
printing_extruders.emplace_back(correct_extruder_id); printing_extruders.emplace_back(correct_extruder_id);
} else { } else {

View File

@ -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) // 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; 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; ExtruderPerCopy& copies_vector = entity_map_it->second;
copies_vector.resize(num_of_copies, -1); 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)) if (!lt.is_extruder_order(lt.wall_filament(region), new_extruder))
continue; 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 { // 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) if ((volume_to_wipe -= float(fill->total_volume())) <= 0.f)
// More material was purged already than asked for. // More material was purged already than asked for.
return 0.f; return 0.f;
@ -1034,8 +1034,8 @@ float WipingExtrusions::mark_wiping_extrusions(const Print& print, unsigned int
{ {
for (const ExtrusionEntity* ee : layerm->perimeters.entities) { for (const ExtrusionEntity* ee : layerm->perimeters.entities) {
auto* fill = dynamic_cast<const ExtrusionEntityCollection*>(ee); auto* fill = dynamic_cast<const ExtrusionEntityCollection*>(ee);
if (is_overriddable(*fill, print.config(), *object, region) && !is_entity_overridden(fill, copy) && fill->total_volume() > min_infill_volume) { if (is_overriddable(*fill, print.config(), *object, region) && !is_entity_overridden(fill, object, copy) && fill->total_volume() > min_infill_volume) {
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) if ((volume_to_wipe -= float(fill->total_volume())) <= 0.f)
// More material was purged already than asked for. // More material was purged already than asked for.
return 0.f; return 0.f;
@ -1125,7 +1125,7 @@ void WipingExtrusions::ensure_perimeters_infills_order(const Print& print)
auto* fill = dynamic_cast<const ExtrusionEntityCollection*>(ee); auto* fill = dynamic_cast<const ExtrusionEntityCollection*>(ee);
if (!is_overriddable(*fill, print.config(), *object, region) if (!is_overriddable(*fill, print.config(), *object, region)
|| is_entity_overridden(fill, copy) ) || is_entity_overridden(fill, object, copy) )
continue; continue;
// This infill could have been overridden but was not - unless we do something, it could be // 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 //|| 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.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) || ! 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 { else {
// In this case we can (and should) leave it to be printed normally. // In this case we can (and should) leave it to be printed normally.
// Force overriding would mean it gets printed before its perimeter. // 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: // Now the same for perimeters - see comments above for explanation:
for (const ExtrusionEntity* ee : layerm->perimeters.entities) { // iterate through all perimeter Collections for (const ExtrusionEntity* ee : layerm->perimeters.entities) { // iterate through all perimeter Collections
auto* fill = dynamic_cast<const ExtrusionEntityCollection*>(ee); auto* fill = dynamic_cast<const ExtrusionEntityCollection*>(ee);
if (is_overriddable(*fill, print.config(), *object, region) && ! is_entity_overridden(fill, copy)) if (is_overriddable(*fill, print.config(), *object, region) && ! is_entity_overridden(fill, object, copy))
set_extruder_override(fill, copy, (is_infill_first ? last_nonsoluble_extruder : first_nonsoluble_extruder), num_of_copies); 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"). // 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, // 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). // 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; 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()) { if (entity_map_it != entity_map.end()) {
overrides = &entity_map_it->second; overrides = &entity_map_it->second;
overrides->resize(num_of_copies, -1); overrides->resize(num_of_copies, -1);

View File

@ -31,7 +31,7 @@ public:
typedef boost::container::small_vector<int32_t, 3> ExtruderPerCopy; typedef boost::container::small_vector<int32_t, 3> ExtruderPerCopy;
// This is called from GCode::process_layer - see implementation for further comments: // 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_extruder_overrides(const PrintObject* object);
int get_support_interface_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; 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) // 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 // BBS
void set_support_extruder_override(const PrintObject* object, size_t copy_id, int extruder, size_t num_of_copies); 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); 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: // 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 { bool is_entity_overridden(const ExtrusionEntity* entity, const PrintObject *object, size_t copy_id) const {
auto it = entity_map.find(entity); auto it = entity_map.find(std::make_tuple(entity, object));
return it == entity_map.end() ? false : it->second[copy_id] != -1; return it == entity_map.end() ? false : it->second[copy_id] != -1;
} }
std::map<const ExtrusionEntity*, ExtruderPerCopy> entity_map; // to keep track of who prints what std::map<std::tuple<const ExtrusionEntity*, const PrintObject *>, ExtruderPerCopy> entity_map; // to keep track of who prints what
// BBS // BBS
std::map<const PrintObject*, int> support_map; std::map<const PrintObject*, int> support_map;
std::map<const PrintObject*, int> support_intf_map; std::map<const PrintObject*, int> support_intf_map;