diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index a602a77de4..e6740fe91c 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -4423,6 +4423,11 @@ void GCodeProcessor::store_move_vertex(EMoveType type, bool internal_only) m_fan_speed, m_extruder_temps[m_extruder_id], static_cast(m_result.moves.size()), +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + std::max(1, m_layer_id) - 1, // CHECK THIS !! +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ internal_only }); diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 759ce4f57d..eee09798b0 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -142,6 +142,11 @@ namespace Slic3r { float fan_speed{ 0.0f }; // percentage float temperature{ 0.0f }; // Celsius degrees float time{ 0.0f }; // s +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + unsigned int layer_id{ 0 }; +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool internal_only{ false }; float volumetric_rate() const { return feedrate * mm3_per_mm; } diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index b95b7a37fd..c6e422b8e5 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -59,5 +59,8 @@ // Enable imgui dialog which allows to set the parameters used to export binarized gcode #define ENABLE_BINARIZED_GCODE_DEBUG_WINDOW 0 +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#define ENABLE_NEW_GCODE_VIEWER 1 +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // _prusaslicer_technologies_h_ diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index 479144dab9..a8b15c95ca 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -92,6 +92,39 @@ set(SLIC3R_GUI_SOURCES GUI/Gizmos/GLGizmoMmuSegmentation.hpp GUI/Gizmos/GLGizmoMeasure.cpp GUI/Gizmos/GLGizmoMeasure.hpp +#==================================================================================================================== + GUI/LibVGCode/Viewer.hpp + GUI/LibVGCode/Viewer.cpp + GUI/LibVGCode/Settings.hpp + GUI/LibVGCode/Settings.cpp + GUI/LibVGCode/SegmentTemplate.hpp + GUI/LibVGCode/SegmentTemplate.cpp + GUI/LibVGCode/OptionTemplate.hpp + GUI/LibVGCode/OptionTemplate.cpp + GUI/LibVGCode/Toolpaths.hpp + GUI/LibVGCode/Toolpaths.cpp + GUI/LibVGCode/PathVertex.hpp + GUI/LibVGCode/PathVertex.cpp + GUI/LibVGCode/Types.hpp + GUI/LibVGCode/Types.cpp + GUI/LibVGCode/Bitset.hpp + GUI/LibVGCode/Bitset.cpp + GUI/LibVGCode/ViewRange.hpp + GUI/LibVGCode/ViewRange.cpp + GUI/LibVGCode/ColorRange.hpp + GUI/LibVGCode/ColorRange.cpp + GUI/LibVGCode/Shaders.hpp + GUI/LibVGCode/OpenGLUtils.hpp + GUI/LibVGCode/OpenGLUtils.cpp + GUI/LibVGCode/CogMarker.hpp + GUI/LibVGCode/CogMarker.cpp + GUI/LibVGCode/ToolMarker.hpp + GUI/LibVGCode/ToolMarker.cpp + GUI/LibVGCode/Shell.hpp + GUI/LibVGCode/Shell.cpp + GUI/LibVGCode/Utils.hpp + GUI/LibVGCode/Utils.cpp +#==================================================================================================================== GUI/GLSelectionRectangle.cpp GUI/GLSelectionRectangle.hpp GUI/GLModel.hpp diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 0ac5f4294a..b8aa6abc52 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -29,6 +29,11 @@ #include "GLToolbar.hpp" #include "GUI_Preview.hpp" #include "GUI_ObjectManipulation.hpp" +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER +#include "MsgDialog.hpp" +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include @@ -40,6 +45,12 @@ #include #include +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +//#if ENABLE_NEW_GCODE_VIEWER +//#include "GCodeViewer/Types.hpp" +//#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + #include #include #include @@ -186,12 +197,29 @@ void GCodeViewer::TBuffer::add_path(const GCodeProcessorResult::MoveVertex& move move.volumetric_rate(), move.extruder_id, move.cp_color_id, { { endpoint, endpoint } } }); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER +void GCodeViewer::COG::render(bool fixed_screen_size) +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void GCodeViewer::COG::render() +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { if (!m_visible) return; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + fixed_screen_size = true; + init(fixed_screen_size); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ init(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ GLShaderProgram* shader = wxGetApp().get_shader("toolpaths_cog"); if (shader == nullptr) @@ -203,7 +231,15 @@ void GCodeViewer::COG::render() const Camera& camera = wxGetApp().plater()->get_camera(); Transform3d model_matrix = Geometry::translation_transform(cog()); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + if (fixed_screen_size) { +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (m_fixed_size) { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ const double inv_zoom = camera.get_inv_zoom(); model_matrix = model_matrix * Geometry::scale_transform(inv_zoom); } @@ -748,9 +784,21 @@ const ColorRGBA GCodeViewer::Neutral_Color = ColorRGBA::DARK_GRAY(); GCodeViewer::GCodeViewer() { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_extrusions.reset_role_visibility_flags(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_shells.volumes.set_use_raycasters(false); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // m_sequential_view.skip_invisible_moves = true; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } void GCodeViewer::init() @@ -821,17 +869,60 @@ void GCodeViewer::init() m_sequential_view.marker.init(); m_gl_data_initialized = true; + +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + try + { + m_gcode_viewer_2.init(); + } + catch (const std::exception& e) + { + MessageDialog msg_dlg(wxGetApp().plater(), e.what(), _L("Error"), wxICON_ERROR | wxOK); + msg_dlg.ShowModal(); + } +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER +void GCodeViewer::load(const GCodeProcessorResult& gcode_result, const Print& print, const std::vector& str_tool_colors) +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void GCodeViewer::load(const GCodeProcessorResult& gcode_result, const Print& print) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + m_gcode_viewer_2.load(gcode_result, print, str_tool_colors); +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + // avoid processing if called with the same gcode_result +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + if (m_last_result_id == gcode_result.id) // << TODO: check this + return; +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (m_last_result_id == gcode_result.id && (m_last_view_type == m_view_type || (m_last_view_type != EViewType::VolumetricRate && m_view_type != EViewType::VolumetricRate))) return; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_last_result_id = gcode_result.id; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_last_view_type = m_view_type; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // release gpu memory, if used reset(); @@ -898,12 +989,18 @@ void GCodeViewer::load(const GCodeProcessorResult& gcode_result, const Print& pr m_print_statistics = gcode_result.print_statistics; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (m_time_estimate_mode != PrintEstimatedStatistics::ETimeMode::Normal) { const float time = m_print_statistics.modes[static_cast(m_time_estimate_mode)].time; if (time == 0.0f || short_time(get_time_dhms(time)) == short_time(get_time_dhms(m_print_statistics.modes[static_cast(PrintEstimatedStatistics::ETimeMode::Normal)].time))) m_time_estimate_mode = PrintEstimatedStatistics::ETimeMode::Normal; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_conflict_result = gcode_result.conflict_result; if (m_conflict_result.has_value()) { m_conflict_result->layer = m_layers.get_l_at(m_conflict_result->_height); } @@ -920,7 +1017,15 @@ void GCodeViewer::refresh(const GCodeProcessorResult& gcode_result, const std::v wxBusyCursor busy; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + if (m_gcode_viewer_2.get_view_type() == libvgcode::EViewType::Tool && !gcode_result.extruder_colors.empty()) +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (m_view_type == EViewType::Tool && !gcode_result.extruder_colors.empty()) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // update tool colors from config stored in the gcode decode_colors(gcode_result.extruder_colors, m_tool_colors); else @@ -967,6 +1072,16 @@ void GCodeViewer::refresh(const GCodeProcessorResult& gcode_result, const std::v } } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + const std::array, static_cast(libvgcode::ETimeMode::COUNT)>& layers_times = m_gcode_viewer_2.get_layers_times(); + for (size_t i = 0; i < layers_times.size(); ++i) { + for (float time : layers_times[i]) { + m_extrusions.ranges.layer_time[i].update_from(time); + } + } +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ for (size_t i = 0; i < gcode_result.print_statistics.modes.size(); ++i) { m_layers_times[i] = gcode_result.print_statistics.modes[i].layers_times; } @@ -976,6 +1091,9 @@ void GCodeViewer::refresh(const GCodeProcessorResult& gcode_result, const std::v m_extrusions.ranges.layer_time[i].update_from(time); } } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_GCODE_VIEWER_STATISTICS m_statistics.refresh_time = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start_time).count(); @@ -1013,9 +1131,15 @@ void GCodeViewer::reset() m_layers_z_range = { 0, 0 }; m_roles = std::vector(); m_print_statistics.reset(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ for (size_t i = 0; i < static_cast(PrintEstimatedStatistics::ETimeMode::Count); ++i) { m_layers_times[i] = std::vector(); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_custom_gcode_per_print_z = std::vector(); m_sequential_view.gcode_window.reset(); #if ENABLE_GCODE_VIEWER_STATISTICS @@ -1038,20 +1162,91 @@ void GCodeViewer::render() if (m_roles.empty()) return; - render_toolpaths(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + if (m_use_gcode_viewer_2) { + const Camera& camera = wxGetApp().plater()->get_camera(); + const Matrix4f view_matrix = camera.get_view_matrix().matrix().cast(); + const Matrix4f projection_matrix = camera.get_projection_matrix().matrix().cast(); + const Vec3f camera_position = camera.get_position().cast(); + + libvgcode::Mat4x4f converted_view_matrix; + std::memcpy(converted_view_matrix.data(), view_matrix.data(), 16 * sizeof(float)); + libvgcode::Mat4x4f converted_projetion_matrix; + std::memcpy(converted_projetion_matrix.data(), projection_matrix.data(), 16 * sizeof(float)); + libvgcode::Vec3f converted_camera_position; + std::memcpy(converted_camera_position.data(), camera_position.data(), 3 * sizeof(float)); + libvgcode::Vec3f converted_tool_marker_position; + std::memcpy(converted_tool_marker_position.data(), m_sequential_view.current_position.data(), 3 * sizeof(float)); + + m_gcode_viewer_2.set_cog_marker_scale_factor(m_cog_marker_fixed_screen_size ? 10.0f * m_cog_marker_size * camera.get_inv_zoom() : m_cog_marker_size); + m_gcode_viewer_2.set_tool_marker_position(converted_tool_marker_position); + m_gcode_viewer_2.set_tool_marker_scale_factor(m_tool_marker_fixed_screen_size ? 10.0f * m_tool_marker_size * camera.get_inv_zoom() : m_tool_marker_size); + m_gcode_viewer_2.render(converted_view_matrix, converted_projetion_matrix, converted_camera_position); + } + else +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + render_toolpaths(); + float legend_height = 0.0f; if (!m_layers.empty()) { render_legend(legend_height); - if (m_sequential_view.current.last != m_sequential_view.endpoints.last) { - m_sequential_view.marker.set_world_position(m_sequential_view.current_position); - m_sequential_view.marker.set_world_offset(m_sequential_view.current_offset); - m_sequential_view.marker.set_z_offset(m_z_offset); - m_sequential_view.render(legend_height); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + if (!m_use_gcode_viewer_2) { +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + if (m_sequential_view.current.last != m_sequential_view.endpoints.last) { + m_sequential_view.marker.set_world_position(m_sequential_view.current_position); + m_sequential_view.marker.set_world_offset(m_sequential_view.current_offset); + m_sequential_view.marker.set_z_offset(m_z_offset); + m_sequential_view.render(legend_height); + } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER } +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } #if ENABLE_GCODE_VIEWER_STATISTICS render_statistics(); #endif // ENABLE_GCODE_VIEWER_STATISTICS + +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + if (m_use_gcode_viewer_2) { + ImGuiWrapper& imgui = *Slic3r::GUI::wxGetApp().imgui(); + imgui.begin(std::string("LibVGCode Viewer Controller"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse); + + 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 +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } bool GCodeViewer::can_export_toolpaths() const @@ -1061,6 +1256,14 @@ bool GCodeViewer::can_export_toolpaths() const void GCodeViewer::update_sequential_view_current(unsigned int first, unsigned int last) { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + m_gcode_viewer_2.set_view_current_range((size_t)first, (size_t)last); + m_sequential_view.current.first = first; + m_sequential_view.current.last = last; + m_sequential_view.last_current = m_sequential_view.current; +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ auto is_visible = [this](unsigned int id) { for (const TBuffer& buffer : m_buffers) { if (buffer.visible) { @@ -1098,11 +1301,20 @@ void GCodeViewer::update_sequential_view_current(unsigned int first, unsigned in m_sequential_view.current.first = new_first; m_sequential_view.current.last = new_last; m_sequential_view.last_current = m_sequential_view.current; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ refresh_render_paths(true, true); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (new_first != first || new_last != last) wxGetApp().plater()->update_preview_moves_slider(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } bool GCodeViewer::is_toolpath_move_type_visible(EMoveType type) const @@ -1689,7 +1901,15 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result) m_sequential_view.gcode_ids.push_back(move.gcode_id); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + bool account_for_volumetric_rate = m_gcode_viewer_2.get_view_type() == libvgcode::EViewType::VolumetricFlowRate; +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool account_for_volumetric_rate = m_view_type == EViewType::VolumetricRate; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ std::vector vertices(m_buffers.size()); std::vector indices(m_buffers.size()); @@ -2461,6 +2681,52 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool auto extrusion_color = [this](const Path& path) { ColorRGBA color; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + switch (m_gcode_viewer_2.get_view_type()) + { + case libvgcode::EViewType::FeatureType: { color = Extrusion_Role_Colors[static_cast(path.role)]; break; } + case libvgcode::EViewType::Height: { color = m_extrusions.ranges.height.get_color_at(path.height); break; } + case libvgcode::EViewType::Width: { color = m_extrusions.ranges.width.get_color_at(path.width); break; } + case libvgcode::EViewType::Speed: { color = m_extrusions.ranges.feedrate.get_color_at(path.feedrate); break; } + case libvgcode::EViewType::FanSpeed: { color = m_extrusions.ranges.fan_speed.get_color_at(path.fan_speed); break; } + case libvgcode::EViewType::Temperature: { color = m_extrusions.ranges.temperature.get_color_at(path.temperature); break; } + case libvgcode::EViewType::LayerTimeLinear: + case libvgcode::EViewType::LayerTimeLogarithmic: { + const std::array, static_cast(libvgcode::ETimeMode::COUNT)>& layers_times = m_gcode_viewer_2.get_layers_times(); + if (!layers_times.empty() && m_layers.size() == layers_times.front().size()) { + const Path::Sub_Path& sub_path = path.sub_paths.front(); + double z = static_cast(sub_path.first.position.z()); + const std::vector& zs = m_layers.get_zs(); + const std::vector& ranges = m_layers.get_ranges(); + const size_t time_mode_id = static_cast(m_gcode_viewer_2.get_time_mode()); + for (size_t i = 0; i < zs.size(); ++i) { + if (std::abs(zs[i] - z) < EPSILON) { + if (ranges[i].contains(sub_path.first.s_id)) { + color = m_extrusions.ranges.layer_time[time_mode_id].get_color_at(layers_times[time_mode_id][i], + (m_gcode_viewer_2.get_view_type() == libvgcode::EViewType::LayerTimeLinear) ? + Extrusions::Range::EType::Linear : Extrusions::Range::EType::Logarithmic); + break; + } + } + } + } + break; + } + case libvgcode::EViewType::VolumetricFlowRate: { color = m_extrusions.ranges.volumetric_rate.get_color_at(path.volumetric_rate); break; } + case libvgcode::EViewType::Tool: { color = m_tool_colors[path.extruder_id]; break; } + case libvgcode::EViewType::ColorPrint: { + if (path.cp_color_id >= static_cast(m_tool_colors.size())) + color = ColorRGBA::GRAY(); + else + color = m_tool_colors[path.cp_color_id]; + + break; + } + default: { color = ColorRGBA::WHITE(); break; } + } +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ switch (m_view_type) { case EViewType::FeatureType: { color = Extrusion_Role_Colors[static_cast(path.role)]; break; } @@ -2501,6 +2767,9 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool } default: { color = ColorRGBA::WHITE(); break; } } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ return color; }; @@ -2748,10 +3017,25 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool break; } case EMoveType::Travel: { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + if (!top_layer_only || m_sequential_view.current.last == global_endpoints.last || + is_travel_in_layers_range(path_id, m_layers_z_range[1], m_layers_z_range[1])) { + const libvgcode::EViewType type = m_gcode_viewer_2.get_view_type(); + color = (type == libvgcode::EViewType::Speed || type == libvgcode::EViewType::Tool || type == libvgcode::EViewType::ColorPrint) ? + extrusion_color(path) : travel_color(path); + } + else + color = Neutral_Color; +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (!top_layer_only || m_sequential_view.current.last == global_endpoints.last || is_travel_in_layers_range(path_id, m_layers_z_range[1], m_layers_z_range[1])) color = (m_view_type == EViewType::Feedrate || m_view_type == EViewType::Tool || m_view_type == EViewType::ColorPrint) ? extrusion_color(path) : travel_color(path); else color = Neutral_Color; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ break; } @@ -3406,10 +3690,23 @@ void GCodeViewer::render_legend(float& legend_height) Line }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + const PrintEstimatedStatistics::Mode& time_mode = m_print_statistics.modes[static_cast(m_gcode_viewer_2.get_time_mode())]; + const libvgcode::EViewType curr_view_type = m_gcode_viewer_2.get_view_type(); + const int curr_view_type_i = static_cast(curr_view_type); + bool show_estimated_time = time_mode.time > 0.0f && (curr_view_type == libvgcode::EViewType::FeatureType || + curr_view_type == libvgcode::EViewType::LayerTimeLinear || curr_view_type == libvgcode::EViewType::LayerTimeLogarithmic || + (curr_view_type == libvgcode::EViewType::ColorPrint && !time_mode.custom_gcode_times.empty())); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ const PrintEstimatedStatistics::Mode& time_mode = m_print_statistics.modes[static_cast(m_time_estimate_mode)]; bool show_estimated_time = time_mode.time > 0.0f && (m_view_type == EViewType::FeatureType || m_view_type == EViewType::LayerTimeLinear || m_view_type == EViewType::LayerTimeLogarithmic || (m_view_type == EViewType::ColorPrint && !time_mode.custom_gcode_times.empty())); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ const float icon_size = ImGui::GetTextLineHeight(); const float percent_bar_size = 2.0f * ImGui::GetTextLineHeight(); @@ -3679,7 +3976,15 @@ void GCodeViewer::render_legend(float& legend_height) std::vector used_filaments_g; float max_time_percent = 0.0f; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + if (curr_view_type == libvgcode::EViewType::FeatureType) { +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (m_view_type == EViewType::FeatureType) { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // calculate offsets to align time/percentage data for (GCodeExtrusionRole role : m_roles) { assert(role < GCodeExtrusionRole::Count); @@ -3725,7 +4030,15 @@ void GCodeViewer::render_legend(float& legend_height) return ret; }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + if (curr_view_type == libvgcode::EViewType::Tool) { +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (m_view_type == EViewType::Tool) { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // calculate used filaments data used_filaments_m = std::vector(m_extruders_count, 0.0); used_filaments_g = std::vector(m_extruders_count, 0.0); @@ -3752,14 +4065,31 @@ void GCodeViewer::render_legend(float& legend_height) // selection section bool view_type_changed = false; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + int new_view_type_i = curr_view_type_i; +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ int old_view_type = static_cast(get_view_type()); int view_type = old_view_type; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ImGui::PushStyleColor(ImGuiCol_FrameBg, { 0.1f, 0.1f, 0.1f, 0.8f }); ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, { 0.2f, 0.2f, 0.2f, 0.8f }); std::vector view_options; std::vector view_options_id; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + const std::array, static_cast(libvgcode::ETimeMode::COUNT)>& layers_times = m_gcode_viewer_2.get_layers_times(); + if (!layers_times.empty() && m_layers.size() == layers_times.front().size()) { +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (!m_layers_times.empty() && m_layers.size() == m_layers_times.front().size()) { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ view_options = { _u8L("Feature type"), _u8L("Height (mm)"), _u8L("Width (mm)"), _u8L("Speed (mm/s)"), _u8L("Fan speed (%)"), _u8L("Temperature (°C)"), _u8L("Volumetric flow rate (mm³/s)"), _u8L("Layer time (linear)"), _u8L("Layer time (logarithmic)"), _u8L("Tool"), _u8L("Color Print") }; @@ -3769,15 +4099,55 @@ void GCodeViewer::render_legend(float& legend_height) view_options = { _u8L("Feature type"), _u8L("Height (mm)"), _u8L("Width (mm)"), _u8L("Speed (mm/s)"), _u8L("Fan speed (%)"), _u8L("Temperature (°C)"), _u8L("Volumetric flow rate (mm³/s)"), _u8L("Tool"), _u8L("Color Print") }; view_options_id = { 0, 1, 2, 3, 4, 5, 6, 9, 10 }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + if (new_view_type_i == 7 || new_view_type_i == 8) + new_view_type_i = 0; +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (view_type == 7 || view_type == 8) view_type = 0; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + auto new_view_type_it = std::find(view_options_id.begin(), view_options_id.end(), new_view_type_i); + int new_view_type_id = (new_view_type_it == view_options_id.end()) ? 0 : std::distance(view_options_id.begin(), new_view_type_it); + if (imgui.combo(std::string(), view_options, new_view_type_id, ImGuiComboFlags_HeightLargest, 0.0f, -1.0f)) + new_view_type_i = view_options_id[new_view_type_id]; +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ auto view_type_it = std::find(view_options_id.begin(), view_options_id.end(), view_type); int view_type_id = (view_type_it == view_options_id.end()) ? 0 : std::distance(view_options_id.begin(), view_type_it); if (imgui.combo(std::string(), view_options, view_type_id, ImGuiComboFlags_HeightLargest, 0.0f, -1.0f)) view_type = view_options_id[view_type_id]; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ImGui::PopStyleColor(2); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + if (curr_view_type_i != new_view_type_i) { + m_gcode_viewer_2.set_view_type((libvgcode::EViewType)new_view_type_i); + wxGetApp().plater()->set_keep_current_preview_type(true); + wxGetApp().plater()->refresh_print(); + view_type_changed = true; + } + + const libvgcode::EViewType new_view_type = m_gcode_viewer_2.get_view_type(); + + // extrusion paths section -> title + if (new_view_type == libvgcode::EViewType::FeatureType) + append_headers({ "", _u8L("Time"), _u8L("Percentage"), _u8L("Used filament") }, offsets); + else if (new_view_type == libvgcode::EViewType::Tool) + append_headers({ "", _u8L("Used filament"), "", "" }, offsets); + else + ImGui::Separator(); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (old_view_type != view_type) { set_view_type(static_cast(view_type)); wxGetApp().plater()->set_keep_current_preview_type(true); @@ -3789,15 +4159,28 @@ void GCodeViewer::render_legend(float& legend_height) if (m_view_type == EViewType::FeatureType) append_headers({ "", _u8L("Time"), _u8L("Percentage"), _u8L("Used filament") }, offsets); else if (m_view_type == EViewType::Tool) - append_headers({ "", _u8L("Used filament"), "", ""}, offsets); + append_headers({ "", _u8L("Used filament"), "", "" }, offsets); else ImGui::Separator(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (!view_type_changed) { // extrusion paths section -> items +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + switch (new_view_type) + { + case libvgcode::EViewType::FeatureType: +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ switch (m_view_type) { case EViewType::FeatureType: +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { max_time_percent = std::max(max_time_percent, time_mode.travel_time / time_mode.time); @@ -3808,7 +4191,15 @@ void GCodeViewer::render_legend(float& legend_height) const bool visible = is_visible(role); append_item(EItemType::Rect, Extrusion_Role_Colors[static_cast(role)], labels[i], visible, times[i], percents[i], max_time_percent, offsets, used_filaments_m[i], used_filaments_g[i], [this, role, visible]() { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + m_gcode_viewer_2.toggle_extrusion_role_visibility((libvgcode::EGCodeExtrusionRole)role); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_extrusions.role_visibility_flags = visible ? m_extrusions.role_visibility_flags & ~(1 << int(role)) : m_extrusions.role_visibility_flags | (1 << int(role)); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // update buffers' render paths refresh_render_paths(false, false); wxGetApp().plater()->update_preview_moves_slider(); @@ -3823,6 +4214,19 @@ void GCodeViewer::render_legend(float& legend_height) break; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + case libvgcode::EViewType::Height: { append_range(m_extrusions.ranges.height, 3); break; } + case libvgcode::EViewType::Width: { append_range(m_extrusions.ranges.width, 3); break; } + case libvgcode::EViewType::Speed: { append_range(m_extrusions.ranges.feedrate, 1); break; } + case libvgcode::EViewType::FanSpeed: { append_range(m_extrusions.ranges.fan_speed, 0); break; } + case libvgcode::EViewType::Temperature: { append_range(m_extrusions.ranges.temperature, 0); break; } + case libvgcode::EViewType::VolumetricFlowRate: { append_range(m_extrusions.ranges.volumetric_rate, 3); break; } + case libvgcode::EViewType::LayerTimeLinear: { append_time_range(m_extrusions.ranges.layer_time[static_cast(m_gcode_viewer_2.get_time_mode())], Extrusions::Range::EType::Linear); break; } + case libvgcode::EViewType::LayerTimeLogarithmic: { append_time_range(m_extrusions.ranges.layer_time[static_cast(m_gcode_viewer_2.get_time_mode())], Extrusions::Range::EType::Logarithmic); break; } + case libvgcode::EViewType::Tool: { +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ case EViewType::Height: { append_range(m_extrusions.ranges.height, 3); break; } case EViewType::Width: { append_range(m_extrusions.ranges.width, 3); break; } case EViewType::Feedrate: { append_range(m_extrusions.ranges.feedrate, 1); break; } @@ -3832,6 +4236,9 @@ void GCodeViewer::render_legend(float& legend_height) case EViewType::LayerTimeLinear: { append_time_range(m_extrusions.ranges.layer_time[static_cast(m_time_estimate_mode)], Extrusions::Range::EType::Linear); break; } case EViewType::LayerTimeLogarithmic: { append_time_range(m_extrusions.ranges.layer_time[static_cast(m_time_estimate_mode)], Extrusions::Range::EType::Logarithmic); break; } case EViewType::Tool: { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // shows only extruders actually used for (unsigned char extruder_id : m_extruder_ids) { if (used_filaments_m[extruder_id] > 0.0 && used_filaments_g[extruder_id] > 0.0) @@ -3840,7 +4247,15 @@ void GCodeViewer::render_legend(float& legend_height) } break; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + case libvgcode::EViewType::ColorPrint: +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ case EViewType::ColorPrint: +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { const std::vector& custom_gcode_per_print_z = wxGetApp().is_editor() ? wxGetApp().plater()->model().custom_gcode_per_print_z.gcodes : m_custom_gcode_per_print_z; size_t total_items = 1; @@ -3912,7 +4327,15 @@ void GCodeViewer::render_legend(float& legend_height) } // partial estimated printing time section +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + if (new_view_type == libvgcode::EViewType::ColorPrint) { +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (m_view_type == EViewType::ColorPrint) { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ using Times = std::pair; using TimesList = std::vector>; @@ -4105,7 +4528,15 @@ void GCodeViewer::render_legend(float& legend_height) } has_settings |= has_filament_settings; bool show_settings = wxGetApp().is_gcode_viewer(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + show_settings &= (new_view_type == libvgcode::EViewType::FeatureType || new_view_type == libvgcode::EViewType::Tool); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ show_settings &= (m_view_type == EViewType::FeatureType || m_view_type == EViewType::Tool); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ show_settings &= has_settings; if (show_settings) { ImGui::Spacing(); @@ -4142,17 +4573,41 @@ 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) { +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (m_view_type == EViewType::Width || m_view_type == EViewType::VolumetricRate) { - const auto custom_it = std::find(m_roles.begin(), m_roles.end(), GCodeExtrusionRole::Custom); - if (custom_it != m_roles.end()) { - const bool custom_visible = is_visible(GCodeExtrusionRole::Custom); - const wxString btn_text = custom_visible ? _L("Hide Custom G-code") : _L("Show Custom G-code"); - ImGui::Separator(); - if (imgui.button(btn_text, ImVec2(-1.0f, 0.0f), true)) { - m_extrusions.role_visibility_flags = custom_visible ? m_extrusions.role_visibility_flags & ~(1 << int(GCodeExtrusionRole::Custom)) : - m_extrusions.role_visibility_flags | (1 << int(GCodeExtrusionRole::Custom)); - wxGetApp().plater()->refresh_print(); - } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + const auto custom_it = std::find(m_roles.begin(), m_roles.end(), GCodeExtrusionRole::Custom); + if (custom_it != m_roles.end()) { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + const bool custom_visible = m_gcode_viewer_2.is_extrusion_role_visible((libvgcode::EGCodeExtrusionRole)GCodeExtrusionRole::Custom); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + const bool custom_visible = is_visible(GCodeExtrusionRole::Custom); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + const wxString btn_text = custom_visible ? _L("Hide Custom G-code") : _L("Show Custom G-code"); + ImGui::Separator(); + if (imgui.button(btn_text, ImVec2(-1.0f, 0.0f), true)) { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + m_gcode_viewer_2.toggle_extrusion_role_visibility((libvgcode::EGCodeExtrusionRole)GCodeExtrusionRole::Custom); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + m_extrusions.role_visibility_flags = custom_visible ? m_extrusions.role_visibility_flags & ~(1 << int(GCodeExtrusionRole::Custom)) : + m_extrusions.role_visibility_flags | (1 << int(GCodeExtrusionRole::Custom)); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + wxGetApp().plater()->refresh_print(); + } } } @@ -4160,6 +4615,24 @@ void GCodeViewer::render_legend(float& legend_height) if (show_estimated_time) { ImGui::Spacing(); std::string time_title = _u8L("Estimated printing times"); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + auto can_show_mode_button = [this](libvgcode::ETimeMode mode) { + bool show = false; + if (m_print_statistics.modes.size() > 1 && m_print_statistics.modes[static_cast(mode)].roles_times.size() > 0) { + for (size_t i = 0; i < m_print_statistics.modes.size(); ++i) { + if (i != static_cast(mode) && + m_print_statistics.modes[i].time > 0.0f && + short_time(get_time_dhms(m_print_statistics.modes[static_cast(mode)].time)) != short_time(get_time_dhms(m_print_statistics.modes[i].time))) { + show = true; + break; + } + } + } + return show; + }; +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ auto can_show_mode_button = [this](PrintEstimatedStatistics::ETimeMode mode) { bool show = false; if (m_print_statistics.modes.size() > 1 && m_print_statistics.modes[static_cast(mode)].roles_times.size() > 0) { @@ -4174,12 +4647,28 @@ void GCodeViewer::render_legend(float& legend_height) } return show; }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + const libvgcode::ETimeMode time_mode_id = m_gcode_viewer_2.get_time_mode(); + if (can_show_mode_button(time_mode_id)) { + switch (time_mode_id) + { + case libvgcode::ETimeMode::Normal: { time_title += " [" + _u8L("Normal mode") + "]"; break; } + case libvgcode::ETimeMode::Stealth: { time_title += " [" + _u8L("Stealth mode") + "]"; break; } +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (can_show_mode_button(m_time_estimate_mode)) { switch (m_time_estimate_mode) { case PrintEstimatedStatistics::ETimeMode::Normal: { time_title += " [" + _u8L("Normal mode") + "]"; break; } case PrintEstimatedStatistics::ETimeMode::Stealth: { time_title += " [" + _u8L("Stealth mode") + "]"; break; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ default: { assert(false); break; } } } @@ -4198,17 +4687,47 @@ void GCodeViewer::render_legend(float& legend_height) ImGui::EndTable(); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + auto show_mode_button = [this, &imgui, can_show_mode_button, new_view_type](const wxString& label, libvgcode::ETimeMode mode) { +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ auto show_mode_button = [this, &imgui, can_show_mode_button](const wxString& label, PrintEstimatedStatistics::ETimeMode mode) { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (can_show_mode_button(mode)) { if (imgui.button(label)) { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + m_gcode_viewer_2.set_time_mode(mode); + if (new_view_type == libvgcode::EViewType::LayerTimeLinear || new_view_type == libvgcode::EViewType::LayerTimeLogarithmic) +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_time_estimate_mode = mode; if (m_view_type == EViewType::LayerTimeLinear || m_view_type == EViewType::LayerTimeLogarithmic) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ refresh_render_paths(false, false); imgui.set_requires_extra_frame(); } } }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + switch (time_mode_id) { + case libvgcode::ETimeMode::Normal: { + show_mode_button(_L("Show stealth mode"), libvgcode::ETimeMode::Stealth); + break; + } + case libvgcode::ETimeMode::Stealth: { + show_mode_button(_L("Show normal mode"), libvgcode::ETimeMode::Normal); + break; + } +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ switch (m_time_estimate_mode) { case PrintEstimatedStatistics::ETimeMode::Normal: { show_mode_button(_L("Show stealth mode"), PrintEstimatedStatistics::ETimeMode::Stealth); @@ -4218,14 +4737,25 @@ void GCodeViewer::render_legend(float& legend_height) show_mode_button(_L("Show normal mode"), PrintEstimatedStatistics::ETimeMode::Normal); break; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ default : { assert(false); break; } } } // toolbar section +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + auto toggle_button = [this, &imgui, icon_size, new_view_type](Preview::OptionType type, const std::string& name, +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ auto toggle_button = [this, &imgui, icon_size](Preview::OptionType type, const std::string& name, +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ std::function draw_callback) { - auto is_flag_set = [](unsigned int flags, unsigned int flag) { + auto is_flag_set = [](unsigned int flags, unsigned int flag) { return (flags & (1 << flag)) != 0; }; @@ -4238,11 +4768,24 @@ void GCodeViewer::render_legend(float& legend_height) bool active = is_flag_set(flags, flag); if (imgui.draw_radio_button(name, 1.5f * icon_size, active, draw_callback)) { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + m_gcode_viewer_2.toggle_option_visibility((libvgcode::EOptionType)type); +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ unsigned int new_flags = set_flag(flags, flag, !active); set_options_visibility_from_flags(new_flags); const unsigned int diff_flags = flags ^ new_flags; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + if (new_view_type == libvgcode::EViewType::Speed && is_flag_set(diff_flags, static_cast(Preview::OptionType::Travel))) +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (m_view_type == GCodeViewer::EViewType::Feedrate && is_flag_set(diff_flags, static_cast(Preview::OptionType::Travel))) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ wxGetApp().plater()->refresh_print(); else { bool keep_first = m_sequential_view.current.first != m_sequential_view.global.first; diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 56e72f38ff..2f0669b7a0 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -12,6 +12,12 @@ #include "libslic3r/GCode/GCodeProcessor.hpp" #include "GLModel.hpp" +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER +#include "LibVGCode/Viewer.hpp" +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + #include #include #include @@ -390,13 +396,27 @@ class GCodeViewer { GLModel m_model; bool m_visible{ false }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // whether or not to render the model with fixed screen size bool m_fixed_size{ true }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ double m_total_mass{ 0.0 }; Vec3d m_position{ Vec3d::Zero() }; public: +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + void render(bool fixed_screen_size); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void render(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void reset() { m_position = Vec3d::Zero(); @@ -415,11 +435,27 @@ class GCodeViewer Vec3d cog() const { return (m_total_mass > 0.0) ? (Vec3d)(m_position / m_total_mass) : Vec3d::Zero(); } private: +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + void init(bool fixed_screen_size) { +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void init() { - if (m_model.is_initialized()) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + if (m_model.is_initialized()) return; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + const float radius = fixed_screen_size ? 10.0f : 1.0f; +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ const float radius = m_fixed_size ? 10.0f : 1.0f; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_model.init_from(smooth_sphere(32, radius)); } }; @@ -468,7 +504,15 @@ class GCodeViewer // Color mapping by extrusion temperature. Range temperature; // Color mapping by layer time. +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + std::array(libvgcode::ETimeMode::COUNT)> layer_time; +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ std::array(PrintEstimatedStatistics::ETimeMode::Count)> layer_time; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void reset() { height.reset(); @@ -483,15 +527,27 @@ class GCodeViewer } }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ unsigned int role_visibility_flags{ 0 }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Ranges ranges; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void reset_role_visibility_flags() { role_visibility_flags = 0; for (uint32_t i = 0; i < uint32_t(GCodeExtrusionRole::Count); ++i) { role_visibility_flags |= 1 << i; } } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void reset_ranges() { ranges.reset(); } }; @@ -734,7 +790,13 @@ public: size_t last{ 0 }; }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool skip_invisible_moves{ false }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Endpoints endpoints; Endpoints current; Endpoints last_current; @@ -748,6 +810,9 @@ public: void render(float legend_height); }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ enum class EViewType : unsigned char { FeatureType, @@ -763,11 +828,20 @@ public: ColorPrint, Count }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ private: bool m_gl_data_initialized{ false }; unsigned int m_last_result_id{ 0 }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ EViewType m_last_view_type{ EViewType::Count }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ size_t m_moves_count{ 0 }; std::vector m_buffers{ static_cast(EMoveType::Extrude) }; // bounding box of toolpaths @@ -790,7 +864,24 @@ private: SequentialView m_sequential_view; Shells m_shells; COG m_cog; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + // whether or not to render the cog model with fixed screen size + bool m_cog_marker_fixed_screen_size{ true }; + float m_cog_marker_size{ 1.0f }; + bool m_tool_marker_fixed_screen_size{ false }; + float m_tool_marker_size{ 1.0f }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ EViewType m_view_type{ EViewType::FeatureType }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool m_legend_enabled{ true }; struct LegendResizer { @@ -799,13 +890,25 @@ private: }; LegendResizer m_legend_resizer; PrintEstimatedStatistics m_print_statistics; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ PrintEstimatedStatistics::ETimeMode m_time_estimate_mode{ PrintEstimatedStatistics::ETimeMode::Normal }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_GCODE_VIEWER_STATISTICS Statistics m_statistics; #endif // ENABLE_GCODE_VIEWER_STATISTICS GCodeProcessorResult::SettingsIds m_settings_ids; std::array m_sequential_range_caps; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ std::array, static_cast(PrintEstimatedStatistics::ETimeMode::Count)> m_layers_times; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ std::vector m_custom_gcode_per_print_z; @@ -813,6 +916,13 @@ private: ConflictResultOpt m_conflict_result; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + libvgcode::Viewer m_gcode_viewer_2; + bool m_use_gcode_viewer_2{ false }; +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + public: GCodeViewer(); ~GCodeViewer() { reset(); } @@ -820,7 +930,15 @@ public: void init(); // extract rendering data from the given parameters +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + void load(const GCodeProcessorResult& gcode_result, const Print& print, const std::vector& str_tool_colors); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void load(const GCodeProcessorResult& gcode_result, const Print& print); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // recalculate ranges in dependence of what is visible and sets tool/print colors void refresh(const GCodeProcessorResult& gcode_result, const std::vector& str_tool_colors); void refresh_render_paths(bool keep_sequential_current_first, bool keep_sequential_current_last) const; @@ -828,7 +946,15 @@ public: void reset(); void render(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + void render_cog() { m_cog.render(m_cog_marker_fixed_screen_size); } +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void render_cog() { m_cog.render(); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool has_data() const { return !m_roles.empty(); } bool can_export_toolpaths() const; @@ -855,6 +981,12 @@ public: bool is_contained_in_bed() const { return m_contained_in_bed; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + void set_view_type(libvgcode::EViewType type) { m_gcode_viewer_2.set_view_type(type); } + libvgcode::EViewType get_view_type() const { return m_gcode_viewer_2.get_view_type(); } +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ EViewType get_view_type() const { return m_view_type; } void set_view_type(EViewType type) { if (type == EViewType::Count) @@ -862,11 +994,20 @@ public: m_view_type = type; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool is_toolpath_move_type_visible(EMoveType type) const; void set_toolpath_move_type_visible(EMoveType type, bool visible); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ unsigned int get_toolpath_role_visibility_flags() const { return m_extrusions.role_visibility_flags; } void set_toolpath_role_visibility_flags(unsigned int flags) { m_extrusions.role_visibility_flags = flags; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ unsigned int get_options_visibility_flags() const; void set_options_visibility_from_flags(unsigned int flags); void set_layers_z_range(const std::array& layers_z_range); @@ -889,6 +1030,15 @@ public: void load_shells(const Print& print); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + bool use_gcode_viewer_2() const { return m_use_gcode_viewer_2; } + void toggle_use_gcode_viewer_2() { m_use_gcode_viewer_2 = !m_use_gcode_viewer_2; } + float get_cog_marker_scale_factor() const { return m_gcode_viewer_2.get_cog_marker_scale_factor(); } + void set_cog_marker_scale_factor(float factor) { return m_gcode_viewer_2.set_cog_marker_scale_factor(factor); } +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + private: void load_toolpaths(const GCodeProcessorResult& gcode_result); void load_wipetower_shell(const Print& print); @@ -898,9 +1048,19 @@ private: #if ENABLE_GCODE_VIEWER_STATISTICS void render_statistics(); #endif // ENABLE_GCODE_VIEWER_STATISTICS +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + bool is_visible(GCodeExtrusionRole role) const { + return m_gcode_viewer_2.is_extrusion_role_visible((libvgcode::EGCodeExtrusionRole)role); + } +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool is_visible(GCodeExtrusionRole role) const { return role < GCodeExtrusionRole::Count && (m_extrusions.role_visibility_flags & (1 << int(role))) != 0; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool is_visible(const Path& path) const { return is_visible(path.role); } void log_memory_used(const std::string& label, int64_t additional = 0) const; ColorRGBA option_color(EMoveType move_type) const; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 0c129803a5..82e0985e7d 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1947,8 +1947,19 @@ void GLCanvas3D::render() #if ENABLE_RENDER_SELECTION_CENTER _render_selection_center(); #endif // ENABLE_RENDER_SELECTION_CENTER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + if (!m_main_toolbar.is_enabled()) { + if (!m_gcode_viewer.use_gcode_viewer_2()) + _render_gcode_cog(); + } +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (!m_main_toolbar.is_enabled()) _render_gcode_cog(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // we need to set the mouse's scene position here because the depth buffer // could be invalidated by the following gizmo render methods @@ -2153,6 +2164,9 @@ void GLCanvas3D::set_gcode_options_visibility_from_flags(unsigned int flags) m_gcode_viewer.set_options_visibility_from_flags(flags); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void GLCanvas3D::set_toolpath_role_visibility_flags(unsigned int flags) { m_gcode_viewer.set_toolpath_role_visibility_flags(flags); @@ -2162,6 +2176,9 @@ void GLCanvas3D::set_toolpath_view_type(GCodeViewer::EViewType type) { m_gcode_viewer.set_view_type(type); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void GLCanvas3D::set_volumes_z_range(const std::array& range) { @@ -2679,7 +2696,15 @@ void GLCanvas3D::load_gcode_shells() void GLCanvas3D::load_gcode_preview(const GCodeProcessorResult& gcode_result, const std::vector& str_tool_colors) { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + m_gcode_viewer.load(gcode_result, *this->fff_print(), str_tool_colors); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_gcode_viewer.load(gcode_result, *this->fff_print()); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (wxGetApp().is_editor()) { _set_warning_notification_if_needed(EWarning::ToolpathOutside); @@ -2960,6 +2985,16 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) post_event(SimpleEvent(EVT_GLCANVAS_RELOAD_FROM_DISK)); break; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + case WXK_F2: { + m_gcode_viewer.toggle_use_gcode_viewer_2(); + m_dirty = true; + request_extra_frame(); + break; + } +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ case '0': { select_view("iso"); break; } case '1': { select_view("top"); break; } case '2': { select_view("bottom"); break; } @@ -6096,6 +6131,19 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type) void GLCanvas3D::_render_gcode() { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + Slic3r::GUI::ImGuiWrapper& imgui = *Slic3r::GUI::wxGetApp().imgui(); + const Size cnv_size = get_canvas_size(); + imgui.set_next_window_pos(0.5f * static_cast(cnv_size.get_width()), 0.0f, ImGuiCond_Always, 0.5f, 0.0f); + imgui.begin(std::string("LibVGCode Viewer Info"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar); + if (m_gcode_viewer.use_gcode_viewer_2()) + imgui.text("Press F2 to switch to old visualization"); + else + imgui.text("Press F2 to switch to new visualization"); + imgui.end(); +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_gcode_viewer.render(); } diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 5f714aae30..a0c8374e06 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -734,7 +734,17 @@ public: void init_gcode_viewer() { m_gcode_viewer.init(); } void reset_gcode_toolpaths() { m_gcode_viewer.reset(); } const GCodeViewer::SequentialView& get_gcode_sequential_view() const { return m_gcode_viewer.get_sequential_view(); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + void update_gcode_sequential_view_current(unsigned int first, unsigned int last) { + m_gcode_viewer.update_sequential_view_current(first, last); + } +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void update_gcode_sequential_view_current(unsigned int first, unsigned int last) { m_gcode_viewer.update_sequential_view_current(first, last); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void toggle_sla_auxiliaries_visibility(bool visible, const ModelObject* mo = nullptr, int instance_idx = -1); void toggle_model_objects_visibility(bool visible, const ModelObject* mo = nullptr, int instance_idx = -1, const ModelVolume* mv = nullptr); @@ -824,14 +834,26 @@ public: void ensure_on_bed(unsigned int object_idx, bool allow_negative_z); bool is_gcode_legend_enabled() const { return m_gcode_viewer.is_legend_enabled(); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ GCodeViewer::EViewType get_gcode_view_type() const { return m_gcode_viewer.get_view_type(); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ const std::vector& get_gcode_layers_zs() const; std::vector get_volumes_print_zs(bool active_only) const; unsigned int get_gcode_options_visibility_flags() const { return m_gcode_viewer.get_options_visibility_flags(); } void set_gcode_options_visibility_from_flags(unsigned int flags); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ unsigned int get_toolpath_role_visibility_flags() const { return m_gcode_viewer.get_toolpath_role_visibility_flags(); } void set_toolpath_role_visibility_flags(unsigned int flags); void set_toolpath_view_type(GCodeViewer::EViewType type); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void set_volumes_z_range(const std::array& range); void set_toolpaths_z_range(const std::array& range); std::vector& get_custom_gcode_per_print_z() { return m_gcode_viewer.get_custom_gcode_per_print_z(); } @@ -847,8 +869,17 @@ public: void load_gcode_shells(); void load_gcode_preview(const GCodeProcessorResult& gcode_result, const std::vector& str_tool_colors); void refresh_gcode_preview_render_paths(bool keep_sequential_current_first, bool keep_sequential_current_last); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + void set_gcode_view_preview_type(libvgcode::EViewType type) { return m_gcode_viewer.set_view_type(type); } + libvgcode::EViewType get_gcode_view_preview_type() const { return m_gcode_viewer.get_view_type(); } +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void set_gcode_view_preview_type(GCodeViewer::EViewType type) { return m_gcode_viewer.set_view_type(type); } GCodeViewer::EViewType get_gcode_view_preview_type() const { return m_gcode_viewer.get_view_type(); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void load_sla_preview(); void load_preview(const std::vector& str_tool_colors, const std::vector& color_print_values); void bind_event_handlers(); diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 5eb32a6474..ca4e284eee 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -787,14 +787,30 @@ void Preview::load_print_as_fff(bool keep_z_range) return; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + const libvgcode::EViewType gcode_view_type = m_canvas->get_gcode_view_preview_type(); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ GCodeViewer::EViewType gcode_view_type = m_canvas->get_gcode_view_preview_type(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool gcode_preview_data_valid = !m_gcode_result->moves.empty(); // Collect colors per extruder. std::vector colors; std::vector color_print_values = {}; // set color print values, if it si selected "ColorPrint" view type +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + if (gcode_view_type == libvgcode::EViewType::ColorPrint) { +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (gcode_view_type == GCodeViewer::EViewType::ColorPrint) { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ colors = wxGetApp().plater()->get_colors_for_color_print(m_gcode_result); if (!gcode_preview_data_valid) { @@ -805,7 +821,15 @@ void Preview::load_print_as_fff(bool keep_z_range) colors.push_back("#808080"); // gray color for pause print or custom G-code } } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + else if (gcode_preview_data_valid || gcode_view_type == libvgcode::EViewType::Tool) { +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ else if (gcode_preview_data_valid || gcode_view_type == GCodeViewer::EViewType::Tool) { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ colors = wxGetApp().plater()->get_extruder_colors_from_plater_config(m_gcode_result); color_print_values.clear(); } @@ -847,11 +871,29 @@ void Preview::load_print_as_fff(bool keep_z_range) m_canvas->get_custom_gcode_per_print_z(); const bool contains_color_gcodes = std::any_of(std::begin(gcodes), std::end(gcodes), [](auto const& item) { return item.type == CustomGCode::Type::ColorChange || item.type == CustomGCode::Type::ToolChange; }); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + const libvgcode::EViewType choice = contains_color_gcodes ? + libvgcode::EViewType::ColorPrint : + (number_extruders > 1) ? libvgcode::EViewType::Tool : libvgcode::EViewType::FeatureType; +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ const GCodeViewer::EViewType choice = contains_color_gcodes ? GCodeViewer::EViewType::ColorPrint : (number_extruders > 1) ? GCodeViewer::EViewType::Tool : GCodeViewer::EViewType::FeatureType; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (choice != gcode_view_type) { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER m_canvas->set_gcode_view_preview_type(choice); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + m_canvas->set_gcode_view_preview_type(choice); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (wxGetApp().is_gcode_viewer()) m_keep_current_preview_type = true; refresh_print(); diff --git a/src/slic3r/GUI/LibVGCode/Bitset.cpp b/src/slic3r/GUI/LibVGCode/Bitset.cpp new file mode 100644 index 0000000000..25f0125a84 --- /dev/null +++ b/src/slic3r/GUI/LibVGCode/Bitset.cpp @@ -0,0 +1,24 @@ +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#include "libslic3r/Technologies.hpp" +//################################################################################################################################ + +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#include "Bitset.hpp" + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#if ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +namespace libvgcode { + +} // namespace libvgcode + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#endif // ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ diff --git a/src/slic3r/GUI/LibVGCode/Bitset.hpp b/src/slic3r/GUI/LibVGCode/Bitset.hpp new file mode 100644 index 0000000000..1a8c2c66fc --- /dev/null +++ b/src/slic3r/GUI/LibVGCode/Bitset.hpp @@ -0,0 +1,110 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#ifndef VGCODE_BITSET_HPP +#define VGCODE_BITSET_HPP + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#if ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +#include +#include + +namespace libvgcode { + +// By default, types are not atomic, +template auto constexpr is_atomic = false; + +// but std::atomic types are, +template auto constexpr is_atomic> = true; + +template +struct BitSet +{ + BitSet() = default; + BitSet(unsigned int size) : size(size), blocks(1 + (size / (sizeof(T) * 8))) { clear(); } + + void clear() { + for (size_t i = 0; i < blocks.size(); ++i) { + blocks[i] &= T(0); + } + } + + void setAll() { + for (size_t i = 0; i < blocks.size(); ++i) { + blocks[i] |= ~T(0); + } + } + + //return true if bit changed + bool set(unsigned int index) { + const auto [block_idx, bit_idx] = get_coords(index); + T mask = (T(1) << bit_idx); + bool flip = mask xor blocks[block_idx]; + blocks[block_idx] |= mask; + return flip; + } + + //return true if bit changed + bool reset(unsigned int index) { + const auto [block_idx, bit_idx] = get_coords(index); + T mask = (T(1) << bit_idx); + bool flip = mask xor blocks[block_idx]; + blocks[block_idx] &= (~mask); + return flip; + } + + bool operator [] (unsigned int index) const { + const auto [block_idx, bit_idx] = get_coords(index); + return ((blocks[block_idx] >> bit_idx) & 1) != 0; + } + + template + BitSet& operator &= (const BitSet& other) { + static_assert(sizeof(T) == sizeof(U), "Type1 and Type2 must be of the same size."); + for (size_t i = 0; i < blocks.size(); ++i) { + blocks[i] &= other.blocks[i]; + } + return *this; + } + + // Atomic set operation (enabled only for atomic types), return true if bit changed + template + inline typename std::enable_if, bool>::type set_atomic(unsigned int index) { + const auto [block_idx, bit_idx] = get_coords(index); + T mask = static_cast(1) << bit_idx; + T oldval = blocks[block_idx].fetch_or(mask, std::memory_order_relaxed); + return oldval xor (oldval or mask); + } + + // Atomic reset operation (enabled only for atomic types), return true if bit changed + template + inline typename std::enable_if, bool>::type reset_atomic(unsigned int index) { + const auto [block_idx, bit_idx] = get_coords(index); + T mask = ~(static_cast(1) << bit_idx); + T oldval = blocks[block_idx].fetch_and(mask, std::memory_order_relaxed); + return oldval xor (oldval and mask); + } + + std::pair get_coords(unsigned int index) const + { + unsigned int block_idx = index / (sizeof(T) * 8); + unsigned int bit_idx = index % (sizeof(T) * 8); + return std::make_pair(block_idx, bit_idx); + } + + unsigned int size{ 0 }; + std::vector blocks{ 0 }; +}; + +} // namespace libvgcode + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#endif // ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +#endif // VGCODE_BITSET_HPP \ No newline at end of file diff --git a/src/slic3r/GUI/LibVGCode/CogMarker.cpp b/src/slic3r/GUI/LibVGCode/CogMarker.cpp new file mode 100644 index 0000000000..5be38014a7 --- /dev/null +++ b/src/slic3r/GUI/LibVGCode/CogMarker.cpp @@ -0,0 +1,171 @@ +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#include "libslic3r/Technologies.hpp" +//################################################################################################################################ + +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966 +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#include "CogMarker.hpp" +#include "OpenGLUtils.hpp" +#include "Utils.hpp" + +#include +#include +#include + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#if ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +namespace libvgcode { + +CogMarker::~CogMarker() +{ + if (m_ibo_id != 0) + glsafe(glDeleteBuffers(1, &m_ibo_id)); + if (m_vbo_id != 0) + glsafe(glDeleteBuffers(1, &m_vbo_id)); + if (m_vao_id != 0) + glsafe(glDeleteVertexArrays(1, &m_vao_id)); +} + +// Geometry: +// sphere with 'resolution' sides, centered at (0.0, 0.0, 0.0) and radius equal to 'radius' +void CogMarker::init(uint8_t resolution, float radius) +{ + if (m_vao_id != 0) + return; + + // ensure vertices count does not exceed 65536 + resolution = std::clamp(resolution, 4, 105); + + const uint16_t sector_count = (uint16_t)resolution; + const uint16_t stack_count = (uint16_t)resolution; + + const float sector_step = 2.0f * PI / float(sector_count); + const float stack_step = PI / float(stack_count); + + std::vector vertices; + const uint16_t vertices_count = (stack_count - 1) * sector_count + 2; + vertices.reserve(6 * vertices_count); + + m_indices_count = 3 * (2 * (stack_count - 1) * sector_count); + std::vector indices; + indices.reserve(m_indices_count); + + // vertices + for (uint16_t i = 0; i <= stack_count; ++i) { + // from pi/2 to -pi/2 + const float stack_angle = 0.5f * PI - stack_step * float(i); + const float xy = radius * std::cos(stack_angle); + const float z = radius * std::sin(stack_angle); + if (i == 0 || i == stack_count) { + const Vec3f pos = toVec3f(xy, 0.0f, z); + const Vec3f norm = normalize(pos); + add_vertex(pos, norm, vertices); + } + else { + for (uint16_t j = 0; j < sector_count; ++j) { + // from 0 to 2pi + const float sector_angle = sector_step * float(j); + const Vec3f pos = toVec3f(xy * std::cos(sector_angle), xy * std::sin(sector_angle), z); + const Vec3f norm = normalize(pos); + add_vertex(pos, norm, vertices); + } + } + } + + // indices + for (uint16_t i = 0; i < stack_count; ++i) { + // Beginning of current stack. + uint16_t k1 = (i == 0) ? 0 : (1 + (i - 1) * sector_count); + const uint16_t k1_first = k1; + // Beginning of next stack. + uint16_t k2 = (i == 0) ? 1 : (k1 + sector_count); + const uint16_t k2_first = k2; + for (uint16_t j = 0; j < sector_count; ++j) { + // 2 triangles per sector excluding first and last stacks + uint16_t k1_next = k1; + uint16_t k2_next = k2; + if (i != 0) { + k1_next = (j + 1 == sector_count) ? k1_first : (k1 + 1); + add_triangle(k1, k2, k1_next, indices); + } + if (i + 1 != stack_count) { + k2_next = (j + 1 == sector_count) ? k2_first : (k2 + 1); + add_triangle(k1_next, k2, k2_next, indices); + } + k1 = k1_next; + k2 = k2_next; + } + } + + const size_t vertex_stride = 6 * sizeof(float); + const size_t position_offset = 0; + const size_t normal_offset = 3 * sizeof(float); + + int curr_vertex_array; + glsafe(glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &curr_vertex_array)); + int curr_array_buffer; + glsafe(glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &curr_array_buffer)); + + glsafe(glGenVertexArrays(1, &m_vao_id)); + glsafe(glBindVertexArray(m_vao_id)); + glsafe(glGenBuffers(1, &m_vbo_id)); + glsafe(glBindBuffer(GL_ARRAY_BUFFER, m_vbo_id)); + glsafe(glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), vertices.data(), GL_STATIC_DRAW)); + glsafe(glEnableVertexAttribArray(0)); + glsafe(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, vertex_stride, (const void*)position_offset)); + glsafe(glEnableVertexAttribArray(1)); + glsafe(glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, vertex_stride, (const void*)normal_offset)); + + glsafe(glGenBuffers(1, &m_ibo_id)); + glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo_id)); + glsafe(glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(uint16_t), indices.data(), GL_STATIC_DRAW)); + + glsafe(glBindBuffer(GL_ARRAY_BUFFER, curr_array_buffer)); + glsafe(glBindVertexArray(curr_vertex_array)); +} + +void CogMarker::render() +{ + if (m_vao_id == 0 || m_vbo_id == 0 || m_ibo_id == 0 || m_indices_count == 0) + return; + + int curr_vertex_array; + glsafe(glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &curr_vertex_array)); + glcheck(); + + glsafe(glBindVertexArray(m_vao_id)); + glsafe(glDrawElements(GL_TRIANGLES, m_indices_count, GL_UNSIGNED_SHORT, (const void*)0)); + glsafe(glBindVertexArray(curr_vertex_array)); +} + +void CogMarker::update(const Vec3f& position, float mass) +{ + m_total_position = m_total_position + toVec3f(mass * position[0], mass * position[1], mass * position[2]); + m_total_mass += mass; +} + +void CogMarker::reset() +{ + m_total_position = toVec3f(0.0f, 0.0f, 0.0f); + m_total_mass = 0.0f; +} + +Vec3f CogMarker::get_position() const +{ + assert(m_total_mass > 0.0f); + const float inv_total_mass = 1.0f / m_total_mass; + return { m_total_position[0] * inv_total_mass, m_total_position[1] * inv_total_mass, m_total_position[2] * inv_total_mass }; +} + +} // namespace libvgcode + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#endif // ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ diff --git a/src/slic3r/GUI/LibVGCode/CogMarker.hpp b/src/slic3r/GUI/LibVGCode/CogMarker.hpp new file mode 100644 index 0000000000..67ca4ccdfe --- /dev/null +++ b/src/slic3r/GUI/LibVGCode/CogMarker.hpp @@ -0,0 +1,70 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966 +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#ifndef VGCODE_COGMARKER_HPP +#define VGCODE_COGMARKER_HPP + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#if ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +#include "Types.hpp" + +#include + +namespace libvgcode { + +class CogMarker +{ +public: + CogMarker() = default; + ~CogMarker(); + CogMarker(const CogMarker& other) = delete; + CogMarker(CogMarker&& other) = delete; + CogMarker& operator = (const CogMarker& other) = delete; + CogMarker& operator = (CogMarker&& other) = delete; + + // + // Initialize geometry on gpu + // + void init(uint8_t resolution, float radius); + void render(); + + // + // Update values used to calculate the center of gravity + // + void update(const Vec3f& position, float mass); + + // + // Reset values used to calculate the center of gravity + // + void reset(); + + // + // Return the calculated center of gravity + // + Vec3f get_position() const; + +private: + // + // Values used to calculate the center of gravity + // + float m_total_mass{ 0.0f }; + Vec3f m_total_position{ 0.0f, 0.0f, 0.0f }; + + uint16_t m_indices_count{ 0 }; + unsigned int m_vao_id{ 0 }; + unsigned int m_vbo_id{ 0 }; + unsigned int m_ibo_id{ 0 }; +}; + +} // namespace libvgcode + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#endif // ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +#endif // VGCODE_COGMARKER_HPP \ No newline at end of file diff --git a/src/slic3r/GUI/LibVGCode/ColorRange.cpp b/src/slic3r/GUI/LibVGCode/ColorRange.cpp new file mode 100644 index 0000000000..252e4f696a --- /dev/null +++ b/src/slic3r/GUI/LibVGCode/ColorRange.cpp @@ -0,0 +1,132 @@ +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#include "libslic3r/Technologies.hpp" +//################################################################################################################################ + +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#include "ColorRange.hpp" + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#if ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +#include +#include +#include + +namespace libvgcode { + +static const std::vector Ranges_Colors{ { + { 0.043f, 0.173f, 0.478f }, // bluish + { 0.075f, 0.349f, 0.522f }, + { 0.110f, 0.533f, 0.569f }, + { 0.016f, 0.839f, 0.059f }, + { 0.667f, 0.949f, 0.000f }, + { 0.988f, 0.975f, 0.012f }, + { 0.961f, 0.808f, 0.039f }, + { 0.890f, 0.533f, 0.125f }, + { 0.820f, 0.408f, 0.188f }, + { 0.761f, 0.322f, 0.235f }, + { 0.581f, 0.149f, 0.087f } // reddish +} }; + +ColorRange::ColorRange(EType type) +: m_type(type) +{ +} + +void ColorRange::update(float value) +{ + if (std::abs(value - m_range[0]) > 0.001 && std::abs(value - m_range[1]) > 0.001) + ++m_count; + + m_range[0] = std::min(m_range[0], value); + m_range[1] = std::max(m_range[1], value); +} + +void ColorRange::reset() +{ + m_range = { FLT_MAX, -FLT_MAX }; + m_count = 0; +} + +static float step_size(const std::array& range, ColorRange::EType type) +{ + switch (type) + { + default: + case ColorRange::EType::Linear: + { + return (range[1] - range[0]) / ((float)Ranges_Colors.size() - 1.0f); + } + case ColorRange::EType::Logarithmic: + { + return (range[0] != 0.0f) ? std::log(range[1] / range[0]) / ((float)Ranges_Colors.size() - 1.0f) : 0.0f; + } + } +} + +ColorRange::EType ColorRange::get_type() const +{ + return m_type; +} + +Color ColorRange::get_color_at(float value) const +{ + // std::lerp is available with c++20 + auto lerp = [](const Color& a, const Color& b, float t) { + t = std::clamp(t, 0.0f, 1.0f); + Color ret; + for (int i = 0; i < 3; ++i) { + ret[i] = (1.0f - t) * a[i] + t * b[i]; + } + return ret; + }; + + // Input value scaled to the colors range + float global_t = 0.0f; + value = std::clamp(value, m_range[0], m_range[1]); + const float step = step_size(m_range, m_type); + if (step > 0.0f) { + if (m_type == EType::Logarithmic) { + if (m_range[0] != 0.0f) + global_t = log(value / m_range[0]) / step; + } + else + global_t = (value - m_range[0]) / step; + } + + const size_t color_max_idx = Ranges_Colors.size() - 1; + + // Compute the two colors just below (low) and above (high) the input value + const size_t color_low_idx = std::clamp(static_cast(global_t), 0, color_max_idx); + const size_t color_high_idx = std::clamp(color_low_idx + 1, 0, color_max_idx); + + // Interpolate between the low and high colors to find exactly which color the input value should get + return lerp(Ranges_Colors[color_low_idx], Ranges_Colors[color_high_idx], global_t - static_cast(color_low_idx)); +} + +unsigned int ColorRange::get_count() const +{ + return m_count; +} + +//################################################################################################################################ +// Debug +const std::array& ColorRange::get_range() const +{ + return m_range; +} +//################################################################################################################################ + +} // namespace libvgcode + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#endif // ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + diff --git a/src/slic3r/GUI/LibVGCode/ColorRange.hpp b/src/slic3r/GUI/LibVGCode/ColorRange.hpp new file mode 100644 index 0000000000..72b5b577d2 --- /dev/null +++ b/src/slic3r/GUI/LibVGCode/ColorRange.hpp @@ -0,0 +1,57 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#ifndef VGCODE_COLORRANGE_HPP +#define VGCODE_COLORRANGE_HPP + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#if ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +#include "Types.hpp" + +namespace libvgcode { + +// Alias for GCodeViewer::Extrusion::Range +class ColorRange +{ +public: + enum class EType : unsigned char + { + Linear, + Logarithmic, + COUNT + }; + + explicit ColorRange(EType type = EType::Linear); + + void update(float value); + void reset(); + + EType get_type() const; + Color get_color_at(float value) const; + unsigned int get_count() const; + +//################################################################################################################################ + // Debug + const std::array& get_range() const; +//################################################################################################################################ + +private: + EType m_type{ EType::Linear }; + // [0] = min, [1] = max + std::array m_range{ FLT_MAX, -FLT_MAX }; + // updates counter + unsigned int m_count{ 0 }; +}; + +} // namespace libvgcode + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#endif // ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +#endif // VGCODE_COLORRANGE_HPP \ No newline at end of file diff --git a/src/slic3r/GUI/LibVGCode/OpenGLUtils.cpp b/src/slic3r/GUI/LibVGCode/OpenGLUtils.cpp new file mode 100644 index 0000000000..279ee816a3 --- /dev/null +++ b/src/slic3r/GUI/LibVGCode/OpenGLUtils.cpp @@ -0,0 +1,48 @@ +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#include "libslic3r/Technologies.hpp" +//################################################################################################################################ + +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak, Vojtěch Bubník @bubnikv +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#include "OpenGLUtils.hpp" + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#if ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +#include +#include + +namespace libvgcode { +#ifdef HAS_GLSAFE +void glAssertRecentCallImpl(const char* file_name, unsigned int line, const char* function_name) +{ + const GLenum err = glGetError(); + if (err == GL_NO_ERROR) + return; + const char* sErr = 0; + switch (err) { + case GL_INVALID_ENUM: { sErr = "Invalid Enum"; break; } + case GL_INVALID_VALUE: { sErr = "Invalid Value"; break; } + // be aware that GL_INVALID_OPERATION is generated if glGetError is executed between the execution of glBegin / glEnd + case GL_INVALID_OPERATION: { sErr = "Invalid Operation"; break; } + case GL_STACK_OVERFLOW: { sErr = "Stack Overflow"; break; } + case GL_STACK_UNDERFLOW: { sErr = "Stack Underflow"; break; } + case GL_OUT_OF_MEMORY: { sErr = "Out Of Memory"; break; } + default: { sErr = "Unknown"; break; } + } + std::cout << "OpenGL error in " << file_name << ":" << line << ", function " << function_name << "() : " << (int)err << " - " << sErr << "\n"; + assert(false); +} +#endif // HAS_GLSAFE + +} // namespace libvgcode + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#endif // ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ diff --git a/src/slic3r/GUI/LibVGCode/OpenGLUtils.hpp b/src/slic3r/GUI/LibVGCode/OpenGLUtils.hpp new file mode 100644 index 0000000000..bfa9482e5a --- /dev/null +++ b/src/slic3r/GUI/LibVGCode/OpenGLUtils.hpp @@ -0,0 +1,41 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak, Vojtěch Bubník @bubnikv +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#ifndef VGCODE_OPENGLUTILS_HPP +#define VGCODE_OPENGLUTILS_HPP + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#if ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +//################################################################################################################################ +// OpenGL dependencies +#include +//################################################################################################################################ + +namespace libvgcode { +#ifndef NDEBUG +#define HAS_GLSAFE +#endif // NDEBUG + +#ifdef HAS_GLSAFE +extern void glAssertRecentCallImpl(const char* file_name, unsigned int line, const char* function_name); +inline void glAssertRecentCall() { glAssertRecentCallImpl(__FILE__, __LINE__, __FUNCTION__); } +#define glsafe(cmd) do { cmd; glAssertRecentCallImpl(__FILE__, __LINE__, __FUNCTION__); } while (false) +#define glcheck() do { glAssertRecentCallImpl(__FILE__, __LINE__, __FUNCTION__); } while (false) +#else // HAS_GLSAFE +inline void glAssertRecentCall() { } +#define glsafe(cmd) cmd +#define glcheck() +#endif // HAS_GLSAFE + +} // namespace libvgcode + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#endif // ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +#endif // VGCODE_OPENGLUTILS_HPP \ No newline at end of file diff --git a/src/slic3r/GUI/LibVGCode/OptionTemplate.cpp b/src/slic3r/GUI/LibVGCode/OptionTemplate.cpp new file mode 100644 index 0000000000..779cc86910 --- /dev/null +++ b/src/slic3r/GUI/LibVGCode/OptionTemplate.cpp @@ -0,0 +1,128 @@ +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#include "libslic3r/Technologies.hpp" +//################################################################################################################################ + +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966 +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#include "OptionTemplate.hpp" +#include "OpenGLUtils.hpp" +#include "Utils.hpp" + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#if ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +#include +#include + +namespace libvgcode { + +OptionTemplate::~OptionTemplate() +{ + if (m_bottom_vbo_id != 0) + glsafe(glDeleteBuffers(1, &m_bottom_vbo_id)); + if (m_bottom_vao_id != 0) + glsafe(glDeleteVertexArrays(1, &m_bottom_vao_id)); + if (m_top_vbo_id != 0) + glsafe(glDeleteBuffers(1, &m_top_vbo_id)); + if (m_top_vao_id != 0) + glsafe(glDeleteVertexArrays(1, &m_top_vao_id)); +} + +// Geometry: +// diamond with 'resolution' sides, centered at (0.0, 0.0, 0.0) +// height and width of the diamond are equal to 1.0 +void OptionTemplate::init(uint8_t resolution) +{ + if (m_top_vao_id != 0) + return; + + m_resolution = std::max(resolution, 3); + m_vertices_count = 2 + resolution; + const float step = 2.0f * PI / float(m_resolution); + + // + // top fan + // + std::vector top_vertices; + top_vertices.reserve(6 * m_vertices_count); + add_vertex(toVec3f(0.0f, 0.0f, 0.5f), toVec3f(0.0f, 0.0f, 1.0f), top_vertices); + for (uint8_t i = 0; i <= m_resolution; ++i) { + const float ii = float(i) * step; + const Vec3f pos = toVec3f(0.5f * ::cos(ii), 0.5f * ::sin(ii), 0.0f); + const Vec3f norm = normalize(pos); + add_vertex(pos, norm, top_vertices); + } + + // + // bottom fan + // + std::vector bottom_vertices; + bottom_vertices.reserve(6 * m_vertices_count); + add_vertex(toVec3f(0.0f, 0.0f, -0.5f), toVec3f(0.0f, 0.0f, -1.0f), bottom_vertices); + for (uint8_t i = 0; i <= m_resolution; ++i) { + const float ii = -float(i) * step; + const Vec3f pos = toVec3f(0.5f * ::cos(ii), 0.5f * ::sin(ii), 0.0f); + const Vec3f norm = normalize(pos); + add_vertex(pos, norm, bottom_vertices); + } + + const size_t vertex_stride = 6 * sizeof(float); + const size_t position_offset = 0; + const size_t normal_offset = 3 * sizeof(float); + + int curr_vertex_array; + glsafe(glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &curr_vertex_array)); + int curr_array_buffer; + glsafe(glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &curr_array_buffer)); + + glsafe(glGenVertexArrays(1, &m_top_vao_id)); + glsafe(glBindVertexArray(m_top_vao_id)); + glsafe(glGenBuffers(1, &m_top_vbo_id)); + glsafe(glBindBuffer(GL_ARRAY_BUFFER, m_top_vbo_id)); + glsafe(glBufferData(GL_ARRAY_BUFFER, top_vertices.size() * sizeof(float), top_vertices.data(), GL_STATIC_DRAW)); + glsafe(glEnableVertexAttribArray(0)); + glsafe(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, vertex_stride, (const void*)position_offset)); + glsafe(glEnableVertexAttribArray(1)); + glsafe(glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, vertex_stride, (const void*)normal_offset)); + + glsafe(glGenVertexArrays(1, &m_bottom_vao_id)); + glsafe(glBindVertexArray(m_bottom_vao_id)); + glsafe(glGenBuffers(1, &m_bottom_vbo_id)); + glsafe(glBindBuffer(GL_ARRAY_BUFFER, m_bottom_vbo_id)); + glsafe(glBufferData(GL_ARRAY_BUFFER, bottom_vertices.size() * sizeof(float), bottom_vertices.data(), GL_STATIC_DRAW)); + glsafe(glEnableVertexAttribArray(0)); + glsafe(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, vertex_stride, (const void*)position_offset)); + glsafe(glEnableVertexAttribArray(1)); + glsafe(glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, vertex_stride, (const void*)normal_offset)); + + glsafe(glBindBuffer(GL_ARRAY_BUFFER, curr_array_buffer)); + glsafe(glBindVertexArray(curr_vertex_array)); +} + +void OptionTemplate::render(size_t count) +{ + if (m_top_vao_id == 0 || m_top_vbo_id == 0 || m_bottom_vao_id == 0 || m_bottom_vbo_id == 0 || count == 0) + return; + + int curr_vertex_array; + glsafe(glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &curr_vertex_array)); + + glsafe(glBindVertexArray(m_top_vao_id)); + glsafe(glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, m_vertices_count, count)); + glsafe(glBindVertexArray(m_bottom_vao_id)); + glsafe(glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, m_vertices_count, count)); + + glsafe(glBindVertexArray(curr_vertex_array)); +} + +} // namespace libvgcode + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#endif // ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ diff --git a/src/slic3r/GUI/LibVGCode/OptionTemplate.hpp b/src/slic3r/GUI/LibVGCode/OptionTemplate.hpp new file mode 100644 index 0000000000..d7eaf7d59a --- /dev/null +++ b/src/slic3r/GUI/LibVGCode/OptionTemplate.hpp @@ -0,0 +1,46 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966 +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#ifndef VGCODE_OPTIONTEMPLATE_HPP +#define VGCODE_OPTIONTEMPLATE_HPP + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#if ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +#include + +namespace libvgcode { + +class OptionTemplate +{ +public: + OptionTemplate() = default; + ~OptionTemplate(); + OptionTemplate(const OptionTemplate& other) = delete; + OptionTemplate(OptionTemplate&& other) = delete; + OptionTemplate& operator = (const OptionTemplate& other) = delete; + OptionTemplate& operator = (OptionTemplate&& other) = delete; + + void init(uint8_t resolution); + void render(size_t count); + +private: + uint8_t m_resolution{ 0 }; + uint8_t m_vertices_count{ 0 }; + unsigned int m_top_vao_id{ 0 }; + unsigned int m_top_vbo_id{ 0 }; + unsigned int m_bottom_vao_id{ 0 }; + unsigned int m_bottom_vbo_id{ 0 }; +}; + +} // namespace libvgcode + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#endif // ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +#endif // VGCODE_OPTIONTEMPLATE_HPP \ No newline at end of file diff --git a/src/slic3r/GUI/LibVGCode/PathVertex.cpp b/src/slic3r/GUI/LibVGCode/PathVertex.cpp new file mode 100644 index 0000000000..970efcb4b4 --- /dev/null +++ b/src/slic3r/GUI/LibVGCode/PathVertex.cpp @@ -0,0 +1,143 @@ +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#include "libslic3r/Technologies.hpp" +//################################################################################################################################ + +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#include "PathVertex.hpp" + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#if ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +namespace libvgcode { + +PathVertex::PathVertex(const Vec3f& position, float height, float width, float feedrate, float fan_speed, + float temperature, float volumetric_rate, EGCodeExtrusionRole role, EMoveType type, uint8_t extruder_id, + uint8_t color_id, uint32_t layer_id) +: m_position(position) +, m_height(height) +, m_width(width) +, m_feedrate(feedrate) +, m_fan_speed(fan_speed) +, m_temperature(temperature) +, m_volumetric_rate(volumetric_rate) +, m_extruder_id(extruder_id) +, m_color_id(color_id) +, m_layer_id(layer_id) +, m_type(type) +, m_role(role) +{ +} + +const Vec3f& PathVertex::get_position() const +{ + return m_position; +} + +float PathVertex::get_height() const +{ + return m_height; +} + +float PathVertex::get_width() const +{ + return m_width; +} + +float PathVertex::get_feedrate() const +{ + return m_feedrate; +} + +float PathVertex::get_fan_speed() const +{ + return m_fan_speed; +} + +float PathVertex::get_temperature() const +{ + return m_temperature; +} + +float PathVertex::get_volumetric_rate() const +{ + return m_volumetric_rate; +} + +EMoveType PathVertex::get_type() const +{ + return m_type; +} + +EGCodeExtrusionRole PathVertex::get_role() const +{ + return m_role; +} + +uint8_t PathVertex::get_extruder_id() const +{ + return m_extruder_id; +} + +uint8_t PathVertex::get_color_id() const +{ + return m_color_id; +} + +uint32_t PathVertex::get_layer_id() const +{ + return m_layer_id; +} + +bool PathVertex::is_extrusion() const +{ + return m_type == EMoveType::Extrude; +} + +bool PathVertex::is_travel() const +{ + return m_type == EMoveType::Travel; +} + +bool PathVertex::is_wipe() const +{ + return m_type == EMoveType::Wipe; +} + +bool PathVertex::is_option() const +{ + switch (m_type) + { + case EMoveType::Retract: + case EMoveType::Unretract: + case EMoveType::Seam: + case EMoveType::ToolChange: + case EMoveType::ColorChange: + case EMoveType::PausePrint: + case EMoveType::CustomGCode: + { + return true; + } + default: + { + return false; + } + } +} + +bool PathVertex::is_custom_gcode() const +{ + return m_type == EMoveType::Extrude && m_role == EGCodeExtrusionRole::Custom; +} + +} // namespace libvgcode + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#endif // ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ diff --git a/src/slic3r/GUI/LibVGCode/PathVertex.hpp b/src/slic3r/GUI/LibVGCode/PathVertex.hpp new file mode 100644 index 0000000000..b38bf3ec8c --- /dev/null +++ b/src/slic3r/GUI/LibVGCode/PathVertex.hpp @@ -0,0 +1,65 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#ifndef VGCODE_PATHVERTEX_HPP +#define VGCODE_PATHVERTEX_HPP + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#if ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +#include "Types.hpp" + +namespace libvgcode { + +class PathVertex +{ +public: + PathVertex(const Vec3f& position, float height, float width, float feedrate, float fan_speed, + float temperature, float volumetric_rate, EGCodeExtrusionRole role, EMoveType type, + uint8_t extruder_id, uint8_t color_id, uint32_t layer_id); + + const Vec3f& get_position() const; + float get_height() const; + float get_width() const; + float get_feedrate() const; + float get_fan_speed() const; + float get_temperature() const; + float get_volumetric_rate() const; + EMoveType get_type() const; + EGCodeExtrusionRole get_role() const; + uint8_t get_extruder_id() const; + uint8_t get_color_id() const; + uint32_t get_layer_id() const; + + bool is_extrusion() const; + bool is_travel() const; + bool is_option() const; + bool is_wipe() const; + bool is_custom_gcode() const; + +private: + Vec3f m_position{ toVec3f(0.0f) }; + float m_height{ 0.0f }; + float m_width{ 0.0f }; + float m_feedrate{ 0.0f }; + float m_fan_speed{ 0.0f }; + float m_temperature{ 0.0f }; + float m_volumetric_rate{ 0.0f }; + uint8_t m_extruder_id{ 0 }; + uint8_t m_color_id{ 0 }; + uint32_t m_layer_id{ 0 }; + EMoveType m_type{ EMoveType::Noop }; + EGCodeExtrusionRole m_role{ EGCodeExtrusionRole::None }; +}; + +} // namespace libvgcode + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#endif // ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +#endif // VGCODE_PATHVERTEX_HPP \ No newline at end of file diff --git a/src/slic3r/GUI/LibVGCode/SegmentTemplate.cpp b/src/slic3r/GUI/LibVGCode/SegmentTemplate.cpp new file mode 100644 index 0000000000..5388d89774 --- /dev/null +++ b/src/slic3r/GUI/LibVGCode/SegmentTemplate.cpp @@ -0,0 +1,90 @@ +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#include "libslic3r/Technologies.hpp" +//################################################################################################################################ + +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#include "SegmentTemplate.hpp" +#include "OpenGLUtils.hpp" + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#if ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +#include +#include + +namespace libvgcode { + +// /1-------6\ +// / | | \ +// 2--0-------5--7 +// \ | | / +// 3-------4 +static constexpr const std::array VERTEX_DATA = { + 0, 1, 2, // front spike + 0, 2, 3, // front spike + 0, 3, 4, // right/bottom body + 0, 4, 5, // right/bottom body + 0, 5, 6, // left/top body + 0, 6, 1, // left/top body + 5, 4, 7, // back spike + 5, 7, 6, // back spike +}; + +SegmentTemplate::~SegmentTemplate() +{ + if (m_vbo_id != 0) + glsafe(glDeleteBuffers(1, &m_vbo_id)); + + if (m_vao_id != 0) + glsafe(glDeleteVertexArrays(1, &m_vao_id)); +} + +void SegmentTemplate::init() +{ + if (m_vao_id != 0) + return; + + int curr_vertex_array; + glsafe(glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &curr_vertex_array)); + int curr_array_buffer; + glsafe(glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &curr_array_buffer)); + + glsafe(glGenVertexArrays(1, &m_vao_id)); + glsafe(glBindVertexArray(m_vao_id)); + + glsafe(glGenBuffers(1, &m_vbo_id)); + glsafe(glBindBuffer(GL_ARRAY_BUFFER, m_vbo_id)); + glsafe(glBufferData(GL_ARRAY_BUFFER, VERTEX_DATA.size() * sizeof(uint8_t), VERTEX_DATA.data(), GL_STATIC_DRAW)); + glsafe(glEnableVertexAttribArray(0)); + glsafe(glVertexAttribIPointer(0, 1, GL_UNSIGNED_BYTE, sizeof(uint8_t), (const void*)0)); + + glsafe(glBindBuffer(GL_ARRAY_BUFFER, curr_array_buffer)); + glsafe(glBindVertexArray(curr_vertex_array)); +} + +void SegmentTemplate::render(size_t count) +{ + if (m_vao_id == 0 || m_vbo_id == 0 || count == 0) + return; + + int curr_vertex_array; + glsafe(glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &curr_vertex_array)); + + glsafe(glBindVertexArray(m_vao_id)); + glsafe(glDrawArraysInstanced(GL_TRIANGLES, 0, VERTEX_DATA.size(), count)); + + glsafe(glBindVertexArray(curr_vertex_array)); +} + +} // namespace libvgcode + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#endif // ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ diff --git a/src/slic3r/GUI/LibVGCode/SegmentTemplate.hpp b/src/slic3r/GUI/LibVGCode/SegmentTemplate.hpp new file mode 100644 index 0000000000..44517cda5f --- /dev/null +++ b/src/slic3r/GUI/LibVGCode/SegmentTemplate.hpp @@ -0,0 +1,40 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#ifndef VGCODE_SEGMENTTEMPLATE_HPP +#define VGCODE_SEGMENTTEMPLATE_HPP + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#if ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +namespace libvgcode { + +class SegmentTemplate +{ +public: + SegmentTemplate() = default; + ~SegmentTemplate(); + SegmentTemplate(const SegmentTemplate& other) = delete; + SegmentTemplate(SegmentTemplate&& other) = delete; + SegmentTemplate& operator = (const SegmentTemplate& other) = delete; + SegmentTemplate& operator = (SegmentTemplate&& other) = delete; + + void init(); + void render(size_t count); + +private: + unsigned int m_vao_id{ 0 }; + unsigned int m_vbo_id{ 0 }; +}; + +} // namespace libvgcode + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#endif // ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +#endif // VGCODE_SEGMENTTEMPLATE_HPP \ No newline at end of file diff --git a/src/slic3r/GUI/LibVGCode/Settings.cpp b/src/slic3r/GUI/LibVGCode/Settings.cpp new file mode 100644 index 0000000000..3e8b7a7983 --- /dev/null +++ b/src/slic3r/GUI/LibVGCode/Settings.cpp @@ -0,0 +1,25 @@ +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#include "libslic3r/Technologies.hpp" +//################################################################################################################################ + +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#include "Settings.hpp" + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#if ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +namespace libvgcode { + +} // namespace libvgcode + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#endif // ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + diff --git a/src/slic3r/GUI/LibVGCode/Settings.hpp b/src/slic3r/GUI/LibVGCode/Settings.hpp new file mode 100644 index 0000000000..30158ec0eb --- /dev/null +++ b/src/slic3r/GUI/LibVGCode/Settings.hpp @@ -0,0 +1,67 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#ifndef VGCODE_SETTINGS_HPP +#define VGCODE_SETTINGS_HPP + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#if ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +#include "Types.hpp" + +#include + +namespace libvgcode { + +struct Settings +{ + bool update_enabled_entities{ true }; + bool update_colors{ true }; + EViewType view_type{ EViewType::FeatureType }; + ETimeMode time_mode{ ETimeMode::Normal }; + + std::map options_visibility{ { + { EOptionType::Travels, false }, + { EOptionType::Wipes, false }, + { EOptionType::Retractions, false }, + { EOptionType::Unretractions, false }, + { EOptionType::Seams, false }, + { EOptionType::ToolChanges, false }, + { EOptionType::ColorChanges, false }, + { EOptionType::PausePrints, false }, + { EOptionType::CustomGCodes, false }, + { EOptionType::CenterOfGravity, false }, + { EOptionType::Shells, false }, + { EOptionType::ToolMarker, true } + } }; + + std::map extrusion_roles_visibility{ { + { EGCodeExtrusionRole::None, true }, + { EGCodeExtrusionRole::Perimeter, true }, + { EGCodeExtrusionRole::ExternalPerimeter, true }, + { EGCodeExtrusionRole::OverhangPerimeter, true }, + { EGCodeExtrusionRole::InternalInfill, true }, + { EGCodeExtrusionRole::SolidInfill, true }, + { EGCodeExtrusionRole::TopSolidInfill, true }, + { EGCodeExtrusionRole::Ironing, true }, + { EGCodeExtrusionRole::BridgeInfill, true }, + { EGCodeExtrusionRole::GapFill, true }, + { EGCodeExtrusionRole::Skirt, true }, + { EGCodeExtrusionRole::SupportMaterial, true }, + { EGCodeExtrusionRole::SupportMaterialInterface, true }, + { EGCodeExtrusionRole::WipeTower, true }, + { EGCodeExtrusionRole::Custom, true } + } }; +}; + +} // namespace libvgcode + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#endif // ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +#endif // VGCODE_SETTINGS_HPP \ No newline at end of file diff --git a/src/slic3r/GUI/LibVGCode/Shaders.hpp b/src/slic3r/GUI/LibVGCode/Shaders.hpp new file mode 100644 index 0000000000..ec2b25fb42 --- /dev/null +++ b/src/slic3r/GUI/LibVGCode/Shaders.hpp @@ -0,0 +1,304 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#ifndef VGCODE_SHADERS_HPP +#define VGCODE_SHADERS_HPP + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#if ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +namespace libvgcode { + +static const char* Segments_Vertex_Shader = +"#version 150\n" +"#define POINTY_CAPS\n" +"#define FIX_TWISTING\n" +"const vec3 light_top_dir = vec3(-0.4574957, 0.4574957, 0.7624929);\n" +"const float light_top_diffuse = 0.6 * 0.8;\n" +"const float light_top_specular = 0.6 * 0.125;\n" +"const float light_top_shininess = 20.0;\n" +"const vec3 light_front_dir = vec3(0.6985074, 0.1397015, 0.6985074);\n" +"const float light_front_diffuse = 0.6 * 0.3;\n" +"const float ambient = 0.3;\n" +"const float emission = 0.15;\n" +"const vec3 UP = vec3(0, 0, 1);\n" +"uniform mat4 view_matrix;\n" +"uniform mat4 projection_matrix;\n" +"uniform vec3 camera_position;\n" +"uniform samplerBuffer positionsTex;\n" +"uniform samplerBuffer heightWidthAngleTex;\n" +"uniform samplerBuffer colorsTex;\n" +"uniform isamplerBuffer segmentIndexTex;\n" +"in int vertex_id;\n" +"out vec3 color;\n" +"vec3 decode_color(float color) {\n" +" int c = int(round(color));\n" +" int r = (c >> 16) & 0xFF;\n" +" int g = (c >> 8) & 0xFF;\n" +" int b = (c >> 0) & 0xFF;\n" +" float f = 1.0 / 255.0f;\n" +" return f * vec3(r, g, b);\n" +"}\n" +"float lighting(vec3 eye_position, vec3 eye_normal) {\n" +" float top_diffuse = light_top_diffuse * max(dot(eye_normal, light_top_dir), 0.0);\n" +" float front_diffuse = light_front_diffuse * max(dot(eye_normal, light_front_dir), 0.0);\n" +" float top_specular = light_top_specular * pow(max(dot(-normalize(eye_position), reflect(-light_top_dir, eye_normal)), 0.0), light_top_shininess);\n" +" return ambient + top_diffuse + front_diffuse + top_specular + emission;\n" +"}\n" +"void main() {\n" +" int id_a = texelFetch(segmentIndexTex, gl_InstanceID).r;\n" +" int id_b = id_a + 1;\n" +" vec3 pos_a = texelFetch(positionsTex, id_a).xyz;\n" +" vec3 pos_b = texelFetch(positionsTex, id_b).xyz;\n" +" vec3 line = pos_b - pos_a;\n" +" // directions of the line box in world space\n" +" float line_len = length(line);\n" +" vec3 line_dir;\n" +" if (line_len < 1e-4)\n" +" line_dir = vec3(1.0, 0.0, 0.0);\n" +" else\n" +" line_dir = line / line_len;\n" +" vec3 line_right_dir;\n" +" if (abs(dot(line_dir, UP)) > 0.9) {\n" +" // For vertical lines, the width and height should be same, there is no concept of up and down.\n" +" // For simplicity, the code will expand width in the x axis, and height in the y axis\n" +" line_right_dir = normalize(cross(vec3(1, 0, 0), line_dir));\n" +" }\n" +" else\n" +" line_right_dir = normalize(cross(line_dir, UP));\n" +" vec3 line_up_dir = normalize(cross(line_right_dir, line_dir));\n" +" const vec2 horizontal_vertical_view_signs_array[16] = vec2[](\n" +" //horizontal view (from right)\n" +" vec2(1.0, 0.0),\n" +" vec2(0.0, 1.0),\n" +" vec2(0.0, 0.0),\n" +" vec2(0.0, -1.0),\n" +" vec2(0.0, -1.0),\n" +" vec2(1.0, 0.0),\n" +" vec2(0.0, 1.0),\n" +" vec2(0.0, 0.0),\n" +" // vertical view (from top)\n" +" vec2(0.0, 1.0),\n" +" vec2(-1.0, 0.0),\n" +" vec2(0.0, 0.0),\n" +" vec2(1.0, 0.0),\n" +" vec2(1.0, 0.0),\n" +" vec2(0.0, 1.0),\n" +" vec2(-1.0, 0.0),\n" +" vec2(0.0, 0.0)\n" +" );\n" +" int id = vertex_id < 4 ? id_a : id_b;\n" +" vec3 endpoint_pos = vertex_id < 4 ? pos_a : pos_b;\n" +" vec3 height_width_angle = texelFetch(heightWidthAngleTex, id).xyz;\n" +"#ifdef FIX_TWISTING\n" +" int closer_id = (dot(camera_position - pos_a, camera_position - pos_a) < dot(camera_position - pos_b, camera_position - pos_b)) ? id_a : id_b;\n" +" vec3 closer_pos = (closer_id == id_a) ? pos_a : pos_b;\n" +" vec3 camera_view_dir = normalize(closer_pos - camera_position);\n" +" vec3 closer_height_width_angle = texelFetch(heightWidthAngleTex, closer_id).xyz;\n" +" vec3 diagonal_dir_border = normalize(closer_height_width_angle.x * line_up_dir + closer_height_width_angle.y * line_right_dir);\n" +"#else\n" +" vec3 camera_view_dir = normalize(endpoint_pos - camera_position);\n" +" vec3 diagonal_dir_border = normalize(height_width_angle.x * line_up_dir + height_width_angle.y * line_right_dir);\n" +"#endif\n" +" bool is_vertical_view = abs(dot(camera_view_dir, line_up_dir)) / abs(dot(diagonal_dir_border, line_up_dir)) >\n" +" abs(dot(camera_view_dir, line_right_dir)) / abs(dot(diagonal_dir_border, line_right_dir));\n" +" vec2 signs = horizontal_vertical_view_signs_array[vertex_id + 8 * int(is_vertical_view)];\n" +"#ifndef POINTY_CAPS\n" +" if (vertex_id == 2 || vertex_id == 7) signs = -horizontal_vertical_view_signs_array[(vertex_id - 2) + 8 * int(is_vertical_view)];\n" +"#endif\n" +" float view_right_sign = sign(dot(-camera_view_dir, line_right_dir));\n" +" float view_top_sign = sign(dot(-camera_view_dir, line_up_dir));\n" +" float half_height = 0.5 * height_width_angle.x;\n" +" float half_width = 0.5 * height_width_angle.y;\n" +" vec3 horizontal_dir = half_width * line_right_dir;\n" +" vec3 vertical_dir = half_height * line_up_dir;\n" +" float horizontal_sign = signs.x * view_right_sign;\n" +" float vertical_sign = signs.y * view_top_sign;\n" +" vec3 pos = endpoint_pos + horizontal_sign * horizontal_dir + vertical_sign * vertical_dir;\n" +" if (vertex_id == 2 || vertex_id == 7) {\n" +" float line_dir_sign = (vertex_id == 2) ? -1.0 : 1.0;\n" +" if (height_width_angle.z == 0) {\n" +"#ifdef POINTY_CAPS\n" +" // There I add a cap to lines that do not have a following line\n" +" // (or they have one, but perfectly aligned, so the cap is hidden inside the next line).\n" +" pos += line_dir_sign * line_dir * half_width;\n" +"#endif\n" +" }\n" +" else {\n" +" pos += line_dir_sign * line_dir * half_width * sin(abs(height_width_angle.z) * 0.5);\n" +" pos += sign(height_width_angle.z) * horizontal_dir * cos(abs(height_width_angle.z) * 0.5);\n" +" }\n" +" }\n" +" vec3 eye_position = (view_matrix * vec4(pos, 1.0)).xyz;\n" +" vec3 eye_normal = (view_matrix * vec4(normalize(pos - endpoint_pos), 0.0)).xyz;\n" +" vec3 color_base = decode_color(texelFetch(colorsTex, id).x);\n" +" color = color_base * lighting(eye_position, eye_normal);\n" +" gl_Position = projection_matrix * vec4(eye_position, 1.0);\n" +"}\n"; + +static const char* Segments_Fragment_Shader = +"#version 150\n" +"in vec3 color;\n" +"out vec4 fragmentColor;\n" +"void main() {\n" +" fragmentColor = vec4(color, 1.0);\n" +"}\n"; + +static const char* Options_Vertex_Shader = +"#version 150\n" +"const vec3 light_top_dir = vec3(-0.4574957, 0.4574957, 0.7624929);\n" +"const float light_top_diffuse = 0.6 * 0.8;\n" +"const float light_top_specular = 0.6 * 0.125;\n" +"const float light_top_shininess = 20.0;\n" +"const vec3 light_front_dir = vec3(0.6985074, 0.1397015, 0.6985074);\n" +"const float light_front_diffuse = 0.6 * 0.3;\n" +"const float ambient = 0.3;\n" +"const float emission = 0.25;\n" +"const float scaling_factor = 1.5;\n" +"uniform mat4 view_matrix;\n" +"uniform mat4 projection_matrix;\n" +"uniform samplerBuffer positionsTex;\n" +"uniform samplerBuffer heightWidthAngleTex;\n" +"uniform samplerBuffer colorsTex;\n" +"uniform isamplerBuffer segmentIndexTex;\n" +"in vec3 in_position;\n" +"in vec3 in_normal;\n" +"out vec3 color;\n" +"vec3 decode_color(float color) {\n" +" int c = int(round(color));\n" +" int r = (c >> 16) & 0xFF;\n" +" int g = (c >> 8) & 0xFF;\n" +" int b = (c >> 0) & 0xFF;\n" +" float f = 1.0 / 255.0f;\n" +" return f * vec3(r, g, b);\n" +"}\n" +"float lighting(vec3 eye_position, vec3 eye_normal) {\n" +" float top_diffuse = light_top_diffuse * max(dot(eye_normal, light_top_dir), 0.0);\n" +" float front_diffuse = light_front_diffuse * max(dot(eye_normal, light_front_dir), 0.0);\n" +" float top_specular = light_top_specular * pow(max(dot(-normalize(eye_position), reflect(-light_top_dir, eye_normal)), 0.0), light_top_shininess);\n" +" return ambient + top_diffuse + front_diffuse + top_specular + emission;\n" +"}\n" +"void main() {\n" +" int id = texelFetch(segmentIndexTex, gl_InstanceID).r;\n" +" vec2 height_width = texelFetch(heightWidthAngleTex, id).xy;\n" +" vec3 offset = texelFetch(positionsTex, id).xyz - vec3(0.0, 0.0, 0.5 * height_width.x);\n" +" height_width *= scaling_factor;\n" +" mat3 scale_matrix = mat3(\n" +" height_width.y, 0.0, 0.0,\n" +" 0.0, height_width.y, 0.0,\n" +" 0.0, 0.0, height_width.x);\n" +" vec3 eye_position = (view_matrix * vec4(scale_matrix * in_position + offset, 1.0)).xyz;\n" +" vec3 eye_normal = (view_matrix * vec4(in_normal, 0.0)).xyz;\n" +" vec3 color_base = decode_color(texelFetch(colorsTex, id).x);\n" +" color = color_base * lighting(eye_position, eye_normal);\n" +" gl_Position = projection_matrix * vec4(eye_position, 1.0);\n" +"}\n"; + +static const char* Options_Fragment_Shader = +"#version 150\n" +"in vec3 color;\n" +"out vec4 fragmentColor;\n" +"void main() {\n" +" fragmentColor = vec4(color, 1.0);\n" +"}\n"; + +static const char* Cog_Marker_Vertex_Shader = +"#version 150\n" +"const vec3 light_top_dir = vec3(-0.4574957, 0.4574957, 0.7624929);\n" +"const float light_top_diffuse = 0.6 * 0.8;\n" +"const float light_top_specular = 0.6 * 0.125;\n" +"const float light_top_shininess = 20.0;\n" +"const vec3 light_front_dir = vec3(0.6985074, 0.1397015, 0.6985074);\n" +"const float light_front_diffuse = 0.6 * 0.3;\n" +"const float ambient = 0.3;\n" +"const float emission = 0.25;\n" +"uniform vec3 world_center_position;\n" +"uniform float scale_factor;\n" +"uniform mat4 view_matrix;\n" +"uniform mat4 projection_matrix;\n" +"in vec3 in_position;\n" +"in vec3 in_normal;\n" +"out float intensity;\n" +"out vec3 world_position;\n" +"float lighting(vec3 eye_position, vec3 eye_normal) {\n" +" float top_diffuse = light_top_diffuse * max(dot(eye_normal, light_top_dir), 0.0);\n" +" float front_diffuse = light_front_diffuse * max(dot(eye_normal, light_front_dir), 0.0);\n" +" float top_specular = light_top_specular * pow(max(dot(-normalize(eye_position), reflect(-light_top_dir, eye_normal)), 0.0), light_top_shininess);\n" +" return ambient + top_diffuse + front_diffuse + top_specular + emission;\n" +"}\n" +"void main() {\n" +" world_position = scale_factor * in_position + world_center_position;\n" +" vec3 eye_position = (view_matrix * vec4(world_position, 1.0)).xyz;\n" +" vec3 eye_normal = (view_matrix * vec4(in_normal, 0.0)).xyz;\n" +" intensity = lighting(eye_position, eye_normal);\n" +" gl_Position = projection_matrix * vec4(eye_position, 1.0);\n" +"}\n"; + +static const char* Cog_Marker_Fragment_Shader = +"#version 150\n" +"const vec3 BLACK = vec3(0.05);\n" +"const vec3 WHITE = vec3(0.95);\n" +"uniform vec3 world_center_position;\n" +"in float intensity;\n" +"in vec3 world_position;\n" +"out vec4 out_color;\n" +"void main()\n" +"{\n" +" vec3 delta = world_position - world_center_position;\n" +" vec3 color = delta.x * delta.y * delta.z > 0.0 ? BLACK : WHITE;\n" +" out_color = intensity * vec4(color, 1.0);\n" +"}\n"; + +static const char* Tool_Marker_Vertex_Shader = +"#version 150\n" +"const vec3 light_top_dir = vec3(-0.4574957, 0.4574957, 0.7624929);\n" +"const float light_top_diffuse = 0.6 * 0.8;\n" +"const float light_top_specular = 0.6 * 0.125;\n" +"const float light_top_shininess = 20.0;\n" +"const vec3 light_front_dir = vec3(0.6985074, 0.1397015, 0.6985074);\n" +"const float light_front_diffuse = 0.6 * 0.3;\n" +"const float ambient = 0.3;\n" +"const float emission = 0.25;\n" +"uniform vec3 world_origin;\n" +"uniform float scale_factor;\n" +"uniform mat4 view_matrix;\n" +"uniform mat4 projection_matrix;\n" +"uniform vec4 color_base;\n" +"in vec3 in_position;\n" +"in vec3 in_normal;\n" +"out vec4 color;\n" +"float lighting(vec3 eye_position, vec3 eye_normal) {\n" +" float top_diffuse = light_top_diffuse * max(dot(eye_normal, light_top_dir), 0.0);\n" +" float front_diffuse = light_front_diffuse * max(dot(eye_normal, light_front_dir), 0.0);\n" +" float top_specular = light_top_specular * pow(max(dot(-normalize(eye_position), reflect(-light_top_dir, eye_normal)), 0.0), light_top_shininess);\n" +" return ambient + top_diffuse + front_diffuse + top_specular + emission;\n" +"}\n" +"void main() {\n" +" vec3 world_position = scale_factor * in_position + world_origin;\n" +" vec3 eye_position = (view_matrix * vec4(world_position, 1.0)).xyz;\n" +" // no need of normal matrix as the scaling is uniform\n" +" vec3 eye_normal = (view_matrix * vec4(in_normal, 0.0)).xyz;\n" +" color = vec4(color_base.rgb * lighting(eye_position, eye_normal), color_base.a);\n" +" gl_Position = projection_matrix * vec4(eye_position, 1.0);\n" +"}\n"; + +static const char* Tool_Marker_Fragment_Shader = +"#version 150\n" +"in vec4 color;\n" +"out vec4 fragment_color;\n" +"void main() {\n" +" fragment_color = color;\n" +"}\n"; + +} // namespace libvgcode + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#endif // ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +#endif // VGCODE_SHADERS_HPP + diff --git a/src/slic3r/GUI/LibVGCode/Shell.cpp b/src/slic3r/GUI/LibVGCode/Shell.cpp new file mode 100644 index 0000000000..2986f04e6d --- /dev/null +++ b/src/slic3r/GUI/LibVGCode/Shell.cpp @@ -0,0 +1,89 @@ +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#include "libslic3r/Technologies.hpp" +//################################################################################################################################ + +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966 +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#include "Shell.hpp" +#include "OpenGLUtils.hpp" +#include "Utils.hpp" + +#include + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#if ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +namespace libvgcode { + +Shell::~Shell() +{ + if (m_ibo_id != 0) + glsafe(glDeleteBuffers(1, &m_ibo_id)); + if (m_vbo_id != 0) + glsafe(glDeleteBuffers(1, &m_vbo_id)); + if (m_vao_id != 0) + glsafe(glDeleteVertexArrays(1, &m_vao_id)); +} + +void Shell::init() +{ + if (m_vao_id != 0) + return; + +} + +void Shell::render() +{ + if (m_vao_id == 0 || m_vbo_id == 0 || m_ibo_id == 0) + return; + + int curr_vertex_array; + glsafe(glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &curr_vertex_array)); + glcheck(); + + glsafe(glBindVertexArray(m_vao_id)); + glsafe(glDrawElements(GL_TRIANGLES, m_indices_count, GL_UNSIGNED_INT, (const void*)0)); + glsafe(glBindVertexArray(curr_vertex_array)); +} + +const Vec3f& Shell::get_position() const +{ + return m_position; +} + +void Shell::set_position(const Vec3f& position) +{ + m_position = position; +} + +const Color& Shell::get_color() const +{ + return m_color; +} + +void Shell::set_color(const Color& color) +{ + m_color = color; +} + +float Shell::get_alpha() const +{ + return m_alpha; +} + +void Shell::set_alpha(float alpha) +{ + m_alpha = std::clamp(alpha, 0.25f, 0.75f); +} + +} // namespace libvgcode + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#endif // ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ diff --git a/src/slic3r/GUI/LibVGCode/Shell.hpp b/src/slic3r/GUI/LibVGCode/Shell.hpp new file mode 100644 index 0000000000..f7747ae453 --- /dev/null +++ b/src/slic3r/GUI/LibVGCode/Shell.hpp @@ -0,0 +1,59 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966 +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#ifndef VGCODE_SHELL_HPP +#define VGCODE_SHELL_HPP + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#if ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +#include "Types.hpp" + +#include + +namespace libvgcode { + +class Shell +{ +public: + Shell() = default; + ~Shell(); + Shell(const Shell& other) = delete; + Shell(Shell&& other) = delete; + Shell& operator = (const Shell& other) = delete; + Shell& operator = (Shell&& other) = delete; + + void init(); + void render(); + + const Vec3f& get_position() const; + void set_position(const Vec3f& position); + + const Color& get_color() const; + void set_color(const Color& color); + + float get_alpha() const; + void set_alpha(float alpha); + +private: + Vec3f m_position{ 0.0f, 0.0f, 0.0f }; + Color m_color{ 1.0f, 1.0f, 1.0f }; + float m_alpha{ 0.5f }; + + uint32_t m_indices_count{ 0 }; + unsigned int m_vao_id{ 0 }; + unsigned int m_vbo_id{ 0 }; + unsigned int m_ibo_id{ 0 }; +}; + +} // namespace libvgcode + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#endif // ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +#endif // VGCODE_SHELL_HPP \ No newline at end of file diff --git a/src/slic3r/GUI/LibVGCode/ToolMarker.cpp b/src/slic3r/GUI/LibVGCode/ToolMarker.cpp new file mode 100644 index 0000000000..9a53371dd2 --- /dev/null +++ b/src/slic3r/GUI/LibVGCode/ToolMarker.cpp @@ -0,0 +1,202 @@ +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#include "libslic3r/Technologies.hpp" +//################################################################################################################################ + +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966 +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#include "ToolMarker.hpp" +#include "OpenGLUtils.hpp" +#include "Utils.hpp" + +#include + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#if ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +namespace libvgcode { + +ToolMarker::~ToolMarker() +{ + if (m_ibo_id != 0) + glsafe(glDeleteBuffers(1, &m_ibo_id)); + if (m_vbo_id != 0) + glsafe(glDeleteBuffers(1, &m_vbo_id)); + if (m_vao_id != 0) + glsafe(glDeleteVertexArrays(1, &m_vao_id)); +} + +// Geometry: +// Arrow with cylindrical stem and conical tip, with the given dimensions and resolution +// The origin of the arrow is at the tip of the conical section +// The axis of symmetry is along the Z axis +// The arrow is pointing downward +void ToolMarker::init(uint16_t resolution, float tip_radius, float tip_height, float stem_radius, float stem_height) +{ + if (m_vao_id != 0) + return; + + // ensure vertices count does not exceed 65536 + resolution = std::clamp(resolution, 4, 10922); + + std::vector vertices; + const uint16_t vertices_count = 6 * resolution + 2; + vertices.reserve(6 * vertices_count); + + m_indices_count = 6 * resolution * 3; + std::vector indices; + indices.reserve(m_indices_count); + + const float angle_step = 2.0f * PI / float(resolution); + std::vector cosines(resolution); + std::vector sines(resolution); + + for (uint16_t i = 0; i < resolution; ++i) { + const float angle = angle_step * float(i); + cosines[i] = ::cos(angle); + sines[i] = -::sin(angle); + } + + const float total_height = tip_height + stem_height; + + // tip vertices + add_vertex(toVec3f(0.0f, 0.0f, 0.0f), toVec3f(0.0f, 0.0f, -1.0f), vertices); + for (uint16_t i = 0; i < resolution; ++i) { + add_vertex(toVec3f(tip_radius * sines[i], tip_radius * cosines[i], tip_height), toVec3f(sines[i], cosines[i], 0.0f), vertices); + } + + // tip triangles + for (uint16_t i = 0; i < resolution; ++i) { + const uint16_t v3 = (i < resolution - 1) ? i + 2 : 1; + add_triangle(0, i + 1, v3, indices); + } + + // tip cap outer perimeter vertices + for (uint16_t i = 0; i < resolution; ++i) { + add_vertex(toVec3f(tip_radius * sines[i], tip_radius * cosines[i], tip_height), toVec3f(0.0f, 0.0f, 1.0f), vertices); + } + + // tip cap inner perimeter vertices + for (uint16_t i = 0; i < resolution; ++i) { + add_vertex(toVec3f(stem_radius * sines[i], stem_radius * cosines[i], tip_height), toVec3f(0.0f, 0.0f, 1.0f), vertices); + } + + // tip cap triangles + for (uint16_t i = 0; i < resolution; ++i) { + const uint16_t v2 = (i < resolution - 1) ? i + resolution + 2 : resolution + 1; + const uint16_t v3 = (i < resolution - 1) ? i + 2 * resolution + 2 : 2 * resolution + 1; + add_triangle(i + resolution + 1, v3, v2, indices); + add_triangle(i + resolution + 1, i + 2 * resolution + 1, v3, indices); + } + + // stem bottom vertices + for (uint16_t i = 0; i < resolution; ++i) { + add_vertex(toVec3f(stem_radius * sines[i], stem_radius * cosines[i], tip_height), toVec3f(sines[i], cosines[i], 0.0f), vertices); + } + + // stem top vertices + for (uint16_t i = 0; i < resolution; ++i) { + add_vertex(toVec3f(stem_radius * sines[i], stem_radius * cosines[i], total_height), toVec3f(sines[i], cosines[i], 0.0f), vertices); + } + + // stem triangles + for (uint16_t i = 0; i < resolution; ++i) { + const uint16_t v2 = (i < resolution - 1) ? i + 3 * resolution + 2 : 3 * resolution + 1; + const uint16_t v3 = (i < resolution - 1) ? i + 4 * resolution + 2 : 4 * resolution + 1; + add_triangle(i + 3 * resolution + 1, v3, v2, indices); + add_triangle(i + 3 * resolution + 1, i + 4 * resolution + 1, v3, indices); + } + + // stem cap vertices + add_vertex(toVec3f(0.0f, 0.0f, total_height), toVec3f(0.0f, 0.0f, 1.0f), vertices); + for (uint16_t i = 0; i < resolution; ++i) { + add_vertex(toVec3f(stem_radius * sines[i], stem_radius * cosines[i], total_height), toVec3f(0.0f, 0.0f, 1.0f), vertices); + } + + // stem cap triangles + for (uint16_t i = 0; i < resolution; ++i) { + const uint16_t v3 = (i < resolution - 1) ? i + 5 * resolution + 3 : 5 * resolution + 2; + add_triangle(5 * resolution + 1, v3, i + 5 * resolution + 2, indices); + } + + const size_t vertex_stride = 6 * sizeof(float); + const size_t position_offset = 0; + const size_t normal_offset = 3 * sizeof(float); + + int curr_vertex_array; + glsafe(glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &curr_vertex_array)); + int curr_array_buffer; + glsafe(glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &curr_array_buffer)); + + glsafe(glGenVertexArrays(1, &m_vao_id)); + glsafe(glBindVertexArray(m_vao_id)); + glsafe(glGenBuffers(1, &m_vbo_id)); + glsafe(glBindBuffer(GL_ARRAY_BUFFER, m_vbo_id)); + glsafe(glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), vertices.data(), GL_STATIC_DRAW)); + glsafe(glEnableVertexAttribArray(0)); + glsafe(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, vertex_stride, (const void*)position_offset)); + glsafe(glEnableVertexAttribArray(1)); + glsafe(glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, vertex_stride, (const void*)normal_offset)); + + glsafe(glGenBuffers(1, &m_ibo_id)); + glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo_id)); + glsafe(glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(uint16_t), indices.data(), GL_STATIC_DRAW)); + + glsafe(glBindBuffer(GL_ARRAY_BUFFER, curr_array_buffer)); + glsafe(glBindVertexArray(curr_vertex_array)); +} + +void ToolMarker::render() +{ + if (m_vao_id == 0 || m_vbo_id == 0 || m_ibo_id == 0) + return; + + int curr_vertex_array; + glsafe(glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &curr_vertex_array)); + glcheck(); + + glsafe(glBindVertexArray(m_vao_id)); + glsafe(glDrawElements(GL_TRIANGLES, m_indices_count, GL_UNSIGNED_SHORT, (const void*)0)); + glsafe(glBindVertexArray(curr_vertex_array)); +} + +const Vec3f& ToolMarker::get_position() const +{ + return m_position; +} + +void ToolMarker::set_position(const Vec3f& position) +{ + m_position = position; +} + +const Color& ToolMarker::get_color() const +{ + return m_color; +} + +void ToolMarker::set_color(const Color& color) +{ + m_color = color; +} + +float ToolMarker::get_alpha() const +{ + return m_alpha; +} + +void ToolMarker::set_alpha(float alpha) +{ + m_alpha = std::clamp(alpha, 0.25f, 0.75f); +} + +} // namespace libvgcode + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#endif // ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ diff --git a/src/slic3r/GUI/LibVGCode/ToolMarker.hpp b/src/slic3r/GUI/LibVGCode/ToolMarker.hpp new file mode 100644 index 0000000000..9c825d95cf --- /dev/null +++ b/src/slic3r/GUI/LibVGCode/ToolMarker.hpp @@ -0,0 +1,59 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966 +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#ifndef VGCODE_TOOLMARKER_HPP +#define VGCODE_TOOLMARKER_HPP + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#if ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +#include "Types.hpp" + +#include + +namespace libvgcode { + +class ToolMarker +{ +public: + ToolMarker() = default; + ~ToolMarker(); + ToolMarker(const ToolMarker& other) = delete; + ToolMarker(ToolMarker&& other) = delete; + ToolMarker& operator = (const ToolMarker& other) = delete; + ToolMarker& operator = (ToolMarker&& other) = delete; + + void init(uint16_t resolution, float tip_radius, float tip_height, float stem_radius, float stem_height); + void render(); + + const Vec3f& get_position() const; + void set_position(const Vec3f& position); + + const Color& get_color() const; + void set_color(const Color& color); + + float get_alpha() const; + void set_alpha(float alpha); + +private: + Vec3f m_position{ 0.0f, 0.0f, 0.0f }; + Color m_color{ 1.0f, 1.0f, 1.0f }; + float m_alpha{ 0.5f }; + + uint16_t m_indices_count{ 0 }; + unsigned int m_vao_id{ 0 }; + unsigned int m_vbo_id{ 0 }; + unsigned int m_ibo_id{ 0 }; +}; + +} // namespace libvgcode + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#endif // ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +#endif // VGCODE_TOOLMARKER_HPP \ No newline at end of file diff --git a/src/slic3r/GUI/LibVGCode/Toolpaths.cpp b/src/slic3r/GUI/LibVGCode/Toolpaths.cpp new file mode 100644 index 0000000000..7c94184bdf --- /dev/null +++ b/src/slic3r/GUI/LibVGCode/Toolpaths.cpp @@ -0,0 +1,1063 @@ +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#include "libslic3r/Technologies.hpp" +//################################################################################################################################ + +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak, Vojtěch Bubník @bubnikv +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#include "Toolpaths.hpp" +#include "ViewRange.hpp" +#include "Settings.hpp" +#include "Shaders.hpp" +#include "OpenGLUtils.hpp" + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#if ENABLE_NEW_GCODE_VIEWER +#include "libslic3r/GCode/GCodeProcessor.hpp" +//################################################################################################################################ + +#include +#include +#include + +namespace libvgcode { + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +static uint8_t valueof(Slic3r::EMoveType type) +{ + return static_cast(type); +} + +static uint8_t valueof(Slic3r::GCodeExtrusionRole role) +{ + return static_cast(role); +} + +static Vec3f toVec3f(const Eigen::Matrix& v) +{ + return { v.x(), v.y(), v.z() }; +} +//################################################################################################################################ + +static const Color Dummy_Color{ 0.0f, 0.0f, 0.0f }; +static const Color Default_Tool_Color{ 1.0f, 0.502f, 0.0f }; + +static const std::map Options_Colors{ { + { EMoveType::Retract, { 0.803f, 0.135f, 0.839f } }, + { EMoveType::Unretract, { 0.287f, 0.679f, 0.810f } }, + { EMoveType::Seam, { 0.900f, 0.900f, 0.900f } }, + { EMoveType::ToolChange, { 0.758f, 0.744f, 0.389f } }, + { EMoveType::ColorChange, { 0.856f, 0.582f, 0.546f } }, + { EMoveType::PausePrint, { 0.322f, 0.942f, 0.512f } }, + { EMoveType::CustomGCode, { 0.886f, 0.825f, 0.262f } } +} }; + +static const std::vector Extrusion_Roles_Colors{ { + { 0.90f, 0.70f, 0.70f }, // None + { 1.00f, 0.90f, 0.30f }, // Perimeter + { 1.00f, 0.49f, 0.22f }, // ExternalPerimeter + { 0.12f, 0.12f, 1.00f }, // OverhangPerimeter + { 0.69f, 0.19f, 0.16f }, // InternalInfill + { 0.59f, 0.33f, 0.80f }, // SolidInfill + { 0.94f, 0.25f, 0.25f }, // TopSolidInfill + { 1.00f, 0.55f, 0.41f }, // Ironing + { 0.30f, 0.50f, 0.73f }, // BridgeInfill + { 1.00f, 1.00f, 1.00f }, // GapFill + { 0.00f, 0.53f, 0.43f }, // Skirt + { 0.00f, 1.00f, 0.00f }, // SupportMaterial + { 0.00f, 0.50f, 0.00f }, // SupportMaterialInterface + { 0.70f, 0.89f, 0.67f }, // WipeTower + { 0.37f, 0.82f, 0.58f }, // Custom +} }; + +static const std::vector Travels_Colors{ { + { 0.219f, 0.282f, 0.609f }, // Move + { 0.112f, 0.422f, 0.103f }, // Extrude + { 0.505f, 0.064f, 0.028f } // Retract +} }; + +static const Color Wipe_Color{ 1.0f, 1.0f, 0.0f }; + +static const float TRAVEL_RADIUS = 0.05f; +static const float WIPE_RADIUS = 0.05f; + +template +using IntegerOnly = std::enable_if_t::value, O>; + +// Rounding up. +// 1.5 is rounded to 2 +// 1.49 is rounded to 1 +// 0.5 is rounded to 1, +// 0.49 is rounded to 0 +// -0.5 is rounded to 0, +// -0.51 is rounded to -1, +// -1.5 is rounded to -1. +// -1.51 is rounded to -2. +// If input is not a valid float (it is infinity NaN or if it does not fit) +// the float to int conversion produces a max int on Intel and +-max int on ARM. +template +inline IntegerOnly fast_round_up(double a) +{ + // Why does Java Math.round(0.49999999999999994) return 1? + // https://stackoverflow.com/questions/9902968/why-does-math-round0-49999999999999994-return-1 + return a == 0.49999999999999994 ? I(0) : I(floor(a + 0.5)); +} + +// Round to a bin with minimum two digits resolution. +// Equivalent to conversion to string with sprintf(buf, "%.2g", value) and conversion back to float, but faster. +static float round_to_bin(const float value) +{ +// assert(value >= 0); + constexpr float const scale[5] = { 100.f, 1000.f, 10000.f, 100000.f, 1000000.f }; + constexpr float const invscale[5] = { 0.01f, 0.001f, 0.0001f, 0.00001f, 0.000001f }; + constexpr float const threshold[5] = { 0.095f, 0.0095f, 0.00095f, 0.000095f, 0.0000095f }; + // Scaling factor, pointer to the tables above. + int i = 0; + // While the scaling factor is not yet large enough to get two integer digits after scaling and rounding: + for (; value < threshold[i] && i < 4; ++i); + // At least on MSVC std::round() calls a complex function, which is pretty expensive. + // our fast_round_up is much cheaper and it could be inlined. +// return std::round(value * scale[i]) * invscale[i]; + double a = value * scale[i]; + assert(std::abs(a) < double(std::numeric_limits::max())); + return fast_round_up(a) * invscale[i]; +} + +static int hex_digit_to_int(const char c) { + return (c >= '0' && c <= '9') ? int(c - '0') : + (c >= 'A' && c <= 'F') ? int(c - 'A') + 10 : + (c >= 'a' && c <= 'f') ? int(c - 'a') + 10 : -1; +}; + +bool decode_color(const std::string& color_in, Color& color_out) +{ + constexpr const float INV_255 = 1.0f / 255.0f; + + color_out.fill(0.0f); + if (color_in.size() == 7 && color_in.front() == '#') { + const char* c = color_in.data() + 1; + for (unsigned int i = 0; i < 3; ++i) { + const int digit1 = hex_digit_to_int(*c++); + const int digit2 = hex_digit_to_int(*c++); + if (digit1 != -1 && digit2 != -1) + color_out[i] = float(digit1 * 16 + digit2) * INV_255; + } + } + else + return false; + + assert(0.0f <= color_out[0] && color_out[0] <= 1.0f); + assert(0.0f <= color_out[1] && color_out[1] <= 1.0f); + assert(0.0f <= color_out[2] && color_out[2] <= 1.0f); + return true; +} + +bool decode_colors(const std::vector& colors_in, std::vector& colors_out) +{ + colors_out = std::vector(colors_in.size()); + for (size_t i = 0; i < colors_in.size(); ++i) { + if (!decode_color(colors_in[i], colors_out[i])) + return false; + } + return true; +} + +std::string check_shader(GLuint handle) +{ + std::string ret; + GLint params; + glsafe(glGetShaderiv(handle, GL_COMPILE_STATUS, ¶ms)); + if (params == GL_FALSE) { + glsafe(glGetShaderiv(handle, GL_INFO_LOG_LENGTH, ¶ms)); + ret.resize(params); + glsafe(glGetShaderInfoLog(handle, params, ¶ms, ret.data())); + } + return ret; +} + +std::string check_program(GLuint handle) +{ + std::string ret; + GLint params; + glsafe(glGetProgramiv(handle, GL_LINK_STATUS, ¶ms)); + if (params == GL_FALSE) { + glsafe(glGetProgramiv(handle, GL_INFO_LOG_LENGTH, ¶ms)); + ret.resize(params); + glsafe(glGetProgramInfoLog(handle, params, ¶ms, ret.data())); + } + return ret; +} + +unsigned int init_shader(const std::string& shader_name, const char* vertex_shader, const char* fragment_shader) +{ + const GLuint vs_id = glCreateShader(GL_VERTEX_SHADER); + glcheck(); + glsafe(glShaderSource(vs_id, 1, &vertex_shader, nullptr)); + glsafe(glCompileShader(vs_id)); + std::string res = check_shader(vs_id); + if (!res.empty()) { + glsafe(glDeleteShader(vs_id)); + throw std::runtime_error("LibVGCode: Unable to compile vertex shader:\n" + shader_name + "\n" + res + "\n"); + } + + const GLuint fs_id = glCreateShader(GL_FRAGMENT_SHADER); + glcheck(); + glsafe(glShaderSource(fs_id, 1, &fragment_shader, nullptr)); + glsafe(glCompileShader(fs_id)); + res = check_shader(fs_id); + if (!res.empty()) { + glsafe(glDeleteShader(vs_id)); + glsafe(glDeleteShader(fs_id)); + throw std::runtime_error("LibVGCode: Unable to compile fragment shader:\n" + shader_name + "\n" + res + "\n"); + } + + const GLuint shader_id = glCreateProgram(); + glcheck(); + glsafe(glAttachShader(shader_id, vs_id)); + glsafe(glAttachShader(shader_id, fs_id)); + glsafe(glLinkProgram(shader_id)); + res = check_program(shader_id); + if (!res.empty()) { + glsafe(glDetachShader(shader_id, vs_id)); + glsafe(glDetachShader(shader_id, fs_id)); + glsafe(glDeleteShader(vs_id)); + glsafe(glDeleteShader(fs_id)); + glsafe(glDeleteProgram(shader_id)); + throw std::runtime_error("LibVGCode: Unable to link shader program:\n" + shader_name + "\n" + res + "\n"); + } + + glsafe(glDetachShader(shader_id, vs_id)); + glsafe(glDetachShader(shader_id, fs_id)); + glsafe(glDeleteShader(vs_id)); + glsafe(glDeleteShader(fs_id)); + return shader_id; +} + +// mapping from EMoveType to EOptionType +static EOptionType type_to_option(EMoveType type) { + switch (type) + { + case EMoveType::Retract: { return EOptionType::Retractions; } + case EMoveType::Unretract: { return EOptionType::Unretractions; } + case EMoveType::Seam: { return EOptionType::Seams; } + case EMoveType::ToolChange: { return EOptionType::ToolChanges; } + case EMoveType::ColorChange: { return EOptionType::ColorChanges; } + case EMoveType::PausePrint: { return EOptionType::PausePrints; } + case EMoveType::CustomGCode: { return EOptionType::CustomGCodes; } + default: { return EOptionType::COUNT; } + } +} + +Toolpaths::~Toolpaths() +{ + reset(); + if (m_options_shader_id != 0) + glDeleteProgram(m_options_shader_id); + if (m_segments_shader_id != 0) + glDeleteProgram(m_segments_shader_id); +} + +void Toolpaths::init() +{ + if (m_segments_shader_id != 0) + return; + + // segments shader + m_segments_shader_id = init_shader("segments", Segments_Vertex_Shader, Segments_Fragment_Shader); + + m_uni_segments_view_matrix_id = glGetUniformLocation(m_segments_shader_id, "view_matrix"); + m_uni_segments_projection_matrix_id = glGetUniformLocation(m_segments_shader_id, "projection_matrix"); + m_uni_segments_camera_position_id = glGetUniformLocation(m_segments_shader_id, "camera_position"); + m_uni_segments_positions_tex_id = glGetUniformLocation(m_segments_shader_id, "positionsTex"); + m_uni_segments_height_width_angle_tex_id = glGetUniformLocation(m_segments_shader_id, "heightWidthAngleTex"); + m_uni_segments_colors_tex_id = glGetUniformLocation(m_segments_shader_id, "colorsTex"); + m_uni_segments_segment_index_tex_id = glGetUniformLocation(m_segments_shader_id, "segmentIndexTex"); + glcheck(); + assert(m_uni_segments_view_matrix_id != -1 && + m_uni_segments_projection_matrix_id != -1 && + m_uni_segments_camera_position_id != -1 && + m_uni_segments_positions_tex_id != -1 && + m_uni_segments_height_width_angle_tex_id != -1 && + m_uni_segments_colors_tex_id != -1 && + m_uni_segments_segment_index_tex_id != -1); + + m_segment_template.init(); + + // options shader + m_options_shader_id = init_shader("options", Options_Vertex_Shader, Options_Fragment_Shader); + + m_uni_options_view_matrix_id = glGetUniformLocation(m_options_shader_id, "view_matrix"); + m_uni_options_projection_matrix_id = glGetUniformLocation(m_options_shader_id, "projection_matrix"); + m_uni_options_positions_tex_id = glGetUniformLocation(m_options_shader_id, "positionsTex"); + m_uni_options_height_width_angle_tex_id = glGetUniformLocation(m_options_shader_id, "heightWidthAngleTex"); + m_uni_options_colors_tex_id = glGetUniformLocation(m_options_shader_id, "colorsTex"); + m_uni_options_segment_index_tex_id = glGetUniformLocation(m_options_shader_id, "segmentIndexTex"); + glcheck(); + assert(m_uni_options_view_matrix_id != -1 && + m_uni_options_projection_matrix_id != -1 && + m_uni_options_positions_tex_id != -1 && + m_uni_options_height_width_angle_tex_id != -1 && + m_uni_options_colors_tex_id != -1 && + m_uni_options_segment_index_tex_id != -1); + + m_option_template.init(16); + + // cog marker shader + m_cog_marker_shader_id = init_shader("cog_marker", Cog_Marker_Vertex_Shader, Cog_Marker_Fragment_Shader); + + m_uni_cog_marker_world_center_position = glGetUniformLocation(m_cog_marker_shader_id, "world_center_position"); + m_uni_cog_marker_scale_factor = glGetUniformLocation(m_cog_marker_shader_id, "scale_factor"); + m_uni_cog_marker_view_matrix = glGetUniformLocation(m_cog_marker_shader_id, "view_matrix"); + m_uni_cog_marker_projection_matrix = glGetUniformLocation(m_cog_marker_shader_id, "projection_matrix"); + glcheck(); + assert(m_uni_cog_marker_world_center_position != -1 && + m_uni_cog_marker_scale_factor != -1 && + m_uni_cog_marker_view_matrix != -1 && + m_uni_cog_marker_projection_matrix != -1); + + m_cog_marker.init(32, 1.0f); + + // tool marker shader + m_tool_marker_shader_id = init_shader("tool_marker", Tool_Marker_Vertex_Shader, Tool_Marker_Fragment_Shader); + + m_uni_tool_marker_world_origin = glGetUniformLocation(m_tool_marker_shader_id, "world_origin"); + m_uni_tool_marker_scale_factor = glGetUniformLocation(m_tool_marker_shader_id, "scale_factor"); + m_uni_tool_marker_view_matrix = glGetUniformLocation(m_tool_marker_shader_id, "view_matrix"); + m_uni_tool_marker_projection_matrix = glGetUniformLocation(m_tool_marker_shader_id, "projection_matrix"); + m_uni_tool_marker_color_base = glGetUniformLocation(m_tool_marker_shader_id, "color_base"); + + glcheck(); + assert(m_uni_tool_marker_world_origin != -1 && + m_uni_tool_marker_scale_factor != -1 && + m_uni_tool_marker_view_matrix != -1 && + m_uni_tool_marker_projection_matrix != -1 && + m_uni_tool_marker_color_base != -1); + + m_tool_marker.init(32, 2.0f, 4.0f, 1.0f, 8.0f); +} + +void Toolpaths::load(const Slic3r::GCodeProcessorResult& gcode_result, const Slic3r::Print& print, + const std::vector& str_tool_colors, const Settings& settings) +{ + m_tool_colors.clear(); + if (settings.view_type == EViewType::Tool && !gcode_result.extruder_colors.empty()) + // update tool colors from config stored in the gcode + decode_colors(gcode_result.extruder_colors, m_tool_colors); + else + // update tool colors + decode_colors(str_tool_colors, m_tool_colors); + + // ensure there are enough colors defined + while (m_tool_colors.size() < std::max(1, gcode_result.extruders_count)) { + m_tool_colors.push_back(Default_Tool_Color); + } + + static unsigned int last_result_id = 0; + if (last_result_id == gcode_result.id) + return; + + last_result_id = gcode_result.id; + + m_cog_marker.reset(); + + std::vector extended_moves; + extended_moves.reserve(2 * gcode_result.moves.size()); + // to be able to properly detect the start/end of a path we add some 'phantom' vertex + for (size_t i = 1; i < gcode_result.moves.size(); ++i) { + const Slic3r::GCodeProcessorResult::MoveVertex& curr = gcode_result.moves[i]; + const Slic3r::GCodeProcessorResult::MoveVertex& prev = gcode_result.moves[i - 1]; + const EMoveType curr_type = static_cast(valueof(curr.type)); + const EGCodeExtrusionRole curr_role = static_cast(valueof(curr.extrusion_role)); + + if (type_to_option(curr_type) == EOptionType::COUNT) { + if (prev.type != curr.type) { + Slic3r::GCodeProcessorResult::MoveVertex& m = extended_moves.emplace_back(curr); + m.position = prev.position; + } + } + extended_moves.emplace_back(curr); + + if (curr_type == EMoveType::Extrude && + curr_role != EGCodeExtrusionRole::Skirt && + curr_role != EGCodeExtrusionRole::SupportMaterial && + curr_role != EGCodeExtrusionRole::SupportMaterialInterface && + curr_role != EGCodeExtrusionRole::WipeTower && + curr_role != EGCodeExtrusionRole::Custom) { + const Vec3f curr_pos = toVec3f(curr.position); + const Vec3f prev_pos = toVec3f(prev.position); + m_cog_marker.update(0.5f * (curr_pos + prev_pos), curr.mm3_per_mm * length(curr_pos - prev_pos)); + } + } + extended_moves.shrink_to_fit(); + + reset(); + + m_vertices.reserve(extended_moves.size()); + m_valid_lines_bitset = BitSet<>(extended_moves.size()); + m_valid_lines_bitset.setAll(); + + // buffers to send to gpu + std::vector positions; + std::vector heights_widths_angles; + positions.reserve(extended_moves.size()); + heights_widths_angles.reserve(extended_moves.size()); + for (size_t i = 0; i < extended_moves.size(); ++i) { + const auto& m = extended_moves[i]; + const EMoveType move_type = static_cast(valueof(m.type)); + + const bool prev_line_valid = i > 0 && m_valid_lines_bitset[i - 1]; + const Vec3f prev_line = prev_line_valid ? toVec3f(m.position - extended_moves[i - 1].position) : toVec3f(0.0f); + + const bool this_line_valid = i + 1 < extended_moves.size() && + extended_moves[i + 1].position != m.position && + extended_moves[i + 1].type == m.type && + move_type != EMoveType::Seam; + const Vec3f this_line = this_line_valid ? toVec3f(extended_moves[i + 1].position - m.position) : toVec3f(0.0f); + + if (this_line_valid) { + // there is a valid path between point i and i+1. + } + else { + // the connection is invalid, there should be no line rendered, ever + m_valid_lines_bitset.reset(i); + } + + EGCodeExtrusionRole extrusion_role; + if (move_type == EMoveType::Travel) { + // for travel moves set the extrusion role + // which will be used later to select the proper color + if (m.delta_extruder == 0.0f) + extrusion_role = static_cast(0); // Move + else if (m.delta_extruder > 0.0f) + extrusion_role = static_cast(1); // Extrude + else + extrusion_role = static_cast(2); // Retract + } + else + extrusion_role = static_cast(m.extrusion_role); + + float width; + float height; + switch (move_type) + { + case EMoveType::Travel: { width = TRAVEL_RADIUS; height = TRAVEL_RADIUS; break; } + case EMoveType::Wipe: { width = WIPE_RADIUS; height = WIPE_RADIUS; break; } + default: { width = m.width; height = m.height; break; } + } + + Vec3f position = { m.position.x(), m.position.y(), m.position.z() }; + m_vertices.emplace_back(position, height, width, m.feedrate, m.fan_speed, m.temperature, m.volumetric_rate(), + extrusion_role, move_type, static_cast(m.extruder_id), static_cast(m.cp_color_id), + static_cast(m.layer_id)); + + if (move_type == EMoveType::Extrude) + // push down extrusion vertices by half height to render them at the right z + position[2] -= 0.5 * m.height; + positions.emplace_back(position); + + const float angle = atan2(prev_line[0] * this_line[1] - prev_line[1] * this_line[0], dot(prev_line, this_line)); + heights_widths_angles.push_back({ height, width, angle }); + } + + if (!positions.empty()) { + int old_bound_texture = 0; + glsafe(glGetIntegerv(GL_TEXTURE_BINDING_BUFFER, &old_bound_texture)); + + // create and fill positions buffer + glsafe(glGenBuffers(1, &m_positions_buf_id)); + glsafe(glBindBuffer(GL_TEXTURE_BUFFER, m_positions_buf_id)); + glsafe(glBufferData(GL_TEXTURE_BUFFER, positions.size() * sizeof(Vec3f), positions.data(), GL_STATIC_DRAW)); + glsafe(glGenTextures(1, &m_positions_tex_id)); + glsafe(glBindTexture(GL_TEXTURE_BUFFER, m_positions_tex_id)); + + // create and fill height, width and angles buffer + glsafe(glGenBuffers(1, &m_heights_widths_angles_buf_id)); + glsafe(glBindBuffer(GL_TEXTURE_BUFFER, m_heights_widths_angles_buf_id)); + glsafe(glBufferData(GL_TEXTURE_BUFFER, heights_widths_angles.size() * sizeof(Vec3f), heights_widths_angles.data(), GL_STATIC_DRAW)); + glsafe(glGenTextures(1, &m_heights_widths_angles_tex_id)); + glsafe(glBindTexture(GL_TEXTURE_BUFFER, m_heights_widths_angles_tex_id)); + + // create (but do not fill) colors buffer (data is set in update_colors()) + glsafe(glGenBuffers(1, &m_colors_buf_id)); + glsafe(glBindBuffer(GL_TEXTURE_BUFFER, m_colors_buf_id)); + glsafe(glGenTextures(1, &m_colors_tex_id)); + glsafe(glBindTexture(GL_TEXTURE_BUFFER, m_colors_tex_id)); + + // create (but do not fill) enabled segments buffer (data is set in update_enabled_entities()) + glsafe(glGenBuffers(1, &m_enabled_segments_buf_id)); + glsafe(glBindBuffer(GL_TEXTURE_BUFFER, m_enabled_segments_buf_id)); + glsafe(glGenTextures(1, &m_enabled_segments_tex_id)); + glsafe(glBindTexture(GL_TEXTURE_BUFFER, m_enabled_segments_tex_id)); + + // create (but do not fill) enabled options buffer (data is set in update_enabled_entities()) + glsafe(glGenBuffers(1, &m_enabled_options_buf_id)); + glsafe(glBindBuffer(GL_TEXTURE_BUFFER, m_enabled_options_buf_id)); + glsafe(glGenTextures(1, &m_enabled_options_tex_id)); + glsafe(glBindTexture(GL_TEXTURE_BUFFER, m_enabled_options_tex_id)); + + glsafe(glBindBuffer(GL_TEXTURE_BUFFER, 0)); + glsafe(glBindTexture(GL_TEXTURE_BUFFER, old_bound_texture)); + } + + for (uint8_t i = 0; i < static_cast(ETimeMode::COUNT); ++i) { + if (i < gcode_result.print_statistics.modes.size()) + m_layers_times[i] = gcode_result.print_statistics.modes[i].layers_times; + } +} + +void Toolpaths::update_enabled_entities(const ViewRange& range, const Settings& settings) +{ + std::vector enabled_segments; + std::vector enabled_options; + + for (uint32_t i = range.get_current_min(); i < range.get_current_max(); i++) { + const PathVertex& v = m_vertices[i]; + + if (!m_valid_lines_bitset[i] && !v.is_option()) + continue; + if (v.is_travel()) { + if (!settings.options_visibility.at(EOptionType::Travels)) + continue; + } + else if (v.is_wipe()) { + if (!settings.options_visibility.at(EOptionType::Wipes)) + continue; + } + else if (v.is_option()) { + if (!settings.options_visibility.at(type_to_option(v.get_type()))) + continue; + } + else if (v.is_extrusion()) { + if (!settings.extrusion_roles_visibility.at(v.get_role())) + continue; + } + else + continue; + + if (v.is_option()) + enabled_options.push_back(i); + else + enabled_segments.push_back(i); + } + + m_enabled_segments_count = enabled_segments.size(); + m_enabled_options_count = enabled_options.size(); + +//################################################################################################################################ + // Debug + m_enabled_segments_range = (m_enabled_segments_count > 0) ? + std::make_pair((uint32_t)enabled_segments.front(), (uint32_t)enabled_segments.back()) : std::make_pair((uint32_t)0, (uint32_t)0); + m_enabled_options_range = (m_enabled_options_count > 0) ? + std::make_pair((uint32_t)enabled_options.front(), (uint32_t)enabled_options.back()) : std::make_pair((uint32_t)0, (uint32_t)0); +//################################################################################################################################ + + // update gpu buffer for enabled segments + assert(m_enabled_segments_buf_id > 0); + glsafe(glBindBuffer(GL_TEXTURE_BUFFER, m_enabled_segments_buf_id)); + if (!enabled_segments.empty()) + glsafe(glBufferData(GL_TEXTURE_BUFFER, enabled_segments.size() * sizeof(uint32_t), enabled_segments.data(), GL_STATIC_DRAW)); + else + glsafe(glBufferData(GL_TEXTURE_BUFFER, 0, nullptr, GL_STATIC_DRAW)); + + // update gpu buffer for enabled options + assert(m_enabled_options_buf_id > 0); + glsafe(glBindBuffer(GL_TEXTURE_BUFFER, m_enabled_options_buf_id)); + if (!enabled_options.empty()) + glsafe(glBufferData(GL_TEXTURE_BUFFER, enabled_options.size() * sizeof(uint32_t), enabled_options.data(), GL_STATIC_DRAW)); + else + glsafe(glBufferData(GL_TEXTURE_BUFFER, 0, nullptr, GL_STATIC_DRAW)); + + glsafe(glBindBuffer(GL_TEXTURE_BUFFER, 0)); +} + +static float encode_color(const Color& color) { + const int r = (int)(255.0f * color[0]); + const int g = (int)(255.0f * color[1]); + const int b = (int)(255.0f * color[2]); + const int i_color = r << 16 | g << 8 | b; + return float(i_color); +} + +void Toolpaths::update_colors(const Settings& settings) +{ + update_color_ranges(settings); + + std::vector colors(m_vertices.size()); + for (size_t i = 0; i < m_vertices.size(); i++) { + colors[i] = encode_color(select_color(m_vertices[i], settings)); + } + + // update gpu buffer for colors + assert(m_colors_buf_id > 0); + glsafe(glBindBuffer(GL_TEXTURE_BUFFER, m_colors_buf_id)); + glsafe(glBufferData(GL_TEXTURE_BUFFER, colors.size() * sizeof(float), colors.data(), GL_STATIC_DRAW)); + glsafe(glBindBuffer(GL_TEXTURE_BUFFER, 0)); +} + +void Toolpaths::render(const Mat4x4f& view_matrix, const Mat4x4f& projection_matrix, const Vec3f& camera_position, const Settings& settings) +{ + render_segments(view_matrix, projection_matrix, camera_position); + render_options(view_matrix, projection_matrix); + if (settings.options_visibility.at(EOptionType::ToolMarker)) + render_tool_marker(view_matrix, projection_matrix); + if (settings.options_visibility.at(EOptionType::CenterOfGravity)) + render_cog_marker(view_matrix, projection_matrix); +} + +const std::array, static_cast(ETimeMode::COUNT)>& Toolpaths::get_layers_times() const +{ + return m_layers_times; +} + +Vec3f Toolpaths::get_cog_marker_position() const +{ + return m_cog_marker.get_position(); +} + +float Toolpaths::get_cog_marker_scale_factor() const +{ + return m_cog_marker_scale_factor; +} + +const Vec3f& Toolpaths::get_tool_marker_position() const +{ + return m_tool_marker.get_position(); +} + +float Toolpaths::get_tool_marker_scale_factor() const +{ + return m_tool_marker_scale_factor; +} + +const Color& Toolpaths::get_tool_marker_color() const +{ + return m_tool_marker.get_color(); +} + +float Toolpaths::get_tool_marker_alpha() const +{ + return m_tool_marker.get_alpha(); +} + +void Toolpaths::set_cog_marker_scale_factor(float factor) +{ + m_cog_marker_scale_factor = std::max(factor, 0.001f); +} + +void Toolpaths::set_tool_marker_position(const Vec3f& position) +{ + m_tool_marker.set_position(position); +} + +void Toolpaths::set_tool_marker_scale_factor(float factor) +{ + m_tool_marker_scale_factor = std::max(factor, 0.001f); +} + +void Toolpaths::set_tool_marker_color(const Color& color) +{ + m_tool_marker.set_color(color); +} + +void Toolpaths::set_tool_marker_alpha(float alpha) +{ + m_tool_marker.set_alpha(alpha); +} + +//################################################################################################################################ +// Debug +size_t Toolpaths::get_vertices_count() const +{ + return m_vertices.size(); +} + +size_t Toolpaths::get_enabled_segments_count() const +{ + return m_enabled_segments_count; +} + +size_t Toolpaths::get_enabled_options_count() const +{ + return m_enabled_options_count; +} + +const std::pair& Toolpaths::get_enabled_segments_range() const +{ + return m_enabled_segments_range; +} + +const std::pair& Toolpaths::get_enabled_options_range() const +{ + return m_enabled_options_range; +} + +const std::array& Toolpaths::get_height_range() const +{ + return m_height_range.get_range(); +} + +const std::array& Toolpaths::get_width_range() const +{ + return m_width_range.get_range(); +} + +const std::array& Toolpaths::get_speed_range() const +{ + return m_speed_range.get_range(); +} + +const std::array& Toolpaths::get_fan_speed_range() const +{ + return m_fan_speed_range.get_range(); +} + +const std::array& Toolpaths::get_temperature_range() const +{ + return m_temperature_range.get_range(); +} + +const std::array& Toolpaths::get_volumetric_rate_range() const +{ + return m_volumetric_rate_range.get_range(); +} + +const std::array& Toolpaths::get_layer_time_linear_range() const +{ + return m_layer_time_range[0].get_range(); +} + +const std::array& Toolpaths::get_layer_time_logarithmic_range() const +{ + return m_layer_time_range[1].get_range(); +} +//################################################################################################################################ + +static void delete_textures(unsigned int& id) +{ + if (id != 0) { + glsafe(glDeleteTextures(1, &id)); + id = 0; + } +} + +static void delete_buffers(unsigned int& id) +{ + if (id != 0) { + glsafe(glDeleteBuffers(1, &id)); + id = 0; + } +} + +void Toolpaths::reset() +{ + m_vertices.clear(); + m_valid_lines_bitset.clear(); + + m_layers_times = std::array, (uint8_t)ETimeMode::COUNT>(); + + delete_textures(m_enabled_options_tex_id); + delete_buffers(m_enabled_options_buf_id); + + delete_textures(m_enabled_segments_tex_id); + delete_buffers(m_enabled_segments_buf_id); + + delete_textures(m_colors_tex_id); + delete_buffers(m_colors_buf_id); + + delete_textures(m_heights_widths_angles_tex_id); + delete_buffers(m_heights_widths_angles_buf_id); + + delete_textures(m_positions_tex_id); + delete_buffers(m_positions_buf_id); +} + +void Toolpaths::update_color_ranges(const Settings& settings) +{ + m_width_range.reset(); + m_height_range.reset(); + m_speed_range.reset(); + m_fan_speed_range.reset(); + m_temperature_range.reset(); + m_volumetric_rate_range.reset(); + m_layer_time_range[0].reset(); // ColorRange::EType::Linear + m_layer_time_range[1].reset(); // ColorRange::EType::Logarithmic + + for (size_t i = 0; i < m_vertices.size(); i++) { + const PathVertex& v = m_vertices[i]; + if (v.is_extrusion()) { + m_height_range.update(round_to_bin(v.get_height())); + if (!v.is_custom_gcode() || settings.extrusion_roles_visibility.at(EGCodeExtrusionRole::Custom)) { + m_width_range.update(round_to_bin(v.get_width())); + m_volumetric_rate_range.update(round_to_bin(v.get_volumetric_rate())); + } + m_fan_speed_range.update(v.get_fan_speed()); + m_temperature_range.update(v.get_temperature()); + } + if ((v.is_travel() && settings.options_visibility.at(EOptionType::Travels)) || v.is_extrusion()) + m_speed_range.update(v.get_feedrate()); + } + + for (size_t i = 0; i < m_layers_times.size(); ++i) { + for (const float time : m_layers_times[static_cast(settings.time_mode)]) { + m_layer_time_range[i].update(time); + } + } +} + +Color Toolpaths::select_color(const PathVertex& v, const Settings& settings) const +{ + if (v.get_type() == EMoveType::Noop) + return Dummy_Color; + + if (v.is_wipe()) + return Wipe_Color; + + if (v.is_option()) + return Options_Colors.at(v.get_type()); + + const unsigned int role = (unsigned int)v.get_role(); + switch (settings.view_type) + { + case EViewType::FeatureType: + { + assert((v.is_travel() && role < Travels_Colors.size()) || (v.is_extrusion() && role < Extrusion_Roles_Colors.size())); + return v.is_travel() ? Travels_Colors[role] : Extrusion_Roles_Colors[role]; + } + case EViewType::Height: + { + assert(!v.is_travel() || role < Travels_Colors.size()); + return v.is_travel() ? Travels_Colors[role] : m_height_range.get_color_at(v.get_height()); + } + case EViewType::Width: + { + assert(!v.is_travel() || role < Travels_Colors.size()); + return v.is_travel() ? Travels_Colors[role] : m_width_range.get_color_at(v.get_width()); + } + case EViewType::Speed: + { + return m_speed_range.get_color_at(v.get_feedrate()); + } + case EViewType::FanSpeed: + { + assert(!v.is_travel() || role < Travels_Colors.size()); + return v.is_travel() ? Travels_Colors[role] : m_fan_speed_range.get_color_at(v.get_fan_speed()); + } + case EViewType::Temperature: + { + assert(!v.is_travel() || role < Travels_Colors.size()); + return v.is_travel() ? Travels_Colors[role] : m_temperature_range.get_color_at(v.get_temperature()); + } + case EViewType::VolumetricFlowRate: + { + assert(!v.is_travel() || role < Travels_Colors.size()); + return v.is_travel() ? Travels_Colors[role] : m_volumetric_rate_range.get_color_at(v.get_volumetric_rate()); + } + case EViewType::LayerTimeLinear: + { + assert(!v.is_travel() || role < Travels_Colors.size()); + return v.is_travel() ? Travels_Colors[role] : m_layer_time_range[0].get_color_at(m_layers_times[static_cast(settings.time_mode)][v.get_layer_id()]); + } + case EViewType::LayerTimeLogarithmic: + { + assert(!v.is_travel() || role < Travels_Colors.size()); + return v.is_travel() ? Travels_Colors[role] : m_layer_time_range[1].get_color_at(m_layers_times[static_cast(settings.time_mode)][v.get_layer_id()]); + } + case EViewType::Tool: + { + assert(v.get_extruder_id() < m_tool_colors.size()); + return m_tool_colors[v.get_extruder_id()]; + } + case EViewType::ColorPrint: + { + return m_tool_colors[v.get_color_id() % m_tool_colors.size()]; + } + } + + return Dummy_Color; +} + +void Toolpaths::render_segments(const Mat4x4f& view_matrix, const Mat4x4f& projection_matrix, const Vec3f& camera_position) +{ + if (m_segments_shader_id == 0) + return; + + int curr_active_texture = 0; + glsafe(glGetIntegerv(GL_ACTIVE_TEXTURE, &curr_active_texture)); + int curr_bound_texture = 0; + glsafe(glGetIntegerv(GL_TEXTURE_BINDING_BUFFER, &curr_bound_texture)); + int curr_shader; + glsafe(glGetIntegerv(GL_CURRENT_PROGRAM, &curr_shader)); + const bool curr_cull_face = glIsEnabled(GL_CULL_FACE); + glcheck(); + + glsafe(glActiveTexture(GL_TEXTURE0)); + glsafe(glBindTexture(GL_TEXTURE_BUFFER, m_positions_tex_id)); + glsafe(glTexBuffer(GL_TEXTURE_BUFFER, GL_RGB32F, m_positions_buf_id)); + + glsafe(glActiveTexture(GL_TEXTURE1)); + glsafe(glBindTexture(GL_TEXTURE_BUFFER, m_heights_widths_angles_tex_id)); + glsafe(glTexBuffer(GL_TEXTURE_BUFFER, GL_RGB32F, m_heights_widths_angles_buf_id)); + + glsafe(glActiveTexture(GL_TEXTURE2)); + glsafe(glBindTexture(GL_TEXTURE_BUFFER, m_colors_tex_id)); + glsafe(glTexBuffer(GL_TEXTURE_BUFFER, GL_R32F, m_colors_buf_id)); + + glsafe(glActiveTexture(GL_TEXTURE3)); + glsafe(glBindTexture(GL_TEXTURE_BUFFER, m_enabled_segments_tex_id)); + glsafe(glTexBuffer(GL_TEXTURE_BUFFER, GL_R32UI, m_enabled_segments_buf_id)); + + glsafe(glUseProgram(m_segments_shader_id)); + + glsafe(glUniform1i(m_uni_segments_positions_tex_id, 0)); + glsafe(glUniform1i(m_uni_segments_height_width_angle_tex_id, 1)); + glsafe(glUniform1i(m_uni_segments_colors_tex_id, 2)); + glsafe(glUniform1i(m_uni_segments_segment_index_tex_id, 3)); + glsafe(glUniformMatrix4fv(m_uni_segments_view_matrix_id, 1, GL_FALSE, view_matrix.data())); + glsafe(glUniformMatrix4fv(m_uni_segments_projection_matrix_id, 1, GL_FALSE, projection_matrix.data())); + glsafe(glUniform3fv(m_uni_segments_camera_position_id, 1, camera_position.data())); + + glsafe(glDisable(GL_CULL_FACE)); + + m_segment_template.render(m_enabled_segments_count); + + if (curr_cull_face) + glsafe(glEnable(GL_CULL_FACE)); + + glsafe(glUseProgram(curr_shader)); + glsafe(glBindTexture(GL_TEXTURE_BUFFER, curr_bound_texture)); + glsafe(glActiveTexture(curr_active_texture)); +} + +void Toolpaths::render_options(const Mat4x4f& view_matrix, const Mat4x4f& projection_matrix) +{ + if (m_options_shader_id == 0) + return; + + int curr_active_texture = 0; + glsafe(glGetIntegerv(GL_ACTIVE_TEXTURE, &curr_active_texture)); + int curr_bound_texture = 0; + glsafe(glGetIntegerv(GL_TEXTURE_BINDING_BUFFER, &curr_bound_texture)); + int curr_shader; + glsafe(glGetIntegerv(GL_CURRENT_PROGRAM, &curr_shader)); + const bool curr_cull_face = glIsEnabled(GL_CULL_FACE); + glcheck(); + + glsafe(glActiveTexture(GL_TEXTURE0)); + glsafe(glBindTexture(GL_TEXTURE_BUFFER, m_positions_tex_id)); + glsafe(glTexBuffer(GL_TEXTURE_BUFFER, GL_RGB32F, m_positions_buf_id)); + + glsafe(glActiveTexture(GL_TEXTURE1)); + glsafe(glBindTexture(GL_TEXTURE_BUFFER, m_heights_widths_angles_tex_id)); + glsafe(glTexBuffer(GL_TEXTURE_BUFFER, GL_RGB32F, m_heights_widths_angles_buf_id)); + + glsafe(glActiveTexture(GL_TEXTURE2)); + glsafe(glBindTexture(GL_TEXTURE_BUFFER, m_colors_tex_id)); + glsafe(glTexBuffer(GL_TEXTURE_BUFFER, GL_R32F, m_colors_buf_id)); + + glsafe(glActiveTexture(GL_TEXTURE3)); + glsafe(glBindTexture(GL_TEXTURE_BUFFER, m_enabled_options_tex_id)); + glsafe(glTexBuffer(GL_TEXTURE_BUFFER, GL_R32UI, m_enabled_options_buf_id)); + + glsafe(glEnable(GL_CULL_FACE)); + + glsafe(glUseProgram(m_options_shader_id)); + + glsafe(glUniform1i(m_uni_options_positions_tex_id, 0)); + glsafe(glUniform1i(m_uni_options_height_width_angle_tex_id, 1)); + glsafe(glUniform1i(m_uni_options_colors_tex_id, 2)); + glsafe(glUniform1i(m_uni_options_segment_index_tex_id, 3)); + glsafe(glUniformMatrix4fv(m_uni_options_view_matrix_id, 1, GL_FALSE, view_matrix.data())); + glsafe(glUniformMatrix4fv(m_uni_options_projection_matrix_id, 1, GL_FALSE, projection_matrix.data())); + + m_option_template.render(m_enabled_options_count); + + if (!curr_cull_face) + glsafe(glDisable(GL_CULL_FACE)); + + glsafe(glUseProgram(curr_shader)); + glsafe(glBindTexture(GL_TEXTURE_BUFFER, curr_bound_texture)); + glsafe(glActiveTexture(curr_active_texture)); +} + +void Toolpaths::render_cog_marker(const Mat4x4f& view_matrix, const Mat4x4f& projection_matrix) +{ + if (m_cog_marker_shader_id == 0) + return; + + int curr_shader; + glsafe(glGetIntegerv(GL_CURRENT_PROGRAM, &curr_shader)); + const bool curr_cull_face = glIsEnabled(GL_CULL_FACE); + const bool curr_depth_test = glIsEnabled(GL_DEPTH_TEST); + glcheck(); + + glsafe(glEnable(GL_CULL_FACE)); + glsafe(glDisable(GL_DEPTH_TEST)); + + glsafe(glUseProgram(m_cog_marker_shader_id)); + + glsafe(glUniform3fv(m_uni_cog_marker_world_center_position, 1, m_cog_marker.get_position().data())); + glsafe(glUniform1f(m_uni_cog_marker_scale_factor, m_cog_marker_scale_factor)); + glsafe(glUniformMatrix4fv(m_uni_cog_marker_view_matrix, 1, GL_FALSE, view_matrix.data())); + glsafe(glUniformMatrix4fv(m_uni_cog_marker_projection_matrix, 1, GL_FALSE, projection_matrix.data())); + + m_cog_marker.render(); + + if (curr_depth_test) + glsafe(glEnable(GL_DEPTH_TEST)); + if (!curr_cull_face) + glsafe(glDisable(GL_CULL_FACE)); + + glsafe(glUseProgram(curr_shader)); +} + +void Toolpaths::render_tool_marker(const Mat4x4f& view_matrix, const Mat4x4f& projection_matrix) +{ + if (m_tool_marker_shader_id == 0) + return; + + int curr_shader; + glsafe(glGetIntegerv(GL_CURRENT_PROGRAM, &curr_shader)); + const bool curr_cull_face = glIsEnabled(GL_CULL_FACE); + int curr_depth_mask; + glsafe(glGetIntegerv(GL_DEPTH_WRITEMASK, &curr_depth_mask)); + const bool curr_blend = glIsEnabled(GL_BLEND); + glcheck(); + int curr_blend_func; + glsafe(glGetIntegerv(GL_BLEND_SRC_ALPHA, &curr_blend_func)); + + glsafe(glDisable(GL_CULL_FACE)); + glsafe(glDepthMask(GL_FALSE)); + glsafe(glEnable(GL_BLEND)); + glsafe(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); + + glsafe(glUseProgram(m_tool_marker_shader_id)); + + glsafe(glUniform3fv(m_uni_tool_marker_world_origin, 1, m_tool_marker.get_position().data())); + glsafe(glUniform1f(m_uni_tool_marker_scale_factor, m_tool_marker_scale_factor)); + glsafe(glUniformMatrix4fv(m_uni_tool_marker_view_matrix, 1, GL_FALSE, view_matrix.data())); + glsafe(glUniformMatrix4fv(m_uni_tool_marker_projection_matrix, 1, GL_FALSE, projection_matrix.data())); + const Color& color = m_tool_marker.get_color(); + glsafe(glUniform4f(m_uni_tool_marker_color_base, color[0], color[1], color[2], m_tool_marker.get_alpha())); + + m_tool_marker.render(); + + glsafe(glBlendFunc(GL_SRC_ALPHA, curr_blend_func)); + if (!curr_blend) + glsafe(glDisable(GL_BLEND)); + glsafe(glDepthMask(curr_depth_mask)); + if (!curr_cull_face) + glsafe(glEnable(GL_CULL_FACE)); + + glsafe(glUseProgram(curr_shader)); +} + +} // namespace libvgcode + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#endif // ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ diff --git a/src/slic3r/GUI/LibVGCode/Toolpaths.hpp b/src/slic3r/GUI/LibVGCode/Toolpaths.hpp new file mode 100644 index 0000000000..813e0a7d1f --- /dev/null +++ b/src/slic3r/GUI/LibVGCode/Toolpaths.hpp @@ -0,0 +1,262 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#ifndef VGCODE_TOOLPATHS_HPP +#define VGCODE_TOOLPATHS_HPP + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#if ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +#include "SegmentTemplate.hpp" +#include "OptionTemplate.hpp" +#include "PathVertex.hpp" +#include "Bitset.hpp" +#include "ColorRange.hpp" +#include "CogMarker.hpp" +#include "ToolMarker.hpp" +//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ +#include "Shell.hpp" +//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + +#include +#include + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +namespace Slic3r { +struct GCodeProcessorResult; +class Print; +} // namespace Slic3r +//################################################################################################################################ + +namespace libvgcode { + +class ViewRange; +struct Settings; + +class Toolpaths +{ +public: + Toolpaths() = default; + ~Toolpaths(); + Toolpaths(const Toolpaths& other) = delete; + Toolpaths(Toolpaths&& other) = delete; + Toolpaths& operator = (const Toolpaths& other) = delete; + Toolpaths& operator = (Toolpaths&& other) = delete; + + // + // Initialize shader, uniform indices and segment geometry + // + void init(); + + // + // Setup all the variables used for visualization and coloring of the toolpaths + // from the gcode moves contained in the given gcode_result, according to the setting + // contained in the given config. + // + void load(const Slic3r::GCodeProcessorResult& gcode_result, const Slic3r::Print& print, + const std::vector& str_tool_colors, const Settings& settings); + + // + // Update the visibility property of toolpaths + // + void update_enabled_entities(const ViewRange& range, const Settings& settings); + // + // Update the color of toolpaths + // + void update_colors(const Settings& settings); + + // + // Render the toolpaths + // + void render(const Mat4x4f& view_matrix, const Mat4x4f& projection_matrix, + const Vec3f& camera_position, const Settings& settings); + + // + // Properties getters + // + const std::array, static_cast(ETimeMode::COUNT)>& get_layers_times() const; + Vec3f get_cog_marker_position() const; + float get_cog_marker_scale_factor() const; + const Vec3f& get_tool_marker_position() const; + float get_tool_marker_scale_factor() const; + const Color& get_tool_marker_color() const; + float get_tool_marker_alpha() const; + + // + // Properties setters + // + void set_cog_marker_scale_factor(float factor); + void set_tool_marker_position(const Vec3f& position); + void set_tool_marker_scale_factor(float factor); + void set_tool_marker_color(const Color& color); + void set_tool_marker_alpha(float size); + +//################################################################################################################################ + // Debug + size_t get_vertices_count() const; + size_t get_enabled_segments_count() const; + size_t get_enabled_options_count() const; + const std::pair& get_enabled_segments_range() const; + const std::pair& get_enabled_options_range() const; + const std::array& get_height_range() const; + const std::array& get_width_range() const; + const std::array& get_speed_range() const; + const std::array& get_fan_speed_range() const; + const std::array& get_temperature_range() const; + const std::array& get_volumetric_rate_range() const; + const std::array& get_layer_time_linear_range() const; + const std::array& get_layer_time_logarithmic_range() const; +//################################################################################################################################ + +private: + // + // The OpenGL element used to represent all toolpath segments + // + SegmentTemplate m_segment_template; + + // + // The OpenGL element used to represent all option markers + // + OptionTemplate m_option_template; + + // + // The OpenGL element used to represent the center of gravity + // + CogMarker m_cog_marker; + float m_cog_marker_scale_factor{ 1.0f }; + + // + // The OpenGL element used to represent the tool nozzle + // + ToolMarker m_tool_marker; + float m_tool_marker_scale_factor{ 1.0f }; + +//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + std::vector m_shells; +//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + + // + // cpu buffer to store vertices + // + std::vector m_vertices; +//################################################################################################################################ + // Debug + std::pair m_enabled_segments_range{ 0, 0 }; + std::pair m_enabled_options_range{ 0, 0 }; +//################################################################################################################################ + + // + // Member variables used for toolpaths visibiliity + // + BitSet<> m_valid_lines_bitset; + size_t m_enabled_segments_count{ 0 }; + size_t m_enabled_options_count{ 0 }; + + // + // Member variables used for toolpaths coloring + // + ColorRange m_height_range; + ColorRange m_width_range; + ColorRange m_speed_range; + ColorRange m_fan_speed_range; + ColorRange m_temperature_range; + ColorRange m_volumetric_rate_range; + std::array(ColorRange::EType::COUNT)> m_layer_time_range{ + ColorRange(ColorRange::EType::Linear), ColorRange(ColorRange::EType::Logarithmic) + }; + std::array, static_cast(ETimeMode::COUNT)> m_layers_times; + std::vector m_tool_colors; + + // + // OpenGL shader ids + // + unsigned int m_segments_shader_id{ 0 }; + unsigned int m_options_shader_id{ 0 }; + unsigned int m_cog_marker_shader_id{ 0 }; + unsigned int m_tool_marker_shader_id{ 0 }; + + // + // Cache for OpenGL uniforms id for segments shader + // + int m_uni_segments_view_matrix_id{ -1 }; + int m_uni_segments_projection_matrix_id{ -1 }; + int m_uni_segments_camera_position_id{ -1 }; + int m_uni_segments_positions_tex_id{ -1 }; + int m_uni_segments_height_width_angle_tex_id{ -1 }; + int m_uni_segments_colors_tex_id{ -1 }; + int m_uni_segments_segment_index_tex_id{ -1 }; + + // + // Cache for OpenGL uniforms id for options shader + // + int m_uni_options_view_matrix_id{ -1 }; + int m_uni_options_projection_matrix_id{ -1 }; + int m_uni_options_positions_tex_id{ -1 }; + int m_uni_options_height_width_angle_tex_id{ -1 }; + int m_uni_options_colors_tex_id{ -1 }; + int m_uni_options_segment_index_tex_id{ -1 }; + + // + // Cache for OpenGL uniforms id for cog marker shader + // + int m_uni_cog_marker_world_center_position{ -1 }; + int m_uni_cog_marker_scale_factor{ -1 }; + int m_uni_cog_marker_view_matrix{ -1 }; + int m_uni_cog_marker_projection_matrix{ -1 }; + + // + // Cache for OpenGL uniforms id for tool marker shader + // + int m_uni_tool_marker_world_origin{ -1 }; + int m_uni_tool_marker_scale_factor{ -1 }; + int m_uni_tool_marker_view_matrix{ -1 }; + int m_uni_tool_marker_projection_matrix{ -1 }; + int m_uni_tool_marker_color_base{ -1 }; + + // + // gpu buffers to store positions + // + unsigned int m_positions_buf_id{ 0 }; + unsigned int m_positions_tex_id{ 0 }; + // + // gpu buffers to store heights, widths and angles + // + unsigned int m_heights_widths_angles_buf_id{ 0 }; + unsigned int m_heights_widths_angles_tex_id{ 0 }; + // + // gpu buffers to store colors + // + unsigned int m_colors_buf_id{ 0 }; + unsigned int m_colors_tex_id{ 0 }; + // + // gpu buffers to store enabled segments + // + unsigned int m_enabled_segments_buf_id{ 0 }; + unsigned int m_enabled_segments_tex_id{ 0 }; + // + // gpu buffers to store enabled options + // + unsigned int m_enabled_options_buf_id{ 0 }; + unsigned int m_enabled_options_tex_id{ 0 }; + + void reset(); + void update_color_ranges(const Settings& settings); + Color select_color(const PathVertex& v, const Settings& settings) const; + void render_segments(const Mat4x4f& view_matrix, const Mat4x4f& projection_matrix, const Vec3f& camera_position); + void render_options(const Mat4x4f& view_matrix, const Mat4x4f& projection_matrix); + void render_cog_marker(const Mat4x4f& view_matrix, const Mat4x4f& projection_matrix); + void render_tool_marker(const Mat4x4f& view_matrix, const Mat4x4f& projection_matrix); +}; + +} // namespace libvgcode + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#endif // ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +#endif // VGCODE_TOOLPATHS_HPP \ No newline at end of file diff --git a/src/slic3r/GUI/LibVGCode/Types.cpp b/src/slic3r/GUI/LibVGCode/Types.cpp new file mode 100644 index 0000000000..31036df968 --- /dev/null +++ b/src/slic3r/GUI/LibVGCode/Types.cpp @@ -0,0 +1,10 @@ +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#include "libslic3r/Technologies.hpp" +//################################################################################################################################ + +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#include "Types.hpp" diff --git a/src/slic3r/GUI/LibVGCode/Types.hpp b/src/slic3r/GUI/LibVGCode/Types.hpp new file mode 100644 index 0000000000..e662fb404b --- /dev/null +++ b/src/slic3r/GUI/LibVGCode/Types.hpp @@ -0,0 +1,183 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#ifndef VGCODE_TYPES_HPP +#define VGCODE_TYPES_HPP + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#if ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +#define LIBVGCODE_USE_EIGEN 1 +#if LIBVGCODE_USE_EIGEN +#include +#else +#include +#include +#endif // LIBVGCODE_USE_EIGEN + +namespace libvgcode { + +#if LIBVGCODE_USE_EIGEN +using Vec3f = Eigen::Matrix; +using Mat4x4f = Eigen::Matrix; + +static float dot(const Vec3f& v1, const Vec3f& v2) +{ + return v1.dot(v2); +} + +static Vec3f normalize(const Vec3f& v) +{ + return v.normalized(); +} + +static float length(const Vec3f& v) +{ + return v.norm(); +} +#else +using Vec3f = std::array; +using Mat4x4f = std::array; + +static float dot(const Vec3f& v1, const Vec3f& v2) +{ + return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]; +} + +static Vec3f normalize(const Vec3f& v) +{ + const float length = std::sqrt(dot(v, v)); + assert(length > 0.0f); + const float inv_length = 1.0f / length; + return { v[0] * inv_length, v[1] * inv_length, v[2] * inv_length }; +} + +static float length(const Vec3f& v) +{ + return std::sqrt(dot(v, v)); +} +#endif // LIBVGCODE_USE_EIGEN + +static_assert(sizeof(Vec3f) == 3 * sizeof(float)); + +static Vec3f toVec3f(float value) { return { value, value, value }; }; +static Vec3f toVec3f(float x, float y, float z) { return { x, y, z }; }; + +static bool operator == (const Vec3f& v1, const Vec3f& v2) { + return v1[0] == v2[0] && v1[1] == v2[1] && v1[2] == v2[2]; +} + +static bool operator != (const Vec3f& v1, const Vec3f& v2) { + return v1[0] != v2[0] || v1[1] != v2[1] || v1[2] != v2[2]; +} + +static Vec3f operator + (const Vec3f& v1, const Vec3f& v2) { + return { v1[0] + v2[0], v1[1] + v2[1], v1[2] + v2[2] }; +} + +static Vec3f operator - (const Vec3f& v1, const Vec3f& v2) { + return { v1[0] - v2[0], v1[1] - v2[1], v1[2] - v2[2] }; +} + +static Vec3f operator * (float f, const Vec3f& v) { + return { f * v[0], f * v[1], f * v[2] }; +} + +using Color = std::array; + +static constexpr float PI = 3.141592f; + +// Alias for GCodeViewer::EViewType defined into GCodeViewer.hpp +enum class EViewType : uint8_t +{ + FeatureType, + Height, + Width, + Speed, + FanSpeed, + Temperature, + VolumetricFlowRate, + LayerTimeLinear, + LayerTimeLogarithmic, + Tool, + ColorPrint +}; + +// Alias for EMoveType defined into GCodeProcessor.hpp +enum class EMoveType : uint8_t +{ + Noop, + Retract, + Unretract, + Seam, + ToolChange, + ColorChange, + PausePrint, + CustomGCode, + Travel, + Wipe, + Extrude +}; + +// Alias for GCodeExtrusionRole defined into ExtrusionRole.hpp +enum class EGCodeExtrusionRole : uint8_t +{ + None, + Perimeter, + ExternalPerimeter, + OverhangPerimeter, + InternalInfill, + SolidInfill, + TopSolidInfill, + Ironing, + BridgeInfill, + GapFill, + Skirt, + SupportMaterial, + SupportMaterialInterface, + WipeTower, + Custom +}; + +// Alias for Preview::OptionType defined into GUI_Preview.hpp +enum class EOptionType : uint8_t +{ + Travels, + Wipes, + Retractions, + Unretractions, + Seams, + ToolChanges, + ColorChanges, + PausePrints, + CustomGCodes, + CenterOfGravity, + Shells, + ToolMarker, + COUNT +}; + +// Alias for PrintEstimatedStatistics::ETimeMode defined into GCodeProcessor.hpp +enum class ETimeMode : uint8_t +{ + Normal, + Stealth, + COUNT +}; + +static uint8_t valueof(EMoveType type) +{ + return static_cast(type); +} + +} // namespace libvgcode + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#endif // ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +#endif // VGCODE_TYPES_HPP \ No newline at end of file diff --git a/src/slic3r/GUI/LibVGCode/Utils.cpp b/src/slic3r/GUI/LibVGCode/Utils.cpp new file mode 100644 index 0000000000..83db777bf1 --- /dev/null +++ b/src/slic3r/GUI/LibVGCode/Utils.cpp @@ -0,0 +1,41 @@ +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#include "libslic3r/Technologies.hpp" +//################################################################################################################################ + +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966 +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#include "Utils.hpp" + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#if ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +namespace libvgcode { + +void add_vertex(const Vec3f& position, const Vec3f& normal, std::vector& vertices) +{ + vertices.emplace_back(position[0]); + vertices.emplace_back(position[1]); + vertices.emplace_back(position[2]); + vertices.emplace_back(normal[0]); + vertices.emplace_back(normal[1]); + vertices.emplace_back(normal[2]); +} + +void add_triangle(uint16_t v1, uint16_t v2, uint16_t v3, std::vector& indices) +{ + indices.emplace_back(v1); + indices.emplace_back(v2); + indices.emplace_back(v3); +} + +} // namespace libvgcode + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#endif // ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ diff --git a/src/slic3r/GUI/LibVGCode/Utils.hpp b/src/slic3r/GUI/LibVGCode/Utils.hpp new file mode 100644 index 0000000000..5da0ee56fe --- /dev/null +++ b/src/slic3r/GUI/LibVGCode/Utils.hpp @@ -0,0 +1,30 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966 +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#ifndef VGCODE_UTILS_HPP +#define VGCODE_UTILS_HPP + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#if ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +#include "Types.hpp" + +#include +#include + +namespace libvgcode { + +extern void add_vertex(const Vec3f& position, const Vec3f& normal, std::vector& vertices); +extern void add_triangle(uint16_t v1, uint16_t v2, uint16_t v3, std::vector& indices); + +} // namespace libvgcode + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#endif // ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +#endif // VGCODE_UTILS_HPP \ No newline at end of file diff --git a/src/slic3r/GUI/LibVGCode/ViewRange.cpp b/src/slic3r/GUI/LibVGCode/ViewRange.cpp new file mode 100644 index 0000000000..d7926c1bc2 --- /dev/null +++ b/src/slic3r/GUI/LibVGCode/ViewRange.cpp @@ -0,0 +1,73 @@ +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#include "libslic3r/Technologies.hpp" +//################################################################################################################################ + +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#include "ViewRange.hpp" + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#if ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +#include +#include + +namespace libvgcode { + +size_t ViewRange::get_current_min() const +{ + return m_current[0]; +} + +size_t ViewRange::get_current_max() const +{ + return m_current[1]; +} + +const std::array& ViewRange::get_current_range() const +{ + return m_current; +} + +void ViewRange::set_current_range(size_t min, size_t max) +{ + assert(min <= max); + m_current[0] = std::clamp(min, m_global[0], m_global[1]); + m_current[1] = std::clamp(max, m_global[0], m_global[1]); +} + +size_t ViewRange::get_global_min() const +{ + return m_global[0]; +} + +size_t ViewRange::get_global_max() const +{ + return m_global[1]; +} + +const std::array& ViewRange::get_global_range() const +{ + return m_global; +} + +void ViewRange::set_global_range(size_t min, size_t max) +{ + assert(min <= max); + m_global[0] = min; + m_global[1] = max; + m_current[0] = std::clamp(m_current[0], m_global[0], m_global[1]); + m_current[1] = std::clamp(m_current[1], m_global[0], m_global[1]); +} + +} // namespace libvgcode + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#endif // ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ diff --git a/src/slic3r/GUI/LibVGCode/ViewRange.hpp b/src/slic3r/GUI/LibVGCode/ViewRange.hpp new file mode 100644 index 0000000000..ecc08008ef --- /dev/null +++ b/src/slic3r/GUI/LibVGCode/ViewRange.hpp @@ -0,0 +1,44 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#ifndef VGCODE_VIEWRANGE_HPP +#define VGCODE_VIEWRANGE_HPP + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#if ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +#include + +namespace libvgcode { + +class ViewRange +{ +public: + size_t get_current_min() const; + size_t get_current_max() const; + + const std::array& get_current_range() const; + void set_current_range(size_t min, size_t max); + + size_t get_global_min() const; + size_t get_global_max() const; + + const std::array& get_global_range() const; + void set_global_range(size_t min, size_t max); + +private: + std::array m_current{ 0, 0 }; + std::array m_global{ 0, 0 }; +}; + +} // namespace libvgcode + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#endif // ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +#endif // VGCODE_VIEWRANGE_HPP \ No newline at end of file diff --git a/src/slic3r/GUI/LibVGCode/Viewer.cpp b/src/slic3r/GUI/LibVGCode/Viewer.cpp new file mode 100644 index 0000000000..decedc0a80 --- /dev/null +++ b/src/slic3r/GUI/LibVGCode/Viewer.cpp @@ -0,0 +1,395 @@ +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#include "libslic3r/Technologies.hpp" +//################################################################################################################################ + +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak, Oleksandra Iushchenko @YuSanka +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#include "Viewer.hpp" + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#if ENABLE_NEW_GCODE_VIEWER + +#include "libslic3r/GCode/GCodeProcessor.hpp" +#include "slic3r/GUI/GUI_App.hpp" +#include "slic3r/GUI/ImGuiWrapper.hpp" +//################################################################################################################################ + +#include + +namespace libvgcode { + +static std::string short_time(const std::string& time) +{ + // Parse the dhms time format. + int days = 0; + int hours = 0; + int minutes = 0; + int seconds = 0; + if (time.find('d') != std::string::npos) + sscanf(time.c_str(), "%dd %dh %dm %ds", &days, &hours, &minutes, &seconds); + else if (time.find('h') != std::string::npos) + sscanf(time.c_str(), "%dh %dm %ds", &hours, &minutes, &seconds); + else if (time.find('m') != std::string::npos) + sscanf(time.c_str(), "%dm %ds", &minutes, &seconds); + else if (time.find('s') != std::string::npos) + sscanf(time.c_str(), "%ds", &seconds); + + // Round to full minutes. + if (days + hours + minutes > 0 && seconds >= 30) { + if (++minutes == 60) { + minutes = 0; + if (++hours == 24) { + hours = 0; + ++days; + } + } + } + + // Format the dhm time + char buffer[64]; + if (days > 0) + sprintf(buffer, "%dd%dh%dm", days, hours, minutes); + else if (hours > 0) + sprintf(buffer, "%dh%dm", hours, minutes); + else if (minutes > 0) + sprintf(buffer, "%dm", minutes); + else + sprintf(buffer, "%ds", seconds); + return buffer; +} + +// Returns the given time is seconds in format DDd HHh MMm SSs +inline std::string get_time_dhms(float time_in_secs) +{ + int days = (int)(time_in_secs / 86400.0f); + time_in_secs -= (float)days * 86400.0f; + int hours = (int)(time_in_secs / 3600.0f); + time_in_secs -= (float)hours * 3600.0f; + int minutes = (int)(time_in_secs / 60.0f); + time_in_secs -= (float)minutes * 60.0f; + + char buffer[64]; + if (days > 0) + sprintf(buffer, "%dd %dh %dm %ds", days, hours, minutes, (int)time_in_secs); + else if (hours > 0) + sprintf(buffer, "%dh %dm %ds", hours, minutes, (int)time_in_secs); + else if (minutes > 0) + sprintf(buffer, "%dm %ds", minutes, (int)time_in_secs); + else + sprintf(buffer, "%ds", (int)std::round(time_in_secs)); + + return buffer; +} + +void Viewer::init() +{ + m_toolpaths.init(); +} + +void Viewer::load(const Slic3r::GCodeProcessorResult& gcode_result, const Slic3r::Print& print, const std::vector& str_tool_colors) +{ + if (m_settings.time_mode != ETimeMode::Normal) { + const Slic3r::PrintEstimatedStatistics& stats = gcode_result.print_statistics; + bool force_normal_mode = static_cast(m_settings.time_mode) >= stats.modes.size(); + if (!force_normal_mode) { + const float normal_time = stats.modes[static_cast(ETimeMode::Normal)].time; + const float mode_time = stats.modes[static_cast(m_settings.time_mode)].time; + force_normal_mode = mode_time == 0.0f || + short_time(get_time_dhms(mode_time)) == short_time(get_time_dhms(normal_time)); // TO CHECK -> Is this necessary ? + } + if (force_normal_mode) + m_settings.time_mode = ETimeMode::Normal; + } + + m_toolpaths.load(gcode_result, print, str_tool_colors, m_settings); + m_view_range.set_global_range(0, m_toolpaths.get_vertices_count() - 1); + m_settings.update_colors = true; +} + +void Viewer::render(const Mat4x4f& view_matrix, const Mat4x4f& projection_matrix, const Vec3f& camera_position) +{ + if (m_settings.update_enabled_entities) { + m_toolpaths.update_enabled_entities(m_view_range, m_settings); + m_settings.update_enabled_entities = false; + } + + if (m_settings.update_colors) { + m_toolpaths.update_colors(m_settings); + m_settings.update_colors = false; + } + + m_toolpaths.render(view_matrix, projection_matrix, camera_position, m_settings); + +//################################################################################################################################ + // Debug + render_debug_window(); +//################################################################################################################################ +} + +EViewType Viewer::get_view_type() const +{ + return m_settings.view_type; +} + +void Viewer::set_view_type(EViewType type) +{ + m_settings.view_type = type; + m_settings.update_colors = true; +} + +ETimeMode Viewer::get_time_mode() const +{ + return m_settings.time_mode; +} + +void Viewer::set_time_mode(ETimeMode mode) +{ + m_settings.time_mode = mode; + m_settings.update_colors = true; +} + +const std::array, static_cast(ETimeMode::COUNT)>& Viewer::get_layers_times() const +{ + return m_toolpaths.get_layers_times(); +} + +bool Viewer::is_option_visible(EOptionType type) const +{ + try + { + return m_settings.options_visibility.at(type); + } + catch (...) + { + return false; + } +} + +void Viewer::toggle_option_visibility(EOptionType type) +{ + try + { + bool& value = m_settings.options_visibility.at(type); + value = !value; + m_settings.update_enabled_entities = true; + m_settings.update_colors = true; + } + catch (...) + { + // do nothing; + } +} + +bool Viewer::is_extrusion_role_visible(EGCodeExtrusionRole role) const +{ + try + { + return m_settings.extrusion_roles_visibility.at(role); + } + catch (...) + { + return false; + } +} + +void Viewer::toggle_extrusion_role_visibility(EGCodeExtrusionRole role) +{ + try + { + bool& value = m_settings.extrusion_roles_visibility.at(role); + value = !value; + m_settings.update_enabled_entities = true; + m_settings.update_colors = true; + } + catch (...) + { + // do nothing; + } +} + +const std::array& Viewer::get_view_current_range() const +{ + return m_view_range.get_current_range(); +} + +const std::array& Viewer::get_view_global_range() const +{ + return m_view_range.get_global_range(); +} + +void Viewer::set_view_current_range(size_t min, size_t max) +{ + m_view_range.set_current_range(min, max); + m_settings.update_enabled_entities = true; +} + +Vec3f Viewer::get_cog_position() const +{ + return m_toolpaths.get_cog_marker_position(); +} + +float Viewer::get_cog_marker_scale_factor() const +{ + return m_toolpaths.get_cog_marker_scale_factor(); +} + +void Viewer::set_cog_marker_scale_factor(float factor) +{ + m_toolpaths.set_cog_marker_scale_factor(factor); +} + +const Vec3f& Viewer::get_tool_marker_position() const +{ + return m_toolpaths.get_tool_marker_position(); +} + +void Viewer::set_tool_marker_position(const Vec3f& position) +{ + m_toolpaths.set_tool_marker_position(position); +} + +float Viewer::get_tool_marker_scale_factor() const +{ + return m_toolpaths.get_tool_marker_scale_factor(); +} + +void Viewer::set_tool_marker_scale_factor(float factor) +{ + m_toolpaths.set_tool_marker_scale_factor(factor); +} + +const Color& Viewer::get_tool_marker_color() const +{ + return m_toolpaths.get_tool_marker_color(); +} + +void Viewer::set_tool_marker_color(const Color& color) +{ + m_toolpaths.set_tool_marker_color(color); +} + +float Viewer::get_tool_marker_alpha() const +{ + return m_toolpaths.get_tool_marker_alpha(); +} + +void Viewer::set_tool_marker_alpha(float alpha) +{ + m_toolpaths.set_tool_marker_alpha(alpha); +} + +//################################################################################################################################ +// Debug +void Viewer::render_debug_window() +{ + Slic3r::GUI::ImGuiWrapper& imgui = *Slic3r::GUI::wxGetApp().imgui(); + imgui.begin(std::string("LibVGCode Viewer Debug"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse); + + if (ImGui::BeginTable("Data", 2)) { + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + imgui.text_colored(Slic3r::GUI::ImGuiWrapper::COL_ORANGE_LIGHT, "# vertices"); + ImGui::TableSetColumnIndex(1); + imgui.text(std::to_string(m_toolpaths.get_vertices_count())); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + imgui.text_colored(Slic3r::GUI::ImGuiWrapper::COL_ORANGE_LIGHT, "# enabled lines"); + ImGui::TableSetColumnIndex(1); + const std::pair& enabled_segments_range = m_toolpaths.get_enabled_segments_range(); + imgui.text(std::to_string(m_toolpaths.get_enabled_segments_count()) + " [" + std::to_string(enabled_segments_range.first) + "-" + std::to_string(enabled_segments_range.second) + "]"); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + imgui.text_colored(Slic3r::GUI::ImGuiWrapper::COL_ORANGE_LIGHT, "# enabled options"); + ImGui::TableSetColumnIndex(1); + const std::pair& enabled_options_range = m_toolpaths.get_enabled_options_range(); + imgui.text(std::to_string(m_toolpaths.get_enabled_options_count()) + " [" + std::to_string(enabled_options_range.first) + "-" + std::to_string(enabled_options_range.second) + "]"); + + ImGui::Separator(); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + imgui.text_colored(Slic3r::GUI::ImGuiWrapper::COL_ORANGE_LIGHT, "sequential range"); + ImGui::TableSetColumnIndex(1); + imgui.text(std::to_string(m_view_range.get_current_min()) + " - " + std::to_string(m_view_range.get_current_max())); + + auto add_range_property_row = [&imgui](const std::string& label, const std::array& range) { + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + imgui.text_colored(Slic3r::GUI::ImGuiWrapper::COL_ORANGE_LIGHT, label); + ImGui::TableSetColumnIndex(1); + char buf[64]; + ::sprintf(buf, "%.3f - %.3f", range[0], range[1]); + imgui.text(buf); + }; + + add_range_property_row("height range", m_toolpaths.get_height_range()); + add_range_property_row("width range", m_toolpaths.get_width_range()); + add_range_property_row("speed range", m_toolpaths.get_speed_range()); + add_range_property_row("fan speed range", m_toolpaths.get_fan_speed_range()); + add_range_property_row("temperature range", m_toolpaths.get_temperature_range()); + add_range_property_row("volumetric rate range", m_toolpaths.get_volumetric_rate_range()); + add_range_property_row("layer time linear range", m_toolpaths.get_layer_time_linear_range()); + add_range_property_row("layer time logarithmic range", m_toolpaths.get_layer_time_logarithmic_range()); + + ImGui::EndTable(); + + ImGui::Separator(); + + if (ImGui::BeginTable("Cog", 2)) { + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + imgui.text_colored(Slic3r::GUI::ImGuiWrapper::COL_ORANGE_LIGHT, "Cog marker scale factor"); + ImGui::TableSetColumnIndex(1); + imgui.text(std::to_string(get_cog_marker_scale_factor())); + + ImGui::EndTable(); + } + + ImGui::Separator(); + + if (ImGui::BeginTable("Tool", 2)) { + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + imgui.text_colored(Slic3r::GUI::ImGuiWrapper::COL_ORANGE_LIGHT, "Tool marker scale factor"); + ImGui::TableSetColumnIndex(1); + imgui.text(std::to_string(get_tool_marker_scale_factor())); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + imgui.text_colored(Slic3r::GUI::ImGuiWrapper::COL_ORANGE_LIGHT, "Tool marker color"); + ImGui::TableSetColumnIndex(1); + Color color = get_tool_marker_color(); + if (ImGui::ColorPicker3("##ToolColor", color.data())) + set_tool_marker_color(color); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + imgui.text_colored(Slic3r::GUI::ImGuiWrapper::COL_ORANGE_LIGHT, "Tool marker alpha"); + ImGui::TableSetColumnIndex(1); + float tool_alpha = get_tool_marker_alpha(); + if (imgui.slider_float("##ToolAlpha", &tool_alpha, 0.25f, 0.75f)) + set_tool_marker_alpha(tool_alpha); + + ImGui::EndTable(); + } + } + + imgui.end(); +} +//################################################################################################################################ + +} // namespace libvgcode + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#endif // ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ diff --git a/src/slic3r/GUI/LibVGCode/Viewer.hpp b/src/slic3r/GUI/LibVGCode/Viewer.hpp new file mode 100644 index 0000000000..44eaf2faed --- /dev/null +++ b/src/slic3r/GUI/LibVGCode/Viewer.hpp @@ -0,0 +1,107 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#ifndef VGCODE_VIEWER_HPP +#define VGCODE_VIEWER_HPP + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#if ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +#include "Settings.hpp" +#include "Toolpaths.hpp" +#include "ViewRange.hpp" + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +namespace Slic3r { +struct GCodeProcessorResult; +class Print; +} // namespace Slic3r +//################################################################################################################################ + +namespace libvgcode { + +class Viewer +{ +public: + Viewer() = default; + ~Viewer() = default; + Viewer(const Viewer& other) = delete; + Viewer(Viewer&& other) = delete; + Viewer& operator = (const Viewer& other) = delete; + Viewer& operator = (Viewer&& other) = delete; + + void init(); + void load(const Slic3r::GCodeProcessorResult& gcode_result, const Slic3r::Print& print, const std::vector& str_tool_colors); + void render(const Mat4x4f& view_matrix, const Mat4x4f& projection_matrix, const Vec3f& camera_position); + + EViewType get_view_type() const; + void set_view_type(EViewType type); + + ETimeMode get_time_mode() const; + void set_time_mode(ETimeMode mode); + + const std::array, static_cast(ETimeMode::COUNT)>& get_layers_times() const; + + bool is_option_visible(EOptionType type) const; + void toggle_option_visibility(EOptionType type); + + bool is_extrusion_role_visible(EGCodeExtrusionRole role) const; + void toggle_extrusion_role_visibility(EGCodeExtrusionRole role); + + const std::array& get_view_current_range() const; + const std::array& get_view_global_range() const; + // + // min must be smaller than max + // values are clamped to the view global range + // + void set_view_current_range(size_t min, size_t max); + + // + // Returns the position of the center of gravity of the toolpaths. + // It does not take in account extrusions of type: + // Skirt + // Support Material + // Support Material Interface + // WipeTower + // Custom + // + Vec3f get_cog_position() const; + + float get_cog_marker_scale_factor() const; + void set_cog_marker_scale_factor(float factor); + + const Vec3f& get_tool_marker_position() const; + void set_tool_marker_position(const Vec3f& position); + + float get_tool_marker_scale_factor() const; + void set_tool_marker_scale_factor(float factor); + + const Color& get_tool_marker_color() const; + void set_tool_marker_color(const Color& color); + + float get_tool_marker_alpha() const; + void set_tool_marker_alpha(float alpha); + +private: + Settings m_settings; + Toolpaths m_toolpaths; + ViewRange m_view_range; + +//################################################################################################################################ + // Debug + void render_debug_window(); +//################################################################################################################################ +}; + +} // namespace libvgcode + +//################################################################################################################################ +// PrusaSlicer development only -> !!!TO BE REMOVED!!! +#endif // ENABLE_NEW_GCODE_VIEWER +//################################################################################################################################ + +#endif // VGCODE_VIEWER_HPP