diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index ccca79dd5..85cb8b3f1 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1642,9 +1642,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()) @@ -1687,6 +1687,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); @@ -1736,7 +1770,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 @@ -1754,7 +1788,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, 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/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()) diff --git a/src/libslic3r/GCode/WipeTower.cpp b/src/libslic3r/GCode/WipeTower.cpp index d6d336292..8bb441786 100644 --- a/src/libslic3r/GCode/WipeTower.cpp +++ b/src/libslic3r/GCode/WipeTower.cpp @@ -126,7 +126,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; @@ -386,7 +386,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 a3e20ca2f..68075c123 100644 --- a/src/libslic3r/GCodeTimeEstimator.cpp +++ b/src/libslic3r/GCodeTimeEstimator.cpp @@ -625,7 +625,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); @@ -1204,7 +1204,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; @@ -1316,7 +1317,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 840cf6168..c09d819de 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,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(gcfRepRapFirmware)) { code = "M109"; comment = "set temperature and wait for it to be reached"; } else { - code = "M104"; + if (FLAVOR_IS(gcfRepRapFirmware)) { // M104 is deprecated on RepRapFirmware + code = "G10"; + } else { + code = "M104"; + } comment = "set temperature"; } @@ -88,14 +98,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(gcfRepRapFirmware)) { + gcode << " P" << tool; + } else { + gcode << " T" << tool; + } } gcode << " ; " << comment << "\n"; - if (FLAVOR_IS(gcfTeacup) && 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 0844e9732..9c5c7bfb7 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -1285,8 +1285,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 030328321..095a1b390 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -983,6 +983,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"); @@ -993,6 +994,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)"); @@ -1003,7 +1005,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"); @@ -3352,11 +3354,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 37244423c..99b5feb95 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, }; @@ -95,7 +95,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;