From 4c2a63e11e10f24b8d99f32abd3050696e3b71d2 Mon Sep 17 00:00:00 2001 From: HanifKoh <76276251+HanifKoh@users.noreply.github.com> Date: Mon, 12 Oct 2026 14:14:28 +0800 Subject: [PATCH] Copy Plate Pick and Pattern File Paths When Loading a G-code 3MF (#16387) The importer assigned pick_file.empty() and pattern_bbox_file.empty(), a bool, to the string fields, storing a one-character string instead of the path. --- src/libslic3r/Format/bbs_3mf.cpp | 4 ++-- tests/libslic3r/test_3mf.cpp | 37 ++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/libslic3r/Format/bbs_3mf.cpp b/src/libslic3r/Format/bbs_3mf.cpp index 8a22201c51..545cb8c05f 100644 --- a/src/libslic3r/Format/bbs_3mf.cpp +++ b/src/libslic3r/Format/bbs_3mf.cpp @@ -1729,8 +1729,8 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) //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(); + plate->pick_file = it->second->pick_file; + plate->pattern_bbox_file = it->second->pattern_bbox_file; plate->config = it->second->config; if (!plate->thumbnail_file.empty()) diff --git a/tests/libslic3r/test_3mf.cpp b/tests/libslic3r/test_3mf.cpp index f7ac744e39..f5ac340c58 100644 --- a/tests/libslic3r/test_3mf.cpp +++ b/tests/libslic3r/test_3mf.cpp @@ -2043,3 +2043,40 @@ TEST_CASE("3MF XML entries declaring more than an int can hold fail to load", "[ CHECK_FALSE(parser.check_3mf_from_prusa(path)); } } + +TEST_CASE("Loading a gcode.3mf from a stream keeps the plate's pick and pattern file paths", "[3mf][Regression]") +{ + Model model; + REQUIRE(load_stl((std::string(TEST_DATA_DIR) + "/test_3mf/Prusa.stl").c_str(), &model)); + model.add_default_instances(); + ScopedTemporaryDir backup_dir("orca_pick"); + model.set_backup_path(backup_dir.string()); + DynamicPrintConfig config = DynamicPrintConfig::full_print_config(); + + auto plate = std::make_unique(); + plate->plate_index = 0; + plate->pick_file = (backup_dir.path() / "pick.png").string(); + plate->pattern_bbox_file = (backup_dir.path() / "plate.json").string(); + + ScopedTemporaryFile temp(".3mf"); + const std::string test_file = temp.string(); + StoreParams store_params; + store_params.path = test_file.c_str(); + store_params.model = &model; + store_params.config = &config; + store_params.plate_data_list.push_back(plate.get()); + store_params.strategy = SaveStrategy::Zip64 | SaveStrategy::Silence; + REQUIRE(store_bbs_3mf(store_params)); + + boost::nowide::ifstream in(test_file, std::ios::binary); + Model dst_model; + DynamicPrintConfig dst_config; + PlateDataPtrs dst_plates; + Semver file_version; + dst_model.set_backup_path(backup_dir.string()); + REQUIRE(load_gcode_3mf_from_stream(in, &dst_config, &dst_model, &dst_plates, &file_version)); + REQUIRE(dst_plates.size() == 1); + CHECK(dst_plates.front()->pick_file == "Metadata/pick_1.png"); + CHECK(dst_plates.front()->pattern_bbox_file == "Metadata/plate_1.json"); + release_PlateData_list(dst_plates); +}