From 66d43b882e75dbeba5f250c17f9240aceb536cee Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 4 Aug 2021 11:58:50 +0200 Subject: [PATCH 01/18] Fixed calls set_uniform(emission_factor, xx) to use floats --- src/slic3r/GUI/3DBed.cpp | 4 ++-- src/slic3r/GUI/GCodeViewer.cpp | 2 +- src/slic3r/GUI/GLCanvas3D.cpp | 2 +- src/slic3r/GUI/Gizmos/GLGizmoBase.cpp | 2 +- src/slic3r/GUI/Gizmos/GLGizmoCut.cpp | 2 +- src/slic3r/GUI/Gizmos/GLGizmoMove.cpp | 4 ++-- src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp | 2 +- src/slic3r/GUI/Gizmos/GLGizmoScale.cpp | 8 ++++---- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp | 4 ++-- src/slic3r/GUI/Selection.cpp | 2 +- 10 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/slic3r/GUI/3DBed.cpp b/src/slic3r/GUI/3DBed.cpp index d7fb937d0..7b08b5f79 100644 --- a/src/slic3r/GUI/3DBed.cpp +++ b/src/slic3r/GUI/3DBed.cpp @@ -119,7 +119,7 @@ void Bed3D::Axes::render() const glsafe(::glEnable(GL_DEPTH_TEST)); shader->start_using(); - shader->set_uniform("emission_factor", 0.0); + shader->set_uniform("emission_factor", 0.0f); // x axis const_cast(&m_arrow)->set_color(-1, { 0.75f, 0.0f, 0.0f, 1.0f }); @@ -498,7 +498,7 @@ void Bed3D::render_model() const GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); if (shader != nullptr) { shader->start_using(); - shader->set_uniform("emission_factor", 0.0); + shader->set_uniform("emission_factor", 0.0f); glsafe(::glPushMatrix()); glsafe(::glTranslated(m_model_offset.x(), m_model_offset.y(), m_model_offset.z())); model->render(); diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 090accb6a..b9a7d2338 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -223,7 +223,7 @@ void GCodeViewer::SequentialView::Marker::render() const glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); shader->start_using(); - shader->set_uniform("emission_factor", 0.0); + shader->set_uniform("emission_factor", 0.0f); glsafe(::glPushMatrix()); glsafe(::glMultMatrixf(m_world_transform.data())); diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index f366100ac..e2699fb6d 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -4148,7 +4148,7 @@ void GLCanvas3D::_render_thumbnail_internal(ThumbnailData& thumbnail_data, const glsafe(::glEnable(GL_DEPTH_TEST)); shader->start_using(); - shader->set_uniform("emission_factor", 0.0); + shader->set_uniform("emission_factor", 0.0f); for (GLVolume* vol : visible_volumes) { shader->set_uniform("uniform_color", (vol->printable && !vol->is_outside) ? orange : gray); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp index 92c03cb75..1177c46ca 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp @@ -183,7 +183,7 @@ void GLGizmoBase::render_grabbers(float size) const if (shader == nullptr) return; shader->start_using(); - shader->set_uniform("emission_factor", 0.1); + shader->set_uniform("emission_factor", 0.1f); for (int i = 0; i < (int)m_grabbers.size(); ++i) { if (m_grabbers[i].enabled) m_grabbers[i].render(m_hover_id == i, size); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index 707726e08..27b54c595 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -136,7 +136,7 @@ void GLGizmoCut::on_render() if (shader == nullptr) return; shader->start_using(); - shader->set_uniform("emission_factor", 0.1); + shader->set_uniform("emission_factor", 0.1f); m_grabbers[0].color = GrabberColor; m_grabbers[0].render(m_hover_id == 0, (float)((box.size().x() + box.size().y() + box.size().z()) / 3.0)); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp index 1211864eb..9a056adcb 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp @@ -141,7 +141,7 @@ void GLGizmoMove3D::on_render() GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); if (shader != nullptr) { shader->start_using(); - shader->set_uniform("emission_factor", 0.1); + shader->set_uniform("emission_factor", 0.1f); // draw grabber float mean_size = (float)((box.size().x() + box.size().y() + box.size().z()) / 3.0); m_grabbers[m_hover_id].render(true, mean_size); @@ -208,7 +208,7 @@ void GLGizmoMove3D::render_grabber_extension(Axis axis, const BoundingBoxf3& box const_cast(&m_vbo_cone)->set_color(-1, color); if (!picking) { shader->start_using(); - shader->set_uniform("emission_factor", 0.1); + shader->set_uniform("emission_factor", 0.1f); } glsafe(::glPushMatrix()); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp index a495db4f1..2e32a2568 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp @@ -339,7 +339,7 @@ void GLGizmoRotate::render_grabber_extension(const BoundingBoxf3& box, bool pick const_cast(&m_cone)->set_color(-1, color); if (!picking) { shader->start_using(); - shader->set_uniform("emission_factor", 0.1); + shader->set_uniform("emission_factor", 0.1f); } glsafe(::glPushMatrix()); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp b/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp index 849046962..894d844d8 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp @@ -236,7 +236,7 @@ void GLGizmoScale3D::on_render() GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); if (shader != nullptr) { shader->start_using(); - shader->set_uniform("emission_factor", 0.1); + shader->set_uniform("emission_factor", 0.1f); // draw grabbers m_grabbers[0].render(true, grabber_mean_size); m_grabbers[1].render(true, grabber_mean_size); @@ -251,7 +251,7 @@ void GLGizmoScale3D::on_render() GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); if (shader != nullptr) { shader->start_using(); - shader->set_uniform("emission_factor", 0.1); + shader->set_uniform("emission_factor", 0.1f); // draw grabbers m_grabbers[2].render(true, grabber_mean_size); m_grabbers[3].render(true, grabber_mean_size); @@ -266,7 +266,7 @@ void GLGizmoScale3D::on_render() GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); if (shader != nullptr) { shader->start_using(); - shader->set_uniform("emission_factor", 0.1); + shader->set_uniform("emission_factor", 0.1f); // draw grabbers m_grabbers[4].render(true, grabber_mean_size); m_grabbers[5].render(true, grabber_mean_size); @@ -284,7 +284,7 @@ void GLGizmoScale3D::on_render() GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); if (shader != nullptr) { shader->start_using(); - shader->set_uniform("emission_factor", 0.1); + shader->set_uniform("emission_factor", 0.1f); // draw grabbers for (int i = 6; i < 10; ++i) { m_grabbers[i].render(true, grabber_mean_size); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index fa61779ec..71607b351 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -169,7 +169,7 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) const_cast(&m_cone)->set_color(-1, render_color); const_cast(&m_sphere)->set_color(-1, render_color); if (shader && !picking) - shader->set_uniform("emission_factor", 0.5); + shader->set_uniform("emission_factor", 0.5f); // Inverse matrix of the instance scaling is applied so that the mark does not scale with the object. glsafe(::glPushMatrix()); @@ -224,7 +224,7 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) render_color[3] = 0.7f; const_cast(&m_cylinder)->set_color(-1, render_color); if (shader) - shader->set_uniform("emission_factor", 0.5); + shader->set_uniform("emission_factor", 0.5f); for (const sla::DrainHole& drain_hole : m_c->selection_info()->model_object()->sla_drain_holes) { if (is_mesh_point_clipped(drain_hole.pos.cast())) continue; diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index dbc259444..6a47113fa 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -1872,7 +1872,7 @@ void Selection::render_sidebar_scale_hints(const std::string& sidebar_field) con const_cast(&m_arrow)->set_color(-1, uniform_scale ? UNIFORM_SCALE_COLOR : get_color(axis)); GLShaderProgram* shader = wxGetApp().get_current_shader(); if (shader != nullptr) - shader->set_uniform("emission_factor", 0.0); + shader->set_uniform("emission_factor", 0.0f); glsafe(::glTranslated(0.0, 5.0, 0.0)); m_arrow.render(); From 599a4d97e38b0c7b50eeb4433b9f1ba007444d97 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 4 Aug 2021 12:47:36 +0200 Subject: [PATCH 02/18] Removed constness from a few renderXXX() methods --- src/slic3r/GUI/GCodeViewer.cpp | 40 ++++++++++++++++------------------ src/slic3r/GUI/GCodeViewer.hpp | 10 ++++----- src/slic3r/GUI/GLCanvas3D.cpp | 2 +- src/slic3r/GUI/GLCanvas3D.hpp | 2 +- 4 files changed, 26 insertions(+), 28 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index b9a7d2338..092ddbfd8 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -757,12 +757,12 @@ void GCodeViewer::reset() #endif // ENABLE_GCODE_VIEWER_STATISTICS } -void GCodeViewer::render() const +void GCodeViewer::render() { auto init_gl_data = [this]() { // initializes opengl data of TBuffers for (size_t i = 0; i < m_buffers.size(); ++i) { - TBuffer& buffer = const_cast(m_buffers[i]); + TBuffer& buffer = m_buffers[i]; switch (buffer_type(i)) { default: { break; } @@ -789,17 +789,17 @@ void GCodeViewer::render() const } // initializes tool marker - const_cast(&m_sequential_view)->marker.init(); + m_sequential_view.marker.init(); // initializes point sizes std::array point_sizes; ::glGetIntegerv(GL_ALIASED_POINT_SIZE_RANGE, point_sizes.data()); - *const_cast*>(&m_detected_point_sizes) = { static_cast(point_sizes[0]), static_cast(point_sizes[1]) }; - *const_cast(&m_gl_data_initialized) = true; + m_detected_point_sizes = { static_cast(point_sizes[0]), static_cast(point_sizes[1]) }; + m_gl_data_initialized = true; }; #if ENABLE_GCODE_VIEWER_STATISTICS - const_cast(&m_statistics)->reset_opengl(); + m_statistics.reset_opengl(); #endif // ENABLE_GCODE_VIEWER_STATISTICS // OpenGL data must be initialized after the glContext has been created. @@ -815,10 +815,9 @@ void GCodeViewer::render() const render_shells(); float legend_height = 0.0f; render_legend(legend_height); - SequentialView* sequential_view = const_cast(&m_sequential_view); - if (sequential_view->current.last != sequential_view->endpoints.last) { - sequential_view->marker.set_world_position(sequential_view->current_position); - sequential_view->render(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.render(legend_height); } #if ENABLE_GCODE_VIEWER_STATISTICS render_statistics(); @@ -2360,7 +2359,7 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool #endif // ENABLE_GCODE_VIEWER_STATISTICS } -void GCodeViewer::render_toolpaths() const +void GCodeViewer::render_toolpaths() { #if ENABLE_FIXED_SCREEN_SIZE_POINT_MARKERS float point_size = 20.0f; @@ -2404,7 +2403,7 @@ void GCodeViewer::render_toolpaths() const set_uniform_color(path.color, shader); glsafe(::glMultiDrawElements(GL_POINTS, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_SHORT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); #if ENABLE_GCODE_VIEWER_STATISTICS - ++const_cast(&m_statistics)->gl_multi_points_calls_count; + ++m_statistics.gl_multi_points_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS } } @@ -2425,7 +2424,7 @@ void GCodeViewer::render_toolpaths() const set_uniform_color(path.color, shader); glsafe(::glMultiDrawElements(GL_LINES, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_SHORT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); #if ENABLE_GCODE_VIEWER_STATISTICS - ++const_cast(&m_statistics)->gl_multi_lines_calls_count; + ++m_statistics.gl_multi_lines_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS } } @@ -2442,7 +2441,7 @@ void GCodeViewer::render_toolpaths() const set_uniform_color(path.color, shader); glsafe(::glMultiDrawElements(GL_TRIANGLES, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_SHORT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); #if ENABLE_GCODE_VIEWER_STATISTICS - ++const_cast(&m_statistics)->gl_multi_triangles_calls_count; + ++m_statistics.gl_multi_triangles_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS } } @@ -2535,7 +2534,7 @@ void GCodeViewer::render_toolpaths() const glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); #if ENABLE_GCODE_VIEWER_STATISTICS - ++const_cast(&m_statistics)->gl_triangles_calls_count; + ++m_statistics.gl_triangles_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS if (has_normals) @@ -2554,7 +2553,7 @@ void GCodeViewer::render_toolpaths() const } } -void GCodeViewer::render_shells() const +void GCodeViewer::render_shells() { if (!m_shells.visible || m_shells.volumes.empty()) return; @@ -2572,7 +2571,7 @@ void GCodeViewer::render_shells() const // glsafe(::glDepthMask(GL_TRUE)); } -void GCodeViewer::render_legend(float& legend_height) const +void GCodeViewer::render_legend(float& legend_height) { if (!m_legend_enabled) return; @@ -2935,8 +2934,7 @@ void GCodeViewer::render_legend(float& legend_height) const const bool visible = is_visible(role); append_item(EItemType::Rect, Extrusion_Role_Colors[static_cast(role)], labels[i], visible, times[i], percents[i], max_percent, offsets, used_filaments_m[i], used_filaments_g[i], [this, role, visible]() { - Extrusions* extrusions = const_cast(&m_extrusions); - extrusions->role_visibility_flags = visible ? extrusions->role_visibility_flags & ~(1 << role) : extrusions->role_visibility_flags | (1 << role); + m_extrusions.role_visibility_flags = visible ? m_extrusions.role_visibility_flags & ~(1 << role) : m_extrusions.role_visibility_flags | (1 << role); // update buffers' render paths refresh_render_paths(false, false); wxGetApp().plater()->update_preview_moves_slider(); @@ -3408,7 +3406,7 @@ void GCodeViewer::render_legend(float& legend_height) const auto show_mode_button = [this, &imgui, can_show_mode_button](const wxString& label, PrintEstimatedStatistics::ETimeMode mode) { if (can_show_mode_button(mode)) { if (imgui.button(label)) { - *const_cast(&m_time_estimate_mode) = mode; + m_time_estimate_mode = mode; wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); wxGetApp().plater()->get_current_canvas3D()->request_extra_frame(); } @@ -3435,7 +3433,7 @@ void GCodeViewer::render_legend(float& legend_height) const } #if ENABLE_GCODE_VIEWER_STATISTICS -void GCodeViewer::render_statistics() const +void GCodeViewer::render_statistics() { static const float offset = 275.0f; diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 41307bad9..ecdffc5fe 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -632,7 +632,7 @@ public: void update_shells_color_by_extruder(const DynamicPrintConfig* config); void reset(); - void render() const; + void render(); bool has_data() const { return !m_roles.empty(); } bool can_export_toolpaths() const; @@ -678,11 +678,11 @@ private: void load_toolpaths(const GCodeProcessor::Result& gcode_result); void load_shells(const Print& print, bool initialized); void refresh_render_paths(bool keep_sequential_current_first, bool keep_sequential_current_last) const; - void render_toolpaths() const; - void render_shells() const; - void render_legend(float& legend_height) const; + void render_toolpaths(); + void render_shells(); + void render_legend(float& legend_height); #if ENABLE_GCODE_VIEWER_STATISTICS - void render_statistics() const; + void render_statistics(); #endif // ENABLE_GCODE_VIEWER_STATISTICS bool is_visible(ExtrusionRole role) const { return role < erCount && (m_extrusions.role_visibility_flags & (1 << role)) != 0; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index e2699fb6d..1e0cb0a32 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -5175,7 +5175,7 @@ void GLCanvas3D::_render_objects() m_camera_clipping_plane = ClippingPlane::ClipsNothing(); } -void GLCanvas3D::_render_gcode() const +void GLCanvas3D::_render_gcode() { m_gcode_viewer.render(); } diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index d9cd55e35..7cdaac1a6 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -906,7 +906,7 @@ private: #else void _render_objects(); #endif // ENABLE_DELAYED_TRANSPARENT_VOLUMES_RENDERING - void _render_gcode() const; + void _render_gcode(); void _render_selection() const; void _render_sequential_clearance(); #if ENABLE_RENDER_SELECTION_CENTER From 329f9a77c2084a815708492fd0a61ca963f63fce Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 4 Aug 2021 13:27:42 +0200 Subject: [PATCH 03/18] Colors defined as std::array in GCodeViewer --- src/slic3r/GUI/GCodeViewer.cpp | 165 +++++++++++++++++---------------- src/slic3r/GUI/GCodeViewer.hpp | 6 +- 2 files changed, 90 insertions(+), 81 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 092ddbfd8..055fb6fab 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -44,10 +44,10 @@ static EMoveType buffer_type(unsigned char id) { return static_cast(static_cast(EMoveType::Retract) + id); } -static std::array decode_color(const std::string& color) { +static std::array decode_color(const std::string& color) { static const float INV_255 = 1.0f / 255.0f; - std::array ret = { 0.0f, 0.0f, 0.0f }; + std::array ret = { 0.0f, 0.0f, 0.0f, 1.0f }; const char* c = color.data() + 1; if (color.size() == 7 && color.front() == '#') { for (size_t j = 0; j < 3; ++j) { @@ -62,8 +62,8 @@ static std::array decode_color(const std::string& color) { return ret; } -static std::vector> decode_colors(const std::vector& colors) { - std::vector> output(colors.size(), { 0.0f, 0.0f, 0.0f }); +static std::vector> decode_colors(const std::vector& colors) { + std::vector> output(colors.size(), { 0.0f, 0.0f, 0.0f, 1.0f }); for (size_t i = 0; i < colors.size(); ++i) { output[i] = decode_color(colors[i]); } @@ -176,7 +176,7 @@ GCodeViewer::Color GCodeViewer::Extrusions::Range::get_color_at(float value) con const float local_t = std::clamp(global_t - static_cast(color_low_idx), 0.0f, 1.0f); // Interpolate between the low and high colors to find exactly which color the input value should get - Color ret; + Color ret = { 0.0f, 0.0f, 0.0f, 1.0f }; for (unsigned int i = 0; i < 3; ++i) { ret[i] = lerp(Range_Colors[color_low_idx][i], Range_Colors[color_high_idx][i], local_t); } @@ -195,7 +195,7 @@ void GCodeViewer::SequentialRangeCap::reset() { buffer = nullptr; ibo = 0; vbo = 0; - color = { 0.0f, 0.0f, 0.0f }; + color = { 0.0f, 0.0f, 0.0f, 1.0f }; } void GCodeViewer::SequentialView::Marker::init() @@ -484,56 +484,57 @@ void GCodeViewer::SequentialView::render(float legend_height) const } const std::vector GCodeViewer::Extrusion_Role_Colors {{ - { 0.75f, 0.75f, 0.75f }, // erNone - { 1.00f, 0.90f, 0.30f }, // erPerimeter - { 1.00f, 0.49f, 0.22f }, // erExternalPerimeter - { 0.12f, 0.12f, 1.00f }, // erOverhangPerimeter - { 0.69f, 0.19f, 0.16f }, // erInternalInfill - { 0.59f, 0.33f, 0.80f }, // erSolidInfill - { 0.94f, 0.25f, 0.25f }, // erTopSolidInfill - { 1.00f, 0.55f, 0.41f }, // erIroning - { 0.30f, 0.50f, 0.73f }, // erBridgeInfill - { 1.00f, 1.00f, 1.00f }, // erGapFill - { 0.00f, 0.53f, 0.43f }, // erSkirt - { 0.00f, 1.00f, 0.00f }, // erSupportMaterial - { 0.00f, 0.50f, 0.00f }, // erSupportMaterialInterface - { 0.70f, 0.89f, 0.67f }, // erWipeTower - { 0.37f, 0.82f, 0.58f }, // erCustom - { 0.00f, 0.00f, 0.00f } // erMixed + { 0.75f, 0.75f, 0.75f, 1.0f }, // erNone + { 1.00f, 0.90f, 0.30f, 1.0f }, // erPerimeter + { 1.00f, 0.49f, 0.22f, 1.0f }, // erExternalPerimeter + { 0.12f, 0.12f, 1.00f, 1.0f }, // erOverhangPerimeter + { 0.69f, 0.19f, 0.16f, 1.0f }, // erInternalInfill + { 0.59f, 0.33f, 0.80f, 1.0f }, // erSolidInfill + { 0.94f, 0.25f, 0.25f, 1.0f }, // erTopSolidInfill + { 1.00f, 0.55f, 0.41f, 1.0f }, // erIroning + { 0.30f, 0.50f, 0.73f, 1.0f }, // erBridgeInfill + { 1.00f, 1.00f, 1.00f, 1.0f }, // erGapFill + { 0.00f, 0.53f, 0.43f, 1.0f }, // erSkirt + { 0.00f, 1.00f, 0.00f, 1.0f }, // erSupportMaterial + { 0.00f, 0.50f, 0.00f, 1.0f }, // erSupportMaterialInterface + { 0.70f, 0.89f, 0.67f, 1.0f }, // erWipeTower + { 0.37f, 0.82f, 0.58f, 1.0f }, // erCustom + { 0.00f, 0.00f, 0.00f, 1.0f } // erMixed }}; const std::vector GCodeViewer::Options_Colors {{ - { 0.803f, 0.135f, 0.839f }, // Retractions - { 0.287f, 0.679f, 0.810f }, // Unretractions - { 0.900f, 0.900f, 0.900f }, // Seams - { 0.758f, 0.744f, 0.389f }, // ToolChanges - { 0.856f, 0.582f, 0.546f }, // ColorChanges - { 0.322f, 0.942f, 0.512f }, // PausePrints - { 0.886f, 0.825f, 0.262f } // CustomGCodes + { 0.803f, 0.135f, 0.839f, 1.0f }, // Retractions + { 0.287f, 0.679f, 0.810f, 1.0f }, // Unretractions + { 0.900f, 0.900f, 0.900f, 1.0f }, // Seams + { 0.758f, 0.744f, 0.389f, 1.0f }, // ToolChanges + { 0.856f, 0.582f, 0.546f, 1.0f }, // ColorChanges + { 0.322f, 0.942f, 0.512f, 1.0f }, // PausePrints + { 0.886f, 0.825f, 0.262f, 1.0f } // CustomGCodes }}; const std::vector GCodeViewer::Travel_Colors {{ - { 0.219f, 0.282f, 0.609f }, // Move - { 0.112f, 0.422f, 0.103f }, // Extrude - { 0.505f, 0.064f, 0.028f } // Retract + { 0.219f, 0.282f, 0.609f, 1.0f }, // Move + { 0.112f, 0.422f, 0.103f, 1.0f }, // Extrude + { 0.505f, 0.064f, 0.028f, 1.0f } // Retract }}; -const GCodeViewer::Color GCodeViewer::Wipe_Color = { 1.0f, 1.0f, 0.0f }; - const std::vector GCodeViewer::Range_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 + { 0.043f, 0.173f, 0.478f, 1.0f }, // bluish + { 0.075f, 0.349f, 0.522f, 1.0f }, + { 0.110f, 0.533f, 0.569f, 1.0f }, + { 0.016f, 0.839f, 0.059f, 1.0f }, + { 0.667f, 0.949f, 0.000f, 1.0f }, + { 0.988f, 0.975f, 0.012f, 1.0f }, + { 0.961f, 0.808f, 0.039f, 1.0f }, + { 0.890f, 0.533f, 0.125f, 1.0f }, + { 0.820f, 0.408f, 0.188f, 1.0f }, + { 0.761f, 0.322f, 0.235f, 1.0f }, + { 0.581f, 0.149f, 0.087f, 1.0f } // reddish }}; +const GCodeViewer::Color GCodeViewer::Wipe_Color = { 1.0f, 1.0f, 0.0f, 1.0f }; +const GCodeViewer::Color GCodeViewer::Neutral_Color = { 0.25f, 0.25f, 0.25f, 1.0f }; + GCodeViewer::GCodeViewer() { // initializes non OpenGL data of TBuffers @@ -1967,18 +1968,14 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool case EViewType::VolumetricRate: { color = m_extrusions.ranges.volumetric_rate.get_color_at(path.volumetric_rate); break; } case EViewType::Tool: { color = m_tool_colors[path.extruder_id]; break; } case EViewType::ColorPrint: { - if (path.cp_color_id >= static_cast(m_tool_colors.size())) { - color = { 0.5f, 0.5f, 0.5f }; -// // complementary color -// color = m_tool_colors[255 - path.cp_color_id]; -// color = { 1.0f - color[0], 1.0f - color[1], 1.0f - color[2] }; - } + if (path.cp_color_id >= static_cast(m_tool_colors.size())) + color = { 0.5f, 0.5f, 0.5f, 1.0f }; else color = m_tool_colors[path.cp_color_id]; break; } - default: { color = { 1.0f, 1.0f, 1.0f }; break; } + default: { color = { 1.0f, 1.0f, 1.0f, 1.0f }; break; } } return color; @@ -2142,20 +2139,20 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool Color color; switch (path.type) { - case EMoveType::Tool_change: { color = Options_Colors[static_cast(EOptionsColors::ToolChanges)]; break; } - case EMoveType::Color_change: { color = Options_Colors[static_cast(EOptionsColors::ColorChanges)]; break; } - case EMoveType::Pause_Print: { color = Options_Colors[static_cast(EOptionsColors::PausePrints)]; break; } - case EMoveType::Custom_GCode: { color = Options_Colors[static_cast(EOptionsColors::CustomGCodes)]; break; } - case EMoveType::Retract: { color = Options_Colors[static_cast(EOptionsColors::Retractions)]; break; } - case EMoveType::Unretract: { color = Options_Colors[static_cast(EOptionsColors::Unretractions)]; break; } - case EMoveType::Seam: { color = Options_Colors[static_cast(EOptionsColors::Seams)]; break; } + case EMoveType::Tool_change: + case EMoveType::Color_change: + case EMoveType::Pause_Print: + case EMoveType::Custom_GCode: + case EMoveType::Retract: + case EMoveType::Unretract: + case EMoveType::Seam: { color = option_color(path.type); break; } case EMoveType::Extrude: { if (!top_layer_only || m_sequential_view.current.last == global_endpoints.last || is_in_layers_range(path, m_layers_z_range[1], m_layers_z_range[1])) color = extrusion_color(path); else - color = { 0.25f, 0.25f, 0.25f }; + color = Neutral_Color; break; } @@ -2163,12 +2160,12 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool 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 = { 0.25f, 0.25f, 0.25f }; + color = Neutral_Color; break; } case EMoveType::Wipe: { color = Wipe_Color; break; } - default: { color = { 0.0f, 0.0f, 0.0f }; break; } + default: { color = { 0.0f, 0.0f, 0.0f, 1.0f }; break; } } RenderPath key{ tbuffer_id, color, static_cast(ibuffer_id), path_id }; @@ -2373,15 +2370,10 @@ void GCodeViewer::render_toolpaths() float near_plane_height = camera.get_type() == Camera::EType::Perspective ? static_cast(viewport[3]) / (2.0f * static_cast(2.0 * std::tan(0.5 * Geometry::deg2rad(camera.get_fov())))) : static_cast(viewport[3]) * 0.0005; - auto set_uniform_color = [](const std::array& color, GLShaderProgram& shader) { - std::array color4 = { color[0], color[1], color[2], 1.0f }; - shader.set_uniform("uniform_color", color4); - }; - #if ENABLE_GCODE_VIEWER_STATISTICS - auto render_as_points = [this, zoom, point_size, near_plane_height, set_uniform_color] + auto render_as_points = [this, zoom, point_size, near_plane_height] #else - auto render_as_points = [zoom, point_size, near_plane_height, set_uniform_color] + auto render_as_points = [zoom, point_size, near_plane_height] #endif // ENABLE_GCODE_VIEWER_STATISTICS (const TBuffer& buffer, unsigned int ibuffer_id, GLShaderProgram& shader) { #if ENABLE_FIXED_SCREEN_SIZE_POINT_MARKERS @@ -2400,7 +2392,7 @@ void GCodeViewer::render_toolpaths() for (const RenderPath& path : buffer.render_paths) { if (path.ibuffer_id == ibuffer_id) { - set_uniform_color(path.color, shader); + shader.set_uniform("uniform_color", path.color); glsafe(::glMultiDrawElements(GL_POINTS, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_SHORT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); #if ENABLE_GCODE_VIEWER_STATISTICS ++m_statistics.gl_multi_points_calls_count; @@ -2413,15 +2405,15 @@ void GCodeViewer::render_toolpaths() }; #if ENABLE_GCODE_VIEWER_STATISTICS - auto render_as_lines = [this, light_intensity, set_uniform_color] + auto render_as_lines = [this, light_intensity] #else - auto render_as_lines = [light_intensity, set_uniform_color] + auto render_as_lines = [light_intensity] #endif // ENABLE_GCODE_VIEWER_STATISTICS (const TBuffer& buffer, unsigned int ibuffer_id, GLShaderProgram& shader) { shader.set_uniform("light_intensity", light_intensity); for (const RenderPath& path : buffer.render_paths) { if (path.ibuffer_id == ibuffer_id) { - set_uniform_color(path.color, shader); + shader.set_uniform("uniform_color", path.color); glsafe(::glMultiDrawElements(GL_LINES, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_SHORT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); #if ENABLE_GCODE_VIEWER_STATISTICS ++m_statistics.gl_multi_lines_calls_count; @@ -2431,14 +2423,14 @@ void GCodeViewer::render_toolpaths() }; #if ENABLE_GCODE_VIEWER_STATISTICS - auto render_as_triangles = [this, set_uniform_color] + auto render_as_triangles = [this] #else - auto render_as_triangles = [set_uniform_color] + auto render_as_triangles = [] #endif // ENABLE_GCODE_VIEWER_STATISTICS (const TBuffer& buffer, unsigned int ibuffer_id, GLShaderProgram& shader) { for (const RenderPath& path : buffer.render_paths) { if (path.ibuffer_id == ibuffer_id) { - set_uniform_color(path.color, shader); + shader.set_uniform("uniform_color", path.color); glsafe(::glMultiDrawElements(GL_TRIANGLES, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_SHORT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); #if ENABLE_GCODE_VIEWER_STATISTICS ++m_statistics.gl_multi_triangles_calls_count; @@ -2509,9 +2501,9 @@ void GCodeViewer::render_toolpaths() } #if ENABLE_GCODE_VIEWER_STATISTICS - auto render_sequential_range_cap = [this, set_uniform_color] + auto render_sequential_range_cap = [this] #else - auto render_sequential_range_cap = [set_uniform_color] + auto render_sequential_range_cap = [] #endif // ENABLE_GCODE_VIEWER_STATISTICS (const SequentialRangeCap& cap) { GLShaderProgram* shader = wxGetApp().get_shader(cap.buffer->shader.c_str()); @@ -2527,7 +2519,7 @@ void GCodeViewer::render_toolpaths() glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); } - set_uniform_color(cap.color, *shader); + shader->set_uniform("uniform_color", cap.color); glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cap.ibo)); glsafe(::glDrawElements(GL_TRIANGLES, (GLsizei)cap.indices_count(), GL_UNSIGNED_SHORT, nullptr)); @@ -3548,6 +3540,21 @@ void GCodeViewer::log_memory_used(const std::string& label, int64_t additional) } } +GCodeViewer::Color GCodeViewer::option_color(EMoveType move_type) const +{ + switch (move_type) + { + case EMoveType::Tool_change: { return Options_Colors[static_cast(EOptionsColors::ToolChanges)]; } + case EMoveType::Color_change: { return Options_Colors[static_cast(EOptionsColors::ColorChanges)]; } + case EMoveType::Pause_Print: { return Options_Colors[static_cast(EOptionsColors::PausePrints)]; } + case EMoveType::Custom_GCode: { return Options_Colors[static_cast(EOptionsColors::CustomGCodes)]; } + case EMoveType::Retract: { return Options_Colors[static_cast(EOptionsColors::Retractions)]; } + case EMoveType::Unretract: { return Options_Colors[static_cast(EOptionsColors::Unretractions)]; } + case EMoveType::Seam: { return Options_Colors[static_cast(EOptionsColors::Seams)]; } + default: { return { 0.0f, 0.0f, 0.0f, 1.0f }; } + } +} + } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index ecdffc5fe..3d9b9bb69 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -22,7 +22,7 @@ namespace GUI { class GCodeViewer { using IBufferType = unsigned short; - using Color = std::array; + using Color = std::array; using VertexBuffer = std::vector; using MultiVertexBuffer = std::vector; using IndexBuffer = std::vector; @@ -31,8 +31,9 @@ class GCodeViewer static const std::vector Extrusion_Role_Colors; static const std::vector Options_Colors; static const std::vector Travel_Colors; - static const Color Wipe_Color; static const std::vector Range_Colors; + static const Color Wipe_Color; + static const Color Neutral_Color; enum class EOptionsColors : unsigned char { @@ -689,6 +690,7 @@ private: } 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; + Color option_color(EMoveType move_type) const; }; } // namespace GUI From 93db27f40c7f655e65ebff29fd67eddfb561940b Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 4 Aug 2021 13:49:51 +0200 Subject: [PATCH 04/18] A bit of refactoring into GCodeViewer --- src/slic3r/GUI/GCodeViewer.cpp | 200 ++++++++++++++++----------------- 1 file changed, 100 insertions(+), 100 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 055fb6fab..c5109f07e 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -125,7 +125,7 @@ bool GCodeViewer::Path::matches(const GCodeProcessor::MoveVertex& move) const case EMoveType::Extrude: { // use rounding to reduce the number of generated paths return type == move.type && extruder_id == move.extruder_id && cp_color_id == move.cp_color_id && role == move.extrusion_role && - move.position[2] <= sub_paths.front().first.position[2] && feedrate == move.feedrate && fan_speed == move.fan_speed && + move.position.z() <= sub_paths.front().first.position.z() && feedrate == move.feedrate && fan_speed == move.fan_speed && height == round_to_nearest(move.height, 2) && width == round_to_nearest(move.width, 2) && matches_percent(volumetric_rate, move.volumetric_rate(), 0.05f); } @@ -207,7 +207,7 @@ void GCodeViewer::SequentialView::Marker::init() void GCodeViewer::SequentialView::Marker::set_world_position(const Vec3f& position) { m_world_position = position; - m_world_transform = (Geometry::assemble_transform((position + m_z_offset * Vec3f::UnitZ()).cast()) * Geometry::assemble_transform(m_model.get_bounding_box().size()[2] * Vec3d::UnitZ(), { M_PI, 0.0, 0.0 })).cast(); + m_world_transform = (Geometry::assemble_transform((position + m_z_offset * Vec3f::UnitZ()).cast()) * Geometry::assemble_transform(m_model.get_bounding_box().size().z() * Vec3d::UnitZ(), { M_PI, 0.0, 0.0 })).cast(); } void GCodeViewer::SequentialView::Marker::render() const @@ -623,23 +623,23 @@ void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print& else { // adjust printbed size in dependence of toolpaths bbox const double margin = 10.0; - Vec2d min(m_paths_bounding_box.min(0) - margin, m_paths_bounding_box.min(1) - margin); - Vec2d max(m_paths_bounding_box.max(0) + margin, m_paths_bounding_box.max(1) + margin); + Vec2d min(m_paths_bounding_box.min.x() - margin, m_paths_bounding_box.min.y() - margin); + Vec2d max(m_paths_bounding_box.max.x() + margin, m_paths_bounding_box.max.y() + margin); Vec2d size = max - min; bed_shape = { - { min(0), min(1) }, - { max(0), min(1) }, - { max(0), min(1) + 0.442265 * size[1]}, - { max(0) - 10.0, min(1) + 0.4711325 * size[1]}, - { max(0) + 10.0, min(1) + 0.5288675 * size[1]}, - { max(0), min(1) + 0.557735 * size[1]}, - { max(0), max(1) }, - { min(0) + 0.557735 * size[0], max(1)}, - { min(0) + 0.5288675 * size[0], max(1) - 10.0}, - { min(0) + 0.4711325 * size[0], max(1) + 10.0}, - { min(0) + 0.442265 * size[0], max(1)}, - { min(0), max(1) } }; + { min.x(), min.y() }, + { max.x(), min.y() }, + { max.x(), min.y() + 0.442265 * size.y()}, + { max.x() - 10.0, min.y() + 0.4711325 * size.y()}, + { max.x() + 10.0, min.y() + 0.5288675 * size.y()}, + { max.x(), min.y() + 0.557735 * size.y()}, + { max.x(), max.y() }, + { min.x() + 0.557735 * size.x(), max.y()}, + { min.x() + 0.5288675 * size.x(), max.y() - 10.0}, + { min.x() + 0.4711325 * size.x(), max.y() + 10.0}, + { min.x() + 0.442265 * size.x(), max.y()}, + { min.x(), max.y() } }; } wxGetApp().plater()->set_bed_shape(bed_shape, texture, model, gcode_result.bed_shape.empty()); @@ -1036,13 +1036,13 @@ void GCodeViewer::export_toolpaths_to_obj(const char* filename) const // save vertices to file fprintf(fp, "\n# vertices\n"); for (const Vec3f& v : out_vertices) { - fprintf(fp, "v %g %g %g\n", v[0], v[1], v[2]); + fprintf(fp, "v %g %g %g\n", v.x(), v.y(), v.x()); } // save normals to file fprintf(fp, "\n# normals\n"); for (const Vec3f& n : out_normals) { - fprintf(fp, "vn %g %g %g\n", n[0], n[1], n[2]); + fprintf(fp, "vn %g %g %g\n", n.x(), n.y(), n.z()); } size_t i = 0; @@ -1124,9 +1124,9 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) // format data into the buffers to be rendered as points auto add_vertices_as_point = [](const GCodeProcessor::MoveVertex& curr, VertexBuffer& vertices) { - vertices.push_back(curr.position[0]); - vertices.push_back(curr.position[1]); - vertices.push_back(curr.position[2]); + vertices.push_back(curr.position.x()); + vertices.push_back(curr.position.y()); + vertices.push_back(curr.position.z()); }; auto add_indices_as_point = [](const GCodeProcessor::MoveVertex& curr, TBuffer& buffer, unsigned int ibuffer_id, IndexBuffer& indices, size_t move_id) { @@ -1137,13 +1137,13 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) // format data into the buffers to be rendered as lines auto add_vertices_as_line = [](const GCodeProcessor::MoveVertex& prev, const GCodeProcessor::MoveVertex& curr, VertexBuffer& vertices) { // x component of the normal to the current segment (the normal is parallel to the XY plane) - float normal_x = (curr.position - prev.position).normalized()[1]; + const float normal_x = (curr.position - prev.position).normalized().y(); auto add_vertex = [&vertices, normal_x](const GCodeProcessor::MoveVertex& vertex) { // add position - vertices.push_back(vertex.position[0]); - vertices.push_back(vertex.position[1]); - vertices.push_back(vertex.position[2]); + vertices.push_back(vertex.position.x()); + vertices.push_back(vertex.position.y()); + vertices.push_back(vertex.position.z()); // add normal x component vertices.push_back(normal_x); }; @@ -1177,13 +1177,13 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) auto add_vertices_as_solid = [](const GCodeProcessor::MoveVertex& prev, const GCodeProcessor::MoveVertex& curr, TBuffer& buffer, unsigned int vbuffer_id, VertexBuffer& vertices, size_t move_id) { auto store_vertex = [](VertexBuffer& vertices, const Vec3f& position, const Vec3f& normal) { // append position - vertices.push_back(position[0]); - vertices.push_back(position[1]); - vertices.push_back(position[2]); + vertices.push_back(position.x()); + vertices.push_back(position.y()); + vertices.push_back(position.z()); // append normal - vertices.push_back(normal[0]); - vertices.push_back(normal[1]); - vertices.push_back(normal[2]); + vertices.push_back(normal.x()); + vertices.push_back(normal.y()); + vertices.push_back(normal.z()); }; if (prev.type != curr.type || !buffer.paths.back().matches(curr)) { @@ -1193,19 +1193,19 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) Path& last_path = buffer.paths.back(); - Vec3f dir = (curr.position - prev.position).normalized(); - Vec3f right = Vec3f(dir[1], -dir[0], 0.0f).normalized(); - Vec3f left = -right; - Vec3f up = right.cross(dir); - Vec3f down = -up; - float half_width = 0.5f * last_path.width; - float half_height = 0.5f * last_path.height; - Vec3f prev_pos = prev.position - half_height * up; - Vec3f curr_pos = curr.position - half_height * up; - Vec3f d_up = half_height * up; - Vec3f d_down = -half_height * up; - Vec3f d_right = half_width * right; - Vec3f d_left = -half_width * right; + const Vec3f dir = (curr.position - prev.position).normalized(); + const Vec3f right = Vec3f(dir.y(), -dir.x(), 0.0f).normalized(); + const Vec3f left = -right; + const Vec3f up = right.cross(dir); + const Vec3f down = -up; + const float half_width = 0.5f * last_path.width; + const float half_height = 0.5f * last_path.height; + const Vec3f prev_pos = prev.position - half_height * up; + const Vec3f curr_pos = curr.position - half_height * up; + const Vec3f d_up = half_height * up; + const Vec3f d_down = -half_height * up; + const Vec3f d_right = half_width * right; + const Vec3f d_left = -half_width * right; // vertices 1st endpoint if (last_path.vertices_count() == 1 || vertices.empty()) { @@ -1284,14 +1284,14 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) Path& last_path = buffer.paths.back(); - Vec3f dir = (curr.position - prev.position).normalized(); - Vec3f right = Vec3f(dir[1], -dir[0], 0.0f).normalized(); - Vec3f up = right.cross(dir); - float sq_length = (curr.position - prev.position).squaredNorm(); + const Vec3f dir = (curr.position - prev.position).normalized(); + const Vec3f right = Vec3f(dir.y(), -dir.x(), 0.0f).normalized(); + const Vec3f up = right.cross(dir); + const float sq_length = (curr.position - prev.position).squaredNorm(); const std::array first_seg_v_offsets = convert_vertices_offset(vbuffer_size, { 0, 1, 2, 3, 4, 5, 6, 7 }); const std::array non_first_seg_v_offsets = convert_vertices_offset(vbuffer_size, { -4, 0, -2, 1, 2, 3, 4, 5 }); - bool is_first_segment = (last_path.vertices_count() == 1); + const bool is_first_segment = (last_path.vertices_count() == 1); if (is_first_segment || vbuffer_size == 0) { // 1st segment or restart into a new vertex buffer // =============================================== @@ -1310,20 +1310,20 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) // any other segment // ================= float displacement = 0.0f; - float cos_dir = prev_dir.dot(dir); + const float cos_dir = prev_dir.dot(dir); if (cos_dir > -0.9998477f) { // if the angle between adjacent segments is smaller than 179 degrees - Vec3f med_dir = (prev_dir + dir).normalized(); - float half_width = 0.5f * last_path.width; + const Vec3f med_dir = (prev_dir + dir).normalized(); + const float half_width = 0.5f * last_path.width; displacement = half_width * ::tan(::acos(std::clamp(dir.dot(med_dir), -1.0f, 1.0f))); } - float sq_displacement = sqr(displacement); - bool can_displace = displacement > 0.0f && sq_displacement < sq_prev_length && sq_displacement < sq_length; + const float sq_displacement = sqr(displacement); + const bool can_displace = displacement > 0.0f && sq_displacement < sq_prev_length && sq_displacement < sq_length; - bool is_right_turn = prev_up.dot(prev_dir.cross(dir)) <= 0.0f; + const bool is_right_turn = prev_up.dot(prev_dir.cross(dir)) <= 0.0f; // whether the angle between adjacent segments is greater than 45 degrees - bool is_sharp = cos_dir < 0.7071068f; + const bool is_sharp = cos_dir < 0.7071068f; bool right_displaced = false; bool left_displaced = false; @@ -1434,7 +1434,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) progress_count = 0; } - unsigned char id = buffer_id(curr.type); + const unsigned char id = buffer_id(curr.type); TBuffer& t_buffer = m_buffers[id]; MultiVertexBuffer& v_multibuffer = vertices[id]; @@ -1476,24 +1476,24 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) return Vec3f(vertices[offset + 0], vertices[offset + 1], vertices[offset + 2]); }; auto update_position_at = [](VertexBuffer& vertices, size_t offset, const Vec3f& position) { - vertices[offset + 0] = position[0]; - vertices[offset + 1] = position[1]; - vertices[offset + 2] = position[2]; + vertices[offset + 0] = position.x(); + vertices[offset + 1] = position.y(); + vertices[offset + 2] = position.z(); }; auto match_right_vertices = [&](const Path::Sub_Path& prev_sub_path, const Path::Sub_Path& next_sub_path, size_t curr_s_id, size_t vertex_size_floats, const Vec3f& displacement_vec) { if (&prev_sub_path == &next_sub_path) { // previous and next segment are both contained into to the same vertex buffer VertexBuffer& vbuffer = v_multibuffer[prev_sub_path.first.b_id]; // offset into the vertex buffer of the next segment 1st vertex - size_t next_1st_offset = (prev_sub_path.last.s_id - curr_s_id) * 6 * vertex_size_floats; + const size_t next_1st_offset = (prev_sub_path.last.s_id - curr_s_id) * 6 * vertex_size_floats; // offset into the vertex buffer of the right vertex of the previous segment - size_t prev_right_offset = prev_sub_path.last.i_id - next_1st_offset - 3 * vertex_size_floats; + const size_t prev_right_offset = prev_sub_path.last.i_id - next_1st_offset - 3 * vertex_size_floats; // new position of the right vertices - Vec3f shared_vertex = extract_position_at(vbuffer, prev_right_offset) + displacement_vec; + const Vec3f shared_vertex = extract_position_at(vbuffer, prev_right_offset) + displacement_vec; // update previous segment update_position_at(vbuffer, prev_right_offset, shared_vertex); // offset into the vertex buffer of the right vertex of the next segment - size_t next_right_offset = next_sub_path.last.i_id - next_1st_offset; + const size_t next_right_offset = next_sub_path.last.i_id - next_1st_offset; // update next segment update_position_at(vbuffer, next_right_offset, shared_vertex); } @@ -1501,13 +1501,13 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) VertexBuffer& prev_vbuffer = v_multibuffer[prev_sub_path.first.b_id]; VertexBuffer& next_vbuffer = v_multibuffer[next_sub_path.first.b_id]; // offset into the previous vertex buffer of the right vertex of the previous segment - size_t prev_right_offset = prev_sub_path.last.i_id - 3 * vertex_size_floats; + const size_t prev_right_offset = prev_sub_path.last.i_id - 3 * vertex_size_floats; // new position of the right vertices - Vec3f shared_vertex = extract_position_at(prev_vbuffer, prev_right_offset) + displacement_vec; + const Vec3f shared_vertex = extract_position_at(prev_vbuffer, prev_right_offset) + displacement_vec; // update previous segment update_position_at(prev_vbuffer, prev_right_offset, shared_vertex); // offset into the next vertex buffer of the right vertex of the next segment - size_t next_right_offset = next_sub_path.first.i_id + 1 * vertex_size_floats; + const size_t next_right_offset = next_sub_path.first.i_id + 1 * vertex_size_floats; // update next segment update_position_at(next_vbuffer, next_right_offset, shared_vertex); } @@ -1517,15 +1517,15 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) if (&prev_sub_path == &next_sub_path) { // previous and next segment are both contained into to the same vertex buffer VertexBuffer& vbuffer = v_multibuffer[prev_sub_path.first.b_id]; // offset into the vertex buffer of the next segment 1st vertex - size_t next_1st_offset = (prev_sub_path.last.s_id - curr_s_id) * 6 * vertex_size_floats; + const size_t next_1st_offset = (prev_sub_path.last.s_id - curr_s_id) * 6 * vertex_size_floats; // offset into the vertex buffer of the left vertex of the previous segment - size_t prev_left_offset = prev_sub_path.last.i_id - next_1st_offset - 1 * vertex_size_floats; + const size_t prev_left_offset = prev_sub_path.last.i_id - next_1st_offset - 1 * vertex_size_floats; // new position of the left vertices - Vec3f shared_vertex = extract_position_at(vbuffer, prev_left_offset) + displacement_vec; + const Vec3f shared_vertex = extract_position_at(vbuffer, prev_left_offset) + displacement_vec; // update previous segment update_position_at(vbuffer, prev_left_offset, shared_vertex); // offset into the vertex buffer of the left vertex of the next segment - size_t next_left_offset = next_sub_path.last.i_id - next_1st_offset + 1 * vertex_size_floats; + const size_t next_left_offset = next_sub_path.last.i_id - next_1st_offset + 1 * vertex_size_floats; // update next segment update_position_at(vbuffer, next_left_offset, shared_vertex); } @@ -1533,13 +1533,13 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) VertexBuffer& prev_vbuffer = v_multibuffer[prev_sub_path.first.b_id]; VertexBuffer& next_vbuffer = v_multibuffer[next_sub_path.first.b_id]; // offset into the previous vertex buffer of the left vertex of the previous segment - size_t prev_left_offset = prev_sub_path.last.i_id - 1 * vertex_size_floats; + const size_t prev_left_offset = prev_sub_path.last.i_id - 1 * vertex_size_floats; // new position of the left vertices - Vec3f shared_vertex = extract_position_at(prev_vbuffer, prev_left_offset) + displacement_vec; + const Vec3f shared_vertex = extract_position_at(prev_vbuffer, prev_left_offset) + displacement_vec; // update previous segment update_position_at(prev_vbuffer, prev_left_offset, shared_vertex); // offset into the next vertex buffer of the left vertex of the next segment - size_t next_left_offset = next_sub_path.first.i_id + 3 * vertex_size_floats; + const size_t next_left_offset = next_sub_path.first.i_id + 3 * vertex_size_floats; // update next segment update_position_at(next_vbuffer, next_left_offset, shared_vertex); } @@ -1551,8 +1551,8 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) // to two different vertex buffers size_t prev_sub_path_id = 0; size_t next_sub_path_id = 0; - size_t path_vertices_count = path.vertices_count(); - float half_width = 0.5f * path.width; + const size_t path_vertices_count = path.vertices_count(); + const float half_width = 0.5f * path.width; for (size_t j = 1; j < path_vertices_count - 1; ++j) { size_t curr_s_id = path.sub_paths.front().first.s_id + j; const Vec3f& prev = gcode_result.moves[curr_s_id - 1].position; @@ -1567,16 +1567,16 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) const Path::Sub_Path& prev_sub_path = path.sub_paths[prev_sub_path_id]; const Path::Sub_Path& next_sub_path = path.sub_paths[next_sub_path_id]; - Vec3f prev_dir = (curr - prev).normalized(); - Vec3f prev_right = Vec3f(prev_dir[1], -prev_dir[0], 0.0f).normalized(); - Vec3f prev_up = prev_right.cross(prev_dir); + const Vec3f prev_dir = (curr - prev).normalized(); + const Vec3f prev_right = Vec3f(prev_dir.y(), -prev_dir.x(), 0.0f).normalized(); + const Vec3f prev_up = prev_right.cross(prev_dir); - Vec3f next_dir = (next - curr).normalized(); + const Vec3f next_dir = (next - curr).normalized(); - bool is_right_turn = prev_up.dot(prev_dir.cross(next_dir)) <= 0.0f; - float cos_dir = prev_dir.dot(next_dir); + const bool is_right_turn = prev_up.dot(prev_dir.cross(next_dir)) <= 0.0f; + const float cos_dir = prev_dir.dot(next_dir); // whether the angle between adjacent segments is greater than 45 degrees - bool is_sharp = cos_dir < 0.7071068f; + const bool is_sharp = cos_dir < 0.7071068f; float displacement = 0.0f; if (cos_dir > -0.9998477f) { @@ -1585,10 +1585,10 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) displacement = half_width * ::tan(::acos(std::clamp(next_dir.dot(med_dir), -1.0f, 1.0f))); } - float sq_prev_length = (curr - prev).squaredNorm(); - float sq_next_length = (next - curr).squaredNorm(); - float sq_displacement = sqr(displacement); - bool can_displace = displacement > 0.0f && sq_displacement < sq_prev_length && sq_displacement < sq_next_length; + const float sq_prev_length = (curr - prev).squaredNorm(); + const float sq_next_length = (next - curr).squaredNorm(); + const float sq_displacement = sqr(displacement); + const bool can_displace = displacement > 0.0f && sq_displacement < sq_prev_length && sq_displacement < sq_next_length; if (can_displace) { // displacement to apply to the vertices to match @@ -1644,9 +1644,9 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) const MultiVertexBuffer& v_multibuffer = vertices[i]; for (const VertexBuffer& v_buffer : v_multibuffer) { - size_t size_elements = v_buffer.size(); - size_t size_bytes = size_elements * sizeof(float); - size_t vertices_count = size_elements / t_buffer.vertices.vertex_size_floats(); + const size_t size_elements = v_buffer.size(); + const size_t size_bytes = size_elements * sizeof(float); + const size_t vertices_count = size_elements / t_buffer.vertices.vertex_size_floats(); t_buffer.vertices.count += vertices_count; #if ENABLE_GCODE_VIEWER_STATISTICS @@ -1709,7 +1709,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) progress_count = 0; } - unsigned char id = buffer_id(curr.type); + const unsigned char id = buffer_id(curr.type); TBuffer& t_buffer = m_buffers[id]; MultiIndexBuffer& i_multibuffer = indices[id]; CurrVertexBuffer& curr_vertex_buffer = curr_vertex_buffers[id]; @@ -1779,8 +1779,8 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) TBuffer& t_buffer = m_buffers[i]; const MultiIndexBuffer& i_multibuffer = indices[i]; for (const IndexBuffer& i_buffer : i_multibuffer) { - size_t size_elements = i_buffer.size(); - size_t size_bytes = size_elements * sizeof(IBufferType); + const size_t size_elements = i_buffer.size(); + const size_t size_bytes = size_elements * sizeof(IBufferType); // stores index buffer informations into TBuffer t_buffer.indices.push_back(IBuffer()); @@ -1844,7 +1844,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) if (move.type == EMoveType::Extrude) { // layers zs const double* const last_z = m_layers.empty() ? nullptr : &m_layers.get_zs().back(); - double z = static_cast(move.position[2]); + const double z = static_cast(move.position.z()); if (last_z == nullptr || z < *last_z - EPSILON || *last_z + EPSILON < z) m_layers.append(z, { last_travel_s_id, i }); else @@ -1881,7 +1881,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) if (!options_zs.empty()) { TBuffer& extrude_buffer = m_buffers[buffer_id(EMoveType::Extrude)]; for (Path& path : extrude_buffer.paths) { - float z = path.sub_paths.front().first.position[2]; + const float z = path.sub_paths.front().first.position.z(); if (std::find_if(options_zs.begin(), options_zs.end(), [z](float f) { return f - EPSILON <= z && z <= f + EPSILON; }) != options_zs.end()) path.cp_color_id = 255 - path.cp_color_id; } @@ -1918,12 +1918,12 @@ void GCodeViewer::load_shells(const Print& print, bool initialized) if (wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptFFF) { // adds wipe tower's volume - double max_z = print.objects()[0]->model_object()->get_model()->bounding_box().max(2); + const double max_z = print.objects()[0]->model_object()->get_model()->bounding_box().max(2); const PrintConfig& config = print.config(); - size_t extruders_count = config.nozzle_diameter.size(); + const size_t extruders_count = config.nozzle_diameter.size(); if ((extruders_count > 1) && config.wipe_tower && !config.complete_objects) { - float depth = print.wipe_tower_data(extruders_count).depth; - float brim_width = print.wipe_tower_data(extruders_count).brim_width; + const float depth = print.wipe_tower_data(extruders_count).depth; + const float brim_width = print.wipe_tower_data(extruders_count).brim_width; m_shells.volumes.load_wipe_tower_preview(1000, config.wipe_tower_x, config.wipe_tower_y, config.wipe_tower_width, depth, max_z, config.wipe_tower_rotation_angle, !print.is_step_done(psWipeTower), brim_width, initialized); @@ -2427,7 +2427,7 @@ void GCodeViewer::render_toolpaths() #else auto render_as_triangles = [] #endif // ENABLE_GCODE_VIEWER_STATISTICS -(const TBuffer& buffer, unsigned int ibuffer_id, GLShaderProgram& shader) { + (const TBuffer& buffer, unsigned int ibuffer_id, GLShaderProgram& shader) { for (const RenderPath& path : buffer.render_paths) { if (path.ibuffer_id == ibuffer_id) { shader.set_uniform("uniform_color", path.color); From c4ec355f41b705d7313b7d2bfd9f94850ff1bf1f Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 4 Aug 2021 13:58:44 +0200 Subject: [PATCH 05/18] Added function to generated diamond shaped model --- src/slic3r/GUI/GLModel.cpp | 48 ++++++++++++++++++++++++++++++++++++++ src/slic3r/GUI/GLModel.hpp | 5 ++++ 2 files changed, 53 insertions(+) diff --git a/src/slic3r/GUI/GLModel.cpp b/src/slic3r/GUI/GLModel.cpp index 6d54ec20e..c4437a87f 100644 --- a/src/slic3r/GUI/GLModel.cpp +++ b/src/slic3r/GUI/GLModel.cpp @@ -597,5 +597,53 @@ GLModel::InitializationData straight_arrow(float tip_width, float tip_height, fl return data; } +GLModel::InitializationData diamond(int resolution) +{ + resolution = std::max(4, resolution); + + GLModel::InitializationData data; + GLModel::InitializationData::Entity entity; + entity.type = GLModel::PrimitiveType::Triangles; + + const float step = 2.0f * float(PI) / float(resolution); + + // positions + for (int i = 0; i < resolution; ++i) { + float ii = float(i) * step; + entity.positions.emplace_back(0.5f * ::cos(ii), 0.5f * ::sin(ii), 0.0f); + } + entity.positions.emplace_back(0.0f, 0.0f, 0.5f); + entity.positions.emplace_back(0.0f, 0.0f, -0.5f); + + // normals + for (const Vec3f& v : entity.positions) { + entity.normals.emplace_back(v.normalized()); + } + + // triangles + // top + for (int i = 0; i < resolution; ++i) { + entity.indices.push_back(i + 0); + entity.indices.push_back(i + 1); + entity.indices.push_back(resolution); + } + entity.indices.push_back(resolution - 1); + entity.indices.push_back(0); + entity.indices.push_back(resolution); + + // bottom + for (int i = 0; i < resolution; ++i) { + entity.indices.push_back(i + 0); + entity.indices.push_back(resolution + 1); + entity.indices.push_back(i + 1); + } + entity.indices.push_back(resolution - 1); + entity.indices.push_back(resolution + 1); + entity.indices.push_back(0); + + data.entities.emplace_back(entity); + return data; +} + } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/GLModel.hpp b/src/slic3r/GUI/GLModel.hpp index cab2fe220..99c4bf442 100644 --- a/src/slic3r/GUI/GLModel.hpp +++ b/src/slic3r/GUI/GLModel.hpp @@ -100,6 +100,11 @@ namespace GUI { // used to render sidebar hints for position and scale GLModel::InitializationData straight_arrow(float tip_width, float tip_height, float stem_width, float stem_height, float thickness); + // create a diamond with the given resolution + // the origin of the diamond is in its center + // the diamond is contained into a box with size [1, 1, 1] + GLModel::InitializationData diamond(int resolution); + } // namespace GUI } // namespace Slic3r From 55bac686031fa366f452111d84b5b58c2dd22a10 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 4 Aug 2021 15:13:43 +0200 Subject: [PATCH 06/18] Tech ENABLE_SEAMS_USING_MODELS - 1st installment --- src/libslic3r/Technologies.hpp | 2 + src/slic3r/GUI/GCodeViewer.cpp | 437 ++++++++++++++++++++++----------- src/slic3r/GUI/GCodeViewer.hpp | 65 ++++- 3 files changed, 361 insertions(+), 143 deletions(-) diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index f6366c18e..768b0cb6a 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -47,6 +47,8 @@ #define ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER (1 && ENABLE_2_4_0_ALPHA0) // Enable drawing contours, at cut level, for sinking volumes #define ENABLE_SINKING_CONTOURS (1 && ENABLE_2_4_0_ALPHA0) +// Enable rendering seams (and other options) in preview using models +#define ENABLE_SEAMS_USING_MODELS (1 && ENABLE_2_4_0_ALPHA0) #endif // _prusaslicer_technologies_h_ diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index c5109f07e..418d00972 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -136,18 +136,26 @@ bool GCodeViewer::Path::matches(const GCodeProcessor::MoveVertex& move) const } } +#if ENABLE_SEAMS_USING_MODELS +void GCodeViewer::TBuffer::Model::reset() +{ + instances.clear(); +} +#endif // ENABLE_SEAMS_USING_MODELS + void GCodeViewer::TBuffer::reset() { - // release gpu memory vertices.reset(); for (IBuffer& buffer : indices) { buffer.reset(); } - // release cpu memory indices.clear(); paths.clear(); render_paths.clear(); +#if ENABLE_SEAMS_USING_MODELS + model.reset(); +#endif // ENABLE_SEAMS_USING_MODELS } void GCodeViewer::TBuffer::add_path(const GCodeProcessor::MoveVertex& move, unsigned int b_id, size_t i_id, size_t s_id) @@ -544,6 +552,18 @@ GCodeViewer::GCodeViewer() switch (buffer_type(i)) { default: { break; } +#if ENABLE_SEAMS_USING_MODELS + case EMoveType::Tool_change: + case EMoveType::Color_change: + case EMoveType::Pause_Print: + case EMoveType::Custom_GCode: + case EMoveType::Retract: + case EMoveType::Unretract: + case EMoveType::Seam: { + buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::Model; + break; + } +#else case EMoveType::Tool_change: case EMoveType::Color_change: case EMoveType::Pause_Print: @@ -555,6 +575,7 @@ GCodeViewer::GCodeViewer() buffer.vertices.format = VBuffer::EFormat::Position; break; } +#endif // ENABLE_SEAMS_USING_MODELS case EMoveType::Wipe: case EMoveType::Extrude: { buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::Triangle; @@ -611,7 +632,7 @@ void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print& if (!gcode_result.bed_shape.empty()) { // bed shape detected in the gcode bed_shape = gcode_result.bed_shape; - auto bundle = wxGetApp().preset_bundle; + const auto bundle = wxGetApp().preset_bundle; if (bundle != nullptr && !m_settings_ids.printer.empty()) { const Preset* preset = bundle->printers.find_preset(m_settings_ids.printer); if (preset != nullptr) { @@ -623,10 +644,10 @@ void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print& else { // adjust printbed size in dependence of toolpaths bbox const double margin = 10.0; - Vec2d min(m_paths_bounding_box.min.x() - margin, m_paths_bounding_box.min.y() - margin); - Vec2d max(m_paths_bounding_box.max.x() + margin, m_paths_bounding_box.max.y() + margin); + const Vec2d min(m_paths_bounding_box.min.x() - margin, m_paths_bounding_box.min.y() - margin); + const Vec2d max(m_paths_bounding_box.max.x() + margin, m_paths_bounding_box.max.y() + margin); - Vec2d size = max - min; + const Vec2d size = max - min; bed_shape = { { min.x(), min.y() }, { max.x(), min.y() }, @@ -648,7 +669,7 @@ void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print& m_print_statistics = gcode_result.print_statistics; if (m_time_estimate_mode != PrintEstimatedStatistics::ETimeMode::Normal) { - float time = m_print_statistics.modes[static_cast(m_time_estimate_mode)].time; + 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; @@ -764,7 +785,8 @@ void GCodeViewer::render() // initializes opengl data of TBuffers for (size_t i = 0; i < m_buffers.size(); ++i) { TBuffer& buffer = m_buffers[i]; - switch (buffer_type(i)) + EMoveType type = buffer_type(i); + switch (type) { default: { break; } case EMoveType::Tool_change: @@ -774,8 +796,15 @@ void GCodeViewer::render() case EMoveType::Retract: case EMoveType::Unretract: case EMoveType::Seam: { +#if ENABLE_SEAMS_USING_MODELS + buffer.shader = "gouraud_light"; + buffer.model.model.init_from(diamond(16)); + buffer.model.color = option_color(type); + break; +#else buffer.shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120" : "options_110"; break; +#endif // ENABLE_SEAMS_USING_MODELS } case EMoveType::Wipe: case EMoveType::Extrude: { @@ -844,8 +873,8 @@ void GCodeViewer::update_sequential_view_current(unsigned int first, unsigned in return false; }; - int first_diff = static_cast(first) - static_cast(m_sequential_view.last_current.first); - int last_diff = static_cast(last) - static_cast(m_sequential_view.last_current.last); + const int first_diff = static_cast(first) - static_cast(m_sequential_view.last_current.first); + const int last_diff = static_cast(last) - static_cast(m_sequential_view.last_current.last); unsigned int new_first = first; unsigned int new_last = last; @@ -1371,6 +1400,18 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) sq_prev_length = sq_length; }; +#if ENABLE_SEAMS_USING_MODELS + // format data into the buffers to be rendered as model + auto add_model_instance = [](const GCodeProcessor::MoveVertex& curr, TBuffer::Model::Instances& instances, size_t move_id) { + TBuffer::Model::Instance instance; + instance.position = curr.position; + instance.width = 1.2f * curr.width; + instance.height = 1.2f * curr.height; + instance.s_id = move_id; + instances.emplace_back(instance); + }; +#endif // ENABLE_SEAMS_USING_MODELS + #if ENABLE_GCODE_VIEWER_STATISTICS auto start_time = std::chrono::high_resolution_clock::now(); m_statistics.results_size = SLIC3R_STDVEC_MEMSIZE(gcode_result.moves, GCodeProcessor::MoveVertex); @@ -1460,6 +1501,9 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) case TBuffer::ERenderPrimitiveType::Point: { add_vertices_as_point(curr, v_buffer); break; } case TBuffer::ERenderPrimitiveType::Line: { add_vertices_as_line(prev, curr, v_buffer); break; } case TBuffer::ERenderPrimitiveType::Triangle: { add_vertices_as_solid(prev, curr, t_buffer, static_cast(v_multibuffer.size()) - 1, v_buffer, i); break; } +#if ENABLE_SEAMS_USING_MODELS + case TBuffer::ERenderPrimitiveType::Model: { add_model_instance(curr, t_buffer.model.instances, i); break; } +#endif // ENABLE_SEAMS_USING_MODELS } // collect options zs for later use @@ -1641,28 +1685,34 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) // send vertices data to gpu for (size_t i = 0; i < m_buffers.size(); ++i) { TBuffer& t_buffer = m_buffers[i]; - - const MultiVertexBuffer& v_multibuffer = vertices[i]; - for (const VertexBuffer& v_buffer : v_multibuffer) { - const size_t size_elements = v_buffer.size(); - const size_t size_bytes = size_elements * sizeof(float); - const size_t vertices_count = size_elements / t_buffer.vertices.vertex_size_floats(); - t_buffer.vertices.count += vertices_count; +#if ENABLE_SEAMS_USING_MODELS + if (t_buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::Model) { +#endif // ENABLE_SEAMS_USING_MODELS + const MultiVertexBuffer& v_multibuffer = vertices[i]; + for (const VertexBuffer& v_buffer : v_multibuffer) { + const size_t size_elements = v_buffer.size(); + const size_t size_bytes = size_elements * sizeof(float); + const size_t vertices_count = size_elements / t_buffer.vertices.vertex_size_floats(); + t_buffer.vertices.count += vertices_count; #if ENABLE_GCODE_VIEWER_STATISTICS - m_statistics.total_vertices_gpu_size += static_cast(size_bytes); - m_statistics.max_vbuffer_gpu_size = std::max(m_statistics.max_vbuffer_gpu_size, static_cast(size_bytes)); - ++m_statistics.vbuffers_count; + m_statistics.total_vertices_gpu_size += static_cast(size_bytes); + m_statistics.max_vbuffer_gpu_size = std::max(m_statistics.max_vbuffer_gpu_size, static_cast(size_bytes)); + ++m_statistics.vbuffers_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS - GLuint id = 0; - glsafe(::glGenBuffers(1, &id)); - t_buffer.vertices.vbos.push_back(static_cast(id)); - t_buffer.vertices.sizes.push_back(size_bytes); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, id)); - glsafe(::glBufferData(GL_ARRAY_BUFFER, size_bytes, v_buffer.data(), GL_STATIC_DRAW)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + GLuint id = 0; + glsafe(::glGenBuffers(1, &id)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, id)); + glsafe(::glBufferData(GL_ARRAY_BUFFER, size_bytes, v_buffer.data(), GL_STATIC_DRAW)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + + t_buffer.vertices.vbos.push_back(static_cast(id)); + t_buffer.vertices.sizes.push_back(size_bytes); + } +#if ENABLE_SEAMS_USING_MODELS } +#endif // ENABLE_SEAMS_USING_MODELS } #if ENABLE_GCODE_VIEWER_STATISTICS @@ -1718,7 +1768,10 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) // ensure there is at least one index buffer if (i_multibuffer.empty()) { i_multibuffer.push_back(IndexBuffer()); - vbo_index_list.push_back(t_buffer.vertices.vbos[curr_vertex_buffer.first]); +#if ENABLE_SEAMS_USING_MODELS + if (!t_buffer.vertices.vbos.empty()) +#endif // ENABLE_SEAMS_USING_MODELS + vbo_index_list.push_back(t_buffer.vertices.vbos[curr_vertex_buffer.first]); } // if adding the indices for the current segment exceeds the threshold size of the current index buffer @@ -1777,28 +1830,34 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) // toolpaths data -> send indices data to gpu for (size_t i = 0; i < m_buffers.size(); ++i) { TBuffer& t_buffer = m_buffers[i]; - const MultiIndexBuffer& i_multibuffer = indices[i]; - for (const IndexBuffer& i_buffer : i_multibuffer) { - const size_t size_elements = i_buffer.size(); - const size_t size_bytes = size_elements * sizeof(IBufferType); +#if ENABLE_SEAMS_USING_MODELS + if (t_buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::Model) { +#endif // ENABLE_SEAMS_USING_MODELS + const MultiIndexBuffer& i_multibuffer = indices[i]; + for (const IndexBuffer& i_buffer : i_multibuffer) { + const size_t size_elements = i_buffer.size(); + const size_t size_bytes = size_elements * sizeof(IBufferType); - // stores index buffer informations into TBuffer - t_buffer.indices.push_back(IBuffer()); - IBuffer& ibuf = t_buffer.indices.back(); - ibuf.count = size_elements; - ibuf.vbo = vbo_indices[i][t_buffer.indices.size() - 1]; + // stores index buffer informations into TBuffer + t_buffer.indices.push_back(IBuffer()); + IBuffer& ibuf = t_buffer.indices.back(); + ibuf.count = size_elements; + ibuf.vbo = vbo_indices[i][t_buffer.indices.size() - 1]; #if ENABLE_GCODE_VIEWER_STATISTICS - m_statistics.total_indices_gpu_size += static_cast(size_bytes); - m_statistics.max_ibuffer_gpu_size = std::max(m_statistics.max_ibuffer_gpu_size, static_cast(size_bytes)); - ++m_statistics.ibuffers_count; + m_statistics.total_indices_gpu_size += static_cast(size_bytes); + m_statistics.max_ibuffer_gpu_size = std::max(m_statistics.max_ibuffer_gpu_size, static_cast(size_bytes)); + ++m_statistics.ibuffers_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS - glsafe(::glGenBuffers(1, &ibuf.ibo)); - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibuf.ibo)); - glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, size_bytes, i_buffer.data(), GL_STATIC_DRAW)); - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + glsafe(::glGenBuffers(1, &ibuf.ibo)); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibuf.ibo)); + glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, size_bytes, i_buffer.data(), GL_STATIC_DRAW)); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + } +#if ENABLE_SEAMS_USING_MODELS } +#endif // ENABLE_SEAMS_USING_MODELS } if (progress_dialog != nullptr) { @@ -1921,7 +1980,7 @@ void GCodeViewer::load_shells(const Print& print, bool initialized) const double max_z = print.objects()[0]->model_object()->get_model()->bounding_box().max(2); const PrintConfig& config = print.config(); const size_t extruders_count = config.nozzle_diameter.size(); - if ((extruders_count > 1) && config.wipe_tower && !config.complete_objects) { + if (extruders_count > 1 && config.wipe_tower && !config.complete_objects) { const float depth = print.wipe_tower_data(extruders_count).depth; const float brim_width = print.wipe_tower_data(extruders_count).brim_width; @@ -2014,8 +2073,8 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool path.sub_paths.back().last = buffer.paths[last].sub_paths.back().last; } - size_t min_s_id = m_layers.get_endpoints_at(min_id).first; - size_t max_s_id = m_layers.get_endpoints_at(max_id).last; + const size_t min_s_id = m_layers.get_endpoints_at(min_id).first; + const size_t max_s_id = m_layers.get_endpoints_at(max_id).last; return (min_s_id <= path.sub_paths.front().first.s_id && path.sub_paths.front().first.s_id <= max_s_id) || (min_s_id <= path.sub_paths.back().last.s_id && path.sub_paths.back().last.s_id <= max_s_id); @@ -2026,7 +2085,7 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool statistics->render_paths_size = 0; #endif // ENABLE_GCODE_VIEWER_STATISTICS - bool top_layer_only = get_app_config()->get("seq_top_layer_only") == "1"; + const bool top_layer_only = get_app_config()->get("seq_top_layer_only") == "1"; SequentialView::Endpoints global_endpoints = { m_moves_count , 0 }; SequentialView::Endpoints top_layer_endpoints = global_endpoints; @@ -2044,39 +2103,62 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool if (!buffer.visible) continue; - for (size_t i = 0; i < buffer.paths.size(); ++i) { - const Path& path = buffer.paths[i]; - if (path.type == EMoveType::Travel) { - if (!is_travel_in_layers_range(i, m_layers_z_range[0], m_layers_z_range[1])) +#if ENABLE_SEAMS_USING_MODELS + if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Model) { + for (const TBuffer::Model::Instance& inst : buffer.model.instances) { + if (inst.s_id < m_layers.get_endpoints_at(m_layers_z_range[0]).first || m_layers.get_endpoints_at(m_layers_z_range[1]).last < inst.s_id) continue; + + global_endpoints.first = std::min(global_endpoints.first, inst.s_id); + global_endpoints.last = std::max(global_endpoints.last, inst.s_id); + + if (top_layer_only) { + if (inst.s_id < m_layers.get_endpoints_at(m_layers_z_range[1]).first || m_layers.get_endpoints_at(m_layers_z_range[1]).last < inst.s_id) + continue; + + top_layer_endpoints.first = std::min(top_layer_endpoints.first, inst.s_id); + top_layer_endpoints.last = std::max(top_layer_endpoints.last, inst.s_id); + } } - else if (!is_in_layers_range(path, m_layers_z_range[0], m_layers_z_range[1])) - continue; - - if (path.type == EMoveType::Extrude && !is_visible(path)) - continue; - - // store valid path - for (size_t j = 0; j < path.sub_paths.size(); ++j) { - paths.push_back({ static_cast(b), path.sub_paths[j].first.b_id, static_cast(i), static_cast(j) }); - } - - global_endpoints.first = std::min(global_endpoints.first, path.sub_paths.front().first.s_id); - global_endpoints.last = std::max(global_endpoints.last, path.sub_paths.back().last.s_id); - - if (top_layer_only) { + } + else { +#endif // ENABLE_SEAMS_USING_MODELS + for (size_t i = 0; i < buffer.paths.size(); ++i) { + const Path& path = buffer.paths[i]; if (path.type == EMoveType::Travel) { - if (is_travel_in_layers_range(i, m_layers_z_range[1], m_layers_z_range[1])) { + if (!is_travel_in_layers_range(i, m_layers_z_range[0], m_layers_z_range[1])) + continue; + } + else if (!is_in_layers_range(path, m_layers_z_range[0], m_layers_z_range[1])) + continue; + + if (path.type == EMoveType::Extrude && !is_visible(path)) + continue; + + // store valid path + for (size_t j = 0; j < path.sub_paths.size(); ++j) { + paths.push_back({ static_cast(b), path.sub_paths[j].first.b_id, static_cast(i), static_cast(j) }); + } + + global_endpoints.first = std::min(global_endpoints.first, path.sub_paths.front().first.s_id); + global_endpoints.last = std::max(global_endpoints.last, path.sub_paths.back().last.s_id); + + if (top_layer_only) { + if (path.type == EMoveType::Travel) { + if (is_travel_in_layers_range(i, m_layers_z_range[1], m_layers_z_range[1])) { + top_layer_endpoints.first = std::min(top_layer_endpoints.first, path.sub_paths.front().first.s_id); + top_layer_endpoints.last = std::max(top_layer_endpoints.last, path.sub_paths.back().last.s_id); + } + } + else if (is_in_layers_range(path, m_layers_z_range[1], m_layers_z_range[1])) { top_layer_endpoints.first = std::min(top_layer_endpoints.first, path.sub_paths.front().first.s_id); top_layer_endpoints.last = std::max(top_layer_endpoints.last, path.sub_paths.back().last.s_id); } } - else if (is_in_layers_range(path, m_layers_z_range[1], m_layers_z_range[1])) { - top_layer_endpoints.first = std::min(top_layer_endpoints.first, path.sub_paths.front().first.s_id); - top_layer_endpoints.last = std::max(top_layer_endpoints.last, path.sub_paths.back().last.s_id); - } } +#if ENABLE_SEAMS_USING_MODELS } +#endif // ENABLE_SEAMS_USING_MODELS } // update current sequential position @@ -2086,42 +2168,57 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool // get the world position from gpu bool found = false; for (const TBuffer& buffer : m_buffers) { - // searches the path containing the current position - for (const Path& path : buffer.paths) { - if (path.contains(m_sequential_view.current.last)) { - int sub_path_id = path.get_id_of_sub_path_containing(m_sequential_view.current.last); - if (sub_path_id != -1) { - const Path::Sub_Path& sub_path = path.sub_paths[sub_path_id]; - unsigned int offset = static_cast(m_sequential_view.current.last - sub_path.first.s_id); - if (offset > 0) { - if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Line) - offset = 2 * offset - 1; - else if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Triangle) { - unsigned int indices_count = buffer.indices_per_segment(); - offset = indices_count * (offset - 1) + (indices_count - 2); - if (sub_path_id == 0) - offset += 6; // add 2 triangles for starting cap - } - } - offset += static_cast(sub_path.first.i_id); - - // gets the vertex index from the index buffer on gpu - const IBuffer& i_buffer = buffer.indices[sub_path.first.b_id]; - unsigned int index = 0; - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, i_buffer.ibo)); - glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, static_cast(offset * sizeof(IBufferType)), static_cast(sizeof(IBufferType)), static_cast(&index))); - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); - - // gets the position from the vertices buffer on gpu - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, i_buffer.vbo)); - glsafe(::glGetBufferSubData(GL_ARRAY_BUFFER, static_cast(index * buffer.vertices.vertex_size_bytes()), static_cast(3 * sizeof(float)), static_cast(sequential_view->current_position.data()))); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); - +#if ENABLE_SEAMS_USING_MODELS + if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Model) { + for (const TBuffer::Model::Instance& inst : buffer.model.instances) { + if (inst.s_id == m_sequential_view.current.last) { + sequential_view->current_position = inst.position; found = true; break; } } } + else { +#endif // ENABLE_SEAMS_USING_MODELS + // searches the path containing the current position + for (const Path& path : buffer.paths) { + if (path.contains(m_sequential_view.current.last)) { + const int sub_path_id = path.get_id_of_sub_path_containing(m_sequential_view.current.last); + if (sub_path_id != -1) { + const Path::Sub_Path& sub_path = path.sub_paths[sub_path_id]; + unsigned int offset = static_cast(m_sequential_view.current.last - sub_path.first.s_id); + if (offset > 0) { + if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Line) + offset = 2 * offset - 1; + else if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Triangle) { + unsigned int indices_count = buffer.indices_per_segment(); + offset = indices_count * (offset - 1) + (indices_count - 2); + if (sub_path_id == 0) + offset += 6; // add 2 triangles for starting cap + } + } + offset += static_cast(sub_path.first.i_id); + + // gets the vertex index from the index buffer on gpu + const IBuffer& i_buffer = buffer.indices[sub_path.first.b_id]; + unsigned int index = 0; + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, i_buffer.ibo)); + glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, static_cast(offset * sizeof(IBufferType)), static_cast(sizeof(IBufferType)), static_cast(&index))); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + + // gets the position from the vertices buffer on gpu + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, i_buffer.vbo)); + glsafe(::glGetBufferSubData(GL_ARRAY_BUFFER, static_cast(index * buffer.vertices.vertex_size_bytes()), static_cast(3 * sizeof(float)), static_cast(sequential_view->current_position.data()))); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + + found = true; + break; + } + } + } +#if ENABLE_SEAMS_USING_MODELS + } +#endif // ENABLE_SEAMS_USING_MODELS if (found) break; @@ -2230,6 +2327,9 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool // set sequential data to their final value sequential_view->endpoints = top_layer_only ? top_layer_endpoints : global_endpoints; sequential_view->current.first = !top_layer_only && keep_sequential_current_first ? std::clamp(sequential_view->current.first, sequential_view->endpoints.first, sequential_view->endpoints.last) : sequential_view->endpoints.first; +#if ENABLE_SEAMS_USING_MODELS + sequential_view->global = global_endpoints; +#endif // ENABLE_SEAMS_USING_MODELS // updates sequential range caps std::array* sequential_range_caps = const_cast*>(&m_sequential_range_caps); @@ -2351,6 +2451,9 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool statistics->render_paths_size += SLIC3R_STDVEC_MEMSIZE(path.sizes, unsigned int); statistics->render_paths_size += SLIC3R_STDVEC_MEMSIZE(path.offsets, size_t); } +#if ENABLE_SEAMS_USING_MODELS + statistics->models_instances_size += SLIC3R_STDVEC_MEMSIZE(buffer.model.instances, TBuffer::Model::Instance); +#endif // ENABLE_SEAMS_USING_MODELS } statistics->refresh_paths_time = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start_time).count(); #endif // ENABLE_GCODE_VIEWER_STATISTICS @@ -2439,17 +2542,49 @@ void GCodeViewer::render_toolpaths() } }; +#if ENABLE_SEAMS_USING_MODELS +#if ENABLE_GCODE_VIEWER_STATISTICS + auto render_as_instanced_model = [this] +#else + auto render_as_instanced_model = [] +#endif // ENABLE_GCODE_VIEWER_STATISTICS + (TBuffer & buffer, GLShaderProgram & shader) { + for (const TBuffer::Model::Instance& inst : buffer.model.instances) { + bool top_layer_only = get_app_config()->get("seq_top_layer_only") == "1"; + bool visible = top_layer_only ? + m_sequential_view.global.first <= inst.s_id && inst.s_id <= m_sequential_view.global.last : + m_sequential_view.current.first <= inst.s_id && inst.s_id <= m_sequential_view.current.last; + + if (visible) { + glsafe(::glPushMatrix()); + glsafe(::glTranslatef(inst.position.x(), inst.position.y(), inst.position.z() - 0.5f * inst.height)); + glsafe(::glScalef(inst.width, inst.width, inst.height)); + Color color = (top_layer_only && m_sequential_view.current.last != m_sequential_view.global.last && inst.s_id < m_sequential_view.endpoints.first) ? + Neutral_Color : buffer.model.color; + buffer.model.model.set_color(-1, color); + buffer.model.model.render(); + glsafe(::glPopMatrix()); +#if ENABLE_GCODE_VIEWER_STATISTICS + ++m_statistics.gl_models_calls_count; +#endif // ENABLE_GCODE_VIEWER_STATISTICS + } + } + }; +#endif // ENABLE_SEAMS_USING_MODELS + auto line_width = [](double zoom) { return (zoom < 5.0) ? 1.0 : (1.0 + 5.0 * (zoom - 5.0) / (100.0 - 5.0)); }; - glsafe(::glLineWidth(static_cast(line_width(zoom)))); - unsigned char begin_id = buffer_id(EMoveType::Retract); unsigned char end_id = buffer_id(EMoveType::Count); for (unsigned char i = begin_id; i < end_id; ++i) { +#if ENABLE_SEAMS_USING_MODELS + TBuffer& buffer = m_buffers[i]; +#else const TBuffer& buffer = m_buffers[i]; +#endif // ENABLE_SEAMS_USING_MODELS if (!buffer.visible || !buffer.has_data()) continue; @@ -2457,44 +2592,56 @@ void GCodeViewer::render_toolpaths() if (shader != nullptr) { shader->start_using(); - for (size_t j = 0; j < buffer.indices.size(); ++j) { - const IBuffer& i_buffer = buffer.indices[j]; - - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, i_buffer.vbo)); - glsafe(::glVertexPointer(buffer.vertices.position_size_floats(), GL_FLOAT, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.position_offset_bytes())); - glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); - bool has_normals = buffer.vertices.normal_size_floats() > 0; - if (has_normals) { - glsafe(::glNormalPointer(GL_FLOAT, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.normal_offset_bytes())); - glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); - } - - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, i_buffer.ibo)); - - switch (buffer.render_primitive_type) - { - case TBuffer::ERenderPrimitiveType::Point: { - render_as_points(buffer, static_cast(j), *shader); - break; - } - case TBuffer::ERenderPrimitiveType::Line: { - render_as_lines(buffer, static_cast(j), *shader); - break; - } - case TBuffer::ERenderPrimitiveType::Triangle: { - render_as_triangles(buffer, static_cast(j), *shader); - break; - } - } - - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); - - if (has_normals) - glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); - - glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); +#if ENABLE_SEAMS_USING_MODELS + if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Model) { + shader->set_uniform("emission_factor", 0.25f); + render_as_instanced_model(buffer, *shader); + shader->set_uniform("emission_factor", 0.0f); } + else { +#endif // ENABLE_SEAMS_USING_MODELS + for (size_t j = 0; j < buffer.indices.size(); ++j) { + const IBuffer& i_buffer = buffer.indices[j]; + + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, i_buffer.vbo)); + glsafe(::glVertexPointer(buffer.vertices.position_size_floats(), GL_FLOAT, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.position_offset_bytes())); + glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); + bool has_normals = buffer.vertices.normal_size_floats() > 0; + if (has_normals) { + glsafe(::glNormalPointer(GL_FLOAT, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.normal_offset_bytes())); + glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); + } + + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, i_buffer.ibo)); + + switch (buffer.render_primitive_type) + { + case TBuffer::ERenderPrimitiveType::Point: { + render_as_points(buffer, static_cast(j), *shader); + break; + } + case TBuffer::ERenderPrimitiveType::Line: { + glsafe(::glLineWidth(static_cast(line_width(zoom)))); + render_as_lines(buffer, static_cast(j), *shader); + break; + } + case TBuffer::ERenderPrimitiveType::Triangle: { + render_as_triangles(buffer, static_cast(j), *shader); + break; + } + } + + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + + if (has_normals) + glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); + + glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + } +#if ENABLE_SEAMS_USING_MODELS + } +#endif // ENABLE_SEAMS_USING_MODELS shader->stop_using(); } @@ -3488,6 +3635,9 @@ void GCodeViewer::render_statistics() add_counter(std::string("Multi GL_LINES:"), m_statistics.gl_multi_lines_calls_count); add_counter(std::string("Multi GL_TRIANGLES:"), m_statistics.gl_multi_triangles_calls_count); add_counter(std::string("GL_TRIANGLES:"), m_statistics.gl_triangles_calls_count); +#if ENABLE_SEAMS_USING_MODELS + add_counter(std::string("Models:"), m_statistics.gl_models_calls_count); +#endif // ENABLE_SEAMS_USING_MODELS } if (ImGui::CollapsingHeader("CPU memory")) { @@ -3496,6 +3646,9 @@ void GCodeViewer::render_statistics() ImGui::Separator(); add_memory(std::string("Paths:"), m_statistics.paths_size); add_memory(std::string("Render paths:"), m_statistics.render_paths_size); +#if ENABLE_SEAMS_USING_MODELS + add_memory(std::string("Models instances:"), m_statistics.models_instances_size); +#endif // ENABLE_SEAMS_USING_MODELS } if (ImGui::CollapsingHeader("GPU memory")) { diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 3d9b9bb69..53bc66def 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -81,7 +81,10 @@ class GCodeViewer size_t position_size_floats() const { return 3; } size_t position_size_bytes() const { return position_size_floats() * sizeof(float); } - size_t normal_offset_floats() const { return position_size_floats(); } + size_t normal_offset_floats() const { + assert(format == EFormat::PositionNormal1 || format == EFormat::PositionNormal3); + return position_size_floats(); + } size_t normal_offset_bytes() const { return normal_offset_floats() * sizeof(float); } size_t normal_size_floats() const { @@ -230,13 +233,43 @@ class GCodeViewer { Point, Line, +#if ENABLE_SEAMS_USING_MODELS + Triangle, + Model +#else Triangle +#endif // ENABLE_SEAMS_USING_MODELS }; ERenderPrimitiveType render_primitive_type; + + // buffers for point, line and triangle primitive types VBuffer vertices; std::vector indices; +#if ENABLE_SEAMS_USING_MODELS + struct Model + { + struct Instance + { + Vec3f position; + float width; + float height; + size_t s_id; + }; + using Instances = std::vector; + + GLModel model; + Color color; + Instances instances; + + void reset(); + }; + + // contain the buffer for model primitive types + Model model; +#endif // ENABLE_SEAMS_USING_MODELS + std::string shader; std::vector paths; // std::set seems to perform significantly better, at least on Windows. @@ -284,9 +317,24 @@ class GCodeViewer } size_t max_indices_per_segment_size_bytes() const { return max_indices_per_segment() * sizeof(IBufferType); } +#if ENABLE_SEAMS_USING_MODELS + bool has_data() const { + switch (render_primitive_type) + { + case ERenderPrimitiveType::Point: + case ERenderPrimitiveType::Line: + case ERenderPrimitiveType::Triangle: { + return !vertices.vbos.empty() && vertices.vbos.front() != 0 && !indices.empty() && indices.front().ibo != 0; + } + case ERenderPrimitiveType::Model: { return model.model.is_initialized() && !model.instances.empty(); } + default: { return false; } + } + } +#else bool has_data() const { return !vertices.vbos.empty() && vertices.vbos.front() != 0 && !indices.empty() && indices.front().ibo != 0; } +#endif // ENABLE_SEAMS_USING_MODELS }; // helper to render shells @@ -434,6 +482,9 @@ class GCodeViewer int64_t gl_multi_lines_calls_count{ 0 }; int64_t gl_multi_triangles_calls_count{ 0 }; int64_t gl_triangles_calls_count{ 0 }; +#if ENABLE_SEAMS_USING_MODELS + int64_t gl_models_calls_count{ 0 }; +#endif // ENABLE_SEAMS_USING_MODELS // memory int64_t results_size{ 0 }; int64_t total_vertices_gpu_size{ 0 }; @@ -442,6 +493,9 @@ class GCodeViewer int64_t max_ibuffer_gpu_size{ 0 }; int64_t paths_size{ 0 }; int64_t render_paths_size{ 0 }; +#if ENABLE_SEAMS_USING_MODELS + int64_t models_instances_size{ 0 }; +#endif // ENABLE_SEAMS_USING_MODELS // other int64_t travel_segments_count{ 0 }; int64_t wipe_segments_count{ 0 }; @@ -471,6 +525,9 @@ class GCodeViewer gl_multi_lines_calls_count = 0; gl_multi_triangles_calls_count = 0; gl_triangles_calls_count = 0; +#if ENABLE_SEAMS_USING_MODELS + gl_models_calls_count = 0; +#endif // ENABLE_SEAMS_USING_MODELS } void reset_sizes() { @@ -481,6 +538,9 @@ class GCodeViewer max_ibuffer_gpu_size = 0; paths_size = 0; render_paths_size = 0; +#if ENABLE_SEAMS_USING_MODELS + models_instances_size = 0; +#endif // ENABLE_SEAMS_USING_MODELS } void reset_others() { @@ -564,6 +624,9 @@ public: Endpoints endpoints; Endpoints current; Endpoints last_current; +#if ENABLE_SEAMS_USING_MODELS + Endpoints global; +#endif // ENABLE_SEAMS_USING_MODELS Vec3f current_position{ Vec3f::Zero() }; Marker marker; GCodeWindow gcode_window; From 1b03eec234089149ec779374e5b5978a0f445a0e Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 4 Aug 2021 15:23:37 +0200 Subject: [PATCH 07/18] Fixed build of tech ENABLE_SEAMS_USING_MODELS when tech ENABLE_GCODE_VIEWER_STATISTICS is disabled --- src/slic3r/GUI/GCodeViewer.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 418d00972..cc25c31d8 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -2543,11 +2543,7 @@ void GCodeViewer::render_toolpaths() }; #if ENABLE_SEAMS_USING_MODELS -#if ENABLE_GCODE_VIEWER_STATISTICS auto render_as_instanced_model = [this] -#else - auto render_as_instanced_model = [] -#endif // ENABLE_GCODE_VIEWER_STATISTICS (TBuffer & buffer, GLShaderProgram & shader) { for (const TBuffer::Model::Instance& inst : buffer.model.instances) { bool top_layer_only = get_app_config()->get("seq_top_layer_only") == "1"; From fd81041adb8e637c4b9422a1c97d723a410cb69c Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 5 Aug 2021 08:10:42 +0200 Subject: [PATCH 08/18] Fixed build warnings on non-Windows OS --- src/slic3r/GUI/GCodeViewer.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index cc25c31d8..87e24c957 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -1818,6 +1818,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) add_indices_as_solid(prev, curr, next, t_buffer, curr_vertex_buffer.second, static_cast(i_multibuffer.size()) - 1, i_buffer, i); break; } + default: { break; } } } @@ -2286,6 +2287,7 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool size_in_indices = buffer.indices_per_segment() * segments_count; break; } + default: { break; } } if (size_in_indices == 0) @@ -2625,6 +2627,7 @@ void GCodeViewer::render_toolpaths() render_as_triangles(buffer, static_cast(j), *shader); break; } + default: { break; } } glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); From 8c4e203e1d90b0003fe584edb522c1ae12048120 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 5 Aug 2021 09:09:07 +0200 Subject: [PATCH 09/18] Tech ENABLE_SEAMS_USING_MODELS -> Use new options visualization only if OpenGL 3.1 or greater is detected --- src/slic3r/GUI/GCodeViewer.cpp | 44 +++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 87e24c957..42c34b59b 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -545,6 +545,7 @@ const GCodeViewer::Color GCodeViewer::Neutral_Color = { 0.25f, 0.25f, 0.25f, 1.0 GCodeViewer::GCodeViewer() { +#if !ENABLE_SEAMS_USING_MODELS // initializes non OpenGL data of TBuffers // OpenGL data are initialized into render().init_gl_data() for (size_t i = 0; i < m_buffers.size(); ++i) { @@ -552,18 +553,6 @@ GCodeViewer::GCodeViewer() switch (buffer_type(i)) { default: { break; } -#if ENABLE_SEAMS_USING_MODELS - case EMoveType::Tool_change: - case EMoveType::Color_change: - case EMoveType::Pause_Print: - case EMoveType::Custom_GCode: - case EMoveType::Retract: - case EMoveType::Unretract: - case EMoveType::Seam: { - buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::Model; - break; - } -#else case EMoveType::Tool_change: case EMoveType::Color_change: case EMoveType::Pause_Print: @@ -575,7 +564,6 @@ GCodeViewer::GCodeViewer() buffer.vertices.format = VBuffer::EFormat::Position; break; } -#endif // ENABLE_SEAMS_USING_MODELS case EMoveType::Wipe: case EMoveType::Extrude: { buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::Triangle; @@ -591,6 +579,8 @@ GCodeViewer::GCodeViewer() } set_toolpath_move_type_visible(EMoveType::Extrude, true); +#endif // !ENABLE_SEAMS_USING_MODELS + // m_sequential_view.skip_invisible_moves = true; } @@ -797,25 +787,47 @@ void GCodeViewer::render() case EMoveType::Unretract: case EMoveType::Seam: { #if ENABLE_SEAMS_USING_MODELS - buffer.shader = "gouraud_light"; - buffer.model.model.init_from(diamond(16)); - buffer.model.color = option_color(type); + if (wxGetApp().is_gl_version_greater_or_equal_to(3, 1)) { + buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::Model; + buffer.shader = "gouraud_light"; + buffer.model.model.init_from(diamond(16)); + buffer.model.color = option_color(type); + } + else { + buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::Point; + buffer.vertices.format = VBuffer::EFormat::Position; + buffer.shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120" : "options_110"; + } break; #else + buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::Point; + buffer.vertices.format = VBuffer::EFormat::Position; buffer.shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120" : "options_110"; break; #endif // ENABLE_SEAMS_USING_MODELS } case EMoveType::Wipe: case EMoveType::Extrude: { +#if ENABLE_SEAMS_USING_MODELS + buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::Triangle; + buffer.vertices.format = VBuffer::EFormat::PositionNormal3; +#endif // ENABLE_SEAMS_USING_MODELS buffer.shader = "gouraud_light"; break; } case EMoveType::Travel: { +#if ENABLE_SEAMS_USING_MODELS + buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::Line; + buffer.vertices.format = VBuffer::EFormat::PositionNormal1; +#endif // ENABLE_SEAMS_USING_MODELS buffer.shader = "toolpaths_lines"; break; } } + +#if ENABLE_SEAMS_USING_MODELS + set_toolpath_move_type_visible(EMoveType::Extrude, true); +#endif // ENABLE_SEAMS_USING_MODELS } // initializes tool marker From 73464c76b9cb36f81e1710e9b0a4404094e1ee38 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 5 Aug 2021 09:35:12 +0200 Subject: [PATCH 10/18] Techs ENABLE_SEAMS_USING_MODELS + ENABLE_GCODE_VIEWER_STATISTICS -> Fixed detection of used memory to store instances data --- src/slic3r/GUI/GCodeViewer.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 42c34b59b..860d693cc 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -2096,6 +2096,9 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool #if ENABLE_GCODE_VIEWER_STATISTICS Statistics* statistics = const_cast(&m_statistics); statistics->render_paths_size = 0; +#if ENABLE_SEAMS_USING_MODELS + statistics->models_instances_size = 0; +#endif // ENABLE_SEAMS_USING_MODELS #endif // ENABLE_GCODE_VIEWER_STATISTICS const bool top_layer_only = get_app_config()->get("seq_top_layer_only") == "1"; From 252935dde74c18c5ee837c4b3a32039105411c24 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 5 Aug 2021 10:19:02 +0200 Subject: [PATCH 11/18] Techs ENABLE_SEAMS_USING_MODELS + ENABLE_GCODE_VIEWER_STATISTICS -> Added instances counter --- src/slic3r/GUI/GCodeViewer.cpp | 21 ++++++++++++++++++++- src/slic3r/GUI/GCodeViewer.hpp | 6 ++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 860d693cc..8730493cb 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -1514,7 +1514,14 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) case TBuffer::ERenderPrimitiveType::Line: { add_vertices_as_line(prev, curr, v_buffer); break; } case TBuffer::ERenderPrimitiveType::Triangle: { add_vertices_as_solid(prev, curr, t_buffer, static_cast(v_multibuffer.size()) - 1, v_buffer, i); break; } #if ENABLE_SEAMS_USING_MODELS - case TBuffer::ERenderPrimitiveType::Model: { add_model_instance(curr, t_buffer.model.instances, i); break; } + case TBuffer::ERenderPrimitiveType::Model: + { + add_model_instance(curr, t_buffer.model.instances, i); +#if ENABLE_GCODE_VIEWER_STATISTICS + ++m_statistics.instances_count; +#endif // ENABLE_GCODE_VIEWER_STATISTICS + break; + } #endif // ENABLE_SEAMS_USING_MODELS } @@ -1686,6 +1693,15 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) } } +#if ENABLE_SEAMS_USING_MODELS + for (size_t i = 0; i < m_buffers.size(); ++i) { + TBuffer& t_buffer = m_buffers[i]; + if (t_buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Model) { + t_buffer.model.instances.shrink_to_fit(); + } + } +#endif // ENABLE_SEAMS_USING_MODELS + // move the wipe toolpaths half height up to render them on proper position MultiVertexBuffer& wipe_vertices = vertices[buffer_id(EMoveType::Wipe)]; for (VertexBuffer& v_buffer : wipe_vertices) { @@ -3677,6 +3693,9 @@ void GCodeViewer::render_statistics() add_counter(std::string("Travel segments count:"), m_statistics.travel_segments_count); add_counter(std::string("Wipe segments count:"), m_statistics.wipe_segments_count); add_counter(std::string("Extrude segments count:"), m_statistics.extrude_segments_count); +#if ENABLE_SEAMS_USING_MODELS + add_counter(std::string("Instances count:"), m_statistics.instances_count); +#endif // ENABLE_SEAMS_USING_MODELS ImGui::Separator(); add_counter(std::string("VBuffers count:"), m_statistics.vbuffers_count); add_counter(std::string("IBuffers count:"), m_statistics.ibuffers_count); diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 53bc66def..6103f9722 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -500,6 +500,9 @@ class GCodeViewer int64_t travel_segments_count{ 0 }; int64_t wipe_segments_count{ 0 }; int64_t extrude_segments_count{ 0 }; +#if ENABLE_SEAMS_USING_MODELS + int64_t instances_count{ 0 }; +#endif // ENABLE_SEAMS_USING_MODELS int64_t vbuffers_count{ 0 }; int64_t ibuffers_count{ 0 }; @@ -547,6 +550,9 @@ class GCodeViewer travel_segments_count = 0; wipe_segments_count = 0; extrude_segments_count = 0; +#if ENABLE_SEAMS_USING_MODELS + instances_count = 0; +#endif // ENABLE_SEAMS_USING_MODELS vbuffers_count = 0; ibuffers_count = 0; } From 34da899c66271262f6c9e8c402d7b2c49decca0c Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 5 Aug 2021 15:08:49 +0200 Subject: [PATCH 12/18] Temporary tech ENABLE_SEAMS_USING_INSTANCED_MODELS -> WIP (still missing opengl calls) --- src/libslic3r/Technologies.hpp | 6 ++ src/slic3r/GUI/GCodeViewer.cpp | 140 +++++++++++++++++++++++++++++++++ src/slic3r/GUI/GCodeViewer.hpp | 47 +++++++++++ 3 files changed, 193 insertions(+) diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 768b0cb6a..79976d4a0 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -49,6 +49,12 @@ #define ENABLE_SINKING_CONTOURS (1 && ENABLE_2_4_0_ALPHA0) // Enable rendering seams (and other options) in preview using models #define ENABLE_SEAMS_USING_MODELS (1 && ENABLE_2_4_0_ALPHA0) +// Enable rendering seams (and other options) in preview using instanced models +// references: +// https://ogldev.org/www/tutorial33/tutorial33.html +// https://docs.gl/gl3/glDrawElementsInstanced +// https://www.khronos.org/opengl/wiki/Vertex_Rendering#Instancing +#define ENABLE_SEAMS_USING_INSTANCED_MODELS (1 && ENABLE_SEAMS_USING_MODELS) #endif // _prusaslicer_technologies_h_ diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 8730493cb..b8388f82f 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -95,6 +95,17 @@ void GCodeViewer::VBuffer::reset() count = 0; } +#if ENABLE_SEAMS_USING_INSTANCED_MODELS +void GCodeViewer::InstanceVBuffer::reset() +{ + // release gpu memory + if (vbo > 0) + glsafe(::glDeleteBuffers(1, &vbo)); + s_ids.clear(); + render_range = { 0, 0 }; +} +#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS + void GCodeViewer::IBuffer::reset() { // release gpu memory @@ -140,6 +151,9 @@ bool GCodeViewer::Path::matches(const GCodeProcessor::MoveVertex& move) const void GCodeViewer::TBuffer::Model::reset() { instances.clear(); +#if ENABLE_SEAMS_USING_INSTANCED_MODELS + instances2.reset(); +#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS } #endif // ENABLE_SEAMS_USING_MODELS @@ -1422,6 +1436,23 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) instance.s_id = move_id; instances.emplace_back(instance); }; + +#if ENABLE_SEAMS_USING_INSTANCED_MODELS + // format data into the buffers to be rendered as model + auto add_model_instance_2 = [](const GCodeProcessor::MoveVertex& curr, InstanceBuffer& instances, InstanceIdBuffer& instances_ids, size_t move_id) { + // append position + instances.push_back(curr.position.x()); + instances.push_back(curr.position.y()); + instances.push_back(curr.position.z()); + // append width + instances.push_back(1.2f * curr.width); + // append height + instances.push_back(1.2f * curr.height); + + // append id + instances_ids.push_back(move_id); + }; +#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS #endif // ENABLE_SEAMS_USING_MODELS #if ENABLE_GCODE_VIEWER_STATISTICS @@ -1466,6 +1497,10 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) std::vector vertices(m_buffers.size()); std::vector indices(m_buffers.size()); +#if ENABLE_SEAMS_USING_INSTANCED_MODELS + std::vector instances(m_buffers.size()); + std::vector instances_ids(m_buffers.size()); +#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS std::vector options_zs; // toolpaths data -> extract vertices from result @@ -1490,6 +1525,10 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) const unsigned char id = buffer_id(curr.type); TBuffer& t_buffer = m_buffers[id]; MultiVertexBuffer& v_multibuffer = vertices[id]; +#if ENABLE_SEAMS_USING_INSTANCED_MODELS + InstanceBuffer& inst_buffer = instances[id]; + InstanceIdBuffer& inst_id_buffer = instances_ids[id]; +#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS // ensure there is at least one vertex buffer if (v_multibuffer.empty()) @@ -1517,6 +1556,9 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) case TBuffer::ERenderPrimitiveType::Model: { add_model_instance(curr, t_buffer.model.instances, i); +#if ENABLE_SEAMS_USING_INSTANCED_MODELS + add_model_instance_2(curr, inst_buffer, inst_id_buffer, i); +#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS #if ENABLE_GCODE_VIEWER_STATISTICS ++m_statistics.instances_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS @@ -1714,7 +1756,31 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) for (size_t i = 0; i < m_buffers.size(); ++i) { TBuffer& t_buffer = m_buffers[i]; #if ENABLE_SEAMS_USING_MODELS +#if ENABLE_SEAMS_USING_INSTANCED_MODELS + if (t_buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Model) { + const InstanceBuffer& inst_buffer = instances[i]; + if (!inst_buffer.empty()) { + const size_t size_bytes = inst_buffer.size() * sizeof(float); + +#if ENABLE_GCODE_VIEWER_STATISTICS + m_statistics.total_instances_gpu_size += static_cast(size_bytes); + m_statistics.max_instance_vbuffer_gpu_size = std::max(m_statistics.max_instance_vbuffer_gpu_size, static_cast(size_bytes)); +#endif // ENABLE_GCODE_VIEWER_STATISTICS + + GLuint id = 0; + glsafe(::glGenBuffers(1, &id)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, id)); + glsafe(::glBufferData(GL_ARRAY_BUFFER, size_bytes, inst_buffer.data(), GL_STATIC_DRAW)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + + t_buffer.model.instances2.vbo = id; + t_buffer.model.instances2.s_ids = instances_ids[i]; + } + } + else { +#else if (t_buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::Model) { +#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS #endif // ENABLE_SEAMS_USING_MODELS const MultiVertexBuffer& v_multibuffer = vertices[i]; for (const VertexBuffer& v_buffer : v_multibuffer) { @@ -1751,6 +1817,10 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) // dismiss vertices data, no more needed std::vector().swap(vertices); +#if ENABLE_SEAMS_USING_INSTANCED_MODELS + std::vector().swap(instances); + std::vector().swap(instances_ids); +#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS // toolpaths data -> extract indices from result // paths may have been filled while extracting vertices, @@ -2137,6 +2207,23 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool #if ENABLE_SEAMS_USING_MODELS if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Model) { +#if ENABLE_SEAMS_USING_INSTANCED_MODELS + for (size_t id : buffer.model.instances2.s_ids) { + if (id < m_layers.get_endpoints_at(m_layers_z_range[0]).first || m_layers.get_endpoints_at(m_layers_z_range[1]).last < id) + continue; + + global_endpoints.first = std::min(global_endpoints.first, id); + global_endpoints.last = std::max(global_endpoints.last, id); + + if (top_layer_only) { + if (id < m_layers.get_endpoints_at(m_layers_z_range[1]).first || m_layers.get_endpoints_at(m_layers_z_range[1]).last < id) + continue; + + top_layer_endpoints.first = std::min(top_layer_endpoints.first, id); + top_layer_endpoints.last = std::max(top_layer_endpoints.last, id); + } + } +#else for (const TBuffer::Model::Instance& inst : buffer.model.instances) { if (inst.s_id < m_layers.get_endpoints_at(m_layers_z_range[0]).first || m_layers.get_endpoints_at(m_layers_z_range[1]).last < inst.s_id) continue; @@ -2152,6 +2239,7 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool top_layer_endpoints.last = std::max(top_layer_endpoints.last, inst.s_id); } } +#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS } else { #endif // ENABLE_SEAMS_USING_MODELS @@ -2202,6 +2290,20 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool for (const TBuffer& buffer : m_buffers) { #if ENABLE_SEAMS_USING_MODELS if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Model) { +#if ENABLE_SEAMS_USING_INSTANCED_MODELS + for (size_t i = 0; i < buffer.model.instances2.s_ids.size(); ++i) { + if (buffer.model.instances2.s_ids[i] == m_sequential_view.current.last) { + + // gets the position from the vertices buffer on gpu + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, buffer.model.instances2.vbo)); + glsafe(::glGetBufferSubData(GL_ARRAY_BUFFER, static_cast(i * buffer.model.instances2.instance_size_bytes()), static_cast(3 * sizeof(float)), static_cast(sequential_view->current_position.data()))); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + + found = true; + break; + } + } +#else for (const TBuffer::Model::Instance& inst : buffer.model.instances) { if (inst.s_id == m_sequential_view.current.last) { sequential_view->current_position = inst.position; @@ -2209,6 +2311,7 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool break; } } +#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS } else { #endif // ENABLE_SEAMS_USING_MODELS @@ -2357,6 +2460,33 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool #endif } +#if ENABLE_SEAMS_USING_INSTANCED_MODELS + // second pass: for buffers using instanced models, update the instances render ranges + for (size_t b = 0; b < m_buffers.size(); ++b) { + TBuffer& buffer = const_cast(m_buffers[b]); + if (buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::Model) + continue; + + buffer.model.instances2.render_range = { 0, 0 }; + + if (!buffer.visible) + continue; + + if (m_sequential_view.current.first <= buffer.model.instances2.s_ids.back() && buffer.model.instances2.s_ids.front() <= m_sequential_view.current.last) { + for (size_t id : buffer.model.instances2.s_ids) { + if (id <= m_sequential_view.current.first) { + buffer.model.instances2.render_range.offset += buffer.model.instances2.instance_size_bytes(); + buffer.model.instances2.render_range.count = 0; + } + else if (id <= m_sequential_view.current.last) + ++buffer.model.instances2.render_range.count; + else + break; + } + } + } +#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS + // set sequential data to their final value sequential_view->endpoints = top_layer_only ? top_layer_endpoints : global_endpoints; sequential_view->current.first = !top_layer_only && keep_sequential_current_first ? std::clamp(sequential_view->current.first, sequential_view->endpoints.first, sequential_view->endpoints.last) : sequential_view->endpoints.first; @@ -2485,7 +2615,11 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool statistics->render_paths_size += SLIC3R_STDVEC_MEMSIZE(path.offsets, size_t); } #if ENABLE_SEAMS_USING_MODELS +#if ENABLE_SEAMS_USING_INSTANCED_MODELS + statistics->models_instances_size += SLIC3R_STDVEC_MEMSIZE(buffer.model.instances2.s_ids, size_t); +#else statistics->models_instances_size += SLIC3R_STDVEC_MEMSIZE(buffer.model.instances, TBuffer::Model::Instance); +#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS #endif // ENABLE_SEAMS_USING_MODELS } statistics->refresh_paths_time = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start_time).count(); @@ -3684,9 +3818,15 @@ void GCodeViewer::render_statistics() if (ImGui::CollapsingHeader("GPU memory")) { add_memory(std::string("Vertices:"), m_statistics.total_vertices_gpu_size); add_memory(std::string("Indices:"), m_statistics.total_indices_gpu_size); +#if ENABLE_SEAMS_USING_INSTANCED_MODELS + add_memory(std::string("Instances:"), m_statistics.total_instances_gpu_size); +#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS ImGui::Separator(); add_memory(std::string("Max VBuffer:"), m_statistics.max_vbuffer_gpu_size); add_memory(std::string("Max IBuffer:"), m_statistics.max_ibuffer_gpu_size); +#if ENABLE_SEAMS_USING_INSTANCED_MODELS + add_memory(std::string("Max instance VBuffer:"), m_statistics.max_instance_vbuffer_gpu_size); +#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS } if (ImGui::CollapsingHeader("Other")) { diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 6103f9722..7bf341a68 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -27,6 +27,10 @@ class GCodeViewer using MultiVertexBuffer = std::vector; using IndexBuffer = std::vector; using MultiIndexBuffer = std::vector; +#if ENABLE_SEAMS_USING_INSTANCED_MODELS + using InstanceBuffer = std::vector; + using InstanceIdBuffer = std::vector; +#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS static const std::vector Extrusion_Role_Colors; static const std::vector Options_Colors; @@ -100,6 +104,34 @@ class GCodeViewer void reset(); }; +#if ENABLE_SEAMS_USING_INSTANCED_MODELS + // vbo buffer containing instances data used to render a toolpaths using instanced models + // record format: 5 floats -> position.x|position.y|position.z|width|height + struct InstanceVBuffer + { + struct RenderRange + { + // offset in bytes of the 1st instance to render + unsigned int offset; + // count of instances to render + unsigned int count; + }; + + // vbo id + unsigned int vbo{ 0 }; + // move ids + std::vector s_ids; + RenderRange render_range; + + size_t data_size_bytes() const { return s_ids.size() * instance_size_bytes(); } + + size_t instance_size_floats() const { return 5; } + size_t instance_size_bytes() const { return instance_size_floats() * sizeof(float); } + + void reset(); + }; +#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS + // ibo buffer containing indices data (for lines/triangles) used to render a specific toolpath type struct IBuffer { @@ -262,6 +294,9 @@ class GCodeViewer GLModel model; Color color; Instances instances; +#if ENABLE_SEAMS_USING_INSTANCED_MODELS + InstanceVBuffer instances2; +#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS void reset(); }; @@ -489,8 +524,14 @@ class GCodeViewer int64_t results_size{ 0 }; int64_t total_vertices_gpu_size{ 0 }; int64_t total_indices_gpu_size{ 0 }; +#if ENABLE_SEAMS_USING_INSTANCED_MODELS + int64_t total_instances_gpu_size{ 0 }; +#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS int64_t max_vbuffer_gpu_size{ 0 }; int64_t max_ibuffer_gpu_size{ 0 }; +#if ENABLE_SEAMS_USING_INSTANCED_MODELS + int64_t max_instance_vbuffer_gpu_size{ 0 }; +#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS int64_t paths_size{ 0 }; int64_t render_paths_size{ 0 }; #if ENABLE_SEAMS_USING_MODELS @@ -537,8 +578,14 @@ class GCodeViewer results_size = 0; total_vertices_gpu_size = 0; total_indices_gpu_size = 0; +#if ENABLE_SEAMS_USING_INSTANCED_MODELS + total_instances_gpu_size = 0; +#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS max_vbuffer_gpu_size = 0; max_ibuffer_gpu_size = 0; +#if ENABLE_SEAMS_USING_INSTANCED_MODELS + max_instance_vbuffer_gpu_size = 0; +#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS paths_size = 0; render_paths_size = 0; #if ENABLE_SEAMS_USING_MODELS From 29804187060529c3fbc55ea737e728fd36be9826 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 26 Aug 2021 12:37:55 +0200 Subject: [PATCH 13/18] ENABLE_SEAMS_USING_INSTANCED_MODELS -> WIP: Render models using glDrawElementsInstanced --- resources/shaders/gouraud_light_instanced.fs | 12 +++ resources/shaders/gouraud_light_instanced.vs | 57 ++++++++++++++ src/libslic3r/Technologies.hpp | 4 - src/slic3r/GUI/GCodeViewer.cpp | 63 ++++++++++++---- src/slic3r/GUI/GCodeViewer.hpp | 28 ++++--- src/slic3r/GUI/GLModel.cpp | 79 ++++++++++++++++++++ src/slic3r/GUI/GLModel.hpp | 3 + src/slic3r/GUI/GLShadersManager.cpp | 14 +++- 8 files changed, 229 insertions(+), 31 deletions(-) create mode 100644 resources/shaders/gouraud_light_instanced.fs create mode 100644 resources/shaders/gouraud_light_instanced.vs diff --git a/resources/shaders/gouraud_light_instanced.fs b/resources/shaders/gouraud_light_instanced.fs new file mode 100644 index 000000000..970185a00 --- /dev/null +++ b/resources/shaders/gouraud_light_instanced.fs @@ -0,0 +1,12 @@ +#version 110 + +uniform vec4 uniform_color; +uniform float emission_factor; + +// x = tainted, y = specular; +varying vec2 intensity; + +void main() +{ + gl_FragColor = vec4(vec3(intensity.y) + uniform_color.rgb * (intensity.x + emission_factor), uniform_color.a); +} diff --git a/resources/shaders/gouraud_light_instanced.vs b/resources/shaders/gouraud_light_instanced.vs new file mode 100644 index 000000000..5d6a05a6f --- /dev/null +++ b/resources/shaders/gouraud_light_instanced.vs @@ -0,0 +1,57 @@ +#version 110 + +#define INTENSITY_CORRECTION 0.6 + +// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31) +const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929); +#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION) +#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION) +#define LIGHT_TOP_SHININESS 20.0 + +// normalized values for (1./1.43, 0.2/1.43, 1./1.43) +const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074); +#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION) + +#define INTENSITY_AMBIENT 0.3 + +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +// vertex attributes +in vec3 v_position; +in vec3 v_normal; +// instance attributes +in vec3 i_offset; +in vec2 i_scales; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + +// x = tainted, y = specular; +varying vec2 intensity; + +void main() +{ + // First transform the normal into camera space and normalize the result. +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + vec3 eye_normal = normalize(gl_NormalMatrix * v_normal); +// vec3 eye_normal = normalize(gl_NormalMatrix * gl_Normal); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + + // Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex. + // Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range. + float NdotL = max(dot(eye_normal, LIGHT_TOP_DIR), 0.0); + + intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + vec4 world_position = vec4(v_position * vec3(vec2(i_scales.x), i_scales.y) + i_offset, 1.0); + vec3 eye_position = (gl_ModelViewMatrix * world_position).xyz; +// vec3 eye_position = (gl_ModelViewMatrix * gl_Vertex).xyz; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(eye_position), reflect(-LIGHT_TOP_DIR, eye_normal)), 0.0), LIGHT_TOP_SHININESS); + + // Perform the same lighting calculation for the 2nd light source (no specular applied). + NdotL = max(dot(eye_normal, LIGHT_FRONT_DIR), 0.0); + intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; + +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + gl_Position = gl_ProjectionMatrix * vec4(eye_position, 1.0); +// gl_Position = ftransform(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +} diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 79976d4a0..0a6b47397 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -50,10 +50,6 @@ // Enable rendering seams (and other options) in preview using models #define ENABLE_SEAMS_USING_MODELS (1 && ENABLE_2_4_0_ALPHA0) // Enable rendering seams (and other options) in preview using instanced models -// references: -// https://ogldev.org/www/tutorial33/tutorial33.html -// https://docs.gl/gl3/glDrawElementsInstanced -// https://www.khronos.org/opengl/wiki/Vertex_Rendering#Instancing #define ENABLE_SEAMS_USING_INSTANCED_MODELS (1 && ENABLE_SEAMS_USING_MODELS) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index b8388f82f..f045cd72a 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -102,7 +102,8 @@ void GCodeViewer::InstanceVBuffer::reset() if (vbo > 0) glsafe(::glDeleteBuffers(1, &vbo)); s_ids.clear(); - render_range = { 0, 0 }; + buffer.clear(); + render_ranges.clear(); } #endif // ENABLE_SEAMS_USING_INSTANCED_MODELS @@ -803,7 +804,11 @@ void GCodeViewer::render() #if ENABLE_SEAMS_USING_MODELS if (wxGetApp().is_gl_version_greater_or_equal_to(3, 1)) { buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::Model; +#if ENABLE_SEAMS_USING_INSTANCED_MODELS + buffer.shader = "gouraud_light_instanced"; +#else buffer.shader = "gouraud_light"; +#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS buffer.model.model.init_from(diamond(16)); buffer.model.color = option_color(type); } @@ -1764,7 +1769,6 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) #if ENABLE_GCODE_VIEWER_STATISTICS m_statistics.total_instances_gpu_size += static_cast(size_bytes); - m_statistics.max_instance_vbuffer_gpu_size = std::max(m_statistics.max_instance_vbuffer_gpu_size, static_cast(size_bytes)); #endif // ENABLE_GCODE_VIEWER_STATISTICS GLuint id = 0; @@ -1774,6 +1778,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); t_buffer.model.instances2.vbo = id; + t_buffer.model.instances2.buffer = inst_buffer; t_buffer.model.instances2.s_ids = instances_ids[i]; } } @@ -2467,21 +2472,36 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool if (buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::Model) continue; - buffer.model.instances2.render_range = { 0, 0 }; + buffer.model.instances2.render_ranges.clear(); if (!buffer.visible) continue; + buffer.model.instances2.render_ranges.push_back({ 0, 0, buffer.model.color }); + bool has_second_range = top_layer_only && m_sequential_view.current.last != m_sequential_view.global.last; + if (has_second_range) + buffer.model.instances2.render_ranges.push_back({ 0, 0, Neutral_Color }); + if (m_sequential_view.current.first <= buffer.model.instances2.s_ids.back() && buffer.model.instances2.s_ids.front() <= m_sequential_view.current.last) { for (size_t id : buffer.model.instances2.s_ids) { - if (id <= m_sequential_view.current.first) { - buffer.model.instances2.render_range.offset += buffer.model.instances2.instance_size_bytes(); - buffer.model.instances2.render_range.count = 0; + if (has_second_range) { + if (id <= m_sequential_view.endpoints.first) { + buffer.model.instances2.render_ranges.front().offset += buffer.model.instances2.instance_size_bytes(); + ++buffer.model.instances2.render_ranges.back().count; + } + else if (id <= m_sequential_view.current.last) + ++buffer.model.instances2.render_ranges.front().count; + else + break; + } + else { + if (id <= m_sequential_view.current.first) + buffer.model.instances2.render_ranges.front().offset += buffer.model.instances2.instance_size_bytes(); + else if (id <= m_sequential_view.current.last) + ++buffer.model.instances2.render_ranges.front().count; + else + break; } - else if (id <= m_sequential_view.current.last) - ++buffer.model.instances2.render_range.count; - else - break; } } } @@ -2616,7 +2636,9 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool } #if ENABLE_SEAMS_USING_MODELS #if ENABLE_SEAMS_USING_INSTANCED_MODELS + statistics->models_instances_size += SLIC3R_STDVEC_MEMSIZE(buffer.model.instances2.buffer, float); statistics->models_instances_size += SLIC3R_STDVEC_MEMSIZE(buffer.model.instances2.s_ids, size_t); + statistics->models_instances_size += SLIC3R_STDVEC_MEMSIZE(buffer.model.instances2.render_ranges, InstanceVBuffer::RenderRange); #else statistics->models_instances_size += SLIC3R_STDVEC_MEMSIZE(buffer.model.instances, TBuffer::Model::Instance); #endif // ENABLE_SEAMS_USING_INSTANCED_MODELS @@ -2711,7 +2733,18 @@ void GCodeViewer::render_toolpaths() #if ENABLE_SEAMS_USING_MODELS auto render_as_instanced_model = [this] - (TBuffer & buffer, GLShaderProgram & shader) { + (TBuffer& buffer, GLShaderProgram & shader) { +#if ENABLE_SEAMS_USING_INSTANCED_MODELS + if (buffer.model.instances2.vbo > 0) { + for (const InstanceVBuffer::RenderRange& range : buffer.model.instances2.render_ranges) { + buffer.model.model.set_color(-1, range.color); + buffer.model.model.render_instanced(buffer.model.instances2.vbo, range.count); +#if ENABLE_GCODE_VIEWER_STATISTICS + ++m_statistics.gl_instanced_models_calls_count; +#endif // ENABLE_GCODE_VIEWER_STATISTICS + } + } +#else for (const TBuffer::Model::Instance& inst : buffer.model.instances) { bool top_layer_only = get_app_config()->get("seq_top_layer_only") == "1"; bool visible = top_layer_only ? @@ -2732,6 +2765,7 @@ void GCodeViewer::render_toolpaths() #endif // ENABLE_GCODE_VIEWER_STATISTICS } } +#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS }; #endif // ENABLE_SEAMS_USING_MODELS @@ -3800,7 +3834,11 @@ void GCodeViewer::render_statistics() add_counter(std::string("Multi GL_TRIANGLES:"), m_statistics.gl_multi_triangles_calls_count); add_counter(std::string("GL_TRIANGLES:"), m_statistics.gl_triangles_calls_count); #if ENABLE_SEAMS_USING_MODELS +#if ENABLE_SEAMS_USING_INSTANCED_MODELS + add_counter(std::string("Instanced models:"), m_statistics.gl_instanced_models_calls_count); +#else add_counter(std::string("Models:"), m_statistics.gl_models_calls_count); +#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS #endif // ENABLE_SEAMS_USING_MODELS } @@ -3824,9 +3862,6 @@ void GCodeViewer::render_statistics() ImGui::Separator(); add_memory(std::string("Max VBuffer:"), m_statistics.max_vbuffer_gpu_size); add_memory(std::string("Max IBuffer:"), m_statistics.max_ibuffer_gpu_size); -#if ENABLE_SEAMS_USING_INSTANCED_MODELS - add_memory(std::string("Max instance VBuffer:"), m_statistics.max_instance_vbuffer_gpu_size); -#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS } if (ImGui::CollapsingHeader("Other")) { diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 7bf341a68..bda0491de 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -105,8 +105,9 @@ class GCodeViewer }; #if ENABLE_SEAMS_USING_INSTANCED_MODELS - // vbo buffer containing instances data used to render a toolpaths using instanced models - // record format: 5 floats -> position.x|position.y|position.z|width|height + // buffer containing instances data used to render a toolpaths using instanced models + // instance record format: 5 floats -> position.x|position.y|position.z|width|height + // which is sent to the shader as -> vec3 (offset) + vec2 (scales) in GLModel::render_instanced() struct InstanceVBuffer { struct RenderRange @@ -115,13 +116,18 @@ class GCodeViewer unsigned int offset; // count of instances to render unsigned int count; + // Color to apply to the instances + Color color; }; // vbo id unsigned int vbo{ 0 }; - // move ids + // cpu-side buffer containing all instances data + InstanceBuffer buffer; + // indices of the moves for all instances std::vector s_ids; - RenderRange render_range; + // ranges used to render only subparts of the intances + std::vector render_ranges; size_t data_size_bytes() const { return s_ids.size() * instance_size_bytes(); } @@ -518,7 +524,11 @@ class GCodeViewer int64_t gl_multi_triangles_calls_count{ 0 }; int64_t gl_triangles_calls_count{ 0 }; #if ENABLE_SEAMS_USING_MODELS +#if ENABLE_SEAMS_USING_INSTANCED_MODELS + int64_t gl_instanced_models_calls_count{ 0 }; +#else int64_t gl_models_calls_count{ 0 }; +#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS #endif // ENABLE_SEAMS_USING_MODELS // memory int64_t results_size{ 0 }; @@ -529,9 +539,6 @@ class GCodeViewer #endif // ENABLE_SEAMS_USING_INSTANCED_MODELS int64_t max_vbuffer_gpu_size{ 0 }; int64_t max_ibuffer_gpu_size{ 0 }; -#if ENABLE_SEAMS_USING_INSTANCED_MODELS - int64_t max_instance_vbuffer_gpu_size{ 0 }; -#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS int64_t paths_size{ 0 }; int64_t render_paths_size{ 0 }; #if ENABLE_SEAMS_USING_MODELS @@ -570,7 +577,11 @@ class GCodeViewer gl_multi_triangles_calls_count = 0; gl_triangles_calls_count = 0; #if ENABLE_SEAMS_USING_MODELS +#if ENABLE_SEAMS_USING_INSTANCED_MODELS + gl_instanced_models_calls_count = 0; +#else gl_models_calls_count = 0; +#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS #endif // ENABLE_SEAMS_USING_MODELS } @@ -583,9 +594,6 @@ class GCodeViewer #endif // ENABLE_SEAMS_USING_INSTANCED_MODELS max_vbuffer_gpu_size = 0; max_ibuffer_gpu_size = 0; -#if ENABLE_SEAMS_USING_INSTANCED_MODELS - max_instance_vbuffer_gpu_size = 0; -#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS paths_size = 0; render_paths_size = 0; #if ENABLE_SEAMS_USING_MODELS diff --git a/src/slic3r/GUI/GLModel.cpp b/src/slic3r/GUI/GLModel.cpp index c4437a87f..58dfcb68b 100644 --- a/src/slic3r/GUI/GLModel.cpp +++ b/src/slic3r/GUI/GLModel.cpp @@ -207,6 +207,85 @@ void GLModel::render() const } } +#if ENABLE_SEAMS_USING_INSTANCED_MODELS +void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instances_count) const +{ + if (instances_vbo == 0) + return; + + GLShaderProgram* shader = wxGetApp().get_current_shader(); + assert(shader == nullptr || boost::algorithm::iends_with(shader->get_name(), "_instanced")); + + // vertex attributes + GLint position_id = (shader != nullptr) ? shader->get_attrib_location("v_position") : -1; + GLint normal_id = (shader != nullptr) ? shader->get_attrib_location("v_normal") : -1; + assert(position_id != -1 && normal_id != -1); + + // instance attributes + GLint offset_id = (shader != nullptr) ? shader->get_attrib_location("i_offset") : -1; + GLint scales_id = (shader != nullptr) ? shader->get_attrib_location("i_scales") : -1; + assert(offset_id != -1 && scales_id != -1); + + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, instances_vbo)); + if (offset_id != -1) { + glsafe(::glVertexAttribPointer(offset_id, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (GLvoid*)0)); + glsafe(::glEnableVertexAttribArray(offset_id)); + glsafe(::glVertexAttribDivisor(offset_id, 1)); + } + if (scales_id != -1) { + glsafe(::glVertexAttribPointer(scales_id, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (GLvoid*)(3 * sizeof(float)))); + glsafe(::glEnableVertexAttribArray(scales_id)); + glsafe(::glVertexAttribDivisor(scales_id, 1)); + } + + for (const RenderData& data : m_render_data) { + if (data.vbo_id == 0 || data.ibo_id == 0) + continue; + + GLenum mode; + switch (data.type) + { + default: + case PrimitiveType::Triangles: { mode = GL_TRIANGLES; break; } + case PrimitiveType::Lines: { mode = GL_LINES; break; } + case PrimitiveType::LineStrip: { mode = GL_LINE_STRIP; break; } + case PrimitiveType::LineLoop: { mode = GL_LINE_LOOP; break; } + } + + if (shader != nullptr) + shader->set_uniform("uniform_color", data.color); + else + glsafe(::glColor4fv(data.color.data())); + + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, data.vbo_id)); + if (position_id != -1) { + glsafe(::glVertexAttribPointer(position_id, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (GLvoid*)0)); + glsafe(::glEnableVertexAttribArray(position_id)); + } + if (normal_id != -1) { + glsafe(::glVertexAttribPointer(normal_id, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (GLvoid*)(3 * sizeof(float)))); + glsafe(::glEnableVertexAttribArray(normal_id)); + } + + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.ibo_id)); + glsafe(::glDrawElementsInstanced(mode, static_cast(data.indices_count), GL_UNSIGNED_INT, (const void*)0, instances_count)); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + + if (normal_id != -1) + glsafe(::glDisableVertexAttribArray(normal_id)); + if (position_id != -1) + glsafe(::glDisableVertexAttribArray(position_id)); + } + + if (scales_id != -1) + glsafe(::glDisableVertexAttribArray(scales_id)); + if (offset_id != -1) + glsafe(::glDisableVertexAttribArray(offset_id)); + + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); +} +#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS + void GLModel::send_to_gpu(RenderData& data, const std::vector& vertices, const std::vector& indices) { assert(data.vbo_id == 0); diff --git a/src/slic3r/GUI/GLModel.hpp b/src/slic3r/GUI/GLModel.hpp index 99c4bf442..73fb90827 100644 --- a/src/slic3r/GUI/GLModel.hpp +++ b/src/slic3r/GUI/GLModel.hpp @@ -72,6 +72,9 @@ namespace GUI { void reset(); void render() const; +#if ENABLE_SEAMS_USING_INSTANCED_MODELS + void render_instanced(unsigned int instances_vbo, unsigned int instances_count) const; +#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS bool is_initialized() const { return !m_render_data.empty(); } diff --git a/src/slic3r/GUI/GLShadersManager.cpp b/src/slic3r/GUI/GLShadersManager.cpp index 788fe90c0..7bb0a50a6 100644 --- a/src/slic3r/GUI/GLShadersManager.cpp +++ b/src/slic3r/GUI/GLShadersManager.cpp @@ -38,9 +38,17 @@ std::pair GLShadersManager::init() // used to render printbed valid &= append_shader("printbed", { "printbed.vs", "printbed.fs" }); // used to render options in gcode preview - valid &= append_shader("options_110", { "options_110.vs", "options_110.fs" }); - if (GUI::wxGetApp().is_glsl_version_greater_or_equal_to(1, 20)) - valid &= append_shader("options_120", { "options_120.vs", "options_120.fs" }); +#if ENABLE_SEAMS_USING_INSTANCED_MODELS + if (GUI::wxGetApp().is_gl_version_greater_or_equal_to(3, 1)) + valid &= append_shader("gouraud_light_instanced", { "gouraud_light_instanced.vs", "gouraud_light_instanced.fs" }); + else { +#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS + valid &= append_shader("options_110", { "options_110.vs", "options_110.fs" }); + if (GUI::wxGetApp().is_glsl_version_greater_or_equal_to(1, 20)) + valid &= append_shader("options_120", { "options_120.vs", "options_120.fs" }); +#if ENABLE_SEAMS_USING_INSTANCED_MODELS + } +#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS // used to render extrusion and travel paths as lines in gcode preview valid &= append_shader("toolpaths_lines", { "toolpaths_lines.vs", "toolpaths_lines.fs" }); // used to render objects in 3d editor From c471c3c7c41b3163a276e3fd2aaa2a312d9185f3 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 26 Aug 2021 14:37:09 +0200 Subject: [PATCH 14/18] Code cleanup and small refactoring --- src/slic3r/GUI/GCodeViewer.cpp | 81 ++++++++++++++++++---------------- src/slic3r/GUI/GCodeViewer.hpp | 11 ++++- 2 files changed, 51 insertions(+), 41 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index f045cd72a..b6cac4059 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -151,9 +151,10 @@ bool GCodeViewer::Path::matches(const GCodeProcessor::MoveVertex& move) const #if ENABLE_SEAMS_USING_MODELS void GCodeViewer::TBuffer::Model::reset() { - instances.clear(); #if ENABLE_SEAMS_USING_INSTANCED_MODELS - instances2.reset(); + instances.reset(); +#else + instances.clear(); #endif // ENABLE_SEAMS_USING_INSTANCED_MODELS } #endif // ENABLE_SEAMS_USING_MODELS @@ -1432,19 +1433,9 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) }; #if ENABLE_SEAMS_USING_MODELS - // format data into the buffers to be rendered as model - auto add_model_instance = [](const GCodeProcessor::MoveVertex& curr, TBuffer::Model::Instances& instances, size_t move_id) { - TBuffer::Model::Instance instance; - instance.position = curr.position; - instance.width = 1.2f * curr.width; - instance.height = 1.2f * curr.height; - instance.s_id = move_id; - instances.emplace_back(instance); - }; - #if ENABLE_SEAMS_USING_INSTANCED_MODELS // format data into the buffers to be rendered as model - auto add_model_instance_2 = [](const GCodeProcessor::MoveVertex& curr, InstanceBuffer& instances, InstanceIdBuffer& instances_ids, size_t move_id) { + auto add_model_instance = [](const GCodeProcessor::MoveVertex& curr, InstanceBuffer& instances, InstanceIdBuffer& instances_ids, size_t move_id) { // append position instances.push_back(curr.position.x()); instances.push_back(curr.position.y()); @@ -1457,6 +1448,15 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) // append id instances_ids.push_back(move_id); }; +#else + auto add_model_instance = [](const GCodeProcessor::MoveVertex& curr, TBuffer::Model::Instances& instances, size_t move_id) { + TBuffer::Model::Instance instance; + instance.position = curr.position; + instance.width = 1.2f * curr.width; + instance.height = 1.2f * curr.height; + instance.s_id = move_id; + instances.emplace_back(instance); + }; #endif // ENABLE_SEAMS_USING_INSTANCED_MODELS #endif // ENABLE_SEAMS_USING_MODELS @@ -1560,9 +1560,10 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) #if ENABLE_SEAMS_USING_MODELS case TBuffer::ERenderPrimitiveType::Model: { - add_model_instance(curr, t_buffer.model.instances, i); #if ENABLE_SEAMS_USING_INSTANCED_MODELS - add_model_instance_2(curr, inst_buffer, inst_id_buffer, i); + add_model_instance(curr, inst_buffer, inst_id_buffer, i); +#else + add_model_instance(curr, t_buffer.model.instances, i); #endif // ENABLE_SEAMS_USING_INSTANCED_MODELS #if ENABLE_GCODE_VIEWER_STATISTICS ++m_statistics.instances_count; @@ -1741,12 +1742,14 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) } #if ENABLE_SEAMS_USING_MODELS +#if !ENABLE_SEAMS_USING_INSTANCED_MODELS for (size_t i = 0; i < m_buffers.size(); ++i) { TBuffer& t_buffer = m_buffers[i]; if (t_buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Model) { t_buffer.model.instances.shrink_to_fit(); } } +#endif // !ENABLE_SEAMS_USING_INSTANCED_MODELS #endif // ENABLE_SEAMS_USING_MODELS // move the wipe toolpaths half height up to render them on proper position @@ -1777,9 +1780,9 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) glsafe(::glBufferData(GL_ARRAY_BUFFER, size_bytes, inst_buffer.data(), GL_STATIC_DRAW)); glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); - t_buffer.model.instances2.vbo = id; - t_buffer.model.instances2.buffer = inst_buffer; - t_buffer.model.instances2.s_ids = instances_ids[i]; + t_buffer.model.instances.vbo = id; + t_buffer.model.instances.buffer = inst_buffer; + t_buffer.model.instances.s_ids = instances_ids[i]; } } else { @@ -2213,7 +2216,7 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool #if ENABLE_SEAMS_USING_MODELS if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Model) { #if ENABLE_SEAMS_USING_INSTANCED_MODELS - for (size_t id : buffer.model.instances2.s_ids) { + for (size_t id : buffer.model.instances.s_ids) { if (id < m_layers.get_endpoints_at(m_layers_z_range[0]).first || m_layers.get_endpoints_at(m_layers_z_range[1]).last < id) continue; @@ -2296,12 +2299,12 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool #if ENABLE_SEAMS_USING_MODELS if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Model) { #if ENABLE_SEAMS_USING_INSTANCED_MODELS - for (size_t i = 0; i < buffer.model.instances2.s_ids.size(); ++i) { - if (buffer.model.instances2.s_ids[i] == m_sequential_view.current.last) { + for (size_t i = 0; i < buffer.model.instances.s_ids.size(); ++i) { + if (buffer.model.instances.s_ids[i] == m_sequential_view.current.last) { // gets the position from the vertices buffer on gpu - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, buffer.model.instances2.vbo)); - glsafe(::glGetBufferSubData(GL_ARRAY_BUFFER, static_cast(i * buffer.model.instances2.instance_size_bytes()), static_cast(3 * sizeof(float)), static_cast(sequential_view->current_position.data()))); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, buffer.model.instances.vbo)); + glsafe(::glGetBufferSubData(GL_ARRAY_BUFFER, static_cast(i * buffer.model.instances.instance_size_bytes()), static_cast(3 * sizeof(float)), static_cast(sequential_view->current_position.data()))); glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); found = true; @@ -2472,33 +2475,33 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool if (buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::Model) continue; - buffer.model.instances2.render_ranges.clear(); + buffer.model.instances.render_ranges.clear(); if (!buffer.visible) continue; - buffer.model.instances2.render_ranges.push_back({ 0, 0, buffer.model.color }); + buffer.model.instances.render_ranges.push_back({ 0, 0, buffer.model.color }); bool has_second_range = top_layer_only && m_sequential_view.current.last != m_sequential_view.global.last; if (has_second_range) - buffer.model.instances2.render_ranges.push_back({ 0, 0, Neutral_Color }); + buffer.model.instances.render_ranges.push_back({ 0, 0, Neutral_Color }); - if (m_sequential_view.current.first <= buffer.model.instances2.s_ids.back() && buffer.model.instances2.s_ids.front() <= m_sequential_view.current.last) { - for (size_t id : buffer.model.instances2.s_ids) { + if (m_sequential_view.current.first <= buffer.model.instances.s_ids.back() && buffer.model.instances.s_ids.front() <= m_sequential_view.current.last) { + for (size_t id : buffer.model.instances.s_ids) { if (has_second_range) { if (id <= m_sequential_view.endpoints.first) { - buffer.model.instances2.render_ranges.front().offset += buffer.model.instances2.instance_size_bytes(); - ++buffer.model.instances2.render_ranges.back().count; + buffer.model.instances.render_ranges.front().offset += buffer.model.instances.instance_size_bytes(); + ++buffer.model.instances.render_ranges.back().count; } else if (id <= m_sequential_view.current.last) - ++buffer.model.instances2.render_ranges.front().count; + ++buffer.model.instances.render_ranges.front().count; else break; } else { if (id <= m_sequential_view.current.first) - buffer.model.instances2.render_ranges.front().offset += buffer.model.instances2.instance_size_bytes(); + buffer.model.instances.render_ranges.front().offset += buffer.model.instances.instance_size_bytes(); else if (id <= m_sequential_view.current.last) - ++buffer.model.instances2.render_ranges.front().count; + ++buffer.model.instances.render_ranges.front().count; else break; } @@ -2636,9 +2639,9 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool } #if ENABLE_SEAMS_USING_MODELS #if ENABLE_SEAMS_USING_INSTANCED_MODELS - statistics->models_instances_size += SLIC3R_STDVEC_MEMSIZE(buffer.model.instances2.buffer, float); - statistics->models_instances_size += SLIC3R_STDVEC_MEMSIZE(buffer.model.instances2.s_ids, size_t); - statistics->models_instances_size += SLIC3R_STDVEC_MEMSIZE(buffer.model.instances2.render_ranges, InstanceVBuffer::RenderRange); + statistics->models_instances_size += SLIC3R_STDVEC_MEMSIZE(buffer.model.instances.buffer, float); + statistics->models_instances_size += SLIC3R_STDVEC_MEMSIZE(buffer.model.instances.s_ids, size_t); + statistics->models_instances_size += SLIC3R_STDVEC_MEMSIZE(buffer.model.instances.render_ranges, InstanceVBuffer::RenderRange); #else statistics->models_instances_size += SLIC3R_STDVEC_MEMSIZE(buffer.model.instances, TBuffer::Model::Instance); #endif // ENABLE_SEAMS_USING_INSTANCED_MODELS @@ -2735,10 +2738,10 @@ void GCodeViewer::render_toolpaths() auto render_as_instanced_model = [this] (TBuffer& buffer, GLShaderProgram & shader) { #if ENABLE_SEAMS_USING_INSTANCED_MODELS - if (buffer.model.instances2.vbo > 0) { - for (const InstanceVBuffer::RenderRange& range : buffer.model.instances2.render_ranges) { + if (buffer.model.instances.vbo > 0) { + for (const InstanceVBuffer::RenderRange& range : buffer.model.instances.render_ranges) { buffer.model.model.set_color(-1, range.color); - buffer.model.model.render_instanced(buffer.model.instances2.vbo, range.count); + buffer.model.model.render_instanced(buffer.model.instances.vbo, range.count); #if ENABLE_GCODE_VIEWER_STATISTICS ++m_statistics.gl_instanced_models_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index bda0491de..3e5e50c82 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -288,6 +288,7 @@ class GCodeViewer #if ENABLE_SEAMS_USING_MODELS struct Model { +#if !ENABLE_SEAMS_USING_INSTANCED_MODELS struct Instance { Vec3f position; @@ -296,12 +297,14 @@ class GCodeViewer size_t s_id; }; using Instances = std::vector; +#endif // !ENABLE_SEAMS_USING_INSTANCED_MODELS GLModel model; Color color; - Instances instances; #if ENABLE_SEAMS_USING_INSTANCED_MODELS - InstanceVBuffer instances2; + InstanceVBuffer instances; +#else + Instances instances; #endif // ENABLE_SEAMS_USING_INSTANCED_MODELS void reset(); @@ -367,7 +370,11 @@ class GCodeViewer case ERenderPrimitiveType::Triangle: { return !vertices.vbos.empty() && vertices.vbos.front() != 0 && !indices.empty() && indices.front().ibo != 0; } +#if ENABLE_SEAMS_USING_INSTANCED_MODELS + case ERenderPrimitiveType::Model: { return model.model.is_initialized() && !model.instances.buffer.empty(); } +#else case ERenderPrimitiveType::Model: { return model.model.is_initialized() && !model.instances.empty(); } +#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS default: { return false; } } } From 03dc2f7c11b128cbef4610f0f70063bf930eff35 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 27 Aug 2021 10:16:50 +0200 Subject: [PATCH 15/18] ENABLE_SEAMS_USING_INSTANCED_MODELS -> Completed implementation of rendering models using instancing --- src/slic3r/GUI/GCodeViewer.cpp | 83 ++++++++++++++++++++-------------- src/slic3r/GUI/GCodeViewer.hpp | 29 +++++++----- 2 files changed, 67 insertions(+), 45 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index b6cac4059..c672f9060 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -96,14 +96,22 @@ void GCodeViewer::VBuffer::reset() } #if ENABLE_SEAMS_USING_INSTANCED_MODELS +void GCodeViewer::InstanceVBuffer::Ranges::reset() +{ + for (Range& range : ranges) { + // release gpu memory + if (range.vbo > 0) + glsafe(::glDeleteBuffers(1, &range.vbo)); + } + + ranges.clear(); +} + void GCodeViewer::InstanceVBuffer::reset() { - // release gpu memory - if (vbo > 0) - glsafe(::glDeleteBuffers(1, &vbo)); s_ids.clear(); buffer.clear(); - render_ranges.clear(); + render_ranges.reset(); } #endif // ENABLE_SEAMS_USING_INSTANCED_MODELS @@ -862,6 +870,9 @@ void GCodeViewer::render() #if ENABLE_GCODE_VIEWER_STATISTICS m_statistics.reset_opengl(); +#if ENABLE_SEAMS_USING_INSTANCED_MODELS + m_statistics.total_instances_gpu_size = 0; +#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS #endif // ENABLE_GCODE_VIEWER_STATISTICS // OpenGL data must be initialized after the glContext has been created. @@ -1760,7 +1771,11 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) } } +#if ENABLE_SEAMS_USING_INSTANCED_MODELS + // send vertices data to gpu, where needed +#else // send vertices data to gpu +#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS for (size_t i = 0; i < m_buffers.size(); ++i) { TBuffer& t_buffer = m_buffers[i]; #if ENABLE_SEAMS_USING_MODELS @@ -1768,19 +1783,6 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) if (t_buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Model) { const InstanceBuffer& inst_buffer = instances[i]; if (!inst_buffer.empty()) { - const size_t size_bytes = inst_buffer.size() * sizeof(float); - -#if ENABLE_GCODE_VIEWER_STATISTICS - m_statistics.total_instances_gpu_size += static_cast(size_bytes); -#endif // ENABLE_GCODE_VIEWER_STATISTICS - - GLuint id = 0; - glsafe(::glGenBuffers(1, &id)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, id)); - glsafe(::glBufferData(GL_ARRAY_BUFFER, size_bytes, inst_buffer.data(), GL_STATIC_DRAW)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); - - t_buffer.model.instances.vbo = id; t_buffer.model.instances.buffer = inst_buffer; t_buffer.model.instances.s_ids = instances_ids[i]; } @@ -2293,7 +2295,11 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool sequential_view->current.first = !top_layer_only && keep_sequential_current_first ? std::clamp(sequential_view->current.first, global_endpoints.first, global_endpoints.last) : global_endpoints.first; sequential_view->current.last = keep_sequential_current_last ? std::clamp(sequential_view->current.last, global_endpoints.first, global_endpoints.last) : global_endpoints.last; +#if ENABLE_SEAMS_USING_INSTANCED_MODELS + // get the world position from the vertex buffer +#else // get the world position from gpu +#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS bool found = false; for (const TBuffer& buffer : m_buffers) { #if ENABLE_SEAMS_USING_MODELS @@ -2301,11 +2307,10 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool #if ENABLE_SEAMS_USING_INSTANCED_MODELS for (size_t i = 0; i < buffer.model.instances.s_ids.size(); ++i) { if (buffer.model.instances.s_ids[i] == m_sequential_view.current.last) { - - // gets the position from the vertices buffer on gpu - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, buffer.model.instances.vbo)); - glsafe(::glGetBufferSubData(GL_ARRAY_BUFFER, static_cast(i * buffer.model.instances.instance_size_bytes()), static_cast(3 * sizeof(float)), static_cast(sequential_view->current_position.data()))); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + size_t offset = i * buffer.model.instances.instance_size_floats(); + sequential_view->current_position.x() = buffer.model.instances.buffer[offset + 0]; + sequential_view->current_position.y() = buffer.model.instances.buffer[offset + 1]; + sequential_view->current_position.z() = buffer.model.instances.buffer[offset + 2]; found = true; break; @@ -2475,33 +2480,33 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool if (buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::Model) continue; - buffer.model.instances.render_ranges.clear(); + buffer.model.instances.render_ranges.reset(); if (!buffer.visible) continue; - buffer.model.instances.render_ranges.push_back({ 0, 0, buffer.model.color }); + buffer.model.instances.render_ranges.ranges.push_back({ 0, 0, 0, buffer.model.color }); bool has_second_range = top_layer_only && m_sequential_view.current.last != m_sequential_view.global.last; if (has_second_range) - buffer.model.instances.render_ranges.push_back({ 0, 0, Neutral_Color }); + buffer.model.instances.render_ranges.ranges.push_back({ 0, 0, 0, Neutral_Color }); if (m_sequential_view.current.first <= buffer.model.instances.s_ids.back() && buffer.model.instances.s_ids.front() <= m_sequential_view.current.last) { for (size_t id : buffer.model.instances.s_ids) { if (has_second_range) { if (id <= m_sequential_view.endpoints.first) { - buffer.model.instances.render_ranges.front().offset += buffer.model.instances.instance_size_bytes(); - ++buffer.model.instances.render_ranges.back().count; + ++buffer.model.instances.render_ranges.ranges.front().offset; + ++buffer.model.instances.render_ranges.ranges.back().count; } else if (id <= m_sequential_view.current.last) - ++buffer.model.instances.render_ranges.front().count; + ++buffer.model.instances.render_ranges.ranges.front().count; else break; } else { if (id <= m_sequential_view.current.first) - buffer.model.instances.render_ranges.front().offset += buffer.model.instances.instance_size_bytes(); + ++buffer.model.instances.render_ranges.ranges.front().offset; else if (id <= m_sequential_view.current.last) - ++buffer.model.instances.render_ranges.front().count; + ++buffer.model.instances.render_ranges.ranges.front().count; else break; } @@ -2641,7 +2646,7 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool #if ENABLE_SEAMS_USING_INSTANCED_MODELS statistics->models_instances_size += SLIC3R_STDVEC_MEMSIZE(buffer.model.instances.buffer, float); statistics->models_instances_size += SLIC3R_STDVEC_MEMSIZE(buffer.model.instances.s_ids, size_t); - statistics->models_instances_size += SLIC3R_STDVEC_MEMSIZE(buffer.model.instances.render_ranges, InstanceVBuffer::RenderRange); + statistics->models_instances_size += SLIC3R_STDVEC_MEMSIZE(buffer.model.instances.render_ranges.ranges, InstanceVBuffer::Ranges::Range); #else statistics->models_instances_size += SLIC3R_STDVEC_MEMSIZE(buffer.model.instances, TBuffer::Model::Instance); #endif // ENABLE_SEAMS_USING_INSTANCED_MODELS @@ -2738,12 +2743,22 @@ void GCodeViewer::render_toolpaths() auto render_as_instanced_model = [this] (TBuffer& buffer, GLShaderProgram & shader) { #if ENABLE_SEAMS_USING_INSTANCED_MODELS - if (buffer.model.instances.vbo > 0) { - for (const InstanceVBuffer::RenderRange& range : buffer.model.instances.render_ranges) { + for (auto& range : buffer.model.instances.render_ranges.ranges) { + if (range.vbo == 0 && range.count > 0) { + std::cout << range.offset * buffer.model.instances.instance_size_bytes() << " + " << range.count * buffer.model.instances.instance_size_bytes() << " = " << buffer.model.instances.buffer.size() * sizeof(float) << "\n"; + + glsafe(::glGenBuffers(1, &range.vbo)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, range.vbo)); + glsafe(::glBufferData(GL_ARRAY_BUFFER, range.count * buffer.model.instances.instance_size_bytes(), (const void*)&buffer.model.instances.buffer[range.offset * buffer.model.instances.instance_size_floats()], GL_STATIC_DRAW)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + } + + if (range.vbo > 0) { buffer.model.model.set_color(-1, range.color); - buffer.model.model.render_instanced(buffer.model.instances.vbo, range.count); + buffer.model.model.render_instanced(range.vbo, range.count); #if ENABLE_GCODE_VIEWER_STATISTICS ++m_statistics.gl_instanced_models_calls_count; + m_statistics.total_instances_gpu_size += static_cast(range.count * buffer.model.instances.instance_size_bytes()); #endif // ENABLE_GCODE_VIEWER_STATISTICS } } diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 3e5e50c82..46f6558dd 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -110,24 +110,31 @@ class GCodeViewer // which is sent to the shader as -> vec3 (offset) + vec2 (scales) in GLModel::render_instanced() struct InstanceVBuffer { - struct RenderRange + // ranges used to render only subparts of the intances + struct Ranges { - // offset in bytes of the 1st instance to render - unsigned int offset; - // count of instances to render - unsigned int count; - // Color to apply to the instances - Color color; + struct Range + { + // offset in bytes of the 1st instance to render + unsigned int offset; + // count of instances to render + unsigned int count; + // vbo id + unsigned int vbo{ 0 }; + // Color to apply to the instances + Color color; + }; + + std::vector ranges; + + void reset(); }; - // vbo id - unsigned int vbo{ 0 }; // cpu-side buffer containing all instances data InstanceBuffer buffer; // indices of the moves for all instances std::vector s_ids; - // ranges used to render only subparts of the intances - std::vector render_ranges; + Ranges render_ranges; size_t data_size_bytes() const { return s_ids.size() * instance_size_bytes(); } From 9c4eeeaa189d5051c3e8e9acc98f91765e0e6068 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 27 Aug 2021 11:41:34 +0200 Subject: [PATCH 16/18] Tech ENABLE_SEAMS_USING_INSTANCED_MODELS merged into tech ENABLE_SEAMS_USING_MODELS --- src/libslic3r/Technologies.hpp | 2 - src/slic3r/GUI/GCodeViewer.cpp | 135 +++------------------------- src/slic3r/GUI/GCodeViewer.hpp | 43 ++------- src/slic3r/GUI/GLModel.cpp | 4 +- src/slic3r/GUI/GLModel.hpp | 4 +- src/slic3r/GUI/GLShadersManager.cpp | 8 +- 6 files changed, 30 insertions(+), 166 deletions(-) diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index f11ad4a17..e03887d26 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -51,8 +51,6 @@ #define ENABLE_RETRACT_ACCELERATION (1 && ENABLE_2_4_0_ALPHA0) // Enable rendering seams (and other options) in preview using models #define ENABLE_SEAMS_USING_MODELS (1 && ENABLE_2_4_0_ALPHA0) -// Enable rendering seams (and other options) in preview using instanced models -#define ENABLE_SEAMS_USING_INSTANCED_MODELS (1 && ENABLE_SEAMS_USING_MODELS) #endif // _prusaslicer_technologies_h_ diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index c672f9060..382b78ca3 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -95,7 +95,7 @@ void GCodeViewer::VBuffer::reset() count = 0; } -#if ENABLE_SEAMS_USING_INSTANCED_MODELS +#if ENABLE_SEAMS_USING_MODELS void GCodeViewer::InstanceVBuffer::Ranges::reset() { for (Range& range : ranges) { @@ -113,7 +113,7 @@ void GCodeViewer::InstanceVBuffer::reset() buffer.clear(); render_ranges.reset(); } -#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS +#endif // ENABLE_SEAMS_USING_MODELS void GCodeViewer::IBuffer::reset() { @@ -159,11 +159,7 @@ bool GCodeViewer::Path::matches(const GCodeProcessor::MoveVertex& move) const #if ENABLE_SEAMS_USING_MODELS void GCodeViewer::TBuffer::Model::reset() { -#if ENABLE_SEAMS_USING_INSTANCED_MODELS instances.reset(); -#else - instances.clear(); -#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS } #endif // ENABLE_SEAMS_USING_MODELS @@ -813,11 +809,7 @@ void GCodeViewer::render() #if ENABLE_SEAMS_USING_MODELS if (wxGetApp().is_gl_version_greater_or_equal_to(3, 1)) { buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::Model; -#if ENABLE_SEAMS_USING_INSTANCED_MODELS buffer.shader = "gouraud_light_instanced"; -#else - buffer.shader = "gouraud_light"; -#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS buffer.model.model.init_from(diamond(16)); buffer.model.color = option_color(type); } @@ -870,9 +862,9 @@ void GCodeViewer::render() #if ENABLE_GCODE_VIEWER_STATISTICS m_statistics.reset_opengl(); -#if ENABLE_SEAMS_USING_INSTANCED_MODELS +#if ENABLE_SEAMS_USING_MODELS m_statistics.total_instances_gpu_size = 0; -#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS +#endif // ENABLE_SEAMS_USING_MODELS #endif // ENABLE_GCODE_VIEWER_STATISTICS // OpenGL data must be initialized after the glContext has been created. @@ -1444,7 +1436,6 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) }; #if ENABLE_SEAMS_USING_MODELS -#if ENABLE_SEAMS_USING_INSTANCED_MODELS // format data into the buffers to be rendered as model auto add_model_instance = [](const GCodeProcessor::MoveVertex& curr, InstanceBuffer& instances, InstanceIdBuffer& instances_ids, size_t move_id) { // append position @@ -1459,16 +1450,6 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) // append id instances_ids.push_back(move_id); }; -#else - auto add_model_instance = [](const GCodeProcessor::MoveVertex& curr, TBuffer::Model::Instances& instances, size_t move_id) { - TBuffer::Model::Instance instance; - instance.position = curr.position; - instance.width = 1.2f * curr.width; - instance.height = 1.2f * curr.height; - instance.s_id = move_id; - instances.emplace_back(instance); - }; -#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS #endif // ENABLE_SEAMS_USING_MODELS #if ENABLE_GCODE_VIEWER_STATISTICS @@ -1513,10 +1494,10 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) std::vector vertices(m_buffers.size()); std::vector indices(m_buffers.size()); -#if ENABLE_SEAMS_USING_INSTANCED_MODELS +#if ENABLE_SEAMS_USING_MODELS std::vector instances(m_buffers.size()); std::vector instances_ids(m_buffers.size()); -#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS +#endif // ENABLE_SEAMS_USING_MODELS std::vector options_zs; // toolpaths data -> extract vertices from result @@ -1541,10 +1522,10 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) const unsigned char id = buffer_id(curr.type); TBuffer& t_buffer = m_buffers[id]; MultiVertexBuffer& v_multibuffer = vertices[id]; -#if ENABLE_SEAMS_USING_INSTANCED_MODELS +#if ENABLE_SEAMS_USING_MODELS InstanceBuffer& inst_buffer = instances[id]; InstanceIdBuffer& inst_id_buffer = instances_ids[id]; -#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS +#endif // ENABLE_SEAMS_USING_MODELS // ensure there is at least one vertex buffer if (v_multibuffer.empty()) @@ -1571,11 +1552,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) #if ENABLE_SEAMS_USING_MODELS case TBuffer::ERenderPrimitiveType::Model: { -#if ENABLE_SEAMS_USING_INSTANCED_MODELS add_model_instance(curr, inst_buffer, inst_id_buffer, i); -#else - add_model_instance(curr, t_buffer.model.instances, i); -#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS #if ENABLE_GCODE_VIEWER_STATISTICS ++m_statistics.instances_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS @@ -1752,17 +1729,6 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) } } -#if ENABLE_SEAMS_USING_MODELS -#if !ENABLE_SEAMS_USING_INSTANCED_MODELS - for (size_t i = 0; i < m_buffers.size(); ++i) { - TBuffer& t_buffer = m_buffers[i]; - if (t_buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Model) { - t_buffer.model.instances.shrink_to_fit(); - } - } -#endif // !ENABLE_SEAMS_USING_INSTANCED_MODELS -#endif // ENABLE_SEAMS_USING_MODELS - // move the wipe toolpaths half height up to render them on proper position MultiVertexBuffer& wipe_vertices = vertices[buffer_id(EMoveType::Wipe)]; for (VertexBuffer& v_buffer : wipe_vertices) { @@ -1771,15 +1737,10 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) } } -#if ENABLE_SEAMS_USING_INSTANCED_MODELS // send vertices data to gpu, where needed -#else - // send vertices data to gpu -#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS for (size_t i = 0; i < m_buffers.size(); ++i) { TBuffer& t_buffer = m_buffers[i]; #if ENABLE_SEAMS_USING_MODELS -#if ENABLE_SEAMS_USING_INSTANCED_MODELS if (t_buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Model) { const InstanceBuffer& inst_buffer = instances[i]; if (!inst_buffer.empty()) { @@ -1788,9 +1749,6 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) } } else { -#else - if (t_buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::Model) { -#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS #endif // ENABLE_SEAMS_USING_MODELS const MultiVertexBuffer& v_multibuffer = vertices[i]; for (const VertexBuffer& v_buffer : v_multibuffer) { @@ -1827,10 +1785,10 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) // dismiss vertices data, no more needed std::vector().swap(vertices); -#if ENABLE_SEAMS_USING_INSTANCED_MODELS +#if ENABLE_SEAMS_USING_MODELS std::vector().swap(instances); std::vector().swap(instances_ids); -#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS +#endif // ENABLE_SEAMS_USING_MODELS // toolpaths data -> extract indices from result // paths may have been filled while extracting vertices, @@ -2217,7 +2175,6 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool #if ENABLE_SEAMS_USING_MODELS if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Model) { -#if ENABLE_SEAMS_USING_INSTANCED_MODELS for (size_t id : buffer.model.instances.s_ids) { if (id < m_layers.get_endpoints_at(m_layers_z_range[0]).first || m_layers.get_endpoints_at(m_layers_z_range[1]).last < id) continue; @@ -2233,23 +2190,6 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool top_layer_endpoints.last = std::max(top_layer_endpoints.last, id); } } -#else - for (const TBuffer::Model::Instance& inst : buffer.model.instances) { - if (inst.s_id < m_layers.get_endpoints_at(m_layers_z_range[0]).first || m_layers.get_endpoints_at(m_layers_z_range[1]).last < inst.s_id) - continue; - - global_endpoints.first = std::min(global_endpoints.first, inst.s_id); - global_endpoints.last = std::max(global_endpoints.last, inst.s_id); - - if (top_layer_only) { - if (inst.s_id < m_layers.get_endpoints_at(m_layers_z_range[1]).first || m_layers.get_endpoints_at(m_layers_z_range[1]).last < inst.s_id) - continue; - - top_layer_endpoints.first = std::min(top_layer_endpoints.first, inst.s_id); - top_layer_endpoints.last = std::max(top_layer_endpoints.last, inst.s_id); - } - } -#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS } else { #endif // ENABLE_SEAMS_USING_MODELS @@ -2295,16 +2235,11 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool sequential_view->current.first = !top_layer_only && keep_sequential_current_first ? std::clamp(sequential_view->current.first, global_endpoints.first, global_endpoints.last) : global_endpoints.first; sequential_view->current.last = keep_sequential_current_last ? std::clamp(sequential_view->current.last, global_endpoints.first, global_endpoints.last) : global_endpoints.last; -#if ENABLE_SEAMS_USING_INSTANCED_MODELS // get the world position from the vertex buffer -#else - // get the world position from gpu -#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS bool found = false; for (const TBuffer& buffer : m_buffers) { #if ENABLE_SEAMS_USING_MODELS if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Model) { -#if ENABLE_SEAMS_USING_INSTANCED_MODELS for (size_t i = 0; i < buffer.model.instances.s_ids.size(); ++i) { if (buffer.model.instances.s_ids[i] == m_sequential_view.current.last) { size_t offset = i * buffer.model.instances.instance_size_floats(); @@ -2316,15 +2251,6 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool break; } } -#else - for (const TBuffer::Model::Instance& inst : buffer.model.instances) { - if (inst.s_id == m_sequential_view.current.last) { - sequential_view->current_position = inst.position; - found = true; - break; - } - } -#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS } else { #endif // ENABLE_SEAMS_USING_MODELS @@ -2473,7 +2399,7 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool #endif } -#if ENABLE_SEAMS_USING_INSTANCED_MODELS +#if ENABLE_SEAMS_USING_MODELS // second pass: for buffers using instanced models, update the instances render ranges for (size_t b = 0; b < m_buffers.size(); ++b) { TBuffer& buffer = const_cast(m_buffers[b]); @@ -2513,7 +2439,7 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool } } } -#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS +#endif // ENABLE_SEAMS_USING_MODELS // set sequential data to their final value sequential_view->endpoints = top_layer_only ? top_layer_endpoints : global_endpoints; @@ -2643,13 +2569,9 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool statistics->render_paths_size += SLIC3R_STDVEC_MEMSIZE(path.offsets, size_t); } #if ENABLE_SEAMS_USING_MODELS -#if ENABLE_SEAMS_USING_INSTANCED_MODELS statistics->models_instances_size += SLIC3R_STDVEC_MEMSIZE(buffer.model.instances.buffer, float); statistics->models_instances_size += SLIC3R_STDVEC_MEMSIZE(buffer.model.instances.s_ids, size_t); statistics->models_instances_size += SLIC3R_STDVEC_MEMSIZE(buffer.model.instances.render_ranges.ranges, InstanceVBuffer::Ranges::Range); -#else - statistics->models_instances_size += SLIC3R_STDVEC_MEMSIZE(buffer.model.instances, TBuffer::Model::Instance); -#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS #endif // ENABLE_SEAMS_USING_MODELS } statistics->refresh_paths_time = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start_time).count(); @@ -2742,11 +2664,8 @@ void GCodeViewer::render_toolpaths() #if ENABLE_SEAMS_USING_MODELS auto render_as_instanced_model = [this] (TBuffer& buffer, GLShaderProgram & shader) { -#if ENABLE_SEAMS_USING_INSTANCED_MODELS for (auto& range : buffer.model.instances.render_ranges.ranges) { if (range.vbo == 0 && range.count > 0) { - std::cout << range.offset * buffer.model.instances.instance_size_bytes() << " + " << range.count * buffer.model.instances.instance_size_bytes() << " = " << buffer.model.instances.buffer.size() * sizeof(float) << "\n"; - glsafe(::glGenBuffers(1, &range.vbo)); glsafe(::glBindBuffer(GL_ARRAY_BUFFER, range.vbo)); glsafe(::glBufferData(GL_ARRAY_BUFFER, range.count * buffer.model.instances.instance_size_bytes(), (const void*)&buffer.model.instances.buffer[range.offset * buffer.model.instances.instance_size_floats()], GL_STATIC_DRAW)); @@ -2762,28 +2681,6 @@ void GCodeViewer::render_toolpaths() #endif // ENABLE_GCODE_VIEWER_STATISTICS } } -#else - for (const TBuffer::Model::Instance& inst : buffer.model.instances) { - bool top_layer_only = get_app_config()->get("seq_top_layer_only") == "1"; - bool visible = top_layer_only ? - m_sequential_view.global.first <= inst.s_id && inst.s_id <= m_sequential_view.global.last : - m_sequential_view.current.first <= inst.s_id && inst.s_id <= m_sequential_view.current.last; - - if (visible) { - glsafe(::glPushMatrix()); - glsafe(::glTranslatef(inst.position.x(), inst.position.y(), inst.position.z() - 0.5f * inst.height)); - glsafe(::glScalef(inst.width, inst.width, inst.height)); - Color color = (top_layer_only && m_sequential_view.current.last != m_sequential_view.global.last && inst.s_id < m_sequential_view.endpoints.first) ? - Neutral_Color : buffer.model.color; - buffer.model.model.set_color(-1, color); - buffer.model.model.render(); - glsafe(::glPopMatrix()); -#if ENABLE_GCODE_VIEWER_STATISTICS - ++m_statistics.gl_models_calls_count; -#endif // ENABLE_GCODE_VIEWER_STATISTICS - } - } -#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS }; #endif // ENABLE_SEAMS_USING_MODELS @@ -3852,11 +3749,7 @@ void GCodeViewer::render_statistics() add_counter(std::string("Multi GL_TRIANGLES:"), m_statistics.gl_multi_triangles_calls_count); add_counter(std::string("GL_TRIANGLES:"), m_statistics.gl_triangles_calls_count); #if ENABLE_SEAMS_USING_MODELS -#if ENABLE_SEAMS_USING_INSTANCED_MODELS add_counter(std::string("Instanced models:"), m_statistics.gl_instanced_models_calls_count); -#else - add_counter(std::string("Models:"), m_statistics.gl_models_calls_count); -#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS #endif // ENABLE_SEAMS_USING_MODELS } @@ -3874,9 +3767,9 @@ void GCodeViewer::render_statistics() if (ImGui::CollapsingHeader("GPU memory")) { add_memory(std::string("Vertices:"), m_statistics.total_vertices_gpu_size); add_memory(std::string("Indices:"), m_statistics.total_indices_gpu_size); -#if ENABLE_SEAMS_USING_INSTANCED_MODELS +#if ENABLE_SEAMS_USING_MODELS add_memory(std::string("Instances:"), m_statistics.total_instances_gpu_size); -#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS +#endif // ENABLE_SEAMS_USING_MODELS ImGui::Separator(); add_memory(std::string("Max VBuffer:"), m_statistics.max_vbuffer_gpu_size); add_memory(std::string("Max IBuffer:"), m_statistics.max_ibuffer_gpu_size); diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 46f6558dd..429175fe6 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -27,10 +27,10 @@ class GCodeViewer using MultiVertexBuffer = std::vector; using IndexBuffer = std::vector; using MultiIndexBuffer = std::vector; -#if ENABLE_SEAMS_USING_INSTANCED_MODELS +#if ENABLE_SEAMS_USING_MODELS using InstanceBuffer = std::vector; using InstanceIdBuffer = std::vector; -#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS +#endif // ENABLE_SEAMS_USING_MODELS static const std::vector Extrusion_Role_Colors; static const std::vector Options_Colors; @@ -104,7 +104,7 @@ class GCodeViewer void reset(); }; -#if ENABLE_SEAMS_USING_INSTANCED_MODELS +#if ENABLE_SEAMS_USING_MODELS // buffer containing instances data used to render a toolpaths using instanced models // instance record format: 5 floats -> position.x|position.y|position.z|width|height // which is sent to the shader as -> vec3 (offset) + vec2 (scales) in GLModel::render_instanced() @@ -143,7 +143,7 @@ class GCodeViewer void reset(); }; -#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS +#endif // ENABLE_SEAMS_USING_MODELS // ibo buffer containing indices data (for lines/triangles) used to render a specific toolpath type struct IBuffer @@ -295,24 +295,9 @@ class GCodeViewer #if ENABLE_SEAMS_USING_MODELS struct Model { -#if !ENABLE_SEAMS_USING_INSTANCED_MODELS - struct Instance - { - Vec3f position; - float width; - float height; - size_t s_id; - }; - using Instances = std::vector; -#endif // !ENABLE_SEAMS_USING_INSTANCED_MODELS - GLModel model; Color color; -#if ENABLE_SEAMS_USING_INSTANCED_MODELS InstanceVBuffer instances; -#else - Instances instances; -#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS void reset(); }; @@ -377,11 +362,7 @@ class GCodeViewer case ERenderPrimitiveType::Triangle: { return !vertices.vbos.empty() && vertices.vbos.front() != 0 && !indices.empty() && indices.front().ibo != 0; } -#if ENABLE_SEAMS_USING_INSTANCED_MODELS case ERenderPrimitiveType::Model: { return model.model.is_initialized() && !model.instances.buffer.empty(); } -#else - case ERenderPrimitiveType::Model: { return model.model.is_initialized() && !model.instances.empty(); } -#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS default: { return false; } } } @@ -538,19 +519,15 @@ class GCodeViewer int64_t gl_multi_triangles_calls_count{ 0 }; int64_t gl_triangles_calls_count{ 0 }; #if ENABLE_SEAMS_USING_MODELS -#if ENABLE_SEAMS_USING_INSTANCED_MODELS int64_t gl_instanced_models_calls_count{ 0 }; -#else - int64_t gl_models_calls_count{ 0 }; -#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS #endif // ENABLE_SEAMS_USING_MODELS // memory int64_t results_size{ 0 }; int64_t total_vertices_gpu_size{ 0 }; int64_t total_indices_gpu_size{ 0 }; -#if ENABLE_SEAMS_USING_INSTANCED_MODELS +#if ENABLE_SEAMS_USING_MODELS int64_t total_instances_gpu_size{ 0 }; -#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS +#endif // ENABLE_SEAMS_USING_MODELS int64_t max_vbuffer_gpu_size{ 0 }; int64_t max_ibuffer_gpu_size{ 0 }; int64_t paths_size{ 0 }; @@ -591,11 +568,7 @@ class GCodeViewer gl_multi_triangles_calls_count = 0; gl_triangles_calls_count = 0; #if ENABLE_SEAMS_USING_MODELS -#if ENABLE_SEAMS_USING_INSTANCED_MODELS gl_instanced_models_calls_count = 0; -#else - gl_models_calls_count = 0; -#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS #endif // ENABLE_SEAMS_USING_MODELS } @@ -603,9 +576,9 @@ class GCodeViewer results_size = 0; total_vertices_gpu_size = 0; total_indices_gpu_size = 0; -#if ENABLE_SEAMS_USING_INSTANCED_MODELS +#if ENABLE_SEAMS_USING_MODELS total_instances_gpu_size = 0; -#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS +#endif // ENABLE_SEAMS_USING_MODELS max_vbuffer_gpu_size = 0; max_ibuffer_gpu_size = 0; paths_size = 0; diff --git a/src/slic3r/GUI/GLModel.cpp b/src/slic3r/GUI/GLModel.cpp index ce44c4649..5cddd7fa3 100644 --- a/src/slic3r/GUI/GLModel.cpp +++ b/src/slic3r/GUI/GLModel.cpp @@ -208,7 +208,7 @@ void GLModel::render() const } } -#if ENABLE_SEAMS_USING_INSTANCED_MODELS +#if ENABLE_SEAMS_USING_MODELS void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instances_count) const { if (instances_vbo == 0) @@ -285,7 +285,7 @@ void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instance glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); } -#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS +#endif // ENABLE_SEAMS_USING_MODELS void GLModel::send_to_gpu(RenderData& data, const std::vector& vertices, const std::vector& indices) { diff --git a/src/slic3r/GUI/GLModel.hpp b/src/slic3r/GUI/GLModel.hpp index 73fb90827..8e0039b08 100644 --- a/src/slic3r/GUI/GLModel.hpp +++ b/src/slic3r/GUI/GLModel.hpp @@ -72,9 +72,9 @@ namespace GUI { void reset(); void render() const; -#if ENABLE_SEAMS_USING_INSTANCED_MODELS +#if ENABLE_SEAMS_USING_MODELS void render_instanced(unsigned int instances_vbo, unsigned int instances_count) const; -#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS +#endif // ENABLE_SEAMS_USING_MODELS bool is_initialized() const { return !m_render_data.empty(); } diff --git a/src/slic3r/GUI/GLShadersManager.cpp b/src/slic3r/GUI/GLShadersManager.cpp index 418fe8d1e..c93f22f46 100644 --- a/src/slic3r/GUI/GLShadersManager.cpp +++ b/src/slic3r/GUI/GLShadersManager.cpp @@ -38,17 +38,17 @@ std::pair GLShadersManager::init() // used to render printbed valid &= append_shader("printbed", { "printbed.vs", "printbed.fs" }); // used to render options in gcode preview -#if ENABLE_SEAMS_USING_INSTANCED_MODELS +#if ENABLE_SEAMS_USING_MODELS if (GUI::wxGetApp().is_gl_version_greater_or_equal_to(3, 1)) valid &= append_shader("gouraud_light_instanced", { "gouraud_light_instanced.vs", "gouraud_light_instanced.fs" }); else { -#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS +#endif // ENABLE_SEAMS_USING_MODELS valid &= append_shader("options_110", { "options_110.vs", "options_110.fs" }); if (GUI::wxGetApp().is_glsl_version_greater_or_equal_to(1, 20)) valid &= append_shader("options_120", { "options_120.vs", "options_120.fs" }); -#if ENABLE_SEAMS_USING_INSTANCED_MODELS +#if ENABLE_SEAMS_USING_MODELS } -#endif // ENABLE_SEAMS_USING_INSTANCED_MODELS +#endif // ENABLE_SEAMS_USING_MODELS // used to render extrusion and travel paths as lines in gcode preview valid &= append_shader("toolpaths_lines", { "toolpaths_lines.vs", "toolpaths_lines.fs" }); // used to render objects in 3d editor From 7bd14bfaf7fef96719a37e5d632c1f09cfebf348 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 27 Aug 2021 15:23:27 +0200 Subject: [PATCH 17/18] ENABLE_SEAMS_USING_MODELS -> Fixed instances when horizontal slider is enabled for top layer only --- src/slic3r/GUI/GCodeViewer.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 382b78ca3..9ac0536a4 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -2421,7 +2421,10 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool if (has_second_range) { if (id <= m_sequential_view.endpoints.first) { ++buffer.model.instances.render_ranges.ranges.front().offset; - ++buffer.model.instances.render_ranges.ranges.back().count; + if (id <= m_sequential_view.current.first) + ++buffer.model.instances.render_ranges.ranges.back().offset; + else + ++buffer.model.instances.render_ranges.ranges.back().count; } else if (id <= m_sequential_view.current.last) ++buffer.model.instances.render_ranges.ranges.front().count; From 876f9d5a990404b568a67cc088497627072e88ed Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 30 Aug 2021 08:37:41 +0200 Subject: [PATCH 18/18] Cleanup in shader gouraud_light_instanced.vs --- resources/shaders/gouraud_light_instanced.vs | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/resources/shaders/gouraud_light_instanced.vs b/resources/shaders/gouraud_light_instanced.vs index 5d6a05a6f..69f58d6e1 100644 --- a/resources/shaders/gouraud_light_instanced.vs +++ b/resources/shaders/gouraud_light_instanced.vs @@ -14,14 +14,12 @@ const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074); #define INTENSITY_AMBIENT 0.3 -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // vertex attributes in vec3 v_position; in vec3 v_normal; // instance attributes in vec3 i_offset; in vec2 i_scales; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // x = tainted, y = specular; varying vec2 intensity; @@ -29,29 +27,20 @@ varying vec2 intensity; void main() { // First transform the normal into camera space and normalize the result. -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ vec3 eye_normal = normalize(gl_NormalMatrix * v_normal); -// vec3 eye_normal = normalize(gl_NormalMatrix * gl_Normal); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex. // Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range. float NdotL = max(dot(eye_normal, LIGHT_TOP_DIR), 0.0); intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ vec4 world_position = vec4(v_position * vec3(vec2(i_scales.x), i_scales.y) + i_offset, 1.0); vec3 eye_position = (gl_ModelViewMatrix * world_position).xyz; -// vec3 eye_position = (gl_ModelViewMatrix * gl_Vertex).xyz; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(eye_position), reflect(-LIGHT_TOP_DIR, eye_normal)), 0.0), LIGHT_TOP_SHININESS); // Perform the same lighting calculation for the 2nd light source (no specular applied). NdotL = max(dot(eye_normal, LIGHT_FRONT_DIR), 0.0); intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ gl_Position = gl_ProjectionMatrix * vec4(eye_position, 1.0); -// gl_Position = ftransform(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ }