diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 0334720ff..107d56da5 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -303,7 +303,7 @@ namespace Slic3r { Vec2f start_pos = tcr.start_pos; Vec2f end_pos = tcr.end_pos; - if (!tcr.priming) { + if (! tcr.priming) { start_pos = transform_wt_pt(start_pos); end_pos = transform_wt_pt(end_pos); } @@ -313,7 +313,7 @@ namespace Slic3r { std::string tcr_rotated_gcode = post_process_wipe_tower_moves(tcr, wipe_tower_offset, wipe_tower_rotation); - if (!tcr.priming) { + 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); @@ -328,7 +328,7 @@ namespace Slic3r { 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)) { + 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(); @@ -350,27 +350,25 @@ namespace Slic3r { // 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 (true /*gcodegen.writer().extruder() != nullptr*/) { - const std::string& toolchange_gcode = gcodegen.config().toolchange_gcode.value; - if (!toolchange_gcode.empty()) { - DynamicConfig config; - int previous_extruder_id = gcodegen.writer().extruder() ? (int)gcodegen.writer().extruder()->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)); - toolchange_gcode_str = gcodegen.placeholder_parser_process("toolchange_gcode", toolchange_gcode, new_extruder_id, &config); - check_add_eol(toolchange_gcode_str); - } + const std::string& toolchange_gcode = gcodegen.config().toolchange_gcode.value; + if (! toolchange_gcode.empty()) { + DynamicConfig config; + int previous_extruder_id = gcodegen.writer().extruder() ? (int)gcodegen.writer().extruder()->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)); + toolchange_gcode_str = gcodegen.placeholder_parser_process("toolchange_gcode", toolchange_gcode, new_extruder_id, &config); + check_add_eol(toolchange_gcode_str); + } - std::string toolchange_command; - if (tcr.priming || (new_extruder_id >= 0 && gcodegen.writer().need_toolchange(new_extruder_id))) - toolchange_command = gcodegen.writer().toolchange(new_extruder_id); - if (!custom_gcode_changes_tool(toolchange_gcode_str, gcodegen.writer().toolchange_prefix(), new_extruder_id)) - toolchange_gcode_str += toolchange_command; - else { - // We have informed the m_writer about the current extruder_id, we can ignore the generated G-code. - } + std::string toolchange_command; + if (tcr.priming || (new_extruder_id >= 0 && gcodegen.writer().need_toolchange(new_extruder_id))) + toolchange_command = gcodegen.writer().toolchange(new_extruder_id); + if (!custom_gcode_changes_tool(toolchange_gcode_str, gcodegen.writer().toolchange_prefix(), new_extruder_id)) + toolchange_gcode_str += toolchange_command; + else { + // We have informed the m_writer about the current extruder_id, we can ignore the generated G-code. } gcodegen.placeholder_parser().set("current_extruder", new_extruder_id); @@ -408,15 +406,6 @@ namespace Slic3r { else { // Prepare a future wipe. - /*gcodegen.m_wipe.path.points.clear(); - if (new_extruder_id >= 0) { - // Start the wipe at the current position. - gcodegen.m_wipe.path.points.emplace_back(wipe_tower_point_to_object_point(gcodegen, end_pos)); - // Wipe end point: Wipe direction away from the closer tower edge to the further tower edge. - gcodegen.m_wipe.path.points.emplace_back(wipe_tower_point_to_object_point(gcodegen, - Vec2f((std::abs(m_left - end_pos.x()) < std::abs(m_right - end_pos.x())) ? m_right : m_left, - end_pos.y()))); - }*/ gcodegen.m_wipe.reset_path(); for (const Vec2f& wipe_pt : tcr.wipe_path) gcodegen.m_wipe.path.points.emplace_back(wipe_tower_point_to_object_point(gcodegen, transform_wt_pt(wipe_pt))); @@ -507,37 +496,11 @@ namespace Slic3r { assert(m_layer_idx == 0); std::string gcode; - - // Disable linear advance for the wipe tower operations. - //gcode += (gcodegen.config().gcode_flavor == gcfRepRap ? std::string("M572 D0 S0\n") : std::string("M900 K0\n")); - for (const WipeTower::ToolChangeResult& tcr : m_priming) { - if (!tcr.extrusions.empty()) + if (! tcr.extrusions.empty()) gcode += append_tcr(gcodegen, tcr, tcr.new_tool); - - - // Let the tool change be executed by the wipe tower class. - // Inform the G-code writer about the changes done behind its back. - //gcode += tcr.gcode; - // Let the m_writer know the current extruder_id, but ignore the generated G-code. - // unsigned int current_extruder_id = tcr.extrusions.back().tool; - // gcodegen.writer().toolchange(current_extruder_id); - // gcodegen.placeholder_parser().set("current_extruder", current_extruder_id); - } - // A phony move to the end position at the wipe tower. - /* gcodegen.writer().travel_to_xy(Vec2d(m_priming.back().end_pos.x, m_priming.back().end_pos.y)); - gcodegen.set_last_pos(wipe_tower_point_to_object_point(gcodegen, m_priming.back().end_pos)); - // Prepare a future wipe. - gcodegen.m_wipe.path.points.clear(); - // Start the wipe at the current position. - gcodegen.m_wipe.path.points.emplace_back(wipe_tower_point_to_object_point(gcodegen, m_priming.back().end_pos)); - // Wipe end point: Wipe direction away from the closer tower edge to the further tower edge. - gcodegen.m_wipe.path.points.emplace_back(wipe_tower_point_to_object_point(gcodegen, - WipeTower::xy((std::abs(m_left - m_priming.back().end_pos.x) < std::abs(m_right - m_priming.back().end_pos.x)) ? m_right : m_left, - m_priming.back().end_pos.y)));*/ - return gcode; } diff --git a/src/libslic3r/GCode/WipeTower.cpp b/src/libslic3r/GCode/WipeTower.cpp index c5178eefa..944bea5c1 100644 --- a/src/libslic3r/GCode/WipeTower.cpp +++ b/src/libslic3r/GCode/WipeTower.cpp @@ -1,22 +1,6 @@ -/* - -TODO LIST ---------- - -1. cooling moves - DONE -2. account for perimeter and finish_layer extrusions and subtract it from last wipe - DONE -3. priming extrusions (last wipe must clear the color) - DONE -4. Peter's wipe tower - layer's are not exactly square -5. Peter's wipe tower - variable width for higher levels -6. Peter's wipe tower - make sure it is not too sparse (apply max_bridge_distance and make last wipe longer) -7. Peter's wipe tower - enable enhanced first layer adhesion - -*/ - #include "WipeTower.hpp" -#include -#include +#include #include #include #include @@ -28,13 +12,16 @@ TODO LIST #endif // ENABLE_GCODE_VIEWER #include "BoundingBox.hpp" -#if defined(__linux) || defined(__GNUC__ ) -#include -#endif /* __linux */ -#ifdef _MSC_VER -#define strcasecmp _stricmp -#endif +// Experimental "Peter's wipe tower" feature was partially implemented, inspired by +// PJR's idea of alternating two perpendicular wiping directions on a square tower. +// It is probably never going to be finished, there are multiple remaining issues +// and there is probably no need to go down this way. m_peters_wipe_tower variable +// turns this on, maybe it should just be removed. Anyway, the issues are +// - layer's are not exactly square +// - variable width for higher levels +// - make sure it is not too sparse (apply max_bridge_distance and make last wipe longer) +// - enable enhanced first layer adhesion namespace Slic3r @@ -730,7 +717,7 @@ std::vector WipeTower::prime( return results; } -WipeTower::ToolChangeResult WipeTower::tool_change(size_t tool, bool last_in_layer) +WipeTower::ToolChangeResult WipeTower::tool_change(size_t tool) { if ( m_print_brim ) return toolchange_Brim(); @@ -807,7 +794,6 @@ WipeTower::ToolChangeResult WipeTower::tool_change(size_t tool, bool last_in_lay else { writer.rectangle(Vec2f::Zero(), m_wipe_tower_width, m_layer_info->depth + m_perimeter_width); if (layer_finished()) { // no finish_layer will be called, we must wipe the nozzle - //writer.travel(writer.x()> m_wipe_tower_width / 2.f ? 0.f : m_wipe_tower_width, writer.y()); writer.add_wipe_point(writer.x(), writer.y()) .add_wipe_point(writer.x()> m_wipe_tower_width / 2.f ? 0.f : m_wipe_tower_width, writer.y()); @@ -878,16 +864,11 @@ WipeTower::ToolChangeResult WipeTower::toolchange_Brim(bool sideOnly, float y_of .extrude(box.rd ).extrude(box.ld); } - //writer.travel(wipeTower_box.ld, 7000); // Move to the front left corner. - //writer.travel(wipeTower_box.rd) // Always wipe the nozzle with a long wipe to reduce stringing when moving away from the wipe tower. - //.travel(wipeTower_box.ld); - box.expand(-spacing); writer.add_wipe_point(writer.x(), writer.y()) .add_wipe_point(box.ld) .add_wipe_point(box.rd); - writer.append("; CP WIPE TOWER FIRST LAYER BRIM END\n" ";-----------------------------------\n"); @@ -956,13 +937,6 @@ void WipeTower::toolchange_Unload( else sparse_beginning_y += (m_layer_info-1)->toolchanges_depth() + m_perimeter_width; - //debugging: - /* float oldx = writer.x(); - float oldy = writer.y(); - writer.travel(xr,sparse_beginning_y); - writer.extrude(xr+5,writer.y()); - writer.travel(oldx,oldy);*/ - float sum_of_depths = 0.f; for (const auto& tch : m_layer_info->tool_changes) { // let's find this toolchange if (tch.old_tool == m_current_tool) { @@ -970,13 +944,6 @@ void WipeTower::toolchange_Unload( float ramming_end_y = sum_of_depths; ramming_end_y -= (y_step/m_extra_spacing-m_perimeter_width) / 2.f; // center of final ramming line - // debugging: - /*float oldx = writer.x(); - float oldy = writer.y(); - writer.travel(xl,ramming_end_y); - writer.extrude(xl-15,writer.y()); - writer.travel(oldx,oldy);*/ - if ( (m_current_shape == SHAPE_REVERSED && ramming_end_y < sparse_beginning_y - 0.5f*m_perimeter_width ) || (m_current_shape == SHAPE_NORMAL && ramming_end_y > sparse_beginning_y + 0.5f*m_perimeter_width ) ) { @@ -1027,12 +994,6 @@ void WipeTower::toolchange_Unload( .retract(0.70f * total_retraction_distance, 1.0f * m_filpar[m_current_tool].unloading_speed * 60.f) .retract(0.20f * total_retraction_distance, 0.5f * m_filpar[m_current_tool].unloading_speed * 60.f) .retract(0.10f * total_retraction_distance, 0.3f * m_filpar[m_current_tool].unloading_speed * 60.f) - - /*.load_move_x_advanced(turning_point, -15.f, 83.f, 50.f) // this is done at fixed speed - .load_move_x_advanced(old_x, -0.70f * total_retraction_distance, 1.0f * m_filpar[m_current_tool].unloading_speed) - .load_move_x_advanced(turning_point, -0.20f * total_retraction_distance, 0.5f * m_filpar[m_current_tool].unloading_speed) - .load_move_x_advanced(old_x, -0.10f * total_retraction_distance, 0.3f * m_filpar[m_current_tool].unloading_speed) - .travel(old_x, writer.y()) // in case previous move was shortened to limit feedrate*/ .resume_preview(); } // Wipe tower should only change temperature with single extruder MM. Otherwise, all temperatures should @@ -1125,11 +1086,6 @@ void WipeTower::toolchange_Load( writer.append("; CP TOOLCHANGE LOAD\n") .suppress_preview() - /*.load_move_x_advanced(turning_point, 0.2f * edist, 0.3f * m_filpar[m_current_tool].loading_speed) // Acceleration - .load_move_x_advanced(oldx, 0.5f * edist, m_filpar[m_current_tool].loading_speed) // Fast phase - .load_move_x_advanced(turning_point, 0.2f * edist, 0.3f * m_filpar[m_current_tool].loading_speed) // Slowing down - .load_move_x_advanced(oldx, 0.1f * edist, 0.1f * m_filpar[m_current_tool].loading_speed) // Super slow*/ - .load(0.2f * edist, 60.f * m_filpar[m_current_tool].loading_speed_start) .load_move_x_advanced(turning_point, 0.7f * edist, m_filpar[m_current_tool].loading_speed) // Fast phase .load_move_x_advanced(oldx, 0.1f * edist, 0.1f * m_filpar[m_current_tool].loading_speed) // Super slow*/ @@ -1203,10 +1159,6 @@ void WipeTower::toolchange_Wipe( // going back to the model - wipe the nozzle. if (m_layer_info != m_plan.end() && m_current_tool != m_layer_info->tool_changes.back().new_tool) { m_left_to_right = !m_left_to_right; - //writer.comment_with_value("starting wipe tower wipe ", 0) - // .travel(writer.x(), writer.y() - dy) - // .travel(m_left_to_right ? m_wipe_tower_width : 0.f, writer.y()) - // .comment_with_value("finished wipe tower wipe ", 0); writer.add_wipe_point(writer.x(), writer.y()) .add_wipe_point(writer.x(), writer.y() - dy) .add_wipe_point(m_left_to_right ? m_wipe_tower_width : 0.f, writer.y() - dy); @@ -1274,7 +1226,6 @@ WipeTower::ToolChangeResult WipeTower::finish_layer() writer.extrude(box.rd.x() - m_perimeter_width / 2.f, writer.y() + 0.5f * step); writer.extrude(box.ld.x() + m_perimeter_width / 2.f, writer.y()); } - //writer.travel(box.rd.x()-m_perimeter_width/2.f,writer.y()); // wipe the nozzle writer.add_wipe_point(writer.x(), writer.y()) .add_wipe_point(box.rd.x()-m_perimeter_width/2.f,writer.y()); } @@ -1297,12 +1248,10 @@ WipeTower::ToolChangeResult WipeTower::finish_layer() } writer.add_wipe_point(Vec2f(writer.x(), writer.y())) .add_wipe_point(Vec2f(left, writer.y())); - //writer.travel(left,writer.y(),7200); // wipes the nozzle before moving away from the wipe tower } else { writer.add_wipe_point(Vec2f(writer.x(), writer.y())) .add_wipe_point(Vec2f(right, writer.y())); - // writer.travel(right,writer.y(),7200); // wipes the nozzle before moving away from the wipe tower } } writer.append("; CP EMPTY GRID END\n" @@ -1400,7 +1349,7 @@ void WipeTower::save_on_last_wipe() continue; for (const auto &toolchange : m_layer_info->tool_changes) - tool_change(toolchange.new_tool, false); + tool_change(toolchange.new_tool); float width = m_wipe_tower_width - 3*m_perimeter_width; // width we draw into float length_to_save = 2*(m_wipe_tower_width+m_wipe_tower_depth) + (!layer_finished() ? finish_layer().total_extrusion_length_in_plane() : 0.f); @@ -1462,7 +1411,7 @@ void WipeTower::generate(std::vector> & m_y_shift = (m_wipe_tower_depth-m_layer_info->depth-m_perimeter_width)/2.f; for (const auto &toolchange : layer.tool_changes) - layer_result.emplace_back(tool_change(toolchange.new_tool, false)); + layer_result.emplace_back(tool_change(toolchange.new_tool)); if (! layer_finished()) { auto finish_layer_toolchange = finish_layer(); @@ -1512,4 +1461,4 @@ void WipeTower::make_wipe_tower_square() lay.extra_spacing = lay.depth / lay.toolchanges_depth(); } -}; // namespace Slic3r +} // namespace Slic3r diff --git a/src/libslic3r/GCode/WipeTower.hpp b/src/libslic3r/GCode/WipeTower.hpp index e4b44e2bb..26f48785a 100644 --- a/src/libslic3r/GCode/WipeTower.hpp +++ b/src/libslic3r/GCode/WipeTower.hpp @@ -161,7 +161,7 @@ public: // Returns gcode for a toolchange and a final print head position. // On the first layer, extrude a brim around the future wipe tower first. - ToolChangeResult tool_change(size_t new_tool, bool last_in_layer); + ToolChangeResult tool_change(size_t new_tool); // Fill the unfilled space with a sparse infill. // Call this method only if layer_finished() is false. diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index a82ab3ddd..a360d840f 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -2174,7 +2174,7 @@ void Print::_make_wipe_tower() wipe_tower.set_layer(float(m_wipe_tower_data.tool_ordering.back().print_z), float(layer_height), 0, false, true); } m_wipe_tower_data.final_purge = Slic3r::make_unique( - wipe_tower.tool_change((unsigned int)-1, false)); + wipe_tower.tool_change((unsigned int)(-1))); m_wipe_tower_data.used_filament = wipe_tower.get_used_filament(); m_wipe_tower_data.number_of_toolchanges = wipe_tower.get_number_of_toolchanges();