mirror of
https://git.mirrors.martin98.com/https://github.com/bambulab/BambuStudio.git
synced 2025-08-08 13:58:58 +08:00
ENH: CLI: add logic for backward compatible check
1. add logic for backward compatible check 2. add export_stls JIRA: no-jira Change-Id: If96ab225b9689e588fae7443e81a73d0872f7eb4 (cherry picked from commit db12cca05c8f60fdc717387253215e361ab29851)
This commit is contained in:
parent
ebe5392932
commit
9b19dc9edd
@ -161,6 +161,8 @@ typedef struct _sliced_info {
|
||||
std::vector<sliced_plate_info_t> sliced_plates;
|
||||
size_t prepare_time;
|
||||
size_t export_time;
|
||||
std::vector<std::string> upward_machines;
|
||||
std::vector<std::string> downward_machines;
|
||||
}sliced_info_t;
|
||||
std::vector<PrintBase::SlicingStatus> g_slicing_warnings;
|
||||
|
||||
@ -409,6 +411,10 @@ void record_exit_reson(std::string outputdir, int code, int plate_id, std::strin
|
||||
try {
|
||||
json j;
|
||||
//record the headers
|
||||
if (sliced_info.downward_machines.size() > 0)
|
||||
j["downward_compatible_machine"] = sliced_info.downward_machines;
|
||||
if (sliced_info.upward_machines.size() > 0)
|
||||
j["upward_compatible_machine"] = sliced_info.upward_machines;
|
||||
j["plate_index"] = plate_id;
|
||||
j["return_code"] = code;
|
||||
j["error_string"] = error_message;
|
||||
@ -979,8 +985,6 @@ int CLI::run(int argc, char **argv)
|
||||
|
||||
PrinterTechnology printer_technology = get_printer_technology(m_config);
|
||||
|
||||
bool start_gui = m_actions.empty();
|
||||
|
||||
//BBS: remove GCodeViewer as seperate APP logic
|
||||
/*bool start_as_gcodeviewer =
|
||||
#ifdef _WIN32
|
||||
@ -990,8 +994,8 @@ int CLI::run(int argc, char **argv)
|
||||
boost::algorithm::iends_with(boost::filesystem::path(argv[0]).filename().string(), "gcodeviewer");
|
||||
#endif // _WIN32*/
|
||||
|
||||
bool translate_old = false, regenerate_thumbnails = false, shrink_to_new_bed = false, filament_color_changed = false;
|
||||
int current_printable_width, current_printable_depth, current_printable_height;
|
||||
bool translate_old = false, regenerate_thumbnails = false, filament_color_changed = false;
|
||||
int current_printable_width, current_printable_depth, current_printable_height, shrink_to_new_bed = 0;
|
||||
int old_printable_height = 0, old_printable_width = 0, old_printable_depth = 0;
|
||||
Pointfs old_printable_area, old_exclude_area;
|
||||
float old_max_radius = 0.f, old_height_to_rod = 0.f, old_height_to_lid = 0.f;
|
||||
@ -1000,6 +1004,8 @@ int CLI::run(int argc, char **argv)
|
||||
const std::vector<std::string> &load_configs = m_config.option<ConfigOptionStrings>("load_settings", true)->values;
|
||||
const std::vector<std::string> &uptodate_configs = m_config.option<ConfigOptionStrings>("uptodate_settings", true)->values;
|
||||
const std::vector<std::string> &uptodate_filaments = m_config.option<ConfigOptionStrings>("uptodate_filaments", true)->values;
|
||||
const std::vector<std::string> &downward_check = m_config.option<ConfigOptionStrings>("downward_check", true)->values;
|
||||
std::vector<std::string> downward_compatible_machines;
|
||||
//BBS: always use ForwardCompatibilitySubstitutionRule::Enable
|
||||
//const ForwardCompatibilitySubstitutionRule config_substitution_rule = m_config.option<ConfigOptionEnum<ForwardCompatibilitySubstitutionRule>>("config_compatibility", true)->value;
|
||||
const ForwardCompatibilitySubstitutionRule config_substitution_rule = ForwardCompatibilitySubstitutionRule::Enable;
|
||||
@ -1012,6 +1018,7 @@ int CLI::run(int argc, char **argv)
|
||||
sliced_info_t sliced_info;
|
||||
std::map<std::string, std::string> record_key_values;
|
||||
|
||||
bool start_gui = m_actions.empty() && downward_check.empty();
|
||||
if (start_gui) {
|
||||
BOOST_LOG_TRIVIAL(info) << "no action, start gui directly" << std::endl;
|
||||
::Label::initSysFont();
|
||||
@ -1080,6 +1087,7 @@ int CLI::run(int argc, char **argv)
|
||||
|
||||
//BBS: add plate data related logic
|
||||
PlateDataPtrs plate_data_src;
|
||||
std::vector<plate_obj_size_info_t> plate_obj_size_infos;
|
||||
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, use_first_fila_as_default = false, minimum_save = false, enable_timelapse = false;
|
||||
@ -2100,7 +2108,7 @@ int CLI::run(int argc, char **argv)
|
||||
}
|
||||
|
||||
//upwards check
|
||||
bool process_compatible = false, machine_upwards = false;
|
||||
bool process_compatible = false, machine_upwards = false, machine_switch = false;
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("current printer %1%, new printer %2%, current process %3%, new process %4%")%current_printer_name %new_printer_name %current_process_name %new_process_name;
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("current printer inherits %1%, new printer inherits %2%, current process inherits %3%, new process inherits %4%")
|
||||
%current_printer_system_name %new_printer_system_name %current_process_system_name %new_process_system_name;
|
||||
@ -2162,11 +2170,16 @@ int CLI::run(int argc, char **argv)
|
||||
%current_printer_name %current_printer_system_name %current_process_name %current_process_system_name %process_compatible;
|
||||
}
|
||||
if (!process_compatible && !new_printer_name.empty() && !current_printer_name.empty() && (new_printer_name != current_printer_name)) {
|
||||
//set all printer to compatible
|
||||
process_compatible = true;
|
||||
machine_switch = true;
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("switch to new printers, set to compatible");
|
||||
if (upward_compatible_printers.size() > 0) {
|
||||
for (int index = 0; index < upward_compatible_printers.size(); index++) {
|
||||
if (upward_compatible_printers[index] == new_printer_system_name) {
|
||||
process_compatible = true;
|
||||
machine_upwards = true;
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("new printer is upward_compatible");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -2176,11 +2189,11 @@ int CLI::run(int argc, char **argv)
|
||||
flush_and_exit(CLI_3MF_NEW_MACHINE_NOT_SUPPORTED);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/*else {
|
||||
BOOST_LOG_TRIVIAL(error) <<__FUNCTION__ << boost::format(" %1%: current 3mf file not support upward_compatible_printers, can not change machine preset.")%__LINE__;
|
||||
record_exit_reson(outfile_dir, CLI_3MF_NOT_SUPPORT_MACHINE_CHANGE, 0, cli_errors[CLI_3MF_NOT_SUPPORT_MACHINE_CHANGE], sliced_info);
|
||||
flush_and_exit(CLI_3MF_NOT_SUPPORT_MACHINE_CHANGE);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
if (!process_compatible) {
|
||||
@ -2188,10 +2201,11 @@ int CLI::run(int argc, char **argv)
|
||||
record_exit_reson(outfile_dir, CLI_PROCESS_NOT_COMPATIBLE, 0, cli_errors[CLI_PROCESS_NOT_COMPATIBLE], sliced_info);
|
||||
flush_and_exit(CLI_PROCESS_NOT_COMPATIBLE);
|
||||
}
|
||||
sliced_info.upward_machines = upward_compatible_printers;
|
||||
|
||||
//create project embedded preset if needed
|
||||
Preset *new_preset = NULL;
|
||||
if (is_bbl_3mf && machine_upwards) {
|
||||
if (is_bbl_3mf && machine_switch) {
|
||||
//we need to update the compatible printer and create a new process here, or if we load the 3mf in studio, the process preset can not be loaded as not compatible
|
||||
Preset *current_preset = NULL;
|
||||
size_t project_presets_count = project_presets.size();
|
||||
@ -2467,7 +2481,7 @@ int CLI::run(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
if (machine_upwards) {
|
||||
if (machine_switch) {
|
||||
print_compatible_printers.push_back(new_printer_system_name);
|
||||
|
||||
std::string old_setting = different_settings[0];
|
||||
@ -2852,134 +2866,6 @@ int CLI::run(int argc, char **argv)
|
||||
flush_and_exit(CLI_INVALID_VALUES_IN_3MF);
|
||||
}
|
||||
|
||||
//BBS: partplate list
|
||||
Slic3r::GUI::PartPlateList partplate_list(NULL, m_models.data(), printer_technology);
|
||||
//use Pointfs insteadof Points
|
||||
Pointfs current_printable_area = m_print_config.opt<ConfigOptionPoints>("printable_area")->values;
|
||||
Pointfs current_exclude_area = m_print_config.opt<ConfigOptionPoints>("bed_exclude_area")->values;
|
||||
//update part plate's size
|
||||
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_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;
|
||||
std::string bed_texture;
|
||||
|
||||
current_printable_width = current_printable_area[2].x() - current_printable_area[0].x();
|
||||
current_printable_depth = current_printable_area[2].y() - current_printable_area[0].y();
|
||||
current_printable_height = print_height;
|
||||
if (old_printable_width == 0)
|
||||
old_printable_width = current_printable_width;
|
||||
if (old_printable_depth == 0)
|
||||
old_printable_depth = current_printable_depth;
|
||||
if (old_printable_height == 0)
|
||||
old_printable_height = current_printable_height;
|
||||
if ((old_printable_width > 0)&&(old_printable_depth > 0)&&(old_printable_height > 0))
|
||||
{
|
||||
//check the printable size logic
|
||||
//if ((old_printable_width > current_printable_width) || (old_printable_depth > current_printable_depth) || (old_printable_height > current_printable_height))
|
||||
if ((old_printable_width > current_printable_width) || (old_printable_depth > current_printable_depth))
|
||||
{
|
||||
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;
|
||||
record_exit_reson(outfile_dir, CLI_PRINTABLE_SIZE_REDUCED, 0, cli_errors[CLI_PRINTABLE_SIZE_REDUCED], sliced_info);
|
||||
flush_and_exit(CLI_PRINTABLE_SIZE_REDUCED);
|
||||
}
|
||||
else if ((old_printable_width < current_printable_width) || (old_printable_depth < current_printable_depth))
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("old printable size {%1%, %2%, %3%} is smaller than new printable size {%4%, %5%, %6%}, need to center the model")
|
||||
%old_printable_width %old_printable_depth %old_printable_height %current_printable_width %current_printable_depth %current_printable_height;
|
||||
shrink_to_new_bed = true;
|
||||
}
|
||||
else {
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("old printable size {%1%, %2%, %3%}, new printable size {%4%, %5%, %6%}")
|
||||
%old_printable_width %old_printable_depth %old_printable_height %current_printable_width %current_printable_depth %current_printable_height;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_models.size() > 0)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("translate_old %1%, shrink_to_new_bed %2%, old bed size {%3%, %4%, %5%}")%translate_old%shrink_to_new_bed %old_printable_width %old_printable_depth %old_printable_height;
|
||||
if (translate_old) {
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("translate old 3mf, switch to older bed size,{%1%, %2%, %3%}")%(old_printable_width + bed3d_ax3s_default_tip_radius)%(old_printable_depth+bed3d_ax3s_default_tip_radius) %old_printable_height;
|
||||
partplate_list.reset_size(old_printable_width + bed3d_ax3s_default_tip_radius, old_printable_depth + bed3d_ax3s_default_tip_radius, old_printable_height, false);
|
||||
}
|
||||
else {
|
||||
partplate_list.reset_size(old_printable_width, old_printable_depth, old_printable_height, false);
|
||||
}
|
||||
partplate_list.set_shapes(current_printable_area, current_exclude_area, bed_texture, height_to_lid, height_to_rod);
|
||||
//plate_stride = partplate_list.plate_stride_x();
|
||||
}
|
||||
|
||||
auto translate_models = [translate_old, shrink_to_new_bed, old_printable_width, old_printable_depth, old_printable_height, current_printable_width, current_printable_depth, current_printable_height] (Slic3r::GUI::PartPlateList& plate_list, DynamicPrintConfig& print_config) {
|
||||
//BBS: translate old 3mf to correct positions
|
||||
if (translate_old) {
|
||||
//translate the objects
|
||||
int plate_count = plate_list.get_plate_count();
|
||||
for (int index = 1; index < plate_count; index ++) {
|
||||
Slic3r::GUI::PartPlate* cur_plate = (Slic3r::GUI::PartPlate *)plate_list.get_plate(index);
|
||||
|
||||
Vec3d cur_origin = cur_plate->get_origin();
|
||||
Vec3d new_origin = plate_list.compute_origin_using_new_size(index, old_printable_width, old_printable_depth);
|
||||
|
||||
cur_plate->translate_all_instance(new_origin - cur_origin);
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("translate old 3mf, switch back to current bed size,{%1%, %2%, %3%}")%old_printable_width %old_printable_depth %old_printable_height;
|
||||
plate_list.reset_size(old_printable_width, old_printable_depth, old_printable_height, true, true);
|
||||
}
|
||||
|
||||
if (shrink_to_new_bed)
|
||||
{
|
||||
int plate_count = plate_list.get_plate_count();
|
||||
ConfigOptionFloats *wipe_x_option = nullptr, *wipe_y_option = nullptr;
|
||||
Vec3d wipe_offset;
|
||||
if (print_config.has("wipe_tower_x")) {
|
||||
wipe_x_option = dynamic_cast<ConfigOptionFloats *>(print_config.option("wipe_tower_x"));
|
||||
wipe_y_option = dynamic_cast<ConfigOptionFloats *>(print_config.option("wipe_tower_y"));
|
||||
}
|
||||
for (int index = 0; index < plate_count; index ++) {
|
||||
Slic3r::GUI::PartPlate* cur_plate = (Slic3r::GUI::PartPlate *)plate_list.get_plate(index);
|
||||
|
||||
Vec3d cur_origin = cur_plate->get_origin();
|
||||
Vec3d new_origin = plate_list.compute_origin_using_new_size(index, current_printable_width, current_printable_depth);
|
||||
Vec3d cur_center_offset { ((double)old_printable_width)/2, ((double)old_printable_depth)/2, 0}, new_center_offset { ((double)current_printable_width)/2, ((double)current_printable_depth)/2, 0};
|
||||
Vec3d cur_center = cur_origin + cur_center_offset;
|
||||
Vec3d new_center = new_origin + new_center_offset;
|
||||
Vec3d offset = new_center - cur_center;
|
||||
|
||||
cur_plate->translate_all_instance(offset);
|
||||
if (index == 0)
|
||||
wipe_offset = offset;
|
||||
if (wipe_x_option) {
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("shrink_to_new_bed, plate %1%: wipe tower src: {%2%, %3%}")%(index+1) %wipe_x_option->get_at(index) %wipe_y_option->get_at(index);
|
||||
ConfigOptionFloat wipe_tower_x(wipe_x_option->get_at(index) + wipe_offset(0));
|
||||
ConfigOptionFloat wipe_tower_y(wipe_y_option->get_at(index) + wipe_offset(1));
|
||||
|
||||
wipe_x_option->set_at(&wipe_tower_x, index, 0);
|
||||
wipe_y_option->set_at(&wipe_tower_y, index, 0);
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("shrink_to_new_bed, plate %1% wipe tower changes to: {%2%, %3%}")%(index+1) %wipe_x_option->get_at(index) %wipe_y_option->get_at(index);
|
||||
}
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("shrink_to_new_bed, plate %1% translate offset: {%2%, %3%, %4%}")%(index+1) %offset[0] %offset[1] %offset[2];
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("shrink_to_new_bed, shrink all the models to current bed size,{%1%, %2%, %3%}")%current_printable_width %current_printable_depth %current_printable_height;
|
||||
plate_list.reset_size(current_printable_width, current_printable_depth, current_printable_height, true, true);
|
||||
}
|
||||
};
|
||||
if (plate_data_src.size() > 0)
|
||||
{
|
||||
partplate_list.load_from_3mf_structure(plate_data_src);
|
||||
|
||||
translate_models(partplate_list, m_print_config);
|
||||
}
|
||||
|
||||
/*for (ModelObject *model_object : m_models[0].objects)
|
||||
for (ModelInstance *model_instance : model_object->instances)
|
||||
{
|
||||
const Vec3d &instance_offset = model_instance->get_offset();
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("instance %1% transform {%2%,%3%,%4%} at %5%:%6%")% model_object->name % instance_offset.x() % instance_offset.y() %instance_offset.z() % __FUNCTION__ % __LINE__<< std::endl;
|
||||
}*/
|
||||
|
||||
auto timelapse_type_opt = m_print_config.option("timelapse_type");
|
||||
bool is_smooth_timelapse = false;
|
||||
if (enable_timelapse && timelapse_type_opt && (timelapse_type_opt->getInt() == TimelapseType::tlSmooth))
|
||||
@ -3015,6 +2901,366 @@ int CLI::run(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
//BBS: partplate list
|
||||
Slic3r::GUI::PartPlateList partplate_list(NULL, m_models.data(), printer_technology);
|
||||
//use Pointfs insteadof Points
|
||||
Pointfs current_printable_area = m_print_config.opt<ConfigOptionPoints>("printable_area")->values;
|
||||
Pointfs current_exclude_area = m_print_config.opt<ConfigOptionPoints>("bed_exclude_area")->values;
|
||||
//update part plate's size
|
||||
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_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;
|
||||
std::string bed_texture;
|
||||
|
||||
current_printable_width = current_printable_area[2].x() - current_printable_area[0].x();
|
||||
current_printable_depth = current_printable_area[2].y() - current_printable_area[0].y();
|
||||
current_printable_height = print_height;
|
||||
if (old_printable_width == 0)
|
||||
old_printable_width = current_printable_width;
|
||||
if (old_printable_depth == 0)
|
||||
old_printable_depth = current_printable_depth;
|
||||
if (old_printable_height == 0)
|
||||
old_printable_height = current_printable_height;
|
||||
if ((old_printable_width > 0)&&(old_printable_depth > 0)&&(old_printable_height > 0))
|
||||
{
|
||||
//check the printable size logic
|
||||
//if ((old_printable_width > current_printable_width) || (old_printable_depth > current_printable_depth) || (old_printable_height > current_printable_height))
|
||||
if ((old_printable_width > current_printable_width) || (old_printable_depth > current_printable_depth) || (old_printable_height > current_printable_height))
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(error) << boost::format("old printable size {%1%, %2%, %3%} is larger than new printable size {%4%, %5%, %6%}, the object size should be limited")
|
||||
%old_printable_width %old_printable_depth %old_printable_height %current_printable_width %current_printable_depth %current_printable_height;
|
||||
/*record_exit_reson(outfile_dir, CLI_PRINTABLE_SIZE_REDUCED, 0, cli_errors[CLI_PRINTABLE_SIZE_REDUCED], sliced_info);
|
||||
flush_and_exit(CLI_PRINTABLE_SIZE_REDUCED);*/
|
||||
shrink_to_new_bed = 2;
|
||||
}
|
||||
else if ((old_printable_width < current_printable_width) || (old_printable_depth < current_printable_depth))
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("old printable size {%1%, %2%, %3%} is smaller than new printable size {%4%, %5%, %6%}, need to center the model")
|
||||
%old_printable_width %old_printable_depth %old_printable_height %current_printable_width %current_printable_depth %current_printable_height;
|
||||
shrink_to_new_bed = 1;
|
||||
}
|
||||
else {
|
||||
if ((current_exclude_area.size() > 0)&&(current_exclude_area != old_exclude_area)) {
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("old printable size {%1%, %2%, %3%}, new printable size {%4%, %5%, %6%}, exclude_area different, need to shrink")
|
||||
%old_printable_width %old_printable_depth %old_printable_height %current_printable_width %current_printable_depth %current_printable_height;
|
||||
shrink_to_new_bed = 2;
|
||||
}
|
||||
else {
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("old printable size {%1%, %2%, %3%}, new printable size {%4%, %5%, %6%}, extract the same, no need shrink")
|
||||
%old_printable_width %old_printable_depth %old_printable_height %current_printable_width %current_printable_depth %current_printable_height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_models.size() > 0)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("translate_old %1%, shrink_to_new_bed %2%, old bed size {%3%, %4%, %5%}")%translate_old%shrink_to_new_bed %old_printable_width %old_printable_depth %old_printable_height;
|
||||
if (translate_old) {
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("translate old 3mf, switch to older bed size,{%1%, %2%, %3%}")%(old_printable_width + bed3d_ax3s_default_tip_radius)%(old_printable_depth+bed3d_ax3s_default_tip_radius) %old_printable_height;
|
||||
partplate_list.reset_size(old_printable_width + bed3d_ax3s_default_tip_radius, old_printable_depth + bed3d_ax3s_default_tip_radius, old_printable_height, false);
|
||||
}
|
||||
else {
|
||||
partplate_list.reset_size(old_printable_width, old_printable_depth, old_printable_height, false);
|
||||
}
|
||||
partplate_list.set_shapes(current_printable_area, current_exclude_area, bed_texture, height_to_lid, height_to_rod);
|
||||
//plate_stride = partplate_list.plate_stride_x();
|
||||
}
|
||||
|
||||
auto get_print_sequence = [](Slic3r::GUI::PartPlate* plate, DynamicPrintConfig& print_config, bool &is_seq_print) {
|
||||
PrintSequence curr_plate_seq = plate->get_print_seq();
|
||||
if (curr_plate_seq == PrintSequence::ByDefault) {
|
||||
auto seq_print = print_config.option<ConfigOptionEnum<PrintSequence>>("print_sequence");
|
||||
if (seq_print && (seq_print->value == PrintSequence::ByObject)) {
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("plate print by object, set from global");
|
||||
is_seq_print = true;
|
||||
}
|
||||
}
|
||||
else if (curr_plate_seq == PrintSequence::ByObject) {
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("plate print by object, set from plate self");
|
||||
is_seq_print = true;
|
||||
}
|
||||
};
|
||||
|
||||
auto check_plate_wipe_tower = [get_print_sequence, is_smooth_timelapse](Slic3r::GUI::PartPlate* plate, int plate_index, DynamicPrintConfig& print_config, plate_obj_size_info_t &plate_obj_size_info) {
|
||||
plate_obj_size_info.obj_bbox= plate->get_objects_bounding_box();
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("plate %1%, object bbox: min {%2%, %3%, %4%} - max {%5%, %6%, %7%}")
|
||||
%(plate_index+1) %plate_obj_size_info.obj_bbox.min.x() % plate_obj_size_info.obj_bbox.min.y() % plate_obj_size_info.obj_bbox.min.z() %plate_obj_size_info.obj_bbox.max.x() % plate_obj_size_info.obj_bbox.max.y() % plate_obj_size_info.obj_bbox.max.z();
|
||||
if (!print_config.has("wipe_tower_x")) {
|
||||
plate_obj_size_info.has_wipe_tower = false;
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("can not found wipe_tower_x in config, set to no wipe tower");
|
||||
return;
|
||||
}
|
||||
|
||||
int valid_count = plate->printable_instance_size();
|
||||
if (valid_count <= 0){
|
||||
plate_obj_size_info.has_wipe_tower = false;
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("no printable object found, set to no wipe tower");
|
||||
return;
|
||||
}
|
||||
|
||||
bool is_sequence = false;
|
||||
get_print_sequence(plate, print_config, is_sequence);
|
||||
if (is_sequence && valid_count > 1) {
|
||||
plate_obj_size_info.has_wipe_tower = false;
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("sequence print, valid_count=%1%, set to no wipe tower")%valid_count;
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<int> extruders = plate->get_extruders_under_cli(true, print_config);
|
||||
unsigned int filaments_cnt = extruders.size();
|
||||
if ((filaments_cnt <= 1) && !is_smooth_timelapse){
|
||||
plate_obj_size_info.has_wipe_tower = false;
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("filaments_cnt=%1%, set to no wipe tower")%filaments_cnt;
|
||||
return;
|
||||
}
|
||||
|
||||
ConfigOptionFloats *wipe_x_option = dynamic_cast<ConfigOptionFloats *>(print_config.option("wipe_tower_x"));
|
||||
ConfigOptionFloats *wipe_y_option = dynamic_cast<ConfigOptionFloats *>(print_config.option("wipe_tower_y"));
|
||||
|
||||
plate_obj_size_info.wipe_x = wipe_x_option->get_at(plate_index);
|
||||
plate_obj_size_info.wipe_y = wipe_y_option->get_at(plate_index);
|
||||
|
||||
ConfigOptionFloat* width_option = print_config.option<ConfigOptionFloat>("prime_tower_width", true);
|
||||
plate_obj_size_info.wipe_width = width_option->value;
|
||||
|
||||
ConfigOptionFloat* brim_width_option = print_config.option<ConfigOptionFloat>("prime_tower_brim_width", true);
|
||||
float brim_width = brim_width_option->value;
|
||||
|
||||
ConfigOptionFloat* volume_option = print_config.option<ConfigOptionFloat>("prime_volume", true);
|
||||
float wipe_volume = volume_option->value;
|
||||
|
||||
Vec3d wipe_tower_size = plate->estimate_wipe_tower_size(print_config, plate_obj_size_info.wipe_width, wipe_volume, filaments_cnt);
|
||||
plate_obj_size_info.wipe_depth = wipe_tower_size(1);
|
||||
|
||||
Vec3d origin = plate->get_origin();
|
||||
Vec3d start(origin(0) + plate_obj_size_info.wipe_x - brim_width, origin(1) + plate_obj_size_info.wipe_y, 0.f);
|
||||
plate_obj_size_info.obj_bbox.merge(start);
|
||||
Vec3d end(origin(0) + plate_obj_size_info.wipe_x + plate_obj_size_info.wipe_width + brim_width, origin(1) + plate_obj_size_info.wipe_y + plate_obj_size_info.wipe_depth, 0.f);
|
||||
plate_obj_size_info.obj_bbox.merge(end);
|
||||
plate_obj_size_info.has_wipe_tower = true;
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("plate %1%, has wipe tower, wipe bbox: min {%2%, %3%, %4%} - max {%5%, %6%, %7%}")
|
||||
%(plate_index+1) %start.x() % start.y() % start.z() %end.x() % end.y() % end.z();
|
||||
};
|
||||
|
||||
auto translate_models = [translate_old, shrink_to_new_bed, old_printable_width, old_printable_depth, old_printable_height, current_printable_width, current_printable_depth, current_printable_height, current_exclude_area, &plate_obj_size_infos] (Slic3r::GUI::PartPlateList& plate_list, DynamicPrintConfig& print_config) {
|
||||
//BBS: translate old 3mf to correct positions
|
||||
if (translate_old) {
|
||||
//translate the objects
|
||||
int plate_count = plate_list.get_plate_count();
|
||||
for (int index = 1; index < plate_count; index ++) {
|
||||
Slic3r::GUI::PartPlate* cur_plate = (Slic3r::GUI::PartPlate *)plate_list.get_plate(index);
|
||||
|
||||
Vec3d cur_origin = cur_plate->get_origin();
|
||||
Vec3d new_origin = plate_list.compute_origin_using_new_size(index, old_printable_width, old_printable_depth);
|
||||
|
||||
cur_plate->translate_all_instance(new_origin - cur_origin);
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("translate old 3mf, switch back to current bed size,{%1%, %2%, %3%}")%old_printable_width %old_printable_depth %old_printable_height;
|
||||
plate_list.reset_size(old_printable_width, old_printable_depth, old_printable_height, true, true);
|
||||
}
|
||||
|
||||
if (shrink_to_new_bed > 0)
|
||||
{
|
||||
int plate_count = plate_list.get_plate_count();
|
||||
ConfigOptionFloats *wipe_x_option = nullptr, *wipe_y_option = nullptr;
|
||||
Vec3d wipe_offset;
|
||||
if (print_config.has("wipe_tower_x")) {
|
||||
wipe_x_option = dynamic_cast<ConfigOptionFloats *>(print_config.option("wipe_tower_x"));
|
||||
wipe_y_option = dynamic_cast<ConfigOptionFloats *>(print_config.option("wipe_tower_y"));
|
||||
}
|
||||
double exclude_width = 0.f, exclude_depth = 0.f;
|
||||
|
||||
if (current_exclude_area.size() >= 4) {
|
||||
exclude_width = current_exclude_area[2].x() - current_exclude_area[0].x();
|
||||
exclude_depth = current_exclude_area[2].y() - current_exclude_area[0].y();
|
||||
}
|
||||
for (int index = 0; index < plate_count; index ++) {
|
||||
Slic3r::GUI::PartPlate* cur_plate = (Slic3r::GUI::PartPlate *)plate_list.get_plate(index);
|
||||
Vec3d cur_origin = cur_plate->get_origin();
|
||||
Vec3d new_origin = plate_list.compute_origin_using_new_size(index, current_printable_width, current_printable_depth);
|
||||
Vec3d offset;
|
||||
|
||||
|
||||
if (shrink_to_new_bed == 1) {
|
||||
Vec3d cur_center_offset { ((double)old_printable_width)/2, ((double)old_printable_depth)/2, 0}, new_center_offset { ((double)current_printable_width)/2, ((double)current_printable_depth)/2, 0};
|
||||
Vec3d cur_center = cur_origin + cur_center_offset;
|
||||
Vec3d new_center = new_origin + new_center_offset;
|
||||
|
||||
offset = new_center - cur_center;
|
||||
|
||||
if (index == 0)
|
||||
wipe_offset = offset;
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("shrink_to_new_bed 1, plate %1%, cur_origin: {%2%, %3%}, new_origin: {%4%, %5%}, cur_center {%6%, %7%} new_center {%8%, %9%}")
|
||||
%(index+1) %cur_origin(0) %cur_origin(1) %new_origin(0) %new_origin(1) %cur_center(0) %cur_center(1) %new_center(0) %new_center(1);
|
||||
}
|
||||
else {
|
||||
//center the object
|
||||
Vec3d new_center_offset { ((double)current_printable_width + exclude_width)/2, ((double)current_printable_depth + exclude_depth)/2, 0};
|
||||
BoundingBoxf3& bbox = plate_obj_size_infos[index].obj_bbox;
|
||||
Vec3d size = bbox.size();
|
||||
if (size.x() > (current_printable_width - exclude_width))
|
||||
new_center_offset(0) = ((double)current_printable_width)/2;
|
||||
if (size.y() > (current_printable_depth - exclude_depth))
|
||||
new_center_offset(1) = ((double)current_printable_depth)/2;
|
||||
Vec3d new_center = new_origin + new_center_offset;
|
||||
|
||||
offset = new_center - bbox.center();
|
||||
|
||||
wipe_offset = offset + cur_origin - new_origin;
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("shrink_to_new_bed 2, plate %1%, new_origin: {%2%, %3%}, new_center: {%4%, %5%}, obj bbox(including wipe tower) min {%6%, %7%} max {%8%, %9%}")
|
||||
%(index+1) %new_origin(0) %new_origin(1) %new_center(0) %new_center(1) %bbox.min(0) %bbox.min(1) %bbox.max(0) %bbox.max(1);
|
||||
}
|
||||
offset(2) = 0.f;
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("shrink_to_new_bed %1%, plate %2% translate offset: {%3%, %4%} wipe_offset {%5%, %6%}") %shrink_to_new_bed %(index+1) %offset[0] %offset[1] %wipe_offset[0] %wipe_offset[1];
|
||||
cur_plate->translate_all_instance(offset);
|
||||
|
||||
if (wipe_x_option) {
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("shrink_to_new_bed %4%, plate %1%: wipe tower src: {%2%, %3%}")%(index+1) %wipe_x_option->get_at(index) %wipe_y_option->get_at(index)%shrink_to_new_bed;
|
||||
ConfigOptionFloat wipe_tower_x(wipe_x_option->get_at(index) + wipe_offset(0));
|
||||
ConfigOptionFloat wipe_tower_y(wipe_y_option->get_at(index) + wipe_offset(1));
|
||||
|
||||
wipe_x_option->set_at(&wipe_tower_x, index, 0);
|
||||
wipe_y_option->set_at(&wipe_tower_y, index, 0);
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("shrink_to_new_bed %4%, plate %1% wipe tower changes to: {%2%, %3%}")%(index+1) %wipe_x_option->get_at(index) %wipe_y_option->get_at(index) %shrink_to_new_bed;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("shrink_to_new_bed, shrink all the models to current bed size,{%1%, %2%, %3%}")%current_printable_width %current_printable_depth %current_printable_height;
|
||||
plate_list.reset_size(current_printable_width, current_printable_depth, current_printable_height, true, true);
|
||||
}
|
||||
};
|
||||
if (plate_data_src.size() > 0)
|
||||
{
|
||||
partplate_list.load_from_3mf_structure(plate_data_src);
|
||||
|
||||
int plate_count = partplate_list.get_plate_count();
|
||||
plate_obj_size_infos.resize(plate_count, plate_obj_size_info_t());
|
||||
for (int index = 0; index < plate_count; index ++) {
|
||||
Slic3r::GUI::PartPlate* cur_plate = (Slic3r::GUI::PartPlate *)partplate_list.get_plate(index);
|
||||
|
||||
check_plate_wipe_tower(cur_plate, index, m_print_config, plate_obj_size_infos[index]);
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("plate %1%, has_wipe_tower %2%, wipe_x %3%, wipe_y %4%, width %5%, depth %6%")
|
||||
%(index+1) %plate_obj_size_infos[index].has_wipe_tower %plate_obj_size_infos[index].wipe_x %plate_obj_size_infos[index].wipe_y %plate_obj_size_infos[index].wipe_width %plate_obj_size_infos[index].wipe_depth;
|
||||
}
|
||||
|
||||
translate_models(partplate_list, m_print_config);
|
||||
}
|
||||
|
||||
/*for (ModelObject *model_object : m_models[0].objects)
|
||||
for (ModelInstance *model_instance : model_object->instances)
|
||||
{
|
||||
const Vec3d &instance_offset = model_instance->get_offset();
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("instance %1% transform {%2%,%3%,%4%} at %5%:%6%")% model_object->name % instance_offset.x() % instance_offset.y() %instance_offset.z() % __FUNCTION__ % __LINE__<< std::endl;
|
||||
}*/
|
||||
|
||||
//doing downward_check
|
||||
std::vector<printer_plate_info_t> downward_check_printers;
|
||||
std::vector<bool> downward_check_status;
|
||||
for (auto const &file : downward_check) {
|
||||
DynamicPrintConfig config;
|
||||
std::string config_type, config_name, filament_id, config_from, downward_printer;
|
||||
int ret = load_config_file(file, config, config_type, config_name, filament_id, config_from);
|
||||
if (ret) {
|
||||
record_exit_reson(outfile_dir, ret, 0, cli_errors[ret], sliced_info);
|
||||
flush_and_exit(ret);
|
||||
}
|
||||
if ((config_type != "machine") || (config_from != "system")) {
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("found invalid config type %1% or from %2% in file %3% when downward_check")%config_type %config_from %file;
|
||||
record_exit_reson(outfile_dir, ret, 0, cli_errors[CLI_CONFIG_FILE_ERROR], sliced_info);
|
||||
flush_and_exit(ret);
|
||||
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("downward_check: loaded machine config %1%, from %2%")%config_name %file ;
|
||||
|
||||
printer_plate_info_t printer_plate;
|
||||
Pointfs temp_printable_area, temp_exclude_area;
|
||||
|
||||
printer_plate.printer_name = config_name;
|
||||
|
||||
temp_printable_area = config.option<ConfigOptionPoints>("printable_area", true)->values;
|
||||
temp_exclude_area = config.option<ConfigOptionPoints>("bed_exclude_area", true)->values;
|
||||
if (temp_printable_area.size() >= 4) {
|
||||
printer_plate.printable_width = (int)(temp_printable_area[2].x() - temp_printable_area[0].x());
|
||||
printer_plate.printable_depth = (int)(temp_printable_area[2].y() - temp_printable_area[0].y());
|
||||
printer_plate.printable_height = (int)(config.opt_float("printable_height"));
|
||||
}
|
||||
if (temp_exclude_area.size() >= 4) {
|
||||
printer_plate.exclude_width = (int)(temp_exclude_area[2].x() - temp_exclude_area[0].x());
|
||||
printer_plate.exclude_depth = (int)(temp_exclude_area[2].y() - temp_exclude_area[0].y());
|
||||
printer_plate.exclude_x = (int)temp_exclude_area[0].x();
|
||||
printer_plate.exclude_y = (int)temp_exclude_area[0].y();
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("downward_check: printable size{%1%,%2%, %3%}, exclude area{%4%, %5%: %6% x %7%}")
|
||||
%printer_plate.printable_width %printer_plate.printable_depth %printer_plate.printable_height
|
||||
%printer_plate.exclude_x %printer_plate.exclude_y %printer_plate.exclude_width %printer_plate.exclude_depth;
|
||||
downward_check_printers.push_back(std::move(printer_plate));
|
||||
}
|
||||
|
||||
int downward_check_size = downward_check_printers.size();
|
||||
if (downward_check_size > 0)
|
||||
{
|
||||
downward_check_status.resize(downward_check_size, false);
|
||||
int plate_count = partplate_list.get_plate_count();
|
||||
int failed_count = 0;
|
||||
for (int index = 0; index < plate_count; index ++)
|
||||
{
|
||||
if (failed_count == downward_check_size) {
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("downward_check: all failed, size %1%")%downward_check_size;
|
||||
break;
|
||||
}
|
||||
Slic3r::GUI::PartPlate* cur_plate = (Slic3r::GUI::PartPlate *)partplate_list.get_plate(index);
|
||||
Vec3d size = plate_obj_size_infos[index].obj_bbox.size();
|
||||
|
||||
for (int index2 = 0; index2 < downward_check_size; index2 ++)
|
||||
{
|
||||
if (failed_count == downward_check_size) {
|
||||
break;
|
||||
}
|
||||
if (downward_check_status[index2])
|
||||
continue;
|
||||
printer_plate_info_t& plate_info = downward_check_printers[index2];
|
||||
if ((size.z() > plate_info.printable_height) || (size.y() > plate_info.printable_depth) || (size.x() > plate_info.printable_width)) {
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("plate %1%, downward_check index %2%, name %3%, bbox {%4%, %5%, %6%} exceeds printer size {%7%, %8%, %9%}")
|
||||
%(index+1) %(index2+1) %plate_info.printer_name
|
||||
%size.x() % size.y() % size.z() %plate_info.printable_width %plate_info.printable_depth %plate_info.printable_height;
|
||||
downward_check_status[index2] = true;
|
||||
failed_count ++;
|
||||
continue;
|
||||
}
|
||||
if (plate_info.exclude_width > 0) {
|
||||
int real_width = plate_info.printable_width - plate_info.exclude_width;
|
||||
int real_depth = plate_info.printable_depth - plate_info.exclude_depth;
|
||||
if ((size.x() > real_width) && (size.y() > real_depth)) {
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("plate %1%, downward_check index %2%, name %3%, bbox {%4%, %5%} exceeds real size without exclude_area {%6%, %7%}")
|
||||
%(index+1) %(index2+1) %plate_info.printer_name
|
||||
%size.x() % size.y() %real_width %real_depth;
|
||||
downward_check_status[index2] = true;
|
||||
failed_count ++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (failed_count < downward_check_size)
|
||||
{
|
||||
//has success ones
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("downward_check: downward_check_size %1%, failed_count %2%")%downward_check_size %failed_count;
|
||||
for (int index2 = 0; index2 < downward_check_size; index2 ++)
|
||||
{
|
||||
if (downward_check_status[index2])
|
||||
continue;
|
||||
printer_plate_info_t& plate_info = downward_check_printers[index2];
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("downward_check: found compatible printer %1%")%plate_info.printer_name;
|
||||
downward_compatible_machines.push_back(plate_info.printer_name);
|
||||
}
|
||||
sliced_info.downward_machines = downward_compatible_machines;
|
||||
}
|
||||
}
|
||||
|
||||
// Loop through transform options.
|
||||
bool user_center_specified = false;
|
||||
Points beds = get_bed_shape(m_print_config);
|
||||
@ -3410,21 +3656,6 @@ int CLI::run(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
auto get_print_sequence = [](Slic3r::GUI::PartPlate* plate, DynamicPrintConfig& print_config, bool &is_seq_print) {
|
||||
PrintSequence curr_plate_seq = plate->get_print_seq();
|
||||
if (curr_plate_seq == PrintSequence::ByDefault) {
|
||||
auto seq_print = print_config.option<ConfigOptionEnum<PrintSequence>>("print_sequence");
|
||||
if (seq_print && (seq_print->value == PrintSequence::ByObject)) {
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("plate print by object, set from global");
|
||||
is_seq_print = true;
|
||||
}
|
||||
}
|
||||
else if (curr_plate_seq == PrintSequence::ByObject) {
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("plate print by object, set from plate self");
|
||||
is_seq_print = true;
|
||||
}
|
||||
};
|
||||
|
||||
if (!assemble_plate_info_list.empty())
|
||||
{
|
||||
//need to arrange for assemble cases
|
||||
@ -4241,7 +4472,7 @@ int CLI::run(int argc, char **argv)
|
||||
// loop through action options
|
||||
bool export_to_3mf = false, load_slicedata = false, export_slicedata = false, export_slicedata_error = false;
|
||||
bool no_check = false;
|
||||
std::string export_3mf_file, load_slice_data_dir, export_slice_data_dir;
|
||||
std::string export_3mf_file, load_slice_data_dir, export_slice_data_dir, export_stls_dir;
|
||||
std::vector<ThumbnailData*> calibration_thumbnails;
|
||||
std::vector<int> plate_object_count(partplate_list.get_plate_count(), 0);
|
||||
int max_slicing_time_per_plate = 0, max_triangle_count_per_plate = 0, sliced_plate = -1;
|
||||
@ -4275,9 +4506,9 @@ int CLI::run(int argc, char **argv)
|
||||
record_exit_reson(outfile_dir, CLI_INVALID_PARAMS, 0, cli_errors[CLI_INVALID_PARAMS], sliced_info);
|
||||
flush_and_exit(CLI_INVALID_PARAMS);
|
||||
}
|
||||
else if (shrink_to_new_bed)
|
||||
else if (shrink_to_new_bed > 0)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(warning) << "use load_slicedata when shrink_to_new_bed(switch printer from small to bigger." << std::endl;
|
||||
BOOST_LOG_TRIVIAL(warning) << "use load_slicedata when shrink_to_new_bed." << std::endl;
|
||||
//record_exit_reson(outfile_dir, CLI_INVALID_PARAMS, 0, cli_errors[CLI_INVALID_PARAMS], sliced_info);
|
||||
//flush_and_exit(CLI_INVALID_PARAMS);
|
||||
}
|
||||
@ -4309,6 +4540,14 @@ int CLI::run(int argc, char **argv)
|
||||
record_exit_reson(outfile_dir, CLI_EXPORT_STL_ERROR, 0, cli_errors[CLI_EXPORT_STL_ERROR], sliced_info);
|
||||
flush_and_exit(CLI_EXPORT_STL_ERROR);
|
||||
}
|
||||
} else if (opt_key == "export_stls") {
|
||||
export_stls_dir = m_config.opt_string(opt_key);
|
||||
for (auto &model : m_models)
|
||||
model.add_default_instances();
|
||||
if (! this->export_models(IO::STL, export_stls_dir)) {
|
||||
record_exit_reson(outfile_dir, CLI_EXPORT_STL_ERROR, 0, cli_errors[CLI_EXPORT_STL_ERROR], sliced_info);
|
||||
flush_and_exit(CLI_EXPORT_STL_ERROR);
|
||||
}
|
||||
} else if (opt_key == "export_obj") {
|
||||
for (auto &model : m_models)
|
||||
model.add_default_instances();
|
||||
@ -5666,7 +5905,7 @@ void CLI::print_help(bool include_print_options, PrinterTechnology printer_techn
|
||||
}*/
|
||||
}
|
||||
|
||||
bool CLI::export_models(IO::ExportFormat format)
|
||||
bool CLI::export_models(IO::ExportFormat format, std::string path_dir)
|
||||
{
|
||||
for (Model &model : m_models) {
|
||||
const std::string path = this->output_filepath(model, format);
|
||||
@ -5687,7 +5926,7 @@ bool CLI::export_models(IO::ExportFormat format)
|
||||
unsigned int index = 1;
|
||||
for (ModelObject* model_object : model.objects)
|
||||
{
|
||||
const std::string path = this->output_filepath(*model_object, index++, format);
|
||||
const std::string path = this->output_filepath(*model_object, index++, format, path_dir);
|
||||
success = Slic3r::store_stl(path.c_str(), model_object, true);
|
||||
if (success)
|
||||
BOOST_LOG_TRIVIAL(info) << "Model successfully exported to " << path << std::endl;
|
||||
@ -5770,7 +6009,7 @@ std::string CLI::output_filepath(const Model &model, IO::ExportFormat format) co
|
||||
return proposed_path.string();
|
||||
}
|
||||
|
||||
std::string CLI::output_filepath(const ModelObject &object, unsigned int index, IO::ExportFormat format) const
|
||||
std::string CLI::output_filepath(const ModelObject &object, unsigned int index, IO::ExportFormat format, std::string path_dir) const
|
||||
{
|
||||
std::string ext, subdir, file_name, output_path;
|
||||
switch (format) {
|
||||
@ -5799,10 +6038,15 @@ std::string CLI::output_filepath(const ModelObject &object, unsigned int index,
|
||||
if (pos != ext_pos)
|
||||
file_name += ext;
|
||||
|
||||
BOOST_LOG_TRIVIAL(trace) << __FUNCTION__ << ": file_name="<<file_name<< ", pos = "<<pos<<", ext_pos="<<ext_pos;
|
||||
std::string cmdline_param = m_config.opt_string("outputdir");
|
||||
if (! cmdline_param.empty()) {
|
||||
subdir = cmdline_param + "/" + subdir;
|
||||
BOOST_LOG_TRIVIAL(trace) << __FUNCTION__ << ": dir = "<< path_dir<<", file_name="<<file_name<< ", pos = "<<pos<<", ext_pos="<<ext_pos;
|
||||
if (path_dir.empty()) {
|
||||
std::string cmdline_param = m_config.opt_string("outputdir");
|
||||
if (! cmdline_param.empty()) {
|
||||
subdir = cmdline_param + "/" + subdir;
|
||||
}
|
||||
}
|
||||
else {
|
||||
subdir = path_dir;
|
||||
}
|
||||
|
||||
output_path = subdir + "/"+file_name;
|
||||
|
@ -67,6 +67,28 @@ typedef struct _assemble_plate_info {
|
||||
}assemble_plate_info_t;
|
||||
|
||||
|
||||
typedef struct _printer_plate_info {
|
||||
std::string printer_name;
|
||||
int printable_width{0};
|
||||
int printable_depth{0};
|
||||
int printable_height{0};
|
||||
|
||||
int exclude_width{0};
|
||||
int exclude_depth{0};
|
||||
int exclude_x{0};
|
||||
int exclude_y{0};
|
||||
}printer_plate_info_t;
|
||||
|
||||
typedef struct _plate_obj_size_info {
|
||||
bool has_wipe_tower{false};
|
||||
float wipe_x{0.f};
|
||||
float wipe_y{0.f};
|
||||
float wipe_width{0.f};
|
||||
float wipe_depth{0.f};
|
||||
BoundingBoxf3 obj_bbox;
|
||||
}plate_obj_size_info_t;
|
||||
|
||||
|
||||
class CLI {
|
||||
public:
|
||||
int run(int argc, char **argv);
|
||||
@ -86,7 +108,7 @@ private:
|
||||
void print_help(bool include_print_options = false, PrinterTechnology printer_technology = ptAny) const;
|
||||
|
||||
/// Exports loaded models to a file of the specified format, according to the options affecting output filename.
|
||||
bool export_models(IO::ExportFormat format);
|
||||
bool export_models(IO::ExportFormat format, std::string path = std::string());
|
||||
//BBS: add export_project function
|
||||
bool export_project(Model *model, std::string& path, PlateDataPtrs &partplate_data, std::vector<Preset*>& project_presets,
|
||||
std::vector<ThumbnailData *> &thumbnails,
|
||||
@ -99,7 +121,7 @@ private:
|
||||
bool has_print_action() const { return m_config.opt_bool("export_gcode") || m_config.opt_bool("export_sla"); }
|
||||
|
||||
std::string output_filepath(const Model &model, IO::ExportFormat format) const;
|
||||
std::string output_filepath(const ModelObject &object, unsigned int index, IO::ExportFormat format) const;
|
||||
std::string output_filepath(const ModelObject &object, unsigned int index, IO::ExportFormat format, std::string path_dir) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -5406,9 +5406,14 @@ CLIActionsConfigDef::CLIActionsConfigDef()
|
||||
|
||||
def = this->add("export_stl", coBool);
|
||||
def->label = "Export STL";
|
||||
def->tooltip = "Export the objects as multiple STL.";
|
||||
def->tooltip = "Export the objects as single STL.";
|
||||
def->set_default_value(new ConfigOptionBool(false));
|
||||
|
||||
def = this->add("export_stls", coString);
|
||||
def->label = "Export multiple stls";
|
||||
def->tooltip = "Export the objects as multiple stls to directory";
|
||||
def->set_default_value(new ConfigOptionString("stl_path"));
|
||||
|
||||
/*def = this->add("export_gcode", coBool);
|
||||
def->label = L("Export G-code");
|
||||
def->tooltip = L("Slice the model and export toolpaths as G-code.");
|
||||
@ -5688,6 +5693,12 @@ CLIMiscConfigDef::CLIMiscConfigDef()
|
||||
def->cli_params = "\"filament1.json;filament2.json;...\"";
|
||||
def->set_default_value(new ConfigOptionStrings());
|
||||
|
||||
def = this->add("downward_check", coStrings);
|
||||
def->label = "downward machines check";
|
||||
def->tooltip = "check whether current machine downward compatible with the machines in the list";
|
||||
def->cli_params = "\"machine1.json;machine2.json;...\"";
|
||||
def->set_default_value(new ConfigOptionStrings());
|
||||
|
||||
def = this->add("load_assemble_list", coString);
|
||||
def->label = "Load assemble list";
|
||||
def->tooltip = "Load assemble object list from config file";
|
||||
|
@ -2216,6 +2216,28 @@ int PartPlate::remove_instance(int obj_id, int instance_id)
|
||||
return result;
|
||||
}
|
||||
|
||||
BoundingBoxf3 PartPlate::get_objects_bounding_box()
|
||||
{
|
||||
BoundingBoxf3 bbox;
|
||||
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];
|
||||
if ((instance_id >= 0) && (instance_id < object->instances.size()))
|
||||
{
|
||||
BoundingBoxf3 instance_bbox = object->instance_bounding_box(instance_id);
|
||||
bbox.merge(instance_bbox);
|
||||
}
|
||||
}
|
||||
}
|
||||
return bbox;
|
||||
}
|
||||
|
||||
|
||||
//translate instance on the plate
|
||||
void PartPlate::translate_all_instance(Vec3d position)
|
||||
{
|
||||
|
@ -304,6 +304,7 @@ public:
|
||||
ModelObjectPtrs get_objects() { return m_model->objects; }
|
||||
ModelObjectPtrs get_objects_on_this_plate();
|
||||
ModelInstance* get_instance(int obj_id, int instance_id);
|
||||
BoundingBoxf3 get_objects_bounding_box();
|
||||
|
||||
Vec3d get_origin() { return m_origin; }
|
||||
Vec3d estimate_wipe_tower_size(const DynamicPrintConfig & config, const double w, const double wipe_volume, int plate_extruder_size = 0, bool use_global_objects = false) const;
|
||||
|
Loading…
x
Reference in New Issue
Block a user