Some functionality moved from class libvgcode::Viewer to class libvgcode::Toolpaths

This commit is contained in:
enricoturri1966 2023-10-26 12:10:00 +02:00 committed by Lukas Matena
parent 8073bdea90
commit 2710ab4005
4 changed files with 262 additions and 183 deletions

View File

@ -3,7 +3,7 @@
#include "libslic3r/Technologies.hpp"
//################################################################################################################################
///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak, Vojtěch Bubník @bubnikv
///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak, Vojtěch Bubník @bubnikv, Oleksandra Iushchenko @YuSanka
///|/
///|/ libvgcode is released under the terms of the AGPLv3 or higher
///|/
@ -23,6 +23,8 @@
#include <map>
#include <assert.h>
#include <exception>
#include <cstdio>
#include <string>
namespace libvgcode {
@ -298,6 +300,69 @@ static Mat4x4f inverse(const Mat4x4f& m)
return ret;
}
static std::string short_time(const std::string& time)
{
// Parse the dhms time format.
int days = 0;
int hours = 0;
int minutes = 0;
int seconds = 0;
if (time.find('d') != std::string::npos)
sscanf(time.c_str(), "%dd %dh %dm %ds", &days, &hours, &minutes, &seconds);
else if (time.find('h') != std::string::npos)
sscanf(time.c_str(), "%dh %dm %ds", &hours, &minutes, &seconds);
else if (time.find('m') != std::string::npos)
sscanf(time.c_str(), "%dm %ds", &minutes, &seconds);
else if (time.find('s') != std::string::npos)
sscanf(time.c_str(), "%ds", &seconds);
// Round to full minutes.
if (days + hours + minutes > 0 && seconds >= 30) {
if (++minutes == 60) {
minutes = 0;
if (++hours == 24) {
hours = 0;
++days;
}
}
}
// Format the dhm time
char buffer[64];
if (days > 0)
sprintf(buffer, "%dd%dh%dm", days, hours, minutes);
else if (hours > 0)
sprintf(buffer, "%dh%dm", hours, minutes);
else if (minutes > 0)
sprintf(buffer, "%dm", minutes);
else
sprintf(buffer, "%ds", seconds);
return buffer;
}
// Returns the given time is seconds in format DDd HHh MMm SSs
static std::string get_time_dhms(float time_in_secs)
{
int days = (int)(time_in_secs / 86400.0f);
time_in_secs -= (float)days * 86400.0f;
int hours = (int)(time_in_secs / 3600.0f);
time_in_secs -= (float)hours * 3600.0f;
int minutes = (int)(time_in_secs / 60.0f);
time_in_secs -= (float)minutes * 60.0f;
char buffer[64];
if (days > 0)
sprintf(buffer, "%dd %dh %dm %ds", days, hours, minutes, (int)time_in_secs);
else if (hours > 0)
sprintf(buffer, "%dh %dm %ds", hours, minutes, (int)time_in_secs);
else if (minutes > 0)
sprintf(buffer, "%dm %ds", minutes, (int)time_in_secs);
else
sprintf(buffer, "%ds", (int)std::round(time_in_secs));
return buffer;
}
std::string check_shader(GLuint handle)
{
std::string ret;
@ -472,11 +537,23 @@ void Toolpaths::init()
m_tool_marker.init(32, 2.0f, 4.0f, 1.0f, 8.0f);
}
void Toolpaths::load(const Slic3r::GCodeProcessorResult& gcode_result, const std::vector<std::string>& str_tool_colors,
const Settings& settings)
void Toolpaths::load(const Slic3r::GCodeProcessorResult& gcode_result, const std::vector<std::string>& str_tool_colors)
{
if (m_settings.time_mode != ETimeMode::Normal) {
const Slic3r::PrintEstimatedStatistics& stats = gcode_result.print_statistics;
bool force_normal_mode = static_cast<size_t>(m_settings.time_mode) >= stats.modes.size();
if (!force_normal_mode) {
const float normal_time = stats.modes[static_cast<uint8_t>(ETimeMode::Normal)].time;
const float mode_time = stats.modes[static_cast<uint8_t>(m_settings.time_mode)].time;
force_normal_mode = mode_time == 0.0f ||
short_time(get_time_dhms(mode_time)) == short_time(get_time_dhms(normal_time)); // TO CHECK -> Is this necessary ?
}
if (force_normal_mode)
m_settings.time_mode = ETimeMode::Normal;
}
m_tool_colors.clear();
if (settings.view_type == EViewType::Tool && !gcode_result.extruder_colors.empty())
if (m_settings.view_type == EViewType::Tool && !gcode_result.extruder_colors.empty())
// update tool colors from config stored in the gcode
decode_colors(gcode_result.extruder_colors, m_tool_colors);
else
@ -644,32 +721,35 @@ void Toolpaths::load(const Slic3r::GCodeProcessorResult& gcode_result, const std
if (i < gcode_result.print_statistics.modes.size())
m_layers_times[i] = gcode_result.print_statistics.modes[i].layers_times;
}
m_view_range.set_global_range(0, m_vertices.size() - 1);
m_settings.update_colors = true;
}
void Toolpaths::update_enabled_entities(const ViewRange& range, const Settings& settings)
void Toolpaths::update_enabled_entities()
{
std::vector<uint32_t> enabled_segments;
std::vector<uint32_t> enabled_options;
for (uint32_t i = range.get_current_min(); i < range.get_current_max(); i++) {
for (uint32_t i = m_view_range.get_current_min(); i < m_view_range.get_current_max(); i++) {
const PathVertex& v = m_vertices[i];
if (!m_valid_lines_bitset[i] && !v.is_option())
continue;
if (v.is_travel()) {
if (!settings.options_visibility.at(EOptionType::Travels))
if (!m_settings.options_visibility.at(EOptionType::Travels))
continue;
}
else if (v.is_wipe()) {
if (!settings.options_visibility.at(EOptionType::Wipes))
if (!m_settings.options_visibility.at(EOptionType::Wipes))
continue;
}
else if (v.is_option()) {
if (!settings.options_visibility.at(type_to_option(v.type)))
continue;
if (!m_settings.options_visibility.at(type_to_option(v.type)))
continue;
}
else if (v.is_extrusion()) {
if (!settings.extrusion_roles_visibility.at(v.role))
if (!m_settings.extrusion_roles_visibility.at(v.role))
continue;
}
else
@ -719,13 +799,13 @@ static float encode_color(const Color& color) {
return float(i_color);
}
void Toolpaths::update_colors(const Settings& settings)
void Toolpaths::update_colors()
{
update_color_ranges(settings);
update_color_ranges();
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], settings));
colors[i] = encode_color(select_color(m_vertices[i]));
}
// update gpu buffer for colors
@ -735,19 +815,121 @@ void Toolpaths::update_colors(const Settings& settings)
glsafe(glBindBuffer(GL_TEXTURE_BUFFER, 0));
}
void Toolpaths::render(const Mat4x4f& view_matrix, const Mat4x4f& projection_matrix, const Settings& settings)
void Toolpaths::render(const Mat4x4f& view_matrix, const Mat4x4f& projection_matrix)
{
if (m_settings.update_enabled_entities) {
update_enabled_entities();
m_settings.update_enabled_entities = false;
}
if (m_settings.update_colors) {
update_colors();
m_settings.update_colors = false;
}
const Mat4x4f inv_view_matrix = inverse(view_matrix);
const Vec3f camera_position = { inv_view_matrix[12], inv_view_matrix[13], inv_view_matrix[14] };
render_segments(view_matrix, projection_matrix, camera_position);
render_options(view_matrix, projection_matrix);
if (settings.options_visibility.at(EOptionType::ToolMarker))
if (m_settings.options_visibility.at(EOptionType::ToolMarker))
render_tool_marker(view_matrix, projection_matrix);
if (settings.options_visibility.at(EOptionType::CenterOfGravity))
if (m_settings.options_visibility.at(EOptionType::CenterOfGravity))
render_cog_marker(view_matrix, projection_matrix);
}
EViewType Toolpaths::get_view_type() const
{
return m_settings.view_type;
}
ETimeMode Toolpaths::get_time_mode() const
{
return m_settings.time_mode;
}
bool Toolpaths::is_option_visible(EOptionType type) const
{
try
{
return m_settings.options_visibility.at(type);
}
catch (...)
{
return false;
}
}
bool Toolpaths::is_extrusion_role_visible(EGCodeExtrusionRole role) const
{
try
{
return m_settings.extrusion_roles_visibility.at(role);
}
catch (...)
{
return false;
}
}
void Toolpaths::set_view_type(EViewType type)
{
m_settings.view_type = type;
m_settings.update_colors = true;
}
void Toolpaths::set_time_mode(ETimeMode mode)
{
m_settings.time_mode = mode;
m_settings.update_colors = true;
}
void Toolpaths::toggle_option_visibility(EOptionType type)
{
try
{
bool& value = m_settings.options_visibility.at(type);
value = !value;
m_settings.update_enabled_entities = true;
m_settings.update_colors = true;
}
catch (...)
{
// do nothing;
}
}
void Toolpaths::toggle_extrusion_role_visibility(EGCodeExtrusionRole role)
{
try
{
bool& value = m_settings.extrusion_roles_visibility.at(role);
value = !value;
m_settings.update_enabled_entities = true;
m_settings.update_colors = true;
}
catch (...)
{
// do nothing;
}
}
const std::array<size_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
{
return m_view_range.get_global_range();
}
void Toolpaths::set_view_current_range(size_t min, size_t max)
{
m_view_range.set_current_range(min, max);
m_settings.update_enabled_entities = true;
}
const std::array<std::vector<float>, static_cast<size_t>(ETimeMode::COUNT)>& Toolpaths::get_layers_times() const
{
return m_layers_times;
@ -915,7 +1097,7 @@ void Toolpaths::reset()
delete_buffers(m_positions_buf_id);
}
void Toolpaths::update_color_ranges(const Settings& settings)
void Toolpaths::update_color_ranges()
{
m_width_range.reset();
m_height_range.reset();
@ -930,25 +1112,25 @@ void Toolpaths::update_color_ranges(const Settings& settings)
const PathVertex& v = m_vertices[i];
if (v.is_extrusion()) {
m_height_range.update(round_to_bin(v.height));
if (!v.is_custom_gcode() || settings.extrusion_roles_visibility.at(EGCodeExtrusionRole::Custom)) {
if (!v.is_custom_gcode() || m_settings.extrusion_roles_visibility.at(EGCodeExtrusionRole::Custom)) {
m_width_range.update(round_to_bin(v.width));
m_volumetric_rate_range.update(round_to_bin(v.volumetric_rate));
}
m_fan_speed_range.update(v.fan_speed);
m_temperature_range.update(v.temperature);
}
if ((v.is_travel() && settings.options_visibility.at(EOptionType::Travels)) || v.is_extrusion())
if ((v.is_travel() && m_settings.options_visibility.at(EOptionType::Travels)) || v.is_extrusion())
m_speed_range.update(v.feedrate);
}
for (size_t i = 0; i < m_layers_times.size(); ++i) {
for (const float time : m_layers_times[static_cast<uint8_t>(settings.time_mode)]) {
for (const float time : m_layers_times[static_cast<uint8_t>(m_settings.time_mode)]) {
m_layer_time_range[i].update(time);
}
}
}
Color Toolpaths::select_color(const PathVertex& v, const Settings& settings) const
Color Toolpaths::select_color(const PathVertex& v) const
{
if (v.type == EMoveType::Noop)
return Dummy_Color;
@ -960,7 +1142,7 @@ Color Toolpaths::select_color(const PathVertex& v, const Settings& settings) con
return Options_Colors.at(v.type);
const size_t role = static_cast<size_t>(v.role);
switch (settings.view_type)
switch (m_settings.view_type)
{
case EViewType::FeatureType:
{
@ -999,12 +1181,12 @@ Color Toolpaths::select_color(const PathVertex& v, const Settings& settings) con
case EViewType::LayerTimeLinear:
{
assert(!v.is_travel() || role < Travels_Colors.size());
return v.is_travel() ? Travels_Colors[role] : m_layer_time_range[0].get_color_at(m_layers_times[static_cast<size_t>(settings.time_mode)][v.layer_id]);
return v.is_travel() ? Travels_Colors[role] : m_layer_time_range[0].get_color_at(m_layers_times[static_cast<size_t>(m_settings.time_mode)][v.layer_id]);
}
case EViewType::LayerTimeLogarithmic:
{
assert(!v.is_travel() || role < Travels_Colors.size());
return v.is_travel() ? Travels_Colors[role] : m_layer_time_range[1].get_color_at(m_layers_times[static_cast<size_t>(settings.time_mode)][v.layer_id]);
return v.is_travel() ? Travels_Colors[role] : m_layer_time_range[1].get_color_at(m_layers_times[static_cast<size_t>(m_settings.time_mode)][v.layer_id]);
}
case EViewType::Tool:
{

View File

@ -10,6 +10,7 @@
#if ENABLE_NEW_GCODE_VIEWER
//################################################################################################################################
#include "Settings.hpp"
#include "SegmentTemplate.hpp"
#include "OptionTemplate.hpp"
#include "CogMarker.hpp"
@ -17,6 +18,7 @@
#include "PathVertex.hpp"
#include "Bitset.hpp"
#include "ColorRange.hpp"
#include "ViewRange.hpp"
#include <vector>
#include <array>
@ -31,9 +33,6 @@ class Print;
namespace libvgcode {
class ViewRange;
struct Settings;
class Toolpaths
{
public:
@ -51,25 +50,50 @@ public:
//
// Setup all the variables used for visualization and coloring of the toolpaths
// from the gcode moves contained in the given gcode_result, according to the setting
// contained in the given config.
// from the gcode moves contained in the given gcode_result.
//
void load(const Slic3r::GCodeProcessorResult& gcode_result, const std::vector<std::string>& str_tool_colors,
const Settings& settings);
void load(const Slic3r::GCodeProcessorResult& gcode_result, const std::vector<std::string>& str_tool_colors);
//
// Update the visibility property of toolpaths
//
void update_enabled_entities(const ViewRange& range, const Settings& settings);
void update_enabled_entities();
//
// Update the color of toolpaths
//
void update_colors(const Settings& settings);
void update_colors();
//
// Render the toolpaths
//
void render(const Mat4x4f& view_matrix, const Mat4x4f& projection_matrix, const Settings& settings);
void render(const Mat4x4f& view_matrix, const Mat4x4f& projection_matrix);
//
// Settings getters
//
EViewType get_view_type() const;
ETimeMode get_time_mode() const;
bool is_option_visible(EOptionType type) const;
bool is_extrusion_role_visible(EGCodeExtrusionRole role) const;
//
// Settings setters
//
void set_view_type(EViewType type);
void set_time_mode(ETimeMode mode);
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;
//
// View range setters
//
void set_view_current_range(size_t min, size_t max);
//
// Properties getters
@ -109,6 +133,9 @@ public:
//################################################################################################################################
private:
Settings m_settings;
ViewRange m_view_range;
//
// The OpenGL element used to represent all toolpath segments
//
@ -236,8 +263,8 @@ private:
unsigned int m_enabled_options_tex_id{ 0 };
void reset();
void update_color_ranges(const Settings& settings);
Color select_color(const PathVertex& v, const Settings& settings) const;
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);
void render_options(const Mat4x4f& view_matrix, const Mat4x4f& projection_matrix);
void render_cog_marker(const Mat4x4f& view_matrix, const Mat4x4f& projection_matrix);

View File

@ -3,7 +3,7 @@
#include "libslic3r/Technologies.hpp"
//################################################################################################################################
///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak, Oleksandra Iushchenko @YuSanka
///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak
///|/
///|/ libvgcode is released under the terms of the AGPLv3 or higher
///|/
@ -18,73 +18,8 @@
#include "slic3r/GUI/ImGuiWrapper.hpp"
//################################################################################################################################
#include <cstdio>
namespace libvgcode {
static std::string short_time(const std::string& time)
{
// Parse the dhms time format.
int days = 0;
int hours = 0;
int minutes = 0;
int seconds = 0;
if (time.find('d') != std::string::npos)
sscanf(time.c_str(), "%dd %dh %dm %ds", &days, &hours, &minutes, &seconds);
else if (time.find('h') != std::string::npos)
sscanf(time.c_str(), "%dh %dm %ds", &hours, &minutes, &seconds);
else if (time.find('m') != std::string::npos)
sscanf(time.c_str(), "%dm %ds", &minutes, &seconds);
else if (time.find('s') != std::string::npos)
sscanf(time.c_str(), "%ds", &seconds);
// Round to full minutes.
if (days + hours + minutes > 0 && seconds >= 30) {
if (++minutes == 60) {
minutes = 0;
if (++hours == 24) {
hours = 0;
++days;
}
}
}
// Format the dhm time
char buffer[64];
if (days > 0)
sprintf(buffer, "%dd%dh%dm", days, hours, minutes);
else if (hours > 0)
sprintf(buffer, "%dh%dm", hours, minutes);
else if (minutes > 0)
sprintf(buffer, "%dm", minutes);
else
sprintf(buffer, "%ds", seconds);
return buffer;
}
// Returns the given time is seconds in format DDd HHh MMm SSs
inline std::string get_time_dhms(float time_in_secs)
{
int days = (int)(time_in_secs / 86400.0f);
time_in_secs -= (float)days * 86400.0f;
int hours = (int)(time_in_secs / 3600.0f);
time_in_secs -= (float)hours * 3600.0f;
int minutes = (int)(time_in_secs / 60.0f);
time_in_secs -= (float)minutes * 60.0f;
char buffer[64];
if (days > 0)
sprintf(buffer, "%dd %dh %dm %ds", days, hours, minutes, (int)time_in_secs);
else if (hours > 0)
sprintf(buffer, "%dh %dm %ds", hours, minutes, (int)time_in_secs);
else if (minutes > 0)
sprintf(buffer, "%dm %ds", minutes, (int)time_in_secs);
else
sprintf(buffer, "%ds", (int)std::round(time_in_secs));
return buffer;
}
void Viewer::init()
{
m_toolpaths.init();
@ -92,37 +27,12 @@ void Viewer::init()
void Viewer::load(const Slic3r::GCodeProcessorResult& gcode_result, const std::vector<std::string>& str_tool_colors)
{
if (m_settings.time_mode != ETimeMode::Normal) {
const Slic3r::PrintEstimatedStatistics& stats = gcode_result.print_statistics;
bool force_normal_mode = static_cast<size_t>(m_settings.time_mode) >= stats.modes.size();
if (!force_normal_mode) {
const float normal_time = stats.modes[static_cast<uint8_t>(ETimeMode::Normal)].time;
const float mode_time = stats.modes[static_cast<uint8_t>(m_settings.time_mode)].time;
force_normal_mode = mode_time == 0.0f ||
short_time(get_time_dhms(mode_time)) == short_time(get_time_dhms(normal_time)); // TO CHECK -> Is this necessary ?
}
if (force_normal_mode)
m_settings.time_mode = ETimeMode::Normal;
}
m_toolpaths.load(gcode_result, str_tool_colors, m_settings);
m_view_range.set_global_range(0, m_toolpaths.get_vertices_count() - 1);
m_settings.update_colors = true;
m_toolpaths.load(gcode_result, str_tool_colors);
}
void Viewer::render(const Mat4x4f& view_matrix, const Mat4x4f& projection_matrix)
{
if (m_settings.update_enabled_entities) {
m_toolpaths.update_enabled_entities(m_view_range, m_settings);
m_settings.update_enabled_entities = false;
}
if (m_settings.update_colors) {
m_toolpaths.update_colors(m_settings);
m_settings.update_colors = false;
}
m_toolpaths.render(view_matrix, projection_matrix, m_settings);
m_toolpaths.render(view_matrix, projection_matrix);
//################################################################################################################################
// Debug
@ -132,24 +42,22 @@ void Viewer::render(const Mat4x4f& view_matrix, const Mat4x4f& projection_matrix
EViewType Viewer::get_view_type() const
{
return m_settings.view_type;
return m_toolpaths.get_view_type();
}
void Viewer::set_view_type(EViewType type)
{
m_settings.view_type = type;
m_settings.update_colors = true;
m_toolpaths.set_view_type(type);
}
ETimeMode Viewer::get_time_mode() const
{
return m_settings.time_mode;
return m_toolpaths.get_time_mode();
}
void Viewer::set_time_mode(ETimeMode mode)
{
m_settings.time_mode = mode;
m_settings.update_colors = true;
m_toolpaths.set_time_mode(mode);
}
const std::array<std::vector<float>, static_cast<size_t>(ETimeMode::COUNT)>& Viewer::get_layers_times() const
@ -159,72 +67,37 @@ const std::array<std::vector<float>, static_cast<size_t>(ETimeMode::COUNT)>& Vie
bool Viewer::is_option_visible(EOptionType type) const
{
try
{
return m_settings.options_visibility.at(type);
}
catch (...)
{
return false;
}
return m_toolpaths.is_option_visible(type);
}
void Viewer::toggle_option_visibility(EOptionType type)
{
try
{
bool& value = m_settings.options_visibility.at(type);
value = !value;
m_settings.update_enabled_entities = true;
m_settings.update_colors = true;
}
catch (...)
{
// do nothing;
}
m_toolpaths.toggle_option_visibility(type);
}
bool Viewer::is_extrusion_role_visible(EGCodeExtrusionRole role) const
{
try
{
return m_settings.extrusion_roles_visibility.at(role);
}
catch (...)
{
return false;
}
return m_toolpaths.is_extrusion_role_visible(role);
}
void Viewer::toggle_extrusion_role_visibility(EGCodeExtrusionRole role)
{
try
{
bool& value = m_settings.extrusion_roles_visibility.at(role);
value = !value;
m_settings.update_enabled_entities = true;
m_settings.update_colors = true;
}
catch (...)
{
// do nothing;
}
m_toolpaths.toggle_extrusion_role_visibility(role);
}
const std::array<size_t, 2>& Viewer::get_view_current_range() const
{
return m_view_range.get_current_range();
return m_toolpaths.get_view_current_range();
}
const std::array<size_t, 2>& Viewer::get_view_global_range() const
{
return m_view_range.get_global_range();
return m_toolpaths.get_view_global_range();
}
void Viewer::set_view_current_range(size_t min, size_t max)
{
m_view_range.set_current_range(min, max);
m_settings.update_enabled_entities = true;
m_toolpaths.set_view_current_range(min, max);
}
Vec3f Viewer::get_cog_position() const
@ -317,7 +190,8 @@ void Viewer::render_debug_window()
ImGui::TableSetColumnIndex(0);
imgui.text_colored(Slic3r::GUI::ImGuiWrapper::COL_ORANGE_LIGHT, "sequential range");
ImGui::TableSetColumnIndex(1);
imgui.text(std::to_string(m_view_range.get_current_min()) + " - " + std::to_string(m_view_range.get_current_max()));
const std::array<size_t, 2>& current_view_range = m_toolpaths.get_view_current_range();
imgui.text(std::to_string(current_view_range[0]) + " - " + std::to_string(current_view_range[1]));
auto add_range_property_row = [&imgui](const std::string& label, const std::array<float, 2>& range) {
ImGui::TableNextRow();

View File

@ -10,9 +10,7 @@
#if ENABLE_NEW_GCODE_VIEWER
//################################################################################################################################
#include "Settings.hpp"
#include "Toolpaths.hpp"
#include "ViewRange.hpp"
//################################################################################################################################
// PrusaSlicer development only -> !!!TO BE REMOVED!!!
@ -87,9 +85,7 @@ public:
void set_tool_marker_alpha(float alpha);
private:
Settings m_settings;
Toolpaths m_toolpaths;
ViewRange m_view_range;
//################################################################################################################################
// Debug