diff --git a/src/libslic3r/Fill/FillAdaptive.cpp b/src/libslic3r/Fill/FillAdaptive.cpp
index bf9cd7f9d..b1a40047d 100644
--- a/src/libslic3r/Fill/FillAdaptive.cpp
+++ b/src/libslic3r/Fill/FillAdaptive.cpp
@@ -3,12 +3,93 @@
 #include "../Surface.hpp"
 #include "../Geometry.hpp"
 #include "../AABBTreeIndirect.hpp"
+#include "../Layer.hpp"
+#include "../Print.hpp"
 #include "../ShortestPath.hpp"
 
 #include "FillAdaptive.hpp"
 
 namespace Slic3r {
 
+std::pair<double, double> adaptive_fill_line_spacing(const PrintObject &print_object)
+{
+    // Output, spacing for icAdaptiveCubic and icSupportCubic
+    double  adaptive_line_spacing = 0.;
+    double  support_line_spacing = 0.;
+
+    enum class Tristate {
+        Yes,
+        No,
+        Maybe
+    };
+    struct RegionFillData {
+        Tristate        has_adaptive_infill;
+        Tristate        has_support_infill;
+        double          density;
+        double          extrusion_width;
+    };
+    std::vector<RegionFillData> region_fill_data;
+    region_fill_data.reserve(print_object.print()->regions().size());
+    bool                        build_octree = false;
+    for (const PrintRegion *region : print_object.print()->regions()) {
+        const PrintRegionConfig &config   = region->config();
+        bool                     nonempty = config.fill_density > 0;
+        bool                     has_adaptive_infill = nonempty && config.fill_pattern == ipAdaptiveCubic;
+        bool                     has_support_infill  = nonempty && false; // config.fill_pattern == icSupportCubic;
+        region_fill_data.push_back(RegionFillData({
+            has_adaptive_infill ? Tristate::Maybe : Tristate::No,
+            has_support_infill ? Tristate::Maybe : Tristate::No,
+            config.fill_density,
+            config.infill_extrusion_width
+        }));
+        build_octree |= has_adaptive_infill || has_support_infill;
+    }
+
+    if (build_octree) {
+        // Compute the average of above parameters over all layers
+        for (const Layer *layer : print_object.layers())
+            for (size_t region_id = 0; region_id < layer->regions().size(); ++ region_id) {
+                RegionFillData &rd = region_fill_data[region_id];
+                if (rd.has_adaptive_infill == Tristate::Maybe && ! layer->regions()[region_id]->fill_surfaces.empty())
+                    rd.has_adaptive_infill = Tristate::Yes;
+                if (rd.has_support_infill == Tristate::Maybe && ! layer->regions()[region_id]->fill_surfaces.empty())
+                    rd.has_support_infill = Tristate::Yes;
+            }
+
+        double  adaptive_fill_density           = 0.;
+        double  adaptive_infill_extrusion_width = 0.;
+        int     adaptive_cnt                    = 0;
+        double  support_fill_density            = 0.;
+        double  support_infill_extrusion_width  = 0.;
+        int     support_cnt                     = 0;
+
+        for (const RegionFillData &rd : region_fill_data) {
+            if (rd.has_adaptive_infill == Tristate::Yes) {
+                adaptive_fill_density           += rd.density;
+                adaptive_infill_extrusion_width += rd.extrusion_width;
+                ++ adaptive_cnt;
+            } else if (rd.has_support_infill == Tristate::Yes) {
+                support_fill_density           += rd.density;
+                support_infill_extrusion_width += rd.extrusion_width;
+                ++ support_cnt;
+            }
+        }
+
+        auto to_line_spacing = [](int cnt, double density, double extrusion_width) {
+            if (cnt) {
+                density         /= double(cnt);
+                extrusion_width /= double(cnt);
+                return extrusion_width / ((density / 100.0f) * 0.333333333f);
+            } else
+                return 0.;
+        };
+        adaptive_line_spacing = to_line_spacing(adaptive_cnt, adaptive_fill_density, adaptive_infill_extrusion_width);
+        support_line_spacing  = to_line_spacing(support_cnt, support_fill_density, support_infill_extrusion_width);
+    }
+
+    return std::make_pair(adaptive_line_spacing, support_line_spacing);
+}
+
 void FillAdaptive::_fill_surface_single(
     const FillParams                &params, 
     unsigned int                     thickness_layers,
@@ -21,7 +102,7 @@ void FillAdaptive::_fill_surface_single(
     this->generate_infill_lines(this->adapt_fill_octree->root_cube.get(),
                                 this->z, this->adapt_fill_octree->origin,infill_lines_dir,
                                 this->adapt_fill_octree->cubes_properties,
-                                this->adapt_fill_octree->cubes_properties.size() - 1);
+                                int(this->adapt_fill_octree->cubes_properties.size()) - 1);
 
     Polylines all_polylines;
     all_polylines.reserve(infill_lines_dir[0].size() * 3);
@@ -131,16 +212,16 @@ void FillAdaptive::generate_infill_lines(
         Point to(-from.x(), from.y());
         // Relative to cube center
 
-        float rotation_angle = (2.0 * M_PI) / 3.0;
+        double rotation_angle = (2.0 * M_PI) / 3.0;
         for (Lines &lines : dir_lines_out)
         {
             Vec3d offset = cube->center - origin;
             Point from_abs(from), to_abs(to);
 
-            from_abs.x() += scale_(offset.x());
-            from_abs.y() += scale_(offset.y());
-            to_abs.x() += scale_(offset.x());
-            to_abs.y() += scale_(offset.y());
+            from_abs.x() += int(scale_(offset.x()));
+            from_abs.y() += int(scale_(offset.y()));
+            to_abs.x() += int(scale_(offset.x()));
+            to_abs.y() += int(scale_(offset.y()));
 
 //            lines.emplace_back(from_abs, to_abs);
             this->connect_lines(lines, Line(from_abs, to_abs));
@@ -161,7 +242,7 @@ void FillAdaptive::generate_infill_lines(
 
 void FillAdaptive::connect_lines(Lines &lines, Line new_line)
 {
-    int eps = scale_(0.10);
+    auto eps = int(scale_(0.10));
     for (size_t i = 0; i < lines.size(); ++i)
     {
         if (std::abs(new_line.a.x() - lines[i].b.x()) < eps && std::abs(new_line.a.y() - lines[i].b.y()) < eps)
@@ -227,7 +308,7 @@ std::unique_ptr<FillAdaptive_Internal::Octree> FillAdaptive::build_octree(
             triangle_mesh.its.vertices, triangle_mesh.its.indices);
     auto octree = std::make_unique<Octree>(std::make_unique<Cube>(cube_center), cube_center, cubes_properties);
 
-    FillAdaptive::expand_cube(octree->root_cube.get(), cubes_properties, rotation_matrix, aabbTree, triangle_mesh, cubes_properties.size() - 1);
+    FillAdaptive::expand_cube(octree->root_cube.get(), cubes_properties, rotation_matrix, aabbTree, triangle_mesh, int(cubes_properties.size()) - 1);
 
     return octree;
 }
diff --git a/src/libslic3r/Fill/FillAdaptive.hpp b/src/libslic3r/Fill/FillAdaptive.hpp
index 14694b766..dd7394384 100644
--- a/src/libslic3r/Fill/FillAdaptive.hpp
+++ b/src/libslic3r/Fill/FillAdaptive.hpp
@@ -7,6 +7,8 @@
 
 namespace Slic3r {
 
+class PrintObject;
+
 namespace FillAdaptive_Internal
 {
     struct CubeProperties
@@ -82,6 +84,12 @@ public:
         int                             depth);
 };
 
+// Calculate line spacing for
+// 1) adaptive cubic infill
+// 2) adaptive internal support cubic infill
+// Returns zero for a particular infill type if no such infill is to be generated.
+std::pair<double, double> adaptive_fill_line_spacing(const PrintObject &print_object);
+
 } // namespace Slic3r
 
 #endif // slic3r_FillAdaptive_hpp_
diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp
index 167be8a36..474417b1e 100644
--- a/src/libslic3r/PrintObject.cpp
+++ b/src/libslic3r/PrintObject.cpp
@@ -434,44 +434,17 @@ void PrintObject::generate_support_material()
 
 std::unique_ptr<FillAdaptive_Internal::Octree> PrintObject::prepare_adaptive_infill_data()
 {
-    float fill_density = 0;
-    float infill_extrusion_width = 0;
-
-    // Compute the average of above parameters over all layers
-    for (size_t layer_idx = 0; layer_idx < this->m_layers.size(); ++layer_idx)
-    {
-        for (size_t region_id = 0; region_id < this->m_layers[layer_idx]->m_regions.size(); ++region_id)
-        {
-            LayerRegion *layerm = this->m_layers[layer_idx]->m_regions[region_id];
-
-            // Check if region_id is used for this layer
-            if(!layerm->fill_surfaces.surfaces.empty()) {
-                const PrintRegionConfig &region_config = layerm->region()->config();
-
-                fill_density += region_config.fill_density;
-                infill_extrusion_width += region_config.infill_extrusion_width;
-            }
-        }
-    }
-
-    fill_density /= this->m_layers.size();
-    infill_extrusion_width /= this->m_layers.size();
-
-    if(fill_density <= 0 || infill_extrusion_width <= 0)
-    {
+    auto [adaptive_line_spacing, support_line_spacing] = adaptive_fill_line_spacing(*this);
+    if (adaptive_line_spacing == 0.)
         return std::unique_ptr<FillAdaptive_Internal::Octree>{};
-    }
-
-    coordf_t line_spacing = infill_extrusion_width / ((fill_density / 100.0f) * 0.333333333f);
 
     TriangleMesh mesh = this->model_object()->raw_mesh();
     mesh.transform(m_trafo, true);
     // Apply XY shift
     mesh.translate(- unscale<float>(m_center_offset.x()), - unscale<float>(m_center_offset.y()), 0);
-
     // Center of the first cube in octree
     Vec3d mesh_origin = mesh.bounding_box().center();
-    return FillAdaptive::build_octree(mesh, line_spacing, mesh_origin);
+    return FillAdaptive::build_octree(mesh, adaptive_line_spacing, mesh_origin);
 }
 
 void PrintObject::clear_layers()