From 641a4fd1f2e8bee0e3bf777a722c8637ba89fef7 Mon Sep 17 00:00:00 2001 From: Arthur Date: Fri, 4 Aug 2023 10:49:14 +0800 Subject: [PATCH] ENH: add load_model_objects_and_custom_gcodes Add cmd line option to pass layer change gcode. This is useful for lithophane auto change colors. Cmd: --custom-gcode custom_gcode_toolchange.json Examples of the input json file can be found in the jira. Jira: STUDIO-4070 Change-Id: I5beb5ff7d6d81028e95013e79f955e498cd3ba30 --- src/BambuStudio.cpp | 53 +++++++++++++++++++++++++++++++++++ src/libslic3r/Config.cpp | 1 + src/libslic3r/CustomGCode.hpp | 37 ++++++++++++++++++++++++ src/libslic3r/PrintConfig.cpp | 6 ++++ 4 files changed, 97 insertions(+) diff --git a/src/BambuStudio.cpp b/src/BambuStudio.cpp index 794622313..f320ca6bb 100644 --- a/src/BambuStudio.cpp +++ b/src/BambuStudio.cpp @@ -655,6 +655,11 @@ int CLI::run(int argc, char **argv) } } + std::string custom_gcode_file; + ConfigOptionString* custom_gcode_option = m_config.option("load_custom_gcodes"); + if (custom_gcode_option) + custom_gcode_file = custom_gcode_option->value; + /*for (const std::string& file : m_input_files) if (is_gcode_file(file) && boost::filesystem::exists(file)) { start_as_gcodeviewer = true; @@ -845,6 +850,41 @@ int CLI::run(int argc, char **argv) } //} + //load custom gcode file + std::map custom_gcodes_map; + if (!custom_gcode_file.empty()) { + // parse the custom gcode json file + std::string file = custom_gcode_file; + if(!boost::filesystem::exists(file)) { + boost::nowide::cerr << __FUNCTION__ << ": can not find custom_gcode file: " << file << std::endl; + record_exit_reson(outfile_dir, CLI_FILE_NOTFOUND, 0, cli_errors[CLI_FILE_NOTFOUND], sliced_info); + flush_and_exit(CLI_FILE_NOTFOUND); + } + try { + nlohmann::json jj; + boost::nowide::ifstream ifs(file); + ifs >> jj; + ifs.close(); + + int plate_id = 0; + if (plate_to_slice == 0) + plate_id = 0; + else + plate_id = plate_to_slice-1; + + CustomGCode::Info info; + info.from_json(jj); + + custom_gcodes_map.emplace(plate_id, info); + BOOST_LOG_TRIVIAL(info) << boost::format("load custom_gcode from file %1% success, store custom gcodes to plate %2%")%file %(plate_id+1); + } + catch (std::exception &ex) { + boost::nowide::cerr << __FUNCTION__<< ":Loading custom-gcode file \"" << file << "\" failed: " << ex.what() << std::endl; + record_exit_reson(outfile_dir, CLI_CONFIG_FILE_ERROR, 0, cli_errors[CLI_CONFIG_FILE_ERROR], sliced_info); + flush_and_exit(CLI_CONFIG_FILE_ERROR); + } + } + auto load_config_file = [config_substitution_rule](const std::string& file, DynamicPrintConfig& config, std::string& config_type, std::string& config_name, std::string& filament_id, std::string& config_from) { if (! boost::filesystem::exists(file)) { @@ -1774,6 +1814,19 @@ int CLI::run(int argc, char **argv) m_models.emplace_back(std::move(m)); } + //load custom gcodes into model if needed + if ((custom_gcodes_map.size() > 0)&&(m_models.size() > 0)) + { + m_models[0].plates_custom_gcodes = custom_gcodes_map; + /*m_models[0].plates_custom_gcodes.clear(); + + for (auto& custom_gcode: custom_gcodes_map) + { + BOOST_LOG_TRIVIAL(info) << boost::format("insert custom_gocde %1% into plate %2%")%plate_id; + m_models[0].plates_custom_gcodes.emplace(custom_gcode.first, custom_gcode.second); + }*/ + } + // Apply command line options to a more specific DynamicPrintConfig which provides normalize() // (command line options override --load files) m_print_config.apply(m_extra_config, true); diff --git a/src/libslic3r/Config.cpp b/src/libslic3r/Config.cpp index 1753318f2..69630c16a 100644 --- a/src/libslic3r/Config.cpp +++ b/src/libslic3r/Config.cpp @@ -756,6 +756,7 @@ int ConfigBase::load_from_json(const std::string &file, ConfigSubstitutionContex try { boost::nowide::ifstream ifs(file); ifs >> j; + ifs.close(); const ConfigDef* config_def = this->def(); if (config_def == nullptr) { diff --git a/src/libslic3r/CustomGCode.hpp b/src/libslic3r/CustomGCode.hpp index 5b21bb45e..7d8c7d998 100644 --- a/src/libslic3r/CustomGCode.hpp +++ b/src/libslic3r/CustomGCode.hpp @@ -3,6 +3,7 @@ #include #include +#include namespace Slic3r { @@ -43,6 +44,24 @@ struct Item std::string extra; // this field is used for the extra data like : // - G-code text for the Type::Custom // - message text for the Type::PausePrint + void from_json(const nlohmann::json& j) { + std::string type_str; + j.at("type").get_to(type_str); + std::map str2type = { {"ColorChange", ColorChange }, + {"PausePrint",PausePrint}, + {"ToolChange",ToolChange}, + {"Template",Template}, + {"Custom",Custom}, + {"Unknown",Unknown} }; + type = Unknown; + if (str2type.find(type_str) != str2type.end()) + type = str2type[type_str]; + j.at("print_z").get_to(print_z); + j.at("color").get_to(color); + j.at("extruder").get_to(extruder); + if(j.contains("extra")) + j.at("extra").get_to(extra); + } }; enum Mode @@ -71,6 +90,24 @@ struct Info (rhs.gcodes == this->gcodes ); } bool operator!=(const Info& rhs) const { return !(*this == rhs); } + + void from_json(const nlohmann::json& j) { + std::string mode_str; + if (j.contains("mode")) + j.at("mode").get_to(mode_str); + if (mode_str == "SingleExtruder") mode = SingleExtruder; + else if (mode_str == "MultiAsSingle") mode = MultiAsSingle; + else if (mode_str == "MultiExtruder") mode = MultiExtruder; + else mode = Undef; + + auto j_gcodes = j.at("gcodes"); + gcodes.reserve(j_gcodes.size()); + for (auto& jj : j_gcodes) { + Item item; + item.from_json(jj); + gcodes.push_back(item); + } + } }; // If loaded configuration has a "colorprint_heights" option (if it was imported from older Slicer), diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 3e72d6df0..0c6b984e3 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -5346,6 +5346,12 @@ CLIMiscConfigDef::CLIMiscConfigDef() def->tooltip = L("Render with a software renderer. The bundled MESA software renderer is loaded instead of the default OpenGL driver."); def->min = 0;*/ #endif /* _MSC_VER */ + + def = this->add("load_custom_gcodes", coString); + def->label = L("Load custom gcode"); + def->tooltip = L("Load custom gcode from json"); + def->cli_params = "custom_gcode_toolchange.json"; + def->set_default_value(new ConfigOptionString()); } const CLIActionsConfigDef cli_actions_config_def;