#718 fix 9f7f5588 : put ironing post-process EE in their own list, so they are correctly processed

This commit is contained in:
supermerill 2020-11-28 19:48:18 +01:00
parent 8d5688a751
commit 4848fad311
4 changed files with 99 additions and 88 deletions

View File

@ -555,7 +555,6 @@ void Layer::make_ironing()
// speed: 20 mm/sec
};
std::unordered_map<ExtrusionEntityCollection*, ExtrusionEntityCollection*> fill_2_ironing_coll;
std::vector<IroningParams> by_extruder;
bool extruder_dont_care = this->object()->config().wipe_into_objects;
double default_layer_height = this->object()->config().layer_height;
@ -638,33 +637,9 @@ void Layer::make_ironing()
} catch (InfillFailedException &) {
}
if (! polylines.empty()) {
//always extrude ironing after infill
ExtrusionEntityCollection* eec_ironing;
if (fill_2_ironing_coll.find(&ironing_params.layerm->fills) == fill_2_ironing_coll.end()) {
if (ironing_params.layerm->fills.empty()) {
eec_ironing = &ironing_params.layerm->fills;
fill_2_ironing_coll[&ironing_params.layerm->fills] = eec_ironing;
} else {
//create the "normal fill" collection
ExtrusionEntityCollection* eec_before_layer_ironing = new ExtrusionEntityCollection(ironing_params.layerm->fills);
eec_before_layer_ironing->no_sort = ironing_params.layerm->fills.no_sort;
//create the "ironing fill" collection
eec_ironing = new ExtrusionEntityCollection();
eec_ironing->no_sort = false;
fill_2_ironing_coll[&ironing_params.layerm->fills] = eec_ironing;
//add them as fills in the right order (and we need an other ExtrusionEntityCollection, as the no_sort of fills isn't read anywhere)
ExtrusionEntityCollection* eec_root = new ExtrusionEntityCollection();
ironing_params.layerm->fills.clear();
ironing_params.layerm->fills.entities.push_back(eec_root);
eec_root->entities.push_back(eec_before_layer_ironing);
eec_root->entities.push_back(eec_ironing);
eec_root->no_sort = true;
}
} else
eec_ironing = fill_2_ironing_coll[&ironing_params.layerm->fills];
// Save into layer.
ExtrusionEntityCollection *eec = new ExtrusionEntityCollection();
eec_ironing->entities.push_back(eec);
ironing_params.layerm->ironings.entities.push_back(eec);
// Don't sort the ironing infill lines as they are monotonicly ordered.
eec->no_sort = true;
extrusion_entities_append_paths(

View File

@ -2290,8 +2290,8 @@ void GCode::process_layer(
// It is also necessary to save which extrusions are part of MM wiping and which are not.
// The process is almost the same for perimeters and infills - we will do it in a cycle that repeats twice:
std::vector<unsigned int> printing_extruders;
for (const ObjectByExtruder::Island::Region::Type entity_type : { ObjectByExtruder::Island::Region::INFILL, ObjectByExtruder::Island::Region::PERIMETERS }) {
for (const ExtrusionEntity *ee : (entity_type == ObjectByExtruder::Island::Region::INFILL) ? layerm->fills.entities : layerm->perimeters.entities) {
auto process_entities = [&](ObjectByExtruder::Island::Region::Type entity_type, const ExtrusionEntitiesPtr& entities) {
for (const ExtrusionEntity* ee : entities) {
// extrusions represents infill or perimeter extrusions of a single island.
assert(dynamic_cast<const ExtrusionEntityCollection*>(ee) != nullptr);
const auto* extrusions = static_cast<const ExtrusionEntityCollection*>(ee);
@ -2349,7 +2349,10 @@ void GCode::process_layer(
}
}
}
}
};
process_entities(ObjectByExtruder::Island::Region::INFILL, layerm->fills.entities);
process_entities(ObjectByExtruder::Island::Region::PERIMETERS, layerm->perimeters.entities);
process_entities(ObjectByExtruder::Island::Region::IRONING, layerm->ironings.entities);
} // for regions
}
} // for objects
@ -2489,6 +2492,7 @@ void GCode::process_layer(
gcode += this->extrude_infill(print, by_region_specific, true);
gcode += this->extrude_perimeters(print, by_region_specific, lower_layer_edge_grids[instance_to_print.layer_id]);
gcode += this->extrude_infill(print, by_region_specific, false);
gcode += this->extrude_ironing(print, by_region_specific);
}
if (this->config().gcode_label_objects)
gcode += std::string("; stop printing object ") + instance_to_print.print_object.model_object()->name
@ -3358,6 +3362,30 @@ std::string GCode::extrude_infill(const Print &print, const std::vector<ObjectBy
return gcode;
}
// Chain the paths hierarchically by a greedy algorithm to minimize a travel distance.
std::string GCode::extrude_ironing(const Print& print, const std::vector<ObjectByExtruder::Island::Region>& by_region)
{
std::string gcode;
for (const ObjectByExtruder::Island::Region& region : by_region) {
if (!region.ironings.empty()) {
m_config.apply(print.regions()[&region - &by_region.front()]->config());
m_writer.apply_print_region_config(print.regions()[&region - &by_region.front()]->config());
if (m_config.print_temperature > 0)
gcode += m_writer.set_temperature(m_config.print_temperature.value, false, m_writer.tool()->id());
else if (m_layer != nullptr && m_layer->bottom_z() < EPSILON)
gcode += m_writer.set_temperature(m_config.first_layer_temperature.get_at(m_writer.tool()->id()), false, m_writer.tool()->id());
else
gcode += m_writer.set_temperature(m_config.temperature.get_at(m_writer.tool()->id()), false, m_writer.tool()->id());
ExtrusionEntitiesPtr extrusions{ region.ironings };
chain_and_reorder_extrusion_entities(extrusions, &m_last_pos);
for (const ExtrusionEntity* fill : extrusions) {
gcode += extrude_entity(*fill, "");
}
}
}
return gcode;
}
std::string GCode::extrude_support(const ExtrusionEntityCollection &support_fills)
{
std::string gcode;
@ -4034,7 +4062,7 @@ const std::vector<GCode::ObjectByExtruder::Island::Region>& GCode::ObjectByExtru
{
bool has_overrides = false;
for (const auto& reg : by_region)
if (! reg.infills_overrides.empty() || ! reg.perimeters_overrides.empty()) {
if (! reg.infills_overrides.empty() || !reg.perimeters_overrides.empty() || !reg.ironings_overrides.empty()) {
has_overrides = true;
break;
}
@ -4050,16 +4078,11 @@ const std::vector<GCode::ObjectByExtruder::Island::Region>& GCode::ObjectByExtru
// Some of the extrusions of some object instances are printed later - those are the clean print extrusions.
// Filter out the extrusions based on the infill_overrides / perimeter_overrides:
for (const auto& reg : by_region) {
for (const Island::Region& reg : by_region) {
by_region_per_copy_cache.emplace_back(); // creates a region in the newly created Island
// Now we are going to iterate through perimeters and infills and pick ones that are supposed to be printed
// References are used so that we don't have to repeat the same code
for (int iter = 0; iter < 2; ++iter) {
const ExtrusionEntitiesPtr& entities = (iter ? reg.infills : reg.perimeters);
ExtrusionEntitiesPtr& target_eec = (iter ? by_region_per_copy_cache.back().infills : by_region_per_copy_cache.back().perimeters);
const std::vector<const WipingExtrusions::ExtruderPerCopy*>& overrides = (iter ? reg.infills_overrides : reg.perimeters_overrides);
auto select_print = [&wiping_entities, &copy, &extruder](const ExtrusionEntitiesPtr& entities, ExtrusionEntitiesPtr& target_eec, const std::vector<const WipingExtrusions::ExtruderPerCopy*>& overrides) {
// Now the most important thing - which extrusion should we print.
// See function ToolOrdering::get_extruder_overrides for details about the negative numbers hack.
if (wiping_entities) {
@ -4082,7 +4105,10 @@ const std::vector<GCode::ObjectByExtruder::Island::Region>& GCode::ObjectByExtru
for (; i < entities.size(); ++i)
target_eec.emplace_back(entities[i]);
}
}
};
select_print(reg.perimeters, by_region_per_copy_cache.back().perimeters, reg.perimeters_overrides);
select_print(reg.infills, by_region_per_copy_cache.back().infills, reg.infills_overrides);
select_print(reg.ironings, by_region_per_copy_cache.back().ironings, reg.ironings_overrides);
}
return by_region_per_copy_cache;
}
@ -4104,6 +4130,10 @@ void GCode::ObjectByExtruder::Island::Region::append(const Type type, const Extr
perimeters_or_infills = &infills;
perimeters_or_infills_overrides = &infills_overrides;
break;
case IRONING:
perimeters_or_infills = &ironings;
perimeters_or_infills_overrides = &ironings_overrides;
break;
default:
throw Slic3r::InvalidArgument("Unknown parameter!");
}

View File

@ -282,13 +282,17 @@ private:
ExtrusionEntitiesPtr perimeters;
// Non-owned references to LayerRegion::fills::entities
ExtrusionEntitiesPtr infills;
// Non-owned references to LayerRegion::ironing::entities
ExtrusionEntitiesPtr ironings;
std::vector<const WipingExtrusions::ExtruderPerCopy*> infills_overrides;
std::vector<const WipingExtrusions::ExtruderPerCopy*> perimeters_overrides;
std::vector<const WipingExtrusions::ExtruderPerCopy*> ironings_overrides;
enum Type {
PERIMETERS,
INFILL,
IRONING,
};
// Appends perimeter/infill entities and writes don't indices of those that are not to be extruder as part of perimeter/infill wiping
@ -329,6 +333,7 @@ private:
std::string extrude_perimeters(const Print &print, const std::vector<ObjectByExtruder::Island::Region> &by_region, std::unique_ptr<EdgeGrid::Grid> &lower_layer_edge_grid);
std::string extrude_infill(const Print& print, const std::vector<ObjectByExtruder::Island::Region>& by_region, bool is_infill_first);
std::string extrude_ironing(const Print& print, const std::vector<ObjectByExtruder::Island::Region>& by_region);
std::string extrude_support(const ExtrusionEntityCollection &support_fills);
std::string travel_to(const Point &point, ExtrusionRole role, std::string comment);

View File

@ -60,6 +60,7 @@ public:
// ordered collection of extrusion paths to fill surfaces
// (this collection contains only ExtrusionEntityCollection objects)
ExtrusionEntityCollection fills;
ExtrusionEntityCollection ironings;
Flow flow(FlowRole role, bool bridge = false, double width = -1) const;
void slices_to_fill_surfaces_clipped();
@ -81,7 +82,7 @@ public:
void export_region_fill_surfaces_to_svg_debug(const char *name) const;
// Is there any valid extrusion assigned to this LayerRegion?
bool has_extrusions() const { return ! this->perimeters.entities.empty() || ! this->fills.entities.empty(); }
bool has_extrusions() const { return !this->perimeters.entities.empty() || !this->fills.entities.empty() || !this->ironings.entities.empty(); }
protected:
friend class Layer;