From 4c9ea5241dd2e1856f3e6f573b35ca46bafa9780 Mon Sep 17 00:00:00 2001
From: Lukas Matena <lukasmatena@seznam.cz>
Date: Wed, 24 Nov 2021 21:25:20 +0100
Subject: [PATCH 1/3] Fixup of a996f33 (When modifiers were used, slicing was
 cancelled immediately after if began): The algorithm checking for dummy
 VolumeRegions jumped over one element and always returned that regions need
 to be regenerated

---
 src/libslic3r/PrintApply.cpp | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/src/libslic3r/PrintApply.cpp b/src/libslic3r/PrintApply.cpp
index 84ff55598..1467aaea0 100644
--- a/src/libslic3r/PrintApply.cpp
+++ b/src/libslic3r/PrintApply.cpp
@@ -662,11 +662,10 @@ bool verify_update_print_object_regions(
                     // if the visited modifier did not modify their properties. Now the visited modifier's configuration may have changed,
                     // which may require new regions to be created.
                     it_model_volume_modifier_last = it_model_volume;
-                    int this_region_id = int(&region - layer_range.volume_regions.data());
-                    int next_region_id = this_region_id + 1;
+                    int next_region_id = int(&region - layer_range.volume_regions.data());
                     const PrintObjectRegions::BoundingBox *bbox = find_volume_extents(layer_range, *region.model_volume);
                     assert(bbox);
-                    for (int parent_region_id = this_region_id - 1; parent_region_id >= 0; -- parent_region_id) {
+                    for (int parent_region_id = next_region_id - 1; parent_region_id >= 0; -- parent_region_id) {
                         const PrintObjectRegions::VolumeRegion &parent_region = layer_range.volume_regions[parent_region_id];
                         assert(parent_region.model_volume != region.model_volume);
                         if (parent_region.model_volume->is_model_part() || parent_region.model_volume->is_modifier()) {

From bc5ef11c05032709e0b923e51cd6cd33dc6924ea Mon Sep 17 00:00:00 2001
From: enricoturri1966 <enricoturri@seznam.cz>
Date: Thu, 25 Nov 2021 09:40:36 +0100
Subject: [PATCH 2/3] Fix of toolpath outside print area wrongly reported -
 SPE-1135

---
 src/libslic3r/BuildVolume.cpp | 38 +++++++++++++++++++++--------------
 src/libslic3r/BuildVolume.hpp |  8 ++++----
 2 files changed, 27 insertions(+), 19 deletions(-)

diff --git a/src/libslic3r/BuildVolume.cpp b/src/libslic3r/BuildVolume.cpp
index f8fcef76f..c580e6f87 100644
--- a/src/libslic3r/BuildVolume.cpp
+++ b/src/libslic3r/BuildVolume.cpp
@@ -269,15 +269,17 @@ BuildVolume::ObjectState object_state_templ(const indexed_triangle_set &its, con
     return inside ? (outside ? BuildVolume::ObjectState::Colliding : BuildVolume::ObjectState::Inside) : BuildVolume::ObjectState::Outside;
 }
 
-BuildVolume::ObjectState BuildVolume::object_state(const indexed_triangle_set &its, const Transform3f &trafo, bool may_be_below_bed) const
+BuildVolume::ObjectState BuildVolume::object_state(const indexed_triangle_set& its, const Transform3f& trafo, bool may_be_below_bed, bool ignore_bottom) const
 {
     switch (m_type) {
     case Type::Rectangle:
     {
         BoundingBox3Base<Vec3d> build_volume = this->bounding_volume().inflated(SceneEpsilon);
-        BoundingBox3Base<Vec3f> build_volumef(build_volume.min.cast<float>(), build_volume.max.cast<float>());
-        if (m_max_print_height == 0)
+        if (m_max_print_height == 0.0)
             build_volume.max.z() = std::numeric_limits<double>::max();
+        if (ignore_bottom)
+            build_volume.min.z() = -std::numeric_limits<double>::max();
+        BoundingBox3Base<Vec3f> build_volumef(build_volume.min.cast<float>(), build_volume.max.cast<float>());
         // The following test correctly interprets intersection of a non-convex object with a rectangular build volume.
         //return rectangle_test(its, trafo, to_2d(build_volume.min), to_2d(build_volume.max), build_volume.max.z());
         //FIXME This test does NOT correctly interprets intersection of a non-convex object with a rectangular build volume.
@@ -286,14 +288,14 @@ BuildVolume::ObjectState BuildVolume::object_state(const indexed_triangle_set &i
     case Type::Circle:
     {
         Geometry::Circlef circle { unscaled<float>(m_circle.center), unscaled<float>(m_circle.radius + SceneEpsilon) };
-        return m_max_print_height == 0 ? 
+        return m_max_print_height == 0.0 ? 
             object_state_templ(its, trafo, may_be_below_bed, [circle](const Vec3f &pt) { return circle.contains(to_2d(pt)); }) :
             object_state_templ(its, trafo, may_be_below_bed, [circle, z = m_max_print_height + SceneEpsilon](const Vec3f &pt) { return pt.z() < z && circle.contains(to_2d(pt)); });
     }
     case Type::Convex:
     //FIXME doing test on convex hull until we learn to do test on non-convex polygons efficiently.
     case Type::Custom:
-        return m_max_print_height == 0 ? 
+        return m_max_print_height == 0.0 ? 
             object_state_templ(its, trafo, may_be_below_bed, [this](const Vec3f &pt) { return Geometry::inside_convex_polygon(m_top_bottom_convex_hull_decomposition_scene, to_2d(pt).cast<double>()); }) :
             object_state_templ(its, trafo, may_be_below_bed, [this, z = m_max_print_height + SceneEpsilon](const Vec3f &pt) { return pt.z() < z && Geometry::inside_convex_polygon(m_top_bottom_convex_hull_decomposition_scene, to_2d(pt).cast<double>()); });
     case Type::Invalid:
@@ -302,18 +304,20 @@ BuildVolume::ObjectState BuildVolume::object_state(const indexed_triangle_set &i
     }
 }
 
-BuildVolume::ObjectState BuildVolume::volume_state_bbox(const BoundingBoxf3 &volume_bbox) const
+BuildVolume::ObjectState BuildVolume::volume_state_bbox(const BoundingBoxf3& volume_bbox, bool ignore_bottom) const
 {
     assert(m_type == Type::Rectangle);
     BoundingBox3Base<Vec3d> build_volume = this->bounding_volume().inflated(SceneEpsilon);
-    if (m_max_print_height == 0)
+    if (m_max_print_height == 0.0)
         build_volume.max.z() = std::numeric_limits<double>::max();
+    if (ignore_bottom)
+        build_volume.min.z() = -std::numeric_limits<double>::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;
 }
 
-bool BuildVolume::all_paths_inside(const GCodeProcessorResult &paths, const BoundingBoxf3 &paths_bbox) const
+bool BuildVolume::all_paths_inside(const GCodeProcessorResult& paths, const BoundingBoxf3& paths_bbox, bool ignore_bottom) const
 {
     auto move_valid = [](const GCodeProcessorResult::MoveVertex &move) {
         return move.type == EMoveType::Extrude && move.extrusion_role != erCustom && move.width != 0.f && move.height != 0.f;
@@ -324,8 +328,10 @@ bool BuildVolume::all_paths_inside(const GCodeProcessorResult &paths, const Boun
     case Type::Rectangle:
     {
         BoundingBox3Base<Vec3d> build_volume = this->bounding_volume().inflated(epsilon);
-        if (m_max_print_height == 0)
+        if (m_max_print_height == 0.0)
             build_volume.max.z() = std::numeric_limits<double>::max();
+        if (ignore_bottom)
+            build_volume.min.z() = -std::numeric_limits<double>::max();
         return build_volume.contains(paths_bbox);
     }
     case Type::Circle:
@@ -333,7 +339,7 @@ bool BuildVolume::all_paths_inside(const GCodeProcessorResult &paths, const Boun
         const Vec2f c = unscaled<float>(m_circle.center);
         const float r = unscaled<double>(m_circle.radius) + epsilon;
         const float r2 = sqr(r);
-        return m_max_print_height == 0 ? 
+        return m_max_print_height == 0.0 ? 
             std::all_of(paths.moves.begin(), paths.moves.end(), [move_valid, c, r2](const GCodeProcessorResult::MoveVertex &move)
                 { return ! move_valid(move) || (to_2d(move.position) - c).squaredNorm() <= r2; }) :
             std::all_of(paths.moves.begin(), paths.moves.end(), [move_valid, c, r2, z = m_max_print_height + epsilon](const GCodeProcessorResult::MoveVertex& move)
@@ -342,7 +348,7 @@ bool BuildVolume::all_paths_inside(const GCodeProcessorResult &paths, const Boun
     case Type::Convex:
     //FIXME doing test on convex hull until we learn to do test on non-convex polygons efficiently.
     case Type::Custom:
-        return m_max_print_height == 0 ?
+        return m_max_print_height == 0.0 ?
             std::all_of(paths.moves.begin(), paths.moves.end(), [move_valid, this](const GCodeProcessorResult::MoveVertex &move) 
                 { return ! move_valid(move) || Geometry::inside_convex_polygon(m_top_bottom_convex_hull_decomposition_bed, to_2d(move.position).cast<double>()); }) :
             std::all_of(paths.moves.begin(), paths.moves.end(), [move_valid, this, z = m_max_print_height + epsilon](const GCodeProcessorResult::MoveVertex &move)
@@ -364,7 +370,7 @@ inline bool all_inside_vertices_normals_interleaved(const std::vector<float> &pa
     return true;
 }
 
-bool BuildVolume::all_paths_inside_vertices_and_normals_interleaved(const std::vector<float> &paths, const Eigen::AlignedBox<float, 3> &paths_bbox) const
+bool BuildVolume::all_paths_inside_vertices_and_normals_interleaved(const std::vector<float>& paths, const Eigen::AlignedBox<float, 3>& paths_bbox, bool ignore_bottom) const
 {
     assert(paths.size() % 6 == 0);
     static constexpr const double epsilon = BedEpsilon;
@@ -372,8 +378,10 @@ bool BuildVolume::all_paths_inside_vertices_and_normals_interleaved(const std::v
     case Type::Rectangle:
     {
         BoundingBox3Base<Vec3d> build_volume = this->bounding_volume().inflated(epsilon);
-        if (m_max_print_height == 0)
+        if (m_max_print_height == 0.0)
             build_volume.max.z() = std::numeric_limits<double>::max();
+        if (ignore_bottom)
+            build_volume.min.z() = -std::numeric_limits<double>::max();
         return build_volume.contains(paths_bbox.min().cast<double>()) && build_volume.contains(paths_bbox.max().cast<double>());
     }
     case Type::Circle:
@@ -381,14 +389,14 @@ bool BuildVolume::all_paths_inside_vertices_and_normals_interleaved(const std::v
         const Vec2f c = unscaled<float>(m_circle.center);
         const float r = unscaled<double>(m_circle.radius) + float(epsilon);
         const float r2 = sqr(r);
-        return m_max_print_height == 0 ?
+        return m_max_print_height == 0.0 ?
             all_inside_vertices_normals_interleaved(paths, [c, r2](Vec3f p) { return (to_2d(p) - c).squaredNorm() <= r2; }) :
             all_inside_vertices_normals_interleaved(paths, [c, r2, z = m_max_print_height + epsilon](Vec3f p) { return (to_2d(p) - c).squaredNorm() <= r2 && p.z() <= z; });
     }
     case Type::Convex:
         //FIXME doing test on convex hull until we learn to do test on non-convex polygons efficiently.
     case Type::Custom:
-        return m_max_print_height == 0 ?
+        return m_max_print_height == 0.0 ?
             all_inside_vertices_normals_interleaved(paths, [this](Vec3f p) { return Geometry::inside_convex_polygon(m_top_bottom_convex_hull_decomposition_bed, to_2d(p).cast<double>()); }) :
             all_inside_vertices_normals_interleaved(paths, [this, z = m_max_print_height + epsilon](Vec3f p) { return Geometry::inside_convex_polygon(m_top_bottom_convex_hull_decomposition_bed, to_2d(p).cast<double>()) && p.z() <= z; });
     default:
diff --git a/src/libslic3r/BuildVolume.hpp b/src/libslic3r/BuildVolume.hpp
index e75710882..6b928d48b 100644
--- a/src/libslic3r/BuildVolume.hpp
+++ b/src/libslic3r/BuildVolume.hpp
@@ -80,19 +80,19 @@ public:
     // Called by Plater to update Inside / Colliding / Outside state of ModelObjects before slicing.
     // Called from Model::update_print_volume_state() -> ModelObject::update_instances_print_volume_state()
     // Using SceneEpsilon
-    ObjectState  object_state(const indexed_triangle_set &its, const Transform3f &trafo, bool may_be_below_bed) const;
+    ObjectState  object_state(const indexed_triangle_set &its, const Transform3f &trafo, bool may_be_below_bed, bool ignore_bottom = true) const;
     // 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) const;
+    ObjectState  volume_state_bbox(const BoundingBoxf3& volume_bbox, bool ignore_bottom = true) const;
 
     // 2) Test called on G-code paths.
     // Using BedEpsilon for all tests.
     static constexpr const double BedEpsilon = 3. * EPSILON;
     // Called on final G-code paths.
     //FIXME The test does not take the thickness of the extrudates into account!
-    bool         all_paths_inside(const GCodeProcessorResult &paths, const BoundingBoxf3 &paths_bbox) const;
+    bool         all_paths_inside(const GCodeProcessorResult& paths, const BoundingBoxf3& paths_bbox, bool ignore_bottom = true) const;
     // Called on initial G-code preview on OpenGL vertex buffer interleaved normals and vertices.
-    bool         all_paths_inside_vertices_and_normals_interleaved(const std::vector<float> &paths, const Eigen::AlignedBox<float, 3> &bbox) const;
+    bool         all_paths_inside_vertices_and_normals_interleaved(const std::vector<float>& paths, const Eigen::AlignedBox<float, 3>& bbox, bool ignore_bottom = true) const;
 
 private:
     // Source definition of the print bed geometry (PrintConfig::bed_shape)

From 2f805de46e3e332f0168ec9fce9a352116233717 Mon Sep 17 00:00:00 2001
From: tamasmeszaros <meszaros.q@gmail.com>
Date: Thu, 25 Nov 2021 10:40:12 +0100
Subject: [PATCH 3/3] Fix locked in version of CGAL

fixes #7341
---
 src/libslic3r/CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/libslic3r/CMakeLists.txt b/src/libslic3r/CMakeLists.txt
index f0283f1cc..96d31bf3f 100644
--- a/src/libslic3r/CMakeLists.txt
+++ b/src/libslic3r/CMakeLists.txt
@@ -288,7 +288,7 @@ set(CGAL_DO_NOT_WARN_ABOUT_CMAKE_BUILD_TYPE ON CACHE BOOL "" FORCE)
 
 cmake_policy(PUSH)
 cmake_policy(SET CMP0011 NEW)
-find_package(CGAL 4.13.2 REQUIRED)
+find_package(CGAL 4.13 REQUIRED)
 cmake_policy(POP)
 
 add_library(libslic3r_cgal STATIC MeshBoolean.cpp MeshBoolean.hpp  TryCatchSignal.hpp