mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-25 07:34:03 -06:00
Merge branch 'master' of https://github.com/prusa3d/Slic3r into et_bug_fixes
This commit is contained in:
commit
9b9d35d90d
31 changed files with 437 additions and 305 deletions
|
@ -635,35 +635,32 @@ void ConfigWizard::priv::load_vendors()
|
|||
const auto rsrc_vendor_dir = fs::path(resources_dir()) / "profiles";
|
||||
|
||||
// Load vendors from the "vendors" directory in datadir
|
||||
for (fs::directory_iterator it(vendor_dir); it != fs::directory_iterator(); ++it) {
|
||||
if (it->path().extension() == ".ini") {
|
||||
for (auto &dir_entry : boost::filesystem::directory_iterator(vendor_dir))
|
||||
if (Slic3r::is_ini_file(dir_entry)) {
|
||||
try {
|
||||
auto vp = VendorProfile::from_ini(it->path());
|
||||
auto vp = VendorProfile::from_ini(dir_entry.path());
|
||||
vendors[vp.id] = std::move(vp);
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
BOOST_LOG_TRIVIAL(error) << boost::format("Error loading vendor bundle %1%: %2%") % it->path() % e.what();
|
||||
BOOST_LOG_TRIVIAL(error) << boost::format("Error loading vendor bundle %1%: %2%") % dir_entry.path() % e.what();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Additionally load up vendors from the application resources directory, but only those not seen in the datadir
|
||||
for (fs::directory_iterator it(rsrc_vendor_dir); it != fs::directory_iterator(); ++it) {
|
||||
if (it->path().extension() == ".ini") {
|
||||
const auto id = it->path().stem().string();
|
||||
for (auto &dir_entry : boost::filesystem::directory_iterator(rsrc_vendor_dir))
|
||||
if (Slic3r::is_ini_file(dir_entry)) {
|
||||
const auto id = dir_entry.path().stem().string();
|
||||
if (vendors.find(id) == vendors.end()) {
|
||||
try {
|
||||
auto vp = VendorProfile::from_ini(it->path());
|
||||
vendors_rsrc[vp.id] = it->path().filename().string();
|
||||
auto vp = VendorProfile::from_ini(dir_entry.path());
|
||||
vendors_rsrc[vp.id] = dir_entry.path().filename().string();
|
||||
vendors[vp.id] = std::move(vp);
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
BOOST_LOG_TRIVIAL(error) << boost::format("Error loading vendor bundle %1%: %2%") % it->path() % e.what();
|
||||
BOOST_LOG_TRIVIAL(error) << boost::format("Error loading vendor bundle %1%: %2%") % dir_entry.path() % e.what();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Load up the set of vendors / models / variants the user has had enabled up till now
|
||||
const AppConfig *app_config = GUI::get_app_config();
|
||||
|
@ -672,14 +669,15 @@ void ConfigWizard::priv::load_vendors()
|
|||
} else {
|
||||
// In case of legacy datadir, try to guess the preference based on the printer preset files that are present
|
||||
const auto printer_dir = fs::path(Slic3r::data_dir()) / "printer";
|
||||
for (fs::directory_iterator it(printer_dir); it != fs::directory_iterator(); ++it) {
|
||||
auto needle = legacy_preset_map.find(it->path().filename().string());
|
||||
if (needle == legacy_preset_map.end()) { continue; }
|
||||
for (auto &dir_entry : boost::filesystem::directory_iterator(printer_dir))
|
||||
if (Slic3r::is_ini_file(dir_entry)) {
|
||||
auto needle = legacy_preset_map.find(dir_entry.path().filename().string());
|
||||
if (needle == legacy_preset_map.end()) { continue; }
|
||||
|
||||
const auto &model = needle->second.first;
|
||||
const auto &variant = needle->second.second;
|
||||
appconfig_vendors.set_variant("PrusaResearch", model, variant, true);
|
||||
}
|
||||
const auto &model = needle->second.first;
|
||||
const auto &variant = needle->second.second;
|
||||
appconfig_vendors.set_variant("PrusaResearch", model, variant, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3998,6 +3998,7 @@ wxDEFINE_EVENT(EVT_GLCANVAS_VIEWPORT_CHANGED, SimpleEvent);
|
|||
wxDEFINE_EVENT(EVT_GLCANVAS_RIGHT_CLICK, Vec2dEvent);
|
||||
wxDEFINE_EVENT(EVT_GLCANVAS_REMOVE_OBJECT, SimpleEvent);
|
||||
wxDEFINE_EVENT(EVT_GLCANVAS_ARRANGE, SimpleEvent);
|
||||
wxDEFINE_EVENT(EVT_GLCANVAS_SELECT_ALL, SimpleEvent);
|
||||
wxDEFINE_EVENT(EVT_GLCANVAS_QUESTION_MARK, SimpleEvent);
|
||||
wxDEFINE_EVENT(EVT_GLCANVAS_INCREASE_INSTANCES, Event<int>);
|
||||
wxDEFINE_EVENT(EVT_GLCANVAS_INSTANCE_MOVED, SimpleEvent);
|
||||
|
@ -4474,6 +4475,7 @@ void GLCanvas3D::update_toolbar_items_visibility()
|
|||
ConfigOptionMode mode = wxGetApp().get_mode();
|
||||
m_toolbar.set_item_visible("more", mode != comSimple);
|
||||
m_toolbar.set_item_visible("fewer", mode != comSimple);
|
||||
m_toolbar.set_item_visible("splitvolumes", mode != comSimple);
|
||||
m_dirty = true;
|
||||
}
|
||||
#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS
|
||||
|
@ -5103,7 +5105,6 @@ void GLCanvas3D::bind_event_handlers()
|
|||
m_canvas->Bind(wxEVT_MIDDLE_DCLICK, &GLCanvas3D::on_mouse, this);
|
||||
m_canvas->Bind(wxEVT_RIGHT_DCLICK, &GLCanvas3D::on_mouse, this);
|
||||
m_canvas->Bind(wxEVT_PAINT, &GLCanvas3D::on_paint, this);
|
||||
m_canvas->Bind(wxEVT_KEY_DOWN, &GLCanvas3D::on_key_down, this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5117,7 +5118,7 @@ void GLCanvas3D::unbind_event_handlers()
|
|||
m_canvas->Unbind(wxEVT_MOUSEWHEEL, &GLCanvas3D::on_mouse_wheel, this);
|
||||
m_canvas->Unbind(wxEVT_TIMER, &GLCanvas3D::on_timer, this);
|
||||
m_canvas->Unbind(wxEVT_LEFT_DOWN, &GLCanvas3D::on_mouse, this);
|
||||
m_canvas->Unbind(wxEVT_LEFT_UP, &GLCanvas3D::on_mouse, this);
|
||||
m_canvas->Unbind(wxEVT_LEFT_UP, &GLCanvas3D::on_mouse, this);
|
||||
m_canvas->Unbind(wxEVT_MIDDLE_DOWN, &GLCanvas3D::on_mouse, this);
|
||||
m_canvas->Unbind(wxEVT_MIDDLE_UP, &GLCanvas3D::on_mouse, this);
|
||||
m_canvas->Unbind(wxEVT_RIGHT_DOWN, &GLCanvas3D::on_mouse, this);
|
||||
|
@ -5129,7 +5130,6 @@ void GLCanvas3D::unbind_event_handlers()
|
|||
m_canvas->Unbind(wxEVT_MIDDLE_DCLICK, &GLCanvas3D::on_mouse, this);
|
||||
m_canvas->Unbind(wxEVT_RIGHT_DCLICK, &GLCanvas3D::on_mouse, this);
|
||||
m_canvas->Unbind(wxEVT_PAINT, &GLCanvas3D::on_paint, this);
|
||||
m_canvas->Unbind(wxEVT_KEY_DOWN, &GLCanvas3D::on_key_down, this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5148,71 +5148,64 @@ void GLCanvas3D::on_idle(wxIdleEvent& evt)
|
|||
|
||||
void GLCanvas3D::on_char(wxKeyEvent& evt)
|
||||
{
|
||||
if (evt.HasModifiers())
|
||||
// see include/wx/defs.h enum wxKeyCode
|
||||
int keyCode = evt.GetKeyCode();
|
||||
int ctrlMask = wxMOD_CONTROL;
|
||||
#ifdef __APPLE__
|
||||
ctrlMask |= wxMOD_RAW_CONTROL;
|
||||
#endif /* __APPLE__ */
|
||||
if ((evt.GetModifiers() & ctrlMask) != 0) {
|
||||
switch (keyCode) {
|
||||
case WXK_CONTROL_A: post_event(SimpleEvent(EVT_GLCANVAS_SELECT_ALL)); break;
|
||||
#ifdef __APPLE__
|
||||
case WXK_BACK: // the low cost Apple solutions are not equipped with a Delete key, use Backspace instead.
|
||||
#endif /* __APPLE__ */
|
||||
case WXK_DELETE: post_event(SimpleEvent(EVT_GLTOOLBAR_DELETE_ALL)); break;
|
||||
default: evt.Skip();
|
||||
}
|
||||
} else if (evt.HasModifiers()) {
|
||||
evt.Skip();
|
||||
else
|
||||
{
|
||||
int keyCode = evt.GetKeyCode();
|
||||
switch (keyCode - 48)
|
||||
} else {
|
||||
switch (keyCode)
|
||||
{
|
||||
// numerical input
|
||||
case 0: { select_view("iso"); break; }
|
||||
case 1: { select_view("top"); break; }
|
||||
case 2: { select_view("bottom"); break; }
|
||||
case 3: { select_view("front"); break; }
|
||||
case 4: { select_view("rear"); break; }
|
||||
case 5: { select_view("left"); break; }
|
||||
case 6: { select_view("right"); break; }
|
||||
// key ESC
|
||||
case WXK_ESCAPE: { m_gizmos.reset_all_states(); m_dirty = true; break; }
|
||||
#ifdef __APPLE__
|
||||
case WXK_BACK: // the low cost Apple solutions are not equipped with a Delete key, use Backspace instead.
|
||||
#endif /* __APPLE__ */
|
||||
case WXK_DELETE: post_event(SimpleEvent(EVT_GLTOOLBAR_DELETE)); break;
|
||||
case '0': { select_view("iso"); break; }
|
||||
case '1': { select_view("top"); break; }
|
||||
case '2': { select_view("bottom"); break; }
|
||||
case '3': { select_view("front"); break; }
|
||||
case '4': { select_view("rear"); break; }
|
||||
case '5': { select_view("left"); break; }
|
||||
case '6': { select_view("right"); break; }
|
||||
case '+': { post_event(Event<int>(EVT_GLCANVAS_INCREASE_INSTANCES, +1)); break; }
|
||||
case '-': { post_event(Event<int>(EVT_GLCANVAS_INCREASE_INSTANCES, -1)); break; }
|
||||
case '?': { post_event(SimpleEvent(EVT_GLCANVAS_QUESTION_MARK)); break; }
|
||||
case 'A':
|
||||
case 'a': { post_event(SimpleEvent(EVT_GLCANVAS_ARRANGE)); break; }
|
||||
case 'B':
|
||||
case 'b': { zoom_to_bed(); break; }
|
||||
case 'I':
|
||||
case 'i': { set_camera_zoom(1.0f); break; }
|
||||
case 'O':
|
||||
case 'o': { set_camera_zoom(-1.0f); break; }
|
||||
case 'Z':
|
||||
case 'z': { m_selection.is_empty() ? zoom_to_volumes() : zoom_to_selection(); break; }
|
||||
default:
|
||||
{
|
||||
if (m_gizmos.handle_shortcut(keyCode, m_selection))
|
||||
{
|
||||
// text input
|
||||
switch (keyCode)
|
||||
{
|
||||
// key ESC
|
||||
case 27: { m_gizmos.reset_all_states(); m_dirty = true; break; }
|
||||
// key +
|
||||
case 43: { post_event(Event<int>(EVT_GLCANVAS_INCREASE_INSTANCES, +1)); break; }
|
||||
// key -
|
||||
case 45: { post_event(Event<int>(EVT_GLCANVAS_INCREASE_INSTANCES, -1)); break; }
|
||||
// key ?
|
||||
case 63: { post_event(SimpleEvent(EVT_GLCANVAS_QUESTION_MARK)); break; }
|
||||
// key A/a
|
||||
case 65:
|
||||
case 97: { post_event(SimpleEvent(EVT_GLCANVAS_ARRANGE)); break; }
|
||||
// key B/b
|
||||
case 66:
|
||||
case 98: { zoom_to_bed(); break; }
|
||||
// key I/i
|
||||
case 73:
|
||||
case 105: { set_camera_zoom(1.0f); break; }
|
||||
// key O/o
|
||||
case 79:
|
||||
case 111: { set_camera_zoom(-1.0f); break; }
|
||||
// key Z/z
|
||||
case 90:
|
||||
case 122:
|
||||
{
|
||||
if (m_selection.is_empty())
|
||||
zoom_to_volumes();
|
||||
else
|
||||
zoom_to_selection();
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
if (m_gizmos.handle_shortcut(keyCode, m_selection))
|
||||
{
|
||||
_update_gizmos_data();
|
||||
m_dirty = true;
|
||||
}
|
||||
else
|
||||
evt.Skip();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
_update_gizmos_data();
|
||||
m_dirty = true;
|
||||
}
|
||||
else
|
||||
evt.Skip();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5727,24 +5720,6 @@ void GLCanvas3D::on_paint(wxPaintEvent& evt)
|
|||
this->render();
|
||||
}
|
||||
|
||||
void GLCanvas3D::on_key_down(wxKeyEvent& evt)
|
||||
{
|
||||
if (evt.HasModifiers())
|
||||
evt.Skip();
|
||||
else
|
||||
{
|
||||
int key = evt.GetKeyCode();
|
||||
#ifdef __WXOSX__
|
||||
if (key == WXK_BACK)
|
||||
#else
|
||||
if (key == WXK_DELETE)
|
||||
#endif // __WXOSX__
|
||||
post_event(SimpleEvent(EVT_GLCANVAS_REMOVE_OBJECT));
|
||||
else
|
||||
evt.Skip();
|
||||
}
|
||||
}
|
||||
|
||||
Size GLCanvas3D::get_canvas_size() const
|
||||
{
|
||||
int w = 0;
|
||||
|
@ -6122,7 +6097,7 @@ bool GLCanvas3D::_init_toolbar()
|
|||
GLToolbarItem::Data item;
|
||||
|
||||
item.name = "add";
|
||||
item.tooltip = GUI::L_str("Add... [Ctrl+I]");
|
||||
item.tooltip = GUI::L_str("Add...") + " [" + GUI::shortkey_ctrl_prefix() + "I]";
|
||||
item.sprite_id = 0;
|
||||
item.is_toggable = false;
|
||||
item.action_event = EVT_GLTOOLBAR_ADD;
|
||||
|
@ -6130,7 +6105,7 @@ bool GLCanvas3D::_init_toolbar()
|
|||
return false;
|
||||
|
||||
item.name = "delete";
|
||||
item.tooltip = GUI::L_str("Delete [Del]");
|
||||
item.tooltip = GUI::L_str("Delete") + " [Del]";
|
||||
item.sprite_id = 1;
|
||||
item.is_toggable = false;
|
||||
item.action_event = EVT_GLTOOLBAR_DELETE;
|
||||
|
@ -6138,7 +6113,7 @@ bool GLCanvas3D::_init_toolbar()
|
|||
return false;
|
||||
|
||||
item.name = "deleteall";
|
||||
item.tooltip = GUI::L_str("Delete all [Ctrl+Del]");
|
||||
item.tooltip = GUI::L_str("Delete all") + " [" + GUI::shortkey_ctrl_prefix() + "Del]";
|
||||
item.sprite_id = 2;
|
||||
item.is_toggable = false;
|
||||
item.action_event = EVT_GLTOOLBAR_DELETE_ALL;
|
||||
|
|
|
@ -121,6 +121,7 @@ wxDECLARE_EVENT(EVT_GLCANVAS_VIEWPORT_CHANGED, SimpleEvent);
|
|||
wxDECLARE_EVENT(EVT_GLCANVAS_RIGHT_CLICK, Vec2dEvent);
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_REMOVE_OBJECT, SimpleEvent);
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_ARRANGE, SimpleEvent);
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_SELECT_ALL, SimpleEvent);
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_QUESTION_MARK, SimpleEvent);
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_INCREASE_INSTANCES, Event<int>); // data: +1 => increase, -1 => decrease
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_INSTANCE_MOVED, SimpleEvent);
|
||||
|
@ -1046,7 +1047,6 @@ public:
|
|||
void on_timer(wxTimerEvent& evt);
|
||||
void on_mouse(wxMouseEvent& evt);
|
||||
void on_paint(wxPaintEvent& evt);
|
||||
void on_key_down(wxKeyEvent& evt);
|
||||
|
||||
Size get_canvas_size() const;
|
||||
Point get_local_mouse_position() const;
|
||||
|
|
|
@ -75,6 +75,30 @@ void break_to_debugger()
|
|||
#endif /* _WIN32 */
|
||||
}
|
||||
|
||||
const std::string& shortkey_ctrl_prefix()
|
||||
{
|
||||
static const std::string str =
|
||||
#ifdef __APPLE__
|
||||
"⌘"
|
||||
#else
|
||||
"Ctrl+"
|
||||
#endif
|
||||
;
|
||||
return str;
|
||||
}
|
||||
|
||||
const std::string& shortkey_alt_prefix()
|
||||
{
|
||||
static const std::string str =
|
||||
#ifdef __APPLE__
|
||||
"⌥"
|
||||
#else
|
||||
"Alt+"
|
||||
#endif
|
||||
;
|
||||
return str;
|
||||
}
|
||||
|
||||
bool config_wizard_startup(bool app_config_exists)
|
||||
{
|
||||
if (!app_config_exists || wxGetApp().preset_bundle->printers.size() <= 1) {
|
||||
|
|
|
@ -27,7 +27,11 @@ void enable_screensaver();
|
|||
bool debugged();
|
||||
void break_to_debugger();
|
||||
|
||||
AppConfig* get_app_config();
|
||||
// Platform specific Ctrl+/Alt+ (Windows, Linux) vs. ⌘/⌥ (OSX) prefixes
|
||||
extern const std::string& shortkey_ctrl_prefix();
|
||||
extern const std::string& shortkey_alt_prefix();
|
||||
|
||||
extern AppConfig* get_app_config();
|
||||
|
||||
extern void add_menus(wxMenuBar *menu, int event_preferences_changed, int event_language_change);
|
||||
|
||||
|
|
|
@ -561,7 +561,13 @@ void GUI_App::add_config_menu(wxMenuBar *menu)
|
|||
local_menu->Append(config_id_base + ConfigMenuTakeSnapshot, _(L("Take Configuration &Snapshot")), _(L("Capture a configuration snapshot")));
|
||||
// local_menu->Append(config_id_base + ConfigMenuUpdate, _(L("Check for updates")), _(L("Check for configuration updates")));
|
||||
local_menu->AppendSeparator();
|
||||
local_menu->Append(config_id_base + ConfigMenuPreferences, _(L("&Preferences")) + dots + "\tCtrl+P", _(L("Application preferences")));
|
||||
local_menu->Append(config_id_base + ConfigMenuPreferences, _(L("&Preferences")) + dots +
|
||||
#ifdef __APPLE__
|
||||
"\tCtrl+,",
|
||||
#else
|
||||
"\tCtrl+P",
|
||||
#endif
|
||||
_(L("Application preferences")));
|
||||
local_menu->AppendSeparator();
|
||||
auto mode_menu = new wxMenu();
|
||||
mode_menu->AppendRadioItem(config_id_base + ConfigMenuModeSimple, _(L("Simple")), _(L("Simple View Mode")));
|
||||
|
|
|
@ -88,13 +88,8 @@ KBShortcutsDialog::KBShortcutsDialog()
|
|||
|
||||
void KBShortcutsDialog::fill_shortcuts()
|
||||
{
|
||||
#ifdef __WXOSX__
|
||||
const std::string ctrl = "⌘";
|
||||
const std::string alt = "⌥";
|
||||
#else
|
||||
const std::string ctrl = "Ctrl+";
|
||||
const std::string alt = "Alt+";
|
||||
#endif // __WXOSX__
|
||||
const std::string &ctrl = GUI::shortkey_ctrl_prefix();
|
||||
const std::string &alt = GUI::shortkey_alt_prefix();
|
||||
|
||||
m_full_shortcuts.reserve(4);
|
||||
|
||||
|
|
|
@ -324,7 +324,19 @@ void MainFrame::init_menubar()
|
|||
if (m_plater != nullptr)
|
||||
{
|
||||
editMenu = new wxMenu();
|
||||
wxMenuItem* item_select_all = append_menu_item(editMenu, wxID_ANY, _(L("&Select all")) + "\tCtrl+A", _(L("Selects all objects")),
|
||||
// \xA0 is a non-breaking space. It is entered here to spoil the automatic accelerators,
|
||||
// as the simple numeric accelerators spoil all numeric data entry.
|
||||
wxMenuItem* item_select_all = append_menu_item(editMenu, wxID_ANY, _(L("&Select all")) +
|
||||
#ifdef _MSC_VER
|
||||
"\t\xA0" + "Ctrl+\xA0" + "A"
|
||||
#else
|
||||
#ifdef __APPLE__
|
||||
"\tCtrl+A"
|
||||
#else
|
||||
" - Ctrl+A"
|
||||
#endif
|
||||
#endif
|
||||
, _(L("Selects all objects")),
|
||||
[this](wxCommandEvent&) { m_plater->select_all(); }, "");
|
||||
editMenu->AppendSeparator();
|
||||
wxMenuItem* item_delete_sel = append_menu_item(editMenu, wxID_ANY, _(L("&Delete selected")) + "\tDel", _(L("Deletes the current selection")),
|
||||
|
@ -386,19 +398,23 @@ void MainFrame::init_menubar()
|
|||
|
||||
// View menu
|
||||
wxMenu* viewMenu = nullptr;
|
||||
wxString sep =
|
||||
#ifdef _MSC_VER
|
||||
"\t";
|
||||
#else
|
||||
" - ";
|
||||
#endif
|
||||
if (m_plater) {
|
||||
viewMenu = new wxMenu();
|
||||
// \xA0 is a non-breaing space. It is entered here to spoil the automatic accelerators,
|
||||
// as the simple numeric accelerators spoil all numeric data entry.
|
||||
// The camera control accelerators are captured by GLCanvas3D::on_char().
|
||||
wxMenuItem* item_iso = append_menu_item(viewMenu, wxID_ANY, _(L("&Iso")) + "\t\xA0" + "0", _(L("Iso View")), [this](wxCommandEvent&) { select_view("iso"); });
|
||||
wxMenuItem* item_iso = append_menu_item(viewMenu, wxID_ANY, _(L("Iso")) + sep + "&0", _(L("Iso View")), [this](wxCommandEvent&) { select_view("iso"); });
|
||||
viewMenu->AppendSeparator();
|
||||
wxMenuItem* item_top = append_menu_item(viewMenu, wxID_ANY, _(L("&Top")) + "\t\xA0" + "1", _(L("Top View")), [this](wxCommandEvent&) { select_view("top"); });
|
||||
wxMenuItem* item_bottom = append_menu_item(viewMenu, wxID_ANY, _(L("&Bottom")) + "\t\xA0" + "2", _(L("Bottom View")), [this](wxCommandEvent&) { select_view("bottom"); });
|
||||
wxMenuItem* item_front = append_menu_item(viewMenu, wxID_ANY, _(L("&Front")) + "\t\xA0" + "3", _(L("Front View")), [this](wxCommandEvent&) { select_view("front"); });
|
||||
wxMenuItem* item_rear = append_menu_item(viewMenu, wxID_ANY, _(L("R&ear")) + "\t\xA0" + "4", _(L("Rear View")), [this](wxCommandEvent&) { select_view("rear"); });
|
||||
wxMenuItem* item_left = append_menu_item(viewMenu, wxID_ANY, _(L("&Left")) + "\t\xA0" + "5", _(L("Left View")), [this](wxCommandEvent&) { select_view("left"); });
|
||||
wxMenuItem* item_right = append_menu_item(viewMenu, wxID_ANY, _(L("&Right")) + "\t\xA0" + "6", _(L("Right View")), [this](wxCommandEvent&) { select_view("right"); });
|
||||
wxMenuItem* item_top = append_menu_item(viewMenu, wxID_ANY, _(L("Top")) + sep + "&1", _(L("Top View")), [this](wxCommandEvent&) { select_view("top"); });
|
||||
wxMenuItem* item_bottom = append_menu_item(viewMenu, wxID_ANY, _(L("Bottom")) + sep + "&2", _(L("Bottom View")), [this](wxCommandEvent&) { select_view("bottom"); });
|
||||
wxMenuItem* item_front = append_menu_item(viewMenu, wxID_ANY, _(L("Front")) + sep + "&3", _(L("Front View")), [this](wxCommandEvent&) { select_view("front"); });
|
||||
wxMenuItem* item_rear = append_menu_item(viewMenu, wxID_ANY, _(L("Rear")) + sep + "&4", _(L("Rear View")), [this](wxCommandEvent&) { select_view("rear"); });
|
||||
wxMenuItem* item_left = append_menu_item(viewMenu, wxID_ANY, _(L("Left")) + sep + "&5", _(L("Left View")), [this](wxCommandEvent&) { select_view("left"); });
|
||||
wxMenuItem* item_right = append_menu_item(viewMenu, wxID_ANY, _(L("Right")) + sep + "&6", _(L("Right View")), [this](wxCommandEvent&) { select_view("right"); });
|
||||
|
||||
Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(can_change_view()); }, item_iso->GetId());
|
||||
Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(can_change_view()); }, item_top->GetId());
|
||||
|
@ -434,7 +450,7 @@ void MainFrame::init_menubar()
|
|||
append_menu_item(helpMenu, wxID_ANY, _(L("&About Slic3r")), _(L("Show about dialog")),
|
||||
[this](wxCommandEvent&) { Slic3r::GUI::about(); });
|
||||
helpMenu->AppendSeparator();
|
||||
append_menu_item(helpMenu, wxID_ANY, _(L("&Keyboard Shortcuts")) + "\t\xA0?", _(L("Show the list of the keyboard shortcuts")),
|
||||
append_menu_item(helpMenu, wxID_ANY, _(L("Keyboard Shortcuts")) + sep + "&?", _(L("Show the list of the keyboard shortcuts")),
|
||||
[this](wxCommandEvent&) { wxGetApp().keyboard_shortcuts(); });
|
||||
}
|
||||
|
||||
|
|
|
@ -1028,7 +1028,8 @@ struct Plater::priv
|
|||
unsigned int update_background_process(bool force_validation = false);
|
||||
// Restart background processing thread based on a bitmask of UpdateBackgroundProcessReturnState.
|
||||
bool restart_background_process(unsigned int state);
|
||||
void update_restart_background_process(bool force_scene_update, bool force_preview_update);
|
||||
// returns bit mask of UpdateBackgroundProcessReturnState
|
||||
unsigned int update_restart_background_process(bool force_scene_update, bool force_preview_update);
|
||||
void export_gcode(fs::path output_path, PrintHostJob upload_job);
|
||||
void reload_from_disk();
|
||||
void fix_through_netfabb(const int obj_idx, const int vol_idx = -1);
|
||||
|
@ -1170,6 +1171,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
|||
view3D_canvas->Bind(EVT_GLCANVAS_RIGHT_CLICK, &priv::on_right_click, this);
|
||||
view3D_canvas->Bind(EVT_GLCANVAS_REMOVE_OBJECT, [q](SimpleEvent&) { q->remove_selected(); });
|
||||
view3D_canvas->Bind(EVT_GLCANVAS_ARRANGE, [this](SimpleEvent&) { arrange(); });
|
||||
view3D_canvas->Bind(EVT_GLCANVAS_SELECT_ALL, [this](SimpleEvent&) { this->q->select_all(); });
|
||||
view3D_canvas->Bind(EVT_GLCANVAS_QUESTION_MARK, [this](SimpleEvent&) { wxGetApp().keyboard_shortcuts(); });
|
||||
view3D_canvas->Bind(EVT_GLCANVAS_INCREASE_INSTANCES, [this](Event<int> &evt)
|
||||
{ if (evt.data == 1) this->q->increase_instances(); else if (this->can_decrease_instances()) this->q->decrease_instances(); });
|
||||
|
@ -1575,7 +1577,7 @@ std::unique_ptr<CheckboxFileDialog> Plater::priv::get_export_file(GUI::FileType
|
|||
// Update printbility state of each of the ModelInstances.
|
||||
this->update_print_volume_state();
|
||||
// Find the file name of the first printable object.
|
||||
fs::path output_file = this->model.propose_export_file_name();
|
||||
fs::path output_file = this->model.propose_export_file_name_and_path();
|
||||
|
||||
switch (file_type) {
|
||||
case FT_STL: output_file.replace_extension("stl"); break;
|
||||
|
@ -1735,6 +1737,8 @@ void Plater::priv::arrange()
|
|||
// Guard the arrange process
|
||||
arranging.store(true);
|
||||
|
||||
wxBusyCursor wait;
|
||||
|
||||
// Disable the arrange button (to prevent reentrancies, we will call wxYied)
|
||||
view3D->enable_toolbar_item("arrange", can_arrange());
|
||||
|
||||
|
@ -2045,7 +2049,7 @@ void Plater::priv::export_gcode(fs::path output_path, PrintHostJob upload_job)
|
|||
this->restart_background_process(priv::UPDATE_BACKGROUND_PROCESS_FORCE_EXPORT);
|
||||
}
|
||||
|
||||
void Plater::priv::update_restart_background_process(bool force_update_scene, bool force_update_preview)
|
||||
unsigned int Plater::priv::update_restart_background_process(bool force_update_scene, bool force_update_preview)
|
||||
{
|
||||
// bitmask of UpdateBackgroundProcessReturnState
|
||||
unsigned int state = this->update_background_process(false);
|
||||
|
@ -2055,6 +2059,7 @@ void Plater::priv::update_restart_background_process(bool force_update_scene, bo
|
|||
if (force_update_preview)
|
||||
this->preview->reload_print();
|
||||
this->restart_background_process(state);
|
||||
return state;
|
||||
}
|
||||
|
||||
void Plater::priv::update_fff_scene()
|
||||
|
@ -2108,31 +2113,10 @@ void Plater::priv::fix_through_netfabb(const int obj_idx, const int vol_idx/* =
|
|||
{
|
||||
if (obj_idx < 0)
|
||||
return;
|
||||
|
||||
const auto model_object = model.objects[obj_idx];
|
||||
Model model_fixed;// = new Model();
|
||||
fix_model_by_win10_sdk_gui(*model_object, this->fff_print, model_fixed);
|
||||
|
||||
auto new_obj_idxs = load_model_objects(model_fixed.objects);
|
||||
if (new_obj_idxs.empty())
|
||||
return;
|
||||
|
||||
for(auto new_obj_idx : new_obj_idxs) {
|
||||
auto o = model.objects[new_obj_idx];
|
||||
o->clear_instances();
|
||||
for (auto instance: model_object->instances)
|
||||
o->add_instance(*instance);
|
||||
o->invalidate_bounding_box();
|
||||
|
||||
if (o->volumes.size() == model_object->volumes.size()) {
|
||||
for (int i = 0; i < o->volumes.size(); i++) {
|
||||
o->volumes[i]->config.apply(model_object->volumes[i]->config);
|
||||
}
|
||||
}
|
||||
// FIXME restore volumes and their configs, layer_height_ranges, layer_height_profile
|
||||
}
|
||||
|
||||
remove(obj_idx);
|
||||
fix_model_by_win10_sdk_gui(*model.objects[obj_idx], vol_idx);
|
||||
this->object_list_changed();
|
||||
this->update();
|
||||
this->schedule_background_process();
|
||||
}
|
||||
|
||||
void Plater::priv::set_current_panel(wxPanel* panel)
|
||||
|
@ -2553,7 +2537,7 @@ void Plater::priv::init_view_toolbar()
|
|||
GLToolbarItem::Data item;
|
||||
|
||||
item.name = "3D";
|
||||
item.tooltip = GUI::L_str("3D editor view [Ctrl+5]");
|
||||
item.tooltip = GUI::L_str("3D editor view") + " [" + GUI::shortkey_ctrl_prefix() + "5]";
|
||||
item.sprite_id = 0;
|
||||
item.action_event = EVT_GLVIEWTOOLBAR_3D;
|
||||
item.is_toggable = false;
|
||||
|
@ -2561,7 +2545,7 @@ void Plater::priv::init_view_toolbar()
|
|||
return;
|
||||
|
||||
item.name = "Preview";
|
||||
item.tooltip = GUI::L_str("Preview [Ctrl+6]");
|
||||
item.tooltip = GUI::L_str("Preview") + " [" + GUI::shortkey_ctrl_prefix() + "6]";
|
||||
item.sprite_id = 1;
|
||||
item.action_event = EVT_GLVIEWTOOLBAR_PREVIEW;
|
||||
item.is_toggable = false;
|
||||
|
@ -2846,51 +2830,43 @@ void Plater::cut(size_t obj_idx, size_t instance_idx, coordf_t z, bool keep_uppe
|
|||
p->load_model_objects(new_objects);
|
||||
}
|
||||
|
||||
void Plater::export_gcode(fs::path output_path)
|
||||
void Plater::export_gcode()
|
||||
{
|
||||
if (p->model.objects.empty())
|
||||
return;
|
||||
|
||||
// select output file
|
||||
if (output_path.empty()) {
|
||||
// XXX: take output path from CLI opts? Ancient Slic3r versions used to do that...
|
||||
|
||||
// If possible, remove accents from accented latin characters.
|
||||
// This function is useful for generating file names to be processed by legacy firmwares.
|
||||
fs::path default_output_file;
|
||||
try {
|
||||
default_output_file = this->p->background_process.current_print()->output_filepath(output_path.string());
|
||||
} catch (const std::exception &ex) {
|
||||
show_error(this, ex.what());
|
||||
return;
|
||||
}
|
||||
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());
|
||||
|
||||
wxFileDialog dlg(this, (printer_technology() == ptFFF) ? _(L("Save G-code file as:")) : _(L("Save Zip file as:")),
|
||||
start_dir,
|
||||
from_path(default_output_file.filename()),
|
||||
GUI::file_wildcards((printer_technology() == ptFFF) ? FT_GCODE : FT_PNGZIP, default_output_file.extension().string()),
|
||||
wxFD_SAVE | wxFD_OVERWRITE_PROMPT
|
||||
);
|
||||
|
||||
if (dlg.ShowModal() == wxID_OK) {
|
||||
fs::path path = into_path(dlg.GetPath());
|
||||
wxGetApp().app_config->update_last_output_dir(path.parent_path().string());
|
||||
output_path = std::move(path);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
output_path = this->p->background_process.current_print()->output_filepath(output_path.string());
|
||||
} catch (const std::exception &ex) {
|
||||
show_error(this, ex.what());
|
||||
return;
|
||||
}
|
||||
// If possible, remove accents from accented latin characters.
|
||||
// This function is useful for generating file names to be processed by legacy firmwares.
|
||||
fs::path default_output_file;
|
||||
try {
|
||||
// Update the background processing, so that the placeholder parser will get the correct values for the ouput file template.
|
||||
// Also if there is something wrong with the current configuration, a pop-up dialog will be shown and the export will not be performed.
|
||||
unsigned int state = this->p->update_restart_background_process(false, false);
|
||||
if (state & priv::UPDATE_BACKGROUND_PROCESS_INVALID)
|
||||
return;
|
||||
default_output_file = this->p->background_process.current_print()->output_filepath("");
|
||||
} catch (const std::exception &ex) {
|
||||
show_error(this, ex.what());
|
||||
return;
|
||||
}
|
||||
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 (! output_path.empty()) {
|
||||
wxFileDialog dlg(this, (printer_technology() == ptFFF) ? _(L("Save G-code file as:")) : _(L("Save Zip file as:")),
|
||||
start_dir,
|
||||
from_path(default_output_file.filename()),
|
||||
GUI::file_wildcards((printer_technology() == ptFFF) ? FT_GCODE : FT_PNGZIP, default_output_file.extension().string()),
|
||||
wxFD_SAVE | wxFD_OVERWRITE_PROMPT
|
||||
);
|
||||
|
||||
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());
|
||||
output_path = std::move(path);
|
||||
}
|
||||
if (! output_path.empty())
|
||||
p->export_gcode(std::move(output_path), PrintHostJob());
|
||||
}
|
||||
}
|
||||
|
||||
void Plater::export_stl(bool selection_only)
|
||||
|
@ -2991,7 +2967,12 @@ void Plater::send_gcode()
|
|||
// Obtain default output path
|
||||
fs::path default_output_file;
|
||||
try {
|
||||
default_output_file = this->p->background_process.current_print()->output_filepath("");
|
||||
// Update the background processing, so that the placeholder parser will get the correct values for the ouput file template.
|
||||
// Also if there is something wrong with the current configuration, a pop-up dialog will be shown and the export will not be performed.
|
||||
unsigned int state = this->p->update_restart_background_process(false, false);
|
||||
if (state & priv::UPDATE_BACKGROUND_PROCESS_INVALID)
|
||||
return;
|
||||
default_output_file = this->p->background_process.current_print()->output_filepath("");
|
||||
} catch (const std::exception &ex) {
|
||||
show_error(this, ex.what());
|
||||
return;
|
||||
|
|
|
@ -140,8 +140,7 @@ public:
|
|||
|
||||
void cut(size_t obj_idx, size_t instance_idx, coordf_t z, bool keep_upper = true, bool keep_lower = true, bool rotate_lower = false);
|
||||
|
||||
// Note: empty path means "use the default"
|
||||
void export_gcode(boost::filesystem::path output_path = boost::filesystem::path());
|
||||
void export_gcode();
|
||||
void export_stl(bool selection_only = false);
|
||||
void export_amf();
|
||||
void export_3mf(const boost::filesystem::path& output_path = boost::filesystem::path());
|
||||
|
|
|
@ -517,16 +517,6 @@ void PresetCollection::add_default_preset(const std::vector<std::string> &keys,
|
|||
++ m_num_default_presets;
|
||||
}
|
||||
|
||||
bool is_file_plain(const std::string &path)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
DWORD attributes = GetFileAttributesW(boost::nowide::widen(path).c_str());
|
||||
return (attributes & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) == 0;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Load all presets found in dir_path.
|
||||
// Throws an exception on error.
|
||||
void PresetCollection::load_presets(const std::string &dir_path, const std::string &subdir)
|
||||
|
@ -538,10 +528,7 @@ void PresetCollection::load_presets(const std::string &dir_path, const std::stri
|
|||
// (see the "Preset already present, not loading" message).
|
||||
std::deque<Preset> presets_loaded;
|
||||
for (auto &dir_entry : boost::filesystem::directory_iterator(dir))
|
||||
if (boost::filesystem::is_regular_file(dir_entry.status()) && boost::algorithm::iends_with(dir_entry.path().filename().string(), ".ini") &&
|
||||
// Ignore system and hidden files, which may be created by the DropBox synchronisation process.
|
||||
// https://github.com/prusa3d/Slic3r/issues/1298
|
||||
is_file_plain(dir_entry.path().string())) {
|
||||
if (Slic3r::is_ini_file(dir_entry)) {
|
||||
std::string name = dir_entry.path().filename().string();
|
||||
// Remove the .ini suffix.
|
||||
name.erase(name.size() - 4);
|
||||
|
@ -1169,6 +1156,18 @@ std::string PresetCollection::name() const
|
|||
}
|
||||
}
|
||||
|
||||
std::string PresetCollection::section_name() const
|
||||
{
|
||||
switch (this->type()) {
|
||||
case Preset::TYPE_PRINT: return "print";
|
||||
case Preset::TYPE_FILAMENT: return "filament";
|
||||
case Preset::TYPE_SLA_PRINT: return "sla_print";
|
||||
case Preset::TYPE_SLA_MATERIAL: return "sla_material";
|
||||
case Preset::TYPE_PRINTER: return "printer";
|
||||
default: return "invalid";
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> PresetCollection::system_preset_names() const
|
||||
{
|
||||
size_t num = 0;
|
||||
|
|
|
@ -230,7 +230,10 @@ public:
|
|||
void reset(bool delete_files);
|
||||
|
||||
Preset::Type type() const { return m_type; }
|
||||
// Name, to be used on the screen and in error messages. Not localized.
|
||||
std::string name() const;
|
||||
// Name, to be used as a section name in config bundle, and as a folder name for presets.
|
||||
std::string section_name() const;
|
||||
const std::deque<Preset>& operator()() const { return m_presets; }
|
||||
|
||||
// Add default preset at the start of the collection, increment the m_default_preset counter.
|
||||
|
|
|
@ -243,7 +243,7 @@ std::string PresetBundle::load_system_presets()
|
|||
std::string errors_cummulative;
|
||||
bool first = true;
|
||||
for (auto &dir_entry : boost::filesystem::directory_iterator(dir))
|
||||
if (boost::filesystem::is_regular_file(dir_entry.status()) && boost::algorithm::iends_with(dir_entry.path().filename().string(), ".ini")) {
|
||||
if (Slic3r::is_ini_file(dir_entry)) {
|
||||
std::string name = dir_entry.path().filename().string();
|
||||
// Remove the .ini suffix.
|
||||
name.erase(name.size() - 4);
|
||||
|
@ -1208,7 +1208,7 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla
|
|||
#else
|
||||
// Store the print/filament/printer presets at the same location as the upstream Slic3r.
|
||||
#endif
|
||||
/ presets->name() / file_name).make_preferred();
|
||||
/ presets->section_name() / file_name).make_preferred();
|
||||
// Load the preset into the list of presets, save it to disk.
|
||||
Preset &loaded = presets->load_preset(file_path.string(), preset_name, std::move(config), false);
|
||||
if (flags & LOAD_CFGBNDLE_SAVE)
|
||||
|
@ -1365,7 +1365,7 @@ void PresetBundle::export_configbundle(const std::string &path, bool export_syst
|
|||
if (preset.is_default || preset.is_external || (preset.is_system && ! export_system_settings))
|
||||
// Only export the common presets, not external files or the default preset.
|
||||
continue;
|
||||
c << std::endl << "[" << presets->name() << ":" << preset.name << "]" << std::endl;
|
||||
c << std::endl << "[" << presets->section_name() << ":" << preset.name << "]" << std::endl;
|
||||
for (const std::string &opt_key : preset.config.keys())
|
||||
c << opt_key << " = " << preset.config.serialize(opt_key) << std::endl;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue