diff --git a/resources/custom_gcodes/before_layer_gcode b/resources/custom_gcodes/before_layer_gcode deleted file mode 100644 index 3e00992c4df..00000000000 --- a/resources/custom_gcodes/before_layer_gcode +++ /dev/null @@ -1,4 +0,0 @@ -# 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 deleted file mode 100644 index 6cd107ae83c..00000000000 --- a/resources/custom_gcodes/end_filament_gcode +++ /dev/null @@ -1,5 +0,0 @@ -# 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 deleted file mode 100644 index 6cd107ae83c..00000000000 --- a/resources/custom_gcodes/end_gcode +++ /dev/null @@ -1,5 +0,0 @@ -# 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 deleted file mode 100644 index 9bebff5d459..00000000000 --- a/resources/custom_gcodes/layer_gcode +++ /dev/null @@ -1,4 +0,0 @@ -# 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 deleted file mode 100644 index e269a084abd..00000000000 --- a/resources/custom_gcodes/rw_slicing_state +++ /dev/null @@ -1,4 +0,0 @@ -# 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 deleted file mode 100644 index 6cd107ae83c..00000000000 --- a/resources/custom_gcodes/start_filament_gcode +++ /dev/null @@ -1,5 +0,0 @@ -# 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 deleted file mode 100644 index b616714f571..00000000000 --- a/resources/custom_gcodes/tcr_rotated_gcode +++ /dev/null @@ -1,3 +0,0 @@ -# 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 deleted file mode 100644 index a254e530b30..00000000000 --- a/resources/custom_gcodes/toolchange_gcode +++ /dev/null @@ -1,7 +0,0 @@ -# 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 deleted file mode 100644 index 511a9c9b596..00000000000 --- a/resources/custom_gcodes/universal +++ /dev/null @@ -1,39 +0,0 @@ -# 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/src/libslic3r/Config.hpp b/src/libslic3r/Config.hpp index d3d9fe93e38..b75ec61db3e 100644 --- a/src/libslic3r/Config.hpp +++ b/src/libslic3r/Config.hpp @@ -1855,6 +1855,8 @@ class ConfigOptionDef // Create a default option to be inserted into a DynamicConfig. ConfigOption* create_default_option() const; + bool is_scalar() const { return (int(this->type) & int(coVectorType)) == 0; } + template ConfigOption* load_option_from_archive(Archive &archive) const { if (this->nullable) { switch (this->type) { @@ -2101,6 +2103,7 @@ class ConfigDef out.push_back(kvp.first); return out; } + bool empty() { return options.empty(); } // Iterate through all of the CLI options and write them to a stream. std::ostream& print_cli_help( diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 4262a4d8ece..192d42bf432 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1625,10 +1625,30 @@ 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; +#ifndef NDEBUG // CHECK_CUSTOM_GCODE_PLACEHOLDERS + if (config_override) { + const auto& custom_gcode_placeholders = custom_gcode_specific_placeholders(); + + // 1-st check: custom G-code "name" have to be present in s_CustomGcodeSpecificOptions; + //if (custom_gcode_placeholders.count(name) > 0) { + // const auto& placeholders = custom_gcode_placeholders.at(name); + if (auto it = custom_gcode_placeholders.find(name); it != custom_gcode_placeholders.end()) { + const auto& placeholders = it->second; + + for (const std::string& key : config_override->keys()) { + // 2-nd check: "key" have to be present in s_CustomGcodeSpecificOptions for "name" custom G-code ; + if (std::find(placeholders.begin(), placeholders.end(), key) == placeholders.end()) + throw Slic3r::PlaceholderParserError(format("\"%s\" placeholder for \"%s\" custom G-code \n" + "needs to be added to s_CustomGcodeSpecificOptions", key.c_str(), name.c_str())); + // 3-rd check: "key" have to be present in CustomGcodeSpecificConfigDef for "key" placeholder; + if (!custom_gcode_specific_config_def.has(key)) + throw Slic3r::PlaceholderParserError(format("Definition of \"%s\" placeholder \n" + "needs to be added to CustomGcodeSpecificConfigDef", key.c_str())); + } + } + else + throw Slic3r::PlaceholderParserError(format("\"%s\" custom G-code needs to be added to s_CustomGcodeSpecificOptions", name.c_str())); + } #endif PlaceholderParserIntegration &ppi = m_placeholder_parser_integration; diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index d34f100bf8e..ae1cc333b1a 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -87,7 +87,6 @@ struct LayerResult { static LayerResult make_nop_layer_result() { return {"", std::numeric_limits::max(), false, false, true}; } }; -#define GET_CUSTOM_GCODE_PLACEHOLDERS 0 class GCodeGenerator { public: @@ -115,13 +114,6 @@ 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 697caa392a2..cbc9404e846 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -1048,46 +1048,6 @@ 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/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index d988070ca95..806e66b19af 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -5013,6 +5013,322 @@ void DynamicPrintAndCLIConfig::handle_legacy(t_config_option_key &opt_key, std:: } } +// SlicingStatesConfigDefs + +ReadOnlySlicingStatesConfigDef::ReadOnlySlicingStatesConfigDef() +{ + ConfigOptionDef* def; + + def = this->add("zhop", coFloat); + def->label = L(""); + def->tooltip = L(""); +} + +ReadWriteSlicingStatesConfigDef::ReadWriteSlicingStatesConfigDef() +{ + ConfigOptionDef* def; + + def = this->add("position", coFloats); + def->label = L("Position"); + def->tooltip = L(""); + + def = this->add("e_retracted", coFloats); + def->label = L(""); + def->tooltip = L(""); + + def = this->add("e_restart_extra", coFloats); + def->label = L(""); + def->tooltip = L(""); + + def = this->add("e_position", coFloats); + def->label = L(""); + def->tooltip = L(""); +} + +OtherSlicingStatesConfigDef::OtherSlicingStatesConfigDef() +{ + ConfigOptionDef* def; + + def = this->add("current_extruder", coInt); + def->label = L("Current extruder"); + def->tooltip = L(""); + + def = this->add("current_object_idx", coInt); + def->label = L("Current object index"); + def->tooltip = L(""); + + def = this->add("has_single_extruder_multi_material_priming", coBool); + def->label = L("Has single extruder MM priming"); + def->tooltip = L(""); + + def = this->add("has_wipe_tower", coBool); + def->label = L("Has wipe tower"); + def->tooltip = L(""); + + def = this->add("initial_extruder", coInt); + def->label = L("Initial extruder"); + def->tooltip = L(""); + + def = this->add("initial_filament_type", coStrings); + def->label = L(""); + def->tooltip = L(""); + + def = this->add("initial_tool", coInt); + def->label = L("Initial tool"); + def->tooltip = L(""); + + def = this->add("is_extruder_used", coBools); + def->label = L(""); + def->tooltip = L(""); +} + +PrintStatisticsConfigDef::PrintStatisticsConfigDef() +{ + ConfigOptionDef* def; + + def = this->add("extruded_volume", coFloats); + def->label = L(""); + def->tooltip = L(""); + + def = this->add("normal_print_time", coString); + def->label = L(""); + def->tooltip = L(""); + + def = this->add("num_printing_extruders", coInt); + def->label = L(""); + def->tooltip = L(""); + + def = this->add("print_time", coString); + def->label = L(""); + def->tooltip = L(""); + + def = this->add("printing_filament_types", coString); + def->label = L(""); + def->tooltip = L(""); + + def = this->add("silent_print_time", coString); + def->label = L(""); + def->tooltip = L(""); + + def = this->add("total_cost", coFloat); + def->label = L(""); + def->tooltip = L(""); + + def = this->add("total_weight", coFloat); + def->label = L(""); + def->tooltip = L(""); + + def = this->add("total_wipe_tower_cost", coFloat); + def->label = L(""); + def->tooltip = L(""); + + def = this->add("total_wipe_tower_filament", coFloat); + def->label = L(""); + def->tooltip = L(""); + + def = this->add("used_filament", coFloat); + def->label = L(""); + def->tooltip = L(""); + + def = this->add("total_toolchanges", coInt); + def->label = L("Total toolchanges"); + def->tooltip = L(""); + + def = this->add("extruded_volume_total", coFloat); + def->label = L(""); + def->tooltip = L(""); + + def = this->add("extruded_weight", coFloats); + def->label = L(""); + def->tooltip = L(""); + + def = this->add("extruded_weight_total", coFloat); + def->label = L(""); + def->tooltip = L(""); + + def = this->add("total_layer_count", coInt); + def->label = L("Total layer count"); + def->tooltip = L(""); +} + +ObjectsInfoConfigDef::ObjectsInfoConfigDef() +{ + ConfigOptionDef* def; + + def = this->add("num_objects", coInt); + def->label = L(""); + def->tooltip = L(""); + + def = this->add("num_instances", coInt); + def->label = L(""); + def->tooltip = L(""); + + def = this->add("scale", coStrings); + def->label = L(""); + def->tooltip = L(""); + + def = this->add("input_filename", coString); + def->label = L(""); + def->tooltip = L(""); + + def = this->add("input_filename_base", coString); + def->label = L(""); + def->tooltip = L(""); +} + +DimensionsConfigDef::DimensionsConfigDef() +{ + ConfigOptionDef* def; + + def = this->add("first_layer_print_convex_hull", coPoints); + def->label = L(""); + def->tooltip = L(""); + + def = this->add("first_layer_print_min", coFloats); + def->label = L(""); + def->tooltip = L(""); + + def = this->add("first_layer_print_max", coFloats); + def->label = L(""); + def->tooltip = L(""); + + def = this->add("first_layer_print_size", coFloats); + def->label = L(""); + def->tooltip = L(""); + + def = this->add("print_bed_min", coFloats); + def->label = L(""); + def->tooltip = L(""); + + def = this->add("print_bed_max", coFloats); + def->label = L(""); + def->tooltip = L(""); + + def = this->add("print_bed_size", coFloats); + def->label = L(""); + def->tooltip = L(""); +} + +TimestampsConfigDef::TimestampsConfigDef() +{ + ConfigOptionDef* def; + + def = this->add("timestamp", coString); + def->label = L(""); + def->tooltip = L(""); + + def = this->add("year", coInt); + def->label = L("Year"); + def->tooltip = L(""); + + def = this->add("month", coInt); + def->label = L("Month"); + def->tooltip = L(""); + + def = this->add("day", coInt); + def->label = L("Day"); + def->tooltip = L(""); + + def = this->add("hour", coInt); + def->label = L("Hour"); + def->tooltip = L(""); + + def = this->add("minute", coInt); + def->label = L("Minute"); + def->tooltip = L(""); + + def = this->add("second", coInt); + def->label = L("Second"); + def->tooltip = L(""); +} + +OtherPresetsConfigDef::OtherPresetsConfigDef() +{ + ConfigOptionDef* def; + + def = this->add("num_extruders", coInt); + def->label = L(""); + def->tooltip = L(""); + + def = this->add("print_preset", coString); + def->label = L(""); + def->tooltip = L(""); + + def = this->add("filament_preset", coString); + def->label = L(""); + def->tooltip = L(""); + + def = this->add("printer_preset", coString); + def->label = L(""); + def->tooltip = L(""); + + def = this->add("physical_printer_preset", coString); + def->label = L(""); + def->tooltip = L(""); +} + + +static std::map s_CustomGcodeSpecificPlaceholders{ + {"start_filament_gcode", {"layer_num", "layer_z", "max_layer_z", "filament_extruder_id"}}, + {"end_filament_gcode", {"layer_num", "layer_z", "max_layer_z", "filament_extruder_id"}}, + {"end_gcode", {"layer_num", "layer_z", "max_layer_z", "filament_extruder_id"}}, + {"before_layer_gcode", {"layer_num", "layer_z", "max_layer_z"}}, + {"layer_gcode", {"layer_num", "layer_z", "max_layer_z"}}, + {"toolchange_gcode", {"layer_num", "layer_z", "max_layer_z", "previous_extruder", "next_extruder", "toolchange_z"}}, + // some internal g_code ? + {"tcr_rotated_gcode", {"toolchange_gcode", "deretraction_from_wipe_tower_generator"}}, +}; + +const std::map& custom_gcode_specific_placeholders() +{ + return s_CustomGcodeSpecificPlaceholders; +} + +CustomGcodeSpecificConfigDef::CustomGcodeSpecificConfigDef() +{ + ConfigOptionDef* def; + + def = this->add("layer_num", coInt); + def->label = L(""); + def->tooltip = L(""); + + def = this->add("layer_z", coFloat); + def->label = L(""); + def->tooltip = L(""); + + def = this->add("max_layer_z", coFloat); + def->label = L(""); + def->tooltip = L(""); + + def = this->add("filament_extruder_id", coInt); + def->label = L(""); + def->tooltip = L(""); + + def = this->add("previous_extruder", coInt); + def->label = L(""); + def->tooltip = L(""); + + def = this->add("next_extruder", coInt); + def->label = L(""); + def->tooltip = L(""); + + def = this->add("toolchange_z", coFloat); + def->label = L(""); + def->tooltip = L(""); + + // I'm not sure if next options are really needed + + def = this->add("toolchange_gcode", coString); + def->label = L(""); + def->tooltip = L(""); + + def = this->add("deretraction_from_wipe_tower_generator", coString); + def->label = L(""); + def->tooltip = L(""); +} + +const CustomGcodeSpecificConfigDef custom_gcode_specific_config_def; + uint64_t ModelConfig::s_last_timestamp = 1; static Points to_points(const std::vector &dpts) diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index bc731d54926..390f91daf6a 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -1190,6 +1190,68 @@ class CLIMiscConfigDef : public ConfigDef CLIMiscConfigDef(); }; +typedef std::string t_custom_gcode_key; +// This map containes list of specific placeholders for each custom G-code, if any exist +const std::map& custom_gcode_specific_placeholders(); + +// Next classes define placeholders used by GUI::EditGCodeDialog. + +class ReadOnlySlicingStatesConfigDef : public ConfigDef +{ +public: + ReadOnlySlicingStatesConfigDef(); +}; + +class ReadWriteSlicingStatesConfigDef : public ConfigDef +{ +public: + ReadWriteSlicingStatesConfigDef(); +}; + +class OtherSlicingStatesConfigDef : public ConfigDef +{ +public: + OtherSlicingStatesConfigDef(); +}; + +class PrintStatisticsConfigDef : public ConfigDef +{ +public: + PrintStatisticsConfigDef(); +}; + +class ObjectsInfoConfigDef : public ConfigDef +{ +public: + ObjectsInfoConfigDef(); +}; + +class DimensionsConfigDef : public ConfigDef +{ +public: + DimensionsConfigDef(); +}; + +class TimestampsConfigDef : public ConfigDef +{ +public: + TimestampsConfigDef(); +}; + +class OtherPresetsConfigDef : public ConfigDef +{ +public: + OtherPresetsConfigDef(); +}; + +// This classes defines all custom G-code specific placeholders. +class CustomGcodeSpecificConfigDef : public ConfigDef +{ +public: + CustomGcodeSpecificConfigDef(); +}; +extern const CustomGcodeSpecificConfigDef custom_gcode_specific_config_def; + // This class defines the command line options representing actions. extern const CLIActionsConfigDef cli_actions_config_def; diff --git a/src/slic3r/GUI/EditGCodeDialog.cpp b/src/slic3r/GUI/EditGCodeDialog.cpp index 028cf99d0e1..413c524a491 100644 --- a/src/slic3r/GUI/EditGCodeDialog.cpp +++ b/src/slic3r/GUI/EditGCodeDialog.cpp @@ -27,99 +27,6 @@ namespace Slic3r { namespace GUI { -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())); - } -} - //------------------------------------------ // EditGCodeDialog //------------------------------------------ @@ -195,148 +102,85 @@ std::string EditGCodeDialog::get_edited_gcode() const return into_u8(m_gcode_editor->GetValue()); } -void EditGCodeDialog::init_params_list(const std::string& custom_gcode_name) +static ParamType get_type(const std::string& opt_key, const ConfigOptionDef& opt_def) { - const std::vector read_write_params = get_params_from_file("rw_slicing_state", m_read_write_config); - const std::vector universal_params = get_params_from_file("universal", m_universal_config); - const std::vector specific_params = get_params_from_file(custom_gcode_name, m_specific_config); - - m_print_statistics_config = PrintStatistics::placeholders(); + return opt_def.is_scalar() ? ParamType::Scalar : ParamType::Vector; +} - auto get_type = [](const std::string& opt_key, const DynamicConfig& config) { - return config.optptr(opt_key)->is_scalar() ? ParamType::Scalar : ParamType::Vector; - }; +void EditGCodeDialog::init_params_list(const std::string& custom_gcode_name) +{ + const auto& custom_gcode_placeholders = custom_gcode_specific_placeholders(); + const auto& specific_params = custom_gcode_placeholders.count(custom_gcode_name) > 0 ? + custom_gcode_placeholders.at(custom_gcode_name) : t_config_option_keys({}); // Add slicing states placeholders - std::set read_only_slicing_state_opts = { "zhop" }; - wxDataViewItem slicing_state = m_params_list->AppendGroup(_L("[Global] Slicing State"), "re_slice"); - if (!universal_params.empty()) { - wxDataViewItem read_only = m_params_list->AppendSubGroup(slicing_state, _L("Read Only"), "lock_closed"); - for (const auto& opt_key : read_only_slicing_state_opts) - m_params_list->AppendParam(read_only, get_type(opt_key, m_universal_config), opt_key); + if (!cgp_ro_slicing_states_config_def.empty()) { + wxDataViewItem read_only = m_params_list->AppendSubGroup(slicing_state, _L("Read Only"), "lock_closed"); + for (const auto& [opt_key, def]: cgp_ro_slicing_states_config_def.options) + m_params_list->AppendParam(read_only, get_type(opt_key, def), opt_key); } - if (!read_write_params.empty()) { + if (!cgp_rw_slicing_states_config_def.empty()) { wxDataViewItem read_write = m_params_list->AppendSubGroup(slicing_state, _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); + for (const auto& [opt_key, def] : cgp_rw_slicing_states_config_def.options) + m_params_list->AppendParam(read_write, get_type(opt_key, def), opt_key); } // add other universal params, which are related to slicing state - const std::set other_slicing_state_opts = { "initial_extruder" - , "initial_filament_type" - , "initial_tool" - , "current_extruder" - , "is_extruder_used" - , "current_object_idx" - , "has_single_extruder_multi_material_priming" - , "has_wipe_tower" }; - - slicing_state = m_params_list->AppendGroup(_L("Slicing State"), "re_slice"); - for (const auto& opt_key : other_slicing_state_opts) { - if (m_print_statistics_config.has(opt_key)) - m_params_list->AppendParam(slicing_state, get_type(opt_key, m_print_statistics_config), opt_key); - else if(!universal_params.empty()) - m_params_list->AppendParam(slicing_state, get_type(opt_key, m_universal_config), opt_key); - } - const std::set other_print_statistics_opts = { "extruded_volume_total" - , "extruded_weight" - , "extruded_weight_total" - , "total_layer_count" }; - - const std::set other_presets_opts = { "filament_preset" - , "physical_printer_preset" - , "printer_preset" - , "print_preset" - , "num_extruders" }; - - const std::set objects_info_opts = { "num_instances" - , "num_objects" - , "scale" - , "input_filename" - , "input_filename_base" }; - - const std::set dimensions_opts = { "first_layer_print_convex_hull" - , "first_layer_print_max" - , "first_layer_print_min" - , "first_layer_print_size" - , "print_bed_max" - , "print_bed_min" - , "print_bed_size" }; + if (!cgp_other_slicing_states_config_def.empty()) { + slicing_state = m_params_list->AppendGroup(_L("Slicing State"), "re_slice"); + for (const auto& [opt_key, def] : cgp_other_slicing_states_config_def.options) + m_params_list->AppendParam(slicing_state, get_type(opt_key, def), opt_key); + } // Add universal placeholders - if (!universal_params.empty()) { -// wxDataViewItem group = m_params_list->AppendGroup(_L("Universal"), "equal"); - + { // Add print statistics subgroup - if (!m_print_statistics_config.empty()) { -// wxDataViewItem statistics = m_params_list->AppendSubGroup(group, _L("Print Statistics"), "info"); + if (!cgp_print_statistics_config_def.empty()) { wxDataViewItem statistics = m_params_list->AppendGroup(_L("Print Statistics"), "info"); - const std::vector statistics_params = m_print_statistics_config.keys(); - for (const auto& opt_key : statistics_params) - if (std::find(other_slicing_state_opts.begin(), other_slicing_state_opts.end(), opt_key) == other_slicing_state_opts.end()) - m_params_list->AppendParam(statistics, get_type(opt_key, m_print_statistics_config), opt_key); - // add other universal params, which are related to print statistics - if (!universal_params.empty()) - for (const auto& opt_key : other_print_statistics_opts) - m_params_list->AppendParam(statistics, get_type(opt_key, m_universal_config), opt_key); + for (const auto& [opt_key, def] : cgp_print_statistics_config_def.options) + m_params_list->AppendParam(statistics, get_type(opt_key, def), opt_key); } // Add objects info subgroup - if (!universal_params.empty()) { -// wxDataViewItem objects_info = m_params_list->AppendSubGroup(group, _L("Objects Info"), "advanced_plus"); + if (!cgp_objects_info_config_def.empty()) { wxDataViewItem objects_info = m_params_list->AppendGroup(_L("Objects Info"), "advanced_plus"); - for (const auto& opt_key : objects_info_opts) - m_params_list->AppendParam(objects_info, get_type(opt_key, m_universal_config), opt_key); + for (const auto& [opt_key, def] : cgp_objects_info_config_def.options) + m_params_list->AppendParam(objects_info, get_type(opt_key, def), opt_key); } - // Add objects info subgroup + // Add dimensions subgroup - if (!universal_params.empty()) { -// wxDataViewItem dimensions = m_params_list->AppendSubGroup(group, _L("Dimensions"), "measure"); + if (!cgp_dimensions_config_def.empty()) { wxDataViewItem dimensions = m_params_list->AppendGroup(_L("Dimensions"), "measure"); - for (const auto& opt_key : dimensions_opts) - m_params_list->AppendParam(dimensions, get_type(opt_key, m_universal_config), opt_key); + for (const auto& [opt_key, def] : cgp_dimensions_config_def.options) + m_params_list->AppendParam(dimensions, get_type(opt_key, def), 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"); - wxDataViewItem time_stamp = m_params_list->AppendGroup(_L("Timestamps"), "time"); - - // Add un-grouped params - -// wxDataViewItem other = m_params_list->AppendSubGroup(group, _L("Other"), "add_gcode"); - wxDataViewItem other = m_params_list->AppendGroup(_L("Other"), "add_gcode"); - for (const auto& opt_key : universal_params) - if (std::find(read_only_slicing_state_opts.begin(), read_only_slicing_state_opts.end(), opt_key)== read_only_slicing_state_opts.end() && - std::find(other_slicing_state_opts.begin(), other_slicing_state_opts.end(), opt_key) == other_slicing_state_opts.end() && - std::find(other_print_statistics_opts.begin(), other_print_statistics_opts.end(), opt_key) == other_print_statistics_opts.end() && - std::find(other_presets_opts.begin(), other_presets_opts.end(), opt_key) == other_presets_opts.end() && - std::find(objects_info_opts.begin(), objects_info_opts.end(), opt_key) == objects_info_opts.end() && - std::find(dimensions_opts.begin(), dimensions_opts.end(), opt_key) == dimensions_opts.end() && - !m_print_statistics_config.has(opt_key)) { - m_params_list->AppendParam(ts_config.has(opt_key) ? time_stamp : other, get_type(opt_key, m_universal_config), opt_key); - } - m_params_list->CheckAndDeleteIfEmpty(other); + if (!cgp_timestamps_config_def.empty()) { + wxDataViewItem dimensions = m_params_list->AppendGroup(_L("Timestamps"), "time"); + for (const auto& [opt_key, def] : cgp_timestamps_config_def.options) + m_params_list->AppendParam(dimensions, get_type(opt_key, def), opt_key); + } } // Add specific placeholders if (!specific_params.empty()) { - wxDataViewItem group = m_params_list->AppendGroup(format_wxstr(_L("Specific for %1%"), custom_gcode_name), /*"not_equal"*/"add_gcode"); + wxDataViewItem group = m_params_list->AppendGroup(format_wxstr(_L("Specific for %1%"), custom_gcode_name), "add_gcode"); for (const auto& opt_key : specific_params) - m_params_list->AppendParam(group, get_type(opt_key, m_specific_config), opt_key); - + if (custom_gcode_specific_config_def.has(opt_key)) { + auto def = custom_gcode_specific_config_def.get(opt_key); + m_params_list->AppendParam(group, get_type(opt_key, *def), opt_key); + } m_params_list->Expand(group); } @@ -344,9 +188,9 @@ void EditGCodeDialog::init_params_list(const std::string& custom_gcode_name) wxDataViewItem presets = add_presets_placeholders(); // add other params which are related to presets - if (!universal_params.empty()) - for (const auto& opt_key : other_presets_opts) - m_params_list->AppendParam(presets, get_type(opt_key, m_universal_config), opt_key); + if (!cgp_other_presets_config_def.empty()) + for (const auto& [opt_key, def] : cgp_other_presets_config_def.options) + m_params_list->AppendParam(presets, get_type(opt_key, def), opt_key); } wxDataViewItem EditGCodeDialog::add_presets_placeholders() @@ -397,24 +241,33 @@ 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 ConfigOptionDef* def { nullptr }; const auto& full_config = wxGetApp().preset_bundle->full_config(); - if (const ConfigDef* def = full_config.def(); def && def->has(opt_key)) { - cod = def->get(opt_key); - optptr = full_config.optptr(opt_key); + if (const ConfigDef* config_def = full_config.def(); config_def && config_def->has(opt_key)) { + def = config_def->get(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) + for (const ConfigDef* config: std::initializer_list { + &custom_gcode_specific_config_def, + &cgp_ro_slicing_states_config_def, + &cgp_rw_slicing_states_config_def, + &cgp_other_slicing_states_config_def, + &cgp_print_statistics_config_def, + &cgp_objects_info_config_def, + &cgp_dimensions_config_def, + &cgp_timestamps_config_def, + &cgp_other_presets_config_def + }) { + if (config->has(opt_key)) { + def = config->get(opt_key); break; + } } } - if (optptr) { - const ConfigOptionType scalar_type = optptr->is_scalar() ? optptr->type() : static_cast(optptr->type() - coVectorType); + if (def) { + const ConfigOptionType scalar_type = def->is_scalar() ? def->type : static_cast(def->type - coVectorType); wxString type_str = scalar_type == coNone ? "none" : scalar_type == coFloat ? "float" : scalar_type == coInt ? "integer" : @@ -424,16 +277,16 @@ void EditGCodeDialog::bind_list_and_button() scalar_type == coPoint ? "point" : scalar_type == coBool ? "bool" : scalar_type == coEnum ? "enum" : "undef"; - if (!optptr->is_scalar()) + if (!def->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); + label = (!def || (def->full_label.empty() && def->label.empty()) ) ? format_wxstr("%1%\n(%2%)", opt_key, type_str) : + (!def->full_label.empty() && !def->label.empty() ) ? + format_wxstr("%1% > %2%\n(%3%)", _(def->full_label), _(def->label), type_str) : + format_wxstr("%1%\n(%2%)", def->label.empty() ? _(def->full_label) : _(def->label), type_str); - if (cod) - description = _(cod->tooltip); + if (def) + description = _(def->tooltip); } else label = "Undef optptr"; diff --git a/src/slic3r/GUI/EditGCodeDialog.hpp b/src/slic3r/GUI/EditGCodeDialog.hpp index 48f14acac0c..39757ab3762 100644 --- a/src/slic3r/GUI/EditGCodeDialog.hpp +++ b/src/slic3r/GUI/EditGCodeDialog.hpp @@ -8,6 +8,7 @@ #include "GUI_Utils.hpp" #include "wxExtensions.hpp" #include "libslic3r/Preset.hpp" +#include "libslic3r/PrintConfig.hpp" class wxListBox; class wxTextCtrl; @@ -31,10 +32,14 @@ class EditGCodeDialog : public DPIDialog wxStaticText* m_param_label {nullptr}; wxStaticText* m_param_description {nullptr}; - DynamicConfig m_read_write_config; - DynamicConfig m_universal_config; - DynamicConfig m_specific_config; - DynamicConfig m_print_statistics_config; + ReadOnlySlicingStatesConfigDef cgp_ro_slicing_states_config_def; + ReadWriteSlicingStatesConfigDef cgp_rw_slicing_states_config_def; + OtherSlicingStatesConfigDef cgp_other_slicing_states_config_def; + PrintStatisticsConfigDef cgp_print_statistics_config_def; + ObjectsInfoConfigDef cgp_objects_info_config_def; + DimensionsConfigDef cgp_dimensions_config_def; + TimestampsConfigDef cgp_timestamps_config_def; + OtherPresetsConfigDef cgp_other_presets_config_def; public: EditGCodeDialog(wxWindow*parent, const std::string&key, const std::string&value);