diff --git a/resources/calibration/retraction/retraction.html b/resources/calibration/retraction/retraction.html
new file mode 100644
index 000000000..7a745d4d9
--- /dev/null
+++ b/resources/calibration/retraction/retraction.html
@@ -0,0 +1,31 @@
+
+
+
+
+ Retraction Calibration
+
+
+
+
+
+
+
+Retraction Calibration
+ |
+
+
+
+ |
+
+
+
+it's preferable to have done the flow and temperature calibration.
+This calibration will help you to choose the right retraction legnth for your extrudr and the current filament.
+This test will print some retraction test patches
+
The goal is to choose the highest temperature possible that doesn't produce artifacts.
+First, you have to analyse the tower. Each floor has the according temperature written on it.
+Notes
+The retraction speed should be set to the maximum value your extruder/drivers/firmware can reliably support.
+
+
diff --git a/resources/calibration/retraction/retraction_calibration.amf b/resources/calibration/retraction/retraction_calibration.amf
new file mode 100644
index 000000000..f465c9a1c
Binary files /dev/null and b/resources/calibration/retraction/retraction_calibration.amf differ
diff --git a/resources/calibration/retraction/retraction_calibration_pillar.amf b/resources/calibration/retraction/retraction_calibration_pillar.amf
new file mode 100644
index 000000000..9ae58aa06
Binary files /dev/null and b/resources/calibration/retraction/retraction_calibration_pillar.amf differ
diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp
index 18496ce51..e0af20a63 100644
--- a/src/libslic3r/GCode.cpp
+++ b/src/libslic3r/GCode.cpp
@@ -234,9 +234,12 @@ std::string Wipe::wipe(GCode &gcodegen, bool toolchange)
double wipe_speed = gcodegen.writer().config.travel_speed.value * 0.8;
// get the retraction length
- double length = toolchange
- ? gcodegen.writer().tool()->retract_length_toolchange()
- : gcodegen.writer().tool()->retract_length();
+ double length = gcodegen.writer().tool()->retract_length();
+ if (toolchange) {
+ length = gcodegen.writer().tool()->retract_length_toolchange();
+ } else if (gcodegen.writer().config_region && gcodegen.writer().config_region->print_retract_length.value >= 0) {
+ length = gcodegen.writer().config_region->print_retract_length.value;
+ }
// Shorten the retraction length by the amount already retracted before wipe.
length *= (1. - gcodegen.writer().tool()->retract_before_wipe());
@@ -2501,7 +2504,7 @@ void GCode::process_layer(
m_layer = layers[instance_to_print.layer_id].layer();
}
for (ObjectByExtruder::Island &island : instance_to_print.object_by_extruder.islands) {
- const auto& by_region_specific =
+ const std::vector& by_region_specific =
is_anything_overridden ?
island.by_region_per_copy(by_region_per_copy_cache,
static_cast(instance_to_print.instance_id),
@@ -3732,8 +3735,9 @@ std::string GCode::extrude_perimeters(const Print &print, const std::vectorconfig());
+ m_writer.apply_print_region_config(print.regions()[®ion - &by_region.front()]->config());
for (const ExtrusionEntity *ee : region.perimeters)
gcode += this->extrude_entity(*ee, "", -1., &lower_layer_edge_grid);
}
@@ -3745,8 +3749,9 @@ std::string GCode::extrude_infill(const Print &print, const std::vectorconfig().infill_first == is_infill_first) {
+ if (!region.infills.empty() && print.regions()[®ion - &by_region.front()]->config().infill_first == is_infill_first) {
m_config.apply(print.regions()[®ion - &by_region.front()]->config());
+ m_writer.apply_print_region_config(print.regions()[®ion - &by_region.front()]->config());
ExtrusionEntitiesPtr extrusions { region.infills };
chain_and_reorder_extrusion_entities(extrusions, &m_last_pos);
for (const ExtrusionEntity *fill : extrusions) {
diff --git a/src/libslic3r/GCodeWriter.cpp b/src/libslic3r/GCodeWriter.cpp
index 1ac899f77..a9bdefdf0 100644
--- a/src/libslic3r/GCodeWriter.cpp
+++ b/src/libslic3r/GCodeWriter.cpp
@@ -26,6 +26,11 @@ void GCodeWriter::apply_print_config(const PrintConfig &print_config)
print_config.machine_max_acceleration_extruding.values.front() : 0);
}
+void GCodeWriter::apply_print_region_config(const PrintRegionConfig& print_region_config)
+{
+ config_region = &print_region_config;
+}
+
void GCodeWriter::set_extruders(std::vector extruder_ids)
{
std::sort(extruder_ids.begin(), extruder_ids.end());
@@ -474,6 +479,14 @@ std::string GCodeWriter::retract(bool before_wipe)
{
double factor = before_wipe ? m_tool->retract_before_wipe() : 1.;
assert(factor >= 0. && factor <= 1. + EPSILON);
+ //check for override
+ if (config_region && config_region->print_retract_length >= 0) {
+ return this->_retract(
+ factor * config_region->print_retract_length,
+ factor * m_tool->retract_restart_extra(),
+ "retract"
+ );
+ }
return this->_retract(
factor * m_tool->retract_length(),
factor * m_tool->retract_restart_extra(),
diff --git a/src/libslic3r/GCodeWriter.hpp b/src/libslic3r/GCodeWriter.hpp
index 954fe4570..976b5e010 100644
--- a/src/libslic3r/GCodeWriter.hpp
+++ b/src/libslic3r/GCodeWriter.hpp
@@ -15,6 +15,8 @@ public:
static std::string PausePrintCode;
GCodeConfig config;
bool multiple_extruders;
+ // override from region
+ const PrintRegionConfig* config_region = nullptr;
GCodeWriter() :
multiple_extruders(false), m_extrusion_axis("E"), m_tool(nullptr),
@@ -28,6 +30,7 @@ public:
std::string extrusion_axis() const { return m_extrusion_axis; }
void apply_print_config(const PrintConfig &print_config);
+ void apply_print_region_config(const PrintRegionConfig& print_region_config);
// Extruders are expected to be sorted in an increasing order.
void set_extruders(std::vector extruder_ids);
const std::vector& extruders() const { return m_extruders; }
diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp
index d50985bb7..3f605079a 100644
--- a/src/libslic3r/PrintConfig.cpp
+++ b/src/libslic3r/PrintConfig.cpp
@@ -2463,6 +2463,7 @@ void PrintConfigDef::init_fff_params()
def->tooltip = L("Retraction is not triggered when travel moves are shorter than this length.");
def->sidetext = L("mm");
def->mode = comAdvanced;
+ def->min = 0;
def->set_default_value(new ConfigOptionFloats { 2. });
def = this->add("retract_before_wipe", coPercents);
@@ -2488,8 +2489,16 @@ void PrintConfigDef::init_fff_params()
def->tooltip = L("When retraction is triggered, filament is pulled back by the specified amount "
"(the length is measured on raw filament, before it enters the extruder).");
def->sidetext = L("mm (zero to disable)");
+ def->min = 0;
def->set_default_value(new ConfigOptionFloats { 2. });
+ def = this->add("print_retract_length", coFloat);
+ def->label = L("Retraction length");
+ def->category = OptionCategory::width;
+ def->tooltip = L("Override the retract_length settign from the printer config. Used for calibration. Set negative to disable");
+ def->mode = comExpert;
+ def->set_default_value(new ConfigOptionFloat( -1.f));
+
def = this->add("retract_length_toolchange", coFloats);
def->label = L("Length");
def->full_label = L("Retraction Length (Toolchange)");
@@ -2498,6 +2507,7 @@ void PrintConfigDef::init_fff_params()
"the extruder).");
def->sidetext = L("mm (zero to disable)");
def->mode = comExpert;
+ def->min = 0;
def->set_default_value(new ConfigOptionFloats { 10. });
def = this->add("retract_lift", coFloats);
diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp
index 698b3d3d0..ebf341e35 100644
--- a/src/libslic3r/PrintConfig.hpp
+++ b/src/libslic3r/PrintConfig.hpp
@@ -681,6 +681,7 @@ public:
// Total number of perimeters.
ConfigOptionInt perimeters;
ConfigOptionPercent print_extrusion_multiplier;
+ ConfigOptionFloat print_retract_length;
ConfigOptionFloatOrPercent small_perimeter_speed;
ConfigOptionEnum solid_fill_pattern;
ConfigOptionFloat solid_infill_below_area;
@@ -768,6 +769,7 @@ protected:
OPT_PTR(perimeter_speed);
OPT_PTR(perimeters);
OPT_PTR(print_extrusion_multiplier);
+ OPT_PTR(print_retract_length);
OPT_PTR(small_perimeter_speed);
OPT_PTR(solid_fill_pattern);
OPT_PTR(solid_infill_below_area);
diff --git a/src/libslic3r/SVG.cpp b/src/libslic3r/SVG.cpp
index 6e4b973ea..1bebfe797 100644
--- a/src/libslic3r/SVG.cpp
+++ b/src/libslic3r/SVG.cpp
@@ -154,16 +154,30 @@ SVG::draw_outline(const Surfaces &surfaces, std::string stroke_outer, std::strin
}
void
-SVG::draw(const SurfacesPtr &surfaces, std::string fill, const float fill_opacity)
+SVG::draw(const SurfacesPtr& surfaces, std::string fill, const float fill_opacity)
{
for (SurfacesPtr::const_iterator it = surfaces.begin(); it != surfaces.end(); ++it)
this->draw(*(*it), fill, fill_opacity);
}
-void
-SVG::draw_outline(const SurfacesPtr &surfaces, std::string stroke_outer, std::string stroke_holes, coordf_t stroke_width)
+void
+SVG::draw_outline(const SurfacesPtr& surfaces, std::string stroke_outer, std::string stroke_holes, coordf_t stroke_width)
{
- for (SurfacesPtr::const_iterator it = surfaces.begin(); it != surfaces.end(); ++ it)
+ for (SurfacesPtr::const_iterator it = surfaces.begin(); it != surfaces.end(); ++it)
+ draw_outline(*(*it), stroke_outer, stroke_holes, stroke_width);
+}
+
+void
+SVG::draw(const SurfacesConstPtr& surfaces, std::string fill, const float fill_opacity)
+{
+ for (SurfacesConstPtr::const_iterator it = surfaces.begin(); it != surfaces.end(); ++it)
+ this->draw(*(*it), fill, fill_opacity);
+}
+
+void
+SVG::draw_outline(const SurfacesConstPtr& surfaces, std::string stroke_outer, std::string stroke_holes, coordf_t stroke_width)
+{
+ for (SurfacesConstPtr::const_iterator it = surfaces.begin(); it != surfaces.end(); ++it)
draw_outline(*(*it), stroke_outer, stroke_holes, stroke_width);
}
diff --git a/src/libslic3r/SVG.hpp b/src/libslic3r/SVG.hpp
index c1b387554..780f2e0ea 100644
--- a/src/libslic3r/SVG.hpp
+++ b/src/libslic3r/SVG.hpp
@@ -53,8 +53,10 @@ public:
void draw_outline(const Surface &surface, std::string stroke_outer = "black", std::string stroke_holes = "blue", coordf_t stroke_width = 0);
void draw(const Surfaces &surfaces, std::string fill = "grey", const float fill_opacity=1.f);
void draw_outline(const Surfaces &surfaces, std::string stroke_outer = "black", std::string stroke_holes = "blue", coordf_t stroke_width = 0);
- void draw(const SurfacesPtr &surfaces, std::string fill = "grey", const float fill_opacity=1.f);
- void draw_outline(const SurfacesPtr &surfaces, std::string stroke_outer = "black", std::string stroke_holes = "blue", coordf_t stroke_width = 0);
+ void draw(const SurfacesPtr& surfaces, std::string fill = "grey", const float fill_opacity = 1.f);
+ void draw_outline(const SurfacesPtr& surfaces, std::string stroke_outer = "black", std::string stroke_holes = "blue", coordf_t stroke_width = 0);
+ void draw(const SurfacesConstPtr& surfaces, std::string fill = "grey", const float fill_opacity = 1.f);
+ void draw_outline(const SurfacesConstPtr& surfaces, std::string stroke_outer = "black", std::string stroke_holes = "blue", coordf_t stroke_width = 0);
void draw(const Polygon &polygon, std::string fill = "grey");
void draw_outline(const Polygon &polygon, std::string stroke = "black", coordf_t stroke_width = 0);
diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt
index 82dfc3a17..bd9136981 100644
--- a/src/slic3r/CMakeLists.txt
+++ b/src/slic3r/CMakeLists.txt
@@ -32,6 +32,8 @@ set(SLIC3R_GUI_SOURCES
GUI/CalibrationOverBridgeDialog.hpp
GUI/CalibrationTempDialog.cpp
GUI/CalibrationTempDialog.hpp
+ GUI/CalibrationRetractionDialog.cpp
+ GUI/CalibrationRetractionDialog.hpp
GUI/ConfigSnapshotDialog.cpp
GUI/ConfigSnapshotDialog.hpp
GUI/3DScene.cpp
diff --git a/src/slic3r/GUI/CalibrationOverBridgeDialog.cpp b/src/slic3r/GUI/CalibrationOverBridgeDialog.cpp
index 1e58a7f4b..7418ed7b2 100644
--- a/src/slic3r/GUI/CalibrationOverBridgeDialog.cpp
+++ b/src/slic3r/GUI/CalibrationOverBridgeDialog.cpp
@@ -41,11 +41,11 @@ void CalibrationOverBridgeDialog::create_geometry(wxCommandEvent& event_args) {
assert(objs_idx.size() == 6);
const DynamicPrintConfig* print_config = this->gui_app->get_tab(Preset::TYPE_PRINT)->get_config();
- const DynamicPrintConfig* printerConfig = this->gui_app->get_tab(Preset::TYPE_PRINTER)->get_config();
+ const DynamicPrintConfig* printer_config = this->gui_app->get_tab(Preset::TYPE_PRINTER)->get_config();
/// --- scale ---
// model is created for a 0.4 nozzle, scale xy with nozzle size.
- const ConfigOptionFloats* nozzle_diameter_config = printerConfig->option("nozzle_diameter");
+ const ConfigOptionFloats* nozzle_diameter_config = printer_config->option("nozzle_diameter");
assert(nozzle_diameter_config->values.size() > 0);
float nozzle_diameter = nozzle_diameter_config->values[0];
float xyz_scale = (0.2 + nozzle_diameter) / 0.6;
@@ -68,7 +68,7 @@ void CalibrationOverBridgeDialog::create_geometry(wxCommandEvent& event_args) {
/// --- translate ---;
const ConfigOptionFloat* extruder_clearance_radius = print_config->option("extruder_clearance_radius");
- const ConfigOptionPoints* bed_shape = printerConfig->option("bed_shape");
+ const ConfigOptionPoints* bed_shape = printer_config->option("bed_shape");
const float brim_width = print_config->option("brim_width")->getFloat();
Vec2d bed_size = BoundingBoxf(bed_shape->values).size();
Vec2d bed_min = BoundingBoxf(bed_shape->values).min;
diff --git a/src/slic3r/GUI/CalibrationRetractionDialog.cpp b/src/slic3r/GUI/CalibrationRetractionDialog.cpp
new file mode 100644
index 000000000..63e7bd3b8
--- /dev/null
+++ b/src/slic3r/GUI/CalibrationRetractionDialog.cpp
@@ -0,0 +1,248 @@
+#include "CalibrationRetractionDialog.hpp"
+#include "I18N.hpp"
+#include "libslic3r/Utils.hpp"
+#include "GUI.hpp"
+#include "GUI_ObjectList.hpp"
+#include "Tab.hpp"
+#include
+#include
+#include
+#include "wxExtensions.hpp"
+
+#if ENABLE_SCROLLABLE
+static wxSize get_screen_size(wxWindow* window)
+{
+ const auto idx = wxDisplay::GetFromWindow(window);
+ wxDisplay display(idx != wxNOT_FOUND ? idx : 0u);
+ return display.GetClientArea().GetSize();
+}
+#endif // ENABLE_SCROLLABLE
+
+namespace Slic3r {
+namespace GUI {
+
+void CalibrationRetractionDialog::create_buttons(wxStdDialogButtonSizer* buttons){
+ wxString choices_steps[] = { "0.1","0.2","0.5","1" };
+ steps = new wxComboBox(this, wxID_ANY, wxString{ "0.2" }, wxDefaultPosition, wxDefaultSize, 4, choices_steps);
+ steps->SetToolTip(_(L("Each militer add this value to the retraction value. ")));
+ steps->SetSelection(1);
+ wxString choices_nb[] = { "2","4","6","8","10","15","20","25" };
+ nb_steps = new wxComboBox(this, wxID_ANY, wxString{ "10" }, wxDefaultPosition, wxDefaultSize, 8, choices_nb);
+ nb_steps->SetToolTip(_(L("Select the number milimeters for the tower.")));
+ nb_steps->SetSelection(4);
+ //wxString choices_start[] = { "current","260","250","240","230","220","210" };
+ //start_step = new wxComboBox(this, wxID_ANY, wxString{ "current" }, wxDefaultPosition, wxDefaultSize, 7, choices_start);
+ //start_step->SetToolTip(_(L("Select the highest temperature to test for.")));
+ //start_step->SetSelection(0);
+ //wxString choices_decr[] = { "one test","2x10°","3x10°","4x10°","3x5°","5x5°" };
+ //decr_temp = new wxComboBox(this, wxID_ANY, wxString{ "current" }, wxDefaultPosition, wxDefaultSize, 6, choices_decr);
+ //decr_temp->SetToolTip(_(L("Select the number tower to print, and by how many degrees C to decrease each time.")));
+ //decr_temp->SetSelection(0);
+
+ buttons->Add(new wxStaticText(this, wxID_ANY, wxString{ "step:" }));
+ buttons->Add(steps);
+ buttons->AddSpacer(15);
+ buttons->Add(new wxStaticText(this, wxID_ANY, wxString{ "height:" }));
+ buttons->Add(nb_steps);
+ buttons->AddSpacer(20);
+
+ //buttons->Add(new wxStaticText(this, wxID_ANY, wxString{ "start temp:" }));
+ //buttons->Add(start_step);
+ //buttons->AddSpacer(15);
+ //buttons->Add(new wxStaticText(this, wxID_ANY, wxString{ "temp decr:" }));
+ //buttons->Add(decr_temp);
+ //buttons->AddSpacer(20);
+
+ wxButton* bt = new wxButton(this, wxID_FILE1, _(L("Remove fil. slowdown")));
+ bt->Bind(wxEVT_BUTTON, &CalibrationRetractionDialog::remove_slowdown, this);
+ buttons->Add(bt);
+
+ buttons->AddSpacer(30);
+
+ bt = new wxButton(this, wxID_FILE1, _(L("Generate")));
+ bt->Bind(wxEVT_BUTTON, &CalibrationRetractionDialog::create_geometry, this);
+ buttons->Add(bt);
+}
+
+void CalibrationRetractionDialog::remove_slowdown(wxCommandEvent& event_args) {
+
+ const DynamicPrintConfig* filament_config = this->gui_app->get_tab(Preset::TYPE_FILAMENT)->get_config();
+ DynamicPrintConfig new_filament_config = *filament_config; //make a copy
+
+ const ConfigOptionInts *fil_conf = filament_config->option("slowdown_below_layer_time");
+ ConfigOptionInts *new_fil_conf = new ConfigOptionInts();
+ new_fil_conf->default_value = 5;
+ new_fil_conf->values = fil_conf->values;
+ new_fil_conf->values[0] = 0;
+ new_filament_config.set_key_value("slowdown_below_layer_time", new_fil_conf);
+
+ fil_conf = filament_config->option("fan_below_layer_time"); new_fil_conf = new ConfigOptionInts();
+ new_fil_conf->default_value = 60;
+ new_fil_conf->values = fil_conf->values;
+ new_fil_conf->values[0] = 0;
+ new_filament_config.set_key_value("fan_below_layer_time", new_fil_conf);
+
+ this->gui_app->get_tab(Preset::TYPE_FILAMENT)->load_config(new_filament_config);
+ this->main_frame->plater()->on_config_change(new_filament_config);
+ this->gui_app->get_tab(Preset::TYPE_FILAMENT)->update_dirty();
+
+}
+
+void CalibrationRetractionDialog::create_geometry(wxCommandEvent& event_args) {
+ Plater* plat = this->main_frame->plater();
+ Model& model = plat->model();
+ plat->reset();
+
+ size_t nb_retract = nb_steps->GetSelection() < 4 ? ((int(nb_steps->GetSelection()) + 1) * 2) : ((int(nb_steps->GetSelection()) - 2) * 5);
+ size_t nb_items = 1;
+ //if (start_step->GetSelection() == 1) {
+ // nb_items = 2;
+ //} else if (start_step->GetSelection() == 2 || start_step->GetSelection() == 4) {
+ // nb_items = 3;
+ //} else if (start_step->GetSelection() == 3) {
+ // nb_items = 4;
+ //} else if (start_step->GetSelection() == 5) {
+ // nb_items = 5;
+ //}
+
+
+ std::vector items;
+ items.emplace_back(Slic3r::resources_dir() + "/calibration/retraction/retraction_calibration.amf");
+ std::vector objs_idx = plat->load_files(items, true, false, false);
+
+
+ assert(objs_idx.size() == nb_items);
+ const DynamicPrintConfig* print_config = this->gui_app->get_tab(Preset::TYPE_PRINT)->get_config();
+ const DynamicPrintConfig* printer_config = this->gui_app->get_tab(Preset::TYPE_PRINTER)->get_config();
+ const DynamicPrintConfig* filament_config = this->gui_app->get_tab(Preset::TYPE_FILAMENT)->get_config();
+
+ double retraction_start = 0;
+ int temp = filament_config->option("temperature")->get_at(0);
+
+ double retraction_steps = 0.01;
+ if (steps->GetSelection() == 0)
+ retraction_steps = 0.1;
+ if (steps->GetSelection() == 1)
+ retraction_steps = 0.2;
+ if (steps->GetSelection() == 2)
+ retraction_steps = 0.5;
+ if (steps->GetSelection() == 3)
+ retraction_steps = 1;
+ if (steps->GetSelection() == 4)
+ retraction_steps = 2;
+
+ /// --- scale ---
+ // model is created for a 0.4 nozzle, scale xy with nozzle size.
+ const ConfigOptionFloats* nozzle_diameter_config = printer_config->option("nozzle_diameter");
+ assert(nozzle_diameter_config->values.size() > 0);
+ float nozzle_diameter = nozzle_diameter_config->values[0];
+ float xyScale = nozzle_diameter / 0.4;
+ //scale z to have 6 layers
+ const ConfigOptionFloatOrPercent* first_layer_height_setting = print_config->option("first_layer_height");
+ double first_layer_height = first_layer_height_setting->get_abs_value(nozzle_diameter);
+ first_layer_height = nozzle_diameter / 2; //TODO remove and use the user's first_layer_height
+ double layer_height = nozzle_diameter / 2.;
+ first_layer_height = std::max(first_layer_height, nozzle_diameter / 2.);
+
+ float scale = nozzle_diameter / 0.4;
+ //do scaling
+ if (scale < 0.9 || 1.2 < scale) {
+ for (size_t i = 0; i < nb_items; i++)
+ model.objects[objs_idx[i]]->scale(scale, scale, scale);
+ }
+
+ //add sub-part after scale
+ float zshift = (1 - scale) / 2 + 0.4 * scale;
+ float zscale_number = (first_layer_height + layer_height) / 0.4;
+ std::vector part_tower;
+ //add_part(model.objects[objs_idx[0]], Slic3r::resources_dir()+"/calibration/filament_temp/t215.amf", Vec3d{ 0,0,zshift-5.2*scale }, Vec3d{ scale,scale,scale });
+ //model.objects[objs_idx[0]]->volumes[1]->rotate(PI/2, Vec3d(0, 0, 1));
+ //model.objects[objs_idx[0]]->volumes[1]->rotate(-PI / 2, Vec3d(1, 0, 0));
+ for (size_t num_retract = 0; num_retract < nb_retract; num_retract++) {
+ part_tower.push_back(add_part(model.objects[objs_idx[0]], Slic3r::resources_dir()+"/calibration/retraction/retraction_calibration_pillar.amf", Vec3d{ 0,0,zshift + scale * num_retract }, Vec3d{ scale,scale,scale }));
+ }
+
+ /// --- translate ---;
+ const ConfigOptionFloat* extruder_clearance_radius = print_config->option("extruder_clearance_radius");
+ const ConfigOptionPoints* bed_shape = printer_config->option("bed_shape");
+ const float brim_width = std::max(print_config->option("brim_width")->value, nozzle_diameter * 5.);
+ Vec2d bed_size = BoundingBoxf(bed_shape->values).size();
+ Vec2d bed_min = BoundingBoxf(bed_shape->values).min;
+ float offsety = 2 + 22 * 1 + extruder_clearance_radius->value + brim_width + (brim_width > extruder_clearance_radius->value ? brim_width - extruder_clearance_radius->value : 0);
+ model.objects[objs_idx[0]]->translate({ bed_min.x() + bed_size.x() / 2, bed_min.y() + bed_size.y() / 2, 0 });
+
+
+
+ /// --- custom config ---
+ for (size_t i = 0; i < nb_items; i++) {
+ //speed
+ double perimeter_speed = print_config->option("perimeter_speed")->value;
+ double external_perimeter_speed = print_config->option("external_perimeter_speed")->get_abs_value(perimeter_speed);
+ //filament test
+ //const ConfigOptionInts* fil_conf = filament_config->option("slowdown_below_layer_time");
+ //ConfigOptionInts* new_fil_conf = new ConfigOptionInts();
+ //new_fil_conf->default_value = 5;
+ //new_fil_conf->values = fil_conf->values;
+ //new_fil_conf->values[0] = 0;
+ //model.objects[objs_idx[i]]->config.set_key_value("slowdown_below_layer_time", new_fil_conf);
+ //fil_conf = filament_config->option("temperature");
+ //new_fil_conf = new ConfigOptionInts();
+ //new_fil_conf->values = fil_conf->values;
+ //new_fil_conf->values[0] = 150;
+ //model.objects[objs_idx[i]]->config.set_key_value("temperature", new_fil_conf);
+ //brim to have some time to build up pressure in the nozzle
+ model.objects[objs_idx[i]]->config.set_key_value("brim_width", new ConfigOptionFloat(0));
+ model.objects[objs_idx[i]]->config.set_key_value("perimeters", new ConfigOptionInt(2));
+ model.objects[objs_idx[i]]->config.set_key_value("external_perimeters_first", new ConfigOptionBool(false));
+ model.objects[objs_idx[i]]->config.set_key_value("bottom_solid_layers", new ConfigOptionInt(0));
+ model.objects[objs_idx[i]]->volumes[0]->config.set_key_value("bottom_solid_layers", new ConfigOptionInt(2));
+ //model.objects[objs_idx[i]]->volumes[1]->config.set_key_value("bottom_solid_layers", new ConfigOptionInt(2));
+ model.objects[objs_idx[i]]->config.set_key_value("top_solid_layers", new ConfigOptionInt(0));
+ model.objects[objs_idx[i]]->config.set_key_value("fill_density", new ConfigOptionPercent(0));
+ //model.objects[objs_idx[i]]->config.set_key_value("fill_pattern", new ConfigOptionEnum(ipRectilinear));
+ model.objects[objs_idx[i]]->config.set_key_value("only_one_perimeter_top", new ConfigOptionBool(false));
+ model.objects[objs_idx[i]]->config.set_key_value("overhangs", new ConfigOptionBool(false));
+ model.objects[objs_idx[i]]->config.set_key_value("thin_walls", new ConfigOptionBool(true));
+ model.objects[objs_idx[i]]->config.set_key_value("thin_walls_min_width", new ConfigOptionFloatOrPercent(2,true));
+ model.objects[objs_idx[i]]->config.set_key_value("gap_fill", new ConfigOptionBool(false));
+ model.objects[objs_idx[i]]->config.set_key_value("first_layer_height", new ConfigOptionFloatOrPercent(nozzle_diameter / 2., false));
+ model.objects[objs_idx[i]]->config.set_key_value("layer_height", new ConfigOptionFloat(nozzle_diameter / 2.));
+ //set retraction override
+ int num_part = 0;
+ for (ModelObject* part : part_tower) {
+ model.objects[objs_idx[i]]->volumes[num_part + 1]->config.set_key_value("print_retract_length", new ConfigOptionFloat(retraction_start + num_part * retraction_steps));
+ model.objects[objs_idx[i]]->volumes[num_part + 1]->config.set_key_value("small_perimeter_speed", new ConfigOptionFloatOrPercent(external_perimeter_speed, false));
+ model.objects[objs_idx[i]]->volumes[num_part + 1]->config.set_key_value("perimeter_speed", new ConfigOptionFloat(std::min(external_perimeter_speed, perimeter_speed)));
+ model.objects[objs_idx[i]]->volumes[num_part + 1]->config.set_key_value("external_perimeter_speed", new ConfigOptionFloatOrPercent(external_perimeter_speed, false));
+ model.objects[objs_idx[i]]->volumes[num_part + 1]->config.set_key_value("small_perimeter_speed", new ConfigOptionFloatOrPercent(external_perimeter_speed, false));
+ //model.objects[objs_idx[i]]->volumes[num_part + 1]->config.set_key_value("infill_speed", new ConfigOptionFloat(std::min(print_config->option("infill_speed")->value, 10.*scale)));
+ num_part++;
+ }
+ }
+
+ /// --- main config, please modify object config when possible ---
+ if (nb_items > 1) {
+ DynamicPrintConfig new_print_config = *print_config; //make a copy
+ new_print_config.set_key_value("complete_objects", new ConfigOptionBool(true));
+ //if skirt, use only one
+ if (print_config->option("skirts")->getInt() > 0 && print_config->option("skirt_height")->getInt() > 0) {
+ new_print_config.set_key_value("complete_objects_one_skirt", new ConfigOptionBool(true));
+ }
+ this->gui_app->get_tab(Preset::TYPE_PRINT)->load_config(new_print_config);
+ plat->on_config_change(new_print_config);
+ this->gui_app->get_tab(Preset::TYPE_PRINT)->update_dirty();
+ }
+
+ //update plater
+ plat->changed_objects(objs_idx);
+ //update everything, easier to code.
+ ObjectList* obj = this->gui_app->obj_list();
+ obj->update_after_undo_redo();
+
+
+ plat->reslice();
+ plat->select_view_3D("Preview");
+}
+
+} // namespace GUI
+} // namespace Slic3r
diff --git a/src/slic3r/GUI/CalibrationRetractionDialog.hpp b/src/slic3r/GUI/CalibrationRetractionDialog.hpp
new file mode 100644
index 000000000..1146ec7b7
--- /dev/null
+++ b/src/slic3r/GUI/CalibrationRetractionDialog.hpp
@@ -0,0 +1,30 @@
+#ifndef slic3r_GUI_CalibrationRetractionDialog_hpp_
+#define slic3r_GUI_CalibrationRetractionDialog_hpp_
+
+#include "CalibrationAbstractDialog.hpp"
+
+namespace Slic3r {
+namespace GUI {
+
+class CalibrationRetractionDialog : public CalibrationAbstractDialog
+{
+
+public:
+ CalibrationRetractionDialog(GUI_App* app, MainFrame* mainframe) : CalibrationAbstractDialog(app, mainframe, "Flow calibration") { create("/calibration/retraction/retraction.html", wxSize(900, 500)); }
+ virtual ~CalibrationRetractionDialog() {}
+
+protected:
+ void create_buttons(wxStdDialogButtonSizer* sizer) override;
+ void remove_slowdown(wxCommandEvent& event_args);
+ void create_geometry(wxCommandEvent& event_args);
+
+ wxComboBox* steps;
+ wxComboBox* nb_steps;
+ wxComboBox* start_step;
+ wxComboBox* decr_temp;
+};
+
+} // namespace GUI
+} // namespace Slic3r
+
+#endif
diff --git a/src/slic3r/GUI/CalibrationTempDialog.cpp b/src/slic3r/GUI/CalibrationTempDialog.cpp
index 7d72f0da9..b4874a01d 100644
--- a/src/slic3r/GUI/CalibrationTempDialog.cpp
+++ b/src/slic3r/GUI/CalibrationTempDialog.cpp
@@ -57,12 +57,12 @@ void CalibrationTempDialog::create_geometry(wxCommandEvent& event_args) {
Slic3r::resources_dir()+"/calibration/filament_temp/Smart_compact_temperature_calibration_item.amf"}, true, false, false);
assert(objs_idx.size() == 1);
- const DynamicPrintConfig* printConfig = this->gui_app->get_tab(Preset::TYPE_PRINT)->get_config();
- const DynamicPrintConfig* filamentConfig = this->gui_app->get_tab(Preset::TYPE_FILAMENT)->get_config();
- const DynamicPrintConfig* printerConfig = this->gui_app->get_tab(Preset::TYPE_PRINTER)->get_config();
+ const DynamicPrintConfig* print_config = this->gui_app->get_tab(Preset::TYPE_PRINT)->get_config();
+ const DynamicPrintConfig* filament_config = this->gui_app->get_tab(Preset::TYPE_FILAMENT)->get_config();
+ const DynamicPrintConfig* printer_config = this->gui_app->get_tab(Preset::TYPE_PRINTER)->get_config();
// -- get temps
- const ConfigOptionInts* temperature_config = filamentConfig->option("temperature");
+ const ConfigOptionInts* temperature_config = filament_config->option("temperature");
assert(temperature_config->values.size() >= 1);
int idx_steps = steps->GetSelection();
int idx_up = nb_up->GetSelection();
@@ -76,7 +76,7 @@ void CalibrationTempDialog::create_geometry(wxCommandEvent& event_args) {
/// --- scale ---
//model is created for a 0.4 nozzle, scale xy with nozzle size.
- const ConfigOptionFloats* nozzle_diameter_config = printerConfig->option("nozzle_diameter");
+ const ConfigOptionFloats* nozzle_diameter_config = printer_config->option("nozzle_diameter");
assert(nozzle_diameter_config->values.size() > 0);
float nozzle_diameter = nozzle_diameter_config->values[0];
float xyzScale = nozzle_diameter / 0.4;
@@ -107,13 +107,13 @@ void CalibrationTempDialog::create_geometry(wxCommandEvent& event_args) {
/// --- translate ---
- const ConfigOptionPoints* bed_shape = printerConfig->option("bed_shape");
+ const ConfigOptionPoints* bed_shape = printer_config->option("bed_shape");
Vec2d bed_size = BoundingBoxf(bed_shape->values).size();
Vec2d bed_min = BoundingBoxf(bed_shape->values).min;
model.objects[objs_idx[0]]->translate({ bed_min.x() + bed_size.x() / 2, bed_min.y() + bed_size.y() / 2, 0 });
/// --- main config, please modify object config when possible ---
- DynamicPrintConfig new_print_config = *printConfig; //make a copy
+ DynamicPrintConfig new_print_config = *print_config; //make a copy
new_print_config.set_key_value("complete_objects", new ConfigOptionBool(false));
/// -- generate the heat change gcode
@@ -129,7 +129,7 @@ void CalibrationTempDialog::create_geometry(wxCommandEvent& event_args) {
//new_printer_config.set_key_value("layer_gcode", new ConfigOptionString(str_layer_gcode));
/// --- custom config ---
- float brim_width = printConfig->option("brim_width")->value;
+ float brim_width = print_config->option("brim_width")->value;
if (brim_width < nozzle_diameter * 8) {
model.objects[objs_idx[0]]->config.set_key_value("brim_width", new ConfigOptionFloat(nozzle_diameter * 8));
}
@@ -152,7 +152,7 @@ void CalibrationTempDialog::create_geometry(wxCommandEvent& event_args) {
//plat->on_config_change(new_printer_config);
plat->changed_objects(objs_idx);
this->gui_app->get_tab(Preset::TYPE_PRINT)->update_dirty();
- this->gui_app->get_tab(Preset::TYPE_PRINTER)->update_dirty();
+ //this->gui_app->get_tab(Preset::TYPE_PRINTER)->update_dirty();
plat->is_preview_shown();
//update everything, easier to code.
ObjectList* obj = this->gui_app->obj_list();
diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp
index c1ecf3232..9bce10bb7 100644
--- a/src/slic3r/GUI/GUI_App.cpp
+++ b/src/slic3r/GUI/GUI_App.cpp
@@ -46,6 +46,7 @@
#include "CalibrationFlowDialog.hpp"
#include "CalibrationOverBridgeDialog.hpp"
#include "CalibrationTempDialog.hpp"
+#include "CalibrationRetractionDialog.hpp"
#include "ConfigSnapshotDialog.hpp"
#include "FreeCADDialog.hpp"
#include "FirmwareDialog.hpp"
@@ -602,6 +603,10 @@ void GUI_App::calibration_cube_dialog()
{
change_calibration_dialog(nullptr, new CalibrationCubeDialog(this, mainframe));
}
+void GUI_App::calibration_retraction_dialog()
+{
+ change_calibration_dialog(nullptr, new CalibrationRetractionDialog(this, mainframe));
+}
void GUI_App::freecad_script_dialog()
{
change_calibration_dialog(nullptr, new FreeCADDialog(this, mainframe));
diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp
index 38fd60b09..933406a53 100644
--- a/src/slic3r/GUI/GUI_App.hpp
+++ b/src/slic3r/GUI/GUI_App.hpp
@@ -139,6 +139,7 @@ public:
void bridge_tuning_dialog();
void over_bridge_dialog();
void calibration_cube_dialog();
+ void calibration_retraction_dialog();
void freecad_script_dialog();
//void support_tuning(); //have to do multiple, in a submenu
void load_project(wxWindow *parent, wxString& input_file) const;
diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp
index bd746f308..1d8349712 100644
--- a/src/slic3r/GUI/MainFrame.cpp
+++ b/src/slic3r/GUI/MainFrame.cpp
@@ -780,6 +780,8 @@ void MainFrame::init_menubar()
[this](wxCommandEvent&) { wxGetApp().bridge_tuning_dialog(); });
append_menu_item(calibrationMenu, wxID_ANY, _(L("Ironing pattern calibration")), _(L("Create a test print to help you to set your over-bridge flow ratio and ironing pattern.")),
[this](wxCommandEvent&) { wxGetApp().over_bridge_dialog(); });
+ append_menu_item(calibrationMenu, wxID_ANY, _(L("Extruder retraction calibration")), _(L("Create a test print to help you to set your retraction length.")),
+ [this](wxCommandEvent&) { wxGetApp().calibration_retraction_dialog(); });
calibrationMenu->AppendSeparator();
append_menu_item(calibrationMenu, wxID_ANY, _(L("Calibration cube")), _(L("Print a calibration cube, for various calibration goals.")),
[this](wxCommandEvent&) { wxGetApp().calibration_cube_dialog(); });
diff --git a/src/slic3r/GUI/Preset.cpp b/src/slic3r/GUI/Preset.cpp
index 4a70e61e7..d25629223 100644
--- a/src/slic3r/GUI/Preset.cpp
+++ b/src/slic3r/GUI/Preset.cpp
@@ -539,6 +539,7 @@ const std::vector& Preset::print_options()
, "curve_smoothing_angle_convex"
, "curve_smoothing_angle_concave",
"print_extrusion_multiplier",
+ "print_retract_length",
"external_perimeter_cut_corners",
"external_perimeter_overlap",
"perimeter_bonding",