diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 718975e26..1423d636e 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1585,6 +1585,21 @@ void GCode::do_export(Print* print, const char* path, GCodeProcessorResult* resu check_placeholder_parser_failed(); +#if ORCA_CHECK_GCODE_PLACEHOLDERS + if (!m_placeholder_error_messages.empty()){ + std::ostringstream message; + message << "Some EditGcodeDialog defs were not specified properly. Do so in PrintConfig under SlicingStatesConfigDef:" << std::endl; + for (const auto& error : m_placeholder_error_messages) { + message << std::endl << error.first << ": " << std::endl; + for (const auto& str : error.second) + message << str << ", "; + message.seekp(-2, std::ios_base::end); + message << std::endl; + } + throw Slic3r::PlaceholderParserError(message.str()); + } +#endif + BOOST_LOG_TRIVIAL(debug) << "Start processing gcode, " << log_memory_info(); // Post-process the G-code to update time stamps. @@ -2915,8 +2930,9 @@ void GCode::process_layers( std::string GCode::placeholder_parser_process(const std::string &name, const std::string &templ, unsigned int current_extruder_id, const DynamicConfig *config_override) { - // Orca: Modified functionality from PS implementation since debug is rarely used in current workflow. - // Allows generation to be toggled via a CMake config option. + // Orca: Added CMake config option since debug is rarely used in current workflow. + // Also changed from throwing error immediately to storing messages till slicing is completed + // to raise all errors at the same time. #if !defined(NDEBUG) || defined(ORCA_CHECK_GCODE_PLACEHOLDERS) // CHECK_CUSTOM_GCODE_PLACEHOLDERS if (config_override) { const auto& custom_gcode_placeholders = custom_gcode_specific_placeholders(); @@ -2929,17 +2945,24 @@ std::string GCode::placeholder_parser_process(const std::string &name, const std 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())); + if (std::find(placeholders.begin(), placeholders.end(), key) == placeholders.end()) { + auto& vector = m_placeholder_error_messages[name + " - option not specified for custom gcode type (s_CustomGcodeSpecificOptions)"]; + if (std::find(vector.begin(), vector.end(), key) == vector.end()) + vector.emplace_back(key); + } // 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())); + if (!custom_gcode_specific_config_def.has(key)) { + auto& vector = m_placeholder_error_messages[name + " - option has no definition (CustomGcodeSpecificConfigDef)"]; + if (std::find(vector.begin(), vector.end(), key) == vector.end()) + vector.emplace_back(key); + } } } - else - throw Slic3r::PlaceholderParserError(format("\"%s\" custom G-code needs to be added to s_CustomGcodeSpecificOptions", name.c_str())); + else { + auto& vector = m_placeholder_error_messages[name + " - gcode type not found in s_CustomGcodeSpecificOptions"]; + if (vector.empty()) + vector.emplace_back(""); + } } #endif @@ -4294,6 +4317,33 @@ void GCode::apply_print_config(const PrintConfig &print_config) m_writer.apply_print_config(print_config); m_config.apply(print_config); m_scaled_resolution = scaled(print_config.resolution.value); + +#if ORCA_CHECK_GCODE_PLACEHOLDERS + // If the gcode value is empty, set a value so that the check code within the parser is run + for (auto opt : std::initializer_list{ + &m_config.machine_start_gcode, + &m_config.machine_end_gcode, + &m_config.before_layer_change_gcode, + &m_config.layer_change_gcode, + &m_config.time_lapse_gcode, + &m_config.change_filament_gcode, + &m_config.change_extrusion_role_gcode, + &m_config.printing_by_object_gcode, + &m_config.machine_pause_gcode, + &m_config.template_custom_gcode, + }) { + if (opt->empty()) + opt->set(new ConfigOptionString(";VALUE FOR TESTING")); + } + for (auto opt : std::initializer_list{ + &m_config.filament_start_gcode, + &m_config.filament_end_gcode + }) { + if (opt->empty()) + for (int i = 0; i < opt->size(); ++i) + opt->set_at(new ConfigOptionString(";VALUE FOR TESTING"), i, 0); + } +#endif } void GCode::append_full_config(const Print &print, std::string &str) diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 7136c83a3..1912dc4d2 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -518,6 +518,10 @@ private: double m_last_mm3_per_mm; #endif // ENABLE_GCODE_VIEWER_DATA_CHECKING +#if ORCA_CHECK_GCODE_PLACEHOLDERS + std::map> m_placeholder_error_messages; +#endif + Point m_last_pos; bool m_last_pos_defined;