From 13d99fd843b5c37c450b206a1902d91186b5306c Mon Sep 17 00:00:00 2001 From: sunsets <845944018@qq.com> Date: Mon, 20 May 2024 16:05:53 +0800 Subject: [PATCH] Exclude region judgment before optimizing slice --- src/libslic3r/BuildVolume.cpp | 49 ++++++++++++++++------------------- src/libslic3r/BuildVolume.hpp | 2 ++ src/libslic3r/Model.cpp | 10 +++++++ src/libslic3r/Model.hpp | 2 ++ src/slic3r/GUI/GLCanvas3D.cpp | 13 ++++++++++ 5 files changed, 49 insertions(+), 27 deletions(-) diff --git a/src/libslic3r/BuildVolume.cpp b/src/libslic3r/BuildVolume.cpp index 946c698..e50e056 100644 --- a/src/libslic3r/BuildVolume.cpp +++ b/src/libslic3r/BuildVolume.cpp @@ -311,47 +311,42 @@ BuildVolume::ObjectState BuildVolume::object_state(const indexed_triangle_set& i } } -//B52 +// B52 //B66 BuildVolume::ObjectState BuildVolume::volume_state_bbox(const BoundingBoxf3& volume_bbox, bool ignore_bottom) const { assert(m_type == Type::Rectangle); BoundingBox3Base build_volume = this->bounding_volume().inflated(SceneEpsilon); - std::vector> exclude_build_volume; + if (m_max_print_height == 0.0) + build_volume.max.z() = std::numeric_limits::max(); + if (ignore_bottom) + build_volume.min.z() = -std::numeric_limits::max(); + + return build_volume.max.z() <= -SceneEpsilon ? ObjectState::Below : + build_volume.contains(volume_bbox) ? ObjectState::Inside : + build_volume.intersects(volume_bbox) ? ObjectState::Colliding : + ObjectState::Outside; +} + +// B66 +BuildVolume::ObjectState BuildVolume::check_outside(Polygon hull) const +{ + if (m_exclude_bed_shape.size() > 0) { for (int i = 1; i < m_exclude_bed_shape.size(); i += 7) { std::vector tem_exclude_bed_shap; for (int j = 1; j < 6; j++) tem_exclude_bed_shap.push_back(m_exclude_bed_shape[i + j]); BoundingBoxf tem_bboxf = get_extents(tem_exclude_bed_shap); auto tem_exclude_bboxf = BoundingBoxf3{to_3d(tem_bboxf.min, 0.), to_3d(tem_bboxf.max, m_max_print_height)}; - BoundingBox3Base tem_build_volume = tem_exclude_bboxf.inflated(SceneEpsilon); - exclude_build_volume.push_back(tem_build_volume); - } - - bool is_contain = false; - bool is_intersect = false; - - for (const auto &tem_build_volume : exclude_build_volume) { - if (tem_build_volume.contains(volume_bbox)) { - is_contain=true; - is_intersect = false; + Slic3r::Polygon p = tem_exclude_bboxf.polygon(true); // instance convex hull is scaled, so we need to scale here + if (intersection({p}, {hull}).empty() == false) { + return ObjectState::Colliding; break; } - else if (tem_build_volume.intersects(volume_bbox)) { - is_contain = false; - is_intersect = true; - break; } + return ObjectState::Inside; + } else { + return ObjectState::Inside; } - if (m_max_print_height == 0.0) - build_volume.max.z() = std::numeric_limits::max(); - if (ignore_bottom) - build_volume.min.z() = -std::numeric_limits::max(); - return build_volume.max.z() <= - SceneEpsilon ? ObjectState::Below : - is_contain ? ObjectState::Outside : - is_intersect ? ObjectState::Outside : - build_volume.contains(volume_bbox) ? ObjectState::Inside : - build_volume.intersects(volume_bbox) ? ObjectState::Colliding : - ObjectState::Outside; } //B52 diff --git a/src/libslic3r/BuildVolume.hpp b/src/libslic3r/BuildVolume.hpp index 7da19b1..b8fd59d 100644 --- a/src/libslic3r/BuildVolume.hpp +++ b/src/libslic3r/BuildVolume.hpp @@ -87,6 +87,8 @@ public: // Called by GLVolumeCollection::check_outside_state() after an object is manipulated with gizmos for example. // Called for a rectangular bed: ObjectState volume_state_bbox(const BoundingBoxf3& volume_bbox, bool ignore_bottom = true) const; + // B66 + BuildVolume::ObjectState check_outside(Polygon hull) const; // 2) Test called on G-code paths. // Using BedEpsilon for all tests. diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 0ea6f70..178e020 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -888,6 +888,16 @@ const BoundingBoxf3& ModelObject::bounding_box_approx() const return m_bounding_box_approx; } +// B66 +Polygon ModelInstance::convex_hull_2d() +{ + Polygon convex_hull; + { + const Transform3d &trafo_instance = get_matrix(); + convex_hull = get_object()->convex_hull_2d(trafo_instance); + } + return convex_hull; +} // Returns the bounding box of the transformed instances. // This bounding box is approximate and not snug. const BoundingBoxf3& ModelObject::bounding_box_exact() const diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index 458ceee..9de4f72 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -1158,6 +1158,8 @@ public: const Transform3d& get_matrix() const { return m_transformation.get_matrix(); } Transform3d get_matrix_no_offset() const { return m_transformation.get_matrix_no_offset(); } + // B66 + Polygon convex_hull_2d(); bool is_printable() const { return object->printable && printable && (print_volume_state == ModelInstancePVS_Inside); } void invalidate_object_bounding_box() { object->invalidate_bounding_box(); } diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 354a0f9..246e46f 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1511,9 +1511,22 @@ bool GLCanvas3D::check_volumes_outside_state(GLVolumeCollection& volumes, ModelI state = BuildVolume::ObjectState::Below; else { switch (build_volume.type()) { + // B66 case BuildVolume::Type::Rectangle: //FIXME this test does not evaluate collision of a build volume bounding box with non-convex objects. state = build_volume.volume_state_bbox(volume_bbox(*volume)); + if (state == BuildVolume::ObjectState::Inside) { + for (size_t i = 0; i < m_model->objects.size(); ++i) { + ModelObject * object = m_model->objects[i]; + ModelInstance *instance = object->instances[0]; + Polygon hull = instance->convex_hull_2d(); + + state = build_volume.check_outside(hull); + if (state != BuildVolume::ObjectState::Inside) { + break; + } + } + } break; case BuildVolume::Type::Circle: case BuildVolume::Type::Convex: