From f71cf324b9770fc9d9cc26510d1bbaac43cdbbd7 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 23 Sep 2021 09:25:13 +0200 Subject: [PATCH 01/11] Tech ENABLE_FIX_SEAMS_SYNCH - Fix the synchronization of seams with the horizontal slider in preview --- src/libslic3r/Technologies.hpp | 2 + src/slic3r/GUI/GCodeViewer.cpp | 124 ++++++++++++++++++++++++++++++++- 2 files changed, 125 insertions(+), 1 deletion(-) diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 94496bbf7..e32f3cde7 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -60,6 +60,8 @@ #define ENABLE_FIX_PREVIEW_OPTIONS_Z (1 && ENABLE_SEAMS_USING_MODELS && ENABLE_2_4_0_ALPHA2) // Enable replacing a missing file during reload from disk command #define ENABLE_RELOAD_FROM_DISK_REPLACE_FILE (1 && ENABLE_2_4_0_ALPHA2) +// Enable fixing the synchronization of seams with the horizontal slider in preview +#define ENABLE_FIX_SEAMS_SYNCH (1 && ENABLE_2_4_0_ALPHA2) #endif // _prusaslicer_technologies_h_ diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 9baee7eba..397e9aa03 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -1500,10 +1500,18 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) m_max_bounding_box = m_paths_bounding_box; m_max_bounding_box.merge(m_paths_bounding_box.max + m_sequential_view.marker.get_bounding_box().size()[2] * Vec3d::UnitZ()); +#if ENABLE_FIX_SEAMS_SYNCH m_sequential_view.gcode_ids.clear(); + for (size_t i = 0; i < gcode_result.moves.size(); ++i) { + const GCodeProcessor::MoveVertex& move = gcode_result.moves[i]; + if (move.type != EMoveType::Seam) + m_sequential_view.gcode_ids.push_back(move.gcode_id); + } +#else for (const GCodeProcessor::MoveVertex& move : gcode_result.moves) { m_sequential_view.gcode_ids.push_back(move.gcode_id); } +#endif // ENABLE_FIX_SEAMS_SYNCH std::vector vertices(m_buffers.size()); std::vector indices(m_buffers.size()); @@ -1513,9 +1521,22 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) #endif // ENABLE_SEAMS_USING_MODELS std::vector options_zs; +#if ENABLE_FIX_SEAMS_SYNCH + size_t seams_count = 0; + std::vector seams_ids; +#endif // ENABLE_FIX_SEAMS_SYNCH + // toolpaths data -> extract vertices from result for (size_t i = 0; i < m_moves_count; ++i) { const GCodeProcessor::MoveVertex& curr = gcode_result.moves[i]; +#if ENABLE_FIX_SEAMS_SYNCH + if (curr.type == EMoveType::Seam) { + ++seams_count; + seams_ids.push_back(i); + } + + size_t move_id = i - seams_count; +#endif // ENABLE_FIX_SEAMS_SYNCH // skip first vertex if (i == 0) @@ -1556,7 +1577,11 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) if (t_buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Triangle) { Path& last_path = t_buffer.paths.back(); if (prev.type == curr.type && last_path.matches(curr)) +#if ENABLE_FIX_SEAMS_SYNCH + last_path.add_sub_path(prev, static_cast(v_multibuffer.size()) - 1, 0, move_id - 1); +#else last_path.add_sub_path(prev, static_cast(v_multibuffer.size()) - 1, 0, i - 1); +#endif // ENABLE_FIX_SEAMS_SYNCH } } @@ -1566,12 +1591,20 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) { case TBuffer::ERenderPrimitiveType::Point: { add_vertices_as_point(curr, v_buffer); break; } case TBuffer::ERenderPrimitiveType::Line: { add_vertices_as_line(prev, curr, v_buffer); break; } +#if ENABLE_FIX_SEAMS_SYNCH + case TBuffer::ERenderPrimitiveType::Triangle: { add_vertices_as_solid(prev, curr, t_buffer, static_cast(v_multibuffer.size()) - 1, v_buffer, move_id); break; } +#else case TBuffer::ERenderPrimitiveType::Triangle: { add_vertices_as_solid(prev, curr, t_buffer, static_cast(v_multibuffer.size()) - 1, v_buffer, i); break; } +#endif // ENABLE_FIX_SEAMS_SYNCH #if ENABLE_SEAMS_USING_MODELS #if ENABLE_SEAMS_USING_BATCHED_MODELS case TBuffer::ERenderPrimitiveType::InstancedModel: { +#if ENABLE_FIX_SEAMS_SYNCH + add_model_instance(curr, inst_buffer, inst_id_buffer, move_id); +#else add_model_instance(curr, inst_buffer, inst_id_buffer, i); +#endif // ENABLE_FIX_SEAMS_SYNCH #if ENABLE_GCODE_VIEWER_STATISTICS ++m_statistics.instances_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS @@ -1579,7 +1612,11 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) } case TBuffer::ERenderPrimitiveType::BatchedModel: { +#if ENABLE_FIX_SEAMS_SYNCH + add_vertices_as_model_batch(curr, t_buffer.model.data, v_buffer, inst_buffer, inst_id_buffer, move_id); +#else add_vertices_as_model_batch(curr, t_buffer.model.data, v_buffer, inst_buffer, inst_id_buffer, i); +#endif // ENABLE_FIX_SEAMS_SYNCH #if ENABLE_GCODE_VIEWER_STATISTICS ++m_statistics.batched_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS @@ -1588,7 +1625,11 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) #else case TBuffer::ERenderPrimitiveType::Model: { +#if ENABLE_FIX_SEAMS_SYNCH + add_model_instance(curr, inst_buffer, inst_id_buffer, move_id); +#else add_model_instance(curr, inst_buffer, inst_id_buffer, i); +#endif // ENABLE_FIX_SEAMS_SYNCH #if ENABLE_GCODE_VIEWER_STATISTICS ++m_statistics.instances_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS @@ -1607,7 +1648,11 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) } // smooth toolpaths corners for the given TBuffer using triangles +#if ENABLE_FIX_SEAMS_SYNCH + auto smooth_triangle_toolpaths_corners = [&gcode_result, &seams_ids](const TBuffer& t_buffer, MultiVertexBuffer& v_multibuffer) { +#else auto smooth_triangle_toolpaths_corners = [&gcode_result](const TBuffer& t_buffer, MultiVertexBuffer& v_multibuffer) { +#endif // ENABLE_FIX_SEAMS_SYNCH auto extract_position_at = [](const VertexBuffer& vertices, size_t offset) { return Vec3f(vertices[offset + 0], vertices[offset + 1], vertices[offset + 2]); }; @@ -1681,6 +1726,16 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) } }; +#if ENABLE_FIX_SEAMS_SYNCH + auto extract_move_id = [&seams_ids](size_t id) { + for (int i = seams_ids.size() - 1; i >= 0; --i) { + if (seams_ids[i] < id + i + 1) + return id + (size_t)i + 1; + } + return id; + }; +#endif // ENABLE_FIX_SEAMS_SYNCH + size_t vertex_size_floats = t_buffer.vertices.vertex_size_floats(); for (const Path& path : t_buffer.paths) { // the two segments of the path sharing the current vertex may belong @@ -1691,9 +1746,16 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) const float half_width = 0.5f * path.width; for (size_t j = 1; j < path_vertices_count - 1; ++j) { size_t curr_s_id = path.sub_paths.front().first.s_id + j; +#if ENABLE_FIX_SEAMS_SYNCH + size_t move_id = extract_move_id(curr_s_id); + const Vec3f& prev = gcode_result.moves[move_id - 1].position; + const Vec3f& curr = gcode_result.moves[move_id].position; + const Vec3f& next = gcode_result.moves[move_id + 1].position; +#else const Vec3f& prev = gcode_result.moves[curr_s_id - 1].position; const Vec3f& curr = gcode_result.moves[curr_s_id].position; const Vec3f& next = gcode_result.moves[curr_s_id + 1].position; +#endif // ENABLE_FIX_SEAMS_SYNCH // select the subpaths which contains the previous/next segments if (!path.sub_paths[prev_sub_path_id].contains(curr_s_id)) @@ -1760,6 +1822,11 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) } } +#if ENABLE_FIX_SEAMS_SYNCH + // dismiss, no more needed + std::vector().swap(seams_ids); +#endif // ENABLE_FIX_SEAMS_SYNCH + for (MultiVertexBuffer& v_multibuffer : vertices) { for (VertexBuffer& v_buffer : v_multibuffer) { v_buffer.shrink_to_fit(); @@ -1860,8 +1927,18 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) using VboIndexList = std::vector; std::vector vbo_indices(m_buffers.size()); +#if ENABLE_FIX_SEAMS_SYNCH + seams_count = 0; +#endif // ENABLE_FIX_SEAMS_SYNCH + for (size_t i = 0; i < m_moves_count; ++i) { const GCodeProcessor::MoveVertex& curr = gcode_result.moves[i]; +#if ENABLE_FIX_SEAMS_SYNCH + if (curr.type == EMoveType::Seam) + ++seams_count; + + size_t move_id = i - seams_count; +#endif // ENABLE_FIX_SEAMS_SYNCH // skip first vertex if (i == 0) @@ -1912,7 +1989,11 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) if (t_buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::Point) { #endif // ENABLE_SEAMS_USING_BATCHED_MODELS Path& last_path = t_buffer.paths.back(); +#if ENABLE_FIX_SEAMS_SYNCH + last_path.add_sub_path(prev, static_cast(i_multibuffer.size()) - 1, 0, move_id - 1); +#else last_path.add_sub_path(prev, static_cast(i_multibuffer.size()) - 1, 0, i - 1); +#endif // ENABLE_FIX_SEAMS_SYNCH } } @@ -1937,7 +2018,11 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) if (t_buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::Point) { #endif // ENABLE_SEAMS_USING_BATCHED_MODELS Path& last_path = t_buffer.paths.back(); +#if ENABLE_FIX_SEAMS_SYNCH + last_path.add_sub_path(prev, static_cast(i_multibuffer.size()) - 1, 0, move_id - 1); +#else last_path.add_sub_path(prev, static_cast(i_multibuffer.size()) - 1, 0, i - 1); +#endif // ENABLE_FIX_SEAMS_SYNCH } } @@ -1946,17 +2031,29 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) switch (t_buffer.render_primitive_type) { case TBuffer::ERenderPrimitiveType::Point: { +#if ENABLE_FIX_SEAMS_SYNCH + add_indices_as_point(curr, t_buffer, static_cast(i_multibuffer.size()) - 1, i_buffer, move_id); +#else add_indices_as_point(curr, t_buffer, static_cast(i_multibuffer.size()) - 1, i_buffer, i); +#endif // ENABLE_FIX_SEAMS_SYNCH curr_vertex_buffer.second += t_buffer.max_vertices_per_segment(); break; } case TBuffer::ERenderPrimitiveType::Line: { +#if ENABLE_FIX_SEAMS_SYNCH + add_indices_as_line(prev, curr, t_buffer, static_cast(i_multibuffer.size()) - 1, i_buffer, move_id); +#else add_indices_as_line(prev, curr, t_buffer, static_cast(i_multibuffer.size()) - 1, i_buffer, i); +#endif // ENABLE_FIX_SEAMS_SYNCH curr_vertex_buffer.second += t_buffer.max_vertices_per_segment(); break; } case TBuffer::ERenderPrimitiveType::Triangle: { +#if ENABLE_FIX_SEAMS_SYNCH + add_indices_as_solid(prev, curr, next, t_buffer, curr_vertex_buffer.second, static_cast(i_multibuffer.size()) - 1, i_buffer, move_id); +#else add_indices_as_solid(prev, curr, next, t_buffer, curr_vertex_buffer.second, static_cast(i_multibuffer.size()) - 1, i_buffer, i); +#endif // ENABLE_FIX_SEAMS_SYNCH break; } #if ENABLE_SEAMS_USING_BATCHED_MODELS @@ -2051,16 +2148,34 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) // layers zs / roles / extruder ids -> extract from result size_t last_travel_s_id = 0; +#if ENABLE_FIX_SEAMS_SYNCH + seams_count = 0; +#endif // ENABLE_FIX_SEAMS_SYNCH for (size_t i = 0; i < m_moves_count; ++i) { const GCodeProcessor::MoveVertex& move = gcode_result.moves[i]; +#if ENABLE_FIX_SEAMS_SYNCH + if (move.type == EMoveType::Seam) + ++seams_count; + + size_t move_id = i - seams_count; +#endif // ENABLE_FIX_SEAMS_SYNCH + if (move.type == EMoveType::Extrude) { // layers zs const double* const last_z = m_layers.empty() ? nullptr : &m_layers.get_zs().back(); const double z = static_cast(move.position.z()); if (last_z == nullptr || z < *last_z - EPSILON || *last_z + EPSILON < z) +#if ENABLE_FIX_SEAMS_SYNCH + m_layers.append(z, { last_travel_s_id, move_id }); +#else m_layers.append(z, { last_travel_s_id, i }); +#endif // ENABLE_FIX_SEAMS_SYNCH else +#if ENABLE_FIX_SEAMS_SYNCH + m_layers.get_endpoints().back().last = move_id; +#else m_layers.get_endpoints().back().last = i; +#endif // ENABLE_FIX_SEAMS_SYNCH // extruder ids m_extruder_ids.emplace_back(move.extruder_id); // roles @@ -2068,10 +2183,17 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) m_roles.emplace_back(move.extrusion_role); } else if (move.type == EMoveType::Travel) { +#if ENABLE_FIX_SEAMS_SYNCH + if (move_id - last_travel_s_id > 1 && !m_layers.empty()) + m_layers.get_endpoints().back().last = move_id; + + last_travel_s_id = move_id; +#else if (i - last_travel_s_id > 1 && !m_layers.empty()) m_layers.get_endpoints().back().last = i; - + last_travel_s_id = i; +#endif // ENABLE_FIX_SEAMS_SYNCH } } From b382ac854111b0cb028b4ad43ae88f3722367f12 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Thu, 23 Sep 2021 09:56:08 +0200 Subject: [PATCH 02/11] Fixed rendering undo/redo toolbar arrow. --- src/slic3r/GUI/GLCanvas3D.cpp | 19 +++++++++++++++++-- src/slic3r/GUI/GLToolbar.cpp | 11 ++++++++++- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 83b907f01..e2aa6fb7b 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -4427,12 +4427,11 @@ bool GLCanvas3D::_init_main_toolbar() arrow_data.top = 0; arrow_data.right = 0; arrow_data.bottom = 0; - if (!m_main_toolbar.init_arrow(arrow_data)) { BOOST_LOG_TRIVIAL(error) << "Main toolbar failed to load arrow texture."; } - + // m_gizmos is created at constructor, thus we can init arrow here. if (!m_gizmos.init_arrow(arrow_data)) { BOOST_LOG_TRIVIAL(error) << "Gizmos manager failed to load arrow texture."; @@ -4643,6 +4642,18 @@ bool GLCanvas3D::_init_undoredo_toolbar() return true; } + // init arrow + BackgroundTexture::Metadata arrow_data; + arrow_data.filename = "toolbar_arrow.svg"; + arrow_data.left = 0; + arrow_data.top = 0; + arrow_data.right = 0; + arrow_data.bottom = 0; + if (!m_undoredo_toolbar.init_arrow(arrow_data)) + { + BOOST_LOG_TRIVIAL(error) << "Undo/Redo toolbar failed to load arrow texture."; + } + // m_undoredo_toolbar.set_layout_type(GLToolbar::Layout::Vertical); m_undoredo_toolbar.set_layout_type(GLToolbar::Layout::Horizontal); m_undoredo_toolbar.set_horizontal_orientation(GLToolbar::Layout::HO_Left); @@ -5376,6 +5387,10 @@ void GLCanvas3D::_render_undoredo_toolbar() m_undoredo_toolbar.set_position(top, left); m_undoredo_toolbar.render(*this); + if (m_toolbar_highlighter.m_render_arrow) + { + m_undoredo_toolbar.render_arrow(*this, m_toolbar_highlighter.m_toolbar_item); + } } void GLCanvas3D::_render_collapse_toolbar() const diff --git a/src/slic3r/GUI/GLToolbar.cpp b/src/slic3r/GUI/GLToolbar.cpp index cea68eaaa..86827442d 100644 --- a/src/slic3r/GUI/GLToolbar.cpp +++ b/src/slic3r/GUI/GLToolbar.cpp @@ -1143,6 +1143,10 @@ void GLToolbar::render_background(float left, float top, float right, float bott void GLToolbar::render_arrow(const GLCanvas3D& parent, GLToolbarItem* highlighted_item) { + // arrow texture not initialized + if (m_arrow_texture.texture.get_id() == 0) + return; + float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom(); float factor = inv_zoom * m_layout.scale; @@ -1157,6 +1161,7 @@ void GLToolbar::render_arrow(const GLCanvas3D& parent, GLToolbarItem* highlighte float left = m_layout.left; float top = m_layout.top - icon_stride; + bool found = false; for (const GLToolbarItem* item : m_items) { if (!item->is_visible()) continue; @@ -1164,11 +1169,15 @@ void GLToolbar::render_arrow(const GLCanvas3D& parent, GLToolbarItem* highlighte if (item->is_separator()) left += separator_stride; else { - if (item->get_name() == highlighted_item->get_name()) + if (item->get_name() == highlighted_item->get_name()) { + found = true; break; + } left += icon_stride; } } + if (!found) + return; left += border; top -= separator_stride; From 1f82714159a7061be086c18d883ebb5982de2ed1 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Thu, 23 Sep 2021 11:15:08 +0200 Subject: [PATCH 03/11] Blacklisted AMHook.dll --- src/libslic3r/BlacklistedLibraryCheck.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libslic3r/BlacklistedLibraryCheck.cpp b/src/libslic3r/BlacklistedLibraryCheck.cpp index 76f675c70..938f54249 100644 --- a/src/libslic3r/BlacklistedLibraryCheck.cpp +++ b/src/libslic3r/BlacklistedLibraryCheck.cpp @@ -12,7 +12,7 @@ namespace Slic3r { #ifdef WIN32 //only dll name with .dll suffix - currently case sensitive -const std::vector BlacklistedLibraryCheck::blacklist({ L"NahimicOSD.dll", L"SS2OSD.dll" }); +const std::vector BlacklistedLibraryCheck::blacklist({ L"NahimicOSD.dll", L"SS2OSD.dll", L"amhook.dll", L"AMHook.dll" }); bool BlacklistedLibraryCheck::get_blacklisted(std::vector& names) { From d7216b5d68766f5ba9aee838deaa60929027c26b Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 23 Sep 2021 11:51:30 +0200 Subject: [PATCH 04/11] Follow-up of f71cf324b9770fc9d9cc26510d1bbaac43cdbbd7 - Fixed shown tool position --- src/slic3r/GUI/GCodeViewer.cpp | 34 +++++++++++++++++++++++++++++++++- src/slic3r/GUI/GCodeViewer.hpp | 19 +++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 397e9aa03..e8a737957 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -267,7 +267,12 @@ void GCodeViewer::SequentialView::Marker::render() const imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, _u8L("Tool position") + ":"); ImGui::SameLine(); char buf[1024]; - sprintf(buf, "X: %.3f, Y: %.3f, Z: %.3f", m_world_position(0), m_world_position(1), m_world_position(2)); +#if ENABLE_FIX_SEAMS_SYNCH + const Vec3f position = m_world_position + m_world_offset; + sprintf(buf, "X: %.3f, Y: %.3f, Z: %.3f", position.x(), position.y(), position.z()); +#else + sprintf(buf, "X: %.3f, Y: %.3f, Z: %.3f", m_world_position.x(), m_world_position.y(), m_world_position.z()); +#endif // ENABLE_FIX_SEAMS_SYNCH imgui.text(std::string(buf)); // force extra frame to automatically update window size @@ -862,6 +867,9 @@ void GCodeViewer::render() render_legend(legend_height); if (m_sequential_view.current.last != m_sequential_view.endpoints.last) { m_sequential_view.marker.set_world_position(m_sequential_view.current_position); +#if ENABLE_FIX_SEAMS_SYNCH + m_sequential_view.marker.set_world_offset(m_sequential_view.current_offset); +#endif // ENABLE_FIX_SEAMS_SYNCH m_sequential_view.render(legend_height); } #if ENABLE_GCODE_VIEWER_STATISTICS @@ -1519,6 +1527,9 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) std::vector instances(m_buffers.size()); std::vector instances_ids(m_buffers.size()); #endif // ENABLE_SEAMS_USING_MODELS +#if ENABLE_FIX_SEAMS_SYNCH + std::vector instances_offsets(m_buffers.size()); +#endif // ENABLE_FIX_SEAMS_SYNCH std::vector options_zs; #if ENABLE_FIX_SEAMS_SYNCH @@ -1559,6 +1570,9 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) #if ENABLE_SEAMS_USING_MODELS InstanceBuffer& inst_buffer = instances[id]; InstanceIdBuffer& inst_id_buffer = instances_ids[id]; +#if ENABLE_FIX_SEAMS_SYNCH + InstancesOffsets& inst_offsets = instances_offsets[id]; +#endif // ENABLE_FIX_SEAMS_SYNCH #endif // ENABLE_SEAMS_USING_MODELS // ensure there is at least one vertex buffer @@ -1602,6 +1616,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) { #if ENABLE_FIX_SEAMS_SYNCH add_model_instance(curr, inst_buffer, inst_id_buffer, move_id); + inst_offsets.push_back(prev.position - curr.position); #else add_model_instance(curr, inst_buffer, inst_id_buffer, i); #endif // ENABLE_FIX_SEAMS_SYNCH @@ -1614,6 +1629,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) { #if ENABLE_FIX_SEAMS_SYNCH add_vertices_as_model_batch(curr, t_buffer.model.data, v_buffer, inst_buffer, inst_id_buffer, move_id); + inst_offsets.push_back(prev.position - curr.position); #else add_vertices_as_model_batch(curr, t_buffer.model.data, v_buffer, inst_buffer, inst_id_buffer, i); #endif // ENABLE_FIX_SEAMS_SYNCH @@ -1851,6 +1867,9 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) if (!inst_buffer.empty()) { t_buffer.model.instances.buffer = inst_buffer; t_buffer.model.instances.s_ids = instances_ids[i]; +#if ENABLE_FIX_SEAMS_SYNCH + t_buffer.model.instances.offsets = instances_offsets[i]; +#endif // ENABLE_FIX_SEAMS_SYNCH } } else { @@ -1859,6 +1878,9 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) if (!inst_buffer.empty()) { t_buffer.model.instances.buffer = inst_buffer; t_buffer.model.instances.s_ids = instances_ids[i]; +#if ENABLE_FIX_SEAMS_SYNCH + t_buffer.model.instances.offsets = instances_offsets[i]; +#endif // ENABLE_FIX_SEAMS_SYNCH } } #else @@ -1867,6 +1889,9 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) if (!inst_buffer.empty()) { t_buffer.model.instances.buffer = inst_buffer; t_buffer.model.instances.s_ids = instances_ids[i]; +#if ENABLE_FIX_SEAMS_SYNCH + t_buffer.model.instances.offsets = instances_offsets[i]; +#endif // ENABLE_FIX_SEAMS_SYNCH } } else { @@ -2464,6 +2489,9 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool sequential_view->current_position.x() = buffer.model.instances.buffer[offset + 0]; sequential_view->current_position.y() = buffer.model.instances.buffer[offset + 1]; sequential_view->current_position.z() = buffer.model.instances.buffer[offset + 2]; +#if ENABLE_FIX_SEAMS_SYNCH + sequential_view->current_offset = buffer.model.instances.offsets[i]; +#endif // ENABLE_FIX_SEAMS_SYNCH found = true; break; @@ -2503,6 +2531,10 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool glsafe(::glGetBufferSubData(GL_ARRAY_BUFFER, static_cast(index * buffer.vertices.vertex_size_bytes()), static_cast(3 * sizeof(float)), static_cast(sequential_view->current_position.data()))); glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); +#if ENABLE_FIX_SEAMS_SYNCH + sequential_view->current_offset = Vec3f::Zero(); +#endif // ENABLE_FIX_SEAMS_SYNCH + found = true; break; } diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 0d5552d67..6c164f5e8 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -31,6 +31,9 @@ class GCodeViewer using InstanceBuffer = std::vector; using InstanceIdBuffer = std::vector; #endif // ENABLE_SEAMS_USING_MODELS +#if ENABLE_FIX_SEAMS_SYNCH + using InstancesOffsets = std::vector; +#endif // ENABLE_FIX_SEAMS_SYNCH static const std::vector Extrusion_Role_Colors; static const std::vector Options_Colors; @@ -151,6 +154,10 @@ class GCodeViewer InstanceBuffer buffer; // indices of the moves for all instances std::vector s_ids; +#if ENABLE_FIX_SEAMS_SYNCH + // position offsets, used to show the correct value of the tool position + InstancesOffsets offsets; +#endif // ENABLE_FIX_SEAMS_SYNCH Ranges render_ranges; size_t data_size_bytes() const { return s_ids.size() * instance_size_bytes(); } @@ -665,6 +672,12 @@ public: GLModel m_model; Vec3f m_world_position; Transform3f m_world_transform; +#if ENABLE_FIX_SEAMS_SYNCH + // for seams, the position of the marker is on the last endpoint of the toolpath containing it + // the offset is used to show the correct value of tool position in the "ToolPosition" window + // see implementation of render() method + Vec3f m_world_offset; +#endif // ENABLE_FIX_SEAMS_SYNCH float m_z_offset{ 0.5f }; bool m_visible{ true }; @@ -674,6 +687,9 @@ public: const BoundingBoxf3& get_bounding_box() const { return m_model.get_bounding_box(); } void set_world_position(const Vec3f& position); +#if ENABLE_FIX_SEAMS_SYNCH + void set_world_offset(const Vec3f& offset) { m_world_offset = offset; } +#endif // ENABLE_FIX_SEAMS_SYNCH bool is_visible() const { return m_visible; } void set_visible(bool visible) { m_visible = visible; } @@ -731,6 +747,9 @@ public: Endpoints global; #endif // ENABLE_SEAMS_USING_MODELS Vec3f current_position{ Vec3f::Zero() }; +#if ENABLE_FIX_SEAMS_SYNCH + Vec3f current_offset{ Vec3f::Zero() }; +#endif // ENABLE_FIX_SEAMS_SYNCH Marker marker; GCodeWindow gcode_window; std::vector gcode_ids; From 683cb4245440fc8926e39bf4b24f42073ab43e35 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 23 Sep 2021 12:21:56 +0200 Subject: [PATCH 05/11] Fix for #6941 - Search Settings: Put focus into input field when navigating to the setting --- src/slic3r/GUI/Plater.cpp | 2 ++ src/slic3r/GUI/Search.cpp | 15 +++++++++++---- src/slic3r/GUI/Search.hpp | 2 ++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 9e7409c11..a71fb1448 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1920,6 +1920,8 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) sidebar->Bind(wxEVT_COMBOBOX, &priv::on_select_preset, this); sidebar->Bind(EVT_OBJ_LIST_OBJECT_SELECT, [this](wxEvent&) { priv::selection_changed(); }); sidebar->Bind(EVT_SCHEDULE_BACKGROUND_PROCESS, [this](SimpleEvent&) { this->schedule_background_process(); }); + // jump to found option from SearchDialog + q->Bind(wxCUSTOMEVT_JUMP_TO_OPTION, [this](wxCommandEvent& evt) { sidebar->jump_to_option(evt.GetInt()); }); } wxGLCanvas* view3D_canvas = view3D->get_wxglcanvas(); diff --git a/src/slic3r/GUI/Search.cpp b/src/slic3r/GUI/Search.cpp index 000ebf402..1e37dc372 100644 --- a/src/slic3r/GUI/Search.cpp +++ b/src/slic3r/GUI/Search.cpp @@ -24,6 +24,8 @@ using boost::optional; namespace Slic3r { +wxDEFINE_EVENT(wxCUSTOMEVT_JUMP_TO_OPTION, wxCommandEvent); + using GUI::from_u8; using GUI::into_u8; @@ -293,8 +295,6 @@ OptionsSearcher::OptionsSearcher() OptionsSearcher::~OptionsSearcher() { - if (search_dialog) - search_dialog->Destroy(); } void OptionsSearcher::init(std::vector input_values) @@ -530,9 +530,16 @@ void SearchDialog::ProcessSelection(wxDataViewItem selection) { if (!selection.IsOk()) return; - - GUI::wxGetApp().sidebar().jump_to_option(search_list_model->GetRow(selection)); this->EndModal(wxID_CLOSE); + + // If call GUI::wxGetApp().sidebar.jump_to_option() directly from here, + // then mainframe will not have focus and found option will not be "active" (have cursor) as a result + // SearchDialog have to be closed and have to lose a focus + // and only after that jump_to_option() function can be called + // So, post event to plater: + wxCommandEvent event(wxCUSTOMEVT_JUMP_TO_OPTION); + event.SetInt(search_list_model->GetRow(selection)); + wxPostEvent(GUI::wxGetApp().plater(), event); } void SearchDialog::OnInputText(wxCommandEvent&) diff --git a/src/slic3r/GUI/Search.hpp b/src/slic3r/GUI/Search.hpp index 99575e1fa..19de58f96 100644 --- a/src/slic3r/GUI/Search.hpp +++ b/src/slic3r/GUI/Search.hpp @@ -22,6 +22,8 @@ namespace Slic3r { +wxDECLARE_EVENT(wxCUSTOMEVT_JUMP_TO_OPTION, wxCommandEvent); + namespace Search{ class SearchDialog; From 6ca474192f35508438b6737df5c6688af19b888b Mon Sep 17 00:00:00 2001 From: David Kocik Date: Thu, 23 Sep 2021 15:01:19 +0200 Subject: [PATCH 06/11] Fix of hidden progress bar in progress indicator notification --- src/slic3r/GUI/NotificationManager.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/slic3r/GUI/NotificationManager.cpp b/src/slic3r/GUI/NotificationManager.cpp index bf43b7645..559ee283f 100644 --- a/src/slic3r/GUI/NotificationManager.cpp +++ b/src/slic3r/GUI/NotificationManager.cpp @@ -1388,6 +1388,7 @@ bool NotificationManager::ProgressIndicatorNotification::update_state(bool pause // percentage was changed (and it called schedule_extra_frame), now update must know this needs render m_next_render = 0; m_progress_state = ProgressIndicatorState::PIS_PROGRESS_UPDATED; + m_current_fade_opacity = 1.0f; return true; } bool ret = ProgressBarNotification::update_state(paused, delta); From 853a5846ececadd7659148c1758afb574cfe48b5 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 23 Sep 2021 15:39:32 +0200 Subject: [PATCH 07/11] Fix for #6993 - Small hieght combobox in "Settings tab as menu items" --- src/slic3r/GUI/Tab.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 4ee733942..6b7044b0d 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -501,6 +501,8 @@ void Tab::OnActivate() m_presets_choice->SetMinSize(ok_sz); m_presets_choice->SetSize(ok_sz); GetSizer()->GetItem(size_t(0))->GetSizer()->Layout(); + if (wxGetApp().tabs_as_menu()) + m_presets_choice->update(); } #endif // _MSW_DARK_MODE Refresh(); From cd4c29b1e59e51b4975bf8dec251b3f55ee7397e Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 23 Sep 2021 16:02:44 +0200 Subject: [PATCH 08/11] MSW specific: Fix for #6938 - Cycling through tabs using Ctrl+PageUp/Down doesn't work OnNavigationKey() function is copied from wxNotebook to Notebook --- src/slic3r/GUI/Notebook.hpp | 86 +++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/src/slic3r/GUI/Notebook.hpp b/src/slic3r/GUI/Notebook.hpp index 56ae5b285..ff5020b9c 100644 --- a/src/slic3r/GUI/Notebook.hpp +++ b/src/slic3r/GUI/Notebook.hpp @@ -84,6 +84,9 @@ public: if (int page_idx = evt.GetId(); page_idx >= 0) SetSelection(page_idx); }); + + this->Bind(wxEVT_NAVIGATION_KEY, &Notebook::OnNavigationKey, this); + return true; } @@ -242,6 +245,89 @@ public: GetBtnsListCtrl()->Rescale(); } + void Notebook::OnNavigationKey(wxNavigationKeyEvent& event) + { + if (event.IsWindowChange()) { + // change pages + AdvanceSelection(event.GetDirection()); + } + else { + // we get this event in 3 cases + // + // a) one of our pages might have generated it because the user TABbed + // out from it in which case we should propagate the event upwards and + // our parent will take care of setting the focus to prev/next sibling + // + // or + // + // b) the parent panel wants to give the focus to us so that we + // forward it to our selected page. We can't deal with this in + // OnSetFocus() because we don't know which direction the focus came + // from in this case and so can't choose between setting the focus to + // first or last panel child + // + // or + // + // c) we ourselves (see MSWTranslateMessage) generated the event + // + wxWindow* const parent = GetParent(); + + // the wxObject* casts are required to avoid MinGW GCC 2.95.3 ICE + const bool isFromParent = event.GetEventObject() == (wxObject*)parent; + const bool isFromSelf = event.GetEventObject() == (wxObject*)this; + const bool isForward = event.GetDirection(); + + if (isFromSelf && !isForward) + { + // focus is currently on notebook tab and should leave + // it backwards (Shift-TAB) + event.SetCurrentFocus(this); + parent->HandleWindowEvent(event); + } + else if (isFromParent || isFromSelf) + { + // no, it doesn't come from child, case (b) or (c): forward to a + // page but only if entering notebook page (i.e. direction is + // backwards (Shift-TAB) comething from out-of-notebook, or + // direction is forward (TAB) from ourselves), + if (m_selection != wxNOT_FOUND && + (!event.GetDirection() || isFromSelf)) + { + // so that the page knows that the event comes from it's parent + // and is being propagated downwards + event.SetEventObject(this); + + wxWindow* page = m_pages[m_selection]; + if (!page->HandleWindowEvent(event)) + { + page->SetFocus(); + } + //else: page manages focus inside it itself + } + else // otherwise set the focus to the notebook itself + { + SetFocus(); + } + } + else + { + // it comes from our child, case (a), pass to the parent, but only + // if the direction is forwards. Otherwise set the focus to the + // notebook itself. The notebook is always the 'first' control of a + // page. + if (!isForward) + { + SetFocus(); + } + else if (parent) + { + event.SetCurrentFocus(this); + parent->HandleWindowEvent(event); + } + } + } + } + protected: virtual void UpdateSelectedPage(size_t WXUNUSED(newsel)) override { From 976ef2c1b937a7a415a1bb462930ba3c0b44d218 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Thu, 23 Sep 2021 15:48:05 +0200 Subject: [PATCH 09/11] Progress bar notifications and Export finished notification changes. Export Finished notification ejecting state. Slicing began state in progress notification. Timing of progress bar notifications. Progress indicator disappears instantly at 100%. While slicing goes into Slicing Finished without fade out. Preventing of negative growth of slicing progress bar. Slicing progress bar - Negative percent value means now No info rather than Canceled. Hiding slicing progress at printer technology change. --- src/slic3r/GUI/NotificationManager.cpp | 126 +++++++++++++++++-------- src/slic3r/GUI/NotificationManager.hpp | 21 +++-- src/slic3r/GUI/Plater.cpp | 7 +- 3 files changed, 107 insertions(+), 47 deletions(-) diff --git a/src/slic3r/GUI/NotificationManager.cpp b/src/slic3r/GUI/NotificationManager.cpp index 559ee283f..1b08e6cd2 100644 --- a/src/slic3r/GUI/NotificationManager.cpp +++ b/src/slic3r/GUI/NotificationManager.cpp @@ -593,7 +593,7 @@ bool NotificationManager::PopNotification::update_state(bool paused, const int64 m_state = EState::Unknown; init(); // Timers when not fading - } else if (m_state != EState::NotFading && m_state != EState::FadingOut && get_duration() != 0 && !paused) { + } else if (m_state != EState::NotFading && m_state != EState::FadingOut && m_state != EState::ClosePending && m_state != EState::Finished && get_duration() != 0 && !paused) { int64_t up_time = now - m_notification_start; if (up_time >= get_duration() * 1000) { m_state = EState::FadingOut; @@ -633,6 +633,10 @@ bool NotificationManager::PopNotification::update_state(bool paused, const int64 //---------------ExportFinishedNotification----------- void NotificationManager::ExportFinishedNotification::count_spaces() { + if (m_eject_pending) + { + return PopNotification::count_spaces(); + } //determine line width m_line_height = ImGui::CalcTextSize("A").y; @@ -650,7 +654,10 @@ void NotificationManager::ExportFinishedNotification::count_spaces() void NotificationManager::ExportFinishedNotification::render_text(ImGuiWrapper& imgui, const float win_size_x, const float win_size_y, const float win_pos_x, const float win_pos_y) { - + if (m_eject_pending) + { + return PopNotification::render_text(imgui, win_size_x, win_size_y, win_pos_x, win_pos_y); + } float x_offset = m_left_indentation; std::string fulltext = m_text1 + m_hypertext; //+ m_text2; // Lines are always at least two and m_multiline is always true for ExportFinishedNotification. @@ -669,7 +676,7 @@ void NotificationManager::ExportFinishedNotification::render_text(ImGuiWrapper& ImGui::SetCursorPosY(starting_y + i * shift_y); imgui.text(line.c_str()); //hyperlink text - if ( i == 0 ) { + if ( i == 0 && !m_eject_pending) { render_hypertext(imgui, x_offset + ImGui::CalcTextSize(line.c_str()).x + ImGui::CalcTextSize(" ").x, starting_y, _u8L("Open Folder.")); } } @@ -680,7 +687,7 @@ void NotificationManager::ExportFinishedNotification::render_text(ImGuiWrapper& void NotificationManager::ExportFinishedNotification::render_close_button(ImGuiWrapper& imgui, const float win_size_x, const float win_size_y, const float win_pos_x, const float win_pos_y) { PopNotification::render_close_button(imgui, win_size_x, win_size_y, win_pos_x, win_pos_y); - if(m_to_removable) + if(m_to_removable && ! m_eject_pending) render_eject_button(imgui, win_size_x, win_size_y, win_pos_x, win_pos_y); } @@ -725,7 +732,7 @@ void NotificationManager::ExportFinishedNotification::render_eject_button(ImGuiW assert(m_evt_handler != nullptr); if (m_evt_handler != nullptr) wxPostEvent(m_evt_handler, EjectDriveNotificationClickedEvent(EVT_EJECT_DRIVE_NOTIFICAION_CLICKED)); - close(); + on_eject_click(); } //invisible large button @@ -736,7 +743,7 @@ void NotificationManager::ExportFinishedNotification::render_eject_button(ImGuiW assert(m_evt_handler != nullptr); if (m_evt_handler != nullptr) wxPostEvent(m_evt_handler, EjectDriveNotificationClickedEvent(EVT_EJECT_DRIVE_NOTIFICAION_CLICKED)); - close(); + on_eject_click(); } ImGui::PopStyleColor(5); } @@ -745,6 +752,14 @@ bool NotificationManager::ExportFinishedNotification::on_text_click() open_folder(m_export_dir_path); return false; } +void NotificationManager::ExportFinishedNotification::on_eject_click() +{ + NotificationData data{ get_data().type, get_data().level , 0, _utf8("Ejecting.") }; + m_eject_pending = true; + m_multiline = false; + update(data); +} + //------ProgressBar---------------- void NotificationManager::ProgressBarNotification::init() { @@ -1071,7 +1086,7 @@ void NotificationManager::UpdatedItemsInfoNotification::render_left_sign(ImGuiWr imgui.text(text.c_str()); } -//------SlicingProgressNotificastion +//------SlicingProgressNotification void NotificationManager::SlicingProgressNotification::init() { if (m_sp_state == SlicingProgressState::SP_PROGRESS) { @@ -1084,46 +1099,53 @@ void NotificationManager::SlicingProgressNotification::init() } } -void NotificationManager::SlicingProgressNotification::set_progress_state(float percent) +bool NotificationManager::SlicingProgressNotification::set_progress_state(float percent) { if (percent < 0.f) - set_progress_state(SlicingProgressState::SP_CANCELLED); + return true;//set_progress_state(SlicingProgressState::SP_CANCELLED); else if (percent >= 1.f) - set_progress_state(SlicingProgressState::SP_COMPLETED); + return set_progress_state(SlicingProgressState::SP_COMPLETED); else - set_progress_state(SlicingProgressState::SP_PROGRESS, percent); + return set_progress_state(SlicingProgressState::SP_PROGRESS, percent); } -void NotificationManager::SlicingProgressNotification::set_progress_state(NotificationManager::SlicingProgressNotification::SlicingProgressState state, float percent/* = 0.f*/) +bool NotificationManager::SlicingProgressNotification::set_progress_state(NotificationManager::SlicingProgressNotification::SlicingProgressState state, float percent/* = 0.f*/) { switch (state) { case Slic3r::GUI::NotificationManager::SlicingProgressNotification::SlicingProgressState::SP_NO_SLICING: + case Slic3r::GUI::NotificationManager::SlicingProgressNotification::SlicingProgressState::SP_BEGAN: m_state = EState::Hidden; set_percentage(-1); m_has_print_info = false; set_export_possible(false); - break; + m_sp_state = state; + return true; case Slic3r::GUI::NotificationManager::SlicingProgressNotification::SlicingProgressState::SP_PROGRESS: + if ((m_sp_state != SlicingProgressState::SP_BEGAN && m_sp_state != SlicingProgressState::SP_PROGRESS) || percent < m_percentage) + return false; set_percentage(percent); m_has_cancel_button = true; - break; + m_sp_state = state; + return true; case Slic3r::GUI::NotificationManager::SlicingProgressNotification::SlicingProgressState::SP_CANCELLED: set_percentage(-1); m_has_cancel_button = false; m_has_print_info = false; set_export_possible(false); - break; + m_sp_state = state; + return true; case Slic3r::GUI::NotificationManager::SlicingProgressNotification::SlicingProgressState::SP_COMPLETED: set_percentage(1); m_has_cancel_button = false; m_has_print_info = false; - // m_export_possible is important only for PROGRESS state, thus we can reset it here + // m_export_possible is important only for SP_PROGRESS state, thus we can reset it here set_export_possible(false); - break; + m_sp_state = state; + return true; default: break; } - m_sp_state = state; + return false; } void NotificationManager::SlicingProgressNotification::set_status_text(const std::string& text) { @@ -1150,7 +1172,7 @@ void NotificationManager::SlicingProgressNotification::set_status_text(const std { NotificationData data{ NotificationType::SlicingProgress, NotificationLevel::ProgressBarNotificationLevel, 0, _u8L("Slicing finished."), m_is_fff ? _u8L("Export G-Code.") : _u8L("Export.") }; update(data); - m_state = EState::Shown; + m_state = EState::NotFading; } break; default: @@ -1170,7 +1192,7 @@ void NotificationManager::SlicingProgressNotification::set_sidebar_collapsed(boo { m_sidebar_collapsed = collapsed; if (m_sp_state == SlicingProgressState::SP_COMPLETED) - m_state = EState::Shown; + m_state = EState::NotFading; } void NotificationManager::SlicingProgressNotification::on_cancel_button() @@ -1184,9 +1206,9 @@ void NotificationManager::SlicingProgressNotification::on_cancel_button() int NotificationManager::SlicingProgressNotification::get_duration() { if (m_sp_state == SlicingProgressState::SP_CANCELLED) - return 10; + return 2; else if (m_sp_state == SlicingProgressState::SP_COMPLETED && !m_sidebar_collapsed) - return 5; + return 0; else return 0; } @@ -1200,7 +1222,7 @@ bool NotificationManager::SlicingProgressNotification::update_state(bool paused } void NotificationManager::SlicingProgressNotification::render_text(ImGuiWrapper& imgui, const float win_size_x, const float win_size_y, const float win_pos_x, const float win_pos_y) { - if (m_sp_state == SlicingProgressState::SP_PROGRESS || (m_sp_state == SlicingProgressState::SP_COMPLETED && !m_sidebar_collapsed)) { + if (m_sp_state == SlicingProgressState::SP_PROGRESS /*|| (m_sp_state == SlicingProgressState::SP_COMPLETED && !m_sidebar_collapsed)*/) { ProgressBarNotification::render_text(imgui, win_size_x, win_size_y, win_pos_x, win_pos_y); /* // enable for hypertext during slicing (correct call of export_enabled needed) if (m_multiline) { @@ -1235,7 +1257,7 @@ void NotificationManager::SlicingProgressNotification::render_text(ImGuiWrapper& render_bar(imgui, win_size_x, win_size_y, win_pos_x, win_pos_y); } */ - } else if (m_sp_state == SlicingProgressState::SP_COMPLETED) { + } else if (m_sp_state == SlicingProgressState::SP_COMPLETED && m_sidebar_collapsed) { // "Slicing Finished" on line 1 + hypertext, print info on line ImVec2 win_size(win_size_x, win_size_y); ImVec2 text1_size = ImGui::CalcTextSize(m_text1.c_str()); @@ -1260,21 +1282,18 @@ void NotificationManager::SlicingProgressNotification::render_text(ImGuiWrapper& PopNotification::render_text(imgui, win_size_x, win_size_y, win_pos_x, win_pos_y); } } -void NotificationManager::SlicingProgressNotification::render_bar(ImGuiWrapper& imgui, const float win_size_x, const float win_size_y, const float win_pos_x, const float win_pos_y) +void NotificationManager::SlicingProgressNotification::render_bar(ImGuiWrapper& imgui, const float win_size_x, const float win_size_y, const float win_pos_x, const float win_pos_y) { - if (!(m_sp_state == SlicingProgressState::SP_PROGRESS || (m_sp_state == SlicingProgressState::SP_COMPLETED && !m_sidebar_collapsed))) { + if (m_sp_state != SlicingProgressState::SP_PROGRESS) { return; } - //std::string text; ProgressBarNotification::render_bar(imgui, win_size_x, win_size_y, win_pos_x, win_pos_y); - /* - std::stringstream stream; - stream << std::fixed << std::setprecision(2) << (int)(m_percentage * 100) << "%"; - text = stream.str(); - ImGui::SetCursorPosX(m_left_indentation); - ImGui::SetCursorPosY(win_size_y / 2 + win_size_y / 6 - (m_multiline ? 0 : m_line_height / 4)); - imgui.text(text.c_str()); - */ +} +void NotificationManager::SlicingProgressNotification::render_hypertext(ImGuiWrapper& imgui,const float text_x, const float text_y, const std::string text, bool more) +{ + if (m_sp_state == SlicingProgressState::SP_COMPLETED && !m_sidebar_collapsed) + return; + ProgressBarNotification::render_hypertext(imgui, text_x, text_y, text, more); } void NotificationManager::SlicingProgressNotification::render_cancel_button(ImGuiWrapper& imgui, const float win_size_x, const float win_size_y, const float win_pos_x, const float win_pos_y) { @@ -1360,7 +1379,7 @@ void NotificationManager::ProgressIndicatorNotification::init() m_state = EState::NotFading; break; case Slic3r::GUI::NotificationManager::ProgressIndicatorNotification::ProgressIndicatorState::PIS_COMPLETED: - m_state = EState::Shown; + m_state = EState::ClosePending; break; default: break; @@ -1374,7 +1393,7 @@ void NotificationManager::ProgressIndicatorNotification::set_percentage(float pe m_has_cancel_button = true; m_progress_state = ProgressIndicatorState::PIS_PROGRESS_REQUEST; } else if (percent >= 1.0f) { - m_state = EState::Shown; + m_state = EState::FadingOut; m_progress_state = ProgressIndicatorState::PIS_COMPLETED; m_has_cancel_button = false; } else { @@ -1629,6 +1648,7 @@ void NotificationManager::push_exporting_finished_notification(const std::string close_notification_of_type(NotificationType::ExportFinished); NotificationData data{ NotificationType::ExportFinished, NotificationLevel::RegularNotificationLevel, on_removable ? 0 : 20, _u8L("Exporting finished.") + "\n" + path }; push_notification_data(std::make_unique(data, m_id_provider, m_evt_handler, on_removable, path, dir_path), 0); + set_slicing_progress_hidden(); } void NotificationManager::push_upload_job_notification(int id, float filesize, const std::string& filename, const std::string& host, float percentage) @@ -1701,12 +1721,39 @@ void NotificationManager::init_slicing_progress_notification(std::function(data, m_id_provider, m_evt_handler, cancel_callback), 0); } +void NotificationManager::set_slicing_progress_began() +{ + for (std::unique_ptr & notification : m_pop_notifications) { + if (notification->get_type() == NotificationType::SlicingProgress) { + SlicingProgressNotification* spn = dynamic_cast(notification.get()); + spn->set_progress_state(SlicingProgressNotification::SlicingProgressState::SP_BEGAN); + return; + } + } + // Slicing progress notification was not found - init it thru plater so correct cancel callback function is appended + wxGetApp().plater()->init_notification_manager(); +} void NotificationManager::set_slicing_progress_percentage(const std::string& text, float percentage) { for (std::unique_ptr& notification : m_pop_notifications) { if (notification->get_type() == NotificationType::SlicingProgress) { SlicingProgressNotification* spn = dynamic_cast(notification.get()); - spn->set_progress_state(percentage); + if(spn->set_progress_state(percentage)) { + spn->set_status_text(text); + wxGetApp().plater()->get_current_canvas3D()->schedule_extra_frame(0); + } + return; + } + } + // Slicing progress notification was not found - init it thru plater so correct cancel callback function is appended + wxGetApp().plater()->init_notification_manager(); +} +void NotificationManager::set_slicing_progress_canceled(const std::string& text) +{ + for (std::unique_ptr& notification : m_pop_notifications) { + if (notification->get_type() == NotificationType::SlicingProgress) { + SlicingProgressNotification* spn = dynamic_cast(notification.get()); + spn->set_progress_state(SlicingProgressNotification::SlicingProgressState::SP_CANCELLED); spn->set_status_text(text); wxGetApp().plater()->get_current_canvas3D()->schedule_extra_frame(0); return; @@ -1715,7 +1762,6 @@ void NotificationManager::set_slicing_progress_percentage(const std::string& tex // Slicing progress notification was not found - init it thru plater so correct cancel callback function is appended wxGetApp().plater()->init_notification_manager(); } - void NotificationManager::set_slicing_progress_hidden() { for (std::unique_ptr& notification : m_pop_notifications) { @@ -1773,7 +1819,7 @@ void NotificationManager::init_progress_indicator() return; } } - NotificationData data{ NotificationType::ProgressIndicator, NotificationLevel::ProgressBarNotificationLevel, 2}; + NotificationData data{ NotificationType::ProgressIndicator, NotificationLevel::ProgressBarNotificationLevel, 1}; auto notification = std::make_unique(data, m_id_provider, m_evt_handler); push_notification_data(std::move(notification), 0); } diff --git a/src/slic3r/GUI/NotificationManager.hpp b/src/slic3r/GUI/NotificationManager.hpp index ee510b112..4481ed701 100644 --- a/src/slic3r/GUI/NotificationManager.hpp +++ b/src/slic3r/GUI/NotificationManager.hpp @@ -189,8 +189,10 @@ public: void upload_job_notification_show_error(int id, const std::string& filename, const std::string& host); // slicing progress void init_slicing_progress_notification(std::function cancel_callback); + void set_slicing_progress_began(); // percentage negative = canceled, <0-1) = progress, 1 = completed void set_slicing_progress_percentage(const std::string& text, float percentage); + void set_slicing_progress_canceled(const std::string& text); // hides slicing progress notification imidietly void set_slicing_progress_hidden(); // Add a print time estimate to an existing SlicingProgress notification. Set said notification to SP_COMPLETED state. @@ -492,6 +494,7 @@ private: enum class SlicingProgressState { SP_NO_SLICING, // hidden + SP_BEGAN, // still hidden but allows to go to SP_PROGRESS state. This prevents showing progress after slicing was canceled. SP_PROGRESS, // never fades outs, no close button, has cancel button SP_CANCELLED, // fades after 10 seconds, simple message SP_COMPLETED // Has export hyperlink and print info, fades after 20 sec if sidebar is shown, otherwise no fade out @@ -509,10 +512,10 @@ private: // sets cancel button callback void set_cancel_callback(std::function callback) { m_cancel_callback = callback; } bool has_cancel_callback() const { return m_cancel_callback != nullptr; } - // sets SlicingProgressState, negative percent means canceled - void set_progress_state(float percent); - // sets SlicingProgressState, percent is used only at progress state. - void set_progress_state(SlicingProgressState state,float percent = 0.f); + // sets SlicingProgressState, negative percent means canceled, returns true if state was set succesfully. + bool set_progress_state(float percent); + // sets SlicingProgressState, percent is used only at progress state. Returns true if state was set succesfully. + bool set_progress_state(SlicingProgressState state,float percent = 0.f); // sets additional string of print info and puts notification into Completed state. void set_print_info(const std::string& info); // sets fading if in Completed state. @@ -541,8 +544,12 @@ private: const float win_size_x, const float win_size_y, const float win_pos_x, const float win_pos_y) override; void render_close_button(ImGuiWrapper& imgui, - const float win_size_x, const float win_size_y, - const float win_pos_x, const float win_pos_y) override; + const float win_size_x, const float win_size_y, + const float win_pos_x, const float win_pos_y) override; + void render_hypertext(ImGuiWrapper& imgui, + const float text_x, const float text_y, + const std::string text, + bool more = false) override ; void on_cancel_button(); int get_duration() override; // if returns false, process was already canceled @@ -626,8 +633,10 @@ private: void render_minimize_button(ImGuiWrapper& imgui, const float win_pos_x, const float win_pos_y) override { m_minimize_b_visible = false; } bool on_text_click() override; + void on_eject_click(); // local time of last hover for showing tooltip long m_hover_time { 0 }; + bool m_eject_pending { false }; }; class UpdatedItemsInfoNotification : public PopNotification diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index a71fb1448..a93a9d5e1 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3104,6 +3104,9 @@ unsigned int Plater::priv::update_background_process(bool force_validation, bool // if ((return_state & UPDATE_BACKGROUND_PROCESS_RESTART) != 0 || // (return_state & UPDATE_BACKGROUND_PROCESS_REFRESH_SCENE) != 0 ) // this->statusbar()->set_status_text(_L("Ready to slice")); + if ((return_state & UPDATE_BACKGROUND_PROCESS_RESTART) != 0 || + (return_state & UPDATE_BACKGROUND_PROCESS_REFRESH_SCENE) != 0 ) + notification_manager->set_slicing_progress_hidden(); sidebar->set_btn_label(ActionButtonType::abExport, _(label_btn_export)); sidebar->set_btn_label(ActionButtonType::abSendGCode, _(label_btn_send)); @@ -3963,6 +3966,7 @@ void Plater::priv::on_slicing_began() clear_warnings(); notification_manager->close_notification_of_type(NotificationType::SignDetected); notification_manager->close_notification_of_type(NotificationType::ExportFinished); + notification_manager->set_slicing_progress_began(); } void Plater::priv::add_warning(const Slic3r::PrintStateBase::Warning& warning, size_t oid) { @@ -4060,7 +4064,7 @@ void Plater::priv::on_process_completed(SlicingProcessCompletedEvent &evt) } if (evt.cancelled()) { // this->statusbar()->set_status_text(_L("Cancelled")); - this->notification_manager->set_slicing_progress_percentage(_utf8("Slicing Cancelled."), -1); + this->notification_manager->set_slicing_progress_canceled(_utf8("Slicing Cancelled.")); } this->sidebar->show_sliced_info_sizer(evt.success()); @@ -6375,6 +6379,7 @@ bool Plater::set_printer_technology(PrinterTechnology printer_technology) p->sidebar->get_searcher().set_printer_technology(printer_technology); p->notification_manager->set_fff(printer_technology == ptFFF); + p->notification_manager->set_slicing_progress_hidden(); return ret; } From 9f62aeabab9df4a6f292e89db8208b7ba52bf881 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 23 Sep 2021 16:37:27 +0200 Subject: [PATCH 10/11] DoubleSlider: Fixed a bug related to the unexpected mouse capture end Steps to repro: 1.Use left mouse button to move thumb of the DoubleSlider 2.Click by right mouse button 3.Thumb is moving even if you move the mouse out of the DoubleSlider --- src/slic3r/GUI/DoubleSlider.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/DoubleSlider.cpp b/src/slic3r/GUI/DoubleSlider.cpp index f83078261..77679a1ad 100644 --- a/src/slic3r/GUI/DoubleSlider.cpp +++ b/src/slic3r/GUI/DoubleSlider.cpp @@ -1819,7 +1819,8 @@ void Control::OnChar(wxKeyEvent& event) void Control::OnRightDown(wxMouseEvent& event) { - if (HasCapture()) return; + if (HasCapture() || m_is_left_down) + return; this->CaptureMouse(); const wxPoint pos = event.GetLogicalPosition(wxClientDC(this)); @@ -2097,7 +2098,7 @@ void Control::auto_color_change() void Control::OnRightUp(wxMouseEvent& event) { - if (!HasCapture()) + if (!HasCapture() || m_is_left_down) return; this->ReleaseMouse(); m_is_right_down = m_is_one_layer = false; From 8f6386cdffa65c6e53510c749f36272878dc465c Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 23 Sep 2021 16:38:34 +0200 Subject: [PATCH 11/11] =?UTF-8?q?Fix=20of=20#7000=20-=20Compilation=20erro?= =?UTF-8?q?r:=20ambiguous=20overload=20for=20=E2=80=98operator+?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/slic3r/GUI/UnsavedChangesDialog.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/UnsavedChangesDialog.cpp b/src/slic3r/GUI/UnsavedChangesDialog.cpp index 40cfa548a..ffa47ed63 100644 --- a/src/slic3r/GUI/UnsavedChangesDialog.cpp +++ b/src/slic3r/GUI/UnsavedChangesDialog.cpp @@ -1214,9 +1214,9 @@ void UnsavedChangesDialog::update(Preset::Type type, PresetCollection* dependent for (Tab* tab : wxGetApp().tabs_list) if (tab->supports_printer_technology(printer_technology) && tab->current_preset_is_dirty()) presets_cnt++; - m_action_line->SetLabel((header.IsEmpty() ? "" : header + "\n\n") + //_L("The following presets were modified:")); - + _L_PLURAL("The following preset was modified", - "The following presets were modified", presets_cnt)); + m_action_line->SetLabel((header.IsEmpty() ? "" : header + "\n\n") + + _L_PLURAL("The following preset was modified", + "The following presets were modified", presets_cnt)); } else { wxString action_msg;