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:
parent
98fea2f6ee
commit
a067da6d53
@ -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);
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
|
@ -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"
|
||||||
|
@ -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:
|
||||||
|
@ -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))
|
||||||
|
@ -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"));
|
||||||
|
Loading…
Reference in New Issue
Block a user