From 75677ba810040ab583ad6b2e19a3a4e9ac90745a Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 11 May 2021 13:12:25 +0200 Subject: [PATCH 01/31] Tech ENABLE_SEQUENTIAL_LIMITS -> 1st installment of visualization of objects clearance for sequential prints --- src/libslic3r/Print.cpp | 49 ++- src/libslic3r/Print.hpp | 4 + src/libslic3r/Technologies.hpp | 2 + src/slic3r/GUI/3DBed.cpp | 33 +- src/slic3r/GUI/3DBed.hpp | 9 +- src/slic3r/GUI/GCodeViewer.cpp | 5 + src/slic3r/GUI/GCodeViewer.hpp | 4 + src/slic3r/GUI/GLCanvas3D.cpp | 86 +++- src/slic3r/GUI/GLCanvas3D.hpp | 22 + src/slic3r/GUI/GLModel.cpp | 584 +++++++++++++++++++++++--- src/slic3r/GUI/GLModel.hpp | 78 +++- src/slic3r/GUI/Gizmos/GLGizmoBase.hpp | 2 - src/slic3r/GUI/Plater.cpp | 43 +- src/slic3r/GUI/Selection.cpp | 55 +++ 14 files changed, 889 insertions(+), 87 deletions(-) diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 7fcb75297..6cb78d2fa 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -1194,9 +1194,18 @@ bool Print::has_brim() const return std::any_of(m_objects.begin(), m_objects.end(), [](PrintObject *object) { return object->has_brim(); }); } +#if ENABLE_SEQUENTIAL_LIMITS +bool Print::sequential_print_horizontal_clearance_valid(const Print& print, Polygons* polygons) +#else static inline bool sequential_print_horizontal_clearance_valid(const Print &print) +#endif // ENABLE_SEQUENTIAL_LIMITS { Polygons convex_hulls_other; +#if ENABLE_SEQUENTIAL_LIMITS + std::vector intersecting_idxs; + bool intersection_detected = false; +#endif // ENABLE_SEQUENTIAL_LIMITS + std::map map_model_object_to_convex_hull; for (const PrintObject *print_object : print.objects()) { assert(! print_object->model_object()->instances.empty()); @@ -1221,21 +1230,49 @@ static inline bool sequential_print_horizontal_clearance_valid(const Print &prin } // Make a copy, so it may be rotated for instances. Polygon convex_hull0 = it_convex_hull->second; - double z_diff = Geometry::rotation_diff_z(model_instance0->get_rotation(), print_object->instances().front().model_instance->get_rotation()); + const double z_diff = Geometry::rotation_diff_z(model_instance0->get_rotation(), print_object->instances().front().model_instance->get_rotation()); if (std::abs(z_diff) > EPSILON) convex_hull0.rotate(z_diff); // Now we check that no instance of convex_hull intersects any of the previously checked object instances. for (const PrintInstance &instance : print_object->instances()) { Polygon convex_hull = convex_hull0; // instance.shift is a position of a centered object, while model object may not be centered. - // Conver the shift from the PrintObject's coordinates into ModelObject's coordinates by removing the centering offset. + // Convert the shift from the PrintObject's coordinates into ModelObject's coordinates by removing the centering offset. convex_hull.translate(instance.shift - print_object->center_offset()); - if (! intersection(convex_hulls_other, (Polygons)convex_hull).empty()) - return false; - convex_hulls_other.emplace_back(std::move(convex_hull)); +#if ENABLE_SEQUENTIAL_LIMITS + for (size_t i = 0; i < convex_hulls_other.size(); ++i) { + if (!intersection((Polygons)convex_hulls_other[i], (Polygons)convex_hull).empty()) { + if (polygons == nullptr) + return false; + else { + intersection_detected = true; + intersecting_idxs.push_back(i); + intersecting_idxs.push_back(convex_hulls_other.size()); + } + } + } +#else + if (!intersection(convex_hulls_other, (Polygons)convex_hull).empty()) + return false; +#endif // ENABLE_SEQUENTIAL_LIMITS + convex_hulls_other.emplace_back(std::move(convex_hull)); } } - return true; + +#if ENABLE_SEQUENTIAL_LIMITS + if (intersection_detected) { + assert(polygons != nullptr); + + std::sort(intersecting_idxs.begin(), intersecting_idxs.end()); + intersecting_idxs.erase(std::unique(intersecting_idxs.begin(), intersecting_idxs.end()), intersecting_idxs.end()); + for (size_t i : intersecting_idxs) { + polygons->emplace_back(std::move(convex_hulls_other[i])); + } + + return false; + } +#endif // ENABLE_SEQUENTIAL_LIMITS + return true; } static inline bool sequential_print_vertical_clearance_valid(const Print &print) diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index 91f86d010..730c88a50 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -502,6 +502,10 @@ public: const PrintRegion* get_region(size_t idx) const { return m_regions[idx]; } const ToolOrdering& get_tool_ordering() const { return m_wipe_tower_data.tool_ordering; } // #ys_FIXME just for testing +#if ENABLE_SEQUENTIAL_LIMITS + static bool sequential_print_horizontal_clearance_valid(const Print& print, Polygons* polygons = nullptr); +#endif // ENABLE_SEQUENTIAL_LIMITS + protected: // methods for handling regions PrintRegion* get_region(size_t idx) { return m_regions[idx]; } diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index a28d23bcc..1bdb36c8f 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -63,6 +63,8 @@ #define ENABLE_START_GCODE_VISUALIZATION (1 && ENABLE_2_4_0_ALPHA0) // Enable visualization of seams in preview #define ENABLE_SEAMS_VISUALIZATION (1 && ENABLE_2_4_0_ALPHA0) +// Enable visualization of objects clearance for sequential prints +#define ENABLE_SEQUENTIAL_LIMITS (1 && ENABLE_2_4_0_ALPHA0) #endif // _prusaslicer_technologies_h_ diff --git a/src/slic3r/GUI/3DBed.cpp b/src/slic3r/GUI/3DBed.cpp index 29551ac15..6ac61ad94 100644 --- a/src/slic3r/GUI/3DBed.cpp +++ b/src/slic3r/GUI/3DBed.cpp @@ -98,12 +98,6 @@ const float Bed3D::Axes::DefaultStemLength = 25.0f; const float Bed3D::Axes::DefaultTipRadius = 2.5f * Bed3D::Axes::DefaultStemRadius; const float Bed3D::Axes::DefaultTipLength = 5.0f; -void Bed3D::Axes::set_stem_length(float length) -{ - m_stem_length = length; - m_arrow.reset(); -} - void Bed3D::Axes::render() const { auto render_axis = [this](const Transform3f& transform) { @@ -113,7 +107,10 @@ void Bed3D::Axes::render() const glsafe(::glPopMatrix()); }; - const_cast(&m_arrow)->init_from(stilized_arrow(16, DefaultTipRadius, DefaultTipLength, DefaultStemRadius, m_stem_length)); +#if ENABLE_SEQUENTIAL_LIMITS + if (!m_arrow.is_initialized()) +#endif // ENABLE_SEQUENTIAL_LIMITS + const_cast(&m_arrow)->init_from(stilized_arrow(16, DefaultTipRadius, DefaultTipLength, DefaultStemRadius, m_stem_length)); GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); if (shader == nullptr) @@ -124,18 +121,30 @@ void Bed3D::Axes::render() const shader->start_using(); // x axis +#if ENABLE_SEQUENTIAL_LIMITS + const_cast(&m_arrow)->set_color(-1, { 0.75f, 0.0f, 0.0f, 1.0f }); +#else std::array color = { 0.75f, 0.0f, 0.0f, 1.0f }; shader->set_uniform("uniform_color", color); - render_axis(Geometry::assemble_transform(m_origin, { 0.0, 0.5 * M_PI, 0.0f }).cast()); +#endif // ENABLE_SEQUENTIAL_LIMITS + render_axis(Geometry::assemble_transform(m_origin, { 0.0, 0.5 * M_PI, 0.0 }).cast()); // y axis +#if ENABLE_SEQUENTIAL_LIMITS + const_cast(&m_arrow)->set_color(-1, { 0.0f, 0.75f, 0.0f, 1.0f }); +#else color = { 0.0f, 0.75f, 0.0f, 1.0f }; shader->set_uniform("uniform_color", color); - render_axis(Geometry::assemble_transform(m_origin, { -0.5 * M_PI, 0.0, 0.0f }).cast()); +#endif // ENABLE_SEQUENTIAL_LIMITS + render_axis(Geometry::assemble_transform(m_origin, { -0.5 * M_PI, 0.0, 0.0 }).cast()); // z axis +#if ENABLE_SEQUENTIAL_LIMITS + const_cast(&m_arrow)->set_color(-1, { 0.0f, 0.0f, 0.75f, 1.0f }); +#else color = { 0.0f, 0.0f, 0.75f, 1.0f }; shader->set_uniform("uniform_color", color); +#endif // ENABLE_SEQUENTIAL_LIMITS render_axis(Geometry::assemble_transform(m_origin).cast()); shader->stop_using(); @@ -475,6 +484,10 @@ void Bed3D::render_model() const GLModel* model = const_cast(&m_model); if (model->get_filename() != m_model_filename && model->init_from_file(m_model_filename)) { +#if ENABLE_SEQUENTIAL_LIMITS + model->set_color(-1, m_model_color); +#endif // ENABLE_SEQUENTIAL_LIMITS + // move the model so that its origin (0.0, 0.0, 0.0) goes into the bed shape center and a bit down to avoid z-fighting with the texture quad Vec3d shift = m_bounding_box.center(); shift(2) = -0.03; @@ -488,7 +501,9 @@ void Bed3D::render_model() const GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); if (shader != nullptr) { shader->start_using(); +#if !ENABLE_SEQUENTIAL_LIMITS shader->set_uniform("uniform_color", m_model_color); +#endif // !ENABLE_SEQUENTIAL_LIMITS ::glPushMatrix(); ::glTranslated(m_model_offset(0), m_model_offset(1), m_model_offset(2)); model->render(); diff --git a/src/slic3r/GUI/3DBed.hpp b/src/slic3r/GUI/3DBed.hpp index c2630b799..71382315d 100644 --- a/src/slic3r/GUI/3DBed.hpp +++ b/src/slic3r/GUI/3DBed.hpp @@ -17,8 +17,8 @@ class GeometryBuffer { struct Vertex { - Vec3f position = Vec3f::Zero(); - Vec2f tex_coords = Vec2f::Zero(); + Vec3f position{ Vec3f::Zero() }; + Vec2f tex_coords{ Vec2f::Zero() }; }; std::vector m_vertices; @@ -53,7 +53,10 @@ class Bed3D public: const Vec3d& get_origin() const { return m_origin; } void set_origin(const Vec3d& origin) { m_origin = origin; } - void set_stem_length(float length); + void set_stem_length(float length) { + m_stem_length = length; + m_arrow.reset(); + } float get_total_length() const { return m_stem_length + DefaultTipLength; } void render() const; }; diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index ca1617bc2..1ed4a97c2 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -241,6 +241,9 @@ void GCodeViewer::SequentialRangeCap::reset() { void GCodeViewer::SequentialView::Marker::init() { m_model.init_from(stilized_arrow(16, 2.0f, 4.0f, 1.0f, 8.0f)); +#if ENABLE_SEQUENTIAL_LIMITS + m_model.set_color(-1, { 1.0f, 1.0f, 1.0f, 0.5f }); +#endif // ENABLE_SEQUENTIAL_LIMITS } void GCodeViewer::SequentialView::Marker::set_world_position(const Vec3f& position) @@ -262,7 +265,9 @@ void GCodeViewer::SequentialView::Marker::render() const glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); shader->start_using(); +#if !ENABLE_SEQUENTIAL_LIMITS shader->set_uniform("uniform_color", m_color); +#endif // !ENABLE_SEQUENTIAL_LIMITS glsafe(::glPushMatrix()); glsafe(::glMultMatrixf(m_world_transform.data())); diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 2ccda6f5d..1ea3b49c8 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -581,7 +581,9 @@ public: Vec3f m_world_position; Transform3f m_world_transform; float m_z_offset{ 0.5f }; +#if !ENABLE_SEQUENTIAL_LIMITS std::array m_color{ 1.0f, 1.0f, 1.0f, 0.5f }; +#endif // !ENABLE_SEQUENTIAL_LIMITS bool m_visible{ true }; public: @@ -590,7 +592,9 @@ public: const BoundingBoxf3& get_bounding_box() const { return m_model.get_bounding_box(); } void set_world_position(const Vec3f& position); +#if !ENABLE_SEQUENTIAL_LIMITS void set_color(const std::array& color) { m_color = color; } +#endif // !ENABLE_SEQUENTIAL_LIMITS bool is_visible() const { return m_visible; } void set_visible(bool visible) { m_visible = visible; } diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 6dcd30c29..55ddfd9f3 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1069,6 +1069,80 @@ void GLCanvas3D::Tooltip::render(const Vec2d& mouse_position, GLCanvas3D& canvas ImGui::PopStyleVar(2); } +#if ENABLE_SEQUENTIAL_LIMITS +void GLCanvas3D::SequentialPrintClearance::set(const Polygons& polygons) +{ + m_model.reset(); + if (polygons.empty()) + return; + + size_t triangles_count = 0; + for (const Polygon& poly : polygons) { + triangles_count += poly.points.size() - 2; + } + size_t vertices_count = 3 * triangles_count; + + GLModel::InitializationData data; + GLModel::InitializationData::Entity entity; + entity.type = GLModel::PrimitiveType::Triangles; + entity.color = { 0.3333f, 0.3333f, 0.3333f, 1.0f }; + entity.positions.reserve(vertices_count); + entity.normals.reserve(vertices_count); + entity.indices.reserve(vertices_count); + + for (const Polygon& poly : polygons) { + std::vector triangulation = triangulate_expolygon_3d(ExPolygon(poly), false); + for (const Vec3d& v : triangulation) { + entity.positions.emplace_back(v.cast()); + entity.normals.emplace_back(Vec3f::UnitZ()); + size_t positions_count = entity.positions.size(); + if (positions_count % 3 == 0) { + entity.indices.emplace_back(positions_count - 3); + entity.indices.emplace_back(positions_count - 2); + entity.indices.emplace_back(positions_count - 1); + } + } + } + + data.entities.emplace_back(entity); + + for (const Polygon& poly : polygons) { + GLModel::InitializationData::Entity ent; + ent.type = GLModel::PrimitiveType::LineLoop; + ent.color = { 1.0f, 1.0f, 0.0f, 1.0f }; + ent.positions.reserve(poly.points.size()); + ent.indices.reserve(poly.points.size()); + unsigned int id_count = 0; + for (const Point& p : poly.points) { + ent.positions.emplace_back(unscale(p.x()), unscale(p.y()), 0.0f); + ent.normals.emplace_back(Vec3f::UnitZ()); + ent.indices.emplace_back(id_count++); + } + + data.entities.emplace_back(ent); + } + + m_model.init_from(data); +} + +void GLCanvas3D::SequentialPrintClearance::render() const +{ + GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); + if (shader == nullptr) + return; + + shader->start_using(); + + glsafe(::glDisable(GL_CULL_FACE)); + + m_model.render(); + + glsafe(::glEnable(GL_CULL_FACE)); + + shader->stop_using(); +} +#endif // ENABLE_SEQUENTIAL_LIMITS + float GLCanvas3D::Slope::s_window_width; wxDEFINE_EVENT(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS, SimpleEvent); @@ -1669,6 +1743,9 @@ void GLCanvas3D::render() _render_gcode(); _render_sla_slices(); _render_selection(); +#if ENABLE_SEQUENTIAL_LIMITS + _render_sequential_clearance(); +#endif // ENABLE_SEQUENTIAL_LIMITS _render_bed(!camera.is_looking_downward(), true); #if ENABLE_RENDER_SELECTION_CENTER @@ -2204,7 +2281,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re bool wt = dynamic_cast(m_config->option("wipe_tower"))->value; bool co = dynamic_cast(m_config->option("complete_objects"))->value; - if ((extruders_count > 1) && wt && !co) { + if (extruders_count > 1 && wt && !co) { // Height of a print (Show at least a slab) double height = std::max(m_model->bounding_box().max(2), 10.0); @@ -5140,6 +5217,13 @@ void GLCanvas3D::_render_selection() const m_selection.render(scale_factor); } +#if ENABLE_SEQUENTIAL_LIMITS +void GLCanvas3D::_render_sequential_clearance() const +{ + m_sequential_print_clearance.render(); +} +#endif // ENABLE_SEQUENTIAL_LIMITS + #if ENABLE_RENDER_SELECTION_CENTER void GLCanvas3D::_render_selection_center() const { diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 9e9a2501e..3ebb3ee6b 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -541,6 +541,19 @@ private: void load_arrange_settings(); +#if ENABLE_SEQUENTIAL_LIMITS + class SequentialPrintClearance + { + GLModel m_model; + + public: + void set(const Polygons& polygons); + void render() const; + }; + + SequentialPrintClearance m_sequential_print_clearance; +#endif // ENABLE_SEQUENTIAL_LIMITS + public: explicit GLCanvas3D(wxGLCanvas* canvas); ~GLCanvas3D(); @@ -782,6 +795,12 @@ public: #endif } +#if ENABLE_SEQUENTIAL_LIMITS + void set_sequential_print_clearance(const Polygons& polygons) { + m_sequential_print_clearance.set(polygons); + } +#endif // ENABLE_SEQUENTIAL_LIMITS + private: bool _is_shown_on_screen() const; @@ -808,6 +827,9 @@ private: void _render_objects() const; void _render_gcode() const; void _render_selection() const; +#if ENABLE_SEQUENTIAL_LIMITS + void _render_sequential_clearance() const; +#endif // ENABLE_SEQUENTIAL_LIMITS #if ENABLE_RENDER_SELECTION_CENTER void _render_selection_center() const; #endif // ENABLE_RENDER_SELECTION_CENTER diff --git a/src/slic3r/GUI/GLModel.cpp b/src/slic3r/GUI/GLModel.cpp index e738aa3c4..5452a1865 100644 --- a/src/slic3r/GUI/GLModel.cpp +++ b/src/slic3r/GUI/GLModel.cpp @@ -2,6 +2,11 @@ #include "GLModel.hpp" #include "3DScene.hpp" +#if ENABLE_SEQUENTIAL_LIMITS +#include "GUI_App.hpp" +#include "GLShader.hpp" +#endif // ENABLE_SEQUENTIAL_LIMITS + #include "libslic3r/TriangleMesh.hpp" #include "libslic3r/Model.hpp" @@ -13,6 +18,45 @@ namespace Slic3r { namespace GUI { +#if ENABLE_SEQUENTIAL_LIMITS +void GLModel::init_from(const InitializationData& data) +{ + if (!m_render_data.empty()) // call reset() if you want to reuse this model + return; + + for (const InitializationData::Entity& entity : data.entities) { + if (entity.positions.empty() || entity.indices.empty()) + continue; + + assert(entity.normals.empty() || entity.normals.size() == entity.positions.size()); + + RenderData rdata; + rdata.type = entity.type; + rdata.color = entity.color; + + // vertices/normals data + std::vector vertices(6 * entity.positions.size()); + for (size_t i = 0; i < entity.positions.size(); ++i) { + const size_t offset = i * 6; + ::memcpy(static_cast(&vertices[offset]), static_cast(entity.positions[i].data()), 3 * sizeof(float)); + if (!entity.normals.empty()) + ::memcpy(static_cast(&vertices[3 + offset]), static_cast(entity.normals[i].data()), 3 * sizeof(float)); + } + + // indices data + std::vector indices = entity.indices; + + rdata.indices_count = static_cast(indices.size()); + + // update bounding box + for (size_t i = 0; i < entity.positions.size(); ++i) { + m_bounding_box.merge(entity.positions[i].cast()); + } + + send_to_gpu(rdata, vertices, indices); + m_render_data.emplace_back(rdata); + } +#else void GLModel::init_from(const GLModelInitializationData& data) { assert(!data.positions.empty() && !data.triangles.empty()); @@ -44,10 +88,41 @@ void GLModel::init_from(const GLModelInitializationData& data) } send_to_gpu(vertices, indices); +#endif // ENABLE_SEQUENTIAL_LIMITS } void GLModel::init_from(const TriangleMesh& mesh) { +#if ENABLE_SEQUENTIAL_LIMITS + if (!m_render_data.empty()) // call reset() if you want to reuse this model + return; + + RenderData data; + data.type = PrimitiveType::Triangles; + + std::vector vertices = std::vector(18 * mesh.stl.stats.number_of_facets); + std::vector indices = std::vector(3 * mesh.stl.stats.number_of_facets); + + unsigned int vertices_count = 0; + for (uint32_t i = 0; i < mesh.stl.stats.number_of_facets; ++i) { + const stl_facet& facet = mesh.stl.facet_start[i]; + for (size_t j = 0; j < 3; ++j) { + size_t offset = i * 18 + j * 6; + ::memcpy(static_cast(&vertices[offset]), static_cast(facet.vertex[j].data()), 3 * sizeof(float)); + ::memcpy(static_cast(&vertices[3 + offset]), static_cast(facet.normal.data()), 3 * sizeof(float)); + } + for (size_t j = 0; j < 3; ++j) { + indices[i * 3 + j] = vertices_count + j; + } + vertices_count += 3; + } + + data.indices_count = static_cast(indices.size()); + m_bounding_box = mesh.bounding_box(); + + send_to_gpu(data, vertices, indices); + m_render_data.emplace_back(data); +#else if (m_vbo_id > 0) // call reset() if you want to reuse this model return; @@ -72,6 +147,7 @@ void GLModel::init_from(const TriangleMesh& mesh) m_bounding_box = mesh.bounding_box(); send_to_gpu(vertices, indices); +#endif // ENABLE_SEQUENTIAL_LIMITS } bool GLModel::init_from_file(const std::string& filename) @@ -99,8 +175,29 @@ bool GLModel::init_from_file(const std::string& filename) return true; } +#if ENABLE_SEQUENTIAL_LIMITS +void GLModel::set_color(int entity_id, const std::array& color) +{ + for (size_t i = 0; i < m_render_data.size(); ++i) { + if (entity_id == -1 || static_cast(i) == entity_id) + m_render_data[i].color = color; + } +} +#endif // ENABLE_SEQUENTIAL_LIMITS + void GLModel::reset() { +#if ENABLE_SEQUENTIAL_LIMITS + for (RenderData& data : m_render_data) { + // release gpu memory + if (data.ibo_id > 0) + glsafe(::glDeleteBuffers(1, &data.ibo_id)); + if (data.vbo_id > 0) + glsafe(::glDeleteBuffers(1, &data.vbo_id)); + } + + m_render_data.clear(); +#else // release gpu memory if (m_ibo_id > 0) { glsafe(::glDeleteBuffers(1, &m_ibo_id)); @@ -113,12 +210,49 @@ void GLModel::reset() } m_indices_count = 0; +#endif // ENABLE_SEQUENTIAL_LIMITS m_bounding_box = BoundingBoxf3(); m_filename = std::string(); } void GLModel::render() const { +#if ENABLE_SEQUENTIAL_LIMITS + 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; } + } + + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, data.vbo_id)); + glsafe(::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)0)); + glsafe(::glNormalPointer(GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float)))); + + glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); + glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); + + GLShaderProgram* shader = wxGetApp().get_current_shader(); + if (shader != nullptr) + shader->set_uniform("uniform_color", data.color); + + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.ibo_id)); + glsafe(::glDrawElements(mode, static_cast(data.indices_count), GL_UNSIGNED_INT, (const void*)0)); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + + glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); + glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); + + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + } +#else if (m_vbo_id == 0 || m_ibo_id == 0) return; @@ -137,8 +271,28 @@ void GLModel::render() const glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); +#endif // ENABLE_SEQUENTIAL_LIMITS } +#if ENABLE_SEQUENTIAL_LIMITS +void GLModel::send_to_gpu(RenderData& data, const std::vector& vertices, const std::vector& indices) +{ + assert(data.vbo_id == 0); + assert(data.ibo_id == 0); + + // vertex data -> send to gpu + glsafe(::glGenBuffers(1, &data.vbo_id)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, data.vbo_id)); + glsafe(::glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), vertices.data(), GL_STATIC_DRAW)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + + // indices data -> send to gpu + glsafe(::glGenBuffers(1, &data.ibo_id)); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.ibo_id)); + glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), indices.data(), GL_STATIC_DRAW)); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); +} +#else void GLModel::send_to_gpu(const std::vector& vertices, const std::vector& indices) { // vertex data -> send to gpu @@ -153,60 +307,138 @@ void GLModel::send_to_gpu(const std::vector& vertices, const std::vector< glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), indices.data(), GL_STATIC_DRAW)); glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); } +#endif // ENABLE_SEQUENTIAL_LIMITS +#if ENABLE_SEQUENTIAL_LIMITS +GLModel::InitializationData stilized_arrow(int resolution, float tip_radius, float tip_height, float stem_radius, float stem_height) +{ + auto append_vertex = [](GLModel::InitializationData::Entity& entity, const Vec3f& position, const Vec3f& normal) { + entity.positions.emplace_back(position); + entity.normals.emplace_back(normal); + }; + auto append_indices = [](GLModel::InitializationData::Entity& entity, unsigned int v1, unsigned int v2, unsigned int v3) { + entity.indices.emplace_back(v1); + entity.indices.emplace_back(v2); + entity.indices.emplace_back(v3); + }; +#else GLModelInitializationData stilized_arrow(int resolution, float tip_radius, float tip_height, float stem_radius, float stem_height) { auto append_vertex = [](GLModelInitializationData& data, const Vec3f& position, const Vec3f& normal) { data.positions.emplace_back(position); data.normals.emplace_back(normal); }; +#endif // ENABLE_SEQUENTIAL_LIMITS resolution = std::max(4, resolution); +#if ENABLE_SEQUENTIAL_LIMITS + GLModel::InitializationData data; + GLModel::InitializationData::Entity entity; + entity.type = GLModel::PrimitiveType::Triangles; +#else GLModelInitializationData data; +#endif // ENABLE_SEQUENTIAL_LIMITS const float angle_step = 2.0f * M_PI / static_cast(resolution); std::vector cosines(resolution); std::vector sines(resolution); - for (int i = 0; i < resolution; ++i) - { - float angle = angle_step * static_cast(i); + for (int i = 0; i < resolution; ++i) { + const float angle = angle_step * static_cast(i); cosines[i] = ::cos(angle); sines[i] = -::sin(angle); } const float total_height = tip_height + stem_height; +#if ENABLE_SEQUENTIAL_LIMITS + // tip vertices/normals + append_vertex(entity, { 0.0f, 0.0f, total_height }, Vec3f::UnitZ()); + for (int i = 0; i < resolution; ++i) { + append_vertex(entity, { tip_radius * sines[i], tip_radius * cosines[i], stem_height }, { sines[i], cosines[i], 0.0f }); + } + + // tip triangles + for (int i = 0; i < resolution; ++i) { + const int v3 = (i < resolution - 1) ? i + 2 : 1; + append_indices(entity, 0, i + 1, v3); + } + + // tip cap outer perimeter vertices + for (int i = 0; i < resolution; ++i) { + append_vertex(entity, { tip_radius * sines[i], tip_radius * cosines[i], stem_height }, -Vec3f::UnitZ()); + } + + // tip cap inner perimeter vertices + for (int i = 0; i < resolution; ++i) { + append_vertex(entity, { stem_radius * sines[i], stem_radius * cosines[i], stem_height }, -Vec3f::UnitZ()); + } + + // tip cap triangles + for (int i = 0; i < resolution; ++i) { + const int v2 = (i < resolution - 1) ? i + resolution + 2 : resolution + 1; + const int v3 = (i < resolution - 1) ? i + 2 * resolution + 2 : 2 * resolution + 1; + append_indices(entity, i + resolution + 1, v3, v2); + append_indices(entity, i + resolution + 1, i + 2 * resolution + 1, v3); + } + + // stem bottom vertices + for (int i = 0; i < resolution; ++i) { + append_vertex(entity, { stem_radius * sines[i], stem_radius * cosines[i], stem_height }, { sines[i], cosines[i], 0.0f }); + } + + // stem top vertices + for (int i = 0; i < resolution; ++i) { + append_vertex(entity, { stem_radius * sines[i], stem_radius * cosines[i], 0.0f }, { sines[i], cosines[i], 0.0f }); + } + + // stem triangles + for (int i = 0; i < resolution; ++i) { + const int v2 = (i < resolution - 1) ? i + 3 * resolution + 2 : 3 * resolution + 1; + const int v3 = (i < resolution - 1) ? i + 4 * resolution + 2 : 4 * resolution + 1; + append_indices(entity, i + 3 * resolution + 1, v3, v2); + append_indices(entity, i + 3 * resolution + 1, i + 4 * resolution + 1, v3); + } + + // stem cap vertices + append_vertex(entity, Vec3f::Zero(), -Vec3f::UnitZ()); + for (int i = 0; i < resolution; ++i) { + append_vertex(entity, { stem_radius * sines[i], stem_radius * cosines[i], 0.0f }, -Vec3f::UnitZ()); + } + + // stem cap triangles + for (int i = 0; i < resolution; ++i) { + const int v3 = (i < resolution - 1) ? i + 5 * resolution + 3 : 5 * resolution + 2; + append_indices(entity, 5 * resolution + 1, v3, i + 5 * resolution + 2); + } + + data.entities.emplace_back(entity); +#else // tip vertices/normals append_vertex(data, { 0.0f, 0.0f, total_height }, Vec3f::UnitZ()); - for (int i = 0; i < resolution; ++i) - { + for (int i = 0; i < resolution; ++i) { append_vertex(data, { tip_radius * sines[i], tip_radius * cosines[i], stem_height }, { sines[i], cosines[i], 0.0f }); } // tip triangles - for (int i = 0; i < resolution; ++i) - { + for (int i = 0; i < resolution; ++i) { int v3 = (i < resolution - 1) ? i + 2 : 1; data.triangles.emplace_back(0, i + 1, v3); } // tip cap outer perimeter vertices - for (int i = 0; i < resolution; ++i) - { + for (int i = 0; i < resolution; ++i) { append_vertex(data, { tip_radius * sines[i], tip_radius * cosines[i], stem_height }, -Vec3f::UnitZ()); } // tip cap inner perimeter vertices - for (int i = 0; i < resolution; ++i) - { + for (int i = 0; i < resolution; ++i) { append_vertex(data, { stem_radius * sines[i], stem_radius * cosines[i], stem_height }, -Vec3f::UnitZ()); } // tip cap triangles - for (int i = 0; i < resolution; ++i) - { + for (int i = 0; i < resolution; ++i) { int v2 = (i < resolution - 1) ? i + resolution + 2 : resolution + 1; int v3 = (i < resolution - 1) ? i + 2 * resolution + 2 : 2 * resolution + 1; data.triangles.emplace_back(i + resolution + 1, v3, v2); @@ -214,20 +446,17 @@ GLModelInitializationData stilized_arrow(int resolution, float tip_radius, float } // stem bottom vertices - for (int i = 0; i < resolution; ++i) - { + for (int i = 0; i < resolution; ++i) { append_vertex(data, { stem_radius * sines[i], stem_radius * cosines[i], stem_height }, { sines[i], cosines[i], 0.0f }); } // stem top vertices - for (int i = 0; i < resolution; ++i) - { + for (int i = 0; i < resolution; ++i) { append_vertex(data, { stem_radius * sines[i], stem_radius * cosines[i], 0.0f }, { sines[i], cosines[i], 0.0f }); } // stem triangles - for (int i = 0; i < resolution; ++i) - { + for (int i = 0; i < resolution; ++i) { int v2 = (i < resolution - 1) ? i + 3 * resolution + 2 : 3 * resolution + 1; int v3 = (i < resolution - 1) ? i + 4 * resolution + 2 : 4 * resolution + 1; data.triangles.emplace_back(i + 3 * resolution + 1, v3, v2); @@ -236,31 +465,50 @@ GLModelInitializationData stilized_arrow(int resolution, float tip_radius, float // stem cap vertices append_vertex(data, Vec3f::Zero(), -Vec3f::UnitZ()); - for (int i = 0; i < resolution; ++i) - { + for (int i = 0; i < resolution; ++i) { append_vertex(data, { stem_radius * sines[i], stem_radius * cosines[i], 0.0f }, -Vec3f::UnitZ()); } // stem cap triangles - for (int i = 0; i < resolution; ++i) - { + for (int i = 0; i < resolution; ++i) { int v3 = (i < resolution - 1) ? i + 5 * resolution + 3 : 5 * resolution + 2; data.triangles.emplace_back(5 * resolution + 1, v3, i + 5 * resolution + 2); } +#endif // ENABLE_SEQUENTIAL_LIMITS return data; } +#if ENABLE_SEQUENTIAL_LIMITS +GLModel::InitializationData circular_arrow(int resolution, float radius, float tip_height, float tip_width, float stem_width, float thickness) +{ + auto append_vertex = [](GLModel::InitializationData::Entity& entity, const Vec3f& position, const Vec3f& normal) { + entity.positions.emplace_back(position); + entity.normals.emplace_back(normal); + }; + auto append_indices = [](GLModel::InitializationData::Entity& entity, unsigned int v1, unsigned int v2, unsigned int v3) { + entity.indices.emplace_back(v1); + entity.indices.emplace_back(v2); + entity.indices.emplace_back(v3); + }; +#else GLModelInitializationData circular_arrow(int resolution, float radius, float tip_height, float tip_width, float stem_width, float thickness) { auto append_vertex = [](GLModelInitializationData& data, const Vec3f& position, const Vec3f& normal) { data.positions.emplace_back(position); data.normals.emplace_back(normal); }; +#endif // ENABLE_SEQUENTIAL_LIMITS resolution = std::max(2, resolution); +#if ENABLE_SEQUENTIAL_LIMITS + GLModel::InitializationData data; + GLModel::InitializationData::Entity entity; + entity.type = GLModel::PrimitiveType::Triangles; +#else GLModelInitializationData data; +#endif // ENABLE_SEQUENTIAL_LIMITS const float half_thickness = 0.5f * thickness; const float half_stem_width = 0.5f * stem_width; @@ -270,6 +518,153 @@ GLModelInitializationData circular_arrow(int resolution, float radius, float tip const float inner_radius = radius - half_stem_width; const float step_angle = 0.5f * PI / static_cast(resolution); +#if ENABLE_SEQUENTIAL_LIMITS + // tip + // top face vertices + append_vertex(entity, { 0.0f, outer_radius, half_thickness }, Vec3f::UnitZ()); + append_vertex(entity, { 0.0f, radius + half_tip_width, half_thickness }, Vec3f::UnitZ()); + append_vertex(entity, { -tip_height, radius, half_thickness }, Vec3f::UnitZ()); + append_vertex(entity, { 0.0f, radius - half_tip_width, half_thickness }, Vec3f::UnitZ()); + append_vertex(entity, { 0.0f, inner_radius, half_thickness }, Vec3f::UnitZ()); + + // top face triangles + append_indices(entity, 0, 1, 2); + append_indices(entity, 0, 2, 4); + append_indices(entity, 4, 2, 3); + + // bottom face vertices + append_vertex(entity, { 0.0f, outer_radius, -half_thickness }, -Vec3f::UnitZ()); + append_vertex(entity, { 0.0f, radius + half_tip_width, -half_thickness }, -Vec3f::UnitZ()); + append_vertex(entity, { -tip_height, radius, -half_thickness }, -Vec3f::UnitZ()); + append_vertex(entity, { 0.0f, radius - half_tip_width, -half_thickness }, -Vec3f::UnitZ()); + append_vertex(entity, { 0.0f, inner_radius, -half_thickness }, -Vec3f::UnitZ()); + + // bottom face triangles + append_indices(entity, 5, 7, 6); + append_indices(entity, 5, 9, 7); + append_indices(entity, 9, 8, 7); + + // side faces vertices + append_vertex(entity, { 0.0f, outer_radius, -half_thickness }, Vec3f::UnitX()); + append_vertex(entity, { 0.0f, radius + half_tip_width, -half_thickness }, Vec3f::UnitX()); + append_vertex(entity, { 0.0f, outer_radius, half_thickness }, Vec3f::UnitX()); + append_vertex(entity, { 0.0f, radius + half_tip_width, half_thickness }, Vec3f::UnitX()); + + Vec3f normal(-half_tip_width, tip_height, 0.0f); + normal.normalize(); + append_vertex(entity, { 0.0f, radius + half_tip_width, -half_thickness }, normal); + append_vertex(entity, { -tip_height, radius, -half_thickness }, normal); + append_vertex(entity, { 0.0f, radius + half_tip_width, half_thickness }, normal); + append_vertex(entity, { -tip_height, radius, half_thickness }, normal); + + normal = Vec3f(-half_tip_width, -tip_height, 0.0f); + normal.normalize(); + append_vertex(entity, { -tip_height, radius, -half_thickness }, normal); + append_vertex(entity, { 0.0f, radius - half_tip_width, -half_thickness }, normal); + append_vertex(entity, { -tip_height, radius, half_thickness }, normal); + append_vertex(entity, { 0.0f, radius - half_tip_width, half_thickness }, normal); + + append_vertex(entity, { 0.0f, radius - half_tip_width, -half_thickness }, Vec3f::UnitX()); + append_vertex(entity, { 0.0f, inner_radius, -half_thickness }, Vec3f::UnitX()); + append_vertex(entity, { 0.0f, radius - half_tip_width, half_thickness }, Vec3f::UnitX()); + append_vertex(entity, { 0.0f, inner_radius, half_thickness }, Vec3f::UnitX()); + + // side face triangles + for (int i = 0; i < 4; ++i) { + const int ii = i * 4; + append_indices(entity, 10 + ii, 11 + ii, 13 + ii); + append_indices(entity, 10 + ii, 13 + ii, 12 + ii); + } + + // stem + // top face vertices + for (int i = 0; i <= resolution; ++i) { + const float angle = static_cast(i) * step_angle; + append_vertex(entity, { inner_radius * ::sin(angle), inner_radius * ::cos(angle), half_thickness }, Vec3f::UnitZ()); + } + + for (int i = 0; i <= resolution; ++i) { + const float angle = static_cast(i) * step_angle; + append_vertex(entity, { outer_radius * ::sin(angle), outer_radius * ::cos(angle), half_thickness }, Vec3f::UnitZ()); + } + + // top face triangles + for (int i = 0; i < resolution; ++i) { + append_indices(entity, 26 + i, 27 + i, 27 + resolution + i); + append_indices(entity, 27 + i, 28 + resolution + i, 27 + resolution + i); + } + + // bottom face vertices + for (int i = 0; i <= resolution; ++i) { + const float angle = static_cast(i) * step_angle; + append_vertex(entity, { inner_radius * ::sin(angle), inner_radius * ::cos(angle), -half_thickness }, -Vec3f::UnitZ()); + } + + for (int i = 0; i <= resolution; ++i) { + const float angle = static_cast(i) * step_angle; + append_vertex(entity, { outer_radius * ::sin(angle), outer_radius * ::cos(angle), -half_thickness }, -Vec3f::UnitZ()); + } + + // bottom face triangles + for (int i = 0; i < resolution; ++i) { + append_indices(entity, 28 + 2 * resolution + i, 29 + 3 * resolution + i, 29 + 2 * resolution + i); + append_indices(entity, 29 + 2 * resolution + i, 29 + 3 * resolution + i, 30 + 3 * resolution + i); + } + + // side faces vertices and triangles + for (int i = 0; i <= resolution; ++i) { + const float angle = static_cast(i) * step_angle; + const float c = ::cos(angle); + const float s = ::sin(angle); + append_vertex(entity, { inner_radius * s, inner_radius * c, -half_thickness }, { -s, -c, 0.0f }); + } + + for (int i = 0; i <= resolution; ++i) { + const float angle = static_cast(i) * step_angle; + const float c = ::cos(angle); + const float s = ::sin(angle); + append_vertex(entity, { inner_radius * s, inner_radius * c, half_thickness }, { -s, -c, 0.0f }); + } + + int first_id = 26 + 4 * (resolution + 1); + for (int i = 0; i < resolution; ++i) { + const int ii = first_id + i; + append_indices(entity, ii, ii + 1, ii + resolution + 2); + append_indices(entity, ii, ii + resolution + 2, ii + resolution + 1); + } + + append_vertex(entity, { inner_radius, 0.0f, -half_thickness }, -Vec3f::UnitY()); + append_vertex(entity, { outer_radius, 0.0f, -half_thickness }, -Vec3f::UnitY()); + append_vertex(entity, { inner_radius, 0.0f, half_thickness }, -Vec3f::UnitY()); + append_vertex(entity, { outer_radius, 0.0f, half_thickness }, -Vec3f::UnitY()); + + first_id = 26 + 6 * (resolution + 1); + append_indices(entity, first_id, first_id + 1, first_id + 3); + append_indices(entity, first_id, first_id + 3, first_id + 2); + + for (int i = resolution; i >= 0; --i) { + const float angle = static_cast(i) * step_angle; + const float c = ::cos(angle); + const float s = ::sin(angle); + append_vertex(entity, { outer_radius * s, outer_radius * c, -half_thickness }, { s, c, 0.0f }); + } + + for (int i = resolution; i >= 0; --i) { + const float angle = static_cast(i) * step_angle; + const float c = ::cos(angle); + const float s = ::sin(angle); + append_vertex(entity, { outer_radius * s, outer_radius * c, +half_thickness }, { s, c, 0.0f }); + } + + first_id = 30 + 6 * (resolution + 1); + for (int i = 0; i < resolution; ++i) { + const int ii = first_id + i; + append_indices(entity, ii, ii + 1, ii + resolution + 2); + append_indices(entity, ii, ii + resolution + 2, ii + resolution + 1); + } + + data.entities.emplace_back(entity); +#else // tip // top face vertices append_vertex(data, { 0.0f, outer_radius, half_thickness }, Vec3f::UnitZ()); @@ -321,8 +716,7 @@ GLModelInitializationData circular_arrow(int resolution, float radius, float tip append_vertex(data, { 0.0f, inner_radius, half_thickness }, Vec3f::UnitX()); // side face triangles - for (int i = 0; i < 4; ++i) - { + for (int i = 0; i < 4; ++i) { int ii = i * 4; data.triangles.emplace_back(10 + ii, 11 + ii, 13 + ii); data.triangles.emplace_back(10 + ii, 13 + ii, 12 + ii); @@ -330,56 +724,48 @@ GLModelInitializationData circular_arrow(int resolution, float radius, float tip // stem // top face vertices - for (int i = 0; i <= resolution; ++i) - { + for (int i = 0; i <= resolution; ++i) { float angle = static_cast(i) * step_angle; append_vertex(data, { inner_radius * ::sin(angle), inner_radius * ::cos(angle), half_thickness }, Vec3f::UnitZ()); } - for (int i = 0; i <= resolution; ++i) - { + for (int i = 0; i <= resolution; ++i) { float angle = static_cast(i) * step_angle; append_vertex(data, { outer_radius * ::sin(angle), outer_radius * ::cos(angle), half_thickness }, Vec3f::UnitZ()); } // top face triangles - for (int i = 0; i < resolution; ++i) - { + for (int i = 0; i < resolution; ++i) { data.triangles.emplace_back(26 + i, 27 + i, 27 + resolution + i); data.triangles.emplace_back(27 + i, 28 + resolution + i, 27 + resolution + i); } // bottom face vertices - for (int i = 0; i <= resolution; ++i) - { + for (int i = 0; i <= resolution; ++i) { float angle = static_cast(i) * step_angle; append_vertex(data, { inner_radius * ::sin(angle), inner_radius * ::cos(angle), -half_thickness }, -Vec3f::UnitZ()); } - for (int i = 0; i <= resolution; ++i) - { + for (int i = 0; i <= resolution; ++i) { float angle = static_cast(i) * step_angle; append_vertex(data, { outer_radius * ::sin(angle), outer_radius * ::cos(angle), -half_thickness }, -Vec3f::UnitZ()); } // bottom face triangles - for (int i = 0; i < resolution; ++i) - { + for (int i = 0; i < resolution; ++i) { data.triangles.emplace_back(28 + 2 * resolution + i, 29 + 3 * resolution + i, 29 + 2 * resolution + i); data.triangles.emplace_back(29 + 2 * resolution + i, 29 + 3 * resolution + i, 30 + 3 * resolution + i); } // side faces vertices and triangles - for (int i = 0; i <= resolution; ++i) - { + for (int i = 0; i <= resolution; ++i) { float angle = static_cast(i) * step_angle; float c = ::cos(angle); float s = ::sin(angle); append_vertex(data, { inner_radius * s, inner_radius * c, -half_thickness }, { -s, -c, 0.0f }); } - for (int i = 0; i <= resolution; ++i) - { + for (int i = 0; i <= resolution; ++i) { float angle = static_cast(i) * step_angle; float c = ::cos(angle); float s = ::sin(angle); @@ -387,8 +773,7 @@ GLModelInitializationData circular_arrow(int resolution, float radius, float tip } int first_id = 26 + 4 * (resolution + 1); - for (int i = 0; i < resolution; ++i) - { + for (int i = 0; i < resolution; ++i) { int ii = first_id + i; data.triangles.emplace_back(ii, ii + 1, ii + resolution + 2); data.triangles.emplace_back(ii, ii + resolution + 2, ii + resolution + 1); @@ -403,16 +788,14 @@ GLModelInitializationData circular_arrow(int resolution, float radius, float tip data.triangles.emplace_back(first_id, first_id + 1, first_id + 3); data.triangles.emplace_back(first_id, first_id + 3, first_id + 2); - for (int i = resolution; i >= 0; --i) - { + for (int i = resolution; i >= 0; --i) { float angle = static_cast(i) * step_angle; float c = ::cos(angle); float s = ::sin(angle); append_vertex(data, { outer_radius * s, outer_radius * c, -half_thickness }, { s, c, 0.0f }); } - for (int i = resolution; i >= 0; --i) - { + for (int i = resolution; i >= 0; --i) { float angle = static_cast(i) * step_angle; float c = ::cos(angle); float s = ::sin(angle); @@ -420,16 +803,33 @@ GLModelInitializationData circular_arrow(int resolution, float radius, float tip } first_id = 30 + 6 * (resolution + 1); - for (int i = 0; i < resolution; ++i) - { + for (int i = 0; i < resolution; ++i) { int ii = first_id + i; data.triangles.emplace_back(ii, ii + 1, ii + resolution + 2); data.triangles.emplace_back(ii, ii + resolution + 2, ii + resolution + 1); } +#endif // ENABLE_SEQUENTIAL_LIMITS return data; } +#if ENABLE_SEQUENTIAL_LIMITS +GLModel::InitializationData straight_arrow(float tip_width, float tip_height, float stem_width, float stem_height, float thickness) +{ + auto append_vertex = [](GLModel::InitializationData::Entity& entity, const Vec3f& position, const Vec3f& normal) { + entity.positions.emplace_back(position); + entity.normals.emplace_back(normal); + }; + auto append_indices = [](GLModel::InitializationData::Entity& entity, unsigned int v1, unsigned int v2, unsigned int v3) { + entity.indices.emplace_back(v1); + entity.indices.emplace_back(v2); + entity.indices.emplace_back(v3); + }; + + GLModel::InitializationData data; + GLModel::InitializationData::Entity entity; + entity.type = GLModel::PrimitiveType::Triangles; +#else GLModelInitializationData straight_arrow(float tip_width, float tip_height, float stem_width, float stem_height, float thickness) { auto append_vertex = [](GLModelInitializationData& data, const Vec3f& position, const Vec3f& normal) { @@ -438,6 +838,7 @@ GLModelInitializationData straight_arrow(float tip_width, float tip_height, floa }; GLModelInitializationData data; +#endif // ENABLE_SEQUENTIAL_LIMITS const float half_thickness = 0.5f * thickness; const float half_stem_width = 0.5f * stem_width; @@ -445,6 +846,87 @@ GLModelInitializationData straight_arrow(float tip_width, float tip_height, floa const float total_height = tip_height + stem_height; // top face vertices +#if ENABLE_SEQUENTIAL_LIMITS + append_vertex(entity, { half_stem_width, 0.0, half_thickness }, Vec3f::UnitZ()); + append_vertex(entity, { half_stem_width, stem_height, half_thickness }, Vec3f::UnitZ()); + append_vertex(entity, { half_tip_width, stem_height, half_thickness }, Vec3f::UnitZ()); + append_vertex(entity, { 0.0, total_height, half_thickness }, Vec3f::UnitZ()); + append_vertex(entity, { -half_tip_width, stem_height, half_thickness }, Vec3f::UnitZ()); + append_vertex(entity, { -half_stem_width, stem_height, half_thickness }, Vec3f::UnitZ()); + append_vertex(entity, { -half_stem_width, 0.0, half_thickness }, Vec3f::UnitZ()); + + // top face triangles + append_indices(entity, 0, 1, 6); + append_indices(entity, 6, 1, 5); + append_indices(entity, 4, 5, 3); + append_indices(entity, 5, 1, 3); + append_indices(entity, 1, 2, 3); + + // bottom face vertices + append_vertex(entity, { half_stem_width, 0.0, -half_thickness }, -Vec3f::UnitZ()); + append_vertex(entity, { half_stem_width, stem_height, -half_thickness }, -Vec3f::UnitZ()); + append_vertex(entity, { half_tip_width, stem_height, -half_thickness }, -Vec3f::UnitZ()); + append_vertex(entity, { 0.0, total_height, -half_thickness }, -Vec3f::UnitZ()); + append_vertex(entity, { -half_tip_width, stem_height, -half_thickness }, -Vec3f::UnitZ()); + append_vertex(entity, { -half_stem_width, stem_height, -half_thickness }, -Vec3f::UnitZ()); + append_vertex(entity, { -half_stem_width, 0.0, -half_thickness }, -Vec3f::UnitZ()); + + // bottom face triangles + append_indices(entity, 7, 13, 8); + append_indices(entity, 13, 12, 8); + append_indices(entity, 12, 11, 10); + append_indices(entity, 8, 12, 10); + append_indices(entity, 9, 8, 10); + + // side faces vertices + append_vertex(entity, { half_stem_width, 0.0, -half_thickness }, Vec3f::UnitX()); + append_vertex(entity, { half_stem_width, stem_height, -half_thickness }, Vec3f::UnitX()); + append_vertex(entity, { half_stem_width, 0.0, half_thickness }, Vec3f::UnitX()); + append_vertex(entity, { half_stem_width, stem_height, half_thickness }, Vec3f::UnitX()); + + append_vertex(entity, { half_stem_width, stem_height, -half_thickness }, -Vec3f::UnitY()); + append_vertex(entity, { half_tip_width, stem_height, -half_thickness }, -Vec3f::UnitY()); + append_vertex(entity, { half_stem_width, stem_height, half_thickness }, -Vec3f::UnitY()); + append_vertex(entity, { half_tip_width, stem_height, half_thickness }, -Vec3f::UnitY()); + + Vec3f normal(tip_height, half_tip_width, 0.0f); + normal.normalize(); + append_vertex(entity, { half_tip_width, stem_height, -half_thickness }, normal); + append_vertex(entity, { 0.0, total_height, -half_thickness }, normal); + append_vertex(entity, { half_tip_width, stem_height, half_thickness }, normal); + append_vertex(entity, { 0.0, total_height, half_thickness }, normal); + + normal = Vec3f(-tip_height, half_tip_width, 0.0f); + normal.normalize(); + append_vertex(entity, { 0.0, total_height, -half_thickness }, normal); + append_vertex(entity, { -half_tip_width, stem_height, -half_thickness }, normal); + append_vertex(entity, { 0.0, total_height, half_thickness }, normal); + append_vertex(entity, { -half_tip_width, stem_height, half_thickness }, normal); + + append_vertex(entity, { -half_tip_width, stem_height, -half_thickness }, -Vec3f::UnitY()); + append_vertex(entity, { -half_stem_width, stem_height, -half_thickness }, -Vec3f::UnitY()); + append_vertex(entity, { -half_tip_width, stem_height, half_thickness }, -Vec3f::UnitY()); + append_vertex(entity, { -half_stem_width, stem_height, half_thickness }, -Vec3f::UnitY()); + + append_vertex(entity, { -half_stem_width, stem_height, -half_thickness }, -Vec3f::UnitX()); + append_vertex(entity, { -half_stem_width, 0.0, -half_thickness }, -Vec3f::UnitX()); + append_vertex(entity, { -half_stem_width, stem_height, half_thickness }, -Vec3f::UnitX()); + append_vertex(entity, { -half_stem_width, 0.0, half_thickness }, -Vec3f::UnitX()); + + append_vertex(entity, { -half_stem_width, 0.0, -half_thickness }, -Vec3f::UnitY()); + append_vertex(entity, { half_stem_width, 0.0, -half_thickness }, -Vec3f::UnitY()); + append_vertex(entity, { -half_stem_width, 0.0, half_thickness }, -Vec3f::UnitY()); + append_vertex(entity, { half_stem_width, 0.0, half_thickness }, -Vec3f::UnitY()); + + // side face triangles + for (int i = 0; i < 7; ++i) { + const int ii = i * 4; + append_indices(entity, 14 + ii, 15 + ii, 17 + ii); + append_indices(entity, 14 + ii, 17 + ii, 16 + ii); + } + + data.entities.emplace_back(entity); +#else append_vertex(data, { half_stem_width, 0.0, half_thickness }, Vec3f::UnitZ()); append_vertex(data, { half_stem_width, stem_height, half_thickness }, Vec3f::UnitZ()); append_vertex(data, { half_tip_width, stem_height, half_thickness }, Vec3f::UnitZ()); @@ -517,12 +999,12 @@ GLModelInitializationData straight_arrow(float tip_width, float tip_height, floa append_vertex(data, { half_stem_width, 0.0, half_thickness }, -Vec3f::UnitY()); // side face triangles - for (int i = 0; i < 7; ++i) - { + for (int i = 0; i < 7; ++i) { int ii = i * 4; data.triangles.emplace_back(14 + ii, 15 + ii, 17 + ii); data.triangles.emplace_back(14 + ii, 17 + ii, 16 + ii); } +#endif // ENABLE_SEQUENTIAL_LIMITS return data; } diff --git a/src/slic3r/GUI/GLModel.hpp b/src/slic3r/GUI/GLModel.hpp index 0b4a69bdb..8e1e3dfd5 100644 --- a/src/slic3r/GUI/GLModel.hpp +++ b/src/slic3r/GUI/GLModel.hpp @@ -12,40 +12,115 @@ class TriangleMesh; namespace GUI { +#if !ENABLE_SEQUENTIAL_LIMITS struct GLModelInitializationData { std::vector positions; std::vector normals; std::vector triangles; }; +#endif // !ENABLE_SEQUENTIAL_LIMITS class GLModel { +#if ENABLE_SEQUENTIAL_LIMITS + public: + enum class PrimitiveType : unsigned char + { + Triangles, + Lines, + LineStrip, + LineLoop + }; + + struct RenderData + { + PrimitiveType type; + unsigned int vbo_id{ 0 }; + unsigned int ibo_id{ 0 }; + size_t indices_count{ 0 }; + std::array color{ 1.0f, 1.0f, 1.0f, 1.0f }; + }; + + struct InitializationData + { + struct Entity + { + PrimitiveType type; + std::vector positions; + std::vector normals; + std::vector indices; + std::array color{ 1.0f, 1.0f, 1.0f, 1.0f }; + }; + + std::vector entities; + }; + + private: + std::vector m_render_data; +#else unsigned int m_vbo_id{ 0 }; unsigned int m_ibo_id{ 0 }; size_t m_indices_count{ 0 }; +#endif // ENABLE_SEQUENTIAL_LIMITS BoundingBoxf3 m_bounding_box; std::string m_filename; public: + GLModel() = default; virtual ~GLModel() { reset(); } +#if ENABLE_SEQUENTIAL_LIMITS + void init_from(const InitializationData& data); +#else void init_from(const GLModelInitializationData& data); +#endif // ENABLE_SEQUENTIAL_LIMITS void init_from(const TriangleMesh& mesh); bool init_from_file(const std::string& filename); + +#if ENABLE_SEQUENTIAL_LIMITS + // if entity_id == -1 set the color of all entities + void set_color(int entity_id, const std::array& color); +#endif // ENABLE_SEQUENTIAL_LIMITS + void reset(); void render() const; - const BoundingBoxf3& get_bounding_box() const { return m_bounding_box; } +#if ENABLE_SEQUENTIAL_LIMITS + bool is_initialized() const { return !m_render_data.empty(); } +#endif // ENABLE_SEQUENTIAL_LIMITS + const BoundingBoxf3& get_bounding_box() const { return m_bounding_box; } const std::string& get_filename() const { return m_filename; } private: +#if ENABLE_SEQUENTIAL_LIMITS + void send_to_gpu(RenderData& data, const std::vector& vertices, const std::vector& indices); +#else void send_to_gpu(const std::vector& vertices, const std::vector& indices); +#endif // ENABLE_SEQUENTIAL_LIMITS }; +#if ENABLE_SEQUENTIAL_LIMITS + // create an arrow with cylindrical stem and conical tip, with the given dimensions and resolution + // the origin of the arrow is in the center of the stem cap + // the arrow has its axis of symmetry along the Z axis and is pointing upward + // used to render bed axes and sequential marker + GLModel::InitializationData stilized_arrow(int resolution, float tip_radius, float tip_height, float stem_radius, float stem_height); + // create an arrow whose stem is a quarter of circle, with the given dimensions and resolution + // the origin of the arrow is in the center of the circle + // the arrow is contained in the 1st quadrant of the XY plane and is pointing counterclockwise + // used to render sidebar hints for rotations + GLModel::InitializationData circular_arrow(int resolution, float radius, float tip_height, float tip_width, float stem_width, float thickness); + + // create an arrow with the given dimensions + // the origin of the arrow is in the center of the stem cap + // the arrow is contained in XY plane and has its main axis along the Y axis + // 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); +#else // create an arrow with cylindrical stem and conical tip, with the given dimensions and resolution // the origin of the arrow is in the center of the stem cap // the arrow has its axis of symmetry along the Z axis and is pointing upward @@ -60,6 +135,7 @@ namespace GUI { // the origin of the arrow is in the center of the stem cap // the arrow is contained in XY plane and has its main axis along the Y axis GLModelInitializationData straight_arrow(float tip_width, float tip_height, float stem_width, float stem_height, float thickness); +#endif // ENABLE_SEQUENTIAL_LIMITS } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp index 44f0a6972..98d4aa858 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp @@ -26,8 +26,6 @@ static const float DEFAULT_HIGHLIGHT_COLOR[4] = { 1.0f, 0.38f, 0.0f, 1.0f }; static const float AXES_COLOR[][4] = { { 0.75f, 0.0f, 0.0f, 1.0f }, { 0.0f, 0.75f, 0.0f, 1.0f }, { 0.0f, 0.0f, 0.75f, 1.0f } }; static const float CONSTRAINED_COLOR[4] = { 0.5f, 0.5f, 0.5f, 1.0f }; - - class ImGuiWrapper; class GLCanvas3D; enum class CommonGizmosDataID; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 841a07513..4826da401 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2828,12 +2828,12 @@ unsigned int Plater::priv::update_background_process(bool force_validation, bool // If the update_background_process() was not called by the timer, kill the timer, // so the update_restart_background_process() will not be called again in vain. - this->background_process_timer.Stop(); + background_process_timer.Stop(); // Update the "out of print bed" state of ModelInstances. - this->update_print_volume_state(); + update_print_volume_state(); // Apply new config to the possibly running background task. - bool was_running = this->background_process.running(); - Print::ApplyStatus invalidated = this->background_process.apply(this->q->model(), wxGetApp().preset_bundle->full_config()); + bool was_running = background_process.running(); + Print::ApplyStatus invalidated = background_process.apply(q->model(), wxGetApp().preset_bundle->full_config()); // Just redraw the 3D canvas without reloading the scene to consume the update of the layer height profile. if (view3D->is_layers_editing_enabled()) @@ -2842,40 +2842,56 @@ unsigned int Plater::priv::update_background_process(bool force_validation, bool if (invalidated == Print::APPLY_STATUS_INVALIDATED) { // Some previously calculated data on the Print was invalidated. // Hide the slicing results, as the current slicing status is no more valid. - this->sidebar->show_sliced_info_sizer(false); + sidebar->show_sliced_info_sizer(false); // Reset preview canvases. If the print has been invalidated, the preview canvases will be cleared. // Otherwise they will be just refreshed. - if (this->preview != nullptr) { + if (preview != nullptr) { // If the preview is not visible, the following line just invalidates the preview, // but the G-code paths or SLA preview are calculated first once the preview is made visible. reset_gcode_toolpaths(); - this->preview->reload_print(); + preview->reload_print(); } // In FDM mode, we need to reload the 3D scene because of the wipe tower preview box. // In SLA mode, we need to reload the 3D scene every time to show the support structures. - if (this->printer_technology == ptSLA || (this->printer_technology == ptFFF && this->config->opt_bool("wipe_tower"))) + if (printer_technology == ptSLA || (printer_technology == ptFFF && config->opt_bool("wipe_tower"))) return_state |= UPDATE_BACKGROUND_PROCESS_REFRESH_SCENE; } - if ((invalidated != Print::APPLY_STATUS_UNCHANGED || force_validation) && ! this->background_process.empty()) { + if ((invalidated != Print::APPLY_STATUS_UNCHANGED || force_validation) && ! background_process.empty()) { // The delayed error message is no more valid. - this->delayed_error_message.clear(); + delayed_error_message.clear(); // The state of the Print changed, and it is non-zero. Let's validate it and give the user feedback on errors. std::string warning; - std::string err = this->background_process.validate(&warning); + std::string err = background_process.validate(&warning); if (err.empty()) { notification_manager->set_all_slicing_errors_gray(true); - if (invalidated != Print::APPLY_STATUS_UNCHANGED && this->background_processing_enabled()) + if (invalidated != Print::APPLY_STATUS_UNCHANGED && background_processing_enabled()) return_state |= UPDATE_BACKGROUND_PROCESS_RESTART; // Pass a warning from validation and either show a notification, // or hide the old one. process_validation_warning(warning); +#if ENABLE_SEQUENTIAL_LIMITS + if (printer_technology == ptFFF) { + view3D->get_canvas3d()->set_sequential_print_clearance(Polygons()); + view3D->get_canvas3d()->set_as_dirty(); + view3D->get_canvas3d()->request_extra_frame(); + } +#endif // ENABLE_SEQUENTIAL_LIMITS } else { // The print is not valid. // Show error as notification. notification_manager->push_slicing_error_notification(err); return_state |= UPDATE_BACKGROUND_PROCESS_INVALID; +#if ENABLE_SEQUENTIAL_LIMITS + if (printer_technology == ptFFF) { + const Print* print = background_process.fff_print(); + Polygons polygons; + if (print->config().complete_objects) + Print::sequential_print_horizontal_clearance_valid(*print, &polygons); + view3D->get_canvas3d()->set_sequential_print_clearance(polygons); + } +#endif // ENABLE_SEQUENTIAL_LIMITS } } else if (! this->delayed_error_message.empty()) { @@ -3011,8 +3027,7 @@ void Plater::priv::update_fff_scene() if (this->preview != nullptr) this->preview->reload_print(); // In case this was MM print, wipe tower bounding box on 3D tab might need redrawing with exact depth: - view3D->reload_scene(true); - + view3D->reload_scene(true); } void Plater::priv::update_sla_scene() diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index fd6873749..432095e51 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -18,7 +18,11 @@ #include #include +#if ENABLE_SEQUENTIAL_LIMITS +static const std::array UNIFORM_SCALE_COLOR = { 0.923f, 0.504f, 0.264f, 1.0f }; +#else static const float UNIFORM_SCALE_COLOR[4] = { 0.923f, 0.504f, 0.264f, 1.0f }; +#endif // ENABLE_SEQUENTIAL_LIMITS namespace Slic3r { namespace GUI { @@ -1869,8 +1873,31 @@ void Selection::render_bounding_box(const BoundingBoxf3& box, float* color) cons glsafe(::glEnd()); } +#if ENABLE_SEQUENTIAL_LIMITS +static std::array get_color(Axis axis) +{ + return { AXES_COLOR[axis][0], AXES_COLOR[axis][1], AXES_COLOR[axis][2], AXES_COLOR[axis][3] }; +}; +#endif // ENABLE_SEQUENTIAL_LIMITS + void Selection::render_sidebar_position_hints(const std::string& sidebar_field) const { +#if ENABLE_SEQUENTIAL_LIMITS + if (boost::ends_with(sidebar_field, "x")) { + glsafe(::glRotated(-90.0, 0.0, 0.0, 1.0)); + const_cast(&m_arrow)->set_color(-1, get_color(X)); + m_arrow.render(); + } + else if (boost::ends_with(sidebar_field, "y")) { + const_cast(&m_arrow)->set_color(-1, get_color(Y)); + m_arrow.render(); + } + else if (boost::ends_with(sidebar_field, "z")) { + glsafe(::glRotated(90.0, 1.0, 0.0, 0.0)); + const_cast(&m_arrow)->set_color(-1, get_color(Z)); + m_arrow.render(); + } +#else auto set_color = [](Axis axis) { GLShaderProgram* shader = wxGetApp().get_current_shader(); if (shader != nullptr) @@ -1889,10 +1916,33 @@ void Selection::render_sidebar_position_hints(const std::string& sidebar_field) glsafe(::glRotated(90.0, 1.0, 0.0, 0.0)); m_arrow.render(); } +#endif // ENABLE_SEQUENTIAL_LIMITS } void Selection::render_sidebar_rotation_hints(const std::string& sidebar_field) const { +#if ENABLE_SEQUENTIAL_LIMITS + auto render_sidebar_rotation_hint = [this]() { + m_curved_arrow.render(); + glsafe(::glRotated(180.0, 0.0, 0.0, 1.0)); + m_curved_arrow.render(); + }; + + if (boost::ends_with(sidebar_field, "x")) { + glsafe(::glRotated(90.0, 0.0, 1.0, 0.0)); + const_cast(&m_curved_arrow)->set_color(-1, get_color(X)); + render_sidebar_rotation_hint(); + } + else if (boost::ends_with(sidebar_field, "y")) { + glsafe(::glRotated(-90.0, 1.0, 0.0, 0.0)); + const_cast(&m_curved_arrow)->set_color(-1, get_color(Y)); + render_sidebar_rotation_hint(); + } + else if (boost::ends_with(sidebar_field, "z")) { + const_cast(&m_curved_arrow)->set_color(-1, get_color(Z)); + render_sidebar_rotation_hint(); + } +#else auto set_color = [](Axis axis) { GLShaderProgram* shader = wxGetApp().get_current_shader(); if (shader != nullptr) @@ -1917,6 +1967,7 @@ void Selection::render_sidebar_rotation_hints(const std::string& sidebar_field) set_color(Z); render_sidebar_rotation_hint(); } +#endif // ENABLE_SEQUENTIAL_LIMITS } void Selection::render_sidebar_scale_hints(const std::string& sidebar_field) const @@ -1924,9 +1975,13 @@ void Selection::render_sidebar_scale_hints(const std::string& sidebar_field) con bool uniform_scale = requires_uniform_scale() || wxGetApp().obj_manipul()->get_uniform_scaling(); auto render_sidebar_scale_hint = [this, uniform_scale](Axis axis) { +#if ENABLE_SEQUENTIAL_LIMITS + const_cast(&m_arrow)->set_color(-1, uniform_scale ? UNIFORM_SCALE_COLOR : get_color(axis)); +#else GLShaderProgram* shader = wxGetApp().get_current_shader(); if (shader != nullptr) shader->set_uniform("uniform_color", uniform_scale ? UNIFORM_SCALE_COLOR : AXES_COLOR[axis], 4); +#endif // ENABLE_SEQUENTIAL_LIMITS glsafe(::glTranslated(0.0, 5.0, 0.0)); m_arrow.render(); From 0d37f66f61903956bb3f3416a8aac636c321bf34 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 12 May 2021 13:09:33 +0200 Subject: [PATCH 02/31] Tech ENABLE_SEQUENTIAL_LIMITS -> Improved rendering of clearance regions --- src/slic3r/GUI/3DBed.cpp | 10 ++++++++-- src/slic3r/GUI/GLCanvas3D.cpp | 17 +++++++++++------ 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/slic3r/GUI/3DBed.cpp b/src/slic3r/GUI/3DBed.cpp index 6ac61ad94..f19ec8d6f 100644 --- a/src/slic3r/GUI/3DBed.cpp +++ b/src/slic3r/GUI/3DBed.cpp @@ -424,7 +424,10 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) const } glsafe(::glEnable(GL_DEPTH_TEST)); - glsafe(::glDepthMask(GL_FALSE)); +#if ENABLE_SEQUENTIAL_LIMITS + if (bottom) +#endif // ENABLE_SEQUENTIAL_LIMITS + glsafe(::glDepthMask(GL_FALSE)); glsafe(::glEnable(GL_BLEND)); glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); @@ -469,7 +472,10 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) const glsafe(::glFrontFace(GL_CCW)); glsafe(::glDisable(GL_BLEND)); - glsafe(::glDepthMask(GL_TRUE)); +#if ENABLE_SEQUENTIAL_LIMITS + if (bottom) +#endif // ENABLE_SEQUENTIAL_LIMITS + glsafe(::glDepthMask(GL_TRUE)); shader->stop_using(); } diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 55ddfd9f3..5a0641461 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1085,13 +1085,14 @@ void GLCanvas3D::SequentialPrintClearance::set(const Polygons& polygons) GLModel::InitializationData data; GLModel::InitializationData::Entity entity; entity.type = GLModel::PrimitiveType::Triangles; - entity.color = { 0.3333f, 0.3333f, 0.3333f, 1.0f }; + entity.color = { 0.3333f, 0.0f, 0.0f, 0.5f }; entity.positions.reserve(vertices_count); entity.normals.reserve(vertices_count); entity.indices.reserve(vertices_count); - for (const Polygon& poly : polygons) { - std::vector triangulation = triangulate_expolygon_3d(ExPolygon(poly), false); + ExPolygons polygons_union = union_ex(polygons); + for (const ExPolygon& poly : polygons_union) { + std::vector triangulation = triangulate_expolygon_3d(poly, false); for (const Vec3d& v : triangulation) { entity.positions.emplace_back(v.cast()); entity.normals.emplace_back(Vec3f::UnitZ()); @@ -1109,7 +1110,7 @@ void GLCanvas3D::SequentialPrintClearance::set(const Polygons& polygons) for (const Polygon& poly : polygons) { GLModel::InitializationData::Entity ent; ent.type = GLModel::PrimitiveType::LineLoop; - ent.color = { 1.0f, 1.0f, 0.0f, 1.0f }; + ent.color = { 1.0f, 0.0f, 0.0f, 1.0f }; ent.positions.reserve(poly.points.size()); ent.indices.reserve(poly.points.size()); unsigned int id_count = 0; @@ -1133,11 +1134,16 @@ void GLCanvas3D::SequentialPrintClearance::render() const shader->start_using(); + glsafe(::glEnable(GL_DEPTH_TEST)); glsafe(::glDisable(GL_CULL_FACE)); + glsafe(::glEnable(GL_BLEND)); + glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); m_model.render(); + glsafe(::glDisable(GL_BLEND)); glsafe(::glEnable(GL_CULL_FACE)); + glsafe(::glDisable(GL_DEPTH_TEST)); shader->stop_using(); } @@ -1743,11 +1749,10 @@ void GLCanvas3D::render() _render_gcode(); _render_sla_slices(); _render_selection(); + _render_bed(!camera.is_looking_downward(), true); #if ENABLE_SEQUENTIAL_LIMITS _render_sequential_clearance(); #endif // ENABLE_SEQUENTIAL_LIMITS - _render_bed(!camera.is_looking_downward(), true); - #if ENABLE_RENDER_SELECTION_CENTER _render_selection_center(); #endif // ENABLE_RENDER_SELECTION_CENTER From bc9fa18044f07c5a9a6d4a280b6982c692f7e654 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 12 May 2021 14:35:57 +0200 Subject: [PATCH 03/31] Tech ENABLE_SEQUENTIAL_LIMITS -> Fixed z-fighting between contours and fill --- src/slic3r/GUI/GLCanvas3D.cpp | 20 ++++++++++++-------- src/slic3r/GUI/GLCanvas3D.hpp | 3 ++- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 5a0641461..7a78781dd 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1072,7 +1072,8 @@ void GLCanvas3D::Tooltip::render(const Vec2d& mouse_position, GLCanvas3D& canvas #if ENABLE_SEQUENTIAL_LIMITS void GLCanvas3D::SequentialPrintClearance::set(const Polygons& polygons) { - m_model.reset(); + m_perimeter.reset(); + m_fill.reset(); if (polygons.empty()) return; @@ -1082,7 +1083,7 @@ void GLCanvas3D::SequentialPrintClearance::set(const Polygons& polygons) } size_t vertices_count = 3 * triangles_count; - GLModel::InitializationData data; + GLModel::InitializationData fill_data; GLModel::InitializationData::Entity entity; entity.type = GLModel::PrimitiveType::Triangles; entity.color = { 0.3333f, 0.0f, 0.0f, 0.5f }; @@ -1105,25 +1106,27 @@ void GLCanvas3D::SequentialPrintClearance::set(const Polygons& polygons) } } - data.entities.emplace_back(entity); + fill_data.entities.emplace_back(entity); + m_fill.init_from(fill_data); + GLModel::InitializationData perimeter_data; for (const Polygon& poly : polygons) { GLModel::InitializationData::Entity ent; ent.type = GLModel::PrimitiveType::LineLoop; - ent.color = { 1.0f, 0.0f, 0.0f, 1.0f }; + ent.color = { 1.0f, 0.0f, 0.0f, 0.5f }; ent.positions.reserve(poly.points.size()); ent.indices.reserve(poly.points.size()); unsigned int id_count = 0; for (const Point& p : poly.points) { - ent.positions.emplace_back(unscale(p.x()), unscale(p.y()), 0.0f); + ent.positions.emplace_back(unscale(p.x()), unscale(p.y()), 0.025f); ent.normals.emplace_back(Vec3f::UnitZ()); ent.indices.emplace_back(id_count++); } - data.entities.emplace_back(ent); + perimeter_data.entities.emplace_back(ent); } - m_model.init_from(data); + m_perimeter.init_from(perimeter_data); } void GLCanvas3D::SequentialPrintClearance::render() const @@ -1139,7 +1142,8 @@ void GLCanvas3D::SequentialPrintClearance::render() const glsafe(::glEnable(GL_BLEND)); glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); - m_model.render(); + m_perimeter.render(); + m_fill.render(); glsafe(::glDisable(GL_BLEND)); glsafe(::glEnable(GL_CULL_FACE)); diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 3ebb3ee6b..92f4e0483 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -544,7 +544,8 @@ private: #if ENABLE_SEQUENTIAL_LIMITS class SequentialPrintClearance { - GLModel m_model; + GLModel m_fill; + GLModel m_perimeter; public: void set(const Polygons& polygons); From 62772060f982bf36a5f2dd047c3841865ee9681c Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 12 May 2021 14:56:14 +0200 Subject: [PATCH 04/31] Tech ENABLE_SEQUENTIAL_LIMITS -> Do not show clearance regions while dragging an object --- src/slic3r/GUI/GLCanvas3D.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 7a78781dd..8a1c2ba9d 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1755,7 +1755,10 @@ void GLCanvas3D::render() _render_selection(); _render_bed(!camera.is_looking_downward(), true); #if ENABLE_SEQUENTIAL_LIMITS - _render_sequential_clearance(); + if (!m_mouse.dragging || m_mouse.drag.move_volume_idx == -1) + _render_sequential_clearance(); + else + set_sequential_print_clearance(Polygons()); #endif // ENABLE_SEQUENTIAL_LIMITS #if ENABLE_RENDER_SELECTION_CENTER _render_selection_center(); From e330b669815c61e745049407c94a40b0f845a417 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 13 May 2021 13:57:09 +0200 Subject: [PATCH 05/31] Small refactoring --- resources/shaders/gouraud_light.fs | 2 +- src/libslic3r/Print.cpp | 15 +++++++-------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/resources/shaders/gouraud_light.fs b/resources/shaders/gouraud_light.fs index 1a58abc85..d1bb2f55b 100644 --- a/resources/shaders/gouraud_light.fs +++ b/resources/shaders/gouraud_light.fs @@ -7,5 +7,5 @@ varying vec2 intensity; void main() { - gl_FragColor = vec4(vec3(intensity.y, intensity.y, intensity.y) + uniform_color.rgb * intensity.x, uniform_color.a); + gl_FragColor = vec4(vec3(intensity.y) + uniform_color.rgb * intensity.x, uniform_color.a); } diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 6cb78d2fa..5108c3b41 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -1202,8 +1202,9 @@ static inline bool sequential_print_horizontal_clearance_valid(const Print &prin { Polygons convex_hulls_other; #if ENABLE_SEQUENTIAL_LIMITS + if (polygons != nullptr) + polygons->clear(); std::vector intersecting_idxs; - bool intersection_detected = false; #endif // ENABLE_SEQUENTIAL_LIMITS std::map map_model_object_to_convex_hull; @@ -1240,14 +1241,14 @@ static inline bool sequential_print_horizontal_clearance_valid(const Print &prin // Convert the shift from the PrintObject's coordinates into ModelObject's coordinates by removing the centering offset. convex_hull.translate(instance.shift - print_object->center_offset()); #if ENABLE_SEQUENTIAL_LIMITS + // if output needed, collect indices (inside convex_hulls_other) of intersecting hulls for (size_t i = 0; i < convex_hulls_other.size(); ++i) { if (!intersection((Polygons)convex_hulls_other[i], (Polygons)convex_hull).empty()) { if (polygons == nullptr) return false; else { - intersection_detected = true; - intersecting_idxs.push_back(i); - intersecting_idxs.push_back(convex_hulls_other.size()); + intersecting_idxs.emplace_back(i); + intersecting_idxs.emplace_back(convex_hulls_other.size()); } } } @@ -1260,15 +1261,13 @@ static inline bool sequential_print_horizontal_clearance_valid(const Print &prin } #if ENABLE_SEQUENTIAL_LIMITS - if (intersection_detected) { - assert(polygons != nullptr); - + if (!intersecting_idxs.empty()) { + // use collected indices (inside convex_hulls_other) to update output std::sort(intersecting_idxs.begin(), intersecting_idxs.end()); intersecting_idxs.erase(std::unique(intersecting_idxs.begin(), intersecting_idxs.end()), intersecting_idxs.end()); for (size_t i : intersecting_idxs) { polygons->emplace_back(std::move(convex_hulls_other[i])); } - return false; } #endif // ENABLE_SEQUENTIAL_LIMITS From 2cf5f83bb66868c1420e7145b6e7d28f1414b738 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 14 May 2021 10:52:18 +0200 Subject: [PATCH 06/31] Tech ENABLE_SEQUENTIAL_LIMITS -> Do not show sequential print clearance regions while any gizmo is active --- src/slic3r/GUI/GLCanvas3D.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index eabc8410f..a12a919cd 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1459,10 +1459,8 @@ void GLCanvas3D::render() _render_selection(); _render_bed(!camera.is_looking_downward(), true); #if ENABLE_SEQUENTIAL_LIMITS - if (!m_mouse.dragging || m_mouse.drag.move_volume_idx == -1) + if ((!m_mouse.dragging || m_mouse.drag.move_volume_idx == -1) && m_gizmos.get_current_type() == GLGizmosManager::EType::Undefined) _render_sequential_clearance(); - else - set_sequential_print_clearance(Polygons()); #endif // ENABLE_SEQUENTIAL_LIMITS #if ENABLE_RENDER_SELECTION_CENTER _render_selection_center(); @@ -3364,15 +3362,15 @@ void GLCanvas3D::do_move(const std::string& snapshot_type) for (const std::pair& i : done) { ModelObject* m = m_model->objects[i.first]; #if ENABLE_ALLOW_NEGATIVE_Z - double shift_z = m->get_instance_min_z(i.second); + const double shift_z = m->get_instance_min_z(i.second); #if DISABLE_ALLOW_NEGATIVE_Z_FOR_SLA if (current_printer_technology() == ptSLA || shift_z > 0.0) { #else if (shift_z > 0.0) { #endif // DISABLE_ALLOW_NEGATIVE_Z_FOR_SLA - Vec3d shift(0.0, 0.0, -shift_z); + const Vec3d shift(0.0, 0.0, -shift_z); #else - Vec3d shift(0.0, 0.0, -m->get_instance_min_z(i.second)); + const Vec3d shift(0.0, 0.0, -m->get_instance_min_z(i.second)); #endif // ENABLE_ALLOW_NEGATIVE_Z m_selection.translate(i.first, i.second, shift); m->translate_instance(i.second, shift); @@ -3394,6 +3392,10 @@ void GLCanvas3D::do_move(const std::string& snapshot_type) if (wipe_tower_origin != Vec3d::Zero()) post_event(Vec3dEvent(EVT_GLCANVAS_WIPETOWER_MOVED, std::move(wipe_tower_origin))); +#if ENABLE_SEQUENTIAL_LIMITS + set_sequential_print_clearance(Polygons()); +#endif // ENABLE_SEQUENTIAL_LIMITS + m_dirty = true; } From b014e87ef7cbd7a6a51859a9c8e2919ce5cb2789 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 14 May 2021 11:13:46 +0200 Subject: [PATCH 07/31] Tech ENABLE_SEQUENTIAL_LIMITS -> Fixed z-fighting between sequential print clearance regions and objects --- src/slic3r/GUI/GLCanvas3D.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index a12a919cd..c840406f5 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -813,7 +813,7 @@ void GLCanvas3D::SequentialPrintClearance::set(const Polygons& polygons) for (const ExPolygon& poly : polygons_union) { std::vector triangulation = triangulate_expolygon_3d(poly, false); for (const Vec3d& v : triangulation) { - entity.positions.emplace_back(v.cast()); + entity.positions.emplace_back(v.cast() + Vec3f(0.0f, 0.0f, 0.0125)); // add a small positive z to avoid z-fighting entity.normals.emplace_back(Vec3f::UnitZ()); size_t positions_count = entity.positions.size(); if (positions_count % 3 == 0) { @@ -836,7 +836,7 @@ void GLCanvas3D::SequentialPrintClearance::set(const Polygons& polygons) ent.indices.reserve(poly.points.size()); unsigned int id_count = 0; for (const Point& p : poly.points) { - ent.positions.emplace_back(unscale(p.x()), unscale(p.y()), 0.025f); + ent.positions.emplace_back(unscale(p.x()), unscale(p.y()), 0.025f); // add a small positive z to avoid z-fighting ent.normals.emplace_back(Vec3f::UnitZ()); ent.indices.emplace_back(id_count++); } From b9011ca5f1f881ea7b480d26e1bdd654f95ab6cb Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 14 May 2021 11:20:02 +0200 Subject: [PATCH 08/31] Tech ENABLE_SEQUENTIAL_LIMITS -> Do not show sequential print clearance regions while layers editing is enabled --- src/slic3r/GUI/GLCanvas3D.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index c840406f5..dffcb15e5 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -813,7 +813,7 @@ void GLCanvas3D::SequentialPrintClearance::set(const Polygons& polygons) for (const ExPolygon& poly : polygons_union) { std::vector triangulation = triangulate_expolygon_3d(poly, false); for (const Vec3d& v : triangulation) { - entity.positions.emplace_back(v.cast() + Vec3f(0.0f, 0.0f, 0.0125)); // add a small positive z to avoid z-fighting + entity.positions.emplace_back(v.cast() + Vec3f(0.0f, 0.0f, 0.0125f)); // add a small positive z to avoid z-fighting entity.normals.emplace_back(Vec3f::UnitZ()); size_t positions_count = entity.positions.size(); if (positions_count % 3 == 0) { @@ -1459,7 +1459,9 @@ void GLCanvas3D::render() _render_selection(); _render_bed(!camera.is_looking_downward(), true); #if ENABLE_SEQUENTIAL_LIMITS - if ((!m_mouse.dragging || m_mouse.drag.move_volume_idx == -1) && m_gizmos.get_current_type() == GLGizmosManager::EType::Undefined) + if ((!m_mouse.dragging || m_mouse.drag.move_volume_idx == -1) && + m_gizmos.get_current_type() == GLGizmosManager::EType::Undefined && + !m_layers_editing.is_enabled()) _render_sequential_clearance(); #endif // ENABLE_SEQUENTIAL_LIMITS #if ENABLE_RENDER_SELECTION_CENTER From 40086784fe1f967992da38f98b9c660f30c6c172 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 17 May 2021 13:14:19 +0200 Subject: [PATCH 09/31] Small refactoring in GLCanvas3D --- src/slic3r/GUI/GLCanvas3D.cpp | 7 ++++--- src/slic3r/GUI/GLCanvas3D.hpp | 7 +++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index dffcb15e5..826342678 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2949,6 +2949,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) m_mouse.set_start_position_3D_as_invalid(); m_mouse.position = pos.cast(); + return; } @@ -3147,7 +3148,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) // See GH issue #3816. Camera& camera = wxGetApp().plater()->get_camera(); camera.recover_from_free_camera(); - camera.rotate_on_sphere(rot.x(), rot.y(), wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() != ptSLA); + camera.rotate_on_sphere(rot.x(), rot.y(), current_printer_technology() != ptSLA); } m_dirty = true; @@ -4837,7 +4838,7 @@ void GLCanvas3D::_render_background() const bool use_error_color = false; if (wxGetApp().is_editor()) { use_error_color = m_dynamic_background_enabled && - (wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() != ptSLA || !m_volumes.empty()); + (current_printer_technology() != ptSLA || !m_volumes.empty()); if (!m_volumes.empty()) use_error_color &= _is_any_volume_outside(); @@ -5255,7 +5256,7 @@ void GLCanvas3D::_render_camera_target() const void GLCanvas3D::_render_sla_slices() const { - if (!m_use_clipping_planes || wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() != ptSLA) + if (!m_use_clipping_planes || current_printer_technology() != ptSLA) return; const SLAPrint* print = this->sla_print(); diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index eebd21024..9b5c3a911 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -753,6 +753,9 @@ public: } #endif // ENABLE_SEQUENTIAL_LIMITS + const Print* fff_print() const; + const SLAPrint* sla_print() const; + private: bool _is_shown_on_screen() const; @@ -858,10 +861,6 @@ private: float get_overlay_window_width() { return LayersEditing::get_overlay_window_width(); } static std::vector _parse_colors(const std::vector& colors); - -public: - const Print* fff_print() const; - const SLAPrint* sla_print() const; }; } // namespace GUI From d5c462f5a63fbbf1f5858aceb3f7278f1cbaacaa Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 21 May 2021 14:57:03 +0200 Subject: [PATCH 10/31] Tech ENABLE_SEQUENTIAL_LIMITS -> Show sequential print clearance regions contours while dragging objects --- src/slic3r/GUI/GLCanvas3D.cpp | 168 ++++++++++++++++++++++++++++------ src/slic3r/GUI/GLCanvas3D.hpp | 8 +- src/slic3r/GUI/Plater.cpp | 4 +- 3 files changed, 148 insertions(+), 32 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 2c4fc0592..c3b9becb5 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -788,8 +788,10 @@ void GLCanvas3D::Tooltip::render(const Vec2d& mouse_position, GLCanvas3D& canvas } #if ENABLE_SEQUENTIAL_LIMITS -void GLCanvas3D::SequentialPrintClearance::set(const Polygons& polygons) +void GLCanvas3D::SequentialPrintClearance::set(const Polygons& polygons, bool fill) { + m_render_fill = fill; + m_perimeter.reset(); m_fill.reset(); if (polygons.empty()) @@ -801,37 +803,38 @@ void GLCanvas3D::SequentialPrintClearance::set(const Polygons& polygons) } size_t vertices_count = 3 * triangles_count; - GLModel::InitializationData fill_data; - GLModel::InitializationData::Entity entity; - entity.type = GLModel::PrimitiveType::Triangles; - entity.color = { 0.3333f, 0.0f, 0.0f, 0.5f }; - entity.positions.reserve(vertices_count); - entity.normals.reserve(vertices_count); - entity.indices.reserve(vertices_count); + if (fill) { + GLModel::InitializationData fill_data; + GLModel::InitializationData::Entity entity; + entity.type = GLModel::PrimitiveType::Triangles; + entity.color = { 0.3333f, 0.0f, 0.0f, 0.5f }; + entity.positions.reserve(vertices_count); + entity.normals.reserve(vertices_count); + entity.indices.reserve(vertices_count); - ExPolygons polygons_union = union_ex(polygons); - for (const ExPolygon& poly : polygons_union) { - std::vector triangulation = triangulate_expolygon_3d(poly, false); - for (const Vec3d& v : triangulation) { - entity.positions.emplace_back(v.cast() + Vec3f(0.0f, 0.0f, 0.0125f)); // add a small positive z to avoid z-fighting - entity.normals.emplace_back(Vec3f::UnitZ()); - size_t positions_count = entity.positions.size(); - if (positions_count % 3 == 0) { - entity.indices.emplace_back(positions_count - 3); - entity.indices.emplace_back(positions_count - 2); - entity.indices.emplace_back(positions_count - 1); + ExPolygons polygons_union = union_ex(polygons); + for (const ExPolygon& poly : polygons_union) { + std::vector triangulation = triangulate_expolygon_3d(poly, false); + for (const Vec3d& v : triangulation) { + entity.positions.emplace_back(v.cast() + Vec3f(0.0f, 0.0f, 0.0125f)); // add a small positive z to avoid z-fighting + entity.normals.emplace_back(Vec3f::UnitZ()); + size_t positions_count = entity.positions.size(); + if (positions_count % 3 == 0) { + entity.indices.emplace_back(positions_count - 3); + entity.indices.emplace_back(positions_count - 2); + entity.indices.emplace_back(positions_count - 1); + } } } - } - fill_data.entities.emplace_back(entity); - m_fill.init_from(fill_data); + fill_data.entities.emplace_back(entity); + m_fill.init_from(fill_data); + } GLModel::InitializationData perimeter_data; for (const Polygon& poly : polygons) { GLModel::InitializationData::Entity ent; ent.type = GLModel::PrimitiveType::LineLoop; - ent.color = { 1.0f, 0.0f, 0.0f, 0.5f }; ent.positions.reserve(poly.points.size()); ent.indices.reserve(poly.points.size()); unsigned int id_count = 0; @@ -849,6 +852,9 @@ void GLCanvas3D::SequentialPrintClearance::set(const Polygons& polygons) void GLCanvas3D::SequentialPrintClearance::render() const { + std::array FILL_COLOR = { 1.0f, 0.0f, 0.0f, 0.5f }; + std::array NO_FILL_COLOR = { 1.0f, 1.0f, 1.0f, 0.75f }; + GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); if (shader == nullptr) return; @@ -860,6 +866,7 @@ void GLCanvas3D::SequentialPrintClearance::render() const glsafe(::glEnable(GL_BLEND)); glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); + const_cast(&m_perimeter)->set_color(-1, m_render_fill ? FILL_COLOR : NO_FILL_COLOR); m_perimeter.render(); m_fill.render(); @@ -1459,8 +1466,7 @@ void GLCanvas3D::render() _render_selection(); _render_bed(!camera.is_looking_downward(), true); #if ENABLE_SEQUENTIAL_LIMITS - if ((!m_mouse.dragging || m_mouse.drag.move_volume_idx == -1) && - m_gizmos.get_current_type() == GLGizmosManager::EType::Undefined && + if (m_gizmos.get_current_type() == GLGizmosManager::EType::Undefined && !m_layers_editing.is_enabled()) _render_sequential_clearance(); #endif // ENABLE_SEQUENTIAL_LIMITS @@ -2950,6 +2956,22 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) m_mouse.set_start_position_3D_as_invalid(); m_mouse.position = pos.cast(); +#if ENABLE_SEQUENTIAL_LIMITS + if (evt.Dragging() && current_printer_technology() == ptFFF && fff_print()->config().complete_objects) { + switch (m_gizmos.get_current_type()) + { + case GLGizmosManager::EType::Move: + case GLGizmosManager::EType::Scale: + case GLGizmosManager::EType::Rotate: + { + update_sequential_clearance(); + break; + } + default: { break; } + } + } +#endif // ENABLE_SEQUENTIAL_LIMITS + return; } @@ -3116,6 +3138,10 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) } m_selection.translate(cur_pos - m_mouse.drag.start_position_3D); +#if ENABLE_SEQUENTIAL_LIMITS + if (current_printer_technology() == ptFFF && fff_print()->config().complete_objects) + update_sequential_clearance(); +#endif // ENABLE_SEQUENTIAL_LIMITS wxGetApp().obj_manipul()->set_dirty(); m_dirty = true; } @@ -3396,7 +3422,7 @@ void GLCanvas3D::do_move(const std::string& snapshot_type) post_event(Vec3dEvent(EVT_GLCANVAS_WIPETOWER_MOVED, std::move(wipe_tower_origin))); #if ENABLE_SEQUENTIAL_LIMITS - set_sequential_print_clearance(Polygons()); + set_sequential_print_clearance(Polygons(), false); #endif // ENABLE_SEQUENTIAL_LIMITS m_dirty = true; @@ -3745,6 +3771,96 @@ void GLCanvas3D::mouse_up_cleanup() m_canvas->ReleaseMouse(); } +#if ENABLE_SEQUENTIAL_LIMITS +void GLCanvas3D::update_sequential_clearance() +{ + if (current_printer_technology() != ptFFF || !fff_print()->config().complete_objects) + return; + + // collect objects and instances from volumes + struct Object + { + int id; + GLVolumePtrs volumes; + }; + std::vector objects; + + struct Instance + { + int id; + int object_id; + Transform3d transform; + }; + std::vector instances; + + for (GLVolume* v : m_volumes.volumes) { + if (v->is_modifier || v->is_wipe_tower) + continue; + + const int object_id = v->object_idx(); + const int instance_id = v->instance_idx(); + + // update instances list + auto inst_it = std::find_if(instances.begin(), instances.end(), [object_id, instance_id](const Instance& i) { return i.object_id == object_id && i.id == instance_id; }); + if (inst_it == instances.end()) { + const Instance i = { instance_id, object_id, v->get_instance_transformation().get_matrix() }; + instances.emplace_back(i); + } + + // update objects list + if (instance_id == 0) { + auto it = std::find_if(objects.begin(), objects.end(), [object_id](const Object& o) { return o.id == object_id; }); + if (it == objects.end()) + it = objects.insert(objects.end(), { object_id, GLVolumePtrs() }); + it->volumes.emplace_back(v); + } + } + + // calculates instances 2d hulls (see also: Print::sequential_print_horizontal_clearance_valid()) + Polygons polygons; + float shrink_factor = static_cast(scale_(0.5 * fff_print()->config().extruder_clearance_radius.value - EPSILON)); + float mitter_limit = static_cast(scale_(0.1)); + for (const Object& o : objects) { + // object 2d hull + ModelObject* model_object = m_model->objects[o.id]; + ModelInstance* model_instance0 = model_object->instances.front(); + Points obj_pts; + for (GLVolume* v : o.volumes) { + const TriangleMesh& mesh = model_object->volumes[v->composite_id.volume_id]->mesh(); + Transform3d inst_trafo = Geometry::assemble_transform({ 0.0, 0.0, model_instance0->get_offset().z() }, model_instance0->get_rotation(), + model_instance0->get_scaling_factor(), model_instance0->get_mirror()); + append(obj_pts, its_convex_hull_2d_above(mesh.its, (inst_trafo * v->get_volume_transformation().get_matrix()).cast(), 0.0f).points); + } + + obj_pts = offset(Polygon(obj_pts), + // Shrink the extruder_clearance_radius a tiny bit, so that if the object arrangement algorithm placed the objects + // exactly by satisfying the extruder_clearance_radius, this test will not trigger collision. + shrink_factor, + jtRound, mitter_limit).front().points; + + Pointf3s obj_pts_d; + for (const Point& p : obj_pts) { + obj_pts_d.emplace_back(unscale(p.x()), unscale(p.y()), 0.0); + } + + // instances 2d hulls + for (const Instance& i : instances) { + if (i.object_id != o.id) + continue; + + Points inst_pts; + for (const Vec3d& p : obj_pts_d) { + const Vec3d i_p = i.transform * p; + inst_pts.emplace_back(scale_(i_p.x()), scale_(i_p.y())); + } + polygons.emplace_back(Geometry::convex_hull(std::move(inst_pts))); + } + } + + set_sequential_print_clearance(polygons, false); +} +#endif // ENABLE_SEQUENTIAL_LIMITS + bool GLCanvas3D::_is_shown_on_screen() const { return (m_canvas != nullptr) ? m_canvas->IsShownOnScreen() : false; diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 9b823eae7..9da08aecd 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -501,9 +501,10 @@ private: { GLModel m_fill; GLModel m_perimeter; + bool m_render_fill{ true }; public: - void set(const Polygons& polygons); + void set(const Polygons& polygons, bool fill); void render() const; }; @@ -752,9 +753,8 @@ public: } #if ENABLE_SEQUENTIAL_LIMITS - void set_sequential_print_clearance(const Polygons& polygons) { - m_sequential_print_clearance.set(polygons); - } + void set_sequential_print_clearance(const Polygons& polygons, bool fill) { m_sequential_print_clearance.set(polygons, fill); } + void update_sequential_clearance(); #endif // ENABLE_SEQUENTIAL_LIMITS const Print* fff_print() const; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 45242c593..920cafaa3 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2939,7 +2939,7 @@ unsigned int Plater::priv::update_background_process(bool force_validation, bool process_validation_warning(warning); #if ENABLE_SEQUENTIAL_LIMITS if (printer_technology == ptFFF) { - view3D->get_canvas3d()->set_sequential_print_clearance(Polygons()); + view3D->get_canvas3d()->set_sequential_print_clearance(Polygons(), false); view3D->get_canvas3d()->set_as_dirty(); view3D->get_canvas3d()->request_extra_frame(); } @@ -2955,7 +2955,7 @@ unsigned int Plater::priv::update_background_process(bool force_validation, bool Polygons polygons; if (print->config().complete_objects) Print::sequential_print_horizontal_clearance_valid(*print, &polygons); - view3D->get_canvas3d()->set_sequential_print_clearance(polygons); + view3D->get_canvas3d()->set_sequential_print_clearance(polygons, true); } #endif // ENABLE_SEQUENTIAL_LIMITS } From 6192a3eaf70bbcc52cf264ff3e78575e6f5e6cee Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 24 May 2021 12:11:49 +0200 Subject: [PATCH 11/31] Tech ENABLE_SEQUENTIAL_LIMITS -> Improved performance when showing sequential print clearance regions contours while dragging objects --- src/libslic3r/Print.cpp | 2 +- src/slic3r/GUI/GLCanvas3D.cpp | 92 ++++++++++++++++------------------- src/slic3r/GUI/GLCanvas3D.hpp | 5 ++ 3 files changed, 49 insertions(+), 50 deletions(-) diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index f8f5cbf59..baaa0497c 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -388,7 +388,7 @@ static inline bool sequential_print_horizontal_clearance_valid(const Print &prin // Shrink the extruder_clearance_radius a tiny bit, so that if the object arrangement algorithm placed the objects // exactly by satisfying the extruder_clearance_radius, this test will not trigger collision. float(scale_(0.5 * print.config().extruder_clearance_radius.value - EPSILON)), - jtRound, float(scale_(0.1))).front()); + jtRound, scale_(0.1)).front()); #else it_convex_hull = map_model_object_to_convex_hull.emplace_hint(it_convex_hull, model_object_id, offset(print_object->model_object()->convex_hull_2d( diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index c3b9becb5..38a5d6fe4 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3093,6 +3093,9 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) m_mouse.drag.move_volume_idx = volume_idx; m_selection.start_dragging(); m_mouse.drag.start_position_3D = m_mouse.scene_position; +#if ENABLE_SEQUENTIAL_LIMITS + m_sequential_print_clearance_first_displacement = true; +#endif // ENABLE_SEQUENTIAL_LIMITS m_moving = true; } } @@ -3777,23 +3780,16 @@ void GLCanvas3D::update_sequential_clearance() if (current_printer_technology() != ptFFF || !fff_print()->config().complete_objects) return; - // collect objects and instances from volumes - struct Object - { - int id; - GLVolumePtrs volumes; - }; - std::vector objects; - struct Instance { - int id; int object_id; + int instance_id; Transform3d transform; }; std::vector instances; - for (GLVolume* v : m_volumes.volumes) { + // collects instance transformations from volumes + for (const GLVolume* v : m_volumes.volumes) { if (v->is_modifier || v->is_wipe_tower) continue; @@ -3801,58 +3797,56 @@ void GLCanvas3D::update_sequential_clearance() const int instance_id = v->instance_idx(); // update instances list - auto inst_it = std::find_if(instances.begin(), instances.end(), [object_id, instance_id](const Instance& i) { return i.object_id == object_id && i.id == instance_id; }); + auto inst_it = std::find_if(instances.begin(), instances.end(), [object_id, instance_id](const Instance& i) { return i.object_id == object_id && i.instance_id == instance_id; }); if (inst_it == instances.end()) { - const Instance i = { instance_id, object_id, v->get_instance_transformation().get_matrix() }; - instances.emplace_back(i); + const Instance instance = { object_id, instance_id, v->get_instance_transformation().get_matrix() }; + instances.emplace_back(instance); } + } - // update objects list - if (instance_id == 0) { - auto it = std::find_if(objects.begin(), objects.end(), [object_id](const Object& o) { return o.id == object_id; }); - if (it == objects.end()) - it = objects.insert(objects.end(), { object_id, GLVolumePtrs() }); - it->volumes.emplace_back(v); + if (m_sequential_print_clearance_first_displacement) { + m_sequential_print_clearance.m_hull_2d_cache.clear(); + // calculates objects 2d hulls (see also: Print::sequential_print_horizontal_clearance_valid()) + // and caches them for following displacements + float shrink_factor = static_cast(scale_(0.5 * fff_print()->config().extruder_clearance_radius.value - EPSILON)); + double mitter_limit = scale_(0.1); + int obj_id = 0; + m_sequential_print_clearance.m_hull_2d_cache.reserve(m_model->objects.size()); + for (size_t i = 0; i < m_model->objects.size(); ++i) { + ModelObject* model_object = m_model->objects[i]; + ModelInstance* model_instance0 = model_object->instances.front(); + Polygon hull_2d = offset(model_object->convex_hull_2d(Geometry::assemble_transform({ 0.0, 0.0, model_instance0->get_offset().z() }, model_instance0->get_rotation(), + model_instance0->get_scaling_factor(), model_instance0->get_mirror())), + // Shrink the extruder_clearance_radius a tiny bit, so that if the object arrangement algorithm placed the objects + // exactly by satisfying the extruder_clearance_radius, this test will not trigger collision. + shrink_factor, + jtRound, mitter_limit).front(); + + Pointf3s& cache_hull_2d = m_sequential_print_clearance.m_hull_2d_cache.emplace_back(Pointf3s()); + cache_hull_2d.reserve(hull_2d.points.size()); + for (const Point& p : hull_2d.points) { + cache_hull_2d.emplace_back(unscale(p.x()), unscale(p.y()), 0.0); + } } + m_sequential_print_clearance_first_displacement = false; } // calculates instances 2d hulls (see also: Print::sequential_print_horizontal_clearance_valid()) Polygons polygons; - float shrink_factor = static_cast(scale_(0.5 * fff_print()->config().extruder_clearance_radius.value - EPSILON)); - float mitter_limit = static_cast(scale_(0.1)); - for (const Object& o : objects) { - // object 2d hull - ModelObject* model_object = m_model->objects[o.id]; - ModelInstance* model_instance0 = model_object->instances.front(); - Points obj_pts; - for (GLVolume* v : o.volumes) { - const TriangleMesh& mesh = model_object->volumes[v->composite_id.volume_id]->mesh(); - Transform3d inst_trafo = Geometry::assemble_transform({ 0.0, 0.0, model_instance0->get_offset().z() }, model_instance0->get_rotation(), - model_instance0->get_scaling_factor(), model_instance0->get_mirror()); - append(obj_pts, its_convex_hull_2d_above(mesh.its, (inst_trafo * v->get_volume_transformation().get_matrix()).cast(), 0.0f).points); - } - - obj_pts = offset(Polygon(obj_pts), - // Shrink the extruder_clearance_radius a tiny bit, so that if the object arrangement algorithm placed the objects - // exactly by satisfying the extruder_clearance_radius, this test will not trigger collision. - shrink_factor, - jtRound, mitter_limit).front().points; - - Pointf3s obj_pts_d; - for (const Point& p : obj_pts) { - obj_pts_d.emplace_back(unscale(p.x()), unscale(p.y()), 0.0); - } - + for (size_t i = 0; i < m_model->objects.size(); ++i) { // instances 2d hulls - for (const Instance& i : instances) { - if (i.object_id != o.id) + for (const Instance& inst : instances) { + if (inst.object_id != static_cast(i)) continue; Points inst_pts; - for (const Vec3d& p : obj_pts_d) { - const Vec3d i_p = i.transform * p; - inst_pts.emplace_back(scale_(i_p.x()), scale_(i_p.y())); + inst_pts.reserve(m_sequential_print_clearance.m_hull_2d_cache[i].size()); + for (size_t j = 0; j < m_sequential_print_clearance.m_hull_2d_cache[i].size(); ++j) { + const Vec3d& p = m_sequential_print_clearance.m_hull_2d_cache[i][j]; + const Vec3d inst_p = inst.transform * p; + inst_pts.emplace_back(scaled(inst_p.x()), scaled(inst_p.y())); } + polygons.emplace_back(Geometry::convex_hull(std::move(inst_pts))); } } diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 9da08aecd..c0ef83b72 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -503,12 +503,17 @@ private: GLModel m_perimeter; bool m_render_fill{ true }; + std::vector m_hull_2d_cache; + public: void set(const Polygons& polygons, bool fill); void render() const; + + friend class GLCanvas3D; }; SequentialPrintClearance m_sequential_print_clearance; + bool m_sequential_print_clearance_first_displacement{ true }; #endif // ENABLE_SEQUENTIAL_LIMITS public: From 40b97c33c57f2900b530774b9b95124b8718caac Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 24 May 2021 13:22:37 +0200 Subject: [PATCH 12/31] Tech ENABLE_SEQUENTIAL_LIMITS -> Another improvement in performance when showing sequential print clearance regions contours while dragging objects --- src/slic3r/GUI/GLCanvas3D.cpp | 48 +++++++++++++++++------------------ 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 38a5d6fe4..c0ba2003a 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3780,34 +3780,34 @@ void GLCanvas3D::update_sequential_clearance() if (current_printer_technology() != ptFFF || !fff_print()->config().complete_objects) return; - struct Instance - { - int object_id; - int instance_id; - Transform3d transform; - }; - std::vector instances; - // collects instance transformations from volumes + // first define temporary cache + std::vector>> instance_transforms; + for (size_t o = 0; o < m_model->objects.size(); ++o) { + instance_transforms.emplace_back(std::vector>()); + const ModelObject* model_object = m_model->objects[o]; + for (size_t i = 0; i < model_object->instances.size(); ++i) { + instance_transforms[o].emplace_back(false, Transform3d()); + } + } + + // second fill temporary cache with data from volumes for (const GLVolume* v : m_volumes.volumes) { if (v->is_modifier || v->is_wipe_tower) continue; - const int object_id = v->object_idx(); - const int instance_id = v->instance_idx(); - - // update instances list - auto inst_it = std::find_if(instances.begin(), instances.end(), [object_id, instance_id](const Instance& i) { return i.object_id == object_id && i.instance_id == instance_id; }); - if (inst_it == instances.end()) { - const Instance instance = { object_id, instance_id, v->get_instance_transformation().get_matrix() }; - instances.emplace_back(instance); + auto& [already_set, transform] = instance_transforms[v->object_idx()][v->instance_idx()]; + if (!already_set) { + transform = v->get_instance_transformation().get_matrix(); + already_set = true; } } + // calculates objects 2d hulls (see also: Print::sequential_print_horizontal_clearance_valid()) + // this is done only the first time this method is called while moving the mouse, + // the results are then cached for following displacements if (m_sequential_print_clearance_first_displacement) { m_sequential_print_clearance.m_hull_2d_cache.clear(); - // calculates objects 2d hulls (see also: Print::sequential_print_horizontal_clearance_valid()) - // and caches them for following displacements float shrink_factor = static_cast(scale_(0.5 * fff_print()->config().extruder_clearance_radius.value - EPSILON)); double mitter_limit = scale_(0.1); int obj_id = 0; @@ -3833,17 +3833,14 @@ void GLCanvas3D::update_sequential_clearance() // calculates instances 2d hulls (see also: Print::sequential_print_horizontal_clearance_valid()) Polygons polygons; - for (size_t i = 0; i < m_model->objects.size(); ++i) { - // instances 2d hulls - for (const Instance& inst : instances) { - if (inst.object_id != static_cast(i)) - continue; - + for (size_t i = 0; i < instance_transforms.size(); ++i) { + const auto& object = instance_transforms[i]; + for (const auto& instance : object) { Points inst_pts; inst_pts.reserve(m_sequential_print_clearance.m_hull_2d_cache[i].size()); for (size_t j = 0; j < m_sequential_print_clearance.m_hull_2d_cache[i].size(); ++j) { const Vec3d& p = m_sequential_print_clearance.m_hull_2d_cache[i][j]; - const Vec3d inst_p = inst.transform * p; + const Vec3d inst_p = instance.second * p; inst_pts.emplace_back(scaled(inst_p.x()), scaled(inst_p.y())); } @@ -3851,6 +3848,7 @@ void GLCanvas3D::update_sequential_clearance() } } + // sends instances 2d hulls to be rendered set_sequential_print_clearance(polygons, false); } #endif // ENABLE_SEQUENTIAL_LIMITS From abbe7f7eeaac57f10016336ea34012b897e7ba23 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 24 May 2021 14:11:09 +0200 Subject: [PATCH 13/31] Tech ENABLE_SEQUENTIAL_LIMITS -> Reset sequential print clearance regions contours when clearing the plater --- src/slic3r/GUI/Plater.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 920cafaa3..63aca0df2 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2730,6 +2730,10 @@ void Plater::priv::reset() reset_gcode_toolpaths(); gcode_result.reset(); +#if ENABLE_SEQUENTIAL_LIMITS + view3D->get_canvas3d()->set_sequential_print_clearance(Polygons(), false); +#endif // ENABLE_SEQUENTIAL_LIMITS + // Stop and reset the Print content. this->background_process.reset(); model.clear_objects(); From 9f6751586c80339825b397cb79430338fc61a683 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 24 May 2021 14:18:52 +0200 Subject: [PATCH 14/31] Tech ENABLE_SEQUENTIAL_LIMITS -> Do not show sequential print clearance regions contours when there is only one instance on the plater --- src/slic3r/GUI/GLCanvas3D.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index c0ba2003a..f9dd08f36 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3782,15 +3782,20 @@ void GLCanvas3D::update_sequential_clearance() // collects instance transformations from volumes // first define temporary cache + unsigned int instances_count = 0; std::vector>> instance_transforms; for (size_t o = 0; o < m_model->objects.size(); ++o) { instance_transforms.emplace_back(std::vector>()); const ModelObject* model_object = m_model->objects[o]; for (size_t i = 0; i < model_object->instances.size(); ++i) { instance_transforms[o].emplace_back(false, Transform3d()); + ++instances_count; } } + if (instances_count == 1) + return; + // second fill temporary cache with data from volumes for (const GLVolume* v : m_volumes.volumes) { if (v->is_modifier || v->is_wipe_tower) @@ -3833,6 +3838,7 @@ void GLCanvas3D::update_sequential_clearance() // calculates instances 2d hulls (see also: Print::sequential_print_horizontal_clearance_valid()) Polygons polygons; + polygons.reserve(instances_count); for (size_t i = 0; i < instance_transforms.size(); ++i) { const auto& object = instance_transforms[i]; for (const auto& instance : object) { From 44e9693789d963f2fed83231256e27c7454b0601 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 25 May 2021 13:34:51 +0200 Subject: [PATCH 15/31] Tech ENABLE_SEQUENTIAL_LIMITS -> Fixed instance transformations --- src/slic3r/GUI/GLCanvas3D.cpp | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 89aceb7c2..2b3c8f2cf 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3783,12 +3783,12 @@ void GLCanvas3D::update_sequential_clearance() // collects instance transformations from volumes // first define temporary cache unsigned int instances_count = 0; - std::vector>> instance_transforms; + std::vector>> instance_transforms; for (size_t o = 0; o < m_model->objects.size(); ++o) { - instance_transforms.emplace_back(std::vector>()); + instance_transforms.emplace_back(std::vector>()); const ModelObject* model_object = m_model->objects[o]; for (size_t i = 0; i < model_object->instances.size(); ++i) { - instance_transforms[o].emplace_back(false, Transform3d()); + instance_transforms[o].emplace_back(false, Geometry::Transformation()); ++instances_count; } } @@ -3803,7 +3803,7 @@ void GLCanvas3D::update_sequential_clearance() auto& [already_set, transform] = instance_transforms[v->object_idx()][v->instance_idx()]; if (!already_set) { - transform = v->get_instance_transformation().get_matrix(); + transform = v->get_instance_transformation(); already_set = true; } } @@ -3840,16 +3840,21 @@ void GLCanvas3D::update_sequential_clearance() Polygons polygons; polygons.reserve(instances_count); for (size_t i = 0; i < instance_transforms.size(); ++i) { - const auto& object = instance_transforms[i]; - for (const auto& instance : object) { + const auto& instances = instance_transforms[i]; + double rotation_z0 = instances.front().second.get_rotation().z(); + for (const auto& instance : instances) { + Geometry::Transformation transformation; + const Vec3d& offset = instance.second.get_offset(); + transformation.set_offset({ offset.x(), offset.y(), 0.0 }); + transformation.set_rotation(Z, instance.second.get_rotation().z() - rotation_z0); + const Transform3d& trafo = transformation.get_matrix(); + const Pointf3s& hull_2d = m_sequential_print_clearance.m_hull_2d_cache[i]; Points inst_pts; - inst_pts.reserve(m_sequential_print_clearance.m_hull_2d_cache[i].size()); - for (size_t j = 0; j < m_sequential_print_clearance.m_hull_2d_cache[i].size(); ++j) { - const Vec3d& p = m_sequential_print_clearance.m_hull_2d_cache[i][j]; - const Vec3d inst_p = instance.second * p; - inst_pts.emplace_back(scaled(inst_p.x()), scaled(inst_p.y())); + inst_pts.reserve(hull_2d.size()); + for (size_t j = 0; j < hull_2d.size(); ++j) { + const Vec3d p = trafo * hull_2d[j]; + inst_pts.emplace_back(scaled(p.x()), scaled(p.y())); } - polygons.emplace_back(Geometry::convex_hull(std::move(inst_pts))); } } From 87815b0b16331db3123d50180c9c3c518eec3cf2 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 25 May 2021 15:55:37 +0200 Subject: [PATCH 16/31] Tech ENABLE_SEQUENTIAL_LIMITS -> Some refactoring --- src/slic3r/GUI/GLCanvas3D.cpp | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 2b3c8f2cf..f266c8611 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3783,12 +3783,12 @@ void GLCanvas3D::update_sequential_clearance() // collects instance transformations from volumes // first define temporary cache unsigned int instances_count = 0; - std::vector>> instance_transforms; - for (size_t o = 0; o < m_model->objects.size(); ++o) { - instance_transforms.emplace_back(std::vector>()); - const ModelObject* model_object = m_model->objects[o]; + std::vector>> instance_transforms; + for (size_t obj = 0; obj < m_model->objects.size(); ++obj) { + instance_transforms.emplace_back(std::vector>()); + const ModelObject* model_object = m_model->objects[obj]; for (size_t i = 0; i < model_object->instances.size(); ++i) { - instance_transforms[o].emplace_back(false, Geometry::Transformation()); + instance_transforms[obj].emplace_back(std::optional()); ++instances_count; } } @@ -3801,11 +3801,9 @@ void GLCanvas3D::update_sequential_clearance() if (v->is_modifier || v->is_wipe_tower) continue; - auto& [already_set, transform] = instance_transforms[v->object_idx()][v->instance_idx()]; - if (!already_set) { + auto& transform = instance_transforms[v->object_idx()][v->instance_idx()]; + if (!transform.has_value()) transform = v->get_instance_transformation(); - already_set = true; - } } // calculates objects 2d hulls (see also: Print::sequential_print_horizontal_clearance_valid()) @@ -3815,7 +3813,6 @@ void GLCanvas3D::update_sequential_clearance() m_sequential_print_clearance.m_hull_2d_cache.clear(); float shrink_factor = static_cast(scale_(0.5 * fff_print()->config().extruder_clearance_radius.value - EPSILON)); double mitter_limit = scale_(0.1); - int obj_id = 0; m_sequential_print_clearance.m_hull_2d_cache.reserve(m_model->objects.size()); for (size_t i = 0; i < m_model->objects.size(); ++i) { ModelObject* model_object = m_model->objects[i]; @@ -3841,12 +3838,12 @@ void GLCanvas3D::update_sequential_clearance() polygons.reserve(instances_count); for (size_t i = 0; i < instance_transforms.size(); ++i) { const auto& instances = instance_transforms[i]; - double rotation_z0 = instances.front().second.get_rotation().z(); + double rotation_z0 = instances.front()->get_rotation().z(); for (const auto& instance : instances) { Geometry::Transformation transformation; - const Vec3d& offset = instance.second.get_offset(); + const Vec3d& offset = instance->get_offset(); transformation.set_offset({ offset.x(), offset.y(), 0.0 }); - transformation.set_rotation(Z, instance.second.get_rotation().z() - rotation_z0); + transformation.set_rotation(Z, instance->get_rotation().z() - rotation_z0); const Transform3d& trafo = transformation.get_matrix(); const Pointf3s& hull_2d = m_sequential_print_clearance.m_hull_2d_cache[i]; Points inst_pts; From 0c7095d807efd960fb779a26b2647ec6e1e45c02 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 28 May 2021 16:28:56 +0200 Subject: [PATCH 17/31] Fixed crash when deleting last obejct from plater --- src/slic3r/GUI/GLCanvas3D.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 455eb8a78..eaa4c7f0d 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1615,6 +1615,8 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re _set_current(); + m_hover_volume_idxs.clear(); + struct ModelVolumeState { ModelVolumeState(const GLVolume* volume) : model_volume(nullptr), geometry_id(volume->geometry_id), volume_idx(-1) {} From 97b7ef7dc0e3d5185eae67edc2d14236a8b659a1 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Fri, 12 Mar 2021 10:29:17 +0100 Subject: [PATCH 18/31] Removed GLU calls from all the gizmos --- src/libslic3r/TriangleMesh.cpp | 27 +++++ src/libslic3r/TriangleMesh.hpp | 4 +- src/slic3r/GUI/Gizmos/GLGizmoBase.cpp | 70 +++--------- src/slic3r/GUI/Gizmos/GLGizmoBase.hpp | 7 +- src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp | 51 +++------ src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp | 6 +- src/slic3r/GUI/Gizmos/GLGizmoMove.cpp | 20 +--- src/slic3r/GUI/Gizmos/GLGizmoMove.hpp | 4 +- src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp | 20 +--- src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp | 4 +- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp | 112 +++++++++---------- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp | 4 +- 12 files changed, 129 insertions(+), 200 deletions(-) diff --git a/src/libslic3r/TriangleMesh.cpp b/src/libslic3r/TriangleMesh.cpp index fba1429ea..99f2c9641 100644 --- a/src/libslic3r/TriangleMesh.cpp +++ b/src/libslic3r/TriangleMesh.cpp @@ -1014,6 +1014,33 @@ TriangleMesh make_cylinder(double r, double h, double fa) return mesh; } + +TriangleMesh make_cone(double r, double h, double fa) +{ + Pointf3s vertices; + std::vector facets; + vertices.reserve(3+size_t(2*PI/fa)); + vertices.reserve(3+2*size_t(2*PI/fa)); + + vertices = { Vec3d::Zero(), Vec3d(0., 0., h) }; // base center and top vertex + size_t i = 0; + for (double angle=0; angle<2*PI; angle+=fa) { + vertices.emplace_back(r*std::cos(angle), r*std::sin(angle), 0.); + if (angle > 0.) { + facets.emplace_back(0, i+2, i+1); + facets.emplace_back(1, i+1, i+2); + } + ++i; + } + facets.emplace_back(0, 2, i+1); // close the shape + facets.emplace_back(1, i+1, 2); + + TriangleMesh mesh(std::move(vertices), std::move(facets)); + mesh.repair(); + return mesh; +} + + // Generates mesh for a sphere centered about the origin, using the generated angle // to determine the granularity. // Default angle is 1 degree. diff --git a/src/libslic3r/TriangleMesh.hpp b/src/libslic3r/TriangleMesh.hpp index 49b11465e..24447d896 100644 --- a/src/libslic3r/TriangleMesh.hpp +++ b/src/libslic3r/TriangleMesh.hpp @@ -122,10 +122,8 @@ Polygon its_convex_hull_2d_above(const indexed_triangle_set &its, const Matrix3f Polygon its_convex_hull_2d_above(const indexed_triangle_set &its, const Transform3f &t, const float z); TriangleMesh make_cube(double x, double y, double z); - -// Generate a TriangleMesh of a cylinder TriangleMesh make_cylinder(double r, double h, double fa=(2*PI/360)); - +TriangleMesh make_cone(double r, double h, double fa=(2*PI/360)); TriangleMesh make_sphere(double rho, double fa=(2*PI/360)); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp index 9bc34f990..ca9b2408c 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp @@ -13,6 +13,10 @@ namespace GUI { const float GLGizmoBase::Grabber::SizeFactor = 0.05f; const float GLGizmoBase::Grabber::MinHalfSize = 1.5f; const float GLGizmoBase::Grabber::DraggingScaleFactor = 1.25f; +GLModel GLGizmoBase::Grabber::VBOCube; +GLModel GLGizmoBase::VBOCone; +GLModel GLGizmoBase::VBOCylinder; +GLModel GLGizmoBase::VBOSphere; GLGizmoBase::Grabber::Grabber() : center(Vec3d::Zero()) @@ -24,6 +28,9 @@ GLGizmoBase::Grabber::Grabber() color[1] = 1.0f; color[2] = 1.0f; color[3] = 1.0f; + TriangleMesh cube = make_cube(1., 1., 1.); + cube.translate(Vec3f(-0.5, -0.5, -0.5)); + VBOCube.init_from(cube); } void GLGizmoBase::Grabber::render(bool hover, float size) const @@ -54,7 +61,7 @@ float GLGizmoBase::Grabber::get_dragging_half_size(float size) const void GLGizmoBase::Grabber::render(float size, const float* render_color, bool use_lighting) const { - float half_size = dragging ? get_dragging_half_size(size) : get_half_size(size); + float fullsize = 2 * (dragging ? get_dragging_half_size(size) : get_half_size(size)); if (use_lighting) glsafe(::glEnable(GL_LIGHTING)); @@ -63,71 +70,17 @@ void GLGizmoBase::Grabber::render(float size, const float* render_color, bool us glsafe(::glPushMatrix()); glsafe(::glTranslated(center(0), center(1), center(2))); - glsafe(::glRotated(Geometry::rad2deg(angles(2)), 0.0, 0.0, 1.0)); glsafe(::glRotated(Geometry::rad2deg(angles(1)), 0.0, 1.0, 0.0)); glsafe(::glRotated(Geometry::rad2deg(angles(0)), 1.0, 0.0, 0.0)); - - // face min x - glsafe(::glPushMatrix()); - glsafe(::glTranslatef(-(GLfloat)half_size, 0.0f, 0.0f)); - glsafe(::glRotatef(-90.0f, 0.0f, 1.0f, 0.0f)); - render_face(half_size); - glsafe(::glPopMatrix()); - - // face max x - glsafe(::glPushMatrix()); - glsafe(::glTranslatef((GLfloat)half_size, 0.0f, 0.0f)); - glsafe(::glRotatef(90.0f, 0.0f, 1.0f, 0.0f)); - render_face(half_size); - glsafe(::glPopMatrix()); - - // face min y - glsafe(::glPushMatrix()); - glsafe(::glTranslatef(0.0f, -(GLfloat)half_size, 0.0f)); - glsafe(::glRotatef(90.0f, 1.0f, 0.0f, 0.0f)); - render_face(half_size); - glsafe(::glPopMatrix()); - - // face max y - glsafe(::glPushMatrix()); - glsafe(::glTranslatef(0.0f, (GLfloat)half_size, 0.0f)); - glsafe(::glRotatef(-90.0f, 1.0f, 0.0f, 0.0f)); - render_face(half_size); - glsafe(::glPopMatrix()); - - // face min z - glsafe(::glPushMatrix()); - glsafe(::glTranslatef(0.0f, 0.0f, -(GLfloat)half_size)); - glsafe(::glRotatef(180.0f, 1.0f, 0.0f, 0.0f)); - render_face(half_size); - glsafe(::glPopMatrix()); - - // face max z - glsafe(::glPushMatrix()); - glsafe(::glTranslatef(0.0f, 0.0f, (GLfloat)half_size)); - render_face(half_size); - glsafe(::glPopMatrix()); - + glsafe(::glScaled(fullsize, fullsize, fullsize)); + VBOCube.render(); glsafe(::glPopMatrix()); if (use_lighting) glsafe(::glDisable(GL_LIGHTING)); } -void GLGizmoBase::Grabber::render_face(float half_size) const -{ - ::glBegin(GL_TRIANGLES); - ::glNormal3f(0.0f, 0.0f, 1.0f); - ::glVertex3f(-(GLfloat)half_size, -(GLfloat)half_size, 0.0f); - ::glVertex3f((GLfloat)half_size, -(GLfloat)half_size, 0.0f); - ::glVertex3f((GLfloat)half_size, (GLfloat)half_size, 0.0f); - ::glVertex3f((GLfloat)half_size, (GLfloat)half_size, 0.0f); - ::glVertex3f(-(GLfloat)half_size, (GLfloat)half_size, 0.0f); - ::glVertex3f(-(GLfloat)half_size, -(GLfloat)half_size, 0.0f); - glsafe(::glEnd()); -} - GLGizmoBase::GLGizmoBase(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) : m_parent(parent) @@ -144,6 +97,9 @@ GLGizmoBase::GLGizmoBase(GLCanvas3D& parent, const std::string& icon_filename, u ::memcpy((void*)m_base_color, (const void*)DEFAULT_BASE_COLOR, 4 * sizeof(float)); ::memcpy((void*)m_drag_color, (const void*)DEFAULT_DRAG_COLOR, 4 * sizeof(float)); ::memcpy((void*)m_highlight_color, (const void*)DEFAULT_HIGHLIGHT_COLOR, 4 * sizeof(float)); + VBOCone.init_from(make_cone(1., 1., 2*PI/24)); + VBOSphere.init_from(make_sphere(1., (2*M_PI)/24.)); + VBOCylinder.init_from(make_cylinder(1., 1., 2*PI/24.)); } void GLGizmoBase::set_hover_id(int id) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp index 44f0a6972..b49619470 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp @@ -4,6 +4,7 @@ #include "libslic3r/Point.hpp" #include "slic3r/GUI/I18N.hpp" +#include "slic3r/GUI/GLModel.hpp" #include @@ -47,6 +48,8 @@ protected: static const float SizeFactor; static const float MinHalfSize; static const float DraggingScaleFactor; + static GLModel VBOCube; + static GLModel VBOCone; Vec3d center; Vec3d angles; @@ -64,7 +67,6 @@ protected: private: void render(float size, const float* render_color, bool use_lighting) const; - void render_face(float half_size) const; }; public: @@ -103,6 +105,9 @@ protected: bool m_first_input_window_render; mutable std::string m_tooltip; CommonGizmosDataPool* m_c; + static GLModel VBOCone; + static GLModel VBOCylinder; + static GLModel VBOSphere; public: GLGizmoBase(GLCanvas3D& parent, diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp index 9db50e6f1..515e0ea76 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp @@ -19,20 +19,10 @@ namespace GUI { GLGizmoHollow::GLGizmoHollow(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) : GLGizmoBase(parent, icon_filename, sprite_id) - , m_quadric(nullptr) { - m_quadric = ::gluNewQuadric(); - if (m_quadric != nullptr) - // using GLU_FILL does not work when the instance's transformation - // contains mirroring (normals are reverted) - ::gluQuadricDrawStyle(m_quadric, GLU_FILL); + m_vbo_cylinder.init_from(make_cylinder(1., 1.)); } -GLGizmoHollow::~GLGizmoHollow() -{ - if (m_quadric != nullptr) - ::gluDeleteQuadric(m_quadric); -} bool GLGizmoHollow::on_init() { @@ -87,7 +77,7 @@ void GLGizmoHollow::on_render() const glsafe(::glEnable(GL_BLEND)); glsafe(::glEnable(GL_DEPTH_TEST)); - if (m_quadric != nullptr && selection.is_from_single_instance()) + if (selection.is_from_single_instance()) render_points(selection, false); m_selection_rectangle.render(m_parent); @@ -111,8 +101,10 @@ void GLGizmoHollow::on_render_for_picking() const void GLGizmoHollow::render_points(const Selection& selection, bool picking) const { - if (!picking) - glsafe(::glEnable(GL_LIGHTING)); + GLShaderProgram* shader = picking ? nullptr : wxGetApp().get_shader("gouraud_light"); + if (shader) + shader->start_using(); + ScopeGuard guard([shader]() { if (shader) shader->stop_using(); }); const GLVolume* vol = selection.get_volume(*selection.get_volume_idxs().begin()); const Transform3d& instance_scaling_matrix_inverse = vol->get_instance_transformation().get_matrix(true, true, false, true).inverse(); @@ -150,16 +142,17 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking) cons } else { // neigher hover nor picking - render_color[0] = point_selected ? 1.0f : 0.7f; - render_color[1] = point_selected ? 0.3f : 0.7f; - render_color[2] = point_selected ? 0.3f : 0.7f; + render_color[0] = point_selected ? 1.0f : 1.f; + render_color[1] = point_selected ? 0.3f : 1.f; + render_color[2] = point_selected ? 0.3f : 1.f; render_color[3] = 0.5f; } } - glsafe(::glColor4fv(render_color.data())); - float render_color_emissive[4] = { 0.5f * render_color[0], 0.5f * render_color[1], 0.5f * render_color[2], 1.f}; - glsafe(::glMaterialfv(GL_FRONT, GL_EMISSION, render_color_emissive)); + if (shader && ! picking) + shader->set_uniform("uniform_color", render_color); + else // picking + glsafe(::glColor4fv(render_color.data())); // Inverse matrix of the instance scaling is applied so that the mark does not scale with the object. glsafe(::glPushMatrix()); @@ -176,12 +169,8 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking) cons glsafe(::glRotated(aa.angle() * (180. / M_PI), aa.axis()(0), aa.axis()(1), aa.axis()(2))); glsafe(::glPushMatrix()); glsafe(::glTranslated(0., 0., -drain_hole.height)); - ::gluCylinder(m_quadric, drain_hole.radius, drain_hole.radius, drain_hole.height + sla::HoleStickOutLength, 24, 1); - glsafe(::glTranslated(0., 0., drain_hole.height + sla::HoleStickOutLength)); - ::gluDisk(m_quadric, 0.0, drain_hole.radius, 24, 1); - glsafe(::glTranslated(0., 0., -drain_hole.height - sla::HoleStickOutLength)); - glsafe(::glRotatef(180.f, 1.f, 0.f, 0.f)); - ::gluDisk(m_quadric, 0.0, drain_hole.radius, 24, 1); + glsafe(::glScaled(drain_hole.radius, drain_hole.radius, drain_hole.height + sla::HoleStickOutLength)); + m_vbo_cylinder.render(); glsafe(::glPopMatrix()); if (vol->is_left_handed()) @@ -189,14 +178,8 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking) cons glsafe(::glPopMatrix()); } - { - // Reset emissive component to zero (the default value) - float render_color_emissive[4] = { 0.f, 0.f, 0.f, 1.f }; - glsafe(::glMaterialfv(GL_FRONT, GL_EMISSION, render_color_emissive)); - } - - if (!picking) - glsafe(::glDisable(GL_LIGHTING)); + //if (!picking) + // glsafe(::glDisable(GL_LIGHTING)); glsafe(::glPopMatrix()); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp index 5d34f04d6..1bcf1713e 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp @@ -25,12 +25,10 @@ class GLGizmoHollow : public GLGizmoBase private: bool unproject_on_mesh(const Vec2d& mouse_pos, std::pair& pos_and_normal); - GLUquadricObj* m_quadric; - public: GLGizmoHollow(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id); - ~GLGizmoHollow() override; + virtual ~GLGizmoHollow() = default; void set_sla_support_data(ModelObject* model_object, const Selection& selection); bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down); void delete_selected_points(); @@ -50,7 +48,7 @@ private: ObjectID m_old_mo_id = -1; - // bool m_show_supports = true; + GLModel m_vbo_cylinder; float m_new_hole_radius = 2.f; // Size of a new hole. float m_new_hole_height = 6.f; mutable std::vector m_selected; // which holes are currently selected diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp index f349776ab..0b65982b7 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp @@ -18,17 +18,8 @@ GLGizmoMove3D::GLGizmoMove3D(GLCanvas3D& parent, const std::string& icon_filenam , m_starting_drag_position(Vec3d::Zero()) , m_starting_box_center(Vec3d::Zero()) , m_starting_box_bottom_center(Vec3d::Zero()) - , m_quadric(nullptr) { - m_quadric = ::gluNewQuadric(); - if (m_quadric != nullptr) - ::gluQuadricDrawStyle(m_quadric, GLU_FILL); -} - -GLGizmoMove3D::~GLGizmoMove3D() -{ - if (m_quadric != nullptr) - ::gluDeleteQuadric(m_quadric); + m_vbo_cone.init_from(make_cone(1., 1., 2*PI/36)); } std::string GLGizmoMove3D::get_tooltip() const @@ -200,9 +191,6 @@ double GLGizmoMove3D::calc_projection(const UpdateData& data) const void GLGizmoMove3D::render_grabber_extension(Axis axis, const BoundingBoxf3& box, bool picking) const { - if (m_quadric == nullptr) - return; - float mean_size = (float)((box.size()(0) + box.size()(1) + box.size()(2)) / 3.0); double size = m_dragging ? (double)m_grabbers[axis].get_dragging_half_size(mean_size) : (double)m_grabbers[axis].get_half_size(mean_size); @@ -228,10 +216,8 @@ void GLGizmoMove3D::render_grabber_extension(Axis axis, const BoundingBoxf3& box glsafe(::glRotated(-90.0, 1.0, 0.0, 0.0)); glsafe(::glTranslated(0.0, 0.0, 2.0 * size)); - ::gluQuadricOrientation(m_quadric, GLU_OUTSIDE); - ::gluCylinder(m_quadric, 0.75 * size, 0.0, 3.0 * size, 36, 1); - ::gluQuadricOrientation(m_quadric, GLU_INSIDE); - ::gluDisk(m_quadric, 0.0, 0.75 * size, 36, 1); + glsafe(::glScaled(0.75 * size, 0.75 * size, 3.0 * size)); + m_vbo_cone.render(); glsafe(::glPopMatrix()); if (!picking) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMove.hpp b/src/slic3r/GUI/Gizmos/GLGizmoMove.hpp index 20aa9f56c..9a86852d6 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMove.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMove.hpp @@ -19,11 +19,11 @@ class GLGizmoMove3D : public GLGizmoBase Vec3d m_starting_box_center; Vec3d m_starting_box_bottom_center; - GLUquadricObj* m_quadric; + GLModel m_vbo_cone; public: GLGizmoMove3D(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id); - virtual ~GLGizmoMove3D(); + virtual ~GLGizmoMove3D() = default; double get_snap_step(double step) const { return m_snap_step; } void set_snap_step(double step) { m_snap_step = step; } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp index 6b6905e4d..eceeb5e87 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp @@ -38,9 +38,6 @@ GLGizmoRotate::GLGizmoRotate(GLCanvas3D& parent, GLGizmoRotate::Axis axis) , m_snap_fine_in_radius(0.0f) , m_snap_fine_out_radius(0.0f) { - m_quadric = ::gluNewQuadric(); - if (m_quadric != nullptr) - ::gluQuadricDrawStyle(m_quadric, GLU_FILL); } GLGizmoRotate::GLGizmoRotate(const GLGizmoRotate& other) @@ -60,11 +57,6 @@ GLGizmoRotate::GLGizmoRotate(const GLGizmoRotate& other) ::gluQuadricDrawStyle(m_quadric, GLU_FILL); } -GLGizmoRotate::~GLGizmoRotate() -{ - if (m_quadric != nullptr) - ::gluDeleteQuadric(m_quadric); -} void GLGizmoRotate::set_angle(double angle) { @@ -361,20 +353,16 @@ void GLGizmoRotate::render_grabber_extension(const BoundingBoxf3& box, bool pick glsafe(::glRotated(Geometry::rad2deg(m_angle), 0.0, 0.0, 1.0)); glsafe(::glRotated(90.0, 1.0, 0.0, 0.0)); glsafe(::glTranslated(0.0, 0.0, 2.0 * size)); - ::gluQuadricOrientation(m_quadric, GLU_OUTSIDE); - ::gluCylinder(m_quadric, 0.75 * size, 0.0, 3.0 * size, 36, 1); - ::gluQuadricOrientation(m_quadric, GLU_INSIDE); - ::gluDisk(m_quadric, 0.0, 0.75 * size, 36, 1); + glsafe(::glScaled(0.75 * size, 0.75 * size, 3.0 * size)); + VBOCone.render(); glsafe(::glPopMatrix()); glsafe(::glPushMatrix()); glsafe(::glTranslated(m_grabbers[0].center(0), m_grabbers[0].center(1), m_grabbers[0].center(2))); glsafe(::glRotated(Geometry::rad2deg(m_angle), 0.0, 0.0, 1.0)); glsafe(::glRotated(-90.0, 1.0, 0.0, 0.0)); glsafe(::glTranslated(0.0, 0.0, 2.0 * size)); - ::gluQuadricOrientation(m_quadric, GLU_OUTSIDE); - ::gluCylinder(m_quadric, 0.75 * size, 0.0, 3.0 * size, 36, 1); - ::gluQuadricOrientation(m_quadric, GLU_INSIDE); - ::gluDisk(m_quadric, 0.0, 0.75 * size, 36, 1); + glsafe(::glScaled(0.75 * size, 0.75 * size, 3.0 * size)); + VBOCone.render(); glsafe(::glPopMatrix()); if (!picking) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp index c18d0eefd..88a5ba169 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp @@ -32,8 +32,6 @@ private: Axis m_axis; double m_angle; - GLUquadricObj* m_quadric; - mutable Vec3d m_center; mutable float m_radius; @@ -45,7 +43,7 @@ private: public: GLGizmoRotate(GLCanvas3D& parent, Axis axis); GLGizmoRotate(const GLGizmoRotate& other); - virtual ~GLGizmoRotate(); + virtual ~GLGizmoRotate() = default; double get_angle() const { return m_angle; } void set_angle(double angle); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index 7ff274aac..ac63d6b72 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -26,20 +26,9 @@ namespace GUI { GLGizmoSlaSupports::GLGizmoSlaSupports(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) : GLGizmoBase(parent, icon_filename, sprite_id) - , m_quadric(nullptr) -{ - m_quadric = ::gluNewQuadric(); - if (m_quadric != nullptr) - // using GLU_FILL does not work when the instance's transformation - // contains mirroring (normals are reverted) - ::gluQuadricDrawStyle(m_quadric, GLU_FILL); +{ } -GLGizmoSlaSupports::~GLGizmoSlaSupports() -{ - if (m_quadric != nullptr) - ::gluDeleteQuadric(m_quadric); -} bool GLGizmoSlaSupports::on_init() { @@ -100,7 +89,7 @@ void GLGizmoSlaSupports::on_render() const glsafe(::glEnable(GL_BLEND)); glsafe(::glEnable(GL_DEPTH_TEST)); - if (m_quadric != nullptr && selection.is_from_single_instance()) + if (selection.is_from_single_instance()) render_points(selection, false); m_selection_rectangle.render(m_parent); @@ -114,14 +103,25 @@ void GLGizmoSlaSupports::on_render() const void GLGizmoSlaSupports::on_render_for_picking() const { const Selection& selection = m_parent.get_selection(); - glsafe(::glEnable(GL_DEPTH_TEST)); + //glsafe(::glEnable(GL_DEPTH_TEST)); render_points(selection, true); } void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) const { - if (!picking) - glsafe(::glEnable(GL_LIGHTING)); + size_t cache_size = m_editing_mode ? m_editing_cache.size() : m_normal_cache.size(); + + bool has_points = (cache_size != 0); + bool has_holes = (! m_c->hollowed_mesh()->get_hollowed_mesh() + && ! m_c->selection_info()->model_object()->sla_drain_holes.empty()); + + if (! has_points && ! has_holes) + return; + + GLShaderProgram* shader = picking ? nullptr : wxGetApp().get_shader("gouraud_light"); + if (shader) + shader->start_using(); + ScopeGuard guard([shader]() { if (shader) shader->stop_using(); }); const GLVolume* vol = selection.get_volume(*selection.get_volume_idxs().begin()); const Transform3d& instance_scaling_matrix_inverse = vol->get_instance_transformation().get_matrix(true, true, false, true).inverse(); @@ -132,8 +132,7 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) glsafe(::glTranslated(0.0, 0.0, z_shift)); glsafe(::glMultMatrixd(instance_matrix.data())); - float render_color[4]; - size_t cache_size = m_editing_mode ? m_editing_cache.size() : m_normal_cache.size(); + std::array render_color; for (size_t i = 0; i < cache_size; ++i) { const sla::SupportPoint& support_point = m_editing_mode ? m_editing_cache[i].support_point : m_normal_cache[i]; @@ -143,34 +142,31 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) continue; // First decide about the color of the point. - if (picking) { - std::array color = picking_color_component(i); - render_color[0] = color[0]; - render_color[1] = color[1]; - render_color[2] = color[2]; - render_color[3] = color[3]; - } + if (picking) + render_color = picking_color_component(i); else { - render_color[3] = 1.f; - if ((size_t(m_hover_id) == i && m_editing_mode)) { // ignore hover state unless editing mode is active - render_color[0] = 0.f; - render_color[1] = 1.0f; - render_color[2] = 1.0f; - } + if ((size_t(m_hover_id) == i && m_editing_mode)) // ignore hover state unless editing mode is active + render_color = { 0.f, 1.f, 1.f, 1.f }; else { // neigher hover nor picking bool supports_new_island = m_lock_unique_islands && support_point.is_new_island; if (m_editing_mode) { - render_color[0] = point_selected ? 1.0f : (supports_new_island ? 0.3f : 0.7f); - render_color[1] = point_selected ? 0.3f : (supports_new_island ? 0.3f : 0.7f); - render_color[2] = point_selected ? 0.3f : (supports_new_island ? 1.0f : 0.7f); + if (point_selected) + render_color = { 1.f, 0.3f, 0.3f, 1.f}; + else + if (supports_new_island) + render_color = { 0.3f, 0.3f, 1.f, 1.f }; + else + render_color = { 0.7f, 0.7f, 0.7f, 1.f }; } else - for (unsigned char i=0; i<3; ++i) render_color[i] = 0.5f; + render_color = { 0.5f, 0.5f, 0.5f, 1.f }; } } - glsafe(::glColor4fv(render_color)); - float render_color_emissive[4] = { 0.5f * render_color[0], 0.5f * render_color[1], 0.5f * render_color[2], 1.f}; - glsafe(::glMaterialfv(GL_FRONT, GL_EMISSION, render_color_emissive)); + if (shader && ! picking) + shader->set_uniform("uniform_color", render_color); + else // picking + glsafe(::glColor4fv(render_color.data())); + // Inverse matrix of the instance scaling is applied so that the mark does not scale with the object. glsafe(::glPushMatrix()); @@ -195,33 +191,36 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) const double cone_radius = 0.25; // mm const double cone_height = 0.75; glsafe(::glPushMatrix()); - glsafe(::glTranslatef(0.f, 0.f, support_point.head_front_radius * RenderPointScale)); - ::gluCylinder(m_quadric, 0., cone_radius, cone_height, 24, 1); + glsafe(::glTranslatef(0.f, 0.f, cone_height + support_point.head_front_radius * RenderPointScale)); + glsafe(::glPushMatrix()); + glsafe(::glRotated(180., 1., 0., 0.)); + glsafe(::glScaled(cone_radius, cone_radius, cone_height)); + VBOCone.render(); + glsafe(::glPopMatrix()); glsafe(::glTranslatef(0.f, 0.f, cone_height)); - ::gluDisk(m_quadric, 0.0, cone_radius, 24, 1); glsafe(::glPopMatrix()); } - ::gluSphere(m_quadric, (double)support_point.head_front_radius * RenderPointScale, 24, 12); + + glsafe(::glPushMatrix()); + double radius = (double)support_point.head_front_radius * RenderPointScale; + glsafe(::glScaled(radius, radius, radius)); + VBOSphere.render(); + glsafe(::glPopMatrix()); + if (vol->is_left_handed()) glFrontFace(GL_CCW); glsafe(::glPopMatrix()); } - { - // Reset emissive component to zero (the default value) - float render_color_emissive[4] = { 0.f, 0.f, 0.f, 1.f }; - glsafe(::glMaterialfv(GL_FRONT, GL_EMISSION, render_color_emissive)); - } - // Now render the drain holes: - //if (! m_c->has_drilled_mesh()) { - if (! m_c->hollowed_mesh()->get_hollowed_mesh()) { + if (has_holes && ! picking) { render_color[0] = 0.7f; render_color[1] = 0.7f; render_color[2] = 0.7f; render_color[3] = 0.7f; - glsafe(::glColor4fv(render_color)); + if (shader) + shader->set_uniform("uniform_color", render_color); 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; @@ -242,12 +241,8 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) glsafe(::glRotated(aa.angle() * (180. / M_PI), aa.axis()(0), aa.axis()(1), aa.axis()(2))); glsafe(::glPushMatrix()); glsafe(::glTranslated(0., 0., -drain_hole.height)); - ::gluCylinder(m_quadric, drain_hole.radius, drain_hole.radius, drain_hole.height + sla::HoleStickOutLength, 24, 1); - glsafe(::glTranslated(0., 0., drain_hole.height + sla::HoleStickOutLength)); - ::gluDisk(m_quadric, 0.0, drain_hole.radius, 24, 1); - glsafe(::glTranslated(0., 0., -drain_hole.height - sla::HoleStickOutLength)); - glsafe(::glRotatef(180.f, 1.f, 0.f, 0.f)); - ::gluDisk(m_quadric, 0.0, drain_hole.radius, 24, 1); + glsafe(::glScaled(drain_hole.radius, drain_hole.radius, drain_hole.height + sla::HoleStickOutLength)); + VBOCylinder.render(); glsafe(::glPopMatrix()); if (vol->is_left_handed()) @@ -256,9 +251,6 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) } } - if (!picking) - glsafe(::glDisable(GL_LIGHTING)); - glsafe(::glPopMatrix()); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp index f9cf2f935..1859dbfd1 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp @@ -27,8 +27,6 @@ private: const float RenderPointScale = 1.f; - GLUquadricObj* m_quadric; - class CacheEntry { public: CacheEntry() : @@ -58,7 +56,7 @@ private: public: GLGizmoSlaSupports(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id); - ~GLGizmoSlaSupports() override; + virtual ~GLGizmoSlaSupports() = default; void set_sla_support_data(ModelObject* model_object, const Selection& selection); bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down); void delete_selected_points(bool force = false); From fd024eadcd1a48907f76c09136bfe450a88a73ff Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Fri, 9 Apr 2021 19:55:03 +0200 Subject: [PATCH 19/31] Removed gluProject and gluUnProject calls --- src/libslic3r/Point.hpp | 4 ++++ src/slic3r/GUI/GLCanvas3D.cpp | 14 +++++++------ src/slic3r/GUI/GLSelectionRectangle.cpp | 26 ++++++++++++++----------- src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp | 8 -------- src/slic3r/GUI/MeshUtils.cpp | 14 ++++++++----- 5 files changed, 36 insertions(+), 30 deletions(-) diff --git a/src/libslic3r/Point.hpp b/src/libslic3r/Point.hpp index e5ce68420..ceb235244 100644 --- a/src/libslic3r/Point.hpp +++ b/src/libslic3r/Point.hpp @@ -27,6 +27,7 @@ using Vec2crd = Eigen::Matrix; using Vec3crd = Eigen::Matrix; using Vec2i = Eigen::Matrix; using Vec3i = Eigen::Matrix; +using Vec4i = Eigen::Matrix; using Vec2i32 = Eigen::Matrix; using Vec2i64 = Eigen::Matrix; using Vec3i32 = Eigen::Matrix; @@ -50,12 +51,15 @@ using Matrix2f = Eigen::Matrix; using Matrix2d = Eigen::Matrix; using Matrix3f = Eigen::Matrix; using Matrix3d = Eigen::Matrix; +using Matrix4f = Eigen::Matrix; +using Matrix4d = Eigen::Matrix; using Transform2f = Eigen::Transform; using Transform2d = Eigen::Transform; using Transform3f = Eigen::Transform; using Transform3d = Eigen::Transform; + inline bool operator<(const Vec2d &lhs, const Vec2d &rhs) { return lhs(0) < rhs(0) || (lhs(0) == rhs(0) && lhs(1) < rhs(1)); } template diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index eaa4c7f0d..880e69bbd 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1,6 +1,8 @@ #include "libslic3r/libslic3r.h" #include "GLCanvas3D.hpp" +#include + #include "libslic3r/ClipperUtils.hpp" #include "libslic3r/PrintConfig.hpp" #include "libslic3r/GCode/ThumbnailData.hpp" @@ -5391,9 +5393,9 @@ Vec3d GLCanvas3D::_mouse_to_3d(const Point& mouse_pos, float* z) return Vec3d(DBL_MAX, DBL_MAX, DBL_MAX); const Camera& camera = wxGetApp().plater()->get_camera(); - const std::array& viewport = camera.get_viewport(); - const Transform3d& modelview_matrix = camera.get_view_matrix(); - const Transform3d& projection_matrix = camera.get_projection_matrix(); + Matrix4d modelview = camera.get_view_matrix().matrix(); + Matrix4d projection= camera.get_projection_matrix().matrix(); + Vec4i viewport(camera.get_viewport().data()); GLint y = viewport[3] - (GLint)mouse_pos(1); GLfloat mouse_z; @@ -5402,9 +5404,9 @@ Vec3d GLCanvas3D::_mouse_to_3d(const Point& mouse_pos, float* z) else mouse_z = *z; - GLdouble out_x, out_y, out_z; - ::gluUnProject((GLdouble)mouse_pos(0), (GLdouble)y, (GLdouble)mouse_z, (GLdouble*)modelview_matrix.data(), (GLdouble*)projection_matrix.data(), (GLint*)viewport.data(), &out_x, &out_y, &out_z); - return Vec3d((double)out_x, (double)out_y, (double)out_z); + Vec3d out; + igl::unproject(Vec3d(mouse_pos(0), y, mouse_z), modelview, projection, viewport, out); + return out; } Vec3d GLCanvas3D::_mouse_to_bed_3d(const Point& mouse_pos) diff --git a/src/slic3r/GUI/GLSelectionRectangle.cpp b/src/slic3r/GUI/GLSelectionRectangle.cpp index d7f3f7a3a..13467499a 100644 --- a/src/slic3r/GUI/GLSelectionRectangle.cpp +++ b/src/slic3r/GUI/GLSelectionRectangle.cpp @@ -4,6 +4,7 @@ #include "GLCanvas3D.hpp" #include "GUI_App.hpp" #include "Plater.hpp" +#include #include @@ -38,23 +39,26 @@ namespace GUI { m_state = Off; const Camera& camera = wxGetApp().plater()->get_camera(); - const std::array& viewport = camera.get_viewport(); - const Transform3d& modelview_matrix = camera.get_view_matrix(); - const Transform3d& projection_matrix = camera.get_projection_matrix(); + Matrix4d modelview = camera.get_view_matrix().matrix(); + Matrix4d projection= camera.get_projection_matrix().matrix(); + Vec4i viewport(camera.get_viewport().data()); + + // Convert our std::vector to Eigen dynamic matrix. + Eigen::Matrix pts(points.size(), 3); + for (size_t i=0; i(i, 0) = points[i]; + + // Get the projections. + Eigen::Matrix projections; + igl::project(pts, modelview, projection, viewport, projections); // bounding box created from the rectangle corners - will take care of order of the corners BoundingBox rectangle(Points{ Point(m_start_corner.cast()), Point(m_end_corner.cast()) }); // Iterate over all points and determine whether they're in the rectangle. - for (unsigned int i = 0; i +#include + namespace Slic3r { namespace GUI { @@ -122,14 +124,16 @@ Vec3f MeshRaycaster::get_triangle_normal(size_t facet_idx) const void MeshRaycaster::line_from_mouse_pos(const Vec2d& mouse_pos, const Transform3d& trafo, const Camera& camera, Vec3d& point, Vec3d& direction) const { - const std::array& viewport = camera.get_viewport(); - const Transform3d& model_mat = camera.get_view_matrix(); - const Transform3d& proj_mat = camera.get_projection_matrix(); + Matrix4d modelview = camera.get_view_matrix().matrix(); + Matrix4d projection= camera.get_projection_matrix().matrix(); + Vec4i viewport(camera.get_viewport().data()); Vec3d pt1; Vec3d pt2; - ::gluUnProject(mouse_pos(0), viewport[3] - mouse_pos(1), 0., model_mat.data(), proj_mat.data(), viewport.data(), &pt1(0), &pt1(1), &pt1(2)); - ::gluUnProject(mouse_pos(0), viewport[3] - mouse_pos(1), 1., model_mat.data(), proj_mat.data(), viewport.data(), &pt2(0), &pt2(1), &pt2(2)); + igl::unproject(Vec3d(mouse_pos(0), viewport[3] - mouse_pos(1), 0.), + modelview, projection, viewport, pt1); + igl::unproject(Vec3d(mouse_pos(0), viewport[3] - mouse_pos(1), 1.), + modelview, projection, viewport, pt2); Transform3d inv = trafo.inverse(); pt1 = inv * pt1; From 846afdf7f3e9148fa36133c4c9d1d138930055a4 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Fri, 9 Apr 2021 20:43:21 +0200 Subject: [PATCH 20/31] Removed last GLU call, removed libGLU from CMakeLists --- src/slic3r/CMakeLists.txt | 2 +- src/slic3r/GUI/Selection.cpp | 20 +++++++------------- src/slic3r/GUI/Selection.hpp | 10 +--------- 3 files changed, 9 insertions(+), 23 deletions(-) diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index aa3bf01c4..caccec5d7 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -240,7 +240,7 @@ add_library(libslic3r_gui STATIC ${SLIC3R_GUI_SOURCES}) encoding_check(libslic3r_gui) -target_link_libraries(libslic3r_gui libslic3r avrdude cereal imgui GLEW::GLEW OpenGL::GL OpenGL::GLU hidapi libcurl ${wxWidgets_LIBRARIES}) +target_link_libraries(libslic3r_gui libslic3r avrdude cereal imgui GLEW::GLEW OpenGL::GL hidapi libcurl ${wxWidgets_LIBRARIES}) if (CMAKE_SYSTEM_NAME STREQUAL "Linux") target_link_libraries(libslic3r_gui ${DBUS_LIBRARIES}) diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 5c34d7de0..5fe6c2c17 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -115,20 +115,8 @@ Selection::Selection() , m_scale_factor(1.0f) { this->set_bounding_boxes_dirty(); -#if ENABLE_RENDER_SELECTION_CENTER - m_quadric = ::gluNewQuadric(); - if (m_quadric != nullptr) - ::gluQuadricDrawStyle(m_quadric, GLU_FILL); -#endif // ENABLE_RENDER_SELECTION_CENTER } -#if ENABLE_RENDER_SELECTION_CENTER -Selection::~Selection() -{ - if (m_quadric != nullptr) - ::gluDeleteQuadric(m_quadric); -} -#endif // ENABLE_RENDER_SELECTION_CENTER void Selection::set_volumes(GLVolumePtrs* volumes) { @@ -141,6 +129,11 @@ bool Selection::init() { m_arrow.init_from(straight_arrow(10.0f, 5.0f, 5.0f, 10.0f, 1.0f)); m_curved_arrow.init_from(circular_arrow(16, 10.0f, 5.0f, 10.0f, 5.0f, 1.0f)); + +#if ENABLE_RENDER_SELECTION_CENTER + m_vbo_sphere.init_from(make_sphere(0.75, 2*PI/24)); +#endif // ENABLE_RENDER_SELECTION_CENTER + return true; } @@ -1177,6 +1170,7 @@ void Selection::render(float scale_factor) const void Selection::render_center(bool gizmo_is_dragging) const { if (!m_valid || is_empty() || m_quadric == nullptr) + if (!m_valid || is_empty()) return; const Vec3d center = gizmo_is_dragging ? m_cache.dragging_center : get_bounding_box().center(); @@ -1188,7 +1182,7 @@ void Selection::render_center(bool gizmo_is_dragging) const glsafe(::glColor3f(1.0f, 1.0f, 1.0f)); glsafe(::glPushMatrix()); glsafe(::glTranslated(center(0), center(1), center(2))); - glsafe(::gluSphere(m_quadric, 0.75, 32, 32)); + m_vbo_sphere.render(); glsafe(::glPopMatrix()); glsafe(::glDisable(GL_LIGHTING)); diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index c28a6e867..ae82f9ca7 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -5,11 +5,6 @@ #include "libslic3r/Geometry.hpp" #include "GLModel.hpp" -#if ENABLE_RENDER_SELECTION_CENTER -class GLUquadric; -typedef class GLUquadric GLUquadricObj; -#endif // ENABLE_RENDER_SELECTION_CENTER - namespace Slic3r { class Shader; @@ -216,7 +211,7 @@ private: bool m_scaled_instance_bounding_box_dirty; #if ENABLE_RENDER_SELECTION_CENTER - GLUquadricObj* m_quadric; + GLModel m_vbo_sphere; #endif // ENABLE_RENDER_SELECTION_CENTER GLModel m_arrow; @@ -226,9 +221,6 @@ private: public: Selection(); -#if ENABLE_RENDER_SELECTION_CENTER - ~Selection(); -#endif // ENABLE_RENDER_SELECTION_CENTER void set_volumes(GLVolumePtrs* volumes); bool init(); From 2e24e689fa7385cb501ea6dd27fca51a121cfdff Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Mon, 12 Apr 2021 09:13:05 +0200 Subject: [PATCH 21/31] Grabbers and support points appearence tweaking, some refactoring --- resources/shaders/gouraud_light.fs | 3 +- src/slic3r/GUI/Gizmos/GLGizmoBase.cpp | 41 +++++++++++--------- src/slic3r/GUI/Gizmos/GLGizmoBase.hpp | 9 ++--- src/slic3r/GUI/Gizmos/GLGizmoCut.cpp | 2 +- src/slic3r/GUI/Gizmos/GLGizmoMove.cpp | 11 +++--- src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp | 7 ++-- src/slic3r/GUI/Gizmos/GLGizmoScale.cpp | 26 ++++++------- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp | 15 +++++-- 8 files changed, 62 insertions(+), 52 deletions(-) diff --git a/resources/shaders/gouraud_light.fs b/resources/shaders/gouraud_light.fs index 1a58abc85..970185a00 100644 --- a/resources/shaders/gouraud_light.fs +++ b/resources/shaders/gouraud_light.fs @@ -1,11 +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, intensity.y, intensity.y) + uniform_color.rgb * intensity.x, uniform_color.a); + gl_FragColor = vec4(vec3(intensity.y) + uniform_color.rgb * (intensity.x + emission_factor), uniform_color.a); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp index ca9b2408c..b018c0829 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp @@ -24,10 +24,7 @@ GLGizmoBase::Grabber::Grabber() , dragging(false) , enabled(true) { - color[0] = 1.0f; - color[1] = 1.0f; - color[2] = 1.0f; - color[3] = 1.0f; + color = { 1.0f, 1.0f, 1.0f, 1.0f }; TriangleMesh cube = make_cube(1., 1., 1.); cube.translate(Vec3f(-0.5, -0.5, -0.5)); VBOCube.init_from(cube); @@ -35,18 +32,18 @@ GLGizmoBase::Grabber::Grabber() void GLGizmoBase::Grabber::render(bool hover, float size) const { - float render_color[4]; + std::array render_color; if (hover) { - render_color[0] = 1.0f - color[0]; - render_color[1] = 1.0f - color[1]; - render_color[2] = 1.0f - color[2]; + render_color[0] = (1.0f - color[0]); + render_color[1] = (1.0f - color[1]); + render_color[2] = (1.0f - color[2]); render_color[3] = color[3]; } else - ::memcpy((void*)render_color, (const void*)color, 4 * sizeof(float)); + render_color = color; - render(size, render_color, true); + render(size, render_color, false); } float GLGizmoBase::Grabber::get_half_size(float size) const @@ -59,14 +56,18 @@ float GLGizmoBase::Grabber::get_dragging_half_size(float size) const return get_half_size(size) * DraggingScaleFactor; } -void GLGizmoBase::Grabber::render(float size, const float* render_color, bool use_lighting) const +void GLGizmoBase::Grabber::render(float size, const std::array& render_color, bool picking) const { float fullsize = 2 * (dragging ? get_dragging_half_size(size) : get_half_size(size)); - if (use_lighting) + if (! picking) glsafe(::glEnable(GL_LIGHTING)); - glsafe(::glColor4fv(render_color)); + GLShaderProgram* shader = picking ? nullptr : wxGetApp().get_current_shader(); + if (shader) + shader->set_uniform("uniform_color", render_color); + else + glsafe(::glColor4fv(render_color.data())); // picking glsafe(::glPushMatrix()); glsafe(::glTranslated(center(0), center(1), center(2))); @@ -77,7 +78,7 @@ void GLGizmoBase::Grabber::render(float size, const float* render_color, bool us VBOCube.render(); glsafe(::glPopMatrix()); - if (use_lighting) + if (! picking) glsafe(::glDisable(GL_LIGHTING)); } @@ -188,11 +189,18 @@ void GLGizmoBase::render_grabbers(const BoundingBoxf3& box) const void GLGizmoBase::render_grabbers(float size) const { + GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); + if (! shader) + return; + shader->start_using(); + shader->set_uniform("emission_factor", 0.1); for (int i = 0; i < (int)m_grabbers.size(); ++i) { if (m_grabbers[i].enabled) m_grabbers[i].render((m_hover_id == i), size); } + shader->set_uniform("emission_factor", 0.); + shader->stop_using(); } void GLGizmoBase::render_grabbers_for_picking(const BoundingBoxf3& box) const @@ -204,10 +212,7 @@ void GLGizmoBase::render_grabbers_for_picking(const BoundingBoxf3& box) const if (m_grabbers[i].enabled) { std::array color = picking_color_component(i); - m_grabbers[i].color[0] = color[0]; - m_grabbers[i].color[1] = color[1]; - m_grabbers[i].color[2] = color[2]; - m_grabbers[i].color[3] = color[3]; + m_grabbers[i].color = color; m_grabbers[i].render_for_picking(mean_size); } } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp index b49619470..7fdae1598 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp @@ -9,9 +9,6 @@ #include class wxWindow; -class GLUquadric; -typedef class GLUquadric GLUquadricObj; - namespace Slic3r { @@ -53,20 +50,20 @@ protected: Vec3d center; Vec3d angles; - float color[4]; + std::array color; bool enabled; bool dragging; Grabber(); void render(bool hover, float size) const; - void render_for_picking(float size) const { render(size, color, false); } + void render_for_picking(float size) const { render(size, color, true); } float get_half_size(float size) const; float get_dragging_half_size(float size) const; private: - void render(float size, const float* render_color, bool use_lighting) const; + void render(float size, const std::array& render_color, bool picking) const; }; public: diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index d43b0f24e..ffa389bb2 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -133,7 +133,7 @@ void GLGizmoCut::on_render() const ::glVertex3dv(m_grabbers[0].center.data()); glsafe(::glEnd()); - std::copy(std::begin(GrabberColor), std::end(GrabberColor), m_grabbers[0].color); + m_grabbers[0].color = GrabberColor; m_grabbers[0].render(m_hover_id == 0, (float)((box.size()(0) + box.size()(1) + box.size()(2)) / 3.0)); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp index 0b65982b7..2385b5e5d 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp @@ -100,15 +100,15 @@ void GLGizmoMove3D::on_render() const // x axis m_grabbers[0].center = Vec3d(box.max(0) + Offset, center(1), center(2)); - ::memcpy((void*)m_grabbers[0].color, (const void*)&AXES_COLOR[0], 4 * sizeof(float)); + ::memcpy((void*)m_grabbers[0].color.data(), (const void*)&AXES_COLOR[0], 4 * sizeof(float)); // y axis m_grabbers[1].center = Vec3d(center(0), box.max(1) + Offset, center(2)); - ::memcpy((void*)m_grabbers[1].color, (const void*)&AXES_COLOR[1], 4 * sizeof(float)); + ::memcpy((void*)m_grabbers[1].color.data(), (const void*)&AXES_COLOR[1], 4 * sizeof(float)); // z axis m_grabbers[2].center = Vec3d(center(0), center(1), box.max(2) + Offset); - ::memcpy((void*)m_grabbers[2].color, (const void*)&AXES_COLOR[2], 4 * sizeof(float)); + ::memcpy((void*)m_grabbers[2].color.data(), (const void*)&AXES_COLOR[2], 4 * sizeof(float)); glsafe(::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f)); @@ -194,8 +194,7 @@ void GLGizmoMove3D::render_grabber_extension(Axis axis, const BoundingBoxf3& box float mean_size = (float)((box.size()(0) + box.size()(1) + box.size()(2)) / 3.0); double size = m_dragging ? (double)m_grabbers[axis].get_dragging_half_size(mean_size) : (double)m_grabbers[axis].get_half_size(mean_size); - float color[4]; - ::memcpy((void*)color, (const void*)m_grabbers[axis].color, 4 * sizeof(float)); + std::array color = m_grabbers[axis].color; if (!picking && (m_hover_id != -1)) { color[0] = 1.0f - color[0]; @@ -207,7 +206,7 @@ void GLGizmoMove3D::render_grabber_extension(Axis axis, const BoundingBoxf3& box if (!picking) glsafe(::glEnable(GL_LIGHTING)); - glsafe(::glColor4fv(color)); + glsafe(::glColor4fv(color.data())); glsafe(::glPushMatrix()); glsafe(::glTranslated(m_grabbers[axis].center(0), m_grabbers[axis].center(1), m_grabbers[axis].center(2))); if (axis == X) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp index eb026a8e8..758ab7529 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp @@ -318,7 +318,7 @@ void GLGizmoRotate::render_grabber(const BoundingBoxf3& box) const ::glVertex3dv(m_grabbers[0].center.data()); glsafe(::glEnd()); - ::memcpy((void*)m_grabbers[0].color, (const void*)m_highlight_color, 4 * sizeof(float)); + ::memcpy((void*)m_grabbers[0].color.data(), (const void*)m_highlight_color, 4 * sizeof(float)); render_grabbers(box); } @@ -327,8 +327,7 @@ void GLGizmoRotate::render_grabber_extension(const BoundingBoxf3& box, bool pick float mean_size = (float)((box.size()(0) + box.size()(1) + box.size()(2)) / 3.0); double size = m_dragging ? (double)m_grabbers[0].get_dragging_half_size(mean_size) : (double)m_grabbers[0].get_half_size(mean_size); - float color[4]; - ::memcpy((void*)color, (const void*)m_grabbers[0].color, 4 * sizeof(float)); + std::array color = m_grabbers[0].color; if (!picking && (m_hover_id != -1)) { color[0] = 1.0f - color[0]; @@ -339,7 +338,7 @@ void GLGizmoRotate::render_grabber_extension(const BoundingBoxf3& box, bool pick if (!picking) glsafe(::glEnable(GL_LIGHTING)); - glsafe(::glColor4fv(color)); + glsafe(::glColor4fv(color.data())); glsafe(::glPushMatrix()); glsafe(::glTranslated(m_grabbers[0].center(0), m_grabbers[0].center(1), m_grabbers[0].center(2))); glsafe(::glRotated(Geometry::rad2deg(m_angle), 0.0, 0.0, 1.0)); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp b/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp index fa2069d0a..425b53f85 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp @@ -173,20 +173,20 @@ void GLGizmoScale3D::on_render() const // x axis m_grabbers[0].center = m_transform * Vec3d(m_box.min(0), center(1), center(2)) - offset_x; m_grabbers[1].center = m_transform * Vec3d(m_box.max(0), center(1), center(2)) + offset_x; - ::memcpy((void*)m_grabbers[0].color, (ctrl_down && (m_hover_id == 1)) ? (const void*)CONSTRAINED_COLOR : (const void*)&AXES_COLOR[0], 4 * sizeof(float)); - ::memcpy((void*)m_grabbers[1].color, (ctrl_down && (m_hover_id == 0)) ? (const void*)CONSTRAINED_COLOR : (const void*)&AXES_COLOR[0], 4 * sizeof(float)); + ::memcpy((void*)m_grabbers[0].color.data(), (ctrl_down && (m_hover_id == 1)) ? (const void*)CONSTRAINED_COLOR : (const void*)&AXES_COLOR[0], 4 * sizeof(float)); + ::memcpy((void*)m_grabbers[1].color.data(), (ctrl_down && (m_hover_id == 0)) ? (const void*)CONSTRAINED_COLOR : (const void*)&AXES_COLOR[0], 4 * sizeof(float)); // y axis m_grabbers[2].center = m_transform * Vec3d(center(0), m_box.min(1), center(2)) - offset_y; m_grabbers[3].center = m_transform * Vec3d(center(0), m_box.max(1), center(2)) + offset_y; - ::memcpy((void*)m_grabbers[2].color, (ctrl_down && (m_hover_id == 3)) ? (const void*)CONSTRAINED_COLOR : (const void*)&AXES_COLOR[1], 4 * sizeof(float)); - ::memcpy((void*)m_grabbers[3].color, (ctrl_down && (m_hover_id == 2)) ? (const void*)CONSTRAINED_COLOR : (const void*)&AXES_COLOR[1], 4 * sizeof(float)); + ::memcpy((void*)m_grabbers[2].color.data(), (ctrl_down && (m_hover_id == 3)) ? (const void*)CONSTRAINED_COLOR : (const void*)&AXES_COLOR[1], 4 * sizeof(float)); + ::memcpy((void*)m_grabbers[3].color.data(), (ctrl_down && (m_hover_id == 2)) ? (const void*)CONSTRAINED_COLOR : (const void*)&AXES_COLOR[1], 4 * sizeof(float)); // z axis m_grabbers[4].center = m_transform * Vec3d(center(0), center(1), m_box.min(2)) - offset_z; m_grabbers[5].center = m_transform * Vec3d(center(0), center(1), m_box.max(2)) + offset_z; - ::memcpy((void*)m_grabbers[4].color, (ctrl_down && (m_hover_id == 5)) ? (const void*)CONSTRAINED_COLOR : (const void*)&AXES_COLOR[2], 4 * sizeof(float)); - ::memcpy((void*)m_grabbers[5].color, (ctrl_down && (m_hover_id == 4)) ? (const void*)CONSTRAINED_COLOR : (const void*)&AXES_COLOR[2], 4 * sizeof(float)); + ::memcpy((void*)m_grabbers[4].color.data(), (ctrl_down && (m_hover_id == 5)) ? (const void*)CONSTRAINED_COLOR : (const void*)&AXES_COLOR[2], 4 * sizeof(float)); + ::memcpy((void*)m_grabbers[5].color.data(), (ctrl_down && (m_hover_id == 4)) ? (const void*)CONSTRAINED_COLOR : (const void*)&AXES_COLOR[2], 4 * sizeof(float)); // uniform m_grabbers[6].center = m_transform * Vec3d(m_box.min(0), m_box.min(1), center(2)) - offset_x - offset_y; @@ -195,7 +195,7 @@ void GLGizmoScale3D::on_render() const m_grabbers[9].center = m_transform * Vec3d(m_box.min(0), m_box.max(1), center(2)) - offset_x + offset_y; for (int i = 6; i < 10; ++i) { - ::memcpy((void*)m_grabbers[i].color, (const void*)m_highlight_color, 4 * sizeof(float)); + ::memcpy((void*)m_grabbers[i].color.data(), (const void*)m_highlight_color, 4 * sizeof(float)); } // sets grabbers orientation @@ -215,17 +215,17 @@ void GLGizmoScale3D::on_render() const // draw connections if (m_grabbers[0].enabled && m_grabbers[1].enabled) { - glsafe(::glColor4fv(m_grabbers[0].color)); + glsafe(::glColor4fv(m_grabbers[0].color.data())); render_grabbers_connection(0, 1); } if (m_grabbers[2].enabled && m_grabbers[3].enabled) { - glsafe(::glColor4fv(m_grabbers[2].color)); + glsafe(::glColor4fv(m_grabbers[2].color.data())); render_grabbers_connection(2, 3); } if (m_grabbers[4].enabled && m_grabbers[5].enabled) { - glsafe(::glColor4fv(m_grabbers[4].color)); + glsafe(::glColor4fv(m_grabbers[4].color.data())); render_grabbers_connection(4, 5); } glsafe(::glColor4fv(m_base_color)); @@ -239,7 +239,7 @@ void GLGizmoScale3D::on_render() const else if ((m_hover_id == 0) || (m_hover_id == 1)) { // draw connection - glsafe(::glColor4fv(m_grabbers[0].color)); + glsafe(::glColor4fv(m_grabbers[0].color.data())); render_grabbers_connection(0, 1); // draw grabbers m_grabbers[0].render(true, grabber_mean_size); @@ -248,7 +248,7 @@ void GLGizmoScale3D::on_render() const else if ((m_hover_id == 2) || (m_hover_id == 3)) { // draw connection - glsafe(::glColor4fv(m_grabbers[2].color)); + glsafe(::glColor4fv(m_grabbers[2].color.data())); render_grabbers_connection(2, 3); // draw grabbers m_grabbers[2].render(true, grabber_mean_size); @@ -257,7 +257,7 @@ void GLGizmoScale3D::on_render() const else if ((m_hover_id == 4) || (m_hover_id == 5)) { // draw connection - glsafe(::glColor4fv(m_grabbers[4].color)); + glsafe(::glColor4fv(m_grabbers[4].color.data())); render_grabbers_connection(4, 5); // draw grabbers m_grabbers[4].render(true, grabber_mean_size); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index ac63d6b72..68fd3a6c0 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -121,7 +121,12 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) GLShaderProgram* shader = picking ? nullptr : wxGetApp().get_shader("gouraud_light"); if (shader) shader->start_using(); - ScopeGuard guard([shader]() { if (shader) shader->stop_using(); }); + ScopeGuard guard([shader]() { + if (shader) { + shader->set_uniform("emission_factor", 0.); + shader->stop_using(); + } + }); const GLVolume* vol = selection.get_volume(*selection.get_volume_idxs().begin()); const Transform3d& instance_scaling_matrix_inverse = vol->get_instance_transformation().get_matrix(true, true, false, true).inverse(); @@ -162,8 +167,10 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) render_color = { 0.5f, 0.5f, 0.5f, 1.f }; } } - if (shader && ! picking) + if (shader && ! picking) { shader->set_uniform("uniform_color", render_color); + shader->set_uniform("emission_factor", 0.5); + } else // picking glsafe(::glColor4fv(render_color.data())); @@ -219,8 +226,10 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) render_color[1] = 0.7f; render_color[2] = 0.7f; render_color[3] = 0.7f; - if (shader) + if (shader) { shader->set_uniform("uniform_color", render_color); + shader->set_uniform("emission_factor", 0.5); + } 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; From b63de990d46c8ea1d5f9c24aba634ff37d252790 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 25 May 2021 11:09:39 +0200 Subject: [PATCH 22/31] Removed static members from GLGizmoBase and GLGizmoBase::Grabber to fix OpenGL error when closing the application --- src/slic3r/GUI/Gizmos/GLGizmoBase.cpp | 18 +++++++----------- src/slic3r/GUI/Gizmos/GLGizmoBase.hpp | 9 ++++----- src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp | 4 ++-- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp | 6 +++--- 4 files changed, 16 insertions(+), 21 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp index b018c0829..8e7c4398e 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp @@ -13,10 +13,6 @@ namespace GUI { const float GLGizmoBase::Grabber::SizeFactor = 0.05f; const float GLGizmoBase::Grabber::MinHalfSize = 1.5f; const float GLGizmoBase::Grabber::DraggingScaleFactor = 1.25f; -GLModel GLGizmoBase::Grabber::VBOCube; -GLModel GLGizmoBase::VBOCone; -GLModel GLGizmoBase::VBOCylinder; -GLModel GLGizmoBase::VBOSphere; GLGizmoBase::Grabber::Grabber() : center(Vec3d::Zero()) @@ -25,9 +21,9 @@ GLGizmoBase::Grabber::Grabber() , enabled(true) { color = { 1.0f, 1.0f, 1.0f, 1.0f }; - TriangleMesh cube = make_cube(1., 1., 1.); - cube.translate(Vec3f(-0.5, -0.5, -0.5)); - VBOCube.init_from(cube); + TriangleMesh mesh = make_cube(1., 1., 1.); + mesh.translate(Vec3f(-0.5, -0.5, -0.5)); + cube.init_from(mesh); } void GLGizmoBase::Grabber::render(bool hover, float size) const @@ -75,7 +71,7 @@ void GLGizmoBase::Grabber::render(float size, const std::array& render glsafe(::glRotated(Geometry::rad2deg(angles(1)), 0.0, 1.0, 0.0)); glsafe(::glRotated(Geometry::rad2deg(angles(0)), 1.0, 0.0, 0.0)); glsafe(::glScaled(fullsize, fullsize, fullsize)); - VBOCube.render(); + cube.render(); glsafe(::glPopMatrix()); if (! picking) @@ -98,9 +94,9 @@ GLGizmoBase::GLGizmoBase(GLCanvas3D& parent, const std::string& icon_filename, u ::memcpy((void*)m_base_color, (const void*)DEFAULT_BASE_COLOR, 4 * sizeof(float)); ::memcpy((void*)m_drag_color, (const void*)DEFAULT_DRAG_COLOR, 4 * sizeof(float)); ::memcpy((void*)m_highlight_color, (const void*)DEFAULT_HIGHLIGHT_COLOR, 4 * sizeof(float)); - VBOCone.init_from(make_cone(1., 1., 2*PI/24)); - VBOSphere.init_from(make_sphere(1., (2*M_PI)/24.)); - VBOCylinder.init_from(make_cylinder(1., 1., 2*PI/24.)); + m_cone.init_from(make_cone(1., 1., 2 * PI / 24)); + m_sphere.init_from(make_sphere(1., (2 * M_PI) / 24.)); + m_cylinder.init_from(make_cylinder(1., 1., 2 * PI / 24.)); } void GLGizmoBase::set_hover_id(int id) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp index 7fdae1598..eed393881 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp @@ -45,9 +45,8 @@ protected: static const float SizeFactor; static const float MinHalfSize; static const float DraggingScaleFactor; - static GLModel VBOCube; - static GLModel VBOCone; + GLModel cube; Vec3d center; Vec3d angles; std::array color; @@ -102,9 +101,9 @@ protected: bool m_first_input_window_render; mutable std::string m_tooltip; CommonGizmosDataPool* m_c; - static GLModel VBOCone; - static GLModel VBOCylinder; - static GLModel VBOSphere; + GLModel m_cone; + GLModel m_cylinder; + GLModel m_sphere; public: GLGizmoBase(GLCanvas3D& parent, diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp index 758ab7529..624cf2b2f 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp @@ -345,7 +345,7 @@ void GLGizmoRotate::render_grabber_extension(const BoundingBoxf3& box, bool pick glsafe(::glRotated(90.0, 1.0, 0.0, 0.0)); glsafe(::glTranslated(0.0, 0.0, 2.0 * size)); glsafe(::glScaled(0.75 * size, 0.75 * size, 3.0 * size)); - VBOCone.render(); + m_cone.render(); glsafe(::glPopMatrix()); glsafe(::glPushMatrix()); glsafe(::glTranslated(m_grabbers[0].center(0), m_grabbers[0].center(1), m_grabbers[0].center(2))); @@ -353,7 +353,7 @@ void GLGizmoRotate::render_grabber_extension(const BoundingBoxf3& box, bool pick glsafe(::glRotated(-90.0, 1.0, 0.0, 0.0)); glsafe(::glTranslated(0.0, 0.0, 2.0 * size)); glsafe(::glScaled(0.75 * size, 0.75 * size, 3.0 * size)); - VBOCone.render(); + m_cone.render(); glsafe(::glPopMatrix()); if (!picking) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index 68fd3a6c0..faeee499d 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -202,7 +202,7 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) glsafe(::glPushMatrix()); glsafe(::glRotated(180., 1., 0., 0.)); glsafe(::glScaled(cone_radius, cone_radius, cone_height)); - VBOCone.render(); + m_cone.render(); glsafe(::glPopMatrix()); glsafe(::glTranslatef(0.f, 0.f, cone_height)); glsafe(::glPopMatrix()); @@ -211,7 +211,7 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) glsafe(::glPushMatrix()); double radius = (double)support_point.head_front_radius * RenderPointScale; glsafe(::glScaled(radius, radius, radius)); - VBOSphere.render(); + m_sphere.render(); glsafe(::glPopMatrix()); if (vol->is_left_handed()) @@ -251,7 +251,7 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) glsafe(::glPushMatrix()); glsafe(::glTranslated(0., 0., -drain_hole.height)); glsafe(::glScaled(drain_hole.radius, drain_hole.radius, drain_hole.height + sla::HoleStickOutLength)); - VBOCylinder.render(); + m_cylinder.render(); glsafe(::glPopMatrix()); if (vol->is_left_handed()) From e6483689345cd7563c80321d56fb2b1b67abc7d3 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 25 May 2021 12:09:40 +0200 Subject: [PATCH 23/31] Removed unneeded calls to GL_LIGHTING --- src/slic3r/GUI/Gizmos/GLGizmoBase.cpp | 6 ------ src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp | 3 --- src/slic3r/GUI/Gizmos/GLGizmoMove.cpp | 6 ------ src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp | 6 ------ src/slic3r/GUI/Selection.cpp | 5 ----- 5 files changed, 26 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp index 8e7c4398e..cd05cba04 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp @@ -56,9 +56,6 @@ void GLGizmoBase::Grabber::render(float size, const std::array& render { float fullsize = 2 * (dragging ? get_dragging_half_size(size) : get_half_size(size)); - if (! picking) - glsafe(::glEnable(GL_LIGHTING)); - GLShaderProgram* shader = picking ? nullptr : wxGetApp().get_current_shader(); if (shader) shader->set_uniform("uniform_color", render_color); @@ -73,9 +70,6 @@ void GLGizmoBase::Grabber::render(float size, const std::array& render glsafe(::glScaled(fullsize, fullsize, fullsize)); cube.render(); glsafe(::glPopMatrix()); - - if (! picking) - glsafe(::glDisable(GL_LIGHTING)); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp index 515e0ea76..486d945ba 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp @@ -178,9 +178,6 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking) cons glsafe(::glPopMatrix()); } - //if (!picking) - // glsafe(::glDisable(GL_LIGHTING)); - glsafe(::glPopMatrix()); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp index 2385b5e5d..8e0cd1366 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp @@ -203,9 +203,6 @@ void GLGizmoMove3D::render_grabber_extension(Axis axis, const BoundingBoxf3& box color[3] = color[3]; } - if (!picking) - glsafe(::glEnable(GL_LIGHTING)); - glsafe(::glColor4fv(color.data())); glsafe(::glPushMatrix()); glsafe(::glTranslated(m_grabbers[axis].center(0), m_grabbers[axis].center(1), m_grabbers[axis].center(2))); @@ -218,9 +215,6 @@ void GLGizmoMove3D::render_grabber_extension(Axis axis, const BoundingBoxf3& box glsafe(::glScaled(0.75 * size, 0.75 * size, 3.0 * size)); m_vbo_cone.render(); glsafe(::glPopMatrix()); - - if (!picking) - glsafe(::glDisable(GL_LIGHTING)); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp index 624cf2b2f..766e8c1a8 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp @@ -335,9 +335,6 @@ void GLGizmoRotate::render_grabber_extension(const BoundingBoxf3& box, bool pick color[2] = 1.0f - color[2]; } - if (!picking) - glsafe(::glEnable(GL_LIGHTING)); - glsafe(::glColor4fv(color.data())); glsafe(::glPushMatrix()); glsafe(::glTranslated(m_grabbers[0].center(0), m_grabbers[0].center(1), m_grabbers[0].center(2))); @@ -355,9 +352,6 @@ void GLGizmoRotate::render_grabber_extension(const BoundingBoxf3& box, bool pick glsafe(::glScaled(0.75 * size, 0.75 * size, 3.0 * size)); m_cone.render(); glsafe(::glPopMatrix()); - - if (!picking) - glsafe(::glDisable(GL_LIGHTING)); } void GLGizmoRotate::transform_to_local(const Selection& selection) const diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 5fe6c2c17..3787e15a2 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -1169,7 +1169,6 @@ void Selection::render(float scale_factor) const #if ENABLE_RENDER_SELECTION_CENTER void Selection::render_center(bool gizmo_is_dragging) const { - if (!m_valid || is_empty() || m_quadric == nullptr) if (!m_valid || is_empty()) return; @@ -1177,15 +1176,11 @@ void Selection::render_center(bool gizmo_is_dragging) const glsafe(::glDisable(GL_DEPTH_TEST)); - glsafe(::glEnable(GL_LIGHTING)); - glsafe(::glColor3f(1.0f, 1.0f, 1.0f)); glsafe(::glPushMatrix()); glsafe(::glTranslated(center(0), center(1), center(2))); m_vbo_sphere.render(); glsafe(::glPopMatrix()); - - glsafe(::glDisable(GL_LIGHTING)); } #endif // ENABLE_RENDER_SELECTION_CENTER From 9605d10caaf2db96acf31f823f71f40fad52abcd Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 25 May 2021 13:46:25 +0200 Subject: [PATCH 24/31] Unified color definition --- src/slic3r/GUI/Gizmos/GLGizmoBase.cpp | 11 +++--- src/slic3r/GUI/Gizmos/GLGizmoBase.hpp | 24 ++++++------ src/slic3r/GUI/Gizmos/GLGizmoMove.cpp | 19 ++++----- src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp | 25 +++++------- src/slic3r/GUI/Gizmos/GLGizmoScale.cpp | 51 ++++++++++--------------- src/slic3r/GUI/Selection.cpp | 8 ++-- 6 files changed, 59 insertions(+), 79 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp index cd05cba04..8a589425e 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp @@ -85,9 +85,9 @@ GLGizmoBase::GLGizmoBase(GLCanvas3D& parent, const std::string& icon_filename, u , m_imgui(wxGetApp().imgui()) , m_first_input_window_render(true) { - ::memcpy((void*)m_base_color, (const void*)DEFAULT_BASE_COLOR, 4 * sizeof(float)); - ::memcpy((void*)m_drag_color, (const void*)DEFAULT_DRAG_COLOR, 4 * sizeof(float)); - ::memcpy((void*)m_highlight_color, (const void*)DEFAULT_HIGHLIGHT_COLOR, 4 * sizeof(float)); + m_base_color = DEFAULT_BASE_COLOR; + m_drag_color = DEFAULT_DRAG_COLOR; + m_highlight_color = DEFAULT_HIGHLIGHT_COLOR; m_cone.init_from(make_cone(1., 1., 2 * PI / 24)); m_sphere.init_from(make_sphere(1., (2 * M_PI) / 24.)); m_cylinder.init_from(make_cylinder(1., 1., 2 * PI / 24.)); @@ -102,10 +102,9 @@ void GLGizmoBase::set_hover_id(int id) } } -void GLGizmoBase::set_highlight_color(const float* color) +void GLGizmoBase::set_highlight_color(const std::array& color) { - if (color != nullptr) - ::memcpy((void*)m_highlight_color, (const void*)color, 4 * sizeof(float)); + m_highlight_color = color; } void GLGizmoBase::enable_grabber(unsigned int id) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp index eed393881..854f740b9 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp @@ -18,13 +18,15 @@ class ModelObject; namespace GUI { -static const float DEFAULT_BASE_COLOR[4] = { 0.625f, 0.625f, 0.625f, 1.0f }; -static const float DEFAULT_DRAG_COLOR[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; -static const float DEFAULT_HIGHLIGHT_COLOR[4] = { 1.0f, 0.38f, 0.0f, 1.0f }; -static const float AXES_COLOR[][4] = { { 0.75f, 0.0f, 0.0f, 1.0f }, { 0.0f, 0.75f, 0.0f, 1.0f }, { 0.0f, 0.0f, 0.75f, 1.0f } }; -static const float CONSTRAINED_COLOR[4] = { 0.5f, 0.5f, 0.5f, 1.0f }; - - +static const std::array DEFAULT_BASE_COLOR = { 0.625f, 0.625f, 0.625f, 1.0f }; +static const std::array DEFAULT_DRAG_COLOR = { 1.0f, 1.0f, 1.0f, 1.0f }; +static const std::array DEFAULT_HIGHLIGHT_COLOR = { 1.0f, 0.38f, 0.0f, 1.0f }; +static const std::array, 3> AXES_COLOR = {{ + { 0.75f, 0.0f, 0.0f, 1.0f }, + { 0.0f, 0.75f, 0.0f, 1.0f }, + { 0.0f, 0.0f, 0.75f, 1.0f } + }}; +static const std::array CONSTRAINED_COLOR = { 0.5f, 0.5f, 0.5f, 1.0f }; class ImGuiWrapper; class GLCanvas3D; @@ -93,9 +95,9 @@ protected: unsigned int m_sprite_id; int m_hover_id; bool m_dragging; - float m_base_color[4]; - float m_drag_color[4]; - float m_highlight_color[4]; + std::array m_base_color; + std::array m_drag_color; + std::array m_highlight_color; mutable std::vector m_grabbers; ImGuiWrapper* m_imgui; bool m_first_input_window_render; @@ -138,7 +140,7 @@ public: int get_hover_id() const { return m_hover_id; } void set_hover_id(int id); - void set_highlight_color(const float* color); + void set_highlight_color(const std::array& color); void enable_grabber(unsigned int id); void disable_grabber(unsigned int id); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp index 8e0cd1366..9761274f4 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp @@ -112,14 +112,11 @@ void GLGizmoMove3D::on_render() const glsafe(::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f)); - if (m_hover_id == -1) - { + if (m_hover_id == -1) { // draw axes - for (unsigned int i = 0; i < 3; ++i) - { - if (m_grabbers[i].enabled) - { - glsafe(::glColor4fv(AXES_COLOR[i])); + for (unsigned int i = 0; i < 3; ++i) { + if (m_grabbers[i].enabled) { + glsafe(::glColor4fv(AXES_COLOR[i].data())); ::glBegin(GL_LINES); ::glVertex3dv(center.data()); ::glVertex3dv(m_grabbers[i].center.data()); @@ -129,16 +126,14 @@ void GLGizmoMove3D::on_render() const // draw grabbers render_grabbers(box); - for (unsigned int i = 0; i < 3; ++i) - { + for (unsigned int i = 0; i < 3; ++i) { if (m_grabbers[i].enabled) render_grabber_extension((Axis)i, box, false); } } - else - { + else { // draw axis - glsafe(::glColor4fv(AXES_COLOR[m_hover_id])); + glsafe(::glColor4fv(AXES_COLOR[m_hover_id].data())); ::glBegin(GL_LINES); ::glVertex3dv(center.data()); ::glVertex3dv(m_grabbers[m_hover_id].center.data()); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp index 766e8c1a8..2a3c8b588 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp @@ -133,8 +133,7 @@ void GLGizmoRotate::on_render() const const Selection& selection = m_parent.get_selection(); const BoundingBoxf3& box = selection.get_bounding_box(); - if (m_hover_id != 0 && !m_grabbers[0].dragging) - { + if (m_hover_id != 0 && !m_grabbers[0].dragging) { m_center = box.center(); m_radius = Offset + box.radius(); m_snap_coarse_in_radius = m_radius / 3.0f; @@ -149,18 +148,17 @@ void GLGizmoRotate::on_render() const transform_to_local(selection); glsafe(::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f)); - glsafe(::glColor4fv((m_hover_id != -1) ? m_drag_color : m_highlight_color)); + glsafe(::glColor4fv((m_hover_id != -1) ? m_drag_color.data() : m_highlight_color.data())); render_circle(); - if (m_hover_id != -1) - { + if (m_hover_id != -1) { render_scale(); render_snap_radii(); render_reference_radius(); } - glsafe(::glColor4fv(m_highlight_color)); + glsafe(::glColor4fv(m_highlight_color.data())); if (m_hover_id != -1) render_angle(); @@ -311,14 +309,14 @@ void GLGizmoRotate::render_grabber(const BoundingBoxf3& box) const m_grabbers[0].center = Vec3d(::cos(m_angle) * grabber_radius, ::sin(m_angle) * grabber_radius, 0.0); m_grabbers[0].angles(2) = m_angle; - glsafe(::glColor4fv((m_hover_id != -1) ? m_drag_color : m_highlight_color)); + glsafe(::glColor4fv((m_hover_id != -1) ? m_drag_color.data() : m_highlight_color.data())); ::glBegin(GL_LINES); ::glVertex3f(0.0f, 0.0f, 0.0f); ::glVertex3dv(m_grabbers[0].center.data()); glsafe(::glEnd()); - ::memcpy((void*)m_grabbers[0].color.data(), (const void*)m_highlight_color, 4 * sizeof(float)); + m_grabbers[0].color = m_highlight_color; render_grabbers(box); } @@ -430,8 +428,7 @@ GLGizmoRotate3D::GLGizmoRotate3D(GLCanvas3D& parent, const std::string& icon_fil m_gizmos.emplace_back(parent, GLGizmoRotate::Y); m_gizmos.emplace_back(parent, GLGizmoRotate::Z); - for (unsigned int i = 0; i < 3; ++i) - { + for (unsigned int i = 0; i < 3; ++i) { m_gizmos[i].set_group_id(i); } @@ -440,14 +437,12 @@ GLGizmoRotate3D::GLGizmoRotate3D(GLCanvas3D& parent, const std::string& icon_fil bool GLGizmoRotate3D::on_init() { - for (GLGizmoRotate& g : m_gizmos) - { + for (GLGizmoRotate& g : m_gizmos) { if (!g.init()) return false; } - for (unsigned int i = 0; i < 3; ++i) - { + for (unsigned int i = 0; i < 3; ++i) { m_gizmos[i].set_highlight_color(AXES_COLOR[i]); } @@ -458,7 +453,7 @@ bool GLGizmoRotate3D::on_init() std::string GLGizmoRotate3D::on_get_name() const { - return (_(L("Rotate")) + " [R]").ToUTF8().data(); + return (_L("Rotate") + " [R]").ToUTF8().data(); } bool GLGizmoRotate3D::on_is_activable() const diff --git a/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp b/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp index 425b53f85..d088b4ba3 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp @@ -173,34 +173,32 @@ void GLGizmoScale3D::on_render() const // x axis m_grabbers[0].center = m_transform * Vec3d(m_box.min(0), center(1), center(2)) - offset_x; m_grabbers[1].center = m_transform * Vec3d(m_box.max(0), center(1), center(2)) + offset_x; - ::memcpy((void*)m_grabbers[0].color.data(), (ctrl_down && (m_hover_id == 1)) ? (const void*)CONSTRAINED_COLOR : (const void*)&AXES_COLOR[0], 4 * sizeof(float)); - ::memcpy((void*)m_grabbers[1].color.data(), (ctrl_down && (m_hover_id == 0)) ? (const void*)CONSTRAINED_COLOR : (const void*)&AXES_COLOR[0], 4 * sizeof(float)); + m_grabbers[0].color = (ctrl_down && (m_hover_id == 1)) ? CONSTRAINED_COLOR : AXES_COLOR[0]; + m_grabbers[1].color = (ctrl_down && (m_hover_id == 0)) ? CONSTRAINED_COLOR : AXES_COLOR[0]; // y axis m_grabbers[2].center = m_transform * Vec3d(center(0), m_box.min(1), center(2)) - offset_y; m_grabbers[3].center = m_transform * Vec3d(center(0), m_box.max(1), center(2)) + offset_y; - ::memcpy((void*)m_grabbers[2].color.data(), (ctrl_down && (m_hover_id == 3)) ? (const void*)CONSTRAINED_COLOR : (const void*)&AXES_COLOR[1], 4 * sizeof(float)); - ::memcpy((void*)m_grabbers[3].color.data(), (ctrl_down && (m_hover_id == 2)) ? (const void*)CONSTRAINED_COLOR : (const void*)&AXES_COLOR[1], 4 * sizeof(float)); + m_grabbers[2].color = (ctrl_down && (m_hover_id == 3)) ? CONSTRAINED_COLOR : AXES_COLOR[1]; + m_grabbers[3].color = (ctrl_down && (m_hover_id == 2)) ? CONSTRAINED_COLOR : AXES_COLOR[1]; // z axis m_grabbers[4].center = m_transform * Vec3d(center(0), center(1), m_box.min(2)) - offset_z; m_grabbers[5].center = m_transform * Vec3d(center(0), center(1), m_box.max(2)) + offset_z; - ::memcpy((void*)m_grabbers[4].color.data(), (ctrl_down && (m_hover_id == 5)) ? (const void*)CONSTRAINED_COLOR : (const void*)&AXES_COLOR[2], 4 * sizeof(float)); - ::memcpy((void*)m_grabbers[5].color.data(), (ctrl_down && (m_hover_id == 4)) ? (const void*)CONSTRAINED_COLOR : (const void*)&AXES_COLOR[2], 4 * sizeof(float)); + m_grabbers[4].color = (ctrl_down && (m_hover_id == 5)) ? CONSTRAINED_COLOR : AXES_COLOR[2]; + m_grabbers[5].color = (ctrl_down && (m_hover_id == 4)) ? CONSTRAINED_COLOR : AXES_COLOR[2]; // uniform m_grabbers[6].center = m_transform * Vec3d(m_box.min(0), m_box.min(1), center(2)) - offset_x - offset_y; m_grabbers[7].center = m_transform * Vec3d(m_box.max(0), m_box.min(1), center(2)) + offset_x - offset_y; m_grabbers[8].center = m_transform * Vec3d(m_box.max(0), m_box.max(1), center(2)) + offset_x + offset_y; m_grabbers[9].center = m_transform * Vec3d(m_box.min(0), m_box.max(1), center(2)) - offset_x + offset_y; - for (int i = 6; i < 10; ++i) - { - ::memcpy((void*)m_grabbers[i].color.data(), (const void*)m_highlight_color, 4 * sizeof(float)); + for (int i = 6; i < 10; ++i) { + m_grabbers[i].color = m_highlight_color; } // sets grabbers orientation - for (int i = 0; i < 10; ++i) - { + for (int i = 0; i < 10; ++i) { m_grabbers[i].angles = angles; } @@ -210,25 +208,21 @@ void GLGizmoScale3D::on_render() const float grabber_mean_size = (float)((selection_box.size()(0) + selection_box.size()(1) + selection_box.size()(2)) / 3.0); - if (m_hover_id == -1) - { + if (m_hover_id == -1) { // draw connections - if (m_grabbers[0].enabled && m_grabbers[1].enabled) - { + if (m_grabbers[0].enabled && m_grabbers[1].enabled) { glsafe(::glColor4fv(m_grabbers[0].color.data())); render_grabbers_connection(0, 1); } - if (m_grabbers[2].enabled && m_grabbers[3].enabled) - { + if (m_grabbers[2].enabled && m_grabbers[3].enabled) { glsafe(::glColor4fv(m_grabbers[2].color.data())); render_grabbers_connection(2, 3); } - if (m_grabbers[4].enabled && m_grabbers[5].enabled) - { + if (m_grabbers[4].enabled && m_grabbers[5].enabled) { glsafe(::glColor4fv(m_grabbers[4].color.data())); render_grabbers_connection(4, 5); } - glsafe(::glColor4fv(m_base_color)); + glsafe(::glColor4fv(m_base_color.data())); render_grabbers_connection(6, 7); render_grabbers_connection(7, 8); render_grabbers_connection(8, 9); @@ -236,8 +230,7 @@ void GLGizmoScale3D::on_render() const // draw grabbers render_grabbers(grabber_mean_size); } - else if ((m_hover_id == 0) || (m_hover_id == 1)) - { + else if (m_hover_id == 0 || m_hover_id == 1) { // draw connection glsafe(::glColor4fv(m_grabbers[0].color.data())); render_grabbers_connection(0, 1); @@ -245,8 +238,7 @@ void GLGizmoScale3D::on_render() const m_grabbers[0].render(true, grabber_mean_size); m_grabbers[1].render(true, grabber_mean_size); } - else if ((m_hover_id == 2) || (m_hover_id == 3)) - { + else if (m_hover_id == 2 || m_hover_id == 3) { // draw connection glsafe(::glColor4fv(m_grabbers[2].color.data())); render_grabbers_connection(2, 3); @@ -254,8 +246,7 @@ void GLGizmoScale3D::on_render() const m_grabbers[2].render(true, grabber_mean_size); m_grabbers[3].render(true, grabber_mean_size); } - else if ((m_hover_id == 4) || (m_hover_id == 5)) - { + else if (m_hover_id == 4 || m_hover_id == 5) { // draw connection glsafe(::glColor4fv(m_grabbers[4].color.data())); render_grabbers_connection(4, 5); @@ -263,17 +254,15 @@ void GLGizmoScale3D::on_render() const m_grabbers[4].render(true, grabber_mean_size); m_grabbers[5].render(true, grabber_mean_size); } - else if (m_hover_id >= 6) - { + else if (m_hover_id >= 6) { // draw connection - glsafe(::glColor4fv(m_drag_color)); + glsafe(::glColor4fv(m_drag_color.data())); render_grabbers_connection(6, 7); render_grabbers_connection(7, 8); render_grabbers_connection(8, 9); render_grabbers_connection(9, 6); // draw grabbers - for (int i = 6; i < 10; ++i) - { + for (int i = 6; i < 10; ++i) { m_grabbers[i].render(true, grabber_mean_size); } } diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 3787e15a2..4a632dca7 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -22,7 +22,7 @@ #include #include -static const float UNIFORM_SCALE_COLOR[4] = { 0.923f, 0.504f, 0.264f, 1.0f }; +static const std::array UNIFORM_SCALE_COLOR = { 0.923f, 0.504f, 0.264f, 1.0f }; namespace Slic3r { namespace GUI { @@ -1823,7 +1823,7 @@ void Selection::render_sidebar_position_hints(const std::string& sidebar_field) auto set_color = [](Axis axis) { GLShaderProgram* shader = wxGetApp().get_current_shader(); if (shader != nullptr) - shader->set_uniform("uniform_color", AXES_COLOR[axis], 4); + shader->set_uniform("uniform_color", AXES_COLOR[axis]); }; if (boost::ends_with(sidebar_field, "x")) { @@ -1845,7 +1845,7 @@ void Selection::render_sidebar_rotation_hints(const std::string& sidebar_field) auto set_color = [](Axis axis) { GLShaderProgram* shader = wxGetApp().get_current_shader(); if (shader != nullptr) - shader->set_uniform("uniform_color", AXES_COLOR[axis], 4); + shader->set_uniform("uniform_color", AXES_COLOR[axis]); }; auto render_sidebar_rotation_hint = [this]() { @@ -1875,7 +1875,7 @@ void Selection::render_sidebar_scale_hints(const std::string& sidebar_field) con auto render_sidebar_scale_hint = [this, uniform_scale](Axis axis) { GLShaderProgram* shader = wxGetApp().get_current_shader(); if (shader != nullptr) - shader->set_uniform("uniform_color", uniform_scale ? UNIFORM_SCALE_COLOR : AXES_COLOR[axis], 4); + shader->set_uniform("uniform_color", uniform_scale ? UNIFORM_SCALE_COLOR : AXES_COLOR[axis]); glsafe(::glTranslated(0.0, 5.0, 0.0)); m_arrow.render(); From f69bd75464feb7968b3d7dd1bcdb0e442f65c14a Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 25 May 2021 15:42:22 +0200 Subject: [PATCH 25/31] Fixed rendering of gizmos' grabbers --- src/slic3r/GUI/Gizmos/GLGizmoBase.cpp | 26 +++++------- src/slic3r/GUI/Gizmos/GLGizmoCut.cpp | 35 ++++++++++------ src/slic3r/GUI/Gizmos/GLGizmoMove.cpp | 44 +++++++++++--------- src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp | 21 ++++++---- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp | 6 +-- 5 files changed, 73 insertions(+), 59 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp index 8a589425e..e284822d2 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp @@ -29,8 +29,7 @@ GLGizmoBase::Grabber::Grabber() void GLGizmoBase::Grabber::render(bool hover, float size) const { std::array render_color; - if (hover) - { + if (hover) { render_color[0] = (1.0f - color[0]); render_color[1] = (1.0f - color[1]); render_color[2] = (1.0f - color[2]); @@ -57,7 +56,7 @@ void GLGizmoBase::Grabber::render(float size, const std::array& render float fullsize = 2 * (dragging ? get_dragging_half_size(size) : get_half_size(size)); GLShaderProgram* shader = picking ? nullptr : wxGetApp().get_current_shader(); - if (shader) + if (shader != nullptr) shader->set_uniform("uniform_color", render_color); else glsafe(::glColor4fv(render_color.data())); // picking @@ -173,33 +172,29 @@ std::array GLGizmoBase::picking_color_component(unsigned int id) const void GLGizmoBase::render_grabbers(const BoundingBoxf3& box) const { - render_grabbers((float)((box.size()(0) + box.size()(1) + box.size()(2)) / 3.0)); + render_grabbers((float)((box.size().x() + box.size().y() + box.size().z()) / 3.0)); } void GLGizmoBase::render_grabbers(float size) const { GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); - if (! shader) + if (shader == nullptr) return; shader->start_using(); shader->set_uniform("emission_factor", 0.1); - for (int i = 0; i < (int)m_grabbers.size(); ++i) - { + for (int i = 0; i < (int)m_grabbers.size(); ++i) { if (m_grabbers[i].enabled) - m_grabbers[i].render((m_hover_id == i), size); + m_grabbers[i].render(m_hover_id == i, size); } - shader->set_uniform("emission_factor", 0.); shader->stop_using(); } void GLGizmoBase::render_grabbers_for_picking(const BoundingBoxf3& box) const { - float mean_size = (float)((box.size()(0) + box.size()(1) + box.size()(2)) / 3.0); + float mean_size = (float)((box.size().x() + box.size().y() + box.size().z()) / 3.0); - for (unsigned int i = 0; i < (unsigned int)m_grabbers.size(); ++i) - { - if (m_grabbers[i].enabled) - { + for (unsigned int i = 0; i < (unsigned int)m_grabbers.size(); ++i) { + if (m_grabbers[i].enabled) { std::array color = picking_color_component(i); m_grabbers[i].color = color; m_grabbers[i].render_for_picking(mean_size); @@ -215,8 +210,7 @@ std::string GLGizmoBase::format(float value, unsigned int decimals) const void GLGizmoBase::render_input_window(float x, float y, float bottom_limit) { on_render_input_window(x, y, bottom_limit); - if (m_first_input_window_render) - { + if (m_first_input_window_render) { // for some reason, the imgui dialogs are not shown on screen in the 1st frame where they are rendered, but show up only with the 2nd rendered frame // so, we forces another frame rendering the first time the imgui window is shown m_parent.set_as_dirty(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index ffa389bb2..f0813732f 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -51,7 +51,7 @@ bool GLGizmoCut::on_init() std::string GLGizmoCut::on_get_name() const { - return (_(L("Cut")) + " [C]").ToUTF8().data(); + return (_L("Cut") + " [C]").ToUTF8().data(); } void GLGizmoCut::on_set_state() @@ -96,12 +96,12 @@ void GLGizmoCut::on_render() const const BoundingBoxf3& box = selection.get_bounding_box(); Vec3d plane_center = box.center(); - plane_center(2) = m_cut_z; + plane_center.z() = m_cut_z; - const float min_x = box.min(0) - Margin; - const float max_x = box.max(0) + Margin; - const float min_y = box.min(1) - Margin; - const float max_y = box.max(1) + Margin; + const float min_x = box.min.x() - Margin; + const float max_x = box.max.x() + Margin; + const float min_y = box.min.y() - Margin; + const float max_y = box.max.y() + Margin; glsafe(::glEnable(GL_DEPTH_TEST)); glsafe(::glDisable(GL_CULL_FACE)); glsafe(::glEnable(GL_BLEND)); @@ -110,10 +110,10 @@ void GLGizmoCut::on_render() const // Draw the cutting plane ::glBegin(GL_QUADS); ::glColor4f(0.8f, 0.8f, 0.8f, 0.5f); - ::glVertex3f(min_x, min_y, plane_center(2)); - ::glVertex3f(max_x, min_y, plane_center(2)); - ::glVertex3f(max_x, max_y, plane_center(2)); - ::glVertex3f(min_x, max_y, plane_center(2)); + ::glVertex3f(min_x, min_y, plane_center.z()); + ::glVertex3f(max_x, min_y, plane_center.z()); + ::glVertex3f(max_x, max_y, plane_center.z()); + ::glVertex3f(min_x, max_y, plane_center.z()); glsafe(::glEnd()); glsafe(::glEnable(GL_CULL_FACE)); @@ -123,9 +123,10 @@ void GLGizmoCut::on_render() const // Draw the grabber and the connecting line m_grabbers[0].center = plane_center; - m_grabbers[0].center(2) = plane_center(2) + Offset; + m_grabbers[0].center.z() = plane_center.z() + Offset; + + glsafe(::glClear(GL_DEPTH_BUFFER_BIT)); - glsafe(::glDisable(GL_DEPTH_TEST)); glsafe(::glLineWidth(m_hover_id != -1 ? 2.0f : 1.5f)); glsafe(::glColor3f(1.0, 1.0, 0.0)); ::glBegin(GL_LINES); @@ -133,8 +134,16 @@ void GLGizmoCut::on_render() const ::glVertex3dv(m_grabbers[0].center.data()); glsafe(::glEnd()); + GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); + if (shader == nullptr) + return; + shader->start_using(); + shader->set_uniform("emission_factor", 0.1); + m_grabbers[0].color = GrabberColor; - m_grabbers[0].render(m_hover_id == 0, (float)((box.size()(0) + box.size()(1) + box.size()(2)) / 3.0)); + m_grabbers[0].render(m_hover_id == 0, (float)((box.size().x() + box.size().y() + box.size().z()) / 3.0)); + + shader->stop_using(); } void GLGizmoCut::on_render_for_picking() const diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp index 9761274f4..458c3233a 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp @@ -1,6 +1,7 @@ // Include GLGizmoBase.hpp before I18N.hpp as it includes some libigl code, which overrides our localization "L" macro. #include "GLGizmoMove.hpp" #include "slic3r/GUI/GLCanvas3D.hpp" +#include "slic3r/GUI/GUI_App.hpp" #include @@ -40,8 +41,7 @@ std::string GLGizmoMove3D::get_tooltip() const bool GLGizmoMove3D::on_init() { - for (int i = 0; i < 3; ++i) - { + for (int i = 0; i < 3; ++i) { m_grabbers.push_back(Grabber()); } @@ -52,7 +52,7 @@ bool GLGizmoMove3D::on_init() std::string GLGizmoMove3D::on_get_name() const { - return (_(L("Move")) + " [M]").ToUTF8().data(); + return (_L("Move") + " [M]").ToUTF8().data(); } bool GLGizmoMove3D::on_is_activable() const @@ -62,8 +62,7 @@ bool GLGizmoMove3D::on_is_activable() const void GLGizmoMove3D::on_start_dragging() { - if (m_hover_id != -1) - { + if (m_hover_id != -1) { m_displacement = Vec3d::Zero(); const BoundingBoxf3& box = m_parent.get_selection().get_bounding_box(); m_starting_drag_position = m_grabbers[m_hover_id].center; @@ -99,16 +98,16 @@ void GLGizmoMove3D::on_render() const const Vec3d& center = box.center(); // x axis - m_grabbers[0].center = Vec3d(box.max(0) + Offset, center(1), center(2)); - ::memcpy((void*)m_grabbers[0].color.data(), (const void*)&AXES_COLOR[0], 4 * sizeof(float)); + m_grabbers[0].center = Vec3d(box.max.x() + Offset, center.y(), center.z()); + m_grabbers[0].color = AXES_COLOR[0]; // y axis - m_grabbers[1].center = Vec3d(center(0), box.max(1) + Offset, center(2)); - ::memcpy((void*)m_grabbers[1].color.data(), (const void*)&AXES_COLOR[1], 4 * sizeof(float)); + m_grabbers[1].center = Vec3d(center.x(), box.max.y() + Offset, center.z()); + m_grabbers[1].color = AXES_COLOR[1]; // z axis - m_grabbers[2].center = Vec3d(center(0), center(1), box.max(2) + Offset); - ::memcpy((void*)m_grabbers[2].color.data(), (const void*)&AXES_COLOR[2], 4 * sizeof(float)); + m_grabbers[2].center = Vec3d(center.x(), center.y(), box.max.z() + Offset); + m_grabbers[2].color = AXES_COLOR[2]; glsafe(::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f)); @@ -140,7 +139,7 @@ void GLGizmoMove3D::on_render() const glsafe(::glEnd()); // draw grabber - float mean_size = (float)((box.size()(0) + box.size()(1) + box.size()(2)) / 3.0); + float mean_size = (float)((box.size().x() + box.size().y() + box.size().z()) / 3.0); m_grabbers[m_hover_id].render(true, mean_size); render_grabber_extension((Axis)m_hover_id, box, false); } @@ -163,8 +162,7 @@ double GLGizmoMove3D::calc_projection(const UpdateData& data) const Vec3d starting_vec = m_starting_drag_position - m_starting_box_center; double len_starting_vec = starting_vec.norm(); - if (len_starting_vec != 0.0) - { + if (len_starting_vec != 0.0) { Vec3d mouse_dir = data.mouse_ray.unit_vector(); // finds the intersection of the mouse ray with the plane parallel to the camera viewport and passing throught the starting position // use ray-plane intersection see i.e. https://en.wikipedia.org/wiki/Line%E2%80%93plane_intersection algebric form @@ -186,21 +184,27 @@ double GLGizmoMove3D::calc_projection(const UpdateData& data) const void GLGizmoMove3D::render_grabber_extension(Axis axis, const BoundingBoxf3& box, bool picking) const { - float mean_size = (float)((box.size()(0) + box.size()(1) + box.size()(2)) / 3.0); + float mean_size = (float)((box.size().x() + box.size().y() + box.size().z()) / 3.0); double size = m_dragging ? (double)m_grabbers[axis].get_dragging_half_size(mean_size) : (double)m_grabbers[axis].get_half_size(mean_size); std::array color = m_grabbers[axis].color; - if (!picking && (m_hover_id != -1)) - { + if (!picking && m_hover_id != -1) { color[0] = 1.0f - color[0]; color[1] = 1.0f - color[1]; color[2] = 1.0f - color[2]; color[3] = color[3]; } - glsafe(::glColor4fv(color.data())); + GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); + if (shader == nullptr) + return; + + shader->start_using(); + shader->set_uniform("emission_factor", 0.1); + shader->set_uniform("uniform_color", color); + glsafe(::glPushMatrix()); - glsafe(::glTranslated(m_grabbers[axis].center(0), m_grabbers[axis].center(1), m_grabbers[axis].center(2))); + glsafe(::glTranslated(m_grabbers[axis].center.x(), m_grabbers[axis].center.y(), m_grabbers[axis].center.z())); if (axis == X) glsafe(::glRotated(90.0, 0.0, 1.0, 0.0)); else if (axis == Y) @@ -210,6 +214,8 @@ void GLGizmoMove3D::render_grabber_extension(Axis axis, const BoundingBoxf3& box glsafe(::glScaled(0.75 * size, 0.75 * size, 3.0 * size)); m_vbo_cone.render(); glsafe(::glPopMatrix()); + + shader->stop_using(); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp index 2a3c8b588..a1adbc95f 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp @@ -326,16 +326,22 @@ void GLGizmoRotate::render_grabber_extension(const BoundingBoxf3& box, bool pick double size = m_dragging ? (double)m_grabbers[0].get_dragging_half_size(mean_size) : (double)m_grabbers[0].get_half_size(mean_size); std::array color = m_grabbers[0].color; - if (!picking && (m_hover_id != -1)) - { + if (!picking && m_hover_id != -1) { color[0] = 1.0f - color[0]; color[1] = 1.0f - color[1]; color[2] = 1.0f - color[2]; } - glsafe(::glColor4fv(color.data())); + GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); + if (shader == nullptr) + return; + + shader->start_using(); + shader->set_uniform("emission_factor", 0.1); + shader->set_uniform("uniform_color", color); + glsafe(::glPushMatrix()); - glsafe(::glTranslated(m_grabbers[0].center(0), m_grabbers[0].center(1), m_grabbers[0].center(2))); + glsafe(::glTranslated(m_grabbers[0].center.x(), m_grabbers[0].center.y(), m_grabbers[0].center.z())); glsafe(::glRotated(Geometry::rad2deg(m_angle), 0.0, 0.0, 1.0)); glsafe(::glRotated(90.0, 1.0, 0.0, 0.0)); glsafe(::glTranslated(0.0, 0.0, 2.0 * size)); @@ -343,21 +349,22 @@ void GLGizmoRotate::render_grabber_extension(const BoundingBoxf3& box, bool pick m_cone.render(); glsafe(::glPopMatrix()); glsafe(::glPushMatrix()); - glsafe(::glTranslated(m_grabbers[0].center(0), m_grabbers[0].center(1), m_grabbers[0].center(2))); + glsafe(::glTranslated(m_grabbers[0].center.x(), m_grabbers[0].center.y(), m_grabbers[0].center.z())); glsafe(::glRotated(Geometry::rad2deg(m_angle), 0.0, 0.0, 1.0)); glsafe(::glRotated(-90.0, 1.0, 0.0, 0.0)); glsafe(::glTranslated(0.0, 0.0, 2.0 * size)); glsafe(::glScaled(0.75 * size, 0.75 * size, 3.0 * size)); m_cone.render(); glsafe(::glPopMatrix()); + + shader->stop_using(); } void GLGizmoRotate::transform_to_local(const Selection& selection) const { glsafe(::glTranslated(m_center(0), m_center(1), m_center(2))); - if (selection.is_single_volume() || selection.is_single_modifier() || selection.requires_local_axes()) - { + if (selection.is_single_volume() || selection.is_single_modifier() || selection.requires_local_axes()) { Transform3d orient_matrix = selection.get_volume(*selection.get_volume_idxs().begin())->get_instance_transformation().get_matrix(true, false, true, true); glsafe(::glMultMatrixd(orient_matrix.data())); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index faeee499d..f0818a2d7 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -119,13 +119,11 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) return; GLShaderProgram* shader = picking ? nullptr : wxGetApp().get_shader("gouraud_light"); - if (shader) + if (shader != nullptr) shader->start_using(); ScopeGuard guard([shader]() { - if (shader) { - shader->set_uniform("emission_factor", 0.); + if (shader != nullptr) shader->stop_using(); - } }); const GLVolume* vol = selection.get_volume(*selection.get_volume_idxs().begin()); From e1d5d0804b938963bb837850dea38358353824d5 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 27 May 2021 12:41:46 +0200 Subject: [PATCH 26/31] Added missing uniform calls for emission_factor --- src/slic3r/GUI/3DBed.cpp | 2 ++ src/slic3r/GUI/GCodeViewer.cpp | 1 + src/slic3r/GUI/GLCanvas3D.cpp | 2 +- src/slic3r/GUI/Selection.cpp | 12 +++++++++--- 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/3DBed.cpp b/src/slic3r/GUI/3DBed.cpp index 29551ac15..f3eec0080 100644 --- a/src/slic3r/GUI/3DBed.cpp +++ b/src/slic3r/GUI/3DBed.cpp @@ -122,6 +122,7 @@ void Bed3D::Axes::render() const glsafe(::glEnable(GL_DEPTH_TEST)); shader->start_using(); + shader->set_uniform("emission_factor", 0.0); // x axis std::array color = { 0.75f, 0.0f, 0.0f, 1.0f }; @@ -489,6 +490,7 @@ void Bed3D::render_model() const if (shader != nullptr) { shader->start_using(); shader->set_uniform("uniform_color", m_model_color); + shader->set_uniform("emission_factor", 0.0); ::glPushMatrix(); ::glTranslated(m_model_offset(0), m_model_offset(1), m_model_offset(2)); model->render(); diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 9139f4450..3949511f5 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -227,6 +227,7 @@ void GCodeViewer::SequentialView::Marker::render() const shader->start_using(); shader->set_uniform("uniform_color", m_color); + shader->set_uniform("emission_factor", 0.0); glsafe(::glPushMatrix()); glsafe(::glMultMatrixf(m_world_transform.data())); diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 880e69bbd..baebbbf2d 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3918,7 +3918,7 @@ void GLCanvas3D::_render_thumbnail_internal(ThumbnailData& thumbnail_data, bool glsafe(::glEnable(GL_DEPTH_TEST)); shader->start_using(); - shader->set_uniform("print_box.volume_detection", 0); + shader->set_uniform("emission_factor", 0.0); for (GLVolume* vol : visible_volumes) { shader->set_uniform("uniform_color", (vol->printable && !vol->is_outside) ? orange : gray); diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 4a632dca7..479b0fa77 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -1822,8 +1822,10 @@ void Selection::render_sidebar_position_hints(const std::string& sidebar_field) { auto set_color = [](Axis axis) { GLShaderProgram* shader = wxGetApp().get_current_shader(); - if (shader != nullptr) + if (shader != nullptr) { shader->set_uniform("uniform_color", AXES_COLOR[axis]); + shader->set_uniform("emission_factor", 0.0); + } }; if (boost::ends_with(sidebar_field, "x")) { @@ -1844,8 +1846,10 @@ void Selection::render_sidebar_rotation_hints(const std::string& sidebar_field) { auto set_color = [](Axis axis) { GLShaderProgram* shader = wxGetApp().get_current_shader(); - if (shader != nullptr) + if (shader != nullptr) { shader->set_uniform("uniform_color", AXES_COLOR[axis]); + shader->set_uniform("emission_factor", 0.0); + } }; auto render_sidebar_rotation_hint = [this]() { @@ -1874,8 +1878,10 @@ void Selection::render_sidebar_scale_hints(const std::string& sidebar_field) con auto render_sidebar_scale_hint = [this, uniform_scale](Axis axis) { GLShaderProgram* shader = wxGetApp().get_current_shader(); - if (shader != nullptr) + if (shader != nullptr) { shader->set_uniform("uniform_color", uniform_scale ? UNIFORM_SCALE_COLOR : AXES_COLOR[axis]); + shader->set_uniform("emission_factor", 0.0); + } glsafe(::glTranslated(0.0, 5.0, 0.0)); m_arrow.render(); From 8c560522a3229021d561d909ba5b6552888b65bf Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Fri, 28 May 2021 15:44:39 +0200 Subject: [PATCH 27/31] Fixed rendering of gizmo grabbers --- src/slic3r/GUI/Gizmos/GLGizmoBase.cpp | 12 +++++++++--- src/slic3r/GUI/Gizmos/GLGizmoBase.hpp | 4 +++- src/slic3r/GUI/Gizmos/GLGizmoMove.cpp | 12 ++++++++---- src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp | 12 ++++++++---- 4 files changed, 28 insertions(+), 12 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp index e284822d2..98729bd7f 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp @@ -21,9 +21,6 @@ GLGizmoBase::Grabber::Grabber() , enabled(true) { color = { 1.0f, 1.0f, 1.0f, 1.0f }; - TriangleMesh mesh = make_cube(1., 1., 1.); - mesh.translate(Vec3f(-0.5, -0.5, -0.5)); - cube.init_from(mesh); } void GLGizmoBase::Grabber::render(bool hover, float size) const @@ -53,6 +50,15 @@ float GLGizmoBase::Grabber::get_dragging_half_size(float size) const void GLGizmoBase::Grabber::render(float size, const std::array& render_color, bool picking) const { + if (! cube_initialized) { + // This cannot be done in constructor, OpenGL is not yet + // initialized at that point (on Linux at least). + TriangleMesh mesh = make_cube(1., 1., 1.); + mesh.translate(Vec3f(-0.5, -0.5, -0.5)); + const_cast(cube).init_from(mesh); + const_cast(cube_initialized) = true; + } + float fullsize = 2 * (dragging ? get_dragging_half_size(size) : get_half_size(size)); GLShaderProgram* shader = picking ? nullptr : wxGetApp().get_current_shader(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp index 854f740b9..ac83b794b 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp @@ -48,7 +48,6 @@ protected: static const float MinHalfSize; static const float DraggingScaleFactor; - GLModel cube; Vec3d center; Vec3d angles; std::array color; @@ -65,6 +64,9 @@ protected: private: void render(float size, const std::array& render_color, bool picking) const; + + GLModel cube; + bool cube_initialized = false; }; public: diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp index 458c3233a..84282f0a8 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp @@ -199,9 +199,12 @@ void GLGizmoMove3D::render_grabber_extension(Axis axis, const BoundingBoxf3& box if (shader == nullptr) return; - shader->start_using(); - shader->set_uniform("emission_factor", 0.1); - shader->set_uniform("uniform_color", color); + if (! picking) { + shader->start_using(); + shader->set_uniform("emission_factor", 0.1); + shader->set_uniform("uniform_color", color); + } else + glsafe(::glColor4fv(color.data())); glsafe(::glPushMatrix()); glsafe(::glTranslated(m_grabbers[axis].center.x(), m_grabbers[axis].center.y(), m_grabbers[axis].center.z())); @@ -215,7 +218,8 @@ void GLGizmoMove3D::render_grabber_extension(Axis axis, const BoundingBoxf3& box m_vbo_cone.render(); glsafe(::glPopMatrix()); - shader->stop_using(); + if (! picking) + shader->stop_using(); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp index a1adbc95f..f72ea014d 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp @@ -336,9 +336,12 @@ void GLGizmoRotate::render_grabber_extension(const BoundingBoxf3& box, bool pick if (shader == nullptr) return; - shader->start_using(); - shader->set_uniform("emission_factor", 0.1); - shader->set_uniform("uniform_color", color); + if (! picking) { + shader->start_using(); + shader->set_uniform("emission_factor", 0.1); + shader->set_uniform("uniform_color", color); + } else + glsafe(::glColor4fv(color.data())); glsafe(::glPushMatrix()); glsafe(::glTranslated(m_grabbers[0].center.x(), m_grabbers[0].center.y(), m_grabbers[0].center.z())); @@ -357,7 +360,8 @@ void GLGizmoRotate::render_grabber_extension(const BoundingBoxf3& box, bool pick m_cone.render(); glsafe(::glPopMatrix()); - shader->stop_using(); + if (! picking) + shader->stop_using(); } void GLGizmoRotate::transform_to_local(const Selection& selection) const From 7f29647d6775dae9ad8890b37e552ef686197463 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hejl?= Date: Sat, 29 May 2021 19:55:20 +0200 Subject: [PATCH 28/31] Added missing includes (GCC 11.1) --- src/libslic3r/SLA/Hollowing.cpp | 1 + src/libslic3r/SLA/SupportTreeBuildsteps.hpp | 1 + 2 files changed, 2 insertions(+) diff --git a/src/libslic3r/SLA/Hollowing.cpp b/src/libslic3r/SLA/Hollowing.cpp index 1d3016bde..32a881037 100644 --- a/src/libslic3r/SLA/Hollowing.cpp +++ b/src/libslic3r/SLA/Hollowing.cpp @@ -1,4 +1,5 @@ #include +#include #include #include diff --git a/src/libslic3r/SLA/SupportTreeBuildsteps.hpp b/src/libslic3r/SLA/SupportTreeBuildsteps.hpp index 013666f07..478e2df1f 100644 --- a/src/libslic3r/SLA/SupportTreeBuildsteps.hpp +++ b/src/libslic3r/SLA/SupportTreeBuildsteps.hpp @@ -2,6 +2,7 @@ #define SLASUPPORTTREEALGORITHM_H #include +#include #include #include From 02a0955a5f7ac1b65d1b1c801252bf746dd808b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hejl?= Date: Sat, 29 May 2021 19:56:20 +0200 Subject: [PATCH 29/31] Fixed possible wrongly filled ZIP headers in case that pState->m_zip64 is sets to true. --- src/miniz/miniz.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/miniz/miniz.c b/src/miniz/miniz.c index d7abeaf3b..0d6fc7d9b 100644 --- a/src/miniz/miniz.c +++ b/src/miniz/miniz.c @@ -5953,16 +5953,18 @@ static mz_uint32 mz_zip_writer_create_zip64_extra_data(mz_uint8 *pBuf, mz_uint64 static mz_bool mz_zip_writer_create_local_dir_header(mz_zip_archive *pZip, mz_uint8 *pDst, mz_uint16 filename_size, mz_uint16 extra_size, mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32, mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date) { + (void)pZip; + mz_bool is_zip64_needed = uncomp_size >= MZ_UINT32_MAX || comp_size >= MZ_UINT32_MAX; memset(pDst, 0, MZ_ZIP_LOCAL_DIR_HEADER_SIZE); MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_SIG_OFS, MZ_ZIP_LOCAL_DIR_HEADER_SIG); - MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_VERSION_NEEDED_OFS, (pZip->m_pState->m_zip64) ? 0x002D : (method ? 0x0014 : 0x0000)); + MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_VERSION_NEEDED_OFS, is_zip64_needed ? 0x002D : (method ? 0x0014 : 0x0000)); MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_BIT_FLAG_OFS, bit_flags); MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_METHOD_OFS, method); MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILE_TIME_OFS, dos_time); MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILE_DATE_OFS, dos_date); MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_CRC32_OFS, uncomp_crc32); - MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_COMPRESSED_SIZE_OFS, (pZip->m_pState->m_zip64 || comp_size > MZ_UINT32_MAX) ? MZ_UINT32_MAX : comp_size); - MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS, (pZip->m_pState->m_zip64 || uncomp_size > MZ_UINT32_MAX) ? MZ_UINT32_MAX : uncomp_size); + MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_COMPRESSED_SIZE_OFS, is_zip64_needed ? MZ_UINT32_MAX : comp_size); + MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS, is_zip64_needed ? MZ_UINT32_MAX : uncomp_size); MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILENAME_LEN_OFS, filename_size); MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_EXTRA_LEN_OFS, extra_size); return MZ_TRUE; @@ -5974,7 +5976,7 @@ static mz_bool mz_zip_writer_create_central_dir_header(mz_zip_archive *pZip, mz_ mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date, mz_uint64 local_header_ofs, mz_uint32 ext_attributes) { - mz_zip_internal_state *pState = pZip->m_pState; + (void)pZip; mz_bool is_zip64_needed = uncomp_size >= MZ_UINT32_MAX || comp_size >= MZ_UINT32_MAX; memset(pDst, 0, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE); MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_SIG_OFS, MZ_ZIP_CENTRAL_DIR_HEADER_SIG); @@ -6793,13 +6795,7 @@ mz_bool mz_zip_writer_add_staged_open(mz_zip_archive* pZip, mz_zip_writer_staged } MZ_CLEAR_OBJ(local_dir_header); - if (pState->m_zip64) - { - pContext->pExtra_data = pContext->extra_data; - pContext->extra_size = mz_zip_writer_create_zip64_extra_data(pContext->extra_data, &pContext->uncomp_size, &pContext->comp_size, - (pContext->local_dir_header_ofs >= MZ_UINT32_MAX) ? &pContext->local_dir_header_ofs : NULL); - } - else if (!pState->m_zip64 && max_size > MZ_UINT32_MAX) + if (max_size > MZ_UINT32_MAX) { pContext->pExtra_data = pContext->extra_data; pContext->extra_size = mz_zip_writer_preallocate_extra_data(pContext->extra_data, 2 * sizeof(mz_uint64)); From 0d721bfb07a32b629f4f961df3f4fafba2113d80 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Mon, 31 May 2021 11:16:28 +0200 Subject: [PATCH 30/31] Slightly reworded 'missing layers' warning, to reflect that it is no longer considered an error --- src/libslic3r/GCode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 208363f35..efcd5e210 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -542,7 +542,7 @@ std::vector GCode::collect_layers_to_print(const PrintObjec if (has_extrusions && layer_to_print.print_z() > maximal_print_z + 2. * EPSILON) { const_cast(object.print())->active_step_add_warning(PrintStateBase::WarningLevel::CRITICAL, - _(L("Empty layers detected, the output would not be printable.")) + "\n\n" + + _(L("Empty layers detected. Make sure the object is printable.")) + "\n\n" + _(L("Object name")) + ": " + object.model_object()->name + "\n" + _(L("Print z")) + ": " + std::to_string(layers_to_print.back().print_z()) + "\n\n" + _(L("This is " "usually caused by negligibly small extrusions or by a faulty model. Try to repair " From b30a6d588390ec50b60828e4560dd252b9155993 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Mon, 31 May 2021 11:48:12 +0200 Subject: [PATCH 31/31] Unify Delete/Backspace behaviour in gizmos with the rest of slicer. Also, backspace on macOS in SLA gizmo now deletes points and not the whole object, which was quite unexpected. --- src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index bd02cbbbb..d1d2b277e 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -774,11 +774,9 @@ bool GLGizmosManager::on_char(wxKeyEvent& evt) break; } -#ifdef __APPLE__ - case WXK_BACK: // the low cost Apple solutions are not equipped with a Delete key, use Backspace instead. -#else /* __APPLE__ */ + + case WXK_BACK: case WXK_DELETE: -#endif /* __APPLE__ */ { if ((m_current == SlaSupports || m_current == Hollow) && gizmo_event(SLAGizmoEventType::Delete)) processed = true;