diff --git a/xs/src/libslic3r/SupportMaterial.cpp b/xs/src/libslic3r/SupportMaterial.cpp
index 7b07fdf74..e9c555541 100644
--- a/xs/src/libslic3r/SupportMaterial.cpp
+++ b/xs/src/libslic3r/SupportMaterial.cpp
@@ -35,6 +35,73 @@ namespace Slic3r {
 //#define SUPPORT_SURFACES_OFFSET_PARAMETERS ClipperLib::jtMiter, 1.5
 #define SUPPORT_SURFACES_OFFSET_PARAMETERS ClipperLib::jtSquare, 0.
 
+
+const char* support_surface_type_to_color_name(const PrintObjectSupportMaterial::SupporLayerType surface_type)
+{
+    switch (surface_type) {
+        case PrintObjectSupportMaterial::sltTopContact:     return "rgb(255,0,0)"; // "red";
+        case PrintObjectSupportMaterial::sltTopInterface:   return "rgb(0,255,0)"; // "green";
+        case PrintObjectSupportMaterial::sltBase:           return "rgb(0,0,255)"; // "blue";
+        case PrintObjectSupportMaterial::sltBottomInterface:return "rgb(255,255,128)"; // yellow 
+        case PrintObjectSupportMaterial::sltBottomContact:  return "rgb(255,0,255)"; // magenta
+        case PrintObjectSupportMaterial::sltRaftInterface:  return "rgb(0,255,255)";
+        case PrintObjectSupportMaterial::sltRaftBase:       return "rgb(128,128,128)";
+        case PrintObjectSupportMaterial::sltUnknown:        return "rgb(128,0,0)"; // maroon
+        default:                                            return "rgb(64,64,64)";
+    };
+}
+
+Point export_support_surface_type_legend_to_svg_box_size()
+{
+    return Point(scale_(1.+10.*8.), scale_(3.)); 
+}
+
+void export_support_surface_type_legend_to_svg(SVG &svg, const Point &pos)
+{
+    // 1st row
+    coord_t pos_x0 = pos.x + scale_(1.);
+    coord_t pos_x = pos_x0;
+    coord_t pos_y = pos.y + scale_(1.5);
+    coord_t step_x = scale_(10.);
+    svg.draw_legend(Point(pos_x, pos_y), "top contact"    , support_surface_type_to_color_name(PrintObjectSupportMaterial::sltTopContact));
+    pos_x += step_x;
+    svg.draw_legend(Point(pos_x, pos_y), "top iface"      , support_surface_type_to_color_name(PrintObjectSupportMaterial::sltTopInterface));
+    pos_x += step_x;
+    svg.draw_legend(Point(pos_x, pos_y), "base"           , support_surface_type_to_color_name(PrintObjectSupportMaterial::sltBase));
+    pos_x += step_x;
+    svg.draw_legend(Point(pos_x, pos_y), "bottom iface"   , support_surface_type_to_color_name(PrintObjectSupportMaterial::sltBottomInterface));
+    pos_x += step_x;
+    svg.draw_legend(Point(pos_x, pos_y), "bottom contact" , support_surface_type_to_color_name(PrintObjectSupportMaterial::sltBottomContact));
+    // 2nd row
+    pos_x = pos_x0;
+    pos_y = pos.y+scale_(2.8);
+    svg.draw_legend(Point(pos_x, pos_y), "raft interface" , support_surface_type_to_color_name(PrintObjectSupportMaterial::sltRaftInterface));
+    pos_x += step_x;
+    svg.draw_legend(Point(pos_x, pos_y), "raft base"      , support_surface_type_to_color_name(PrintObjectSupportMaterial::sltRaftBase));
+    pos_x += step_x;
+    svg.draw_legend(Point(pos_x, pos_y), "unknown"        , support_surface_type_to_color_name(PrintObjectSupportMaterial::sltUnknown));
+    pos_x += step_x;
+    svg.draw_legend(Point(pos_x, pos_y), "intermediate"   , support_surface_type_to_color_name(PrintObjectSupportMaterial::sltIntermediate));
+}
+
+void export_print_z_polygons_to_svg(const char *path, PrintObjectSupportMaterial::MyLayer ** const layers, size_t n_layers)
+{
+    BoundingBox bbox;
+    for (int i = 0; i < n_layers; ++ i)
+        bbox.merge(get_extents(layers[i]->polygons));
+    Point legend_size = export_support_surface_type_legend_to_svg_box_size();
+    Point legend_pos(bbox.min.x, bbox.max.y);
+    bbox.merge(Point(std::max(bbox.min.x + legend_size.x, bbox.max.x), bbox.max.y + legend_size.y));
+    SVG svg(path, bbox);
+    const float transparency = 0.5f;
+    for (int i = 0; i < n_layers; ++ i)
+        svg.draw(union_ex(layers[i]->polygons), support_surface_type_to_color_name(layers[i]->layer_type), transparency);
+    for (int i = 0; i < n_layers; ++ i)
+        svg.draw(to_lines(layers[i]->polygons), support_surface_type_to_color_name(layers[i]->layer_type));
+    export_support_surface_type_legend_to_svg(svg, legend_pos);
+    svg.Close();
+}
+
 PrintObjectSupportMaterial::PrintObjectSupportMaterial(const PrintObject *object, const SlicingParameters &slicing_params) :
     m_object                (object),
     m_print_config          (&object->print()->config),
@@ -251,13 +318,22 @@ void PrintObjectSupportMaterial::generate(PrintObject &object)
     // Sort the layers lexicographically by a raising print_z and a decreasing height.
     std::sort(layers_sorted.begin(), layers_sorted.end(), MyLayersPtrCompare());
     int layer_id = 0;
+    assert(object.support_layers.empty());
     for (int i = 0; i < int(layers_sorted.size());) {
-        // Find the last layer with the same print_z, find the minimum layer height of all.
+        // Find the last layer with roughly the same print_z, find the minimum layer height of all.
+		// Due to the floating point inaccuracies, the print_z may not be the same even if in theory they should.
         int j = i + 1;
-        coordf_t height_min = layers_sorted[i]->height;
-        for (; j < layers_sorted.size() && layers_sorted[i]->print_z == layers_sorted[j]->print_z; ++ j) 
-            height_min = std::min(height_min, layers_sorted[j]->height);
-        object.add_support_layer(layer_id, height_min, layers_sorted[i]->print_z);
+		coordf_t zmax = layers_sorted[i]->print_z + EPSILON;
+		for (; j < layers_sorted.size() && layers_sorted[j]->print_z <= zmax; ++j) ;
+		// Assign an average print_z to the set of layers with nearly equal print_z.
+		coordf_t zavg = 0.5 * (layers_sorted[i]->print_z + layers_sorted[j - 1]->print_z);
+		coordf_t height_min = layers_sorted[i]->height;
+		for (int u = i; u < j; ++u) {
+			MyLayer &layer = *layers_sorted[u];
+			layer.print_z = zavg;
+			height_min = std::min(height_min, layer.height);
+		}
+		object.add_support_layer(layer_id, height_min, zavg);
         if (layer_id > 0) {
             // Inter-link the support layers into a linked list.
             SupportLayer *sl1 = object.support_layers[object.support_layer_count()-2];
@@ -265,6 +341,9 @@ void PrintObjectSupportMaterial::generate(PrintObject &object)
             sl1->upper_layer = sl2;
             sl2->lower_layer = sl1;
         }
+#ifdef SLIC3R_DEBUG
+        export_print_z_polygons_to_svg(debug_out_path("support-%d-%lf.svg", iRun, zavg).c_str(), layers_sorted.data() + i, j - i);
+#endif
         i = j;
         ++ layer_id;
     }
@@ -639,7 +718,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_
             // Store the overhang polygons as the aux_polygons.
             // The overhang polygons are used in the path generator for planning of the contact loops.
             // if (this->has_contact_loops())
-                new_layer.aux_polygons = new Polygons(std::move(overhang_polygons));
+            new_layer.aux_polygons = new Polygons(std::move(overhang_polygons));
             contact_out.push_back(&new_layer);
 
             if (0) { 
@@ -901,7 +980,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::raft_and_int
                 extr2.layer->bottom_z = extr2z = this->first_layer_height();
                 extr2.layer->height = extr2.layer->print_z - extr2.layer->bottom_z;
                 // 2) Insert a new intermediate layer.
-                MyLayer &layer_new = layer_allocate(layer_storage, stlIntermediate);
+                MyLayer &layer_new = layer_allocate(layer_storage, sltIntermediate);
                 layer_new.bottom_z   = extr1z;
                 layer_new.print_z    = this->first_layer_height();
                 layer_new.height     = layer_new.print_z - layer_new.bottom_z;
@@ -909,7 +988,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::raft_and_int
                 continue;
             }
         } else if (extr1z + step < this->first_layer_height()) {
-            MyLayer &layer_new = layer_allocate(layer_storage, stlIntermediate);
+            MyLayer &layer_new = layer_allocate(layer_storage, sltIntermediate);
             layer_new.bottom_z   = extr1z;
             layer_new.print_z    = extr1z = this->first_layer_height();
             layer_new.height     = layer_new.print_z - layer_new.bottom_z;
@@ -933,7 +1012,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::raft_and_int
         }
         // Take the largest allowed step in the Z axis until extr2z_large_steps is reached.
         for (size_t i = 0; i < n_layers_extra; ++ i) {
-            MyLayer &layer_new = layer_allocate(layer_storage, stlIntermediate);
+            MyLayer &layer_new = layer_allocate(layer_storage, sltIntermediate);
 			if (i + 1 == n_layers_extra) {
 				// Last intermediate layer added. Align the last entered layer with extr2z_large_steps exactly.
 				layer_new.bottom_z = (i == 0) ? extr1z : intermediate_layers.back()->print_z;
@@ -1051,6 +1130,7 @@ void PrintObjectSupportMaterial::generate_base_layers(
                 polygons_new,
                 polygons_trimming,
                 true); // safety offset to merge the touching source polygons
+        layer_intermediate.layer_type = sltBase;
 
 /*
         if (0) {
@@ -1515,8 +1595,11 @@ void PrintObjectSupportMaterial::generate_toolpaths(
     // Insert the raft base layers.
     size_t support_layer_id = 0;
     for (; support_layer_id < size_t(std::max(0, int(m_slicing_params.raft_layers()) - 1)); ++ support_layer_id) {
-        SupportLayer &support_layer = *object.support_layers[support_layer_id];
         assert(support_layer_id < raft_layers.size());
+        SupportLayer &support_layer = *object.support_layers[support_layer_id];
+        assert(support_layer.support_fills.entities.empty());
+        assert(support_layer.support_interface_fills.entities.empty());
+        assert(support_layer.support_islands.expolygons.empty());
         MyLayer      &raft_layer    = *raft_layers[support_layer_id];
         //FIXME When paralellizing, each thread shall have its own copy of the fillers.
         Fill *filler = filler_support.get();
@@ -1635,9 +1718,10 @@ void PrintObjectSupportMaterial::generate_toolpaths(
         if (! interface_layer.empty() && ! base_layer.empty()) {
             // turn base support into interface when it's contained in our holes
             // (this way we get wider interface anchoring)
+            //FIXME one wants to fill in the inner most holes of the interfaces, not all the holes.
             Polygons islands = top_level_islands(interface_layer.layer->polygons);
-            base_layer.layer->polygons = diff(base_layer.layer->polygons, islands);
             polygons_append(interface_layer.layer->polygons, intersection(base_layer.layer->polygons, islands));
+            base_layer.layer->polygons = diff(base_layer.layer->polygons, islands);
         }
 
 		// interface and contact infill
diff --git a/xs/src/libslic3r/SupportMaterial.hpp b/xs/src/libslic3r/SupportMaterial.hpp
index 3a319dd2e..48c5fc3bd 100644
--- a/xs/src/libslic3r/SupportMaterial.hpp
+++ b/xs/src/libslic3r/SupportMaterial.hpp
@@ -42,7 +42,7 @@ public:
 		// Top contact layer directly supporting an overhang. To be printed with a support interface material.
 		sltTopContact,
 		// Some undecided type yet. It will turn into sltBase first, then it may turn into sltBottomInterface or sltTopInterface.
-		stlIntermediate,
+		sltIntermediate,
 	};
 
 	// A support layer type used internally by the SupportMaterial class. This class carries a much more detailed