mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-13 09:47:58 -06:00
GCodeViewer -> Extrusion toolpaths colored by feedrate and ranges calculations dependent on travel paths visibility
This commit is contained in:
parent
dc3c5db9fe
commit
3ba6ac7836
5 changed files with 74 additions and 32 deletions
|
@ -62,7 +62,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 });
|
paths.push_back({ move.type, move.extrusion_role, id, id, move.height, move.width, move.feedrate });
|
||||||
}
|
}
|
||||||
|
|
||||||
std::array<float, 3> GCodeViewer::Extrusions::Range::get_color_at(float value, const std::array<std::array<float, 3>, Default_Range_Colors_Count>& colors) const
|
std::array<float, 3> GCodeViewer::Extrusions::Range::get_color_at(float value, const std::array<std::array<float, 3>, Default_Range_Colors_Count>& colors) const
|
||||||
|
@ -78,7 +78,7 @@ std::array<float, 3> GCodeViewer::Extrusions::Range::get_color_at(float value, c
|
||||||
const size_t color_high_idx = std::clamp<size_t>(color_low_idx + 1, 0, color_max_idx);
|
const size_t color_high_idx = std::clamp<size_t>(color_low_idx + 1, 0, color_max_idx);
|
||||||
|
|
||||||
// Compute how far the value is between the low and high colors so that they can be interpolated
|
// Compute how far the value is between the low and high colors so that they can be interpolated
|
||||||
const float local_t = std::min(global_t - static_cast<float>(color_low_idx), 1.0f); // upper limit of 1.0f
|
const float local_t = std::clamp(global_t - static_cast<float>(color_low_idx), 0.0f, 1.0f);
|
||||||
|
|
||||||
// Interpolate between the low and high colors in RGB space to find exactly which color the input value should get
|
// Interpolate between the low and high colors in RGB space to find exactly which color the input value should get
|
||||||
std::array<float, 3> ret;
|
std::array<float, 3> ret;
|
||||||
|
@ -134,6 +134,42 @@ void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print&
|
||||||
load_shells(print, initialized);
|
load_shells(print, initialized);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GCodeViewer::refresh_toolpaths_ranges(const GCodeProcessor::Result& gcode_result)
|
||||||
|
{
|
||||||
|
if (m_vertices.vertices_count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_extrusions.reset_ranges();
|
||||||
|
|
||||||
|
for (size_t i = 0; i < m_vertices.vertices_count; ++i)
|
||||||
|
{
|
||||||
|
// skip first vertex
|
||||||
|
if (i == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const GCodeProcessor::MoveVertex& curr = gcode_result.moves[i];
|
||||||
|
|
||||||
|
switch (curr.type)
|
||||||
|
{
|
||||||
|
case GCodeProcessor::EMoveType::Extrude:
|
||||||
|
case GCodeProcessor::EMoveType::Travel:
|
||||||
|
{
|
||||||
|
if (m_buffers[buffer_id(curr.type)].visible)
|
||||||
|
{
|
||||||
|
m_extrusions.ranges.height.update_from(curr.height);
|
||||||
|
m_extrusions.ranges.width.update_from(curr.width);
|
||||||
|
m_extrusions.ranges.feedrate.update_from(curr.feedrate);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void GCodeViewer::reset()
|
void GCodeViewer::reset()
|
||||||
{
|
{
|
||||||
m_vertices.reset();
|
m_vertices.reset();
|
||||||
|
@ -290,12 +326,6 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
|
||||||
{
|
{
|
||||||
buffer.add_path(curr);
|
buffer.add_path(curr);
|
||||||
buffer.data.push_back(static_cast<unsigned int>(i - 1));
|
buffer.data.push_back(static_cast<unsigned int>(i - 1));
|
||||||
|
|
||||||
if (curr.type == GCodeProcessor::EMoveType::Extrude)
|
|
||||||
{
|
|
||||||
m_extrusions.ranges.height.update_from(curr.height);
|
|
||||||
m_extrusions.ranges.width.update_from(curr.width);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer.paths.back().last = static_cast<unsigned int>(buffer.data.size());
|
buffer.paths.back().last = static_cast<unsigned int>(buffer.data.size());
|
||||||
|
@ -416,16 +446,12 @@ void GCodeViewer::render_toolpaths() const
|
||||||
case EViewType::FeatureType: { color = m_extrusions.role_colors[static_cast<unsigned int>(path.role)]; break; }
|
case EViewType::FeatureType: { color = m_extrusions.role_colors[static_cast<unsigned int>(path.role)]; break; }
|
||||||
case EViewType::Height: { color = m_extrusions.ranges.height.get_color_at(path.height, m_extrusions.ranges.colors); break; }
|
case EViewType::Height: { color = m_extrusions.ranges.height.get_color_at(path.height, m_extrusions.ranges.colors); break; }
|
||||||
case EViewType::Width: { color = m_extrusions.ranges.width.get_color_at(path.width, m_extrusions.ranges.colors); break; }
|
case EViewType::Width: { color = m_extrusions.ranges.width.get_color_at(path.width, m_extrusions.ranges.colors); break; }
|
||||||
case EViewType::Feedrate:
|
case EViewType::Feedrate: { color = m_extrusions.ranges.feedrate.get_color_at(path.feedrate, m_extrusions.ranges.colors); break; }
|
||||||
case EViewType::FanSpeed:
|
case EViewType::FanSpeed:
|
||||||
case EViewType::VolumetricRate:
|
case EViewType::VolumetricRate:
|
||||||
case EViewType::Tool:
|
case EViewType::Tool:
|
||||||
case EViewType::ColorPrint:
|
case EViewType::ColorPrint:
|
||||||
default:
|
default: { color = { 1.0f, 1.0f, 1.0f }; break; }
|
||||||
{
|
|
||||||
color = { 1.0f, 1.0f, 1.0f };
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return color;
|
return color;
|
||||||
};
|
};
|
||||||
|
@ -568,8 +594,8 @@ void GCodeViewer::render_overlay() const
|
||||||
|
|
||||||
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||||||
|
|
||||||
auto add_range = [this, draw_list, &imgui](const Extrusions::Range& range) {
|
auto add_range = [this, draw_list, &imgui](const Extrusions::Range& range, unsigned int decimals) {
|
||||||
auto add_item = [this, draw_list, &imgui](int i, float value) {
|
auto add_item = [this, draw_list, &imgui](int i, float value, unsigned int decimals) {
|
||||||
ImVec2 pos(ImGui::GetCursorPosX() + 2.0f, ImGui::GetCursorPosY() + 2.0f);
|
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);
|
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_extrusions.ranges.colors[i];
|
const std::array<float, 3>& color = m_extrusions.ranges.colors[i];
|
||||||
|
@ -578,18 +604,18 @@ void GCodeViewer::render_overlay() const
|
||||||
ImGui::SetCursorPosX(pos.x + ICON_BORDER_SIZE + GAP_ICON_TEXT);
|
ImGui::SetCursorPosX(pos.x + ICON_BORDER_SIZE + GAP_ICON_TEXT);
|
||||||
ImGui::AlignTextToFramePadding();
|
ImGui::AlignTextToFramePadding();
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
::sprintf(buf, "%.*f", 3, value);
|
::sprintf(buf, "%.*f", decimals, value);
|
||||||
imgui.text(buf);
|
imgui.text(buf);
|
||||||
};
|
};
|
||||||
|
|
||||||
float step_size = range.step_size();
|
float step_size = range.step_size();
|
||||||
if (step_size == 0.0f)
|
if (step_size == 0.0f)
|
||||||
add_item(0, range.min);
|
add_item(0, range.min, decimals);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (int i = Default_Range_Colors_Count - 1; i >= 0; --i)
|
for (int i = Default_Range_Colors_Count - 1; i >= 0; --i)
|
||||||
{
|
{
|
||||||
add_item(i, range.min + static_cast<float>(i) * step_size);
|
add_item(i, range.min + static_cast<float>(i) * step_size, decimals);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -619,7 +645,7 @@ void GCodeViewer::render_overlay() const
|
||||||
ImVec2 pos(ImGui::GetCursorPosX() + 2.0f, ImGui::GetCursorPosY() + 2.0f);
|
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);
|
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_extrusions.role_colors[static_cast<unsigned int>(role)];
|
const std::array<float, 3>& color = m_extrusions.role_colors[static_cast<unsigned int>(role)];
|
||||||
ImU32 fill_color = ImGui::GetColorU32(ImVec4(color[0], color[1], color[2], color[3]));
|
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);
|
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::SetCursorPosX(pos.x + ICON_BORDER_SIZE + GAP_ICON_TEXT);
|
||||||
ImGui::AlignTextToFramePadding();
|
ImGui::AlignTextToFramePadding();
|
||||||
|
@ -629,15 +655,19 @@ void GCodeViewer::render_overlay() const
|
||||||
}
|
}
|
||||||
case EViewType::Height:
|
case EViewType::Height:
|
||||||
{
|
{
|
||||||
add_range(m_extrusions.ranges.height);
|
add_range(m_extrusions.ranges.height, 3);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EViewType::Width:
|
case EViewType::Width:
|
||||||
{
|
{
|
||||||
add_range(m_extrusions.ranges.width);
|
add_range(m_extrusions.ranges.width, 3);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EViewType::Feedrate:
|
||||||
|
{
|
||||||
|
add_range(m_extrusions.ranges.feedrate, 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EViewType::Feedrate: { break; }
|
|
||||||
case EViewType::FanSpeed: { break; }
|
case EViewType::FanSpeed: { break; }
|
||||||
case EViewType::VolumetricRate: { break; }
|
case EViewType::VolumetricRate: { break; }
|
||||||
case EViewType::Tool: { break; }
|
case EViewType::Tool: { break; }
|
||||||
|
|
|
@ -42,9 +42,10 @@ class GCodeViewer
|
||||||
unsigned int last{ 0 };
|
unsigned int last{ 0 };
|
||||||
float height{ 0.0f };
|
float height{ 0.0f };
|
||||||
float width{ 0.0f };
|
float width{ 0.0f };
|
||||||
|
float feedrate{ 0.0f };
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -104,8 +105,8 @@ class GCodeViewer
|
||||||
Range height;
|
Range height;
|
||||||
// Color mapping by extrusion width.
|
// Color mapping by extrusion width.
|
||||||
Range width;
|
Range width;
|
||||||
// // Color mapping by feedrate.
|
// Color mapping by feedrate.
|
||||||
// MultiRange<FeedrateKind> feedrate;
|
Range feedrate;
|
||||||
// // Color mapping by fan speed.
|
// // Color mapping by fan speed.
|
||||||
// Range fan_speed;
|
// Range fan_speed;
|
||||||
// // Color mapping by volumetric extrusion rate.
|
// // Color mapping by volumetric extrusion rate.
|
||||||
|
@ -114,6 +115,7 @@ class GCodeViewer
|
||||||
void reset() {
|
void reset() {
|
||||||
height.reset();
|
height.reset();
|
||||||
width.reset();
|
width.reset();
|
||||||
|
feedrate.reset();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -173,7 +175,10 @@ public:
|
||||||
set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Extrude, true);
|
set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Extrude, true);
|
||||||
return init_shaders();
|
return init_shaders();
|
||||||
}
|
}
|
||||||
|
|
||||||
void load(const GCodeProcessor::Result& gcode_result, const Print& print, bool initialized);
|
void load(const GCodeProcessor::Result& gcode_result, const Print& print, bool initialized);
|
||||||
|
void refresh_toolpaths_ranges(const GCodeProcessor::Result& gcode_result);
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
void render() const;
|
void render() const;
|
||||||
|
|
||||||
|
|
|
@ -2833,7 +2833,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_2(const GCodeProcessor::Result& gcode_result)
|
void GLCanvas3D::load_gcode_preview(const GCodeProcessor::Result& gcode_result)
|
||||||
{
|
{
|
||||||
#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,6 +2852,11 @@ void GLCanvas3D::load_gcode_preview_2(const GCodeProcessor::Result& gcode_result
|
||||||
#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, *this->fff_print(), m_initialized);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GLCanvas3D::refresh_toolpaths_ranges(const GCodeProcessor::Result& gcode_result)
|
||||||
|
{
|
||||||
|
m_gcode_viewer.refresh_toolpaths_ranges(gcode_result);
|
||||||
|
}
|
||||||
#endif // ENABLE_GCODE_VIEWER
|
#endif // ENABLE_GCODE_VIEWER
|
||||||
|
|
||||||
#if !ENABLE_GCODE_VIEWER
|
#if !ENABLE_GCODE_VIEWER
|
||||||
|
|
|
@ -664,7 +664,8 @@ 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_2(const GCodeProcessor::Result& gcode_result);
|
void load_gcode_preview(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);
|
||||||
#endif // ENABLE_GCODE_VIEWER
|
#endif // ENABLE_GCODE_VIEWER
|
||||||
|
|
|
@ -984,7 +984,8 @@ 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_2(*m_gcode_result);
|
m_canvas->load_gcode_preview(*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);
|
||||||
#endif // ENABLE_GCODE_VIEWER
|
#endif // ENABLE_GCODE_VIEWER
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue