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
This commit is contained in:
parent
09c94acfcf
commit
0c45cac1a8
|
@ -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<std::string, std::string> key_values = std::map<std::string, std::string>())
|
||||
{
|
||||
#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<size_t, bool> orients_requirement;
|
||||
std::vector<Preset*> 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<ConfigOptionBool>("load_defaultfila");
|
||||
if (load_defaultfila_option)
|
||||
use_first_fila_as_default = load_defaultfila_option->value;
|
||||
|
||||
ConfigOptionString* pipe_option = m_config.option<ConfigOptionString>("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<std::string> load_filaments_id;
|
||||
std::vector<std::string> 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 " <<printer_technology<<", from filament file "<< file <<std::endl;
|
||||
BOOST_LOG_TRIVIAL(error) << "invalid printer_technology " <<printer_technology<<", from filament file "<< file;
|
||||
record_exit_reson(outfile_dir, CLI_INVALID_PRINTER_TECH, 0, cli_errors[CLI_INVALID_PRINTER_TECH]);
|
||||
flush_and_exit(CLI_INVALID_PRINTER_TECH);
|
||||
}
|
||||
|
@ -911,6 +960,13 @@ int CLI::run(int argc, char **argv)
|
|||
load_filaments_index.push_back(current_index);
|
||||
}
|
||||
else {
|
||||
if (use_first_fila_as_default) {
|
||||
BOOST_LOG_TRIVIAL(info)<<__FUNCTION__ << boost::format(": load filament %1% from default, config name %2%, filament_id %3%, current_index %4%") % (index+1) % default_load_fila_name %default_load_fila_id %current_index;
|
||||
load_filaments_id.push_back(default_load_fila_id);
|
||||
load_filaments_name.push_back(default_load_fila_name);
|
||||
load_filaments_config.push_back(default_load_fila_config);
|
||||
load_filaments_index.push_back(current_index);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -1758,7 +1814,7 @@ int CLI::run(int argc, char **argv)
|
|||
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);
|
||||
cur_plate->duplicate_all_instance(repetitions_count-1, need_skip, skip_maps);
|
||||
|
||||
need_arrange = true;
|
||||
duplicate_count = repetitions_count - 1;
|
||||
|
@ -2112,13 +2168,20 @@ int CLI::run(int argc, char **argv)
|
|||
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)
|
||||
if ((filaments_cnt == 0) || need_skip)
|
||||
{
|
||||
// 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;
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": slice filaments info invalid or need_skip, get from partplate: filament_count %1%")%filaments_cnt;
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -2126,7 +2189,7 @@ int CLI::run(int argc, char **argv)
|
|||
|
||||
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%")
|
||||
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();
|
||||
|
@ -2151,6 +2214,7 @@ int CLI::run(int argc, char **argv)
|
|||
++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);
|
||||
|
@ -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<ConfigOptionInt>("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<std::string, std::string> 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]);
|
||||
|
|
|
@ -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.");
|
||||
|
|
|
@ -1450,6 +1450,11 @@ std::vector<int> 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<int> 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<int, bool>& skip_objects)
|
||||
{
|
||||
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;
|
||||
|
@ -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);
|
||||
|
|
|
@ -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<int, bool>& skip_objects);
|
||||
|
||||
//update instance exclude state
|
||||
void update_instance_exclude_status(int obj_id, int instance_id, BoundingBoxf3* bounding_box = nullptr);
|
||||
|
|
Loading…
Reference in New Issue