New gcode visualization integration - Export toolpaths to obj

This commit is contained in:
enricoturri1966 2023-12-15 12:37:24 +01:00 committed by Lukas Matena
parent dcd8b30842
commit 137495dd88
5 changed files with 500 additions and 187 deletions

View File

@ -1,9 +1,9 @@
///|/ Copyright (c) Prusa Research 2020 - 2023 Enrico Turri @enricoturri1966, Oleksandra Iushchenko @YuSanka, Lukáš Matěna @lukasmatena, Vojtěch Bubník @bubnikv, Filip Sykala @Jony01, Lukáš Hejl @hejllukas
///|/ Copyright (c) BambuStudio 2023 manch1n @manch1n
///|/ Copyright (c) SuperSlicer 2023 Remi Durand @supermerill
///|/
///|/ PrusaSlicer is released under the terms of the AGPLv3 or higher
///|/
///|/ Copyright (c) Prusa Research 2020 - 2023 Enrico Turri @enricoturri1966, Oleksandra Iushchenko @YuSanka, Lukáš Matěna @lukasmatena, Vojtěch Bubník @bubnikv, Filip Sykala @Jony01, Lukáš Hejl @hejllukas
///|/ Copyright (c) BambuStudio 2023 manch1n @manch1n
///|/ Copyright (c) SuperSlicer 2023 Remi Durand @supermerill
///|/
///|/ PrusaSlicer is released under the terms of the AGPLv3 or higher
///|/
#include "libslic3r/libslic3r.h"
#include "GCodeViewer.hpp"
@ -200,11 +200,11 @@ void GCodeViewer::TBuffer::add_path(const GCodeProcessorResult::MoveVertex& move
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#if ENABLE_NEW_GCODE_VIEWER
#if ENABLE_NEW_GCODE_VIEWER_NO_COG_AND_TOOL_MARKERS
#if ENABLE_NEW_GCODE_VIEWER_NO_COG_AND_TOOL_MARKERS
void GCodeViewer::COG::render()
#else
void GCodeViewer::COG::render(bool fixed_screen_size)
#endif // ENABLE_NEW_GCODE_VIEWER_NO_COG_AND_TOOL_MARKERS
#endif // ENABLE_NEW_GCODE_VIEWER_NO_COG_AND_TOOL_MARKERS
#else
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
void GCodeViewer::COG::render()
@ -217,12 +217,12 @@ void GCodeViewer::COG::render()
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#if ENABLE_NEW_GCODE_VIEWER
#if ENABLE_NEW_GCODE_VIEWER_NO_COG_AND_TOOL_MARKERS
#if ENABLE_NEW_GCODE_VIEWER_NO_COG_AND_TOOL_MARKERS
init();
#else
fixed_screen_size = true;
init(fixed_screen_size);
#endif // ENABLE_NEW_GCODE_VIEWER_NO_COG_AND_TOOL_MARKERS
#endif // ENABLE_NEW_GCODE_VIEWER_NO_COG_AND_TOOL_MARKERS
#else
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
init();
@ -242,11 +242,11 @@ void GCodeViewer::COG::render()
Transform3d model_matrix = Geometry::translation_transform(cog()) * Geometry::scale_transform(m_scale_factor);
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#if ENABLE_NEW_GCODE_VIEWER
#if ENABLE_NEW_GCODE_VIEWER_NO_COG_AND_TOOL_MARKERS
#if ENABLE_NEW_GCODE_VIEWER_NO_COG_AND_TOOL_MARKERS
if (m_fixed_screen_size) {
#else
if (fixed_screen_size) {
#endif // ENABLE_NEW_GCODE_VIEWER_NO_COG_AND_TOOL_MARKERS
#endif // ENABLE_NEW_GCODE_VIEWER_NO_COG_AND_TOOL_MARKERS
#else
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
if (m_fixed_screen_size) {
@ -429,8 +429,8 @@ void GCodeViewer::SequentialView::Marker::render()
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#if ENABLE_NEW_GCODE_VIEWER
static std::string to_string(libvgcode::EMoveType type)
{
static std::string to_string(libvgcode::EMoveType type)
{
switch (type)
{
case libvgcode::EMoveType::Noop: { return _u8L("Noop"); }
@ -445,13 +445,13 @@ static std::string to_string(libvgcode::EMoveType type)
case libvgcode::EMoveType::Wipe: { return _u8L("Wipe"); }
case libvgcode::EMoveType::Extrude: { return _u8L("Extrude"); }
default: { return _u8L("Unknown"); }
}
}
static std::string to_string(libvgcode::EGCodeExtrusionRole role)
{
switch (role)
{
}
}
static std::string to_string(libvgcode::EGCodeExtrusionRole role)
{
switch (role)
{
case libvgcode::EGCodeExtrusionRole::None: { return _u8L("Unknown"); }
case libvgcode::EGCodeExtrusionRole::Perimeter: { return _u8L("Perimeter"); }
case libvgcode::EGCodeExtrusionRole::ExternalPerimeter: { return _u8L("External perimeter"); }
@ -468,16 +468,16 @@ static std::string to_string(libvgcode::EGCodeExtrusionRole role)
case libvgcode::EGCodeExtrusionRole::WipeTower: { return _u8L("Wipe tower"); }
case libvgcode::EGCodeExtrusionRole::Custom: { return _u8L("Custom"); }
default: { return _u8L("Unknown"); }
}
}
}
}
void GCodeViewer::SequentialView::Marker::render_position_window(const libvgcode::Viewer* viewer)
{
static float last_window_width = 0.0f;
static size_t last_text_length = 0;
static bool properties_shown = false;
if (viewer != nullptr) {
if (viewer != nullptr) {
ImGuiWrapper& imgui = *wxGetApp().imgui();
const Size cnv_size = wxGetApp().plater()->get_current_canvas3D()->get_canvas_size();
imgui.set_next_window_pos(0.5f * static_cast<float>(cnv_size.get_width()), static_cast<float>(cnv_size.get_height()), ImGuiCond_Always, 0.5f, 1.0f);
@ -552,8 +552,8 @@ void GCodeViewer::SequentialView::Marker::render_position_window(const libvgcode
imgui.end();
ImGui::PopStyleVar();
}
else {
}
else {
ImGuiWrapper& imgui = *wxGetApp().imgui();
const Size cnv_size = wxGetApp().plater()->get_current_canvas3D()->get_canvas_size();
imgui.set_next_window_pos(0.5f * static_cast<float>(cnv_size.get_width()), static_cast<float>(cnv_size.get_height()), ImGuiCond_Always, 0.5f, 1.0f);
@ -578,7 +578,7 @@ void GCodeViewer::SequentialView::Marker::render_position_window(const libvgcode
imgui.end();
ImGui::PopStyleVar();
}
}
}
#endif // ENABLE_NEW_GCODE_VIEWER
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ -907,10 +907,10 @@ void GCodeViewer::SequentialView::GCodeWindow::render(float top, float bottom, s
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#if ENABLE_NEW_GCODE_VIEWER
void GCodeViewer::SequentialView::render(float legend_height, const libvgcode::Viewer* viewer, uint32_t gcode_id)
{
#if !ENABLE_NEW_GCODE_VIEWER_NO_COG_AND_TOOL_MARKERS
{
#if !ENABLE_NEW_GCODE_VIEWER_NO_COG_AND_TOOL_MARKERS
if (viewer == nullptr)
#endif // !ENABLE_NEW_GCODE_VIEWER_NO_COG_AND_TOOL_MARKERS
#endif // !ENABLE_NEW_GCODE_VIEWER_NO_COG_AND_TOOL_MARKERS
#else
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
void GCodeViewer::SequentialView::render(float legend_height)
@ -1150,28 +1150,28 @@ void GCodeViewer::load_as_gcode(const GCodeProcessorResult& gcode_result, const
const ColorRGBA default_color = { 1.0f, 0.5f, 0.0f, 1.0f }; // "#FF8000"
while (tool_colors.size() < std::max<size_t>(1, gcode_result.extruders_count)) {
tool_colors.push_back(default_color);
}
std::vector<libvgcode::Color> colors;
colors.reserve(tool_colors.size());
for (const ColorRGBA& color : tool_colors) {
colors.emplace_back(libvgcode::convert(color));
}
m_viewer.set_tool_colors(colors);
}
std::vector<libvgcode::Color> colors;
colors.reserve(tool_colors.size());
for (const ColorRGBA& color : tool_colors) {
colors.emplace_back(libvgcode::convert(color));
}
m_viewer.set_tool_colors(colors);
// avoid processing if called with the same gcode_result
if (m_last_result_id == gcode_result.id)
return;
m_last_result_id = gcode_result.id;
// release gpu memory, if used
reset();
// convert data from PrusaSlicer format to libvgcode format
libvgcode::GCodeInputData data = libvgcode::convert(gcode_result, m_viewer.get_travels_radius(), m_viewer.get_wipes_radius());
// send data to the viewer
// convert data from PrusaSlicer format to libvgcode format
libvgcode::GCodeInputData data = libvgcode::convert(gcode_result, m_viewer.get_travels_radius(), m_viewer.get_wipes_radius());
// send data to the viewer
m_viewer.reset_default_extrusion_roles_colors();
m_viewer.load(std::move(data));
@ -1339,11 +1339,11 @@ void GCodeViewer::load_as_preview(libvgcode::GCodeInputData&& data, const std::v
if (!str_tool_colors.empty()) {
std::vector<ColorRGBA> tool_colors;
decode_colors(str_tool_colors, tool_colors);
std::vector<libvgcode::Color> colors;
colors.reserve(tool_colors.size());
for (const ColorRGBA& color : tool_colors) {
colors.emplace_back(libvgcode::convert(color));
}
std::vector<libvgcode::Color> colors;
colors.reserve(tool_colors.size());
for (const ColorRGBA& color : tool_colors) {
colors.emplace_back(libvgcode::convert(color));
}
m_viewer.set_tool_colors(colors);
}
@ -1569,40 +1569,40 @@ void GCodeViewer::render()
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#if ENABLE_NEW_GCODE_VIEWER
#if !ENABLE_NEW_GCODE_VIEWER_NO_COG_AND_TOOL_MARKERS
#if !ENABLE_NEW_GCODE_VIEWER_NO_COG_AND_TOOL_MARKERS
if (is_legend_shown()) {
ImGuiWrapper& imgui = *Slic3r::GUI::wxGetApp().imgui();
ImGuiWrapper& imgui = *Slic3r::GUI::wxGetApp().imgui();
const Size cnv_size = wxGetApp().plater()->get_current_canvas3D()->get_canvas_size();
imgui.set_next_window_pos(static_cast<float>(cnv_size.get_width()), static_cast<float>(cnv_size.get_height()), ImGuiCond_Always, 1.0f, 1.0f);
imgui.begin(std::string("LibVGCode Viewer Controller"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize);
imgui.checkbox("Cog marker fixed screen size", m_cog_marker_fixed_screen_size);
if (ImGui::BeginTable("Cog", 2)) {
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
imgui.text_colored(Slic3r::GUI::ImGuiWrapper::COL_ORANGE_LIGHT, "Cog marker size");
ImGui::TableSetColumnIndex(1);
imgui.slider_float("##CogSize", &m_cog_marker_size, 1.0f, 5.0f);
ImGui::EndTable();
}
imgui.checkbox("Tool marker fixed screen size", m_tool_marker_fixed_screen_size);
if (ImGui::BeginTable("Tool", 2)) {
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
imgui.text_colored(Slic3r::GUI::ImGuiWrapper::COL_ORANGE_LIGHT, "Tool marker size");
ImGui::TableSetColumnIndex(1);
imgui.slider_float("##ToolSize", &m_tool_marker_size, 1.0f, 5.0f);
ImGui::EndTable();
}
imgui.end();
}
#endif // !ENABLE_NEW_GCODE_VIEWER_NO_COG_AND_TOOL_MARKERS
imgui.begin(std::string("LibVGCode Viewer Controller"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize);
imgui.checkbox("Cog marker fixed screen size", m_cog_marker_fixed_screen_size);
if (ImGui::BeginTable("Cog", 2)) {
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
imgui.text_colored(Slic3r::GUI::ImGuiWrapper::COL_ORANGE_LIGHT, "Cog marker size");
ImGui::TableSetColumnIndex(1);
imgui.slider_float("##CogSize", &m_cog_marker_size, 1.0f, 5.0f);
ImGui::EndTable();
}
imgui.checkbox("Tool marker fixed screen size", m_tool_marker_fixed_screen_size);
if (ImGui::BeginTable("Tool", 2)) {
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
imgui.text_colored(Slic3r::GUI::ImGuiWrapper::COL_ORANGE_LIGHT, "Tool marker size");
ImGui::TableSetColumnIndex(1);
imgui.slider_float("##ToolSize", &m_tool_marker_size, 1.0f, 5.0f);
ImGui::EndTable();
}
imgui.end();
}
#endif // !ENABLE_NEW_GCODE_VIEWER_NO_COG_AND_TOOL_MARKERS
#endif // ENABLE_NEW_GCODE_VIEWER
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
}
@ -1611,7 +1611,11 @@ bool GCodeViewer::can_export_toolpaths() const
{
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#if ENABLE_NEW_GCODE_VIEWER
// TODO: Fix the export to obj first
const std::array<uint32_t, 2>& visible_range = m_viewer.get_view_visible_range();
for (size_t i = visible_range[0]; i <= visible_range[1]; ++i) {
if (m_viewer.get_vertex_at(i).is_extrusion())
return true;
}
return false;
#else
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ -1756,6 +1760,307 @@ void GCodeViewer::set_layers_z_range(const std::array<unsigned int, 2>& layers_z
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
}
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#if ENABLE_NEW_GCODE_VIEWER
class ToolpathsObjExporter
{
public:
explicit ToolpathsObjExporter(const libvgcode::Viewer& viewer)
: m_viewer(viewer) {
}
void export_to(const std::string& filename) {
CNumericLocalesSetter locales_setter;
// open geometry file
FilePtr f_geo = boost::nowide::fopen(filename.c_str(), "w");
if (f_geo.f == nullptr) {
BOOST_LOG_TRIVIAL(error) << "ToolpathsObjExporter: Couldn't open " << filename << " for writing";
return;
}
boost::filesystem::path materials_filename(filename);
materials_filename.replace_extension("mtl");
// write header to geometry file
fprintf(f_geo.f, "# G-Code Toolpaths\n");
fprintf(f_geo.f, "# Generated by %s-%s based on Slic3r\n", SLIC3R_APP_NAME, SLIC3R_VERSION);
fprintf(f_geo.f, "\nmtllib ./%s\n", materials_filename.filename().string().c_str());
// open material file
FilePtr f_mat = boost::nowide::fopen(materials_filename.string().c_str(), "w");
if (f_mat.f == nullptr) {
BOOST_LOG_TRIVIAL(error) << "ToolpathsObjExporter: Couldn't open " << materials_filename.string() << " for writing";
return;
}
// write header to material file
fprintf(f_mat.f, "# G-Code Toolpaths Materials\n");
fprintf(f_mat.f, "# Generated by %s-%s based on Slic3r\n", SLIC3R_APP_NAME, SLIC3R_VERSION);
const std::array<uint32_t, 2>& visible_range = m_viewer.get_view_visible_range();
for (size_t i = visible_range[0]; i <= visible_range[1]; ++i) {
const libvgcode::PathVertex& curr = m_viewer.get_vertex_at(i);
const libvgcode::PathVertex& next = m_viewer.get_vertex_at(i + 1);
if (!curr.is_extrusion() || !next.is_extrusion())
continue;
const libvgcode::PathVertex& nextnext = m_viewer.get_vertex_at(i + 2);
unsigned char flags = 0;
if (curr.gcode_id == next.gcode_id)
flags |= Flag_First;
if (!nextnext.is_extrusion())
flags |= Flag_Last;
else
flags |= Flag_Internal;
export_segment(*f_geo.f, flags, curr, next, nextnext);
}
export_materials(*f_mat.f);
}
private:
const libvgcode::Viewer& m_viewer;
size_t m_vertices_count{ 0 };
std::vector<libvgcode::Color> m_colors;
static const unsigned char Flag_First = 0x01;
static const unsigned char Flag_Last = 0x02;
static const unsigned char Flag_Internal = 0x04;
unsigned char m_flags{ 0 };
static const float Cap_Rounding_Factor;
struct SegmentLocalSystem
{
Vec3f forward;
Vec3f right;
Vec3f up;
};
SegmentLocalSystem segment_local_system(const Vec3f& v1, const Vec3f& v2) {
SegmentLocalSystem ret;
const Vec3f line = v2 - v1;
const float line_sqlen = line.squaredNorm();
ret.forward = (line_sqlen < 1e-4) ? Vec3f::UnitX() : line.normalized();
ret.right = ret.forward.cross(Vec3f::UnitZ()).normalized();
ret.up = ret.right.cross(ret.forward);
return ret;
}
struct Vertex
{
Vec3f position;
Vec3f normal;
};
struct VertexCrossSection
{
Vertex right;
Vertex top;
Vertex left;
Vertex bottom;
};
VertexCrossSection cross_section(const Vec3f& v, const Vec3f& right, const Vec3f& up, float width, float height) {
VertexCrossSection ret;
const Vec3f w_shift = 0.5f * width * right;
const Vec3f h_shift = 0.5f * height * up;
ret.right.position = v + w_shift;
ret.right.normal = right;
ret.top.position = v + h_shift;
ret.top.normal = up;
ret.left.position = v - w_shift;
ret.left.normal = -right;
ret.bottom.position = v - h_shift;
ret.bottom.normal = -up;
return ret;
}
VertexCrossSection normal_cross_section(const Vec3f& v, const SegmentLocalSystem& axes, float width, float height) {
return cross_section(v, axes.right, axes.up, width, height);
}
enum CornerType : unsigned char
{
RightTurn,
LeftTurn,
Straight
};
VertexCrossSection corner_cross_section(const Vec3f& v, const SegmentLocalSystem& axes1, const SegmentLocalSystem& axes2,
float width, float height, CornerType& corner_type) {
if (std::abs(std::abs(axes1.forward.dot(axes2.forward)) - 1.0f) < EPSILON)
corner_type = CornerType::Straight;
else if (axes1.up.dot(axes1.forward.cross(axes2.forward)) < 0.0f)
corner_type = CornerType::RightTurn;
else
corner_type = CornerType::LeftTurn;
const Vec3f right = (0.5f * (axes1.right + axes2.right)).normalized();
return cross_section(v, right, axes1.up, width, height);
}
void export_segment(FILE& f, unsigned char flags, const libvgcode::PathVertex& v1, const libvgcode::PathVertex& v2, const libvgcode::PathVertex& v3) {
const Vec3f v1_pos = libvgcode::convert(v1.position);
const Vec3f v2_pos = libvgcode::convert(v2.position);
const Vec3f v3_pos = libvgcode::convert(v3.position);
const SegmentLocalSystem v1_v2 = segment_local_system(v1_pos, v2_pos);
const SegmentLocalSystem v2_v3 = segment_local_system(v2_pos, v3_pos);
// starting cap
if ((flags & Flag_First) > 0) {
const Vertex v0 = { v1_pos - Cap_Rounding_Factor * v1.width * v1_v2.forward, -v1_v2.forward };
const VertexCrossSection ncs = normal_cross_section(v1_pos, v1_v2, v1.width, v1.height);
export_vertex(f, v0); // 0
export_vertex(f, ncs.right); // 1
export_vertex(f, ncs.top); // 2
export_vertex(f, ncs.left); // 3
export_vertex(f, ncs.bottom); // 4
export_material(f, color_id(v1));
export_triangle(f, vertex_id(0), vertex_id(1), vertex_id(2));
export_triangle(f, vertex_id(0), vertex_id(2), vertex_id(3));
export_triangle(f, vertex_id(0), vertex_id(3), vertex_id(4));
export_triangle(f, vertex_id(0), vertex_id(4), vertex_id(1));
m_vertices_count += 5;
}
// segment body + ending cap
if ((flags & Flag_Last) > 0) {
const Vertex v0 = { v2_pos + Cap_Rounding_Factor * v2.width * v1_v2.forward, v1_v2.forward };
const VertexCrossSection ncs = normal_cross_section(v2_pos, v1_v2, v2.width, v2.height);
export_vertex(f, v0); // 0
export_vertex(f, ncs.right); // 1
export_vertex(f, ncs.top); // 2
export_vertex(f, ncs.left); // 3
export_vertex(f, ncs.bottom); // 4
export_material(f, color_id(v2));
// segment body
export_triangle(f, vertex_id(-4), vertex_id(1), vertex_id(2));
export_triangle(f, vertex_id(-4), vertex_id(2), vertex_id(-3));
export_triangle(f, vertex_id(-3), vertex_id(2), vertex_id(3));
export_triangle(f, vertex_id(-3), vertex_id(3), vertex_id(-2));
export_triangle(f, vertex_id(-2), vertex_id(3), vertex_id(4));
export_triangle(f, vertex_id(-2), vertex_id(4), vertex_id(-1));
export_triangle(f, vertex_id(-1), vertex_id(4), vertex_id(1));
export_triangle(f, vertex_id(-1), vertex_id(1), vertex_id(-4));
// ending cap
export_triangle(f, vertex_id(0), vertex_id(3), vertex_id(2));
export_triangle(f, vertex_id(0), vertex_id(2), vertex_id(1));
export_triangle(f, vertex_id(0), vertex_id(1), vertex_id(4));
export_triangle(f, vertex_id(0), vertex_id(4), vertex_id(3));
m_vertices_count += 5;
}
else {
CornerType corner_type;
const VertexCrossSection ccs = corner_cross_section(v2_pos, v1_v2, v2_v3, v2.width, v2.height, corner_type);
const VertexCrossSection ncs12 = normal_cross_section(v2_pos, v1_v2, v2.width, v2.height);
const VertexCrossSection ncs23 = normal_cross_section(v2_pos, v2_v3, v2.width, v2.height);
if (corner_type == CornerType::Straight) {
export_vertex(f, ncs12.right); // 0
export_vertex(f, ncs12.top); // 1
export_vertex(f, ncs12.left); // 2
export_vertex(f, ncs12.bottom); // 3
export_material(f, color_id(v2));
// segment body
export_triangle(f, vertex_id(-4), vertex_id(0), vertex_id(1));
export_triangle(f, vertex_id(-4), vertex_id(1), vertex_id(-3));
export_triangle(f, vertex_id(-3), vertex_id(1), vertex_id(2));
export_triangle(f, vertex_id(-3), vertex_id(2), vertex_id(-2));
export_triangle(f, vertex_id(-2), vertex_id(2), vertex_id(3));
export_triangle(f, vertex_id(-2), vertex_id(3), vertex_id(-1));
export_triangle(f, vertex_id(-1), vertex_id(3), vertex_id(0));
export_triangle(f, vertex_id(-1), vertex_id(0), vertex_id(-4));
m_vertices_count += 4;
}
else if (corner_type == CornerType::RightTurn) {
export_vertex(f, ncs12.left); // 0
export_vertex(f, ccs.left); // 1
export_vertex(f, ccs.right); // 2
export_vertex(f, ncs12.top); // 3
export_vertex(f, ncs23.left); // 4
export_vertex(f, ncs12.bottom); // 5
export_material(f, color_id(v2));
// segment body
export_triangle(f, vertex_id(-4), vertex_id(2), vertex_id(3));
export_triangle(f, vertex_id(-4), vertex_id(3), vertex_id(-3));
export_triangle(f, vertex_id(-3), vertex_id(3), vertex_id(0));
export_triangle(f, vertex_id(-3), vertex_id(0), vertex_id(-2));
export_triangle(f, vertex_id(-2), vertex_id(0), vertex_id(5));
export_triangle(f, vertex_id(-2), vertex_id(5), vertex_id(-1));
export_triangle(f, vertex_id(-1), vertex_id(5), vertex_id(2));
export_triangle(f, vertex_id(-1), vertex_id(2), vertex_id(-4));
// corner
export_triangle(f, vertex_id(1), vertex_id(0), vertex_id(3));
export_triangle(f, vertex_id(1), vertex_id(3), vertex_id(4));
export_triangle(f, vertex_id(1), vertex_id(4), vertex_id(5));
export_triangle(f, vertex_id(1), vertex_id(5), vertex_id(0));
m_vertices_count += 6;
}
else {
export_vertex(f, ncs12.right); // 0
export_vertex(f, ccs.right); // 1
export_vertex(f, ncs23.right); // 2
export_vertex(f, ncs12.top); // 3
export_vertex(f, ccs.left); // 4
export_vertex(f, ncs12.bottom); // 5
export_material(f, color_id(v2));
// segment body
export_triangle(f, vertex_id(-4), vertex_id(0), vertex_id(3));
export_triangle(f, vertex_id(-4), vertex_id(3), vertex_id(-3));
export_triangle(f, vertex_id(-3), vertex_id(3), vertex_id(4));
export_triangle(f, vertex_id(-3), vertex_id(4), vertex_id(-2));
export_triangle(f, vertex_id(-2), vertex_id(4), vertex_id(5));
export_triangle(f, vertex_id(-2), vertex_id(5), vertex_id(-1));
export_triangle(f, vertex_id(-1), vertex_id(5), vertex_id(0));
export_triangle(f, vertex_id(-1), vertex_id(0), vertex_id(-4));
// corner
export_triangle(f, vertex_id(1), vertex_id(2), vertex_id(3));
export_triangle(f, vertex_id(1), vertex_id(3), vertex_id(0));
export_triangle(f, vertex_id(1), vertex_id(0), vertex_id(5));
export_triangle(f, vertex_id(1), vertex_id(5), vertex_id(2));
m_vertices_count += 6;
}
}
}
size_t vertex_id(int id) { return static_cast<size_t>(1 + static_cast<int>(m_vertices_count) + id); }
void export_vertex(FILE& f, const Vertex& v) {
fprintf(&f, "v %g %g %g\n", v.position.x(), v.position.y(), v.position.z());
fprintf(&f, "vn %g %g %g\n", v.normal.x(), v.normal.y(), v.normal.z());
}
void export_material(FILE& f, size_t material_id) {
fprintf(&f, "\nusemtl material_%zu\n", material_id + 1);
}
void export_triangle(FILE& f, size_t v1, size_t v2, size_t v3) {
fprintf(&f, "f %zu//%zu %zu//%zu %zu//%zu\n", v1, v1, v2, v2, v3, v3);
}
void export_materials(FILE& f) {
static const float inv_255 = 1.0f / 255.0f;
size_t materials_counter = 0;
for (const auto& color : m_colors) {
fprintf(&f, "\nnewmtl material_%zu\n", ++materials_counter);
fprintf(&f, "Ka 1 1 1\n");
fprintf(&f, "Kd %g %g %g\n", static_cast<float>(color[0]) * inv_255,
static_cast<float>(color[1]) * inv_255,
static_cast<float>(color[2]) * inv_255);
fprintf(&f, "Ks 0 0 0\n");
}
}
size_t color_id(const libvgcode::PathVertex& v) {
const libvgcode::Color color = m_viewer.get_vertex_color(v);
auto color_it = std::find_if(m_colors.begin(), m_colors.end(), [&color](const libvgcode::Color& m) { return m == color; });
if (color_it == m_colors.end()) {
m_colors.emplace_back(color);
color_it = std::prev(m_colors.end());
}
return std::distance(m_colors.begin(), color_it);
}
};
const float ToolpathsObjExporter::Cap_Rounding_Factor = 0.25f;
#endif // ENABLE_NEW_GCODE_VIEWER
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
void GCodeViewer::export_toolpaths_to_obj(const char* filename) const
{
if (filename == nullptr)
@ -1768,7 +2073,8 @@ void GCodeViewer::export_toolpaths_to_obj(const char* filename) const
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#if ENABLE_NEW_GCODE_VIEWER
// TODO -> new export to obj
ToolpathsObjExporter exporter(m_viewer);
exporter.export_to(filename);
#else
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// the data needed is contained into the Extrude TBuffer
@ -4573,8 +4879,8 @@ void GCodeViewer::render_legend(float& legend_height)
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#if ENABLE_NEW_GCODE_VIEWER
auto role_time_and_percent = [this, time_mode](libvgcode::EGCodeExtrusionRole role) {
const float time = m_viewer.get_extrusion_role_time(role);
return std::make_pair(time, time / time_mode.time);
const float time = m_viewer.get_extrusion_role_time(role);
return std::make_pair(time, time / time_mode.time);
};
#else
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ -4608,7 +4914,7 @@ void GCodeViewer::render_legend(float& legend_height)
#if ENABLE_NEW_GCODE_VIEWER
if (curr_view_type == libvgcode::EViewType::FeatureType) {
// calculate offsets to align time/percentage data
const std::vector<libvgcode::EGCodeExtrusionRole>& roles = m_viewer.get_extrusion_roles();
const std::vector<libvgcode::EGCodeExtrusionRole>& roles = m_viewer.get_extrusion_roles();
for (libvgcode::EGCodeExtrusionRole role : roles) {
assert(static_cast<size_t>(role) < libvgcode::GCode_Extrusion_Roles_Count);
if (static_cast<size_t>(role) < libvgcode::GCode_Extrusion_Roles_Count) {
@ -4835,7 +5141,7 @@ void GCodeViewer::render_legend(float& legend_height)
#if ENABLE_NEW_GCODE_VIEWER
const float travels_time = m_viewer.get_travels_time();
max_time_percent = std::max(max_time_percent, travels_time / time_mode.time);
const std::vector<libvgcode::EGCodeExtrusionRole>& roles = m_viewer.get_extrusion_roles();
const std::vector<libvgcode::EGCodeExtrusionRole>& roles = m_viewer.get_extrusion_roles();
for (size_t i = 0; i < roles.size(); ++i) {
libvgcode::EGCodeExtrusionRole role = roles[i];
if (static_cast<size_t>(role) >= libvgcode::GCode_Extrusion_Roles_Count)
@ -5361,7 +5667,7 @@ void GCodeViewer::render_legend(float& legend_height)
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#if ENABLE_NEW_GCODE_VIEWER
if (new_view_type == libvgcode::EViewType::Width || new_view_type == libvgcode::EViewType::VolumetricFlowRate) {
const std::vector<libvgcode::EGCodeExtrusionRole>& roles = m_viewer.get_extrusion_roles();
const std::vector<libvgcode::EGCodeExtrusionRole>& roles = m_viewer.get_extrusion_roles();
const auto custom_it = std::find(roles.begin(), roles.end(), libvgcode::EGCodeExtrusionRole::Custom);
if (custom_it != roles.end()) {
const bool custom_visible = m_viewer.is_extrusion_role_visible((libvgcode::EGCodeExtrusionRole)GCodeExtrusionRole::Custom);
@ -5457,7 +5763,7 @@ void GCodeViewer::render_legend(float& legend_height)
if (ImGui::BeginTable("Times", 2)) {
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#if ENABLE_NEW_GCODE_VIEWER
const std::vector<float> layers_times = get_layers_times();
const std::vector<float> layers_times = get_layers_times();
if (!layers_times.empty())
add_strings_row_to_table(_u8L("First layer") + ":", ImGuiWrapper::COL_ORANGE_LIGHT,
short_time_ui(get_time_dhms(layers_times.front())), ImGuiWrapper::to_ImVec4(ColorRGBA::WHITE()));
@ -5548,13 +5854,13 @@ void GCodeViewer::render_legend(float& legend_height)
#if ENABLE_NEW_GCODE_VIEWER
bool active = false;
#if ENABLE_NEW_GCODE_VIEWER_NO_COG_AND_TOOL_MARKERS
switch (type)
{
case Preview::OptionType::CenterOfGravity: { active = m_cog.is_visible(); break; }
case Preview::OptionType::ToolMarker: { active = m_sequential_view.marker.is_visible(); break; }
case Preview::OptionType::Shells: { active = m_shells.visible; break; }
default: { active = m_viewer.is_option_visible(libvgcode::convert(type)); break; }
}
switch (type)
{
case Preview::OptionType::CenterOfGravity: { active = m_cog.is_visible(); break; }
case Preview::OptionType::ToolMarker: { active = m_sequential_view.marker.is_visible(); break; }
case Preview::OptionType::Shells: { active = m_shells.visible; break; }
default: { active = m_viewer.is_option_visible(libvgcode::convert(type)); break; }
}
#else
active = (type == Preview::OptionType::Shells) ? m_shells.visible : m_viewer.is_option_visible(libvgcode::convert(type));
#endif // ENABLE_NEW_GCODE_VIEWER_NO_COG_AND_TOOL_MARKERS
@ -5581,28 +5887,28 @@ void GCodeViewer::render_legend(float& legend_height)
const std::array<uint32_t, 2> view_visible_range = m_viewer.get_view_visible_range();
const std::array<uint32_t, 2> view_enabled_range = m_viewer.get_view_enabled_range();
bool keep_visible_range = false;
#if ENABLE_NEW_GCODE_VIEWER_NO_COG_AND_TOOL_MARKERS
switch (type)
{
case Preview::OptionType::CenterOfGravity: { m_cog.set_visible(!active); break; }
case Preview::OptionType::ToolMarker: { m_sequential_view.marker.set_visible(!active); break; }
case Preview::OptionType::Shells: { m_shells.visible = !active; break; }
default: {
m_viewer.toggle_option_visibility(libvgcode::convert(type));
if (view_visible_range != view_enabled_range)
keep_visible_range = true;
break;
}
}
#else
if (type == Preview::OptionType::Shells)
m_shells.visible = !active;
else {
#if ENABLE_NEW_GCODE_VIEWER_NO_COG_AND_TOOL_MARKERS
switch (type)
{
case Preview::OptionType::CenterOfGravity: { m_cog.set_visible(!active); break; }
case Preview::OptionType::ToolMarker: { m_sequential_view.marker.set_visible(!active); break; }
case Preview::OptionType::Shells: { m_shells.visible = !active; break; }
default: {
m_viewer.toggle_option_visibility(libvgcode::convert(type));
if (view_visible_range != view_enabled_range)
keep_visible_range = true;
if (view_visible_range != view_enabled_range)
keep_visible_range = true;
break;
}
#endif // ENABLE_NEW_GCODE_VIEWER_NO_COG_AND_TOOL_MARKERS
}
#else
if (type == Preview::OptionType::Shells)
m_shells.visible = !active;
else {
m_viewer.toggle_option_visibility(libvgcode::convert(type));
if (view_visible_range != view_enabled_range)
keep_visible_range = true;
}
#endif // ENABLE_NEW_GCODE_VIEWER_NO_COG_AND_TOOL_MARKERS
std::optional<int> view_visible_range_min;
std::optional<int> view_visible_range_max;
if (keep_visible_range) {

View File

@ -89,6 +89,8 @@ public:
//
PathVertex get_vertex_at(uint32_t id) const;
Color get_vertex_color(const PathVertex& vertex) const;
//
// Return the count of path segments enabled for rendering
//

View File

@ -182,6 +182,11 @@ PathVertex Viewer::get_vertex_at(uint32_t id) const
return m_impl->get_vertex_at(id);
}
Color Viewer::get_vertex_color(const PathVertex& vertex) const
{
return m_impl->get_vertex_color(vertex);
}
size_t Viewer::get_enabled_segments_count() const
{
return m_impl->get_enabled_segments_count();

View File

@ -703,7 +703,7 @@ void ViewerImpl::update_colors()
for (size_t i = 0; i < m_vertices.size(); ++i) {
colors[i] = (color_top_layer_only && m_vertices[i].layer_id < top_layer_id &&
(!m_settings.spiral_vase_mode || i != m_view_range.get_enabled()[0])) ?
encode_color(Dummy_Color) : encode_color(select_color(m_vertices[i]));
encode_color(Dummy_Color) : encode_color(get_vertex_color(m_vertices[i]));
}
// update gpu buffer for colors
@ -933,6 +933,73 @@ PathVertex ViewerImpl::get_vertex_at(size_t id) const
return (id < m_vertices.size()) ? m_vertices[id] : PathVertex();
}
Color ViewerImpl::get_vertex_color(const PathVertex& v) const
{
if (v.type == EMoveType::Noop)
return Dummy_Color;
if (v.is_wipe())
return Wipe_Color;
if (v.is_option())
return get_option_color(type_to_option(v.type));
switch (m_settings.view_type)
{
case EViewType::FeatureType:
{
return v.is_travel() ? get_travel_move_color(static_cast<ETravelMoveType>(v.role)) : get_extrusion_role_color(v.role);
}
case EViewType::Height:
{
return v.is_travel() ? get_travel_move_color(static_cast<ETravelMoveType>(v.role)) : m_height_range.get_color_at(v.height);
}
case EViewType::Width:
{
return v.is_travel() ? get_travel_move_color(static_cast<ETravelMoveType>(v.role)) : m_width_range.get_color_at(v.width);
}
case EViewType::Speed:
{
return m_speed_range.get_color_at(v.feedrate);
}
case EViewType::FanSpeed:
{
return v.is_travel() ? get_travel_move_color(static_cast<ETravelMoveType>(v.role)) : m_fan_speed_range.get_color_at(v.fan_speed);
}
case EViewType::Temperature:
{
return v.is_travel() ? get_travel_move_color(static_cast<ETravelMoveType>(v.role)) : m_temperature_range.get_color_at(v.temperature);
}
case EViewType::VolumetricFlowRate:
{
return v.is_travel() ? get_travel_move_color(static_cast<ETravelMoveType>(v.role)) : m_volumetric_rate_range.get_color_at(v.volumetric_rate);
}
case EViewType::LayerTimeLinear:
{
return v.is_travel() ? get_travel_move_color(static_cast<ETravelMoveType>(v.role)) :
m_layer_time_range[0].get_color_at(m_layers.get_layer_time(m_settings.time_mode, static_cast<size_t>(v.layer_id)));
}
case EViewType::LayerTimeLogarithmic:
{
return v.is_travel() ? get_travel_move_color(static_cast<ETravelMoveType>(v.role)) :
m_layer_time_range[1].get_color_at(m_layers.get_layer_time(m_settings.time_mode, static_cast<size_t>(v.layer_id)));
}
case EViewType::Tool:
{
assert(static_cast<size_t>(v.extruder_id) < m_tool_colors.size());
return m_tool_colors[v.extruder_id];
}
case EViewType::ColorPrint:
{
return m_layers.layer_contains_colorprint_options(static_cast<size_t>(v.layer_id)) ? Dummy_Color :
m_tool_colors[static_cast<size_t>(v.color_id) % m_tool_colors.size()];
}
default: { break; }
}
return Dummy_Color;
}
size_t ViewerImpl::get_enabled_segments_count() const
{
return m_enabled_segments_count;
@ -1369,73 +1436,6 @@ void ViewerImpl::update_heights_widths()
glsafe(glBindBuffer(GL_TEXTURE_BUFFER, 0));
}
Color ViewerImpl::select_color(const PathVertex& v) const
{
if (v.type == EMoveType::Noop)
return Dummy_Color;
if (v.is_wipe())
return Wipe_Color;
if (v.is_option())
return get_option_color(type_to_option(v.type));
switch (m_settings.view_type)
{
case EViewType::FeatureType:
{
return v.is_travel() ? get_travel_move_color(static_cast<ETravelMoveType>(v.role)) : get_extrusion_role_color(v.role);
}
case EViewType::Height:
{
return v.is_travel() ? get_travel_move_color(static_cast<ETravelMoveType>(v.role)) : m_height_range.get_color_at(v.height);
}
case EViewType::Width:
{
return v.is_travel() ? get_travel_move_color(static_cast<ETravelMoveType>(v.role)) : m_width_range.get_color_at(v.width);
}
case EViewType::Speed:
{
return m_speed_range.get_color_at(v.feedrate);
}
case EViewType::FanSpeed:
{
return v.is_travel() ? get_travel_move_color(static_cast<ETravelMoveType>(v.role)) : m_fan_speed_range.get_color_at(v.fan_speed);
}
case EViewType::Temperature:
{
return v.is_travel() ? get_travel_move_color(static_cast<ETravelMoveType>(v.role)) : m_temperature_range.get_color_at(v.temperature);
}
case EViewType::VolumetricFlowRate:
{
return v.is_travel() ? get_travel_move_color(static_cast<ETravelMoveType>(v.role)) : m_volumetric_rate_range.get_color_at(v.volumetric_rate);
}
case EViewType::LayerTimeLinear:
{
return v.is_travel() ? get_travel_move_color(static_cast<ETravelMoveType>(v.role)) :
m_layer_time_range[0].get_color_at(m_layers.get_layer_time(m_settings.time_mode, static_cast<size_t>(v.layer_id)));
}
case EViewType::LayerTimeLogarithmic:
{
return v.is_travel() ? get_travel_move_color(static_cast<ETravelMoveType>(v.role)) :
m_layer_time_range[1].get_color_at(m_layers.get_layer_time(m_settings.time_mode, static_cast<size_t>(v.layer_id)));
}
case EViewType::Tool:
{
assert(static_cast<size_t>(v.extruder_id) < m_tool_colors.size());
return m_tool_colors[v.extruder_id];
}
case EViewType::ColorPrint:
{
return m_layers.layer_contains_colorprint_options(static_cast<size_t>(v.layer_id)) ? Dummy_Color :
m_tool_colors[static_cast<size_t>(v.color_id) % m_tool_colors.size()];
}
default: { break; }
}
return Dummy_Color;
}
void ViewerImpl::render_segments(const Mat4x4& view_matrix, const Mat4x4& projection_matrix, const Vec3& camera_position)
{
if (m_segments_shader_id == 0)

View File

@ -109,6 +109,7 @@ public:
size_t get_vertices_count() const;
PathVertex get_current_vertex() const;
PathVertex get_vertex_at(size_t id) const;
Color get_vertex_color(const PathVertex& vertex) const;
size_t get_enabled_segments_count() const;
const std::array<uint32_t, 2>& get_enabled_segments_range() const;
@ -328,7 +329,6 @@ private:
void update_view_full_range();
void update_color_ranges();
void update_heights_widths();
Color select_color(const PathVertex& vertex) const;
void render_segments(const Mat4x4& view_matrix, const Mat4x4& projection_matrix, const Vec3& camera_position);
void render_options(const Mat4x4& view_matrix, const Mat4x4& projection_matrix);
#if !ENABLE_NEW_GCODE_VIEWER_NO_COG_AND_TOOL_MARKERS