From b5ff4bbb5213b7d87840715d8979ac51ddb74cbc 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 49717b68d..8259c13f0 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 82f89229a99225decc86c2a218920ac8bc1cf5bc 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 127f7d743..79116dfc8 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 107bb1a308bb106332705c5701933aceaf75b947 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 af1298bfb..29f12a4d2 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 206dbb81c7b54a32bf2a06c3812c070072b33e85 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 7bfae3084..71bacd815 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 0b03f0eb66aa4721772fff1a68e3d3ce62f4eb0e 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 d4f72ffb3..f3561d60b 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 729bd529dc9f09fed9a45d261b93a692f7cf5554 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 f3561d60b..0f89e6193 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 f43724cb6..92c958d8a 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 94712544aa65110b7305c78fe517c49fdfc910ce 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 bb2dd34d9..454b4874f 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 11775a67c..b3cbf573f 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 f40138408..c17569c11 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; }