From e27519751896025c8d629556755b31d0ea8abf69 Mon Sep 17 00:00:00 2001 From: Paul Arden <paul@migenius.com> Date: Mon, 20 Jul 2020 20:57:37 +1000 Subject: [PATCH 1/3] Add G10 temperature G-code support for the RepRapFirmware flavour. --- src/libslic3r/GCode.cpp | 42 +++++++++++++++++++++++++++++++---- src/libslic3r/GCodeWriter.cpp | 21 ++++++++++++------ 2 files changed, 52 insertions(+), 11 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 7fc531b92..975e15c6c 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1574,9 +1574,9 @@ std::string GCode::placeholder_parser_process(const std::string &name, const std } } -// Parse the custom G-code, try to find mcode_set_temp_dont_wait and mcode_set_temp_and_wait inside the custom G-code. +// Parse the custom G-code, try to find mcode_set_temp_dont_wait and mcode_set_temp_and_wait or optionally G10 with temperature inside the custom G-code. // Returns true if one of the temp commands are found, and try to parse the target temperature value into temp_out. -static bool custom_gcode_sets_temperature(const std::string &gcode, const int mcode_set_temp_dont_wait, const int mcode_set_temp_and_wait, int &temp_out) +static bool custom_gcode_sets_temperature(const std::string &gcode, const int mcode_set_temp_dont_wait, const int mcode_set_temp_and_wait, const bool include_g10, int &temp_out) { temp_out = -1; if (gcode.empty()) @@ -1619,6 +1619,40 @@ static bool custom_gcode_sets_temperature(const std::string &gcode, const int mc } } } + } else if (*ptr == 'G' && include_g10) { // Only check for G10 if requested + // Line starts with 'G'. + ++ ptr; + // Parse the G code value. + char *endptr = nullptr; + int gcode = int(strtol(ptr, &endptr, 10)); + if (endptr != nullptr && endptr != ptr && gcode == 10 /* G10 */) { + // G10 code found + ptr = endptr; + // Now try to parse the temperature value. + // While not at the end of the line: + while (strchr(";\r\n\0", *ptr) == nullptr) { + // Skip whitespaces. + for (; *ptr == ' ' || *ptr == '\t'; ++ ptr); + if (*ptr == 'S') { + // Skip whitespaces. + for (++ ptr; *ptr == ' ' || *ptr == '\t'; ++ ptr); + // Parse an int. + endptr = nullptr; + long temp_parsed = strtol(ptr, &endptr, 10); + if (endptr > ptr) { + ptr = endptr; + temp_out = temp_parsed; + // Let the caller know that the custom G-code sets the temperature + // Only do this after successfully parsing temperature since G10 + // can be used for other reasons + temp_set_by_gcode = true; + } + } else { + // Skip this word. + for (; strchr(" \t;\r\n\0", *ptr) == nullptr; ++ ptr); + } + } + } } // Skip the rest of the line. for (; *ptr != 0 && *ptr != '\r' && *ptr != '\n'; ++ ptr); @@ -1668,7 +1702,7 @@ void GCode::_print_first_layer_bed_temperature(FILE *file, Print &print, const s int temp = print.config().first_layer_bed_temperature.get_at(first_printing_extruder_id); // 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, 140, 190, temp_by_gcode); + bool temp_set_by_gcode = custom_gcode_sets_temperature(gcode, 140, 190, 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_bed_temperature() so it will set the internal "current" state of the bed temp as if @@ -1686,7 +1720,7 @@ void GCode::_print_first_layer_extruder_temperatures(FILE *file, Print &print, c { // Is the bed temperature set by the provided custom G-code? int temp_by_gcode = -1; - if (custom_gcode_sets_temperature(gcode, 104, 109, temp_by_gcode)) { + if (custom_gcode_sets_temperature(gcode, 104, 109, true, temp_by_gcode)) { // Set the extruder temperature at m_writer, but throw away the generated G-code as it will be written with the custom G-code. int temp = print.config().first_layer_temperature.get_at(first_printing_extruder_id); if (temp_by_gcode >= 0 && temp_by_gcode < 1000) diff --git a/src/libslic3r/GCodeWriter.cpp b/src/libslic3r/GCodeWriter.cpp index 38a1c3ebe..98a6ed4a4 100644 --- a/src/libslic3r/GCodeWriter.cpp +++ b/src/libslic3r/GCodeWriter.cpp @@ -72,11 +72,15 @@ std::string GCodeWriter::set_temperature(unsigned int temperature, bool wait, in return ""; std::string code, comment; - if (wait && FLAVOR_IS_NOT(gcfTeacup)) { + if (wait && FLAVOR_IS_NOT(gcfTeacup) && FLAVOR_IS_NOT(gcfRepRap)) { code = "M109"; comment = "set temperature and wait for it to be reached"; } else { - code = "M104"; + if (FLAVOR_IS(gcfRepRap)) { // M104 is deprecated on RepRapFirmware + code = "G10"; + } else { + code = "M104"; + } comment = "set temperature"; } @@ -88,14 +92,17 @@ std::string GCodeWriter::set_temperature(unsigned int temperature, bool wait, in gcode << "S"; } gcode << temperature; - if (tool != -1 && - ( (this->multiple_extruders && ! m_single_extruder_multi_material) || - FLAVOR_IS(gcfMakerWare) || FLAVOR_IS(gcfSailfish)) ) { - gcode << " T" << tool; + bool multiple_tools = this->multiple_extruders && ! m_single_extruder_multi_material; + if (tool != -1 && (multiple_tools || FLAVOR_IS(gcfMakerWare) || FLAVOR_IS(gcfSailfish)) ) { + if (FLAVOR_IS(gcfRepRap)) { + gcode << " P" << tool; + } else { + gcode << " T" << tool; + } } gcode << " ; " << comment << "\n"; - if (FLAVOR_IS(gcfTeacup) && wait) + if ((FLAVOR_IS(gcfTeacup) || FLAVOR_IS(gcfRepRap)) && wait) gcode << "M116 ; wait for temperature to be reached\n"; return gcode.str(); From f6d25d0634c0c40855aafce02bad4c3de734eea2 Mon Sep 17 00:00:00 2001 From: Paul Arden <paul@migenius.com> Date: Fri, 21 Aug 2020 14:07:50 +1000 Subject: [PATCH 2/3] Rework G10 temperature support to be enabled only for a new Firmware type `RepRapFirmware` leaving the `RepRap/Sprinter` behaviour alone. Rename the enum for `gcfRepRap` to `gcfRepRapSprinter` and add new `gcfRepRapFirmware` enum value. Also adds code to only use the G10 searching in custom G-code if the flavour is RepRapFirmware. --- src/libslic3r/GCode.cpp | 5 +++-- src/libslic3r/GCode/WipeTower.cpp | 4 ++-- src/libslic3r/GCodeTimeEstimator.cpp | 7 ++++--- src/libslic3r/GCodeWriter.cpp | 16 +++++++++++----- src/libslic3r/Print.cpp | 5 +++-- src/libslic3r/PrintConfig.cpp | 9 ++++++--- src/libslic3r/PrintConfig.hpp | 5 +++-- 7 files changed, 32 insertions(+), 19 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 975e15c6c..f863fd3ee 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -500,7 +500,7 @@ std::string WipeTowerIntegration::prime(GCode &gcodegen) // Disable linear advance for the wipe tower operations. - //gcode += (gcodegen.config().gcode_flavor == gcfRepRap ? std::string("M572 D0 S0\n") : std::string("M900 K0\n")); + //gcode += (gcodegen.config().gcode_flavor == gcfRepRapSprinter ? std::string("M572 D0 S0\n") : std::string("M900 K0\n")); for (const WipeTower::ToolChangeResult& tcr : m_priming) { if (!tcr.extrusions.empty()) @@ -1720,7 +1720,8 @@ void GCode::_print_first_layer_extruder_temperatures(FILE *file, Print &print, c { // Is the bed temperature set by the provided custom G-code? int temp_by_gcode = -1; - if (custom_gcode_sets_temperature(gcode, 104, 109, true, temp_by_gcode)) { + bool include_g10 = (print.config().gcode_flavor == gcfRepRapFirmware); + if (custom_gcode_sets_temperature(gcode, 104, 109, include_g10, temp_by_gcode)) { // Set the extruder temperature at m_writer, but throw away the generated G-code as it will be written with the custom G-code. int temp = print.config().first_layer_temperature.get_at(first_printing_extruder_id); if (temp_by_gcode >= 0 && temp_by_gcode < 1000) diff --git a/src/libslic3r/GCode/WipeTower.cpp b/src/libslic3r/GCode/WipeTower.cpp index c0f778687..b2534361f 100644 --- a/src/libslic3r/GCode/WipeTower.cpp +++ b/src/libslic3r/GCode/WipeTower.cpp @@ -102,7 +102,7 @@ public: } WipeTowerWriter& disable_linear_advance() { - m_gcode += (m_gcode_flavor == gcfRepRap + m_gcode += (m_gcode_flavor == gcfRepRapSprinter || m_gcode_flavor == gcfRepRapFirmware ? (std::string("M572 D") + std::to_string(m_current_tool) + " S0\n") : std::string("M900 K0\n")); return *this; @@ -351,7 +351,7 @@ public: // Set digital trimpot motor WipeTowerWriter& set_extruder_trimpot(int current) { - if (m_gcode_flavor == gcfRepRap) + if (m_gcode_flavor == gcfRepRapSprinter || m_gcode_flavor == gcfRepRapFirmware) m_gcode += "M906 E"; else m_gcode += "M907 E"; diff --git a/src/libslic3r/GCodeTimeEstimator.cpp b/src/libslic3r/GCodeTimeEstimator.cpp index 9e8137ef0..795fecbeb 100644 --- a/src/libslic3r/GCodeTimeEstimator.cpp +++ b/src/libslic3r/GCodeTimeEstimator.cpp @@ -622,7 +622,7 @@ namespace Slic3r { void GCodeTimeEstimator::set_default() { set_units(Millimeters); - set_dialect(gcfRepRap); + set_dialect(gcfRepRapSprinter); set_global_positioning_type(Absolute); set_e_local_positioning_type(Absolute); @@ -1201,7 +1201,8 @@ namespace Slic3r { if ((dialect == gcfRepetier) || (dialect == gcfMarlin) || (dialect == gcfSmoothie) || - (dialect == gcfRepRap)) + (dialect == gcfRepRapSprinter) || + (dialect == gcfRepRapFirmware)) { if (line.has_value('S', value)) extra_time += value; @@ -1313,7 +1314,7 @@ namespace Slic3r { GCodeFlavor dialect = get_dialect(); // see http://reprap.org/wiki/G-code#M201:_Set_max_printing_acceleration - float factor = ((dialect != gcfRepRap) && (get_units() == GCodeTimeEstimator::Inches)) ? INCHES_TO_MM : 1.0f; + float factor = ((dialect != gcfRepRapSprinter && dialect != gcfRepRapFirmware) && (get_units() == GCodeTimeEstimator::Inches)) ? INCHES_TO_MM : 1.0f; if (line.has_x()) set_axis_max_acceleration(X, line.x() * factor); diff --git a/src/libslic3r/GCodeWriter.cpp b/src/libslic3r/GCodeWriter.cpp index 98a6ed4a4..569ae65e5 100644 --- a/src/libslic3r/GCodeWriter.cpp +++ b/src/libslic3r/GCodeWriter.cpp @@ -46,7 +46,13 @@ std::string GCodeWriter::preamble() gcode << "G21 ; set units to millimeters\n"; gcode << "G90 ; use absolute coordinates\n"; } - if (FLAVOR_IS(gcfRepRap) || FLAVOR_IS(gcfMarlin) || FLAVOR_IS(gcfTeacup) || FLAVOR_IS(gcfRepetier) || FLAVOR_IS(gcfSmoothie)) { + if (FLAVOR_IS(gcfRepRapSprinter) || + FLAVOR_IS(gcfRepRapFirmware) || + FLAVOR_IS(gcfMarlin) || + FLAVOR_IS(gcfTeacup) || + FLAVOR_IS(gcfRepetier) || + FLAVOR_IS(gcfSmoothie)) + { if (this->config.use_relative_e_distances) { gcode << "M83 ; use relative distances for extrusion\n"; } else { @@ -72,11 +78,11 @@ std::string GCodeWriter::set_temperature(unsigned int temperature, bool wait, in return ""; std::string code, comment; - if (wait && FLAVOR_IS_NOT(gcfTeacup) && FLAVOR_IS_NOT(gcfRepRap)) { + if (wait && FLAVOR_IS_NOT(gcfTeacup) && FLAVOR_IS_NOT(gcfRepRapFirmware)) { code = "M109"; comment = "set temperature and wait for it to be reached"; } else { - if (FLAVOR_IS(gcfRepRap)) { // M104 is deprecated on RepRapFirmware + if (FLAVOR_IS(gcfRepRapFirmware)) { // M104 is deprecated on RepRapFirmware code = "G10"; } else { code = "M104"; @@ -94,7 +100,7 @@ std::string GCodeWriter::set_temperature(unsigned int temperature, bool wait, in gcode << temperature; bool multiple_tools = this->multiple_extruders && ! m_single_extruder_multi_material; if (tool != -1 && (multiple_tools || FLAVOR_IS(gcfMakerWare) || FLAVOR_IS(gcfSailfish)) ) { - if (FLAVOR_IS(gcfRepRap)) { + if (FLAVOR_IS(gcfRepRapFirmware)) { gcode << " P" << tool; } else { gcode << " T" << tool; @@ -102,7 +108,7 @@ std::string GCodeWriter::set_temperature(unsigned int temperature, bool wait, in } gcode << " ; " << comment << "\n"; - if ((FLAVOR_IS(gcfTeacup) || FLAVOR_IS(gcfRepRap)) && wait) + if ((FLAVOR_IS(gcfTeacup) || FLAVOR_IS(gcfRepRapFirmware)) && wait) gcode << "M116 ; wait for temperature to be reached\n"; return gcode.str(); diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 0c8a11fcf..878380955 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -1259,8 +1259,9 @@ std::string Print::validate() const "and use filaments of the same diameter."); } - if (m_config.gcode_flavor != gcfRepRap && m_config.gcode_flavor != gcfRepetier && m_config.gcode_flavor != gcfMarlin) - return L("The Wipe Tower is currently only supported for the Marlin, RepRap/Sprinter and Repetier G-code flavors."); + if (m_config.gcode_flavor != gcfRepRapSprinter && m_config.gcode_flavor != gcfRepRapFirmware && + m_config.gcode_flavor != gcfRepetier && m_config.gcode_flavor != gcfMarlin) + return L("The Wipe Tower is currently only supported for the Marlin, RepRap/Sprinter, RepRapFirmware and Repetier G-code flavors."); if (! m_config.use_relative_e_distances) return L("The Wipe Tower is currently only supported with the relative extruder addressing (use_relative_e_distances=1)."); if (m_config.ooze_prevention) diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index d6a23d75d..0d7ddeecd 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -953,6 +953,7 @@ void PrintConfigDef::init_fff_params() "The \"No extrusion\" flavor prevents PrusaSlicer from exporting any extrusion value at all."); def->enum_keys_map = &ConfigOptionEnum<GCodeFlavor>::get_enum_values(); def->enum_values.push_back("reprap"); + def->enum_values.push_back("reprapfirmware"); def->enum_values.push_back("repetier"); def->enum_values.push_back("teacup"); def->enum_values.push_back("makerware"); @@ -963,6 +964,7 @@ void PrintConfigDef::init_fff_params() def->enum_values.push_back("smoothie"); def->enum_values.push_back("no-extrusion"); def->enum_labels.push_back("RepRap/Sprinter"); + def->enum_labels.push_back("RepRapFirmware"); def->enum_labels.push_back("Repetier"); def->enum_labels.push_back("Teacup"); def->enum_labels.push_back("MakerWare (MakerBot)"); @@ -973,7 +975,7 @@ void PrintConfigDef::init_fff_params() def->enum_labels.push_back("Smoothie"); def->enum_labels.push_back(L("No extrusion")); def->mode = comExpert; - def->set_default_value(new ConfigOptionEnum<GCodeFlavor>(gcfRepRap)); + def->set_default_value(new ConfigOptionEnum<GCodeFlavor>(gcfRepRapSprinter)); def = this->add("gcode_label_objects", coBool); def->label = L("Label objects"); @@ -3290,11 +3292,12 @@ std::string FullPrintConfig::validate() if (this->use_firmware_retraction.value && this->gcode_flavor.value != gcfSmoothie && - this->gcode_flavor.value != gcfRepRap && + this->gcode_flavor.value != gcfRepRapSprinter && + this->gcode_flavor.value != gcfRepRapFirmware && this->gcode_flavor.value != gcfMarlin && this->gcode_flavor.value != gcfMachinekit && this->gcode_flavor.value != gcfRepetier) - return "--use-firmware-retraction is only supported by Marlin, Smoothie, Repetier and Machinekit firmware"; + return "--use-firmware-retraction is only supported by Marlin, Smoothie, RepRapFirmware, Repetier and Machinekit firmware"; if (this->use_firmware_retraction.value) for (unsigned char wipe : this->wipe.values) diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index f28ef2a22..0ab51718b 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -25,7 +25,7 @@ namespace Slic3r { enum GCodeFlavor : unsigned char { - gcfRepRap, gcfRepetier, gcfTeacup, gcfMakerWare, gcfMarlin, gcfSailfish, gcfMach3, gcfMachinekit, + gcfRepRapSprinter, gcfRepRapFirmware, gcfRepetier, gcfTeacup, gcfMakerWare, gcfMarlin, gcfSailfish, gcfMach3, gcfMachinekit, gcfSmoothie, gcfNoExtrusion, }; @@ -84,7 +84,8 @@ template<> inline const t_config_enum_values& ConfigOptionEnum<PrinterTechnology template<> inline const t_config_enum_values& ConfigOptionEnum<GCodeFlavor>::get_enum_values() { static t_config_enum_values keys_map; if (keys_map.empty()) { - keys_map["reprap"] = gcfRepRap; + keys_map["reprap"] = gcfRepRapSprinter; + keys_map["reprapfirmware"] = gcfRepRapFirmware; keys_map["repetier"] = gcfRepetier; keys_map["teacup"] = gcfTeacup; keys_map["makerware"] = gcfMakerWare; From 8cd13803cac8c68f549de1afde845e5d58e58934 Mon Sep 17 00:00:00 2001 From: Lukas Matena <lukasmatena@seznam.cz> Date: Fri, 23 Oct 2020 13:27:45 +0200 Subject: [PATCH 3/3] Updated the G10 RepRapFirmware pull request to current master --- src/libslic3r/GCode/GCodeProcessor.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index fb7e83303..665316296 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -689,7 +689,7 @@ void GCodeProcessor::reset() m_global_positioning_type = EPositioningType::Absolute; m_e_local_positioning_type = EPositioningType::Absolute; m_extruder_offsets = std::vector<Vec3f>(Min_Extruder_Count, Vec3f::Zero()); - m_flavor = gcfRepRap; + m_flavor = gcfRepRapSprinter; m_start_position = { 0.0f, 0.0f, 0.0f, 0.0f }; m_end_position = { 0.0f, 0.0f, 0.0f, 0.0f }; @@ -1109,7 +1109,7 @@ bool GCodeProcessor::process_cura_tags(const std::string& comment) else if (flavor == "Repetier") m_flavor = gcfRepetier; else if (flavor == "RepRap") - m_flavor = gcfRepRap; + m_flavor = gcfRepRapFirmware; else if (flavor == "Marlin") m_flavor = gcfMarlin; else @@ -1801,7 +1801,7 @@ void GCodeProcessor::process_M201(const GCodeReader::GCodeLine& line) return; // see http://reprap.org/wiki/G-code#M201:_Set_max_printing_acceleration - float factor = (m_flavor != gcfRepRap && m_units == EUnits::Inches) ? INCHES_TO_MM : 1.0f; + float factor = ((m_flavor != gcfRepRapSprinter && m_flavor != gcfRepRapFirmware) && m_units == EUnits::Inches) ? INCHES_TO_MM : 1.0f; for (size_t i = 0; i < static_cast<size_t>(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) { if (line.has_x())