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
This commit is contained in:
Arthur 2023-08-04 10:49:14 +08:00 committed by Lane.Wei
parent 2a6bb02d60
commit 641a4fd1f2
4 changed files with 97 additions and 0 deletions

View File

@ -655,6 +655,11 @@ int CLI::run(int argc, char **argv)
} }
} }
std::string custom_gcode_file;
ConfigOptionString* custom_gcode_option = m_config.option<ConfigOptionString>("load_custom_gcodes");
if (custom_gcode_option)
custom_gcode_file = custom_gcode_option->value;
/*for (const std::string& file : m_input_files) /*for (const std::string& file : m_input_files)
if (is_gcode_file(file) && boost::filesystem::exists(file)) { if (is_gcode_file(file) && boost::filesystem::exists(file)) {
start_as_gcodeviewer = true; start_as_gcodeviewer = true;
@ -845,6 +850,41 @@ int CLI::run(int argc, char **argv)
} }
//} //}
//load custom gcode file
std::map<int, CustomGCode::Info> 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, 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) { std::string& config_name, std::string& filament_id, std::string& config_from) {
if (! boost::filesystem::exists(file)) { if (! boost::filesystem::exists(file)) {
@ -1774,6 +1814,19 @@ int CLI::run(int argc, char **argv)
m_models.emplace_back(std::move(m)); 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() // Apply command line options to a more specific DynamicPrintConfig which provides normalize()
// (command line options override --load files) // (command line options override --load files)
m_print_config.apply(m_extra_config, true); m_print_config.apply(m_extra_config, true);

View File

@ -756,6 +756,7 @@ int ConfigBase::load_from_json(const std::string &file, ConfigSubstitutionContex
try { try {
boost::nowide::ifstream ifs(file); boost::nowide::ifstream ifs(file);
ifs >> j; ifs >> j;
ifs.close();
const ConfigDef* config_def = this->def(); const ConfigDef* config_def = this->def();
if (config_def == nullptr) { if (config_def == nullptr) {

View File

@ -3,6 +3,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <nlohmann/json.hpp>
namespace Slic3r { namespace Slic3r {
@ -43,6 +44,24 @@ struct Item
std::string extra; // this field is used for the extra data like : std::string extra; // this field is used for the extra data like :
// - G-code text for the Type::Custom // - G-code text for the Type::Custom
// - message text for the Type::PausePrint // - 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<std::string,Type> 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 enum Mode
@ -71,6 +90,24 @@ struct Info
(rhs.gcodes == this->gcodes ); (rhs.gcodes == this->gcodes );
} }
bool operator!=(const Info& rhs) const { return !(*this == rhs); } 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), // If loaded configuration has a "colorprint_heights" option (if it was imported from older Slicer),

View File

@ -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->tooltip = L("Render with a software renderer. The bundled MESA software renderer is loaded instead of the default OpenGL driver.");
def->min = 0;*/ def->min = 0;*/
#endif /* _MSC_VER */ #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; const CLIActionsConfigDef cli_actions_config_def;