GCodeViewer -> Extrusion toolpaths colored by tool
This commit is contained in:
parent
61db595f53
commit
4c4485a9b5
7 changed files with 81 additions and 19 deletions
|
@ -3,6 +3,9 @@
|
||||||
#include "libslic3r/Utils.hpp"
|
#include "libslic3r/Utils.hpp"
|
||||||
#include "../Utils/MacDarkMode.hpp"
|
#include "../Utils/MacDarkMode.hpp"
|
||||||
#include "GUI.hpp"
|
#include "GUI.hpp"
|
||||||
|
#if ENABLE_GCODE_VIEWER
|
||||||
|
#include "GUI_Utils.hpp"
|
||||||
|
#endif // ENABLE_GCODE_VIEWER
|
||||||
|
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
|
|
||||||
|
@ -352,6 +355,7 @@ wxBitmap BitmapCache::mksolid(size_t width, size_t height, unsigned char r, unsi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if !ENABLE_GCODE_VIEWER
|
||||||
static inline int hex_digit_to_int(const char c)
|
static inline int hex_digit_to_int(const char c)
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
|
@ -359,6 +363,7 @@ static inline int hex_digit_to_int(const char c)
|
||||||
(c >= 'A' && c <= 'F') ? int(c - 'A') + 10 :
|
(c >= 'A' && c <= 'F') ? int(c - 'A') + 10 :
|
||||||
(c >= 'a' && c <= 'f') ? int(c - 'a') + 10 : -1;
|
(c >= 'a' && c <= 'f') ? int(c - 'a') + 10 : -1;
|
||||||
}
|
}
|
||||||
|
#endif // !ENABLE_GCODE_VIEWER
|
||||||
|
|
||||||
bool BitmapCache::parse_color(const std::string& scolor, unsigned char* rgb_out)
|
bool BitmapCache::parse_color(const std::string& scolor, unsigned char* rgb_out)
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,6 +8,9 @@
|
||||||
#include "Camera.hpp"
|
#include "Camera.hpp"
|
||||||
#include "I18N.hpp"
|
#include "I18N.hpp"
|
||||||
#include "libslic3r/I18N.hpp"
|
#include "libslic3r/I18N.hpp"
|
||||||
|
#if ENABLE_GCODE_VIEWER
|
||||||
|
#include "GUI_Utils.hpp"
|
||||||
|
#endif // ENABLE_GCODE_VIEWER
|
||||||
|
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include <boost/log/trivial.hpp>
|
#include <boost/log/trivial.hpp>
|
||||||
|
@ -27,6 +30,31 @@ static GCodeProcessor::EMoveType buffer_type(unsigned char id) {
|
||||||
return static_cast<GCodeProcessor::EMoveType>(static_cast<unsigned char>(GCodeProcessor::EMoveType::Retract) + id);
|
return static_cast<GCodeProcessor::EMoveType>(static_cast<unsigned char>(GCodeProcessor::EMoveType::Retract) + id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::array<float, 3>> decode_colors(const std::vector<std::string>& colors)
|
||||||
|
{
|
||||||
|
static const float INV_255 = 1.0f / 255.0f;
|
||||||
|
|
||||||
|
std::vector<std::array<float, 3>> output(colors.size(), {0.0f, 0.0f, 0.0f} );
|
||||||
|
for (size_t i = 0; i < colors.size(); ++i)
|
||||||
|
{
|
||||||
|
const std::string& color = colors[i];
|
||||||
|
const char* c = color.data() + 1;
|
||||||
|
if ((color.size() == 7) && (color.front() == '#'))
|
||||||
|
{
|
||||||
|
for (size_t j = 0; j < 3; ++j)
|
||||||
|
{
|
||||||
|
int digit1 = hex_digit_to_int(*c++);
|
||||||
|
int digit2 = hex_digit_to_int(*c++);
|
||||||
|
if ((digit1 == -1) || (digit2 == -1))
|
||||||
|
break;
|
||||||
|
|
||||||
|
output[i][j] = float(digit1 * 16 + digit2) * INV_255;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
void GCodeViewer::VBuffer::reset()
|
void GCodeViewer::VBuffer::reset()
|
||||||
{
|
{
|
||||||
// release gpu memory
|
// release gpu memory
|
||||||
|
@ -68,7 +96,7 @@ bool GCodeViewer::IBuffer::init_shader(const std::string& vertex_shader_src, con
|
||||||
void GCodeViewer::IBuffer::add_path(const GCodeProcessor::MoveVertex& move)
|
void GCodeViewer::IBuffer::add_path(const GCodeProcessor::MoveVertex& move)
|
||||||
{
|
{
|
||||||
unsigned int id = static_cast<unsigned int>(data.size());
|
unsigned int id = static_cast<unsigned int>(data.size());
|
||||||
paths.push_back({ move.type, move.extrusion_role, id, id, move.height, move.width, move.feedrate, move.fan_speed, move.volumetric_rate() });
|
paths.push_back({ move.type, move.extrusion_role, id, id, move.height, move.width, move.feedrate, move.fan_speed, move.volumetric_rate(), move.extruder_id });
|
||||||
}
|
}
|
||||||
|
|
||||||
std::array<float, 3> GCodeViewer::Extrusions::Range::get_color_at(float value) const
|
std::array<float, 3> GCodeViewer::Extrusions::Range::get_color_at(float value) const
|
||||||
|
@ -126,8 +154,9 @@ const std::array<std::array<float, 3>, GCodeViewer::Range_Colors_Count> GCodeVie
|
||||||
{ 0.761f, 0.322f, 0.235f } // reddish
|
{ 0.761f, 0.322f, 0.235f } // reddish
|
||||||
}};
|
}};
|
||||||
|
|
||||||
void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print& print, bool initialized)
|
void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const std::vector<std::string>& str_tool_colors, const Print& print, bool initialized)
|
||||||
{
|
{
|
||||||
|
// avoid processing if called with the same gcode_result
|
||||||
if (m_last_result_id == gcode_result.id)
|
if (m_last_result_id == gcode_result.id)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -136,6 +165,8 @@ void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print&
|
||||||
// release gpu memory, if used
|
// release gpu memory, if used
|
||||||
reset();
|
reset();
|
||||||
|
|
||||||
|
m_tool_colors = decode_colors(str_tool_colors);
|
||||||
|
|
||||||
load_toolpaths(gcode_result);
|
load_toolpaths(gcode_result);
|
||||||
load_shells(print, initialized);
|
load_shells(print, initialized);
|
||||||
}
|
}
|
||||||
|
@ -170,10 +201,7 @@ void GCodeViewer::refresh_toolpaths_ranges(const GCodeProcessor::Result& gcode_r
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default: { break; }
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -188,6 +216,7 @@ void GCodeViewer::reset()
|
||||||
}
|
}
|
||||||
|
|
||||||
m_bounding_box = BoundingBoxf3();
|
m_bounding_box = BoundingBoxf3();
|
||||||
|
m_tool_colors = std::vector<std::array<float, 3>>();
|
||||||
m_extrusions.reset_role_visibility_flags();
|
m_extrusions.reset_role_visibility_flags();
|
||||||
m_extrusions.reset_ranges();
|
m_extrusions.reset_ranges();
|
||||||
m_shells.volumes.clear();
|
m_shells.volumes.clear();
|
||||||
|
@ -430,7 +459,7 @@ void GCodeViewer::render_toolpaths() const
|
||||||
case EViewType::Feedrate: { color = m_extrusions.ranges.feedrate.get_color_at(path.feedrate); break; }
|
case EViewType::Feedrate: { color = m_extrusions.ranges.feedrate.get_color_at(path.feedrate); break; }
|
||||||
case EViewType::FanSpeed: { color = m_extrusions.ranges.fan_speed.get_color_at(path.fan_speed); break; }
|
case EViewType::FanSpeed: { color = m_extrusions.ranges.fan_speed.get_color_at(path.fan_speed); break; }
|
||||||
case EViewType::VolumetricRate: { color = m_extrusions.ranges.volumetric_rate.get_color_at(path.volumetric_rate); break; }
|
case EViewType::VolumetricRate: { color = m_extrusions.ranges.volumetric_rate.get_color_at(path.volumetric_rate); break; }
|
||||||
case EViewType::Tool:
|
case EViewType::Tool: { color = m_tool_colors[path.extruder_id]; break; }
|
||||||
case EViewType::ColorPrint:
|
case EViewType::ColorPrint:
|
||||||
default: { color = { 1.0f, 1.0f, 1.0f }; break; }
|
default: { color = { 1.0f, 1.0f, 1.0f }; break; }
|
||||||
}
|
}
|
||||||
|
@ -640,7 +669,22 @@ void GCodeViewer::render_overlay() const
|
||||||
case EViewType::Feedrate: { add_range(m_extrusions.ranges.feedrate, 1); break; }
|
case EViewType::Feedrate: { add_range(m_extrusions.ranges.feedrate, 1); break; }
|
||||||
case EViewType::FanSpeed: { add_range(m_extrusions.ranges.fan_speed, 0); break; }
|
case EViewType::FanSpeed: { add_range(m_extrusions.ranges.fan_speed, 0); break; }
|
||||||
case EViewType::VolumetricRate: { add_range(m_extrusions.ranges.volumetric_rate, 3); break; }
|
case EViewType::VolumetricRate: { add_range(m_extrusions.ranges.volumetric_rate, 3); break; }
|
||||||
case EViewType::Tool: { break; }
|
case EViewType::Tool:
|
||||||
|
{
|
||||||
|
size_t tools_count = m_tool_colors.size();
|
||||||
|
for (size_t i = 0; i < tools_count; ++i)
|
||||||
|
{
|
||||||
|
ImVec2 pos(ImGui::GetCursorPosX() + 2.0f, ImGui::GetCursorPosY() + 2.0f);
|
||||||
|
draw_list->AddRect(ImVec2(pos.x, pos.y), ImVec2(pos.x + ICON_BORDER_SIZE, pos.y + ICON_BORDER_SIZE), ICON_BORDER_COLOR, 0.0f, 0);
|
||||||
|
const std::array<float, 3>& color = m_tool_colors[i];
|
||||||
|
ImU32 fill_color = ImGui::GetColorU32(ImVec4(color[0], color[1], color[2], 1.0));
|
||||||
|
draw_list->AddRectFilled(ImVec2(pos.x + 1.0f, pos.y + 1.0f), ImVec2(pos.x + ICON_BORDER_SIZE - 1.0f, pos.y + ICON_BORDER_SIZE - 1.0f), fill_color);
|
||||||
|
ImGui::SetCursorPosX(pos.x + ICON_BORDER_SIZE + GAP_ICON_TEXT);
|
||||||
|
ImGui::AlignTextToFramePadding();
|
||||||
|
imgui.text((boost::format(Slic3r::I18N::translate(L("Extruder %d"))) % (i + 1)).str());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case EViewType::ColorPrint: { break; }
|
case EViewType::ColorPrint: { break; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,10 +45,12 @@ class GCodeViewer
|
||||||
float feedrate{ 0.0f };
|
float feedrate{ 0.0f };
|
||||||
float fan_speed{ 0.0f };
|
float fan_speed{ 0.0f };
|
||||||
float volumetric_rate{ 0.0f };
|
float volumetric_rate{ 0.0f };
|
||||||
|
unsigned char extruder_id{ 0 };
|
||||||
|
|
||||||
bool matches(const GCodeProcessor::MoveVertex& move) const {
|
bool matches(const GCodeProcessor::MoveVertex& move) const {
|
||||||
return type == move.type && role == move.extrusion_role && height == move.height && width == move.width &&
|
return type == move.type && role == move.extrusion_role && height == move.height && width == move.width &&
|
||||||
feedrate == move.feedrate && fan_speed == move.fan_speed && volumetric_rate == move.volumetric_rate();
|
feedrate == move.feedrate && fan_speed == move.fan_speed && volumetric_rate == move.volumetric_rate() &&
|
||||||
|
extruder_id == move.extruder_id;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -146,11 +148,11 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
unsigned int m_last_result_id{ 0 };
|
||||||
VBuffer m_vertices;
|
VBuffer m_vertices;
|
||||||
std::vector<IBuffer> m_buffers{ static_cast<size_t>(GCodeProcessor::EMoveType::Extrude) };
|
std::vector<IBuffer> m_buffers{ static_cast<size_t>(GCodeProcessor::EMoveType::Extrude) };
|
||||||
BoundingBoxf3 m_bounding_box;
|
BoundingBoxf3 m_bounding_box;
|
||||||
|
std::vector<std::array<float, 3>> m_tool_colors;
|
||||||
unsigned int m_last_result_id{ 0 };
|
|
||||||
std::vector<double> m_layers_zs;
|
std::vector<double> m_layers_zs;
|
||||||
std::vector<ExtrusionRole> m_roles;
|
std::vector<ExtrusionRole> m_roles;
|
||||||
Extrusions m_extrusions;
|
Extrusions m_extrusions;
|
||||||
|
@ -167,7 +169,9 @@ public:
|
||||||
return init_shaders();
|
return init_shaders();
|
||||||
}
|
}
|
||||||
|
|
||||||
void load(const GCodeProcessor::Result& gcode_result, const Print& print, bool initialized);
|
// extract rendering data from the given parameters
|
||||||
|
void load(const GCodeProcessor::Result& gcode_result, const std::vector<std::string>& str_tool_colors, const Print& print, bool initialized);
|
||||||
|
// recalculate ranges in dependence of what is visible
|
||||||
void refresh_toolpaths_ranges(const GCodeProcessor::Result& gcode_result);
|
void refresh_toolpaths_ranges(const GCodeProcessor::Result& gcode_result);
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
|
|
|
@ -2835,7 +2835,7 @@ static void load_gcode_retractions(const GCodePreviewData::Retraction& retractio
|
||||||
#endif // !ENABLE_GCODE_VIEWER
|
#endif // !ENABLE_GCODE_VIEWER
|
||||||
|
|
||||||
#if ENABLE_GCODE_VIEWER
|
#if ENABLE_GCODE_VIEWER
|
||||||
void GLCanvas3D::load_gcode_preview(const GCodeProcessor::Result& gcode_result)
|
void GLCanvas3D::load_gcode_preview(const GCodeProcessor::Result& gcode_result, const std::vector<std::string>& str_tool_colors)
|
||||||
{
|
{
|
||||||
#if ENABLE_GCODE_VIEWER_DEBUG_OUTPUT
|
#if ENABLE_GCODE_VIEWER_DEBUG_OUTPUT
|
||||||
static unsigned int last_result_id = 0;
|
static unsigned int last_result_id = 0;
|
||||||
|
@ -2852,7 +2852,7 @@ void GLCanvas3D::load_gcode_preview(const GCodeProcessor::Result& gcode_result)
|
||||||
out.close();
|
out.close();
|
||||||
}
|
}
|
||||||
#endif // ENABLE_GCODE_VIEWER_DEBUG_OUTPUT
|
#endif // ENABLE_GCODE_VIEWER_DEBUG_OUTPUT
|
||||||
m_gcode_viewer.load(gcode_result, *this->fff_print(), m_initialized);
|
m_gcode_viewer.load(gcode_result, str_tool_colors , *this->fff_print(), m_initialized);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLCanvas3D::refresh_toolpaths_ranges(const GCodeProcessor::Result& gcode_result)
|
void GLCanvas3D::refresh_toolpaths_ranges(const GCodeProcessor::Result& gcode_result)
|
||||||
|
@ -6594,6 +6594,7 @@ void GLCanvas3D::_load_wipe_tower_toolpaths(const std::vector<std::string>& str_
|
||||||
BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - end" << m_volumes.log_memory_info() << log_memory_info();
|
BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - end" << m_volumes.log_memory_info() << log_memory_info();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !ENABLE_GCODE_VIEWER
|
||||||
static inline int hex_digit_to_int(const char c)
|
static inline int hex_digit_to_int(const char c)
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
|
@ -6602,7 +6603,6 @@ static inline int hex_digit_to_int(const char c)
|
||||||
(c >= 'a' && c <= 'f') ? int(c - 'a') + 10 : -1;
|
(c >= 'a' && c <= 'f') ? int(c - 'a') + 10 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !ENABLE_GCODE_VIEWER
|
|
||||||
void GLCanvas3D::_load_gcode_extrusion_paths(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors)
|
void GLCanvas3D::_load_gcode_extrusion_paths(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors)
|
||||||
{
|
{
|
||||||
BOOST_LOG_TRIVIAL(debug) << "Loading G-code extrusion paths - start" << m_volumes.log_memory_info() << log_memory_info();
|
BOOST_LOG_TRIVIAL(debug) << "Loading G-code extrusion paths - start" << m_volumes.log_memory_info() << log_memory_info();
|
||||||
|
|
|
@ -664,7 +664,7 @@ public:
|
||||||
void reload_scene(bool refresh_immediately, bool force_full_scene_refresh = false);
|
void reload_scene(bool refresh_immediately, bool force_full_scene_refresh = false);
|
||||||
|
|
||||||
#if ENABLE_GCODE_VIEWER
|
#if ENABLE_GCODE_VIEWER
|
||||||
void load_gcode_preview(const GCodeProcessor::Result& gcode_result);
|
void load_gcode_preview(const GCodeProcessor::Result& gcode_result, const std::vector<std::string>& str_tool_colors);
|
||||||
void refresh_toolpaths_ranges(const GCodeProcessor::Result& gcode_result);
|
void refresh_toolpaths_ranges(const GCodeProcessor::Result& gcode_result);
|
||||||
#else
|
#else
|
||||||
void load_gcode_preview(const GCodePreviewData& preview_data, const std::vector<std::string>& str_tool_colors);
|
void load_gcode_preview(const GCodePreviewData& preview_data, const std::vector<std::string>& str_tool_colors);
|
||||||
|
|
|
@ -984,7 +984,7 @@ void Preview::load_print_as_fff(bool keep_z_range)
|
||||||
if (gcode_preview_data_valid) {
|
if (gcode_preview_data_valid) {
|
||||||
// Load the real G-code preview.
|
// Load the real G-code preview.
|
||||||
#if ENABLE_GCODE_VIEWER
|
#if ENABLE_GCODE_VIEWER
|
||||||
m_canvas->load_gcode_preview(*m_gcode_result);
|
m_canvas->load_gcode_preview(*m_gcode_result, colors);
|
||||||
m_canvas->refresh_toolpaths_ranges(*m_gcode_result);
|
m_canvas->refresh_toolpaths_ranges(*m_gcode_result);
|
||||||
#else
|
#else
|
||||||
m_canvas->load_gcode_preview(*m_gcode_preview_data, colors);
|
m_canvas->load_gcode_preview(*m_gcode_preview_data, colors);
|
||||||
|
|
|
@ -343,6 +343,15 @@ public:
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream &os, const WindowMetrics& metrics);
|
std::ostream& operator<<(std::ostream &os, const WindowMetrics& metrics);
|
||||||
|
|
||||||
|
#if ENABLE_GCODE_VIEWER
|
||||||
|
inline int hex_digit_to_int(const char c)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
(c >= '0' && c <= '9') ? int(c - '0') :
|
||||||
|
(c >= 'A' && c <= 'F') ? int(c - 'A') + 10 :
|
||||||
|
(c >= 'a' && c <= 'f') ? int(c - 'a') + 10 : -1;
|
||||||
|
}
|
||||||
|
#endif // ENABLE_GCODE_VIEWER
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue