diff --git a/src/libslic3r/GCode/WipeTower.cpp b/src/libslic3r/GCode/WipeTower.cpp index 7a764d0f6..6f09f034f 100644 --- a/src/libslic3r/GCode/WipeTower.cpp +++ b/src/libslic3r/GCode/WipeTower.cpp @@ -22,6 +22,7 @@ TODO LIST #include #include "Analyzer.hpp" +#include "BoundingBox.hpp" #if defined(__linux) || defined(__GNUC__ ) #include @@ -475,6 +476,83 @@ private: +WipeTower::WipeTower(const PrintConfig& config, const std::vector>& wiping_matrix, size_t initial_tool) : + m_semm(config.single_extruder_multi_material.value), + m_wipe_tower_pos(config.wipe_tower_x, config.wipe_tower_y), + m_wipe_tower_width(config.wipe_tower_width), + m_wipe_tower_rotation_angle(config.wipe_tower_rotation_angle), + m_y_shift(0.f), + m_z_pos(0.f), + m_is_first_layer(false), + m_bridging(config.wipe_tower_bridging), + m_gcode_flavor(config.gcode_flavor), + m_current_tool(initial_tool), + wipe_volumes(wiping_matrix) +{ + // If this is a single extruder MM printer, we will use all the SE-specific config values. + // Otherwise, the defaults will be used to turn off the SE stuff. + if (m_semm) { + m_cooling_tube_retraction = config.cooling_tube_retraction; + m_cooling_tube_length = config.cooling_tube_length; + m_parking_pos_retraction = config.parking_pos_retraction; + m_extra_loading_move = config.extra_loading_move; + m_set_extruder_trimpot = config.high_current_on_filament_swap; + } + // Calculate where the priming lines should be - very naive test not detecting parallelograms or custom shapes + const std::vector& bed_points = config.bed_shape.values; + m_bed_shape = (bed_points.size() == 4 ? RectangularBed : CircularBed); + m_bed_width = BoundingBoxf(bed_points).size().x(); +} + + + +void WipeTower::set_extruder(size_t idx, const PrintConfig& config) +{ + //while (m_filpar.size() < idx+1) // makes sure the required element is in the vector + m_filpar.push_back(FilamentParameters()); + + m_filpar[idx].material = config.filament_type.get_at(idx); + m_filpar[idx].temperature = config.temperature.get_at(idx); + m_filpar[idx].first_layer_temperature = config.first_layer_temperature.get_at(idx); + + // If this is a single extruder MM printer, we will use all the SE-specific config values. + // Otherwise, the defaults will be used to turn off the SE stuff. + if (m_semm) { + m_filpar[idx].loading_speed = config.filament_loading_speed.get_at(idx); + m_filpar[idx].loading_speed_start = config.filament_loading_speed_start.get_at(idx); + m_filpar[idx].unloading_speed = config.filament_unloading_speed.get_at(idx); + m_filpar[idx].unloading_speed_start = config.filament_unloading_speed_start.get_at(idx); + m_filpar[idx].delay = config.filament_toolchange_delay.get_at(idx); + m_filpar[idx].cooling_moves = config.filament_cooling_moves.get_at(idx); + m_filpar[idx].cooling_initial_speed = config.filament_cooling_initial_speed.get_at(idx); + m_filpar[idx].cooling_final_speed = config.filament_cooling_final_speed.get_at(idx); + } + + m_filpar[idx].filament_area = float((M_PI/4.f) * pow(config.filament_diameter.get_at(idx), 2)); // all extruders are assumed to have the same filament diameter at this point + float nozzle_diameter = config.nozzle_diameter.get_at(idx); + m_filpar[idx].nozzle_diameter = nozzle_diameter; // to be used in future with (non-single) multiextruder MM + + float max_vol_speed = config.filament_max_volumetric_speed.get_at(idx); + if (max_vol_speed!= 0.f) + m_filpar[idx].max_e_speed = (max_vol_speed / filament_area()); + + m_perimeter_width = nozzle_diameter * Width_To_Nozzle_Ratio; // all extruders are now assumed to have the same diameter + + if (m_semm) { + std::istringstream stream{config.filament_ramming_parameters.get_at(idx)}; + float speed = 0.f; + stream >> m_filpar[idx].ramming_line_width_multiplicator >> m_filpar[idx].ramming_step_multiplicator; + m_filpar[idx].ramming_line_width_multiplicator /= 100; + m_filpar[idx].ramming_step_multiplicator /= 100; + while (stream >> speed) + m_filpar[idx].ramming_speed.push_back(speed); + } + + m_used_filament_length.resize(std::max(m_used_filament_length.size(), idx + 1)); // makes sure that the vector is big enough so we don't have to check later +} + + + // Returns gcode to prime the nozzles at the front edge of the print bed. std::vector WipeTower::prime( // print_z of the first layer. @@ -493,9 +571,11 @@ std::vector WipeTower::prime( // therefore the homing position is shifted inside the bed by 0.2 in the firmware to [0.2, -2.0]. // box_coordinates cleaning_box(xy(0.5f, - 1.5f), m_wipe_tower_width, wipe_area); - const float prime_section_width = std::min(240.f / tools.size(), 60.f); - box_coordinates cleaning_box(Vec2f(5.f, 0.01f + m_perimeter_width/2.f), prime_section_width, 100.f); - + float prime_section_width = std::min(0.9f * m_bed_width / tools.size(), 60.f); + box_coordinates cleaning_box(Vec2f(0.02f * m_bed_width, 0.01f + m_perimeter_width/2.f), prime_section_width, 100.f); + // In case of a circular bed, place it so it goes across the diameter and hope it will fit + if (m_bed_shape == CircularBed) + cleaning_box.translate(-m_bed_width/2 + m_bed_width * 0.03f, -m_bed_width * 0.12f); std::vector results; diff --git a/src/libslic3r/GCode/WipeTower.hpp b/src/libslic3r/GCode/WipeTower.hpp index 3c6b4afca..fab75c5e6 100644 --- a/src/libslic3r/GCode/WipeTower.hpp +++ b/src/libslic3r/GCode/WipeTower.hpp @@ -78,83 +78,12 @@ public: // y -- y coordinates of wipe tower in mm ( left bottom corner ) // width -- width of wipe tower in mm ( default 60 mm - leave as it is ) // wipe_area -- space available for one toolchange in mm - WipeTower(bool semm, float x, float y, float width, float rotation_angle, float cooling_tube_retraction, - float cooling_tube_length, float parking_pos_retraction, float extra_loading_move, - float bridging, bool set_extruder_trimpot, GCodeFlavor flavor, - const std::vector>& wiping_matrix, unsigned int initial_tool) : - m_semm(semm), - m_wipe_tower_pos(x, y), - m_wipe_tower_width(width), - m_wipe_tower_rotation_angle(rotation_angle), - m_y_shift(0.f), - m_z_pos(0.f), - m_is_first_layer(false), - m_gcode_flavor(flavor), - m_bridging(bridging), - m_current_tool(initial_tool), - wipe_volumes(wiping_matrix) - { - // If this is a single extruder MM printer, we will use all the SE-specific config values. - // Otherwise, the defaults will be used to turn off the SE stuff. - if (m_semm) { - m_cooling_tube_retraction = cooling_tube_retraction; - m_cooling_tube_length = cooling_tube_length; - m_parking_pos_retraction = parking_pos_retraction; - m_extra_loading_move = extra_loading_move; - m_set_extruder_trimpot = set_extruder_trimpot; - } - } - + WipeTower(const PrintConfig& config, const std::vector>& wiping_matrix, size_t initial_tool); virtual ~WipeTower() {} // Set the extruder properties. - void set_extruder(size_t idx, std::string material, int temp, int first_layer_temp, float loading_speed, float loading_speed_start, - float unloading_speed, float unloading_speed_start, float delay, int cooling_moves, - float cooling_initial_speed, float cooling_final_speed, std::string ramming_parameters, float max_volumetric_speed, - float nozzle_diameter, float filament_diameter) - { - //while (m_filpar.size() < idx+1) // makes sure the required element is in the vector - m_filpar.push_back(FilamentParameters()); - - m_filpar[idx].material = material; - m_filpar[idx].temperature = temp; - m_filpar[idx].first_layer_temperature = first_layer_temp; - - // If this is a single extruder MM printer, we will use all the SE-specific config values. - // Otherwise, the defaults will be used to turn off the SE stuff. - if (m_semm) { - m_filpar[idx].loading_speed = loading_speed; - m_filpar[idx].loading_speed_start = loading_speed_start; - m_filpar[idx].unloading_speed = unloading_speed; - m_filpar[idx].unloading_speed_start = unloading_speed_start; - m_filpar[idx].delay = delay; - m_filpar[idx].cooling_moves = cooling_moves; - m_filpar[idx].cooling_initial_speed = cooling_initial_speed; - m_filpar[idx].cooling_final_speed = cooling_final_speed; - } - - m_filpar[idx].filament_area = float((M_PI/4.f) * pow(filament_diameter, 2)); // all extruders are assumed to have the same filament diameter at this point - m_filpar[idx].nozzle_diameter = nozzle_diameter; // to be used in future with (non-single) multiextruder MM - - if (max_volumetric_speed != 0.f) - m_filpar[idx].max_e_speed = (max_volumetric_speed / filament_area()); - - m_perimeter_width = nozzle_diameter * Width_To_Nozzle_Ratio; // all extruders are now assumed to have the same diameter - - if (m_semm) { - std::stringstream stream{ramming_parameters}; - float speed = 0.f; - stream >> m_filpar[idx].ramming_line_width_multiplicator >> m_filpar[idx].ramming_step_multiplicator; - m_filpar[idx].ramming_line_width_multiplicator /= 100; - m_filpar[idx].ramming_step_multiplicator /= 100; - while (stream >> speed) - m_filpar[idx].ramming_speed.push_back(speed); - } - - m_used_filament_length.resize(std::max(m_used_filament_length.size(), idx + 1)); // makes sure that the vector is big enough so we don't have to check later - } - + void set_extruder(size_t idx, const PrintConfig& config); // Appends into internal structure m_plan containing info about the future wipe tower // to be used before building begins. The entries must be added ordered in z. @@ -263,7 +192,6 @@ private: SHAPE_REVERSED = -1 }; - const bool m_peters_wipe_tower = false; // sparse wipe tower inspired by Peter's post processor - not finished yet const float Width_To_Nozzle_Ratio = 1.25f; // desired line width (oval) in multiples of nozzle diameter - may not be actually neccessary to adjust const float WT_EPSILON = 1e-3f; @@ -295,6 +223,13 @@ private: bool m_adhesion = true; GCodeFlavor m_gcode_flavor; + // Bed properties + enum { + RectangularBed, + CircularBed + } m_bed_shape; + float m_bed_width; // width of the bed bounding box + float m_perimeter_width = 0.4f * Width_To_Nozzle_Ratio; // Width of an extrusion line, also a perimeter spacing for 100% infill. float m_extrusion_flow = 0.038f; //0.029f;// Extrusion flow is derived from m_perimeter_width, layer height and filament diameter. diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index e376f54c3..e875db1dc 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -1762,15 +1762,7 @@ void Print::_make_wipe_tower() this->throw_if_canceled(); // Initialize the wipe tower. - WipeTower wipe_tower( - m_config.single_extruder_multi_material.value, - float(m_config.wipe_tower_x.value), float(m_config.wipe_tower_y.value), - float(m_config.wipe_tower_width.value), - float(m_config.wipe_tower_rotation_angle.value), float(m_config.cooling_tube_retraction.value), - float(m_config.cooling_tube_length.value), float(m_config.parking_pos_retraction.value), - float(m_config.extra_loading_move.value), float(m_config.wipe_tower_bridging), - m_config.high_current_on_filament_swap.value, m_config.gcode_flavor, wipe_volumes, - m_wipe_tower_data.tool_ordering.first_extruder()); + WipeTower wipe_tower(m_config, wipe_volumes, m_wipe_tower_data.tool_ordering.first_extruder()); //wipe_tower.set_retract(); //wipe_tower.set_zhop(); @@ -1779,22 +1771,7 @@ void Print::_make_wipe_tower() for (size_t i = 0; i < number_of_extruders; ++ i) wipe_tower.set_extruder( - i, - m_config.filament_type.get_at(i), - m_config.temperature.get_at(i), - m_config.first_layer_temperature.get_at(i), - (float)m_config.filament_loading_speed.get_at(i), - (float)m_config.filament_loading_speed_start.get_at(i), - (float)m_config.filament_unloading_speed.get_at(i), - (float)m_config.filament_unloading_speed_start.get_at(i), - (float)m_config.filament_toolchange_delay.get_at(i), - m_config.filament_cooling_moves.get_at(i), - (float)m_config.filament_cooling_initial_speed.get_at(i), - (float)m_config.filament_cooling_final_speed.get_at(i), - m_config.filament_ramming_parameters.get_at(i), - (float)m_config.filament_max_volumetric_speed.get_at(i), - (float)m_config.nozzle_diameter.get_at(i), - (float)m_config.filament_diameter.get_at(i)); + i, m_config); m_wipe_tower_data.priming = Slic3r::make_unique>( wipe_tower.prime((float)this->skirt_first_layer_height(), m_wipe_tower_data.tool_ordering.all_extruders(), false));