diff --git a/deps/wxWidgets/wxWidgets.cmake b/deps/wxWidgets/wxWidgets.cmake index ee38309a6..bf23698cf 100644 --- a/deps/wxWidgets/wxWidgets.cmake +++ b/deps/wxWidgets/wxWidgets.cmake @@ -1,4 +1,4 @@ -if (APPLE AND ${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm") +if (APPLE) # The new OSX 11 (Big Sur) is not compatible with wxWidgets 3.1.3. # Let's use patched wxWidgets 3.1.4, even though it is not quite tested. set(_wx_git_tag v3.1.4-patched) diff --git a/src/PrusaSlicer.cpp b/src/PrusaSlicer.cpp index 277bf1250..35450782b 100644 --- a/src/PrusaSlicer.cpp +++ b/src/PrusaSlicer.cpp @@ -57,6 +57,12 @@ using namespace Slic3r; +static PrinterTechnology get_printer_technology(const DynamicConfig &config) +{ + const ConfigOptionEnum *opt = config.option>("printer_technology"); + return (opt == nullptr) ? ptUnknown : opt->value; +} + int CLI::run(int argc, char **argv) { // Mark the main thread for the debugger and for runtime checks. @@ -95,7 +101,7 @@ int CLI::run(int argc, char **argv) m_extra_config.apply(m_config, true); m_extra_config.normalize_fdm(); - PrinterTechnology printer_technology = Slic3r::printer_technology(m_config); + PrinterTechnology printer_technology = get_printer_technology(m_config); bool start_gui = m_actions.empty() && // cutting transformations are setting an "export" action. @@ -130,7 +136,7 @@ int CLI::run(int argc, char **argv) return 1; } config.normalize_fdm(); - PrinterTechnology other_printer_technology = Slic3r::printer_technology(config); + PrinterTechnology other_printer_technology = get_printer_technology(config); if (printer_technology == ptUnknown) { printer_technology = other_printer_technology; } else if (printer_technology != other_printer_technology && other_printer_technology != ptUnknown) { @@ -167,7 +173,7 @@ int CLI::run(int argc, char **argv) // When loading an AMF or 3MF, config is imported as well, including the printer technology. DynamicPrintConfig config; model = Model::read_from_file(file, &config, true); - PrinterTechnology other_printer_technology = Slic3r::printer_technology(config); + PrinterTechnology other_printer_technology = get_printer_technology(config); if (printer_technology == ptUnknown) { printer_technology = other_printer_technology; } @@ -197,6 +203,10 @@ int CLI::run(int argc, char **argv) // Normalizing after importing the 3MFs / AMFs m_print_config.normalize_fdm(); + if (printer_technology == ptUnknown) + printer_technology = std::find(m_actions.begin(), m_actions.end(), "export_sla") == m_actions.end() ? ptFFF : ptSLA; + m_print_config.option>("printer_technology", true)->value = printer_technology; + // Initialize full print configs for both the FFF and SLA technologies. FullPrintConfig fff_print_config; SLAFullPrintConfig sla_print_config; @@ -205,9 +215,8 @@ int CLI::run(int argc, char **argv) if (printer_technology == ptFFF) { fff_print_config.apply(m_print_config, true); m_print_config.apply(fff_print_config, true); - } else if (printer_technology == ptSLA) { - // The default value has to be different from the one in fff mode. - sla_print_config.printer_technology.value = ptSLA; + } else { + assert(printer_technology == ptSLA); sla_print_config.output_filename_format.value = "[input_filename_base].sl1"; // The default bed shape should reflect the default display parameters @@ -220,10 +229,12 @@ int CLI::run(int argc, char **argv) m_print_config.apply(sla_print_config, true); } - std::string validity = m_print_config.validate(); - if (!validity.empty()) { - boost::nowide::cerr << "error: " << validity << std::endl; - return 1; + { + std::string validity = m_print_config.validate(); + if (! validity.empty()) { + boost::nowide::cerr << "Error: The composite configation is not valid: " << validity << std::endl; + return 1; + } } // Loop through transform options. @@ -481,12 +492,6 @@ int CLI::run(int argc, char **argv) if (printer_technology == ptFFF) { for (auto* mo : model.objects) fff_print.auto_assign_extruders(mo); - } else { - // The default for "output_filename_format" is good for FDM: "[input_filename_base].gcode" - // Replace it with a reasonable SLA default. - std::string &format = m_print_config.opt_string("output_filename_format", true); - if (format == static_cast(m_print_config.def()->get("output_filename_format")->default_value.get())->value) - format = "[input_filename_base].SL1"; } print->apply(model, m_print_config); std::string err = print->validate(); @@ -647,6 +652,7 @@ bool CLI::setup(int argc, char **argv) set_logging_level(opt_loglevel->value); } + //FIXME Validating at this stage most likely does not make sense, as the config is not fully initialized yet. std::string validity = m_config.validate(); // Initialize with defaults. @@ -656,6 +662,7 @@ bool CLI::setup(int argc, char **argv) set_data_dir(m_config.opt_string("datadir")); + //FIXME Validating at this stage most likely does not make sense, as the config is not fully initialized yet. if (!validity.empty()) { boost::nowide::cerr << "error: " << validity << std::endl; return false; diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index cc9dfce30..87bfe3065 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -2591,10 +2591,10 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, throw Slic3r::InvalidArgument("Invalid speed"); } } - if (this->on_first_layer()) - speed = m_config.get_abs_value("first_layer_speed", speed); if (m_volumetric_speed != 0. && speed == 0) speed = m_volumetric_speed / path.mm3_per_mm; + if (this->on_first_layer()) + speed = m_config.get_abs_value("first_layer_speed", speed); if (m_config.max_volumetric_speed.value > 0) { // cap speed with max_volumetric_speed anyway (even if user is not using autospeed) speed = std::min( diff --git a/src/libslic3r/PresetBundle.cpp b/src/libslic3r/PresetBundle.cpp index b31ee6664..b57ff0e14 100644 --- a/src/libslic3r/PresetBundle.cpp +++ b/src/libslic3r/PresetBundle.cpp @@ -928,7 +928,11 @@ void PresetBundle::load_config_file_config_bundle(const std::string &path, const if (opt_compatible->type() == coStrings) static_cast(opt_compatible)->values.clear(); } - collection_dst.load_preset(path, preset_name_dst, std::move(preset_src->config), activate).is_external = true; + (collection_dst.type() == Preset::TYPE_FILAMENT ? + collection_dst.load_preset(path, preset_name_dst, preset_src->config, activate) : + // Only move the source config for non filament profiles, as single filament profile may be referenced multiple times. + collection_dst.load_preset(path, preset_name_dst, std::move(preset_src->config), activate)) + .is_external = true; return preset_name_dst; }; load_one(this->prints, tmp_bundle.prints, tmp_bundle.prints .get_selected_preset_name(), true); diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 693c4e5be..d50ff19e8 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -1400,8 +1400,12 @@ std::string Print::validate() const #endif auto validate_extrusion_width = [min_nozzle_diameter, max_nozzle_diameter](const ConfigBase &config, const char *opt_key, double layer_height, std::string &err_msg) -> bool { - double extrusion_width_min = config.get_abs_value(opt_key, min_nozzle_diameter); - double extrusion_width_max = config.get_abs_value(opt_key, max_nozzle_diameter); + // This may change in the future, if we switch to "extrusion width wrt. nozzle diameter" + // instead of currently used logic "extrusion width wrt. layer height", see GH issues #1923 #2829. +// double extrusion_width_min = config.get_abs_value(opt_key, min_nozzle_diameter); +// double extrusion_width_max = config.get_abs_value(opt_key, max_nozzle_diameter); + double extrusion_width_min = config.get_abs_value(opt_key, layer_height); + double extrusion_width_max = config.get_abs_value(opt_key, layer_height); if (extrusion_width_min == 0) { // Default "auto-generated" extrusion width is always valid. } else if (extrusion_width_min <= layer_height) { diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index b3084f550..da2b65568 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -3299,15 +3299,20 @@ DynamicPrintConfig* DynamicPrintConfig::new_from_defaults_keys(const std::vector double min_object_distance(const ConfigBase &cfg) { + const ConfigOptionEnum *opt_printer_technology = cfg.option>("printer_technology"); + auto printer_technology = opt_printer_technology ? opt_printer_technology->value : ptUnknown; + double ret = 0.; - - if (printer_technology(cfg) == ptSLA) ret = 6.; + + if (printer_technology == ptSLA) + ret = 6.; else { auto ecr_opt = cfg.option("extruder_clearance_radius"); auto dd_opt = cfg.option("duplicate_distance"); auto co_opt = cfg.option("complete_objects"); - if (!ecr_opt || !dd_opt || !co_opt) ret = 0.; + if (!ecr_opt || !dd_opt || !co_opt) + ret = 0.; else { // min object distance is max(duplicate_distance, clearance_radius) ret = (co_opt->value && ecr_opt->value > dd_opt->value) ? @@ -3318,21 +3323,6 @@ double min_object_distance(const ConfigBase &cfg) return ret; } -PrinterTechnology printer_technology(const ConfigBase &cfg) -{ - const ConfigOptionEnum *opt = cfg.option>("printer_technology"); - - if (opt) return opt->value; - - const ConfigOptionBool *export_opt = cfg.option("export_sla"); - if (export_opt && export_opt->getBool()) return ptSLA; - - export_opt = cfg.option("export_gcode"); - if (export_opt && export_opt->getBool()) return ptFFF; - - return ptUnknown; -} - void DynamicPrintConfig::normalize_fdm() { if (this->has("extruder")) { diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index b5896891e..fa09cfb17 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -246,7 +246,7 @@ extern const PrintConfigDef print_config_def; class StaticPrintConfig; -PrinterTechnology printer_technology(const ConfigBase &cfg); +// Minimum object distance for arrangement, based on printer technology. double min_object_distance(const ConfigBase &cfg); // Slic3r dynamic configuration, used to override the configuration diff --git a/src/platform/osx/Info.plist.in b/src/platform/osx/Info.plist.in index e922b23f5..46858bb29 100644 --- a/src/platform/osx/Info.plist.in +++ b/src/platform/osx/Info.plist.in @@ -23,98 +23,103 @@ CFBundleVersion @SLIC3R_BUILD_ID@ CFBundleDocumentTypes - - - CFBundleTypeExtensions - - stl - STL - - CFBundleTypeIconFile - stl.icns - CFBundleTypeName + + + CFBundleTypeExtensions + + stl STL - CFBundleTypeRole - Viewer - LISsAppleDefaultForType - - LSHandlerRank - Alternate - - - CFBundleTypeExtensions - - obj - OBJ - - CFBundleTypeIconFile - PrusaSlicer.icns - CFBundleTypeName - STL - CFBundleTypeRole - Viewer - LISsAppleDefaultForType - - LSHandlerRank - Alternate - - - CFBundleTypeExtensions - - amf - AMF - - CFBundleTypeIconFile - PrusaSlicer.icns - CFBundleTypeName + + CFBundleTypeIconFile + stl.icns + CFBundleTypeName + STL + CFBundleTypeRole + Viewer + LISsAppleDefaultForType + + LSHandlerRank + Alternate + + + CFBundleTypeExtensions + + obj + OBJ + + CFBundleTypeIconFile + PrusaSlicer.icns + CFBundleTypeName + STL + CFBundleTypeRole + Viewer + LISsAppleDefaultForType + + LSHandlerRank + Alternate + + + CFBundleTypeExtensions + + amf AMF - CFBundleTypeRole - Viewer - LISsAppleDefaultForType - - LSHandlerRank - Alternate - - - CFBundleTypeExtensions - - 3mf - 3MF - - CFBundleTypeIconFile - PrusaSlicer.icns - CFBundleTypeName + + CFBundleTypeIconFile + PrusaSlicer.icns + CFBundleTypeName + AMF + CFBundleTypeRole + Viewer + LISsAppleDefaultForType + + LSHandlerRank + Alternate + + + CFBundleTypeExtensions + + 3mf 3MF - CFBundleTypeRole - Viewer - LISsAppleDefaultForType - - LSHandlerRank - Alternate - - - CFBundleTypeExtensions - - gcode - GCODE - - CFBundleTypeIconFile - gcode.icns - CFBundleTypeName + + CFBundleTypeIconFile + PrusaSlicer.icns + CFBundleTypeName + 3MF + CFBundleTypeRole + Viewer + LISsAppleDefaultForType + + LSHandlerRank + Alternate + + + CFBundleTypeExtensions + + gcode GCODE - CFBundleTypeRole - Viewer - LISsAppleDefaultForType - - LSHandlerRank - Alternate - - - LSMinimumSystemVersion - 10.9 - NSPrincipalClass - NSApplication - NSHighResolutionCapable - + + CFBundleTypeIconFile + gcode.icns + CFBundleTypeName + GCODE + CFBundleTypeRole + Viewer + LISsAppleDefaultForType + + LSHandlerRank + Alternate + + + LSMinimumSystemVersion + 10.10 + NSPrincipalClass + NSApplication + NSHighResolutionCapable + + LSEnvironment + + ASAN_OPTIONS + detect_container_overflow=0 + diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index e040de727..505c8f0f2 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -158,6 +158,8 @@ set(SLIC3R_GUI_SOURCES GUI/PrintHostDialogs.hpp GUI/Jobs/Job.hpp GUI/Jobs/Job.cpp + GUI/Jobs/PlaterJob.hpp + GUI/Jobs/PlaterJob.cpp GUI/Jobs/ArrangeJob.hpp GUI/Jobs/ArrangeJob.cpp GUI/Jobs/RotoptimizeJob.hpp diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 388db4a27..0ff2fef80 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1377,7 +1377,7 @@ void GLCanvas3D::update_instance_printable_state_for_object(const size_t obj_idx } } -void GLCanvas3D::update_instance_printable_state_for_objects(std::vector& object_idxs) +void GLCanvas3D::update_instance_printable_state_for_objects(const std::vector& object_idxs) { for (size_t obj_idx : object_idxs) update_instance_printable_state_for_object(obj_idx); diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index fee136087..8e31addaa 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -565,7 +565,7 @@ public: void toggle_sla_auxiliaries_visibility(bool visible, const ModelObject* mo = nullptr, int instance_idx = -1); void toggle_model_objects_visibility(bool visible, const ModelObject* mo = nullptr, int instance_idx = -1); void update_instance_printable_state_for_object(size_t obj_idx); - void update_instance_printable_state_for_objects(std::vector& object_idxs); + void update_instance_printable_state_for_objects(const std::vector& object_idxs); void set_config(const DynamicPrintConfig* config); void set_process(BackgroundSlicingProcess* process); diff --git a/src/slic3r/GUI/Jobs/ArrangeJob.cpp b/src/slic3r/GUI/Jobs/ArrangeJob.cpp index 0f17e6e9f..276e20c1a 100644 --- a/src/slic3r/GUI/Jobs/ArrangeJob.cpp +++ b/src/slic3r/GUI/Jobs/ArrangeJob.cpp @@ -7,6 +7,8 @@ #include "slic3r/GUI/GLCanvas3D.hpp" #include "slic3r/GUI/GUI.hpp" +#include "libnest2d/common.hpp" + namespace Slic3r { namespace GUI { // Cache the wti info @@ -140,6 +142,19 @@ void ArrangeJob::prepare() wxGetKeyState(WXK_SHIFT) ? prepare_selected() : prepare_all(); } +void ArrangeJob::on_exception(const std::exception_ptr &eptr) +{ + try { + if (eptr) + std::rethrow_exception(eptr); + } catch (libnest2d::GeometryException &) { + show_error(m_plater, _(L("Could not arrange model objects! " + "Some geometries may be invalid."))); + } catch (std::exception &e) { + PlaterJob::on_exception(eptr); + } +} + void ArrangeJob::process() { static const auto arrangestr = _(L("Arranging")); @@ -151,30 +166,23 @@ void ArrangeJob::process() params.allow_rotations = settings.enable_rotation; params.min_obj_distance = scaled(settings.distance); - auto count = unsigned(m_selected.size() + m_unprintable.size()); Points bedpts = get_bed_shape(*m_plater->config()); params.stopcondition = [this]() { return was_canceled(); }; - try { - params.progressind = [this, count](unsigned st) { - st += m_unprintable.size(); - if (st > 0) update_status(int(count - st), arrangestr); - }; - - arrangement::arrange(m_selected, m_unselected, bedpts, params); - - params.progressind = [this, count](unsigned st) { - if (st > 0) update_status(int(count - st), arrangestr); - }; - - arrangement::arrange(m_unprintable, {}, bedpts, params); - } catch (std::exception & /*e*/) { - GUI::show_error(m_plater, - _(L("Could not arrange model objects! " - "Some geometries may be invalid."))); - } + params.progressind = [this, count](unsigned st) { + st += m_unprintable.size(); + if (st > 0) update_status(int(count - st), arrangestr); + }; + + arrangement::arrange(m_selected, m_unselected, bedpts, params); + + params.progressind = [this, count](unsigned st) { + if (st > 0) update_status(int(count - st), arrangestr); + }; + + arrangement::arrange(m_unprintable, {}, bedpts, params); // finalize just here. update_status(int(count), diff --git a/src/slic3r/GUI/Jobs/ArrangeJob.hpp b/src/slic3r/GUI/Jobs/ArrangeJob.hpp index 73540c230..38aafb52c 100644 --- a/src/slic3r/GUI/Jobs/ArrangeJob.hpp +++ b/src/slic3r/GUI/Jobs/ArrangeJob.hpp @@ -1,17 +1,13 @@ #ifndef ARRANGEJOB_HPP #define ARRANGEJOB_HPP -#include "Job.hpp" +#include "PlaterJob.hpp" #include "libslic3r/Arrange.hpp" namespace Slic3r { namespace GUI { -class Plater; - -class ArrangeJob : public Job +class ArrangeJob : public PlaterJob { - Plater *m_plater; - using ArrangePolygon = arrangement::ArrangePolygon; using ArrangePolygons = arrangement::ArrangePolygons; @@ -30,10 +26,12 @@ class ArrangeJob : public Job protected: void prepare() override; + + void on_exception(const std::exception_ptr &) override; public: ArrangeJob(std::shared_ptr pri, Plater *plater) - : Job{std::move(pri)}, m_plater{plater} + : PlaterJob{std::move(pri), plater} {} int status_range() const override diff --git a/src/slic3r/GUI/Jobs/FillBedJob.hpp b/src/slic3r/GUI/Jobs/FillBedJob.hpp index 448ae53d4..07290d2f2 100644 --- a/src/slic3r/GUI/Jobs/FillBedJob.hpp +++ b/src/slic3r/GUI/Jobs/FillBedJob.hpp @@ -7,9 +7,8 @@ namespace Slic3r { namespace GUI { class Plater; -class FillBedJob : public Job +class FillBedJob : public PlaterJob { - Plater *m_plater; int m_object_idx = -1; using ArrangePolygon = arrangement::ArrangePolygon; @@ -28,7 +27,7 @@ protected: public: FillBedJob(std::shared_ptr pri, Plater *plater) - : Job{std::move(pri)}, m_plater{plater} + : PlaterJob{std::move(pri), plater} {} int status_range() const override diff --git a/src/slic3r/GUI/Jobs/Job.cpp b/src/slic3r/GUI/Jobs/Job.cpp index fedb6f4ac..1f7f58875 100644 --- a/src/slic3r/GUI/Jobs/Job.cpp +++ b/src/slic3r/GUI/Jobs/Job.cpp @@ -1,4 +1,5 @@ #include +#include #include "Job.hpp" #include @@ -6,10 +7,15 @@ namespace Slic3r { -void GUI::Job::run() +void GUI::Job::run(std::exception_ptr &eptr) { m_running.store(true); - process(); + try { + process(); + } catch (...) { + eptr = std::current_exception(); + } + m_running.store(false); // ensure to call the last status to finalize the job @@ -27,22 +33,29 @@ void GUI::Job::update_status(int st, const wxString &msg) GUI::Job::Job(std::shared_ptr pri) : m_progress(std::move(pri)) { - Bind(wxEVT_THREAD, [this](const wxThreadEvent &evt) { + Bind(wxEVT_THREAD, [this](const wxThreadEvent &evt) { auto msg = evt.GetString(); - if (!msg.empty()) + if (!msg.empty() && !m_worker_error) m_progress->set_status_text(msg.ToUTF8().data()); - + if (m_finalized) return; - + m_progress->set_progress(evt.GetInt()); - if (evt.GetInt() == status_range()) { + if (evt.GetInt() == status_range() || m_worker_error) { // set back the original range and cancel callback m_progress->set_range(m_range); m_progress->set_cancel_callback(); wxEndBusyCursor(); - finalize(); - + if (m_worker_error) { + m_finalized = true; + m_progress->set_status_text(""); + m_progress->set_progress(m_range); + on_exception(m_worker_error); + } + else + finalize(); + // dont do finalization again for the same process m_finalized = true; } @@ -69,7 +82,8 @@ void GUI::Job::start() wxBeginBusyCursor(); try { // Execute the job - m_thread = create_thread([this] { this->run(); }); + m_worker_error = nullptr; + m_thread = create_thread([this] { this->run(m_worker_error); }); } catch (std::exception &) { update_status(status_range(), _(L("ERROR: not enough resources to " diff --git a/src/slic3r/GUI/Jobs/Job.hpp b/src/slic3r/GUI/Jobs/Job.hpp index aea7692e7..cb73fe74d 100644 --- a/src/slic3r/GUI/Jobs/Job.hpp +++ b/src/slic3r/GUI/Jobs/Job.hpp @@ -2,6 +2,7 @@ #define JOB_HPP #include +#include #include "libslic3r/libslic3r.h" @@ -32,8 +33,9 @@ class Job : public wxEvtHandler std::atomic m_running{false}, m_canceled{false}; bool m_finalized = false; std::shared_ptr m_progress; + std::exception_ptr m_worker_error = nullptr; - void run(); + void run(std::exception_ptr &); protected: // status range for a particular job @@ -49,6 +51,8 @@ protected: // Launched when the job is finished. It refreshes the 3Dscene by def. virtual void finalize() { m_finalized = true; } + + virtual void on_exception(const std::exception_ptr &) {} public: Job(std::shared_ptr pri); diff --git a/src/slic3r/GUI/Jobs/PlaterJob.cpp b/src/slic3r/GUI/Jobs/PlaterJob.cpp new file mode 100644 index 000000000..cbf764068 --- /dev/null +++ b/src/slic3r/GUI/Jobs/PlaterJob.cpp @@ -0,0 +1,17 @@ +#include "PlaterJob.hpp" +#include "slic3r/GUI/GUI.hpp" +#include "slic3r/GUI/Plater.hpp" + +namespace Slic3r { namespace GUI { + +void PlaterJob::on_exception(const std::exception_ptr &eptr) +{ + try { + if (eptr) + std::rethrow_exception(eptr); + } catch (std::exception &e) { + show_error(m_plater, _(L("An unexpected error occured: ")) + e.what()); + } +} + +}} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/Jobs/PlaterJob.hpp b/src/slic3r/GUI/Jobs/PlaterJob.hpp new file mode 100644 index 000000000..fcf0a54b8 --- /dev/null +++ b/src/slic3r/GUI/Jobs/PlaterJob.hpp @@ -0,0 +1,24 @@ +#ifndef PLATERJOB_HPP +#define PLATERJOB_HPP + +#include "Job.hpp" + +namespace Slic3r { namespace GUI { + +class Plater; + +class PlaterJob : public Job { +protected: + Plater *m_plater; + + void on_exception(const std::exception_ptr &) override; + +public: + + PlaterJob(std::shared_ptr pri, Plater *plater): + Job{std::move(pri)}, m_plater{plater} {} +}; + +}} // namespace Slic3r::GUI + +#endif // PLATERJOB_HPP diff --git a/src/slic3r/GUI/Jobs/RotoptimizeJob.hpp b/src/slic3r/GUI/Jobs/RotoptimizeJob.hpp index 983c43c68..06688b52d 100644 --- a/src/slic3r/GUI/Jobs/RotoptimizeJob.hpp +++ b/src/slic3r/GUI/Jobs/RotoptimizeJob.hpp @@ -1,18 +1,15 @@ #ifndef ROTOPTIMIZEJOB_HPP #define ROTOPTIMIZEJOB_HPP -#include "Job.hpp" +#include "PlaterJob.hpp" namespace Slic3r { namespace GUI { -class Plater; - -class RotoptimizeJob : public Job +class RotoptimizeJob : public PlaterJob { - Plater *m_plater; public: RotoptimizeJob(std::shared_ptr pri, Plater *plater) - : Job{std::move(pri)}, m_plater{plater} + : PlaterJob{std::move(pri), plater} {} void process() override; diff --git a/src/slic3r/GUI/Jobs/SLAImportJob.cpp b/src/slic3r/GUI/Jobs/SLAImportJob.cpp index ec289ae34..f9fbef8a8 100644 --- a/src/slic3r/GUI/Jobs/SLAImportJob.cpp +++ b/src/slic3r/GUI/Jobs/SLAImportJob.cpp @@ -124,7 +124,7 @@ public: }; SLAImportJob::SLAImportJob(std::shared_ptr pri, Plater *plater) - : Job{std::move(pri)}, p{std::make_unique(plater)} + : PlaterJob{std::move(pri), plater}, p{std::make_unique(plater)} {} SLAImportJob::~SLAImportJob() = default; diff --git a/src/slic3r/GUI/Jobs/SLAImportJob.hpp b/src/slic3r/GUI/Jobs/SLAImportJob.hpp index cff6cc899..543f42006 100644 --- a/src/slic3r/GUI/Jobs/SLAImportJob.hpp +++ b/src/slic3r/GUI/Jobs/SLAImportJob.hpp @@ -1,13 +1,11 @@ #ifndef SLAIMPORTJOB_HPP #define SLAIMPORTJOB_HPP -#include "Job.hpp" +#include "PlaterJob.hpp" namespace Slic3r { namespace GUI { -class Plater; - -class SLAImportJob : public Job { +class SLAImportJob : public PlaterJob { class priv; std::unique_ptr p; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 4d6b1178f..41e9c8ff5 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -6111,8 +6111,10 @@ void Plater::changed_objects(const std::vector& object_idxs) // pulls the correct data, update the 3D scene. this->p->update_restart_background_process(true, false); } - else + else { p->view3D->reload_scene(false); + p->view3D->get_canvas3d()->update_instance_printable_state_for_objects(object_idxs); + } // update print this->p->schedule_background_process();