ENH: CLI: add the repetitions logic
support to duplicate object in a plate Change-Id: I6bc964a2b9660adf3be7919f230524c979da9d50
This commit is contained in:
parent
b8fa5decc1
commit
99bbce0f0f
|
@ -349,7 +349,7 @@ static PrinterTechnology get_printer_technology(const DynamicConfig &config)
|
||||||
return(ret);}
|
return(ret);}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void record_fail_reson(std::string outputdir, int code, int plate_id, std::string error_message)
|
void record_exit_reson(std::string outputdir, int code, int plate_id, std::string error_message, int extra_param1 = 0)
|
||||||
{
|
{
|
||||||
#if defined(__linux__) || defined(__LINUX__)
|
#if defined(__linux__) || defined(__LINUX__)
|
||||||
std::string result_file;
|
std::string result_file;
|
||||||
|
@ -365,6 +365,8 @@ void record_fail_reson(std::string outputdir, int code, int plate_id, std::strin
|
||||||
j["plate_index"] = plate_id;
|
j["plate_index"] = plate_id;
|
||||||
j["return_code"] = code;
|
j["return_code"] = code;
|
||||||
j["error_string"] = error_message;
|
j["error_string"] = error_message;
|
||||||
|
if (extra_param1 != 0)
|
||||||
|
j["extra_param1"] = extra_param1;
|
||||||
|
|
||||||
boost::nowide::ofstream c;
|
boost::nowide::ofstream c;
|
||||||
c.open(result_file, std::ios::out | std::ios::trunc);
|
c.open(result_file, std::ios::out | std::ios::trunc);
|
||||||
|
@ -425,16 +427,16 @@ int CLI::run(int argc, char **argv)
|
||||||
BOOST_LOG_TRIVIAL(info) << "index="<< index <<", arg is "<< argv[index] <<std::endl;
|
BOOST_LOG_TRIVIAL(info) << "index="<< index <<", arg is "<< argv[index] <<std::endl;
|
||||||
int debug_argc = 7;
|
int debug_argc = 7;
|
||||||
char *debug_argv[] = {
|
char *debug_argv[] = {
|
||||||
"E:\work\projects\bambu_debug\bamboo_slicer\build_debug\src\Debug\bambu-studio.exe",
|
"F:\work\projects\bambu_debug\bamboo_slicer\build_debug\src\Debug\bambu-studio.exe",
|
||||||
//"--uptodate",
|
//"--uptodate",
|
||||||
//"--load-settings",
|
//"--load-settings",
|
||||||
//"machine.json;process.json",
|
//"machine.json;process.json",
|
||||||
"--load-slicedata",
|
"--repetitions",
|
||||||
"cached_data",
|
"3",
|
||||||
"--export-3mf=output.3mf",
|
"--export-3mf=output.3mf",
|
||||||
"--slice",
|
"--slice",
|
||||||
"0",
|
"1",
|
||||||
"boats.3mf"
|
"test_repetitions.3mf"
|
||||||
};
|
};
|
||||||
if (! this->setup(debug_argc, debug_argv))*/
|
if (! this->setup(debug_argc, debug_argv))*/
|
||||||
if (!this->setup(argc, argv))
|
if (!this->setup(argc, argv))
|
||||||
|
@ -545,8 +547,8 @@ int CLI::run(int argc, char **argv)
|
||||||
//BBS: add plate data related logic
|
//BBS: add plate data related logic
|
||||||
PlateDataPtrs plate_data_src;
|
PlateDataPtrs plate_data_src;
|
||||||
int arrange_option;
|
int arrange_option;
|
||||||
int plate_to_slice = 0, filament_count = 0, duplicate_count = 0;
|
int plate_to_slice = 0, filament_count = 0, duplicate_count = 0, real_duplicate_count = 0;
|
||||||
bool first_file = true, is_bbl_3mf = false, need_arrange = true, has_thumbnails = false, up_config_to_date = false, normative_check = true;
|
bool first_file = true, is_bbl_3mf = false, need_arrange = true, has_thumbnails = false, up_config_to_date = false, normative_check = true, duplicate_single_object = false;
|
||||||
Semver file_version;
|
Semver file_version;
|
||||||
std::map<size_t, bool> orients_requirement;
|
std::map<size_t, bool> orients_requirement;
|
||||||
std::vector<Preset*> project_presets;
|
std::vector<Preset*> project_presets;
|
||||||
|
@ -594,7 +596,7 @@ int CLI::run(int argc, char **argv)
|
||||||
for (const std::string& file : m_input_files) {
|
for (const std::string& file : m_input_files) {
|
||||||
if (!boost::filesystem::exists(file)) {
|
if (!boost::filesystem::exists(file)) {
|
||||||
boost::nowide::cerr << "No such file: " << file << std::endl;
|
boost::nowide::cerr << "No such file: " << file << std::endl;
|
||||||
record_fail_reson(outfile_dir, CLI_FILE_NOTFOUND, 0, cli_errors[CLI_FILE_NOTFOUND]);
|
record_exit_reson(outfile_dir, CLI_FILE_NOTFOUND, 0, cli_errors[CLI_FILE_NOTFOUND]);
|
||||||
flush_and_exit(CLI_FILE_NOTFOUND);
|
flush_and_exit(CLI_FILE_NOTFOUND);
|
||||||
}
|
}
|
||||||
Model model;
|
Model model;
|
||||||
|
@ -624,7 +626,7 @@ int CLI::run(int argc, char **argv)
|
||||||
if (!first_file)
|
if (!first_file)
|
||||||
{
|
{
|
||||||
BOOST_LOG_TRIVIAL(info) << "The BBL 3mf file should be placed at the first position, filename=" << file << "\n";
|
BOOST_LOG_TRIVIAL(info) << "The BBL 3mf file should be placed at the first position, filename=" << file << "\n";
|
||||||
record_fail_reson(outfile_dir, CLI_FILELIST_INVALID_ORDER, 0, cli_errors[CLI_FILELIST_INVALID_ORDER]);
|
record_exit_reson(outfile_dir, CLI_FILELIST_INVALID_ORDER, 0, cli_errors[CLI_FILELIST_INVALID_ORDER]);
|
||||||
flush_and_exit(CLI_FILELIST_INVALID_ORDER);
|
flush_and_exit(CLI_FILELIST_INVALID_ORDER);
|
||||||
}
|
}
|
||||||
BOOST_LOG_TRIVIAL(info) << "the first file is a 3mf, got plate count:" << plate_data_src.size() << "\n";
|
BOOST_LOG_TRIVIAL(info) << "the first file is a 3mf, got plate count:" << plate_data_src.size() << "\n";
|
||||||
|
@ -651,7 +653,7 @@ int CLI::run(int argc, char **argv)
|
||||||
std::vector<std::string> postprocess_values = postprocess_scripts->values;
|
std::vector<std::string> postprocess_values = postprocess_scripts->values;
|
||||||
if (postprocess_values.size() > 0) {
|
if (postprocess_values.size() > 0) {
|
||||||
BOOST_LOG_TRIVIAL(error) << boost::format("normative_check: postprocess not supported, array size %1%")%postprocess_values.size();
|
BOOST_LOG_TRIVIAL(error) << boost::format("normative_check: postprocess not supported, array size %1%")%postprocess_values.size();
|
||||||
record_fail_reson(outfile_dir, CLI_POSTPROCESS_NOT_SUPPORTED, 0, cli_errors[CLI_POSTPROCESS_NOT_SUPPORTED]);
|
record_exit_reson(outfile_dir, CLI_POSTPROCESS_NOT_SUPPORTED, 0, cli_errors[CLI_POSTPROCESS_NOT_SUPPORTED]);
|
||||||
flush_and_exit(CLI_POSTPROCESS_NOT_SUPPORTED);
|
flush_and_exit(CLI_POSTPROCESS_NOT_SUPPORTED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -726,7 +728,7 @@ int CLI::run(int argc, char **argv)
|
||||||
}
|
}
|
||||||
if ((printer_technology != other_printer_technology) && (other_printer_technology != ptUnknown)) {
|
if ((printer_technology != other_printer_technology) && (other_printer_technology != ptUnknown)) {
|
||||||
boost::nowide::cerr << "invalid printer_technology " <<printer_technology<<", from source file "<< file <<std::endl;
|
boost::nowide::cerr << "invalid printer_technology " <<printer_technology<<", from source file "<< file <<std::endl;
|
||||||
record_fail_reson(outfile_dir, CLI_INVALID_PRINTER_TECH, 0, cli_errors[CLI_INVALID_PRINTER_TECH]);
|
record_exit_reson(outfile_dir, CLI_INVALID_PRINTER_TECH, 0, cli_errors[CLI_INVALID_PRINTER_TECH]);
|
||||||
flush_and_exit(CLI_INVALID_PRINTER_TECH);
|
flush_and_exit(CLI_INVALID_PRINTER_TECH);
|
||||||
}
|
}
|
||||||
if (!config_substitutions.substitutions.empty()) {
|
if (!config_substitutions.substitutions.empty()) {
|
||||||
|
@ -741,7 +743,7 @@ int CLI::run(int argc, char **argv)
|
||||||
}
|
}
|
||||||
catch (std::exception& e) {
|
catch (std::exception& e) {
|
||||||
boost::nowide::cerr << file << ": " << e.what() << std::endl;
|
boost::nowide::cerr << file << ": " << e.what() << std::endl;
|
||||||
record_fail_reson(outfile_dir, CLI_DATA_FILE_ERROR, 0, cli_errors[CLI_DATA_FILE_ERROR]);
|
record_exit_reson(outfile_dir, CLI_DATA_FILE_ERROR, 0, cli_errors[CLI_DATA_FILE_ERROR]);
|
||||||
flush_and_exit(CLI_DATA_FILE_ERROR);
|
flush_and_exit(CLI_DATA_FILE_ERROR);
|
||||||
}
|
}
|
||||||
if (model.objects.empty()) {
|
if (model.objects.empty()) {
|
||||||
|
@ -828,14 +830,14 @@ int CLI::run(int argc, char **argv)
|
||||||
std::string config_type, config_name, filament_id;
|
std::string config_type, config_name, filament_id;
|
||||||
int ret = load_system_config_file(file, config, config_type, config_name, filament_id);
|
int ret = load_system_config_file(file, config, config_type, config_name, filament_id);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
record_fail_reson(outfile_dir, ret, 0, cli_errors[ret]);
|
record_exit_reson(outfile_dir, ret, 0, cli_errors[ret]);
|
||||||
flush_and_exit(ret);
|
flush_and_exit(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config_type == "machine") {
|
if (config_type == "machine") {
|
||||||
if (!new_printer_name.empty()) {
|
if (!new_printer_name.empty()) {
|
||||||
boost::nowide::cerr << "duplicate machine config file: " << file << std::endl;
|
boost::nowide::cerr << "duplicate machine config file: " << file << std::endl;
|
||||||
record_fail_reson(outfile_dir, CLI_CONFIG_FILE_ERROR, 0, cli_errors[CLI_CONFIG_FILE_ERROR]);
|
record_exit_reson(outfile_dir, CLI_CONFIG_FILE_ERROR, 0, cli_errors[CLI_CONFIG_FILE_ERROR]);
|
||||||
flush_and_exit(CLI_CONFIG_FILE_ERROR);
|
flush_and_exit(CLI_CONFIG_FILE_ERROR);
|
||||||
}
|
}
|
||||||
new_printer_name = config_name;
|
new_printer_name = config_name;
|
||||||
|
@ -846,7 +848,7 @@ int CLI::run(int argc, char **argv)
|
||||||
else if (config_type == "process") {
|
else if (config_type == "process") {
|
||||||
if (!new_process_name.empty()) {
|
if (!new_process_name.empty()) {
|
||||||
boost::nowide::cerr << "duplicate process config file: " << file << std::endl;
|
boost::nowide::cerr << "duplicate process config file: " << file << std::endl;
|
||||||
record_fail_reson(outfile_dir, CLI_CONFIG_FILE_ERROR, 0, cli_errors[CLI_CONFIG_FILE_ERROR]);
|
record_exit_reson(outfile_dir, CLI_CONFIG_FILE_ERROR, 0, cli_errors[CLI_CONFIG_FILE_ERROR]);
|
||||||
flush_and_exit(CLI_CONFIG_FILE_ERROR);
|
flush_and_exit(CLI_CONFIG_FILE_ERROR);
|
||||||
}
|
}
|
||||||
new_process_name = config_name;
|
new_process_name = config_name;
|
||||||
|
@ -863,7 +865,7 @@ int CLI::run(int argc, char **argv)
|
||||||
|
|
||||||
if ((printer_technology != other_printer_technology)&&(other_printer_technology != ptUnknown)){
|
if ((printer_technology != other_printer_technology)&&(other_printer_technology != ptUnknown)){
|
||||||
boost::nowide::cerr << "invalid printer_technology " <<printer_technology<<", from config "<< file <<std::endl;
|
boost::nowide::cerr << "invalid printer_technology " <<printer_technology<<", from config "<< file <<std::endl;
|
||||||
record_fail_reson(outfile_dir, CLI_INVALID_PRINTER_TECH, 0, cli_errors[CLI_INVALID_PRINTER_TECH]);
|
record_exit_reson(outfile_dir, CLI_INVALID_PRINTER_TECH, 0, cli_errors[CLI_INVALID_PRINTER_TECH]);
|
||||||
flush_and_exit(CLI_INVALID_PRINTER_TECH);
|
flush_and_exit(CLI_INVALID_PRINTER_TECH);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -883,13 +885,13 @@ int CLI::run(int argc, char **argv)
|
||||||
std::string config_type, config_name, filament_id;
|
std::string config_type, config_name, filament_id;
|
||||||
int ret = load_system_config_file(file, config, config_type, config_name, filament_id);
|
int ret = load_system_config_file(file, config, config_type, config_name, filament_id);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
record_fail_reson(outfile_dir, ret, 0, cli_errors[ret]);
|
record_exit_reson(outfile_dir, ret, 0, cli_errors[ret]);
|
||||||
flush_and_exit(ret);
|
flush_and_exit(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config_type != "filament") {
|
if (config_type != "filament") {
|
||||||
boost::nowide::cerr <<__FUNCTION__ << boost::format(": unknown config type %1% of file %2% in load-filaments") % config_type % file;
|
boost::nowide::cerr <<__FUNCTION__ << boost::format(": unknown config type %1% of file %2% in load-filaments") % config_type % file;
|
||||||
record_fail_reson(outfile_dir, CLI_CONFIG_FILE_ERROR, 0, cli_errors[CLI_CONFIG_FILE_ERROR]);
|
record_exit_reson(outfile_dir, CLI_CONFIG_FILE_ERROR, 0, cli_errors[CLI_CONFIG_FILE_ERROR]);
|
||||||
flush_and_exit(CLI_CONFIG_FILE_ERROR);
|
flush_and_exit(CLI_CONFIG_FILE_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -899,7 +901,7 @@ int CLI::run(int argc, char **argv)
|
||||||
}
|
}
|
||||||
if ((printer_technology != other_printer_technology) && (other_printer_technology != ptUnknown)) {
|
if ((printer_technology != other_printer_technology) && (other_printer_technology != ptUnknown)) {
|
||||||
boost::nowide::cerr << "invalid printer_technology " <<printer_technology<<", from filament file "<< file <<std::endl;
|
boost::nowide::cerr << "invalid printer_technology " <<printer_technology<<", from filament file "<< file <<std::endl;
|
||||||
record_fail_reson(outfile_dir, CLI_INVALID_PRINTER_TECH, 0, cli_errors[CLI_INVALID_PRINTER_TECH]);
|
record_exit_reson(outfile_dir, CLI_INVALID_PRINTER_TECH, 0, cli_errors[CLI_INVALID_PRINTER_TECH]);
|
||||||
flush_and_exit(CLI_INVALID_PRINTER_TECH);
|
flush_and_exit(CLI_INVALID_PRINTER_TECH);
|
||||||
}
|
}
|
||||||
load_filaments_id.push_back(filament_id);
|
load_filaments_id.push_back(filament_id);
|
||||||
|
@ -930,7 +932,7 @@ int CLI::run(int argc, char **argv)
|
||||||
std::string config_type, config_name, filament_id;
|
std::string config_type, config_name, filament_id;
|
||||||
int ret = load_system_config_file(system_printer_path, config, config_type, config_name, filament_id);
|
int ret = load_system_config_file(system_printer_path, config, config_type, config_name, filament_id);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
record_fail_reson(outfile_dir, ret, 0, cli_errors[ret]);
|
record_exit_reson(outfile_dir, ret, 0, cli_errors[ret]);
|
||||||
flush_and_exit(ret);
|
flush_and_exit(ret);
|
||||||
}
|
}
|
||||||
upward_compatible_printers = config.option<ConfigOptionStrings>("upward_compatible_machine", true)->values;
|
upward_compatible_printers = config.option<ConfigOptionStrings>("upward_compatible_machine", true)->values;
|
||||||
|
@ -953,7 +955,7 @@ int CLI::run(int argc, char **argv)
|
||||||
std::string config_type, config_name, filament_id;
|
std::string config_type, config_name, filament_id;
|
||||||
int ret = load_system_config_file(system_process_path, config, config_type, config_name, filament_id);
|
int ret = load_system_config_file(system_process_path, config, config_type, config_name, filament_id);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
record_fail_reson(outfile_dir, ret, 0, cli_errors[ret]);
|
record_exit_reson(outfile_dir, ret, 0, cli_errors[ret]);
|
||||||
flush_and_exit(ret);
|
flush_and_exit(ret);
|
||||||
}
|
}
|
||||||
current_print_compatible_printers = config.option<ConfigOptionStrings>("compatible_printers", true)->values;
|
current_print_compatible_printers = config.option<ConfigOptionStrings>("compatible_printers", true)->values;
|
||||||
|
@ -976,7 +978,7 @@ int CLI::run(int argc, char **argv)
|
||||||
std::string config_type, config_name, filament_id;
|
std::string config_type, config_name, filament_id;
|
||||||
int ret = load_system_config_file(system_filament_path, config, config_type, config_name, filament_id);
|
int ret = load_system_config_file(system_filament_path, config, config_type, config_name, filament_id);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
record_fail_reson(outfile_dir, ret, 0, cli_errors[ret]);
|
record_exit_reson(outfile_dir, ret, 0, cli_errors[ret]);
|
||||||
flush_and_exit(ret);
|
flush_and_exit(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1006,7 +1008,7 @@ int CLI::run(int argc, char **argv)
|
||||||
std::string config_type, config_name, filament_id;
|
std::string config_type, config_name, filament_id;
|
||||||
int ret = load_system_config_file(system_printer_path, config, config_type, config_name, filament_id);
|
int ret = load_system_config_file(system_printer_path, config, config_type, config_name, filament_id);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
record_fail_reson(outfile_dir, ret, 0, cli_errors[ret]);
|
record_exit_reson(outfile_dir, ret, 0, cli_errors[ret]);
|
||||||
flush_and_exit(ret);
|
flush_and_exit(ret);
|
||||||
}
|
}
|
||||||
upward_compatible_printers = config.option<ConfigOptionStrings>("upward_compatible_machine", true)->values;
|
upward_compatible_printers = config.option<ConfigOptionStrings>("upward_compatible_machine", true)->values;
|
||||||
|
@ -1028,7 +1030,7 @@ int CLI::run(int argc, char **argv)
|
||||||
std::string config_type, config_name, filament_id;
|
std::string config_type, config_name, filament_id;
|
||||||
int ret = load_system_config_file(system_process_path, config, config_type, config_name, filament_id);
|
int ret = load_system_config_file(system_process_path, config, config_type, config_name, filament_id);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
record_fail_reson(outfile_dir, ret, 0, cli_errors[ret]);
|
record_exit_reson(outfile_dir, ret, 0, cli_errors[ret]);
|
||||||
flush_and_exit(ret);
|
flush_and_exit(ret);
|
||||||
}
|
}
|
||||||
current_print_compatible_printers = config.option<ConfigOptionStrings>("compatible_printers", true)->values;
|
current_print_compatible_printers = config.option<ConfigOptionStrings>("compatible_printers", true)->values;
|
||||||
|
@ -1103,20 +1105,20 @@ int CLI::run(int argc, char **argv)
|
||||||
}
|
}
|
||||||
if (!process_compatible) {
|
if (!process_compatible) {
|
||||||
boost::nowide::cout <<__FUNCTION__ << boost::format(": current 3mf file not support the new printer %1%")%new_printer_name;
|
boost::nowide::cout <<__FUNCTION__ << boost::format(": current 3mf file not support the new printer %1%")%new_printer_name;
|
||||||
record_fail_reson(outfile_dir, CLI_3MF_NEW_MACHINE_NOT_SUPPORTED, 0, cli_errors[CLI_3MF_NEW_MACHINE_NOT_SUPPORTED]);
|
record_exit_reson(outfile_dir, CLI_3MF_NEW_MACHINE_NOT_SUPPORTED, 0, cli_errors[CLI_3MF_NEW_MACHINE_NOT_SUPPORTED]);
|
||||||
flush_and_exit(CLI_3MF_NEW_MACHINE_NOT_SUPPORTED);
|
flush_and_exit(CLI_3MF_NEW_MACHINE_NOT_SUPPORTED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
boost::nowide::cout <<__FUNCTION__ << boost::format(": current 3mf file not support upward_compatible_printers, can not change machine preset.");
|
boost::nowide::cout <<__FUNCTION__ << boost::format(": current 3mf file not support upward_compatible_printers, can not change machine preset.");
|
||||||
record_fail_reson(outfile_dir, CLI_3MF_NOT_SUPPORT_MACHINE_CHANGE, 0, cli_errors[CLI_3MF_NOT_SUPPORT_MACHINE_CHANGE]);
|
record_exit_reson(outfile_dir, CLI_3MF_NOT_SUPPORT_MACHINE_CHANGE, 0, cli_errors[CLI_3MF_NOT_SUPPORT_MACHINE_CHANGE]);
|
||||||
flush_and_exit(CLI_3MF_NOT_SUPPORT_MACHINE_CHANGE);
|
flush_and_exit(CLI_3MF_NOT_SUPPORT_MACHINE_CHANGE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!process_compatible) {
|
if (!process_compatible) {
|
||||||
boost::nowide::cout <<__FUNCTION__ << boost::format(": process not compatible with printer.");
|
boost::nowide::cout <<__FUNCTION__ << boost::format(": process not compatible with printer.");
|
||||||
record_fail_reson(outfile_dir, CLI_PROCESS_NOT_COMPATIBLE, 0, cli_errors[CLI_PROCESS_NOT_COMPATIBLE]);
|
record_exit_reson(outfile_dir, CLI_PROCESS_NOT_COMPATIBLE, 0, cli_errors[CLI_PROCESS_NOT_COMPATIBLE]);
|
||||||
flush_and_exit(CLI_PROCESS_NOT_COMPATIBLE);
|
flush_and_exit(CLI_PROCESS_NOT_COMPATIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1220,7 +1222,7 @@ int CLI::run(int argc, char **argv)
|
||||||
BOOST_LOG_TRIVIAL(info) << boost::format("update printer config to newest, different size %1%")%different_keys_set.size();
|
BOOST_LOG_TRIVIAL(info) << boost::format("update printer config to newest, different size %1%")%different_keys_set.size();
|
||||||
int ret = update_full_config(m_print_config, load_machine_config, different_keys_set);
|
int ret = update_full_config(m_print_config, load_machine_config, different_keys_set);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
record_fail_reson(outfile_dir, ret, 0, cli_errors[ret]);
|
record_exit_reson(outfile_dir, ret, 0, cli_errors[ret]);
|
||||||
flush_and_exit(ret);
|
flush_and_exit(ret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1260,7 +1262,7 @@ int CLI::run(int argc, char **argv)
|
||||||
BOOST_LOG_TRIVIAL(info) << boost::format("update process config to newest, different size %1%")%different_keys_set.size();
|
BOOST_LOG_TRIVIAL(info) << boost::format("update process config to newest, different size %1%")%different_keys_set.size();
|
||||||
int ret = update_full_config(m_print_config, load_process_config, different_keys_set);
|
int ret = update_full_config(m_print_config, load_process_config, different_keys_set);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
record_fail_reson(outfile_dir, ret, 0, cli_errors[ret]);
|
record_exit_reson(outfile_dir, ret, 0, cli_errors[ret]);
|
||||||
flush_and_exit(ret);
|
flush_and_exit(ret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1340,7 +1342,7 @@ int CLI::run(int argc, char **argv)
|
||||||
if (source_opt == nullptr) {
|
if (source_opt == nullptr) {
|
||||||
// The key was not found in the source config, therefore it will not be initialized!
|
// The key was not found in the source config, therefore it will not be initialized!
|
||||||
BOOST_LOG_TRIVIAL(error) << boost::format("can not find %1% from filament %2%: %3%")%opt_key%filament_index%load_filaments_name[index];
|
BOOST_LOG_TRIVIAL(error) << boost::format("can not find %1% from filament %2%: %3%")%opt_key%filament_index%load_filaments_name[index];
|
||||||
record_fail_reson(outfile_dir, CLI_CONFIG_FILE_ERROR, 0, cli_errors[CLI_CONFIG_FILE_ERROR]);
|
record_exit_reson(outfile_dir, CLI_CONFIG_FILE_ERROR, 0, cli_errors[CLI_CONFIG_FILE_ERROR]);
|
||||||
flush_and_exit(CLI_CONFIG_FILE_ERROR);
|
flush_and_exit(CLI_CONFIG_FILE_ERROR);
|
||||||
}
|
}
|
||||||
if (source_opt->is_scalar()) {
|
if (source_opt->is_scalar()) {
|
||||||
|
@ -1373,7 +1375,7 @@ int CLI::run(int argc, char **argv)
|
||||||
// opt_key does not exist in this ConfigBase and it cannot be created, because it is not defined by this->def().
|
// opt_key does not exist in this ConfigBase and it cannot be created, because it is not defined by this->def().
|
||||||
// This is only possible if other is of DynamicConfig type.
|
// This is only possible if other is of DynamicConfig type.
|
||||||
BOOST_LOG_TRIVIAL(error) << boost::format("can not create option %1% to config, from filament %2%: %3%")%opt_key%filament_index%load_filaments_name[index];
|
BOOST_LOG_TRIVIAL(error) << boost::format("can not create option %1% to config, from filament %2%: %3%")%opt_key%filament_index%load_filaments_name[index];
|
||||||
record_fail_reson(outfile_dir, CLI_CONFIG_FILE_ERROR, 0, cli_errors[CLI_CONFIG_FILE_ERROR]);
|
record_exit_reson(outfile_dir, CLI_CONFIG_FILE_ERROR, 0, cli_errors[CLI_CONFIG_FILE_ERROR]);
|
||||||
flush_and_exit(CLI_CONFIG_FILE_ERROR);
|
flush_and_exit(CLI_CONFIG_FILE_ERROR);
|
||||||
}
|
}
|
||||||
ConfigOptionVectorBase* opt_vec_dst = static_cast<ConfigOptionVectorBase*>(opt);
|
ConfigOptionVectorBase* opt_vec_dst = static_cast<ConfigOptionVectorBase*>(opt);
|
||||||
|
@ -1429,7 +1431,7 @@ int CLI::run(int argc, char **argv)
|
||||||
if (filament_is_support->size() != project_filament_count)
|
if (filament_is_support->size() != project_filament_count)
|
||||||
{
|
{
|
||||||
BOOST_LOG_TRIVIAL(error) << boost::format("filament_is_support's count %1% not equal to filament_colour's size %2%")%filament_is_support->size() %project_filament_count;
|
BOOST_LOG_TRIVIAL(error) << boost::format("filament_is_support's count %1% not equal to filament_colour's size %2%")%filament_is_support->size() %project_filament_count;
|
||||||
record_fail_reson(outfile_dir, CLI_CONFIG_FILE_ERROR, 0, cli_errors[CLI_CONFIG_FILE_ERROR]);
|
record_exit_reson(outfile_dir, CLI_CONFIG_FILE_ERROR, 0, cli_errors[CLI_CONFIG_FILE_ERROR]);
|
||||||
flush_and_exit(CLI_CONFIG_FILE_ERROR);
|
flush_and_exit(CLI_CONFIG_FILE_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1526,7 +1528,7 @@ int CLI::run(int argc, char **argv)
|
||||||
m_print_config.apply(fff_print_config, true);
|
m_print_config.apply(fff_print_config, true);
|
||||||
} else {
|
} else {
|
||||||
boost::nowide::cerr << "invalid printer_technology " << std::endl;
|
boost::nowide::cerr << "invalid printer_technology " << std::endl;
|
||||||
record_fail_reson(outfile_dir, CLI_INVALID_PRINTER_TECH, 0, cli_errors[CLI_INVALID_PRINTER_TECH]);
|
record_exit_reson(outfile_dir, CLI_INVALID_PRINTER_TECH, 0, cli_errors[CLI_INVALID_PRINTER_TECH]);
|
||||||
flush_and_exit(CLI_INVALID_PRINTER_TECH);
|
flush_and_exit(CLI_INVALID_PRINTER_TECH);
|
||||||
/*assert(printer_technology == ptSLA);
|
/*assert(printer_technology == ptSLA);
|
||||||
sla_print_config.filename_format.value = "[input_filename_base].sl1";
|
sla_print_config.filename_format.value = "[input_filename_base].sl1";
|
||||||
|
@ -1546,7 +1548,7 @@ int CLI::run(int argc, char **argv)
|
||||||
boost::nowide::cerr << "Param values in 3mf/config error: "<< std::endl;
|
boost::nowide::cerr << "Param values in 3mf/config error: "<< std::endl;
|
||||||
for (std::map<std::string, std::string>::iterator it=validity.begin(); it!=validity.end(); ++it)
|
for (std::map<std::string, std::string>::iterator it=validity.begin(); it!=validity.end(); ++it)
|
||||||
boost::nowide::cerr << it->first <<": "<< it->second << std::endl;
|
boost::nowide::cerr << it->first <<": "<< it->second << std::endl;
|
||||||
record_fail_reson(outfile_dir, CLI_INVALID_VALUES_IN_3MF, 0, cli_errors[CLI_INVALID_VALUES_IN_3MF]);
|
record_exit_reson(outfile_dir, CLI_INVALID_VALUES_IN_3MF, 0, cli_errors[CLI_INVALID_VALUES_IN_3MF]);
|
||||||
flush_and_exit(CLI_INVALID_VALUES_IN_3MF);
|
flush_and_exit(CLI_INVALID_VALUES_IN_3MF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1559,6 +1561,7 @@ int CLI::run(int argc, char **argv)
|
||||||
double print_height = m_print_config.opt_float("printable_height");
|
double print_height = m_print_config.opt_float("printable_height");
|
||||||
double height_to_lid = m_print_config.opt_float("extruder_clearance_height_to_lid");
|
double height_to_lid = m_print_config.opt_float("extruder_clearance_height_to_lid");
|
||||||
double height_to_rod = m_print_config.opt_float("extruder_clearance_height_to_rod");
|
double height_to_rod = m_print_config.opt_float("extruder_clearance_height_to_rod");
|
||||||
|
double cleareance_radius = m_print_config.opt_float("extruder_clearance_max_radius");
|
||||||
//double plate_stride;
|
//double plate_stride;
|
||||||
std::string bed_texture;
|
std::string bed_texture;
|
||||||
|
|
||||||
|
@ -1578,7 +1581,7 @@ int CLI::run(int argc, char **argv)
|
||||||
{
|
{
|
||||||
BOOST_LOG_TRIVIAL(error) << boost::format("old printable size {%1%, %2%, %3%} is larger than new printable size {%4%, %5%, %6%}, can not print")
|
BOOST_LOG_TRIVIAL(error) << boost::format("old printable size {%1%, %2%, %3%} is larger than new printable size {%4%, %5%, %6%}, can not print")
|
||||||
%old_printable_width %old_printable_depth %old_printable_height %current_printable_width %current_printable_depth %current_printable_height;
|
%old_printable_width %old_printable_depth %old_printable_height %current_printable_width %current_printable_depth %current_printable_height;
|
||||||
record_fail_reson(outfile_dir, CLI_PRINTABLE_SIZE_REDUCED, 0, cli_errors[CLI_PRINTABLE_SIZE_REDUCED]);
|
record_exit_reson(outfile_dir, CLI_PRINTABLE_SIZE_REDUCED, 0, cli_errors[CLI_PRINTABLE_SIZE_REDUCED]);
|
||||||
flush_and_exit(CLI_PRINTABLE_SIZE_REDUCED);
|
flush_and_exit(CLI_PRINTABLE_SIZE_REDUCED);
|
||||||
}
|
}
|
||||||
else if ((old_printable_width < current_printable_width) || (old_printable_depth < current_printable_depth))
|
else if ((old_printable_width < current_printable_width) || (old_printable_depth < current_printable_depth))
|
||||||
|
@ -1693,9 +1696,21 @@ int CLI::run(int argc, char **argv)
|
||||||
BOOST_LOG_TRIVIAL(info) << "invalid repetitions value " << repetitions_count << ", just skip\n";
|
BOOST_LOG_TRIVIAL(info) << "invalid repetitions value " << repetitions_count << ", just skip\n";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//todo
|
if (plate_to_slice == 0) {
|
||||||
//copy model objects and instances
|
BOOST_LOG_TRIVIAL(error) << "Invalid params: can not set repetitions when slice all." << std::endl;
|
||||||
|
record_exit_reson(outfile_dir, CLI_INVALID_PARAMS, 0, cli_errors[CLI_INVALID_PARAMS]);
|
||||||
|
flush_and_exit(CLI_INVALID_PARAMS);
|
||||||
|
}
|
||||||
|
else if (plate_to_slice > partplate_list.get_plate_count()) {
|
||||||
|
BOOST_LOG_TRIVIAL(error) << boost::format("Invalid params:invalid plate %1% to slice, total %2%")%plate_to_slice %partplate_list.get_plate_count();
|
||||||
|
record_exit_reson(outfile_dir, CLI_INVALID_PARAMS, 0, cli_errors[CLI_INVALID_PARAMS]);
|
||||||
|
flush_and_exit(CLI_INVALID_PARAMS);
|
||||||
|
}
|
||||||
BOOST_LOG_TRIVIAL(info) << "repetitions value " << repetitions_count << ", will copy model object first\n";
|
BOOST_LOG_TRIVIAL(info) << "repetitions value " << repetitions_count << ", will copy model object first\n";
|
||||||
|
Slic3r::GUI::PartPlate* cur_plate = (Slic3r::GUI::PartPlate *)partplate_list.get_plate(plate_to_slice-1);
|
||||||
|
//copy model objects and instances on plate
|
||||||
|
cur_plate->duplicate_all_instance(repetitions_count-1);
|
||||||
|
|
||||||
need_arrange = true;
|
need_arrange = true;
|
||||||
duplicate_count = repetitions_count - 1;
|
duplicate_count = repetitions_count - 1;
|
||||||
}
|
}
|
||||||
|
@ -1745,7 +1760,7 @@ int CLI::run(int argc, char **argv)
|
||||||
}
|
}
|
||||||
} catch (std::exception &ex) {
|
} catch (std::exception &ex) {
|
||||||
boost::nowide::cerr << "error: " << ex.what() << std::endl;
|
boost::nowide::cerr << "error: " << ex.what() << std::endl;
|
||||||
record_fail_reson(outfile_dir, CLI_COPY_OBJECTS_ERROR, 0, cli_errors[CLI_COPY_OBJECTS_ERROR]);
|
record_exit_reson(outfile_dir, CLI_COPY_OBJECTS_ERROR, 0, cli_errors[CLI_COPY_OBJECTS_ERROR]);
|
||||||
flush_and_exit(CLI_COPY_OBJECTS_ERROR);
|
flush_and_exit(CLI_COPY_OBJECTS_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1815,7 +1830,7 @@ int CLI::run(int argc, char **argv)
|
||||||
const Vec3d &opt = m_config.opt<ConfigOptionPoint3>(opt_key)->value;
|
const Vec3d &opt = m_config.opt<ConfigOptionPoint3>(opt_key)->value;
|
||||||
if (opt.x() <= 0 || opt.y() <= 0 || opt.z() <= 0) {
|
if (opt.x() <= 0 || opt.y() <= 0 || opt.z() <= 0) {
|
||||||
boost::nowide::cerr << "--scale-to-fit requires a positive volume" << std::endl;
|
boost::nowide::cerr << "--scale-to-fit requires a positive volume" << std::endl;
|
||||||
record_fail_reson(outfile_dir, CLI_SCALE_TO_FIT_ERROR, 0, cli_errors[CLI_SCALE_TO_FIT_ERROR]);
|
record_exit_reson(outfile_dir, CLI_SCALE_TO_FIT_ERROR, 0, cli_errors[CLI_SCALE_TO_FIT_ERROR]);
|
||||||
flush_and_exit(CLI_SCALE_TO_FIT_ERROR);
|
flush_and_exit(CLI_SCALE_TO_FIT_ERROR);
|
||||||
}
|
}
|
||||||
for (auto &model : m_models)
|
for (auto &model : m_models)
|
||||||
|
@ -1906,7 +1921,7 @@ int CLI::run(int argc, char **argv)
|
||||||
// model.repair();
|
// model.repair();
|
||||||
} else {
|
} else {
|
||||||
boost::nowide::cerr << "error: option not implemented yet: " << opt_key << std::endl;
|
boost::nowide::cerr << "error: option not implemented yet: " << opt_key << std::endl;
|
||||||
record_fail_reson(outfile_dir, CLI_UNSUPPORTED_OPERATION, 0, cli_errors[CLI_UNSUPPORTED_OPERATION]);
|
record_exit_reson(outfile_dir, CLI_UNSUPPORTED_OPERATION, 0, cli_errors[CLI_UNSUPPORTED_OPERATION]);
|
||||||
flush_and_exit(CLI_UNSUPPORTED_OPERATION);
|
flush_and_exit(CLI_UNSUPPORTED_OPERATION);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1934,51 +1949,175 @@ int CLI::run(int argc, char **argv)
|
||||||
orients_requirement.clear();
|
orients_requirement.clear();
|
||||||
oriented_or_arranged |= need_arrange;
|
oriented_or_arranged |= need_arrange;
|
||||||
|
|
||||||
|
BOOST_LOG_TRIVIAL(info) << boost::format("before arrange, need_arrange=%1%, duplicate_count %2%")%need_arrange%duplicate_count;
|
||||||
if (need_arrange)
|
if (need_arrange)
|
||||||
{
|
{
|
||||||
ArrangePolygons selected, unselected, unprintable, locked_aps;
|
ArrangePolygons selected, unselected, unprintable, locked_aps;
|
||||||
BOOST_LOG_TRIVIAL(info) << "Will arrange now, need_arrange="<<need_arrange<<"\n";
|
|
||||||
|
|
||||||
for (Model &model : m_models)
|
//for (Model &model : m_models)
|
||||||
|
if (m_models.size() > 0)
|
||||||
{
|
{
|
||||||
//Step-1: prepare arrange polygons
|
Model &model = m_models[0];
|
||||||
for (size_t oidx = 0; oidx < model.objects.size(); ++oidx)
|
|
||||||
{
|
|
||||||
ModelObject* mo = model.objects[oidx];
|
|
||||||
for (size_t inst_idx = 0; inst_idx < mo->instances.size(); ++inst_idx)
|
|
||||||
{
|
|
||||||
ModelInstance* minst = mo->instances[inst_idx];
|
|
||||||
ArrangePolygon ap = get_instance_arrange_poly(minst, m_print_config);
|
|
||||||
|
|
||||||
//preprocess by partplate list
|
arrange_cfg.is_seq_print = false;
|
||||||
//remove the locked plate's instances, neither in selected, nor in un-selected
|
|
||||||
bool locked = partplate_list.preprocess_arrange_polygon(oidx, inst_idx, ap, true);
|
//Step-1: prepare arrange polygons
|
||||||
if (!locked)
|
if (duplicate_count == 0)
|
||||||
|
{
|
||||||
|
for (size_t oidx = 0; oidx < model.objects.size(); ++oidx)
|
||||||
|
{
|
||||||
|
ModelObject* mo = model.objects[oidx];
|
||||||
|
for (size_t inst_idx = 0; inst_idx < mo->instances.size(); ++inst_idx)
|
||||||
{
|
{
|
||||||
ap.itemid = selected.size();
|
ModelInstance* minst = mo->instances[inst_idx];
|
||||||
if (minst->printable)
|
ArrangePolygon ap = get_instance_arrange_poly(minst, m_print_config);
|
||||||
selected.emplace_back(ap);
|
|
||||||
|
//preprocess by partplate list
|
||||||
|
//remove the locked plate's instances, neither in selected, nor in un-selected
|
||||||
|
bool locked = partplate_list.preprocess_arrange_polygon(oidx, inst_idx, ap, true);
|
||||||
|
if (!locked)
|
||||||
|
{
|
||||||
|
ap.itemid = selected.size();
|
||||||
|
if (minst->printable)
|
||||||
|
selected.emplace_back(ap);
|
||||||
|
else
|
||||||
|
unprintable.emplace_back(ap);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
unprintable.emplace_back(ap);
|
{
|
||||||
}
|
//skip this object due to be locked in plate
|
||||||
else
|
ap.itemid = locked_aps.size();
|
||||||
{
|
locked_aps.emplace_back(ap);
|
||||||
//skip this object due to be locked in plate
|
boost::nowide::cout <<__FUNCTION__ << boost::format(": skip locked instance, obj_id %1%, instance_id %2%") % oidx % inst_idx;
|
||||||
ap.itemid = locked_aps.size();
|
}
|
||||||
locked_aps.emplace_back(ap);
|
|
||||||
boost::nowide::cout <<__FUNCTION__ << boost::format(": skip locked instance, obj_id %1%, instance_id %2%") % oidx % inst_idx;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_print_config.has("print_sequence")) {
|
||||||
|
PrintSequence seq = m_print_config.option<ConfigOptionEnum<PrintSequence>>("print_sequence")->value;
|
||||||
|
arrange_cfg.is_seq_print = (seq == PrintSequence::ByObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
//add the virtual object into unselect list if has
|
||||||
|
partplate_list.preprocess_exclude_areas(unselected);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//only arrange current plate
|
||||||
|
Slic3r::GUI::PartPlate* cur_plate = (Slic3r::GUI::PartPlate *)partplate_list.get_plate(plate_to_slice-1);
|
||||||
|
PrintSequence curr_plate_seq = cur_plate->get_print_seq();
|
||||||
|
if (curr_plate_seq == PrintSequence::ByDefault) {
|
||||||
|
auto seq_print = m_print_config.option<ConfigOptionEnum<PrintSequence>>("print_sequence");
|
||||||
|
if (seq_print && (seq_print->value == PrintSequence::ByObject)) {
|
||||||
|
BOOST_LOG_TRIVIAL(info) << boost::format("plate %1% print by object, set from global")%plate_to_slice;
|
||||||
|
arrange_cfg.is_seq_print = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (curr_plate_seq == PrintSequence::ByObject) {
|
||||||
|
BOOST_LOG_TRIVIAL(info) << boost::format("plate %1% print by object, set from plate self")%plate_to_slice;
|
||||||
|
arrange_cfg.is_seq_print = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
partplate_list.lock_plate(plate_to_slice - 1, false);
|
||||||
|
partplate_list.select_plate(plate_to_slice-1);
|
||||||
|
BOOST_LOG_TRIVIAL(info) << boost::format("plate %1% set to selected")%plate_to_slice;
|
||||||
|
|
||||||
|
for (size_t oidx = 0; oidx < model.objects.size(); ++oidx)
|
||||||
|
{
|
||||||
|
ModelObject* mo = model.objects[oidx];
|
||||||
|
|
||||||
|
for (size_t inst_idx = 0; inst_idx < mo->instances.size(); ++inst_idx)
|
||||||
|
{
|
||||||
|
ModelInstance* minst = mo->instances[inst_idx];
|
||||||
|
bool in_plate = cur_plate->contain_instance(oidx, inst_idx) || cur_plate->intersect_instance(oidx, inst_idx);
|
||||||
|
ArrangePolygon ap = get_instance_arrange_poly(minst, m_print_config);
|
||||||
|
|
||||||
|
ArrangePolygons& cont = mo->instances[inst_idx]->printable ?
|
||||||
|
(in_plate ? selected : unselected) :
|
||||||
|
unprintable;
|
||||||
|
bool locked = partplate_list.preprocess_arrange_polygon_other_locked(oidx, inst_idx, ap, in_plate);
|
||||||
|
BOOST_LOG_TRIVIAL(info) << boost::format("name %4% in_plate %1% printable %2%, locked %3%")%in_plate %mo->instances[inst_idx]->printable %locked % ap.name ;
|
||||||
|
if (!locked)
|
||||||
|
{
|
||||||
|
ap.itemid = cont.size();
|
||||||
|
cont.emplace_back(std::move(ap));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//skip this object due to be not in current plate, treated as locked
|
||||||
|
ap.itemid = locked_aps.size();
|
||||||
|
locked_aps.emplace_back(std::move(ap));
|
||||||
|
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": skip locked instance, obj_id %1%, name %2%") % oidx % mo->name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (selected.size() == (duplicate_count + 1))
|
||||||
|
{
|
||||||
|
duplicate_single_object = true;
|
||||||
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": found single object mode");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_print_config.has("wipe_tower_x")) {
|
||||||
|
float x = dynamic_cast<const ConfigOptionFloats *>(m_print_config.option("wipe_tower_x"))->get_at(plate_to_slice-1);
|
||||||
|
float y = dynamic_cast<const ConfigOptionFloats *>(m_print_config.option("wipe_tower_y"))->get_at(plate_to_slice-1);
|
||||||
|
float w = dynamic_cast<const ConfigOptionFloat *>(m_print_config.option("prime_tower_width"))->value;
|
||||||
|
float a = dynamic_cast<const ConfigOptionFloat *>(m_print_config.option("wipe_tower_rotation_angle"))->value;
|
||||||
|
float v = dynamic_cast<const ConfigOptionFloat *>(m_print_config.option("prime_volume"))->value;
|
||||||
|
unsigned int filaments_cnt = plate_data_src[plate_to_slice-1]->slice_filaments_info.size();
|
||||||
|
if (filaments_cnt == 0)
|
||||||
|
{
|
||||||
|
// slice filaments info invalid
|
||||||
|
std::vector<int> extruders = cur_plate->get_extruders_under_cli(true, m_print_config);
|
||||||
|
filaments_cnt = extruders.size();
|
||||||
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": slice filaments info invalid, get from partplate: filament_count %1%")%filaments_cnt;
|
||||||
|
}
|
||||||
|
float layer_height = 0.2;
|
||||||
|
ConfigOption* layer_height_opt = m_print_config.option("layer_height");
|
||||||
|
if (layer_height_opt)
|
||||||
|
layer_height = layer_height_opt->getFloat();
|
||||||
|
|
||||||
|
float depth = v * (filaments_cnt - 1) / (layer_height * w);
|
||||||
|
|
||||||
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format("wipe_tower: x=%1%, y=%2%, width=%3%, depth=%4%, angle=%5%, prime_volume=%6%, filaments_cnt=%7%, layer_height=%8%")
|
||||||
|
%x %y %w %depth %a %v %filaments_cnt %layer_height;
|
||||||
|
|
||||||
|
Vec3d plate_origin = cur_plate->get_origin();
|
||||||
|
|
||||||
|
ArrangePolygon wipe_tower_ap;
|
||||||
|
|
||||||
|
Polygon ap({
|
||||||
|
{scaled(x), scaled(y)},
|
||||||
|
{scaled(x + w), scaled(y)},
|
||||||
|
{scaled(x + w), scaled(y + depth)},
|
||||||
|
{scaled(x), scaled(y + depth)}
|
||||||
|
});
|
||||||
|
wipe_tower_ap.bed_idx = 0;
|
||||||
|
wipe_tower_ap.setter = NULL; // do not move wipe tower
|
||||||
|
|
||||||
|
wipe_tower_ap.poly.contour = std::move(ap);
|
||||||
|
wipe_tower_ap.translation = {scaled(0.f), scaled(0.f)};
|
||||||
|
wipe_tower_ap.rotation = a;
|
||||||
|
wipe_tower_ap.name = "WipeTower";
|
||||||
|
wipe_tower_ap.is_virt_object = true;
|
||||||
|
wipe_tower_ap.is_wipe_tower = true;
|
||||||
|
++wipe_tower_ap.priority;
|
||||||
|
unselected.emplace_back(std::move(wipe_tower_ap));
|
||||||
|
}
|
||||||
|
|
||||||
|
// add the virtual object into unselect list if has
|
||||||
|
partplate_list.preprocess_exclude_areas(unselected, plate_to_slice);
|
||||||
}
|
}
|
||||||
|
|
||||||
//add the virtual object into unselect list if has
|
|
||||||
partplate_list.preprocess_exclude_areas(unselected);
|
|
||||||
|
|
||||||
//Step-2:prepare the arrange params
|
//Step-2:prepare the arrange params
|
||||||
arrange_cfg.allow_rotations = true;
|
arrange_cfg.allow_rotations = true;
|
||||||
arrange_cfg.min_obj_distance = scaled(6.0);
|
arrange_cfg.allow_multi_materials_on_same_plate = true;
|
||||||
//BBS: add specific params
|
arrange_cfg.avoid_extrusion_cali_region = false;
|
||||||
arrange_cfg.is_seq_print = false;
|
arrange_cfg.min_obj_distance = scaled(22.0);
|
||||||
|
arrange_cfg.clearance_height_to_rod = height_to_rod;
|
||||||
|
arrange_cfg.clearance_height_to_lid = height_to_lid;
|
||||||
|
arrange_cfg.cleareance_radius = cleareance_radius;
|
||||||
|
arrange_cfg.printable_height = print_height;
|
||||||
|
|
||||||
arrange_cfg.bed_shrink_x = 0;
|
arrange_cfg.bed_shrink_x = 0;
|
||||||
arrange_cfg.bed_shrink_y = 0;
|
arrange_cfg.bed_shrink_y = 0;
|
||||||
double skirt_distance = m_print_config.opt_float("skirt_distance");
|
double skirt_distance = m_print_config.opt_float("skirt_distance");
|
||||||
|
@ -1990,6 +2129,14 @@ int CLI::run(int argc, char **argv)
|
||||||
// So we can't do max but do adding instead.
|
// So we can't do max but do adding instead.
|
||||||
arrange_cfg.bed_shrink_x += arrange_cfg.brim_skirt_distance;
|
arrange_cfg.bed_shrink_x += arrange_cfg.brim_skirt_distance;
|
||||||
arrange_cfg.bed_shrink_y += arrange_cfg.brim_skirt_distance;
|
arrange_cfg.bed_shrink_y += arrange_cfg.brim_skirt_distance;
|
||||||
|
|
||||||
|
if (arrange_cfg.is_seq_print)
|
||||||
|
{
|
||||||
|
arrange_cfg.min_obj_distance = std::max(arrange_cfg.min_obj_distance, scaled(arrange_cfg.cleareance_radius + 0.001));
|
||||||
|
float shift_dist = arrange_cfg.cleareance_radius / 2 - 5;
|
||||||
|
arrange_cfg.bed_shrink_x -= shift_dist;
|
||||||
|
arrange_cfg.bed_shrink_y -= shift_dist;
|
||||||
|
}
|
||||||
// shrink bed
|
// shrink bed
|
||||||
beds[0] += Point(scaled(arrange_cfg.bed_shrink_x), scaled(arrange_cfg.bed_shrink_y));
|
beds[0] += Point(scaled(arrange_cfg.bed_shrink_x), scaled(arrange_cfg.bed_shrink_y));
|
||||||
beds[1] += Point(-scaled(arrange_cfg.bed_shrink_x), scaled(arrange_cfg.bed_shrink_y));
|
beds[1] += Point(-scaled(arrange_cfg.bed_shrink_x), scaled(arrange_cfg.bed_shrink_y));
|
||||||
|
@ -2015,43 +2162,133 @@ int CLI::run(int argc, char **argv)
|
||||||
|
|
||||||
//Step-4:postprocess by partplate list&&apply the result
|
//Step-4:postprocess by partplate list&&apply the result
|
||||||
int bed_idx_max = 0;
|
int bed_idx_max = 0;
|
||||||
//clear all the relations before apply the arrangement results
|
if (duplicate_count == 0)
|
||||||
partplate_list.clear();
|
{
|
||||||
|
//clear all the relations before apply the arrangement results
|
||||||
|
partplate_list.clear();
|
||||||
|
|
||||||
// Apply the arrange result to all selected objects
|
// Apply the arrange result to all selected objects
|
||||||
for (ArrangePolygon &ap : selected) {
|
for (ArrangePolygon &ap : selected) {
|
||||||
//BBS: partplate postprocess
|
//BBS: partplate postprocess
|
||||||
partplate_list.postprocess_bed_index_for_selected(ap);
|
partplate_list.postprocess_bed_index_for_selected(ap);
|
||||||
|
|
||||||
bed_idx_max = std::max(ap.bed_idx, bed_idx_max);
|
bed_idx_max = std::max(ap.bed_idx, bed_idx_max);
|
||||||
boost::nowide::cout<< "after arrange: name=" << ap.name << boost::format(",bed_id %1%, trans {%2%,%3%}") % ap.bed_idx % unscale<double>(ap.translation(X)) % unscale<double>(ap.translation(Y)) << "\n";
|
boost::nowide::cout<< "after arrange: name=" << ap.name << boost::format(",bed_id %1%, trans {%2%,%3%}") % ap.bed_idx % unscale<double>(ap.translation(X)) % unscale<double>(ap.translation(Y)) << "\n";
|
||||||
|
}
|
||||||
|
for (ArrangePolygon &ap : locked_aps) {
|
||||||
|
bed_idx_max = std::max(ap.bed_idx, bed_idx_max);
|
||||||
|
|
||||||
|
partplate_list.postprocess_arrange_polygon(ap, false);
|
||||||
|
|
||||||
|
ap.apply();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply the arrange result to all selected objects
|
||||||
|
for (ArrangePolygon &ap : selected) {
|
||||||
|
//BBS: partplate postprocess
|
||||||
|
partplate_list.postprocess_arrange_polygon(ap, true);
|
||||||
|
|
||||||
|
ap.apply();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move the unprintable items to the last virtual bed.
|
||||||
|
for (ArrangePolygon &ap : unprintable) {
|
||||||
|
ap.bed_idx += bed_idx_max + 1;
|
||||||
|
partplate_list.postprocess_arrange_polygon(ap, true);
|
||||||
|
|
||||||
|
ap.apply();
|
||||||
|
}
|
||||||
|
|
||||||
|
//BBS: reload all objects due to arrange
|
||||||
|
partplate_list.rebuild_plates_after_arrangement();
|
||||||
}
|
}
|
||||||
for (ArrangePolygon &ap : locked_aps) {
|
else {
|
||||||
bed_idx_max = std::max(ap.bed_idx, bed_idx_max);
|
//only for partplate case
|
||||||
|
partplate_list.clear(false, false, true, plate_to_slice-1);
|
||||||
|
|
||||||
partplate_list.postprocess_arrange_polygon(ap, false);
|
//BBS: adjust the bed_index, create new plates, get the max bed_index
|
||||||
|
|
||||||
ap.apply();
|
for (ArrangePolygon& ap : selected) {
|
||||||
|
if (ap.bed_idx != (plate_to_slice-1))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(":arrange failed: ap.name %1% ap.bed_idx %2%, plate index %3%")% ap.name % ap.bed_idx % (plate_to_slice-1);
|
||||||
|
if (!duplicate_single_object)
|
||||||
|
{
|
||||||
|
BOOST_LOG_TRIVIAL(error) << "arrange failed when duplicate multiple objects." << std::endl;
|
||||||
|
record_exit_reson(outfile_dir, CLI_OBJECT_ARRANGE_FAILED, 0, cli_errors[CLI_OBJECT_ARRANGE_FAILED]);
|
||||||
|
flush_and_exit(CLI_OBJECT_ARRANGE_FAILED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(":arrange success: ap.name %1% ap.bed_idx %2%, plate index %3%")% ap.name % ap.bed_idx % (plate_to_slice-1);
|
||||||
|
real_duplicate_count ++;
|
||||||
|
}
|
||||||
|
partplate_list.postprocess_bed_index_for_current_plate(ap);
|
||||||
|
|
||||||
|
bed_idx_max = std::max(ap.bed_idx, bed_idx_max);
|
||||||
|
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": arrange selected %4%: bed_id %1%, trans {%2%,%3%}") % ap.bed_idx % unscale<double>(ap.translation(X)) % unscale<double>(ap.translation(Y)) % ap.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (duplicate_single_object && (real_duplicate_count <= 0))
|
||||||
|
{
|
||||||
|
BOOST_LOG_TRIVIAL(error) << "no object can be placed under single object mode." << std::endl;
|
||||||
|
record_exit_reson(outfile_dir, CLI_OBJECT_ARRANGE_FAILED, 0, cli_errors[CLI_OBJECT_ARRANGE_FAILED]);
|
||||||
|
flush_and_exit(CLI_OBJECT_ARRANGE_FAILED);
|
||||||
|
}
|
||||||
|
|
||||||
|
//BBS: adjust the bed_index, create new plates, get the max bed_index
|
||||||
|
for (ArrangePolygon& ap : unselected)
|
||||||
|
{
|
||||||
|
if (ap.is_virt_object)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
bed_idx_max = std::max(ap.bed_idx, bed_idx_max);
|
||||||
|
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(":arrange unselected %4%: bed_id %1%, trans {%2%,%3%}") % ap.bed_idx % unscale<double>(ap.translation(X)) % unscale<double>(ap.translation(Y)) % ap.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ArrangePolygon& ap : locked_aps)
|
||||||
|
{
|
||||||
|
bed_idx_max = std::max(ap.bed_idx, bed_idx_max);
|
||||||
|
|
||||||
|
partplate_list.postprocess_arrange_polygon(ap, false);
|
||||||
|
|
||||||
|
ap.apply();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply the arrange result to all selected objects
|
||||||
|
for (ArrangePolygon& ap : selected) {
|
||||||
|
//BBS: partplate postprocess
|
||||||
|
partplate_list.postprocess_arrange_polygon(ap, true);
|
||||||
|
|
||||||
|
ap.apply();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply the arrange result to unselected objects(due to the sukodu-style column changes, the position of unselected may also be modified)
|
||||||
|
for (ArrangePolygon& ap : unselected)
|
||||||
|
{
|
||||||
|
if (ap.is_virt_object)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
//BBS: partplate postprocess
|
||||||
|
partplate_list.postprocess_arrange_polygon(ap, false);
|
||||||
|
|
||||||
|
ap.apply();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move the unprintable items to the last virtual bed.
|
||||||
|
// Note ap.apply() moves relatively according to bed_idx, so we need to subtract the orignal bed_idx
|
||||||
|
for (ArrangePolygon& ap : unprintable)
|
||||||
|
{
|
||||||
|
ap.bed_idx = bed_idx_max + 1;
|
||||||
|
partplate_list.postprocess_arrange_polygon(ap, true);
|
||||||
|
|
||||||
|
ap.apply();
|
||||||
|
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(":arrange m_unprintable: name: %4%, bed_id %1%, trans {%2%,%3%}") % ap.bed_idx % unscale<double>(ap.translation(X)) % unscale<double>(ap.translation(Y)) % ap.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
partplate_list.rebuild_plates_after_arrangement(false, true, plate_to_slice-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply the arrange result to all selected objects
|
|
||||||
for (ArrangePolygon &ap : selected) {
|
|
||||||
//BBS: partplate postprocess
|
|
||||||
partplate_list.postprocess_arrange_polygon(ap, true);
|
|
||||||
|
|
||||||
ap.apply();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move the unprintable items to the last virtual bed.
|
|
||||||
for (ArrangePolygon &ap : unprintable) {
|
|
||||||
ap.bed_idx += bed_idx_max + 1;
|
|
||||||
partplate_list.postprocess_arrange_polygon(ap, true);
|
|
||||||
|
|
||||||
ap.apply();
|
|
||||||
}
|
|
||||||
|
|
||||||
//BBS: reload all objects due to arrange
|
|
||||||
partplate_list.rebuild_plates_after_arrangement();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2085,7 +2322,19 @@ int CLI::run(int argc, char **argv)
|
||||||
load_slice_data_dir = m_config.opt_string(opt_key);
|
load_slice_data_dir = m_config.opt_string(opt_key);
|
||||||
if (export_slicedata) {
|
if (export_slicedata) {
|
||||||
BOOST_LOG_TRIVIAL(error) << "should not set load_slicedata and export_slicedata together." << std::endl;
|
BOOST_LOG_TRIVIAL(error) << "should not set load_slicedata and export_slicedata together." << std::endl;
|
||||||
record_fail_reson(outfile_dir, CLI_INVALID_PARAMS, 0, cli_errors[CLI_INVALID_PARAMS]);
|
record_exit_reson(outfile_dir, CLI_INVALID_PARAMS, 0, cli_errors[CLI_INVALID_PARAMS]);
|
||||||
|
flush_and_exit(CLI_INVALID_PARAMS);
|
||||||
|
}
|
||||||
|
else if (duplicate_count > 0)
|
||||||
|
{
|
||||||
|
BOOST_LOG_TRIVIAL(error) << "should not set load_slicedata when set repetitions." << std::endl;
|
||||||
|
record_exit_reson(outfile_dir, CLI_INVALID_PARAMS, 0, cli_errors[CLI_INVALID_PARAMS]);
|
||||||
|
flush_and_exit(CLI_INVALID_PARAMS);
|
||||||
|
}
|
||||||
|
else if (shrink_to_new_bed)
|
||||||
|
{
|
||||||
|
BOOST_LOG_TRIVIAL(error) << "should not set load_slicedata when shrink_to_new_bed(switch printer from small to bigger." << std::endl;
|
||||||
|
record_exit_reson(outfile_dir, CLI_INVALID_PARAMS, 0, cli_errors[CLI_INVALID_PARAMS]);
|
||||||
flush_and_exit(CLI_INVALID_PARAMS);
|
flush_and_exit(CLI_INVALID_PARAMS);
|
||||||
}
|
}
|
||||||
} else if (opt_key == "export_settings") {
|
} else if (opt_key == "export_settings") {
|
||||||
|
@ -2109,14 +2358,14 @@ int CLI::run(int argc, char **argv)
|
||||||
for (auto &model : m_models)
|
for (auto &model : m_models)
|
||||||
model.add_default_instances();
|
model.add_default_instances();
|
||||||
if (! this->export_models(IO::STL)) {
|
if (! this->export_models(IO::STL)) {
|
||||||
record_fail_reson(outfile_dir, CLI_EXPORT_STL_ERROR, 0, cli_errors[CLI_EXPORT_STL_ERROR]);
|
record_exit_reson(outfile_dir, CLI_EXPORT_STL_ERROR, 0, cli_errors[CLI_EXPORT_STL_ERROR]);
|
||||||
flush_and_exit(CLI_EXPORT_STL_ERROR);
|
flush_and_exit(CLI_EXPORT_STL_ERROR);
|
||||||
}
|
}
|
||||||
} else if (opt_key == "export_obj") {
|
} else if (opt_key == "export_obj") {
|
||||||
for (auto &model : m_models)
|
for (auto &model : m_models)
|
||||||
model.add_default_instances();
|
model.add_default_instances();
|
||||||
if (! this->export_models(IO::OBJ)) {
|
if (! this->export_models(IO::OBJ)) {
|
||||||
record_fail_reson(outfile_dir, CLI_EXPORT_OBJ_ERROR, 0, cli_errors[CLI_EXPORT_OBJ_ERROR]);
|
record_exit_reson(outfile_dir, CLI_EXPORT_OBJ_ERROR, 0, cli_errors[CLI_EXPORT_OBJ_ERROR]);
|
||||||
flush_and_exit(CLI_EXPORT_OBJ_ERROR);
|
flush_and_exit(CLI_EXPORT_OBJ_ERROR);
|
||||||
}
|
}
|
||||||
}/* else if (opt_key == "export_amf") {
|
}/* else if (opt_key == "export_amf") {
|
||||||
|
@ -2135,7 +2384,7 @@ int CLI::run(int argc, char **argv)
|
||||||
export_slice_data_dir = m_config.opt_string(opt_key);
|
export_slice_data_dir = m_config.opt_string(opt_key);
|
||||||
if (load_slicedata) {
|
if (load_slicedata) {
|
||||||
BOOST_LOG_TRIVIAL(error) << "should not set load_slicedata and export_slicedata together." << std::endl;
|
BOOST_LOG_TRIVIAL(error) << "should not set load_slicedata and export_slicedata together." << std::endl;
|
||||||
record_fail_reson(outfile_dir, CLI_INVALID_PARAMS, 0, cli_errors[CLI_INVALID_PARAMS]);
|
record_exit_reson(outfile_dir, CLI_INVALID_PARAMS, 0, cli_errors[CLI_INVALID_PARAMS]);
|
||||||
flush_and_exit(CLI_INVALID_PARAMS);
|
flush_and_exit(CLI_INVALID_PARAMS);
|
||||||
}
|
}
|
||||||
} else if (opt_key == "slice") {
|
} else if (opt_key == "slice") {
|
||||||
|
@ -2157,11 +2406,11 @@ int CLI::run(int argc, char **argv)
|
||||||
}
|
}
|
||||||
/*if (opt_key == "export_gcode" && printer_technology == ptSLA) {
|
/*if (opt_key == "export_gcode" && printer_technology == ptSLA) {
|
||||||
boost::nowide::cerr << "error: cannot export G-code for an FFF configuration" << std::endl;
|
boost::nowide::cerr << "error: cannot export G-code for an FFF configuration" << std::endl;
|
||||||
record_fail_reson(outfile_dir, 1, 0, cli_errors[1]);
|
record_exit_reson(outfile_dir, 1, 0, cli_errors[1]);
|
||||||
flush_and_exit(1);
|
flush_and_exit(1);
|
||||||
} else if (opt_key == "export_sla" && printer_technology == ptFFF) {
|
} else if (opt_key == "export_sla" && printer_technology == ptFFF) {
|
||||||
boost::nowide::cerr << "error: cannot export SLA slices for a SLA configuration" << std::endl;
|
boost::nowide::cerr << "error: cannot export SLA slices for a SLA configuration" << std::endl;
|
||||||
record_fail_reson(outfile_dir, 1, 0, cli_errors[1]);
|
record_exit_reson(outfile_dir, 1, 0, cli_errors[1]);
|
||||||
flush_and_exit(1);
|
flush_and_exit(1);
|
||||||
}*/
|
}*/
|
||||||
BOOST_LOG_TRIVIAL(info) << "Need to slice for plate "<<plate_to_slice <<", total plate count "<<partplate_list.get_plate_count()<<" partplates!" << std::endl;
|
BOOST_LOG_TRIVIAL(info) << "Need to slice for plate "<<plate_to_slice <<", total plate count "<<partplate_list.get_plate_count()<<" partplates!" << std::endl;
|
||||||
|
@ -2228,7 +2477,7 @@ int CLI::run(int argc, char **argv)
|
||||||
|
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
BOOST_LOG_TRIVIAL(error) << "plate "<< index+1<< ": Nothing to be sliced, Either the print is empty or no object is fully inside the print volume before apply." << std::endl;
|
BOOST_LOG_TRIVIAL(error) << "plate "<< index+1<< ": Nothing to be sliced, Either the print is empty or no object is fully inside the print volume before apply." << std::endl;
|
||||||
record_fail_reson(outfile_dir, CLI_NO_SUITABLE_OBJECTS, index+1, cli_errors[CLI_NO_SUITABLE_OBJECTS]);
|
record_exit_reson(outfile_dir, CLI_NO_SUITABLE_OBJECTS, index+1, cli_errors[CLI_NO_SUITABLE_OBJECTS]);
|
||||||
flush_and_exit(CLI_NO_SUITABLE_OBJECTS);
|
flush_and_exit(CLI_NO_SUITABLE_OBJECTS);
|
||||||
}
|
}
|
||||||
else if ((plate_to_slice != 0) || pre_check) {
|
else if ((plate_to_slice != 0) || pre_check) {
|
||||||
|
@ -2269,7 +2518,7 @@ int CLI::run(int argc, char **argv)
|
||||||
if (i->print_volume_state == ModelInstancePVS_Partly_Outside)
|
if (i->print_volume_state == ModelInstancePVS_Partly_Outside)
|
||||||
{
|
{
|
||||||
BOOST_LOG_TRIVIAL(error) << "plate "<< index+1<< ": Found Object " << model_object->name <<" partly inside, can not be sliced." << std::endl;
|
BOOST_LOG_TRIVIAL(error) << "plate "<< index+1<< ": Found Object " << model_object->name <<" partly inside, can not be sliced." << std::endl;
|
||||||
record_fail_reson(outfile_dir, CLI_OBJECTS_PARTLY_INSIDE, index+1, cli_errors[CLI_OBJECTS_PARTLY_INSIDE]);
|
record_exit_reson(outfile_dir, CLI_OBJECTS_PARTLY_INSIDE, index+1, cli_errors[CLI_OBJECTS_PARTLY_INSIDE]);
|
||||||
flush_and_exit(CLI_OBJECTS_PARTLY_INSIDE);
|
flush_and_exit(CLI_OBJECTS_PARTLY_INSIDE);
|
||||||
}
|
}
|
||||||
else if ((max_triangle_count_per_plate != 0) && (i->print_volume_state == ModelInstancePVS_Inside))
|
else if ((max_triangle_count_per_plate != 0) && (i->print_volume_state == ModelInstancePVS_Inside))
|
||||||
|
@ -2283,7 +2532,7 @@ int CLI::run(int argc, char **argv)
|
||||||
if (triangle_count > max_triangle_count_per_plate)
|
if (triangle_count > max_triangle_count_per_plate)
|
||||||
{
|
{
|
||||||
BOOST_LOG_TRIVIAL(error) << "plate "<< index+1<< ": triangle count " << triangle_count <<" exceeds the limit:" << max_triangle_count_per_plate;
|
BOOST_LOG_TRIVIAL(error) << "plate "<< index+1<< ": triangle count " << triangle_count <<" exceeds the limit:" << max_triangle_count_per_plate;
|
||||||
record_fail_reson(outfile_dir, CLI_TRIANGLE_COUNT_EXCEEDS_LIMIT, index+1, cli_errors[CLI_TRIANGLE_COUNT_EXCEEDS_LIMIT]);
|
record_exit_reson(outfile_dir, CLI_TRIANGLE_COUNT_EXCEEDS_LIMIT, index+1, cli_errors[CLI_TRIANGLE_COUNT_EXCEEDS_LIMIT]);
|
||||||
flush_and_exit(CLI_TRIANGLE_COUNT_EXCEEDS_LIMIT);
|
flush_and_exit(CLI_TRIANGLE_COUNT_EXCEEDS_LIMIT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2296,7 +2545,7 @@ int CLI::run(int argc, char **argv)
|
||||||
|
|
||||||
if (printable_instances == 0) {
|
if (printable_instances == 0) {
|
||||||
BOOST_LOG_TRIVIAL(error) << "plate "<< index+1<< ": Nothing to be sliced, after skipping "<<skipped_count<<" objects."<< std::endl;
|
BOOST_LOG_TRIVIAL(error) << "plate "<< index+1<< ": Nothing to be sliced, after skipping "<<skipped_count<<" objects."<< std::endl;
|
||||||
record_fail_reson(outfile_dir, CLI_NO_SUITABLE_OBJECTS_AFTER_SKIP, index+1, cli_errors[CLI_NO_SUITABLE_OBJECTS_AFTER_SKIP]);
|
record_exit_reson(outfile_dir, CLI_NO_SUITABLE_OBJECTS_AFTER_SKIP, index+1, cli_errors[CLI_NO_SUITABLE_OBJECTS_AFTER_SKIP]);
|
||||||
flush_and_exit(CLI_NO_SUITABLE_OBJECTS_AFTER_SKIP);
|
flush_and_exit(CLI_NO_SUITABLE_OBJECTS_AFTER_SKIP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2334,7 +2583,7 @@ int CLI::run(int argc, char **argv)
|
||||||
validate_error = CLI_VALIDATE_ERROR;
|
validate_error = CLI_VALIDATE_ERROR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
record_fail_reson(outfile_dir, validate_error, index+1, cli_errors[validate_error]);
|
record_exit_reson(outfile_dir, validate_error, index+1, cli_errors[validate_error]);
|
||||||
flush_and_exit(validate_error);
|
flush_and_exit(validate_error);
|
||||||
}
|
}
|
||||||
else if (!warning.string.empty())
|
else if (!warning.string.empty())
|
||||||
|
@ -2342,7 +2591,7 @@ int CLI::run(int argc, char **argv)
|
||||||
|
|
||||||
if (print->empty()) {
|
if (print->empty()) {
|
||||||
BOOST_LOG_TRIVIAL(error) << "plate "<< index+1<< ": Nothing to be sliced, Either the print is empty or no object is fully inside the print volume after apply." << std::endl;
|
BOOST_LOG_TRIVIAL(error) << "plate "<< index+1<< ": Nothing to be sliced, Either the print is empty or no object is fully inside the print volume after apply." << std::endl;
|
||||||
record_fail_reson(outfile_dir, CLI_NO_SUITABLE_OBJECTS, index+1, cli_errors[CLI_NO_SUITABLE_OBJECTS]);
|
record_exit_reson(outfile_dir, CLI_NO_SUITABLE_OBJECTS, index+1, cli_errors[CLI_NO_SUITABLE_OBJECTS]);
|
||||||
flush_and_exit(CLI_NO_SUITABLE_OBJECTS);
|
flush_and_exit(CLI_NO_SUITABLE_OBJECTS);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -2410,7 +2659,7 @@ int CLI::run(int argc, char **argv)
|
||||||
std::string conflict_result = dynamic_cast<Print *>(print)->get_conflict_string();
|
std::string conflict_result = dynamic_cast<Print *>(print)->get_conflict_string();
|
||||||
if (!conflict_result.empty()) {
|
if (!conflict_result.empty()) {
|
||||||
BOOST_LOG_TRIVIAL(error) << "plate "<< index+1<< ": found slicing result conflict!"<< std::endl;
|
BOOST_LOG_TRIVIAL(error) << "plate "<< index+1<< ": found slicing result conflict!"<< std::endl;
|
||||||
record_fail_reson(outfile_dir, CLI_GCODE_PATH_CONFLICTS, index+1, cli_errors[CLI_GCODE_PATH_CONFLICTS]);
|
record_exit_reson(outfile_dir, CLI_GCODE_PATH_CONFLICTS, index+1, cli_errors[CLI_GCODE_PATH_CONFLICTS]);
|
||||||
flush_and_exit(CLI_GCODE_PATH_CONFLICTS);
|
flush_and_exit(CLI_GCODE_PATH_CONFLICTS);
|
||||||
}
|
}
|
||||||
// The outfile is processed by a PlaceholderParser.
|
// The outfile is processed by a PlaceholderParser.
|
||||||
|
@ -2435,7 +2684,7 @@ int CLI::run(int argc, char **argv)
|
||||||
/*if (outfile != outfile_final) {
|
/*if (outfile != outfile_final) {
|
||||||
if (Slic3r::rename_file(outfile, outfile_final)) {
|
if (Slic3r::rename_file(outfile, outfile_final)) {
|
||||||
boost::nowide::cerr << "Renaming file " << outfile << " to " << outfile_final << " failed" << std::endl;
|
boost::nowide::cerr << "Renaming file " << outfile << " to " << outfile_final << " failed" << std::endl;
|
||||||
record_fail_reson(outfile_dir, 1, index+1, cli_errors[1]);
|
record_exit_reson(outfile_dir, 1, index+1, cli_errors[1]);
|
||||||
flush_and_exit(1);
|
flush_and_exit(1);
|
||||||
}
|
}
|
||||||
outfile = outfile_final;
|
outfile = outfile_final;
|
||||||
|
@ -2460,7 +2709,7 @@ int CLI::run(int argc, char **argv)
|
||||||
export_slicedata_error = true;
|
export_slicedata_error = true;
|
||||||
if (fs::exists(plate_dir))
|
if (fs::exists(plate_dir))
|
||||||
fs::remove_all(plate_dir);
|
fs::remove_all(plate_dir);
|
||||||
record_fail_reson(outfile_dir, ret, index+1, cli_errors[ret]);
|
record_exit_reson(outfile_dir, ret, index+1, cli_errors[ret]);
|
||||||
flush_and_exit(ret);
|
flush_and_exit(ret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2470,7 +2719,7 @@ int CLI::run(int argc, char **argv)
|
||||||
if (time_cost > max_slicing_time_per_plate) {
|
if (time_cost > max_slicing_time_per_plate) {
|
||||||
BOOST_LOG_TRIVIAL(error) << boost::format("plate %1%'s slice time %2% exceeds the limit %3%, return error.")
|
BOOST_LOG_TRIVIAL(error) << boost::format("plate %1%'s slice time %2% exceeds the limit %3%, return error.")
|
||||||
%(index+1) %time_cost %max_slicing_time_per_plate;
|
%(index+1) %time_cost %max_slicing_time_per_plate;
|
||||||
record_fail_reson(outfile_dir, CLI_SLICING_TIME_EXCEEDS_LIMIT, index+1, cli_errors[CLI_SLICING_TIME_EXCEEDS_LIMIT]);
|
record_exit_reson(outfile_dir, CLI_SLICING_TIME_EXCEEDS_LIMIT, index+1, cli_errors[CLI_SLICING_TIME_EXCEEDS_LIMIT]);
|
||||||
flush_and_exit(CLI_SLICING_TIME_EXCEEDS_LIMIT);
|
flush_and_exit(CLI_SLICING_TIME_EXCEEDS_LIMIT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2478,7 +2727,7 @@ int CLI::run(int argc, char **argv)
|
||||||
BOOST_LOG_TRIVIAL(error) << "found slicing or export error for partplate "<<index+1 << std::endl;
|
BOOST_LOG_TRIVIAL(error) << "found slicing or export error for partplate "<<index+1 << std::endl;
|
||||||
boost::nowide::cerr << ex.what() << std::endl;
|
boost::nowide::cerr << ex.what() << std::endl;
|
||||||
//continue;
|
//continue;
|
||||||
record_fail_reson(outfile_dir, CLI_SLICING_ERROR, index+1, cli_errors[CLI_SLICING_ERROR]);
|
record_exit_reson(outfile_dir, CLI_SLICING_ERROR, index+1, cli_errors[CLI_SLICING_ERROR]);
|
||||||
flush_and_exit(CLI_SLICING_ERROR);
|
flush_and_exit(CLI_SLICING_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2528,7 +2777,7 @@ int CLI::run(int argc, char **argv)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
boost::nowide::cerr << "error: option not supported yet: " << opt_key << std::endl;
|
boost::nowide::cerr << "error: option not supported yet: " << opt_key << std::endl;
|
||||||
record_fail_reson(outfile_dir, CLI_UNSUPPORTED_OPERATION, 0, cli_errors[CLI_UNSUPPORTED_OPERATION]);
|
record_exit_reson(outfile_dir, CLI_UNSUPPORTED_OPERATION, 0, cli_errors[CLI_UNSUPPORTED_OPERATION]);
|
||||||
flush_and_exit(CLI_UNSUPPORTED_OPERATION);
|
flush_and_exit(CLI_UNSUPPORTED_OPERATION);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3048,7 +3297,7 @@ int CLI::run(int argc, char **argv)
|
||||||
calibration_thumbnails, plate_bboxes, &m_print_config))
|
calibration_thumbnails, plate_bboxes, &m_print_config))
|
||||||
{
|
{
|
||||||
release_PlateData_list(plate_data_list);
|
release_PlateData_list(plate_data_list);
|
||||||
record_fail_reson(outfile_dir, CLI_EXPORT_3MF_ERROR, 0, cli_errors[CLI_EXPORT_3MF_ERROR]);
|
record_exit_reson(outfile_dir, CLI_EXPORT_3MF_ERROR, 0, cli_errors[CLI_EXPORT_3MF_ERROR]);
|
||||||
flush_and_exit(CLI_EXPORT_3MF_ERROR);
|
flush_and_exit(CLI_EXPORT_3MF_ERROR);
|
||||||
}
|
}
|
||||||
release_PlateData_list(plate_data_list);
|
release_PlateData_list(plate_data_list);
|
||||||
|
@ -3085,6 +3334,15 @@ int CLI::run(int argc, char **argv)
|
||||||
}
|
}
|
||||||
//BBS: flush logs
|
//BBS: flush logs
|
||||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", Finished" << std::endl;
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", Finished" << std::endl;
|
||||||
|
|
||||||
|
//record the duplicate here
|
||||||
|
if ((duplicate_count > 0) && duplicate_single_object)
|
||||||
|
{
|
||||||
|
record_exit_reson(outfile_dir, 0, plate_to_slice, cli_errors[0], real_duplicate_count);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
record_exit_reson(outfile_dir, 0, plate_to_slice, cli_errors[0]);
|
||||||
|
|
||||||
boost::nowide::cout.flush();
|
boost::nowide::cout.flush();
|
||||||
boost::nowide::cerr.flush();
|
boost::nowide::cerr.flush();
|
||||||
|
|
||||||
|
|
|
@ -1432,6 +1432,92 @@ std::vector<int> PartPlate::get_extruders(bool conside_custom_gcode) const
|
||||||
return plate_extruders;
|
return plate_extruders;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<int> PartPlate::get_extruders_under_cli(bool conside_custom_gcode, DynamicPrintConfig& full_config) const
|
||||||
|
{
|
||||||
|
std::vector<int> plate_extruders;
|
||||||
|
|
||||||
|
// if 3mf file
|
||||||
|
int glb_support_intf_extr = full_config.opt_int("support_interface_filament");
|
||||||
|
int glb_support_extr = full_config.opt_int("support_filament");
|
||||||
|
bool glb_support = full_config.opt_bool("enable_support");
|
||||||
|
glb_support |= full_config.opt_int("raft_layers") > 0;
|
||||||
|
|
||||||
|
for (std::set<std::pair<int, int>>::iterator it = obj_to_instance_set.begin(); it != obj_to_instance_set.end(); ++it)
|
||||||
|
{
|
||||||
|
int obj_id = it->first;
|
||||||
|
int instance_id = it->second;
|
||||||
|
|
||||||
|
if ((obj_id >= 0) && (obj_id < m_model->objects.size()))
|
||||||
|
{
|
||||||
|
ModelObject* object = m_model->objects[obj_id];
|
||||||
|
for (ModelVolume* mv : object->volumes) {
|
||||||
|
std::vector<int> volume_extruders = mv->get_extruders();
|
||||||
|
plate_extruders.insert(plate_extruders.end(), volume_extruders.begin(), volume_extruders.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
// layer range
|
||||||
|
for (auto layer_range : object->layer_config_ranges) {
|
||||||
|
if (layer_range.second.has("extruder")) {
|
||||||
|
if (auto id = layer_range.second.option("extruder")->getInt(); id > 0)
|
||||||
|
plate_extruders.push_back(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool obj_support = false;
|
||||||
|
const ConfigOption* obj_support_opt = object->config.option("enable_support");
|
||||||
|
const ConfigOption *obj_raft_opt = object->config.option("raft_layers");
|
||||||
|
if (obj_support_opt != nullptr || obj_raft_opt != nullptr) {
|
||||||
|
if (obj_support_opt != nullptr)
|
||||||
|
obj_support = obj_support_opt->getBool();
|
||||||
|
if (obj_raft_opt != nullptr)
|
||||||
|
obj_support |= obj_raft_opt->getInt() > 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
obj_support = glb_support;
|
||||||
|
|
||||||
|
if (!obj_support)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int obj_support_intf_extr = 0;
|
||||||
|
const ConfigOption* support_intf_extr_opt = object->config.option("support_interface_filament");
|
||||||
|
if (support_intf_extr_opt != nullptr)
|
||||||
|
obj_support_intf_extr = support_intf_extr_opt->getInt();
|
||||||
|
if (obj_support_intf_extr != 0)
|
||||||
|
plate_extruders.push_back(obj_support_intf_extr);
|
||||||
|
else if (glb_support_intf_extr != 0)
|
||||||
|
plate_extruders.push_back(glb_support_intf_extr);
|
||||||
|
|
||||||
|
int obj_support_extr = 0;
|
||||||
|
const ConfigOption* support_extr_opt = object->config.option("support_filament");
|
||||||
|
if (support_extr_opt != nullptr)
|
||||||
|
obj_support_extr = support_extr_opt->getInt();
|
||||||
|
if (obj_support_extr != 0)
|
||||||
|
plate_extruders.push_back(obj_support_extr);
|
||||||
|
else if (glb_support_extr != 0)
|
||||||
|
plate_extruders.push_back(glb_support_extr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conside_custom_gcode) {
|
||||||
|
//BBS
|
||||||
|
int nums_extruders = 0;
|
||||||
|
if (const ConfigOptionStrings *color_option = dynamic_cast<const ConfigOptionStrings *>(full_config.option("filament_colour"))) {
|
||||||
|
nums_extruders = color_option->values.size();
|
||||||
|
if (m_model->plates_custom_gcodes.find(m_plate_index) != m_model->plates_custom_gcodes.end()) {
|
||||||
|
for (auto item : m_model->plates_custom_gcodes.at(m_plate_index).gcodes) {
|
||||||
|
if (item.type == CustomGCode::Type::ToolChange && item.extruder <= nums_extruders)
|
||||||
|
plate_extruders.push_back(item.extruder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sort(plate_extruders.begin(), plate_extruders.end());
|
||||||
|
auto it_end = std::unique(plate_extruders.begin(), plate_extruders.end());
|
||||||
|
plate_extruders.resize(std::distance(plate_extruders.begin(), it_end));
|
||||||
|
return plate_extruders;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<int> PartPlate::get_extruders_without_support(bool conside_custom_gcode) const
|
std::vector<int> PartPlate::get_extruders_without_support(bool conside_custom_gcode) const
|
||||||
{
|
{
|
||||||
std::vector<int> plate_extruders;
|
std::vector<int> plate_extruders;
|
||||||
|
@ -2018,6 +2104,36 @@ void PartPlate::translate_all_instance(Vec3d position)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PartPlate::duplicate_all_instance(unsigned int dup_count)
|
||||||
|
{
|
||||||
|
std::set<std::pair<int, int>> old_obj_list = obj_to_instance_set;
|
||||||
|
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": plate_id %1%, dup_count %2%") % m_plate_index % dup_count;
|
||||||
|
for (std::set<std::pair<int, int>>::iterator it = old_obj_list.begin(); it != old_obj_list.end(); ++it)
|
||||||
|
{
|
||||||
|
int obj_id = it->first;
|
||||||
|
int instance_id = it->second;
|
||||||
|
|
||||||
|
if ((obj_id >= 0) && (obj_id < m_model->objects.size()))
|
||||||
|
{
|
||||||
|
ModelObject* object = m_model->objects[obj_id];
|
||||||
|
for (size_t index = 0; index < dup_count; index ++)
|
||||||
|
{
|
||||||
|
ModelObject* newObj = m_model->add_object(*object);
|
||||||
|
newObj->name = object->name +"_"+ std::to_string(index+1);
|
||||||
|
int new_obj_id = m_model->objects.size() - 1;
|
||||||
|
for ( size_t new_instance_id = 0; new_instance_id < object->instances.size(); new_instance_id++ )
|
||||||
|
{
|
||||||
|
obj_to_instance_set.emplace(std::pair(new_obj_id, new_instance_id));
|
||||||
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": duplicate object into plate: index_pair [%1%,%2%], obj_id %3%") % new_obj_id % new_instance_id % newObj->id().id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//update instance exclude state
|
//update instance exclude state
|
||||||
void PartPlate::update_instance_exclude_status(int obj_id, int instance_id, BoundingBoxf3* bounding_box)
|
void PartPlate::update_instance_exclude_status(int obj_id, int instance_id, BoundingBoxf3* bounding_box)
|
||||||
|
@ -4491,15 +4607,15 @@ bool PartPlateList::is_all_slice_results_ready_for_print() const
|
||||||
|
|
||||||
for (unsigned int i = 0; i < (unsigned int) m_plate_list.size(); ++i) {
|
for (unsigned int i = 0; i < (unsigned int) m_plate_list.size(); ++i) {
|
||||||
if (!m_plate_list[i]->empty()) {
|
if (!m_plate_list[i]->empty()) {
|
||||||
if (m_plate_list[i]->is_all_instances_unprintable()) {
|
if (m_plate_list[i]->is_all_instances_unprintable()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!m_plate_list[i]->is_slice_result_ready_for_print()) {
|
if (!m_plate_list[i]->is_slice_result_ready_for_print()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m_plate_list[i]->is_slice_result_ready_for_print()) {
|
if (m_plate_list[i]->is_slice_result_ready_for_print()) {
|
||||||
res = true;
|
res = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -263,7 +263,7 @@ public:
|
||||||
// set the plate's name
|
// set the plate's name
|
||||||
void set_plate_name(const std::string &name);
|
void set_plate_name(const std::string &name);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//get the print's object, result and index
|
//get the print's object, result and index
|
||||||
void get_print(PrintBase **print, GCodeResult **result, int *index);
|
void get_print(PrintBase **print, GCodeResult **result, int *index);
|
||||||
|
@ -289,6 +289,7 @@ public:
|
||||||
Vec3d get_origin() { return m_origin; }
|
Vec3d get_origin() { return m_origin; }
|
||||||
Vec3d estimate_wipe_tower_size(const double w, const double wipe_volume) const;
|
Vec3d estimate_wipe_tower_size(const double w, const double wipe_volume) const;
|
||||||
std::vector<int> get_extruders(bool conside_custom_gcode = false) const;
|
std::vector<int> get_extruders(bool conside_custom_gcode = false) const;
|
||||||
|
std::vector<int> get_extruders_under_cli(bool conside_custom_gcode, DynamicPrintConfig& full_config) const;
|
||||||
std::vector<int> get_extruders_without_support(bool conside_custom_gcode = false) const;
|
std::vector<int> get_extruders_without_support(bool conside_custom_gcode = false) const;
|
||||||
std::vector<int> get_used_extruders();
|
std::vector<int> get_used_extruders();
|
||||||
|
|
||||||
|
@ -317,6 +318,9 @@ public:
|
||||||
//translate instance on the plate
|
//translate instance on the plate
|
||||||
void translate_all_instance(Vec3d position);
|
void translate_all_instance(Vec3d position);
|
||||||
|
|
||||||
|
//duplicate all instance for count
|
||||||
|
void duplicate_all_instance(unsigned int dup_count);
|
||||||
|
|
||||||
//update instance exclude state
|
//update instance exclude state
|
||||||
void update_instance_exclude_status(int obj_id, int instance_id, BoundingBoxf3* bounding_box = nullptr);
|
void update_instance_exclude_status(int obj_id, int instance_id, BoundingBoxf3* bounding_box = nullptr);
|
||||||
|
|
||||||
|
@ -403,7 +407,7 @@ public:
|
||||||
{
|
{
|
||||||
bool result = m_slice_result_valid;
|
bool result = m_slice_result_valid;
|
||||||
if (result)
|
if (result)
|
||||||
result = m_gcode_result ? (!m_gcode_result->toolpath_outside) : false;// && !m_gcode_result->conflict_result.has_value() gcode conflict can also print
|
result = m_gcode_result ? (!m_gcode_result->toolpath_outside) : false;// && !m_gcode_result->conflict_result.has_value() gcode conflict can also print
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue