Skip to content

Commit

Permalink
FIX: fix an flush_into_object bug for copied objects
Browse files Browse the repository at this point in the history
Copied objects share extrusion paths but they should be treated
seperately.
Thanks hisptoot for the fix.

Signed-off-by: yifan.wu <[email protected]>
Change-Id: I24d3050df7d284e92fc50a0213023a43ee8c529c
  • Loading branch information
YifanWuBambu authored and lanewei120 committed Oct 20, 2022
1 parent 65f5788 commit 76b40c9
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 18 deletions.
2 changes: 1 addition & 1 deletion src/libslic3r/GCode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2791,7 +2791,7 @@ GCode::LayerResult GCode::process_layer(
}
printing_extruders.clear();
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) {
printing_extruders.emplace_back(correct_extruder_id);
} else {
Expand Down
24 changes: 12 additions & 12 deletions src/libslic3r/GCode/ToolOrdering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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;
Expand All @@ -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<const ExtrusionEntityCollection*>(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;
Expand Down Expand Up @@ -1125,7 +1125,7 @@ void WipingExtrusions::ensure_perimeters_infills_order(const Print& print)
auto* fill = dynamic_cast<const ExtrusionEntityCollection*>(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
Expand All @@ -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.
Expand All @@ -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<const ExtrusionEntityCollection*>(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);
}
}
}
Expand All @@ -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);
Expand Down
10 changes: 5 additions & 5 deletions src/libslic3r/GCode/ToolOrdering.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class WipingExtrusions
typedef boost::container::small_vector<int32_t, 3> 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);

Expand Down Expand Up @@ -71,18 +71,18 @@ class WipingExtrusions
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<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
std::map<const PrintObject*, int> support_map;
std::map<const PrintObject*, int> support_intf_map;
Expand Down

0 comments on commit 76b40c9

Please sign in to comment.