mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-14 17:05:53 +08:00
New gcode visualization integration - Export toolpaths to obj
This commit is contained in:
parent
dcd8b30842
commit
137495dd88
@ -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) {
|
||||
|
@ -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
|
||||
//
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user