From 27f140fb1889ab6890aafd6c0035235cf5316772 Mon Sep 17 00:00:00 2001 From: SoftFever Date: Mon, 15 Apr 2024 22:09:01 +0800 Subject: [PATCH] Mdel preview renders the actual colors of the filaments based on the filaments currently loaded in the AMS Ported from BambuStudio --- resources/shaders/110/thumbnail.fs | 7 +- resources/shaders/140/thumbnail.fs | 7 +- src/OrcaSlicer.cpp | 909 +++++++++++++++++++++++------ src/OrcaSlicer.hpp | 51 +- src/libslic3r/Color.hpp | 4 +- src/libslic3r/Format/bbs_3mf.cpp | 47 +- src/libslic3r/Format/bbs_3mf.hpp | 3 + src/libslic3r/PrintConfig.cpp | 24 +- src/slic3r/GUI/3DScene.cpp | 55 +- src/slic3r/GUI/3DScene.hpp | 2 +- src/slic3r/GUI/GLCanvas3D.cpp | 58 +- src/slic3r/GUI/GLCanvas3D.hpp | 17 +- src/slic3r/GUI/GUI_App.hpp | 1 + src/slic3r/GUI/PartPlate.cpp | 39 +- src/slic3r/GUI/PartPlate.hpp | 2 + src/slic3r/GUI/Plater.cpp | 29 +- src/slic3r/GUI/SelectMachine.cpp | 547 ++++++++++++----- src/slic3r/GUI/SelectMachine.hpp | 20 +- src/slic3r/GUI/StatusPanel.cpp | 16 +- src/slic3r/GUI/StatusPanel.hpp | 3 +- 20 files changed, 1441 insertions(+), 400 deletions(-) diff --git a/resources/shaders/110/thumbnail.fs b/resources/shaders/110/thumbnail.fs index 4b269734ee..5a57674602 100644 --- a/resources/shaders/110/thumbnail.fs +++ b/resources/shaders/110/thumbnail.fs @@ -1,5 +1,6 @@ #version 110 +uniform bool ban_light; uniform vec4 uniform_color; uniform float emission_factor; @@ -12,5 +13,9 @@ void main() { if (world_pos.z < 0.0) discard; - gl_FragColor = vec4(vec3(intensity.y) + uniform_color.rgb * (intensity.x + emission_factor), uniform_color.a); + if(ban_light){ + gl_FragColor = uniform_color; + } else{ + gl_FragColor = vec4(vec3(intensity.y) + uniform_color.rgb * (intensity.x + emission_factor), uniform_color.a); + } } diff --git a/resources/shaders/140/thumbnail.fs b/resources/shaders/140/thumbnail.fs index 9e6d5d854c..e7963328f9 100644 --- a/resources/shaders/140/thumbnail.fs +++ b/resources/shaders/140/thumbnail.fs @@ -1,5 +1,6 @@ #version 140 +uniform bool ban_light; uniform vec4 uniform_color; uniform float emission_factor; @@ -12,5 +13,9 @@ void main() { if (world_pos.z < 0.0) discard; - gl_FragColor = vec4(vec3(intensity.y) + uniform_color.rgb * (intensity.x + emission_factor), uniform_color.a); + if(ban_light){ + gl_FragColor = uniform_color; + } else{ + gl_FragColor = vec4(vec3(intensity.y) + uniform_color.rgb * (intensity.x + emission_factor), uniform_color.a); + } } diff --git a/src/OrcaSlicer.cpp b/src/OrcaSlicer.cpp index e9a5d6e641..5df3b0300f 100644 --- a/src/OrcaSlicer.cpp +++ b/src/OrcaSlicer.cpp @@ -161,6 +161,8 @@ typedef struct _sliced_info { std::vector sliced_plates; size_t prepare_time; size_t export_time; + std::vector upward_machines; + std::vector downward_machines; }sliced_info_t; std::vector 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; @@ -679,6 +685,51 @@ static int load_assemble_plate_list(std::string config_file, std::vector>(); BOOST_LOG_TRIVIAL(debug) << boost::format("Plate %1%, object %2% has %3% print params") % (plate_index + 1) %assemble_object.path % assemble_object.print_params.size(); } + if (object_json.contains(JSON_ASSEMPLE_OBJECT_HEIGHT_RANGES)) { + json height_range_json = object_json[JSON_ASSEMPLE_OBJECT_HEIGHT_RANGES]; + int range_count = height_range_json.size(); + + BOOST_LOG_TRIVIAL(debug) << boost::format("Plate %1%, object %2% has %3% height ranges") % (plate_index + 1) %assemble_object.path % range_count; + + assemble_object.height_ranges.resize(range_count); + for (int range_index = 0; range_index < range_count; range_index++) + { + height_range_info_t& height_range = assemble_object.height_ranges[range_index]; + height_range.min_z = height_range_json[range_index][JSON_ASSEMPLE_OBJECT_MIN_Z]; + height_range.max_z = height_range_json[range_index][JSON_ASSEMPLE_OBJECT_MAX_Z]; + height_range.range_params = height_range_json[range_index][JSON_ASSEMPLE_OBJECT_RANGE_PARAMS].get>(); + } + } + } + if (plate_json.contains(JSON_ASSEMPLE_ASSEMBLE_PARAMS)) { + json assemble_params_json = plate_json[JSON_ASSEMPLE_ASSEMBLE_PARAMS]; + int assemble_count = assemble_params_json.size(); + for (int i = 0; i < assemble_count; i++) + { + assembled_param_info_t assembled_param; + int assemble_index = assemble_params_json[i][JSON_ASSEMPLE_OBJECT_ASSEMBLE_INDEX]; + if (assemble_params_json[i].contains(JSON_ASSEMPLE_OBJECT_PRINT_PARAMS)) { + assembled_param.print_params = assemble_params_json[i][JSON_ASSEMPLE_OBJECT_PRINT_PARAMS].get>(); + BOOST_LOG_TRIVIAL(debug) << boost::format("Plate %1%, assemble object %2% has %3% print params") % (plate_index + 1) %i % assembled_param.print_params.size(); + } + if (assemble_params_json[i].contains(JSON_ASSEMPLE_OBJECT_HEIGHT_RANGES)) { + json height_range_json = assemble_params_json[i][JSON_ASSEMPLE_OBJECT_HEIGHT_RANGES]; + int range_count = height_range_json.size(); + + BOOST_LOG_TRIVIAL(debug) << boost::format("Plate %1%, assemble object %2% has %3% height ranges") % (plate_index + 1) %i % range_count; + + assembled_param.height_ranges.resize(range_count); + for (int range_index = 0; range_index < range_count; range_index++) + { + height_range_info_t& height_range = assembled_param.height_ranges[range_index]; + height_range.min_z = height_range_json[range_index][JSON_ASSEMPLE_OBJECT_MIN_Z]; + height_range.max_z = height_range_json[range_index][JSON_ASSEMPLE_OBJECT_MAX_Z]; + height_range.range_params = height_range_json[range_index][JSON_ASSEMPLE_OBJECT_RANGE_PARAMS].get>(); + } + } + assemble_plate.assembled_param_list.emplace(assemble_index, std::move(assembled_param)); + } + BOOST_LOG_TRIVIAL(debug) << boost::format("Plate %1%, has %2% plate params") % (plate_index + 1) % assemble_plate.plate_params.size(); } } } @@ -820,6 +871,21 @@ static int construct_assemble_list(std::vector &assemble_ } } + if (!assemble_object.height_ranges.empty()) + { + for (int range_index = 0; range_index < assemble_object.height_ranges.size(); range_index++) + { + height_range_info_t& range = assemble_object.height_ranges[range_index]; + DynamicPrintConfig range_config; + for (auto range_config_iter = range.range_params.begin(); range_config_iter != range.range_params.end(); range_config_iter++) + { + range_config.set_deserialize(range_config_iter->first, range_config_iter->second, config_substitutions); + BOOST_LOG_TRIVIAL(debug) << boost::format("object %1%, height range %2% key %3%, value %4%") % object_1_name % range_index % range_config_iter->first % range_config_iter->second; + } + object->layer_config_ranges[{ range.min_z, range.max_z }].assign_config(std::move(range_config)); + } + } + if (assemble_object.pos_x.empty()) assemble_object.pos_x.resize(1, 0.f); if (assemble_object.pos_y.empty()) @@ -864,6 +930,46 @@ static int construct_assemble_list(std::vector &assemble_ } } + size_t assemble_count = merged_objects.size(); + if ((assemble_count > 0) && (assemble_plate_info.assembled_param_list.size() > 0)) + { + for (auto& iter : merged_objects) + { + ModelObject* assemble_obj = iter.second; + int assemble_index = iter.first; + + auto assemble_iter = assemble_plate_info.assembled_param_list.find(assemble_index); + + if (assemble_iter != assemble_plate_info.assembled_param_list.end()) + { + assembled_param_info_t& assembled_param = assemble_iter->second; + if (!assembled_param.print_params.empty()) + { + for (auto param_iter = assembled_param.print_params.begin(); param_iter != assembled_param.print_params.end(); param_iter++) + { + assemble_obj->config.set_deserialize(param_iter->first, param_iter->second, config_substitutions); + BOOST_LOG_TRIVIAL(debug) << boost::format("Plate %1%, assemble object %2% key %3%, value %4%") % (index + 1) % assemble_obj->name % param_iter->first % param_iter->second; + } + } + + if (!assembled_param.height_ranges.empty()) + { + for (int range_index = 0; range_index < assembled_param.height_ranges.size(); range_index++) + { + height_range_info_t& range = assembled_param.height_ranges[range_index]; + DynamicPrintConfig range_config; + for (auto range_config_iter = range.range_params.begin(); range_config_iter != range.range_params.end(); range_config_iter++) + { + range_config.set_deserialize(range_config_iter->first, range_config_iter->second, config_substitutions); + BOOST_LOG_TRIVIAL(debug) << boost::format("assenble object %1%, height range %2% key %3%, value %4%") % assemble_obj->name % range_index % range_config_iter->first % range_config_iter->second; + } + assemble_obj->layer_config_ranges[{ range.min_z, range.max_z }].assign_config(std::move(range_config)); + } + } + } + } + } + assemble_plate_info.filaments_count = used_filaments.size(); assemble_plate_info.assemble_obj_list.clear(); assemble_plate_info.assemble_obj_list.shrink_to_fit(); @@ -879,6 +985,56 @@ static int construct_assemble_list(std::vector &assemble_ return ret; } +static void load_downward_settings_list_from_config(std::string config_file, std::string printer_name, std::string printer_model, std::vector& downward_settings) +{ + std::map printer_params; + + boost::filesystem::path directory_path(config_file); + + BOOST_LOG_TRIVIAL(info) << boost::format("%1%, will parse file %2% for printer mode %3%, printer name %4%")%__FUNCTION__ % config_file %printer_model %printer_name; + if (!fs::exists(directory_path)) { + BOOST_LOG_TRIVIAL(warning) << boost::format("file %1% not exist.")%config_file; + } + else { + try { + json root_json; + boost::nowide::ifstream ifs(config_file); + ifs >> root_json; + ifs.close(); + + if (root_json.contains("printer")) { + json printer_json = root_json["printer"]; + if (!printer_model.empty() && printer_json.contains(printer_model)) { + json printer_model_json = printer_json[printer_model]; + + if (printer_model_json.contains("downward_check")) { + json downward_check_json = printer_model_json["downward_check"]; + if (downward_check_json.contains(printer_name)) { + downward_settings = downward_check_json[printer_name].get>(); + BOOST_LOG_TRIVIAL(info) << boost::format("got %1% downward settings of %2% in cli_config.json")%downward_settings.size() %printer_name; + } + else { + BOOST_LOG_TRIVIAL(info) << boost::format("can not find %1% in downward_check of %2% in cli_config.json")%printer_name %printer_model; + } + } + else { + BOOST_LOG_TRIVIAL(info) << boost::format("can not find downward_check for %1% in cli_config.json")%printer_model; + } + } + else { + BOOST_LOG_TRIVIAL(info) << boost::format("can not find printer_model %1% in the file")%printer_model; + } + } + else { + BOOST_LOG_TRIVIAL(warning) << boost::format("can not find key printer in the file"); + } + } + catch (std::exception &err) { + BOOST_LOG_TRIVIAL(error) << __FUNCTION__<< ": parse file "< &load_configs = m_config.option("load_settings", true)->values; const std::vector &uptodate_configs = m_config.option("uptodate_settings", true)->values; const std::vector &uptodate_filaments = m_config.option("uptodate_filaments", true)->values; + std::vector downward_settings = m_config.option("downward_settings", true)->values; + std::vector downward_compatible_machines; //BBS: always use ForwardCompatibilitySubstitutionRule::Enable //const ForwardCompatibilitySubstitutionRule config_substitution_rule = m_config.option>("config_compatibility", true)->value; const ForwardCompatibilitySubstitutionRule config_substitution_rule = ForwardCompatibilitySubstitutionRule::Enable; @@ -960,6 +1116,11 @@ int CLI::run(int argc, char **argv) sliced_info_t sliced_info; std::map record_key_values; + ConfigOptionBool* downward_check_option = m_config.option("downward_check"); + if (downward_check_option) + downward_check = downward_check_option->value; + + bool start_gui = m_actions.empty() && !downward_check; if (start_gui) { BOOST_LOG_TRIVIAL(info) << "no action, start gui directly" << std::endl; ::Label::initSysFont(); @@ -1028,6 +1189,7 @@ int CLI::run(int argc, char **argv) //BBS: add plate data related logic PlateDataPtrs plate_data_src; + std::vector 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; @@ -1035,12 +1197,12 @@ int CLI::run(int argc, char **argv) Semver file_version; std::map orients_requirement; std::vector project_presets; - std::string new_printer_name, current_printer_name, new_process_name, current_process_name, current_printer_system_name, current_process_system_name, new_process_system_name, new_printer_system_name, printer_model_id, printer_model;//, printer_inherits, print_inherits; + std::string new_printer_name, current_printer_name, new_process_name, current_process_name, current_printer_system_name, current_process_system_name, new_process_system_name, new_printer_system_name, printer_model_id, current_printer_model, printer_model;//, printer_inherits, print_inherits; std::vector upward_compatible_printers, new_print_compatible_printers, current_print_compatible_printers, current_different_settings; std::vector current_filaments_name, current_filaments_system_name, current_inherits_group; DynamicPrintConfig load_process_config, load_machine_config; bool new_process_config_is_system = true, new_printer_config_is_system = true; - std::string pipe_name, makerlab_name, makerlab_version; + std::string pipe_name, makerlab_name, makerlab_version, different_process_setting; // Read input file(s) if any. BOOST_LOG_TRIVIAL(info) << "Will start to read model file now, file count :" << m_input_files.size() << "\n"; @@ -1270,6 +1432,7 @@ int CLI::run(int argc, char **argv) }*/ current_printer_name = config.option("printer_settings_id")->value; current_process_name = config.option("print_settings_id")->value; + current_printer_model = config.option("printer_model", true)->value; current_filaments_name = config.option("filament_settings_id")->values; BOOST_LOG_TRIVIAL(info) << boost::format("current_printer_name %1%, current_process_name %2%")%current_printer_name %current_process_name; @@ -1631,6 +1794,11 @@ int CLI::run(int argc, char **argv) config.set("print_settings_id", new_process_name, true); //print_inherits = config.option("inherits", true)->value; new_print_compatible_printers = config.option("compatible_printers", true)->values; + + if (!is_bbl_3mf && config.option("different_settings_to_system")) { + std::vector diff_settings = config.option("different_settings_to_system")->values; + different_process_setting = diff_settings[0]; + } load_process_config = std::move(config); BOOST_LOG_TRIVIAL(info) << boost::format("loaded process config %1%, type %2%, name %3%, inherits %4%")%file %config_name %config_from % new_process_system_name; } @@ -2043,7 +2211,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; @@ -2105,11 +2273,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; } } @@ -2119,11 +2292,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) { @@ -2131,10 +2304,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(); @@ -2226,6 +2400,9 @@ int CLI::run(int argc, char **argv) std::vector& inherits_group = m_print_config.option("inherits_group", true)->values; inherits_group.resize(filament_count + 2, std::string()); different_settings.resize(filament_count + 2, std::string()); + if (!is_bbl_3mf && !different_process_setting.empty()) { + different_settings[0] = different_process_setting; + } //set the machine settings into print config if (!new_printer_name.empty() || up_config_to_date) { std::vector different_keys; @@ -2291,33 +2468,40 @@ int CLI::run(int argc, char **argv) if (root_json.contains("printer")) { json printer_json = root_json["printer"]; if (!printer_model.empty() && printer_json.contains(printer_model)) { - json new_printer_json = printer_json[printer_model]; - printer_params = new_printer_json.get>(); + json printer_model_json = printer_json[printer_model]; - for (auto param_iter = printer_params.begin(); param_iter != printer_params.end(); param_iter++) - { - std::string key = param_iter->first; - //replace "cli_safe" with "machine_max" - key.replace(0, 8, "machine_max"); + if (printer_model_json.contains("machine_limits")) { + json machine_limits_json = printer_model_json["machine_limits"]; + printer_params = machine_limits_json.get>(); - ConfigOptionFloats* option = m_print_config.option(key); - if (option) { - //de-serialize the values from param_iter->second, and do the compare here - unsigned int array_count = option->size(); - ConfigOptionFloats new_option; - new_option.deserialize(param_iter->second); - unsigned int new_array_count = new_option.size(); - for (unsigned int index = 0; index < array_count; index++) - { - if ((index < new_array_count) && new_option.values[index] != 0.f && (new_option.values[index] < option->values[index])) + for (auto param_iter = printer_params.begin(); param_iter != printer_params.end(); param_iter++) + { + std::string key = param_iter->first; + //replace "cli_safe" with "machine_max" + key.replace(0, 8, "machine_max"); + + ConfigOptionFloats* option = m_print_config.option(key); + if (option) { + //de-serialize the values from param_iter->second, and do the compare here + unsigned int array_count = option->size(); + ConfigOptionFloats new_option; + new_option.deserialize(param_iter->second); + unsigned int new_array_count = new_option.size(); + for (unsigned int index = 0; index < array_count; index++) { - BOOST_LOG_TRIVIAL(info) << boost::format("set key %1% index %2%, from %3% to %4%") % key %index %option->values[index] % new_option.values[index]; - option->values[index] = new_option.values[index]; + if ((index < new_array_count) && new_option.values[index] != 0.f && (new_option.values[index] < option->values[index])) + { + BOOST_LOG_TRIVIAL(info) << boost::format("set key %1% index %2%, from %3% to %4%") % key %index %option->values[index] % new_option.values[index]; + option->values[index] = new_option.values[index]; + } } } + else + BOOST_LOG_TRIVIAL(warning) << boost::format("can not find key %1% in config") %key; } - else - BOOST_LOG_TRIVIAL(warning) << boost::format("can not find key %1% in config") %key; + } + else { + BOOST_LOG_TRIVIAL(info) << boost::format("can not find machine_limits for printer %1% in cli_config.json")%printer_model; } } else { @@ -2407,7 +2591,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]; @@ -2792,134 +2976,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("printable_area")->values; - Pointfs current_exclude_area = m_print_config.opt("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_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(print_config.option("wipe_tower_x")); - wipe_y_option = dynamic_cast(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)) @@ -2955,6 +3011,378 @@ 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("printable_area")->values; + Pointfs current_exclude_area = m_print_config.opt("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_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 (is_bbl_3mf && (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>("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 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(print_config.option("wipe_tower_x")); + ConfigOptionFloats *wipe_y_option = dynamic_cast(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("prime_tower_width", true); + plate_obj_size_info.wipe_width = width_option->value; + + ConfigOptionFloat* brim_width_option = print_config.option("prime_tower_brim_width", true); + float brim_width = brim_width_option->value; + + ConfigOptionFloat* volume_option = print_config.option("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(print_config.option("wipe_tower_x")); + wipe_y_option = dynamic_cast(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 downward_check_printers; + std::vector downward_check_status; + if (downward_check) { + bool use_default = false; + std::string default_path; + if (downward_settings.size() == 0) { + //parse from internal + std::string cli_config_file = resources_dir() + "/profiles/BBL/cli_config.json"; + load_downward_settings_list_from_config(cli_config_file, current_printer_name, current_printer_model, downward_settings); + use_default = true; + default_path = resources_dir() + "/profiles/BBL/machine_full/"; + } + for (auto const &file : downward_settings) { + DynamicPrintConfig config; + std::string config_type, config_name, filament_id, config_from, downward_printer; + std::string file_path = use_default?(default_path+file+".json"):file; + int ret = load_config_file(file_path, 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_path; + 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_path ; + + printer_plate_info_t printer_plate; + Pointfs temp_printable_area, temp_exclude_area; + + printer_plate.printer_name = config_name; + + temp_printable_area = config.option("printable_area", true)->values; + temp_exclude_area = config.option("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); @@ -3262,7 +3690,7 @@ int CLI::run(int argc, char **argv) } else { - BOOST_LOG_TRIVIAL(info) << "Before process command, no need to orient, object id :" << o->id().id<id().id<thumbnail_file; plate_data_src[index]->thumbnail_file.clear(); } + if (!plate_data_src[index]->no_light_thumbnail_file.empty()) { + BOOST_LOG_TRIVIAL(info) << boost::format("Plate %1%: clear loaded no_light_thumbnail %2%.")%(index+1)%plate_data_src[index]->no_light_thumbnail_file; + plate_data_src[index]->no_light_thumbnail_file.clear(); + } if (!plate_data_src[index]->top_file.empty()) { BOOST_LOG_TRIVIAL(info) << boost::format("Plate %1%: clear loaded top_thumbnail %2%.")%(index+1)%plate_data_src[index]->top_file; plate_data_src[index]->top_file.clear(); @@ -3350,21 +3782,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>("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 @@ -4181,7 +4598,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 calibration_thumbnails; std::vector 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; @@ -4215,9 +4632,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); } @@ -4249,6 +4666,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(); @@ -4389,6 +4814,10 @@ int CLI::run(int argc, char **argv) BOOST_LOG_TRIVIAL(info) << boost::format("Plate %1%: clear loaded thumbnail %2%.")%(index+1)%plate_data_src[index]->thumbnail_file; plate_data_src[index]->thumbnail_file.clear(); } + if (!plate_data_src[index]->no_light_thumbnail_file.empty()) { + BOOST_LOG_TRIVIAL(info) << boost::format("Plate %1%: clear loaded no_light_thumbnail %2%.")%(index+1)%plate_data_src[index]->no_light_thumbnail_file; + plate_data_src[index]->no_light_thumbnail_file.clear(); + } if (!plate_data_src[index]->top_file.empty()) { BOOST_LOG_TRIVIAL(info) << boost::format("Plate %1%: clear loaded top_thumbnail %2%.")%(index+1)%plate_data_src[index]->top_file; plate_data_src[index]->top_file.clear(); @@ -4415,7 +4844,7 @@ int CLI::run(int argc, char **argv) if (vol->is_model_part()) { size_t volume_triangle_count = vol->mesh().facets_count(); triangle_count += volume_triangle_count; - BOOST_LOG_TRIVIAL(info) << boost::format("volume triangle count %1%, total %2%")%volume_triangle_count %triangle_count; + BOOST_LOG_TRIVIAL(debug) << boost::format("volume triangle count %1%, total %2%")%volume_triangle_count %triangle_count; if ((max_triangle_count_per_plate != 0) && (triangle_count > max_triangle_count_per_plate)) { BOOST_LOG_TRIVIAL(error) << "plate "<< index+1<< ": triangle count " << triangle_count <<" exceeds the limit:" << max_triangle_count_per_plate; @@ -4740,7 +5169,7 @@ int CLI::run(int argc, char **argv) global_begin_time = (long long)Slic3r::Utils::get_current_time_utc(); if (export_to_3mf) { //BBS: export as bbl 3mf - std::vector thumbnails, top_thumbnails, pick_thumbnails; + std::vector thumbnails, no_light_thumbnails, top_thumbnails, pick_thumbnails; std::vector plate_bboxes; PlateDataPtrs plate_data_list; partplate_list.store_to_3mf_structure(plate_data_list); @@ -4779,8 +5208,9 @@ int CLI::run(int argc, char **argv) #endif bool need_regenerate_thumbnail = oriented_or_arranged || regenerate_thumbnails; + bool need_regenerate_no_light_thumbnail = oriented_or_arranged || regenerate_thumbnails; bool need_regenerate_top_thumbnail = oriented_or_arranged || regenerate_thumbnails; - bool need_create_thumbnail_group = false, need_create_top_group = false; + bool need_create_thumbnail_group = false, need_create_no_light_group = false, need_create_top_group = false; // get type and color for platedata auto* filament_types = dynamic_cast(m_print_config.option("filament_type")); @@ -4837,6 +5267,27 @@ int CLI::run(int argc, char **argv) } } + if (plate_data->no_light_thumbnail_file.empty()) { + if (!regenerate_thumbnails && (plate_data_src.size() > i)) { + plate_data->no_light_thumbnail_file = plate_data_src[i]->no_light_thumbnail_file; + } + if (plate_data->no_light_thumbnail_file.empty() || (!boost::filesystem::exists(plate_data->no_light_thumbnail_file))) { + BOOST_LOG_TRIVIAL(info) << boost::format("thumbnails stage: plate %1%'s no_light_thumbnail_file %2% also not there, need to regenerate")%(i+1)%plate_data->no_light_thumbnail_file; + if (!skip_this_plate) { + need_regenerate_no_light_thumbnail = true; + need_create_no_light_group = true; + } + } + else { + if (regenerate_thumbnails) { + BOOST_LOG_TRIVIAL(info) << boost::format("thumbnails stage: plate %1%'s no_light_thumbnail file %2% cleared, need to regenerate")%(i+1) %plate_data->no_light_thumbnail_file; + plate_data->no_light_thumbnail_file.clear(); + } + else + BOOST_LOG_TRIVIAL(info) << boost::format("thumbnails stage: plate %1%'s no_light_thumbnail file exists, no need to regenerate")%(i+1); + } + } + if (plate_data->top_file.empty() || plate_data->pick_file.empty()) { if (!regenerate_thumbnails && (plate_data_src.size() > i)) { plate_data->top_file = plate_data_src[i]->top_file; @@ -4862,7 +5313,7 @@ int CLI::run(int argc, char **argv) } } - if (need_regenerate_thumbnail || need_regenerate_top_thumbnail) { + if (need_regenerate_thumbnail || need_regenerate_no_light_thumbnail || need_regenerate_top_thumbnail) { std::vector colors; if (filament_color) { colors= filament_color->vserialize(); @@ -5050,6 +5501,60 @@ int CLI::run(int argc, char **argv) BOOST_LOG_TRIVIAL(info) << boost::format("plate %1%: add thumbnail data into group")%(i+1); } + //no light thumbnail + if (!plate_data->no_light_thumbnail_file.empty() && (boost::filesystem::exists(plate_data->no_light_thumbnail_file))) + { + if ((plate_to_slice != 0) && (plate_to_slice != (i + 1))) { + BOOST_LOG_TRIVIAL(info) << boost::format("Line %1%: regenerate thumbnail, clear plate %2%'s no_light_thumbnail_file path to empty.")%__LINE__%(i+1); + plate_data->no_light_thumbnail_file.clear(); + } + else + BOOST_LOG_TRIVIAL(info) << boost::format("plate %1% has valid no_light_thumbnail_file extracted from 3mf, directly using it")%(i+1); + } + else{ + ThumbnailData *no_light_thumbnail = &part_plate->no_light_thumbnail_data; + if ((plate_to_slice != 0) && (plate_to_slice != (i + 1))) { + BOOST_LOG_TRIVIAL(info) << boost::format("Line %1%: regenerate thumbnail, Skip plate %2%.")%__LINE__%(i+1); + part_plate->no_light_thumbnail_data.reset(); + plate_data->no_light_thumbnail_file.clear(); + } + else { + unsigned int thumbnail_width = 512, thumbnail_height = 512; + const ThumbnailsParams thumbnail_params = { {}, false, true, false, true, i }; + + BOOST_LOG_TRIVIAL(info) << boost::format("plate %1%'s no_light_thumbnail_file missed, need to regenerate")%(i+1); + switch (Slic3r::GUI::OpenGLManager::get_framebuffers_type()) + { + case Slic3r::GUI::OpenGLManager::EFramebufferType::Arb: + { + BOOST_LOG_TRIVIAL(info) << boost::format("framebuffer_type: ARB"); + Slic3r::GUI::GLCanvas3D::render_thumbnail_framebuffer(*no_light_thumbnail, + thumbnail_width, thumbnail_height, thumbnail_params, + partplate_list, model.objects, glvolume_collection, colors_out, shader, Slic3r::GUI::Camera::EType::Ortho, false, false, true); + break; + } + case Slic3r::GUI::OpenGLManager::EFramebufferType::Ext: + { + BOOST_LOG_TRIVIAL(info) << boost::format("framebuffer_type: EXT"); + Slic3r::GUI::GLCanvas3D::render_thumbnail_framebuffer_ext(*no_light_thumbnail, + thumbnail_width, thumbnail_height, thumbnail_params, + partplate_list, model.objects, glvolume_collection, colors_out, shader, Slic3r::GUI::Camera::EType::Ortho, false, false, true); + break; + } + default: + BOOST_LOG_TRIVIAL(info) << boost::format("framebuffer_type: unknown"); + break; + } + plate_data->no_light_thumbnail_file = "valid_no_light"; + BOOST_LOG_TRIVIAL(info) << boost::format("plate %1%'s no_light thumbnail,finished rendering")%(i+1); + } + } + + if (need_create_no_light_group) { + no_light_thumbnails.push_back(&part_plate->no_light_thumbnail_data); + BOOST_LOG_TRIVIAL(info) << boost::format("plate %1%: add thumbnail data for no_light into group")%(i+1); + } + //top thumbnails /*if (part_plate->top_thumbnail_data.is_valid() && part_plate->pick_thumbnail_data.is_valid()) { if ((plate_to_slice != 0) && (plate_to_slice != (i + 1))) { @@ -5160,6 +5665,9 @@ int CLI::run(int argc, char **argv) BOOST_LOG_TRIVIAL(info) << boost::format("plate %1%'s all the thumbnails skipped, reset here")%(i+1); plate_data->plate_thumbnail.reset(); plate_data->thumbnail_file.clear(); + part_plate->no_light_thumbnail_data.reset(); + plate_data->no_light_thumbnail_file.clear(); + part_plate->top_thumbnail_data.reset(); part_plate->pick_thumbnail_data.reset(); plate_data->top_file.clear(); @@ -5189,6 +5697,11 @@ int CLI::run(int argc, char **argv) BOOST_LOG_TRIVIAL(info) << boost::format("plate %1%: add thumbnail data into group")%(i+1); } + if (need_create_no_light_group) { + no_light_thumbnails.push_back(&part_plate->no_light_thumbnail_data); + BOOST_LOG_TRIVIAL(info) << boost::format("plate %1%: add thumbnail data into group")%(i+1); + } + if (need_create_top_group) { top_thumbnails.push_back(&part_plate->top_thumbnail_data); pick_thumbnails.push_back(&part_plate->pick_thumbnail_data); @@ -5334,7 +5847,7 @@ int CLI::run(int argc, char **argv) model.mk_version = makerlab_version; BOOST_LOG_TRIVIAL(info) << boost::format("mk_name %1%, mk_version %2%")%makerlab_name %makerlab_version; } - if (! this->export_project(&m_models[0], export_3mf_file, plate_data_list, project_presets, thumbnails, top_thumbnails, pick_thumbnails, + if (!this->export_project(&m_models[0], export_3mf_file, plate_data_list, project_presets, thumbnails, no_light_thumbnails, top_thumbnails, pick_thumbnails, calibration_thumbnails, plate_bboxes, &m_print_config, minimum_save, plate_to_slice - 1)) { release_PlateData_list(plate_data_list); @@ -5344,6 +5857,8 @@ int CLI::run(int argc, char **argv) for (unsigned int i = 0; i < thumbnails.size(); i++) thumbnails[i]->reset(); + for (unsigned int i = 0; i < no_light_thumbnails.size(); i++) + no_light_thumbnails[i]->reset(); for (unsigned int i = 0; i < top_thumbnails.size(); i++) top_thumbnails[i]->reset(); for (unsigned int i = 0; i < pick_thumbnails.size(); i++) @@ -5517,7 +6032,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); @@ -5538,7 +6053,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; @@ -5559,7 +6074,11 @@ bool CLI::export_models(IO::ExportFormat format) //BBS: add export_project function bool CLI::export_project(Model *model, std::string& path, PlateDataPtrs &partplate_data, - std::vector& project_presets, std::vector& thumbnails, std::vector& top_thumbnails, std::vector& pick_thumbnails, + std::vector & project_presets, + std::vector &thumbnails, + std::vector &no_light_thumbnails, + std::vector &top_thumbnails, + std::vector &pick_thumbnails, std::vector& calibration_thumbnails, std::vector& plate_bboxes, const DynamicPrintConfig* config, bool minimum_save, int plate_to_export) { //const std::string path = this->output_filepath(*model, IO::TMF); @@ -5572,6 +6091,7 @@ bool CLI::export_project(Model *model, std::string& path, PlateDataPtrs &partpla store_params.project_presets = project_presets; store_params.config = (DynamicPrintConfig*)config; store_params.thumbnail_data = thumbnails; + store_params.no_light_thumbnail_data = no_light_thumbnails; store_params.top_thumbnail_data = top_thumbnails; store_params.pick_thumbnail_data = pick_thumbnails; store_params.calibration_thumbnail_data = calibration_thumbnails; @@ -5616,7 +6136,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) { @@ -5645,10 +6165,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="< range_params; +}height_range_info_t; + +typedef struct _assembled_param_info { + std::map print_params; + std::vector height_ranges; +}assembled_param_info_t; + typedef struct _assemble_object_info { std::string path; int count; @@ -42,6 +60,7 @@ typedef struct _assemble_object_info { std::vector pos_y; std::vector pos_z; std::map print_params; + std::vector height_ranges; }assemble_object_info_t; typedef struct _assemble_plate_info { @@ -52,9 +71,32 @@ typedef struct _assemble_plate_info { std::map plate_params; std::vector assemble_obj_list; std::vector loaded_obj_list; + std::map assembled_param_list; }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); @@ -74,17 +116,20 @@ 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& project_presets, - std::vector& thumbnails, std::vector& top_thumbnails, std::vector& pick_thumbnails, + std::vector &thumbnails, + std::vector &no_light_thumbnails, + std::vector &top_thumbnails, + std::vector &pick_thumbnails, std::vector& calibration_thumbnails, std::vector& plate_bboxes, const DynamicPrintConfig* config, bool minimum_save, int plate_to_export = -1); 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; }; } diff --git a/src/libslic3r/Color.hpp b/src/libslic3r/Color.hpp index 4c96458b40..ad119d3c56 100644 --- a/src/libslic3r/Color.hpp +++ b/src/libslic3r/Color.hpp @@ -91,8 +91,10 @@ public: bool operator != (const ColorRGBA& other) const { return !operator==(other); } bool operator < (const ColorRGBA& other) const; bool operator > (const ColorRGBA& other) const; + float operator[](int i) const { return m_data[i]; } + float& operator[](int i) { return m_data[i]; } - ColorRGBA operator + (const ColorRGBA& other) const; + ColorRGBA operator + (const ColorRGBA& other) const; ColorRGBA operator * (float value) const; const float* const data() const { return m_data.data(); } diff --git a/src/libslic3r/Format/bbs_3mf.cpp b/src/libslic3r/Format/bbs_3mf.cpp index 3ef3ad3006..b6955ab80e 100644 --- a/src/libslic3r/Format/bbs_3mf.cpp +++ b/src/libslic3r/Format/bbs_3mf.cpp @@ -292,6 +292,7 @@ static constexpr const char* OTHER_LAYERS_PRINT_SEQUENCE_NUMS_ATTR = "other_laye static constexpr const char* SPIRAL_VASE_MODE = "spiral_mode"; static constexpr const char* GCODE_FILE_ATTR = "gcode_file"; static constexpr const char* THUMBNAIL_FILE_ATTR = "thumbnail_file"; +static constexpr const char* NO_LIGHT_THUMBNAIL_FILE_ATTR = "thumbnail_no_light_file"; static constexpr const char* TOP_FILE_ATTR = "top_file"; static constexpr const char* PICK_FILE_ATTR = "pick_file"; static constexpr const char* PATTERN_FILE_ATTR = "pattern_file"; @@ -1491,6 +1492,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) boost::algorithm::replace_all(plate->thumbnail_file, ".gcode", ".png"); } //plate->pattern_file = it->second->pattern_file; + plate->no_light_thumbnail_file = it->second->no_light_thumbnail_file; plate->top_file = it->second->top_file; plate->pick_file = it->second->pick_file.empty(); plate->pattern_bbox_file = it->second->pattern_bbox_file.empty(); @@ -1502,7 +1504,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) return mz_zip_reader_extract_to_mem(&archive, stat.m_file_index, pixels.data(), pixels.size(), 0); }); - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format(", plate %1%, thumbnail_file=%2%")%it->first %plate->thumbnail_file; + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format(", plate %1%, thumbnail_file=%2%, no_light_thumbnail_file=%3%")%it->first %plate->thumbnail_file %plate->no_light_thumbnail_file; BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format(", top_thumbnail_file=%1%, pick_thumbnail_file=%2%")%plate->top_file %plate->pick_file; it++; } @@ -2136,13 +2138,14 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) plate_data_list[it->first-1]->warnings = it->second->warnings; plate_data_list[it->first-1]->thumbnail_file = (m_load_restore || it->second->thumbnail_file.empty()) ? it->second->thumbnail_file : m_backup_path + "/" + it->second->thumbnail_file; //plate_data_list[it->first-1]->pattern_file = (m_load_restore || it->second->pattern_file.empty()) ? it->second->pattern_file : m_backup_path + "/" + it->second->pattern_file; + plate_data_list[it->first-1]->no_light_thumbnail_file = (m_load_restore || it->second->no_light_thumbnail_file.empty()) ? it->second->no_light_thumbnail_file : m_backup_path + "/" + it->second->no_light_thumbnail_file; plate_data_list[it->first-1]->top_file = (m_load_restore || it->second->top_file.empty()) ? it->second->top_file : m_backup_path + "/" + it->second->top_file; plate_data_list[it->first-1]->pick_file = (m_load_restore || it->second->pick_file.empty()) ? it->second->pick_file : m_backup_path + "/" + it->second->pick_file; plate_data_list[it->first-1]->pattern_bbox_file = (m_load_restore || it->second->pattern_bbox_file.empty()) ? it->second->pattern_bbox_file : m_backup_path + "/" + it->second->pattern_bbox_file; plate_data_list[it->first-1]->config = it->second->config; current_plate_data = plate_data_list[it->first - 1]; - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format(", plate %1%, thumbnail_file=%2%")%it->first %plate_data_list[it->first-1]->thumbnail_file; + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format(", plate %1%, thumbnail_file=%2%, no_light_thumbnail_file=%3%")%it->first %plate_data_list[it->first-1]->thumbnail_file %plate_data_list[it->first-1]->no_light_thumbnail_file; BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format(", top_thumbnail_file=%1%, pick_thumbnail_file=%2%")%plate_data_list[it->first-1]->top_file %plate_data_list[it->first-1]->pick_file; it++; @@ -4115,6 +4118,10 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) { m_curr_plater->thumbnail_file = value; } + else if (key == NO_LIGHT_THUMBNAIL_FILE_ATTR) + { + m_curr_plater->no_light_thumbnail_file = value; + } else if (key == TOP_FILE_ATTR) { m_curr_plater->top_file = value; @@ -5470,6 +5477,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) std::vector& project_presets, const DynamicPrintConfig* config, const std::vector& thumbnail_data, + const std::vector& no_light_thumbnail_data, const std::vector& top_thumbnail_data, const std::vector& pick_thumbnail_data, Export3mfProgressFn proFn, @@ -5556,7 +5564,8 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) boost::filesystem::remove(filename + ".tmp", ec); bool result = _save_model_to_file(filename + ".tmp", *store_params.model, store_params.plate_data_list, store_params.project_presets, store_params.config, - store_params.thumbnail_data, store_params.top_thumbnail_data, store_params.pick_thumbnail_data, store_params.proFn, + store_params.thumbnail_data, store_params.no_light_thumbnail_data, store_params.top_thumbnail_data, store_params.pick_thumbnail_data, + store_params.proFn, store_params.calibration_thumbnail_data, store_params.id_bboxes, store_params.project, store_params.export_plate_idx); if (result) { boost::filesystem::rename(filename + ".tmp", filename, ec); @@ -5632,6 +5641,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) std::vector& project_presets, const DynamicPrintConfig* config, const std::vector& thumbnail_data, + const std::vector& no_light_thumbnail_data, const std::vector& top_thumbnail_data, const std::vector& pick_thumbnail_data, Export3mfProgressFn proFn, @@ -5696,6 +5706,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) //BBS: add thumbnail for each plate if (!m_skip_static) { std::vector thumbnail_status(plate_data_list.size(), false); + std::vector no_light_thumbnail_status(plate_data_list.size(), false); std::vector top_thumbnail_status(plate_data_list.size(), false); std::vector pick_thumbnail_status(plate_data_list.size(), false); @@ -5704,6 +5715,11 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) % thumbnail_data.size() %plate_data_list.size(); return false; } + if ((no_light_thumbnail_data.size() > 0) && (no_light_thumbnail_data.size() > plate_data_list.size())) { + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":" << __LINE__ << boost::format(", no_light_thumbnail_data size %1% > plate count %2%") % + no_light_thumbnail_data.size() % plate_data_list.size(); + return false; + } if ((top_thumbnail_data.size() > 0)&&(top_thumbnail_data.size() > plate_data_list.size())) { BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":" << __LINE__ << boost::format(", top_thumbnail_data size %1% > plate count %2%") % top_thumbnail_data.size() %plate_data_list.size(); @@ -5739,6 +5755,16 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) } } + for (unsigned int index = 0; index < no_light_thumbnail_data.size(); index++) { + if (no_light_thumbnail_data[index]->is_valid()) { + if (!_add_thumbnail_file_to_archive(archive, *no_light_thumbnail_data[index], "Metadata/plate_no_light", index)) { + return false; + } + + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format(",add no light thumbnail %1%'s data into 3mf") % (index + 1); + thumbnail_status[index] = true; + } + } // Adds the file Metadata/top_i.png and Metadata/pick_i.png for (unsigned int index = 0; index < top_thumbnail_data.size(); index++) { @@ -5774,6 +5800,16 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) } } + if (!no_light_thumbnail_status[i] && !plate_data->no_light_thumbnail_file.empty() && (boost::filesystem::exists(plate_data->no_light_thumbnail_file))){ + std::string dst_in_3mf = (boost::format("Metadata/plate_no_light_%1%.png") % (i + 1)).str(); + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" <<__LINE__ << boost::format(", add no light thumbnail %1% from file %2%") % (i+1) %plate_data->no_light_thumbnail_file; + + if (!_add_file_to_archive(archive, dst_in_3mf, plate_data->no_light_thumbnail_file)) { + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":" << __LINE__ << boost::format(", add no light thumbnail %1% from file %2% failed\n") % (i+1) %plate_data->no_light_thumbnail_file; + return false; + } + } + if (!top_thumbnail_status[i] && !plate_data->top_file.empty() && (boost::filesystem::exists(plate_data->top_file))){ std::string dst_in_3mf = (boost::format("Metadata/top_%1%.png") % (i + 1)).str(); @@ -7468,6 +7504,11 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << THUMBNAIL_FILE_ATTR << "\" " << VALUE_ATTR << "=\"" << std::boolalpha << thumbnail_file_in_3mf << "\"/>\n"; } + if (!plate_data->no_light_thumbnail_file.empty()){ + std::string no_light_thumbnail_file_in_3mf = (boost::format(NO_LIGHT_THUMBNAIL_FILE_FORMAT) % (plate_data->plate_index + 1)).str(); + stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << NO_LIGHT_THUMBNAIL_FILE_ATTR << "\" " << VALUE_ATTR << "=\"" << std::boolalpha << no_light_thumbnail_file_in_3mf << "\"/>\n"; + } + if (!plate_data->top_file.empty()) { std::string top_file_in_3mf = (boost::format(TOP_FILE_FORMAT) % (plate_data->plate_index + 1)).str(); stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << TOP_FILE_ATTR << "\" " << VALUE_ATTR << "=\"" << std::boolalpha << top_file_in_3mf << "\"/>\n"; diff --git a/src/libslic3r/Format/bbs_3mf.hpp b/src/libslic3r/Format/bbs_3mf.hpp index d2f46be3e0..6d0c092b77 100644 --- a/src/libslic3r/Format/bbs_3mf.hpp +++ b/src/libslic3r/Format/bbs_3mf.hpp @@ -21,6 +21,7 @@ struct ThumbnailData; #define GCODE_FILE_FORMAT "Metadata/plate_%1%.gcode" #define THUMBNAIL_FILE_FORMAT "Metadata/plate_%1%.png" +#define NO_LIGHT_THUMBNAIL_FILE_FORMAT "Metadata/plate_no_light_%1%.png" #define TOP_FILE_FORMAT "Metadata/top_%1%.png" #define PICK_FILE_FORMAT "Metadata/pick_%1%.png" //#define PATTERN_FILE_FORMAT "Metadata/plate_%1%_pattern_layer_0.png" @@ -75,6 +76,7 @@ struct PlateData std::string gcode_file; std::string gcode_file_md5; std::string thumbnail_file; + std::string no_light_thumbnail_file; ThumbnailData plate_thumbnail; std::string top_file; std::string pick_file; @@ -213,6 +215,7 @@ struct StoreParams std::vector project_presets; DynamicPrintConfig* config; std::vector thumbnail_data; + std::vector no_light_thumbnail_data; std::vector top_thumbnail_data; std::vector pick_thumbnail_data; std::vector calibration_thumbnail_data; diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 1185e44caa..20f5310592 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -6657,9 +6657,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."); @@ -6692,6 +6697,12 @@ CLIActionsConfigDef::CLIActionsConfigDef() def->cli = "uptodate"; def->set_default_value(new ConfigOptionBool(false)); + 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_defaultfila", coBool); def->label = "Load default filaments"; def->tooltip = "Load first filament as default for those not loaded"; @@ -6945,6 +6956,17 @@ CLIMiscConfigDef::CLIMiscConfigDef() def->cli_params = "\"filament1.json;filament2.json;...\""; def->set_default_value(new ConfigOptionStrings()); + def = this->add("downward_check", coBool); + def->label = "downward machines check"; + def->tooltip = "if enabled, check whether current machine downward compatible with the machines in the list"; + def->set_default_value(new ConfigOptionBool(false)); + + def = this->add("downward_settings", coStrings); + def->label = "downward machines settings"; + def->tooltip = "the machine settings list need to do downward checking"; + 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"; diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index 52fc38c8aa..86ab5d2239 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -66,17 +66,22 @@ void glAssertRecentCallImpl(const char* file_name, unsigned int line, const char // BBS std::vector get_extruders_colors() { - Slic3r::ColorRGBA rgba_color; - std::vector colors = Slic3r::GUI::wxGetApp().plater()->get_extruder_colors_from_plater_config(); + unsigned char rgba_color[4] = {}; + std::vector colors = Slic3r::GUI::wxGetApp().plater()->get_extruder_colors_from_plater_config(); std::vector colors_out(colors.size()); for (const std::string &color : colors) { - Slic3r::decode_color(color, rgba_color); + Slic3r::GUI::BitmapCache::parse_color4(color, rgba_color); size_t color_idx = &color - &colors.front(); - colors_out[color_idx] = rgba_color; + colors_out[color_idx] = { + float(rgba_color[0]) / 255.f, + float(rgba_color[1]) / 255.f, + float(rgba_color[2]) / 255.f, + float(rgba_color[3]) / 255.f, + }; } - return colors_out; } + float FullyTransparentMaterialThreshold = 0.1f; float FullTransparentModdifiedToFixAlpha = 0.3f; float FULL_BLACK_THRESHOLD = 0.18f; @@ -464,7 +469,7 @@ void GLVolume::render_with_outline(const Transform3d &view_model_matrix) } //BBS add render for simple case -void GLVolume::simple_render(GLShaderProgram* shader, ModelObjectPtrs& model_objects, std::vector extruder_colors) +void GLVolume::simple_render(GLShaderProgram* shader, ModelObjectPtrs& model_objects, std::vector& extruder_colors, bool ban_light) { if (this->is_left_handed()) glFrontFace(GL_CW); @@ -510,22 +515,36 @@ void GLVolume::simple_render(GLShaderProgram* shader, ModelObjectPtrs& model_obj if (!m.is_initialized()) continue; - if (idx == 0) { - int extruder_id = model_volume->extruder_id(); - //to make black not too hard too see - ColorRGBA new_color = adjust_color_for_rendering(extruder_colors[extruder_id - 1]); - m.set_color(new_color); - } - else { - if (idx <= extruder_colors.size()) { + if (shader) { + if (idx == 0) { + int extruder_id = model_volume->extruder_id(); //to make black not too hard too see - ColorRGBA new_color = adjust_color_for_rendering(extruder_colors[idx - 1]); + ColorRGBA new_color = adjust_color_for_rendering(extruder_colors[extruder_id - 1]); + if (ban_light) { + new_color[3] = (255 - (extruder_id - 1))/255.0f; + } m.set_color(new_color); + // shader->set_uniform("uniform_color", new_color); } else { - //to make black not too hard too see - ColorRGBA new_color = adjust_color_for_rendering(extruder_colors[0]); - m.set_color(new_color); + if (idx <= extruder_colors.size()) { + //to make black not too hard too see + ColorRGBA new_color = adjust_color_for_rendering(extruder_colors[idx - 1]); + if (ban_light) { + new_color[3] = (255 - (idx - 1))/255.0f; + } + m.set_color(new_color); + // shader->set_uniform("uniform_color", new_color); + } + else { + //to make black not too hard too see + ColorRGBA new_color = adjust_color_for_rendering(extruder_colors[0]); + if (ban_light) { + new_color[3] = (255 - 0) / 255.0f; + } + m.set_color(new_color); + // shader->set_uniform("uniform_color", new_color); + } } } if (tverts_range == std::make_pair(0, -1)) diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index 1b58dd6dec..4479c24632 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -325,7 +325,7 @@ public: virtual void render_with_outline(const Transform3d &view_model_matrix); //BBS: add simple render function for thumbnail - void simple_render(GLShaderProgram* shader, ModelObjectPtrs& model_objects, std::vector extruder_colors); + void simple_render(GLShaderProgram* shader, ModelObjectPtrs& model_objects, std::vector& extruder_colors, bool ban_light =false); void set_bounding_boxes_as_dirty() { m_transformed_bounding_box.reset(); diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 16d9beff1a..f63f666e90 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2051,13 +2051,24 @@ void GLCanvas3D::render(bool only_init) m_render_stats.increment_fps_counter(); } -void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, Camera::EType camera_type, bool use_top_view, bool for_picking) +void GLCanvas3D::render_thumbnail(ThumbnailData & thumbnail_data, + unsigned int w, + unsigned int h, + const ThumbnailsParams &thumbnail_params, + Camera::EType camera_type, + bool use_top_view, + bool for_picking, + bool ban_light) { - render_thumbnail(thumbnail_data, w, h, thumbnail_params, m_volumes, camera_type, use_top_view, for_picking); + render_thumbnail(thumbnail_data, w, h, thumbnail_params, m_volumes, camera_type, use_top_view, for_picking, ban_light); } void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, - const GLVolumeCollection& volumes, Camera::EType camera_type, bool use_top_view, bool for_picking) + const GLVolumeCollection &volumes, + Camera::EType camera_type, + bool use_top_view, + bool for_picking, + bool ban_light) { GLShaderProgram* shader = nullptr; if (for_picking) @@ -2069,14 +2080,19 @@ void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, switch (OpenGLManager::get_framebuffers_type()) { case OpenGLManager::EFramebufferType::Arb: - { render_thumbnail_framebuffer(thumbnail_data, w, h, thumbnail_params, - wxGetApp().plater()->get_partplate_list(), model_objects, volumes, colors, shader, camera_type, use_top_view, for_picking); break; } + { render_thumbnail_framebuffer(thumbnail_data, w, h, thumbnail_params, wxGetApp().plater()->get_partplate_list(), model_objects, volumes, colors, shader, camera_type, + use_top_view, for_picking, ban_light); + break; + } case OpenGLManager::EFramebufferType::Ext: - { render_thumbnail_framebuffer_ext(thumbnail_data, w, h, thumbnail_params, - wxGetApp().plater()->get_partplate_list(), model_objects, volumes, colors, shader, camera_type, use_top_view, for_picking); break; } + { render_thumbnail_framebuffer_ext(thumbnail_data, w, h, thumbnail_params, wxGetApp().plater()->get_partplate_list(), model_objects, volumes, colors, shader, camera_type, + use_top_view, for_picking, ban_light); + break; + } default: - { render_thumbnail_legacy(thumbnail_data, w, h, thumbnail_params, - wxGetApp().plater()->get_partplate_list(), model_objects, volumes, colors, shader, camera_type); break; } + { render_thumbnail_legacy(thumbnail_data, w, h, thumbnail_params, wxGetApp().plater()->get_partplate_list(), model_objects, volumes, colors, shader, camera_type); + break; + } } } @@ -5733,7 +5749,7 @@ static void debug_output_thumbnail(const ThumbnailData& thumbnail_data) void GLCanvas3D::render_thumbnail_internal(ThumbnailData& thumbnail_data, const ThumbnailsParams& thumbnail_params, PartPlateList& partplate_list, ModelObjectPtrs& model_objects, const GLVolumeCollection& volumes, std::vector& extruder_colors, - GLShaderProgram* shader, Camera::EType camera_type, bool use_top_view, bool for_picking) + GLShaderProgram* shader, Camera::EType camera_type, bool use_top_view, bool for_picking, bool ban_light) { //BBS modify visible calc function int plate_idx = thumbnail_params.plate_id; @@ -5849,7 +5865,9 @@ void GLCanvas3D::render_thumbnail_internal(ThumbnailData& thumbnail_data, const glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); glsafe(::glEnable(GL_DEPTH_TEST)); - + if (ban_light) { + glsafe(::glDisable(GL_BLEND)); + } const Transform3d &projection_matrix = camera.get_projection_matrix(); if (for_picking) { @@ -5903,12 +5921,16 @@ void GLCanvas3D::render_thumbnail_internal(ThumbnailData& thumbnail_data, const else { shader->start_using(); shader->set_uniform("emission_factor", 0.1f); + shader->set_uniform("ban_light", ban_light); for (GLVolume* vol : visible_volumes) { //BBS set render color for thumbnails curr_color = vol->color; ColorRGBA new_color = adjust_color_for_rendering(curr_color); - vol->model.set_color(new_color); + if (ban_light) { + new_color[3] = (255 - vol->extruder_id) / 255.0f; + } + vol->model.set_color(new_color); shader->set_uniform("volume_world_matrix", vol->world_matrix()); //BBS set all volume to orange //shader->set_uniform("uniform_color", orange); @@ -5926,7 +5948,7 @@ void GLCanvas3D::render_thumbnail_internal(ThumbnailData& thumbnail_data, const shader->set_uniform("projection_matrix", projection_matrix); const Matrix3d view_normal_matrix = view_matrix.matrix().block(0, 0, 3, 3) * model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose(); shader->set_uniform("view_normal_matrix", view_normal_matrix); - vol->simple_render(shader, model_objects, extruder_colors); + vol->simple_render(shader, model_objects, extruder_colors, ban_light); vol->is_active = is_active; } shader->stop_using(); @@ -5945,7 +5967,7 @@ void GLCanvas3D::render_thumbnail_internal(ThumbnailData& thumbnail_data, const void GLCanvas3D::render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, PartPlateList& partplate_list, ModelObjectPtrs& model_objects, const GLVolumeCollection& volumes, std::vector& extruder_colors, - GLShaderProgram* shader, Camera::EType camera_type, bool use_top_view, bool for_picking) + GLShaderProgram* shader, Camera::EType camera_type, bool use_top_view, bool for_picking, bool ban_light) { thumbnail_data.set(w, h); if (!thumbnail_data.is_valid()) @@ -5998,7 +6020,8 @@ void GLCanvas3D::render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, uns glsafe(::glDrawBuffers(1, drawBufs)); if (::glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE) { - render_thumbnail_internal(thumbnail_data, thumbnail_params, partplate_list, model_objects, volumes, extruder_colors, shader, camera_type, use_top_view, for_picking); + render_thumbnail_internal(thumbnail_data, thumbnail_params, partplate_list, model_objects, volumes, extruder_colors, shader, + camera_type, use_top_view, for_picking,ban_light); if (multisample) { GLuint resolve_fbo; @@ -6053,7 +6076,7 @@ void GLCanvas3D::render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, uns void GLCanvas3D::render_thumbnail_framebuffer_ext(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, PartPlateList& partplate_list, ModelObjectPtrs& model_objects, const GLVolumeCollection& volumes, std::vector& extruder_colors, - GLShaderProgram* shader, Camera::EType camera_type, bool use_top_view, bool for_picking) + GLShaderProgram* shader, Camera::EType camera_type, bool use_top_view, bool for_picking, bool ban_light) { thumbnail_data.set(w, h); if (!thumbnail_data.is_valid()) @@ -6105,7 +6128,8 @@ void GLCanvas3D::render_thumbnail_framebuffer_ext(ThumbnailData& thumbnail_data, glsafe(::glDrawBuffers(1, drawBufs)); if (::glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT) { - render_thumbnail_internal(thumbnail_data, thumbnail_params, partplate_list, model_objects, volumes, extruder_colors, shader, camera_type, use_top_view, for_picking); + render_thumbnail_internal(thumbnail_data, thumbnail_params, partplate_list, model_objects, volumes, extruder_colors, shader, camera_type, use_top_view, for_picking, + ban_light); if (multisample) { GLuint resolve_fbo; diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index c5a3a1562a..ad4d21cf3a 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -874,20 +874,27 @@ public: // printable_only == false -> render also non printable volumes as grayed // parts_only == false -> render also sla support and pad void render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, - Camera::EType camera_type, bool use_top_view = false, bool for_picking = false); + Camera::EType camera_type, + bool use_top_view = false, + bool for_picking = false, + bool ban_light = false); void render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, - const GLVolumeCollection& volumes, Camera::EType camera_type, bool use_top_view = false, bool for_picking = false); + const GLVolumeCollection &volumes, + Camera::EType camera_type, + bool use_top_view = false, + bool for_picking = false, + bool ban_light = false); static void render_thumbnail_internal(ThumbnailData& thumbnail_data, const ThumbnailsParams& thumbnail_params, PartPlateList& partplate_list, ModelObjectPtrs& model_objects, const GLVolumeCollection& volumes, std::vector& extruder_colors, - GLShaderProgram* shader, Camera::EType camera_type, bool use_top_view = false, bool for_picking = false); + GLShaderProgram* shader, Camera::EType camera_type, bool use_top_view = false, bool for_picking = false, bool ban_light = false); // render thumbnail using an off-screen framebuffer static void render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, PartPlateList& partplate_list, ModelObjectPtrs& model_objects, const GLVolumeCollection& volumes, std::vector& extruder_colors, - GLShaderProgram* shader, Camera::EType camera_type, bool use_top_view = false, bool for_picking = false); + GLShaderProgram* shader, Camera::EType camera_type, bool use_top_view = false, bool for_picking = false, bool ban_light = false); // render thumbnail using an off-screen framebuffer when GLEW_EXT_framebuffer_object is supported static void render_thumbnail_framebuffer_ext(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, PartPlateList& partplate_list, ModelObjectPtrs& model_objects, const GLVolumeCollection& volumes, std::vector& extruder_colors, - GLShaderProgram* shader, Camera::EType camera_type, bool use_top_view = false, bool for_picking = false); + GLShaderProgram* shader, Camera::EType camera_type, bool use_top_view = false, bool for_picking = false, bool ban_light = false); //BBS use gcoder viewer render calibration thumbnails void render_calibration_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params); diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index 5817a47ebb..44d430d2d1 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -36,6 +36,7 @@ #define TIMEOUT_RESPONSE 15 #define BE_UNACTED_ON 0x00200001 +#define SHOW_BACKGROUND_BITMAP_PIXEL_THRESHOLD 80 #ifndef _MSW_DARK_MODE #define _MSW_DARK_MODE 1 #endif // _MSW_DARK_MODE diff --git a/src/slic3r/GUI/PartPlate.cpp b/src/slic3r/GUI/PartPlate.cpp index 6c4a75f06f..907525c190 100644 --- a/src/slic3r/GUI/PartPlate.cpp +++ b/src/slic3r/GUI/PartPlate.cpp @@ -287,7 +287,7 @@ PrintSequence PartPlate::get_real_print_seq(bool* plate_same_as_global) const if (curr_plate_seq == PrintSequence::ByDefault) { curr_plate_seq = global_print_seq; } - + if(plate_same_as_global) *plate_same_as_global = (curr_plate_seq == global_print_seq); @@ -2145,6 +2145,27 @@ int PartPlate::remove_instance(int obj_id, int instance_id) return result; } +BoundingBoxf3 PartPlate::get_objects_bounding_box() +{ + BoundingBoxf3 bbox; + for (std::set>::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) { @@ -4083,6 +4104,7 @@ int PartPlateList::notify_instance_update(int obj_id, int instance_id, bool is_n PartPlate* plate = m_plate_list[obj_id - 1000]; plate->update_slice_result_valid_state( false ); plate->thumbnail_data.reset(); + plate->no_light_thumbnail_data.reset(); plate->top_thumbnail_data.reset(); plate->pick_thumbnail_data.reset(); @@ -4113,12 +4135,14 @@ int PartPlateList::notify_instance_update(int obj_id, int instance_id, bool is_n plate->update_states(); plate->update_slice_result_valid_state(); plate->thumbnail_data.reset(); + plate->no_light_thumbnail_data.reset(); plate->top_thumbnail_data.reset(); plate->pick_thumbnail_data.reset(); return 0; } plate->update_slice_result_valid_state(); plate->thumbnail_data.reset(); + plate->no_light_thumbnail_data.reset(); plate->top_thumbnail_data.reset(); plate->pick_thumbnail_data.reset(); } @@ -4164,7 +4188,7 @@ int PartPlateList::notify_instance_update(int obj_id, int instance_id, bool is_n { //found a new plate, add it to plate plate->add_instance(obj_id, instance_id, false, &boundingbox); - + // spiral mode, update object setting if (plate->config()->has("spiral_mode") && plate->config()->opt_bool("spiral_mode") && !is_object_config_compatible_with_spiral_vase(object)) { if (!is_new) { @@ -4180,6 +4204,7 @@ int PartPlateList::notify_instance_update(int obj_id, int instance_id, bool is_n plate->update_slice_result_valid_state(); plate->thumbnail_data.reset(); + plate->no_light_thumbnail_data.reset(); plate->top_thumbnail_data.reset(); plate->pick_thumbnail_data.reset(); BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": add it to new plate %1%") % i; @@ -4217,6 +4242,7 @@ int PartPlateList::notify_instance_removed(int obj_id, int instance_id) plate->remove_instance(obj_id, instance_to_delete); plate->update_slice_result_valid_state(); plate->thumbnail_data.reset(); + plate->no_light_thumbnail_data.reset(); plate->top_thumbnail_data.reset(); plate->pick_thumbnail_data.reset(); } @@ -5141,6 +5167,8 @@ int PartPlateList::store_to_3mf_structure(PlateDataPtrs& plate_data_list, bool w %(i+1) %plate_data_item->plate_thumbnail.width %plate_data_item->plate_thumbnail.height %plate_data_item->plate_thumbnail.pixels.size(); plate_data_item->config.apply(*m_plate_list[i]->config()); + if (m_plate_list[i]->no_light_thumbnail_data.is_valid()) + plate_data_item->no_light_thumbnail_file = "valid_no_light"; if (m_plate_list[i]->top_thumbnail_data.is_valid()) plate_data_item->top_file = "valid_top"; if (m_plate_list[i]->pick_thumbnail_data.is_valid()) @@ -5256,6 +5284,13 @@ int PartPlateList::load_from_3mf_structure(PlateDataPtrs& plate_data_list) } } + if (m_plater && !plate_data_list[i]->no_light_thumbnail_file.empty()) { + if (boost::filesystem::exists(plate_data_list[i]->no_light_thumbnail_file)) { + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": plate %1%, load no_light_thumbnail_file from %2%.")%(i+1) %plate_data_list[i]->no_light_thumbnail_file; + m_plate_list[index]->load_thumbnail_data(plate_data_list[i]->no_light_thumbnail_file, m_plate_list[index]->no_light_thumbnail_data); + } + } + /*if (m_plater && !plate_data_list[i]->pattern_file.empty()) { if (boost::filesystem::exists(plate_data_list[i]->pattern_file)) { //no need to load pattern data currently diff --git a/src/slic3r/GUI/PartPlate.hpp b/src/slic3r/GUI/PartPlate.hpp index 530b994181..e0b0e90ace 100644 --- a/src/slic3r/GUI/PartPlate.hpp +++ b/src/slic3r/GUI/PartPlate.hpp @@ -246,6 +246,7 @@ public: //static const int plate_x_offset = 20; //mm //static const double plate_x_gap = 0.2; ThumbnailData thumbnail_data; + ThumbnailData no_light_thumbnail_data; static const int plate_thumbnail_width = 512; static const int plate_thumbnail_height = 512; @@ -295,6 +296,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 d, int plate_extruder_size = 0, bool use_global_objects = false) const; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 8aea8262bd..f27cad243c 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2555,7 +2555,7 @@ struct Plater::priv //BBS: add plate_id for thumbnail void generate_thumbnail(ThumbnailData& data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, - Camera::EType camera_type, bool use_top_view = false, bool for_picking = false); + Camera::EType camera_type, bool use_top_view = false, bool for_picking = false,bool ban_light = false); ThumbnailsList generate_thumbnails(const ThumbnailsParams& params, Camera::EType camera_type); //BBS void generate_calibration_thumbnail(ThumbnailData& data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params); @@ -7482,10 +7482,9 @@ void Plater::priv::on_3dcanvas_mouse_dragging_finished(SimpleEvent&) } //BBS: add plate id for thumbnail generate param -void Plater::priv::generate_thumbnail(ThumbnailData& data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, - Camera::EType camera_type, bool use_top_view, bool for_picking) +void Plater::priv::generate_thumbnail(ThumbnailData& data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, Camera::EType camera_type, bool use_top_view, bool for_picking, bool ban_light) { - view3D->get_canvas3d()->render_thumbnail(data, w, h, thumbnail_params, camera_type, use_top_view, for_picking); + view3D->get_canvas3d()->render_thumbnail(data, w, h, thumbnail_params, camera_type, use_top_view, for_picking, ban_light); } //BBS: add plate id for thumbnail generate param @@ -9978,6 +9977,10 @@ void Plater::update_all_plate_thumbnails(bool force_update) if (force_update || !plate->thumbnail_data.is_valid()) { get_view3D_canvas3D()->render_thumbnail(plate->thumbnail_data, plate->plate_thumbnail_width, plate->plate_thumbnail_height, thumbnail_params, Camera::EType::Ortho); } + if (force_update || !plate->no_light_thumbnail_data.is_valid()) { + get_view3D_canvas3D()->render_thumbnail(plate->no_light_thumbnail_data, plate->plate_thumbnail_width, plate->plate_thumbnail_height, thumbnail_params, + Camera::EType::Ortho,false,false,true); + } } } @@ -9990,6 +9993,7 @@ void Plater::invalid_all_plate_thumbnails() for (int i = 0; i < get_partplate_list().get_plate_count(); i++) { PartPlate* plate = get_partplate_list().get_plate(i); plate->thumbnail_data.reset(); + plate->no_light_thumbnail_data.reset(); } } @@ -11819,6 +11823,7 @@ int Plater::export_3mf(const boost::filesystem::path& output_path, SaveStrategy //BBS: add plate logic for thumbnail generate std::vector thumbnails; + std::vector no_light_thumbnails; std::vector calibration_thumbnails; std::vector top_thumbnails; std::vector picking_thumbnails; @@ -11839,6 +11844,17 @@ int Plater::export_3mf(const boost::filesystem::path& output_path, SaveStrategy } thumbnails.push_back(thumbnail_data); + ThumbnailData *no_light_thumbnail_data = &p->partplate_list.get_plate(i)->no_light_thumbnail_data; + if (p->partplate_list.get_plate(i)->no_light_thumbnail_data.is_valid() && using_exported_file()) { + // no need to generate thumbnail + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": non need to re-generate thumbnail for gcode/exported mode of plate %1%") % i; + } else { + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": re-generate thumbnail for plate %1%") % i; + const ThumbnailsParams thumbnail_params = {{}, false, true, true, true, i}; + p->generate_thumbnail(p->partplate_list.get_plate(i)->no_light_thumbnail_data, THUMBNAIL_SIZE_3MF.first, THUMBNAIL_SIZE_3MF.second, + thumbnail_params, Camera::EType::Ortho,false,false,true); + } + no_light_thumbnails.push_back(no_light_thumbnail_data); //ThumbnailData* calibration_data = &p->partplate_list.get_plate(i)->cali_thumbnail_data; //calibration_thumbnails.push_back(calibration_data); PlateBBoxData* plate_bbox_data = &p->partplate_list.get_plate(i)->cali_bboxes_data; @@ -11902,6 +11918,7 @@ int Plater::export_3mf(const boost::filesystem::path& output_path, SaveStrategy store_params.project_presets = project_presets; store_params.config = export_config ? &cfg : nullptr; store_params.thumbnail_data = thumbnails; + store_params.no_light_thumbnail_data = no_light_thumbnails; store_params.top_thumbnail_data = top_thumbnails; store_params.pick_thumbnail_data = picking_thumbnails; store_params.calibration_thumbnail_data = calibration_thumbnails; @@ -11995,6 +12012,10 @@ int Plater::export_3mf(const boost::filesystem::path& output_path, SaveStrategy //release the data here, as it will always be generated when export calibration_thumbnails[i]->reset(); } + for (unsigned int i = 0; i < no_light_thumbnails.size(); i++) { + // release the data here, as it will always be generated when export + no_light_thumbnails[i]->reset(); + } for (unsigned int i = 0; i < top_thumbnails.size(); i++) { //release the data here, as it will always be generated when export diff --git a/src/slic3r/GUI/SelectMachine.cpp b/src/slic3r/GUI/SelectMachine.cpp index 612e3f8ec7..416f047e19 100644 --- a/src/slic3r/GUI/SelectMachine.cpp +++ b/src/slic3r/GUI/SelectMachine.cpp @@ -24,6 +24,7 @@ #include #include #include "Plater.hpp" +#include "Notebook.hpp" #include "BitmapCache.hpp" #include "BindDialog.hpp" @@ -1825,6 +1826,10 @@ void SelectMachineDialog::sync_ams_mapping_result(std::vector &res iter++; } } + auto tab_index = (MainFrame::TabPosition) dynamic_cast(wxGetApp().tab_panel())->GetSelection(); + if (tab_index == MainFrame::TabPosition::tp3DEditor || tab_index == MainFrame::TabPosition::tpPreview) { + updata_thumbnail_data_after_connected_printer(); + } } void print_ams_mapping_result(std::vector& result) @@ -1843,7 +1848,7 @@ void print_ams_mapping_result(std::vector& result) bool SelectMachineDialog::do_ams_mapping(MachineObject *obj_) { if (!obj_) return false; - + obj_->get_ams_colors(m_cur_colors_in_thumbnail); // try color and type mapping int result = obj_->ams_filament_mapping(m_filaments, m_ams_mapping_result); if (result == 0) { @@ -2574,6 +2579,7 @@ void SelectMachineDialog::on_ok_btn(wxCommandEvent &event) if (!obj_->nozzle_type.empty() && (m_print_type == PrintFromType::FROM_NORMAL)) { if (!is_same_nozzle_diameters(tag_nozzle_type, nozzle_diameter)) { has_slice_warnings = true; + is_printing_block = true; wxString nozzle_in_preset = wxString::Format(_L("nozzle in preset: %s %s"),nozzle_diameter, ""); wxString nozzle_in_printer = wxString::Format(_L("nozzle memorized: %.2f %s"), obj_->nozzle_diameter, ""); @@ -2945,6 +2951,14 @@ void SelectMachineDialog::on_set_finish_mapping(wxCommandEvent &evt) BOOST_LOG_TRIVIAL(info) << "The ams mapping selection result: data is " << selection_data; if (selection_data_arr.size() == 6) { + auto ams_colour = wxColour(wxAtoi(selection_data_arr[0]), wxAtoi(selection_data_arr[1]), wxAtoi(selection_data_arr[2]), wxAtoi(selection_data_arr[3])); + int old_filament_id = (int) wxAtoi(selection_data_arr[5]); + if (m_print_type == PrintFromType::FROM_NORMAL) {//todo:support sd card + change_default_normal(old_filament_id, ams_colour); + final_deal_edge_pixels_data(m_preview_thumbnail_data); + set_default_normal(m_preview_thumbnail_data); // do't reset ams + } + int ctype = 0; std::vector material_cols; std::vector tray_cols; @@ -3350,8 +3364,6 @@ void SelectMachineDialog::on_selection_changed(wxCommandEvent &event) show_status(PrintDialogStatus::PrintStatusInit); - reset_ams_material(); - update_show_status(); } @@ -3926,20 +3938,399 @@ void SelectMachineDialog::set_default() m_checkbox_list["use_ams"]->SetValue(true); if (m_print_type == PrintFromType::FROM_NORMAL) { - set_default_normal(); + reset_and_sync_ams_list(); + set_default_normal(m_plater->get_partplate_list().get_curr_plate()->thumbnail_data); } else if (m_print_type == PrintFromType::FROM_SDCARD_VIEW) { + //todo:unify_deal_thumbnail_data(input_data, no_light_data);this include m_print_type = PrintFromType::FROM_SDCARD_VIEW + //and notice update_page_turn_state(true) set_default_from_sdcard(); } - + Layout(); Fit(); } -void SelectMachineDialog::set_default_normal() +void SelectMachineDialog::reset_and_sync_ams_list() +{ + // for black list + std::vector materials; + std::vector brands; + std::vector display_materials; + std::vector m_filaments_id; + auto preset_bundle = wxGetApp().preset_bundle; + + for (auto filament_name : preset_bundle->filament_presets) { + for (int f_index = 0; f_index < preset_bundle->filaments.size(); f_index++) { + PresetCollection *filament_presets = &wxGetApp().preset_bundle->filaments; + Preset * preset = &filament_presets->preset(f_index); + + if (preset && filament_name.compare(preset->name) == 0) { + std::string display_filament_type; + std::string filament_type = preset->config.get_filament_type(display_filament_type); + std::string m_filament_id = preset->filament_id; + display_materials.push_back(display_filament_type); + materials.push_back(filament_type); + m_filaments_id.push_back(m_filament_id); + + std::string m_vendor_name = ""; + auto vendor = dynamic_cast(preset->config.option("filament_vendor")); + if (vendor && (vendor->values.size() > 0)) { + std::string vendor_name = vendor->values[0]; + m_vendor_name = vendor_name; + } + brands.push_back(m_vendor_name); + } + } + } + + auto extruders = wxGetApp().plater()->get_partplate_list().get_curr_plate()->get_used_extruders(); + BitmapCache bmcache; + MaterialHash::iterator iter = m_materialList.begin(); + while (iter != m_materialList.end()) { + int id = iter->first; + Material *item = iter->second; + item->item->Destroy(); + delete item; + iter++; + } + + m_sizer_material->Clear(); + m_materialList.clear(); + m_filaments.clear(); + + for (auto i = 0; i < extruders.size(); i++) { + auto extruder = extruders[i] - 1; + auto colour = wxGetApp().preset_bundle->project_config.opt_string("filament_colour", (unsigned int) extruder); + unsigned char rgb[4]; + bmcache.parse_color4(colour, rgb); + + auto colour_rgb = wxColour((int) rgb[0], (int) rgb[1], (int) rgb[2], (int) rgb[3]); + if (extruder >= materials.size() || extruder < 0 || extruder >= display_materials.size()) continue; + + MaterialItem *item = new MaterialItem(m_scrollable_region, colour_rgb, _L(display_materials[extruder])); + m_sizer_material->Add(item, 0, wxALL, FromDIP(4)); + + item->Bind(wxEVT_LEFT_UP, [this, item, materials, extruder](wxMouseEvent &e) {}); + item->Bind(wxEVT_LEFT_DOWN, [this, item, materials, extruder](wxMouseEvent &e) { + MaterialHash::iterator iter = m_materialList.begin(); + while (iter != m_materialList.end()) { + int id = iter->first; + Material * item = iter->second; + MaterialItem *m = item->item; + m->on_normal(); + iter++; + } + + m_current_filament_id = extruder; + item->on_selected(); + + auto mouse_pos = ClientToScreen(e.GetPosition()); + wxPoint rect = item->ClientToScreen(wxPoint(0, 0)); + + // update ams data + DeviceManager *dev_manager = Slic3r::GUI::wxGetApp().getDeviceManager(); + if (!dev_manager) return; + MachineObject *obj_ = dev_manager->get_selected_machine(); + + if (obj_ && obj_->is_support_ams_mapping()) { + if (m_mapping_popup.IsShown()) return; + wxPoint pos = item->ClientToScreen(wxPoint(0, 0)); + pos.y += item->GetRect().height; + m_mapping_popup.Move(pos); + + if (obj_ && obj_->has_ams() && m_checkbox_list["use_ams"]->GetValue() && obj_->dev_id == m_printer_last_select) { + m_mapping_popup.set_parent_item(item); + m_mapping_popup.set_current_filament_id(extruder); + m_mapping_popup.set_tag_texture(materials[extruder]); + m_mapping_popup.update_ams_data(obj_->amsList); + m_mapping_popup.Popup(); + } + } + }); + + Material *material_item = new Material(); + material_item->id = extruder; + material_item->item = item; + m_materialList[i] = material_item; + + // build for ams mapping + if (extruder < materials.size() && extruder >= 0) { + FilamentInfo info; + info.id = extruder; + info.type = materials[extruder]; + info.brand = brands[extruder]; + info.filament_id = m_filaments_id[extruder]; + info.color = wxString::Format("#%02X%02X%02X%02X", colour_rgb.Red(), colour_rgb.Green(), colour_rgb.Blue(), colour_rgb.Alpha()).ToStdString(); + m_filaments.push_back(info); + } + } + + if (extruders.size() <= 4) { + m_sizer_material->SetCols(extruders.size()); + } else { + m_sizer_material->SetCols(4); + } + + // reset_ams_material();//show "-" +} + +void SelectMachineDialog::clone_thumbnail_data() { + //record preview_colors + MaterialHash::iterator iter = m_materialList.begin(); + if (m_preview_colors_in_thumbnail.size() != m_materialList.size()) { + m_preview_colors_in_thumbnail.resize(m_materialList.size()); + } + while (iter != m_materialList.end()) { + int id = iter->first; + Material * item = iter->second; + MaterialItem *m = item->item; + m_preview_colors_in_thumbnail[id] = m->m_material_coloul; + if (item->id < m_cur_colors_in_thumbnail.size()) { + m_cur_colors_in_thumbnail[item->id] = m->m_ams_coloul; + } + else {//exist empty or unrecognized type ams in machine + m_cur_colors_in_thumbnail.resize(item->id + 1); + m_cur_colors_in_thumbnail[item->id] = m->m_ams_coloul; + } + iter++; + } + //copy data + auto &data = m_cur_input_thumbnail_data; + m_preview_thumbnail_data.reset(); + m_preview_thumbnail_data.set(data.width, data.height); + if (data.width > 0 && data.height > 0) { + for (unsigned int r = 0; r < data.height; ++r) { + unsigned int rr = (data.height - 1 - r) * data.width; + for (unsigned int c = 0; c < data.width; ++c) { + unsigned char *origin_px = (unsigned char *) data.pixels.data() + 4 * (rr + c); + unsigned char *new_px = (unsigned char *) m_preview_thumbnail_data.pixels.data() + 4 * (rr + c); + for (size_t i = 0; i < 4; i++) { + new_px[i] = origin_px[i]; + } + } + } + } + //record_edge_pixels_data + record_edge_pixels_data(); +} + +void SelectMachineDialog::record_edge_pixels_data() +{ + auto is_not_in_preview_colors = [this](unsigned char r, unsigned char g , unsigned char b , unsigned char a) { + for (size_t i = 0; i < m_preview_colors_in_thumbnail.size(); i++) { + wxColour render_color = adjust_color_for_render(m_preview_colors_in_thumbnail[i]); + if (render_color.Red() == r && render_color.Green() == g && render_color.Blue() == b /*&& render_color.Alpha() == a*/) { + return false; + } + } + return true; + }; + ThumbnailData &data = m_cur_no_light_thumbnail_data; + ThumbnailData &origin_data = m_cur_input_thumbnail_data; + if (data.width > 0 && data.height > 0) { + m_edge_pixels.resize(data.width * data.height); + for (unsigned int r = 0; r < data.height; ++r) { + unsigned int rr = (data.height - 1 - r) * data.width; + for (unsigned int c = 0; c < data.width; ++c) { + unsigned char *no_light_px = (unsigned char *) data.pixels.data() + 4 * (rr + c); + unsigned char *origin_px = (unsigned char *) origin_data.pixels.data() + 4 * (rr + c); + m_edge_pixels[r * data.width + c] = false; + if (origin_px[3] > 0) { + if (is_not_in_preview_colors(no_light_px[0], no_light_px[1], no_light_px[2], origin_px[3])) { + m_edge_pixels[r * data.width + c] = true; + } + } + } + } + } +} + +wxColour SelectMachineDialog::adjust_color_for_render(const wxColour &color) +{ + ColorRGBA _temp_color_color(color.Red() / 255.0f, color.Green() / 255.0f, color.Blue() / 255.0f, color.Alpha() / 255.0f); + auto _temp_color_color_ = adjust_color_for_rendering(_temp_color_color); + wxColour render_color((int) (_temp_color_color_[0] * 255.0f), (int) (_temp_color_color_[1] * 255.0f), (int) (_temp_color_color_[2] * 255.0f), + (int) (_temp_color_color_[3] * 255.0f)); + return render_color; +} + +void SelectMachineDialog::final_deal_edge_pixels_data(ThumbnailData &data) +{ + if (data.width > 0 && data.height > 0 && m_edge_pixels.size() >0 ) { + for (unsigned int r = 0; r < data.height; ++r) { + unsigned int rr = (data.height - 1 - r) * data.width; + bool exist_rr_up = r >= 1 ? true : false; + bool exist_rr_down = r <= data.height - 2 ? true : false; + unsigned int rr_up = exist_rr_up ? (data.height - 1 - (r - 1)) * data.width : 0; + unsigned int rr_down = exist_rr_down ? (data.height - 1 - (r + 1)) * data.width : 0; + for (unsigned int c = 0; c < data.width; ++c) { + bool exist_c_left = c >= 1 ? true : false; + bool exist_c_right = c <= data.width - 2 ? true : false; + unsigned int c_left = exist_c_left ? c - 1 : 0; + unsigned int c_right = exist_c_right ? c + 1 : 0; + unsigned char *cur_px = (unsigned char *) data.pixels.data() + 4 * (rr + c); + unsigned char *relational_pxs[8] = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; + if (exist_rr_up && exist_c_left) { relational_pxs[0] = (unsigned char *) data.pixels.data() + 4 * (rr_up + c_left); } + if (exist_rr_up) { relational_pxs[1] = (unsigned char *) data.pixels.data() + 4 * (rr_up + c); } + if (exist_rr_up && exist_c_right) { relational_pxs[2] = (unsigned char *) data.pixels.data() + 4 * (rr_up + c_right); } + if (exist_c_left) { relational_pxs[3] = (unsigned char *) data.pixels.data() + 4 * (rr + c_left); } + if (exist_c_right) { relational_pxs[4] = (unsigned char *) data.pixels.data() + 4 * (rr + c_right); } + if (exist_rr_down && exist_c_left) { relational_pxs[5] = (unsigned char *) data.pixels.data() + 4 * (rr_down + c_left); } + if (exist_rr_down) { relational_pxs[6] = (unsigned char *) data.pixels.data() + 4 * (rr_down + c); } + if (exist_rr_down && exist_c_right) { relational_pxs[7] = (unsigned char *) data.pixels.data() + 4 * (rr_down + c_right); } + if (cur_px[3] > 0 && m_edge_pixels[r * data.width + c]) { + int rgba_sum[4] = {0, 0, 0, 0}; + int valid_count = 0; + for (size_t k = 0; k < 8; k++) { + if (relational_pxs[k]) { + if (k == 0 && m_edge_pixels[(r - 1) * data.width + c_left]) { + continue; + } + if (k == 1 && m_edge_pixels[(r - 1) * data.width + c]) { + continue; + } + if (k == 2 && m_edge_pixels[(r - 1) * data.width + c_right]) { + continue; + } + if (k == 3 && m_edge_pixels[r * data.width + c_left]) { + continue; + } + if (k == 4 && m_edge_pixels[r * data.width + c_right]) { + continue; + } + if (k == 5 && m_edge_pixels[(r + 1) * data.width + c_left]) { + continue; + } + if (k == 6 && m_edge_pixels[(r + 1) * data.width + c]) { + continue; + } + if (k == 7 && m_edge_pixels[(r + 1) * data.width + c_right]) { + continue; + } + for (size_t m = 0; m < 4; m++) { + rgba_sum[m] += relational_pxs[k][m]; + } + valid_count++; + } + } + if (valid_count > 0) { + for (size_t m = 0; m < 4; m++) { + cur_px[m] = std::clamp(int(rgba_sum[m] / (float)valid_count), 0, 255); + } + } + } + } + } + } +} + +void SelectMachineDialog::updata_thumbnail_data_after_connected_printer() +{ + // change thumbnail_data + ThumbnailData &input_data = m_plater->get_partplate_list().get_curr_plate()->thumbnail_data; + ThumbnailData &no_light_data = m_plater->get_partplate_list().get_curr_plate()->no_light_thumbnail_data; + if (input_data.width == 0 || input_data.height == 0 || no_light_data.width == 0 || no_light_data.height == 0) { + wxGetApp().plater()->update_all_plate_thumbnails(false); + } + unify_deal_thumbnail_data(input_data, no_light_data); +} + +void SelectMachineDialog::unify_deal_thumbnail_data(ThumbnailData &input_data, ThumbnailData &no_light_data) { + if (input_data.width == 0 || input_data.height == 0 || no_light_data.width == 0 || no_light_data.height == 0) { + BOOST_LOG_TRIVIAL(error) << "SelectMachineDialog::no_light_data is empty,error"; + return; + } + m_cur_input_thumbnail_data = input_data; + m_cur_no_light_thumbnail_data = no_light_data; + clone_thumbnail_data(); + MaterialHash::iterator iter = m_materialList.begin(); + bool is_connect_printer = true; + while (iter != m_materialList.end()) { + int id = iter->first; + Material * item = iter->second; + MaterialItem *m = item->item; + if (m->m_ams_name == "-") { + is_connect_printer = false; + break; + } + iter++; + } + if (is_connect_printer) { + change_default_normal(-1, wxColour()); + final_deal_edge_pixels_data(m_preview_thumbnail_data); + set_default_normal(m_preview_thumbnail_data); + } +} + +void SelectMachineDialog::change_default_normal(int old_filament_id, wxColour temp_ams_color) +{ + if (m_cur_colors_in_thumbnail.size() == 0) { + BOOST_LOG_TRIVIAL(error) << "SelectMachineDialog::change_default_normal:error:m_cur_colors_in_thumbnail.size() == 0"; + return; + } + if (old_filament_id >= 0) { + if (old_filament_id < m_cur_colors_in_thumbnail.size()) { + m_cur_colors_in_thumbnail[old_filament_id] = temp_ams_color; + } + else { + BOOST_LOG_TRIVIAL(error) << "SelectMachineDialog::change_default_normal:error:old_filament_id > m_cur_colors_in_thumbnail.size()"; + return; + } + } + ThumbnailData& data = m_cur_input_thumbnail_data; + ThumbnailData& no_light_data = m_cur_no_light_thumbnail_data; + if (data.width > 0 && data.height > 0 && data.width == no_light_data.width && data.height == no_light_data.height) { + for (unsigned int r = 0; r < data.height; ++r) { + unsigned int rr = (data.height - 1 - r) * data.width; + for (unsigned int c = 0; c < data.width; ++c) { + unsigned char *no_light_px = (unsigned char *) no_light_data.pixels.data() + 4 * (rr + c); + unsigned char *origin_px = (unsigned char *) data.pixels.data() + 4 * (rr + c); + unsigned char *new_px = (unsigned char *) m_preview_thumbnail_data.pixels.data() + 4 * (rr + c); + if (origin_px[3] > 0 && m_edge_pixels[r * data.width + c] == false) { + auto filament_id = 255 - no_light_px[3]; + if (filament_id >= m_cur_colors_in_thumbnail.size()) { + continue; + } + wxColour temp_ams_color_in_loop = m_cur_colors_in_thumbnail[filament_id]; + wxColour ams_color = adjust_color_for_render(temp_ams_color_in_loop); + //change color + new_px[3] = origin_px[3]; // alpha + int origin_rgb = origin_px[0] + origin_px[1] + origin_px[2]; + int no_light_px_rgb = no_light_px[0] + no_light_px[1] + no_light_px[2]; + unsigned char i = 0; + if (origin_rgb >= no_light_px_rgb) {//Brighten up + unsigned char cur_single_color = ams_color.Red(); + new_px[i] = std::clamp(cur_single_color + (origin_px[i] - no_light_px[i]), 0, 255); + i++; + cur_single_color = ams_color.Green(); + new_px[i] = std::clamp(cur_single_color + (origin_px[i] - no_light_px[i]), 0, 255); + i++; + cur_single_color = ams_color.Blue(); + new_px[i] = std::clamp(cur_single_color + (origin_px[i] - no_light_px[i]), 0, 255); + } else {//Dimming + float ratio = origin_rgb / (float) no_light_px_rgb; + unsigned char cur_single_color = ams_color.Red(); + new_px[i] = std::clamp((int)(cur_single_color * ratio), 0, 255); + i++; + cur_single_color = ams_color.Green(); + new_px[i] = std::clamp((int) (cur_single_color * ratio), 0, 255); + i++; + cur_single_color = ams_color.Blue(); + new_px[i] = std::clamp((int) (cur_single_color * ratio), 0, 255); + } + } + } + } + } + else { + BOOST_LOG_TRIVIAL(error) << "SelectMachineDialog::change_defa:no_light_data is empty,error"; + } +} + +void SelectMachineDialog::set_default_normal(const ThumbnailData &data) { update_page_turn_state(false); - ThumbnailData& data = m_plater->get_partplate_list().get_curr_plate()->thumbnail_data; if (data.is_valid()) { wxImage image(data.width, data.height); image.InitAlpha(); @@ -3955,135 +4346,6 @@ void SelectMachineDialog::set_default_normal() m_thumbnailPanel->set_thumbnail(image); } - //for black list - std::vector materials; - std::vector brands; - std::vector display_materials; - std::vector m_filaments_id; - - - auto preset_bundle = wxGetApp().preset_bundle; - - for (auto filament_name : preset_bundle->filament_presets) { - for (int f_index = 0; f_index < preset_bundle->filaments.size(); f_index++) { - PresetCollection* filament_presets = &wxGetApp().preset_bundle->filaments; - Preset* preset = &filament_presets->preset(f_index); - - if (preset && filament_name.compare(preset->name) == 0) { - std::string display_filament_type; - std::string filament_type = preset->config.get_filament_type(display_filament_type); - std::string m_filament_id=preset->filament_id; - display_materials.push_back(display_filament_type); - materials.push_back(filament_type); - m_filaments_id.push_back(m_filament_id); - - std::string m_vendor_name = ""; - auto vendor = dynamic_cast (preset->config.option("filament_vendor")); - if (vendor && (vendor->values.size() > 0)) { - std::string vendor_name = vendor->values[0]; - m_vendor_name = vendor_name; - } - brands.push_back(m_vendor_name); - } - } - } - - //init MaterialItem - auto extruders = wxGetApp().plater()->get_partplate_list().get_curr_plate()->get_used_extruders(); - - MaterialHash::iterator iter = m_materialList.begin(); - while (iter != m_materialList.end()) { - int id = iter->first; - Material* item = iter->second; - item->item->Destroy(); - delete item; - iter++; - } - - m_sizer_material->Clear(); - m_materialList.clear(); - m_filaments.clear(); - - for (auto i = 0; i < extruders.size(); i++) { - auto extruder = extruders[i] - 1; - auto colour = wxGetApp().preset_bundle->project_config.opt_string("filament_colour", (unsigned int) extruder); - ColorRGBA rgb; - decode_color(colour, rgb); - - auto colour_rgb = wxColour((int) rgb.r_uchar(), (int) rgb.g_uchar(), (int) rgb.b_uchar(), (int) rgb.a_uchar()); - if (extruder >= materials.size() || extruder < 0 || extruder >= display_materials.size()) - continue; - - MaterialItem* item = new MaterialItem(m_scrollable_region, colour_rgb, _L(display_materials[extruder])); - m_sizer_material->Add(item, 0, wxALL, FromDIP(4)); - - item->Bind(wxEVT_LEFT_UP, [this, item, materials, extruder](wxMouseEvent& e) {}); - item->Bind(wxEVT_LEFT_DOWN, [this, item, materials, extruder](wxMouseEvent& e) { - MaterialHash::iterator iter = m_materialList.begin(); - while (iter != m_materialList.end()) { - int id = iter->first; - Material* item = iter->second; - MaterialItem* m = item->item; - m->on_normal(); - iter++; - } - - m_current_filament_id = extruder; - item->on_selected(); - - - auto mouse_pos = ClientToScreen(e.GetPosition()); - wxPoint rect = item->ClientToScreen(wxPoint(0, 0)); - - // update ams data - DeviceManager* dev_manager = Slic3r::GUI::wxGetApp().getDeviceManager(); - if (!dev_manager) return; - MachineObject* obj_ = dev_manager->get_selected_machine(); - - if (obj_ && obj_->is_support_ams_mapping()) { - if (m_mapping_popup.IsShown()) return; - wxPoint pos = item->ClientToScreen(wxPoint(0, 0)); - pos.y += item->GetRect().height; - m_mapping_popup.Move(pos); - - if (obj_ && - obj_->has_ams() && - m_checkbox_list["use_ams"]->GetValue() && - obj_->dev_id == m_printer_last_select) - { - m_mapping_popup.set_parent_item(item); - m_mapping_popup.set_current_filament_id(extruder); - m_mapping_popup.set_tag_texture(materials[extruder]); - m_mapping_popup.update_ams_data(obj_->amsList); - m_mapping_popup.Popup(); - } - } - }); - - Material* material_item = new Material(); - material_item->id = extruder; - material_item->item = item; - m_materialList[i] = material_item; - - // build for ams mapping - if (extruder < materials.size() && extruder >= 0) { - FilamentInfo info; - info.id = extruder; - info.type = materials[extruder]; - info.brand = brands[extruder]; - info.filament_id=m_filaments_id[extruder]; - info.color = wxString::Format("#%02X%02X%02X%02X", colour_rgb.Red(), colour_rgb.Green(), colour_rgb.Blue(), colour_rgb.Alpha()).ToStdString(); - m_filaments.push_back(info); - } - } - - if (extruders.size() <= 4) { - m_sizer_material->SetCols(extruders.size()); - } - else { - m_sizer_material->SetCols(4); - } - m_scrollable_region->Layout(); m_scrollable_region->Fit(); @@ -4112,10 +4374,6 @@ void SelectMachineDialog::set_default_normal() m_scrollable_view->SetScrollRate(0, 0); } #endif // __WXOSX_MAC__ - - - reset_ams_material(); - // basic info auto aprint_stats = m_plater->get_partplate_list().get_current_fff_print().print_statistics(); wxString time; @@ -4149,7 +4407,7 @@ void SelectMachineDialog::set_default_from_sdcard() image = image.Rescale(FromDIP(256), FromDIP(256)); m_thumbnailPanel->set_thumbnail(image); } - + //for black list std::vector materials; std::vector brands; @@ -4556,9 +4814,10 @@ void EditDevNameDialog::on_edit_name(wxCommandEvent &e) Fit(); } - void ThumbnailPanel::set_thumbnail(wxImage img) + void ThumbnailPanel::set_thumbnail(wxImage &img) { - m_bitmap = img; + m_brightness_value = get_brightness_value(img); + m_bitmap = img; //Paint the background bitmap to the thumbnail bitmap with wxMemoryDC wxMemoryDC dc; bitmap_with_background.Create(wxSize(m_bitmap.GetWidth(), m_bitmap.GetHeight())); @@ -4577,7 +4836,7 @@ void EditDevNameDialog::on_edit_name(wxCommandEvent &e) void ThumbnailPanel::render(wxDC& dc) { - if (wxGetApp().dark_mode()) { + if (wxGetApp().dark_mode() && m_brightness_value < SHOW_BACKGROUND_BITMAP_PIXEL_THRESHOLD) { #ifdef __WXMSW__ wxMemoryDC memdc; wxBitmap bmp(GetSize()); diff --git a/src/slic3r/GUI/SelectMachine.hpp b/src/slic3r/GUI/SelectMachine.hpp index bab4d3d4e9..16da5e05d5 100644 --- a/src/slic3r/GUI/SelectMachine.hpp +++ b/src/slic3r/GUI/SelectMachine.hpp @@ -445,6 +445,12 @@ protected: wxStaticBitmap * img_use_ams_tip{nullptr}; wxStaticBitmap * img_ams_backup{nullptr}; ScalableBitmap * enable_ams{nullptr}; + ThumbnailData m_cur_input_thumbnail_data; + ThumbnailData m_cur_no_light_thumbnail_data; + ThumbnailData m_preview_thumbnail_data;//when ams map change + std::vector m_preview_colors_in_thumbnail; + std::vector m_cur_colors_in_thumbnail; + std::vector m_edge_pixels; public: SelectMachineDialog(Plater *plater = nullptr); @@ -483,7 +489,15 @@ public: void on_set_finish_mapping(wxCommandEvent& evt); void on_print_job_cancel(wxCommandEvent& evt); void set_default(); - void set_default_normal(); + void reset_and_sync_ams_list(); + void clone_thumbnail_data(); + void record_edge_pixels_data(); + wxColour adjust_color_for_render(const wxColour& color); + void final_deal_edge_pixels_data(ThumbnailData& data); + void updata_thumbnail_data_after_connected_printer(); + void unify_deal_thumbnail_data(ThumbnailData &input_data, ThumbnailData &no_light_data); + void change_default_normal(int old_filament_id, wxColour temp_ams_color); + void set_default_normal(const ThumbnailData&); void set_default_from_sdcard(); void update_page_turn_state(bool show); void on_timer(wxTimerEvent& event); @@ -567,12 +581,12 @@ public: void OnPaint(wxPaintEvent &event); void PaintBackground(wxDC &dc); void OnEraseBackground(wxEraseEvent &event); - void set_thumbnail(wxImage img); + void set_thumbnail(wxImage &img); void render(wxDC &dc); private: ScalableBitmap m_background_bitmap; wxBitmap bitmap_with_background; - + int m_brightness_value{ -1 }; }; }} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/StatusPanel.cpp b/src/slic3r/GUI/StatusPanel.cpp index 80fe7199a7..2a7ff21b76 100644 --- a/src/slic3r/GUI/StatusPanel.cpp +++ b/src/slic3r/GUI/StatusPanel.cpp @@ -561,11 +561,19 @@ void PrintingTaskPanel::create_panel(wxWindow* parent) void PrintingTaskPanel::paint(wxPaintEvent&) { wxPaintDC dc(m_bitmap_thumbnail); - if (wxGetApp().dark_mode()) - dc.DrawBitmap(m_bitmap_background.bmp(), 0, 0); + if (wxGetApp().dark_mode()) { + if (m_brightness_value > 0 && m_brightness_value < SHOW_BACKGROUND_BITMAP_PIXEL_THRESHOLD) { + dc.DrawBitmap(m_bitmap_background.bmp(), 0, 0); + dc.SetTextForeground(*wxBLACK); + } + else + dc.SetTextForeground(*wxWHITE); + } + else + dc.SetTextForeground(*wxBLACK); dc.DrawBitmap(m_thumbnail_bmp_display, wxPoint(0, 0)); - dc.SetTextForeground(*wxBLACK); dc.SetFont(Label::Body_12); + if (m_plate_index >= 0) { wxString plate_id_str = wxString::Format("%d", m_plate_index); dc.DrawText(plate_id_str, wxPoint(4, 4)); @@ -1990,6 +1998,7 @@ void StatusPanel::on_webrequest_state(wxWebRequestEvent &evt) img_list.insert(std::make_pair(m_request_url, img)); wxImage resize_img = img.Scale(m_project_task_panel->get_bitmap_thumbnail()->GetSize().x, m_project_task_panel->get_bitmap_thumbnail()->GetSize().y, wxIMAGE_QUALITY_HIGH); m_project_task_panel->set_thumbnail_img(resize_img); + m_project_task_panel->set_brightness_value(get_brightness_value(resize_img)); } if (obj) { m_project_task_panel->set_plate_index(obj->m_plate_index); @@ -3229,6 +3238,7 @@ void StatusPanel::update_cloud_subtask(MachineObject *obj) img = it->second; wxImage resize_img = img.Scale(m_project_task_panel->get_bitmap_thumbnail()->GetSize().x, m_project_task_panel->get_bitmap_thumbnail()->GetSize().y); m_project_task_panel->set_thumbnail_img(resize_img); + m_project_task_panel->set_brightness_value(get_brightness_value(resize_img)); } if (this->obj) { m_project_task_panel->set_plate_index(obj->m_plate_index); diff --git a/src/slic3r/GUI/StatusPanel.hpp b/src/slic3r/GUI/StatusPanel.hpp index eee2fafdfe..517367d7f3 100644 --- a/src/slic3r/GUI/StatusPanel.hpp +++ b/src/slic3r/GUI/StatusPanel.hpp @@ -206,6 +206,7 @@ private: ProgressBar* m_gauge_progress; Label* m_error_text; PrintingTaskType m_type; + int m_brightness_value{ -1 }; public: void init_bitmaps(); @@ -227,6 +228,7 @@ public: void show_priting_use_info(bool show, wxString time = wxEmptyString, wxString weight = wxEmptyString); void show_profile_info(bool show, wxString profile = wxEmptyString); void set_thumbnail_img(const wxBitmap& bmp); + void set_brightness_value(int value) { m_brightness_value = value; } void set_plate_index(int plate_idx = -1); void market_scoring_show(); void market_scoring_hide(); @@ -246,7 +248,6 @@ public: void set_star_count_dirty(bool dirty) { m_star_count_dirty = dirty; } void set_has_reted_text(bool has_rated); void paint(wxPaintEvent&); - }; class StatusBasePanel : public wxScrolledWindow