From 11da45e32fb623a8a2717964f091f998c13b692e Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 20 Dec 2018 11:42:26 +0100 Subject: [PATCH 01/14] Visual hints in the 3D scene when sidebar matrix fields have focus -> legacy render case --- src/slic3r/GUI/3DScene.cpp | 22 ++++++++++++++++++++-- src/slic3r/GUI/3DScene.hpp | 1 + 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index b431cf8bc..961d4822a 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -1920,8 +1920,7 @@ void GLModel::render() const if (m_useVBOs) render_VBOs(); else - { - } + render_legacy(); } void GLModel::render_VBOs() const @@ -1949,6 +1948,25 @@ void GLModel::render_VBOs() const ::glDisable(GL_BLEND); } +void GLModel::render_legacy() const +{ + ::glEnable(GL_LIGHTING); + ::glEnable(GL_BLEND); + ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + ::glCullFace(GL_BACK); + ::glEnableClientState(GL_VERTEX_ARRAY); + ::glEnableClientState(GL_NORMAL_ARRAY); + + m_volume.render_legacy(); + + ::glDisableClientState(GL_VERTEX_ARRAY); + ::glDisableClientState(GL_NORMAL_ARRAY); + + ::glDisable(GL_BLEND); + ::glDisable(GL_LIGHTING); +} + bool GLArrow::on_init(bool useVBOs) { Pointf3s vertices; diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index 09bb54e2f..76cacabbd 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -611,6 +611,7 @@ protected: private: void render_VBOs() const; + void render_legacy() const; }; class GLArrow : public GLModel From a5b846f7fc3569854fd977b55dc4aeca5929f116 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Thu, 20 Dec 2018 12:08:06 +0100 Subject: [PATCH 02/14] Improved edge normal detection. Also removed some warnings. --- .../include/libnest2d/placers/nfpplacer.hpp | 4 +- src/libslic3r/ModelArrange.cpp | 14 ++----- src/libslic3r/SLA/SLASupportTreeIGL.cpp | 39 +++++++++++++------ 3 files changed, 34 insertions(+), 23 deletions(-) diff --git a/src/libnest2d/include/libnest2d/placers/nfpplacer.hpp b/src/libnest2d/include/libnest2d/placers/nfpplacer.hpp index 14ed3d22c..28659c512 100644 --- a/src/libnest2d/include/libnest2d/placers/nfpplacer.hpp +++ b/src/libnest2d/include/libnest2d/placers/nfpplacer.hpp @@ -545,8 +545,8 @@ public: _NofitPolyPlacer& operator=(const _NofitPolyPlacer&) = default; #ifndef BP2D_COMPILER_MSVC12 // MSVC2013 does not support default move ctors - _NofitPolyPlacer(_NofitPolyPlacer&&) BP2D_NOEXCEPT = default; - _NofitPolyPlacer& operator=(_NofitPolyPlacer&&) BP2D_NOEXCEPT = default; + _NofitPolyPlacer(_NofitPolyPlacer&&) /*BP2D_NOEXCEPT*/ = default; + _NofitPolyPlacer& operator=(_NofitPolyPlacer&&) /*BP2D_NOEXCEPT*/ = default; #endif static inline double overfit(const Box& bb, const RawShape& bin) { diff --git a/src/libslic3r/ModelArrange.cpp b/src/libslic3r/ModelArrange.cpp index d182f1501..562527290 100644 --- a/src/libslic3r/ModelArrange.cpp +++ b/src/libslic3r/ModelArrange.cpp @@ -135,11 +135,6 @@ objfunc(const PointImpl& bincenter, const ItemGroup& remaining ) { - using Coord = TCoord; - - static const double ROUNDNESS_RATIO = 0.5; - static const double DENSITY_RATIO = 1.0 - ROUNDNESS_RATIO; - // We will treat big items (compared to the print bed) differently auto isBig = [bin_area](double a) { return a/bin_area > BIG_ITEM_TRESHOLD ; @@ -629,11 +624,12 @@ BedShapeHint bedShape(const Polyline &bed) { avg_dist /= vertex_distances.size(); Circle ret(center, avg_dist); - for (auto el: vertex_distances) + for(auto el : vertex_distances) { - if (abs(el - avg_dist) > 10 * SCALED_EPSILON) + if (std::abs(el - avg_dist) > 10 * SCALED_EPSILON) { ret = Circle(); - break; + break; + } } return ret; @@ -665,8 +661,6 @@ bool arrange(Model &model, std::function progressind, std::function stopcondition) { - using ArrangeResult = _IndexedPackGroup; - bool ret = true; // Get the 2D projected shapes with their 3D model instance pointers diff --git a/src/libslic3r/SLA/SLASupportTreeIGL.cpp b/src/libslic3r/SLA/SLASupportTreeIGL.cpp index 5d40bb514..49290b3b8 100644 --- a/src/libslic3r/SLA/SLASupportTreeIGL.cpp +++ b/src/libslic3r/SLA/SLASupportTreeIGL.cpp @@ -107,7 +107,8 @@ PointSet normals(const PointSet& points, const EigenMesh3D& emesh, // structure EigenMesh3D mesh; Eigen::VectorXi SVI, SVJ; - igl::remove_duplicate_vertices(emesh.V, emesh.F, 1e-6, + static const double dEPS = 1e-6; + igl::remove_duplicate_vertices(emesh.V, emesh.F, dEPS, mesh.V, SVI, SVJ, mesh.F); igl::point_mesh_squared_distance( points, mesh.V, mesh.F, dists, I, C); @@ -155,6 +156,7 @@ PointSet normals(const PointSet& points, const EigenMesh3D& emesh, ia = trindex(0); ib = trindex(2); } + // vector for the neigboring triangles including the detected one. std::vector neigh; if(ic >= 0) { // The point is right on a vertex of the triangle for(int n = 0; n < mesh.F.rows(); ++n) { @@ -175,17 +177,32 @@ PointSet normals(const PointSet& points, const EigenMesh3D& emesh, } } - if(!neigh.empty()) { // there were neighbors to count with + // Calculate the normals for the neighboring triangles + std::vector neighnorms; neighnorms.reserve(neigh.size()); + for(const Vec3i& tri : neigh) { + const Vec3d& pt1 = mesh.V.row(tri(0)); + const Vec3d& pt2 = mesh.V.row(tri(1)); + const Vec3d& pt3 = mesh.V.row(tri(2)); + Eigen::Vector3d U = pt2 - pt1; + Eigen::Vector3d V = pt3 - pt1; + neighnorms.emplace_back(U.cross(V).normalized()); + } + + // Throw out duplicates. They would case trouble with summing. + auto lend = std::unique(neighnorms.begin(), neighnorms.end(), + [](const Vec3d& n1, const Vec3d& n2) { + // Compare normals for equivalence. This is controvers stuff. + // We will go for the third significant digit precision. + auto deq = [](double a, double b) { return std::abs(a-b) < 1e-3; }; + return deq(n1(X), n2(X)) && deq(n1(Y), n2(Y)) && deq(n1(Z), n2(Z)); + }); + + if(!neighnorms.empty()) { // there were neighbors to count with + // sum up the normals and than normalize the result again. + // This unification seems to be enough. Vec3d sumnorm(0, 0, 0); - for(const Vec3i& tri : neigh) { - const Vec3d& pt1 = mesh.V.row(tri(0)); - const Vec3d& pt2 = mesh.V.row(tri(1)); - const Vec3d& pt3 = mesh.V.row(tri(2)); - Eigen::Vector3d U = pt2 - pt1; - Eigen::Vector3d V = pt3 - pt1; - sumnorm += U.cross(V).normalized(); - } - sumnorm /= neigh.size(); + sumnorm = std::accumulate(neighnorms.begin(), lend, sumnorm); + sumnorm.normalize(); ret.row(i) = sumnorm; } else { // point lies safely within its triangle From 780e3c700e9f5e1d9beb7b16b0a62067bf4e7d31 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 20 Dec 2018 12:51:42 +0100 Subject: [PATCH 03/14] Attempt to reduce ugly artifacts when switching to preview for the 1st time --- src/slic3r/GUI/Plater.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index cba53cf17..6a8bcc79b 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1162,9 +1162,9 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) hsizer->Add(sidebar, 0, wxEXPAND | wxLEFT | wxRIGHT, 0); q->SetSizer(hsizer); -#if ENABLE_REMOVE_TABS_FROM_PLATER - set_current_panel(view3D); -#endif // ENABLE_REMOVE_TABS_FROM_PLATER +//#if ENABLE_REMOVE_TABS_FROM_PLATER +// set_current_panel(view3D); +//#endif // ENABLE_REMOVE_TABS_FROM_PLATER init_object_menu(); @@ -1251,6 +1251,10 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) update_ui_from_settings(); q->Layout(); + +#if ENABLE_REMOVE_TABS_FROM_PLATER + set_current_panel(view3D); +#endif // ENABLE_REMOVE_TABS_FROM_PLATER } void Plater::priv::update(bool force_full_scene_refresh) From 3fbc4afc9593108bc1486dfb76ce7887ce141e65 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 20 Dec 2018 12:52:16 +0100 Subject: [PATCH 04/14] Upgraded "Keyboard shortcuts" dialog --- src/slic3r/GUI/KBShortcutsDialog.cpp | 100 +++++++++++++++------------ src/slic3r/GUI/SysInfoDialog.cpp | 2 +- 2 files changed, 58 insertions(+), 44 deletions(-) diff --git a/src/slic3r/GUI/KBShortcutsDialog.cpp b/src/slic3r/GUI/KBShortcutsDialog.cpp index b3edbc9a8..12929b2cc 100644 --- a/src/slic3r/GUI/KBShortcutsDialog.cpp +++ b/src/slic3r/GUI/KBShortcutsDialog.cpp @@ -3,6 +3,7 @@ #include "libslic3r/Utils.hpp" #include "GUI.hpp" #include +#include "GUI_App.hpp" namespace Slic3r { namespace GUI { @@ -19,41 +20,46 @@ KBShortcutsDialog::KBShortcutsDialog() // fonts wxFont head_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Bold(); - head_font.SetPointSize(19); - - wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); - font.SetPointSize(10); - wxFont bold_font = font.Bold(); #ifdef __WXOSX__ - font.SetPointSize(12); - bold_font.SetPointSize(14); -#endif /*__WXOSX__*/ + head_font.SetPointSize(14); +#else + head_font.SetPointSize(12); +#endif // __WXOSX__ + + const wxFont& font = wxGetApp().small_font(); + const wxFont& bold_font = wxGetApp().bold_font(); fill_shortcuts(); - auto panel = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxSize(500, 600)); - panel->SetScrollbars(0, 20, 1, 2); - auto sizer = new wxBoxSizer(wxVERTICAL); - panel->SetSizer(sizer); + auto panel = new wxPanel(this); + auto main_grid_sizer = new wxFlexGridSizer(2, 10, 10); + panel->SetSizer(main_grid_sizer); main_sizer->Add(panel, 1, wxEXPAND | wxALL, 0); + wxBoxSizer* l_sizer = new wxBoxSizer(wxVERTICAL); + main_grid_sizer->Add(l_sizer, 0); + + wxBoxSizer* r_sizer = new wxBoxSizer(wxVERTICAL); + main_grid_sizer->Add(r_sizer, 0); + for (auto& sc : m_full_shortcuts) { + auto sizer = sc.first == _(L("Main Shortcuts")) ? l_sizer : r_sizer; wxBoxSizer* hsizer = new wxBoxSizer(wxHORIZONTAL); - sizer->Add(hsizer, 0, wxEXPAND | wxTOP, 25); + sizer->Add(hsizer, 0, wxEXPAND | wxTOP | wxBOTTOM, 10); // logo auto *logo = new wxStaticBitmap(panel, wxID_ANY, logo_bmp); hsizer->Add(logo, 0, wxEXPAND | wxLEFT | wxRIGHT, 15); // head - wxStaticText* head = new wxStaticText(panel, wxID_ANY, sc.first, wxDefaultPosition, wxSize(400,-1)); + wxStaticText* head = new wxStaticText(panel, wxID_ANY, sc.first, wxDefaultPosition, wxSize(200,-1)); head->SetFont(head_font); hsizer->Add(head, 0, wxALIGN_CENTER_VERTICAL); // Shortcuts list - auto grid_sizer = new wxFlexGridSizer(2, 10, 25); - sizer->Add(grid_sizer, 0, wxEXPAND | wxLEFT | wxTOP, 10); + auto grid_sizer = new wxFlexGridSizer(2, 5, 15); + sizer->Add(grid_sizer, 0, wxEXPAND | wxLEFT| wxRIGHT, 15); for (auto pair : sc.second) { @@ -69,9 +75,9 @@ KBShortcutsDialog::KBShortcutsDialog() wxStdDialogButtonSizer* buttons = this->CreateStdDialogButtonSizer(wxOK); - this->SetEscapeId(wxID_CLOSE); + this->SetEscapeId(wxID_OK); this->Bind(wxEVT_BUTTON, &KBShortcutsDialog::onCloseDialog, this, wxID_OK); - main_sizer->Add(buttons, 0, wxEXPAND | wxALL, 15); + main_sizer->Add(buttons, 0, wxEXPAND | wxRIGHT | wxBOTTOM, 15); this->Bind(wxEVT_LEFT_DOWN, &KBShortcutsDialog::onCloseDialog, this); @@ -81,32 +87,40 @@ KBShortcutsDialog::KBShortcutsDialog() void KBShortcutsDialog::fill_shortcuts() { +#ifdef __WXOSX__ + const std::string ctrl = "Cmd+"; // #ys_FIXME_cmd_smb // Change it for the accorded symbol + const std::string alt = "Alt+"; // #ys_FIXME_cmd_smb // Change it for the accorded symbol +#else + const std::string ctrl = "Ctrl+"; + const std::string alt = "Alt+"; +#endif // __WXOSX__ + Shortcuts main_shortcuts; main_shortcuts.reserve(25); - main_shortcuts.push_back(Shortcut("Ctrl+O", L("Open project STL/OBJ/AMF/3MF with config, delete bed"))); - main_shortcuts.push_back(Shortcut("Ctrl+I", L("Import STL//OBJ/AMF/3MF without config, keep bed"))); - main_shortcuts.push_back(Shortcut("Ctrl+L", L("Load Config from .ini/amf/3mf/gcode"))); - main_shortcuts.push_back(Shortcut("Ctrl+Alt+L", L("Load Config from .ini/amf/3mf/gcode and merge"))); - main_shortcuts.push_back(Shortcut("Ctrl+G", L("Export Gcode"))); - main_shortcuts.push_back(Shortcut("Ctrl+S", L("Save project (3MF)"))); - main_shortcuts.push_back(Shortcut("Ctrl+R", L("(Re)slice"))); - main_shortcuts.push_back(Shortcut("Ctrl+U", L("Quick slice"))); - main_shortcuts.push_back(Shortcut("Ctrl+Alt+U", L("Quick slice and Save as"))); - main_shortcuts.push_back(Shortcut("Ctrl+Shift+U", L("Repeat last quick slice"))); - main_shortcuts.push_back(Shortcut("Ctrl+1", L("Select Plater Tab"))); - main_shortcuts.push_back(Shortcut("Ctrl+2", L("Select Print Settings Tab"))); - main_shortcuts.push_back(Shortcut("Ctrl+3", L("Select Filament Setting Tab"))); - main_shortcuts.push_back(Shortcut("Ctrl+4", L("Select Printer Setting Tab"))); - main_shortcuts.push_back(Shortcut("Ctrl+5", L("Switch to 3D"))); - main_shortcuts.push_back(Shortcut("Ctrl+6", L("Switch to Preview"))); - main_shortcuts.push_back(Shortcut("Ctrl+P", L("Preferences"))); - main_shortcuts.push_back(Shortcut("0-6", L("Camera view "))); - main_shortcuts.push_back(Shortcut("+", L("Add Instance to selected object "))); - main_shortcuts.push_back(Shortcut("-", L("Remove Instance from selected object"))); - main_shortcuts.push_back(Shortcut("?", L("Show keyboard shortcuts list"))); - main_shortcuts.push_back(Shortcut("PgUp/PgDn", L("Switch between 3D and Preview"))); - main_shortcuts.push_back(Shortcut("Shift+LeftMouse",L("Select multiple object/Move multiple object"))); + main_shortcuts.push_back(Shortcut(ctrl+"O" ,L("Open project STL/OBJ/AMF/3MF with config, delete bed"))); + main_shortcuts.push_back(Shortcut(ctrl+"I" ,L("Import STL//OBJ/AMF/3MF without config, keep bed"))); + main_shortcuts.push_back(Shortcut(ctrl+"L" ,L("Load Config from .ini/amf/3mf/gcode"))); + main_shortcuts.push_back(Shortcut(ctrl+"G" ,L("Export Gcode"))); + main_shortcuts.push_back(Shortcut(ctrl+"S" ,L("Save project (3MF)"))); + main_shortcuts.push_back(Shortcut(ctrl+alt+"L" ,L("Load Config from .ini/amf/3mf/gcode and merge"))); + main_shortcuts.push_back(Shortcut(ctrl+"R" ,L("(Re)slice"))); + main_shortcuts.push_back(Shortcut(ctrl+"U" ,L("Quick slice"))); + main_shortcuts.push_back(Shortcut(ctrl+"Shift+U" ,L("Repeat last quick slice"))); + main_shortcuts.push_back(Shortcut(ctrl+"1" ,L("Select Plater Tab"))); + main_shortcuts.push_back(Shortcut(ctrl+alt+"U" ,L("Quick slice and Save as"))); + main_shortcuts.push_back(Shortcut(ctrl+"2" ,L("Select Print Settings Tab"))); + main_shortcuts.push_back(Shortcut(ctrl+"3" ,L("Select Filament Setting Tab"))); + main_shortcuts.push_back(Shortcut(ctrl+"4" ,L("Select Printer Setting Tab"))); + main_shortcuts.push_back(Shortcut(ctrl+"5" ,L("Switch to 3D"))); + main_shortcuts.push_back(Shortcut(ctrl+"6" ,L("Switch to Preview"))); + main_shortcuts.push_back(Shortcut(ctrl+"P" ,L("Preferences"))); + main_shortcuts.push_back(Shortcut("0-6" ,L("Camera view "))); + main_shortcuts.push_back(Shortcut("+" ,L("Add Instance to selected object "))); + main_shortcuts.push_back(Shortcut("-" ,L("Remove Instance from selected object"))); + main_shortcuts.push_back(Shortcut("?" ,L("Show keyboard shortcuts list"))); + main_shortcuts.push_back(Shortcut("PgUp/PgDn" ,L("Switch between 3D and Preview"))); + main_shortcuts.push_back(Shortcut("Shift+LeftMouse" ,L("Select multiple object/Move multiple object"))); m_full_shortcuts.emplace(_(L("Main Shortcuts")), main_shortcuts); @@ -115,9 +129,9 @@ void KBShortcutsDialog::fill_shortcuts() plater_shortcuts.reserve(20); plater_shortcuts.push_back(Shortcut("A", L("Arrange"))); - plater_shortcuts.push_back(Shortcut("Ctrl+A", L("Select All objects"))); + plater_shortcuts.push_back(Shortcut(ctrl+"A", L("Select All objects"))); plater_shortcuts.push_back(Shortcut("Del", L("Delete selected"))); - plater_shortcuts.push_back(Shortcut("Ctrl+Del", L("Delete all"))); + plater_shortcuts.push_back(Shortcut(ctrl+"Del", L("Delete all"))); plater_shortcuts.push_back(Shortcut("M", L("Gizmo move"))); plater_shortcuts.push_back(Shortcut("S", L("Gizmo scale"))); plater_shortcuts.push_back(Shortcut("R", L("Gizmo rotate"))); diff --git a/src/slic3r/GUI/SysInfoDialog.cpp b/src/slic3r/GUI/SysInfoDialog.cpp index f7f1cfedb..110bfaf44 100644 --- a/src/slic3r/GUI/SysInfoDialog.cpp +++ b/src/slic3r/GUI/SysInfoDialog.cpp @@ -116,7 +116,7 @@ SysInfoDialog::SysInfoDialog() buttons->Insert(0, btn_copy_to_clipboard, 0, wxLEFT, 5); btn_copy_to_clipboard->Bind(wxEVT_BUTTON, &SysInfoDialog::onCopyToClipboard, this); - this->SetEscapeId(wxID_CLOSE); + this->SetEscapeId(wxID_OK); this->Bind(wxEVT_BUTTON, &SysInfoDialog::onCloseDialog, this, wxID_OK); main_sizer->Add(buttons, 0, wxEXPAND | wxRIGHT | wxBOTTOM, 3); From 68684dd0037a76d1f74e7368159bfc2a43ae6d9d Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 20 Dec 2018 13:20:21 +0100 Subject: [PATCH 05/14] Removed obsolete GLCanvas3D::m_shader_enabled --- src/slic3r/GUI/GLCanvas3D.cpp | 10 +--------- src/slic3r/GUI/GLCanvas3D.hpp | 2 -- src/slic3r/GUI/GUI_Preview.cpp | 2 -- src/slic3r/GUI/Plater.cpp | 1 - 4 files changed, 1 insertion(+), 14 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 77d0f0776..66d4622fe 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3830,7 +3830,6 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas) , m_legend_texture_enabled(false) , m_picking_enabled(false) , m_moving_enabled(false) - , m_shader_enabled(false) , m_dynamic_background_enabled(false) , m_multisample_allowed(false) , m_regenerate_volumes(true) @@ -4144,11 +4143,6 @@ void GLCanvas3D::enable_toolbar(bool enable) m_toolbar.set_enabled(enable); } -void GLCanvas3D::enable_shader(bool enable) -{ - m_shader_enabled = enable; -} - void GLCanvas3D::enable_force_zoom_to_bed(bool enable) { m_force_zoom_to_bed_enabled = enable; @@ -6322,9 +6316,7 @@ void GLCanvas3D::_render_objects() const ::glEnable(GL_LIGHTING); ::glEnable(GL_DEPTH_TEST); - if (!m_shader_enabled) - _render_volumes(false); - else if (m_use_VBOs) + if (m_use_VBOs) { if (m_picking_enabled) { diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 8e9d44a4b..0cd6cb9b9 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -850,7 +850,6 @@ private: bool m_legend_texture_enabled; bool m_picking_enabled; bool m_moving_enabled; - bool m_shader_enabled; bool m_dynamic_background_enabled; bool m_multisample_allowed; bool m_regenerate_volumes; @@ -950,7 +949,6 @@ public: void enable_moving(bool enable); void enable_gizmos(bool enable); void enable_toolbar(bool enable); - void enable_shader(bool enable); void enable_force_zoom_to_bed(bool enable); void enable_dynamic_background(bool enable); void allow_multisample(bool allow); diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 988a7b6a1..459bd9e5b 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -70,7 +70,6 @@ bool View3D::init(wxWindow* parent, Model* model, DynamicPrintConfig* config, Ba m_canvas->set_config(config); m_canvas->enable_gizmos(true); m_canvas->enable_toolbar(true); - m_canvas->enable_shader(true); m_canvas->enable_force_zoom_to_bed(true); #if !ENABLE_IMGUI @@ -257,7 +256,6 @@ bool Preview::init(wxNotebook* notebook, DynamicPrintConfig* config, BackgroundS _3DScene::add_canvas(m_canvas_widget); m_canvas = _3DScene::get_canvas(this->m_canvas_widget); m_canvas->allow_multisample(GLCanvas3DManager::can_multisample()); - m_canvas->enable_shader(true); m_canvas->set_config(m_config); m_canvas->set_process(process); m_canvas->enable_legend_texture(true); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 6a8bcc79b..db19180b4 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1132,7 +1132,6 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) this->canvas3D->set_config(config); this->canvas3D->enable_gizmos(true); this->canvas3D->enable_toolbar(true); - this->canvas3D->enable_shader(true); this->canvas3D->enable_force_zoom_to_bed(true); #endif // ENABLE_REMOVE_TABS_FROM_PLATER From afc5ed0c624b585cb41c365b591e3a917d80a096 Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Thu, 20 Dec 2018 11:50:08 +0100 Subject: [PATCH 06/14] Printhost: Error message stashing, improvements --- src/slic3r/GUI/PrintHostDialogs.cpp | 78 +++++++++++++++++++++++++---- src/slic3r/GUI/PrintHostDialogs.hpp | 25 +++++++++ src/slic3r/Utils/PrintHost.cpp | 1 + 3 files changed, 95 insertions(+), 9 deletions(-) diff --git a/src/slic3r/GUI/PrintHostDialogs.cpp b/src/slic3r/GUI/PrintHostDialogs.cpp index 586fe3d83..3ab4821bd 100644 --- a/src/slic3r/GUI/PrintHostDialogs.cpp +++ b/src/slic3r/GUI/PrintHostDialogs.cpp @@ -95,22 +95,46 @@ PrintHostQueueDialog::PrintHostQueueDialog(wxWindow *parent) auto *topsizer = new wxBoxSizer(wxVERTICAL); job_list = new wxDataViewListCtrl(this, wxID_ANY); + // Note: Keep these in sync with Column job_list->AppendTextColumn("ID", wxDATAVIEW_CELL_INERT); job_list->AppendProgressColumn("Progress", wxDATAVIEW_CELL_INERT); job_list->AppendTextColumn("Status", wxDATAVIEW_CELL_INERT); job_list->AppendTextColumn("Host", wxDATAVIEW_CELL_INERT); job_list->AppendTextColumn("Filename", wxDATAVIEW_CELL_INERT); + job_list->AppendTextColumn("error_message", wxDATAVIEW_CELL_INERT, -1, wxALIGN_CENTER, wxDATAVIEW_COL_HIDDEN); auto *btnsizer = new wxBoxSizer(wxHORIZONTAL); - auto *btn_cancel = new wxButton(this, wxID_DELETE, _(L("Cancel selected"))); // TODO: enable based on status ("show error" for failed jobs) + btn_cancel = new wxButton(this, wxID_DELETE, _(L("Cancel selected"))); + btn_cancel->Disable(); + btn_error = new wxButton(this, wxID_ANY, _(L("Show error message"))); + btn_error->Disable(); auto *btn_close = new wxButton(this, wxID_CANCEL, _(L("Close"))); btnsizer->Add(btn_cancel, 0, wxRIGHT, SPACING); + btnsizer->Add(btn_error, 0); btnsizer->AddStretchSpacer(); btnsizer->Add(btn_close); topsizer->Add(job_list, 1, wxEXPAND | wxBOTTOM, SPACING); topsizer->Add(btnsizer, 0, wxEXPAND); SetSizer(topsizer); + + job_list->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [this](wxDataViewEvent&) { on_list_select(); }); + + btn_cancel->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { + int selected = job_list->GetSelectedRow(); + if (selected == wxNOT_FOUND) { return; } + + const JobState state = get_state(selected); + if (state < ST_ERROR) { + // TODO: cancel + } + }); + + btn_error->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { + int selected = job_list->GetSelectedRow(); + if (selected == wxNOT_FOUND) { return; } + GUI::show_error(nullptr, job_list->GetTextValue(selected, COL_ERRORMSG)); + }); } void PrintHostQueueDialog::append_job(const PrintHostJob &job) @@ -123,29 +147,65 @@ void PrintHostQueueDialog::append_job(const PrintHostJob &job) fields.push_back(wxVariant(_(L("Enqueued")))); fields.push_back(wxVariant(job.printhost->get_host())); fields.push_back(wxVariant(job.upload_data.upload_path.string())); - job_list->AppendItem(fields); + fields.push_back(wxVariant("")); + job_list->AppendItem(fields, static_cast(ST_NEW)); +} + +PrintHostQueueDialog::JobState PrintHostQueueDialog::get_state(int idx) +{ + wxCHECK_MSG(idx >= 0 && idx < job_list->GetItemCount(), ST_ERROR, "Out of bounds access to job list"); + return static_cast(job_list->GetItemData(job_list->RowToItem(idx))); +} + +void PrintHostQueueDialog::set_state(int idx, JobState state) +{ + wxCHECK_RET(idx >= 0 && idx < job_list->GetItemCount(), "Out of bounds access to job list"); + job_list->SetItemData(job_list->RowToItem(idx), static_cast(state)); +} + +void PrintHostQueueDialog::on_list_select() +{ + int selected = job_list->GetSelectedRow(); + if (selected != wxNOT_FOUND) { + const JobState state = get_state(selected); + btn_cancel->Enable(state < ST_ERROR); + btn_error->Enable(state == ST_ERROR); + Layout(); + } else { + btn_cancel->Disable(); + } } void PrintHostQueueDialog::on_progress(Event &evt) { wxCHECK_RET(evt.job_id < job_list->GetItemCount(), "Out of bounds access to job list"); - const wxVariant status(evt.progress < 100 ? _(L("Uploading")) : _(L("Complete"))); + if (evt.progress < 100) { + set_state(evt.job_id, ST_PROGRESS); + job_list->SetValue(wxVariant(evt.progress), evt.job_id, COL_PROGRESS); + job_list->SetValue(_(L("Uploading")), evt.job_id, COL_STATUS); + } else { + set_state(evt.job_id, ST_COMPLETED); + job_list->SetValue(wxVariant(100), evt.job_id, COL_PROGRESS); + job_list->SetValue(_(L("Complete")), evt.job_id, COL_STATUS); + } - job_list->SetValue(wxVariant(evt.progress), evt.job_id, 1); - job_list->SetValue(status, evt.job_id, 2); + on_list_select(); } void PrintHostQueueDialog::on_error(Event &evt) { wxCHECK_RET(evt.job_id < job_list->GetItemCount(), "Out of bounds access to job list"); - job_list->SetValue(wxVariant(0), evt.job_id, 1); - job_list->SetValue(wxVariant(_(L("Error"))), evt.job_id, 2); - - // TODO: keep the error for repeated display + set_state(evt.job_id, ST_ERROR); auto errormsg = wxString::Format("%s\n%s", _(L("Error uploading to print host:")), evt.error); + job_list->SetValue(wxVariant(0), evt.job_id, COL_PROGRESS); + job_list->SetValue(wxVariant(_(L("Error"))), evt.job_id, COL_STATUS); + job_list->SetValue(wxVariant(errormsg), evt.job_id, COL_ERRORMSG); // Stashes the error message into a hidden column for later + + on_list_select(); + GUI::show_error(nullptr, std::move(errormsg)); } diff --git a/src/slic3r/GUI/PrintHostDialogs.hpp b/src/slic3r/GUI/PrintHostDialogs.hpp index e38acee32..b8b5d62bb 100644 --- a/src/slic3r/GUI/PrintHostDialogs.hpp +++ b/src/slic3r/GUI/PrintHostDialogs.hpp @@ -13,10 +13,12 @@ #include "MsgDialog.hpp" #include "../Utils/PrintHost.hpp" +class wxButton; class wxTextCtrl; class wxCheckBox; class wxDataViewListCtrl; + namespace Slic3r { struct PrintHostJob; @@ -60,11 +62,34 @@ public: void append_job(const PrintHostJob &job); private: + enum Column { + COL_ID, + COL_PROGRESS, + COL_STATUS, + COL_HOST, + COL_FILENAME, + COL_ERRORMSG, + }; + + enum JobState { + ST_NEW, + ST_PROGRESS, + ST_ERROR, + ST_CANCELLING, + ST_CANCELLED, + ST_COMPLETED, + }; + + wxButton *btn_cancel; + wxButton *btn_error; wxDataViewListCtrl *job_list; // Note: EventGuard prevents delivery of progress evts to a freed PrintHostQueueDialog EventGuard on_progress_evt; EventGuard on_error_evt; + JobState get_state(int idx); + void set_state(int idx, JobState); + void on_list_select(); void on_progress(Event&); void on_error(Event&); }; diff --git a/src/slic3r/Utils/PrintHost.cpp b/src/slic3r/Utils/PrintHost.cpp index 934436a19..5d0275d2b 100644 --- a/src/slic3r/Utils/PrintHost.cpp +++ b/src/slic3r/Utils/PrintHost.cpp @@ -127,6 +127,7 @@ void PrintHostJobQueue::priv::progress_fn(Http::Progress progress, bool &cancel) } else if (cancel_id > job_id) { jobs->at(cancel_id - job_id).cancelled = true; } + // TODO: emit cancelled } cancels->clear(); From 2d0dc6b050ebf9288f187fa7f321d6394bdcc4ad Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Thu, 20 Dec 2018 13:36:49 +0100 Subject: [PATCH 07/14] Printhost: Cancelation, bugfixes --- src/libslic3r/Channel.hpp | 3 +- src/slic3r/GUI/PrintHostDialogs.cpp | 28 ++++++- src/slic3r/GUI/PrintHostDialogs.hpp | 3 + src/slic3r/Utils/Http.cpp | 6 +- src/slic3r/Utils/PrintHost.cpp | 109 +++++++++++++++++++++------- src/slic3r/Utils/PrintHost.hpp | 2 + 6 files changed, 118 insertions(+), 33 deletions(-) diff --git a/src/libslic3r/Channel.hpp b/src/libslic3r/Channel.hpp index 9cf025f2c..68369af63 100644 --- a/src/libslic3r/Channel.hpp +++ b/src/libslic3r/Channel.hpp @@ -77,8 +77,7 @@ public: } } - // Unlocked observers/hints - // Thread unsafe! Keep in mind you need to re-verify the result after locking! + // Unlocked observer/hint. Thread unsafe! Keep in mind you need to re-verify the result after locking. size_t size_hint() const noexcept { return m_queue.size(); } LockedConstPtr lock_read() const diff --git a/src/slic3r/GUI/PrintHostDialogs.cpp b/src/slic3r/GUI/PrintHostDialogs.cpp index 3ab4821bd..8c0c0fc85 100644 --- a/src/slic3r/GUI/PrintHostDialogs.cpp +++ b/src/slic3r/GUI/PrintHostDialogs.cpp @@ -14,6 +14,7 @@ #include #include "GUI.hpp" +#include "GUI_App.hpp" #include "MsgDialog.hpp" #include "I18N.hpp" #include "../Utils/PrintHost.hpp" @@ -59,7 +60,8 @@ bool PrintHostSendDialog::start_print() const wxDEFINE_EVENT(EVT_PRINTHOST_PROGRESS, PrintHostQueueDialog::Event); -wxDEFINE_EVENT(EVT_PRINTHOST_ERROR, PrintHostQueueDialog::Event); +wxDEFINE_EVENT(EVT_PRINTHOST_ERROR, PrintHostQueueDialog::Event); +wxDEFINE_EVENT(EVT_PRINTHOST_CANCEL, PrintHostQueueDialog::Event); PrintHostQueueDialog::Event::Event(wxEventType eventType, int winid, size_t job_id) : wxEvent(winid, eventType) @@ -87,6 +89,7 @@ PrintHostQueueDialog::PrintHostQueueDialog(wxWindow *parent) : wxDialog(parent, wxID_ANY, _(L("Print host upload queue")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) , on_progress_evt(this, EVT_PRINTHOST_PROGRESS, &PrintHostQueueDialog::on_progress, this) , on_error_evt(this, EVT_PRINTHOST_ERROR, &PrintHostQueueDialog::on_error, this) + , on_cancel_evt(this, EVT_PRINTHOST_CANCEL, &PrintHostQueueDialog::on_cancel, this) { enum { HEIGHT = 800, WIDTH = 400, SPACING = 5 }; @@ -127,6 +130,7 @@ PrintHostQueueDialog::PrintHostQueueDialog(wxWindow *parent) const JobState state = get_state(selected); if (state < ST_ERROR) { // TODO: cancel + GUI::wxGetApp().printhost_job_queue().cancel(selected); } }); @@ -161,6 +165,15 @@ void PrintHostQueueDialog::set_state(int idx, JobState state) { wxCHECK_RET(idx >= 0 && idx < job_list->GetItemCount(), "Out of bounds access to job list"); job_list->SetItemData(job_list->RowToItem(idx), static_cast(state)); + + switch (state) { + case ST_NEW: job_list->SetValue(_(L("Enqueued")), idx, COL_STATUS); break; + case ST_PROGRESS: job_list->SetValue(_(L("Uploading")), idx, COL_STATUS); break; + case ST_ERROR: job_list->SetValue(_(L("Error")), idx, COL_STATUS); break; + case ST_CANCELLING: job_list->SetValue(_(L("Cancelling")), idx, COL_STATUS); break; + case ST_CANCELLED: job_list->SetValue(_(L("Cancelled")), idx, COL_STATUS); break; + case ST_COMPLETED: job_list->SetValue(_(L("Completed")), idx, COL_STATUS); break; + } } void PrintHostQueueDialog::on_list_select() @@ -183,11 +196,9 @@ void PrintHostQueueDialog::on_progress(Event &evt) if (evt.progress < 100) { set_state(evt.job_id, ST_PROGRESS); job_list->SetValue(wxVariant(evt.progress), evt.job_id, COL_PROGRESS); - job_list->SetValue(_(L("Uploading")), evt.job_id, COL_STATUS); } else { set_state(evt.job_id, ST_COMPLETED); job_list->SetValue(wxVariant(100), evt.job_id, COL_PROGRESS); - job_list->SetValue(_(L("Complete")), evt.job_id, COL_STATUS); } on_list_select(); @@ -201,7 +212,6 @@ void PrintHostQueueDialog::on_error(Event &evt) auto errormsg = wxString::Format("%s\n%s", _(L("Error uploading to print host:")), evt.error); job_list->SetValue(wxVariant(0), evt.job_id, COL_PROGRESS); - job_list->SetValue(wxVariant(_(L("Error"))), evt.job_id, COL_STATUS); job_list->SetValue(wxVariant(errormsg), evt.job_id, COL_ERRORMSG); // Stashes the error message into a hidden column for later on_list_select(); @@ -209,5 +219,15 @@ void PrintHostQueueDialog::on_error(Event &evt) GUI::show_error(nullptr, std::move(errormsg)); } +void PrintHostQueueDialog::on_cancel(Event &evt) +{ + wxCHECK_RET(evt.job_id < job_list->GetItemCount(), "Out of bounds access to job list"); + + set_state(evt.job_id, ST_CANCELLED); + job_list->SetValue(wxVariant(0), evt.job_id, COL_PROGRESS); + + on_list_select(); +} + }} diff --git a/src/slic3r/GUI/PrintHostDialogs.hpp b/src/slic3r/GUI/PrintHostDialogs.hpp index b8b5d62bb..ee3fe26d8 100644 --- a/src/slic3r/GUI/PrintHostDialogs.hpp +++ b/src/slic3r/GUI/PrintHostDialogs.hpp @@ -86,16 +86,19 @@ private: // Note: EventGuard prevents delivery of progress evts to a freed PrintHostQueueDialog EventGuard on_progress_evt; EventGuard on_error_evt; + EventGuard on_cancel_evt; JobState get_state(int idx); void set_state(int idx, JobState); void on_list_select(); void on_progress(Event&); void on_error(Event&); + void on_cancel(Event&); }; wxDECLARE_EVENT(EVT_PRINTHOST_PROGRESS, PrintHostQueueDialog::Event); wxDECLARE_EVENT(EVT_PRINTHOST_ERROR, PrintHostQueueDialog::Event); +wxDECLARE_EVENT(EVT_PRINTHOST_CANCEL, PrintHostQueueDialog::Event); }} diff --git a/src/slic3r/Utils/Http.cpp b/src/slic3r/Utils/Http.cpp index 30478cb01..2561348bb 100644 --- a/src/slic3r/Utils/Http.cpp +++ b/src/slic3r/Utils/Http.cpp @@ -149,7 +149,9 @@ int Http::priv::xfercb(void *userp, curl_off_t dltotal, curl_off_t dlnow, curl_o self->progressfn(progress, cb_cancel); } - return self->cancel || cb_cancel; + if (cb_cancel) { self->cancel = true; } + + return self->cancel; } int Http::priv::xfercb_legacy(void *userp, double dltotal, double dlnow, double ultotal, double ulnow) @@ -278,7 +280,7 @@ void Http::priv::http_perform() } else { long http_status = 0; ::curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_status); - + if (http_status >= 400) { if (errorfn) { errorfn(std::move(buffer), std::string(), http_status); } } else { diff --git a/src/slic3r/Utils/PrintHost.cpp b/src/slic3r/Utils/PrintHost.cpp index 5d0275d2b..d50d6c6bd 100644 --- a/src/slic3r/Utils/PrintHost.cpp +++ b/src/slic3r/Utils/PrintHost.cpp @@ -49,6 +49,7 @@ struct PrintHostJobQueue::priv Channel channel_cancels; size_t job_id = 0; int prev_progress = -1; + fs::path source_to_remove; std::thread bg_thread; bool bg_exit = false; @@ -57,9 +58,14 @@ struct PrintHostJobQueue::priv priv(PrintHostJobQueue *q) : q(q) {} + void emit_progress(int progress); + void emit_error(wxString error); + void emit_cancel(size_t id); void start_bg_thread(); void bg_thread_main(); void progress_fn(Http::Progress progress, bool &cancel); + void remove_source(const fs::path &path); + void remove_source(); void perform_job(PrintHostJob the_job); }; @@ -78,6 +84,24 @@ PrintHostJobQueue::~PrintHostJobQueue() } } +void PrintHostJobQueue::priv::emit_progress(int progress) +{ + auto evt = new PrintHostQueueDialog::Event(GUI::EVT_PRINTHOST_PROGRESS, queue_dialog->GetId(), job_id, progress); + wxQueueEvent(queue_dialog, evt); +} + +void PrintHostJobQueue::priv::emit_error(wxString error) +{ + auto evt = new PrintHostQueueDialog::Event(GUI::EVT_PRINTHOST_ERROR, queue_dialog->GetId(), job_id, std::move(error)); + wxQueueEvent(queue_dialog, evt); +} + +void PrintHostJobQueue::priv::emit_cancel(size_t id) +{ + auto evt = new PrintHostQueueDialog::Event(GUI::EVT_PRINTHOST_CANCEL, queue_dialog->GetId(), id); + wxQueueEvent(queue_dialog, evt); +} + void PrintHostJobQueue::priv::start_bg_thread() { if (bg_thread.joinable()) { return; } @@ -96,21 +120,43 @@ void PrintHostJobQueue::priv::bg_thread_main() // Pick up jobs from the job channel: while (! bg_exit) { auto job = channel_jobs.pop(); // Sleeps in a cond var if there are no jobs + source_to_remove = job.upload_data.source_path; + + BOOST_LOG_TRIVIAL(debug) << boost::format("PrintHostJobQueue/bg_thread: Received job: [%1%]: `%2%` -> `%3%`, cancelled: %4%") + % job_id + % job.upload_data.upload_path + % job.printhost->get_host() + % job.cancelled; + if (! job.cancelled) { perform_job(std::move(job)); } + + remove_source(); job_id++; } } catch (const std::exception &e) { - auto evt = new PrintHostQueueDialog::Event(GUI::EVT_PRINTHOST_ERROR, queue_dialog->GetId(), job_id, e.what()); - wxQueueEvent(queue_dialog, evt); + emit_error(e.what()); } catch (...) { wxTheApp->OnUnhandledException(); } + + // Cleanup leftover files, if any + remove_source(); + auto jobs = channel_jobs.lock_rw(); + for (const PrintHostJob &job : *jobs) { + remove_source(job.upload_data.source_path); + } } void PrintHostJobQueue::priv::progress_fn(Http::Progress progress, bool &cancel) { + if (cancel) { + // When cancel is true from the start, Http indicates request has been cancelled + emit_cancel(job_id); + return; + } + if (bg_exit) { cancel = true; return; @@ -125,49 +171,57 @@ void PrintHostJobQueue::priv::progress_fn(Http::Progress progress, bool &cancel) if (cancel_id == job_id) { cancel = true; } else if (cancel_id > job_id) { - jobs->at(cancel_id - job_id).cancelled = true; + const size_t idx = cancel_id - job_id - 1; + if (idx < jobs->size()) { + jobs->at(idx).cancelled = true; + BOOST_LOG_TRIVIAL(debug) << boost::format("PrintHostJobQueue: Job id %1% cancelled") % cancel_id; + emit_cancel(cancel_id); + } } - // TODO: emit cancelled } cancels->clear(); } - int gui_progress = progress.ultotal > 0 ? 100*progress.ulnow / progress.ultotal : 0; - if (gui_progress != prev_progress) { - auto evt = new PrintHostQueueDialog::Event(GUI::EVT_PRINTHOST_PROGRESS, queue_dialog->GetId(), job_id, gui_progress); - wxQueueEvent(queue_dialog, evt); - prev_progress = gui_progress; + if (! cancel) { + int gui_progress = progress.ultotal > 0 ? 100*progress.ulnow / progress.ultotal : 0; + if (gui_progress != prev_progress) { + emit_progress(gui_progress); + prev_progress = gui_progress; + } } } +void PrintHostJobQueue::priv::remove_source(const fs::path &path) +{ + if (! path.empty()) { + boost::system::error_code ec; + fs::remove(path, ec); + if (ec) { + BOOST_LOG_TRIVIAL(error) << boost::format("PrintHostJobQueue: Error removing file `%1%`: %2%") % path % ec; + } + } +} + +void PrintHostJobQueue::priv::remove_source() +{ + remove_source(source_to_remove); + source_to_remove.clear(); +} + void PrintHostJobQueue::priv::perform_job(PrintHostJob the_job) { if (bg_exit || the_job.empty()) { return; } - BOOST_LOG_TRIVIAL(debug) << boost::format("PrintHostJobQueue/bg_thread: Got job: `%1%` -> `%2%`") - % the_job.upload_data.upload_path - % the_job.printhost->get_host(); - - const fs::path gcode_path = the_job.upload_data.source_path; - bool success = the_job.printhost->upload(std::move(the_job.upload_data), [this](Http::Progress progress, bool &cancel) { this->progress_fn(std::move(progress), cancel); }, [this](wxString error) { - auto evt = new PrintHostQueueDialog::Event(GUI::EVT_PRINTHOST_ERROR, queue_dialog->GetId(), job_id, std::move(error)); - wxQueueEvent(queue_dialog, evt); + emit_error(std::move(error)); } ); if (success) { - auto evt = new PrintHostQueueDialog::Event(GUI::EVT_PRINTHOST_PROGRESS, queue_dialog->GetId(), job_id, 100); - wxQueueEvent(queue_dialog, evt); - } - - boost::system::error_code ec; - fs::remove(gcode_path, ec); - if (ec) { - BOOST_LOG_TRIVIAL(error) << boost::format("PrintHostJobQueue: Error removing file `%1%`: %2%") % gcode_path % ec; + emit_progress(100); } } @@ -178,5 +232,10 @@ void PrintHostJobQueue::enqueue(PrintHostJob job) p->channel_jobs.push(std::move(job)); } +void PrintHostJobQueue::cancel(size_t id) +{ + p->channel_cancels.push(id); +} + } diff --git a/src/slic3r/Utils/PrintHost.hpp b/src/slic3r/Utils/PrintHost.hpp index a6c7a4723..39b93f5fb 100644 --- a/src/slic3r/Utils/PrintHost.hpp +++ b/src/slic3r/Utils/PrintHost.hpp @@ -55,6 +55,7 @@ struct PrintHostJob PrintHostJob(PrintHostJob &&other) : upload_data(std::move(other.upload_data)) , printhost(std::move(other.printhost)) + , cancelled(other.cancelled) {} PrintHostJob(DynamicPrintConfig *config) @@ -66,6 +67,7 @@ struct PrintHostJob { upload_data = std::move(other.upload_data); printhost = std::move(other.printhost); + cancelled = other.cancelled; return *this; } From ece3c74380ce9dae3abcbf5293bf1f7eb7a82aaa Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Thu, 20 Dec 2018 13:44:44 +0100 Subject: [PATCH 08/14] Printhost: Minor bugfix --- src/slic3r/Utils/PrintHost.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/Utils/PrintHost.cpp b/src/slic3r/Utils/PrintHost.cpp index d50d6c6bd..b6f5b8b9c 100644 --- a/src/slic3r/Utils/PrintHost.cpp +++ b/src/slic3r/Utils/PrintHost.cpp @@ -138,7 +138,7 @@ void PrintHostJobQueue::priv::bg_thread_main() } catch (const std::exception &e) { emit_error(e.what()); } catch (...) { - wxTheApp->OnUnhandledException(); + emit_error("Unknown exception"); } // Cleanup leftover files, if any From 70bfa4202f15e40331107c884cc8ee4fa8b09d3c Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Thu, 20 Dec 2018 15:22:58 +0100 Subject: [PATCH 09/14] Fix for SPE-700 (Corrupted slice data) --- src/libslic3r/SLA/SLASupportTree.cpp | 9 +++++++++ src/libslic3r/SLA/SLASupportTree.hpp | 2 ++ src/libslic3r/SLA/SLASupportTreeIGL.cpp | 2 +- src/libslic3r/SLAPrint.cpp | 12 +++++++++--- 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/libslic3r/SLA/SLASupportTree.cpp b/src/libslic3r/SLA/SLASupportTree.cpp index 37b0c0ffc..c599cd83e 100644 --- a/src/libslic3r/SLA/SLASupportTree.cpp +++ b/src/libslic3r/SLA/SLASupportTree.cpp @@ -722,6 +722,10 @@ public: return m_pad; } + void remove_pad() { + m_pad = Pad(); + } + const Pad& pad() const { return m_pad; } // WITHOUT THE PAD!!! @@ -1729,6 +1733,11 @@ const TriangleMesh &SLASupportTree::get_pad() const return m_impl->pad().tmesh; } +void SLASupportTree::remove_pad() +{ + m_impl->remove_pad(); +} + SLASupportTree::SLASupportTree(const PointSet &points, const EigenMesh3D& emesh, const SupportConfig &cfg, diff --git a/src/libslic3r/SLA/SLASupportTree.hpp b/src/libslic3r/SLA/SLASupportTree.hpp index 62e790611..e19f263b6 100644 --- a/src/libslic3r/SLA/SLASupportTree.hpp +++ b/src/libslic3r/SLA/SLASupportTree.hpp @@ -164,6 +164,8 @@ public: /// Get the pad geometry const TriangleMesh& get_pad() const; + void remove_pad(); + }; } diff --git a/src/libslic3r/SLA/SLASupportTreeIGL.cpp b/src/libslic3r/SLA/SLASupportTreeIGL.cpp index 49290b3b8..6d4a770aa 100644 --- a/src/libslic3r/SLA/SLASupportTreeIGL.cpp +++ b/src/libslic3r/SLA/SLASupportTreeIGL.cpp @@ -198,7 +198,7 @@ PointSet normals(const PointSet& points, const EigenMesh3D& emesh, }); if(!neighnorms.empty()) { // there were neighbors to count with - // sum up the normals and than normalize the result again. + // sum up the normals and then normalize the result again. // This unification seems to be enough. Vec3d sumnorm(0, 0, 0); sumnorm = std::accumulate(neighnorms.begin(), lend, sumnorm); diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index 90abe290f..15f0e410e 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -560,9 +560,13 @@ void SLAPrint::process() // and before the supports had been sliced. (or the slicing has to be // repeated) - if(po.m_config.pad_enable.getBool() && - po.m_supportdata && - po.m_supportdata->support_tree_ptr) + if(!po.m_supportdata || !po.m_supportdata->support_tree_ptr) { + BOOST_LOG_TRIVIAL(warning) << "Uninitialized support data at " + << "pad creation."; + return; + } + + if(po.m_config.pad_enable.getBool()) { double wt = po.m_config.pad_wall_thickness.getFloat(); double h = po.m_config.pad_wall_height.getFloat(); @@ -586,6 +590,8 @@ void SLAPrint::process() pcfg.throw_on_cancel = thrfn; po.m_supportdata->support_tree_ptr->add_pad(bp, pcfg); + } else { + po.m_supportdata->support_tree_ptr->remove_pad(); } po.throw_if_canceled(); From 5cd59377953d7bfaf5fbf79c351821c2c862b9df Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 20 Dec 2018 16:09:25 +0100 Subject: [PATCH 10/14] More transparent background texture for toolbars --- resources/icons/toolbar_background.png | Bin 1544 -> 1540 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/resources/icons/toolbar_background.png b/resources/icons/toolbar_background.png index 2b5ea013be7a6b804fb8390bec7d386e39e42d16..e7ce3c14615b551ea8fa873b1fe52c4215160a8f 100644 GIT binary patch delta 1256 zcmVOt{9C}mBHD29)sZ>waKge_JOYoK|c zR7aT@(H<12QGcO9eYKS;mKeCRp=GWtOP0hqb6rrvEHv08OLJhvQbA21=4&mq{O0Aa zQiA73&}4$KN%T{3uY`Y6E<|nmCkhxh0FUKu>*e{yZ9FZ5u#{;9Id65`PfzkwhtyH)bP39258ytehqA z0Rp7Tjobhmkq9`6r*F(LTDq)!igC37gyNtW&}1oq6@nsvEF|PmQPJR3HL7XStR+ee zQDcl2=N(l{ESOp}vt-#yk`$7rm@K7~Q^}kKSD5CQ&E=GHE(J~tOc%^9&?x2LLymCh z5f3}kk$;a;kv=t4t+857HP_O(NyG7Pv6*YB^3jyP|xZK{vd=!x9d)M!(i#KO|E8#Rc{K1|TOPINK@F%AUcHVGi1c{1~fLf}bmGV_^n zD3n2sbi!#giGg6~#5(9=cO&;DH>csZxbd&Zxk-ucUyySX-6r>$+Y4%~tZx)qfaWQj zG4(QVu|c7y!l}&fq(5%m-x_!udK-EhdK-EhdK-Eh`hN@!{CL1$P4^RitdWu+h246S z2m>;I6b}a*L#rkB00082NklJG9Kw`%~MxcI@jU$u3NU;s>i{x^Uc&;{Dg^(GC0emp{)9l%GR2i!Tw zo3;Qx1K$t*@V#^QBk<(8y%cibA$~tOC4fiZlXEMbCa~F$AU|-}e{xo(bq~A(FU1F8 z?}D%Aj7qN;*ZQvjx?b=l;V!QAn*bW#>LsNe*ZfZa9cPl9P7y%ycvop@0o8zycT*K7 zfL4h2hf4I>Kw$e;Pid-$-FreMrxw`0&sUl%0blr}Ecfc)TLBr9sstaCx&#Xx*JACG zrX7GsGzTUFkO9a5lvn^8mox1EGMCd+ld1%B0r8U_1u%b$=Kurek(@#C8~|Vf44p|b zhH=f`JPGUr3ujY$i@4SR6W|s2aAX_Z&N=^i|1ZCg{o|KwKo@8`$D6&{?{nmRPj=#t8bAkV z;r|d^yEQ!9hdhJgR_~bX%$-+b1WlkGj}R446Bn~$`#OKd_NCr9F8=(~9sCCDH&b3) Sn1ts50000yS&GhaJQZPIe*%=>DfHr2SYHLLQmLn z7ZQ&;&RGO2kR$~)uR8Fwc=UPMRqS=_+|_*w-qm}GoiE!ikD+irZio03qirXB9lI5w z`xVh`=7$F+*A$;(H%3ci^mBJ5L_{jOy{V6_tR5T>gi_Y9h+_CC`nF0&N!Vfqu?Ct4 zN_CWp5zRq?8h;fU)K^=nVu^t}8(QYdvTR9=GuH(r%tC`rvNQ)4EEUuQX1>-!Yu>!( ztCTQvBX}}FY!dxc+$-asluKxgnYu(iU9rNtc;+;gG0DvuUI0R4$5dB*S8;cFVBszx}#;yj~@i3L-OW|k~lNs>a+6qBWtaw?g#;0V(kv$>pd&ZS_|0_lR$1s?F zJ>p?UI)Cy}D$=Khsx?-tspeW5H)(kNTWsc9YPpq89jVkq*B-m|)N?Nbxi(~kp(73( zY2;BZYMbgKHF_fVH8tAQCb6*m>_!b{vkwWH$B9m6AjW|}+$I4eG*4zeQ3yQAO=dnb zUJ7MUBb{&>O=2JzI^1-0ap z2m>;I4hbAP>e>bE00086Nklv2ex?mCSNzY@``V1tRDl-I1nNKyr~qYj z4l7^@%z!B{21daA*bQVyey#y@;^GJAe$m!{F@gaw`QHF)Ko@8`*Q+!H`f(3&asZ!! z9&qCvui66m3j93uX6cm=Zp%k7uWi)0J@&=CE+Hn^_u`1Ug{;K9oPI%03BzNoK7A;nsD zQ+SKG)&P`t-gpIGfLmu&Xb-@zLjeFh#h*>*R7l@|AG?f3cMc~5rah8jQzXyN}5T)H*eJDWU% z{8H~D*@+vk#t51~J? Date: Thu, 20 Dec 2018 16:25:32 +0100 Subject: [PATCH 11/14] Don't set done on a canceled step. --- src/libslic3r/SLAPrint.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index 15f0e410e..31ba0be3d 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -872,6 +872,7 @@ void SLAPrint::process() if(po->m_stepmask[currentstep] && po->set_started(currentstep)) { report_status(*this, int(st), OBJ_STEP_LABELS[currentstep]); pobj_program[currentstep](*po); + throw_if_canceled(); po->set_done(currentstep); } @@ -897,6 +898,7 @@ void SLAPrint::process() { report_status(*this, int(st), PRINT_STEP_LABELS[currentstep]); print_program[currentstep](); + throw_if_canceled(); set_done(currentstep); } From 4d70546a0596eb3e256a9d78bfee7c0b924383e2 Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Thu, 20 Dec 2018 16:35:54 +0100 Subject: [PATCH 12/14] Fix: Schedule SLA print uploads too (the same way as FFF) --- src/slic3r/GUI/BackgroundSlicingProcess.cpp | 56 +++++++++++++-------- src/slic3r/GUI/BackgroundSlicingProcess.hpp | 1 + 2 files changed, 37 insertions(+), 20 deletions(-) diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp index 66a0884a4..44ac1bc71 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp @@ -84,26 +84,7 @@ void BackgroundSlicingProcess::process_fff() run_post_process_scripts(export_path, m_fff_print->config()); m_print->set_status(100, "G-code file exported to " + export_path); } else if (! m_upload_job.empty()) { - // A print host upload job has been scheduled - - // XXX: is fs::path::string() right? - - // Generate a unique temp path to which the gcode is copied - boost::filesystem::path source_path = boost::filesystem::temp_directory_path() - / boost::filesystem::unique_path(".printhost.%%%%-%%%%-%%%%-%%%%.gcode"); - - if (copy_file(m_temp_output_path, source_path.string()) != 0) { - throw std::runtime_error("Copying of the temporary G-code to the output G-code failed"); - } - - m_print->set_status(95, "Running post-processing scripts"); - run_post_process_scripts(source_path.string(), m_fff_print->config()); - m_print->set_status(100, (boost::format("Scheduling upload to `%1%`. See Window -> Print Host Upload Queue") % m_upload_job.printhost->get_host()).str()); - - m_upload_job.upload_data.source_path = std::move(source_path); - m_upload_job.upload_data.upload_path = m_fff_print->print_statistics().finalize_output_path(m_upload_job.upload_data.upload_path.string()); - - GUI::wxGetApp().printhost_job_queue().enqueue(std::move(m_upload_job)); + prepare_upload(); } else { m_print->set_status(100, "Slicing complete"); } @@ -170,6 +151,10 @@ void BackgroundSlicingProcess::process_sla() if (! m_export_path.empty()) { m_sla_print->export_raster(m_export_path); m_print->set_status(100, "Zip file exported to " + m_export_path); + } else if (! m_upload_job.empty()) { + prepare_upload(); + } else { + m_print->set_status(100, "Slicing complete"); } this->set_step_done(bspsGCodeFinalize); } @@ -440,4 +425,35 @@ bool BackgroundSlicingProcess::invalidate_all_steps() return m_step_state.invalidate_all([this](){ this->stop_internal(); }); } +void BackgroundSlicingProcess::prepare_upload() +{ + // A print host upload job has been scheduled, enqueue it to the printhost job queue + + // XXX: is fs::path::string() right? + + // Generate a unique temp path to which the gcode/zip file is copied/exported + boost::filesystem::path source_path = boost::filesystem::temp_directory_path() + / boost::filesystem::unique_path(".printhost.%%%%-%%%%-%%%%-%%%%.gcode"); + + if (m_print == m_fff_print) { + m_print->set_status(95, "Running post-processing scripts"); + run_post_process_scripts(source_path.string(), m_fff_print->config()); + + if (copy_file(m_temp_output_path, source_path.string()) != 0) { + throw std::runtime_error("Copying of the temporary G-code to the output G-code failed"); + } + + m_upload_job.upload_data.upload_path = m_fff_print->print_statistics().finalize_output_path(m_upload_job.upload_data.upload_path.string()); + } else { + m_sla_print->export_raster(source_path.string()); + // TODO: Also finalize upload path like with FFF when there are statistics for SLA print + } + + m_print->set_status(100, (boost::format("Scheduling upload to `%1%`. See Window -> Print Host Upload Queue") % m_upload_job.printhost->get_host()).str()); + + m_upload_job.upload_data.source_path = std::move(source_path); + + GUI::wxGetApp().printhost_job_queue().enqueue(std::move(m_upload_job)); +} + }; // namespace Slic3r diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.hpp b/src/slic3r/GUI/BackgroundSlicingProcess.hpp index 222ed147e..5911c8a02 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.hpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.hpp @@ -167,6 +167,7 @@ private: bool invalidate_all_steps(); // If the background processing stop was requested, throw CanceledException. void throw_if_canceled() const { if (m_print->canceled()) throw CanceledException(); } + void prepare_upload(); // wxWidgets command ID to be sent to the platter to inform that the slicing is finished, and the G-code export will continue. int m_event_slicing_completed_id = 0; From f3185365566d3389c017ed39903e083a8942d901 Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Thu, 20 Dec 2018 16:42:46 +0100 Subject: [PATCH 13/14] Printhost: Make queue window non-modal, fix upload start progress --- src/slic3r/GUI/MainFrame.cpp | 2 +- src/slic3r/Utils/PrintHost.cpp | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 871d50a3d..5b38129de 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -376,7 +376,7 @@ void MainFrame::init_menubar() windowMenu->AppendSeparator(); append_menu_item(windowMenu, wxID_ANY, L("Print Host Upload Queue"), L("Display the Print Host Upload Queue window"), - [this](wxCommandEvent&) { m_printhost_queue_dlg->ShowModal(); }, "arrow_up.png"); + [this](wxCommandEvent&) { m_printhost_queue_dlg->Show(); }, "arrow_up.png"); } // View menu diff --git a/src/slic3r/Utils/PrintHost.cpp b/src/slic3r/Utils/PrintHost.cpp index b6f5b8b9c..84d823d89 100644 --- a/src/slic3r/Utils/PrintHost.cpp +++ b/src/slic3r/Utils/PrintHost.cpp @@ -213,6 +213,8 @@ void PrintHostJobQueue::priv::perform_job(PrintHostJob the_job) { if (bg_exit || the_job.empty()) { return; } + emit_progress(0); // Indicate the upload is starting + bool success = the_job.printhost->upload(std::move(the_job.upload_data), [this](Http::Progress progress, bool &cancel) { this->progress_fn(std::move(progress), cancel); }, [this](wxString error) { From af086263988d9ac50361bff47370e64610fecf33 Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Thu, 20 Dec 2018 16:00:51 +0100 Subject: [PATCH 14/14] Duet: Implement upload() (refactoring from old code) --- src/slic3r/Utils/Duet.cpp | 133 ++++++++++----------------------- src/slic3r/Utils/Duet.hpp | 2 +- src/slic3r/Utils/OctoPrint.cpp | 15 +--- src/slic3r/Utils/OctoPrint.hpp | 1 - src/slic3r/Utils/PrintHost.cpp | 10 +++ src/slic3r/Utils/PrintHost.hpp | 3 + 6 files changed, 55 insertions(+), 109 deletions(-) diff --git a/src/slic3r/Utils/Duet.cpp b/src/slic3r/Utils/Duet.cpp index fd77fc130..3449e610e 100644 --- a/src/slic3r/Utils/Duet.cpp +++ b/src/slic3r/Utils/Duet.cpp @@ -54,91 +54,46 @@ wxString Duet::get_test_failed_msg (wxString &msg) const return wxString::Format("%s: %s", _(L("Could not connect to Duet")), msg); } -// bool Duet::send_gcode(const std::string &filename) const -// { -// enum { PROGRESS_RANGE = 1000 }; - -// const auto errortitle = _(L("Error while uploading to the Duet")); -// fs::path filepath(filename); - -// GUI::PrintHostSendDialog send_dialog(filepath.filename()); -// if (send_dialog.ShowModal() != wxID_OK) { return false; } - -// const bool print = send_dialog.start_print(); -// const auto upload_filepath = send_dialog.filename(); -// const auto upload_filename = upload_filepath.filename(); -// const auto upload_parent_path = upload_filepath.parent_path(); - -// wxProgressDialog progress_dialog( -// _(L("Duet upload")), -// _(L("Sending G-code file to Duet...")), -// PROGRESS_RANGE, nullptr, wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_CAN_ABORT); -// progress_dialog.Pulse(); - -// wxString connect_msg; -// if (!connect(connect_msg)) { -// auto errormsg = wxString::Format("%s: %s", errortitle, connect_msg); -// GUI::show_error(&progress_dialog, std::move(errormsg)); -// return false; -// } - -// bool res = true; - -// auto upload_cmd = get_upload_url(upload_filepath.string()); -// BOOST_LOG_TRIVIAL(info) << boost::format("Duet: Uploading file %1%, filename: %2%, path: %3%, print: %4%, command: %5%") -// % filepath.string() -// % upload_filename.string() -// % upload_parent_path.string() -// % print -// % upload_cmd; - -// auto http = Http::post(std::move(upload_cmd)); -// http.set_post_body(filename) -// .on_complete([&](std::string body, unsigned status) { -// BOOST_LOG_TRIVIAL(debug) << boost::format("Duet: File uploaded: HTTP %1%: %2%") % status % body; -// progress_dialog.Update(PROGRESS_RANGE); - -// int err_code = get_err_code_from_body(body); -// if (err_code != 0) { -// auto msg = format_error(body, L("Unknown error occured"), 0); -// GUI::show_error(&progress_dialog, std::move(msg)); -// res = false; -// } else if (print) { -// wxString errormsg; -// res = start_print(errormsg, upload_filepath.string()); -// if (!res) { -// GUI::show_error(&progress_dialog, std::move(errormsg)); -// } -// } -// }) -// .on_error([&](std::string body, std::string error, unsigned status) { -// BOOST_LOG_TRIVIAL(error) << boost::format("Duet: Error uploading file: %1%, HTTP %2%, body: `%3%`") % error % status % body; -// auto errormsg = wxString::Format("%s: %s", errortitle, format_error(body, error, status)); -// GUI::show_error(&progress_dialog, std::move(errormsg)); -// res = false; -// }) -// .on_progress([&](Http::Progress progress, bool &cancel) { -// if (cancel) { -// // Upload was canceled -// res = false; -// } else if (progress.ultotal > 0) { -// int value = PROGRESS_RANGE * progress.ulnow / progress.ultotal; -// cancel = !progress_dialog.Update(std::min(value, PROGRESS_RANGE - 1)); // Cap the value to prevent premature dialog closing -// } else { -// cancel = !progress_dialog.Pulse(); -// } -// }) -// .perform_sync(); - -// disconnect(); - -// return res; -// } - bool Duet::upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, ErrorFn error_fn) const { - // XXX: TODO - throw "unimplemented"; + wxString connect_msg; + if (!connect(connect_msg)) { + error_fn(std::move(connect_msg)); + return false; + } + + bool res = true; + + auto upload_cmd = get_upload_url(upload_data.upload_path.string()); + BOOST_LOG_TRIVIAL(info) << boost::format("Duet: Uploading file %1%, filepath: %2%, print: %3%, command: %4%") + % upload_data.source_path + % upload_data.upload_path + % upload_data.start_print + % upload_cmd; + + auto http = Http::post(std::move(upload_cmd)); + http.set_post_body(upload_data.source_path) + .on_complete([&](std::string body, unsigned status) { + BOOST_LOG_TRIVIAL(debug) << boost::format("Duet: File uploaded: HTTP %1%: %2%") % status % body; + }) + .on_error([&](std::string body, std::string error, unsigned status) { + BOOST_LOG_TRIVIAL(error) << boost::format("Duet: Error uploading file: %1%, HTTP %2%, body: `%3%`") % error % status % body; + error_fn(format_error(body, error, status)); + res = false; + }) + .on_progress([&](Http::Progress progress, bool &cancel) { + prorgess_fn(std::move(progress), cancel); + if (cancel) { + // Upload was canceled + BOOST_LOG_TRIVIAL(info) << "Duet: Upload canceled"; + res = false; + } + }) + .perform_sync(); + + disconnect(); + + return res; } bool Duet::has_auto_discovery() const @@ -241,20 +196,10 @@ std::string Duet::timestamp_str() const return std::string(buffer); } -wxString Duet::format_error(const std::string &body, const std::string &error, unsigned status) -{ - if (status != 0) { - auto wxbody = wxString::FromUTF8(body.data()); - return wxString::Format("HTTP %u: %s", status, wxbody); - } else { - return wxString::FromUTF8(error.data()); - } -} - bool Duet::start_print(wxString &msg, const std::string &filename) const { bool res = false; - + auto url = (boost::format("%1%rr_gcode?gcode=M32%%20\"%2%\"") % get_base_url() % Http::url_encode(filename)).str(); diff --git a/src/slic3r/Utils/Duet.hpp b/src/slic3r/Utils/Duet.hpp index e053f91ef..e1c28d149 100644 --- a/src/slic3r/Utils/Duet.hpp +++ b/src/slic3r/Utils/Duet.hpp @@ -26,6 +26,7 @@ public: virtual bool has_auto_discovery() const; virtual bool can_test() const; virtual std::string get_host() const { return host; } + private: std::string host; std::string password; @@ -38,7 +39,6 @@ private: void disconnect() const; bool start_print(wxString &msg, const std::string &filename) const; int get_err_code_from_body(const std::string &body) const; - static wxString format_error(const std::string &body, const std::string &error, unsigned status); }; diff --git a/src/slic3r/Utils/OctoPrint.cpp b/src/slic3r/Utils/OctoPrint.cpp index af9d6e4f0..2e2e169b8 100644 --- a/src/slic3r/Utils/OctoPrint.cpp +++ b/src/slic3r/Utils/OctoPrint.cpp @@ -102,7 +102,7 @@ bool OctoPrint::upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, Erro auto url = make_url("api/files/local"); BOOST_LOG_TRIVIAL(info) << boost::format("Octoprint: Uploading file %1% at %2%, filename: %3%, path: %4%, print: %5%") - % upload_data.source_path.string() + % upload_data.source_path % url % upload_filename.string() % upload_parent_path.string() @@ -118,7 +118,6 @@ bool OctoPrint::upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, Erro }) .on_error([&](std::string body, std::string error, unsigned status) { BOOST_LOG_TRIVIAL(error) << boost::format("Octoprint: Error uploading file: %1%, HTTP %2%, body: `%3%`") % error % status % body; - // error_fn(std::move(body), std::move(error), status); error_fn(format_error(body, error, status)); res = false; }) @@ -126,7 +125,7 @@ bool OctoPrint::upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, Erro prorgess_fn(std::move(progress), cancel); if (cancel) { // Upload was canceled - BOOST_LOG_TRIVIAL(error) << "Octoprint: Upload canceled"; + BOOST_LOG_TRIVIAL(info) << "Octoprint: Upload canceled"; res = false; } }) @@ -172,16 +171,6 @@ std::string OctoPrint::make_url(const std::string &path) const } } -wxString OctoPrint::format_error(const std::string &body, const std::string &error, unsigned status) -{ - if (status != 0) { - auto wxbody = wxString::FromUTF8(body.data()); - return wxString::Format("HTTP %u: %s", status, wxbody); - } else { - return wxString::FromUTF8(error.data()); - } -} - // SLAHost diff --git a/src/slic3r/Utils/OctoPrint.hpp b/src/slic3r/Utils/OctoPrint.hpp index 1e739c99d..8da149f53 100644 --- a/src/slic3r/Utils/OctoPrint.hpp +++ b/src/slic3r/Utils/OctoPrint.hpp @@ -38,7 +38,6 @@ private: void set_auth(Http &http) const; std::string make_url(const std::string &path) const; - static wxString format_error(const std::string &body, const std::string &error, unsigned status); }; diff --git a/src/slic3r/Utils/PrintHost.cpp b/src/slic3r/Utils/PrintHost.cpp index 84d823d89..31fe909c4 100644 --- a/src/slic3r/Utils/PrintHost.cpp +++ b/src/slic3r/Utils/PrintHost.cpp @@ -38,6 +38,16 @@ PrintHost* PrintHost::get_print_host(DynamicPrintConfig *config) } } +wxString PrintHost::format_error(const std::string &body, const std::string &error, unsigned status) const +{ + if (status != 0) { + auto wxbody = wxString::FromUTF8(body.data()); + return wxString::Format("HTTP %u: %s", status, wxbody); + } else { + return wxString::FromUTF8(error.data()); + } +} + struct PrintHostJobQueue::priv { diff --git a/src/slic3r/Utils/PrintHost.hpp b/src/slic3r/Utils/PrintHost.hpp index 39b93f5fb..d740ea99e 100644 --- a/src/slic3r/Utils/PrintHost.hpp +++ b/src/slic3r/Utils/PrintHost.hpp @@ -41,6 +41,9 @@ public: virtual std::string get_host() const = 0; static PrintHost* get_print_host(DynamicPrintConfig *config); + +protected: + virtual wxString format_error(const std::string &body, const std::string &error, unsigned status) const; };