Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/supermerill/SuperSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsupermerill <merill@free.fr>2021-11-09 17:06:01 +0300
committersupermerill <merill@free.fr>2021-11-09 17:06:01 +0300
commit704740c8beb2bdba06e2611c19eb1c4ad5ceee9a (patch)
treeefeac16948616995d7a8e1274634b2fdf1912d95
parent710016b54c093d351442b86d3736b9eedd9d5081 (diff)
parentc9c958157d0b7aac9b186a389f0d9ce325784ddb (diff)
add custom vars, fix min/max layer height, custom gcode unsaved change2.3.57.5
-rw-r--r--resources/ui_layout/filament.ui2
-rw-r--r--resources/ui_layout/print.ui2
-rw-r--r--resources/ui_layout/printer_fff.ui2
-rw-r--r--src/libslic3r/Config.cpp46
-rw-r--r--src/libslic3r/Config.hpp1
-rw-r--r--src/libslic3r/GCode.cpp6
-rw-r--r--src/libslic3r/PlaceholderParser.cpp183
-rw-r--r--src/libslic3r/PlaceholderParser.hpp7
-rw-r--r--src/libslic3r/Preset.cpp24
-rw-r--r--src/libslic3r/Print.cpp1
-rw-r--r--src/libslic3r/PrintConfig.cpp54
-rw-r--r--src/libslic3r/PrintConfig.hpp6
-rw-r--r--src/slic3r/GUI/MainFrame.cpp2
-rw-r--r--src/slic3r/GUI/Tab.cpp8
-rw-r--r--src/slic3r/GUI/UnsavedChangesDialog.cpp10
15 files changed, 312 insertions, 42 deletions
diff --git a/resources/ui_layout/filament.ui b/resources/ui_layout/filament.ui
index f6fd8931d..49793d74f 100644
--- a/resources/ui_layout/filament.ui
+++ b/resources/ui_layout/filament.ui
@@ -94,6 +94,8 @@ group:no_title:End G-code
page:Notes:note.png
group:label_width$0:Notes
setting:full_width:height$25:filament_notes
+group:label_width$0:Custom variables
+ setting:full_width:height$15:filament_custom_variables
page:Dependencies:wrench.png
group:Profile dependencies
diff --git a/resources/ui_layout/print.ui b/resources/ui_layout/print.ui
index 94f54222d..2eb5ff0d6 100644
--- a/resources/ui_layout/print.ui
+++ b/resources/ui_layout/print.ui
@@ -384,6 +384,8 @@ group:Post-processing script
page:Notes:note
group:no_title:Notes
setting:full_width:height$25:notes
+group:no_title:Custom variables
+ setting:full_width:height$15:print_custom_variables
page:Dependencies:wrench
group:Profile dependencies
diff --git a/resources/ui_layout/printer_fff.ui b/resources/ui_layout/printer_fff.ui
index 90acf9b84..696e4f4cd 100644
--- a/resources/ui_layout/printer_fff.ui
+++ b/resources/ui_layout/printer_fff.ui
@@ -83,6 +83,8 @@ height:0
page:Notes:note.png
group:no_title:Notes
setting:full_width:height$25:printer_notes
+group:no_title:Custom variables
+ setting:full_width:height$15:printer_custom_variables
page:Dependencies:wrench.png
group:Profile dependencies
diff --git a/src/libslic3r/Config.cpp b/src/libslic3r/Config.cpp
index 75f882161..741c1d832 100644
--- a/src/libslic3r/Config.cpp
+++ b/src/libslic3r/Config.cpp
@@ -664,6 +664,15 @@ bool ConfigBase::set_deserialize_raw(const t_config_option_key &opt_key_src, con
return success;
}
+const ConfigOptionDef* ConfigBase::get_option_def(const t_config_option_key& opt_key) const {
+ // Get option definition.
+ const ConfigDef* def = this->def();
+ if (def == nullptr)
+ throw NoDefinitionException(opt_key);
+ const ConfigOptionDef* opt_def = def->get(opt_key);
+ return opt_def;
+}
+
// Return an absolute value of a possibly relative config variable.
// For example, return absolute infill extrusion width, either from an absolute value, or relative to the layer height.
double ConfigBase::get_computed_value(const t_config_option_key &opt_key, int extruder_id) const
@@ -674,12 +683,6 @@ double ConfigBase::get_computed_value(const t_config_option_key &opt_key, int ex
std::stringstream ss; ss << "You can't define an option that need " << opt_key << " without defining it!";
throw std::runtime_error(ss.str());
}
- // Get option definition.
- const ConfigDef* def = this->def();
- if (def == nullptr)
- throw NoDefinitionException(opt_key);
- const ConfigOptionDef* opt_def = def->get(opt_key);
- assert(opt_def != nullptr);
if (!raw_opt->is_vector()) {
if (raw_opt->type() == coFloat)
@@ -697,19 +700,20 @@ double ConfigBase::get_computed_value(const t_config_option_key &opt_key, int ex
if (raw_opt->type() == coPercent) {
cast_opt = static_cast<const ConfigOptionPercent*>(raw_opt);
}
- if (opt_def != nullptr) {
- //if over no other key, it's most probably a simple %
- if (opt_def->ratio_over == "")
- return cast_opt->get_abs_value(1);
- // Compute absolute value over the absolute value of the base option.
- //FIXME there are some ratio_over chains, which end with empty ratio_with.
- // For example, XXX_extrusion_width parameters are not handled by get_abs_value correctly.
- if (!opt_def->ratio_over.empty() && opt_def->ratio_over != "depends")
- return cast_opt->get_abs_value(this->get_computed_value(opt_def->ratio_over));
+ const ConfigOptionDef* opt_def = get_option_def(opt_key);
+ if (opt_def == nullptr) // maybe a placeholder?
+ return cast_opt->get_abs_value(1);
+ //if over no other key, it's most probably a simple %
+ if (opt_def->ratio_over == "")
+ return cast_opt->get_abs_value(1);
+ // Compute absolute value over the absolute value of the base option.
+ //FIXME there are some ratio_over chains, which end with empty ratio_with.
+ // For example, XXX_extrusion_width parameters are not handled by get_abs_value correctly.
+ if (!opt_def->ratio_over.empty() && opt_def->ratio_over != "depends")
+ return cast_opt->get_abs_value(this->get_computed_value(opt_def->ratio_over));
- std::stringstream ss; ss << "ConfigBase::get_abs_value(): " << opt_key << " has no valid ratio_over to compute of";
- throw ConfigurationError(ss.str());
- }
+ std::stringstream ss; ss << "ConfigBase::get_abs_value(): " << opt_key << " has no valid ratio_over to compute of";
+ throw ConfigurationError(ss.str());
} else {
// check if it's an extruder_id array
const ConfigOptionVectorBase* vector_opt = static_cast<const ConfigOptionVectorBase*>(raw_opt);
@@ -741,6 +745,9 @@ double ConfigBase::get_computed_value(const t_config_option_key &opt_key, int ex
if (!opt_fl_per->values[idx].percent)
return opt_fl_per->values[idx].value;
+ const ConfigOptionDef* opt_def = get_option_def(opt_key);
+ if (opt_def == nullptr) // maybe a placeholder?
+ return opt_fl_per->get_abs_value(extruder_id, 1);
if (opt_def->ratio_over.empty())
return opt_fl_per->get_abs_value(idx, 1);
if (opt_def->ratio_over != "depends")
@@ -750,6 +757,9 @@ double ConfigBase::get_computed_value(const t_config_option_key &opt_key, int ex
}
if (raw_opt->type() == coPercents) {
const ConfigOptionPercents* opt_per = static_cast<const ConfigOptionPercents*>(raw_opt);
+ const ConfigOptionDef* opt_def = get_option_def(opt_key);
+ if (opt_def == nullptr) // maybe a placeholder?
+ return opt_per->get_abs_value(extruder_id, 1);
if (opt_def->ratio_over.empty())
return opt_per->get_abs_value(idx, 1);
if (opt_def->ratio_over != "depends")
diff --git a/src/libslic3r/Config.hpp b/src/libslic3r/Config.hpp
index d20514e60..c451d5c66 100644
--- a/src/libslic3r/Config.hpp
+++ b/src/libslic3r/Config.hpp
@@ -2084,6 +2084,7 @@ public:
void set_deserialize_strict(std::initializer_list<SetDeserializeItem> items)
{ ConfigSubstitutionContext ctxt{ ForwardCompatibilitySubstitutionRule::Disable }; this->set_deserialize(items, ctxt); }
+ const ConfigOptionDef* get_option_def(const t_config_option_key& opt_key) const;
double get_computed_value(const t_config_option_key &opt_key, int extruder_id = -1) const;
double get_abs_value(const t_config_option_key &opt_key, double ratio_over) const;
void setenv_() const;
diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp
index 0e18211f4..b792985d3 100644
--- a/src/libslic3r/GCode.cpp
+++ b/src/libslic3r/GCode.cpp
@@ -18,6 +18,7 @@
#include <cstdlib>
#include <math.h>
#include <string_view>
+#include <map>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/find.hpp>
@@ -1107,7 +1108,6 @@ void GCode::_init_multiextruders(FILE *file, Print &print, GCodeWriter & writer,
}
}
-
void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thumbnail_cb)
{
PROFILE_FUNC();
@@ -1359,6 +1359,10 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu
// Emit machine envelope limits for the Marlin firmware.
this->print_machine_envelope(file, print);
+ //add variables from filament_custom_variables
+ m_placeholder_parser.parse_custom_variables(m_config.print_custom_variables);
+ m_placeholder_parser.parse_custom_variables(m_config.printer_custom_variables);
+ m_placeholder_parser.parse_custom_variables(m_config.filament_custom_variables);
// Let the start-up script prime the 1st printing tool.
m_placeholder_parser.set("initial_tool", initial_extruder_id);
diff --git a/src/libslic3r/PlaceholderParser.cpp b/src/libslic3r/PlaceholderParser.cpp
index 8ca131f34..660f45ee4 100644
--- a/src/libslic3r/PlaceholderParser.cpp
+++ b/src/libslic3r/PlaceholderParser.cpp
@@ -836,9 +836,10 @@ namespace client
expr<Iterator> &output)
{
std::string opt_key(opt.it_range.begin(), opt.it_range.end());
+ const ConfigOptionVectorBase* vector_opt = nullptr;
if (opt.opt->is_vector()) {
- const ConfigOptionDef* opt_def = print_config_def.get(opt_key);
- if (!opt_def->is_vector_extruder)
+ vector_opt = static_cast<const ConfigOptionVectorBase*>(opt.opt);
+ if (!vector_opt->is_extruder_size())
ctx->throw_exception("Referencing a vector variable when scalar is expected", opt.it_range);
}
const ConfigOptionDef* opt_def;
@@ -898,29 +899,29 @@ namespace client
ctx->throw_exception("Unknown scalar variable type", opt.it_range);
case coFloats:
case coPercents:
- opt_def = print_config_def.get(opt_key);
- if (opt_def->is_vector_extruder) {
+ vector_opt = static_cast<const ConfigOptionVectorBase*>(opt.opt);
+ if (vector_opt->is_extruder_size()) {
output.set_d(((ConfigOptionVectorBase*)opt.opt)->getFloat(ctx->current_extruder_id));
break;
} else
ctx->throw_exception("Unknown scalar variable type", opt.it_range);
case coFloatsOrPercents:
- opt_def = print_config_def.get(opt_key);
- if (opt_def->is_vector_extruder) {
+ vector_opt = static_cast<const ConfigOptionVectorBase*>(opt.opt);
+ if (vector_opt->is_extruder_size()) {
output.set_d(ctx->get_computed_value(opt_key));
break;
} else
ctx->throw_exception("Unknown scalar variable type", opt.it_range);
case coStrings:
- opt_def = print_config_def.get(opt_key);
- if (opt_def->is_vector_extruder) {
+ vector_opt = static_cast<const ConfigOptionVectorBase*>(opt.opt);
+ if (vector_opt->is_extruder_size()) {
output.set_s(((ConfigOptionStrings*)opt.opt)->values[ctx->current_extruder_id]);
break;
} else
ctx->throw_exception("Unknown scalar variable type", opt.it_range);
case coPoints:
- opt_def = print_config_def.get(opt_key);
- if (opt_def->is_vector_extruder) {
+ vector_opt = static_cast<const ConfigOptionVectorBase*>(opt.opt);
+ if (vector_opt->is_extruder_size()) {
output.set_s(to_string(((ConfigOptionPoints*)opt.opt)->values[ctx->current_extruder_id]));
break;
}else
@@ -1493,4 +1494,166 @@ bool PlaceholderParser::evaluate_boolean_expression(const std::string &templ, co
return process_macro(templ, context) == "true";
}
+
+void PlaceholderParser::append_custom_variables(std::map<std::string, std::vector<std::string>> name2var_array, int nb_extruders) {
+ std::regex is_a_name("[a-zA-Z_]+");
+ for (const auto& entry : name2var_array) {
+ if (entry.first.empty())
+ continue;
+ if (!std::regex_match(entry.first, is_a_name))
+ continue;
+ const std::vector<std::string>& values = entry.second;
+ //check if all values are empty
+ bool is_not_string = false;
+ for (int extruder_id = 0; extruder_id < nb_extruders; ++extruder_id) {
+ if (!values[extruder_id].empty()) {
+ is_not_string = true;
+ break;
+ }
+ }
+ std::vector<std::string> string_values;
+ //check if all values are strings
+ if (is_not_string) {
+ is_not_string = false;
+ for (int extruder_id = 0; extruder_id < nb_extruders; ++extruder_id) {
+ if (!values[extruder_id].empty()) {
+ if (values[extruder_id].front() != '\"' && values[extruder_id].back() != '\"') {
+ is_not_string = true;
+ break;
+ }
+ string_values.push_back(values[extruder_id].substr(1, values[extruder_id].size() - 2));
+ } else {
+ string_values.push_back("");
+ }
+ }
+ }
+ //check if all values are bools
+ bool is_not_bool = !is_not_string;
+ std::vector<unsigned char> bool_values;
+ if (!is_not_bool) {
+ for (int extruder_id = 0; extruder_id < nb_extruders; ++extruder_id) {
+ if (!values[extruder_id].empty()) {
+ if (boost::algorithm::to_lower_copy(values[extruder_id]) == "true") {
+ bool_values.push_back(true);
+ } else if (boost::algorithm::to_lower_copy(values[extruder_id]) == "false") {
+ bool_values.push_back(false);
+ } else {
+ is_not_bool = true;
+ break;
+ }
+ } else {
+ bool_values.push_back(false);
+ }
+ }
+ }
+ //check if all values are numeric
+ bool is_not_numeric = !is_not_string || !is_not_bool;
+ std::vector<double> double_values;
+ //std::regex("\\s*[+-]?([0-9]+\\.[0-9]*([Ee][+-]?[0-9]+)?|\\.[0-9]+([Ee][+-]?[0-9]+)?|[0-9]+[Ee][+-]?[0-9]+)");
+ if (!is_not_numeric) {
+ for (int extruder_id = 0; extruder_id < nb_extruders; ++extruder_id) {
+ if (!values[extruder_id].empty()) {
+ try {
+ double_values.push_back(boost::lexical_cast<float>(values[extruder_id]));
+ }
+ catch (boost::bad_lexical_cast&) {
+ is_not_numeric = true;
+ break;
+ }
+ } else {
+ double_values.push_back(0);
+ }
+ }
+ }
+ //if nothing, then it's strings
+ if (is_not_string && is_not_numeric && is_not_bool) {
+ string_values = values;
+ is_not_string = false;
+ }
+ if (!is_not_numeric) {
+ std::stringstream log;
+ log << "Parsing NUM custom variable '" << entry.first << "' : ";
+ for (auto s : double_values) log << ", " << s;
+ BOOST_LOG_TRIVIAL(trace) << log.str();
+ ConfigOptionFloats* conf = new ConfigOptionFloats(double_values);
+ conf->set_is_extruder_size(true);
+ this->set(entry.first, conf);
+ } else if (!is_not_bool) {
+ std::stringstream log;
+ log << "Parsing BOOL custom variable '" << entry.first << "' : ";
+ for (auto s : bool_values) log << ", " << s;
+ BOOST_LOG_TRIVIAL(trace) << log.str();
+ ConfigOptionBools* conf = new ConfigOptionBools(bool_values);
+ conf->set_is_extruder_size(true);
+ this->set(entry.first, conf);
+ } else {
+ for (std::string& s : string_values)
+ boost::replace_all(s, "\\n", "\n");
+ std::stringstream log;
+ log << "Parsing STR custom variable '" << entry.first << "' : ";
+ for (auto s : string_values) log << ", " << s;
+ BOOST_LOG_TRIVIAL(trace) << log.str();
+ ConfigOptionStrings* conf = new ConfigOptionStrings(string_values);
+ conf->set_is_extruder_size(true);
+ this->set(entry.first, conf);
+ }
+ }
+
+}
+
+void PlaceholderParser::parse_custom_variables(const ConfigOptionString& custom_variables) {
+
+ std::map<std::string, std::vector<std::string>> name2var_array;
+
+ std::string raw_text = custom_variables.value;
+ boost::erase_all(raw_text, "\r");
+ std::vector<std::string> lines;
+ boost::algorithm::split(lines, raw_text, boost::is_any_of("\n"));
+ for (const std::string& line : lines) {
+ int equal_pos = line.find_first_of('=');
+ if (equal_pos != std::string::npos) {
+ std::string name = line.substr(0, equal_pos);
+ std::string value = line.substr(equal_pos + 1);
+ boost::algorithm::trim(name);
+ boost::algorithm::trim(value);
+ if (name2var_array.find(name) == name2var_array.end()) {
+ name2var_array.emplace(name, std::vector<std::string>{ 1, value });
+ } else
+ name2var_array[name][0] = value;
+
+ }
+ }
+ append_custom_variables(name2var_array, 1);
+}
+
+void PlaceholderParser::parse_custom_variables(const ConfigOptionStrings& filament_custom_variables)
+{
+ std::map<std::string, std::vector<std::string>> name2var_array;
+ const std::vector<std::string> empty_array(filament_custom_variables.values.size());
+
+ for (int extruder_id = 0; extruder_id < filament_custom_variables.values.size(); ++extruder_id)
+ {
+ std::string raw_text = filament_custom_variables.values[extruder_id];
+ boost::erase_all(raw_text, "\r");
+ std::vector<std::string> lines;
+ boost::algorithm::split(lines, raw_text, boost::is_any_of("\n"));
+ for (const std::string& line : lines) {
+ int equal_pos = line.find_first_of('=');
+ if (equal_pos != std::string::npos) {
+ std::string name = line.substr(0, equal_pos);
+ std::string value = line.substr(equal_pos + 1);
+ boost::algorithm::trim(name);
+ boost::algorithm::trim(value);
+ if (name2var_array.find(name) == name2var_array.end()) {
+ name2var_array.emplace(name, empty_array);
+ }
+ name2var_array[name][extruder_id] = value;
+
+ }
+ }
+ }
+ append_custom_variables(name2var_array, filament_custom_variables.values.size());
+}
+
+
}
diff --git a/src/libslic3r/PlaceholderParser.hpp b/src/libslic3r/PlaceholderParser.hpp
index ae6ef8f02..f0867443e 100644
--- a/src/libslic3r/PlaceholderParser.hpp
+++ b/src/libslic3r/PlaceholderParser.hpp
@@ -62,7 +62,14 @@ public:
// Update timestamp, year, month, day, hour, minute, second variables at m_config.
void update_timestamp() { update_timestamp(m_config); }
+ // set custom variables
+ void parse_custom_variables(const ConfigOptionString& custom_variables);
+ void parse_custom_variables(const ConfigOptionStrings& filament_custom_variables);
+
+
private:
+ void append_custom_variables(std::map<std::string, std::vector<std::string>> name2var_array, int nb_extruders);
+
// config has a higher priority than external_config when looking up a symbol.
DynamicConfig m_config;
const DynamicConfig *m_external_config;
diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp
index a133254fc..f79542964 100644
--- a/src/libslic3r/Preset.cpp
+++ b/src/libslic3r/Preset.cpp
@@ -555,7 +555,10 @@ const std::vector<std::string>& Preset::print_options()
"support_material_contact_distance_type",
"support_material_contact_distance_top",
"support_material_contact_distance_bottom",
- "support_material_buildplate_only", "dont_support_bridges", "notes",
+ "support_material_buildplate_only", "dont_support_bridges",
+ // miscellaneous
+ "notes",
+ "print_custom_variables",
"complete_objects",
"complete_objects_one_skirt",
"complete_objects_one_brim",
@@ -650,7 +653,9 @@ const std::vector<std::string>& Preset::print_options()
const std::vector<std::string>& Preset::filament_options()
{
static std::vector<std::string> s_opts {
- "filament_colour", "filament_diameter", "filament_type", "filament_soluble", "filament_notes",
+ "filament_colour",
+ "filament_custom_variables",
+ "filament_diameter", "filament_type", "filament_soluble", "filament_notes",
"filament_max_speed",
"filament_max_volumetric_speed",
"filament_max_wipe_tower_speed",
@@ -741,14 +746,23 @@ const std::vector<std::string>& Preset::printer_options()
//FIXME the print host keys are left here just for conversion from the Printer preset to Physical Printer preset.
"host_type", "print_host", "printhost_apikey", "printhost_cafile", "printhost_port",
"single_extruder_multi_material",
+ // custom gcode
"start_gcode",
"start_gcode_manual",
"end_gcode",
"before_layer_gcode",
"layer_gcode",
"toolchange_gcode",
- "color_change_gcode", "pause_print_gcode", "template_custom_gcode", "feature_gcode",
- "between_objects_gcode", "printer_vendor", "printer_model", "printer_variant", "printer_notes", "cooling_tube_retraction",
+ "color_change_gcode", "pause_print_gcode", "template_custom_gcode","feature_gcode",
+ "between_objects_gcode",
+ //printer fields
+ "printer_custom_variables",
+ "printer_vendor",
+ "printer_model",
+ "printer_variant",
+ "printer_notes",
+ // mmu
+ "cooling_tube_retraction",
"cooling_tube_length", "high_current_on_filament_swap", "parking_pos_retraction", "extra_loading_move", "max_print_height",
"default_print_profile", "inherits",
"remaining_times",
@@ -884,7 +898,7 @@ const std::vector<std::string>& Preset::sla_printer_options()
"min_initial_exposure_time", "max_initial_exposure_time",
//FIXME the print host keys are left here just for conversion from the Printer preset to Physical Printer preset.
"print_host", "printhost_apikey", "printhost_cafile", "printhost_port",
- "printer_notes",
+ "printer_custom_variables",
"inherits",
"thumbnails",
"thumbnails_color",
diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp
index d4b3f7336..87c2cc2b3 100644
--- a/src/libslic3r/Print.cpp
+++ b/src/libslic3r/Print.cpp
@@ -108,6 +108,7 @@ bool Print::invalidate_state_by_config_options(const std::vector<t_config_option
"fan_speedup_time",
"fan_percentage",
"filament_colour",
+ "filament_custom_variables",
"filament_diameter",
"filament_density",
"filament_notes",
diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp
index e69d584e4..505200986 100644
--- a/src/libslic3r/PrintConfig.cpp
+++ b/src/libslic3r/PrintConfig.cpp
@@ -1305,6 +1305,26 @@ void PrintConfigDef::init_fff_params()
def->is_vector_extruder = true;
def->set_default_value(new ConfigOptionStrings{ "#29B2B2" });
+ def = this->add("filament_custom_variables", coStrings);
+ def->label = L("Custom variables");
+ def->full_label = L("Filament custom variables");
+ def->category = OptionCategory::filament;
+ def->tooltip = L("You can add data accessible to custom-gcode macros."
+ "\nEach line can define one variable."
+ "\nThe format is 'variable_name=value'. the variabel name should only have [a-zA-Z] characters or '_'."
+ "\nA value that can be parsed as a int or float will be avaible as a numeric value."
+ "\nA value that is enclosed by double-quotes will be available as a string (without the quotes)"
+ "\nA value that only takes values as 'true' or 'false' will be a boolean)"
+ "\nEvery other value will be parsed as a string as-is."
+ "\nThese varibles will be available as an array in the custom gcode (one item per extruder), don't forget to use them with the [current_extruder] index to get the current value."
+ " If a filament has a typo on the variable that change its type, then the parser will convert evrything to strings.");
+ def->multiline = true;
+ def->full_width = true;
+ def->height = 13;
+ def->mode = comAdvanced;
+ def->is_vector_extruder = true;
+ def->set_default_value(new ConfigOptionStrings{ "" });
+
def = this->add("filament_notes", coStrings);
def->label = L("Filament notes");
def->category = OptionCategory::notes;
@@ -2982,6 +3002,23 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionString(""));
+ def = this->add("print_custom_variables", coString);
+ def->label = L("Custom variables");
+ def->full_label = L("Print custom variables");
+ def->category = OptionCategory::filament;
+ def->tooltip = L("You can add data accessible to custom-gcode macros."
+ "\nEach line can define one variable."
+ "\nThe format is 'variable_name=value'. the variabel name should only have [a-zA-Z] characters or '_'."
+ "\nA value that can be parsed as a int or float will be avaible as a numeric value."
+ "\nA value that is enclosed by double-quotes will be available as a string (without the quotes)"
+ "\nA value that only takes values as 'true' or 'false' will be a boolean)"
+ "\nEvery other value will be parsed as a string as-is.");
+ def->multiline = true;
+ def->full_width = true;
+ def->height = 13;
+ def->mode = comAdvanced;
+ def->set_default_value(new ConfigOptionString{ "" });
+
def = this->add("print_host", coString);
def->label = L("Hostname, IP or URL");
def->category = OptionCategory::general;
@@ -3223,6 +3260,23 @@ void PrintConfigDef::init_fff_params()
def->mode = comExpert;
def->set_default_value(new ConfigOptionStrings());
+ def = this->add("printer_custom_variables", coString);
+ def->label = L("Custom variables");
+ def->full_label = L("Printer custom variables");
+ def->category = OptionCategory::filament;
+ def->tooltip = L("You can add data accessible to custom-gcode macros."
+ "\nEach line can define one variable."
+ "\nThe format is 'variable_name=value'. the variabel name should only have [a-zA-Z] characters or '_'."
+ "\nA value that can be parsed as a int or float will be avaible as a numeric value."
+ "\nA value that is enclosed by double-quotes will be available as a string (without the quotes)"
+ "\nA value that only takes values as 'true' or 'false' will be a boolean)"
+ "\nEvery other value will be parsed as a string as-is.");
+ def->multiline = true;
+ def->full_width = true;
+ def->height = 13;
+ def->mode = comAdvanced;
+ def->set_default_value(new ConfigOptionString{ "" });
+
def = this->add("printer_model", coString);
def->label = L("Printer type");
def->tooltip = L("Type of the printer.");
diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp
index a575f7a99..ce90d35f5 100644
--- a/src/libslic3r/PrintConfig.hpp
+++ b/src/libslic3r/PrintConfig.hpp
@@ -1330,6 +1330,7 @@ public:
ConfigOptionBools fan_always_on;
ConfigOptionInts fan_below_layer_time;
ConfigOptionStrings filament_colour;
+ ConfigOptionStrings filament_custom_variables;
ConfigOptionStrings filament_notes;
ConfigOptionPercents filament_max_overlap;
ConfigOptionPercents filament_shrink;
@@ -1363,6 +1364,8 @@ public:
ConfigOptionString output_filename_format;
ConfigOptionFloatOrPercent perimeter_acceleration;
ConfigOptionStrings post_process;
+ ConfigOptionString print_custom_variables;
+ ConfigOptionString printer_custom_variables;
ConfigOptionString printer_model;
ConfigOptionString printer_notes;
ConfigOptionFloat resolution;
@@ -1435,6 +1438,7 @@ protected:
OPT_PTR(fan_always_on);
OPT_PTR(fan_below_layer_time);
OPT_PTR(filament_colour);
+ OPT_PTR(filament_custom_variables);
OPT_PTR(filament_notes);
OPT_PTR(filament_max_overlap);
OPT_PTR(filament_shrink);
@@ -1468,6 +1472,8 @@ protected:
OPT_PTR(output_filename_format);
OPT_PTR(perimeter_acceleration);
OPT_PTR(post_process);
+ OPT_PTR(print_custom_variables);
+ OPT_PTR(printer_custom_variables);
OPT_PTR(printer_model);
OPT_PTR(printer_notes);
OPT_PTR(resolution);
diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp
index 60b46ce5f..1804cb13d 100644
--- a/src/slic3r/GUI/MainFrame.cpp
+++ b/src/slic3r/GUI/MainFrame.cpp
@@ -417,7 +417,6 @@ void MainFrame::update_layout()
// From the very beginning the Print settings should be selected
m_last_selected_setting_tab = 0;
m_last_selected_plater_tab = 999;
- std::cout << "update_layout1: " << m_tabpanel->GetPageCount() << "\n";
// Set new settings
switch (m_layout)
@@ -815,7 +814,6 @@ void MainFrame::init_tabpanel()
if (wxGetApp().is_editor())
create_preset_tabs();
- std::cout << "create_preset_tabs: " << m_tabpanel->GetPageCount() << "\n";
if (m_plater) {
// load initial config
diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp
index fc789adbd..1236efa08 100644
--- a/src/slic3r/GUI/Tab.cpp
+++ b/src/slic3r/GUI/Tab.cpp
@@ -3079,20 +3079,20 @@ void TabPrinter::toggle_options()
const std::vector<FloatOrPercent>& min_layer_height = m_config->option<ConfigOptionFloatsOrPercents>("min_layer_height")->values;
for (int i = 0; i < min_layer_height.size(); i++) {
if(!min_layer_height[i].percent)
- if (min_layer_height[i].get_abs_value(nozzle_diameters[i]) != 0 && (int64_t)(min_layer_height[i].get_abs_value(nozzle_diameters[i]) * 1000000.) % z_step_Mlong != 0) {
+ if (min_layer_height[i].value != 0 && (int64_t)(min_layer_height[i].value * 1000000.) % z_step_Mlong != 0) {
if (!has_changed)
new_conf = *m_config;
- new_conf.option<ConfigOptionFloatsOrPercents>("min_layer_height")->values[i] = FloatOrPercent{ std::max(z_step, Slic3r::check_z_step(min_layer_height[i].get_abs_value(nozzle_diameters[i]), z_step)), false };
+ new_conf.option<ConfigOptionFloatsOrPercents>("min_layer_height")->values[i].value = std::max(z_step, Slic3r::check_z_step(min_layer_height[i].value, z_step));
has_changed = true;
}
}
std::vector<FloatOrPercent> max_layer_height = m_config->option<ConfigOptionFloatsOrPercents>("max_layer_height")->values;
for (int i = 0; i < max_layer_height.size(); i++) {
if (!max_layer_height[i].percent)
- if ((int64_t)(max_layer_height[i].get_abs_value(nozzle_diameters[i]) * 1000000.) % z_step_Mlong != 0) {
+ if ((int64_t)(max_layer_height[i].value * 1000000.) % z_step_Mlong != 0) {
if (!has_changed)
new_conf = *m_config;
- new_conf.option<ConfigOptionFloatsOrPercents>("max_layer_height")->values[i] = FloatOrPercent{ std::max(z_step, Slic3r::check_z_step(new_conf.option<ConfigOptionFloats>("max_layer_height")->values[i], z_step)), false };
+ new_conf.option<ConfigOptionFloatsOrPercents>("max_layer_height")->values[i].value = std::max(z_step, Slic3r::check_z_step(max_layer_height[i].value, z_step));
has_changed = true;
}
}
diff --git a/src/slic3r/GUI/UnsavedChangesDialog.cpp b/src/slic3r/GUI/UnsavedChangesDialog.cpp
index d56e82d80..c3b1071ee 100644
--- a/src/slic3r/GUI/UnsavedChangesDialog.cpp
+++ b/src/slic3r/GUI/UnsavedChangesDialog.cpp
@@ -922,8 +922,14 @@ static wxString get_string_value(std::string opt_key, const DynamicPrintConfig&
config.opt<ConfigOptionFloats>(opt_key)->get_at(opt_idx);
return double_to_string(val, opt->precision);
}
- case coString:
- return from_u8(config.opt_string(opt_key));
+ case coString: {
+ //character '<' '>' create strange problems for wxWidget, so remove them (only for the display)
+ std::string str = config.opt_string(opt_key);
+ boost::erase_all(str, "<");
+ boost::erase_all(str, ">");
+ return from_u8(str);
+ }
+
case coStrings: {
const ConfigOptionStrings* strings = config.opt<ConfigOptionStrings>(opt_key);
if (strings) {