diff --git a/src/libslic3r/Format/3mf.cpp b/src/libslic3r/Format/3mf.cpp index 59dc85a0ae..c25b7b96a5 100644 --- a/src/libslic3r/Format/3mf.cpp +++ b/src/libslic3r/Format/3mf.cpp @@ -1103,7 +1103,7 @@ namespace Slic3r { sla::DrainHoles sla_drain_holes; - if (version == 1) { + if (version == 1 || version == 2) { for (unsigned int i=0; i; +constexpr float HoleStickOutLength = 1.f; + std::unique_ptr generate_interior(const TriangleMesh &mesh, const HollowingConfig & = {}, const JobController &ctl = {}); diff --git a/src/libslic3r/SLA/ReprojectPointsOnMesh.hpp b/src/libslic3r/SLA/ReprojectPointsOnMesh.hpp index 4737a6c212..20804193e2 100644 --- a/src/libslic3r/SLA/ReprojectPointsOnMesh.hpp +++ b/src/libslic3r/SLA/ReprojectPointsOnMesh.hpp @@ -28,15 +28,9 @@ void reproject_support_points(const IndexedMesh &mesh, std::vector &p inline void reproject_points_and_holes(ModelObject *object) { bool has_sppoints = !object->sla_support_points.empty(); + bool has_holes = !object->sla_drain_holes.empty(); - // Disabling reprojection of holes as they have a significant offset away - // from the model body which tolerates minor geometrical changes. - // - // TODO: uncomment and ensure the right offset of the hole points if - // reprojection would still be necessary. - // bool has_holes = !object->sla_drain_holes.empty(); - - if (!object || (/*!has_holes &&*/ !has_sppoints)) return; + if (!object || (!has_holes && !has_sppoints)) return; TriangleMesh rmsh = object->raw_mesh(); rmsh.require_shared_vertices(); @@ -45,8 +39,8 @@ inline void reproject_points_and_holes(ModelObject *object) if (has_sppoints) reproject_support_points(emesh, object->sla_support_points); -// if (has_holes) -// reproject_support_points(emesh, object->sla_drain_holes); + if (has_holes) + reproject_support_points(emesh, object->sla_drain_holes); } }} diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index 4395bea461..07ec380160 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -1181,6 +1181,12 @@ sla::DrainHoles SLAPrintObject::transformed_drainhole_points() const hl.normal = Vec3f(hl.normal(0)/(sc(0)*sc(0)), hl.normal(1)/(sc(1)*sc(1)), hl.normal(2)/(sc(2)*sc(2))); + + // Now shift the hole a bit above the object and make it deeper to + // compensate for it. This is to avoid problems when the hole is placed + // on (nearly) flat surface. + hl.pos -= hl.normal.normalized() * sla::HoleStickOutLength; + hl.height += sla::HoleStickOutLength; } return pts; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp index 273384da2e..04ada52536 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp @@ -130,7 +130,7 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking) cons const sla::DrainHole& drain_hole = drain_holes[i]; const bool& point_selected = m_selected[i]; - if (is_mesh_point_clipped((drain_hole.pos+HoleStickOutLength*drain_hole.normal).cast())) + if (is_mesh_point_clipped(drain_hole.pos.cast())) continue; // First decide about the color of the point. @@ -174,10 +174,10 @@ 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, 24, 1); - 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)); + 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(::glPopMatrix()); @@ -307,13 +307,8 @@ bool GLGizmoHollow::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_pos if (unproject_on_mesh(mouse_position, pos_and_normal)) { // we got an intersection Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("Add drainage hole"))); - Vec3d scaling = mo->instances[active_inst]->get_scaling_factor(); - Vec3f normal_transformed(pos_and_normal.second(0)/scaling(0), - pos_and_normal.second(1)/scaling(1), - pos_and_normal.second(2)/scaling(2)); - - mo->sla_drain_holes.emplace_back(pos_and_normal.first + HoleStickOutLength * pos_and_normal.second/* normal_transformed.normalized()*/, - -pos_and_normal.second, m_new_hole_radius, m_new_hole_height); + mo->sla_drain_holes.emplace_back(pos_and_normal.first, + -pos_and_normal.second, m_new_hole_radius, m_new_hole_height); m_selected.push_back(false); assert(m_selected.size() == mo->sla_drain_holes.size()); m_parent.set_as_dirty(); @@ -447,7 +442,7 @@ void GLGizmoHollow::on_update(const UpdateData& data) std::pair pos_and_normal; if (! unproject_on_mesh(data.mouse_pos.cast(), pos_and_normal)) return; - drain_holes[m_hover_id].pos = pos_and_normal.first + HoleStickOutLength * pos_and_normal.second; + drain_holes[m_hover_id].pos = pos_and_normal.first; drain_holes[m_hover_id].normal = -pos_and_normal.second; } } @@ -661,9 +656,7 @@ RENDER_AGAIN: m_imgui->text(m_desc["hole_depth"]); ImGui::SameLine(diameter_slider_left); - m_new_hole_height -= HoleStickOutLength; ImGui::SliderFloat(" ", &m_new_hole_height, 0.f, 10.f, "%.1f mm"); - m_new_hole_height += HoleStickOutLength; clicked |= ImGui::IsItemClicked(); edited |= ImGui::IsItemEdited(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index 2856bb35de..bc29da6d2b 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -222,7 +222,7 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) render_color[3] = 0.7f; glsafe(::glColor4fv(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+HoleStickOutLength*drain_hole.normal).cast())) + if (is_mesh_point_clipped(drain_hole.pos.cast())) continue; // Inverse matrix of the instance scaling is applied so that the mark does not scale with the object. @@ -241,10 +241,10 @@ 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, 24, 1); - 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)); + 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(::glPopMatrix()); diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp index 31c473bac7..aedf782e89 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp @@ -15,8 +15,6 @@ namespace GUI { class GLCanvas3D; -static constexpr float HoleStickOutLength = 1.f; - enum class SLAGizmoEventType : unsigned char { LeftDown = 1, LeftUp,