diff --git a/resources/ui_layout/default/printer_fff.ui b/resources/ui_layout/default/printer_fff.ui index 36a9a8142d9..15324b1a31e 100644 --- a/resources/ui_layout/default/printer_fff.ui +++ b/resources/ui_layout/default/printer_fff.ui @@ -36,7 +36,10 @@ group:silent_mode_event:Firmware setting:arc_fitting setting:arc_fitting_tolerance end_line - setting:gcode_filename_illegal_char + line:Formatting + setting:gcode_filename_illegal_char + setting:gcode_ascii + end_line group:Cooling fan setting:fan_printer_min_speed line:Speedup time diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 0ef9e1a00e3..c6c32102793 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1328,6 +1328,7 @@ void GCode::_do_export(Print& print_mod, GCodeOutputStream &file, ThumbnailsGene m_find_replace = make_unique(print.config()); file.set_find_replace(m_find_replace.get(), false); } + file.set_only_ascii(print.config().gcode_ascii.value); // resets analyzer's tracking data m_last_height = 0.f; @@ -5145,6 +5146,9 @@ void GCode::GCodeOutputStream::write(const char *what) if (what != nullptr) { //FIXME don't allocate a string, maybe process a batch of lines? std::string gcode(m_find_replace ? m_find_replace->process_layer(what) : what); + if (m_only_ascii) { + remove_not_ascii(gcode); + } // writes string to file fwrite(gcode.c_str(), 1, gcode.size(), this->f); m_processor.process_buffer(gcode); diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index ccd71b884d0..b185e5942be 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -214,6 +214,7 @@ class GCode : ExtrusionVisitorConst { // It is being set to null inside process_layers(), because the find-replace process // is being called on a secondary thread to improve performance. void set_find_replace(GCodeFindReplace *find_replace, bool enabled) { m_find_replace_backup = find_replace; m_find_replace = enabled ? find_replace : nullptr; } + void set_only_ascii(bool only_ascii) { m_only_ascii = only_ascii; } void find_replace_enable() { m_find_replace = m_find_replace_backup; } void find_replace_supress() { m_find_replace = nullptr; } @@ -239,6 +240,7 @@ class GCode : ExtrusionVisitorConst { FILE *f { nullptr }; // Find-replace post-processor to be called before GCodePostProcessor. GCodeFindReplace *m_find_replace { nullptr }; + bool m_only_ascii; // If suppressed, the backoup holds m_find_replace. GCodeFindReplace *m_find_replace_backup { nullptr }; GCodeProcessor &m_processor; diff --git a/src/libslic3r/LocalesUtils.cpp b/src/libslic3r/LocalesUtils.cpp index 5bf520568a2..f189466e017 100644 --- a/src/libslic3r/LocalesUtils.cpp +++ b/src/libslic3r/LocalesUtils.cpp @@ -124,6 +124,32 @@ std::string float_to_string_decimal_point(double value, int precision/* = -1*/) return to_string_nozero(value, precision < 0 ? 6 : precision); } +void remove_not_ascii(std::string &tomodify) { + size_t pos_read = 0; + bool previous_ascii = true; + //skip until a not-ascii character + while (pos_read < tomodify.length() && ((tomodify[pos_read] & 0x80) == 0)) { ++pos_read; } + size_t pos_write = pos_read; + //then modify the string + while (pos_read < tomodify.length()) { + if ((tomodify[pos_read] & 0x80) == 0) { + //ascii, write + tomodify[pos_write] = tomodify[pos_read]; + ++pos_write; + previous_ascii = true; + } else { + //not-ascii, remove + if (previous_ascii) { + tomodify[pos_write] = '_'; + ++pos_write; + } + previous_ascii = false; + } + ++pos_read; + } + //remove extra bits + tomodify.resize(pos_write); +} } // namespace Slic3r diff --git a/src/libslic3r/LocalesUtils.hpp b/src/libslic3r/LocalesUtils.hpp index 18ec1102bba..c7e5abdddfb 100644 --- a/src/libslic3r/LocalesUtils.hpp +++ b/src/libslic3r/LocalesUtils.hpp @@ -37,6 +37,8 @@ bool is_decimal_separator_point(); std::string to_string_nozero(double value, int32_t max_precision); +void remove_not_ascii(std::string &tomodify); + // A substitute for std::to_string that works according to // C++ locales, not C locale. Meant to be used when we need // to be sure that decimal point is used as a separator. diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 52a0c4e872e..fbcb25e6b2e 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -810,6 +810,7 @@ static std::vector s_Preset_printer_options { "fan_speedup_time", "fan_percentage", "fan_printer_min_speed", + "gcode_ascii", "gcode_filename_illegal_char", "gcode_flavor", "gcode_precision_xyz", diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index fa9e9e14cd6..ab63b9f9c54 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -123,6 +123,7 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver& /* ne "gap_fill_fan_speed", "gap_fill_flow_match_perimeter", "gap_fill_speed", + "gcode_ascii", "gcode_comments", "gcode_filename_illegal_char", "gcode_label_objects", diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index b72026d503b..8fab71f50df 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -2833,6 +2833,14 @@ void PrintConfigDef::init_fff_params() def->mode = comExpert | comPrusa; def->set_default_value(new ConfigOptionFloatOrPercent(50,true)); + def = this->add("gcode_ascii", coBool); + def->label = L("Only ascii characters in gcode"); + def->category = OptionCategory::firmware; + def->tooltip = L("When printing the gcode file, replace any non-ascii character by a '_'." + " Can be useful if the firmware or a software in a workflow doesn't support uft-8."); + def->mode = comExpert | comSuSi; + def->set_default_value(new ConfigOptionBool(false)); + def = this->add("gcode_comments", coBool); def->label = L("Verbose G-code"); def->category = OptionCategory::output; @@ -7901,6 +7909,7 @@ std::unordered_set prusa_export_to_remove_keys = { "first_layer_infill_speed", "first_layer_min_speed", "first_layer_size_compensation_layers", +"gcode_ascii", "gap_fill_acceleration", "gap_fill_extension", "gap_fill_fan_speed", diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index e4361227a01..647c63e501c 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -1041,6 +1041,7 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionFloats, filament_wipe_advanced_pigment)) ((ConfigOptionFloats, filament_cooling_final_speed)) ((ConfigOptionStrings, filament_ramming_parameters)) + ((ConfigOptionBool, gcode_ascii)) ((ConfigOptionBool, gcode_comments)) ((ConfigOptionString, gcode_filename_illegal_char)) ((ConfigOptionEnum, gcode_flavor))