From ebe5392932d51acc528730460ed5c6d639331e7d Mon Sep 17 00:00:00 2001 From: "lane.wei" Date: Mon, 15 Apr 2024 22:09:01 +0800 Subject: [PATCH] ENH: CLI: add no light thumbnail logic for CLI previously lots of logic are missed JIRA: no jira Change-Id: I3beadbb78127049594614212e8f9a60633e73b56 (cherry picked from commit 8fe9b854fa58c302c56b4f84bd0db9c5d1a4b571) --- src/BambuStudio.cpp | 101 ++++++++++++++++++++++++++++--- src/libslic3r/Format/bbs_3mf.cpp | 29 ++++++++- src/libslic3r/Format/bbs_3mf.hpp | 2 + src/slic3r/GUI/PartPlate.cpp | 13 +++- 4 files changed, 133 insertions(+), 12 deletions(-) diff --git a/src/BambuStudio.cpp b/src/BambuStudio.cpp index 9e132022e..5f012d4f8 100644 --- a/src/BambuStudio.cpp +++ b/src/BambuStudio.cpp @@ -3394,6 +3394,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(); @@ -4445,6 +4449,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(); @@ -4835,8 +4843,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")); @@ -4893,6 +4902,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; @@ -4918,7 +4948,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(); @@ -5106,6 +5136,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))) { @@ -5136,11 +5220,9 @@ int CLI::run(int argc, char **argv) else{ ThumbnailData* top_thumbnail = &part_plate->top_thumbnail_data; ThumbnailData* picking_thumbnail = &part_plate->pick_thumbnail_data; - 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->top_thumbnail_data.reset(); - part_plate->no_light_thumbnail_data.reset(); part_plate->pick_thumbnail_data.reset(); plate_data->top_file.clear(); plate_data->pick_file.clear(); @@ -5153,7 +5235,6 @@ int CLI::run(int argc, char **argv) if (skip_useless_pick && ((plate_object_count[i] <= 1) || (plate_object_count[i] > 64))) { //don't render pick and top - part_plate->no_light_thumbnail_data.reset(); part_plate->top_thumbnail_data.reset(); part_plate->pick_thumbnail_data.reset(); plate_data->top_file.clear(); @@ -5197,7 +5278,6 @@ int CLI::run(int argc, char **argv) } if (need_create_top_group) { - no_light_thumbnails.push_back(&part_plate->no_light_thumbnail_data); top_thumbnails.push_back(&part_plate->top_thumbnail_data); pick_thumbnails.push_back(&part_plate->pick_thumbnail_data); BOOST_LOG_TRIVIAL(info) << boost::format("plate %1%: add thumbnail data for top and pick into group")%(i+1); @@ -5220,6 +5300,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(); @@ -5249,8 +5332,12 @@ 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_top_group) { + 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); BOOST_LOG_TRIVIAL(info) << boost::format("plate %1%: add thumbnail data for top and pick into group")%(i+1); diff --git a/src/libslic3r/Format/bbs_3mf.cpp b/src/libslic3r/Format/bbs_3mf.cpp index cb0074c68..e7269b019 100644 --- a/src/libslic3r/Format/bbs_3mf.cpp +++ b/src/libslic3r/Format/bbs_3mf.cpp @@ -284,6 +284,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"; @@ -1444,6 +1445,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(); @@ -1455,7 +1457,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++; } @@ -2084,13 +2086,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++; @@ -3926,6 +3929,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; @@ -5500,6 +5507,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); @@ -5555,7 +5563,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) } BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format(",add no light thumbnail %1%'s data into 3mf") % (index + 1); - thumbnail_status[index] = true; + no_light_thumbnail_status[index] = true; } } // Adds the file Metadata/top_i.png and Metadata/pick_i.png @@ -5593,6 +5601,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(); @@ -7247,6 +7265,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 78ba7ece7..6d0c092b7 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; diff --git a/src/slic3r/GUI/PartPlate.cpp b/src/slic3r/GUI/PartPlate.cpp index 555ebe2ab..b62ab34c1 100644 --- a/src/slic3r/GUI/PartPlate.cpp +++ b/src/slic3r/GUI/PartPlate.cpp @@ -249,7 +249,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); @@ -4280,7 +4280,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) { @@ -5264,6 +5264,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()) @@ -5379,6 +5381,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