diff --git a/src/libslic3r/SLA/Hollowing.hpp b/src/libslic3r/SLA/Hollowing.hpp index 5d2181e7a..1778c692a 100644 --- a/src/libslic3r/SLA/Hollowing.hpp +++ b/src/libslic3r/SLA/Hollowing.hpp @@ -36,6 +36,7 @@ struct DrainHole Vec3f normal; float radius; float height; + bool failed = false; DrainHole() : pos(Vec3f::Zero()), normal(Vec3f::UnitZ()), radius(5.f), height(10.f) diff --git a/src/libslic3r/SLAPrintSteps.cpp b/src/libslic3r/SLAPrintSteps.cpp index 22fee6976..4d8abb798 100644 --- a/src/libslic3r/SLAPrintSteps.cpp +++ b/src/libslic3r/SLAPrintSteps.cpp @@ -244,6 +244,8 @@ static std::vector create_exclude_mask( Vec3f face_normal = C.normalized(); for (const sla::DrainHole &dh : holes) { + if (dh.failed) continue; + Vec3d dhpos = dh.pos.cast(); Vec3d dhend = dhpos + dh.normal.cast() * dh.height; @@ -312,41 +314,42 @@ void SLAPrint::Steps::drill_holes(SLAPrintObject &po) BOOST_LOG_TRIVIAL(info) << "Drilling drainage holes."; sla::DrainHoles drainholes = po.transformed_drainhole_points(); + + auto hollowed_mesh_cgal = MeshBoolean::cgal::triangle_mesh_to_cgal(hollowed_mesh); + + bool hole_fail = false; + for (size_t i = 0; i < drainholes.size(); ++i) { + const sla::DrainHole &holept = drainholes[i]; + po.model_object()->sla_drain_holes[i].failed = false; - std::uniform_real_distribution dist(0., float(EPSILON)); - auto holes_mesh_cgal = MeshBoolean::cgal::triangle_mesh_to_cgal({}); - for (sla::DrainHole holept : drainholes) { - holept.normal += Vec3f{dist(m_rng), dist(m_rng), dist(m_rng)}; - holept.normal.normalize(); - holept.pos += Vec3f{dist(m_rng), dist(m_rng), dist(m_rng)}; TriangleMesh m = sla::to_triangle_mesh(holept.to_mesh()); m.require_shared_vertices(); auto cgal_m = MeshBoolean::cgal::triangle_mesh_to_cgal(m); - MeshBoolean::cgal::plus(*holes_mesh_cgal, *cgal_m); + + try { + MeshBoolean::cgal::minus(*hollowed_mesh_cgal, *cgal_m); + } catch (const std::runtime_error &) { + BOOST_LOG_TRIVIAL(error) << "Failed to drill hole"; + + hole_fail = drainholes[i].failed = + po.model_object()->sla_drain_holes[i].failed = true; + } } - if (MeshBoolean::cgal::does_self_intersect(*holes_mesh_cgal)) - throw Slic3r::SlicingError(L("Too many overlapping holes.")); + if (hole_fail) + po.active_step_add_warning(PrintStateBase::WarningLevel::NON_CRITICAL, + L("Failed to drill some holes into the model")); - auto hollowed_mesh_cgal = MeshBoolean::cgal::triangle_mesh_to_cgal(hollowed_mesh); - try { - MeshBoolean::cgal::minus(*hollowed_mesh_cgal, *holes_mesh_cgal); - hollowed_mesh = MeshBoolean::cgal::cgal_to_triangle_mesh(*hollowed_mesh_cgal); - mesh_view = hollowed_mesh; + hollowed_mesh = MeshBoolean::cgal::cgal_to_triangle_mesh(*hollowed_mesh_cgal); + mesh_view = hollowed_mesh; - if (is_hollowed) { - auto &interior = *po.m_hollowing_data->interior; - std::vector exclude_mask = - create_exclude_mask(mesh_view.its, interior, drainholes); + if (is_hollowed) { + auto &interior = *po.m_hollowing_data->interior; + std::vector exclude_mask = + create_exclude_mask(mesh_view.its, interior, drainholes); - sla::remove_inside_triangles(mesh_view, interior, exclude_mask); - } - - } catch (const std::runtime_error &) { - throw Slic3r::SlicingError(L( - "Drilling holes into the mesh failed. " - "This is usually caused by broken model. Try to fix it first.")); + sla::remove_inside_triangles(mesh_view, interior, exclude_mask); } } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp index 3d0d9c79a..67133956d 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp @@ -125,6 +125,8 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking) cons float render_color[4]; const sla::DrainHoles& drain_holes = m_c->selection_info()->model_object()->sla_drain_holes; size_t cache_size = drain_holes.size(); + + const auto *hollowed_mesh = m_c->hollowed_mesh(); for (size_t i = 0; i < cache_size; ++i) { const sla::DrainHole& drain_hole = drain_holes[i]; @@ -136,6 +138,13 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking) cons // First decide about the color of the point. if (picking) { std::array color = picking_color_component(i); + + if (hollowed_mesh && i < hollowed_mesh->get_drainholes().size() && hollowed_mesh->get_drainholes()[i].failed) { + render_color[0] = 1.f; + render_color[1] = 1.f; + render_color[2] = 0.f; + render_color[3] = color[3]; + } render_color[0] = color[0]; render_color[1] = color[1]; render_color[2] = color[2]; @@ -149,9 +158,15 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking) cons render_color[2] = 1.0f; } 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; + if (hollowed_mesh && i < hollowed_mesh->get_drainholes().size() && hollowed_mesh->get_drainholes()[i].failed) { + render_color[0] = 1.f; + render_color[1] = 1.f; + render_color[2] = 0.f; + } else { + 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[3] = 0.5f; } } diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp index 7f6b10670..acb85d539 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp @@ -205,6 +205,7 @@ void HollowedMesh::on_update() m_hollowed_mesh_transformed.reset(new TriangleMesh(backend_mesh)); Transform3d trafo_inv = canvas->sla_print()->sla_trafo(*mo).inverse(); m_hollowed_mesh_transformed->transform(trafo_inv); + m_drainholes = print_object->model_object()->sla_drain_holes; m_old_hollowing_timestamp = timestamp; const TriangleMesh &interior = print_object->hollowed_interior_mesh(); @@ -215,8 +216,9 @@ void HollowedMesh::on_update() m_hollowed_interior_transformed->transform(trafo_inv); } } - else + else { m_hollowed_mesh_transformed.reset(nullptr); + } } } else diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp index ace256748..28be1b97f 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp @@ -5,6 +5,7 @@ #include #include "slic3r/GUI/MeshUtils.hpp" +#include "libslic3r/SLA/Hollowing.hpp" namespace Slic3r { @@ -198,6 +199,8 @@ public: CommonGizmosDataID get_dependencies() const override { return CommonGizmosDataID::SelectionInfo; } #endif // NDEBUG + const sla::DrainHoles &get_drainholes() const { return m_drainholes; } + const TriangleMesh* get_hollowed_mesh() const; const TriangleMesh* get_hollowed_interior() const; @@ -211,6 +214,7 @@ private: size_t m_old_hollowing_timestamp = 0; int m_print_object_idx = -1; int m_print_objects_count = 0; + sla::DrainHoles m_drainholes; };