Merge branch 'ms_fix_arrange_on_load'

This commit is contained in:
Lukas Matena 2024-12-10 11:26:53 +01:00
commit 14be8a9cb8
10 changed files with 76 additions and 31 deletions

View File

@ -3888,8 +3888,10 @@ bool _3MF_Exporter::_add_wipe_tower_information_file_to_archive( mz_zip_archive&
}
// Perform conversions based on the config values available.
static void handle_legacy_project_loaded(unsigned int version_project_file, DynamicPrintConfig& config, const boost::optional<Semver>& prusaslicer_generator_version)
{
static void handle_legacy_project_loaded(
DynamicPrintConfig& config,
const boost::optional<Semver>& prusaslicer_generator_version
) {
if (! config.has("brim_separation")) {
if (auto *opt_elephant_foot = config.option<ConfigOptionFloat>("elefant_foot_compensation", false); opt_elephant_foot) {
// Conversion from older PrusaSlicer which applied brim separation equal to elephant foot compensation.
@ -3897,7 +3899,7 @@ static void handle_legacy_project_loaded(unsigned int version_project_file, Dyna
opt_brim_separation->value = opt_elephant_foot->value;
}
}
// In PrusaSlicer 2.5.0-alpha2 and 2.5.0-alpha3, we introduce several parameters for Arachne that depend
// on nozzle size . Later we decided to make default values for those parameters computed automatically
// until the user changes them.
@ -3946,7 +3948,14 @@ bool is_project_3mf(const std::string& filename)
return config_found;
}
bool load_3mf(const char* path, DynamicPrintConfig& config, ConfigSubstitutionContext& config_substitutions, Model* model, bool check_version)
bool load_3mf(
const char* path,
DynamicPrintConfig& config,
ConfigSubstitutionContext& config_substitutions,
Model* model,
bool check_version,
boost::optional<Semver> &prusaslicer_generator_version
)
{
if (path == nullptr || model == nullptr)
return false;
@ -3956,7 +3965,8 @@ bool load_3mf(const char* path, DynamicPrintConfig& config, ConfigSubstitutionCo
_3MF_Importer importer;
bool res = importer.load_model_from_file(path, *model, config, config_substitutions, check_version);
importer.log_errors();
handle_legacy_project_loaded(importer.version(), config, importer.prusaslicer_generator_version());
handle_legacy_project_loaded(config, importer.prusaslicer_generator_version());
prusaslicer_generator_version = importer.prusaslicer_generator_version();
return res;
}

View File

@ -5,6 +5,8 @@
#ifndef slic3r_Format_3mf_hpp_
#define slic3r_Format_3mf_hpp_
#include "libslic3r/Semver.hpp"
#include <boost/optional/optional.hpp>
namespace Slic3r {
/* The format for saving the SLA points was changing in the past. This enum holds the latest version that is being currently used.
@ -37,7 +39,14 @@ namespace Slic3r {
extern bool is_project_3mf(const std::string& filename);
// Load the content of a 3mf file into the given model and preset bundle.
extern bool load_3mf(const char* path, DynamicPrintConfig& config, ConfigSubstitutionContext& config_substitutions, Model* model, bool check_version);
extern bool load_3mf(
const char* path,
DynamicPrintConfig& config,
ConfigSubstitutionContext& config_substitutions,
Model* model,
bool check_version,
boost::optional<Semver> &prusaslicer_generator_version
);
// Save the given model and the config data contained in the given Print into a 3mf file.
// The model could be modified during the export process if meshes are not repaired or have no shared vertices

View File

@ -171,10 +171,11 @@ Model Model::read_from_file(const std::string& input_file, DynamicPrintConfig* c
result = load_step(input_file.c_str(), &model);
else if (boost::algorithm::iends_with(input_file, ".amf") || boost::algorithm::iends_with(input_file, ".amf.xml"))
result = load_amf(input_file.c_str(), config, config_substitutions, &model, options & LoadAttribute::CheckVersion);
else if (boost::algorithm::iends_with(input_file, ".3mf") || boost::algorithm::iends_with(input_file, ".zip"))
else if (boost::algorithm::iends_with(input_file, ".3mf") || boost::algorithm::iends_with(input_file, ".zip")) {
//FIXME options & LoadAttribute::CheckVersion ?
result = load_3mf(input_file.c_str(), *config, *config_substitutions, &model, false);
else if (boost::algorithm::iends_with(input_file, ".svg"))
boost::optional<Semver> prusaslicer_generator_version;
result = load_3mf(input_file.c_str(), *config, *config_substitutions, &model, false, prusaslicer_generator_version);
} else if (boost::algorithm::iends_with(input_file, ".svg"))
result = load_svg(input_file, model);
else if (boost::ends_with(input_file, ".printRequest"))
result = load_printRequest(input_file.c_str(), &model);
@ -204,17 +205,22 @@ Model Model::read_from_file(const std::string& input_file, DynamicPrintConfig* c
}
// Loading model from a file (3MF or AMF), not from a simple geometry file (STL or OBJ).
Model Model::read_from_archive(const std::string& input_file, DynamicPrintConfig* config, ConfigSubstitutionContext* config_substitutions, LoadAttributes options)
{
Model Model::read_from_archive(
const std::string& input_file,
DynamicPrintConfig* config,
ConfigSubstitutionContext* config_substitutions,
boost::optional<Semver> &prusaslicer_generator_version,
LoadAttributes options
) {
assert(config != nullptr);
assert(config_substitutions != nullptr);
Model model;
bool result = false;
if (boost::algorithm::iends_with(input_file, ".3mf") || boost::algorithm::iends_with(input_file, ".zip"))
result = load_3mf(input_file.c_str(), *config, *config_substitutions, &model, options & LoadAttribute::CheckVersion);
else if (boost::algorithm::iends_with(input_file, ".zip.amf"))
if (boost::algorithm::iends_with(input_file, ".3mf") || boost::algorithm::iends_with(input_file, ".zip")) {
result = load_3mf(input_file.c_str(), *config, *config_substitutions, &model, options & LoadAttribute::CheckVersion, prusaslicer_generator_version);
} else if (boost::algorithm::iends_with(input_file, ".zip.amf"))
result = load_amf(input_file.c_str(), config, config_substitutions, &model, options & LoadAttribute::CheckVersion);
else
throw Slic3r::RuntimeError("Unknown file format. Input file must have .3mf or .zip.amf extension.");

View File

@ -1329,9 +1329,12 @@ public:
DynamicPrintConfig* config = nullptr, ConfigSubstitutionContext* config_substitutions = nullptr,
LoadAttributes options = LoadAttribute::AddDefaultInstances);
static Model read_from_archive(
const std::string& input_file,
DynamicPrintConfig* config, ConfigSubstitutionContext* config_substitutions,
LoadAttributes options = LoadAttribute::AddDefaultInstances);
const std::string& input_file,
DynamicPrintConfig* config,
ConfigSubstitutionContext* config_substitutions,
boost::optional<Semver> &prusaslicer_generator_version,
LoadAttributes options = LoadAttribute::AddDefaultInstances
);
// Add a new ModelObject to this Model, generate a new ID for this ModelObject.
ModelObject* add_object();

View File

@ -218,7 +218,7 @@ void MultipleBeds::update_shown_beds(Model& model, const BuildVolume& build_volu
set_active_bed(m_number_of_beds != original_number_of_beds ? 0 : stash_active);
}
bool MultipleBeds::rearrange_after_load(Model& model, const BuildVolume& build_volume, std::function<void()> update_fn)
bool MultipleBeds::rearrange_after_load(Model& model, const BuildVolume& build_volume)
{
int original_number_of_beds = m_number_of_beds;
int stash_active = get_active_bed();
@ -233,7 +233,6 @@ bool MultipleBeds::rearrange_after_load(Model& model, const BuildVolume& build_v
model.update_print_volume_state(build_volume);
request_next_bed(false);
set_active_bed(m_number_of_beds != original_number_of_beds ? 0 : stash_active);
update_fn();
});
m_legacy_layout = true;

View File

@ -54,7 +54,7 @@ public:
int get_last_hovered_bed() const { return m_last_hovered_bed; }
void update_shown_beds(Model& model, const BuildVolume& build_volume, bool only_remove = false);
bool rearrange_after_load(Model& model, const BuildVolume& build_volume, std::function<void()> update_fn);
bool rearrange_after_load(Model& model, const BuildVolume& build_volume);
void set_loading_project_flag(bool project) { m_loading_project = project; }
bool get_loading_project_flag() const { return m_loading_project; }

View File

@ -1245,6 +1245,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
auto *new_model = (!load_model || one_by_one) ? nullptr : new Slic3r::Model();
std::vector<size_t> obj_idxs;
boost::optional<Semver> prusaslicer_generator_version;
int answer_convert_from_meters = wxOK_DEFAULT;
int answer_convert_from_imperial_units = wxOK_DEFAULT;
@ -1285,6 +1286,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
Slic3r::Model model;
bool is_project_file = type_prusa;
try {
if (type_3mf || type_zip_amf) {
#ifdef __linux__
@ -1304,7 +1306,13 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
{
DynamicPrintConfig config_loaded;
ConfigSubstitutionContext config_substitutions{ ForwardCompatibilitySubstitutionRule::Enable };
model = Slic3r::Model::read_from_archive(path.string(), &config_loaded, &config_substitutions, only_if(load_config, Model::LoadAttribute::CheckVersion));
model = Slic3r::Model::read_from_archive(
path.string(),
&config_loaded,
&config_substitutions,
prusaslicer_generator_version,
only_if(load_config, Model::LoadAttribute::CheckVersion)
);
if (load_config && !config_loaded.empty()) {
// Based on the printer technology field found in the loaded config, select the base for the config,
loaded_printer_technology = Preset::printer_technology(config_loaded);
@ -1600,15 +1608,20 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
// this is required because the selected object changed and the flatten on face an sla support gizmos need to be updated accordingly
view3D->get_canvas3d()->update_gizmos_on_off_state();
}
GLGizmoSimplify::add_simplify_suggestion_notification(
obj_idxs, model.objects, *notification_manager);
s_multiple_beds.rearrange_after_load(model, q->build_volume(), [this]() {
q->canvas3D()->check_volumes_outside_state();
s_multiple_beds.ensure_wipe_towers_on_beds(model, fff_prints);
s_multiple_beds.update_shown_beds(model, q->build_volume());
});
if (
prusaslicer_generator_version
&& *prusaslicer_generator_version < Semver("2.9.0-alpha1")
) {
BOOST_LOG_TRIVIAL(info) << "Rearranging legacy project...";
s_multiple_beds.rearrange_after_load(model, q->build_volume());
}
q->canvas3D()->check_volumes_outside_state();
s_multiple_beds.ensure_wipe_towers_on_beds(model, fff_prints);
s_multiple_beds.update_shown_beds(model, q->build_volume());
update();
return obj_idxs;

View File

@ -37,6 +37,7 @@
#include "libslic3r/Print.hpp"
#include "libslic3r/PresetBundle.hpp"
#include "libslic3r/Format/3mf.hpp"
#include "libslic3r/Semver.hpp"
#include "../GUI/GUI.hpp"
#include "../GUI/I18N.hpp"
#include "../GUI/MsgDialog.hpp"
@ -392,7 +393,8 @@ bool fix_model_by_win10_sdk_gui(ModelObject &model_object, int volume_idx, wxPro
on_progress(L("Loading repaired model"), 80);
DynamicPrintConfig config;
ConfigSubstitutionContext config_substitutions{ ForwardCompatibilitySubstitutionRule::EnableSilent };
bool loaded = Slic3r::load_3mf(path_dst.string().c_str(), config, config_substitutions, &model, false);
boost::optional<Semver> prusaslicer_generator_version;
bool loaded = Slic3r::load_3mf(path_dst.string().c_str(), config, config_substitutions, &model, false, prusaslicer_generator_version);
boost::filesystem::remove(path_dst);
if (! loaded)
throw Slic3r::RuntimeError("Import of the repaired 3mf file failed");

View File

@ -165,7 +165,8 @@ inline std::unique_ptr<Print> process_3mf(const std::filesystem::path &path) {
Model model;
ConfigSubstitutionContext context{ForwardCompatibilitySubstitutionRule::Disable};
load_3mf(path.string().c_str(), config, context, &model, false);
boost::optional<Semver> version;
load_3mf(path.string().c_str(), config, context, &model, false, version);
Slic3r::Test::init_print(std::vector<TriangleMesh>{}, *print, model, config);
print->process();

View File

@ -15,7 +15,8 @@ SCENARIO("Reading 3mf file", "[3mf]") {
std::string path = std::string(TEST_DATA_DIR) + "/test_3mf/Geräte/Büchse.3mf";
DynamicPrintConfig config;
ConfigSubstitutionContext ctxt{ ForwardCompatibilitySubstitutionRule::Disable };
bool ret = load_3mf(path.c_str(), config, ctxt, &model, false);
boost::optional<Semver> version;
bool ret = load_3mf(path.c_str(), config, ctxt, &model, false, version);
THEN("load should succeed") {
REQUIRE(ret);
}
@ -59,7 +60,8 @@ SCENARIO("Export+Import geometry to/from 3mf file cycle", "[3mf]") {
DynamicPrintConfig dst_config;
{
ConfigSubstitutionContext ctxt{ ForwardCompatibilitySubstitutionRule::Disable };
load_3mf(test_file.c_str(), dst_config, ctxt, &dst_model, false);
boost::optional<Semver> version;
load_3mf(test_file.c_str(), dst_config, ctxt, &dst_model, false, version);
}
boost::filesystem::remove(test_file);