mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-16 13:32:44 +00:00
Only serialize selected published settings. Minor cleanup
This commit is contained in:
@@ -5943,6 +5943,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
|
|||||||
bool m_save_gcode { false }; // whether to save gcode for normal save
|
bool m_save_gcode { false }; // whether to save gcode for normal save
|
||||||
bool m_skip_model { false }; // skip model when exporting .gcode.3mf
|
bool m_skip_model { false }; // skip model when exporting .gcode.3mf
|
||||||
bool m_skip_auxiliary { false }; // skip normal axuiliary files
|
bool m_skip_auxiliary { false }; // skip normal axuiliary files
|
||||||
|
bool m_minimal_published { false }; // published 3MF: omit embedded preset files
|
||||||
bool m_use_loaded_id { false }; // whether to use loaded id for identify_id
|
bool m_use_loaded_id { false }; // whether to use loaded id for identify_id
|
||||||
bool m_share_mesh { false }; // whether to share mesh between objects
|
bool m_share_mesh { false }; // whether to share mesh between objects
|
||||||
std::string m_thumbnail_middle = PRINTER_THUMBNAIL_MIDDLE_FILE;
|
std::string m_thumbnail_middle = PRINTER_THUMBNAIL_MIDDLE_FILE;
|
||||||
@@ -6042,6 +6043,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
|
|||||||
m_skip_auxiliary = store_params.strategy & SaveStrategy::SkipAuxiliary;
|
m_skip_auxiliary = store_params.strategy & SaveStrategy::SkipAuxiliary;
|
||||||
m_share_mesh = store_params.strategy & SaveStrategy::ShareMesh;
|
m_share_mesh = store_params.strategy & SaveStrategy::ShareMesh;
|
||||||
m_from_backup_save = store_params.strategy & SaveStrategy::Backup;
|
m_from_backup_save = store_params.strategy & SaveStrategy::Backup;
|
||||||
|
m_minimal_published = store_params.strategy & SaveStrategy::MinimalPublished;
|
||||||
|
|
||||||
m_use_loaded_id = store_params.strategy & SaveStrategy::UseLoadedId;
|
m_use_loaded_id = store_params.strategy & SaveStrategy::UseLoadedId;
|
||||||
|
|
||||||
@@ -6464,8 +6466,8 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
|
|||||||
if (cb_cancel) return false;
|
if (cb_cancel) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// BBS: add project config
|
// BBS: add project config (omitted for minimal published 3MF)
|
||||||
if (project_presets.size() > 0) {
|
if (!m_minimal_published && project_presets.size() > 0) {
|
||||||
// BBS: add project embedded preset files
|
// BBS: add project embedded preset files
|
||||||
_add_project_embedded_presets_to_archive(archive, model, project_presets);
|
_add_project_embedded_presets_to_archive(archive, model, project_presets);
|
||||||
|
|
||||||
|
|||||||
@@ -145,6 +145,7 @@ enum class SaveStrategy
|
|||||||
SkipAuxiliary = 1 << 9,
|
SkipAuxiliary = 1 << 9,
|
||||||
UseLoadedId = 1 << 10,
|
UseLoadedId = 1 << 10,
|
||||||
ShareMesh = 1 << 11,
|
ShareMesh = 1 << 11,
|
||||||
|
MinimalPublished = 1 << 12,
|
||||||
|
|
||||||
SplitModel = 0x1000 | ProductionExt,
|
SplitModel = 0x1000 | ProductionExt,
|
||||||
Encrypted = SecureContentExt | SplitModel,
|
Encrypted = SecureContentExt | SplitModel,
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "PresetBundle.hpp"
|
#include "PresetBundle.hpp"
|
||||||
#include "Preset.hpp"
|
#include "Preset.hpp"
|
||||||
|
#include "PrintConfig.hpp"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
@@ -102,4 +103,60 @@ std::vector<std::string> collect_dirty_settings_keys(const PresetBundle& bundle)
|
|||||||
return keys;
|
return keys;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DynamicPrintConfig filter_published_config(
|
||||||
|
const DynamicPrintConfig &full_config,
|
||||||
|
const std::vector<std::string> &published_keys,
|
||||||
|
const std::vector<PublishedMaterialEntry> &material_keys)
|
||||||
|
{
|
||||||
|
DynamicPrintConfig filtered;
|
||||||
|
|
||||||
|
std::set<std::string> base_keys_to_include;
|
||||||
|
|
||||||
|
// 1. Mandatory material identity & slot count keys for 3MF validation/normalization
|
||||||
|
static const std::vector<std::string> s_material_identity_keys = {
|
||||||
|
"filament_colour",
|
||||||
|
"filament_type",
|
||||||
|
"filament_vendor",
|
||||||
|
"filament_ids",
|
||||||
|
"filament_diameter",
|
||||||
|
"filament_self_index",
|
||||||
|
"filament_extruder_variant"
|
||||||
|
};
|
||||||
|
for (const std::string &key : s_material_identity_keys)
|
||||||
|
base_keys_to_include.insert(key);
|
||||||
|
|
||||||
|
// 2. Published plate / bed geometry keys (wipe tower positioning)
|
||||||
|
static const std::vector<std::string> s_plate_geometry_keys = {
|
||||||
|
"wipe_tower_x",
|
||||||
|
"wipe_tower_y",
|
||||||
|
"wipe_tower_rotation_angle"
|
||||||
|
};
|
||||||
|
for (const std::string &key : s_plate_geometry_keys)
|
||||||
|
base_keys_to_include.insert(key);
|
||||||
|
|
||||||
|
// 3. Process and printer published keys
|
||||||
|
for (const std::string &key : published_keys) {
|
||||||
|
const std::string base_key = key.substr(0, key.find('#'));
|
||||||
|
if (!base_key.empty())
|
||||||
|
base_keys_to_include.insert(base_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Material-specific published keys
|
||||||
|
for (const PublishedMaterialEntry &entry : material_keys) {
|
||||||
|
for (const std::string &key : entry.keys) {
|
||||||
|
const std::string base_key = key.substr(0, key.find('#'));
|
||||||
|
if (!base_key.empty())
|
||||||
|
base_keys_to_include.insert(base_key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy selected options from full_config into filtered config
|
||||||
|
for (const std::string &key : base_keys_to_include) {
|
||||||
|
if (const ConfigOption *opt = full_config.option(key))
|
||||||
|
filtered.set_key_value(key, opt->clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
return filtered;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
|||||||
@@ -53,4 +53,12 @@ struct PublishedMaterialEntry {
|
|||||||
int slot{-1};
|
int slot{-1};
|
||||||
std::vector<std::string> keys;
|
std::vector<std::string> keys;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Constructs a minimal DynamicPrintConfig for a published 3MF export containing only the
|
||||||
|
// author-selected published keys, material keys, material identity fields, and plate geometry keys.
|
||||||
|
class DynamicPrintConfig;
|
||||||
|
DynamicPrintConfig filter_published_config(
|
||||||
|
const DynamicPrintConfig &full_config,
|
||||||
|
const std::vector<std::string> &published_keys,
|
||||||
|
const std::vector<PublishedMaterialEntry> &material_keys);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ wxString get_string_value(const std::string& opt_key, const DynamicPrintConfig&
|
|||||||
std::string temp_str = opt_key;
|
std::string temp_str = opt_key;
|
||||||
if (pos > 0) {
|
if (pos > 0) {
|
||||||
boost::erase_head(temp_str, pos + 1);
|
boost::erase_head(temp_str, pos + 1);
|
||||||
orig_opt_idx = static_cast<size_t>(atoi(temp_str.c_str()));
|
orig_opt_idx = std::atoi(temp_str.c_str());
|
||||||
}
|
}
|
||||||
opt_idx = orig_opt_idx >= 0 ? orig_opt_idx : 0;
|
opt_idx = orig_opt_idx >= 0 ? orig_opt_idx : 0;
|
||||||
const std::string pure_key = get_pure_opt_key(opt_key);
|
const std::string pure_key = get_pure_opt_key(opt_key);
|
||||||
@@ -83,8 +83,8 @@ wxString get_string_value(const std::string& opt_key, const DynamicPrintConfig&
|
|||||||
}
|
}
|
||||||
auto opt_vector = dynamic_cast<const ConfigOptionVectorBase *>(option);
|
auto opt_vector = dynamic_cast<const ConfigOptionVectorBase *>(option);
|
||||||
|
|
||||||
if (option->is_scalar() && config.option(pure_key)->is_nil() ||
|
if ((option->is_scalar() && option->is_nil()) ||
|
||||||
option->is_vector() && opt_vector && opt_idx >= 0 && opt_idx < opt_vector->size() && opt_vector->is_nil(opt_idx))
|
(option->is_vector() && opt_vector && opt_idx >= 0 && opt_idx < opt_vector->size() && opt_vector->is_nil(opt_idx)))
|
||||||
return _L("N/A");
|
return _L("N/A");
|
||||||
|
|
||||||
wxString out;
|
wxString out;
|
||||||
|
|||||||
@@ -7324,7 +7324,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto choise = wxGetApp().app_config->get("no_warn_when_modified_gcodes");
|
auto choise = wxGetApp().app_config->get("no_warn_when_modified_gcodes");
|
||||||
if (choise.empty() || choise != "true") {
|
if (!published_config.published && (choise.empty() || choise != "true")) {
|
||||||
// BBS: first validate the printer
|
// BBS: first validate the printer
|
||||||
// validate the system profiles
|
// validate the system profiles
|
||||||
std::set<std::string> modified_gcodes;
|
std::set<std::string> modified_gcodes;
|
||||||
@@ -16204,16 +16204,21 @@ int Plater::export_published_3mf(const std::vector<std::string>& published_keys,
|
|||||||
model.model_info->metadata_items["published_keys"] = j.dump();
|
model.model_info->metadata_items["published_keys"] = j.dump();
|
||||||
model.model_info->metadata_items["published_material_keys"] = jm.dump();
|
model.model_info->metadata_items["published_material_keys"] = jm.dump();
|
||||||
|
|
||||||
// Same file layout save_project() uses for its project files, plus SaveStrategy::Silence:
|
// Minimal published export: filter full_config to only the published keys, material keys,
|
||||||
|
// identity fields, and plate geometry keys, and omit project-embedded preset dumps.
|
||||||
|
DynamicPrintConfig full_cfg = wxGetApp().preset_bundle->full_config_secure();
|
||||||
|
DynamicPrintConfig filtered_cfg = filter_published_config(full_cfg, published_keys, material_keys);
|
||||||
|
|
||||||
|
// Same file layout save_project() uses for its project files, plus SaveStrategy::Silence and SaveStrategy::MinimalPublished:
|
||||||
// without it export_3mf() calls set_project_filename() on success, which would make this
|
// without it export_3mf() calls set_project_filename() on success, which would make this
|
||||||
// pure export the current project file. Silence keeps the project state untouched, exactly
|
// pure export the current project file. Silence keeps the project state untouched, exactly
|
||||||
// like export_core_3mf().
|
// like export_core_3mf().
|
||||||
auto save_strategy = SaveStrategy::SplitModel | SaveStrategy::ShareMesh | SaveStrategy::Silence;
|
auto save_strategy = SaveStrategy::SplitModel | SaveStrategy::ShareMesh | SaveStrategy::Silence | SaveStrategy::MinimalPublished;
|
||||||
bool full_pathnames = wxGetApp().app_config->get_bool("export_sources_full_pathnames");
|
bool full_pathnames = wxGetApp().app_config->get_bool("export_sources_full_pathnames");
|
||||||
if (full_pathnames)
|
if (full_pathnames)
|
||||||
save_strategy = save_strategy | SaveStrategy::FullPathSources;
|
save_strategy = save_strategy | SaveStrategy::FullPathSources;
|
||||||
|
|
||||||
const int ret = export_3mf(into_path(path), save_strategy);
|
const int ret = export_3mf(into_path(path), save_strategy, -1, nullptr, &filtered_cfg);
|
||||||
|
|
||||||
// Restore the previous metadata state (both on success and on failure).
|
// Restore the previous metadata state (both on success and on failure).
|
||||||
if (!had_model_info) {
|
if (!had_model_info) {
|
||||||
@@ -16737,7 +16742,7 @@ void publish(Model &model, SaveStrategy strategy) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// BBS: backup
|
// BBS: backup
|
||||||
int Plater::export_3mf(const boost::filesystem::path& output_path, SaveStrategy strategy, int export_plate_idx, Export3mfProgressFn proFn)
|
int Plater::export_3mf(const boost::filesystem::path& output_path, SaveStrategy strategy, int export_plate_idx, Export3mfProgressFn proFn, const DynamicPrintConfig* override_config)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
//if (p->model.objects.empty()) {
|
//if (p->model.objects.empty()) {
|
||||||
@@ -16759,7 +16764,7 @@ int Plater::export_3mf(const boost::filesystem::path& output_path, SaveStrategy
|
|||||||
// modify model
|
// modify model
|
||||||
publish(p->model, strategy);
|
publish(p->model, strategy);
|
||||||
|
|
||||||
DynamicPrintConfig cfg = wxGetApp().preset_bundle->full_config_secure();
|
DynamicPrintConfig cfg = override_config ? *override_config : wxGetApp().preset_bundle->full_config_secure();
|
||||||
const std::string path_u8 = into_u8(path);
|
const std::string path_u8 = into_u8(path);
|
||||||
wxBusyCursor wait;
|
wxBusyCursor wait;
|
||||||
|
|
||||||
|
|||||||
@@ -505,7 +505,7 @@ public:
|
|||||||
//void export_amf();
|
//void export_amf();
|
||||||
//BBS add extra param for exporting 3mf silence
|
//BBS add extra param for exporting 3mf silence
|
||||||
// BBS: backup
|
// BBS: backup
|
||||||
int export_3mf(const boost::filesystem::path& output_path = boost::filesystem::path(), SaveStrategy strategy = SaveStrategy::Default, int export_plate_idx = -1, Export3mfProgressFn proFn = nullptr);
|
int export_3mf(const boost::filesystem::path& output_path = boost::filesystem::path(), SaveStrategy strategy = SaveStrategy::Default, int export_plate_idx = -1, Export3mfProgressFn proFn = nullptr, const DynamicPrintConfig* override_config = nullptr);
|
||||||
|
|
||||||
//BBS
|
//BBS
|
||||||
void publish_project();
|
void publish_project();
|
||||||
|
|||||||
@@ -321,8 +321,8 @@ void PublishSettingsDialog::build_option_model()
|
|||||||
cat.filament_id = identity.id;
|
cat.filament_id = identity.id;
|
||||||
cat.filament_slot = slot;
|
cat.filament_slot = slot;
|
||||||
if (!icon_name.empty()) {
|
if (!icon_name.empty()) {
|
||||||
ScalableBitmap icon_bmp(m_scroll, icon_name, 18);
|
cat.icon_bmp = ScalableBitmap(m_scroll, icon_name, 18);
|
||||||
cat.icon = new wxStaticBitmap(m_scroll, wxID_ANY, icon_bmp.bmp());
|
cat.icon = new wxStaticBitmap(m_scroll, wxID_ANY, cat.icon_bmp.bmp());
|
||||||
}
|
}
|
||||||
if (section == Section::Material) {
|
if (section == Section::Material) {
|
||||||
// Material header: [master (title)][slim tri-state select-all].
|
// Material header: [master (title)][slim tri-state select-all].
|
||||||
@@ -667,8 +667,8 @@ size_t PublishSettingsDialog::section_group_for(Section kind)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!section.icon_name.empty()) {
|
if (!section.icon_name.empty()) {
|
||||||
ScalableBitmap icon_bmp(m_scroll, section.icon_name, 18);
|
section.icon_bmp = ScalableBitmap(m_scroll, section.icon_name, 18);
|
||||||
section.icon = new wxStaticBitmap(m_scroll, wxID_ANY, icon_bmp.bmp());
|
section.icon = new wxStaticBitmap(m_scroll, wxID_ANY, section.icon_bmp.bmp());
|
||||||
}
|
}
|
||||||
|
|
||||||
section.chevron = create_chevron(m_scroll, wxEVT_LEFT_DOWN, [this, new_index] { toggle_section(new_index); });
|
section.chevron = create_chevron(m_scroll, wxEVT_LEFT_DOWN, [this, new_index] { toggle_section(new_index); });
|
||||||
@@ -1062,12 +1062,32 @@ std::vector<Slic3r::PublishedMaterialEntry> PublishSettingsDialog::GetPublishedM
|
|||||||
|
|
||||||
void PublishSettingsDialog::on_dpi_changed(const wxRect& suggested_rect)
|
void PublishSettingsDialog::on_dpi_changed(const wxRect& suggested_rect)
|
||||||
{
|
{
|
||||||
// The remaining bitmap icons are rescaled; the collapse chevrons are
|
// Rescale toolbar bitmaps and icons; collapse chevrons are vector-drawn and repaint themselves.
|
||||||
// vector-drawn and repaint themselves.
|
|
||||||
m_search.msw_rescale();
|
m_search.msw_rescale();
|
||||||
m_menu.msw_rescale();
|
m_menu.msw_rescale();
|
||||||
m_filter_box->SetIcon(m_search.bmp());
|
m_filter_box->SetIcon(m_search.bmp());
|
||||||
m_menu_button->SetBitmap(m_menu.bmp());
|
m_menu_button->SetBitmap(m_menu.bmp());
|
||||||
|
|
||||||
|
for (SectionGroup& section : m_sections) {
|
||||||
|
if (section.icon != nullptr && section.icon_bmp.bmp().IsOk()) {
|
||||||
|
section.icon_bmp.msw_rescale();
|
||||||
|
section.icon->SetBitmap(section.icon_bmp.bmp());
|
||||||
|
}
|
||||||
|
if (section.header_line != nullptr)
|
||||||
|
section.header_line->Rescale();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Category& cat : m_categories) {
|
||||||
|
if (cat.icon != nullptr && cat.icon_bmp.bmp().IsOk()) {
|
||||||
|
cat.icon_bmp.msw_rescale();
|
||||||
|
cat.icon->SetBitmap(cat.icon_bmp.bmp());
|
||||||
|
}
|
||||||
|
for (Subcategory& sub : cat.subs) {
|
||||||
|
if (sub.header != nullptr)
|
||||||
|
sub.header->Rescale();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SetMinSize(FromDIP(wxSize(600, 500)));
|
SetMinSize(FromDIP(wxSize(600, 500)));
|
||||||
m_scroll->FitInside();
|
m_scroll->FitInside();
|
||||||
m_list_sizer->Layout();
|
m_list_sizer->Layout();
|
||||||
|
|||||||
@@ -91,6 +91,7 @@ private:
|
|||||||
Section section{Section::Print};
|
Section section{Section::Print};
|
||||||
size_t group{0}; // index into m_sections
|
size_t group{0}; // index into m_sections
|
||||||
std::string icon_name; // bitmap name; empty = no icon
|
std::string icon_name; // bitmap name; empty = no icon
|
||||||
|
ScalableBitmap icon_bmp; // scalable bitmap for DPI changes
|
||||||
wxStaticBitmap* icon{nullptr}; // 18px category icon (null when icon_name empty)
|
wxStaticBitmap* icon{nullptr}; // 18px category icon (null when icon_name empty)
|
||||||
wxCheckBox* header{nullptr}; // select-all tri-state
|
wxCheckBox* header{nullptr}; // select-all tri-state
|
||||||
// Material opt-in: the master checkbox carries the material title and
|
// Material opt-in: the master checkbox carries the material title and
|
||||||
@@ -117,6 +118,7 @@ private:
|
|||||||
wxString title; // _L("Printer") / _L("Filament") / _L("Process")
|
wxString title; // _L("Printer") / _L("Filament") / _L("Process")
|
||||||
Section kind{Section::Print}; // maps 1:1 to the display group
|
Section kind{Section::Print}; // maps 1:1 to the display group
|
||||||
std::string icon_name; // "printer" / "filament" / "process"
|
std::string icon_name; // "printer" / "filament" / "process"
|
||||||
|
ScalableBitmap icon_bmp; // scalable bitmap for DPI changes
|
||||||
wxStaticBitmap* icon{nullptr}; // 18px, like Category::icon
|
wxStaticBitmap* icon{nullptr}; // 18px, like Category::icon
|
||||||
wxCheckBox* header{nullptr}; // tri-state select-all; nullptr for the Filament group
|
wxCheckBox* header{nullptr}; // tri-state select-all; nullptr for the Filament group
|
||||||
::StaticLine* header_line{nullptr}; // Filament group's clickable title
|
::StaticLine* header_line{nullptr}; // Filament group's clickable title
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include "libslic3r/Preset.hpp"
|
#include "libslic3r/Preset.hpp"
|
||||||
#include "libslic3r/MultiNozzleUtils.hpp"
|
#include "libslic3r/MultiNozzleUtils.hpp"
|
||||||
#include "libslic3r/ProjectTask.hpp"
|
#include "libslic3r/ProjectTask.hpp"
|
||||||
|
#include "libslic3r/PublishSettings.hpp"
|
||||||
|
|
||||||
#include "test_utils.hpp"
|
#include "test_utils.hpp"
|
||||||
|
|
||||||
@@ -674,3 +675,79 @@ SCENARIO("Published 3MF round-trips the published_material_keys metadata", "[3mf
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SCENARIO("Minimal published 3MF serialization filters config and omits embedded presets", "[3mf]") {
|
||||||
|
GIVEN("a full print configuration and published keys") {
|
||||||
|
Model model;
|
||||||
|
std::string src_file = std::string(TEST_DATA_DIR) + "/test_3mf/Prusa.stl";
|
||||||
|
REQUIRE(load_stl(src_file.c_str(), &model));
|
||||||
|
model.add_default_instances();
|
||||||
|
|
||||||
|
DynamicPrintConfig full_cfg = DynamicPrintConfig::full_print_config();
|
||||||
|
full_cfg.set_key_value("layer_height", new ConfigOptionFloat(0.24));
|
||||||
|
full_cfg.set_key_value("retraction_length", new ConfigOptionFloats({ 1.2 }));
|
||||||
|
|
||||||
|
const std::vector<std::string> published_keys = { "layer_height", "retraction_length" };
|
||||||
|
const std::vector<PublishedMaterialEntry> material_keys = {
|
||||||
|
{ "PLA", "Generic", "GFL99", 0, { "filament_retraction_length" } }
|
||||||
|
};
|
||||||
|
|
||||||
|
DynamicPrintConfig filtered_cfg = filter_published_config(full_cfg, published_keys, material_keys);
|
||||||
|
|
||||||
|
// Filtered config must contain the published keys and identity keys
|
||||||
|
REQUIRE(filtered_cfg.option("layer_height") != nullptr);
|
||||||
|
REQUIRE(filtered_cfg.option("retraction_length") != nullptr);
|
||||||
|
REQUIRE(filtered_cfg.option("filament_colour") != nullptr);
|
||||||
|
REQUIRE(filtered_cfg.option("filament_type") != nullptr);
|
||||||
|
REQUIRE(filtered_cfg.option("wipe_tower_x") != nullptr);
|
||||||
|
|
||||||
|
// Non-published settings should NOT be in filtered_cfg
|
||||||
|
REQUIRE(filtered_cfg.option("sparse_infill_density") == nullptr);
|
||||||
|
REQUIRE(filtered_cfg.option("machine_start_gcode") == nullptr);
|
||||||
|
|
||||||
|
model.model_info = std::make_shared<ModelInfo>();
|
||||||
|
model.model_info->metadata_items["published"] = "1";
|
||||||
|
model.model_info->metadata_items["published_keys"] = R"(["layer_height","retraction_length"])";
|
||||||
|
|
||||||
|
ScopedTemporaryDir backup_dir("orca_min_pub");
|
||||||
|
model.set_backup_path(backup_dir.string());
|
||||||
|
|
||||||
|
WHEN("stored using SaveStrategy::MinimalPublished") {
|
||||||
|
ScopedTemporaryFile temp(".3mf");
|
||||||
|
const std::string test_file = temp.string();
|
||||||
|
|
||||||
|
// Create a fake project preset to verify it gets omitted with MinimalPublished
|
||||||
|
Preset preset(Preset::TYPE_PRINT, "TestPrintPreset");
|
||||||
|
preset.config = full_cfg;
|
||||||
|
std::vector<Preset*> project_presets = { &preset };
|
||||||
|
|
||||||
|
StoreParams store_params;
|
||||||
|
store_params.path = test_file.c_str();
|
||||||
|
store_params.model = &model;
|
||||||
|
store_params.config = &filtered_cfg;
|
||||||
|
store_params.project_presets = project_presets;
|
||||||
|
store_params.strategy = SaveStrategy::Zip64 | SaveStrategy::Silence | SaveStrategy::MinimalPublished;
|
||||||
|
REQUIRE(store_bbs_3mf(store_params));
|
||||||
|
|
||||||
|
Model dst_model;
|
||||||
|
DynamicPrintConfig dst_config;
|
||||||
|
ConfigSubstitutionContext ctxt{ ForwardCompatibilitySubstitutionRule::Enable };
|
||||||
|
PlateDataPtrs dst_plates;
|
||||||
|
std::vector<Preset*> loaded_presets;
|
||||||
|
bool is_bbl_3mf = false, is_orca_3mf = false;
|
||||||
|
Semver file_version;
|
||||||
|
bool loaded = load_bbs_3mf(test_file.c_str(), &dst_config, &ctxt, &dst_model, &dst_plates,
|
||||||
|
&loaded_presets, &is_bbl_3mf, &is_orca_3mf, &file_version, nullptr,
|
||||||
|
LoadStrategy::LoadModel | LoadStrategy::LoadConfig);
|
||||||
|
THEN("the 3MF loads successfully without project embedded presets") {
|
||||||
|
REQUIRE(loaded);
|
||||||
|
REQUIRE(loaded_presets.empty());
|
||||||
|
REQUIRE(dst_config.option("layer_height") != nullptr);
|
||||||
|
REQUIRE(dst_config.opt_float("layer_height") == 0.24);
|
||||||
|
REQUIRE(dst_config.option("sparse_infill_density") == nullptr);
|
||||||
|
}
|
||||||
|
release_PlateData_list(dst_plates);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user