From b8bb7f271616df67dbfd969f4c61b6888a58a9c6 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 7 Sep 2023 16:58:37 +0200 Subject: [PATCH 1/6] Edit custom G-codes: Improvements * Prepared ConfigDefs for placeholders used in EditGCodeDialog. * Removed unused code and files * DEBUG mode only: Added check of placeholder's existence in custom_gcode_specific_placeholders and custom_gcode_specific_config_def during the custom G-code parsing. --- 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 --- src/libslic3r/Config.hpp | 3 + src/libslic3r/GCode.cpp | 28 +- src/libslic3r/GCode.hpp | 8 - src/libslic3r/Print.cpp | 40 --- src/libslic3r/PrintConfig.cpp | 316 +++++++++++++++++++ src/libslic3r/PrintConfig.hpp | 62 ++++ src/slic3r/GUI/EditGCodeDialog.cpp | 285 ++++------------- src/slic3r/GUI/EditGCodeDialog.hpp | 13 +- 17 files changed, 483 insertions(+), 348 deletions(-) delete mode 100644 resources/custom_gcodes/before_layer_gcode delete mode 100644 resources/custom_gcodes/end_filament_gcode delete mode 100644 resources/custom_gcodes/end_gcode delete mode 100644 resources/custom_gcodes/layer_gcode delete mode 100644 resources/custom_gcodes/rw_slicing_state delete mode 100644 resources/custom_gcodes/start_filament_gcode delete mode 100644 resources/custom_gcodes/tcr_rotated_gcode delete mode 100644 resources/custom_gcodes/toolchange_gcode delete mode 100644 resources/custom_gcodes/universal diff --git a/resources/custom_gcodes/before_layer_gcode b/resources/custom_gcodes/before_layer_gcode deleted file mode 100644 index 3e00992c4d..0000000000 --- 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 6cd107ae83..0000000000 --- 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 6cd107ae83..0000000000 --- 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 9bebff5d45..0000000000 --- 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 e269a084ab..0000000000 --- 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 6cd107ae83..0000000000 --- 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 b616714f57..0000000000 --- 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 a254e530b3..0000000000 --- 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 511a9c9b59..0000000000 --- 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 d3d9fe93e3..b75ec61db3 100644 --- a/src/libslic3r/Config.hpp +++ b/src/libslic3r/Config.hpp @@ -1855,6 +1855,8 @@ public: // 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 @@ public: 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 4262a4d8ec..192d42bf43 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 d34f100bf8..ae1cc333b1 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 @@ public: {} ~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 697caa392a..cbc9404e84 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 d988070ca9..806e66b19a 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 bc731d5492..390f91daf6 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -1190,6 +1190,68 @@ public: 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 028cf99d0e..413c524a49 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()); } +static ParamType get_type(const std::string& opt_key, const ConfigOptionDef& opt_def) +{ + return opt_def.is_scalar() ? ParamType::Scalar : ParamType::Vector; +} + void EditGCodeDialog::init_params_list(const std::string& custom_gcode_name) { - 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(); - - auto get_type = [](const std::string& opt_key, const DynamicConfig& config) { - return config.optptr(opt_key)->is_scalar() ? ParamType::Scalar : ParamType::Vector; - }; + 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); + 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); } - 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" }; - // 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 48f14acac0..39757ab376 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); From c66929387e2d056faf0bcf820af82258f0ba53e8 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Tue, 12 Sep 2023 10:41:59 +0200 Subject: [PATCH 2/6] Custom G-code editor: removed internal parsing of wipe tower gcode --- src/libslic3r/Config.hpp | 2 +- src/libslic3r/GCode/WipeTower.cpp | 2 +- src/libslic3r/GCode/WipeTowerIntegration.cpp | 18 ++++++++---------- src/libslic3r/PrintConfig.cpp | 12 ------------ 4 files changed, 10 insertions(+), 24 deletions(-) diff --git a/src/libslic3r/Config.hpp b/src/libslic3r/Config.hpp index b75ec61db3..09d283a327 100644 --- a/src/libslic3r/Config.hpp +++ b/src/libslic3r/Config.hpp @@ -2103,7 +2103,7 @@ public: out.push_back(kvp.first); return out; } - bool empty() { return options.empty(); } + bool empty() const { 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/WipeTower.cpp b/src/libslic3r/GCode/WipeTower.cpp index ca80dd3dc2..464d0fe755 100644 --- a/src/libslic3r/GCode/WipeTower.cpp +++ b/src/libslic3r/GCode/WipeTower.cpp @@ -1008,7 +1008,7 @@ void WipeTower::toolchange_Change( // This is where we want to place the custom gcodes. We will use placeholders for this. // These will be substituted by the actual gcodes when the gcode is generated. //writer.append("[end_filament_gcode]\n"); - writer.append("[toolchange_gcode]\n"); + writer.append("[toolchange_gcode_from_wipe_tower_generator]\n"); // Travel to where we assume we are. Custom toolchange or some special T code handling (parking extruder etc) // gcode could have left the extruder somewhere, we cannot just start extruding. We should also inform the diff --git a/src/libslic3r/GCode/WipeTowerIntegration.cpp b/src/libslic3r/GCode/WipeTowerIntegration.cpp index d8afefdf95..eb06ddd165 100644 --- a/src/libslic3r/GCode/WipeTowerIntegration.cpp +++ b/src/libslic3r/GCode/WipeTowerIntegration.cpp @@ -3,6 +3,8 @@ #include "../GCode.hpp" #include "../libslic3r.h" +#include "boost/algorithm/string/replace.hpp" + namespace Slic3r::GCode { static inline Point wipe_tower_point_to_object_point(GCodeGenerator &gcodegen, const Vec2f& wipe_tower_pt) @@ -81,19 +83,15 @@ std::string WipeTowerIntegration::append_tcr(GCodeGenerator &gcodegen, const Wip if (gcodegen.config().wipe_tower) deretraction_str = gcodegen.unretract(); } - - - + assert(toolchange_gcode_str.empty() || toolchange_gcode_str.back() == '\n'); + assert(deretraction_str.empty() || deretraction_str.back() == '\n'); // Insert the toolchange and deretraction gcode into the generated gcode. - DynamicConfig config; - config.set_key_value("toolchange_gcode", new ConfigOptionString(toolchange_gcode_str)); - config.set_key_value("deretraction_from_wipe_tower_generator", new ConfigOptionString(deretraction_str)); - std::string tcr_gcode, tcr_escaped_gcode = gcodegen.placeholder_parser_process("tcr_rotated_gcode", tcr_rotated_gcode, new_extruder_id, &config); - unescape_string_cstyle(tcr_escaped_gcode, tcr_gcode); + boost::replace_first(tcr_rotated_gcode, "[toolchange_gcode_from_wipe_tower_generator]", toolchange_gcode_str); + boost::replace_first(tcr_rotated_gcode, "[deretraction_from_wipe_tower_generator]", deretraction_str); + std::string tcr_gcode; + unescape_string_cstyle(tcr_rotated_gcode, tcr_gcode); gcode += tcr_gcode; - if (! toolchange_gcode_str.empty() && toolchange_gcode_str.back() != '\n') - toolchange_gcode_str += '\n'; // A phony move to the end position at the wipe tower. gcodegen.writer().travel_to_xy(end_pos.cast()); diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 806e66b19a..0246280e35 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -5275,8 +5275,6 @@ static std::map s_CustomGcodeSpecificP {"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() @@ -5315,16 +5313,6 @@ CustomGcodeSpecificConfigDef::CustomGcodeSpecificConfigDef() 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; From 7efdbecaf43bba0dad939fe99fcae23077e7fe04 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Tue, 12 Sep 2023 13:55:04 +0200 Subject: [PATCH 3/6] Custom GCode editor: updated labels and tooltips --- src/libslic3r/PrintConfig.cpp | 199 +++++++++++++++++----------------- 1 file changed, 102 insertions(+), 97 deletions(-) diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 0246280e35..832db5ecf0 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -5020,8 +5020,8 @@ ReadOnlySlicingStatesConfigDef::ReadOnlySlicingStatesConfigDef() ConfigOptionDef* def; def = this->add("zhop", coFloat); - def->label = L(""); - def->tooltip = L(""); + def->label = L("Current z-hop"); + def->tooltip = L("Contains z-hop present at the beginning of the custom G-code block."); } ReadWriteSlicingStatesConfigDef::ReadWriteSlicingStatesConfigDef() @@ -5030,19 +5030,21 @@ ReadWriteSlicingStatesConfigDef::ReadWriteSlicingStatesConfigDef() def = this->add("position", coFloats); def->label = L("Position"); - def->tooltip = L(""); + def->tooltip = L("Position of the extruder at the beginning of the custom G-code block. If the custom G-code travels somewhere else, " + "it should write to this variable so PrusaSlicer knows where it travels from when it gets control back."); def = this->add("e_retracted", coFloats); - def->label = L(""); - def->tooltip = L(""); + def->label = L("Retraction"); + def->tooltip = L("Retraction state at the beginning of the custom G-code block. If the custom G-code moves the extruder axis, " + "it should write to this variable so PrusaSlicer deretracts correctly when it gets control back."); def = this->add("e_restart_extra", coFloats); - def->label = L(""); - def->tooltip = L(""); + def->label = L("Extra deretraction"); + def->tooltip = L("Currently planned extra extruder priming after deretraction."); def = this->add("e_position", coFloats); - def->label = L(""); - def->tooltip = L(""); + def->label = L("Absolute E position"); + def->tooltip = L("Current position of the extruder axis. Only used with absolute extruder addressing."); } OtherSlicingStatesConfigDef::OtherSlicingStatesConfigDef() @@ -5051,35 +5053,35 @@ OtherSlicingStatesConfigDef::OtherSlicingStatesConfigDef() def = this->add("current_extruder", coInt); def->label = L("Current extruder"); - def->tooltip = L(""); + def->tooltip = L("Zero-based index of currently used extruder."); def = this->add("current_object_idx", coInt); def->label = L("Current object index"); - def->tooltip = L(""); + def->tooltip = L("Specific for sequential printing. Zero-based index of currently printed object."); def = this->add("has_single_extruder_multi_material_priming", coBool); def->label = L("Has single extruder MM priming"); - def->tooltip = L(""); + def->tooltip = L("Are the extra multi-material priming regions used in this print?"); def = this->add("has_wipe_tower", coBool); def->label = L("Has wipe tower"); - def->tooltip = L(""); + def->tooltip = L("Whether or not wipe tower is being generated in the print."); def = this->add("initial_extruder", coInt); def->label = L("Initial extruder"); - def->tooltip = L(""); + def->tooltip = L("Zero-based index of the first extruder used in the print. Same as initial_tool."); - def = this->add("initial_filament_type", coStrings); - def->label = L(""); - def->tooltip = L(""); + def = this->add("initial_filament_type", coString); + def->label = L("Initial filament type"); + def->tooltip = L("String containing filament type of the first used extruder."); def = this->add("initial_tool", coInt); def->label = L("Initial tool"); - def->tooltip = L(""); + def->tooltip = L("Zero-based index of the first extruder used in the print. Same as initial_extruder."); def = this->add("is_extruder_used", coBools); - def->label = L(""); - def->tooltip = L(""); + def->label = L("Is extruder used?"); + def->tooltip = L("Vector of bools stating whether a given extruder is used in the print."); } PrintStatisticsConfigDef::PrintStatisticsConfigDef() @@ -5087,68 +5089,68 @@ PrintStatisticsConfigDef::PrintStatisticsConfigDef() ConfigOptionDef* def; def = this->add("extruded_volume", coFloats); - def->label = L(""); - def->tooltip = L(""); + def->label = L("Volume per extruder"); + def->tooltip = L("Total filament volume extruded per extruder during the entire print."); def = this->add("normal_print_time", coString); - def->label = L(""); - def->tooltip = L(""); + def->label = L("Print time (normal mode)"); + def->tooltip = L("Estimated print time when printed in normal mode (i.e. not in silent mode). Same as print_time."); def = this->add("num_printing_extruders", coInt); - def->label = L(""); - def->tooltip = L(""); + def->label = L("Number of printing extruders"); + def->tooltip = L("Number of extruders used during the print."); def = this->add("print_time", coString); - def->label = L(""); - def->tooltip = L(""); + def->label = L("Print time (normal mode)"); + def->tooltip = L("Estimated print time when printed in normal mode (i.e. not in silent mode). Same as normal_print_time."); def = this->add("printing_filament_types", coString); - def->label = L(""); - def->tooltip = L(""); + def->label = L("Used filament types"); + def->tooltip = L("Comma-separated list of all filament types used during the print."); def = this->add("silent_print_time", coString); - def->label = L(""); - def->tooltip = L(""); + def->label = L("Print time (silent mode)"); + def->tooltip = L("Estimated print time when printed in silent mode."); def = this->add("total_cost", coFloat); - def->label = L(""); - def->tooltip = L(""); + def->label = L("Total cost"); + def->tooltip = L("Total cost of all material used in the print. Calculated from filament_cost value in Filament Settings."); def = this->add("total_weight", coFloat); - def->label = L(""); - def->tooltip = L(""); + def->label = L("Total weight"); + def->tooltip = L("Total weight of the print. Calculated from filament_density value in Filament Settings."); def = this->add("total_wipe_tower_cost", coFloat); - def->label = L(""); - def->tooltip = L(""); + def->label = L("Total wipe tower cost"); + def->tooltip = L("Total cost of the material wasted on the wipe tower. Calculated from filament_cost value in Filament Settings."); def = this->add("total_wipe_tower_filament", coFloat); - def->label = L(""); - def->tooltip = L(""); + def->label = L("Wipe tower volume"); + def->tooltip = L("Total filament volume extruded on the wipe tower."); def = this->add("used_filament", coFloat); - def->label = L(""); - def->tooltip = L(""); + def->label = L("Used filament"); + def->tooltip = L("Total length of filament used in the print."); def = this->add("total_toolchanges", coInt); def->label = L("Total toolchanges"); - def->tooltip = L(""); + def->tooltip = L("Number of toolchanges during the print."); def = this->add("extruded_volume_total", coFloat); - def->label = L(""); - def->tooltip = L(""); + def->label = L("Total volume"); + def->tooltip = L("Total volume of filament used during the entire print."); def = this->add("extruded_weight", coFloats); - def->label = L(""); - def->tooltip = L(""); + def->label = L("Weight per extruder"); + def->tooltip = L("Weight per extruder extruded during the entire print. Calculated from filament_density value in Filament Settings."); def = this->add("extruded_weight_total", coFloat); - def->label = L(""); - def->tooltip = L(""); + def->label = L("Total weight"); + def->tooltip = L("Total weight of the print. Calculated from filament_density value in Filament Settings."); def = this->add("total_layer_count", coInt); def->label = L("Total layer count"); - def->tooltip = L(""); + def->tooltip = L("Number of layers in the entire print."); } ObjectsInfoConfigDef::ObjectsInfoConfigDef() @@ -5156,57 +5158,59 @@ ObjectsInfoConfigDef::ObjectsInfoConfigDef() ConfigOptionDef* def; def = this->add("num_objects", coInt); - def->label = L(""); - def->tooltip = L(""); + def->label = L("Number of objects"); + def->tooltip = L("Total number of objects in the print."); def = this->add("num_instances", coInt); - def->label = L(""); - def->tooltip = L(""); + def->label = L("Number of instances"); + def->tooltip = L("Total number of object instances in the print, summed over all objects."); def = this->add("scale", coStrings); - def->label = L(""); - def->tooltip = L(""); - - def = this->add("input_filename", coString); - def->label = L(""); - def->tooltip = L(""); + def->label = L("Scale per object"); + def->tooltip = L("Contains a string with the information about what scaling was applied to the individual objects. " + "Indexing of the objects is zero-based (first object has index 0).\n" + "Example: 'x:100% y:50% z:100'."); def = this->add("input_filename_base", coString); - def->label = L(""); - def->tooltip = L(""); + def->label = L("Input filename without extension"); + def->tooltip = L("Source filename of the first object, without extension."); } DimensionsConfigDef::DimensionsConfigDef() { ConfigOptionDef* def; + const std::string point_tooltip = L("The vector has two elements: x and y coordinate of the point. Values in mm."); + const std::string bb_size_tooltip = L("The vector has two elements: x and y dimension of the bounding box. Values in mm."); + def = this->add("first_layer_print_convex_hull", coPoints); - def->label = L(""); - def->tooltip = L(""); + def->label = L("First layer convex hull"); + def->tooltip = L("Vector of points of the first layer convex hull. Each element has the following format:" + "'[x, y]' (x and y are floating-point numbers in mm)."); def = this->add("first_layer_print_min", coFloats); - def->label = L(""); - def->tooltip = L(""); + def->label = L("Bottom-left corner of first layer bounding box"); + def->tooltip = point_tooltip; def = this->add("first_layer_print_max", coFloats); - def->label = L(""); - def->tooltip = L(""); + def->label = L("Top-right corner of first layer bounding box"); + def->tooltip = point_tooltip; def = this->add("first_layer_print_size", coFloats); - def->label = L(""); - def->tooltip = L(""); + def->label = L("Size of the first layer bounding box"); + def->tooltip = bb_size_tooltip; def = this->add("print_bed_min", coFloats); - def->label = L(""); - def->tooltip = L(""); + def->label = L("Bottom-left corner of print bed bounding box"); + def->tooltip = point_tooltip; def = this->add("print_bed_max", coFloats); - def->label = L(""); - def->tooltip = L(""); + def->label = L("Top-right corner of print bed bounding box"); + def->tooltip = point_tooltip; def = this->add("print_bed_size", coFloats); - def->label = L(""); - def->tooltip = L(""); + def->label = L("Size of the print bed bounding box"); + def->tooltip = bb_size_tooltip; } TimestampsConfigDef::TimestampsConfigDef() @@ -5214,8 +5218,8 @@ TimestampsConfigDef::TimestampsConfigDef() ConfigOptionDef* def; def = this->add("timestamp", coString); - def->label = L(""); - def->tooltip = L(""); + def->label = L("Timestamp"); + def->tooltip = L("String containing current time in yyyyMMdd-hhmmss format."); def = this->add("year", coInt); def->label = L("Year"); @@ -5247,24 +5251,25 @@ OtherPresetsConfigDef::OtherPresetsConfigDef() ConfigOptionDef* def; def = this->add("num_extruders", coInt); - def->label = L(""); - def->tooltip = L(""); + def->label = L("Number of extruders"); + def->tooltip = L("Total number of extruders, regardless of whether they are used in the current print."); def = this->add("print_preset", coString); - def->label = L(""); - def->tooltip = L(""); + def->label = L("Print preset name"); + def->tooltip = L("Name of the print preset used for slicing."); def = this->add("filament_preset", coString); def->label = L(""); - def->tooltip = L(""); + def->tooltip = L("Names of the filament presets used for slicing. The variable is a vector " + "containing one name for each extruder."); def = this->add("printer_preset", coString); def->label = L(""); - def->tooltip = L(""); + def->tooltip = L("Name of the printer preset used for slicing."); def = this->add("physical_printer_preset", coString); def->label = L(""); - def->tooltip = L(""); + def->tooltip = L("Name of the physical print preset used for slicing."); } @@ -5287,32 +5292,32 @@ CustomGcodeSpecificConfigDef::CustomGcodeSpecificConfigDef() ConfigOptionDef* def; def = this->add("layer_num", coInt); - def->label = L(""); - def->tooltip = L(""); + def->label = L("Layer number"); + def->tooltip = L("Index of the current layer. One-based (i.e. first layer is number 1)."); def = this->add("layer_z", coFloat); - def->label = L(""); - def->tooltip = L(""); + def->label = L("Layer z"); + def->tooltip = L("Height of the current layer above the print bed, measured to the top of the layer."); def = this->add("max_layer_z", coFloat); - def->label = L(""); - def->tooltip = L(""); + def->label = L("Maximal layer z"); + def->tooltip = L("Height of the last layer above the print bed."); 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->label = L("Previous extruder"); + def->tooltip = L("Index of the extruder that is being unloaded. The index is zero based (first extruder has index 0)."); def = this->add("next_extruder", coInt); - def->label = L(""); - def->tooltip = L(""); + def->label = L("Next extruder"); + def->tooltip = L("Index of the extruder that is being loaded. The index is zero based (first extruder has index 0)."); def = this->add("toolchange_z", coFloat); - def->label = L(""); - def->tooltip = L(""); + def->label = L("Toolchange z"); + def->tooltip = L("Height above the print bed when the toolchange takes place. Usually the same as layer_z, but can be different."); } const CustomGcodeSpecificConfigDef custom_gcode_specific_config_def; From 83b8988524ada62bf5c742df88627575e7545ba9 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 12 Sep 2023 15:48:03 +0200 Subject: [PATCH 4/6] Custom GCode editor: Added wrapping for descriptions lines in dialog + Some fixes for tooltips and labels in *Configs --- src/libslic3r/PrintConfig.cpp | 14 ++++---------- src/slic3r/GUI/EditGCodeDialog.cpp | 2 +- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 832db5ecf0..e521b2bc08 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -5223,27 +5223,21 @@ TimestampsConfigDef::TimestampsConfigDef() 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() @@ -5259,17 +5253,17 @@ OtherPresetsConfigDef::OtherPresetsConfigDef() def->tooltip = L("Name of the print preset used for slicing."); def = this->add("filament_preset", coString); - def->label = L(""); + def->label = L("Filament preset name"); def->tooltip = L("Names of the filament presets used for slicing. The variable is a vector " "containing one name for each extruder."); def = this->add("printer_preset", coString); - def->label = L(""); + def->label = L("Printer preset name"); def->tooltip = L("Name of the printer preset used for slicing."); def = this->add("physical_printer_preset", coString); - def->label = L(""); - def->tooltip = L("Name of the physical print preset used for slicing."); + def->label = L("Physical printer name"); + def->tooltip = L("Name of the physical printer used for slicing."); } diff --git a/src/slic3r/GUI/EditGCodeDialog.cpp b/src/slic3r/GUI/EditGCodeDialog.cpp index 413c524a49..26ad5e827f 100644 --- a/src/slic3r/GUI/EditGCodeDialog.cpp +++ b/src/slic3r/GUI/EditGCodeDialog.cpp @@ -286,7 +286,7 @@ void EditGCodeDialog::bind_list_and_button() format_wxstr("%1%\n(%2%)", def->label.empty() ? _(def->full_label) : _(def->label), type_str); if (def) - description = _(def->tooltip); + description = get_wraped_wxString(_(def->tooltip), 120); } else label = "Undef optptr"; From d389ce91f67cb37644d59c98795557deca467806 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Wed, 13 Sep 2023 10:03:44 +0200 Subject: [PATCH 5/6] Custom GCode editor: Updated tooltips, fixed end_filament_gcode, fixed type of filament_preset --- src/libslic3r/GCode.cpp | 7 ++++++- src/libslic3r/PrintConfig.cpp | 10 +++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 192d42bf43..8e7f43d9f8 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -3299,7 +3299,12 @@ std::string GCodeGenerator::set_extruder(unsigned int extruder_id, double print_ unsigned int old_extruder_id = m_writer.extruder()->id(); const std::string &end_filament_gcode = m_config.end_filament_gcode.get_at(old_extruder_id); if (! end_filament_gcode.empty()) { - gcode += placeholder_parser_process("end_filament_gcode", end_filament_gcode, old_extruder_id); + DynamicConfig config; + config.set_key_value("layer_num", new ConfigOptionInt(m_layer_index)); + config.set_key_value("layer_z", new ConfigOptionFloat(m_writer.get_position().z() - m_config.z_offset.value)); + config.set_key_value("max_layer_z", new ConfigOptionFloat(m_max_layer_z)); + config.set_key_value("filament_extruder_id", new ConfigOptionInt(int(old_extruder_id))); + gcode += placeholder_parser_process("end_filament_gcode", end_filament_gcode, old_extruder_id, &config); check_add_eol(gcode); } } diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index e521b2bc08..15b7639227 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -5185,7 +5185,7 @@ DimensionsConfigDef::DimensionsConfigDef() def = this->add("first_layer_print_convex_hull", coPoints); def->label = L("First layer convex hull"); - def->tooltip = L("Vector of points of the first layer convex hull. Each element has the following format:" + def->tooltip = L("Vector of points of the first layer convex hull. Each element has the following format: " "'[x, y]' (x and y are floating-point numbers in mm)."); def = this->add("first_layer_print_min", coFloats); @@ -5252,7 +5252,7 @@ OtherPresetsConfigDef::OtherPresetsConfigDef() def->label = L("Print preset name"); def->tooltip = L("Name of the print preset used for slicing."); - def = this->add("filament_preset", coString); + def = this->add("filament_preset", coStrings); def->label = L("Filament preset name"); def->tooltip = L("Names of the filament presets used for slicing. The variable is a vector " "containing one name for each extruder."); @@ -5287,7 +5287,7 @@ CustomGcodeSpecificConfigDef::CustomGcodeSpecificConfigDef() def = this->add("layer_num", coInt); def->label = L("Layer number"); - def->tooltip = L("Index of the current layer. One-based (i.e. first layer is number 1)."); + def->tooltip = L("Zero-based index of the current layer (i.e. first layer is number 0)."); def = this->add("layer_z", coFloat); def->label = L("Layer z"); @@ -5298,8 +5298,8 @@ CustomGcodeSpecificConfigDef::CustomGcodeSpecificConfigDef() def->tooltip = L("Height of the last layer above the print bed."); def = this->add("filament_extruder_id", coInt); - def->label = L(""); - def->tooltip = L(""); + def->label = L("Current extruder index"); + def->tooltip = L("Zero-based index of currently used extruder (i.e. first extruder has index 0)."); def = this->add("previous_extruder", coInt); def->label = L("Previous extruder"); From 82a0c09a57c4366f11969280a9de0cdab25599e9 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Wed, 13 Sep 2023 09:04:50 +0200 Subject: [PATCH 6/6] Fixed compilation on Linux (gcc 9.4.0) --- src/libslic3r/Config.cpp | 1 + src/slic3r/GUI/EditGCodeDialog.hpp | 1 + src/slic3r/GUI/Plater.cpp | 1 + src/slic3r/GUI/Tab.cpp | 2 +- 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libslic3r/Config.cpp b/src/libslic3r/Config.cpp index 75a71acb0e..63e2b3821e 100644 --- a/src/libslic3r/Config.cpp +++ b/src/libslic3r/Config.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include diff --git a/src/slic3r/GUI/EditGCodeDialog.hpp b/src/slic3r/GUI/EditGCodeDialog.hpp index 39757ab376..b54b9cc045 100644 --- a/src/slic3r/GUI/EditGCodeDialog.hpp +++ b/src/slic3r/GUI/EditGCodeDialog.hpp @@ -13,6 +13,7 @@ class wxListBox; class wxTextCtrl; class ScalableButton; +class wxStaticText; namespace Slic3r { diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index c60e58d47f..282f0d0185 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index ee7af794db..f318f84959 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -2456,7 +2456,7 @@ void TabFilament::load_current_preset() m_extruders_cb->Select(m_active_extruder); } - assert(m_active_extruder >= 0 && m_active_extruder < m_preset_bundle->extruders_filaments.size()); + assert(m_active_extruder >= 0 && size_t(m_active_extruder) < m_preset_bundle->extruders_filaments.size()); const std::string& selected_extr_filament_name = m_preset_bundle->extruders_filaments[m_active_extruder].get_selected_preset_name(); if (selected_extr_filament_name != selected_filament_name) { m_presets->select_preset_by_name(selected_extr_filament_name, false);