Ooze prevention:

- remove the infinite skirt
- added 'idle_temperature' in Filament Settings as an optional parameter
- the logic is changed: if idle_temp is present, it is used,
  otherwise it uses the old delta value from Print Settings
- TODO: the optional parameter is not well supported in UI
This commit is contained in:
Lukas Matena 2023-01-10 14:26:53 +01:00
parent 98fea2f6ee
commit a067da6d53
7 changed files with 54 additions and 64 deletions

View File

@ -113,26 +113,19 @@ namespace Slic3r {
{ {
std::string gcode; std::string gcode;
// move to the nearest standby point unsigned int extruder_id = gcodegen.writer().extruder()->id();
if (!this->standby_points.empty()) { const ConfigOptionIntsNullable& filament_idle_temp = gcodegen.config().idle_temperature;
// get current position in print coordinates if (filament_idle_temp.is_nil(extruder_id)) {
Vec3d writer_pos = gcodegen.writer().get_position(); // There is no idle temperature defined in filament settings.
Point pos = Point::new_scale(writer_pos(0), writer_pos(1)); // Use the delta value from print config.
// find standby point
Point standby_point = nearest_point(this->standby_points, pos).first;
/* We don't call gcodegen.travel_to() because we don't need retraction (it was already
triggered by the caller) nor avoid_crossing_perimeters and also because the coordinates
of the destination point must not be transformed by origin nor current extruder offset. */
gcode += gcodegen.writer().travel_to_xy(unscale(standby_point),
"move to standby position");
}
if (gcodegen.config().standby_temperature_delta.value != 0) { if (gcodegen.config().standby_temperature_delta.value != 0) {
// we assume that heating is always slower than cooling, so no need to block // we assume that heating is always slower than cooling, so no need to block
gcode += gcodegen.writer().set_temperature gcode += gcodegen.writer().set_temperature
(this->_get_temp(gcodegen) + gcodegen.config().standby_temperature_delta.value, false, gcodegen.writer().extruder()->id()); (this->_get_temp(gcodegen) + gcodegen.config().standby_temperature_delta.value, false, extruder_id);
}
} else {
// Use the value from filament settings. That one is absolute, not delta.
gcode += gcodegen.writer().set_temperature(filament_idle_temp.get_at(extruder_id), false, extruder_id);
} }
return gcode; return gcode;
@ -145,8 +138,7 @@ namespace Slic3r {
std::string(); std::string();
} }
int int OozePrevention::_get_temp(const GCode& gcodegen) const
OozePrevention::_get_temp(GCode& gcodegen)
{ {
return (gcodegen.layer() != nullptr && gcodegen.layer()->id() == 0) return (gcodegen.layer() != nullptr && gcodegen.layer()->id() == 0)
? gcodegen.config().first_layer_temperature.get_at(gcodegen.writer().extruder()->id()) ? gcodegen.config().first_layer_temperature.get_at(gcodegen.writer().extruder()->id())
@ -885,34 +877,7 @@ namespace DoExport {
static void init_ooze_prevention(const Print &print, OozePrevention &ooze_prevention) static void init_ooze_prevention(const Print &print, OozePrevention &ooze_prevention)
{ {
// Calculate wiping points if needed ooze_prevention.enable = print.config().ooze_prevention.value && ! print.config().single_extruder_multi_material;
if (print.config().ooze_prevention.value && ! print.config().single_extruder_multi_material) {
Points skirt_points;
for (const ExtrusionEntity *ee : print.skirt().entities)
for (const ExtrusionPath &path : dynamic_cast<const ExtrusionLoop*>(ee)->paths)
append(skirt_points, path.polyline.points);
if (! skirt_points.empty()) {
Polygon outer_skirt = Slic3r::Geometry::convex_hull(skirt_points);
Polygons skirts;
for (unsigned int extruder_id : print.extruders()) {
const Vec2d &extruder_offset = print.config().extruder_offset.get_at(extruder_id);
Polygon s(outer_skirt);
s.translate(Point::new_scale(-extruder_offset(0), -extruder_offset(1)));
skirts.emplace_back(std::move(s));
}
ooze_prevention.enable = true;
//ooze_prevention.standby_points = offset(Slic3r::Geometry::convex_hull(skirts), float(scale_(3.))).front().equally_spaced_points(float(scale_(10.)));
#if 0
require "Slic3r/SVG.pm";
Slic3r::SVG::output(
"ooze_prevention.svg",
red_polygons => \@skirts,
polygons => [$outer_skirt],
points => $gcodegen->ooze_prevention->standby_points,
);
#endif
}
}
} }
// Fill in print_statistics and return formatted string containing filament statistics to be inserted into G-code comment section. // Fill in print_statistics and return formatted string containing filament statistics to be inserted into G-code comment section.
@ -1274,8 +1239,9 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
// Set other general things. // Set other general things.
file.write(this->preamble()); file.write(this->preamble());
// Calculate wiping points if needed // Enable ooze prevention if configured so.
DoExport::init_ooze_prevention(print, m_ooze_prevention); DoExport::init_ooze_prevention(print, m_ooze_prevention);
print.throw_if_canceled(); print.throw_if_canceled();
// Collect custom seam data from all objects. // Collect custom seam data from all objects.
@ -1806,7 +1772,7 @@ void GCode::_print_first_layer_extruder_temperatures(GCodeOutputStream &file, Pr
m_writer.set_temperature(temp, wait, first_printing_extruder_id); m_writer.set_temperature(temp, wait, first_printing_extruder_id);
} else { } else {
// Custom G-code does not set the extruder temperature. Do it now. // Custom G-code does not set the extruder temperature. Do it now.
if (print.config().single_extruder_multi_material.value) { if (print.config().single_extruder_multi_material.value || m_ooze_prevention.enable) {
// Set temperature of the first printing extruder only. // Set temperature of the first printing extruder only.
int temp = print.config().first_layer_temperature.get_at(first_printing_extruder_id); int temp = print.config().first_layer_temperature.get_at(first_printing_extruder_id);
if (temp > 0) if (temp > 0)
@ -2128,11 +2094,14 @@ LayerResult GCode::process_layer(
// Transition from 1st to 2nd layer. Adjust nozzle temperatures as prescribed by the nozzle dependent // Transition from 1st to 2nd layer. Adjust nozzle temperatures as prescribed by the nozzle dependent
// first_layer_temperature vs. temperature settings. // first_layer_temperature vs. temperature settings.
for (const Extruder &extruder : m_writer.extruders()) { for (const Extruder &extruder : m_writer.extruders()) {
if (print.config().single_extruder_multi_material.value && extruder.id() != m_writer.extruder()->id()) if (print.config().single_extruder_multi_material.value || m_ooze_prevention.enable) {
// In single extruder multi material mode, set the temperature for the current extruder only. // In single extruder multi material mode, set the temperature for the current extruder only.
// The same applies when ooze prevention is enabled.
if (extruder.id() != m_writer.extruder()->id())
continue; continue;
}
int temperature = print.config().temperature.get_at(extruder.id()); int temperature = print.config().temperature.get_at(extruder.id());
if (temperature > 0 && temperature != print.config().first_layer_temperature.get_at(extruder.id())) if (temperature > 0 && (temperature != print.config().first_layer_temperature.get_at(extruder.id())))
gcode += m_writer.set_temperature(temperature, false, extruder.id()); gcode += m_writer.set_temperature(temperature, false, extruder.id());
} }
gcode += m_writer.set_bed_temperature(print.config().bed_temperature.get_at(first_extruder_id)); gcode += m_writer.set_bed_temperature(print.config().bed_temperature.get_at(first_extruder_id));
@ -3206,8 +3175,7 @@ std::string GCode::set_extruder(unsigned int extruder_id, double print_z)
} }
// If ooze prevention is enabled, park current extruder in the nearest // If ooze prevention is enabled, set current extruder to the standby temperature.
// standby point and set it to the standby temperature.
if (m_ooze_prevention.enable && m_writer.extruder() != nullptr) if (m_ooze_prevention.enable && m_writer.extruder() != nullptr)
gcode += m_ooze_prevention.pre_toolchange(*this); gcode += m_ooze_prevention.pre_toolchange(*this);

View File

@ -39,14 +39,13 @@ struct PrintInstance;
class OozePrevention { class OozePrevention {
public: public:
bool enable; bool enable;
Points standby_points;
OozePrevention() : enable(false) {} OozePrevention() : enable(false) {}
std::string pre_toolchange(GCode &gcodegen); std::string pre_toolchange(GCode &gcodegen);
std::string post_toolchange(GCode &gcodegen); std::string post_toolchange(GCode &gcodegen);
private: private:
int _get_temp(GCode &gcodegen); int _get_temp(const GCode &gcodegen) const;
}; };
class Wipe { class Wipe {

View File

@ -470,7 +470,7 @@ static std::vector<std::string> s_Preset_filament_options {
"extrusion_multiplier", "filament_density", "filament_cost", "filament_spool_weight", "filament_loading_speed", "filament_loading_speed_start", "filament_load_time", "extrusion_multiplier", "filament_density", "filament_cost", "filament_spool_weight", "filament_loading_speed", "filament_loading_speed_start", "filament_load_time",
"filament_unloading_speed", "filament_unloading_speed_start", "filament_unload_time", "filament_toolchange_delay", "filament_cooling_moves", "filament_unloading_speed", "filament_unloading_speed_start", "filament_unload_time", "filament_toolchange_delay", "filament_cooling_moves",
"filament_cooling_initial_speed", "filament_cooling_final_speed", "filament_ramming_parameters", "filament_minimal_purge_on_wipe_tower", "filament_cooling_initial_speed", "filament_cooling_final_speed", "filament_ramming_parameters", "filament_minimal_purge_on_wipe_tower",
"temperature", "first_layer_temperature", "bed_temperature", "first_layer_bed_temperature", "fan_always_on", "cooling", "min_fan_speed", "temperature", "idle_temperature", "first_layer_temperature", "bed_temperature", "first_layer_bed_temperature", "fan_always_on", "cooling", "min_fan_speed",
"max_fan_speed", "bridge_fan_speed", "disable_fan_first_layers", "full_fan_speed_layer", "fan_below_layer_time", "slowdown_below_layer_time", "min_print_speed", "max_fan_speed", "bridge_fan_speed", "disable_fan_first_layers", "full_fan_speed_layer", "fan_below_layer_time", "slowdown_below_layer_time", "min_print_speed",
"start_filament_gcode", "end_filament_gcode", "start_filament_gcode", "end_filament_gcode",
// Retract overrides // Retract overrides

View File

@ -191,6 +191,7 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
|| opt_key == "infill_first" || opt_key == "infill_first"
|| opt_key == "single_extruder_multi_material" || opt_key == "single_extruder_multi_material"
|| opt_key == "temperature" || opt_key == "temperature"
|| opt_key == "idle_temperature"
|| opt_key == "wipe_tower" || opt_key == "wipe_tower"
|| opt_key == "wipe_tower_width" || opt_key == "wipe_tower_width"
|| opt_key == "wipe_tower_brim_width" || opt_key == "wipe_tower_brim_width"

View File

@ -229,6 +229,11 @@ static void assign_printer_technology_to_unknown(t_optiondef_map &options, Print
kvp.second.printer_technology = printer_technology; kvp.second.printer_technology = printer_technology;
} }
// Maximum extruder temperature, bumped to 1500 to support printing of glass.
namespace {
const int max_temp = 1500;
};
PrintConfigDef::PrintConfigDef() PrintConfigDef::PrintConfigDef()
{ {
this->init_common_params(); this->init_common_params();
@ -1972,9 +1977,7 @@ void PrintConfigDef::init_fff_params()
def = this->add("ooze_prevention", coBool); def = this->add("ooze_prevention", coBool);
def->label = L("Enable"); def->label = L("Enable");
def->tooltip = L("This option will drop the temperature of the inactive extruders to prevent oozing. " def->tooltip = L("This option will drop the temperature of the inactive extruders to prevent oozing. ");
"It will enable a tall skirt automatically and move extruders outside such "
"skirt when changing temperatures.");
def->mode = comExpert; def->mode = comExpert;
def->set_default_value(new ConfigOptionBool(false)); def->set_default_value(new ConfigOptionBool(false));
@ -2475,7 +2478,8 @@ void PrintConfigDef::init_fff_params()
def = this->add("standby_temperature_delta", coInt); def = this->add("standby_temperature_delta", coInt);
def->label = L("Temperature variation"); def->label = L("Temperature variation");
def->tooltip = L("Temperature difference to be applied when an extruder is not active. " def->tooltip = L("Temperature difference to be applied when an extruder is not active. "
"Enables a full-height \"sacrificial\" skirt on which the nozzles are periodically wiped."); "The value is not used when 'idle_temperature' in filament settings "
"is defined.");
def->sidetext = "∆°C"; def->sidetext = "∆°C";
def->min = -max_temp; def->min = -max_temp;
def->max = max_temp; def->max = max_temp;
@ -3731,6 +3735,15 @@ void PrintConfigDef::init_sla_params()
def->min = 0; def->min = 0;
def->set_default_value(new ConfigOptionFloat(0.3)); def->set_default_value(new ConfigOptionFloat(0.3));
def = this->add_nullable("idle_temperature", coInts);
def->label = L("Idle temperature");
def->tooltip = L("Nozzle temperature when the tool is currently not used in multi-tool setups."
"This is only used when 'Ooze prevention is active in Print Settings.'");
def->sidetext = L("°C");
//def->min = 0;
//def->max = max_temp;
def->set_default_value(new ConfigOptionIntsNullable { ConfigOptionIntsNullable::nil_value() });
def = this->add("bottle_volume", coFloat); def = this->add("bottle_volume", coFloat);
def->label = L("Bottle volume"); def->label = L("Bottle volume");
def->tooltip = L("Bottle volume"); def->tooltip = L("Bottle volume");
@ -4511,6 +4524,12 @@ std::string validate(const FullPrintConfig &cfg)
assert(opt != nullptr); assert(opt != nullptr);
const ConfigOptionDef *optdef = print_config_def.get(opt_key); const ConfigOptionDef *optdef = print_config_def.get(opt_key);
assert(optdef != nullptr); assert(optdef != nullptr);
if (opt->nullable() && opt->is_nil()) {
// Do not check nil values
continue;
}
bool out_of_range = false; bool out_of_range = false;
switch (opt->type()) { switch (opt->type()) {
case coFloat: case coFloat:

View File

@ -769,6 +769,7 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
((ConfigOptionFloatOrPercent, first_layer_height)) ((ConfigOptionFloatOrPercent, first_layer_height))
((ConfigOptionFloatOrPercent, first_layer_speed)) ((ConfigOptionFloatOrPercent, first_layer_speed))
((ConfigOptionInts, first_layer_temperature)) ((ConfigOptionInts, first_layer_temperature))
((ConfigOptionIntsNullable, idle_temperature))
((ConfigOptionInts, full_fan_speed_layer)) ((ConfigOptionInts, full_fan_speed_layer))
((ConfigOptionFloat, infill_acceleration)) ((ConfigOptionFloat, infill_acceleration))
((ConfigOptionBool, infill_first)) ((ConfigOptionBool, infill_first))

View File

@ -1957,6 +1957,8 @@ void TabFilament::build()
line.append_option(optgroup->get_option("temperature")); line.append_option(optgroup->get_option("temperature"));
optgroup->append_line(line); optgroup->append_line(line);
optgroup->append_single_option_line("idle_temperature");
line = { L("Bed"), "" }; line = { L("Bed"), "" };
line.append_option(optgroup->get_option("first_layer_bed_temperature")); line.append_option(optgroup->get_option("first_layer_bed_temperature"));
line.append_option(optgroup->get_option("bed_temperature")); line.append_option(optgroup->get_option("bed_temperature"));