diff --git a/resources/icons/sla_support_points_reset.png b/resources/icons/sla_support_points_reset.png
new file mode 100644
index 000000000..6e051fe95
Binary files /dev/null and b/resources/icons/sla_support_points_reset.png differ
diff --git a/resources/icons/sla_support_points_tooltip.png b/resources/icons/sla_support_points_tooltip.png
new file mode 100644
index 000000000..1bdfd3440
Binary files /dev/null and b/resources/icons/sla_support_points_tooltip.png differ
diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp
index ae8feee77..47e750427 100644
--- a/src/slic3r/GUI/GLCanvas3D.cpp
+++ b/src/slic3r/GUI/GLCanvas3D.cpp
@@ -1,3 +1,4 @@
+#include "slic3r/GUI/GLGizmo.hpp"
 #include "GLCanvas3D.hpp"
 
 #include "admesh/stl.h"
@@ -7,7 +8,6 @@
 #include "slic3r/GUI/GLShader.hpp"
 #include "slic3r/GUI/GUI.hpp"
 #include "slic3r/GUI/PresetBundle.hpp"
-#include "slic3r/GUI/GLGizmo.hpp"
 #include "libslic3r/ClipperUtils.hpp"
 #include "libslic3r/PrintConfig.hpp"
 #include "libslic3r/GCode/PreviewData.hpp"
diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp
index 3a6759393..ca52c244a 100644
--- a/src/slic3r/GUI/GLCanvas3D.hpp
+++ b/src/slic3r/GUI/GLCanvas3D.hpp
@@ -738,7 +738,6 @@ private:
     wxWindow *m_external_gizmo_widgets_parent;
 #endif // not ENABLE_IMGUI
 
-    void post_event(wxEvent &&event);
     void viewport_changed();
 
 public:
@@ -752,6 +751,7 @@ public:
     wxGLCanvas* get_wxglcanvas() { return m_canvas; }
 
     bool init(bool useVBOs, bool use_legacy_opengl);
+    void post_event(wxEvent &&event);
 
 #if !ENABLE_USE_UNIQUE_GLCONTEXT
     bool set_current();
diff --git a/src/slic3r/GUI/GLGizmo.cpp b/src/slic3r/GUI/GLGizmo.cpp
index e2d57c8ab..ae2d05542 100644
--- a/src/slic3r/GUI/GLGizmo.cpp
+++ b/src/slic3r/GUI/GLGizmo.cpp
@@ -10,7 +10,6 @@
 #include <Eigen/Dense>
 #include "libslic3r/Geometry.hpp"
 
-#include <igl/unproject_onto_mesh.h>
 #include <GL/glew.h>
 
 #include <SLA/SLASupportTree.hpp>
@@ -1627,7 +1626,11 @@ void GLGizmoSlaSupports::set_model_object_ptr(ModelObject* model_object)
     {
         m_starting_center = Vec3d::Zero();
         m_model_object = model_object;
-        m_model_object_matrix = model_object->instances.front()->get_matrix();
+
+        int selected_instance = m_parent.get_selection().get_instance_idx();
+        assert(selected_instance < (int)model_object->instances.size());
+
+        m_instance_matrix = model_object->instances[selected_instance]->get_matrix();
         if (is_mesh_update_necessary())
             update_mesh();
     }
@@ -1639,7 +1642,7 @@ void GLGizmoSlaSupports::on_render(const GLCanvas3D::Selection& selection) const
     ::glEnable(GL_DEPTH_TEST);
 
     // the dragged_offset is a vector measuring where was the object moved
-    // with the gizmo being on. This is reset in set_flattening_data and
+    // with the gizmo being on. This is reset in set_model_object_ptr and
     // does not work correctly when there are multiple copies.
     
     if (m_starting_center == Vec3d::Zero())
@@ -1653,7 +1656,7 @@ void GLGizmoSlaSupports::on_render(const GLCanvas3D::Selection& selection) const
     }
 
     ::glPushMatrix();
-    ::glTranslatef((GLfloat)dragged_offset(0), (GLfloat)dragged_offset(1), (GLfloat)dragged_offset(2));
+    //::glTranslatef((GLfloat)dragged_offset(0), (GLfloat)dragged_offset(1), (GLfloat)dragged_offset(2));
     render_grabbers();
     ::glPopMatrix();
 
@@ -1675,33 +1678,35 @@ void GLGizmoSlaSupports::on_render_for_picking(const GLCanvas3D::Selection& sele
 
 void GLGizmoSlaSupports::render_grabbers(bool picking) const
 {
-    for (int i = 0; i < (int)m_grabbers.size(); ++i)
-    {
-        if (!m_grabbers[i].enabled)
-            continue;
+    for (const ModelInstance* inst : m_model_object->instances) {
+        for (int i = 0; i < (int)m_grabbers.size(); ++i)
+        {
+            if (!m_grabbers[i].enabled)
+                continue;
 
-        float render_color[3];
-        if (!picking && m_hover_id == i) {
-            render_color[0] = 1.0f - m_grabbers[i].color[0];
-            render_color[1] = 1.0f - m_grabbers[i].color[1];
-            render_color[2] = 1.0f - m_grabbers[i].color[2];
+            float render_color[3];
+            if (!picking && m_hover_id == i) {
+                render_color[0] = 1.0f - m_grabbers[i].color[0];
+                render_color[1] = 1.0f - m_grabbers[i].color[1];
+                render_color[2] = 1.0f - m_grabbers[i].color[2];
+            }
+            else
+                ::memcpy((void*)render_color, (const void*)m_grabbers[i].color, 3 * sizeof(float));
+            if (!picking)
+                ::glEnable(GL_LIGHTING);
+            ::glColor3f((GLfloat)render_color[0], (GLfloat)render_color[1], (GLfloat)render_color[2]);
+            ::glPushMatrix();
+            Vec3d center = inst->get_matrix() * m_grabbers[i].center;
+            ::glTranslatef((GLfloat)center(0), (GLfloat)center(1), (GLfloat)center(2));
+            GLUquadricObj *quadric;
+            quadric = ::gluNewQuadric();
+            ::gluQuadricDrawStyle(quadric, GLU_FILL );
+            ::gluSphere( quadric , 0.75f, 36 , 18 );
+            ::gluDeleteQuadric(quadric);
+            ::glPopMatrix();
+            if (!picking)
+                ::glDisable(GL_LIGHTING);
         }
-        else
-            ::memcpy((void*)render_color, (const void*)m_grabbers[i].color, 3 * sizeof(float));
-        if (!picking)
-            ::glEnable(GL_LIGHTING);
-        ::glColor3f((GLfloat)render_color[0], (GLfloat)render_color[1], (GLfloat)render_color[2]);
-        ::glPushMatrix();
-        Vec3d center = m_model_object_matrix * m_grabbers[i].center;
-        ::glTranslatef((GLfloat)center(0), (GLfloat)center(1), (GLfloat)center(2));
-        GLUquadricObj *quadric;
-        quadric = ::gluNewQuadric();
-        ::gluQuadricDrawStyle(quadric, GLU_FILL );
-        ::gluSphere( quadric , 0.75f, 36 , 18 );
-        ::gluDeleteQuadric(quadric);
-        ::glPopMatrix();
-        if (!picking)
-            ::glDisable(GL_LIGHTING);
     }
 }
 
@@ -1710,7 +1715,7 @@ bool GLGizmoSlaSupports::is_mesh_update_necessary() const
     if (m_state != On || !m_model_object || m_model_object->instances.empty())
         return false;
 
-    if ((m_model_object->instances.front()->get_matrix() * m_source_data.matrix.inverse() * Vec3d(1., 1., 1.) - Vec3d(1., 1., 1.)).norm() > 0.001)
+    if ((m_instance_matrix * m_source_data.matrix.inverse() * Vec3d(1., 1., 1.) - Vec3d(1., 1., 1.)).norm() > 0.001)
         return true;
 
     // following should detect direct mesh changes (can be removed after the mesh is made completely immutable):
@@ -1726,7 +1731,7 @@ void GLGizmoSlaSupports::update_mesh()
 {
     Eigen::MatrixXf& V = m_V;
     Eigen::MatrixXi& F = m_F;
-    TriangleMesh mesh(m_model_object->mesh());
+    TriangleMesh mesh = m_model_object->mesh();
     const stl_file& stl = mesh.stl;
     V.resize(3 * stl.stats.number_of_facets, 3);
     F.resize(stl.stats.number_of_facets, 3);
@@ -1739,15 +1744,19 @@ void GLGizmoSlaSupports::update_mesh()
         F(i, 1) = 3*i+1;
         F(i, 2) = 3*i+2;
     }
-    m_source_data.matrix = m_model_object->instances.front()->get_matrix();
-    const float* first_vertex = m_model_object->volumes.front()->get_convex_hull().first_vertex();
-    m_source_data.mesh_first_point = Vec3d((double)first_vertex[0], (double)first_vertex[1], (double)first_vertex[2]);
+
+    m_AABB = igl::AABB<Eigen::MatrixXf,3>();
+    m_AABB.init(m_V, m_F);
+
+    m_source_data.matrix = m_instance_matrix;
+
     // we'll now reload Grabbers (selection might have changed):
     m_grabbers.clear();
     for (const Vec3f& point : m_model_object->sla_support_points) {
         m_grabbers.push_back(Grabber());
         m_grabbers.back().center = point.cast<double>();
     }
+    m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
 }
 
 Vec3f GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse_pos)
@@ -1763,24 +1772,21 @@ Vec3f GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse_pos)
     Eigen::Matrix<GLdouble, 4, 4, Eigen::DontAlign> projection_matrix;
     ::glGetDoublev(GL_PROJECTION_MATRIX, projection_matrix.data());
 
-    int fid = 0;
-    Eigen::Vector3f bc(0, 0, 0);
-    if (!igl::unproject_onto_mesh(Vec2f(mouse_pos(0), viewport(3)-mouse_pos(1)), modelview_matrix.cast<float>(), projection_matrix.cast<float>(), viewport.cast<float>(), m_V, m_F, fid, bc))
-    /*if (!igl::embree::unproject_onto_mesh(Vec2f(mouse_pos(0), viewport(3)-mouse_pos(1)),
-                                 m_F,
-                                 modelview_matrix.cast<float>(),
-                                 projection_matrix.cast<float>(),
-                                 viewport.cast<float>(),
-                                 m_intersector,
-                                 fid,
-                                 bc))*/
-        throw "unable to unproject_onto_mesh";
+    Vec3d point1;
+    Vec3d point2;
+    ::gluUnProject(mouse_pos(0), viewport(3)-mouse_pos(1), 0.f, modelview_matrix.data(), projection_matrix.data(), viewport.data(), &point1(0), &point1(1), &point1(2));
+    ::gluUnProject(mouse_pos(0), viewport(3)-mouse_pos(1), 1.f, modelview_matrix.data(), projection_matrix.data(), viewport.data(), &point2(0), &point2(1), &point2(2));
 
-    const Vec3f& a = m_V.row(m_F(fid, 0));
-    const Vec3f& b = m_V.row(m_F(fid, 1));
-    const Vec3f& c = m_V.row(m_F(fid, 2));
-    Vec3f point = bc(0)*a + bc(1)*b + bc(2)*c;
-    return m_model_object->instances.front()->get_matrix().inverse().cast<float>() * point;
+    igl::Hit hit;
+
+    if (!m_AABB.intersect_ray(m_V, m_F, point1.cast<float>(), (point2-point1).cast<float>(), hit))
+        throw std::invalid_argument("unproject_on_mesh(): No intersection found.");
+
+    int fid = hit.id;
+    Vec3f bc(1-hit.u-hit.v, hit.u, hit.v);
+    Vec3f point = bc(0) * m_V.row(m_F(fid, 0)) + bc(1) * m_V.row(m_F(fid, 1)) + bc(2)*m_V.row(m_F(fid, 2));
+
+    return m_instance_matrix.inverse().cast<float>() * point;
 }
 
 void GLGizmoSlaSupports::clicked_on_object(const Vec2d& mouse_position)
@@ -1788,14 +1794,17 @@ void GLGizmoSlaSupports::clicked_on_object(const Vec2d& mouse_position)
     Vec3f new_pos;
     try {
         new_pos = unproject_on_mesh(mouse_position); // this can throw - we don't want to create a new grabber in that case
-        m_grabbers.push_back(Grabber());
-        m_grabbers.back().center = new_pos.cast<double>();
-        m_model_object->sla_support_points.push_back(new_pos);
-
-        // This should trigger the support generation
-        // wxGetApp().plater()->reslice();
     }
-    catch (...) {}
+    catch (...) { return; }
+
+    m_grabbers.push_back(Grabber());
+    m_grabbers.back().center = new_pos.cast<double>();
+    m_model_object->sla_support_points.push_back(new_pos);
+
+    // This should trigger the support generation
+    // wxGetApp().plater()->reslice();
+
+    m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
 }
 
 void GLGizmoSlaSupports::delete_current_grabber(bool delete_all)
@@ -1816,6 +1825,8 @@ void GLGizmoSlaSupports::delete_current_grabber(bool delete_all)
             // This should trigger the support generation
             // wxGetApp().plater()->reslice();
         }
+
+    m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
 }
 
 void GLGizmoSlaSupports::on_update(const UpdateData& data)
@@ -1824,20 +1835,21 @@ void GLGizmoSlaSupports::on_update(const UpdateData& data)
         Vec3f new_pos;
         try {
             new_pos = unproject_on_mesh(Vec2d((*data.mouse_pos)(0), (*data.mouse_pos)(1)));
-            m_grabbers[m_hover_id].center = new_pos.cast<double>();
-            m_model_object->sla_support_points[m_hover_id] = new_pos;
         }
-        catch (...) {}
+        catch (...) { return; }
+        m_grabbers[m_hover_id].center = new_pos.cast<double>();
+        m_model_object->sla_support_points[m_hover_id] = new_pos;
+        m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
     }
 }
 
 
 void GLGizmoSlaSupports::render_tooltip_texture() const {
     if (m_tooltip_texture.get_id() == 0)
-        if (!m_tooltip_texture.load_from_file(resources_dir() + "/icons/variable_layer_height_tooltip.png", false))
+        if (!m_tooltip_texture.load_from_file(resources_dir() + "/icons/sla_support_points_tooltip.png", false))
             return;
     if (m_reset_texture.get_id() == 0)
-        if (!m_reset_texture.load_from_file(resources_dir() + "/icons/variable_layer_height_reset.png", false))
+        if (!m_reset_texture.load_from_file(resources_dir() + "/icons/sla_support_points_reset.png", false))
             return;
 
     float zoom = m_parent.get_camera_zoom();
@@ -1863,7 +1875,8 @@ void GLGizmoSlaSupports::render_tooltip_texture() const {
 
 bool GLGizmoSlaSupports::on_is_activable(const GLCanvas3D::Selection& selection) const
 {
-    return (wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptSLA);
+    return (wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptSLA)
+        && selection.is_from_single_instance();
 }
 
 bool GLGizmoSlaSupports::on_is_selectable() const
diff --git a/src/slic3r/GUI/GLGizmo.hpp b/src/slic3r/GUI/GLGizmo.hpp
index 64bd71876..6ce22f395 100644
--- a/src/slic3r/GUI/GLGizmo.hpp
+++ b/src/slic3r/GUI/GLGizmo.hpp
@@ -1,6 +1,8 @@
 #ifndef slic3r_GLGizmo_hpp_
 #define slic3r_GLGizmo_hpp_
 
+#include <igl/AABB.h>
+
 #include "../../slic3r/GUI/GLTexture.hpp"
 #include "../../slic3r/GUI/GLCanvas3D.hpp"
 #include "../../libslic3r/Point.hpp"
@@ -449,11 +451,13 @@ class GLGizmoSlaSupports : public GLGizmoBase
 {
 private:
     ModelObject* m_model_object = nullptr;
-    Transform3d m_model_object_matrix;
+    Transform3d m_instance_matrix;
     Vec3f unproject_on_mesh(const Vec2d& mouse_pos);
 
     Eigen::MatrixXf m_V; // vertices
     Eigen::MatrixXi m_F; // facets indices
+    igl::AABB<Eigen::MatrixXf,3> m_AABB;
+
     struct SourceDataSummary {
         BoundingBoxf3 bounding_box;
         Transform3d matrix;