diff --git a/resources/icons/toolbar_arrow.png b/resources/icons/toolbar_arrow.png
deleted file mode 100644
index a370442ff..000000000
Binary files a/resources/icons/toolbar_arrow.png and /dev/null differ
diff --git a/resources/icons/toolbar_arrow.svg b/resources/icons/toolbar_arrow.svg
index 998646a24..b49645190 100644
--- a/resources/icons/toolbar_arrow.svg
+++ b/resources/icons/toolbar_arrow.svg
@@ -1,76 +1,22 @@
-
-
+
+
\ No newline at end of file
diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp
index 8eb5bb389..e32285106 100644
--- a/src/libslic3r/Model.cpp
+++ b/src/libslic3r/Model.cpp
@@ -959,7 +959,7 @@ void ModelObject::ensure_on_bed(bool allow_negative_z)
double z_offset = 0.0;
if (allow_negative_z) {
- if (volumes.size() == 1)
+ if (parts_count() == 1)
z_offset = -get_min_z();
else {
const double max_z = get_max_z();
@@ -1127,6 +1127,15 @@ size_t ModelObject::facets_count() const
return num;
}
+size_t ModelObject::parts_count() const
+{
+ size_t num = 0;
+ for (const ModelVolume* v : this->volumes)
+ if (v->is_model_part())
+ ++num;
+ return num;
+}
+
bool ModelObject::needed_repair() const
{
for (const ModelVolume *v : this->volumes)
diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp
index 25f19e792..b89dd5aa1 100644
--- a/src/libslic3r/Model.hpp
+++ b/src/libslic3r/Model.hpp
@@ -347,6 +347,7 @@ public:
size_t materials_count() const;
size_t facets_count() const;
+ size_t parts_count() const;
bool needed_repair() const;
ModelObjectPtrs cut(size_t instance, coordf_t z, ModelObjectCutAttributes attributes);
void split(ModelObjectPtrs* new_objects);
diff --git a/src/slic3r/GUI/AboutDialog.cpp b/src/slic3r/GUI/AboutDialog.cpp
index fdbc1a6d3..72f1421f6 100644
--- a/src/slic3r/GUI/AboutDialog.cpp
+++ b/src/slic3r/GUI/AboutDialog.cpp
@@ -195,7 +195,7 @@ void CopyrightsDialog::on_dpi_changed(const wxRect &suggested_rect)
void CopyrightsDialog::onLinkClicked(wxHtmlLinkEvent &event)
{
- wxLaunchDefaultBrowser(event.GetLinkInfo().GetHref());
+ wxGetApp().open_browser_with_warning_dialog(event.GetLinkInfo().GetHref());
event.Skip(false);
}
@@ -344,7 +344,7 @@ void AboutDialog::on_dpi_changed(const wxRect &suggested_rect)
void AboutDialog::onLinkClicked(wxHtmlLinkEvent &event)
{
- wxLaunchDefaultBrowser(event.GetLinkInfo().GetHref());
+ wxGetApp().open_browser_with_warning_dialog(event.GetLinkInfo().GetHref());
event.Skip(false);
}
diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp
index cae2dfc23..ee1d3b14a 100644
--- a/src/slic3r/GUI/GLCanvas3D.cpp
+++ b/src/slic3r/GUI/GLCanvas3D.cpp
@@ -4433,13 +4433,7 @@ bool GLCanvas3D::_init_main_toolbar()
}
// init arrow
BackgroundTexture::Metadata arrow_data;
- arrow_data.filename = "toolbar_arrow.png";
-// arrow_data.filename = "toolbar_arrow.svg";
- //arrow_data.left = 16;
- //arrow_data.top = 16;
- //arrow_data.right = 16;
- //arrow_data.bottom = 16;
-
+ arrow_data.filename = "toolbar_arrow.svg";
arrow_data.left = 0;
arrow_data.top = 0;
arrow_data.right = 0;
diff --git a/src/slic3r/GUI/GLToolbar.cpp b/src/slic3r/GUI/GLToolbar.cpp
index 243031847..515b6ed3a 100644
--- a/src/slic3r/GUI/GLToolbar.cpp
+++ b/src/slic3r/GUI/GLToolbar.cpp
@@ -193,10 +193,9 @@ bool GLToolbar::init_arrow(const BackgroundTexture::Metadata& arrow_texture)
std::string path = resources_dir() + "/icons/";
bool res = false;
- if (!arrow_texture.filename.empty())
- res = m_arrow_texture.texture.load_from_file(path + arrow_texture.filename, false, GLTexture::SingleThreaded, false);
-// res = m_arrow_texture.texture.load_from_svg_file(path + arrow_texture.filename, false, true, false, 100);
-
+ if (!arrow_texture.filename.empty()) {
+ res = m_arrow_texture.texture.load_from_svg_file(path + arrow_texture.filename, false, false, false, 1000);
+ }
if (res)
m_arrow_texture.metadata = arrow_texture;
@@ -1176,19 +1175,22 @@ void GLToolbar::render_arrow(const GLCanvas3D& parent, GLToolbarItem* highlighte
float right = left + scaled_icons_size;
unsigned int tex_id = m_arrow_texture.texture.get_id();
+ // width and height of icon arrow is pointing to
float tex_width = (float)m_icons_texture.get_width();
float tex_height = (float)m_icons_texture.get_height();
+ // arrow width and height
+ float arr_tex_width = (float)m_arrow_texture.texture.get_width();
+ float arr_tex_height = (float)m_arrow_texture.texture.get_height();
+ if ((tex_id != 0) && (arr_tex_width > 0) && (arr_tex_height > 0)) {
+ float inv_tex_width = (arr_tex_width != 0.0f) ? 1.0f / arr_tex_width : 0.0f;
+ float inv_tex_height = (arr_tex_height != 0.0f) ? 1.0f / arr_tex_height : 0.0f;
- if ((tex_id != 0) && (tex_width > 0) && (tex_height > 0)) {
- float inv_tex_width = (tex_width != 0.0f) ? 1.0f / tex_width : 0.0f;
- float inv_tex_height = (tex_height != 0.0f) ? 1.0f / tex_height : 0.0f;
-
- float internal_left = left + border - scaled_icons_size / 2; // add half scaled_icons_size for huge arrow
- float internal_right = right - border + scaled_icons_size / 2;
+ float internal_left = left + border - scaled_icons_size * 1.5f; // add scaled_icons_size for huge arrow
+ float internal_right = right - border + scaled_icons_size * 1.5f;
float internal_top = top - border;
// bottom is not moving and should be calculated from arrow texture sides ratio
float arrow_sides_ratio = (float)m_arrow_texture.texture.get_height() / (float)m_arrow_texture.texture.get_width();
- float internal_bottom = internal_top - (internal_right - internal_left) * arrow_sides_ratio;
+ float internal_bottom = internal_top - (internal_right - internal_left) * arrow_sides_ratio ;
float internal_left_uv = (float)m_arrow_texture.metadata.left * inv_tex_width;
float internal_right_uv = 1.0f - (float)m_arrow_texture.metadata.right * inv_tex_width;
diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp
index 58ce12ae4..102026a0c 100644
--- a/src/slic3r/GUI/GUI_App.cpp
+++ b/src/slic3r/GUI/GUI_App.cpp
@@ -2327,7 +2327,7 @@ wxString GUI_App::current_language_code_safe() const
void GUI_App::open_web_page_localized(const std::string &http_address)
{
- wxLaunchDefaultBrowser(http_address + "&lng=" + this->current_language_code_safe());
+ open_browser_with_warning_dialog(http_address + "&lng=" + this->current_language_code_safe());
}
bool GUI_App::run_wizard(ConfigWizard::RunReason reason, ConfigWizard::StartPage start_page)
@@ -2525,6 +2525,23 @@ void GUI_App::check_updates(const bool verbose)
}
}
+bool GUI_App::open_browser_with_warning_dialog(const wxString& url, int flags/* = 0*/)
+{
+ bool launch = true;
+
+ if (get_app_config()->get("suppress_hyperlinks").empty()) {
+ wxRichMessageDialog dialog(nullptr, _L("Should we open this hyperlink in your default browser?"), _L("PrusaSlicer: Open hyperlink"), wxICON_QUESTION | wxYES_NO);
+ dialog.ShowCheckBox(_L("Remember my choice"));
+ int answer = dialog.ShowModal();
+ launch = answer == wxID_YES;
+ get_app_config()->set("suppress_hyperlinks", dialog.IsCheckBoxChecked() ? (answer == wxID_NO ? "1" : "0") : "");
+ }
+ if (launch)
+ launch = get_app_config()->get("suppress_hyperlinks") != "1";
+
+ return launch && wxLaunchDefaultBrowser(url, flags);
+}
+
// static method accepting a wxWindow object as first parameter
// void warning_catcher{
// my($self, $message_dialog) = @_;
diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp
index a140247e0..1d8c2fcf7 100644
--- a/src/slic3r/GUI/GUI_App.hpp
+++ b/src/slic3r/GUI/GUI_App.hpp
@@ -261,7 +261,8 @@ public:
void open_preferences(size_t open_on_tab = 0);
virtual bool OnExceptionInMainLoop() override;
-
+ // Calls wxLaunchDefaultBrowser if user confirms in dialog.
+ bool open_browser_with_warning_dialog(const wxString& url, int flags = 0);
#ifdef __APPLE__
void OSXStoreOpenFiles(const wxArrayString &files) override;
// wxWidgets override to get an event on open files.
diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
index 5617b5ed8..6d9a03977 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
@@ -132,8 +132,7 @@ bool GLGizmosManager::init_arrow(const BackgroundTexture::Metadata& arrow_textur
bool res = false;
if (!arrow_texture.filename.empty())
- res = m_arrow_texture.texture.load_from_file(path + arrow_texture.filename, false, GLTexture::SingleThreaded, false);
-// res = m_arrow_texture.texture.load_from_svg_file(path + arrow_texture.filename, false, true, false, 100);
+ res = m_arrow_texture.texture.load_from_svg_file(path + arrow_texture.filename, false, false, false, 1000);
if (res)
m_arrow_texture.metadata = arrow_texture;
@@ -1019,7 +1018,7 @@ void GLGizmosManager::render_arrow(const GLCanvas3D& parent, EType highlighted_t
float arrow_sides_ratio = (float)m_arrow_texture.texture.get_height() / (float)m_arrow_texture.texture.get_width();
- GLTexture::render_sub_texture(tex_id, zoomed_top_x + zoomed_icons_size * 1.2f, zoomed_top_x + zoomed_icons_size * 1.2f + zoomed_icons_size * arrow_sides_ratio, zoomed_top_y - zoomed_icons_size, zoomed_top_y, { { internal_left_uv, internal_bottom_uv }, { internal_left_uv, internal_top_uv }, { internal_right_uv, internal_top_uv }, { internal_right_uv, internal_bottom_uv } });
+ GLTexture::render_sub_texture(tex_id, zoomed_top_x + zoomed_icons_size * 1.2f, zoomed_top_x + zoomed_icons_size * 1.2f + zoomed_icons_size * 2.2f * arrow_sides_ratio, zoomed_top_y - zoomed_icons_size * 1.6f , zoomed_top_y + zoomed_icons_size * 0.6f, { { internal_left_uv, internal_bottom_uv }, { internal_left_uv, internal_top_uv }, { internal_right_uv, internal_top_uv }, { internal_right_uv, internal_bottom_uv } });
break;
}
zoomed_top_y -= zoomed_stride_y;
diff --git a/src/slic3r/GUI/HintNotification.cpp b/src/slic3r/GUI/HintNotification.cpp
index 1d5931c48..ead7a8f29 100644
--- a/src/slic3r/GUI/HintNotification.cpp
+++ b/src/slic3r/GUI/HintNotification.cpp
@@ -236,8 +236,7 @@ bool tags_check(const std::string& disabled_tags, const std::string& enabled_tag
}
void launch_browser_if_allowed(const std::string& url)
{
- if (wxGetApp().app_config->get("suppress_hyperlinks") != "1")
- wxLaunchDefaultBrowser(url);
+ wxGetApp().open_browser_with_warning_dialog(url);
}
} //namespace
HintDatabase::~HintDatabase()
diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp
index 498b02605..329a9a62a 100644
--- a/src/slic3r/GUI/MainFrame.cpp
+++ b/src/slic3r/GUI/MainFrame.cpp
@@ -1057,7 +1057,7 @@ static wxMenu* generate_help_menu()
append_menu_item(helpMenu, wxID_ANY, _L("Prusa 3D &Drivers"), _L("Open the Prusa3D drivers download page in your browser"),
[](wxCommandEvent&) { wxGetApp().open_web_page_localized("https://www.prusa3d.com/downloads"); });
append_menu_item(helpMenu, wxID_ANY, _L("Software &Releases"), _L("Open the software releases page in your browser"),
- [](wxCommandEvent&) { wxLaunchDefaultBrowser("https://github.com/prusa3d/PrusaSlicer/releases"); });
+ [](wxCommandEvent&) { wxGetApp().open_browser_with_warning_dialog("https://github.com/prusa3d/PrusaSlicer/releases"); });
//# my $versioncheck = $self->_append_menu_item($helpMenu, "Check for &Updates...", "Check for new Slic3r versions", sub{
//# wxTheApp->check_version(1);
//# });
@@ -1067,14 +1067,14 @@ static wxMenu* generate_help_menu()
[](wxCommandEvent&) { wxGetApp().open_web_page_localized("https://www.prusa3d.com/slicerweb"); });
// append_menu_item(helpMenu, wxID_ANY, wxString::Format(_L("%s &Manual"), SLIC3R_APP_NAME),
// wxString::Format(_L("Open the %s manual in your browser"), SLIC3R_APP_NAME),
-// [this](wxCommandEvent&) { wxLaunchDefaultBrowser("http://manual.slic3r.org/"); });
+// [this](wxCommandEvent&) { wxGetApp().open_browser_with_warning_dialog("http://manual.slic3r.org/"); });
helpMenu->AppendSeparator();
append_menu_item(helpMenu, wxID_ANY, _L("System &Info"), _L("Show system information"),
[](wxCommandEvent&) { wxGetApp().system_info(); });
append_menu_item(helpMenu, wxID_ANY, _L("Show &Configuration Folder"), _L("Show user configuration folder (datadir)"),
[](wxCommandEvent&) { Slic3r::GUI::desktop_open_datadir_folder(); });
append_menu_item(helpMenu, wxID_ANY, _L("Report an I&ssue"), wxString::Format(_L("Report an issue on %s"), SLIC3R_APP_NAME),
- [](wxCommandEvent&) { wxLaunchDefaultBrowser("https://github.com/prusa3d/slic3r/issues/new"); });
+ [](wxCommandEvent&) { wxGetApp().open_browser_with_warning_dialog("https://github.com/prusa3d/slic3r/issues/new"); });
if (wxGetApp().is_editor())
append_menu_item(helpMenu, wxID_ANY, wxString::Format(_L("&About %s"), SLIC3R_APP_NAME), _L("Show about dialog"),
[](wxCommandEvent&) { Slic3r::GUI::about(); });
diff --git a/src/slic3r/GUI/NotificationManager.cpp b/src/slic3r/GUI/NotificationManager.cpp
index 4c1c404da..3278a5a6e 100644
--- a/src/slic3r/GUI/NotificationManager.cpp
+++ b/src/slic3r/GUI/NotificationManager.cpp
@@ -42,7 +42,7 @@ const NotificationManager::NotificationData NotificationManager::basic_notificat
}
},
{NotificationType::NewAppAvailable, NotificationLevel::ImportantNotification, 20, _u8L("New version is available."), _u8L("See Releases page."), [](wxEvtHandler* evnthndlr) {
- wxLaunchDefaultBrowser("https://github.com/prusa3d/PrusaSlicer/releases"); return true; }},
+ wxGetApp().open_browser_with_warning_dialog("https://github.com/prusa3d/PrusaSlicer/releases"); return true; }},
{NotificationType::EmptyColorChangeCode, NotificationLevel::RegularNotification, 10,
_u8L("You have just added a G-code for color change, but its value is empty.\n"
"To export the G-code correctly, check the \"Color Change G-code\" in \"Printer Settings > Custom G-code\"") },
diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp
index ba4577bfb..3409c531d 100644
--- a/src/slic3r/GUI/Selection.cpp
+++ b/src/slic3r/GUI/Selection.cpp
@@ -2154,11 +2154,23 @@ void Selection::ensure_not_below_bed()
}
}
- for (GLVolume* volume : *m_volumes) {
- std::pair instance = std::make_pair(volume->object_idx(), volume->instance_idx());
- InstancesToZMap::iterator it = instances_max_z.find(instance);
- if (it != instances_max_z.end() && it->second < SINKING_MIN_Z_THRESHOLD)
- volume->set_instance_offset(Z, volume->get_instance_offset(Z) + SINKING_MIN_Z_THRESHOLD - it->second);
+ if (is_any_volume()) {
+ for (unsigned int i : m_list) {
+ GLVolume& volume = *(*m_volumes)[i];
+ std::pair instance = std::make_pair(volume.object_idx(), volume.instance_idx());
+ InstancesToZMap::iterator it = instances_max_z.find(instance);
+ double z_shift = SINKING_MIN_Z_THRESHOLD - it->second;
+ if (it != instances_max_z.end() && z_shift > 0.0)
+ volume.set_volume_offset(Z, volume.get_volume_offset(Z) + z_shift);
+ }
+ }
+ else {
+ for (GLVolume* volume : *m_volumes) {
+ std::pair instance = std::make_pair(volume->object_idx(), volume->instance_idx());
+ InstancesToZMap::iterator it = instances_max_z.find(instance);
+ if (it != instances_max_z.end() && it->second < SINKING_MIN_Z_THRESHOLD)
+ volume->set_instance_offset(Z, volume->get_instance_offset(Z) + SINKING_MIN_Z_THRESHOLD - it->second);
+ }
}
}