diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt
index 1f1284a9e..2ac8a1ff0 100644
--- a/src/slic3r/CMakeLists.txt
+++ b/src/slic3r/CMakeLists.txt
@@ -150,6 +150,8 @@ set(SLIC3R_GUI_SOURCES
     GUI/Jobs/ArrangeJob.cpp
     GUI/Jobs/RotoptimizeJob.hpp
     GUI/Jobs/RotoptimizeJob.cpp
+    GUI/Jobs/SLAImportJob.hpp
+    GUI/Jobs/SLAImportJob.cpp
     GUI/Jobs/ProgressIndicator.hpp
     GUI/ProgressStatusBar.hpp
     GUI/ProgressStatusBar.cpp
diff --git a/src/slic3r/GUI/Jobs/SLAImportJob.cpp b/src/slic3r/GUI/Jobs/SLAImportJob.cpp
new file mode 100644
index 000000000..e791bf94e
--- /dev/null
+++ b/src/slic3r/GUI/Jobs/SLAImportJob.cpp
@@ -0,0 +1,226 @@
+#include "SLAImportJob.hpp"
+
+#include "slic3r/GUI/GUI.hpp"
+#include "slic3r/GUI/GUI_App.hpp"
+#include "slic3r/GUI/AppConfig.hpp"
+#include "slic3r/GUI/Plater.hpp"
+#include "slic3r/GUI/PresetBundle.hpp"
+#include "slic3r/GUI/GUI_ObjectList.hpp"
+#include "slic3r/Utils/SLAImport.hpp"
+
+#include <wx/dialog.h>
+#include <wx/stattext.h>
+#include <wx/combobox.h>
+#include <wx/filename.h>
+#include <wx/filepicker.h>
+
+namespace Slic3r { namespace GUI {
+
+enum class Sel { modelAndProfile, profileOnly, modelOnly};
+    
+class ImportDlg: public wxDialog {
+    wxFilePickerCtrl *m_filepicker;
+    wxComboBox *m_import_dropdown, *m_quality_dropdown;
+    
+public:
+    ImportDlg(Plater *plater)
+        : wxDialog{plater, wxID_ANY, "Import SLA archive"}
+    {
+        auto szvert = new wxBoxSizer{wxVERTICAL};
+        auto szfilepck = new wxBoxSizer{wxHORIZONTAL};
+        
+        m_filepicker = new wxFilePickerCtrl(this, wxID_ANY,
+                                            from_u8(wxGetApp().app_config->get_last_dir()), _(L("Choose SLA archive:")),
+                                            "SL1 archive files (*.sl1, *.zip)|*.sl1;*.SL1;*.zip;*.ZIP",
+                                            wxDefaultPosition, wxDefaultSize, wxFLP_DEFAULT_STYLE | wxFD_OPEN | wxFD_FILE_MUST_EXIST);
+        
+        szfilepck->Add(new wxStaticText(this, wxID_ANY, _(L("Import file: "))), 0, wxALIGN_CENTER);
+        szfilepck->Add(m_filepicker, 1);
+        szvert->Add(szfilepck, 0, wxALL | wxEXPAND, 5);
+        
+        auto szchoices = new wxBoxSizer{wxHORIZONTAL};
+        
+        static const std::vector<wxString> inp_choices = {
+            _(L("Import model and profile")),
+            _(L("Import profile only")),
+            _(L("Import model only"))
+        };
+        
+        m_import_dropdown = new wxComboBox(
+            this, wxID_ANY, inp_choices[0], wxDefaultPosition, wxDefaultSize,
+            inp_choices.size(), inp_choices.data(), wxCB_READONLY | wxCB_DROPDOWN);
+        
+        szchoices->Add(m_import_dropdown);
+        szchoices->Add(new wxStaticText(this, wxID_ANY, _(L("Quality: "))), 0, wxALIGN_CENTER | wxALL, 5);
+        
+        static const std::vector<wxString> qual_choices = {
+            _(L("Accurate")),
+            _(L("Balanced")),
+            _(L("Quick"))
+        };
+        
+        m_quality_dropdown = new wxComboBox(
+            this, wxID_ANY, qual_choices[0], wxDefaultPosition, wxDefaultSize,
+            qual_choices.size(), qual_choices.data(), wxCB_READONLY | wxCB_DROPDOWN);
+        szchoices->Add(m_quality_dropdown);
+        
+        m_import_dropdown->Bind(wxEVT_COMBOBOX, [this](wxCommandEvent &) {
+            if (get_selection() == Sel::profileOnly)
+                m_quality_dropdown->Disable();
+            else m_quality_dropdown->Enable();
+        });
+        
+        szvert->Add(szchoices, 0, wxALL, 5);
+        szvert->AddStretchSpacer(1);
+        auto szbtn = new wxBoxSizer(wxHORIZONTAL);
+        szbtn->Add(new wxButton{this, wxID_CANCEL});
+        szbtn->Add(new wxButton{this, wxID_OK});
+        szvert->Add(szbtn, 0, wxALIGN_RIGHT | wxALL, 5);
+        
+        SetSizerAndFit(szvert);
+    }
+    
+    Sel get_selection() const
+    {
+        int sel = m_import_dropdown->GetSelection();
+        return Sel(std::min(int(Sel::modelOnly), std::max(0, sel)));
+    }
+    
+    Vec2i get_marchsq_windowsize() const
+    {
+        enum { Accurate, Balanced, Fast};
+        
+        switch(m_quality_dropdown->GetSelection())
+        {
+        case Fast: return {8, 8};
+        case Balanced: return {4, 4};
+        default:
+        case Accurate:
+            return {2, 2};
+        }
+    }
+    
+    wxString get_path() const
+    {
+        return m_filepicker->GetPath();
+    }
+};
+
+class SLAImportJob::priv {
+public:
+    Plater *plater;
+    
+    Sel sel = Sel::modelAndProfile;
+    
+    TriangleMesh       mesh;
+    DynamicPrintConfig profile;
+    wxString           path;
+    Vec2i              win = {2, 2};
+    std::string        err;
+    
+    priv(Plater *plt): plater{plt} {}
+};
+
+SLAImportJob::SLAImportJob(std::shared_ptr<ProgressIndicator> pri, Plater *plater)
+    : Job{std::move(pri)}, p{std::make_unique<priv>(plater)}
+{}
+
+SLAImportJob::~SLAImportJob() = default;
+
+void SLAImportJob::process()
+{
+    auto progr = [this](int s) {
+        if (s < 100) update_status(int(s), _(L("Importing SLA archive")));
+        return !was_canceled();
+    };
+    
+    if (p->path.empty()) return;
+    
+    std::string path = p->path.ToUTF8().data();
+    try {
+        switch (p->sel) {
+        case Sel::modelAndProfile:
+            import_sla_archive(path, p->win, p->mesh, p->profile, progr);
+            break;
+        case Sel::modelOnly:
+            import_sla_archive(path, p->win, p->mesh, progr);
+            break;
+        case Sel::profileOnly:
+            import_sla_archive(path, p->profile);
+            break;
+        }
+        
+    } catch (std::exception &ex) {
+        p->err = ex.what();
+    }
+    
+    update_status(100, was_canceled() ? _(L("Importing canceled.")) :
+                                        _(L("Importing done.")));
+}
+
+void SLAImportJob::reset()
+{
+    p->sel     = Sel::modelAndProfile;
+    p->mesh    = {};
+    p->profile = {};
+    p->win     = {2, 2};
+    p->path.Clear();
+}
+
+void SLAImportJob::prepare()
+{
+    reset();
+    
+    ImportDlg dlg{p->plater};
+    
+    if (dlg.ShowModal() == wxID_OK) {
+        auto path = dlg.get_path();
+        auto nm = wxFileName(path);
+        p->path = !nm.Exists(wxFILE_EXISTS_REGULAR) ? "" : path.ToUTF8();
+        p->sel  = dlg.get_selection();
+        p->win  = dlg.get_marchsq_windowsize();
+    } else {
+        p->path = "";
+    }
+}
+
+void SLAImportJob::finalize()
+{
+    // Ignore the arrange result if aborted.
+    if (was_canceled()) return;
+    
+    if (!p->err.empty()) {
+        show_error(p->plater, p->err);
+        p->err = "";
+        return;
+    }
+    
+    std::string name = wxFileName(p->path).GetName().ToUTF8().data();
+    
+    if (!p->profile.empty()) {
+        const ModelObjectPtrs& objects = p->plater->model().objects;
+        for (auto object : objects)
+            if (object->volumes.size() > 1)
+            {
+                Slic3r::GUI::show_info(nullptr,
+                                       _(L("You cannot load SLA project with a multi-part object on the bed")) + "\n\n" +
+                                       _(L("Please check your object list before preset changing.")),
+                                       _(L("Attention!")) );
+                return;
+            }
+        
+        DynamicPrintConfig config = {};
+        config.apply(SLAFullPrintConfig::defaults());
+        config += std::move(p->profile);
+        
+        wxGetApp().preset_bundle->load_config_model(name, std::move(config));
+        wxGetApp().load_current_presets();
+    }
+    
+    if (!p->mesh.empty())
+        p->plater->sidebar().obj_list()->load_mesh_object(p->mesh, name);
+    
+    reset();
+}
+
+}}
diff --git a/src/slic3r/GUI/Jobs/SLAImportJob.hpp b/src/slic3r/GUI/Jobs/SLAImportJob.hpp
new file mode 100644
index 000000000..cff6cc899
--- /dev/null
+++ b/src/slic3r/GUI/Jobs/SLAImportJob.hpp
@@ -0,0 +1,31 @@
+#ifndef SLAIMPORTJOB_HPP
+#define SLAIMPORTJOB_HPP
+
+#include "Job.hpp"
+
+namespace Slic3r { namespace GUI {
+
+class Plater;
+
+class SLAImportJob : public Job {    
+    class priv;
+    
+    std::unique_ptr<priv> p;
+    
+public:
+    SLAImportJob(std::shared_ptr<ProgressIndicator> pri, Plater *plater);
+    ~SLAImportJob();
+
+    void process() override;
+    
+    void reset();
+    
+protected:
+    void prepare() override;
+    
+    void finalize() override;
+};
+
+}}     // namespace Slic3r::GUI
+
+#endif // SLAIMPORTJOB_HPP
diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp
index f9fe06a85..db9e7e59a 100644
--- a/src/slic3r/GUI/Plater.cpp
+++ b/src/slic3r/GUI/Plater.cpp
@@ -27,7 +27,6 @@
 #include <wx/numdlg.h>
 #include <wx/debug.h>
 #include <wx/busyinfo.h>
-#include <wx/filename.h>
 
 #include "libslic3r/libslic3r.h"
 #include "libslic3r/Format/STL.hpp"
@@ -64,6 +63,7 @@
 #include "Tab.hpp"
 #include "Jobs/ArrangeJob.hpp"
 #include "Jobs/RotoptimizeJob.hpp"
+#include "Jobs/SLAImportJob.hpp"
 #include "PresetBundle.hpp"
 #include "BackgroundSlicingProcess.hpp"
 #include "ProgressStatusBar.hpp"
@@ -73,7 +73,6 @@
 #include "../Utils/PrintHost.hpp"
 #include "../Utils/FixModelByWin10.hpp"
 #include "../Utils/UndoRedo.hpp"
-#include "../Utils/SLAImport.hpp"
 #include "RemovableDriveManager.hpp"
 #if ENABLE_NON_STATIC_CANVAS_MANAGER
 #ifdef __APPLE__
@@ -1487,7 +1486,7 @@ struct Plater::priv
     class Jobs: public ExclusiveJobGroup
     {
         priv *m;
-        size_t m_arrange_id, m_rotoptimize_id;
+        size_t m_arrange_id, m_rotoptimize_id, m_sla_import_id;
         
         void before_start() override { m->background_process.stop(); }
         
@@ -1496,6 +1495,7 @@ struct Plater::priv
         {
             m_arrange_id = add_job(std::make_unique<ArrangeJob>(m->statusbar(), m->q));
             m_rotoptimize_id = add_job(std::make_unique<RotoptimizeJob>(m->statusbar(), m->q));
+            m_sla_import_id = add_job(std::make_unique<SLAImportJob>(m->statusbar(), m->q));
         }
         
         void arrange()
@@ -1510,6 +1510,12 @@ struct Plater::priv
             start(m_rotoptimize_id);
         }
         
+        void import_sla_arch()
+        {
+            m->take_snapshot(_(L("Import SLA archive")));
+            start(m_sla_import_id);
+        }
+        
     } m_ui_jobs;
 
     bool                        delayed_scene_refresh;
@@ -4255,19 +4261,7 @@ void Plater::add_model()
 
 void Plater::import_sl1_archive()
 {
-    wxFileDialog dlg(this, _(L("Choose SL1 archive:")),
-                     from_u8(wxGetApp().app_config->get_last_dir()), "",
-                     "SL1 archive files (*.sl1)|*.sl1;*.SL1;*.zip;*.ZIP",
-                     wxFD_OPEN | wxFD_FILE_MUST_EXIST);
-
-    if (dlg.ShowModal() == wxID_OK) {
-        try {
-            TriangleMesh mesh = import_model_from_sla_zip(dlg.GetPath());
-            p->sidebar->obj_list()->load_mesh_object(mesh, wxFileName(dlg.GetPath()).GetName());
-        } catch (std::exception &ex) {
-            show_error(this, ex.what());
-        }
-    }
+    p->m_ui_jobs.import_sla_arch();
 }
 
 void Plater::extract_config_from_project()