mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-21 13:47:59 -06:00
Fixed conflicts after merge with master
This commit is contained in:
commit
6bddacee44
90 changed files with 4276 additions and 4185 deletions
|
@ -81,6 +81,9 @@
|
|||
#include "InstanceCheck.hpp"
|
||||
#include "NotificationManager.hpp"
|
||||
#include "PresetComboBoxes.hpp"
|
||||
#if ENABLE_PROJECT_DIRTY_STATE
|
||||
#include "ProjectDirtyStateManager.hpp"
|
||||
#endif // ENABLE_PROJECT_DIRTY_STATE
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include "Gizmos/GLGizmosManager.hpp"
|
||||
|
@ -1172,10 +1175,10 @@ void Sidebar::update_sliced_info_sizer()
|
|||
new_label += format_wxstr(":\n - %1%\n - %2%", _L("objects"), _L("wipe tower"));
|
||||
|
||||
wxString info_text = is_wipe_tower ?
|
||||
wxString::Format("%.2f \n%.2f \n%.2f", ps.total_used_filament / /*1000*/koef,
|
||||
(ps.total_used_filament - ps.total_wipe_tower_filament) / /*1000*/koef,
|
||||
ps.total_wipe_tower_filament / /*1000*/koef) :
|
||||
wxString::Format("%.2f", ps.total_used_filament / /*1000*/koef);
|
||||
wxString::Format("%.2f \n%.2f \n%.2f", ps.total_used_filament / koef,
|
||||
(ps.total_used_filament - ps.total_wipe_tower_filament) / koef,
|
||||
ps.total_wipe_tower_filament / koef) :
|
||||
wxString::Format("%.2f", ps.total_used_filament / koef);
|
||||
p->sliced_info->SetTextAndShow(siFilament_m, info_text, new_label);
|
||||
|
||||
koef = imperial_units ? pow(ObjectManipulation::mm_to_in, 3) : 1.0f;
|
||||
|
@ -1203,7 +1206,7 @@ void Sidebar::update_sliced_info_sizer()
|
|||
filament_weight = ps.total_weight;
|
||||
else {
|
||||
double filament_density = filament_preset->config.opt_float("filament_density", 0);
|
||||
filament_weight = filament.second * filament_density * 2.4052f * 0.001; // assumes 1.75mm filament diameter;
|
||||
filament_weight = filament.second * filament_density/* *2.4052f*/ * 0.001; // assumes 1.75mm filament diameter;
|
||||
|
||||
new_label += "\n - " + format_wxstr(_L("Filament at extruder %1%"), filament.first + 1);
|
||||
info_text += wxString::Format("\n%.2f", filament_weight);
|
||||
|
@ -1357,7 +1360,8 @@ void Sidebar::update_ui_from_settings()
|
|||
update_sliced_info_sizer();
|
||||
// update Cut gizmo, if it's open
|
||||
p->plater->canvas3D()->update_gizmos_on_off_state();
|
||||
p->plater->canvas3D()->request_extra_frame();
|
||||
p->plater->set_current_canvas_as_dirty();
|
||||
p->plater->get_current_canvas3D()->request_extra_frame();
|
||||
}
|
||||
|
||||
std::vector<PlaterPresetComboBox*>& Sidebar::combos_filament()
|
||||
|
@ -1395,7 +1399,13 @@ bool PlaterDropTarget::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &fi
|
|||
this->MSWUpdateDragImageOnLeave();
|
||||
#endif // WIN32
|
||||
|
||||
#if ENABLE_PROJECT_DIRTY_STATE
|
||||
bool res = (m_plater != nullptr) ? m_plater->load_files(filenames) : false;
|
||||
wxGetApp().mainframe->update_title();
|
||||
return res;
|
||||
#else
|
||||
return (m_plater != nullptr) ? m_plater->load_files(filenames) : false;
|
||||
#endif // ENABLE_PROJECT_DIRTY_STATE
|
||||
}
|
||||
|
||||
// State to manage showing after export notifications and device ejecting
|
||||
|
@ -1439,6 +1449,10 @@ struct Plater::priv
|
|||
Preview *preview;
|
||||
NotificationManager* notification_manager { nullptr };
|
||||
|
||||
#if ENABLE_PROJECT_DIRTY_STATE
|
||||
ProjectDirtyStateManager dirty_state;
|
||||
#endif // ENABLE_PROJECT_DIRTY_STATE
|
||||
|
||||
BackgroundSlicingProcess background_process;
|
||||
bool suppressed_backround_processing_update { false };
|
||||
|
||||
|
@ -1509,6 +1523,31 @@ struct Plater::priv
|
|||
priv(Plater *q, MainFrame *main_frame);
|
||||
~priv();
|
||||
|
||||
#if ENABLE_PROJECT_DIRTY_STATE
|
||||
bool is_project_dirty() const { return dirty_state.is_dirty(); }
|
||||
void update_project_dirty_from_presets() { dirty_state.update_from_presets(); }
|
||||
bool save_project_if_dirty() {
|
||||
if (dirty_state.is_dirty()) {
|
||||
MainFrame* mainframe = wxGetApp().mainframe;
|
||||
if (mainframe->can_save_as()) {
|
||||
wxMessageDialog dlg(mainframe, _L("Do you want to save the changes to the current project ?"), wxString(SLIC3R_APP_NAME), wxYES_NO | wxCANCEL);
|
||||
int res = dlg.ShowModal();
|
||||
if (res == wxID_YES)
|
||||
mainframe->save_project_as(wxGetApp().plater()->get_project_filename());
|
||||
else if (res == wxID_CANCEL)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void reset_project_dirty_after_save() { dirty_state.reset_after_save(); }
|
||||
void reset_project_dirty_initial_presets() { dirty_state.reset_initial_presets(); }
|
||||
|
||||
#if ENABLE_PROJECT_DIRTY_STATE_DEBUG_WINDOW
|
||||
void render_project_state_debug_window() const { dirty_state.render_debug_window(); }
|
||||
#endif // ENABLE_PROJECT_DIRTY_STATE_DEBUG_WINDOW
|
||||
#endif // ENABLE_PROJECT_DIRTY_STATE
|
||||
|
||||
enum class UpdateParams {
|
||||
FORCE_FULL_SCREEN_REFRESH = 1,
|
||||
FORCE_BACKGROUND_PROCESSING_UPDATE = 2,
|
||||
|
@ -1554,7 +1593,11 @@ struct Plater::priv
|
|||
BoundingBox scaled_bed_shape_bb() const;
|
||||
|
||||
std::vector<size_t> load_files(const std::vector<fs::path>& input_files, bool load_model, bool load_config, bool used_inches = false);
|
||||
#if ENABLE_ALLOW_NEGATIVE_Z
|
||||
std::vector<size_t> load_model_objects(const ModelObjectPtrs& model_objects, bool allow_negative_z = false);
|
||||
#else
|
||||
std::vector<size_t> load_model_objects(const ModelObjectPtrs &model_objects);
|
||||
#endif // ENABLE_ALLOW_NEGATIVE_Z
|
||||
wxString get_export_file(GUI::FileType file_type);
|
||||
|
||||
const Selection& get_selection() const;
|
||||
|
@ -1588,8 +1631,8 @@ struct Plater::priv
|
|||
void redo();
|
||||
void undo_redo_to(size_t time_to_load);
|
||||
|
||||
void suppress_snapshots() { this->m_prevent_snapshots++; }
|
||||
void allow_snapshots() { this->m_prevent_snapshots--; }
|
||||
void suppress_snapshots() { m_prevent_snapshots++; }
|
||||
void allow_snapshots() { m_prevent_snapshots--; }
|
||||
|
||||
void process_validation_warning(const std::string& warning) const;
|
||||
|
||||
|
@ -2294,11 +2337,19 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
|||
return obj_idxs;
|
||||
}
|
||||
|
||||
#if ENABLE_ALLOW_NEGATIVE_Z
|
||||
for (ModelObject* model_object : model.objects) {
|
||||
if (!type_3mf && !type_zip_amf)
|
||||
model_object->center_around_origin(false);
|
||||
model_object->ensure_on_bed(is_project_file);
|
||||
}
|
||||
#else
|
||||
for (ModelObject* model_object : model.objects) {
|
||||
if (!type_3mf && !type_zip_amf)
|
||||
model_object->center_around_origin(false);
|
||||
model_object->ensure_on_bed();
|
||||
}
|
||||
#endif // ENABLE_ALLOW_NEGATIVE_Z
|
||||
|
||||
// check multi-part object adding for the SLA-printing
|
||||
if (printer_technology == ptSLA) {
|
||||
|
@ -2312,7 +2363,11 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
|||
}
|
||||
|
||||
if (one_by_one) {
|
||||
#if ENABLE_ALLOW_NEGATIVE_Z
|
||||
auto loaded_idxs = load_model_objects(model.objects, is_project_file);
|
||||
#else
|
||||
auto loaded_idxs = load_model_objects(model.objects);
|
||||
#endif // ENABLE_ALLOW_NEGATIVE_Z
|
||||
obj_idxs.insert(obj_idxs.end(), loaded_idxs.begin(), loaded_idxs.end());
|
||||
} else {
|
||||
// This must be an .stl or .obj file, which may contain a maximum of one volume.
|
||||
|
@ -2364,7 +2419,11 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
|||
|
||||
// #define AUTOPLACEMENT_ON_LOAD
|
||||
|
||||
#if ENABLE_ALLOW_NEGATIVE_Z
|
||||
std::vector<size_t> Plater::priv::load_model_objects(const ModelObjectPtrs& model_objects, bool allow_negative_z)
|
||||
#else
|
||||
std::vector<size_t> Plater::priv::load_model_objects(const ModelObjectPtrs &model_objects)
|
||||
#endif // ENABLE_ALLOW_NEGATIVE_Z
|
||||
{
|
||||
const BoundingBoxf bed_shape = bed_shape_bb();
|
||||
const Vec3d bed_size = Slic3r::to_3d(bed_shape.size().cast<double>(), 1.0) - 2.0 * Vec3d::Ones();
|
||||
|
@ -2441,7 +2500,11 @@ std::vector<size_t> Plater::priv::load_model_objects(const ModelObjectPtrs &mode
|
|||
}
|
||||
#endif // ENABLE_MODIFIED_DOWNSCALE_ON_LOAD_OBJECTS_TOO_BIG
|
||||
|
||||
#if ENABLE_ALLOW_NEGATIVE_Z
|
||||
object->ensure_on_bed(allow_negative_z);
|
||||
#else
|
||||
object->ensure_on_bed();
|
||||
#endif // ENABLE_ALLOW_NEGATIVE_Z
|
||||
}
|
||||
|
||||
#ifdef AUTOPLACEMENT_ON_LOAD
|
||||
|
@ -2597,8 +2660,7 @@ int Plater::priv::get_selected_volume_idx() const
|
|||
void Plater::priv::selection_changed()
|
||||
{
|
||||
// if the selection is not valid to allow for layer editing, we need to turn off the tool if it is running
|
||||
bool enable_layer_editing = layers_height_allowed();
|
||||
if (!enable_layer_editing && view3D->is_layers_editing_enabled()) {
|
||||
if (!layers_height_allowed() && view3D->is_layers_editing_enabled()) {
|
||||
SimpleEvent evt(EVT_GLTOOLBAR_LAYERSEDITING);
|
||||
on_action_layersediting(evt);
|
||||
}
|
||||
|
@ -2735,10 +2797,11 @@ void Plater::priv::split_object()
|
|||
Slic3r::GUI::warning_catcher(q, _L("The selected object couldn't be split because it contains only one solid part."));
|
||||
else
|
||||
{
|
||||
if (current_model_object->volumes.size() != new_objects.size())
|
||||
// If we splited object which is contain some parts/modifiers then all non-solid parts (modifiers) were deleted
|
||||
if (current_model_object->volumes.size() > 1 && current_model_object->volumes.size() != new_objects.size())
|
||||
notification_manager->push_notification(NotificationType::CustomNotification,
|
||||
NotificationManager::NotificationLevel::RegularNotification,
|
||||
_u8L("All non-solid parts (modifiers) was deleted"));
|
||||
_u8L("All non-solid parts (modifiers) were deleted"));
|
||||
|
||||
Plater::TakeSnapshot snapshot(q, _L("Split to Objects"));
|
||||
|
||||
|
@ -3054,21 +3117,19 @@ void Plater::priv::reload_from_disk()
|
|||
int volume_idx;
|
||||
|
||||
// operators needed by std::algorithms
|
||||
bool operator < (const SelectedVolume& other) const { return (object_idx < other.object_idx) || ((object_idx == other.object_idx) && (volume_idx < other.volume_idx)); }
|
||||
bool operator == (const SelectedVolume& other) const { return (object_idx == other.object_idx) && (volume_idx == other.volume_idx); }
|
||||
bool operator < (const SelectedVolume& other) const { return object_idx < other.object_idx || (object_idx == other.object_idx && volume_idx < other.volume_idx); }
|
||||
bool operator == (const SelectedVolume& other) const { return object_idx == other.object_idx && volume_idx == other.volume_idx; }
|
||||
};
|
||||
std::vector<SelectedVolume> selected_volumes;
|
||||
|
||||
// collects selected ModelVolumes
|
||||
const std::set<unsigned int>& selected_volumes_idxs = selection.get_volume_idxs();
|
||||
for (unsigned int idx : selected_volumes_idxs)
|
||||
{
|
||||
for (unsigned int idx : selected_volumes_idxs) {
|
||||
const GLVolume* v = selection.get_volume(idx);
|
||||
int v_idx = v->volume_idx();
|
||||
if (v_idx >= 0)
|
||||
{
|
||||
if (v_idx >= 0) {
|
||||
int o_idx = v->object_idx();
|
||||
if ((0 <= o_idx) && (o_idx < (int)model.objects.size()))
|
||||
if (0 <= o_idx && o_idx < (int)model.objects.size())
|
||||
selected_volumes.push_back({ o_idx, v_idx });
|
||||
}
|
||||
}
|
||||
|
@ -3078,13 +3139,11 @@ void Plater::priv::reload_from_disk()
|
|||
// collects paths of files to load
|
||||
std::vector<fs::path> input_paths;
|
||||
std::vector<fs::path> missing_input_paths;
|
||||
for (const SelectedVolume& v : selected_volumes)
|
||||
{
|
||||
for (const SelectedVolume& v : selected_volumes) {
|
||||
const ModelObject* object = model.objects[v.object_idx];
|
||||
const ModelVolume* volume = object->volumes[v.volume_idx];
|
||||
|
||||
if (!volume->source.input_file.empty())
|
||||
{
|
||||
if (!volume->source.input_file.empty()) {
|
||||
if (fs::exists(volume->source.input_file))
|
||||
input_paths.push_back(volume->source.input_file);
|
||||
else
|
||||
|
@ -3097,8 +3156,7 @@ void Plater::priv::reload_from_disk()
|
|||
std::sort(missing_input_paths.begin(), missing_input_paths.end());
|
||||
missing_input_paths.erase(std::unique(missing_input_paths.begin(), missing_input_paths.end()), missing_input_paths.end());
|
||||
|
||||
while (!missing_input_paths.empty())
|
||||
{
|
||||
while (!missing_input_paths.empty()) {
|
||||
// ask user to select the missing file
|
||||
fs::path search = missing_input_paths.back();
|
||||
wxString title = _L("Please select the file to reload");
|
||||
|
@ -3112,21 +3170,18 @@ void Plater::priv::reload_from_disk()
|
|||
|
||||
std::string sel_filename_path = dialog.GetPath().ToUTF8().data();
|
||||
std::string sel_filename = fs::path(sel_filename_path).filename().string();
|
||||
if (boost::algorithm::iequals(search.filename().string(), sel_filename))
|
||||
{
|
||||
if (boost::algorithm::iequals(search.filename().string(), sel_filename)) {
|
||||
input_paths.push_back(sel_filename_path);
|
||||
missing_input_paths.pop_back();
|
||||
|
||||
fs::path sel_path = fs::path(sel_filename_path).remove_filename().string();
|
||||
|
||||
std::vector<fs::path>::iterator it = missing_input_paths.begin();
|
||||
while (it != missing_input_paths.end())
|
||||
{
|
||||
while (it != missing_input_paths.end()) {
|
||||
// try to use the path of the selected file with all remaining missing files
|
||||
fs::path repathed_filename = sel_path;
|
||||
repathed_filename /= it->filename();
|
||||
if (fs::exists(repathed_filename))
|
||||
{
|
||||
if (fs::exists(repathed_filename)) {
|
||||
input_paths.push_back(repathed_filename.string());
|
||||
it = missing_input_paths.erase(it);
|
||||
}
|
||||
|
@ -3134,8 +3189,7 @@ void Plater::priv::reload_from_disk()
|
|||
++it;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
wxString message = _L("It is not allowed to change the file to reload") + " (" + from_u8(search.filename().string()) + ").\n" + _L("Do you want to retry") + " ?";
|
||||
wxMessageDialog dlg(q, message, wxMessageBoxCaptionStr, wxYES_NO | wxYES_DEFAULT | wxICON_QUESTION);
|
||||
if (dlg.ShowModal() != wxID_YES)
|
||||
|
@ -3149,8 +3203,7 @@ void Plater::priv::reload_from_disk()
|
|||
std::vector<wxString> fail_list;
|
||||
|
||||
// load one file at a time
|
||||
for (size_t i = 0; i < input_paths.size(); ++i)
|
||||
{
|
||||
for (size_t i = 0; i < input_paths.size(); ++i) {
|
||||
const auto& path = input_paths[i].string();
|
||||
|
||||
wxBusyCursor wait;
|
||||
|
@ -3160,8 +3213,7 @@ void Plater::priv::reload_from_disk()
|
|||
try
|
||||
{
|
||||
new_model = Model::read_from_file(path, nullptr, true, false);
|
||||
for (ModelObject* model_object : new_model.objects)
|
||||
{
|
||||
for (ModelObject* model_object : new_model.objects) {
|
||||
model_object->center_around_origin();
|
||||
model_object->ensure_on_bed();
|
||||
}
|
||||
|
@ -3173,34 +3225,31 @@ void Plater::priv::reload_from_disk()
|
|||
}
|
||||
|
||||
// update the selected volumes whose source is the current file
|
||||
for (const SelectedVolume& sel_v : selected_volumes)
|
||||
{
|
||||
for (const SelectedVolume& sel_v : selected_volumes) {
|
||||
ModelObject* old_model_object = model.objects[sel_v.object_idx];
|
||||
ModelVolume* old_volume = old_model_object->volumes[sel_v.volume_idx];
|
||||
|
||||
#if ENABLE_ALLOW_NEGATIVE_Z
|
||||
bool sinking = old_model_object->bounding_box().min.z() < 0.0;
|
||||
#endif // ENABLE_ALLOW_NEGATIVE_Z
|
||||
|
||||
bool has_source = !old_volume->source.input_file.empty() && boost::algorithm::iequals(fs::path(old_volume->source.input_file).filename().string(), fs::path(path).filename().string());
|
||||
bool has_name = !old_volume->name.empty() && boost::algorithm::iequals(old_volume->name, fs::path(path).filename().string());
|
||||
if (has_source || has_name)
|
||||
{
|
||||
if (has_source || has_name) {
|
||||
int new_volume_idx = -1;
|
||||
int new_object_idx = -1;
|
||||
if (has_source)
|
||||
{
|
||||
if (has_source) {
|
||||
// take idxs from source
|
||||
new_volume_idx = old_volume->source.volume_idx;
|
||||
new_object_idx = old_volume->source.object_idx;
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
// take idxs from the 1st matching volume
|
||||
for (size_t o = 0; o < new_model.objects.size(); ++o)
|
||||
{
|
||||
for (size_t o = 0; o < new_model.objects.size(); ++o) {
|
||||
ModelObject* obj = new_model.objects[o];
|
||||
bool found = false;
|
||||
for (size_t v = 0; v < obj->volumes.size(); ++v)
|
||||
{
|
||||
if (obj->volumes[v]->name == old_volume->name)
|
||||
{
|
||||
for (size_t v = 0; v < obj->volumes.size(); ++v) {
|
||||
if (obj->volumes[v]->name == old_volume->name) {
|
||||
new_volume_idx = (int)v;
|
||||
new_object_idx = (int)o;
|
||||
found = true;
|
||||
|
@ -3212,19 +3261,16 @@ void Plater::priv::reload_from_disk()
|
|||
}
|
||||
}
|
||||
|
||||
if ((new_object_idx < 0) && ((int)new_model.objects.size() <= new_object_idx))
|
||||
{
|
||||
if (new_object_idx < 0 && (int)new_model.objects.size() <= new_object_idx) {
|
||||
fail_list.push_back(from_u8(has_source ? old_volume->source.input_file : old_volume->name));
|
||||
continue;
|
||||
}
|
||||
ModelObject* new_model_object = new_model.objects[new_object_idx];
|
||||
if ((new_volume_idx < 0) && ((int)new_model.objects.size() <= new_volume_idx))
|
||||
{
|
||||
if (new_volume_idx < 0 && (int)new_model.objects.size() <= new_volume_idx) {
|
||||
fail_list.push_back(from_u8(has_source ? old_volume->source.input_file : old_volume->name));
|
||||
continue;
|
||||
}
|
||||
if (new_volume_idx < (int)new_model_object->volumes.size())
|
||||
{
|
||||
if (new_volume_idx < (int)new_model_object->volumes.size()) {
|
||||
old_model_object->add_volume(*new_model_object->volumes[new_volume_idx]);
|
||||
ModelVolume* new_volume = old_model_object->volumes.back();
|
||||
new_volume->set_new_unique_id();
|
||||
|
@ -3241,7 +3287,10 @@ void Plater::priv::reload_from_disk()
|
|||
new_volume->seam_facets.assign(old_volume->seam_facets);
|
||||
std::swap(old_model_object->volumes[sel_v.volume_idx], old_model_object->volumes.back());
|
||||
old_model_object->delete_volume(old_model_object->volumes.size() - 1);
|
||||
old_model_object->ensure_on_bed();
|
||||
#if ENABLE_ALLOW_NEGATIVE_Z
|
||||
if (!sinking)
|
||||
#endif // ENABLE_ALLOW_NEGATIVE_Z
|
||||
old_model_object->ensure_on_bed();
|
||||
|
||||
sla::reproject_points_and_holes(old_model_object);
|
||||
}
|
||||
|
@ -3249,11 +3298,9 @@ void Plater::priv::reload_from_disk()
|
|||
}
|
||||
}
|
||||
|
||||
if (!fail_list.empty())
|
||||
{
|
||||
if (!fail_list.empty()) {
|
||||
wxString message = _L("Unable to reload:") + "\n";
|
||||
for (const wxString& s : fail_list)
|
||||
{
|
||||
for (const wxString& s : fail_list) {
|
||||
message += s + "\n";
|
||||
}
|
||||
wxMessageDialog dlg(q, message, _L("Error during reload"), wxOK | wxOK_DEFAULT | wxICON_WARNING);
|
||||
|
@ -3264,8 +3311,7 @@ void Plater::priv::reload_from_disk()
|
|||
update();
|
||||
|
||||
// new GLVolumes have been created at this point, so update their printable state
|
||||
for (size_t i = 0; i < model.objects.size(); ++i)
|
||||
{
|
||||
for (size_t i = 0; i < model.objects.size(); ++i) {
|
||||
view3D->get_canvas3d()->update_instance_printable_state_for_object(i);
|
||||
}
|
||||
}
|
||||
|
@ -3285,8 +3331,7 @@ void Plater::priv::reload_all_from_disk()
|
|||
reload_from_disk();
|
||||
// restore previous selection
|
||||
selection.clear();
|
||||
for (unsigned int idx : curr_idxs)
|
||||
{
|
||||
for (unsigned int idx : curr_idxs) {
|
||||
selection.add(idx, false);
|
||||
}
|
||||
}
|
||||
|
@ -4006,7 +4051,7 @@ void Plater::priv::reset_gcode_toolpaths()
|
|||
bool Plater::priv::can_set_instance_to_object() const
|
||||
{
|
||||
const int obj_idx = get_selected_object_idx();
|
||||
return (0 <= obj_idx) && (obj_idx < (int)model.objects.size()) && (model.objects[obj_idx]->instances.size() > 1);
|
||||
return 0 <= obj_idx && obj_idx < (int)model.objects.size() && model.objects[obj_idx]->instances.size() > 1;
|
||||
}
|
||||
|
||||
bool Plater::priv::can_split(bool to_objects) const
|
||||
|
@ -4020,7 +4065,12 @@ bool Plater::priv::layers_height_allowed() const
|
|||
return false;
|
||||
|
||||
int obj_idx = get_selected_object_idx();
|
||||
return (0 <= obj_idx) && (obj_idx < (int)model.objects.size()) && config->opt_bool("variable_layer_height") && view3D->is_layers_editing_allowed();
|
||||
#if ENABLE_ALLOW_NEGATIVE_Z
|
||||
return 0 <= obj_idx && obj_idx < (int)model.objects.size() && model.objects[obj_idx]->bounding_box().max.z() > 0.0 &&
|
||||
config->opt_bool("variable_layer_height") && view3D->is_layers_editing_allowed();
|
||||
#else
|
||||
return 0 <= obj_idx && obj_idx < (int)model.objects.size() && config->opt_bool("variable_layer_height") && view3D->is_layers_editing_allowed();
|
||||
#endif // ENABLE_ALLOW_NEGATIVE_Z
|
||||
}
|
||||
|
||||
bool Plater::priv::can_mirror() const
|
||||
|
@ -4213,9 +4263,9 @@ int Plater::priv::get_active_snapshot_index()
|
|||
|
||||
void Plater::priv::take_snapshot(const std::string& snapshot_name)
|
||||
{
|
||||
if (this->m_prevent_snapshots > 0)
|
||||
if (m_prevent_snapshots > 0)
|
||||
return;
|
||||
assert(this->m_prevent_snapshots >= 0);
|
||||
assert(m_prevent_snapshots >= 0);
|
||||
UndoRedo::SnapshotData snapshot_data;
|
||||
snapshot_data.printer_technology = this->printer_technology;
|
||||
if (this->view3D->is_layers_editing_enabled())
|
||||
|
@ -4245,6 +4295,11 @@ void Plater::priv::take_snapshot(const std::string& snapshot_name)
|
|||
}
|
||||
this->undo_redo_stack().take_snapshot(snapshot_name, model, view3D->get_canvas3d()->get_selection(), view3D->get_canvas3d()->get_gizmos_manager(), snapshot_data);
|
||||
this->undo_redo_stack().release_least_recently_used();
|
||||
|
||||
#if ENABLE_PROJECT_DIRTY_STATE
|
||||
dirty_state.update_from_undo_redo_stack(ProjectDirtyStateManager::UpdateType::TakeSnapshot);
|
||||
#endif // ENABLE_PROJECT_DIRTY_STATE
|
||||
|
||||
// Save the last active preset name of a particular printer technology.
|
||||
((this->printer_technology == ptFFF) ? m_last_fff_printer_profile_name : m_last_sla_printer_profile_name) = wxGetApp().preset_bundle->printers.get_selected_preset_name();
|
||||
BOOST_LOG_TRIVIAL(info) << "Undo / Redo snapshot taken: " << snapshot_name << ", Undo / Redo stack memory: " << Slic3r::format_memsize_MB(this->undo_redo_stack().memsize()) << log_memory_info();
|
||||
|
@ -4285,8 +4340,13 @@ void Plater::priv::undo_redo_to(std::vector<UndoRedo::Snapshot>::const_iterator
|
|||
if (printer_technology_changed) {
|
||||
// Switching the printer technology when jumping forwards / backwards in time. Switch to the last active printer profile of the other type.
|
||||
std::string s_pt = (it_snapshot->snapshot_data.printer_technology == ptFFF) ? "FFF" : "SLA";
|
||||
#if ENABLE_PROJECT_DIRTY_STATE
|
||||
if (!wxGetApp().check_and_save_current_preset_changes(format_wxstr(_L(
|
||||
"%1% printer was active at the time the target Undo / Redo snapshot was taken. Switching to %1% printer requires reloading of %1% presets."), s_pt)))
|
||||
#else
|
||||
if (! wxGetApp().check_unsaved_changes(format_wxstr(_L(
|
||||
"%1% printer was active at the time the target Undo / Redo snapshot was taken. Switching to %1% printer requires reloading of %1% presets."), s_pt)))
|
||||
#endif // ENABLE_PROJECT_DIRTY_STATE
|
||||
// Don't switch the profiles.
|
||||
return;
|
||||
}
|
||||
|
@ -4375,6 +4435,10 @@ void Plater::priv::undo_redo_to(std::vector<UndoRedo::Snapshot>::const_iterator
|
|||
if (! view3D->is_layers_editing_enabled() && this->layers_height_allowed() && new_variable_layer_editing_active)
|
||||
view3D->get_canvas3d()->force_main_toolbar_left_action(view3D->get_canvas3d()->get_main_toolbar_item_id("layersediting"));
|
||||
}
|
||||
|
||||
#if ENABLE_PROJECT_DIRTY_STATE
|
||||
dirty_state.update_from_undo_redo_stack(ProjectDirtyStateManager::UpdateType::UndoRedoTo);
|
||||
#endif // ENABLE_PROJECT_DIRTY_STATE
|
||||
}
|
||||
|
||||
void Plater::priv::update_after_undo_redo(const UndoRedo::Snapshot& snapshot, bool /* temp_snapshot_was_taken */)
|
||||
|
@ -4458,9 +4522,16 @@ Plater::Plater(wxWindow *parent, MainFrame *main_frame)
|
|||
// Initialization performed in the private c-tor
|
||||
}
|
||||
|
||||
Plater::~Plater()
|
||||
{
|
||||
}
|
||||
#if ENABLE_PROJECT_DIRTY_STATE
|
||||
bool Plater::is_project_dirty() const { return p->is_project_dirty(); }
|
||||
void Plater::update_project_dirty_from_presets() { p->update_project_dirty_from_presets(); }
|
||||
bool Plater::save_project_if_dirty() { return p->save_project_if_dirty(); }
|
||||
void Plater::reset_project_dirty_after_save() { p->reset_project_dirty_after_save(); }
|
||||
void Plater::reset_project_dirty_initial_presets() { p->reset_project_dirty_initial_presets(); }
|
||||
#if ENABLE_PROJECT_DIRTY_STATE_DEBUG_WINDOW
|
||||
void Plater::render_project_state_debug_window() const { p->render_project_state_debug_window(); }
|
||||
#endif // ENABLE_PROJECT_DIRTY_STATE_DEBUG_WINDOW
|
||||
#endif // ENABLE_PROJECT_DIRTY_STATE
|
||||
|
||||
Sidebar& Plater::sidebar() { return *p->sidebar; }
|
||||
Model& Plater::model() { return p->model; }
|
||||
|
@ -4471,12 +4542,30 @@ SLAPrint& Plater::sla_print() { return p->sla_print; }
|
|||
|
||||
void Plater::new_project()
|
||||
{
|
||||
#if ENABLE_PROJECT_DIRTY_STATE
|
||||
if (!p->save_project_if_dirty())
|
||||
return;
|
||||
#endif // ENABLE_PROJECT_DIRTY_STATE
|
||||
|
||||
p->select_view_3D("3D");
|
||||
#if ENABLE_PROJECT_DIRTY_STATE
|
||||
take_snapshot(_L("New Project"));
|
||||
Plater::SuppressSnapshots suppress(this);
|
||||
reset();
|
||||
reset_project_dirty_initial_presets();
|
||||
update_project_dirty_from_presets();
|
||||
#else
|
||||
wxPostEvent(p->view3D->get_wxglcanvas(), SimpleEvent(EVT_GLTOOLBAR_DELETE_ALL));
|
||||
#endif // ENABLE_PROJECT_DIRTY_STATE
|
||||
}
|
||||
|
||||
void Plater::load_project()
|
||||
{
|
||||
#if ENABLE_PROJECT_DIRTY_STATE
|
||||
if (!p->save_project_if_dirty())
|
||||
return;
|
||||
#endif // ENABLE_PROJECT_DIRTY_STATE
|
||||
|
||||
// Ask user for a project file name.
|
||||
wxString input_file;
|
||||
wxGetApp().load_project(this, input_file);
|
||||
|
@ -4500,8 +4589,16 @@ void Plater::load_project(const wxString& filename)
|
|||
std::vector<size_t> res = load_files(input_paths);
|
||||
|
||||
// if res is empty no data has been loaded
|
||||
#if ENABLE_PROJECT_DIRTY_STATE
|
||||
if (!res.empty()) {
|
||||
p->set_project_filename(filename);
|
||||
reset_project_dirty_initial_presets();
|
||||
update_project_dirty_from_presets();
|
||||
}
|
||||
#else
|
||||
if (!res.empty())
|
||||
p->set_project_filename(filename);
|
||||
#endif // ENABLE_PROJECT_DIRTY_STATE
|
||||
}
|
||||
|
||||
void Plater::add_model(bool imperial_units/* = false*/)
|
||||
|
@ -4532,7 +4629,13 @@ void Plater::add_model(bool imperial_units/* = false*/)
|
|||
}
|
||||
|
||||
Plater::TakeSnapshot snapshot(this, snapshot_label);
|
||||
#if ENABLE_PROJECT_DIRTY_STATE
|
||||
std::vector<size_t> res = load_files(paths, true, false, imperial_units);
|
||||
if (!res.empty())
|
||||
wxGetApp().mainframe->update_title();
|
||||
#else
|
||||
load_files(paths, true, false, imperial_units);
|
||||
#endif // ENABLE_PROJECT_DIRTY_STATE
|
||||
}
|
||||
|
||||
void Plater::import_sl1_archive()
|
||||
|
@ -5247,24 +5350,39 @@ void Plater::export_amf()
|
|||
}
|
||||
}
|
||||
|
||||
#if ENABLE_PROJECT_DIRTY_STATE
|
||||
bool Plater::export_3mf(const boost::filesystem::path& output_path)
|
||||
#else
|
||||
void Plater::export_3mf(const boost::filesystem::path& output_path)
|
||||
#endif // ENABLE_PROJECT_DIRTY_STATE
|
||||
{
|
||||
if (p->model.objects.empty()
|
||||
|| canvas3D()->get_gizmos_manager().is_in_editing_mode(true))
|
||||
#if ENABLE_PROJECT_DIRTY_STATE
|
||||
return false;
|
||||
#else
|
||||
return;
|
||||
#endif // ENABLE_PROJECT_DIRTY_STATE
|
||||
|
||||
wxString path;
|
||||
bool export_config = true;
|
||||
if (output_path.empty())
|
||||
{
|
||||
if (output_path.empty()) {
|
||||
path = p->get_export_file(FT_3MF);
|
||||
#if ENABLE_PROJECT_DIRTY_STATE
|
||||
if (path.empty()) { return false; }
|
||||
#else
|
||||
if (path.empty()) { return; }
|
||||
#endif // ENABLE_PROJECT_DIRTY_STATE
|
||||
}
|
||||
else
|
||||
path = from_path(output_path);
|
||||
|
||||
if (!path.Lower().EndsWith(".3mf"))
|
||||
#if ENABLE_PROJECT_DIRTY_STATE
|
||||
return false;
|
||||
#else
|
||||
return;
|
||||
#endif // ENABLE_PROJECT_DIRTY_STATE
|
||||
|
||||
DynamicPrintConfig cfg = wxGetApp().preset_bundle->full_config_secure();
|
||||
const std::string path_u8 = into_u8(path);
|
||||
|
@ -5272,6 +5390,19 @@ void Plater::export_3mf(const boost::filesystem::path& output_path)
|
|||
bool full_pathnames = wxGetApp().app_config->get("export_sources_full_pathnames") == "1";
|
||||
ThumbnailData thumbnail_data;
|
||||
p->generate_thumbnail(thumbnail_data, THUMBNAIL_SIZE_3MF.first, THUMBNAIL_SIZE_3MF.second, false, true, true, true);
|
||||
#if ENABLE_PROJECT_DIRTY_STATE
|
||||
bool ret = Slic3r::store_3mf(path_u8.c_str(), &p->model, export_config ? &cfg : nullptr, full_pathnames, &thumbnail_data);
|
||||
if (ret) {
|
||||
// Success
|
||||
p->statusbar()->set_status_text(format_wxstr(_L("3MF file exported to %s"), path));
|
||||
p->set_project_filename(path);
|
||||
}
|
||||
else {
|
||||
// Failure
|
||||
p->statusbar()->set_status_text(format_wxstr(_L("Error exporting 3MF file %s"), path));
|
||||
}
|
||||
return ret;
|
||||
#else
|
||||
if (Slic3r::store_3mf(path_u8.c_str(), &p->model, export_config ? &cfg : nullptr, full_pathnames, &thumbnail_data)) {
|
||||
// Success
|
||||
p->statusbar()->set_status_text(format_wxstr(_L("3MF file exported to %s"), path));
|
||||
|
@ -5281,6 +5412,7 @@ void Plater::export_3mf(const boost::filesystem::path& output_path)
|
|||
// Failure
|
||||
p->statusbar()->set_status_text(format_wxstr(_L("Error exporting 3MF file %s"), path));
|
||||
}
|
||||
#endif // ENABLE_PROJECT_DIRTY_STATE
|
||||
}
|
||||
|
||||
void Plater::reload_from_disk()
|
||||
|
@ -5737,7 +5869,7 @@ wxString Plater::get_project_filename(const wxString& extension) const
|
|||
|
||||
void Plater::set_project_filename(const wxString& filename)
|
||||
{
|
||||
return p->set_project_filename(filename);
|
||||
p->set_project_filename(filename);
|
||||
}
|
||||
|
||||
bool Plater::is_export_gcode_scheduled() const
|
||||
|
@ -5817,6 +5949,14 @@ bool Plater::set_printer_technology(PrinterTechnology printer_technology)
|
|||
//FIXME for SLA synchronize
|
||||
//p->background_process.apply(Model)!
|
||||
|
||||
#if DISABLE_ALLOW_NEGATIVE_Z_FOR_SLA
|
||||
if (printer_technology == ptSLA) {
|
||||
for (ModelObject* model_object : p->model.objects) {
|
||||
model_object->ensure_on_bed();
|
||||
}
|
||||
}
|
||||
#endif // DISABLE_ALLOW_NEGATIVE_Z_FOR_SLA
|
||||
|
||||
p->label_btn_export = printer_technology == ptFFF ? L("Export G-code") : L("Export");
|
||||
p->label_btn_send = printer_technology == ptFFF ? L("Send G-code") : L("Send to printer");
|
||||
|
||||
|
@ -5836,7 +5976,15 @@ void Plater::changed_object(int obj_idx)
|
|||
return;
|
||||
// recenter and re - align to Z = 0
|
||||
auto model_object = p->model.objects[obj_idx];
|
||||
#if ENABLE_ALLOW_NEGATIVE_Z
|
||||
#if DISABLE_ALLOW_NEGATIVE_Z_FOR_SLA
|
||||
model_object->ensure_on_bed(this->p->printer_technology != ptSLA);
|
||||
#else
|
||||
model_object->ensure_on_bed(true);
|
||||
#endif // DISABLE_ALLOW_NEGATIVE_Z_FOR_SLA
|
||||
#else
|
||||
model_object->ensure_on_bed();
|
||||
#endif // ENABLE_ALLOW_NEGATIVE_Z
|
||||
if (this->p->printer_technology == ptSLA) {
|
||||
// Update the SLAPrint from the current Model, so that the reload_scene()
|
||||
// pulls the correct data, update the 3D scene.
|
||||
|
@ -5854,11 +6002,18 @@ void Plater::changed_objects(const std::vector<size_t>& object_idxs)
|
|||
if (object_idxs.empty())
|
||||
return;
|
||||
|
||||
for (size_t obj_idx : object_idxs)
|
||||
{
|
||||
for (size_t obj_idx : object_idxs) {
|
||||
#if ENABLE_ALLOW_NEGATIVE_Z
|
||||
if (obj_idx < p->model.objects.size()) {
|
||||
if (p->model.objects[obj_idx]->bounding_box().min.z() >= 0.0)
|
||||
// re - align to Z = 0
|
||||
p->model.objects[obj_idx]->ensure_on_bed();
|
||||
}
|
||||
#else
|
||||
if (obj_idx < p->model.objects.size())
|
||||
// recenter and re - align to Z = 0
|
||||
p->model.objects[obj_idx]->ensure_on_bed();
|
||||
#endif // ENABLE_ALLOW_NEGATIVE_Z
|
||||
}
|
||||
if (this->p->printer_technology == ptSLA) {
|
||||
// Update the SLAPrint from the current Model, so that the reload_scene()
|
||||
|
@ -6141,6 +6296,9 @@ bool Plater::can_mirror() const { return p->can_mirror(); }
|
|||
bool Plater::can_split(bool to_objects) const { return p->can_split(to_objects); }
|
||||
const UndoRedo::Stack& Plater::undo_redo_stack_main() const { return p->undo_redo_stack_main(); }
|
||||
void Plater::clear_undo_redo_stack_main() { p->undo_redo_stack_main().clear(); }
|
||||
#if ENABLE_PROJECT_DIRTY_STATE
|
||||
const UndoRedo::Stack& Plater::undo_redo_stack_active() const { return p->undo_redo_stack(); }
|
||||
#endif // ENABLE_PROJECT_DIRTY_STATE
|
||||
void Plater::enter_gizmos_stack() { p->enter_gizmos_stack(); }
|
||||
void Plater::leave_gizmos_stack() { p->leave_gizmos_stack(); }
|
||||
bool Plater::inside_snapshot_capture() { return p->inside_snapshot_capture(); }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue