mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-11 16:57:53 -06:00
Merge branch 'master' into lm_tm_hollowing
This commit is contained in:
commit
b45e95877e
59 changed files with 3532 additions and 2470 deletions
|
@ -26,6 +26,9 @@
|
|||
#include <wx/colordlg.h>
|
||||
#include <wx/numdlg.h>
|
||||
#include <wx/debug.h>
|
||||
#if ENABLE_BACKWARD_COMPATIBLE_RELOAD_FROM_DISK
|
||||
#include <wx/busyinfo.h>
|
||||
#endif // ENABLE_BACKWARD_COMPATIBLE_RELOAD_FROM_DISK
|
||||
|
||||
#include "libslic3r/libslic3r.h"
|
||||
#include "libslic3r/Format/STL.hpp"
|
||||
|
@ -84,6 +87,7 @@
|
|||
|
||||
#include <wx/glcanvas.h> // Needs to be last because reasons :-/
|
||||
#include "WipeTowerDialog.hpp"
|
||||
#include "libslic3r/CustomGCode.hpp"
|
||||
|
||||
using boost::optional;
|
||||
namespace fs = boost::filesystem;
|
||||
|
@ -704,6 +708,7 @@ struct Sidebar::priv
|
|||
wxButton *btn_reslice;
|
||||
ScalableButton *btn_send_gcode;
|
||||
ScalableButton *btn_remove_device;
|
||||
ScalableButton* btn_export_gcode_removable; //exports to removable drives (appears only if removable drive is connected)
|
||||
|
||||
priv(Plater *plater) : plater(plater) {}
|
||||
~priv();
|
||||
|
@ -869,6 +874,7 @@ Sidebar::Sidebar(Plater *parent)
|
|||
|
||||
init_scalable_btn(&p->btn_send_gcode , "export_gcode", _(L("Send to printer")));
|
||||
init_scalable_btn(&p->btn_remove_device, "cross" , _(L("Remove device")));
|
||||
init_scalable_btn(&p->btn_export_gcode_removable, "export_to_sd", _(L("Export to SD card/ USB thumb drive")));
|
||||
|
||||
// regular buttons "Slice now" and "Export G-code"
|
||||
|
||||
|
@ -889,7 +895,9 @@ Sidebar::Sidebar(Plater *parent)
|
|||
auto* complect_btns_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
complect_btns_sizer->Add(p->btn_export_gcode, 1, wxEXPAND);
|
||||
complect_btns_sizer->Add(p->btn_send_gcode);
|
||||
complect_btns_sizer->Add(p->btn_export_gcode_removable);
|
||||
complect_btns_sizer->Add(p->btn_remove_device);
|
||||
|
||||
|
||||
btns_sizer->Add(p->btn_reslice, 0, wxEXPAND | wxTOP, margin_5);
|
||||
btns_sizer->Add(complect_btns_sizer, 0, wxEXPAND | wxTOP, margin_5);
|
||||
|
@ -900,7 +908,7 @@ Sidebar::Sidebar(Plater *parent)
|
|||
SetSizer(sizer);
|
||||
|
||||
// Events
|
||||
p->btn_export_gcode->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { p->plater->export_gcode(); });
|
||||
p->btn_export_gcode->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { p->plater->export_gcode(false); });
|
||||
p->btn_reslice->Bind(wxEVT_BUTTON, [this](wxCommandEvent&)
|
||||
{
|
||||
const bool export_gcode_after_slicing = wxGetKeyState(WXK_SHIFT);
|
||||
|
@ -912,6 +920,7 @@ Sidebar::Sidebar(Plater *parent)
|
|||
});
|
||||
p->btn_send_gcode->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { p->plater->send_gcode(); });
|
||||
p->btn_remove_device->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { p->plater->eject_drive(); });
|
||||
p->btn_export_gcode_removable->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { p->plater->export_gcode(true); });
|
||||
}
|
||||
|
||||
Sidebar::~Sidebar() {}
|
||||
|
@ -1059,6 +1068,7 @@ void Sidebar::msw_rescale()
|
|||
|
||||
p->btn_send_gcode->msw_rescale();
|
||||
p->btn_remove_device->msw_rescale();
|
||||
p->btn_export_gcode_removable->msw_rescale();
|
||||
const int scaled_height = p->btn_remove_device->GetBitmap().GetHeight() + 4;
|
||||
p->btn_export_gcode->SetMinSize(wxSize(-1, scaled_height));
|
||||
p->btn_reslice ->SetMinSize(wxSize(-1, scaled_height));
|
||||
|
@ -1292,12 +1302,14 @@ void Sidebar::enable_buttons(bool enable)
|
|||
p->btn_export_gcode->Enable(enable);
|
||||
p->btn_send_gcode->Enable(enable);
|
||||
p->btn_remove_device->Enable(enable);
|
||||
p->btn_export_gcode_removable->Enable(enable);
|
||||
}
|
||||
|
||||
bool Sidebar::show_reslice(bool show) const { return p->btn_reslice->Show(show); }
|
||||
bool Sidebar::show_export(bool show) const { return p->btn_export_gcode->Show(show); }
|
||||
bool Sidebar::show_send(bool show) const { return p->btn_send_gcode->Show(show); }
|
||||
bool Sidebar::show_disconnect(bool show)const { return p->btn_remove_device->Show(show); }
|
||||
bool Sidebar::show_reslice(bool show) const { return p->btn_reslice->Show(show); }
|
||||
bool Sidebar::show_export(bool show) const { return p->btn_export_gcode->Show(show); }
|
||||
bool Sidebar::show_send(bool show) const { return p->btn_send_gcode->Show(show); }
|
||||
bool Sidebar::show_disconnect(bool show) const { return p->btn_remove_device->Show(show); }
|
||||
bool Sidebar::show_export_removable(bool show)const { return p->btn_export_gcode_removable->Show(show); }
|
||||
|
||||
bool Sidebar::is_multifilament()
|
||||
{
|
||||
|
@ -1773,6 +1785,9 @@ struct Plater::priv
|
|||
bool is_view3D_shown() const { return current_panel == view3D; }
|
||||
|
||||
void set_current_canvas_as_dirty();
|
||||
#if ENABLE_BACKWARD_COMPATIBLE_RELOAD_FROM_DISK
|
||||
GLCanvas3D* get_current_canvas3D();
|
||||
#endif // ENABLE_BACKWARD_COMPATIBLE_RELOAD_FROM_DISK
|
||||
|
||||
bool init_view_toolbar();
|
||||
|
||||
|
@ -1902,7 +1917,9 @@ struct Plater::priv
|
|||
bool can_fix_through_netfabb() const;
|
||||
bool can_set_instance_to_object() const;
|
||||
bool can_mirror() const;
|
||||
#if !ENABLE_BACKWARD_COMPATIBLE_RELOAD_FROM_DISK
|
||||
bool can_reload_from_disk() const;
|
||||
#endif // !ENABLE_BACKWARD_COMPATIBLE_RELOAD_FROM_DISK
|
||||
|
||||
#if ENABLE_THUMBNAIL_GENERATOR
|
||||
void generate_thumbnail(ThumbnailData& data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool show_bed, bool transparent_background);
|
||||
|
@ -2110,6 +2127,9 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
|||
|
||||
// Initialize the Undo / Redo stack with a first snapshot.
|
||||
this->take_snapshot(_(L("New Project")));
|
||||
|
||||
//void Plater::priv::show_action_buttons(const bool is_ready_to_slice) const
|
||||
RemovableDriveManager::get_instance().set_drive_count_changed_callback(std::bind(&Plater::priv::show_action_buttons, this, std::placeholders::_1));
|
||||
}
|
||||
|
||||
Plater::priv::~priv()
|
||||
|
@ -3230,6 +3250,10 @@ void Plater::priv::reload_from_disk()
|
|||
else
|
||||
missing_input_paths.push_back(volume->source.input_file);
|
||||
}
|
||||
#if ENABLE_BACKWARD_COMPATIBLE_RELOAD_FROM_DISK
|
||||
else if (!volume->name.empty())
|
||||
missing_input_paths.push_back(volume->name);
|
||||
#endif // ENABLE_BACKWARD_COMPATIBLE_RELOAD_FROM_DISK
|
||||
}
|
||||
|
||||
std::sort(missing_input_paths.begin(), missing_input_paths.end());
|
||||
|
@ -3241,10 +3265,9 @@ void Plater::priv::reload_from_disk()
|
|||
fs::path search = missing_input_paths.back();
|
||||
wxString title = _(L("Please select the file to reload"));
|
||||
#if defined(__APPLE__)
|
||||
title += " (" + from_u8(search.filename().string()) + "):";
|
||||
#else
|
||||
title += ":";
|
||||
title += " (" + from_u8(search.filename().string()) + ")";
|
||||
#endif // __APPLE__
|
||||
title += ":";
|
||||
wxFileDialog dialog(q, title, "", from_u8(search.filename().string()), file_wildcards(FT_MODEL), wxFD_OPEN | wxFD_FILE_MUST_EXIST);
|
||||
if (dialog.ShowModal() != wxID_OK)
|
||||
return;
|
||||
|
@ -3285,10 +3308,20 @@ void Plater::priv::reload_from_disk()
|
|||
std::sort(input_paths.begin(), input_paths.end());
|
||||
input_paths.erase(std::unique(input_paths.begin(), input_paths.end()), input_paths.end());
|
||||
|
||||
#if ENABLE_BACKWARD_COMPATIBLE_RELOAD_FROM_DISK
|
||||
std::vector<wxString> fail_list;
|
||||
#endif // ENABLE_BACKWARD_COMPATIBLE_RELOAD_FROM_DISK
|
||||
|
||||
// load one file at a time
|
||||
for (size_t i = 0; i < input_paths.size(); ++i)
|
||||
{
|
||||
const auto& path = input_paths[i].string();
|
||||
|
||||
#if ENABLE_BACKWARD_COMPATIBLE_RELOAD_FROM_DISK
|
||||
wxBusyCursor wait;
|
||||
wxBusyInfo info(_(L("Reload from: ")) + from_u8(path), q->get_current_canvas3D()->get_wxglcanvas());
|
||||
#endif // ENABLE_BACKWARD_COMPATIBLE_RELOAD_FROM_DISK
|
||||
|
||||
Model new_model;
|
||||
try
|
||||
{
|
||||
|
@ -3306,18 +3339,70 @@ void Plater::priv::reload_from_disk()
|
|||
}
|
||||
|
||||
// update the selected volumes whose source is the current file
|
||||
for (const SelectedVolume& old_v : selected_volumes)
|
||||
for (const SelectedVolume& sel_v : selected_volumes)
|
||||
{
|
||||
ModelObject* old_model_object = model.objects[old_v.object_idx];
|
||||
ModelVolume* old_volume = old_model_object->volumes[old_v.volume_idx];
|
||||
ModelObject* old_model_object = model.objects[sel_v.object_idx];
|
||||
ModelVolume* old_volume = old_model_object->volumes[sel_v.volume_idx];
|
||||
|
||||
#if ENABLE_BACKWARD_COMPATIBLE_RELOAD_FROM_DISK
|
||||
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)
|
||||
#else
|
||||
int new_volume_idx = old_volume->source.volume_idx;
|
||||
int new_object_idx = old_volume->source.object_idx;
|
||||
|
||||
if (boost::algorithm::iequals(fs::path(old_volume->source.input_file).filename().string(),
|
||||
fs::path(path).filename().string()))
|
||||
#endif // ENABLE_BACKWARD_COMPATIBLE_RELOAD_FROM_DISK
|
||||
{
|
||||
#if ENABLE_BACKWARD_COMPATIBLE_RELOAD_FROM_DISK
|
||||
int new_volume_idx = -1;
|
||||
int new_object_idx = -1;
|
||||
if (has_source)
|
||||
{
|
||||
// take idxs from source
|
||||
new_volume_idx = old_volume->source.volume_idx;
|
||||
new_object_idx = old_volume->source.object_idx;
|
||||
}
|
||||
else
|
||||
{
|
||||
// take idxs from the 1st matching volume
|
||||
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)
|
||||
{
|
||||
new_volume_idx = (int)v;
|
||||
new_object_idx = (int)o;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
#else
|
||||
assert(new_object_idx < (int)new_model.objects.size());
|
||||
#endif // ENABLE_BACKWARD_COMPATIBLE_RELOAD_FROM_DISK
|
||||
ModelObject* new_model_object = new_model.objects[new_object_idx];
|
||||
#if ENABLE_BACKWARD_COMPATIBLE_RELOAD_FROM_DISK
|
||||
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;
|
||||
}
|
||||
#endif // ENABLE_BACKWARD_COMPATIBLE_RELOAD_FROM_DISK
|
||||
if (new_volume_idx < (int)new_model_object->volumes.size())
|
||||
{
|
||||
old_model_object->add_volume(*new_model_object->volumes[new_volume_idx]);
|
||||
|
@ -3328,8 +3413,10 @@ void Plater::priv::reload_from_disk()
|
|||
new_volume->set_material_id(old_volume->material_id());
|
||||
new_volume->set_transformation(old_volume->get_transformation() * old_volume->source.transform);
|
||||
new_volume->translate(new_volume->get_transformation().get_matrix(true) * (new_volume->source.mesh_offset - old_volume->source.mesh_offset));
|
||||
#if !ENABLE_BACKWARD_COMPATIBLE_RELOAD_FROM_DISK
|
||||
new_volume->source.input_file = path;
|
||||
std::swap(old_model_object->volumes[old_v.volume_idx], old_model_object->volumes.back());
|
||||
#endif // !ENABLE_BACKWARD_COMPATIBLE_RELOAD_FROM_DISK
|
||||
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();
|
||||
}
|
||||
|
@ -3337,6 +3424,19 @@ void Plater::priv::reload_from_disk()
|
|||
}
|
||||
}
|
||||
|
||||
#if ENABLE_BACKWARD_COMPATIBLE_RELOAD_FROM_DISK
|
||||
if (!fail_list.empty())
|
||||
{
|
||||
wxString message = _(L("Unable to reload:")) + "\n";
|
||||
for (const wxString& s : fail_list)
|
||||
{
|
||||
message += s + "\n";
|
||||
}
|
||||
wxMessageDialog dlg(q, message, _(L("Error during reload")), wxOK | wxOK_DEFAULT | wxICON_WARNING);
|
||||
dlg.ShowModal();
|
||||
}
|
||||
#endif // ENABLE_BACKWARD_COMPATIBLE_RELOAD_FROM_DISK
|
||||
|
||||
// update 3D scene
|
||||
update();
|
||||
|
||||
|
@ -3582,12 +3682,8 @@ void Plater::priv::on_process_completed(wxCommandEvent &evt)
|
|||
|
||||
if(!canceled && RemovableDriveManager::get_instance().get_is_writing())
|
||||
{
|
||||
//if (!RemovableDriveManager::get_instance().is_last_drive_removed())
|
||||
//{
|
||||
RemovableDriveManager::get_instance().set_is_writing(false);
|
||||
show_action_buttons(false);
|
||||
//}
|
||||
|
||||
RemovableDriveManager::get_instance().set_is_writing(false);
|
||||
show_action_buttons(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3817,8 +3913,13 @@ bool Plater::priv::init_common_menu(wxMenu* menu, const bool is_part/* = false*/
|
|||
append_menu_item(menu, wxID_ANY, _(L("Delete")) + "\tDel", _(L("Remove the selected object")),
|
||||
[this](wxCommandEvent&) { q->remove_selected(); }, "delete", nullptr, [this]() { return can_delete(); }, q);
|
||||
|
||||
#if ENABLE_BACKWARD_COMPATIBLE_RELOAD_FROM_DISK
|
||||
append_menu_item(menu, wxID_ANY, _(L("Reload from disk")), _(L("Reload the selected volumes from disk")),
|
||||
[this](wxCommandEvent&) { q->reload_from_disk(); }, "", menu);
|
||||
#else
|
||||
append_menu_item(menu, wxID_ANY, _(L("Reload from disk")), _(L("Reload the selected volumes from disk")),
|
||||
[this](wxCommandEvent&) { q->reload_from_disk(); }, "", menu, [this]() { return can_reload_from_disk(); }, q);
|
||||
#endif // ENABLE_BACKWARD_COMPATIBLE_RELOAD_FROM_DISK
|
||||
|
||||
sidebar->obj_list()->append_menu_item_export_stl(menu);
|
||||
}
|
||||
|
@ -3846,8 +3947,13 @@ bool Plater::priv::init_common_menu(wxMenu* menu, const bool is_part/* = false*/
|
|||
wxMenuItem* menu_item_printable = sidebar->obj_list()->append_menu_item_printable(menu, q);
|
||||
menu->AppendSeparator();
|
||||
|
||||
#if ENABLE_BACKWARD_COMPATIBLE_RELOAD_FROM_DISK
|
||||
append_menu_item(menu, wxID_ANY, _(L("Reload from disk")), _(L("Reload the selected object from disk")),
|
||||
[this](wxCommandEvent&) { reload_from_disk(); }, "", nullptr);
|
||||
#else
|
||||
append_menu_item(menu, wxID_ANY, _(L("Reload from disk")), _(L("Reload the selected object from disk")),
|
||||
[this](wxCommandEvent&) { reload_from_disk(); }, "", nullptr, [this]() { return can_reload_from_disk(); }, q);
|
||||
#endif // ENABLE_BACKWARD_COMPATIBLE_RELOAD_FROM_DISK
|
||||
|
||||
append_menu_item(menu, wxID_ANY, _(L("Export as STL")) + dots, _(L("Export the selected object as STL file")),
|
||||
[this](wxCommandEvent&) { q->export_stl(false, true); }, "", nullptr,
|
||||
|
@ -3950,6 +4056,13 @@ void Plater::priv::set_current_canvas_as_dirty()
|
|||
preview->set_as_dirty();
|
||||
}
|
||||
|
||||
#if ENABLE_BACKWARD_COMPATIBLE_RELOAD_FROM_DISK
|
||||
GLCanvas3D* Plater::priv::get_current_canvas3D()
|
||||
{
|
||||
return (current_panel == view3D) ? view3D->get_canvas3d() : ((current_panel == preview) ? preview->get_canvas3d() : nullptr);
|
||||
}
|
||||
#endif // ENABLE_BACKWARD_COMPATIBLE_RELOAD_FROM_DISK
|
||||
|
||||
bool Plater::priv::init_view_toolbar()
|
||||
{
|
||||
if (view_toolbar.get_items_count() > 0)
|
||||
|
@ -4020,6 +4133,7 @@ bool Plater::priv::can_mirror() const
|
|||
return get_selection().is_from_single_instance();
|
||||
}
|
||||
|
||||
#if !ENABLE_BACKWARD_COMPATIBLE_RELOAD_FROM_DISK
|
||||
bool Plater::priv::can_reload_from_disk() const
|
||||
{
|
||||
// struct to hold selected ModelVolumes by their indices
|
||||
|
@ -4065,6 +4179,7 @@ bool Plater::priv::can_reload_from_disk() const
|
|||
|
||||
return !paths.empty();
|
||||
}
|
||||
#endif // !ENABLE_BACKWARD_COMPATIBLE_RELOAD_FROM_DISK
|
||||
|
||||
void Plater::priv::set_bed_shape(const Pointfs& shape, const std::string& custom_texture, const std::string& custom_model)
|
||||
{
|
||||
|
@ -4142,18 +4257,21 @@ void Plater::priv::update_object_menu()
|
|||
|
||||
void Plater::priv::show_action_buttons(const bool is_ready_to_slice) const
|
||||
{
|
||||
RemovableDriveManager::get_instance().set_plater_ready_to_slice(is_ready_to_slice);
|
||||
wxWindowUpdateLocker noUpdater(sidebar);
|
||||
const auto prin_host_opt = config->option<ConfigOptionString>("print_host");
|
||||
const bool send_gcode_shown = prin_host_opt != nullptr && !prin_host_opt->value.empty();
|
||||
|
||||
bool disconnect_shown = !RemovableDriveManager::get_instance().is_last_drive_removed() ; // #dk_FIXME
|
||||
bool disconnect_shown = !RemovableDriveManager::get_instance().is_last_drive_removed();
|
||||
bool export_removable_shown = RemovableDriveManager::get_instance().get_drives_count() > 0;
|
||||
// when a background processing is ON, export_btn and/or send_btn are showing
|
||||
if (wxGetApp().app_config->get("background_processing") == "1")
|
||||
{
|
||||
if (sidebar->show_reslice(false) |
|
||||
sidebar->show_export(true) |
|
||||
sidebar->show_send(send_gcode_shown) |
|
||||
sidebar->show_disconnect(disconnect_shown))
|
||||
if (sidebar->show_reslice(false) |
|
||||
sidebar->show_export(true) |
|
||||
sidebar->show_send(send_gcode_shown) |
|
||||
sidebar->show_export_removable(export_removable_shown) |
|
||||
sidebar->show_disconnect(disconnect_shown))
|
||||
sidebar->Layout();
|
||||
}
|
||||
else
|
||||
|
@ -4161,6 +4279,7 @@ void Plater::priv::show_action_buttons(const bool is_ready_to_slice) const
|
|||
if (sidebar->show_reslice(is_ready_to_slice) |
|
||||
sidebar->show_export(!is_ready_to_slice) |
|
||||
sidebar->show_send(send_gcode_shown && !is_ready_to_slice) |
|
||||
sidebar->show_export_removable(export_removable_shown && !is_ready_to_slice) |
|
||||
sidebar->show_disconnect(disconnect_shown && !is_ready_to_slice))
|
||||
sidebar->Layout();
|
||||
}
|
||||
|
@ -4537,7 +4656,7 @@ void Plater::remove(size_t obj_idx) { p->remove(obj_idx); }
|
|||
void Plater::reset() { p->reset(); }
|
||||
void Plater::reset_with_confirm()
|
||||
{
|
||||
if (wxMessageDialog((wxWindow*)this, _(L("All objects will be removed, continue ?")), wxString(SLIC3R_APP_NAME) + " - " + _(L("Delete all")), wxYES_NO | wxCANCEL | wxYES_DEFAULT | wxCENTRE).ShowModal() == wxID_YES)
|
||||
if (wxMessageDialog((wxWindow*)this, _(L("All objects will be removed, continue?")), wxString(SLIC3R_APP_NAME) + " - " + _(L("Delete all")), wxYES_NO | wxCANCEL | wxYES_DEFAULT | wxCENTRE).ShowModal() == wxID_YES)
|
||||
reset();
|
||||
}
|
||||
|
||||
|
@ -4670,7 +4789,7 @@ void Plater::cut(size_t obj_idx, size_t instance_idx, coordf_t z, bool keep_uppe
|
|||
}
|
||||
}
|
||||
|
||||
void Plater::export_gcode()
|
||||
void Plater::export_gcode(bool prefer_removable)
|
||||
{
|
||||
if (p->model.objects.empty())
|
||||
return;
|
||||
|
@ -4692,11 +4811,19 @@ void Plater::export_gcode()
|
|||
}
|
||||
default_output_file = fs::path(Slic3r::fold_utf8_to_ascii(default_output_file.string()));
|
||||
auto start_dir = wxGetApp().app_config->get_last_output_dir(default_output_file.parent_path().string());
|
||||
if (GUI::RemovableDriveManager::get_instance().update())
|
||||
bool removable_drives_connected = GUI::RemovableDriveManager::get_instance().update();
|
||||
if(prefer_removable)
|
||||
{
|
||||
if (!RemovableDriveManager::get_instance().is_path_on_removable_drive(start_dir))
|
||||
if(removable_drives_connected)
|
||||
{
|
||||
start_dir = RemovableDriveManager::get_instance().get_drive_path();
|
||||
auto start_dir_removable = wxGetApp().app_config->get_last_output_dir(default_output_file.parent_path().string(), true);
|
||||
if (RemovableDriveManager::get_instance().is_path_on_removable_drive(start_dir_removable))
|
||||
{
|
||||
start_dir = start_dir_removable;
|
||||
}else
|
||||
{
|
||||
start_dir = RemovableDriveManager::get_instance().get_drive_path();
|
||||
}
|
||||
}
|
||||
}
|
||||
wxFileDialog dlg(this, (printer_technology() == ptFFF) ? _(L("Save G-code file as:")) : _(L("Save SL1 file as:")),
|
||||
|
@ -4709,7 +4836,7 @@ void Plater::export_gcode()
|
|||
fs::path output_path;
|
||||
if (dlg.ShowModal() == wxID_OK) {
|
||||
fs::path path = into_path(dlg.GetPath());
|
||||
wxGetApp().app_config->update_last_output_dir(path.parent_path().string());
|
||||
wxGetApp().app_config->update_last_output_dir(path.parent_path().string(), RemovableDriveManager::get_instance().is_path_on_removable_drive(path.parent_path().string()));
|
||||
output_path = std::move(path);
|
||||
}
|
||||
if (! output_path.empty())
|
||||
|
@ -4725,7 +4852,7 @@ void Plater::export_gcode()
|
|||
{
|
||||
RemovableDriveManager::get_instance().set_is_writing(true);
|
||||
RemovableDriveManager::get_instance().erase_callbacks();
|
||||
RemovableDriveManager::get_instance().add_callback(std::bind(&Plater::drive_ejected_callback, this));
|
||||
RemovableDriveManager::get_instance().add_remove_callback(std::bind(&Plater::drive_ejected_callback, this));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5032,8 +5159,8 @@ void Plater::send_gcode()
|
|||
void Plater::eject_drive()
|
||||
{
|
||||
RemovableDriveManager::get_instance().update(0, true);
|
||||
//RemovableDriveManager::get_instance().erase_callbacks();
|
||||
//RemovableDriveManager::get_instance().add_callback(std::bind(&Plater::drive_ejected_callback, this));
|
||||
RemovableDriveManager::get_instance().erase_callbacks();
|
||||
RemovableDriveManager::get_instance().add_remove_callback(std::bind(&Plater::drive_ejected_callback, this));
|
||||
RemovableDriveManager::get_instance().eject_drive(RemovableDriveManager::get_instance().get_last_save_path());
|
||||
|
||||
}
|
||||
|
@ -5042,7 +5169,7 @@ void Plater::drive_ejected_callback()
|
|||
if (RemovableDriveManager::get_instance().get_did_eject())
|
||||
{
|
||||
RemovableDriveManager::get_instance().set_did_eject(false);
|
||||
wxString message = "Unmounting succesesful. The device " + RemovableDriveManager::get_instance().get_last_save_name() + "(" + RemovableDriveManager::get_instance().get_last_save_path() + ")" + " can now be safely removed from the computer.";
|
||||
wxString message = "Unmounting successful. The device " + RemovableDriveManager::get_instance().get_ejected_name() + "(" + RemovableDriveManager::get_instance().get_ejected_path() + ")" + " can now be safely removed from the computer.";
|
||||
wxMessageBox(message);
|
||||
}
|
||||
p->show_action_buttons(false);
|
||||
|
@ -5288,7 +5415,7 @@ std::vector<std::string> Plater::get_colors_for_color_print() const
|
|||
std::vector<std::string> colors = get_extruder_colors_from_plater_config();
|
||||
colors.reserve(colors.size() + p->model.custom_gcode_per_print_z.gcodes.size());
|
||||
|
||||
for (const Model::CustomGCode& code : p->model.custom_gcode_per_print_z.gcodes)
|
||||
for (const CustomGCode::Item& code : p->model.custom_gcode_per_print_z.gcodes)
|
||||
if (code.gcode == ColorChangeCode)
|
||||
colors.emplace_back(code.color);
|
||||
|
||||
|
@ -5325,6 +5452,13 @@ GLCanvas3D* Plater::canvas3D()
|
|||
return p->view3D->get_canvas3d();
|
||||
}
|
||||
|
||||
#if ENABLE_BACKWARD_COMPATIBLE_RELOAD_FROM_DISK
|
||||
GLCanvas3D* Plater::get_current_canvas3D()
|
||||
{
|
||||
return p->get_current_canvas3D();
|
||||
}
|
||||
#endif // ENABLE_BACKWARD_COMPATIBLE_RELOAD_FROM_DISK
|
||||
|
||||
BoundingBoxf Plater::bed_shape_bb() const
|
||||
{
|
||||
return p->bed_shape_bb();
|
||||
|
@ -5517,7 +5651,9 @@ bool Plater::can_copy_to_clipboard() const
|
|||
|
||||
bool Plater::can_undo() const { return p->undo_redo_stack().has_undo_snapshot(); }
|
||||
bool Plater::can_redo() const { return p->undo_redo_stack().has_redo_snapshot(); }
|
||||
#if !ENABLE_BACKWARD_COMPATIBLE_RELOAD_FROM_DISK
|
||||
bool Plater::can_reload_from_disk() const { return p->can_reload_from_disk(); }
|
||||
#endif // !ENABLE_BACKWARD_COMPATIBLE_RELOAD_FROM_DISK
|
||||
const UndoRedo::Stack& Plater::undo_redo_stack_main() const { return p->undo_redo_stack_main(); }
|
||||
void Plater::enter_gizmos_stack() { p->enter_gizmos_stack(); }
|
||||
void Plater::leave_gizmos_stack() { p->leave_gizmos_stack(); }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue