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);}
|
return(ret);}
|
||||||
#endif
|
#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__)
|
#if defined(__linux__) || defined(__LINUX__)
|
||||||
std::string result_file;
|
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["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)
|
for (auto& iter: key_values)
|
||||||
j["extra_param1"] = extra_param1;
|
j[iter.first] = iter.second;
|
||||||
|
|
||||||
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);
|
||||||
|
@ -549,7 +549,7 @@ int CLI::run(int argc, char **argv)
|
||||||
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, real_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, 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;
|
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;
|
||||||
|
@ -573,6 +573,10 @@ int CLI::run(int argc, char **argv)
|
||||||
if (uptodate_option)
|
if (uptodate_option)
|
||||||
up_config_to_date = uptodate_option->value;
|
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");
|
ConfigOptionString* pipe_option = m_config.option<ConfigOptionString>("pipe");
|
||||||
if (pipe_option) {
|
if (pipe_option) {
|
||||||
pipe_name = pipe_option->value;
|
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)
|
/*for (const std::string& file : m_input_files)
|
||||||
if (is_gcode_file(file) && boost::filesystem::exists(file)) {
|
if (is_gcode_file(file) && boost::filesystem::exists(file)) {
|
||||||
start_as_gcodeviewer = true;
|
start_as_gcodeviewer = true;
|
||||||
BOOST_LOG_TRIVIAL(info) << "found a gcode file:" << file << ", will start as gcode viewer\n";
|
BOOST_LOG_TRIVIAL(info) << "found a gcode file:" << file << ", will start as gcode viewer\n";
|
||||||
break;
|
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) {
|
//if (!start_as_gcodeviewer) {
|
||||||
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)) {
|
||||||
|
@ -878,6 +892,41 @@ int CLI::run(int argc, char **argv)
|
||||||
std::vector<std::string> load_filaments_id;
|
std::vector<std::string> load_filaments_id;
|
||||||
std::vector<std::string> load_filaments_name;
|
std::vector<std::string> load_filaments_name;
|
||||||
int current_index = 0;
|
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++) {
|
for (int index = 0; index < load_filament_count; index++) {
|
||||||
const std::string& file = load_filaments[index];
|
const std::string& file = load_filaments[index];
|
||||||
current_index++;
|
current_index++;
|
||||||
|
@ -891,7 +940,7 @@ int CLI::run(int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
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_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]);
|
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);
|
||||||
}
|
}
|
||||||
|
@ -901,7 +950,7 @@ int CLI::run(int argc, char **argv)
|
||||||
printer_technology = other_printer_technology;
|
printer_technology = other_printer_technology;
|
||||||
}
|
}
|
||||||
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_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]);
|
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);
|
||||||
}
|
}
|
||||||
|
@ -911,6 +960,13 @@ int CLI::run(int argc, char **argv)
|
||||||
load_filaments_index.push_back(current_index);
|
load_filaments_index.push_back(current_index);
|
||||||
}
|
}
|
||||||
else {
|
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;
|
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";
|
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);
|
Slic3r::GUI::PartPlate* cur_plate = (Slic3r::GUI::PartPlate *)partplate_list.get_plate(plate_to_slice-1);
|
||||||
//copy model objects and instances on plate
|
//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;
|
need_arrange = true;
|
||||||
duplicate_count = repetitions_count - 1;
|
duplicate_count = repetitions_count - 1;
|
||||||
|
@ -2112,44 +2168,52 @@ int CLI::run(int argc, char **argv)
|
||||||
float a = dynamic_cast<const ConfigOptionFloat *>(m_print_config.option("wipe_tower_rotation_angle"))->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;
|
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();
|
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
|
// slice filaments info invalid
|
||||||
std::vector<int> extruders = cur_plate->get_extruders_under_cli(true, m_print_config);
|
std::vector<int> extruders = cur_plate->get_extruders_under_cli(true, m_print_config);
|
||||||
filaments_cnt = extruders.size();
|
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%")
|
float depth = v * (filaments_cnt - 1) / (layer_height * w);
|
||||||
%x %y %w %depth %a %v %filaments_cnt %layer_height;
|
|
||||||
|
|
||||||
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({
|
ArrangePolygon wipe_tower_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);
|
Polygon ap({
|
||||||
wipe_tower_ap.translation = {scaled(0.f), scaled(0.f)};
|
{scaled(x), scaled(y)},
|
||||||
wipe_tower_ap.rotation = a;
|
{scaled(x + w), scaled(y)},
|
||||||
wipe_tower_ap.name = "WipeTower";
|
{scaled(x + w), scaled(y + depth)},
|
||||||
wipe_tower_ap.is_virt_object = true;
|
{scaled(x), scaled(y + depth)}
|
||||||
wipe_tower_ap.is_wipe_tower = true;
|
});
|
||||||
++wipe_tower_ap.priority;
|
wipe_tower_ap.bed_idx = 0;
|
||||||
unselected.emplace_back(std::move(wipe_tower_ap));
|
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
|
// 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") {
|
} else if (opt_key == "uptodate") {
|
||||||
//already processed before
|
//already processed before
|
||||||
|
} else if (opt_key == "load_defaultfila") {
|
||||||
|
//already processed before
|
||||||
} else if (opt_key == "mtcpp") {
|
} else if (opt_key == "mtcpp") {
|
||||||
max_triangle_count_per_plate = m_config.option<ConfigOptionInt>("mtcpp")->value;
|
max_triangle_count_per_plate = m_config.option<ConfigOptionInt>("mtcpp")->value;
|
||||||
} else if (opt_key == "mstpp") {
|
} else if (opt_key == "mstpp") {
|
||||||
|
@ -2444,15 +2510,6 @@ int CLI::run(int argc, char **argv)
|
||||||
pre_check = false;
|
pre_check = false;
|
||||||
bool finished = 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) {
|
/*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_exit_reson(outfile_dir, 1, 0, cli_errors[1]);
|
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()) {
|
if (skip_maps.find(i->loaded_id) != skip_maps.end()) {
|
||||||
skip_maps[i->loaded_id] = true;
|
skip_maps[i->loaded_id] = true;
|
||||||
i->printable = false;
|
i->printable = false;
|
||||||
if (i->print_volume_state == ModelInstancePVS_Inside) {
|
if (i->print_volume_state == ModelInstancePVS_Inside || need_arrange) {
|
||||||
skipped_count++;
|
skipped_count++;
|
||||||
plate_has_skips[index] = true;
|
plate_has_skips[index] = true;
|
||||||
plate_skipped_objects[index].emplace_back(i->loaded_id);
|
plate_skipped_objects[index].emplace_back(i->loaded_id);
|
||||||
|
@ -3387,7 +3444,9 @@ int CLI::run(int argc, char **argv)
|
||||||
//record the duplicate here
|
//record the duplicate here
|
||||||
if ((duplicate_count > 0) && duplicate_single_object)
|
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
|
else
|
||||||
record_exit_reson(outfile_dir, 0, plate_to_slice, cli_errors[0]);
|
record_exit_reson(outfile_dir, 0, plate_to_slice, cli_errors[0]);
|
||||||
|
|
|
@ -4945,6 +4945,12 @@ CLIActionsConfigDef::CLIActionsConfigDef()
|
||||||
def->cli = "uptodate";
|
def->cli = "uptodate";
|
||||||
def->set_default_value(new ConfigOptionBool(false));
|
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 = this->add("mtcpp", coInt);
|
||||||
def->label = L("mtcpp");
|
def->label = L("mtcpp");
|
||||||
def->tooltip = L("max triangle count per plate for slicing.");
|
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()))
|
if ((obj_id >= 0) && (obj_id < m_model->objects.size()))
|
||||||
{
|
{
|
||||||
ModelObject* object = m_model->objects[obj_id];
|
ModelObject* object = m_model->objects[obj_id];
|
||||||
|
ModelInstance* instance = object->instances[instance_id];
|
||||||
|
|
||||||
|
if (!instance->printable)
|
||||||
|
continue;
|
||||||
|
|
||||||
for (ModelVolume* mv : object->volumes) {
|
for (ModelVolume* mv : object->volumes) {
|
||||||
std::vector<int> volume_extruders = mv->get_extruders();
|
std::vector<int> volume_extruders = mv->get_extruders();
|
||||||
plate_extruders.insert(plate_extruders.end(), volume_extruders.begin(), volume_extruders.end());
|
plate_extruders.insert(plate_extruders.end(), volume_extruders.begin(), volume_extruders.end());
|
||||||
|
@ -2104,7 +2109,7 @@ void PartPlate::translate_all_instance(Vec3d position)
|
||||||
return;
|
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;
|
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;
|
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()))
|
if ((obj_id >= 0) && (obj_id < m_model->objects.size()))
|
||||||
{
|
{
|
||||||
ModelObject* object = m_model->objects[obj_id];
|
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 ++)
|
for (size_t index = 0; index < dup_count; index ++)
|
||||||
{
|
{
|
||||||
ModelObject* newObj = m_model->add_object(*object);
|
ModelObject* newObj = m_model->add_object(*object);
|
||||||
|
|
|
@ -319,7 +319,7 @@ public:
|
||||||
void translate_all_instance(Vec3d position);
|
void translate_all_instance(Vec3d position);
|
||||||
|
|
||||||
//duplicate all instance for count
|
//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
|
//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);
|
||||||
|
|
Loading…
Reference in New Issue