diff --git a/src/libslic3r/SLA/SLASupportTree.cpp b/src/libslic3r/SLA/SLASupportTree.cpp
index ae75478e1..48e949c69 100644
--- a/src/libslic3r/SLA/SLASupportTree.cpp
+++ b/src/libslic3r/SLA/SLASupportTree.cpp
@@ -416,9 +416,9 @@ struct Pillar {
         base.points.emplace_back(ep);
 
         auto& indices = base.indices;
-        auto hcenter = base.points.size() - 1;
-        auto lcenter = base.points.size() - 2;
-        auto offs = steps;
+        auto hcenter = int(base.points.size() - 1);
+        auto lcenter = int(base.points.size() - 2);
+        auto offs = int(steps);
         for(int i = 0; i < steps - 1; ++i) {
             indices.emplace_back(i, i + offs, offs + i + 1);
             indices.emplace_back(i, offs + i + 1, i + 1);
@@ -426,7 +426,7 @@ struct Pillar {
             indices.emplace_back(lcenter, offs + i + 1, offs + i);
         }
 
-        auto last = steps - 1;
+        auto last = int(steps - 1);
         indices.emplace_back(0, last, offs);
         indices.emplace_back(last, offs + last, offs);
         indices.emplace_back(hcenter, last, 0);
@@ -720,20 +720,18 @@ public:
         return m_pillars.back();
     }
 
-    const Head& pillar_head(long pillar_id) {
-        assert(pillar_id > 0 && pillar_id < m_pillars.size());
-        Pillar& p = m_pillars[pillar_id];
-        assert(p.starts_from_head && p.start_junction_id > 0 &&
+    const Head& pillar_head(long pillar_id) const {
+        assert(pillar_id >= 0 && pillar_id < m_pillars.size());
+        const Pillar& p = m_pillars[pillar_id];
+        assert(p.starts_from_head && p.start_junction_id >= 0 &&
                p.start_junction_id < m_heads.size() );
-        meshcache_valid = false;
         return m_heads[p.start_junction_id];
     }
 
-    const Pillar& head_pillar(long headid) {
+    const Pillar& head_pillar(long headid) const {
         assert(headid >= 0 && headid < m_heads.size());
-        Head& h = m_heads[headid];
-        assert(h.pillar_id > 0 && h.pillar_id < m_pillars.size());
-        meshcache_valid = false;
+        const Head& h = m_heads[headid];
+        assert(h.pillar_id >= 0 && h.pillar_id < m_pillars.size());
         return m_pillars[h.pillar_id];
     }
 
@@ -804,7 +802,7 @@ public:
         }
 
         BoundingBoxf3&& bb = meshcache.bounding_box();
-        model_height = bb.max(Z);
+        model_height = bb.max(Z) - bb.min(Z);
 
         meshcache_valid = true;
         return meshcache;
@@ -1691,49 +1689,74 @@ void SLASupportTree::merged_mesh_with_pad(TriangleMesh &outmesh) const {
     outmesh.merge(get_pad());
 }
 
-template<class T> void slice_part(const T& inp,
-                                  std::vector<SlicedSupports>& mergev,
-                                  const std::vector<float>& heights)
-{
-    for(auto& part : inp) {
-        TriangleMesh&& m = mesh(part.mesh);
-        TriangleMeshSlicer slicer(&m);
-        SlicedSupports slout;
-        slicer.slice(heights, &slout, [](){});
+//void slice_mesh(const Contour3D& cntr,
+//                std::vector<SlicedSupports>& mergev,
+//                const std::vector<float>& heights)
+//{
+//    TriangleMesh&& m = mesh(cntr);
+//    TriangleMeshSlicer slicer(&m);
+//    SlicedSupports slout;
+//    slicer.slice(heights, &slout, [](){});
 
-        for(size_t i = 0; i < slout.size(); i++) {
-            // move the layers obtained from this mesh to the merge area
-            mergev[i].emplace_back(std::move(slout[i]));
-        }
-    }
-}
+//    for(size_t i = 0; i < slout.size(); i++) {
+//        // move the layers obtained from this mesh to the merge area
+//        mergev[i].emplace_back(std::move(slout[i]));
+//    }
+//}
+
+//template<class T> void slice_part(const T& inp,
+//                                  std::vector<SlicedSupports>& mergev,
+//                                  const std::vector<float>& heights)
+//{
+//    for(auto& part : inp) {
+//        slice_mesh(part.mesh, mergev, heights);
+//    }
+//}
 
 SlicedSupports SLASupportTree::slice(float layerh, float init_layerh) const
 {
     if(init_layerh < 0) init_layerh = layerh;
     auto& stree = get();
-    const float modelh = stree.full_height();
+    const auto modelh = float(stree.full_height());
 
-    std::vector<float> heights; heights.reserve(size_t(modelh/layerh) + 1);
-    for(float h = init_layerh; h <= modelh; h += layerh) {
+    auto gndlvl = float(this->m_impl->ground_level);
+    std::vector<float> heights = {gndlvl};
+    heights.reserve(size_t(modelh/layerh) + 1);
+
+    for(float h = gndlvl + init_layerh; h < gndlvl + modelh; h += layerh) {
         heights.emplace_back(h);
     }
 
-    std::vector<SlicedSupports> mergev(heights.size());
+    TriangleMesh fullmesh = m_impl->merged_mesh();
+    TriangleMeshSlicer slicer(&fullmesh);
+    SlicedSupports ret;
+    slicer.slice(heights, &ret, [](){});
 
-    slice_part(stree.heads(), mergev, heights);
-    slice_part(stree.pillars(), mergev, heights);
-    slice_part(stree.junctions(), mergev, heights);
-    slice_part(stree.bridges(), mergev, heights);
-    slice_part(stree.compact_bridges(), mergev, heights);
+//    std::vector<SlicedSupports> mergev(heights.size());
 
-    // TODO: do this for all
+//    slice_part(stree.heads(), mergev, heights);
+//    slice_part(stree.pillars(), mergev, heights);
+//    for(auto& pillar : stree.pillars()) slice_mesh(pillar.base, mergev, heights);
+//    slice_part(stree.junctions(), mergev, heights);
+////    slice_part(stree.bridges(), mergev, heights);
+////    slice_part(stree.compact_bridges(), mergev, heights);
 
-    for(SlicedSupports& level : mergev) {
-        // TODO merge all expolygon in the current level
-    }
+//    // TODO: slicing base pool geometry
 
-    return {};
+//    // We could make a union of the slices at the same height level but at the
+//    // end they will be loaded into the rasterizer and it will unite them
+//    // anyway.
+
+//    SlicedSupports ret; ret.reserve(mergev.size());
+//    for(SlicedSupports& level : mergev) {
+//        size_t count = 0;
+//        for(auto& v : level) count += v.size();
+//        ret.emplace_back(); auto& merg = ret.back(); merg.reserve(count);
+//        for(ExPolygons& v : level)
+//            for(ExPolygon& ex : v) merg.emplace_back(ex);
+//    }
+
+    return ret;
 }
 
 const TriangleMesh &SLASupportTree::add_pad(double min_wall_thickness_mm,
diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp
index 6b6455e18..c50cc8066 100644
--- a/src/libslic3r/SLAPrint.cpp
+++ b/src/libslic3r/SLAPrint.cpp
@@ -138,8 +138,10 @@ void SLAPrint::process()
         auto bb3d = mesh.bounding_box();
 
         auto H = bb3d.max(Z) - bb3d.min(Z);
-        std::vector<float> heights = {ilh};
-        for(float h = ilh; h < H; h += lh) heights.emplace_back(h);
+        auto gnd = float(bb3d.min(Z));
+        std::vector<float> heights = {gnd};
+        for(float h = gnd + ilh; h < gnd + H; h += lh) heights.emplace_back(h);
+
         auto& layers = po.m_model_slices;
         slicer.slice(heights, &layers, [](){});
     };
@@ -163,6 +165,8 @@ void SLAPrint::process()
 
     // In this step we create the supports
     auto support_tree = [this](SLAPrintObject& po) {
+        if(!po.m_supportdata) return;
+
         auto& emesh = po.m_supportdata->emesh;
         auto& pts = po.m_supportdata->support_points; // nowhere filled yet
         try {
@@ -190,17 +194,18 @@ void SLAPrint::process()
         // this step can only go after the support tree has been created
         // and before the supports had been sliced. (or the slicing has to be
         // repeated)
-        if(po.is_step_done(slaposSupportTree) &&
-           po.m_supportdata &&
-           po.m_supportdata->support_tree_ptr)
-        {
-            double wt = po.m_config.pad_wall_thickness.getFloat();
-            double h =  po.m_config.pad_wall_height.getFloat();
-            double md = po.m_config.pad_max_merge_distance.getFloat();
-            double er = po.m_config.pad_edge_radius.getFloat();
 
-            po.m_supportdata->support_tree_ptr->add_pad(wt, h, md, er);
-        }
+//        if(po.is_step_done(slaposSupportTree) &&
+//           po.m_supportdata &&
+//           po.m_supportdata->support_tree_ptr)
+//        {
+//            double wt = po.m_config.pad_wall_thickness.getFloat();
+//            double h =  po.m_config.pad_wall_height.getFloat();
+//            double md = po.m_config.pad_max_merge_distance.getFloat();
+//            double er = po.m_config.pad_edge_radius.getFloat();
+
+//            po.m_supportdata->support_tree_ptr->add_pad(wt, h, md, er);
+//        }
     };
 
     // Slicing the support geometries similarly to the model slicing procedure.
@@ -211,6 +216,7 @@ void SLAPrint::process()
         if(sd && sd->support_tree_ptr) {
             auto lh = float(po.m_config.layer_height.getFloat());
             sd->support_slices = sd->support_tree_ptr->slice(lh, ilh);
+            std::cout << "support slice count " << sd->support_slices.size() << std::endl;
         }
     };
 
@@ -232,7 +238,6 @@ void SLAPrint::process()
 
         // For all print objects, go through its initial layers and place them
         // into the layers hash
-//        long long initlyridx = static_cast<long long>(scale_(ilh));
         for(SLAPrintObject *o : m_objects) {
             double lh = o->m_config.layer_height.getFloat();
             std::vector<ExPolygons> & oslices = o->m_model_slices;
@@ -243,8 +248,11 @@ void SLAPrint::process()
                 lyrs.emplace_back(oslices[i], o->m_instances);
             }
 
+            std::cout << "model slice count at rasterization: " << oslices.size() << std::endl;
+
             if(o->m_supportdata) { // deal with the support slices if present
                 auto& sslices = o->m_supportdata->support_slices;
+                std::cout << "support slice count at rasterization: " << o->m_supportdata->support_slices.size() << std::endl;
 
                 for(int i = 0; i < sslices.size(); ++i) {
                     double h = ilh + i * lh;
@@ -253,32 +261,14 @@ void SLAPrint::process()
                     lyrs.emplace_back(sslices[i], o->m_instances);
                 }
             }
-
-//            auto& oslices = o->m_model_slices;
-//            auto& firstlyr = oslices.front();
-//            auto& initlevel = levels[initlyridx];
-//            initlevel.emplace_back(firstlyr, o->m_instances);
-
-//            // now push the support slices as well
-//            // TODO
-
-//            double lh = o->m_config.layer_height.getFloat();
-//            size_t li = 1;
-//            for(auto lit = std::next(oslices.begin());
-//                lit != oslices.end();
-//                ++lit)
-//            {
-//                double h = ilh + li++ * lh;
-//                long long lyridx = static_cast<long long>(scale_(h));
-//                auto& lyrs = levels[lyridx];
-//                lyrs.emplace_back(*lit, o->m_instances);
-//            }
         }
 
         // collect all the keys
         std::vector<long long> keys; keys.reserve(levels.size());
         for(auto& e : levels) keys.emplace_back(e.first);
 
+        std::cout << "levels count at rasterization " << levels.size() << std::endl;
+
         { // create a raster printer for the current print parameters
             // I don't know any better
             auto& ocfg = m_objects.front()->m_config;
@@ -305,26 +295,25 @@ void SLAPrint::process()
         auto lvlfn = [&keys, &levels, &printer](unsigned level_id) {
             LayerRefs& lrange = levels[keys[level_id]];
 
-            for(auto& lyrref : lrange) { // for all layers in the current level
-                const Layer& l = lyrref.lref;   // get the layer reference
-                const LayerCopies& copies = lyrref.copies;
-                ExPolygonCollection sl = l;
+            // Switch to the appropriate layer in the printer
+            printer.begin_layer(level_id);
 
-                // Switch to the appropriate layer in the printer
-                printer.begin_layer(level_id);
+            for(auto& lyrref : lrange) { // for all layers in the current level
+                const Layer& sl = lyrref.lref;   // get the layer reference
+                const LayerCopies& copies = lyrref.copies;
 
                 // Draw all the polygons in the slice to the actual layer.
                 for(auto& cp : copies) {
-                    for(ExPolygon slice : sl.expolygons) {
+                    for(ExPolygon slice : sl) {
                         slice.translate(cp.shift(X), cp.shift(Y));
                         slice.rotate(cp.rotation);
                         printer.draw_polygon(slice, level_id);
                     }
                 }
-
-                // Finish the layer for later saving it.
-                printer.finish_layer(level_id);
             }
+
+            // Finish the layer for later saving it.
+            printer.finish_layer(level_id);
         };
 
         // Sequential version (for testing)
@@ -387,7 +376,7 @@ void SLAPrint::process()
     };
 
     // TODO: enable rasterizing
-     m_stepmask[slapsRasterize] = false;
+    // m_stepmask[slapsRasterize] = false;
 
     for(size_t s = 0; s < print_program.size(); ++s) {
         auto currentstep = printsteps[s];