From 3e2f4cdff2b6496a3841c74e340825627b1ec010 Mon Sep 17 00:00:00 2001 From: supermerill Date: Wed, 29 May 2024 11:33:28 +0200 Subject: [PATCH 1/8] post-process ironing angle: now use fill_angle_cross, and can go into negative. supermerill/SuperSlicer#4286 --- src/libslic3r/Fill/Fill.cpp | 21 +++++++++++++-------- src/libslic3r/Fill/FillBase.cpp | 1 + src/libslic3r/Fill/FillSmooth.cpp | 2 +- src/libslic3r/PrintConfig.cpp | 9 ++++++--- 4 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/libslic3r/Fill/Fill.cpp b/src/libslic3r/Fill/Fill.cpp index 09a652ba77b..9f3b3848ea5 100644 --- a/src/libslic3r/Fill/Fill.cpp +++ b/src/libslic3r/Fill/Fill.cpp @@ -844,14 +844,18 @@ void Layer::make_ironing() } if (ironing_params.extruder != -1) { //TODO just_infill is currently not used. - ironing_params.type = config.ironing_type; - ironing_params.just_infill = false; + ironing_params.type = config.ironing_type; + ironing_params.just_infill = false; ironing_params.line_spacing = config.ironing_spacing; - ironing_params.height = default_layer_height * 0.01 * config.ironing_flowrate; - ironing_params.speed = config.ironing_speed; - ironing_params.angle = config.ironing_angle <0 ? - compute_fill_angle(config, layerm->layer()->id()) : - float(Geometry::deg2rad(config.ironing_angle.value)); + ironing_params.height = default_layer_height * 0.01 * config.ironing_flowrate; + ironing_params.speed = config.ironing_speed; + if (config.ironing_angle.value >= 0) { + ironing_params.angle = float(Geometry::deg2rad(config.ironing_angle.value)); + } else { + ironing_params.angle = compute_fill_angle(config, layerm->layer()->id()); + if (config.ironing_angle.value < -1) + ironing_params.angle += float(Geometry::deg2rad(-config.ironing_angle.value)); + } ironing_params.layerm = layerm; by_extruder.emplace_back(ironing_params); } @@ -933,7 +937,8 @@ void Layer::make_ironing() // Create the filler object. fill.init_spacing(ironing_params.line_spacing, fill_params); - fill.angle = float(ironing_params.angle + 0.25 * M_PI); + fill.can_angle_cross = region_config.fill_angle_cross.value; + fill.angle = float(ironing_params.angle); fill.link_max_length = (coord_t)scale_(3. * fill.get_spacing()); double extrusion_height = ironing_params.height * fill.get_spacing() / nozzle_dmr; //FIXME FLOW decide if it's good diff --git a/src/libslic3r/Fill/FillBase.cpp b/src/libslic3r/Fill/FillBase.cpp index 4bb29ebb644..5a18e1e555c 100644 --- a/src/libslic3r/Fill/FillBase.cpp +++ b/src/libslic3r/Fill/FillBase.cpp @@ -156,6 +156,7 @@ std::pair Fill::_infill_direction(const Surface *surface) const // printf("Layer_ID undefined!\n"); } + //why? out_angle += float(M_PI/2.); return std::pair(out_angle, out_shift); } diff --git a/src/libslic3r/Fill/FillSmooth.cpp b/src/libslic3r/Fill/FillSmooth.cpp index e2577632813..0e039f59909 100644 --- a/src/libslic3r/Fill/FillSmooth.cpp +++ b/src/libslic3r/Fill/FillSmooth.cpp @@ -69,7 +69,7 @@ namespace Slic3r { f2->init_spacing(this->get_spacing(), params); f2->layer_id = this->layer_id; f2->z = this->z; - f2->angle = anglePass[idx] + this->angle; + f2->angle = (this->can_angle_cross ? anglePass[idx] : 0) + this->angle; // Maximum length of the perimeter segment linking two infill lines. f2->link_max_length = this->link_max_length; // Used by the concentric infill pattern to clip the loops to create extrusion paths. diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 34561c81b30..6d8e38dceca 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -3339,11 +3339,14 @@ void PrintConfigDef::init_fff_params() def = this->add("ironing_angle", coFloat); def->label = L("Ironing angle"); def->category = OptionCategory::ironing; - def->tooltip = L("Ironing angle. if negative, it will use the fill angle."); + def->tooltip = L("Ironing post-process angle." + "\nIf positive, the ironing will use this angle." + "\nIf -1, it will use the fill angle." + "\nIf lower than -1, it will use the fill angle minus this angle."); def->sidetext = L("°"); - def->min = -1; + def->min = -360; def->mode = comExpert | comSuSi; - def->set_default_value(new ConfigOptionFloat(-1)); + def->set_default_value(new ConfigOptionFloat(-45)); def = this->add("ironing_type", coEnum); def->label = L("Ironing Type"); From 8d6c4c1e30c5d198cb7410be07ad50d364849d83 Mon Sep 17 00:00:00 2001 From: supermerill Date: Wed, 29 May 2024 14:13:34 +0200 Subject: [PATCH 2/8] fix gcode viewer refresh when selecting travel moves supermerill/SuperSlicer#4287 --- src/slic3r/GUI/GLCanvas3D.cpp | 8 +++++--- src/slic3r/GUI/GLCanvas3D.hpp | 2 +- src/slic3r/GUI/GUI_Preview.cpp | 20 +++++++++++++------- src/slic3r/GUI/GUI_Preview.hpp | 1 + 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index e8662dc2d14..5fec69be56b 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2264,10 +2264,12 @@ bool GLCanvas3D::is_gcode_preview_dirty(const GCodeProcessorResult& gcode_result return last_showned_gcode != gcode_result.computed_timestamp; } -void GLCanvas3D::load_gcode_preview(const GCodeProcessorResult& gcode_result, const std::vector& str_tool_colors) +void GLCanvas3D::load_gcode_preview(const GCodeProcessorResult &gcode_result, + const std::vector &str_tool_colors, + bool force_gcode_color_recompute) { - if (last_showned_gcode != gcode_result.computed_timestamp - || !m_gcode_viewer.is_loaded(gcode_result)) { + if (last_showned_gcode != gcode_result.computed_timestamp || force_gcode_color_recompute || + !m_gcode_viewer.is_loaded(gcode_result)) { last_showned_gcode = gcode_result.computed_timestamp; m_gcode_viewer.load(gcode_result, *this->fff_print(), m_initialized); diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index b319ccefb34..cb83907fe5d 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -741,7 +741,7 @@ class GLCanvas3D void reload_scene(bool refresh_immediately, bool force_full_scene_refresh = false); - void load_gcode_preview(const GCodeProcessorResult& gcode_result, const std::vector& str_tool_colors); + void load_gcode_preview(const GCodeProcessorResult& gcode_result, const std::vector& str_tool_colors, bool force_gcode_color_recompute = false); void refresh_gcode_preview_render_paths(); void set_gcode_view_preview_type(GCodeViewer::EViewType type) { return m_gcode_viewer.set_view_type(type); } GCodeViewer::EViewType get_gcode_view_preview_type() const { return m_gcode_viewer.get_view_type(); } diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 11664a45046..9c492156c92 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -565,10 +565,12 @@ void Preview::on_combochecklist_options(wxCommandEvent& evt) m_canvas->set_gcode_options_visibility_from_flags(new_flags); if (m_canvas->get_gcode_view_type() == GCodeViewer::EViewType::Feedrate) { const unsigned int diff_flags = curr_flags ^ new_flags; - if ((diff_flags & (1 << static_cast(Preview::OptionType::Travel))) != 0) + if ((diff_flags & (1 << static_cast(Preview::OptionType::Travel))) != 0) { + m_force_gcode_color_recompute = true; refresh_print(); - else + } else { m_canvas->refresh_gcode_preview_render_paths(); + } } else m_canvas->refresh_gcode_preview_render_paths(); @@ -951,13 +953,16 @@ void Preview::update_moves_slider() alternate_values[count] = static_cast(view.gcode_ids[i]); ++count; } - + // should the end of the horizontal slider stay at the end? + bool max_is_max = m_moves_slider->GetMaxValue() == m_moves_slider->GetHigherValue(); + // update values m_moves_slider->SetSliderValues(values); m_moves_slider->SetSliderAlternateValues(alternate_values); m_moves_slider->SetMaxValue(view.endpoints.last - view.endpoints.first); - m_moves_slider->SetSelectionSpan(view.current.first - view.endpoints.first, view.current.last - view.endpoints.first); - m_moves_slider->Refresh(); - m_moves_slider->Update(); + m_moves_slider->SetSelectionSpan(view.current.first - view.endpoints.first, + max_is_max ? m_moves_slider->GetMaxValue() : + (view.current.last - view.endpoints.first)); + m_moves_slider->fire_update_if_needed(); } void Preview::enable_moves_slider(bool enable) @@ -1065,7 +1070,8 @@ void Preview::load_print_as_fff(bool keep_z_range) // Load the real G-code preview. if (current_force_state == ForceState::NoForce) m_canvas->set_items_show(false, true); - m_canvas->load_gcode_preview(*m_gcode_result, colors); + m_canvas->load_gcode_preview(*m_gcode_result, colors, m_force_gcode_color_recompute); + m_force_gcode_color_recompute = false; m_left_sizer->Show(m_bottom_toolbar_panel); m_left_sizer->Layout(); Refresh(); diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index d4339712f54..3bc93bb9aee 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -126,6 +126,7 @@ class Preview : public wxTitledPanel //fields to see what color to display bool m_has_switched_to_color = false; bool m_has_switched_to_extruders = false; + bool m_force_gcode_color_recompute = false; bool m_loaded { false }; From e6457fdc8bb1b73a86c69402b5c9f1a38e15b2dc Mon Sep 17 00:00:00 2001 From: supermerill Date: Wed, 29 May 2024 15:46:39 +0200 Subject: [PATCH 3/8] fix multipath can_reverse supermerill/SuperSlicer#4217 --- src/libslic3r/ExtrusionEntity.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libslic3r/ExtrusionEntity.hpp b/src/libslic3r/ExtrusionEntity.hpp index 08718a2f70c..3157a2e3df5 100644 --- a/src/libslic3r/ExtrusionEntity.hpp +++ b/src/libslic3r/ExtrusionEntity.hpp @@ -336,8 +336,8 @@ class ExtrusionMultiEntity : public ExtrusionEntity { std::vector paths; ExtrusionMultiEntity(): ExtrusionEntity(false) {}; - ExtrusionMultiEntity(const ExtrusionMultiEntity &rhs) : paths(rhs.paths), ExtrusionEntity(false) {} - ExtrusionMultiEntity(ExtrusionMultiEntity &&rhs) : paths(std::move(rhs.paths)), ExtrusionEntity(false) {} + ExtrusionMultiEntity(const ExtrusionMultiEntity &rhs) : paths(rhs.paths), ExtrusionEntity(rhs.m_can_reverse) {} + ExtrusionMultiEntity(ExtrusionMultiEntity &&rhs) : paths(std::move(rhs.paths)), ExtrusionEntity(rhs.m_can_reverse) {} ExtrusionMultiEntity(const std::vector &paths) : paths(paths), ExtrusionEntity(false) {}; ExtrusionMultiEntity(const THING &path): ExtrusionEntity(false) { this->paths.push_back(path); } From 4b3d091233f3b309915257c878bbb88f1dbb1d9f Mon Sep 17 00:00:00 2001 From: supermerill Date: Mon, 3 Jun 2024 10:32:09 +0200 Subject: [PATCH 4/8] Add chamber temperature gcode if not detected. supermerill/SuperSlicer#4289 --- src/libslic3r/GCode.cpp | 29 +++++++++++++++++++++++++++++ src/libslic3r/GCode.hpp | 1 + src/libslic3r/GCode/WipeTower.cpp | 2 +- src/libslic3r/GCodeWriter.cpp | 29 ++++++++++++++++++++++++++++- src/libslic3r/GCodeWriter.hpp | 2 ++ 5 files changed, 61 insertions(+), 2 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 6400a5551ff..2f663166cc5 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1854,6 +1854,11 @@ void GCode::_do_export(Print& print_mod, GCodeOutputStream &file, ThumbnailsGene start_filament_gcode = this->placeholder_parser_process("start_filament_gcode", m_config.start_filament_gcode.get_at(initial_extruder_id), initial_extruder_id, &config); } std::string start_all_gcode = start_gcode + "\"n" + start_filament_gcode; + + // Set chamber temperature + if((initial_extruder_id != (uint16_t)-1) && !this->config().start_gcode_manual && print.config().chamber_temperature.get_at(initial_extruder_id) != 0) + this->_print_first_layer_chamber_temperature(preamble_to_put_start_layer, print, start_all_gcode, initial_extruder_id, false); + // Set bed temperature if the start G-code does not contain any bed temp control G-codes. if((initial_extruder_id != (uint16_t)-1) && !this->config().start_gcode_manual && this->config().gcode_flavor != gcfKlipper && print.config().first_layer_bed_temperature.get_at(initial_extruder_id) != 0) this->_print_first_layer_bed_temperature(preamble_to_put_start_layer, print, start_all_gcode, initial_extruder_id, false); @@ -2155,6 +2160,8 @@ void GCode::_do_export(Print& print_mod, GCodeOutputStream &file, ThumbnailsGene } } file.writeln(this->placeholder_parser_process("end_gcode", print.config().end_gcode, m_writer.tool()->id(), &config)); + } else { + assert(false); // what is the use-case? } file.write(m_writer.update_progress(m_layer_count, m_layer_count, true)); // 100% file.write(m_writer.postamble()); @@ -2695,6 +2702,28 @@ void GCode::_print_first_layer_bed_temperature(std::string &out, const Print &pr out += (set_temp_gcode); } +// Write 1st layer chamber temperatures into the G-code. +// Only do that if the start G-code does not already contain any M-code controlling an extruder temperature. +// M141 - Set chamber Temperature +// M191 - Set chamber Temperature and Wait +void GCode::_print_first_layer_chamber_temperature(std::string &out, const Print &print, const std::string &gcode, uint16_t first_printing_extruder_id, bool wait) +{ + // Initial bed temperature based on the first extruder. + int temp = print.config().chamber_temperature.get_at(first_printing_extruder_id); + //disable bed temp control if 0 + if (temp == 0) return; + // Is the bed temperature set by the provided custom G-code? + int temp_by_gcode = -1; + bool temp_set_by_gcode = custom_gcode_sets_temperature(gcode, 141, 191, false, temp_by_gcode); + if (temp_set_by_gcode && temp_by_gcode >= 0 && temp_by_gcode < 1000) + temp = temp_by_gcode; + // Always call m_writer.set_chamber_temperature() so it will set the internal "current" state of the chamber temp as if + // the custom start G-code emited these. + std::string set_temp_gcode = m_writer.set_chamber_temperature(temp, wait); + if (!temp_set_by_gcode && !set_temp_gcode.empty()) + out += (set_temp_gcode); +} + // Write 1st layer extruder temperatures into the G-code. // Only do that if the start G-code does not already contain any M-code controlling an extruder temperature. // M104 - Set Extruder Temperature diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 8f5b62434f2..89f70520151 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -523,6 +523,7 @@ class GCode : ExtrusionVisitorConst { std::string _after_extrude(const ExtrusionPath &path); void print_machine_envelope(GCodeOutputStream &file, const Print &print); void _print_first_layer_bed_temperature(std::string &out, const Print &print, const std::string &gcode, uint16_t first_printing_extruder_id, bool wait); + void _print_first_layer_chamber_temperature(std::string &out, const Print &print, const std::string &gcode, uint16_t first_printing_extruder_id, bool wait); void _print_first_layer_extruder_temperatures(std::string &out, const Print &print, const std::string &gcode, uint16_t first_printing_extruder_id, bool wait); // On the first printing layer. This flag triggers first layer speeds. bool on_first_layer() const { return m_layer != nullptr && m_layer->id() == 0; } diff --git a/src/libslic3r/GCode/WipeTower.cpp b/src/libslic3r/GCode/WipeTower.cpp index 6201c80c01f..9797f884736 100644 --- a/src/libslic3r/GCode/WipeTower.cpp +++ b/src/libslic3r/GCode/WipeTower.cpp @@ -513,7 +513,7 @@ class WipeTowerWriter assert(comment.empty() || comment[0] == ';' || (comment.size() > 1 && comment[0] == ' ' && comment[1] == ';')); if (speed == m_last_fan_speed) return *this; - if (speed == 0) + if (speed == 0 && (gcfTeacup != m_gcode_flavor && gcfRepRap != m_gcode_flavor)) m_gcode += "M107" + comment + "\n"; else m_gcode += "M106 S" + std::to_string(unsigned(255.0 * speed / 100.0)) + comment + "\n"; diff --git a/src/libslic3r/GCodeWriter.cpp b/src/libslic3r/GCodeWriter.cpp index 76fc83ee814..0dfa90f206f 100644 --- a/src/libslic3r/GCodeWriter.cpp +++ b/src/libslic3r/GCodeWriter.cpp @@ -269,7 +269,34 @@ std::string GCodeWriter::set_bed_temperature(uint32_t temperature, bool wait) return gcode.str(); } +std::string GCodeWriter::set_chamber_temperature(uint32_t temperature, bool wait) +{ + if (temperature == m_last_chamber_temperature && !wait) + return std::string(); + + if (FLAVOR_IS(gcfMarlinFirmware) || FLAVOR_IS(gcfRepRap) || FLAVOR_IS(gcfMachinekit)) { + // ok + } else { + return std::string(); + } + m_last_chamber_temperature = temperature; + + std::string code, comment; + if (wait) { + code = "M191"; + comment = "set chamber temperature and wait for it to be reached"; + } else { + code = "M141"; + comment = "set chamber temperature"; + } + + std::ostringstream gcode; + gcode << code << " " << "S"; + gcode << temperature << " ; " << comment << "\n"; + + return gcode.str(); +} void GCodeWriter::set_acceleration(uint32_t acceleration) { @@ -926,7 +953,7 @@ std::string GCodeWriter::set_fan(const GCodeFlavor gcode_flavor, bool gcode_comm // write it if (fan_speed == 0) { - if ((gcfTeacup == gcode_flavor)) { + if ((gcfTeacup == gcode_flavor || gcfRepRap == gcode_flavor)) { gcode << "M106 S0"; } else if ((gcfMakerWare == gcode_flavor) || (gcfSailfish == gcode_flavor)) { gcode << "M127"; diff --git a/src/libslic3r/GCodeWriter.hpp b/src/libslic3r/GCodeWriter.hpp index 72f04152831..96cb13a114b 100644 --- a/src/libslic3r/GCodeWriter.hpp +++ b/src/libslic3r/GCodeWriter.hpp @@ -40,6 +40,7 @@ class GCodeWriter { std::string postamble() const; std::string set_temperature(int16_t temperature, bool wait = false, int tool = -1); std::string set_bed_temperature(uint32_t temperature, bool wait = false); + std::string set_chamber_temperature(uint32_t temperature, bool wait = false); void set_acceleration(uint32_t acceleration); void set_travel_acceleration(uint32_t acceleration); uint32_t get_acceleration() const; @@ -103,6 +104,7 @@ class GCodeWriter { int16_t m_last_temperature_with_offset = 0; int16_t m_last_bed_temperature = 0; bool m_last_bed_temperature_reached = true; + int16_t m_last_chamber_temperature = 0; // if positive, it's set, and the next lift wil have this extra lift double m_extra_lift = 0; // current lift, to remove from m_pos to have the current height. From 14edab6153aaeb4ae3d62b7524139a246f46bbaf Mon Sep 17 00:00:00 2001 From: supermerill Date: Mon, 3 Jun 2024 10:34:24 +0200 Subject: [PATCH 5/8] fix missing gapfill supermerill/SuperSlicer#4290 --- src/libslic3r/MultiPoint.cpp | 19 +++++++++++++++++++ src/libslic3r/MultiPoint.hpp | 1 + 2 files changed, 20 insertions(+) diff --git a/src/libslic3r/MultiPoint.cpp b/src/libslic3r/MultiPoint.cpp index eac91ece652..506e36f2a94 100644 --- a/src/libslic3r/MultiPoint.cpp +++ b/src/libslic3r/MultiPoint.cpp @@ -152,6 +152,25 @@ bool MultiPoint::first_intersection(const Line& line, Point* intersection) const } } } + /*last-to-first line */{ + assert(!points.back().coincides_with_epsilon(points.front())); + l.a = points.back(); + l.b = points.front(); + Point ip; + if (l.intersection(line, &ip)) { + if (!found) { + found = true; + dmin = (line.a - ip).cast().norm(); + *intersection = ip; + } else { + double d = (line.a - ip).cast().norm(); + if (d < dmin) { + dmin = d; + *intersection = ip; + } + } + } + } return found; } diff --git a/src/libslic3r/MultiPoint.hpp b/src/libslic3r/MultiPoint.hpp index 25998031535..51cf2648981 100644 --- a/src/libslic3r/MultiPoint.hpp +++ b/src/libslic3r/MultiPoint.hpp @@ -88,6 +88,7 @@ class MultiPoint } bool intersection(const Line& line, Point* intersection) const; + // if the line cross multiple times, it will return the poitn nearest from line.a bool first_intersection(const Line& line, Point* intersection) const; bool intersections(const Line &line, Points *intersections) const; // Projection of a point onto the lines defined by the points. From 9e6d52ffd09ed4824acb3be1d283e5b9d75a9b22 Mon Sep 17 00:00:00 2001 From: supermerill Date: Mon, 3 Jun 2024 10:44:09 +0200 Subject: [PATCH 6/8] typo wipe_only_crossing supermerill/SuperSlicer#4293 --- src/libslic3r/PrintConfig.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 6d8e38dceca..0a3ed36a046 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -6222,7 +6222,7 @@ void PrintConfigDef::init_fff_params() def = this->add("wipe_only_crossing", coBools); def->label = L("Wipe only when crossing perimeters"); def->category = OptionCategory::extruders; - def->tooltip = L("Don't wipe when you don't cross a perimeter. Need 'only_retract_when_crossing_perimeters'and 'wipe' enabled."); + def->tooltip = L("Don't wipe when you don't cross a perimeter. Need 'avoid_crossing_perimeters' and 'wipe' enabled."); def->mode = comAdvancedE | comSuSi; def->is_vector_extruder = true; def->set_default_value(new ConfigOptionBools{ true }); From c260c1c14155a0ac6d88820b18fdf1f9294eabc1 Mon Sep 17 00:00:00 2001 From: supermerill Date: Mon, 3 Jun 2024 10:53:17 +0200 Subject: [PATCH 7/8] calibration project name, and over-bridge -> above the bridges supermerill/SuperSlicer#4295 --- .../over-bridge_tuning/over-bridge_tuning.html | 10 +++++----- src/slic3r/GUI/CalibrationFlowDialog.cpp | 17 +++++++++++++++-- src/slic3r/GUI/CalibrationFlowDialog.hpp | 4 ++-- src/slic3r/GUI/CalibrationOverBridgeDialog.cpp | 12 ++++++++---- 4 files changed, 30 insertions(+), 13 deletions(-) diff --git a/resources/calibration/over-bridge_tuning/over-bridge_tuning.html b/resources/calibration/over-bridge_tuning/over-bridge_tuning.html index b0ef65906d0..9f0dde320f2 100644 --- a/resources/calibration/over-bridge_tuning/over-bridge_tuning.html +++ b/resources/calibration/over-bridge_tuning/over-bridge_tuning.html @@ -25,8 +25,8 @@

Ironing Pattern Calibration

You need to do the filament flow calibration and the bridge flow ratio before this one. It's better if you have done the filament temperature calibration as well.

-

This calibration method will print test samples with various levels of over-bridge flow ratio, between 100 and 125. Choose the lowest value on which the top surface is smooth without rough "holes". Begin with the over-bridge calibraiton.

-

If the over-bridge calibration is not conclusive (same holes on all samples), then set it to 110% and use the top flow calibration. This setting is a bit more unpredictable so it's best to not move it far away from 100%.

+

This calibration method will print test samples with various levels of above-bridge flow ratio, between 100 and 125. Choose the lowest value on which the top surface is smooth without rough "holes". Begin with the above-bridge calibraiton.

+

If the above-bridge calibration is not conclusive (same holes on all samples), then set it to 110% and use the top flow calibration. This setting is a bit more unpredictable so it's best to not move it far away from 100%.

Results

@@ -46,10 +46,10 @@

Example:

Flat
-Here, we can see that artifacts exist until the over-bridge flow was set to 115. It was flat from the flow calibration, if it's not now, it's because the bridges below the top surfaces are dropping a bit, and so it leaves more volume to fill afterwards. Here, 115 should be enough, but 120 is a more safe bet. +Here, we can see that artifacts exist until the above-bridge flow was set to 115. It was flat from the flow calibration, if it's not now, it's because the bridges below the top surfaces are dropping a bit, and so it leaves more volume to fill afterwards. Here, 115 should be enough, but 120 is a more safe bet. -

Advice

-

TODO

+ +

Notes

This test set the setting "Complete individual objects" to true, so you may want to reset your print settings afterwards

diff --git a/src/slic3r/GUI/CalibrationFlowDialog.cpp b/src/slic3r/GUI/CalibrationFlowDialog.cpp index f128b9923d4..2dddeb0edf4 100644 --- a/src/slic3r/GUI/CalibrationFlowDialog.cpp +++ b/src/slic3r/GUI/CalibrationFlowDialog.cpp @@ -35,12 +35,25 @@ void CalibrationFlowDialog::create_buttons(wxStdDialogButtonSizer* buttons){ buttons->Add(bt); } +void CalibrationFlowDialog::create_geometry_10(wxCommandEvent &event_args) +{ + Plater *plat = this->main_frame->plater(); + if (!plat->new_project(L("Flow 10 percent calibration"))) + return; + create_geometry(80.f, 10.f); +} + +void CalibrationFlowDialog::create_geometry_2_5(wxCommandEvent &event_args) +{ + Plater *plat = this->main_frame->plater(); + if (!plat->new_project(L("Flow 2 percent calibration"))) + return; + create_geometry(92.f, 2.F); +} void CalibrationFlowDialog::create_geometry(float start, float delta) { Plater* plat = this->main_frame->plater(); Model& model = plat->model(); - if (!plat->new_project(L("Flow calibration"))) - return; //GLCanvas3D::set_warning_freeze(true); bool autocenter = gui_app->app_config->get("autocenter") == "1"; diff --git a/src/slic3r/GUI/CalibrationFlowDialog.hpp b/src/slic3r/GUI/CalibrationFlowDialog.hpp index 9c047cff8c0..6c5a047f35d 100644 --- a/src/slic3r/GUI/CalibrationFlowDialog.hpp +++ b/src/slic3r/GUI/CalibrationFlowDialog.hpp @@ -16,8 +16,8 @@ class CalibrationFlowDialog : public CalibrationAbstractDialog protected: void create_buttons(wxStdDialogButtonSizer* sizer) override; void create_geometry(float start, float delta); - void create_geometry_10(wxCommandEvent& event_args) { create_geometry(80.f, 10.f); } - void create_geometry_2_5(wxCommandEvent& event_args) { create_geometry(92.f, 2.F); } + void create_geometry_10(wxCommandEvent& event_args); + void create_geometry_2_5(wxCommandEvent& event_args); }; diff --git a/src/slic3r/GUI/CalibrationOverBridgeDialog.cpp b/src/slic3r/GUI/CalibrationOverBridgeDialog.cpp index 4ad8cf4818a..a5297cb9a89 100644 --- a/src/slic3r/GUI/CalibrationOverBridgeDialog.cpp +++ b/src/slic3r/GUI/CalibrationOverBridgeDialog.cpp @@ -27,8 +27,8 @@ namespace Slic3r { namespace GUI { void CalibrationOverBridgeDialog::create_buttons(wxStdDialogButtonSizer* buttons){ - wxButton* bt1 = new wxButton(this, wxID_FILE1, _L("Over-Bridge calibration")); - wxButton* bt2 = new wxButton(this, wxID_FILE1, _L("Top flow calibration")); + wxButton* bt1 = new wxButton(this, wxID_FILE1, _L("'Above the Bridges' flow calibration")); + wxButton* bt2 = new wxButton(this, wxID_FILE1, _L("'Top Fill' flow calibration")); bt1->Bind(wxEVT_BUTTON, &CalibrationOverBridgeDialog::create_geometry1, this); bt2->Bind(wxEVT_BUTTON, &CalibrationOverBridgeDialog::create_geometry2, this); buttons->Add(bt1); @@ -36,16 +36,20 @@ void CalibrationOverBridgeDialog::create_buttons(wxStdDialogButtonSizer* buttons } void CalibrationOverBridgeDialog::create_geometry1(wxCommandEvent& event_args) { + Plater* plat = this->main_frame->plater(); + if (!plat->new_project(L("'Above the Bridges flow calibration"))) + return; create_geometry(true); } void CalibrationOverBridgeDialog::create_geometry2(wxCommandEvent& event_args) { + Plater* plat = this->main_frame->plater(); + if (!plat->new_project(L("Top Fill flow calibration"))) + return; create_geometry(false); } void CalibrationOverBridgeDialog::create_geometry(bool over_bridge) { Plater* plat = this->main_frame->plater(); Model& model = plat->model(); - if (!plat->new_project(L("Over-bridge calibration"))) - return; //GLCanvas3D::set_warning_freeze(true); bool autocenter = gui_app->app_config->get("autocenter") == "1"; From 6cdc5c9d4a8f058fc9c3cbc8ad9ab7bdb8b6407c Mon Sep 17 00:00:00 2001 From: supermerill Date: Mon, 3 Jun 2024 11:42:16 +0200 Subject: [PATCH 8/8] Add gcode to add if start_gcode_manual --- src/libslic3r/PrintConfig.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 0a3ed36a046..a9444b68fab 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -5227,7 +5227,8 @@ void PrintConfigDef::init_fff_params() def->label = L("Only custom Start G-code"); def->category = OptionCategory::customgcode; def->tooltip = L("Ensure that the slicer won't add heating, fan, extruder... commands before or just after your start-gcode." - "If set to true, you have to write a good and complete start_gcode, as no checks are made anymore."); + "\nIf set to true, you have to write a good and complete start_gcode, as no checks are made anymore." + "\nExemple:\nG21 ; set units to millimeters\nG90 ; use absolute coordinates\n{if use_relative_e_distances}M83{else}M82{endif}\nG92 E0 ; reset extrusion distance"); def->mode = comExpert | comPrusa; def->set_default_value(new ConfigOptionBool(false));