From 0c45cac1a815b9257cdaa16f208e720f5e47f08d Mon Sep 17 00:00:00 2001 From: "lane.wei" Date: Wed, 26 Jul 2023 16:13:00 +0800 Subject: [PATCH] ENH: CLI: refine some logic of repetions and load configs 1. when object skipped, it should not be duplicated it is set to unprintable before arrange and the plate needs to be considered a skipped plate also 2. skip the wipe tower if not multi-color after skip 3. load default configs if there are no configs loaded 4. refine the result.json to include key_values Change-Id: I8c132cabcdd78756673fe900267a226a41ae1b4d --- src/BambuStudio.cpp | 151 +++++++++++++++++++++++----------- src/libslic3r/PrintConfig.cpp | 6 ++ src/slic3r/GUI/PartPlate.cpp | 18 +++- src/slic3r/GUI/PartPlate.hpp | 2 +- 4 files changed, 129 insertions(+), 48 deletions(-) diff --git a/src/BambuStudio.cpp b/src/BambuStudio.cpp index 24e1abbdd..e09c304cd 100644 --- a/src/BambuStudio.cpp +++ b/src/BambuStudio.cpp @@ -349,7 +349,7 @@ static PrinterTechnology get_printer_technology(const DynamicConfig &config) return(ret);} #endif -void record_exit_reson(std::string outputdir, int code, int plate_id, std::string error_message, int extra_param1 = 0) +void record_exit_reson(std::string outputdir, int code, int plate_id, std::string error_message, std::map key_values = std::map()) { #if defined(__linux__) || defined(__LINUX__) std::string result_file; @@ -365,8 +365,8 @@ void record_exit_reson(std::string outputdir, int code, int plate_id, std::strin j["plate_index"] = plate_id; j["return_code"] = code; j["error_string"] = error_message; - if (extra_param1 != 0) - j["extra_param1"] = extra_param1; + for (auto& iter: key_values) + j[iter.first] = iter.second; boost::nowide::ofstream c; c.open(result_file, std::ios::out | std::ios::trunc); @@ -549,7 +549,7 @@ int CLI::run(int argc, char **argv) PlateDataPtrs plate_data_src; int arrange_option; 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, duplicate_single_object = false; + 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, use_first_fila_as_default = false; Semver file_version; std::map orients_requirement; std::vector project_presets; @@ -573,6 +573,10 @@ int CLI::run(int argc, char **argv) if (uptodate_option) up_config_to_date = uptodate_option->value; + ConfigOptionBool* load_defaultfila_option = m_config.option("load_defaultfila"); + if (load_defaultfila_option) + use_first_fila_as_default = load_defaultfila_option->value; + ConfigOptionString* pipe_option = m_config.option("pipe"); if (pipe_option) { pipe_name = pipe_option->value; @@ -586,13 +590,23 @@ int CLI::run(int argc, char **argv) } } + //skip model object map construct + if (need_skip) { + BOOST_LOG_TRIVIAL(info) << boost::format("need to skip objects, size %1%:")%skip_objects.size(); + for (int index = 0; index < skip_objects.size(); index++) + { + skip_maps[skip_objects[index]] = false; + BOOST_LOG_TRIVIAL(info) << boost::format("object %1%, id %2%")%index %skip_objects[index]; + } + } + /*for (const std::string& file : m_input_files) if (is_gcode_file(file) && boost::filesystem::exists(file)) { start_as_gcodeviewer = true; BOOST_LOG_TRIVIAL(info) << "found a gcode file:" << file << ", will start as gcode viewer\n"; break; }*/ - BOOST_LOG_TRIVIAL(info) << boost::format("plate_to_slice=%1%, normative_check=%2%")%plate_to_slice %normative_check; + BOOST_LOG_TRIVIAL(info) << boost::format("plate_to_slice=%1%, normative_check=%2%, use_first_fila_as_default=%3%")%plate_to_slice %normative_check %use_first_fila_as_default; //if (!start_as_gcodeviewer) { for (const std::string& file : m_input_files) { if (!boost::filesystem::exists(file)) { @@ -878,6 +892,41 @@ int CLI::run(int argc, char **argv) std::vector load_filaments_id; std::vector load_filaments_name; int current_index = 0; + std::string default_load_fila_name, default_load_fila_id, default_filament_file; + DynamicPrintConfig default_load_fila_config; + if (use_first_fila_as_default) { + //construct default filament + for (int index = 0; index < load_filament_count; index++) { + const std::string& file = load_filaments[index]; + if (default_filament_file.empty() && !file.empty()) { + DynamicPrintConfig config; + std::string config_type, config_name, filament_id; + int ret = load_system_config_file(file, config, config_type, config_name, filament_id); + if (ret) { + record_exit_reson(outfile_dir, ret, 0, cli_errors[ret]); + flush_and_exit(ret); + } + + if (config_type != "filament") { + BOOST_LOG_TRIVIAL(error) <<__FUNCTION__ << boost::format(": unknown config type %1% of file %2% in load-filaments") % config_type % file; + record_exit_reson(outfile_dir, CLI_CONFIG_FILE_ERROR, 0, cli_errors[CLI_CONFIG_FILE_ERROR]); + flush_and_exit(CLI_CONFIG_FILE_ERROR); + } + + default_filament_file = file; + default_load_fila_name = config_name; + default_load_fila_id = filament_id; + default_load_fila_config = std::move(config); + break; + } + } + if ((load_filament_count > 0) && default_filament_file.empty()) + { + BOOST_LOG_TRIVIAL(error) <<__FUNCTION__ << boost::format(": load_filament_count is %1%, but can not load a default filament") % load_filament_count; + record_exit_reson(outfile_dir, CLI_CONFIG_FILE_ERROR, 0, cli_errors[CLI_CONFIG_FILE_ERROR]); + flush_and_exit(CLI_CONFIG_FILE_ERROR); + } + } for (int index = 0; index < load_filament_count; index++) { const std::string& file = load_filaments[index]; current_index++; @@ -891,7 +940,7 @@ int CLI::run(int argc, char **argv) } if (config_type != "filament") { - boost::nowide::cerr <<__FUNCTION__ << boost::format(": unknown config type %1% of file %2% in load-filaments") % config_type % file; + BOOST_LOG_TRIVIAL(error) <<__FUNCTION__ << boost::format(": unknown config type %1% of file %2% in load-filaments") % config_type % file; record_exit_reson(outfile_dir, CLI_CONFIG_FILE_ERROR, 0, cli_errors[CLI_CONFIG_FILE_ERROR]); flush_and_exit(CLI_CONFIG_FILE_ERROR); } @@ -901,7 +950,7 @@ int CLI::run(int argc, char **argv) printer_technology = other_printer_technology; } if ((printer_technology != other_printer_technology) && (other_printer_technology != ptUnknown)) { - boost::nowide::cerr << "invalid printer_technology " <duplicate_all_instance(repetitions_count-1); + cur_plate->duplicate_all_instance(repetitions_count-1, need_skip, skip_maps); need_arrange = true; duplicate_count = repetitions_count - 1; @@ -2112,44 +2168,52 @@ int CLI::run(int argc, char **argv) float a = dynamic_cast(m_print_config.option("wipe_tower_rotation_angle"))->value; float v = dynamic_cast(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) + if ((filaments_cnt == 0) || need_skip) { // slice filaments info invalid std::vector 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; + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": slice filaments info invalid or need_skip, 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); + if (filaments_cnt <= 1) + { + BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": not a multi-color object anymore, drop the wipe tower before arrange."); + } + else + { + 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(); - 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; + float depth = v * (filaments_cnt - 1) / (layer_height * w); - Vec3d plate_origin = cur_plate->get_origin(); + 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; - ArrangePolygon wipe_tower_ap; + Vec3d plate_origin = cur_plate->get_origin(); - 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 + ArrangePolygon wipe_tower_ap; - 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)); + 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 @@ -2399,6 +2463,8 @@ int CLI::run(int argc, char **argv) } } else if (opt_key == "uptodate") { //already processed before + } else if (opt_key == "load_defaultfila") { + //already processed before } else if (opt_key == "mtcpp") { max_triangle_count_per_plate = m_config.option("mtcpp")->value; } else if (opt_key == "mstpp") { @@ -2444,15 +2510,6 @@ int CLI::run(int argc, char **argv) pre_check = false; bool finished = false; - //skip model object logic - if (need_skip) { - BOOST_LOG_TRIVIAL(info) << boost::format("need to skip objects, size %1%:")%skip_objects.size(); - for (int index = 0; index < skip_objects.size(); index++) - { - skip_maps[skip_objects[index]] = false; - BOOST_LOG_TRIVIAL(info) << boost::format("object %1%, id %2%")%index %skip_objects[index]; - } - } /*if (opt_key == "export_gcode" && printer_technology == ptSLA) { boost::nowide::cerr << "error: cannot export G-code for an FFF configuration" << std::endl; record_exit_reson(outfile_dir, 1, 0, cli_errors[1]); @@ -2540,7 +2597,7 @@ int CLI::run(int argc, char **argv) if (skip_maps.find(i->loaded_id) != skip_maps.end()) { skip_maps[i->loaded_id] = true; i->printable = false; - if (i->print_volume_state == ModelInstancePVS_Inside) { + if (i->print_volume_state == ModelInstancePVS_Inside || need_arrange) { skipped_count++; plate_has_skips[index] = true; plate_skipped_objects[index].emplace_back(i->loaded_id); @@ -3387,7 +3444,9 @@ int CLI::run(int argc, char **argv) //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); + std::map key_values; + key_values["sliced_count"] = std::to_string(real_duplicate_count); + record_exit_reson(outfile_dir, 0, plate_to_slice, cli_errors[0], key_values); } else record_exit_reson(outfile_dir, 0, plate_to_slice, cli_errors[0]); diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index d06210733..1e20604e0 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -4945,6 +4945,12 @@ CLIActionsConfigDef::CLIActionsConfigDef() def->cli = "uptodate"; def->set_default_value(new ConfigOptionBool(false)); + def = this->add("load_defaultfila", coBool); + def->label = L("Load default filaments"); + def->tooltip = L("Load first filament as default for those not loaded"); + def->cli_params = "option"; + def->set_default_value(new ConfigOptionBool(false)); + def = this->add("mtcpp", coInt); def->label = L("mtcpp"); def->tooltip = L("max triangle count per plate for slicing."); diff --git a/src/slic3r/GUI/PartPlate.cpp b/src/slic3r/GUI/PartPlate.cpp index 2878c6269..391d37b4f 100644 --- a/src/slic3r/GUI/PartPlate.cpp +++ b/src/slic3r/GUI/PartPlate.cpp @@ -1450,6 +1450,11 @@ std::vector PartPlate::get_extruders_under_cli(bool conside_custom_gcode, D if ((obj_id >= 0) && (obj_id < m_model->objects.size())) { ModelObject* object = m_model->objects[obj_id]; + ModelInstance* instance = object->instances[instance_id]; + + if (!instance->printable) + continue; + for (ModelVolume* mv : object->volumes) { std::vector volume_extruders = mv->get_extruders(); plate_extruders.insert(plate_extruders.end(), volume_extruders.begin(), volume_extruders.end()); @@ -2104,7 +2109,7 @@ void PartPlate::translate_all_instance(Vec3d position) return; } -void PartPlate::duplicate_all_instance(unsigned int dup_count) +void PartPlate::duplicate_all_instance(unsigned int dup_count, bool need_skip, std::map& skip_objects) { std::set> 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; @@ -2116,6 +2121,17 @@ void PartPlate::duplicate_all_instance(unsigned int dup_count) if ((obj_id >= 0) && (obj_id < m_model->objects.size())) { ModelObject* object = m_model->objects[obj_id]; + ModelInstance* instance = object->instances[instance_id]; + + if (need_skip) + { + if (skip_objects.find(instance->loaded_id) != skip_objects.end()) + { + instance->printable = false; + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": skipped object, loaded_id %1%, name %2%, set to unprintable, no need to duplicate") % instance->loaded_id % object->name; + continue; + } + } for (size_t index = 0; index < dup_count; index ++) { ModelObject* newObj = m_model->add_object(*object); diff --git a/src/slic3r/GUI/PartPlate.hpp b/src/slic3r/GUI/PartPlate.hpp index a176bc024..22fd7bf5e 100644 --- a/src/slic3r/GUI/PartPlate.hpp +++ b/src/slic3r/GUI/PartPlate.hpp @@ -319,7 +319,7 @@ public: void translate_all_instance(Vec3d position); //duplicate all instance for count - void duplicate_all_instance(unsigned int dup_count); + void duplicate_all_instance(unsigned int dup_count, bool need_skip, std::map& skip_objects); //update instance exclude state void update_instance_exclude_status(int obj_id, int instance_id, BoundingBoxf3* bounding_box = nullptr);