Merge branch 'master' of https://github.com/prusa3d/PrusaSlicer into et_world_coordinates
This commit is contained in:
commit
a32c8b77eb
47 changed files with 18897 additions and 18251 deletions
|
@ -1285,8 +1285,13 @@ bool GUI_App::on_init_inner()
|
|||
else
|
||||
load_current_presets();
|
||||
|
||||
// Save the active profiles as a "saved into project".
|
||||
update_saved_preset_from_current_preset();
|
||||
|
||||
if (plater_ != nullptr) {
|
||||
// Save the names of active presets and project specific config into ProjectDirtyStateManager.
|
||||
plater_->reset_project_dirty_initial_presets();
|
||||
// Update Project dirty state, update application title bar.
|
||||
plater_->update_project_dirty_from_presets();
|
||||
}
|
||||
|
||||
|
@ -2447,16 +2452,13 @@ void GUI_App::update_saved_preset_from_current_preset()
|
|||
}
|
||||
}
|
||||
|
||||
std::vector<std::pair<unsigned int, std::string>> GUI_App::get_selected_presets() const
|
||||
std::vector<const PresetCollection*> GUI_App::get_active_preset_collections() const
|
||||
{
|
||||
std::vector<std::pair<unsigned int, std::string>> ret;
|
||||
std::vector<const PresetCollection*> ret;
|
||||
PrinterTechnology printer_technology = preset_bundle->printers.get_edited_preset().printer_technology();
|
||||
for (Tab* tab : tabs_list) {
|
||||
if (tab->supports_printer_technology(printer_technology)) {
|
||||
const PresetCollection* presets = tab->get_presets();
|
||||
ret.push_back({ static_cast<unsigned int>(presets->type()), presets->get_selected_preset_name() });
|
||||
}
|
||||
}
|
||||
for (const Tab* tab : tabs_list)
|
||||
if (tab->supports_printer_technology(printer_technology))
|
||||
ret.push_back(tab->get_presets());
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -252,7 +252,7 @@ public:
|
|||
bool has_unsaved_preset_changes() const;
|
||||
bool has_current_preset_changes() const;
|
||||
void update_saved_preset_from_current_preset();
|
||||
std::vector<std::pair<unsigned int, std::string>> get_selected_presets() const;
|
||||
std::vector<const PresetCollection*> get_active_preset_collections() const;
|
||||
bool check_and_save_current_preset_changes(const wxString& caption, const wxString& header, bool remember_choice = true, bool use_dont_save_insted_of_discard = false);
|
||||
void apply_keeped_preset_modifications();
|
||||
bool check_and_keep_current_preset_changes(const wxString& caption, const wxString& header, int action_buttons, bool* postponed_apply_of_keeped_changes = nullptr);
|
||||
|
|
|
@ -141,6 +141,8 @@ bool ObjectSettings::update_settings_list()
|
|||
{
|
||||
Option option = optgroup->get_option(opt);
|
||||
option.opt.width = 12;
|
||||
if (!option.opt.full_label.empty())
|
||||
option.opt.label = option.opt.full_label;
|
||||
if (is_extruders_cat)
|
||||
option.opt.max = wxGetApp().extruders_edited_cnt();
|
||||
optgroup->append_single_option_line(option);
|
||||
|
|
|
@ -378,6 +378,8 @@ void GLGizmoCut::update_contours()
|
|||
|
||||
MeshSlicingParams slicing_params;
|
||||
slicing_params.trafo = first_glvolume->get_instance_transformation().get_matrix();
|
||||
slicing_params.trafo.pretranslate(Vec3d(0., 0., first_glvolume->get_sla_shift_z()));
|
||||
|
||||
const Polygons polys = slice_mesh(m_cut_contours.mesh.its, m_cut_z, slicing_params);
|
||||
if (!polys.empty()) {
|
||||
m_cut_contours.contours.init_from(polys, static_cast<float>(m_cut_z));
|
||||
|
|
|
@ -859,7 +859,10 @@ bool MainFrame::save_project_as(const wxString& filename)
|
|||
{
|
||||
bool ret = (m_plater != nullptr) ? m_plater->export_3mf(into_path(filename)) : false;
|
||||
if (ret) {
|
||||
// wxGetApp().update_saved_preset_from_current_preset();
|
||||
// Make a copy of the active presets for detecting changes in preset values.
|
||||
wxGetApp().update_saved_preset_from_current_preset();
|
||||
// Save the names of active presets and project specific config into ProjectDirtyStateManager.
|
||||
// Reset ProjectDirtyStateManager's state as saved, mark active UndoRedo step as saved with project.
|
||||
m_plater->reset_project_dirty_after_save();
|
||||
}
|
||||
return ret;
|
||||
|
|
|
@ -311,7 +311,11 @@ wxString get_wraped_wxString(const wxString& in, size_t line_len /*=80*/)
|
|||
overwrite = true;
|
||||
if (newline)
|
||||
break;
|
||||
} else if (in[j] == '/') {
|
||||
} else if (in[j] == '/'
|
||||
#ifdef _WIN32
|
||||
|| in[j] == '\\'
|
||||
#endif // _WIN32
|
||||
) {
|
||||
// Insert after the slash.
|
||||
ibreak = ++ j;
|
||||
overwrite = false;
|
||||
|
|
|
@ -502,6 +502,7 @@ FreqChangedParams::FreqChangedParams(wxWindow* parent) :
|
|||
std::vector<float> extruders = dlg.get_extruders();
|
||||
(project_config.option<ConfigOptionFloats>("wiping_volumes_matrix"))->values = std::vector<double>(matrix.begin(), matrix.end());
|
||||
(project_config.option<ConfigOptionFloats>("wiping_volumes_extruders"))->values = std::vector<double>(extruders.begin(), extruders.end());
|
||||
// Update Project dirty state, update application title bar.
|
||||
wxGetApp().plater()->update_project_dirty_from_presets();
|
||||
wxPostEvent(parent, SimpleEvent(EVT_SCHEDULE_BACKGROUND_PROCESS, parent));
|
||||
}
|
||||
|
@ -2359,7 +2360,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
|||
}
|
||||
|
||||
const auto loading = _L("Loading") + dots;
|
||||
wxProgressDialog dlg(loading, "", 100, find_toplevel_parent(q), wxPD_AUTO_HIDE);
|
||||
wxProgressDialog progress_dlg(loading, "", 100, find_toplevel_parent(q), wxPD_AUTO_HIDE);
|
||||
wxBusyCursor busy;
|
||||
|
||||
auto *new_model = (!load_model || one_by_one) ? nullptr : new Slic3r::Model();
|
||||
|
@ -2368,7 +2369,8 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
|||
int answer_convert_from_meters = wxOK_DEFAULT;
|
||||
int answer_convert_from_imperial_units = wxOK_DEFAULT;
|
||||
|
||||
for (size_t i = 0; i < input_files.size(); ++i) {
|
||||
size_t input_files_size = input_files.size();
|
||||
for (size_t i = 0; i < input_files_size; ++i) {
|
||||
#ifdef _WIN32
|
||||
auto path = input_files[i];
|
||||
// On Windows, we swap slashes to back slashes, see GH #6803 as read_from_file() does not understand slashes on Windows thus it assignes full path to names of loaded objects.
|
||||
|
@ -2378,8 +2380,8 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
|||
const auto &path = input_files[i];
|
||||
#endif // _WIN32
|
||||
const auto filename = path.filename();
|
||||
dlg.Update(static_cast<int>(100.0f * static_cast<float>(i) / static_cast<float>(input_files.size())), _L("Loading file") + ": " + from_path(filename));
|
||||
dlg.Fit();
|
||||
progress_dlg.Update(static_cast<int>(100.0f * static_cast<float>(i) / static_cast<float>(input_files.size())), _L("Loading file") + ": " + from_path(filename));
|
||||
progress_dlg.Fit();
|
||||
|
||||
const bool type_3mf = std::regex_match(path.string(), pattern_3mf);
|
||||
const bool type_zip_amf = !type_3mf && std::regex_match(path.string(), pattern_zip_amf);
|
||||
|
@ -2390,17 +2392,28 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
|||
bool is_project_file = type_prusa;
|
||||
try {
|
||||
if (type_3mf || type_zip_amf) {
|
||||
#ifdef __linux__
|
||||
// On Linux Constructor of the ProgressDialog calls DisableOtherWindows() function which causes a disabling of all children of the find_toplevel_parent(q)
|
||||
// And a destructor of the ProgressDialog calls ReenableOtherWindows() function which revert previously disabled children.
|
||||
// But if printer technology will be changes during project loading,
|
||||
// then related SLA Print and Materials Settings or FFF Print and Filaments Settings will be unparent from the wxNoteBook
|
||||
// and that is why they will never be enabled after destruction of the ProgressDialog.
|
||||
// So, distroy progress_gialog if we are loading project file
|
||||
if (input_files_size == 1)
|
||||
progress_dlg.Destroy();
|
||||
#endif
|
||||
DynamicPrintConfig config;
|
||||
PrinterTechnology loaded_printer_technology {ptFFF};
|
||||
{
|
||||
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));
|
||||
if (load_config && !config_loaded.empty()) {
|
||||
// Based on the printer technology field found in the loaded config, select the base for the config,
|
||||
PrinterTechnology printer_technology = Preset::printer_technology(config_loaded);
|
||||
loaded_printer_technology = Preset::printer_technology(config_loaded);
|
||||
|
||||
// We can't to load SLA project if there is at least one multi-part object on the bed
|
||||
if (printer_technology == ptSLA) {
|
||||
if (loaded_printer_technology == ptSLA) {
|
||||
const ModelObjectPtrs& objects = q->model().objects;
|
||||
for (auto object : objects)
|
||||
if (object->volumes.size() > 1) {
|
||||
|
@ -2412,7 +2425,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
|||
}
|
||||
}
|
||||
|
||||
config.apply(printer_technology == ptFFF ?
|
||||
config.apply(loaded_printer_technology == ptFFF ?
|
||||
static_cast<const ConfigBase&>(FullPrintConfig::defaults()) :
|
||||
static_cast<const ConfigBase&>(SLAFullPrintConfig::defaults()));
|
||||
// and place the loaded config over the base.
|
||||
|
@ -2443,7 +2456,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
|||
};
|
||||
|
||||
std::vector<std::string> names;
|
||||
if (printer_technology == ptFFF) {
|
||||
if (loaded_printer_technology == ptFFF) {
|
||||
update_selected_preset_visibility(preset_bundle->prints, names);
|
||||
for (const std::string& filament : preset_bundle->filament_presets) {
|
||||
Preset* preset = preset_bundle->filaments.find_preset(filament);
|
||||
|
@ -2474,7 +2487,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
|||
}
|
||||
}
|
||||
|
||||
if (printer_technology == ptFFF)
|
||||
if (loaded_printer_technology == ptFFF)
|
||||
CustomGCode::update_custom_gcode_per_print_z_from_config(model.custom_gcode_per_print_z, &preset_bundle->project_config);
|
||||
|
||||
// For exporting from the amf/3mf we shouldn't check printer_presets for the containing information about "Print Host upload"
|
||||
|
@ -5269,8 +5282,11 @@ void Plater::new_project()
|
|||
take_snapshot(_L("New Project"), UndoRedo::SnapshotType::ProjectSeparator);
|
||||
Plater::SuppressSnapshots suppress(this);
|
||||
reset();
|
||||
// Save the names of active presets and project specific config into ProjectDirtyStateManager.
|
||||
reset_project_dirty_initial_presets();
|
||||
// Make a copy of the active presets for detecting changes in preset values.
|
||||
wxGetApp().update_saved_preset_from_current_preset();
|
||||
// Update Project dirty state, update application title bar.
|
||||
update_project_dirty_from_presets();
|
||||
}
|
||||
|
||||
|
@ -5299,7 +5315,11 @@ void Plater::load_project(const wxString& filename)
|
|||
if (! load_files({ into_path(filename) }).empty()) {
|
||||
// At least one file was loaded.
|
||||
p->set_project_filename(filename);
|
||||
// Save the names of active presets and project specific config into ProjectDirtyStateManager.
|
||||
reset_project_dirty_initial_presets();
|
||||
// Make a copy of the active presets for detecting changes in preset values.
|
||||
wxGetApp().update_saved_preset_from_current_preset();
|
||||
// Update Project dirty state, update application title bar.
|
||||
update_project_dirty_from_presets();
|
||||
}
|
||||
}
|
||||
|
@ -5984,7 +6004,6 @@ void Plater::export_stl_obj(bool extended, bool selection_only)
|
|||
}
|
||||
else if (0 <= instance_id && instance_id < int(mo.instances.size()))
|
||||
mesh.transform(mo.instances[instance_id]->get_matrix(), true);
|
||||
|
||||
return mesh;
|
||||
};
|
||||
|
||||
|
|
|
@ -17,9 +17,11 @@ namespace GUI {
|
|||
|
||||
void ProjectDirtyStateManager::update_from_undo_redo_stack(bool dirty)
|
||||
{
|
||||
m_plater_dirty = dirty;
|
||||
if (const Plater *plater = wxGetApp().plater(); plater && wxGetApp().initialized())
|
||||
wxGetApp().mainframe->update_title();
|
||||
if (m_plater_dirty != dirty) {
|
||||
m_plater_dirty = dirty;
|
||||
if (const Plater *plater = wxGetApp().plater(); plater && wxGetApp().initialized())
|
||||
wxGetApp().mainframe->update_title();
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectDirtyStateManager::update_from_presets()
|
||||
|
@ -27,11 +29,11 @@ void ProjectDirtyStateManager::update_from_presets()
|
|||
m_presets_dirty = false;
|
||||
// check switching of the presets only for exist/loaded project, but not for new
|
||||
GUI_App &app = wxGetApp();
|
||||
if (!app.plater()->get_project_filename().IsEmpty()) {
|
||||
for (const auto& [type, name] : app.get_selected_presets())
|
||||
m_presets_dirty |= !m_initial_presets[type].empty() && m_initial_presets[type] != name;
|
||||
bool has_project = ! app.plater()->get_project_filename().IsEmpty();
|
||||
for (const PresetCollection *preset_collection : app.get_active_preset_collections()) {
|
||||
auto type = preset_collection->type();
|
||||
m_presets_dirty |= (has_project && !m_initial_presets[type].empty() && m_initial_presets[type] != preset_collection->get_selected_preset_name()) || preset_collection->saved_is_dirty();
|
||||
}
|
||||
m_presets_dirty |= app.has_unsaved_preset_changes();
|
||||
m_project_config_dirty = m_initial_project_config != app.preset_bundle->project_config;
|
||||
app.mainframe->update_title();
|
||||
}
|
||||
|
@ -49,8 +51,8 @@ void ProjectDirtyStateManager::reset_initial_presets()
|
|||
{
|
||||
m_initial_presets.fill(std::string{});
|
||||
GUI_App &app = wxGetApp();
|
||||
for (const auto& [type, name] : app.get_selected_presets())
|
||||
m_initial_presets[type] = name;
|
||||
for (const PresetCollection *preset_collection : app.get_active_preset_collections())
|
||||
m_initial_presets[preset_collection->type()] = preset_collection->get_selected_preset_name();
|
||||
m_initial_project_config = app.preset_bundle->project_config;
|
||||
}
|
||||
|
||||
|
|
|
@ -1247,6 +1247,7 @@ void Tab::on_presets_changed()
|
|||
// to avoid needless preset loading from update() function
|
||||
m_dependent_tabs.clear();
|
||||
|
||||
// Update Project dirty state, update application title bar.
|
||||
wxGetApp().plater()->update_project_dirty_from_presets();
|
||||
}
|
||||
|
||||
|
@ -4113,7 +4114,7 @@ wxSizer* TabPrint::create_manage_substitution_widget(wxWindow* parent)
|
|||
|
||||
create_btn(&m_del_all_substitutions_btn, _L("Delete all"), "cross");
|
||||
m_del_all_substitutions_btn->Bind(wxEVT_BUTTON, [this, parent](wxCommandEvent e) {
|
||||
if (MessageDialog(parent, _L("Are you sure you want to delete all substitutions?"), SLIC3R_APP_NAME, wxYES_NO | wxICON_QUESTION).
|
||||
if (MessageDialog(parent, _L("Are you sure you want to delete all substitutions?"), SLIC3R_APP_NAME, wxYES_NO | wxCANCEL | wxICON_QUESTION).
|
||||
ShowModal() != wxID_YES)
|
||||
return;
|
||||
m_subst_manager.delete_all();
|
||||
|
|
|
@ -371,6 +371,7 @@ public:
|
|||
|
||||
DynamicPrintConfig* get_config() { return m_config; }
|
||||
PresetCollection* get_presets() { return m_presets; }
|
||||
const PresetCollection* get_presets() const { return m_presets; }
|
||||
|
||||
void on_value_change(const std::string& opt_key, const boost::any& value);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue