diff --git a/src/libslic3r/SLA/Hollowing.cpp b/src/libslic3r/SLA/Hollowing.cpp index ecc42b889..2a9662e85 100644 --- a/src/libslic3r/SLA/Hollowing.cpp +++ b/src/libslic3r/SLA/Hollowing.cpp @@ -119,7 +119,7 @@ Contour3D DrainHole::to_mesh() const { auto r = double(radius); auto h = double(height); - sla::Contour3D hole = sla::cylinder(r, h); + sla::Contour3D hole = sla::cylinder(r, h, steps); Eigen::Quaterniond q; q.setFromTwoVectors(Vec3d{0., 0., 1.}, normal.cast<double>()); for(auto& p : hole.points) p = q * p + pos.cast<double>(); diff --git a/src/libslic3r/SLA/Hollowing.hpp b/src/libslic3r/SLA/Hollowing.hpp index b3375ed1a..cc7d310ea 100644 --- a/src/libslic3r/SLA/Hollowing.hpp +++ b/src/libslic3r/SLA/Hollowing.hpp @@ -34,6 +34,9 @@ struct DrainHole DrainHole(Vec3f p, Vec3f n, float r, float h) : pos(p), normal(n), radius(r), height(h) {} + + DrainHole(const DrainHole& rhs) : + DrainHole(rhs.pos, rhs.normal, rhs.radius, rhs.height) {} bool operator==(const DrainHole &sp) const; @@ -50,6 +53,8 @@ struct DrainHole { ar(pos, normal, radius, height); } + + static constexpr size_t steps = 32; }; using DrainHoles = std::vector<DrainHole>; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp index c237198a9..daf7e1fd1 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp @@ -384,7 +384,7 @@ bool CommonGizmosData::update_from_backend(GLCanvas3D& canvas, ModelObject* mode if (! recent_update) recent_update = m_print_object_idx < 0 && old_po_idx >= 0; - return m_print_object_idx < 0 ? old_po_idx >=0 : false; + return recent_update; } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp index 11a78fd60..87a4960ee 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp @@ -12,7 +12,6 @@ #include "slic3r/GUI/PresetBundle.hpp" #include "libslic3r/SLAPrint.hpp" #include "libslic3r/TriangleMesh.hpp" -#include "libslic3r/MeshBoolean.hpp" namespace Slic3r { @@ -59,8 +58,11 @@ void GLGizmoHollow::set_sla_support_data(ModelObject*, const Selection&) { if (m_c->recent_update) { - if (m_c->m_model_object) + if (m_c->m_model_object) { reload_cache(); + if (m_c->has_drilled_mesh()) + m_holes_in_drilled_mesh = m_c->m_model_object->sla_drain_holes; + } if (m_state == On) { m_parent.toggle_model_objects_visibility(false); @@ -344,18 +346,25 @@ bool GLGizmoHollow::unproject_on_mesh(const Vec2d& mouse_pos, std::pair<Vec3f, V // The raycaster query Vec3f hit; Vec3f normal; - if (m_c->m_mesh_raycaster->unproject_on_mesh(mouse_pos, trafo.get_matrix(), camera, hit, normal, m_c->m_clipping_plane.get())) { - - // User is about to manipulate a hole. If the gizmo currently shows drilled mesh, - // invalidate slaposDrillHoles so it returns to normal. To do this, hackishly - // add a hole, force SLAPrint::apply call that will invalidate the step because - // of it and then remove the hole again. + if (m_c->m_mesh_raycaster->unproject_on_mesh( + mouse_pos, + trafo.get_matrix(), + camera, + hit, + normal, + m_c->m_clipping_plane_distance != 0.f ? m_c->m_clipping_plane.get() : nullptr)) + { if (m_c->has_drilled_mesh()) { - m_c->m_model_object->sla_drain_holes.push_back(sla::DrainHole()); - m_selected.push_back(false); - m_parent.post_event(SimpleEvent(EVT_GLCANVAS_FORCE_UPDATE)); - wxGetApp().CallAfter([this] { m_c->m_model_object->sla_drain_holes.pop_back(); m_selected.pop_back(); }); - return false; + // in this case the raycaster sees the hollowed and drilled mesh. + // if the point lies on the surface created by the hole, we want + // to ignore it. + for (const sla::DrainHole& hole : m_holes_in_drilled_mesh) { + sla::DrainHole outer(hole); + outer.radius *= 1.001f; + outer.height *= 1.001f; + if (outer.is_inside(hit)) + return false; + } } // Return both the point and the facet normal. @@ -527,8 +536,6 @@ void GLGizmoHollow::delete_selected_points() } } - m_parent.post_event(SimpleEvent(EVT_GLCANVAS_FORCE_UPDATE)); - select_point(NoPoints); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp index c0e518e4d..2daf28b2a 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp @@ -70,6 +70,7 @@ private: float m_quality_stash = 0.5f; float m_closing_d_stash = 2.f; Vec3f m_hole_before_drag = Vec3f::Zero(); + sla::DrainHoles m_holes_in_drilled_mesh; sla::DrainHoles m_holes_stash; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index 5130b7a9a..05f33ae52 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -408,7 +408,14 @@ bool GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse_pos, std::pair<Vec // The raycaster query Vec3f hit; Vec3f normal; - if (m_c->m_mesh_raycaster->unproject_on_mesh(mouse_pos, trafo.get_matrix(), camera, hit, normal, m_c->m_clipping_plane.get())) { + if (m_c->m_mesh_raycaster->unproject_on_mesh( + mouse_pos, + trafo.get_matrix(), + camera, + hit, + normal, + m_c->m_clipping_plane_distance != 0.f ? m_c->m_clipping_plane.get() : nullptr)) + { // Check whether the hit is in a hole bool in_hole = false; // In case the hollowed and drilled mesh is available, we can allow