Synchronization of moves between old and new visualization

This commit is contained in:
enricoturri1966 2023-10-30 11:50:02 +01:00 committed by Lukas Matena
parent a23d86bd2b
commit 7ee937857b
15 changed files with 491 additions and 161 deletions

View File

@ -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

View File

@ -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<uint32_t>(first), static_cast<uint32_t>(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<unsigned int, 2>& 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<uint32_t>(layers_z_range[0]), static_cast<uint32_t>(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();
}

View File

@ -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 <assert.h>
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<uint32_t>(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
//################################################################################################################################

View File

@ -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 <vector>
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<Range> m_ranges;
};
} // namespace libvgcode
//################################################################################################################################
// PrusaSlicer development only -> !!!TO BE REMOVED!!!
#endif // ENABLE_NEW_GCODE_VIEWER
//################################################################################################################################
#endif // VGCODE_LAYERS_HPP

View File

@ -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 <algorithm>
#include "Range.hpp"
//################################################################################################################################
// PrusaSlicer development only -> !!!TO BE REMOVED!!!
#if ENABLE_NEW_GCODE_VIEWER
//################################################################################################################################
#include <algorithm>
namespace libvgcode {
Shell::~Shell()
const std::array<uint32_t, 2>& 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<uint32_t, 2>& 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

View File

@ -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 <array>
#include <cstdint>
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<uint32_t, 2>& get() const;
void set(const std::array<uint32_t, 2>& 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<uint32_t, 2> m_range{ 0, 0 };
};
} // namespace libvgcode
@ -56,4 +40,4 @@ private:
#endif // ENABLE_NEW_GCODE_VIEWER
//################################################################################################################################
#endif // VGCODE_SHELL_HPP
#endif // VGCODE_RANGE_HPP

View File

@ -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<EOptionType, bool> options_visibility{ {
{ EOptionType::Travels, false },

View File

@ -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;

View File

@ -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 };

View File

@ -48,7 +48,7 @@ static Vec3f toVec3f(const Eigen::Matrix<float, 3, 1, Eigen::DontAlign>& 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<EMoveType, Color> 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<uint8_t>(curr.extruder_id), static_cast<uint8_t>(curr.cp_color_id),
static_cast<uint32_t>(curr.layer_id) };
m_vertices_map.emplace_back(static_cast<uint32_t>(i) - seams_count);
m_vertices.emplace_back(vertex);
m_layers.update(static_cast<uint32_t>(curr.layer_id), static_cast<uint32_t>(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<uint8_t>(curr.extruder_id),
static_cast<uint8_t>(curr.cp_color_id), static_cast<uint32_t>(curr.layer_id) };
m_vertices_map.emplace_back(static_cast<uint32_t>(i) - seams_count);
m_vertices.emplace_back(vertex);
m_layers.update(static_cast<uint32_t>(curr.layer_id), static_cast<uint32_t>(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<uint32_t>(m_layers.size() - 1));
update_view_global_range();
m_settings.update_colors = true;
}
@ -733,7 +745,8 @@ void Toolpaths::update_enabled_entities()
std::vector<uint32_t> enabled_segments;
std::vector<uint32_t> enabled_options;
for (uint32_t i = m_view_range.get_current_min(); i < m_view_range.get_current_max(); i++) {
const std::array<uint32_t, 2>& 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<float> 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<uint32_t, 2>& 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<uint32_t, 2>& 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<size_t, 2>& Toolpaths::get_view_current_range() const
const std::array<uint32_t, 2>& Toolpaths::get_view_current_range() const
{
return m_view_range.get_current_range();
}
const std::array<size_t, 2>& Toolpaths::get_view_global_range() const
const std::array<uint32_t, 2>& 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<uint32_t>(i);
else
break;
}
++min_id;
uint32_t max_id = min_id;
if (max > min) {
for (size_t i = static_cast<size_t>(min_id); i < m_vertices_map.size(); ++i) {
if (m_vertices_map[i] < max)
max_id = static_cast<uint32_t>(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<std::vector<float>, static_cast<size_t>(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<std::vector<float>, (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<uint32_t, 2>& 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<size_t, 2>& current_view_range = get_view_current_range();
const std::array<uint32_t, 2>& 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<uint32_t, 2>& 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<uint32_t, 2>& 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<float, 2>& 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();
}
//################################################################################################################################

View File

@ -19,6 +19,7 @@
#include "Bitset.hpp"
#include "ColorRange.hpp"
#include "ViewRange.hpp"
#include "Layers.hpp"
#include <vector>
#include <array>
@ -73,6 +74,8 @@ public:
//
EViewType get_view_type() const;
ETimeMode get_time_mode() const;
const std::array<uint32_t, 2>& 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<uint32_t, 2>& 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<size_t, 2>& get_view_current_range() const;
const std::array<size_t, 2>& get_view_global_range() const;
const std::array<uint32_t, 2>& get_view_current_range() const;
const std::array<uint32_t, 2>& 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<PathVertex> m_vertices;
std::vector<uint32_t> m_vertices_map;
//################################################################################################################################
// Debug
std::pair<uint32_t, uint32_t> 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);

View File

@ -14,55 +14,56 @@
#if ENABLE_NEW_GCODE_VIEWER
//################################################################################################################################
#include <assert.h>
#include <algorithm>
namespace libvgcode {
size_t ViewRange::get_current_min() const
const std::array<uint32_t, 2>& 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<size_t, 2>& ViewRange::get_current_range() const
void ViewRange::set_current_range(const std::array<uint32_t, 2>& 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<uint32_t, 2>& 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<size_t, 2>& ViewRange::get_global_range() const
void ViewRange::set_global_range(const std::array<uint32_t, 2>& 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

View File

@ -10,28 +10,28 @@
#if ENABLE_NEW_GCODE_VIEWER
//################################################################################################################################
#include <array>
#include "Range.hpp"
namespace libvgcode {
class ViewRange
{
public:
size_t get_current_min() const;
size_t get_current_max() const;
const std::array<uint32_t, 2>& get_current_range() const;
void set_current_range(const Range& other);
void set_current_range(const std::array<uint32_t, 2>& range);
void set_current_range(uint32_t min, uint32_t max);
const std::array<size_t, 2>& get_current_range() const;
void set_current_range(size_t min, size_t max);
const std::array<uint32_t, 2>& get_global_range() const;
void set_global_range(const Range& other);
void set_global_range(const std::array<uint32_t, 2>& 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<size_t, 2>& get_global_range() const;
void set_global_range(size_t min, size_t max);
void reset();
private:
std::array<size_t, 2> m_current{ 0, 0 };
std::array<size_t, 2> m_global{ 0, 0 };
Range m_current;
Range m_global;
};
} // namespace libvgcode

View File

@ -53,6 +53,31 @@ void Viewer::set_time_mode(ETimeMode mode)
m_toolpaths.set_time_mode(mode);
}
const std::array<uint32_t, 2>& Viewer::get_layers_range() const
{
return m_toolpaths.get_layers_range();
}
void Viewer::set_layers_range(const std::array<uint32_t, 2>& 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<std::vector<float>, static_cast<size_t>(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<size_t, 2>& Viewer::get_view_current_range() const
const std::array<uint32_t, 2>& Viewer::get_view_current_range() const
{
return m_toolpaths.get_view_current_range();
}
const std::array<size_t, 2>& Viewer::get_view_global_range() const
const std::array<uint32_t, 2>& 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);
}

View File

@ -42,6 +42,13 @@ public:
ETimeMode get_time_mode() const;
void set_time_mode(ETimeMode mode);
const std::array<uint32_t, 2>& get_layers_range() const;
void set_layers_range(const std::array<uint32_t, 2>& 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<std::vector<float>, static_cast<size_t>(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<size_t, 2>& get_view_current_range() const;
const std::array<size_t, 2>& get_view_global_range() const;
const std::array<uint32_t, 2>& get_view_current_range() const;
const std::array<uint32_t, 2>& 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.