From 273fcf68a134b0c7526663049fad2f5636b67488 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Mon, 25 Mar 2019 10:47:23 +0100 Subject: [PATCH] SLA gizmo now uses glClipPlane instead of touching projection matrix Messing with the projection matrix invalidates the z-buffer This currently only works in OpenGL legacy mode --- src/slic3r/GUI/GLCanvas3D.cpp | 36 +++++++++----------- src/slic3r/GUI/GLCanvas3D.hpp | 2 +- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp | 25 ++++++-------- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp | 3 +- 4 files changed, 30 insertions(+), 36 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 6f55e4059..3e4824cde 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1319,16 +1319,16 @@ bool GLCanvas3D::Gizmos::gizmo_event(SLAGizmoEventType action, const Vec2d& mous -std::pair GLCanvas3D::Gizmos::get_sla_clipping_plane() const +GLCanvas3D::ClippingPlane GLCanvas3D::Gizmos::get_sla_clipping_plane() const { if (!m_enabled) - return std::make_pair(0.f, 0.f); + return ClippingPlane(); GizmosMap::const_iterator it = m_gizmos.find(SlaSupports); if (it != m_gizmos.end()) return reinterpret_cast(it->second)->get_sla_clipping_plane(); - return std::make_pair(0.f, 0.f);; + return ClippingPlane(); } @@ -4706,19 +4706,17 @@ void GLCanvas3D::set_sla_clipping(bool enable) const return; if (enable) { - ::glMatrixMode(GL_PROJECTION); - ::glPushMatrix(); - ::glMatrixMode(GL_MODELVIEW); - const Size& cnv_size = get_canvas_size(); - std::pair clipping_limits = m_gizmos.get_sla_clipping_plane(); - set_ortho_projection((unsigned int)cnv_size.get_width(), (unsigned int)cnv_size.get_height(), clipping_limits.first, clipping_limits.second); - } - else { - ::glMatrixMode(GL_PROJECTION); - ::glPopMatrix(); - ::glMatrixMode(GL_MODELVIEW); - ::glClear(GL_DEPTH_BUFFER_BIT); + ClippingPlane gizmo_clipping_plane; + try { + gizmo_clipping_plane = m_gizmos.get_sla_clipping_plane(); + } + catch (...) { return; } + + ::glClipPlane(GL_CLIP_PLANE0, (GLdouble*)gizmo_clipping_plane.get_data()); + ::glEnable(GL_CLIP_PLANE0); } + else + ::glDisable(GL_CLIP_PLANE0); } @@ -4774,10 +4772,10 @@ void GLCanvas3D::_render_objects() const { if (m_use_clipping_planes) { - ::glClipPlane(GL_CLIP_PLANE0, (GLdouble*)m_clipping_planes[0].get_data()); - ::glEnable(GL_CLIP_PLANE0); - ::glClipPlane(GL_CLIP_PLANE1, (GLdouble*)m_clipping_planes[1].get_data()); + ::glClipPlane(GL_CLIP_PLANE1, (GLdouble*)m_clipping_planes[0].get_data()); ::glEnable(GL_CLIP_PLANE1); + ::glClipPlane(GL_CLIP_PLANE2, (GLdouble*)m_clipping_planes[1].get_data()); + ::glEnable(GL_CLIP_PLANE2); } // do not cull backfaces to show broken geometry, if any @@ -4788,8 +4786,8 @@ void GLCanvas3D::_render_objects() const if (m_use_clipping_planes) { - ::glDisable(GL_CLIP_PLANE0); ::glDisable(GL_CLIP_PLANE1); + ::glDisable(GL_CLIP_PLANE2); } } diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 44c43a1e3..b09f3746f 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -448,7 +448,7 @@ private: void set_sla_support_data(ModelObject* model_object, const Selection& selection); bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position = Vec2d::Zero(), bool shift_down = false); - std::pair get_sla_clipping_plane() const; + ClippingPlane get_sla_clipping_plane() const; void render_current_gizmo(const Selection& selection) const; void render_current_gizmo_for_picking_pass(const Selection& selection) const; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index 07eec27e2..65be22b44 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -612,47 +612,42 @@ void GLGizmoSlaSupports::update_cache_entry_normal(unsigned int i) const -std::pair GLGizmoSlaSupports::get_sla_clipping_plane() const +GLCanvas3D::ClippingPlane GLGizmoSlaSupports::get_sla_clipping_plane() const { if (!m_model_object) - return std::make_pair(0.f, 0.f);; + throw std::invalid_argument("GLGizmoSlaSupports::get_sla_clipping_plane() has no model object pointer."); Eigen::Matrix modelview_matrix; ::glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix.data()); - // clipping space origin transformed to world coords: - Vec3d clipping_origin = (modelview_matrix.inverse() * Eigen::Matrix{0, 0, 0, 1}).block<3,1>(0,0); - // we'll recover current look direction from the modelview matrix (in world coords): Vec3d direction_to_camera(modelview_matrix.data()[2], modelview_matrix.data()[6], modelview_matrix.data()[10]); - float dist = direction_to_camera.dot(clipping_origin) - direction_to_camera.dot(m_active_instance_bb.center()); + float dist = direction_to_camera.dot(m_active_instance_bb.center()); - return std::make_pair((dist - m_active_instance_bb.radius()) + m_clipping_plane_distance * 2*m_active_instance_bb.radius(), dist + 5.f*m_active_instance_bb.radius()); + return GLCanvas3D::ClippingPlane(-direction_to_camera.normalized(),(dist - (-m_active_instance_bb.radius()) - m_clipping_plane_distance * 2*m_active_instance_bb.radius())); } /* -void GLGizmoSlaSupports::find_intersections(const igl::AABB* aabb, const Vec3f& normal, double offset, std::vector& idxs) const +void GLGizmoSlaSupports::find_intersecting_facets(const igl::AABB* aabb, const Vec3f& normal, double offset, std::vector& idxs) const { if (aabb->is_leaf()) { // this is a facet // corner.dot(normal) - offset - unsigned int facet_idx = aabb->m_primitive; - - Vec3f a = m_V.row(m_F(facet_idx, 0)); - Vec3f b = m_V.row(m_F(facet_idx, 1)); - Vec3f c = m_V.row(m_F(facet_idx, 2)); + idxs.push_back(aabb->m_primitive); } else { // not a leaf using CornerType = Eigen::AlignedBox::CornerType; bool sign = std::signbit(offset - normal.dot(aabb->m_box.corner(CornerType(0)))); for (unsigned int i=1; i<8; ++i) if (std::signbit(offset - normal.dot(aabb->m_box.corner(CornerType(i)))) != sign) { - find_intersections(aabb->m_left, normal, offset, idxs); - find_intersections(aabb->m_right, normal, offset, idxs); + find_intersecting_facets(aabb->m_left, normal, offset, idxs); + find_intersecting_facets(aabb->m_right, normal, offset, idxs); } } } + + void GLGizmoSlaSupports::make_line_segments() const { TriangleMeshSlicer tms(&m_model_object->volumes.front()->mesh); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp index 872e3541f..f61709d61 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp @@ -52,7 +52,7 @@ public: void set_sla_support_data(ModelObject* model_object, const Selection& selection); bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down); void delete_selected_points(bool force = false); - std::pair get_sla_clipping_plane() const; + GLCanvas3D::ClippingPlane get_sla_clipping_plane() const; private: bool on_init(); @@ -87,6 +87,7 @@ private: std::vector get_config_options(const std::vector& keys) const; bool is_point_clipped(const Vec3d& point, const Vec3d& direction_to_camera, float z_shift) const; + void find_intersecting_facets(const igl::AABB* aabb, const Vec3f& normal, double offset, std::vector& out) const; // Methods that do the model_object and editing cache synchronization, // editing mode selection, etc: