From 55d5921d53fdfdaeb1dad38e2407b598c84a4be7 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 13 Jun 2023 12:21:23 +0200 Subject: [PATCH] Editing of Custom G-code: Partially automation to get a list of placeholders for custom gcodes + Added missed resources --- resources/custom_gcodes/before_layer_gcode | 4 + resources/custom_gcodes/end_filament_gcode | 5 + resources/custom_gcodes/end_gcode | 5 + resources/custom_gcodes/layer_gcode | 4 + resources/custom_gcodes/rw_slicing_state | 4 + resources/custom_gcodes/start_filament_gcode | 5 + resources/custom_gcodes/tcr_rotated_gcode | 3 + resources/custom_gcodes/toolchange_gcode | 7 + resources/custom_gcodes/universal | 39 +++ resources/icons/scalar_param.svg | 21 ++ resources/icons/vector_filament_param.svg | 28 ++ resources/icons/vector_param.svg | 28 ++ src/PrusaSlicer.cpp | 1 + src/libslic3r/GCode.cpp | 6 + src/libslic3r/GCode.hpp | 9 + src/libslic3r/Print.cpp | 40 +++ src/libslic3r/Utils.hpp | 5 + src/libslic3r/utils.cpp | 12 + src/slic3r/GUI/EditGCodeDialog.cpp | 324 ++++++++++++------- src/slic3r/GUI/EditGCodeDialog.hpp | 7 + 20 files changed, 444 insertions(+), 113 deletions(-) create mode 100644 resources/custom_gcodes/before_layer_gcode create mode 100644 resources/custom_gcodes/end_filament_gcode create mode 100644 resources/custom_gcodes/end_gcode create mode 100644 resources/custom_gcodes/layer_gcode create mode 100644 resources/custom_gcodes/rw_slicing_state create mode 100644 resources/custom_gcodes/start_filament_gcode create mode 100644 resources/custom_gcodes/tcr_rotated_gcode create mode 100644 resources/custom_gcodes/toolchange_gcode create mode 100644 resources/custom_gcodes/universal create mode 100644 resources/icons/scalar_param.svg create mode 100644 resources/icons/vector_filament_param.svg create mode 100644 resources/icons/vector_param.svg diff --git a/resources/custom_gcodes/before_layer_gcode b/resources/custom_gcodes/before_layer_gcode new file mode 100644 index 00000000000..3e00992c4df --- /dev/null +++ b/resources/custom_gcodes/before_layer_gcode @@ -0,0 +1,4 @@ +# generated by PrusaSlicer 2.6.0-rc1 on 2023-06-15 at 13:29:08 UTC +layer_num = 2 +layer_z = 1 +max_layer_z = 1 diff --git a/resources/custom_gcodes/end_filament_gcode b/resources/custom_gcodes/end_filament_gcode new file mode 100644 index 00000000000..6cd107ae83c --- /dev/null +++ b/resources/custom_gcodes/end_filament_gcode @@ -0,0 +1,5 @@ +# generated by PrusaSlicer 2.6.0-rc1 on 2023-06-15 at 13:29:09 UTC +filament_extruder_id = 2 +layer_num = 2 +layer_z = 1 +max_layer_z = 1 diff --git a/resources/custom_gcodes/end_gcode b/resources/custom_gcodes/end_gcode new file mode 100644 index 00000000000..6cd107ae83c --- /dev/null +++ b/resources/custom_gcodes/end_gcode @@ -0,0 +1,5 @@ +# generated by PrusaSlicer 2.6.0-rc1 on 2023-06-15 at 13:29:09 UTC +filament_extruder_id = 2 +layer_num = 2 +layer_z = 1 +max_layer_z = 1 diff --git a/resources/custom_gcodes/layer_gcode b/resources/custom_gcodes/layer_gcode new file mode 100644 index 00000000000..9bebff5d459 --- /dev/null +++ b/resources/custom_gcodes/layer_gcode @@ -0,0 +1,4 @@ +# generated by PrusaSlicer 2.6.0-rc1 on 2023-06-15 at 13:29:09 UTC +layer_num = 2 +layer_z = 1 +max_layer_z = 1 diff --git a/resources/custom_gcodes/rw_slicing_state b/resources/custom_gcodes/rw_slicing_state new file mode 100644 index 00000000000..e269a084abd --- /dev/null +++ b/resources/custom_gcodes/rw_slicing_state @@ -0,0 +1,4 @@ +# generated by PrusaSlicer 2.6.0-rc1 on 2023-06-15 at 13:29:09 UTC +e_restart_extra = 16385 +e_retracted = 16385 +position = 16385 diff --git a/resources/custom_gcodes/start_filament_gcode b/resources/custom_gcodes/start_filament_gcode new file mode 100644 index 00000000000..6cd107ae83c --- /dev/null +++ b/resources/custom_gcodes/start_filament_gcode @@ -0,0 +1,5 @@ +# generated by PrusaSlicer 2.6.0-rc1 on 2023-06-15 at 13:29:09 UTC +filament_extruder_id = 2 +layer_num = 2 +layer_z = 1 +max_layer_z = 1 diff --git a/resources/custom_gcodes/tcr_rotated_gcode b/resources/custom_gcodes/tcr_rotated_gcode new file mode 100644 index 00000000000..b616714f571 --- /dev/null +++ b/resources/custom_gcodes/tcr_rotated_gcode @@ -0,0 +1,3 @@ +# generated by PrusaSlicer 2.6.0-rc1 on 2023-06-14 at 11:40:58 UTC +deretraction_from_wipe_tower_generator = 3 +toolchange_gcode = 3 diff --git a/resources/custom_gcodes/toolchange_gcode b/resources/custom_gcodes/toolchange_gcode new file mode 100644 index 00000000000..a254e530b30 --- /dev/null +++ b/resources/custom_gcodes/toolchange_gcode @@ -0,0 +1,7 @@ +# generated by PrusaSlicer 2.6.0-rc1 on 2023-06-14 at 11:40:58 UTC +layer_num = 2 +layer_z = 1 +max_layer_z = 1 +next_extruder = 2 +previous_extruder = 2 +toolchange_z = 1 diff --git a/resources/custom_gcodes/universal b/resources/custom_gcodes/universal new file mode 100644 index 00000000000..511a9c9b596 --- /dev/null +++ b/resources/custom_gcodes/universal @@ -0,0 +1,39 @@ +# generated by PrusaSlicer 2.6.0-rc1 on 2023-06-15 at 13:29:09 UTC +current_extruder = 2 +current_object_idx = 2 +day = 2 +extruded_volume = 16385 +extruded_volume_total = 1 +extruded_weight = 16385 +extruded_weight_total = 1 +filament_preset = 16387 +first_layer_print_convex_hull = 16390 +first_layer_print_max = 16385 +first_layer_print_min = 16385 +first_layer_print_size = 16385 +has_single_extruder_multi_material_priming = 8 +has_wipe_tower = 8 +hour = 2 +initial_extruder = 2 +initial_tool = 2 +input_filename = 3 +input_filename_base = 3 +is_extruder_used = 16392 +minute = 2 +month = 2 +num_extruders = 2 +num_instances = 2 +num_objects = 2 +physical_printer_preset = 3 +print_bed_max = 16385 +print_bed_min = 16385 +print_bed_size = 16385 +print_preset = 3 +printer_preset = 3 +scale = 16387 +second = 2 +timestamp = 3 +total_layer_count = 2 +total_toolchanges = 2 +year = 2 +zhop = 1 diff --git a/resources/icons/scalar_param.svg b/resources/icons/scalar_param.svg new file mode 100644 index 00000000000..f9386ab70e8 --- /dev/null +++ b/resources/icons/scalar_param.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + diff --git a/resources/icons/vector_filament_param.svg b/resources/icons/vector_filament_param.svg new file mode 100644 index 00000000000..a3404cfd88f --- /dev/null +++ b/resources/icons/vector_filament_param.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/icons/vector_param.svg b/resources/icons/vector_param.svg new file mode 100644 index 00000000000..a5c8affc7fd --- /dev/null +++ b/resources/icons/vector_param.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/PrusaSlicer.cpp b/src/PrusaSlicer.cpp index 0d627aa8372..4b2aaed18dc 100644 --- a/src/PrusaSlicer.cpp +++ b/src/PrusaSlicer.cpp @@ -763,6 +763,7 @@ bool CLI::setup(int argc, char **argv) set_var_dir((path_resources / "icons").string()); set_local_dir((path_resources / "localization").string()); set_sys_shapes_dir((path_resources / "shapes").string()); + set_custom_gcodes_dir((path_resources / "custom_gcodes").string()); // Parse all command line options into a DynamicConfig. // If any option is unsupported, print usage and abort immediately. diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index debe3e63b9e..5ae7cd0dd0a 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1504,6 +1504,12 @@ std::string GCodeGenerator::placeholder_parser_process( unsigned int current_extruder_id, const DynamicConfig *config_override) { +#if GET_CUSTOM_GCODE_PLACEHOLDERS + if (config_override && + g_code_placeholders_map.find(name) == g_code_placeholders_map.end()) + g_code_placeholders_map[name] = *config_override; +#endif + PlaceholderParserIntegration &ppi = m_placeholder_parser_integration; try { ppi.update_from_gcodewriter(m_writer); diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 1c928749220..888055cc9ac 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -72,6 +72,8 @@ struct LayerResult { }; class GCodeGenerator { +#define GET_CUSTOM_GCODE_PLACEHOLDERS 1 + public: GCodeGenerator() : m_origin(Vec2d::Zero()), @@ -97,6 +99,13 @@ class GCodeGenerator { {} ~GCodeGenerator() = default; +#if GET_CUSTOM_GCODE_PLACEHOLDERS + std::map g_code_placeholders_map; + const std::map& get_g_code_placeholders_map() { return g_code_placeholders_map; } + const DynamicConfig& get_placeholder_parser_config() const { return m_placeholder_parser_integration.parser.config(); } + const DynamicConfig& get_placeholder_output_config() const { return m_placeholder_parser_integration.output_config; } +#endif + // throws std::runtime_exception on error, // throws CanceledException through print->throw_if_canceled(). void do_export(Print* print, const char* path, GCodeProcessorResult* result = nullptr, ThumbnailsGeneratorCallback thumbnail_cb = nullptr); diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 1ee545606cb..c63b3b1a95d 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -1014,6 +1014,46 @@ std::string Print::export_gcode(const std::string& path_template, GCodeProcessor std::unique_ptr gcode(new GCodeGenerator); gcode->do_export(this, path.c_str(), result, thumbnail_cb); + +#if GET_CUSTOM_GCODE_PLACEHOLDERS + + const std::string dir = custom_gcodes_dir() + +#ifdef _WIN32 + "\\"; +#else + "/"; +#endif + + auto save_placeholders = [dir](const std::string& file_name, const DynamicConfig& config) { + try { + boost::nowide::ofstream c; + c.open(dir + file_name, std::ios::out | std::ios::trunc); + c << "# " << header_slic3r_generated() << std::endl; + auto keys = config.keys(); + for (const std::string& opt_key : keys) { + const std::string type = std::to_string(int(config.optptr(opt_key)->type())); + c << opt_key << " = " << type << std::endl; + } + c.close(); + } + catch (const std::ofstream::failure& err) { + throw RuntimeError(format("The %1% cannot be loaded:\n\tReason: %2%", file_name, err.what())); + } + }; + + // save specific placeholders + const auto& gcode_placeholders = gcode->get_g_code_placeholders_map(); + for (const auto& [gcode_name, config] : gcode_placeholders) + save_placeholders(gcode_name, config); + + // save universal placeholders + save_placeholders("universal", gcode->get_placeholder_parser_config()); + + // save placeholders for "rw_slicing_state" slicing state + save_placeholders("rw_slicing_state", gcode->get_placeholder_output_config()); + +#endif + if (m_conflict_result.has_value()) result->conflict_result = *m_conflict_result; diff --git a/src/libslic3r/Utils.hpp b/src/libslic3r/Utils.hpp index 9cc81b241fe..201cbcc88d6 100644 --- a/src/libslic3r/Utils.hpp +++ b/src/libslic3r/Utils.hpp @@ -53,6 +53,11 @@ const std::string& sys_shapes_dir(); // Return a full path to the custom shapes gallery directory. std::string custom_shapes_dir(); +// Set a path with shapes gallery files. +void set_custom_gcodes_dir(const std::string &path); +// Return a full path to the system shapes gallery directory. +const std::string& custom_gcodes_dir(); + // Set a path with preset files. void set_data_dir(const std::string &path); // Return a full path to the GUI resource files. diff --git a/src/libslic3r/utils.cpp b/src/libslic3r/utils.cpp index d934819bfe8..161a24e0a6a 100644 --- a/src/libslic3r/utils.cpp +++ b/src/libslic3r/utils.cpp @@ -193,6 +193,18 @@ const std::string& sys_shapes_dir() return g_sys_shapes_dir; } +static std::string g_custom_gcodes_dir; + +void set_custom_gcodes_dir(const std::string &dir) +{ + g_custom_gcodes_dir = dir; +} + +const std::string& custom_gcodes_dir() +{ + return g_custom_gcodes_dir; +} + // Translate function callback, to call wxWidgets translate function to convert non-localized UTF8 string to a localized one. Slic3r::I18N::translate_fn_type Slic3r::I18N::translate_fn = nullptr; diff --git a/src/slic3r/GUI/EditGCodeDialog.cpp b/src/slic3r/GUI/EditGCodeDialog.cpp index ea80d95351a..2875ffe7e37 100644 --- a/src/slic3r/GUI/EditGCodeDialog.cpp +++ b/src/slic3r/GUI/EditGCodeDialog.cpp @@ -20,30 +20,104 @@ #include "MsgDialog.hpp" #include "Plater.hpp" +#include "libslic3r/PlaceholderParser.hpp" #include "libslic3r/Preset.hpp" +#include "libslic3r/Print.hpp" namespace Slic3r { namespace GUI { - -static std::vector get_specific_params(const std::string& custom_gcode) -{ - if (custom_gcode == "start_filament_gcode" || custom_gcode == "end_filament_gcode") - return{ "max_layer_z", - "layer_num", - "layer_z", - "filament_extruder_id" }; - if (custom_gcode == "end_gcode" || custom_gcode == "before_layer_gcode" || custom_gcode == "layer_gcode") - return{ "max_layer_z", - "layer_num", - "layer_z" }; - if (custom_gcode == "toolchange_gcode") - return{ "next_extruder", - "previous_extruder", - "toolchange_z", - "max_layer_z", - "layer_num", - "layer_z" }; - return {}; + +ConfigOption* get_new_option(const ConfigOptionType type) +{ + switch (type) { + case coFloat: + return new ConfigOptionFloat(0.); + case coFloats: + return new ConfigOptionFloats({ 0. }); + case coInt: + return new ConfigOptionInt(0); + case coInts: + return new ConfigOptionInts({ 0 }); + case coString: + return new ConfigOptionString(""); + case coStrings: + return new ConfigOptionStrings({ ""}); + case coPercent: + return new ConfigOptionPercent(0); + case coPercents: + return new ConfigOptionPercents({ 0}); + case coFloatOrPercent: + return new ConfigOptionFloatOrPercent(); + case coFloatsOrPercents: + return new ConfigOptionFloatsOrPercents(); + case coPoint: + return new ConfigOptionPoint(Vec2d(100, 100)); + case coPoints: + return new ConfigOptionPoints({ Vec2d(100,100) }); + case coPoint3: + return new ConfigOptionPoint3(); + case coBool: + return new ConfigOptionBool(true); + case coBools: + return new ConfigOptionBools({ true }); + case coEnum: + return new ConfigOptionEnum(); + default: + return nullptr; + } +} + +namespace fs = boost::filesystem; +namespace pt = boost::property_tree; +static std::vector get_params_from_file(const std::string& file_name, DynamicConfig& out_config) +{ + const fs::path file_path = fs::path(custom_gcodes_dir() + +#ifdef _WIN32 + "\\" +#else + "/" +#endif + + file_name); + + if (!fs::exists(file_path)) + return {}; + + const std::string file = file_path.string(); + + // Load the preset file, apply preset values on top of defaults. + try { + DynamicConfig config; + + try { + pt::ptree tree; + boost::nowide::ifstream ifs(file); + pt::read_ini(ifs, tree); + for (const pt::ptree::value_type& v : tree) { + try { + t_config_option_key opt_key = v.first; + const std::string type_str = v.second.get_value(); + const ConfigOptionType type = ConfigOptionType(std::atoi(type_str.c_str())); + if (ConfigOption* opt = get_new_option(type)) + config.set_key_value(opt_key, std::move(opt)); + } + catch (UnknownOptionException& err) { + throw RuntimeError(format("Some option from %1% cannot be loaded:\n\tReason: %2%", file, err.what())); + } + } + } + catch (const ConfigurationError& e) { + throw ConfigurationError(format("Failed loading configuration file \"%1%\": \n\t%2%", file, e.what())); + } + + out_config += config; + return config.keys(); + } + catch (const std::ifstream::failure& err) { + throw RuntimeError(format("The %1% cannot be loaded:\n\tReason: %2%", file, err.what())); + } + catch (const std::runtime_error& err) { + throw RuntimeError(format("Failed loading the custom_gcode_placeholders file: \"%1%\"\n\tReason: %2%", file , err.what())); + } } //------------------------------------------ @@ -120,97 +194,106 @@ std::string EditGCodeDialog::get_edited_gcode() const void EditGCodeDialog::init_params_list(const std::string& custom_gcode_name) { - wxDataViewItem group = m_params_list->AppendGroup(_L("Slicing State"), "re_slice"); + const std::vector universal_params = get_params_from_file("universal", m_universal_config); + + auto get_type = [](const std::string& opt_key, const DynamicConfig& config) { + return config.optptr(opt_key)->is_scalar() ? ParamType::Scalar : ParamType::Vector; + }; + + // Add slicing states placeholders + + std::vector read_only_opts = { "zhop" }; + wxDataViewItem group = m_params_list->AppendGroup(_L("Slicing State"), "re_slice"); { - wxDataViewItem read_only = m_params_list->AppendSubGroup(group, _L("Read Only"), "lock_closed"); - m_params_list->AppendParam(read_only, ParamType::Scalar, "zhop"); + wxDataViewItem read_only = m_params_list->AppendSubGroup(group, _L("Read Only"), "lock_closed"); + for (const auto& opt_key : read_only_opts) + m_params_list->AppendParam(read_only, get_type(opt_key, m_universal_config), opt_key); } - { - wxDataViewItem read_write = m_params_list->AppendSubGroup(group, _L("Read Write"), "lock_open"); - for (const auto& opt_name : { "position", "e_position"}) - m_params_list->AppendParam(read_write, ParamType::Vector, opt_name); - for (const auto& opt_name : { "e_retracted", "e_restart_extra"}) - m_params_list->AppendParam(read_write, ParamType::FilamentVector, opt_name); + + const std::vector read_write_params = get_params_from_file("rw_slicing_state", m_read_write_config); + if (!read_write_params.empty()) { + wxDataViewItem read_write = m_params_list->AppendSubGroup(group, _L("Read Write"), "lock_open"); + for (const auto& opt_key : read_write_params) + m_params_list->AppendParam(read_write, get_type(opt_key, m_read_write_config), opt_key); } - group = m_params_list->AppendGroup(_L("Universal"), "equal"); - { - wxDataViewItem time_stamp = m_params_list->AppendSubGroup(group, _L("Time Stamp"), "time"); - for (const auto& opt_name : { "day", - "hour", - "minute", - "month", - "second", - "year", - "timestamp" }) - m_params_list->AppendParam(time_stamp, ParamType::Scalar, opt_name); - - for (const auto& opt_name : { "current_extruder", - "current_object_idx", - "filament_preset", - "first_layer_print_convex_hull", - "first_layer_print_max", - "first_layer_print_min", - "first_layer_print_size", - "has_single_extruder_multi_material_priming", - "has_wipe_tower", - "initial_extruder", - "initial_tool", - "input_filename", - "input_filename_base", - "is_extruder_used", - "num_instances", - "num_objects", - "physical_printer_preset", - "print_bed_max", - "print_bed_min", - "print_bed_size", - "print_preset", - "printer_preset", - "scale", - "total_layer_count", - "total_toolchanges" }) - m_params_list->AppendParam(group, ParamType::Scalar, opt_name); + // Add universal placeholders + + if (!universal_params.empty()) { + group = m_params_list->AppendGroup(_L("Universal"), "equal"); + + // Add print statistics subgroup + + m_print_statistics_config = PrintStatistics::placeholders(); + if (!m_print_statistics_config.empty()) { + wxDataViewItem statistics = m_params_list->AppendSubGroup(group, _L("Print Statistics"), "info"); + const std::vector statistics_params = m_print_statistics_config.keys(); + for (const auto& opt_key : statistics_params) + m_params_list->AppendParam(statistics, get_type(opt_key, m_print_statistics_config), opt_key); + } + + // Add timestamp subgroup + + PlaceholderParser parser; + parser.update_timestamp(); + const DynamicConfig& ts_config = parser.config(); + wxDataViewItem time_stamp = ts_config.empty() ? group : m_params_list->AppendSubGroup(group, _L("Timestamps"), "time"); + + // Add un-grouped params + + wxDataViewItem other = m_params_list->AppendSubGroup(group, _L("Other"), "add_gcode"); + for (const auto& opt_key : universal_params) { + if (m_print_statistics_config.has(opt_key) || std::find(read_only_opts.begin(), read_only_opts.end(), opt_key) != read_only_opts.end()) + continue; + m_params_list->AppendParam( ts_config.has(opt_key) ? time_stamp : other, get_type(opt_key, m_universal_config), opt_key); + } } - std::vector specific_params = get_specific_params(custom_gcode_name); + // Add specific placeholders + + const std::vector specific_params = get_params_from_file(custom_gcode_name, m_specific_config); if (!specific_params.empty()) { group = m_params_list->AppendGroup(format_wxstr(_L("Specific for %1%"), custom_gcode_name), "not_equal"); - for (const auto& opt_name : specific_params) - m_params_list->AppendParam(group, ParamType::Scalar, opt_name); + for (const auto& opt_key : specific_params) + m_params_list->AppendParam(group, get_type(opt_key, m_specific_config), opt_key); + + m_params_list->Expand(group); } - auto get_set_from_vec = [](const std::vector& vec) { + // Add placeholders from presets + + add_presets_placeholders(); +} + +void EditGCodeDialog::add_presets_placeholders() +{ + auto get_set_from_vec = [](const std::vector&vec) { return std::set(vec.begin(), vec.end()); }; - const bool is_fff = wxGetApp().plater()->printer_technology() == ptFFF; + + const bool is_fff = wxGetApp().plater()->printer_technology() == ptFFF; const std::set print_options = get_set_from_vec(is_fff ? Preset::print_options() : Preset::sla_print_options()); const std::set material_options = get_set_from_vec(is_fff ? Preset::filament_options() : Preset::sla_material_options()); const std::set printer_options = get_set_from_vec(is_fff ? Preset::printer_options() : Preset::sla_printer_options()); - const auto& full_config = wxGetApp().preset_bundle->full_config(); + const auto&full_config = wxGetApp().preset_bundle->full_config(); - const auto& def = full_config.def()->get("")->label; + wxDataViewItem group = m_params_list->AppendGroup(_L("Presets"), "cog"); + wxDataViewItem print = m_params_list->AppendSubGroup(group, _L("Print settings"), "cog"); + for (const auto&opt : print_options) + if (const ConfigOption *optptr = full_config.optptr(opt)) + m_params_list->AppendParam(print, optptr->is_scalar() ? ParamType::Scalar : ParamType::Vector, opt); + + wxDataViewItem material = m_params_list->AppendSubGroup(group, _(is_fff ? L("Filament settings") : L("SLA Materials settings")), is_fff ? "spool" : "resin"); + for (const auto&opt : material_options) + if (const ConfigOption *optptr = full_config.optptr(opt)) + m_params_list->AppendParam(material, optptr->is_scalar() ? ParamType::Scalar : ParamType::FilamentVector, opt); - group = m_params_list->AppendGroup(_L("Presets"), "cog"); - { - wxDataViewItem print = m_params_list->AppendSubGroup(group, _L("Print settings"), "cog"); - for (const auto& opt : print_options) - if (const ConfigOption *optptr = full_config.optptr(opt)) - m_params_list->AppendParam(print, optptr->is_scalar() ? ParamType::Scalar : ParamType::Vector, opt); - - wxDataViewItem material = m_params_list->AppendSubGroup(group, _(is_fff ? L("Filament settings") : L("SLA Materials settings")), is_fff ? "spool" : "resin"); - for (const auto& opt : material_options) - if (const ConfigOption *optptr = full_config.optptr(opt)) - m_params_list->AppendParam(material, optptr->is_scalar() ? ParamType::Scalar : ParamType::FilamentVector, opt); - - wxDataViewItem printer = m_params_list->AppendSubGroup(group, _L("Printer settings"), is_fff ? "printer" : "sla_printer"); - for (const auto& opt : printer_options) - if (const ConfigOption *optptr = full_config.optptr(opt)) - m_params_list->AppendParam(printer, optptr->is_scalar() ? ParamType::Scalar : ParamType::Vector, opt); - - } + wxDataViewItem printer = m_params_list->AppendSubGroup(group, _L("Printer settings"), is_fff ? "printer" : "sla_printer"); + for (const auto&opt : printer_options) + if (const ConfigOption *optptr = full_config.optptr(opt)) + m_params_list->AppendParam(printer, optptr->is_scalar() ? ParamType::Scalar : ParamType::Vector, opt); } void EditGCodeDialog::add_selected_value_to_gcode() @@ -227,28 +310,43 @@ void EditGCodeDialog::bind_list_and_button() const std::string opt_key = m_params_list->GetSelectedParamKey(); if (!opt_key.empty()) { + const ConfigOptionDef* cod { nullptr }; + const ConfigOption* optptr { nullptr }; + const auto& full_config = wxGetApp().preset_bundle->full_config(); - if (const ConfigDef* def = full_config.def(); - def && def->has(opt_key)) { - const ConfigOptionDef* cod = def->get(opt_key); - const ConfigOption* optptr = full_config.optptr(opt_key); - const ConfigOptionType type = optptr->type(); - - wxString type_str = type == coNone ? "none" : - type == coFloat || type == coFloats ? "float" : - type == coInt || type == coInts ? "integer" : - type == coString || type == coStrings ? "string" : - type == coPercent || type == coPercents ? "percent" : - type == coFloatOrPercent || type == coFloatsOrPercents ? "float ar percent" : - type == coPoint || type == coPoints || type == coPoint3 ? "point" : - type == coBool || type == coBools ? "bool" : - type == coEnum ? "enum" : "undef"; - - label = ( cod->full_label.empty() && cod->label.empty() ) ? format_wxstr("Undef Label\n(%1%)", type_str) : + if (const ConfigDef* def = full_config.def(); def && def->has(opt_key)) { + cod = def->get(opt_key); + optptr = full_config.optptr(opt_key); + } + else { + for (const DynamicConfig* config: { &m_read_write_config, &m_universal_config, &m_specific_config, &m_print_statistics_config }) { + optptr = config->optptr(opt_key); + if (optptr) + break; + } + } + + if (optptr) { + const ConfigOptionType scalar_type = optptr->is_scalar() ? optptr->type() : static_cast(optptr->type() - coVectorType); + wxString type_str = scalar_type == coNone ? "none" : + scalar_type == coFloat ? "float" : + scalar_type == coInt ? "integer" : + scalar_type == coString ? "string" : + scalar_type == coPercent ? "percent" : + scalar_type == coFloatOrPercent ? "float or percent" : + scalar_type == coPoint ? "point" : + scalar_type == coBool ? "bool" : + scalar_type == coEnum ? "enum" : "undef"; + if (!optptr->is_scalar()) + type_str += "[]"; + + label = (!cod || (cod->full_label.empty() && cod->label.empty()) ) ? format_wxstr("%1%\n(%2%)", opt_key, type_str) : (!cod->full_label.empty() && !cod->label.empty() ) ? format_wxstr("%1% > %2%\n(%3%)", _(cod->full_label), _(cod->label), type_str) : format_wxstr("%1%\n(%2%)", cod->label.empty() ? _(cod->full_label) : _(cod->label), type_str); } + else + label = "Undef optptr"; } m_param_label->SetLabel(label); @@ -461,7 +559,7 @@ void ParamsModel::GetValue(wxVariant& variant, const wxDataViewItem& item, unsig assert(item.IsOk()); ParamsNode* node = static_cast(item.GetID()); - if (col == unsigned int(0)) + if (col == (unsigned int)0) #ifdef __linux__ variant << wxDataViewIconText(node->text, get_bmp_bundle(node->icon_name)->GetIconFor(m_ctrl->GetParent())); #else @@ -476,11 +574,11 @@ bool ParamsModel::SetValue(const wxVariant& variant, const wxDataViewItem& item, assert(item.IsOk()); ParamsNode* node = static_cast(item.GetID()); - if (col == unsigned int(0)) { + if (col == (unsigned int)0) { #ifdef __linux__ wxDataViewIconText data; data << variant; - node->m_icon = data.GetIcon(); + node->icon = data.GetIcon(); #else DataViewBitmapText data; data << variant; @@ -559,7 +657,7 @@ ParamsViewCtrl::ParamsViewCtrl(wxWindow *parent, wxSize size) #ifdef SUPPORTS_MARKUP rd->EnableMarkup(true); #endif - wxDataViewColumn* column = new wxDataViewColumn("", rd, 0, width * m_em_unit, wxALIGN_TOP, wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_CELL_INERT); + wxDataViewColumn* column = new wxDataViewColumn("", rd, 0, 20 * m_em_unit, wxALIGN_TOP, wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_CELL_INERT); #else wxDataViewColumn* column = new wxDataViewColumn("", new BitmapTextRenderer(true, wxDATAVIEW_CELL_INERT), 0, 20 * m_em_unit, wxALIGN_TOP, wxDATAVIEW_COL_RESIZABLE); #endif //__linux__ diff --git a/src/slic3r/GUI/EditGCodeDialog.hpp b/src/slic3r/GUI/EditGCodeDialog.hpp index be7746b413e..f255190f98b 100644 --- a/src/slic3r/GUI/EditGCodeDialog.hpp +++ b/src/slic3r/GUI/EditGCodeDialog.hpp @@ -30,6 +30,11 @@ class EditGCodeDialog : public DPIDialog wxTextCtrl* m_gcode_editor {nullptr}; wxStaticText* m_param_label {nullptr}; + DynamicConfig m_read_write_config; + DynamicConfig m_universal_config; + DynamicConfig m_specific_config; + DynamicConfig m_print_statistics_config; + public: EditGCodeDialog(wxWindow*parent, const std::string&key, const std::string&value); ~EditGCodeDialog() {} @@ -37,6 +42,8 @@ class EditGCodeDialog : public DPIDialog std::string get_edited_gcode() const; void init_params_list(const std::string& custom_gcode_name); + void add_presets_placeholders(); + void add_selected_value_to_gcode(); void bind_list_and_button();