Skip to content

Commit

Permalink
PrusaSlicer 2.4.0 with Dribbling C01 inside
Browse files Browse the repository at this point in the history
  • Loading branch information
antimix authored and Votre Nom committed Jan 2, 2022
1 parent 215e845 commit d3c5e3f
Show file tree
Hide file tree
Showing 10 changed files with 307 additions and 8 deletions.
34 changes: 33 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,43 @@

![PrusaSlicer logo](/resources/icons/PrusaSlicer.png?raw=true)

# PrusaSlicer
# PrusaSlicer 2.4.0 DRIBBLING V.B01

This is a Fork of the PrusaSlicer 2.4.0
You may want to check the [PrusaSlicer project page](https://www.prusa3d.com/prusaslicer/).
Prebuilt Windows, OSX and Linux binaries are available through the [git releases page](https://github.com/prusa3d/PrusaSlicer/releases) or from the [Prusa3D downloads page](https://www.prusa3d.com/drivers/). There are also [3rd party Linux builds available](https://github.com/prusa3d/PrusaSlicer/wiki/PrusaSlicer-on-Linux---binary-distributions).

## What are the PrusaSlicer's DRIBBLING features compared to the original PrusaSlicer?

PrusaSlicer DRIBBLING version **is capable to produce better filament tips during MMU2 filament change with wipe tower, and to handle transitions from materials with different melting temperatures in multicolor mode (e.g. PLA to PETG, PLA to ABS, etc.)**
I had developed it especially for PLA filaments, in order to use bad quality / low cost filaments spools with MMU2.

### Where are those features ?

On the `Print settings` tab, selecting Multiple Extruders on the left, you can find a new checkbox in Advanced group:

- **DRIBBLING MODE** (on/off) -> if you do not enable dribbling mode, it works exactly as the standard PrusaSlicer.
If Dribbling mode is enabled, during the MMU2S filament change, just before extracting the filament, it plays with the filament doing a sort of dribbling and each hit of the filament in the melting area shapes the head almost squared, limiting the strings and strange big balls shapes to the minimum.

On the `Filament settings` tab, there are 3 new fields in the Temperature group:

- **MANUFACTURER MIN TEMP° and MAX TEMP°** -> Those are the manufacturer printing specification **temperature** (in C°) of the filament, normally printed on the roll.
Normally under the MIN TEMP the filament does not melt, and over the MAX TEMP the filament degrades or burn.

- **DRIBBLING TIP SHAPE** temperature -> This is the ideal **temperature** (in C°) at which the tip shaping comes better. It is a matter of experimentation, and each filament could be different.

On the `Filament settings` tab, selecting Advanced on the left, you can find a new parameter in Toolchange Parameters with single extruder MM printers group:

- **NUMBER OF DRIBBLING MOVES** -> This number represent how many times the filament is Dribbled up and down hitting the melted area to perform the perfect tip shape. A reasonable number is between 1 and 4.

On the `Printer settings` tab, selecting Single Extruder MM setup on the left, you can find a new parameter:

- **MELTING DISTANCE** (do not change) -> It represents how many mm the filament is dropped down from the rest position to just hit the melted area. This should allow to just hit the melted surface and not going deep into it.


*See a close-up picture of some filament heads I got during a MMU2 multicolour print.*
![heads](/heads.jpg?raw=true)

PrusaSlicer takes 3D models (STL, OBJ, AMF) and converts them into G-code
instructions for FFF printers or PNG layers for mSLA 3D printers. It's
compatible with any modern printer based on the RepRap toolchain, including all
Expand Down
Binary file added heads.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
158 changes: 157 additions & 1 deletion src/libslic3r/GCode/WipeTower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,19 @@ class WipeTowerWriter
return *this;
}

// dribbling
// Wait for a period of time (milliseconds).
WipeTowerWriter& waitmills(float time)
{
if (time==0)
return *this;
char buf[128];
sprintf(buf, "G4 P%.3f\n", time);
m_gcode += buf;
return *this;
};
// dribbling

// Set speed factor override percentage.
WipeTowerWriter& speed_override(int speed)
{
Expand Down Expand Up @@ -527,6 +540,7 @@ WipeTower::WipeTower(const PrintConfig& config, const std::vector<std::vector<fl
m_parking_pos_retraction = float(config.parking_pos_retraction);
m_extra_loading_move = float(config.extra_loading_move);
m_set_extruder_trimpot = config.high_current_on_filament_swap;
m_dribbling_enabled = bool(config.dribbling_enabled.value);
}
// Calculate where the priming lines should be - very naive test not detecting parallelograms etc.
const std::vector<Vec2d>& bed_points = config.bed_shape.values;
Expand Down Expand Up @@ -574,6 +588,13 @@ void WipeTower::set_extruder(size_t idx, const PrintConfig& config)
m_filpar[idx].cooling_moves = config.filament_cooling_moves.get_at(idx);
m_filpar[idx].cooling_initial_speed = float(config.filament_cooling_initial_speed.get_at(idx));
m_filpar[idx].cooling_final_speed = float(config.filament_cooling_final_speed.get_at(idx));
// dribbling
m_filpar[idx].dribbling_meltingzone = float(config.dribbling_meltingzone);
m_filpar[idx].dribbling_moves = int(config.dribbling_moves.get_at(idx));
m_filpar[idx].dribbling_temperature = int(config.dribbling_temperature.get_at(idx));
m_filpar[idx].filament_mintemp = int(config.filament_mintemp.get_at(idx));
m_filpar[idx].filament_maxtemp = int(config.filament_maxtemp.get_at(idx));
// dribbling
}

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
Expand Down Expand Up @@ -757,6 +778,40 @@ WipeTower::ToolChangeResult WipeTower::tool_change(size_t tool)
if (tool != (unsigned int)-1){ // This is not the last change.
toolchange_Unload(writer, cleaning_box, m_filpar[m_current_tool].material,
is_first_layer() ? m_filpar[tool].first_layer_temperature : m_filpar[tool].temperature);
// dribbling

unsigned int common_temp_L;
unsigned int common_temp_H;
if ((m_semm == true) && (m_dribbling_enabled == true))
{
if (m_filpar[m_current_tool].filament_maxtemp > m_filpar[tool].filament_maxtemp)
{ common_temp_L = m_filpar[m_current_tool].filament_mintemp;
common_temp_H = m_filpar[tool].filament_maxtemp;
}
else
if (m_filpar[m_current_tool].filament_maxtemp > m_filpar[tool].filament_mintemp)
{
common_temp_L = m_filpar[tool].filament_mintemp;
common_temp_H = m_filpar[m_current_tool].filament_maxtemp;
}
else
{
// cleaning filament required....
common_temp_L = m_filpar[tool].filament_mintemp;
common_temp_H = m_filpar[tool].filament_mintemp;
}
}

toolchange_Change(writer, tool, m_filpar[tool].material); // Change the tool, set a speed override for soluble and flex materials.

// dribbling
if ((m_semm == true) && (m_dribbling_enabled == true)) {
writer.append(";--------------------\n"
"; SET COMMON TEMPERATURE to use between two different materials\n");
writer.comment_with_value(" Common flushing temperature =", common_temp_H);
writer.set_extruder_temp(common_temp_H, true);
writer.append(";--------------------\n");
}
toolchange_Change(writer, tool, m_filpar[tool].material); // Change the tool, set a speed override for soluble and flex materials.
toolchange_Load(writer, cleaning_box);
writer.travel(writer.x(), writer.y()-m_perimeter_width); // cooling and loading were done a bit down the road
Expand All @@ -776,6 +831,12 @@ WipeTower::ToolChangeResult WipeTower::tool_change(size_t tool)
.append("; CP TOOLCHANGE END\n"
";------------------\n"
"\n\n");
// dribbling
if ((m_semm == true) && (m_dribbling_enabled == true)) {
writer.append(";------ SET AGAIN CORRECT LAYER TEMP --------------\n");
writer.set_extruder_temp(is_first_layer() ? m_filpar[m_current_tool].first_layer_temperature : m_filpar[m_current_tool].temperature, false);
}
// dribbling ***

// Ask our writer about how much material was consumed:
if (m_current_tool < m_used_filament_length.size())
Expand Down Expand Up @@ -840,6 +901,13 @@ void WipeTower::toolchange_Unload(

writer.disable_linear_advance();

if ((m_semm == true) && (m_dribbling_enabled == true)) {
writer.append(";--------------------\n"
"; SET DRIBBLING SHAPING TEMPERATURE\n");
writer.set_extruder_temp(m_filpar[m_current_tool].dribbling_temperature, false);
writer.append(";--------------------\n");
}

// now the ramming itself:
while (i < m_filpar[m_current_tool].ramming_speed.size())
{
Expand Down Expand Up @@ -869,12 +937,88 @@ void WipeTower::toolchange_Unload(
float turning_point = (!m_left_to_right ? xl : xr );
if (m_semm && (m_cooling_tube_retraction != 0 || m_cooling_tube_length != 0)) {
float total_retraction_distance = m_cooling_tube_retraction + m_cooling_tube_length/2.f - 15.f; // the 15mm is reserved for the first part after ramming
writer.suppress_preview()
if ((m_semm == false) || (m_dribbling_enabled == false)) {
writer.append("; START PRUSA standard Retraction GCODE\n");
writer.suppress_preview()
.retract(15.f, m_filpar[m_current_tool].unloading_speed_start * 60.f) // feedrate 5000mm/min = 83mm/s
.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)
.resume_preview();
writer.append("; END Retraction GCODE\n");
}
else
{
writer.append(";--------------------\n"
"; START Dribbling GCODE\n");
writer.suppress_preview();

// go to the left border
writer.travel(xl, writer.y());
old_x = writer.x();
turning_point = xr - old_x > old_x - xl ? xr : xl;

float dribbling_meltingzone = m_filpar[m_current_tool].dribbling_meltingzone; // from the end of PTFE Tube
int dribbling_moves = m_filpar[m_current_tool].dribbling_moves;
int dribbling_temperature = m_filpar[m_current_tool].dribbling_temperature;
int filament_mintemp = m_filpar[m_current_tool].filament_mintemp;
int filament_maxtemp = m_filpar[m_current_tool].filament_maxtemp;
float dribbling_distance = dribbling_meltingzone * 3.f; // 25mm

int dribbling_tictac = 50;
float dr_offset = 2.0f; // initial break dribbling distance
float speed = m_filpar[m_current_tool].cooling_initial_speed;

// dribbling
/*
// Extract inital
for (int i = 0; i < dribbling_tictac; ++i) {
writer.retract(0.10f * dr_offset, 0.40f * m_filpar[m_current_tool].unloading_speed_start * 60.f) // feedrate 5000mm/min = 83mm/s
.retract(0.20f * dr_offset, 0.30f * m_filpar[m_current_tool].unloading_speed_start * 60.f) // feedrate 5000mm/min = 83mm/s
.retract(0.30f * dr_offset, 0.20f * m_filpar[m_current_tool].unloading_speed_start * 60.f) // feedrate 5000mm/min = 83mm/s
.retract(0.40f * dr_offset, 0.10f * m_filpar[m_current_tool].unloading_speed_start * 60.f) // feedrate 5000mm/min = 83mm/s
.waitmills(10);
writer.retract(-0.40f * dr_offset, 0.10f * m_filpar[m_current_tool].unloading_speed_start * 60.f) // feedrate 5000mm/min = 83mm/s
.retract(-0.30f * dr_offset, 0.20f * m_filpar[m_current_tool].unloading_speed_start * 60.f) // feedrate 5000mm/min = 83mm/s
.retract(-0.20f * dr_offset, 0.30f * m_filpar[m_current_tool].unloading_speed_start * 60.f) // feedrate 5000mm/min = 83mm/s
.retract(-0.10f * dr_offset, 0.40f * m_filpar[m_current_tool].unloading_speed_start * 60.f) // feedrate 5000mm/min = 83mm/s
.waitmills(10);
}
*/
writer.retract(0.40f * dribbling_distance, m_filpar[m_current_tool].unloading_speed_start * 60.f) // feedrate 5000mm/min = 83mm/s
.retract(0.30f * dribbling_distance, 1.0f * m_filpar[m_current_tool].unloading_speed * 60.f)
.retract(0.20f * dribbling_distance, 0.5f * m_filpar[m_current_tool].unloading_speed * 60.f)
.retract(0.10f * dribbling_distance, 0.3f * m_filpar[m_current_tool].unloading_speed * 60.f);

writer.load_move_x_advanced(turning_point, -(dribbling_distance / 2), speed * 0.40f);
writer.load_move_x_advanced(old_x, (dribbling_distance / 2), speed * 0.40f);

for (int i = 0; i < dribbling_moves; ++i) {
for (int j = 0; j < 1; ++j) {
// Insert 1
writer.retract(-0.10f * dribbling_distance, 0.3f * m_filpar[m_current_tool].unloading_speed * 60.f)
.retract(-0.20f * dribbling_distance, 0.5f * m_filpar[m_current_tool].unloading_speed * 60.f)
.retract(-0.30f * dribbling_distance, 1.0f * m_filpar[m_current_tool].unloading_speed * 60.f)
.retract(-0.40f * dribbling_distance, m_filpar[m_current_tool].unloading_speed_start * 60.f) // feedrate 5000mm/min = 83mm/s
.waitmills(100)

// Extract 2
.retract(0.40f * dribbling_distance, m_filpar[m_current_tool].unloading_speed_start * 60.f) // feedrate 5000mm/min = 83mm/s
.retract(0.30f * dribbling_distance, 1.0f * m_filpar[m_current_tool].unloading_speed * 60.f)
.retract(0.20f * dribbling_distance, 0.5f * m_filpar[m_current_tool].unloading_speed * 60.f)
.retract(0.10f * dribbling_distance, 0.3f * m_filpar[m_current_tool].unloading_speed * 60.f)
.waitmills(500);
}
writer.append("; ---\n");
}

float total_dribbling_distance = m_cooling_tube_retraction + (m_cooling_tube_length / 2.f) - 15.f - dribbling_distance; // the 15mm is reserved for the first part after ramming
writer.retract(total_dribbling_distance, 0.3f * m_filpar[m_current_tool].unloading_speed * 60.f)
.resume_preview();
writer.append("; END Dribbling GCODE\n"
";----------------------\n");
}
}
// Wipe tower should only change temperature with single extruder MM. Otherwise, all temperatures should
// be already set and there is no need to change anything. Also, the temperature could be changed
Expand Down Expand Up @@ -908,6 +1052,18 @@ void WipeTower::toolchange_Unload(
}
}

// Wipe tower should only change temperature with single extruder MM. Otherwise, all temperatures should
// be already set and there is no need to change anything. Also, the temperature could be changed
// for wrong extruder.
if ((m_semm) && (m_dribbling_enabled == false)) {
if (new_temperature != 0 && (new_temperature != m_old_temperature || is_first_layer()) ) { // Set the extruder temperature, but don't wait.
// If the required temperature is the same as last time, don't emit the M104 again (if user adjusted the value, it would be reset)
// However, always change temperatures on the first layer (this is to avoid issues with priming lines turned off).
writer.set_extruder_temp(new_temperature, false);
m_old_temperature = new_temperature;
}
}

// let's wait is necessary:
writer.wait(m_filpar[m_current_tool].delay);
// we should be at the beginning of the cooling tube again - let's move to parking position:
Expand Down
8 changes: 8 additions & 0 deletions src/libslic3r/GCode/WipeTower.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,13 @@ class WipeTower
std::vector<float> ramming_speed;
float nozzle_diameter;
float filament_area;
// dribbling
float dribbling_meltingzone = 8.f ;
int dribbling_moves = 1 ;
int dribbling_temperature = 0 ;
int filament_mintemp = 0 ;
int filament_maxtemp = 0 ;
// dribbling
};

private:
Expand Down Expand Up @@ -261,6 +268,7 @@ class WipeTower
float m_travel_speed = 0.f;
float m_first_layer_speed = 0.f;
size_t m_first_layer_idx = size_t(-1);
bool m_dribbling_enabled = false;

// G-code generator parameters.
float m_cooling_tube_retraction = 0.f;
Expand Down
18 changes: 14 additions & 4 deletions src/libslic3r/Preset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,7 @@ static std::vector<std::string> s_Preset_print_options {
"support_material_buildplate_only", "dont_support_bridges", "thick_bridges", "notes", "complete_objects", "extruder_clearance_radius",
"extruder_clearance_height", "gcode_comments", "gcode_label_objects", "output_filename_format", "post_process", "perimeter_extruder",
"infill_extruder", "solid_infill_extruder", "support_material_extruder", "support_material_interface_extruder",
"ooze_prevention", "standby_temperature_delta", "interface_shells", "extrusion_width", "first_layer_extrusion_width",
"ooze_prevention", "standby_temperature_delta", "interface_shells", "dribbling_enabled", "extrusion_width", "first_layer_extrusion_width",
"perimeter_extrusion_width", "external_perimeter_extrusion_width", "infill_extrusion_width", "solid_infill_extrusion_width",
"top_infill_extrusion_width", "support_material_extrusion_width", "infill_overlap", "infill_anchor", "infill_anchor_max", "bridge_flow_ratio", "clip_multipart_objects",
"elefant_foot_compensation", "xy_size_compensation", "threads", "resolution", "gcode_resolution", "wipe_tower", "wipe_tower_x", "wipe_tower_y",
Expand All @@ -451,9 +451,19 @@ static std::vector<std::string> s_Preset_print_options {

static std::vector<std::string> s_Preset_filament_options {
"filament_colour", "filament_diameter", "filament_type", "filament_soluble", "filament_notes", "filament_max_volumetric_speed",
"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",
// dribbling
"filament_mintemp",
"filament_maxtemp",
// dribbling
"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_cooling_initial_speed", "filament_cooling_final_speed", "filament_ramming_parameters", "filament_minimal_purge_on_wipe_tower",
"filament_cooling_initial_speed", "filament_cooling_final_speed",
// dribbling start
"dribbling_moves",
"dribbling_temperature",
// dribbling end
"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",
"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",
Expand Down Expand Up @@ -481,7 +491,7 @@ static std::vector<std::string> s_Preset_printer_options {
"single_extruder_multi_material", "start_gcode", "end_gcode", "before_layer_gcode", "layer_gcode", "toolchange_gcode",
"color_change_gcode", "pause_print_gcode", "template_custom_gcode",
"between_objects_gcode", "printer_vendor", "printer_model", "printer_variant", "printer_notes", "cooling_tube_retraction",
"cooling_tube_length", "high_current_on_filament_swap", "parking_pos_retraction", "extra_loading_move", "max_print_height",
"cooling_tube_length", "high_current_on_filament_swap", "parking_pos_retraction", "extra_loading_move", "dribbling_meltingzone", "max_print_height",
"default_print_profile", "inherits",
"remaining_times", "silent_mode",
"machine_limits_usage", "thumbnails"
Expand Down
Loading

0 comments on commit d3c5e3f

Please sign in to comment.