From 03c39c7e4c68c6a6b666b4beb3effb3509546bb5 Mon Sep 17 00:00:00 2001 From: Sam Segers Date: Tue, 16 Jul 2019 23:12:07 +0200 Subject: [PATCH 1/7] Only set SLIC3R_FHS_RESOURCES when SLIC3R_FHS is set This makes it possible to run slic3r in a temporary direction with make DESTDIR="run" install --- CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 49717b68d8c..8259c13f04c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -392,8 +392,10 @@ endif() # Resources install target, configure fhs.hpp on UNIX if (WIN32) install(DIRECTORY "${SLIC3R_RESOURCES_DIR}/" DESTINATION "${CMAKE_INSTALL_PREFIX}/resources") -else () +elseif (SLIC3R_FHS) set(SLIC3R_FHS_RESOURCES "${CMAKE_INSTALL_FULL_DATAROOTDIR}/PrusaSlicer") install(DIRECTORY "${SLIC3R_RESOURCES_DIR}/" DESTINATION "${SLIC3R_FHS_RESOURCES}") +else () + install(DIRECTORY "${SLIC3R_RESOURCES_DIR}/" DESTINATION "${CMAKE_INSTALL_PREFIX}/resources") endif () configure_file(${LIBDIR}/platform/unix/fhs.hpp.in ${LIBDIR_BIN}/platform/unix/fhs.hpp) From 1e4b8f9fcdd4838e624e95adf2687929c5c0e7af Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 2 Sep 2019 10:03:07 +0200 Subject: [PATCH 2/7] Fixed side effect after changes in https://github.com/prusa3d/PrusaSlicer/commit/54cf0f22d5654cc0d1794144e466321dd33255b6 + Code cleaning --- src/slic3r/GUI/wxExtensions.cpp | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 127f7d743c0..79116dfc84b 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -786,7 +786,12 @@ wxDataViewItem ObjectDataViewModel::AddInstanceRoot(const wxDataViewItem &parent wxDataViewItem ObjectDataViewModel::AddInstanceChild(const wxDataViewItem &parent_item, size_t num) { - const std::vector print_indicator(num, true); + std::vector print_indicator(num, true); + + // if InstanceRoot item isn't created for this moment + if (!GetInstanceRootItem(parent_item).IsOk()) + // use object's printable state to first instance + print_indicator[0] = IsPrintable(parent_item); return wxDataViewItem((void*)AddInstanceChild(parent_item, print_indicator)); } @@ -799,21 +804,12 @@ wxDataViewItem ObjectDataViewModel::AddInstanceChild(const wxDataViewItem& paren ObjectDataViewModelNode* inst_root_node = (ObjectDataViewModelNode*)inst_root_item.GetID(); - const bool just_created = inst_root_node->GetChildren().Count() == 0; - // Add instance nodes ObjectDataViewModelNode *instance_node = nullptr; size_t counter = 0; while (counter < print_indicator.size()) { instance_node = new ObjectDataViewModelNode(inst_root_node, itInstance); -// // if InstanceRoot item is just created and start to adding Instances -// if (just_created && counter == 0) { -// ObjectDataViewModelNode* obj_node = (ObjectDataViewModelNode*)parent_item.GetID(); -// // use object's printable state to first instance -// instance_node->set_printable_icon(obj_node->IsPrintable()); -// } -// else instance_node->set_printable_icon(print_indicator[counter] ? piPrintable : piUnprintable); inst_root_node->Append(instance_node); From c698e9c902d88dce60fed0dbbf942df2aa082eab Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 2 Sep 2019 10:53:07 +0200 Subject: [PATCH 3/7] Fix of #2850 --- src/slic3r/GUI/PresetBundle.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/PresetBundle.cpp b/src/slic3r/GUI/PresetBundle.cpp index af1298bfb94..29f12a4d271 100644 --- a/src/slic3r/GUI/PresetBundle.cpp +++ b/src/slic3r/GUI/PresetBundle.cpp @@ -1532,7 +1532,9 @@ void PresetBundle::update_platter_filament_ui(unsigned int idx_extruder, GUI::Pr } // Paint a lock at the system presets. bmps.emplace_back(m_bitmapCache->mkclear(space_icon_width, icon_height)); - bmps.emplace_back((preset.is_system || preset.is_default) ? *m_bitmapLock : m_bitmapCache->mkclear(normal_icon_width, icon_height)); + // To avoid asserts, each added bitmap to wxBitmapCombobox should be the same size, so + // for nonsystem presets set a width of empty bitmap to m_bitmapLock->GetWidth() + bmps.emplace_back((preset.is_system || preset.is_default) ? *m_bitmapLock : m_bitmapCache->mkclear(m_bitmapLock->GetWidth(), icon_height)); // (preset.is_dirty ? *m_bitmapLockOpen : *m_bitmapLock) : m_bitmapCache->mkclear(16, 16)); bitmap = m_bitmapCache->insert(bitmap_key, bmps); } From dce4a179d05aa808b61c1d0d3807bc782a411412 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Mon, 2 Sep 2019 11:47:11 +0200 Subject: [PATCH 4/7] Fix of "Extra overhanging perimeters are added in 2.1.0-beta3" #2857 Two bugs were fixed: 1) An entry in the GLVolume index was not always created when it should have been. 2) Removing empty volumes from the list of GLVolumes did not update the GLVolume index. This is an old issue, but it likely surfaced now with the introduction of splitting the large GLVolumes into multiple shorter ones. --- src/slic3r/GUI/GLCanvas3D.cpp | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 7bfae30849c..71bacd81540 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2152,9 +2152,36 @@ void GLCanvas3D::load_gcode_preview(const GCodePreviewData& preview_data, const if (!m_volumes.empty()) { - // removes empty volumes - m_volumes.volumes.erase(std::remove_if(m_volumes.volumes.begin(), m_volumes.volumes.end(), - [](const GLVolume* volume) { return volume->print_zs.empty(); }), m_volumes.volumes.end()); + // Remove empty volumes from both m_volumes, update m_gcode_preview_volume_index. + { + size_t idx_volume_src = 0; + size_t idx_volume_dst = 0; + size_t idx_volume_index_src = 0; + size_t idx_volume_index_dst = 0; + size_t idx_volume_of_this_type_last = (idx_volume_index_src + 1 == m_gcode_preview_volume_index.first_volumes.size()) ? m_volumes.volumes.size() : m_gcode_preview_volume_index.first_volumes[idx_volume_index_src + 1].id; + size_t idx_volume_of_this_type_first_new = 0; + for (;;) { + if (idx_volume_src == idx_volume_of_this_type_last) { + if (idx_volume_of_this_type_first_new < idx_volume_dst) { + // There are some volumes of this type left, therefore their entry in the index has to be maintained. + if (idx_volume_index_dst < idx_volume_index_src) + m_gcode_preview_volume_index.first_volumes[idx_volume_index_dst] = m_gcode_preview_volume_index.first_volumes[idx_volume_index_src]; + m_gcode_preview_volume_index.first_volumes[idx_volume_index_dst].id = idx_volume_of_this_type_first_new; + ++ idx_volume_index_dst; + } + if (idx_volume_of_this_type_last == m_volumes.volumes.size()) + break; + ++ idx_volume_index_src; + idx_volume_of_this_type_last = (idx_volume_index_src + 1 == m_gcode_preview_volume_index.first_volumes.size()) ? m_volumes.volumes.size() : m_gcode_preview_volume_index.first_volumes[idx_volume_index_src + 1].id; + idx_volume_of_this_type_first_new = idx_volume_dst; + } + if (! m_volumes.volumes[idx_volume_src]->print_zs.empty()) + m_volumes.volumes[idx_volume_dst ++] = m_volumes.volumes[idx_volume_src]; + ++ idx_volume_src; + } + m_volumes.volumes.erase(m_volumes.volumes.begin() + idx_volume_dst, m_volumes.volumes.end()); + m_gcode_preview_volume_index.first_volumes.erase(m_gcode_preview_volume_index.first_volumes.begin() + idx_volume_index_dst, m_gcode_preview_volume_index.first_volumes.end()); + } _load_fff_shells(); } @@ -5097,7 +5124,7 @@ void GLCanvas3D::_load_gcode_extrusion_paths(const GCodePreviewData& preview_dat unsigned int role = (unsigned int)(&filters - &roles_filters.front()); for (std::pair &filter : filters) if (filter.second->indexed_vertex_array.vertices_and_normals_interleaved.size() > MAX_VERTEX_BUFFER_SIZE) { - if (m_gcode_preview_volume_index.first_volumes.back().id != role) + if (m_gcode_preview_volume_index.first_volumes.back().type != GCodePreviewVolumeIndex::Extrusion || m_gcode_preview_volume_index.first_volumes.back().flag != role) m_gcode_preview_volume_index.first_volumes.emplace_back(GCodePreviewVolumeIndex::Extrusion, role, (unsigned int)m_volumes.volumes.size()); GLVolume& vol = *filter.second; filter.second = m_volumes.new_toolpath_volume(vol.color); From 5d85e485008f2f63614209e2aba914281f5ca3dd Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 2 Sep 2019 11:55:14 +0200 Subject: [PATCH 5/7] 2nd attempt to fix non compatible (newer) .3mf and .amf import error handling on Linux and OsX --- src/libslic3r/Format/3mf.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/libslic3r/Format/3mf.cpp b/src/libslic3r/Format/3mf.cpp index d4f72ffb32c..f3561d60bd2 100644 --- a/src/libslic3r/Format/3mf.cpp +++ b/src/libslic3r/Format/3mf.cpp @@ -9,6 +9,7 @@ #include "3mf.hpp" #include +#include #include #include @@ -102,6 +103,13 @@ const char* INVALID_OBJECT_TYPES[] = "other" }; +class version_error : public std::runtime_error +{ +public: + version_error(const std::string& what_arg) : std::runtime_error(what_arg) {} + version_error(const char* what_arg) : std::runtime_error(what_arg) {} +}; + const char* get_attribute_value_charptr(const char** attributes, unsigned int attributes_size, const char* attribute_key) { if ((attributes == nullptr) || (attributes_size == 0) || (attributes_size % 2 != 0) || (attribute_key == nullptr)) @@ -731,6 +739,11 @@ namespace Slic3r { return n; }, &data, 0); } + catch (const version_error& e) + { + // rethrow the exception + throw std::runtime_error(e.what()); + } catch (std::exception& e) { add_error(e.what()); @@ -1440,7 +1453,7 @@ namespace Slic3r { if (m_check_version && (m_version > VERSION_3MF)) { std::string msg = _(L("The selected 3mf file has been saved with a newer version of " + std::string(SLIC3R_APP_NAME) + " and is not compatibile.")); - throw std::runtime_error(msg.c_str()); + throw version_error(msg.c_str()); } } From 074d7dfaa99d2221813f9b66897776954c971882 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 2 Sep 2019 13:02:28 +0200 Subject: [PATCH 6/7] Fixed typo --- src/libslic3r/Format/3mf.cpp | 2 +- src/libslic3r/Format/AMF.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libslic3r/Format/3mf.cpp b/src/libslic3r/Format/3mf.cpp index f3561d60bd2..0f89e61930c 100644 --- a/src/libslic3r/Format/3mf.cpp +++ b/src/libslic3r/Format/3mf.cpp @@ -1452,7 +1452,7 @@ namespace Slic3r { if (m_check_version && (m_version > VERSION_3MF)) { - std::string msg = _(L("The selected 3mf file has been saved with a newer version of " + std::string(SLIC3R_APP_NAME) + " and is not compatibile.")); + std::string msg = _(L("The selected 3mf file has been saved with a newer version of " + std::string(SLIC3R_APP_NAME) + " and is not compatible.")); throw version_error(msg.c_str()); } } diff --git a/src/libslic3r/Format/AMF.cpp b/src/libslic3r/Format/AMF.cpp index f43724cb645..92c958d8ab3 100644 --- a/src/libslic3r/Format/AMF.cpp +++ b/src/libslic3r/Format/AMF.cpp @@ -827,7 +827,7 @@ bool extract_model_from_archive(mz_zip_archive& archive, const mz_zip_archive_fi if (check_version && (ctx.m_version > VERSION_AMF)) { - std::string msg = _(L("The selected amf file has been saved with a newer version of " + std::string(SLIC3R_APP_NAME) + " and is not compatibile.")); + std::string msg = _(L("The selected amf file has been saved with a newer version of " + std::string(SLIC3R_APP_NAME) + " and is not compatible.")); throw std::runtime_error(msg.c_str()); } From 2ca84416bd0221926e11097410d10882d0f3886e Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 2 Sep 2019 14:02:26 +0200 Subject: [PATCH 7/7] Fix for #2845 + Fixed get_config_value for coFloatOrPercent (percent mode allow non-just-int values) --- src/slic3r/GUI/Field.cpp | 19 ++++++++++--------- src/slic3r/GUI/Field.hpp | 2 +- src/slic3r/GUI/OptionsGroup.cpp | 8 +++----- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index bb2dd34d933..454b4874fcd 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -138,7 +138,7 @@ bool Field::is_matched(const std::string& string, const std::string& pattern) static wxString na_value() { return _(L("N/A")); } -void Field::get_value_by_opt_type(wxString& str) +void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true*/) { switch (m_opt.type) { case coInt: @@ -150,7 +150,7 @@ void Field::get_value_by_opt_type(wxString& str) case coFloat:{ if (m_opt.type == coPercent && !str.IsEmpty() && str.Last() == '%') str.RemoveLast(); - else if (!str.IsEmpty() && str.Last() == '%') { + else if (check_value && !str.IsEmpty() && str.Last() == '%') { wxString label = m_Label->GetLabel(); if (label.Last() == '\n') label.RemoveLast(); while (label.Last() == ' ') label.RemoveLast(); @@ -169,12 +169,12 @@ void Field::get_value_by_opt_type(wxString& str) { if (m_opt.nullable && str == na_value()) val = ConfigOptionFloatsNullable::nil_value(); - else if (!str.ToCDouble(&val)) + else if (check_value && !str.ToCDouble(&val)) { show_error(m_parent, _(L("Invalid numeric input."))); set_value(double_to_string(val), true); } - if (m_opt.min > val || val > m_opt.max) + if (check_value && (m_opt.min > val || val > m_opt.max)) { show_error(m_parent, _(L("Input value is out of range"))); if (m_opt.min > val) val = m_opt.min; @@ -192,12 +192,12 @@ void Field::get_value_by_opt_type(wxString& str) double val; // Replace the first occurence of comma in decimal number. str.Replace(",", ".", false); - if (!str.ToCDouble(&val)) + if (check_value && !str.ToCDouble(&val)) { show_error(m_parent, _(L("Invalid numeric input."))); set_value(double_to_string(val), true); } - else if ((m_opt.sidetext.rfind("mm/s") != std::string::npos && val > m_opt.max || + else if (check_value && (m_opt.sidetext.rfind("mm/s") != std::string::npos && val > m_opt.max || m_opt.sidetext.rfind("mm ") != std::string::npos && val > 1) && (m_value.empty() || std::string(str.ToUTF8().data()) != boost::any_cast(m_value))) { @@ -206,7 +206,7 @@ void Field::get_value_by_opt_type(wxString& str) const wxString msg_text = wxString::Format(_(L("Do you mean %s%% instead of %s %s?\n" "Select YES if you want to change this value to %s%%, \n" "or NO if you are sure that %s %s is a correct value.")), stVal, stVal, sidetext, stVal, stVal, sidetext); - wxMessageDialog dialog(m_parent, msg_text, _(L("Parameter validation")), wxICON_WARNING | wxYES | wxNO); + wxMessageDialog dialog(m_parent, msg_text, _(L("Parameter validation")) + ": " + m_opt_id , wxICON_WARNING | wxYES | wxNO); if (dialog.ShowModal() == wxID_YES) { set_value(wxString::Format("%s%%", stVal), false/*true*/); str += "%%"; @@ -396,8 +396,9 @@ void TextCtrl::set_value(const boost::any& value, bool change_event/* = false*/) if (!change_event) { wxString ret_str = static_cast(window)->GetValue(); - // update m_value to correct work of next value_was_changed() - get_value_by_opt_type(ret_str); + // update m_value to correct work of next value_was_changed(), + // but don't check/change inputed value and don't show a warning message + get_value_by_opt_type(ret_str, false); } } diff --git a/src/slic3r/GUI/Field.hpp b/src/slic3r/GUI/Field.hpp index 11775a67c75..b3cbf573f6c 100644 --- a/src/slic3r/GUI/Field.hpp +++ b/src/slic3r/GUI/Field.hpp @@ -152,7 +152,7 @@ public: virtual wxWindow* getWindow() { return nullptr; } bool is_matched(const std::string& string, const std::string& pattern); - void get_value_by_opt_type(wxString& str); + void get_value_by_opt_type(wxString& str, const bool check_value = true); /// Factory method for generating new derived classes. template diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp index f4013840898..c17569c1112 100644 --- a/src/slic3r/GUI/OptionsGroup.cpp +++ b/src/slic3r/GUI/OptionsGroup.cpp @@ -589,13 +589,11 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config switch (opt->type) { case coFloatOrPercent:{ const auto &value = *config.option(opt_key); + + text_value = double_to_string(value.value); if (value.percent) - { - text_value = wxString::Format(_T("%i"), int(value.value)); text_value += "%"; - } - else - text_value = double_to_string(value.value); + ret = text_value; break; }