diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index a8b15c95ca..8a40279c1f 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -93,37 +93,39 @@ set(SLIC3R_GUI_SOURCES GUI/Gizmos/GLGizmoMeasure.cpp GUI/Gizmos/GLGizmoMeasure.hpp #==================================================================================================================== - GUI/LibVGCode/Viewer.hpp - GUI/LibVGCode/Viewer.cpp - GUI/LibVGCode/Settings.hpp - GUI/LibVGCode/Settings.cpp - GUI/LibVGCode/SegmentTemplate.hpp - GUI/LibVGCode/SegmentTemplate.cpp - GUI/LibVGCode/OptionTemplate.hpp - GUI/LibVGCode/OptionTemplate.cpp - GUI/LibVGCode/Toolpaths.hpp - GUI/LibVGCode/Toolpaths.cpp - GUI/LibVGCode/PathVertex.hpp - GUI/LibVGCode/PathVertex.cpp - GUI/LibVGCode/Types.hpp - GUI/LibVGCode/Types.cpp GUI/LibVGCode/Bitset.hpp GUI/LibVGCode/Bitset.cpp - GUI/LibVGCode/ViewRange.hpp - GUI/LibVGCode/ViewRange.cpp - GUI/LibVGCode/ColorRange.hpp - GUI/LibVGCode/ColorRange.cpp - GUI/LibVGCode/Shaders.hpp - GUI/LibVGCode/OpenGLUtils.hpp - GUI/LibVGCode/OpenGLUtils.cpp GUI/LibVGCode/CogMarker.hpp GUI/LibVGCode/CogMarker.cpp + GUI/LibVGCode/ColorRange.hpp + GUI/LibVGCode/ColorRange.cpp + GUI/LibVGCode/Layers.hpp + GUI/LibVGCode/Layers.cpp + GUI/LibVGCode/OpenGLUtils.hpp + GUI/LibVGCode/OpenGLUtils.cpp + GUI/LibVGCode/OptionTemplate.hpp + GUI/LibVGCode/OptionTemplate.cpp + GUI/LibVGCode/PathVertex.hpp + GUI/LibVGCode/PathVertex.cpp + GUI/LibVGCode/Range.hpp + GUI/LibVGCode/Range.cpp + GUI/LibVGCode/SegmentTemplate.hpp + GUI/LibVGCode/SegmentTemplate.cpp + GUI/LibVGCode/Settings.hpp + GUI/LibVGCode/Settings.cpp + GUI/LibVGCode/Shaders.hpp GUI/LibVGCode/ToolMarker.hpp GUI/LibVGCode/ToolMarker.cpp - GUI/LibVGCode/Shell.hpp - GUI/LibVGCode/Shell.cpp + GUI/LibVGCode/Toolpaths.hpp + GUI/LibVGCode/Toolpaths.cpp + GUI/LibVGCode/Types.hpp + GUI/LibVGCode/Types.cpp GUI/LibVGCode/Utils.hpp GUI/LibVGCode/Utils.cpp + GUI/LibVGCode/Viewer.hpp + GUI/LibVGCode/Viewer.cpp + GUI/LibVGCode/ViewRange.hpp + GUI/LibVGCode/ViewRange.cpp #==================================================================================================================== GUI/GLSelectionRectangle.cpp GUI/GLSelectionRectangle.hpp diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 75ffb1427e..2207814436 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -907,6 +907,7 @@ void GCodeViewer::load(const GCodeProcessorResult& gcode_result, const Print& pr { //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_NEW_GCODE_VIEWER + m_gcode_viewer_2.set_top_layer_only_view(get_app_config()->get_bool("seq_top_layer_only")); m_gcode_viewer_2.load(gcode_result, str_tool_colors); #endif // ENABLE_NEW_GCODE_VIEWER //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@ -1264,7 +1265,7 @@ void GCodeViewer::update_sequential_view_current(unsigned int first, unsigned in { //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_NEW_GCODE_VIEWER - m_gcode_viewer_2.set_view_current_range((size_t)first, (size_t)last); + m_gcode_viewer_2.set_view_current_range(static_cast(first), static_cast(last)); m_sequential_view.current.first = first; m_sequential_view.current.last = last; m_sequential_view.last_current = m_sequential_view.current; @@ -1383,6 +1384,9 @@ void GCodeViewer::set_layers_z_range(const std::array& layers_z bool keep_sequential_current_first = layers_z_range[0] >= m_layers_z_range[0]; bool keep_sequential_current_last = layers_z_range[1] <= m_layers_z_range[1]; m_layers_z_range = layers_z_range; +#if ENABLE_NEW_GCODE_VIEWER + m_gcode_viewer_2.set_layers_range(static_cast(layers_z_range[0]), static_cast(layers_z_range[1])); +#endif // ENABLE_NEW_GCODE_VIEWER refresh_render_paths(keep_sequential_current_first, keep_sequential_current_last); wxGetApp().plater()->update_preview_moves_slider(); } diff --git a/src/slic3r/GUI/LibVGCode/Layers.cpp b/src/slic3r/GUI/LibVGCode/Layers.cpp new file mode 100644 index 0000000000..879de7518b --- /dev/null +++ b/src/slic3r/GUI/LibVGCode/Layers.cpp @@ -0,0 +1,55 @@ +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#include "libslic3r/Technologies.hpp" +//################################################################################################################################ + +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#include "Layers.hpp" + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#if ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +#include + +namespace libvgcode { + +void Layers::update(uint32_t layer_id, uint32_t vertex_id) +{ + if (m_ranges.empty() || layer_id == m_ranges.size()) { + // this code assumes that gcode paths are sent sequentially, one layer after the other + assert(layer_id == static_cast(m_ranges.size())); + Range& range = m_ranges.emplace_back(Range()); + range.set(vertex_id, vertex_id); + } + else { + Range& range = m_ranges.back(); + range.set(range.get()[0], vertex_id); + } +} + +void Layers::reset() +{ + m_ranges.clear(); +} + +bool Layers::empty() const +{ + return m_ranges.empty(); +} + +size_t Layers::size() const +{ + return m_ranges.size(); +} + +} // namespace libvgcode + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#endif // ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ diff --git a/src/slic3r/GUI/LibVGCode/Layers.hpp b/src/slic3r/GUI/LibVGCode/Layers.hpp new file mode 100644 index 0000000000..f585cc8b7a --- /dev/null +++ b/src/slic3r/GUI/LibVGCode/Layers.hpp @@ -0,0 +1,39 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#ifndef VGCODE_LAYERS_HPP +#define VGCODE_LAYERS_HPP + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#if ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +#include "Range.hpp" + +#include + +namespace libvgcode { + +class Layers +{ +public: + void update(uint32_t layer_id, uint32_t vertex_id); + void reset(); + + bool empty() const; + size_t size() const; + +private: + std::vector m_ranges; +}; + +} // namespace libvgcode + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#endif // ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +#endif // VGCODE_LAYERS_HPP \ No newline at end of file diff --git a/src/slic3r/GUI/LibVGCode/Shell.cpp b/src/slic3r/GUI/LibVGCode/Range.cpp similarity index 53% rename from src/slic3r/GUI/LibVGCode/Shell.cpp rename to src/slic3r/GUI/LibVGCode/Range.cpp index 2986f04e6d..31f76c310c 100644 --- a/src/slic3r/GUI/LibVGCode/Shell.cpp +++ b/src/slic3r/GUI/LibVGCode/Range.cpp @@ -3,82 +3,58 @@ #include "libslic3r/Technologies.hpp" //################################################################################################################################ -///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966 +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak ///|/ ///|/ libvgcode is released under the terms of the AGPLv3 or higher ///|/ -#include "Shell.hpp" -#include "OpenGLUtils.hpp" -#include "Utils.hpp" - -#include +#include "Range.hpp" //################################################################################################################################ // PrusaSlicer development only -> !!!TO BE REMOVED!!! #if ENABLE_NEW_GCODE_VIEWER //################################################################################################################################ +#include + namespace libvgcode { -Shell::~Shell() +const std::array& Range::get() const { - if (m_ibo_id != 0) - glsafe(glDeleteBuffers(1, &m_ibo_id)); - if (m_vbo_id != 0) - glsafe(glDeleteBuffers(1, &m_vbo_id)); - if (m_vao_id != 0) - glsafe(glDeleteVertexArrays(1, &m_vao_id)); + return m_range; } -void Shell::init() +void Range::set(const std::array& range) { - if (m_vao_id != 0) - return; - + set(range[0], range[1]); } -void Shell::render() +void Range::set(uint32_t min, uint32_t max) { - if (m_vao_id == 0 || m_vbo_id == 0 || m_ibo_id == 0) - return; - - int curr_vertex_array; - glsafe(glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &curr_vertex_array)); - glcheck(); - - glsafe(glBindVertexArray(m_vao_id)); - glsafe(glDrawElements(GL_TRIANGLES, m_indices_count, GL_UNSIGNED_INT, (const void*)0)); - glsafe(glBindVertexArray(curr_vertex_array)); + if (max < min) + std::swap(min, max); + m_range[0] = min; + m_range[1] = max; } -const Vec3f& Shell::get_position() const +void Range::clamp(Range& other) { - return m_position; + other.m_range[0] = std::clamp(other.m_range[0], m_range[0], m_range[1]); + other.m_range[1] = std::clamp(other.m_range[1], m_range[0], m_range[1]); } -void Shell::set_position(const Vec3f& position) +void Range::reset() { - m_position = position; + m_range = { 0, 0 }; } -const Color& Shell::get_color() const +bool Range::operator == (const Range& other) const { - return m_color; + return m_range == other.m_range; } -void Shell::set_color(const Color& color) +bool Range::operator != (const Range& other) const { - m_color = color; -} - -float Shell::get_alpha() const -{ - return m_alpha; -} - -void Shell::set_alpha(float alpha) -{ - m_alpha = std::clamp(alpha, 0.25f, 0.75f); + return m_range != other.m_range; } } // namespace libvgcode diff --git a/src/slic3r/GUI/LibVGCode/Shell.hpp b/src/slic3r/GUI/LibVGCode/Range.hpp similarity index 52% rename from src/slic3r/GUI/LibVGCode/Shell.hpp rename to src/slic3r/GUI/LibVGCode/Range.hpp index f7747ae453..7829b28335 100644 --- a/src/slic3r/GUI/LibVGCode/Shell.hpp +++ b/src/slic3r/GUI/LibVGCode/Range.hpp @@ -1,52 +1,36 @@ -///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966 +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak ///|/ ///|/ libvgcode is released under the terms of the AGPLv3 or higher ///|/ -#ifndef VGCODE_SHELL_HPP -#define VGCODE_SHELL_HPP +#ifndef VGCODE_RANGE_HPP +#define VGCODE_RANGE_HPP //################################################################################################################################ // PrusaSlicer development only -> !!!TO BE REMOVED!!! #if ENABLE_NEW_GCODE_VIEWER //################################################################################################################################ -#include "Types.hpp" - +#include #include namespace libvgcode { -class Shell +class Range { public: - Shell() = default; - ~Shell(); - Shell(const Shell& other) = delete; - Shell(Shell&& other) = delete; - Shell& operator = (const Shell& other) = delete; - Shell& operator = (Shell&& other) = delete; + const std::array& get() const; + void set(const std::array& range); + void set(uint32_t min, uint32_t max); + // clamp the given range to stay inside this range + void clamp(Range& other); + void reset(); - void init(); - void render(); - - const Vec3f& get_position() const; - void set_position(const Vec3f& position); - - const Color& get_color() const; - void set_color(const Color& color); - - float get_alpha() const; - void set_alpha(float alpha); + bool operator == (const Range& other) const; + bool operator != (const Range& other) const; private: - Vec3f m_position{ 0.0f, 0.0f, 0.0f }; - Color m_color{ 1.0f, 1.0f, 1.0f }; - float m_alpha{ 0.5f }; - - uint32_t m_indices_count{ 0 }; - unsigned int m_vao_id{ 0 }; - unsigned int m_vbo_id{ 0 }; - unsigned int m_ibo_id{ 0 }; + // [0] = min, [1] = max + std::array m_range{ 0, 0 }; }; } // namespace libvgcode @@ -56,4 +40,4 @@ private: #endif // ENABLE_NEW_GCODE_VIEWER //################################################################################################################################ -#endif // VGCODE_SHELL_HPP \ No newline at end of file +#endif // VGCODE_RANGE_HPP \ No newline at end of file diff --git a/src/slic3r/GUI/LibVGCode/Settings.hpp b/src/slic3r/GUI/LibVGCode/Settings.hpp index 30158ec0eb..e0f0bfc350 100644 --- a/src/slic3r/GUI/LibVGCode/Settings.hpp +++ b/src/slic3r/GUI/LibVGCode/Settings.hpp @@ -18,10 +18,12 @@ namespace libvgcode { struct Settings { - bool update_enabled_entities{ true }; + bool update_view_global_range{ true }; + bool update_enabled_entities{ true }; bool update_colors{ true }; EViewType view_type{ EViewType::FeatureType }; ETimeMode time_mode{ ETimeMode::Normal }; + bool top_layer_only_view{ false }; std::map options_visibility{ { { EOptionType::Travels, false }, diff --git a/src/slic3r/GUI/LibVGCode/ToolMarker.cpp b/src/slic3r/GUI/LibVGCode/ToolMarker.cpp index 9e043c778e..33ad9b5596 100644 --- a/src/slic3r/GUI/LibVGCode/ToolMarker.cpp +++ b/src/slic3r/GUI/LibVGCode/ToolMarker.cpp @@ -174,6 +174,16 @@ void ToolMarker::set_position(const Vec3f& position) m_position = position; } +float ToolMarker::get_offset_z() const +{ + return m_offset_z; +} + +void ToolMarker::set_offset_z(float offset_z) +{ + m_offset_z = std::max(offset_z, 0.0f); +} + const Color& ToolMarker::get_color() const { return m_color; diff --git a/src/slic3r/GUI/LibVGCode/ToolMarker.hpp b/src/slic3r/GUI/LibVGCode/ToolMarker.hpp index 9c825d95cf..9c10e23d67 100644 --- a/src/slic3r/GUI/LibVGCode/ToolMarker.hpp +++ b/src/slic3r/GUI/LibVGCode/ToolMarker.hpp @@ -32,6 +32,9 @@ public: const Vec3f& get_position() const; void set_position(const Vec3f& position); + float get_offset_z() const; + void set_offset_z(float offset_z); + const Color& get_color() const; void set_color(const Color& color); @@ -40,6 +43,7 @@ public: private: Vec3f m_position{ 0.0f, 0.0f, 0.0f }; + float m_offset_z{ 0.5f }; Color m_color{ 1.0f, 1.0f, 1.0f }; float m_alpha{ 0.5f }; diff --git a/src/slic3r/GUI/LibVGCode/Toolpaths.cpp b/src/slic3r/GUI/LibVGCode/Toolpaths.cpp index 2d6af07b80..1ebc3ec1fe 100644 --- a/src/slic3r/GUI/LibVGCode/Toolpaths.cpp +++ b/src/slic3r/GUI/LibVGCode/Toolpaths.cpp @@ -48,7 +48,7 @@ static Vec3f toVec3f(const Eigen::Matrix& v) } //################################################################################################################################ -static const Color Dummy_Color{ 0.0f, 0.0f, 0.0f }; +static const Color Dummy_Color{ 0.25f, 0.25f, 0.25f }; static const Color Default_Tool_Color{ 1.0f, 0.502f, 0.0f }; static const std::map Options_Colors{ { @@ -577,13 +577,18 @@ void Toolpaths::load(const Slic3r::GCodeProcessorResult& gcode_result, const std reset(); + m_vertices_map.reserve(2 * gcode_result.moves.size()); m_vertices.reserve(2 * gcode_result.moves.size()); + uint32_t seams_count = 0; for (size_t i = 1; i < gcode_result.moves.size(); ++i) { const Slic3r::GCodeProcessorResult::MoveVertex& curr = gcode_result.moves[i]; const Slic3r::GCodeProcessorResult::MoveVertex& prev = gcode_result.moves[i - 1]; const EMoveType curr_type = valueof(curr.type); const EGCodeExtrusionRole curr_role = valueof(curr.extrusion_role); + if (curr_type == EMoveType::Seam) + ++seams_count; + EGCodeExtrusionRole extrusion_role; if (curr_type == EMoveType::Travel) { // for travel moves set the extrusion role @@ -615,14 +620,18 @@ void Toolpaths::load(const Slic3r::GCodeProcessorResult& gcode_result, const std curr.temperature, curr.volumetric_rate(), extrusion_role, curr_type, static_cast(curr.extruder_id), static_cast(curr.cp_color_id), static_cast(curr.layer_id) }; + m_vertices_map.emplace_back(static_cast(i) - seams_count); m_vertices.emplace_back(vertex); + m_layers.update(static_cast(curr.layer_id), static_cast(m_vertices.size())); } } const PathVertex vertex = { toVec3f(curr.position), height, width, curr.feedrate, curr.fan_speed, curr.temperature, curr.volumetric_rate(), extrusion_role, curr_type, static_cast(curr.extruder_id), static_cast(curr.cp_color_id), static_cast(curr.layer_id) }; + m_vertices_map.emplace_back(static_cast(i) - seams_count); m_vertices.emplace_back(vertex); + m_layers.update(static_cast(curr.layer_id), static_cast(m_vertices.size())); // updates calculation for center of gravity if (curr_type == EMoveType::Extrude && @@ -636,8 +645,11 @@ void Toolpaths::load(const Slic3r::GCodeProcessorResult& gcode_result, const std m_cog_marker.update(0.5f * (curr_pos + prev_pos), curr.mm3_per_mm * length(curr_pos - prev_pos)); } } + m_vertices_map.shrink_to_fit(); m_vertices.shrink_to_fit(); + assert(m_vertices_map.size() == m_vertices.size()); + m_valid_lines_bitset = BitSet<>(m_vertices.size()); m_valid_lines_bitset.setAll(); @@ -651,10 +663,8 @@ void Toolpaths::load(const Slic3r::GCodeProcessorResult& gcode_result, const std for (size_t i = 0; i < m_vertices.size(); ++i) { const PathVertex& v = m_vertices[i]; const EMoveType move_type = v.type; - const bool prev_line_valid = i > 0 && m_valid_lines_bitset[i - 1]; const Vec3f prev_line = prev_line_valid ? v.position - m_vertices[i - 1].position : ZERO; - const bool this_line_valid = i + 1 < m_vertices.size() && m_vertices[i + 1].position != v.position && m_vertices[i + 1].type == move_type && @@ -724,7 +734,9 @@ void Toolpaths::load(const Slic3r::GCodeProcessorResult& gcode_result, const std m_layers_times[i] = gcode_result.print_statistics.modes[i].layers_times; } - m_view_range.set_global_range(0, m_vertices.size() - 1); + if (!m_layers.empty()) + set_layers_range(0, static_cast(m_layers.size() - 1)); + update_view_global_range(); m_settings.update_colors = true; } @@ -733,7 +745,8 @@ void Toolpaths::update_enabled_entities() std::vector enabled_segments; std::vector enabled_options; - for (uint32_t i = m_view_range.get_current_min(); i < m_view_range.get_current_max(); i++) { + const std::array& current_range = m_view_range.get_current_range(); + for (uint32_t i = current_range[0]; i < current_range[1]; ++i) { const PathVertex& v = m_vertices[i]; if (!m_valid_lines_bitset[i] && !v.is_option()) @@ -805,9 +818,11 @@ void Toolpaths::update_colors() { update_color_ranges(); + const uint32_t top_layer_id = m_settings.top_layer_only_view ? m_layers_range.get()[1] : 0; std::vector colors(m_vertices.size()); for (size_t i = 0; i < m_vertices.size(); i++) { - colors[i] = encode_color(select_color(m_vertices[i])); + colors[i] = (m_vertices[i].layer_id < top_layer_id) ? + encode_color(Dummy_Color) : encode_color(select_color(m_vertices[i])); } // update gpu buffer for colors @@ -819,6 +834,11 @@ void Toolpaths::update_colors() void Toolpaths::render(const Mat4x4f& view_matrix, const Mat4x4f& projection_matrix) { + if (m_settings.update_view_global_range) { + update_view_global_range(); + m_settings.update_view_global_range = false; + } + if (m_settings.update_enabled_entities) { update_enabled_entities(); m_settings.update_enabled_entities = false; @@ -855,6 +875,16 @@ ETimeMode Toolpaths::get_time_mode() const return m_settings.time_mode; } +const std::array& Toolpaths::get_layers_range() const +{ + return m_layers_range.get(); +} + +bool Toolpaths::is_top_layer_only_view() const +{ + return m_settings.top_layer_only_view; +} + bool Toolpaths::is_option_visible(EOptionType type) const { try @@ -891,12 +921,32 @@ void Toolpaths::set_time_mode(ETimeMode mode) m_settings.update_colors = true; } +void Toolpaths::set_layers_range(const std::array& range) +{ + set_layers_range(range[0], range[1]); +} + +void Toolpaths::set_layers_range(uint32_t min, uint32_t max) +{ + m_layers_range.set(min, max); + m_settings.update_view_global_range = true; + m_settings.update_enabled_entities = true; +} + +void Toolpaths::set_top_layer_only_view(bool top_layer_only_view) +{ + m_settings.top_layer_only_view = top_layer_only_view; + m_settings.update_colors = true; +} + void Toolpaths::toggle_option_visibility(EOptionType type) { try { bool& value = m_settings.options_visibility.at(type); value = !value; + if (type == EOptionType::Travels) + m_settings.update_view_global_range = true; m_settings.update_enabled_entities = true; m_settings.update_colors = true; } @@ -921,20 +971,51 @@ void Toolpaths::toggle_extrusion_role_visibility(EGCodeExtrusionRole role) } } -const std::array& Toolpaths::get_view_current_range() const +const std::array& Toolpaths::get_view_current_range() const { return m_view_range.get_current_range(); } -const std::array& Toolpaths::get_view_global_range() const +const std::array& Toolpaths::get_view_global_range() const { return m_view_range.get_global_range(); } -void Toolpaths::set_view_current_range(size_t min, size_t max) +void Toolpaths::set_view_current_range(uint32_t min, uint32_t max) { - m_view_range.set_current_range(min, max); - m_settings.update_enabled_entities = true; + uint32_t min_id = 0; + for (size_t i = 0; i < m_vertices_map.size(); ++i) { + if (m_vertices_map[i] < min) + min_id = static_cast(i); + else + break; + } + ++min_id; + + uint32_t max_id = min_id; + if (max > min) { + for (size_t i = static_cast(min_id); i < m_vertices_map.size(); ++i) { + if (m_vertices_map[i] < max) + max_id = static_cast(i); + else + break; + } + ++max_id; + } + + if (max_id < m_vertices_map.size() - 1 && + m_vertices[max_id + 1].type == m_vertices[max_id].type && + m_vertices_map[max_id + 1] == m_vertices_map[max_id]) + ++max_id; + + Range new_range; + new_range.set(min_id, max_id); + + if (m_old_current_range != new_range) { + m_view_range.set_current_range(new_range); + m_old_current_range = new_range; + m_settings.update_enabled_entities = true; + } } const std::array, static_cast(ETimeMode::COUNT)>& Toolpaths::get_layers_times() const @@ -957,6 +1038,11 @@ const Vec3f& Toolpaths::get_tool_marker_position() const return m_tool_marker.get_position(); } +float Toolpaths::get_tool_marker_offset_z() const +{ + return m_tool_marker.get_offset_z(); +} + float Toolpaths::get_tool_marker_scale_factor() const { return m_tool_marker_scale_factor; @@ -982,6 +1068,11 @@ void Toolpaths::set_tool_marker_position(const Vec3f& position) m_tool_marker.set_position(position); } +void Toolpaths::set_tool_marker_offset_z(float offset_z) +{ + m_tool_marker.set_offset_z(offset_z); +} + void Toolpaths::set_tool_marker_scale_factor(float factor) { m_tool_marker_scale_factor = std::max(factor, 0.001f); @@ -1015,7 +1106,12 @@ static void delete_buffers(unsigned int& id) void Toolpaths::reset() { + m_layers.reset(); + m_layers_range.reset(); + m_view_range.reset(); + m_old_current_range.reset(); m_vertices.clear(); + m_vertices_map.clear(); m_valid_lines_bitset.clear(); m_layers_times = std::array, (uint8_t)ETimeMode::COUNT>(); @@ -1036,6 +1132,53 @@ void Toolpaths::reset() delete_buffers(m_positions_buf_id); } +void Toolpaths::update_view_global_range() +{ + const std::array& layers_range = m_layers_range.get(); + const bool travels_visible = m_settings.options_visibility.at(EOptionType::Travels); + + auto first_it = m_vertices.begin(); + while (first_it != m_vertices.end() && ( + first_it->layer_id < layers_range[0] || + first_it->is_option() || + (first_it->is_travel() && !travels_visible))) { + ++first_it; + } + + if (first_it == m_vertices.end()) + m_view_range.set_global_range(0, 0); + else { + if (travels_visible) { + // if the global range starts with a travel move, extend it to the travel start + while (first_it != m_vertices.begin() && first_it->is_travel()) { + --first_it; + } + } + + auto last_it = first_it; + while (last_it != m_vertices.end() && last_it->layer_id <= layers_range[1]) { + ++last_it; + } + + // remove trailing options, if any + auto rev_first_it = std::make_reverse_iterator(first_it); + auto rev_last_it = std::make_reverse_iterator(last_it); + while (rev_last_it != rev_first_it && rev_last_it->is_option()) { + ++rev_last_it; + } + + last_it = rev_last_it.base(); + if (travels_visible) { + // if the global range ends with a travel move, extend it to the travel end + while (last_it != m_vertices.end() && last_it->is_travel()) { + ++last_it; + } + } + + m_view_range.set_global_range(std::distance(m_vertices.begin(), first_it), std::distance(m_vertices.begin(), last_it)); + } +} + void Toolpaths::update_color_ranges() { m_width_range.reset(); @@ -1298,7 +1441,10 @@ void Toolpaths::render_tool_marker(const Mat4x4f& view_matrix, const Mat4x4f& pr glsafe(glUseProgram(m_tool_marker_shader_id)); - glsafe(glUniform3fv(m_uni_tool_marker_world_origin, 1, m_tool_marker.get_position().data())); + const Vec3f& origin = m_tool_marker.get_position(); + const Vec3f offset = { 0.0f, 0.0f, m_tool_marker.get_offset_z() }; + const Vec3f position = origin + offset; + glsafe(glUniform3fv(m_uni_tool_marker_world_origin, 1, position.data())); glsafe(glUniform1f(m_uni_tool_marker_scale_factor, m_tool_marker_scale_factor)); glsafe(glUniformMatrix4fv(m_uni_tool_marker_view_matrix, 1, GL_FALSE, view_matrix.data())); glsafe(glUniformMatrix4fv(m_uni_tool_marker_projection_matrix, 1, GL_FALSE, projection_matrix.data())); @@ -1348,11 +1494,25 @@ void Toolpaths::render_debug_window() ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); - imgui.text_colored(Slic3r::GUI::ImGuiWrapper::COL_ORANGE_LIGHT, "sequential range"); + imgui.text_colored(Slic3r::GUI::ImGuiWrapper::COL_ORANGE_LIGHT, "layers range"); ImGui::TableSetColumnIndex(1); - const std::array& current_view_range = get_view_current_range(); + const std::array& layers_range = get_layers_range(); + imgui.text(std::to_string(layers_range[0]) + " - " + std::to_string(layers_range[1])); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + imgui.text_colored(Slic3r::GUI::ImGuiWrapper::COL_ORANGE_LIGHT, "view range (current)"); + ImGui::TableSetColumnIndex(1); + const std::array& current_view_range = get_view_current_range(); imgui.text(std::to_string(current_view_range[0]) + " - " + std::to_string(current_view_range[1])); + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + imgui.text_colored(Slic3r::GUI::ImGuiWrapper::COL_ORANGE_LIGHT, "view range (global)"); + ImGui::TableSetColumnIndex(1); + const std::array& global_view_range = get_view_global_range(); + imgui.text(std::to_string(global_view_range[0]) + " - " + std::to_string(global_view_range[1])); + auto add_range_property_row = [&imgui](const std::string& label, const std::array& range) { ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); @@ -1397,6 +1557,14 @@ void Toolpaths::render_debug_window() ImGui::TableSetColumnIndex(1); imgui.text(std::to_string(get_tool_marker_scale_factor())); + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + imgui.text_colored(Slic3r::GUI::ImGuiWrapper::COL_ORANGE_LIGHT, "Tool marker z offset"); + ImGui::TableSetColumnIndex(1); + float tool_z_offset = get_tool_marker_offset_z(); + if (imgui.slider_float("##ToolZOffset", &tool_z_offset, 0.0f, 1.0f)) + set_tool_marker_offset_z(tool_z_offset); + ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); imgui.text_colored(Slic3r::GUI::ImGuiWrapper::COL_ORANGE_LIGHT, "Tool marker color"); @@ -1418,6 +1586,46 @@ void Toolpaths::render_debug_window() } imgui.end(); + + auto to_string = [](EMoveType type) { + switch (type) + { + case EMoveType::Noop: { return "Noop"; } + case EMoveType::Retract: { return "Retract"; } + case EMoveType::Unretract: { return "Unretract"; } + case EMoveType::Seam: { return "Seam"; } + case EMoveType::ToolChange: { return "ToolChange"; } + case EMoveType::ColorChange: { return "ColorChange"; } + case EMoveType::PausePrint: { return "PausePrint"; } + case EMoveType::CustomGCode: { return "CustomGCode"; } + case EMoveType::Travel: { return "Travel"; } + case EMoveType::Wipe: { return "Wipe"; } + case EMoveType::Extrude: { return "Extrude"; } + default: { return "Error"; } + } + }; + + imgui.begin(std::string("LibVGCode Viewer Vertices"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse); + if (ImGui::BeginTable("VertexData", 4)) { + uint32_t counter = 0; + for (size_t i = 0; i < m_vertices.size(); ++i) { + const PathVertex& v = m_vertices[i]; + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + imgui.text_colored(m_valid_lines_bitset[i] ? Slic3r::GUI::ImGuiWrapper::COL_ORANGE_LIGHT : Slic3r::GUI::ImGuiWrapper::COL_GREY_LIGHT, std::to_string(++counter)); + ImGui::TableSetColumnIndex(1); + imgui.text(to_string(v.type)); + + ImGui::TableSetColumnIndex(2); + imgui.text(std::to_string(m_vertices_map[i])); + + ImGui::TableSetColumnIndex(3); + imgui.text(std::to_string(v.position[0]) + ", " + std::to_string(v.position[1]) + ", " + std::to_string(v.position[2])); + } + + ImGui::EndTable(); + } + imgui.end(); } //################################################################################################################################ diff --git a/src/slic3r/GUI/LibVGCode/Toolpaths.hpp b/src/slic3r/GUI/LibVGCode/Toolpaths.hpp index f3b86e3ce2..a6906b310b 100644 --- a/src/slic3r/GUI/LibVGCode/Toolpaths.hpp +++ b/src/slic3r/GUI/LibVGCode/Toolpaths.hpp @@ -19,6 +19,7 @@ #include "Bitset.hpp" #include "ColorRange.hpp" #include "ViewRange.hpp" +#include "Layers.hpp" #include #include @@ -73,6 +74,8 @@ public: // EViewType get_view_type() const; ETimeMode get_time_mode() const; + const std::array& get_layers_range() const; + bool is_top_layer_only_view() const; bool is_option_visible(EOptionType type) const; bool is_extrusion_role_visible(EGCodeExtrusionRole role) const; @@ -81,19 +84,22 @@ public: // void set_view_type(EViewType type); void set_time_mode(ETimeMode mode); + void set_layers_range(const std::array& range); + void set_layers_range(uint32_t min, uint32_t max); + void set_top_layer_only_view(bool top_layer_only_view); void toggle_option_visibility(EOptionType type); void toggle_extrusion_role_visibility(EGCodeExtrusionRole role); // // View range getters // - const std::array& get_view_current_range() const; - const std::array& get_view_global_range() const; + const std::array& get_view_current_range() const; + const std::array& get_view_global_range() const; // // View range setters // - void set_view_current_range(size_t min, size_t max); + void set_view_current_range(uint32_t min, uint32_t max); // // Properties getters @@ -102,6 +108,7 @@ public: Vec3f get_cog_marker_position() const; float get_cog_marker_scale_factor() const; const Vec3f& get_tool_marker_position() const; + float get_tool_marker_offset_z() const; float get_tool_marker_scale_factor() const; const Color& get_tool_marker_color() const; float get_tool_marker_alpha() const; @@ -111,13 +118,17 @@ public: // void set_cog_marker_scale_factor(float factor); void set_tool_marker_position(const Vec3f& position); + void set_tool_marker_offset_z(float offset_z); void set_tool_marker_scale_factor(float factor); void set_tool_marker_color(const Color& color); void set_tool_marker_alpha(float size); private: Settings m_settings; + Layers m_layers; + Range m_layers_range; ViewRange m_view_range; + Range m_old_current_range; // // The OpenGL element used to represent all toolpath segments @@ -145,6 +156,7 @@ private: // cpu buffer to store vertices // std::vector m_vertices; + std::vector m_vertices_map; //################################################################################################################################ // Debug std::pair m_enabled_segments_range{ 0, 0 }; @@ -246,6 +258,7 @@ private: unsigned int m_enabled_options_tex_id{ 0 }; void reset(); + void update_view_global_range(); void update_color_ranges(); Color select_color(const PathVertex& v) const; void render_segments(const Mat4x4f& view_matrix, const Mat4x4f& projection_matrix, const Vec3f& camera_position); diff --git a/src/slic3r/GUI/LibVGCode/ViewRange.cpp b/src/slic3r/GUI/LibVGCode/ViewRange.cpp index d7926c1bc2..ec19d6cbf5 100644 --- a/src/slic3r/GUI/LibVGCode/ViewRange.cpp +++ b/src/slic3r/GUI/LibVGCode/ViewRange.cpp @@ -14,55 +14,56 @@ #if ENABLE_NEW_GCODE_VIEWER //################################################################################################################################ -#include #include namespace libvgcode { -size_t ViewRange::get_current_min() const +const std::array& ViewRange::get_current_range() const { - return m_current[0]; + return m_current.get(); } -size_t ViewRange::get_current_max() const +void ViewRange::set_current_range(const Range& other) { - return m_current[1]; + set_current_range(other.get()); } -const std::array& ViewRange::get_current_range() const +void ViewRange::set_current_range(const std::array& range) { - return m_current; + set_current_range(range[0], range[1]); } -void ViewRange::set_current_range(size_t min, size_t max) +void ViewRange::set_current_range(uint32_t min, uint32_t max) { - assert(min <= max); - m_current[0] = std::clamp(min, m_global[0], m_global[1]); - m_current[1] = std::clamp(max, m_global[0], m_global[1]); + m_current.set(min, max); + m_global.clamp(m_current); } -size_t ViewRange::get_global_min() const +const std::array& ViewRange::get_global_range() const { - return m_global[0]; + return m_global.get(); } -size_t ViewRange::get_global_max() const +void ViewRange::set_global_range(const Range& other) { - return m_global[1]; + set_global_range(other.get()); } -const std::array& ViewRange::get_global_range() const +void ViewRange::set_global_range(const std::array& range) { - return m_global; + set_global_range(range[0], range[1]); } -void ViewRange::set_global_range(size_t min, size_t max) +void ViewRange::set_global_range(uint32_t min, uint32_t max) { - assert(min <= max); - m_global[0] = min; - m_global[1] = max; - m_current[0] = std::clamp(m_current[0], m_global[0], m_global[1]); - m_current[1] = std::clamp(m_current[1], m_global[0], m_global[1]); + m_global.set(min, max); + m_global.clamp(m_current); +} + +void ViewRange::reset() +{ + m_global.reset(); + m_global.reset(); } } // namespace libvgcode diff --git a/src/slic3r/GUI/LibVGCode/ViewRange.hpp b/src/slic3r/GUI/LibVGCode/ViewRange.hpp index ecc08008ef..ade871d70b 100644 --- a/src/slic3r/GUI/LibVGCode/ViewRange.hpp +++ b/src/slic3r/GUI/LibVGCode/ViewRange.hpp @@ -10,28 +10,28 @@ #if ENABLE_NEW_GCODE_VIEWER //################################################################################################################################ -#include +#include "Range.hpp" namespace libvgcode { class ViewRange { public: - size_t get_current_min() const; - size_t get_current_max() const; + const std::array& get_current_range() const; + void set_current_range(const Range& other); + void set_current_range(const std::array& range); + void set_current_range(uint32_t min, uint32_t max); - const std::array& get_current_range() const; - void set_current_range(size_t min, size_t max); + const std::array& get_global_range() const; + void set_global_range(const Range& other); + void set_global_range(const std::array& range); + void set_global_range(uint32_t min, uint32_t max); - size_t get_global_min() const; - size_t get_global_max() const; - - const std::array& get_global_range() const; - void set_global_range(size_t min, size_t max); + void reset(); private: - std::array m_current{ 0, 0 }; - std::array m_global{ 0, 0 }; + Range m_current; + Range m_global; }; } // namespace libvgcode diff --git a/src/slic3r/GUI/LibVGCode/Viewer.cpp b/src/slic3r/GUI/LibVGCode/Viewer.cpp index 30e90b80b4..b9fbabd359 100644 --- a/src/slic3r/GUI/LibVGCode/Viewer.cpp +++ b/src/slic3r/GUI/LibVGCode/Viewer.cpp @@ -53,6 +53,31 @@ void Viewer::set_time_mode(ETimeMode mode) m_toolpaths.set_time_mode(mode); } +const std::array& Viewer::get_layers_range() const +{ + return m_toolpaths.get_layers_range(); +} + +void Viewer::set_layers_range(const std::array& range) +{ + m_toolpaths.set_layers_range(range); +} + +void Viewer::set_layers_range(uint32_t min, uint32_t max) +{ + m_toolpaths.set_layers_range(min, max); +} + +bool Viewer::is_top_layer_only_view() const +{ + return m_toolpaths.is_top_layer_only_view(); +} + +void Viewer::set_top_layer_only_view(bool top_layer_only_view) +{ + m_toolpaths.set_top_layer_only_view(top_layer_only_view); +} + const std::array, static_cast(ETimeMode::COUNT)>& Viewer::get_layers_times() const { return m_toolpaths.get_layers_times(); @@ -78,17 +103,17 @@ void Viewer::toggle_extrusion_role_visibility(EGCodeExtrusionRole role) m_toolpaths.toggle_extrusion_role_visibility(role); } -const std::array& Viewer::get_view_current_range() const +const std::array& Viewer::get_view_current_range() const { return m_toolpaths.get_view_current_range(); } -const std::array& Viewer::get_view_global_range() const +const std::array& Viewer::get_view_global_range() const { return m_toolpaths.get_view_global_range(); } -void Viewer::set_view_current_range(size_t min, size_t max) +void Viewer::set_view_current_range(uint32_t min, uint32_t max) { m_toolpaths.set_view_current_range(min, max); } diff --git a/src/slic3r/GUI/LibVGCode/Viewer.hpp b/src/slic3r/GUI/LibVGCode/Viewer.hpp index 1f5aea98b3..1589b10017 100644 --- a/src/slic3r/GUI/LibVGCode/Viewer.hpp +++ b/src/slic3r/GUI/LibVGCode/Viewer.hpp @@ -42,6 +42,13 @@ public: ETimeMode get_time_mode() const; void set_time_mode(ETimeMode mode); + const std::array& get_layers_range() const; + void set_layers_range(const std::array& range); + void set_layers_range(uint32_t min, uint32_t max); + + bool is_top_layer_only_view() const; + void set_top_layer_only_view(bool top_layer_only_view); + const std::array, static_cast(ETimeMode::COUNT)>& get_layers_times() const; bool is_option_visible(EOptionType type) const; @@ -50,13 +57,13 @@ public: bool is_extrusion_role_visible(EGCodeExtrusionRole role) const; void toggle_extrusion_role_visibility(EGCodeExtrusionRole role); - const std::array& get_view_current_range() const; - const std::array& get_view_global_range() const; + const std::array& get_view_current_range() const; + const std::array& get_view_global_range() const; // // min must be smaller than max // values are clamped to the view global range // - void set_view_current_range(size_t min, size_t max); + void set_view_current_range(uint32_t min, uint32_t max); // // Returns the position of the center of gravity of the toolpaths.