mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-08-15 06:35:56 +08:00
parent
d8f5882872
commit
d0459d60ce
@ -29,7 +29,9 @@ group:Retraction
|
|||||||
setting:idx:retract_restart_extra
|
setting:idx:retract_restart_extra
|
||||||
setting:idx:retract_before_travel
|
setting:idx:retract_before_travel
|
||||||
setting:idx:retract_layer_change
|
setting:idx:retract_layer_change
|
||||||
|
group:Retraction wipe
|
||||||
setting:idx:wipe
|
setting:idx:wipe
|
||||||
|
setting:idx:wipe_speed
|
||||||
setting:idx:retract_before_wipe
|
setting:idx:retract_before_wipe
|
||||||
setting:idx:wipe_extra_perimeter
|
setting:idx:wipe_extra_perimeter
|
||||||
group:Retraction when tool is disabled (advanced settings for multi-extruder setups)
|
group:Retraction when tool is disabled (advanced settings for multi-extruder setups)
|
||||||
|
@ -158,6 +158,8 @@ std::string Wipe::wipe(GCode& gcodegen, bool toolchange)
|
|||||||
/* Reduce feedrate a bit; travel speed is often too high to move on existing material.
|
/* Reduce feedrate a bit; travel speed is often too high to move on existing material.
|
||||||
Too fast = ripping of existing material; too slow = short wipe path, thus more blob. */
|
Too fast = ripping of existing material; too slow = short wipe path, thus more blob. */
|
||||||
double wipe_speed = gcodegen.writer().config.travel_speed.value * 0.8;
|
double wipe_speed = gcodegen.writer().config.travel_speed.value * 0.8;
|
||||||
|
if(gcodegen.writer().tool_is_extruder() && gcodegen.writer().config.wipe_speed.get_at(gcodegen.writer().tool()->id()) > 0)
|
||||||
|
wipe_speed = gcodegen.writer().config.wipe_speed.get_at(gcodegen.writer().tool()->id());
|
||||||
|
|
||||||
// get the retraction length
|
// get the retraction length
|
||||||
double length = gcodegen.writer().tool()->retract_length();
|
double length = gcodegen.writer().tool()->retract_length();
|
||||||
@ -190,7 +192,7 @@ std::string Wipe::wipe(GCode& gcodegen, bool toolchange)
|
|||||||
if (!wipe_path.empty()) {
|
if (!wipe_path.empty()) {
|
||||||
// add tag for processor
|
// add tag for processor
|
||||||
gcode += ";" + GCodeProcessor::Wipe_Start_Tag + "\n";
|
gcode += ";" + GCodeProcessor::Wipe_Start_Tag + "\n";
|
||||||
for (const Line& line : wipe_path.lines()) {
|
for (const Line& line : wipe_path.lines()) {
|
||||||
double segment_length = line.length();
|
double segment_length = line.length();
|
||||||
/* Reduce retraction length a bit to avoid effective retraction speed to be greater than the configured one
|
/* Reduce retraction length a bit to avoid effective retraction speed to be greater than the configured one
|
||||||
due to rounding (TODO: test and/or better math for this) */
|
due to rounding (TODO: test and/or better math for this) */
|
||||||
@ -235,13 +237,13 @@ static inline void set_extra_lift(const Layer& layer, const Print& print, GCodeW
|
|||||||
|
|
||||||
std::string WipeTowerIntegration::append_tcr(GCode& gcodegen, const WipeTower::ToolChangeResult& tcr, int new_extruder_id, double z) const
|
std::string WipeTowerIntegration::append_tcr(GCode& gcodegen, const WipeTower::ToolChangeResult& tcr, int new_extruder_id, double z) const
|
||||||
{
|
{
|
||||||
if (new_extruder_id != -1 && new_extruder_id != tcr.new_tool)
|
if (new_extruder_id != -1 && new_extruder_id != tcr.new_tool)
|
||||||
throw Slic3r::InvalidArgument("Error: WipeTowerIntegration::append_tcr was asked to do a toolchange it didn't expect.");
|
throw Slic3r::InvalidArgument("Error: WipeTowerIntegration::append_tcr was asked to do a toolchange it didn't expect.");
|
||||||
|
|
||||||
std::string gcode;
|
std::string gcode;
|
||||||
|
|
||||||
// Toolchangeresult.gcode assumes the wipe tower corner is at the origin (except for priming lines)
|
// Toolchangeresult.gcode assumes the wipe tower corner is at the origin (except for priming lines)
|
||||||
// We want to rotate and shift all extrusions (gcode postprocessing) and starting and ending position
|
// We want to rotate and shift all extrusions (gcode postprocessing) and starting and ending position
|
||||||
float alpha = m_wipe_tower_rotation / 180.f * float(M_PI);
|
float alpha = m_wipe_tower_rotation / 180.f * float(M_PI);
|
||||||
|
|
||||||
auto transform_wt_pt = [&alpha, this](const Vec2f& pt) -> Vec2f {
|
auto transform_wt_pt = [&alpha, this](const Vec2f& pt) -> Vec2f {
|
||||||
@ -250,112 +252,112 @@ static inline void set_extra_lift(const Layer& layer, const Print& print, GCodeW
|
|||||||
return out;
|
return out;
|
||||||
};
|
};
|
||||||
|
|
||||||
Vec2f start_pos = tcr.start_pos;
|
Vec2f start_pos = tcr.start_pos;
|
||||||
Vec2f end_pos = tcr.end_pos;
|
Vec2f end_pos = tcr.end_pos;
|
||||||
if (! tcr.priming) {
|
if (! tcr.priming) {
|
||||||
start_pos = transform_wt_pt(start_pos);
|
start_pos = transform_wt_pt(start_pos);
|
||||||
end_pos = transform_wt_pt(end_pos);
|
end_pos = transform_wt_pt(end_pos);
|
||||||
}
|
|
||||||
|
|
||||||
Vec2f wipe_tower_offset = tcr.priming ? Vec2f::Zero() : m_wipe_tower_pos;
|
|
||||||
float wipe_tower_rotation = tcr.priming ? 0.f : alpha;
|
|
||||||
|
|
||||||
std::string tcr_rotated_gcode = post_process_wipe_tower_moves(tcr, wipe_tower_offset, wipe_tower_rotation);
|
|
||||||
|
|
||||||
//if needed, write the gcode_label_objects_end then priming tower
|
|
||||||
if (!gcodegen.m_gcode_label_objects_end.empty()) {
|
|
||||||
gcode += gcodegen.m_gcode_label_objects_end;
|
|
||||||
gcodegen.m_gcode_label_objects_end = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! tcr.priming) {
|
|
||||||
// Move over the wipe tower.
|
|
||||||
// Retract for a tool change, using the toolchange retract value and setting the priming extra length.
|
|
||||||
gcode += gcodegen.retract(true);
|
|
||||||
gcodegen.m_avoid_crossing_perimeters.use_external_mp_once();
|
|
||||||
Polyline polyline = gcodegen.travel_to(
|
|
||||||
gcode,
|
|
||||||
wipe_tower_point_to_object_point(gcodegen, start_pos),
|
|
||||||
erMixed);
|
|
||||||
gcodegen.write_travel_to(gcode, polyline, "Travel to a Wipe Tower");
|
|
||||||
gcode += gcodegen.unretract();
|
|
||||||
}
|
|
||||||
|
|
||||||
double current_z = gcodegen.writer().get_position().z();
|
|
||||||
if (z == -1.) // in case no specific z was provided, print at current_z pos
|
|
||||||
z = current_z;
|
|
||||||
if (! is_approx(z, current_z)) {
|
|
||||||
gcode += gcodegen.writer().retract();
|
|
||||||
gcode += gcodegen.writer().travel_to_z(z, "Travel down to the last wipe tower layer.");
|
|
||||||
gcode += gcodegen.writer().unretract();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Process the end filament gcode.
|
|
||||||
std::string end_filament_gcode_str;
|
|
||||||
if (gcodegen.writer().tool() != nullptr && gcodegen.writer().tool_is_extruder()) {
|
|
||||||
// Process the custom end_filament_gcode in case of single_extruder_multi_material.
|
|
||||||
uint16_t old_extruder_id = gcodegen.writer().tool()->id();
|
|
||||||
const std::string& end_filament_gcode = gcodegen.config().end_filament_gcode.get_at(old_extruder_id);
|
|
||||||
if (gcodegen.writer().tool() != nullptr && ! end_filament_gcode.empty()) {
|
|
||||||
DynamicConfig config;
|
|
||||||
int previous_extruder_id = gcodegen.writer().tool() ? (int)gcodegen.writer().tool()->id() : -1;
|
|
||||||
config.set_key_value("previous_extruder", new ConfigOptionInt(previous_extruder_id));
|
|
||||||
config.set_key_value("next_extruder", new ConfigOptionInt((int)new_extruder_id));
|
|
||||||
config.set_key_value("layer_num", new ConfigOptionInt(gcodegen.m_layer_index));
|
|
||||||
config.set_key_value("layer_z", new ConfigOptionFloat(tcr.print_z));
|
|
||||||
end_filament_gcode_str = gcodegen.placeholder_parser_process("end_filament_gcode", end_filament_gcode, old_extruder_id, &config);
|
|
||||||
check_add_eol(end_filament_gcode_str);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Process the custom toolchange_gcode. If it is empty, provide a simple Tn command to change the filament.
|
Vec2f wipe_tower_offset = tcr.priming ? Vec2f::Zero() : m_wipe_tower_pos;
|
||||||
// Otherwise, leave control to the user completely.
|
float wipe_tower_rotation = tcr.priming ? 0.f : alpha;
|
||||||
std::string toolchange_gcode_str;
|
|
||||||
|
|
||||||
if (tcr.priming || (new_extruder_id >= 0 && gcodegen.writer().need_toolchange(new_extruder_id)))
|
std::string tcr_rotated_gcode = post_process_wipe_tower_moves(tcr, wipe_tower_offset, wipe_tower_rotation);
|
||||||
toolchange_gcode_str += gcodegen.toolchange(new_extruder_id, tcr.print_z);
|
|
||||||
|
|
||||||
gcodegen.placeholder_parser().set("current_extruder", new_extruder_id);
|
//if needed, write the gcode_label_objects_end then priming tower
|
||||||
|
if (!gcodegen.m_gcode_label_objects_end.empty()) {
|
||||||
|
gcode += gcodegen.m_gcode_label_objects_end;
|
||||||
|
gcodegen.m_gcode_label_objects_end = "";
|
||||||
|
}
|
||||||
|
|
||||||
// Process the start filament gcode.
|
if (! tcr.priming) {
|
||||||
std::string start_filament_gcode_str;
|
// Move over the wipe tower.
|
||||||
|
// Retract for a tool change, using the toolchange retract value and setting the priming extra length.
|
||||||
|
gcode += gcodegen.retract(true);
|
||||||
|
gcodegen.m_avoid_crossing_perimeters.use_external_mp_once();
|
||||||
|
Polyline polyline = gcodegen.travel_to(
|
||||||
|
gcode,
|
||||||
|
wipe_tower_point_to_object_point(gcodegen, start_pos),
|
||||||
|
erMixed);
|
||||||
|
gcodegen.write_travel_to(gcode, polyline, "Travel to a Wipe Tower");
|
||||||
|
gcode += gcodegen.unretract();
|
||||||
|
}
|
||||||
|
|
||||||
|
double current_z = gcodegen.writer().get_position().z();
|
||||||
|
if (z == -1.) // in case no specific z was provided, print at current_z pos
|
||||||
|
z = current_z;
|
||||||
|
if (! is_approx(z, current_z)) {
|
||||||
|
gcode += gcodegen.writer().retract();
|
||||||
|
gcode += gcodegen.writer().travel_to_z(z, "Travel down to the last wipe tower layer.");
|
||||||
|
gcode += gcodegen.writer().unretract();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Process the end filament gcode.
|
||||||
|
std::string end_filament_gcode_str;
|
||||||
|
if (gcodegen.writer().tool() != nullptr && gcodegen.writer().tool_is_extruder()) {
|
||||||
|
// Process the custom end_filament_gcode in case of single_extruder_multi_material.
|
||||||
|
uint16_t old_extruder_id = gcodegen.writer().tool()->id();
|
||||||
|
const std::string& end_filament_gcode = gcodegen.config().end_filament_gcode.get_at(old_extruder_id);
|
||||||
|
if (gcodegen.writer().tool() != nullptr && ! end_filament_gcode.empty()) {
|
||||||
|
DynamicConfig config;
|
||||||
|
int previous_extruder_id = gcodegen.writer().tool() ? (int)gcodegen.writer().tool()->id() : -1;
|
||||||
|
config.set_key_value("previous_extruder", new ConfigOptionInt(previous_extruder_id));
|
||||||
|
config.set_key_value("next_extruder", new ConfigOptionInt((int)new_extruder_id));
|
||||||
|
config.set_key_value("layer_num", new ConfigOptionInt(gcodegen.m_layer_index));
|
||||||
|
config.set_key_value("layer_z", new ConfigOptionFloat(tcr.print_z));
|
||||||
|
end_filament_gcode_str = gcodegen.placeholder_parser_process("end_filament_gcode", end_filament_gcode, old_extruder_id, &config);
|
||||||
|
check_add_eol(end_filament_gcode_str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process the custom toolchange_gcode. If it is empty, provide a simple Tn command to change the filament.
|
||||||
|
// Otherwise, leave control to the user completely.
|
||||||
|
std::string toolchange_gcode_str;
|
||||||
|
|
||||||
|
if (tcr.priming || (new_extruder_id >= 0 && gcodegen.writer().need_toolchange(new_extruder_id)))
|
||||||
|
toolchange_gcode_str += gcodegen.toolchange(new_extruder_id, tcr.print_z);
|
||||||
|
|
||||||
|
gcodegen.placeholder_parser().set("current_extruder", new_extruder_id);
|
||||||
|
|
||||||
|
// Process the start filament gcode.
|
||||||
|
std::string start_filament_gcode_str;
|
||||||
const std::string& start_filament_gcode = gcodegen.config().start_filament_gcode.get_at(new_extruder_id);
|
const std::string& start_filament_gcode = gcodegen.config().start_filament_gcode.get_at(new_extruder_id);
|
||||||
if (!start_filament_gcode.empty()) {
|
if (!start_filament_gcode.empty()) {
|
||||||
// Process the start_filament_gcode for the active filament only.
|
// Process the start_filament_gcode for the active filament only.
|
||||||
|
DynamicConfig config;
|
||||||
|
config.set_key_value("filament_extruder_id", new ConfigOptionInt(new_extruder_id));
|
||||||
|
config.set_key_value("previous_extruder", new ConfigOptionInt(gcodegen.writer().tool() ? (int)gcodegen.writer().tool()->id() : -1));
|
||||||
|
config.set_key_value("next_extruder", new ConfigOptionInt(new_extruder_id));
|
||||||
|
config.set_key_value("layer_num", new ConfigOptionInt(0));
|
||||||
|
config.set_key_value("layer_z", new ConfigOptionFloat(z));
|
||||||
|
start_filament_gcode_str = gcodegen.placeholder_parser_process("start_filament_gcode", start_filament_gcode, new_extruder_id, &config);
|
||||||
|
check_add_eol(start_filament_gcode_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert the end filament, toolchange, and start filament gcode into the generated gcode.
|
||||||
DynamicConfig config;
|
DynamicConfig config;
|
||||||
config.set_key_value("filament_extruder_id", new ConfigOptionInt(new_extruder_id));
|
config.set_key_value("end_filament_gcode", new ConfigOptionString(end_filament_gcode_str));
|
||||||
config.set_key_value("previous_extruder", new ConfigOptionInt(gcodegen.writer().tool() ? (int)gcodegen.writer().tool()->id() : -1));
|
config.set_key_value("toolchange_gcode", new ConfigOptionString(toolchange_gcode_str));
|
||||||
config.set_key_value("next_extruder", new ConfigOptionInt(new_extruder_id));
|
config.set_key_value("start_filament_gcode", new ConfigOptionString(start_filament_gcode_str));
|
||||||
config.set_key_value("layer_num", new ConfigOptionInt(0));
|
std::string tcr_gcode, tcr_escaped_gcode = gcodegen.placeholder_parser_process("tcr_rotated_gcode", tcr_rotated_gcode, new_extruder_id, &config);
|
||||||
config.set_key_value("layer_z", new ConfigOptionFloat(z));
|
unescape_string_cstyle(tcr_escaped_gcode, tcr_gcode);
|
||||||
start_filament_gcode_str = gcodegen.placeholder_parser_process("start_filament_gcode", start_filament_gcode, new_extruder_id, &config);
|
gcode += tcr_gcode;
|
||||||
check_add_eol(start_filament_gcode_str);
|
check_add_eol(toolchange_gcode_str);
|
||||||
}
|
|
||||||
|
|
||||||
// Insert the end filament, toolchange, and start filament gcode into the generated gcode.
|
if (gcodegen.writer().tool() && gcodegen.m_config.filament_enable_toolchange_part_fan.values[gcodegen.writer().tool()->id()]) {
|
||||||
DynamicConfig config;
|
//if the fan may have been changed silently by the wipetower, recover it.
|
||||||
config.set_key_value("end_filament_gcode", new ConfigOptionString(end_filament_gcode_str));
|
gcode += gcodegen.m_writer.set_fan(gcodegen.m_writer.get_fan(), true);
|
||||||
config.set_key_value("toolchange_gcode", new ConfigOptionString(toolchange_gcode_str));
|
}
|
||||||
config.set_key_value("start_filament_gcode", new ConfigOptionString(start_filament_gcode_str));
|
|
||||||
std::string tcr_gcode, tcr_escaped_gcode = gcodegen.placeholder_parser_process("tcr_rotated_gcode", tcr_rotated_gcode, new_extruder_id, &config);
|
|
||||||
unescape_string_cstyle(tcr_escaped_gcode, tcr_gcode);
|
|
||||||
gcode += tcr_gcode;
|
|
||||||
check_add_eol(toolchange_gcode_str);
|
|
||||||
|
|
||||||
if (gcodegen.writer().tool() && gcodegen.m_config.filament_enable_toolchange_part_fan.values[gcodegen.writer().tool()->id()]) {
|
// A phony move to the end position at the wipe tower.
|
||||||
//if the fan may have been changed silently by the wipetower, recover it.
|
gcodegen.writer().travel_to_xy(end_pos.cast<double>());
|
||||||
gcode += gcodegen.m_writer.set_fan(gcodegen.m_writer.get_fan(), true);
|
gcodegen.set_last_pos(wipe_tower_point_to_object_point(gcodegen, end_pos));
|
||||||
}
|
|
||||||
|
|
||||||
// A phony move to the end position at the wipe tower.
|
|
||||||
gcodegen.writer().travel_to_xy(end_pos.cast<double>());
|
|
||||||
gcodegen.set_last_pos(wipe_tower_point_to_object_point(gcodegen, end_pos));
|
|
||||||
if (!is_approx(z, current_z)) {
|
if (!is_approx(z, current_z)) {
|
||||||
gcode += gcodegen.writer().retract();
|
gcode += gcodegen.writer().retract();
|
||||||
gcode += gcodegen.writer().travel_to_z(current_z, "Travel back up to the topmost object layer.");
|
gcode += gcodegen.writer().travel_to_z(current_z, "Travel back up to the topmost object layer.");
|
||||||
gcode += gcodegen.writer().unretract();
|
gcode += gcodegen.writer().unretract();
|
||||||
} else {
|
} else {
|
||||||
// Prepare a future wipe.
|
// Prepare a future wipe.
|
||||||
gcodegen.m_wipe.reset_path();
|
gcodegen.m_wipe.reset_path();
|
||||||
for (const Vec2f& wipe_pt : tcr.wipe_path)
|
for (const Vec2f& wipe_pt : tcr.wipe_path)
|
||||||
@ -367,10 +369,10 @@ static inline void set_extra_lift(const Layer& layer, const Print& print, GCodeW
|
|||||||
return gcode;
|
return gcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function postprocesses gcode_original, rotates and moves all G1 extrusions and returns resulting gcode
|
// This function postprocesses gcode_original, rotates and moves all G1 extrusions and returns resulting gcode
|
||||||
// Starting position has to be supplied explicitely (otherwise it would fail in case first G1 command only contained one coordinate)
|
// Starting position has to be supplied explicitely (otherwise it would fail in case first G1 command only contained one coordinate)
|
||||||
std::string WipeTowerIntegration::post_process_wipe_tower_moves(const WipeTower::ToolChangeResult& tcr, const Vec2f& translation, float angle) const
|
std::string WipeTowerIntegration::post_process_wipe_tower_moves(const WipeTower::ToolChangeResult& tcr, const Vec2f& translation, float angle) const
|
||||||
{
|
{
|
||||||
Vec2f extruder_offset = m_extruder_offsets[tcr.initial_tool].cast<float>();
|
Vec2f extruder_offset = m_extruder_offsets[tcr.initial_tool].cast<float>();
|
||||||
|
|
||||||
std::istringstream gcode_str(tcr.gcode);
|
std::istringstream gcode_str(tcr.gcode);
|
||||||
@ -388,7 +390,7 @@ static inline void set_extra_lift(const Layer& layer, const Print& print, GCodeW
|
|||||||
// WT generator can override this by appending the never_skip_tag
|
// WT generator can override this by appending the never_skip_tag
|
||||||
if (line.find("G1 ") == 0) {
|
if (line.find("G1 ") == 0) {
|
||||||
bool never_skip = false;
|
bool never_skip = false;
|
||||||
auto it = line.find(WipeTower::never_skip_tag());
|
auto it = line.find(WipeTower::never_skip_tag());
|
||||||
if (it != std::string::npos) {
|
if (it != std::string::npos) {
|
||||||
// remove the tag and remember we saw it
|
// remove the tag and remember we saw it
|
||||||
never_skip = true;
|
never_skip = true;
|
||||||
@ -399,7 +401,7 @@ static inline void set_extra_lift(const Layer& layer, const Print& print, GCodeW
|
|||||||
line_str >> std::noskipws; // don't skip whitespace
|
line_str >> std::noskipws; // don't skip whitespace
|
||||||
char ch = 0;
|
char ch = 0;
|
||||||
while (line_str >> ch) {
|
while (line_str >> ch) {
|
||||||
if (ch == 'X' || ch == 'Y')
|
if (ch == 'X' || ch == 'Y')
|
||||||
line_str >> (ch == 'X' ? pos.x() : pos.y());
|
line_str >> (ch == 'X' ? pos.x() : pos.y());
|
||||||
else
|
else
|
||||||
line_out << ch;
|
line_out << ch;
|
||||||
@ -439,7 +441,7 @@ static inline void set_extra_lift(const Layer& layer, const Print& print, GCodeW
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return gcode_out;
|
return gcode_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string WipeTowerIntegration::prime(GCode& gcodegen)
|
std::string WipeTowerIntegration::prime(GCode& gcodegen)
|
||||||
@ -454,33 +456,32 @@ static inline void set_extra_lift(const Layer& layer, const Print& print, GCodeW
|
|||||||
|
|
||||||
std::string WipeTowerIntegration::tool_change(GCode& gcodegen, int extruder_id, bool finish_layer)
|
std::string WipeTowerIntegration::tool_change(GCode& gcodegen, int extruder_id, bool finish_layer)
|
||||||
{
|
{
|
||||||
std::string gcode;
|
std::string gcode;
|
||||||
assert(m_layer_idx >= 0);
|
assert(m_layer_idx >= 0);
|
||||||
if (!m_brim_done || gcodegen.writer().need_toolchange(extruder_id) || finish_layer) {
|
if (!m_brim_done || gcodegen.writer().need_toolchange(extruder_id) || finish_layer) {
|
||||||
if (m_layer_idx < (int)m_tool_changes.size()) {
|
if (m_layer_idx < (int)m_tool_changes.size()) {
|
||||||
if (!(size_t(m_tool_change_idx) < m_tool_changes[m_layer_idx].size()))
|
if (!(size_t(m_tool_change_idx) < m_tool_changes[m_layer_idx].size()))
|
||||||
throw Slic3r::RuntimeError("Wipe tower generation failed, possibly due to empty first layer.");
|
throw Slic3r::RuntimeError("Wipe tower generation failed, possibly due to empty first layer.");
|
||||||
|
|
||||||
|
// Calculate where the wipe tower layer will be printed. -1 means that print z will not change,
|
||||||
// Calculate where the wipe tower layer will be printed. -1 means that print z will not change,
|
// resulting in a wipe tower with sparse layers.
|
||||||
// resulting in a wipe tower with sparse layers.
|
double wipe_tower_z = -1;
|
||||||
double wipe_tower_z = -1;
|
bool ignore_sparse = false;
|
||||||
bool ignore_sparse = false;
|
if (gcodegen.config().wipe_tower_no_sparse_layers.value) {
|
||||||
if (gcodegen.config().wipe_tower_no_sparse_layers.value) {
|
wipe_tower_z = m_last_wipe_tower_print_z;
|
||||||
wipe_tower_z = m_last_wipe_tower_print_z;
|
ignore_sparse = (m_brim_done && m_tool_changes[m_layer_idx].size() == 1 && m_tool_changes[m_layer_idx].front().initial_tool == m_tool_changes[m_layer_idx].front().new_tool);
|
||||||
ignore_sparse = (m_brim_done && m_tool_changes[m_layer_idx].size() == 1 && m_tool_changes[m_layer_idx].front().initial_tool == m_tool_changes[m_layer_idx].front().new_tool);
|
|
||||||
if (m_tool_change_idx == 0 && !ignore_sparse)
|
if (m_tool_change_idx == 0 && !ignore_sparse)
|
||||||
wipe_tower_z = m_last_wipe_tower_print_z + m_tool_changes[m_layer_idx].front().layer_height;
|
wipe_tower_z = m_last_wipe_tower_print_z + m_tool_changes[m_layer_idx].front().layer_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ignore_sparse) {
|
if (!ignore_sparse) {
|
||||||
gcode += append_tcr(gcodegen, m_tool_changes[m_layer_idx][m_tool_change_idx++], extruder_id, wipe_tower_z);
|
gcode += append_tcr(gcodegen, m_tool_changes[m_layer_idx][m_tool_change_idx++], extruder_id, wipe_tower_z);
|
||||||
m_last_wipe_tower_print_z = wipe_tower_z;
|
m_last_wipe_tower_print_z = wipe_tower_z;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
m_brim_done = true;
|
||||||
m_brim_done = true;
|
}
|
||||||
}
|
return gcode;
|
||||||
return gcode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print is finished. Now it remains to unload the filament safely with ramming over the wipe tower.
|
// Print is finished. Now it remains to unload the filament safely with ramming over the wipe tower.
|
||||||
@ -575,8 +576,8 @@ std::vector<GCode::LayerToPrint> GCode::collect_layers_to_print(const PrintObjec
|
|||||||
|
|
||||||
// Remember last layer with extrusions.
|
// Remember last layer with extrusions.
|
||||||
if (has_extrusions)
|
if (has_extrusions)
|
||||||
last_extrusion_layer = &layers_to_print.back();
|
last_extrusion_layer = &layers_to_print.back();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return layers_to_print;
|
return layers_to_print;
|
||||||
|
@ -686,7 +686,7 @@ const std::vector<std::string>& Preset::filament_options()
|
|||||||
"external_perimeter_fan_speed",
|
"external_perimeter_fan_speed",
|
||||||
// Retract overrides
|
// Retract overrides
|
||||||
"filament_retract_length", "filament_retract_lift", "filament_retract_lift_above", "filament_retract_lift_below", "filament_retract_speed", "filament_deretract_speed", "filament_retract_restart_extra", "filament_retract_before_travel",
|
"filament_retract_length", "filament_retract_lift", "filament_retract_lift_above", "filament_retract_lift_below", "filament_retract_speed", "filament_deretract_speed", "filament_retract_restart_extra", "filament_retract_before_travel",
|
||||||
"filament_retract_layer_change", "filament_wipe", "filament_wipe_extra_perimeter", "filament_retract_before_wipe",
|
"filament_retract_layer_change", "filament_wipe", "filament_wipe_speed", "filament_wipe_extra_perimeter", "filament_retract_before_wipe",
|
||||||
// Profile compatibility
|
// Profile compatibility
|
||||||
"filament_vendor", "compatible_prints", "compatible_prints_condition", "compatible_printers", "compatible_printers_condition", "inherits"
|
"filament_vendor", "compatible_prints", "compatible_prints_condition", "compatible_printers", "compatible_printers_condition", "inherits"
|
||||||
//merill adds
|
//merill adds
|
||||||
|
@ -184,6 +184,7 @@ bool Print::invalidate_state_by_config_options(const std::vector<t_config_option
|
|||||||
"use_volumetric_e",
|
"use_volumetric_e",
|
||||||
"variable_layer_height",
|
"variable_layer_height",
|
||||||
"wipe",
|
"wipe",
|
||||||
|
"wipe_speed",
|
||||||
"wipe_extra_perimeter"
|
"wipe_extra_perimeter"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4272,11 +4272,19 @@ void PrintConfigDef::init_fff_params()
|
|||||||
|
|
||||||
def = this->add("wipe", coBools);
|
def = this->add("wipe", coBools);
|
||||||
def->label = L("Wipe while retracting");
|
def->label = L("Wipe while retracting");
|
||||||
def->category = OptionCategory::general;
|
def->category = OptionCategory::extruders;
|
||||||
def->tooltip = L("This flag will move the nozzle while retracting to minimize the possible blob "
|
def->tooltip = L("This flag will move the nozzle while retracting to minimize the possible blob "
|
||||||
"on leaky extruders.");
|
"on leaky extruders.");
|
||||||
def->mode = comAdvanced;
|
def->mode = comAdvanced;
|
||||||
def->set_default_value(new ConfigOptionBools { false });
|
def->set_default_value(new ConfigOptionBools{ false });
|
||||||
|
|
||||||
|
def = this->add("wipe_speed", coFloats);
|
||||||
|
def->label = L("Wipe speed");
|
||||||
|
def->category = OptionCategory::extruders;
|
||||||
|
def->tooltip = L("Speed in mm/s of the wipe. If it's faster, it will try to go further away, as the wipe time is set by ( 100% - 'retract before wipe') * 'retaction length' / 'retraction speed'."
|
||||||
|
"\nIf set to zero, the travel speed is used.");
|
||||||
|
def->mode = comAdvanced;
|
||||||
|
def->set_default_value(new ConfigOptionFloats{ 0 });
|
||||||
|
|
||||||
def = this->add("wipe_tower", coBool);
|
def = this->add("wipe_tower", coBool);
|
||||||
def->label = L("Enable");
|
def->label = L("Enable");
|
||||||
@ -4527,7 +4535,7 @@ void PrintConfigDef::init_fff_params()
|
|||||||
for (const char *opt_key : {
|
for (const char *opt_key : {
|
||||||
// floats
|
// floats
|
||||||
"retract_length", "retract_lift", "retract_lift_above", "retract_lift_below", "retract_speed", "deretract_speed", "retract_restart_extra", "retract_before_travel",
|
"retract_length", "retract_lift", "retract_lift_above", "retract_lift_below", "retract_speed", "deretract_speed", "retract_restart_extra", "retract_before_travel",
|
||||||
"wipe_extra_perimeter",
|
"wipe_extra_perimeter", "wipe_speed",
|
||||||
// bools
|
// bools
|
||||||
"retract_layer_change", "wipe",
|
"retract_layer_change", "wipe",
|
||||||
// percents
|
// percents
|
||||||
@ -4574,6 +4582,7 @@ void PrintConfigDef::init_extruder_option_keys()
|
|||||||
"retract_before_travel",
|
"retract_before_travel",
|
||||||
"wipe",
|
"wipe",
|
||||||
"wipe_extra_perimeter",
|
"wipe_extra_perimeter",
|
||||||
|
"wipe_speed",
|
||||||
"retract_layer_change",
|
"retract_layer_change",
|
||||||
"retract_length_toolchange",
|
"retract_length_toolchange",
|
||||||
"retract_restart_extra_toolchange",
|
"retract_restart_extra_toolchange",
|
||||||
@ -4593,6 +4602,7 @@ void PrintConfigDef::init_extruder_option_keys()
|
|||||||
"retract_restart_extra",
|
"retract_restart_extra",
|
||||||
"retract_speed",
|
"retract_speed",
|
||||||
"wipe",
|
"wipe",
|
||||||
|
"wipe_speed",
|
||||||
"wipe_extra_perimeter"
|
"wipe_extra_perimeter"
|
||||||
};
|
};
|
||||||
assert(std::is_sorted(m_extruder_retract_keys.begin(), m_extruder_retract_keys.end()));
|
assert(std::is_sorted(m_extruder_retract_keys.begin(), m_extruder_retract_keys.end()));
|
||||||
@ -5670,6 +5680,7 @@ std::unordered_set<std::string> prusa_export_to_remove_keys = {
|
|||||||
"wipe_advanced_nozzle_melted_volume",
|
"wipe_advanced_nozzle_melted_volume",
|
||||||
"wipe_advanced",
|
"wipe_advanced",
|
||||||
"wipe_extra_perimeter",
|
"wipe_extra_perimeter",
|
||||||
|
"wipe_speed",
|
||||||
"wipe_tower_brim",
|
"wipe_tower_brim",
|
||||||
"xy_inner_size_compensation",
|
"xy_inner_size_compensation",
|
||||||
"z_step",
|
"z_step",
|
||||||
|
@ -1143,6 +1143,7 @@ public:
|
|||||||
ConfigOptionFloat wipe_advanced_multiplier;
|
ConfigOptionFloat wipe_advanced_multiplier;
|
||||||
ConfigOptionFloats wipe_extra_perimeter;
|
ConfigOptionFloats wipe_extra_perimeter;
|
||||||
ConfigOptionEnum<WipeAlgo> wipe_advanced_algo;
|
ConfigOptionEnum<WipeAlgo> wipe_advanced_algo;
|
||||||
|
ConfigOptionFloats wipe_speed;
|
||||||
ConfigOptionFloat z_step;
|
ConfigOptionFloat z_step;
|
||||||
ConfigOptionString color_change_gcode;
|
ConfigOptionString color_change_gcode;
|
||||||
ConfigOptionString pause_print_gcode;
|
ConfigOptionString pause_print_gcode;
|
||||||
@ -1258,6 +1259,7 @@ protected:
|
|||||||
OPT_PTR(wipe_advanced_multiplier);
|
OPT_PTR(wipe_advanced_multiplier);
|
||||||
OPT_PTR(wipe_advanced_algo);
|
OPT_PTR(wipe_advanced_algo);
|
||||||
OPT_PTR(wipe_extra_perimeter);
|
OPT_PTR(wipe_extra_perimeter);
|
||||||
|
OPT_PTR(wipe_speed);
|
||||||
OPT_PTR(z_step);
|
OPT_PTR(z_step);
|
||||||
OPT_PTR(color_change_gcode);
|
OPT_PTR(color_change_gcode);
|
||||||
OPT_PTR(pause_print_gcode);
|
OPT_PTR(pause_print_gcode);
|
||||||
|
@ -2263,6 +2263,7 @@ void TabFilament::add_filament_overrides_page()
|
|||||||
"filament_retract_before_travel",
|
"filament_retract_before_travel",
|
||||||
"filament_retract_layer_change",
|
"filament_retract_layer_change",
|
||||||
"filament_wipe",
|
"filament_wipe",
|
||||||
|
"filament_wipe_speed",
|
||||||
"filament_wipe_extra_perimeter",
|
"filament_wipe_extra_perimeter",
|
||||||
"filament_retract_before_wipe"
|
"filament_retract_before_wipe"
|
||||||
})
|
})
|
||||||
@ -2290,6 +2291,7 @@ void TabFilament::update_filament_overrides_page()
|
|||||||
"filament_retract_before_travel",
|
"filament_retract_before_travel",
|
||||||
"filament_retract_layer_change",
|
"filament_retract_layer_change",
|
||||||
"filament_wipe",
|
"filament_wipe",
|
||||||
|
"filament_wipe_speed",
|
||||||
"filament_wipe_extra_perimeter",
|
"filament_wipe_extra_perimeter",
|
||||||
"filament_retract_before_wipe"
|
"filament_retract_before_wipe"
|
||||||
};
|
};
|
||||||
@ -2912,17 +2914,20 @@ void TabPrinter::toggle_options()
|
|||||||
|
|
||||||
// some options only apply when not using firmware retraction
|
// some options only apply when not using firmware retraction
|
||||||
vec.resize(0);
|
vec.resize(0);
|
||||||
vec = { "retract_speed", "deretract_speed", "retract_before_wipe", "retract_restart_extra", "wipe" };
|
vec = { "retract_speed", "deretract_speed", "retract_before_wipe", "retract_restart_extra", "wipe", "wipe_speed" };
|
||||||
for (auto el : vec) {
|
for (auto el : vec) {
|
||||||
field = get_field(el, i);
|
field = get_field(el, i);
|
||||||
if (field)
|
if (field)
|
||||||
field->toggle(retraction && !use_firmware_retraction);
|
field->toggle(retraction && !use_firmware_retraction);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wipe = m_config->opt_bool("wipe", i);
|
bool wipe = m_config->opt_bool("wipe", i) && have_retract_length;
|
||||||
field = get_field("retract_before_wipe", i);
|
vec = { "retract_before_wipe", "wipe_speed" };
|
||||||
if (field)
|
for (auto el : vec) {
|
||||||
field->toggle(wipe);
|
field = get_field(el, i);
|
||||||
|
if (field)
|
||||||
|
field->toggle(wipe);
|
||||||
|
}
|
||||||
|
|
||||||
if (use_firmware_retraction && wipe) {
|
if (use_firmware_retraction && wipe) {
|
||||||
wxMessageDialog dialog(parent(),
|
wxMessageDialog dialog(parent(),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user