Can set illegal characters for gcode filemane

supermerill/SuperSlicer#1518
This commit is contained in:
supermerill 2021-08-31 02:31:11 +02:00
parent 6b6035ad00
commit 77fd66bcd6
6 changed files with 72 additions and 5 deletions

View File

@ -23,6 +23,7 @@ group:silent_mode_event:Firmware
setting:max_gcode_per_second
setting:min_length
end_line
setting:gcode_filename_illegal_char
group:Cooling fan
line:Speedup
setting:label$Speedup time:fan_speedup_time

View File

@ -725,8 +725,10 @@ const std::vector<std::string>& Preset::printer_options()
"fan_speedup_overhangs",
"fan_speedup_time",
"fan_percentage",
"gcode_flavor",
"gcode_filename_illegal_char",
"gcode_flavor",
"gcode_precision_xyz",
"gcode_precision_e",
"use_relative_e_distances",
"use_firmware_retraction", "use_volumetric_e", "variable_layer_height",
"min_length",

View File

@ -122,6 +122,7 @@ bool Print::invalidate_state_by_config_options(const std::vector<t_config_option
"full_fan_speed_layer",
"gap_fill_speed",
"gcode_comments",
"gcode_filename_illegal_char",
"gcode_label_objects",
"gcode_precision_xyz",
"gcode_precision_e",

View File

@ -62,12 +62,54 @@ std::string PrintBase::output_filename(const std::string &format, const std::str
cfg.set_key_value("input_filename_base", new ConfigOptionString(filename_base));
}
try {
boost::filesystem::path filename = format.empty() ?
boost::filesystem::path filepath = format.empty() ?
cfg.opt_string("input_filename_base") + default_ext :
this->placeholder_parser().process(format, 0, &cfg);
if (filename.extension().empty())
filename = boost::filesystem::change_extension(filename, default_ext);
return filename.string();
//remove unwanted characters
std::string forbidden_base;
if (const ConfigOptionString* opt = this->placeholder_parser().external_config()->option<ConfigOptionString>("gcode_filename_illegal_char")) {
forbidden_base = opt->value;
}
if (!forbidden_base.empty()) {
const std::string filename_init = filepath.stem().string();
std::string filename = filename_init;
std::string extension = filepath.extension().string();
//remove {print_time} and things like that that may be computed after, and re-put them inside it after the replace.
std::regex placehoder = std::regex("\\{[a-z_]+\\}");
std::smatch matches;
std::string::const_iterator searchStart(filename_init.cbegin());
while (std::regex_search(searchStart, filename_init.cend(), matches, placehoder)) {
for (int i = 0; i < matches.size(); i++) {
filename.replace(matches.position(i), matches.length(i), matches.length(i), '_');
}
searchStart = matches.suffix().first;
}
//remove unwanted characters from the cleaned string
bool regexp_used = false;
if (forbidden_base.front() == '(' || forbidden_base.front() == '[') {
try {
filename = std::regex_replace(filename, std::regex(forbidden_base), "_");
regexp_used = true;
}catch(std::exception){}
}
if (!regexp_used) {
for(int i=0; i< forbidden_base.size(); i++)
std::replace(filename.begin(), filename.end(), forbidden_base.at(i), '_');
}
//re-put {print_time} and things like that
searchStart = (filename_init.cbegin());
while (std::regex_search(searchStart, filename_init.cend(), matches, placehoder)) {
for (int i = 0; i < matches.size(); i++) {
filename.replace(matches.position(i), matches.length(i), matches.str());
}
searchStart = matches.suffix().first;
}
// set the path var
filepath = filename + extension;
}
if (filepath.extension().empty())
filepath = boost::filesystem::change_extension(filepath, default_ext);
return filepath.string();
} catch (std::runtime_error &err) {
throw Slic3r::PlaceholderParserError(L("Failed processing of the output_filename_format template.") + "\n" + err.what());
}

View File

@ -1963,6 +1963,15 @@ void PrintConfigDef::init_fff_params()
def->mode = comExpert;
def->set_default_value(new ConfigOptionBool(0));
def = this->add("gcode_filename_illegal_char", coString);
def->label = L("Illegal characters");
def->full_label = L("Illegal characters for filename");
def->category = OptionCategory::output;
def->tooltip = L("All characters that are written here will be replaced by '_' when writing the gcode file name."
"\nIf the first charater is '[' or '(', then this field will be considered as a regexp (enter '[^a-zA-Z0-9]' to only use ascii char).");
def->mode = comExpert;
def->set_default_value(new ConfigOptionString(""));
def = this->add("gcode_flavor", coEnum);
def->label = L("G-code flavor");
def->category = OptionCategory::general;
@ -1999,6 +2008,15 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionEnum<GCodeFlavor>(gcfSprinter));
def = this->add("gcode_filename_illegal_char", coString);
def->label = L("Illegal characters");
def->full_label = L("Illegal characters for filename");
def->category = OptionCategory::output;
def->tooltip = L("All characters that are written here will be replaced by '_' when writing the gcode file name."
"\nIf the first charater is '[' or '(', then this field will be considered as a regexp (enter '[^a-zA-Z]' to only use ascii char).");
def->mode = comExpert;
def->set_default_value(new ConfigOptionString(""));
def = this->add("gcode_label_objects", coBool);
def->label = L("Label objects");
def->category = OptionCategory::output;
@ -5568,6 +5586,7 @@ std::unordered_set<std::string> prusa_export_to_remove_keys = {
"gap_fill_min_area",
"gap_fill_overlap",
"gap_fill",
"gcode_filename_illegal_char",
"hole_size_compensation",
"hole_size_threshold",
"hole_to_polyhole_threshold",

View File

@ -1090,6 +1090,7 @@ public:
ConfigOptionFloats filament_cooling_final_speed;
ConfigOptionStrings filament_ramming_parameters;
ConfigOptionBool gcode_comments;
ConfigOptionString gcode_filename_illegal_char;
ConfigOptionEnum<GCodeFlavor> gcode_flavor;
ConfigOptionBool gcode_label_objects;
ConfigOptionInt gcode_precision_xyz;
@ -1204,6 +1205,7 @@ protected:
OPT_PTR(filament_cooling_final_speed);
OPT_PTR(filament_ramming_parameters);
OPT_PTR(gcode_comments);
OPT_PTR(gcode_filename_illegal_char);
OPT_PTR(gcode_flavor);
OPT_PTR(gcode_label_objects);
OPT_PTR(gcode_precision_xyz);