diff --git a/src/libslic3r/Fill/Fill.cpp b/src/libslic3r/Fill/Fill.cpp
index 082cf93cc..e0e2e0ca8 100644
--- a/src/libslic3r/Fill/Fill.cpp
+++ b/src/libslic3r/Fill/Fill.cpp
@@ -441,11 +441,15 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
 	}
 #endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
 
+	size_t first_object_layer_id = this->object()->get_layer(0)->id();
     for (SurfaceFill &surface_fill : surface_fills) {
         // Create the filler object.
         std::unique_ptr<Fill> f = std::unique_ptr<Fill>(Fill::new_from_type(surface_fill.params.pattern));
         f->set_bounding_box(bbox);
-        f->layer_id = this->id();
+		// Layer ID is used for orienting the infill in alternating directions.
+		// Layer::id() returns layer ID including raft layers, subtract them to make the infill direction independent
+		// from raft.
+        f->layer_id = this->id() - first_object_layer_id;
         f->z 		= this->print_z;
         f->angle 	= surface_fill.params.angle;
         f->adapt_fill_octree = (surface_fill.params.pattern == ipSupportCubic) ? support_fill_octree : adaptive_fill_octree;
@@ -698,7 +702,11 @@ void Layer::make_ironing()
     FillRectilinear 	fill;
     FillParams 			fill_params;
 	fill.set_bounding_box(this->object()->bounding_box());
-	fill.layer_id 			 = this->id();
+	// Layer ID is used for orienting the infill in alternating directions.
+	// Layer::id() returns layer ID including raft layers, subtract them to make the infill direction independent
+	// from raft.
+	//FIXME ironing does not take fill angle into account. Shall it? Does it matter?
+	fill.layer_id 			 = this->id() - this->object()->get_layer(0)->id();
     fill.z 					 = this->print_z;
     fill.overlap 			 = 0;
     fill_params.density 	 = 1.;
diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp
index efdcb4fc6..65deb8261 100644
--- a/src/libslic3r/PrintObject.cpp
+++ b/src/libslic3r/PrintObject.cpp
@@ -20,6 +20,7 @@
 #include "Fill/FillAdaptive.hpp"
 #include "Fill/FillLightning.hpp"
 #include "Format/STL.hpp"
+#include "SupportMaterial.hpp"
 #include "SupportSpotsGenerator.hpp"
 #include "TriangleSelectorWrapper.hpp"
 #include "format.hpp"
@@ -1129,6 +1130,15 @@ void PrintObject::process_external_surfaces()
         m_print->throw_if_canceled();
         BOOST_LOG_TRIVIAL(debug) << "Processing external surfaces for region " << region_id << " in parallel - end";
     }
+
+    if (this->has_raft() && ! m_layers.empty()) {
+        // Adjust bridge direction of 1st object layer over raft to be perpendicular to the raft contact layer direction.
+        Layer &layer = *m_layers.front();
+        assert(layer.id() > 0);
+        for (LayerRegion *layerm : layer.regions())
+            for (Surface &fill : layerm->m_fill_surfaces)
+                fill.bridge_angle = -1;
+    }
 } // void PrintObject::process_external_surfaces()
 
 void PrintObject::discover_vertical_shells()
diff --git a/src/libslic3r/SupportMaterial.cpp b/src/libslic3r/SupportMaterial.cpp
index 6be62c4b3..965a9398f 100644
--- a/src/libslic3r/SupportMaterial.cpp
+++ b/src/libslic3r/SupportMaterial.cpp
@@ -376,8 +376,6 @@ SupportParameters::SupportParameters(const PrintObject &object)
     }
 
 
-    this->base_angle         = Geometry::deg2rad(float(object_config.support_material_angle.value));
-    this->interface_angle    = Geometry::deg2rad(float(object_config.support_material_angle.value + 90.));
     double interface_spacing = object_config.support_material_interface_spacing.value + this->support_material_interface_flow.spacing();
     this->interface_density  = std::min(1., this->support_material_interface_flow.spacing() / interface_spacing);
     double raft_interface_spacing = object_config.support_material_interface_spacing.value + this->raft_interface_flow.spacing();
@@ -401,6 +399,39 @@ SupportParameters::SupportParameters(const PrintObject &object)
         object_config.support_material_interface_pattern == smipConcentric ?
         ipConcentric :
         (this->interface_density > 0.95 ? ipRectilinear : ipSupportBase);
+
+    this->base_angle            = Geometry::deg2rad(float(object_config.support_material_angle.value));
+    this->interface_angle       = Geometry::deg2rad(float(object_config.support_material_angle.value + 90.));
+    this->raft_angle_1st_layer  = 0.f;
+    this->raft_angle_base       = 0.f;
+    this->raft_angle_interface  = 0.f;
+    if (slicing_params.base_raft_layers > 1) {
+        assert(slicing_params.raft_layers() >= 4);
+        // There are all raft layer types (1st layer, base, interface & contact layers) available.
+        this->raft_angle_1st_layer  = this->interface_angle;
+        this->raft_angle_base       = this->base_angle;
+        this->raft_angle_interface  = this->interface_angle;
+        if ((slicing_params.interface_raft_layers & 1) == 0)
+            // Allign the 1st raft interface layer so that the object 1st layer is hatched perpendicularly to the raft contact interface.
+            this->raft_angle_interface += float(0.5 * M_PI);
+    } else if (slicing_params.base_raft_layers == 1 || slicing_params.interface_raft_layers > 1) {
+        assert(slicing_params.raft_layers() == 2 || slicing_params.raft_layers() == 3);
+        // 1st layer, interface & contact layers available.
+        this->raft_angle_1st_layer  = this->base_angle;
+        this->raft_angle_interface  = this->interface_angle + 0.5 * M_PI;
+    } else if (slicing_params.interface_raft_layers == 1) {
+        // Only the contact raft layer is non-empty, which will be printed as the 1st layer.
+        assert(slicing_params.base_raft_layers == 0);
+        assert(slicing_params.interface_raft_layers == 1);
+        assert(slicing_params.raft_layers() == 1);
+        this->raft_angle_1st_layer = float(0.5 * M_PI);
+        this->raft_angle_interface = this->raft_angle_1st_layer;
+    } else {
+        // No raft.
+        assert(slicing_params.base_raft_layers == 0);
+        assert(slicing_params.interface_raft_layers == 0);
+        assert(slicing_params.raft_layers() == 0);
+    }
 }
 
 PrintObjectSupportMaterial::PrintObjectSupportMaterial(const PrintObject *object, const SlicingParameters &slicing_params) :
@@ -4207,38 +4238,12 @@ void generate_support_toolpaths(
 //    const coordf_t link_max_length_factor = 3.;
     const coordf_t link_max_length_factor = 0.;
 
-    float raft_angle_1st_layer  = 0.f;
-    float raft_angle_base       = 0.f;
-    float raft_angle_interface  = 0.f;
-    if (slicing_params.base_raft_layers > 1) {
-        // There are all raft layer types (1st layer, base, interface & contact layers) available.
-        raft_angle_1st_layer  = support_params.interface_angle;
-        raft_angle_base       = support_params.base_angle;
-        raft_angle_interface  = support_params.interface_angle;
-    } else if (slicing_params.base_raft_layers == 1 || slicing_params.interface_raft_layers > 1) {
-        // 1st layer, interface & contact layers available.
-        raft_angle_1st_layer  = support_params.base_angle;
-        if (config.support_material || config.support_material_enforce_layers > 0)
-            // Print 1st layer at 45 degrees from both the interface and base angles as both can land on the 1st layer.
-            raft_angle_1st_layer += 0.7854f;
-        raft_angle_interface  = support_params.interface_angle;
-    } else if (slicing_params.interface_raft_layers == 1) {
-        // Only the contact raft layer is non-empty, which will be printed as the 1st layer.
-        assert(slicing_params.base_raft_layers == 0);
-        assert(slicing_params.interface_raft_layers == 1);
-        assert(slicing_params.raft_layers() == 1 && raft_layers.size() == 0);
-    } else {
-        // No raft.
-        assert(slicing_params.base_raft_layers == 0);
-        assert(slicing_params.interface_raft_layers == 0);
-        assert(slicing_params.raft_layers() == 0 && raft_layers.size() == 0);
-    }
-
     // Insert the raft base layers.
     auto n_raft_layers = std::min<size_t>(support_layers.size(), std::max(0, int(slicing_params.raft_layers()) - 1));
+
     tbb::parallel_for(tbb::blocked_range<size_t>(0, n_raft_layers),
         [&support_layers, &raft_layers, &intermediate_layers, &config, &support_params, &slicing_params,
-            &bbox_object, raft_angle_1st_layer, raft_angle_base, raft_angle_interface, link_max_length_factor]
+            &bbox_object, link_max_length_factor]
             (const tbb::blocked_range<size_t>& range) {
         for (size_t support_layer_id = range.begin(); support_layer_id < range.end(); ++ support_layer_id)
         {
@@ -4270,7 +4275,7 @@ void generate_support_toolpaths(
                 assert(!raft_layer.bridging);
                 if (! to_infill_polygons.empty()) {
                     Fill *filler = filler_support.get();
-                    filler->angle = raft_angle_base;
+                    filler->angle = support_params.raft_angle_base;
                     filler->spacing = support_params.support_material_flow.spacing();
                     filler->link_max_length = coord_t(scale_(filler->spacing * link_max_length_factor / support_params.support_density));
                     fill_expolygons_with_sheath_generate_paths(
@@ -4293,11 +4298,11 @@ void generate_support_toolpaths(
             float density = 0.f;
             if (support_layer_id == 0) {
                 // Base flange.
-                filler->angle = raft_angle_1st_layer;
+                filler->angle = support_params.raft_angle_1st_layer;
                 filler->spacing = support_params.first_layer_flow.spacing();
                 density       = float(config.raft_first_layer_density.value * 0.01);
             } else if (support_layer_id >= slicing_params.base_raft_layers) {
-                filler->angle = raft_angle_interface;
+                filler->angle = support_params.raft_interface_angle(support_layer.interface_id());
                 // We don't use $base_flow->spacing because we need a constant spacing
                 // value that guarantees that all layers are correctly aligned.
                 filler->spacing = support_params.support_material_flow.spacing();
@@ -4345,7 +4350,7 @@ void generate_support_toolpaths(
     std::vector<LayerCache>             layer_caches(support_layers.size());
 
     tbb::parallel_for(tbb::blocked_range<size_t>(n_raft_layers, support_layers.size()),
-        [&config, &support_params, &support_layers, &bottom_contacts, &top_contacts, &intermediate_layers, &interface_layers, &base_interface_layers, &layer_caches, &loop_interface_processor,
+        [&config, &slicing_params, &support_params, &support_layers, &bottom_contacts, &top_contacts, &intermediate_layers, &interface_layers, &base_interface_layers, &layer_caches, &loop_interface_processor,
             &bbox_object, &angles, n_raft_layers, link_max_length_factor]
             (const tbb::blocked_range<size_t>& range) {
         // Indices of the 1st layer in their respective container at the support layer height.
@@ -4381,9 +4386,8 @@ void generate_support_toolpaths(
         {
             SupportLayer &support_layer = *support_layers[support_layer_id];
             LayerCache   &layer_cache   = layer_caches[support_layer_id];
-            float         interface_angle_delta = config.support_material_style.value != smsGrid ? 
-                (support_layer.interface_id() & 1) ? float(- M_PI / 4.) : float(+ M_PI / 4.) :
-                0;
+            const float   support_interface_angle = config.support_material_style.value == smsGrid ?
+                support_params.interface_angle : support_params.raft_interface_angle(support_layer.interface_id());
 
             // Find polygons with the same print_z.
             SupportGeneratorLayerExtruded &bottom_contact_layer = layer_cache.bottom_contact_layer;
@@ -4412,7 +4416,8 @@ void generate_support_toolpaths(
             if (idx_layer_intermediate < intermediate_layers.size() && intermediate_layers[idx_layer_intermediate]->print_z < support_layer.print_z + EPSILON)
                 base_layer.layer = intermediate_layers[idx_layer_intermediate];
 
-            bool raft_layer = support_layer_id == n_raft_layers;
+            // This layer is a raft contact layer. Any contact polygons at this layer are raft contacts.
+            bool raft_layer = slicing_params.interface_raft_layers && top_contact_layer.layer && is_approx(top_contact_layer.layer->print_z, slicing_params.raft_contact_top_z);
             if (config.support_material_interface_layers == 0) {
                 // If no top interface layers were requested, we treat the contact layer exactly as a generic base layer.
                 // Don't merge the raft contact layer though.
@@ -4470,7 +4475,9 @@ void generate_support_toolpaths(
                             // If zero interface layers are configured, use the same angle as for the base layers.
                             angles[support_layer_id % angles.size()] :
                             // Use interface angle for the interface layers.
-                            support_params.interface_angle + interface_angle_delta;
+                            raft_contact ? 
+                                support_params.raft_interface_angle(support_layer.interface_id()) :
+                                support_interface_angle;
                     double density = raft_contact ? support_params.raft_interface_density : interface_as_base ? support_params.support_density : support_params.interface_density;
                     filler->spacing = raft_contact ? support_params.raft_interface_flow.spacing() :
                         interface_as_base ? support_params.support_material_flow.spacing() : support_params.support_material_interface_flow.spacing();
@@ -4499,7 +4506,7 @@ void generate_support_toolpaths(
                 // the bridging flow does not quite apply. Reduce the flow to area of an ellipse? (A = pi * a * b)
                 assert(! base_interface_layer.layer->bridging);
                 Flow interface_flow = support_params.support_material_flow.with_height(float(base_interface_layer.layer->height));
-                filler->angle   = support_params.interface_angle + interface_angle_delta;
+                filler->angle   = support_interface_angle;
                 filler->spacing = support_params.support_material_interface_flow.spacing();
                 filler->link_max_length = coord_t(scale_(filler->spacing * link_max_length_factor / support_params.interface_density));
                 fill_expolygons_generate_paths(
diff --git a/src/libslic3r/SupportMaterial.hpp b/src/libslic3r/SupportMaterial.hpp
index eda70517f..2bd321144 100644
--- a/src/libslic3r/SupportMaterial.hpp
+++ b/src/libslic3r/SupportMaterial.hpp
@@ -161,6 +161,14 @@ struct SupportParameters {
     InfillPattern 			contact_fill_pattern;
     // Shall the sparse (base) layers be printed with a single perimeter line (sheath) for robustness?
     bool                    with_sheath;
+
+    float 					raft_angle_1st_layer;
+    float 					raft_angle_base;
+    float 					raft_angle_interface;
+
+    // Produce a raft interface angle for a given SupportLayer::interface_id()
+    float 					raft_interface_angle(size_t interface_id) const 
+    	{ return this->raft_angle_interface + ((interface_id & 1) ? float(- M_PI / 4.) : float(+ M_PI / 4.)); }
 };
 
 // Remove bridges from support contact areas.