diff options
Diffstat (limited to 'xs/src/slic3r/AppController.cpp')
-rw-r--r-- | xs/src/slic3r/AppController.cpp | 382 |
1 files changed, 24 insertions, 358 deletions
diff --git a/xs/src/slic3r/AppController.cpp b/xs/src/slic3r/AppController.cpp index 5e259c367..4a36b5d7f 100644 --- a/xs/src/slic3r/AppController.cpp +++ b/xs/src/slic3r/AppController.cpp @@ -11,12 +11,11 @@ #include <ModelArrange.hpp> #include <slic3r/GUI/PresetBundle.hpp> -#include <Print.hpp> -#include <PrintExport.hpp> #include <Geometry.hpp> +#include <PrintConfig.hpp> +#include <Print.hpp> #include <Model.hpp> #include <Utils.hpp> -#include <SLABasePool.hpp> namespace Slic3r { @@ -44,15 +43,6 @@ namespace GUI { PresetBundle* get_preset_bundle(); } -static const PrintObjectStep STEP_SLICE = posSlice; -static const PrintObjectStep STEP_PERIMETERS = posPerimeters; -static const PrintObjectStep STEP_PREPARE_INFILL = posPrepareInfill; -static const PrintObjectStep STEP_INFILL = posInfill; -static const PrintObjectStep STEP_SUPPORTMATERIAL = posSupportMaterial; -static const PrintStep STEP_SKIRT = psSkirt; -static const PrintStep STEP_BRIM = psBrim; -static const PrintStep STEP_WIPE_TOWER = psWipeTower; - AppControllerBoilerplate::ProgresIndicatorPtr AppControllerBoilerplate::global_progress_indicator() { ProgresIndicatorPtr ret; @@ -72,343 +62,8 @@ void AppControllerBoilerplate::global_progress_indicator( pri_data_->m.unlock(); } -#if 0 -void PrintController::make_skirt() -{ - assert(print_ != nullptr); - - // prerequisites - for(auto obj : print_->objects()) make_perimeters(obj); - for(auto obj : print_->objects()) infill(obj); - for(auto obj : print_->objects()) gen_support_material(obj); - - if(!print_->state.is_done(STEP_SKIRT)) { - print_->state.set_started(STEP_SKIRT); - print_->skirt.clear(); - if(print_->has_skirt()) print_->_make_skirt(); - - print_->state.set_done(STEP_SKIRT); - } -} - -void PrintController::make_brim() -{ - assert(print_ != nullptr); - - // prerequisites - for(auto obj : print_->objects()) make_perimeters(obj); - for(auto obj : print_->objects()) infill(obj); - for(auto obj : print_->objects()) gen_support_material(obj); - make_skirt(); - - if(!print_->state.is_done(STEP_BRIM)) { - print_->state.set_started(STEP_BRIM); - - // since this method must be idempotent, we clear brim paths *before* - // checking whether we need to generate them - print_->brim.clear(); - - if(print_->config.brim_width > 0) print_->_make_brim(); - - print_->state.set_done(STEP_BRIM); - } -} - -void PrintController::make_wipe_tower() -{ - assert(print_ != nullptr); - - // prerequisites - for(auto obj : print_->objects()) make_perimeters(obj); - for(auto obj : print_->objects()) infill(obj); - for(auto obj : print_->objects()) gen_support_material(obj); - make_skirt(); - make_brim(); - - if(!print_->state.is_done(STEP_WIPE_TOWER)) { - print_->state.set_started(STEP_WIPE_TOWER); - - // since this method must be idempotent, we clear brim paths *before* - // checking whether we need to generate them - print_->brim.clear(); - - if(print_->has_wipe_tower()) print_->_make_wipe_tower(); - - print_->state.set_done(STEP_WIPE_TOWER); - } -} - -void PrintController::slice(PrintObject *pobj) -{ - assert(pobj != nullptr && print_ != nullptr); - - if(pobj->state.is_done(STEP_SLICE)) return; - - pobj->state.set_started(STEP_SLICE); - - pobj->_slice(); - - auto msg = pobj->_fix_slicing_errors(); - if(!msg.empty()) report_issue(IssueType::WARN, msg); - - // simplify slices if required - if (print_->config.resolution) - pobj->_simplify_slices(scale_(print_->config.resolution)); - - - if(pobj->layers.empty()) - report_issue(IssueType::ERR, - _(L("No layers were detected. You might want to repair your " - "STL file(s) or check their size or thickness and retry")) - ); - - pobj->state.set_done(STEP_SLICE); -} - -void PrintController::make_perimeters(PrintObject *pobj) -{ - assert(pobj != nullptr); - - slice(pobj); - - if (!pobj->state.is_done(STEP_PERIMETERS)) { - pobj->_make_perimeters(); - } -} - -void PrintController::infill(PrintObject *pobj) -{ - assert(pobj != nullptr); - - make_perimeters(pobj); - - if (!pobj->state.is_done(STEP_PREPARE_INFILL)) { - pobj->state.set_started(STEP_PREPARE_INFILL); - - pobj->_prepare_infill(); - - pobj->state.set_done(STEP_PREPARE_INFILL); - } - - pobj->_infill(); -} - -void PrintController::gen_support_material(PrintObject *pobj) -{ - assert(pobj != nullptr); - - // prerequisites - slice(pobj); - - if(!pobj->state.is_done(STEP_SUPPORTMATERIAL)) { - pobj->state.set_started(STEP_SUPPORTMATERIAL); - - pobj->clear_support_layers(); - - if((pobj->config.support_material || pobj->config.raft_layers > 0) - && pobj->layers.size() > 1) { - pobj->_generate_support_material(); - } - - pobj->state.set_done(STEP_SUPPORTMATERIAL); - } -} - -PrintController::PngExportData -PrintController::query_png_export_data(const DynamicPrintConfig& conf) -{ - PngExportData ret; - - auto zippath = query_destination_path("Output zip file", "*.zip", "out"); - - ret.zippath = zippath; - - ret.width_mm = conf.opt_float("display_width"); - ret.height_mm = conf.opt_float("display_height"); - - ret.width_px = conf.opt_int("display_pixels_x"); - ret.height_px = conf.opt_int("display_pixels_y"); - - auto opt_corr = conf.opt<ConfigOptionFloats>("printer_correction"); - - if(opt_corr) { - ret.corr_x = opt_corr->values[0]; - ret.corr_y = opt_corr->values[1]; - ret.corr_z = opt_corr->values[2]; - } - - ret.exp_time_first_s = conf.opt_float("initial_exposure_time"); - ret.exp_time_s = conf.opt_float("exposure_time"); - - return ret; -} - -void PrintController::slice(AppControllerBoilerplate::ProgresIndicatorPtr pri) -{ - auto st = pri->state(); - - Slic3r::trace(3, "Starting the slicing process."); - - pri->update(st+20, _(L("Generating perimeters"))); - for(auto obj : print_->objects()) make_perimeters(obj); - - pri->update(st+60, _(L("Infilling layers"))); - for(auto obj : print_->objects()) infill(obj); - - pri->update(st+70, _(L("Generating support material"))); - for(auto obj : print_->objects()) gen_support_material(obj); - - pri->message_fmt(_(L("Weight: %.1fg, Cost: %.1f")), - print_->total_weight, print_->total_cost); - pri->state(st+85); - - - pri->update(st+88, _(L("Generating skirt"))); - make_skirt(); - - - pri->update(st+90, _(L("Generating brim"))); - make_brim(); - - pri->update(st+95, _(L("Generating wipe tower"))); - make_wipe_tower(); - - pri->update(st+100, _(L("Done"))); - - // time to make some statistics.. - - Slic3r::trace(3, _(L("Slicing process finished."))); -} - -void PrintController::slice() -{ - auto pri = global_progress_indicator(); - if(!pri) pri = create_progress_indicator(100, L("Slicing")); - slice(pri); -} - -void PrintController::slice_to_png() -{ - using Pointf3 = Vec3d; - - auto presetbundle = GUI::get_preset_bundle(); - - assert(presetbundle); - - auto pt = presetbundle->printers.get_selected_preset().printer_technology(); - if(pt != ptSLA) { - report_issue(IssueType::ERR, _("Printer technology is not SLA!"), - _("Error")); - return; - } - - auto conf = presetbundle->full_config(); - conf.validate(); - - auto exd = query_png_export_data(conf); - if(exd.zippath.empty()) return; - - try { - print_->apply_config(conf); - print_->validate(); - } catch(std::exception& e) { - report_issue(IssueType::ERR, e.what(), "Error"); - return; - } - - // TODO: copy the model and work with the copy only - bool correction = false; - if(exd.corr_x != 1.0 || exd.corr_y != 1.0 || exd.corr_z != 1.0) { - correction = true; - print_->invalidate_all_steps(); - - for(auto po : print_->objects()) { - po->model_object()->scale( - Pointf3(exd.corr_x, exd.corr_y, exd.corr_z) - ); - po->model_object()->invalidate_bounding_box(); - po->reload_model_instances(); - po->invalidate_all_steps(); - } - } - - // Turn back the correction scaling on the model. - auto scale_back = [this, correction, exd]() { - if(correction) { // scale the model back - print_->invalidate_all_steps(); - for(auto po : print_->objects()) { - po->model_object()->scale( - Pointf3(1.0/exd.corr_x, 1.0/exd.corr_y, 1.0/exd.corr_z) - ); - po->model_object()->invalidate_bounding_box(); - po->reload_model_instances(); - po->invalidate_all_steps(); - } - } - }; - - auto print_bb = print_->bounding_box(); - Vec2d punsc = unscale(print_bb.size()); - - // If the print does not fit into the print area we should cry about it. - if(px(punsc) > exd.width_mm || py(punsc) > exd.height_mm) { - std::stringstream ss; - - ss << _(L("Print will not fit and will be truncated!")) << "\n" - << _(L("Width needed: ")) << px(punsc) << " mm\n" - << _(L("Height needed: ")) << py(punsc) << " mm\n"; - - if(!report_issue(IssueType::WARN_Q, ss.str(), _(L("Warning")))) { - scale_back(); - return; - } - } - -// std::async(supports_asynch()? std::launch::async : std::launch::deferred, -// [this, exd, scale_back]() -// { - - auto pri = create_progress_indicator( - 200, _(L("Slicing to zipped png files..."))); - - try { - pri->update(0, _(L("Slicing..."))); - slice(pri); - } catch (std::exception& e) { - pri->cancel(); - report_issue(IssueType::ERR, e.what(), _(L("Exception occured"))); - scale_back(); - return; - } - - auto pbak = print_->progressindicator; - print_->progressindicator = pri; - - try { - print_to<FilePrinterFormat::PNG>( *print_, exd.zippath, - exd.width_mm, exd.height_mm, - exd.width_px, exd.height_px, - exd.exp_time_s, exd.exp_time_first_s); - - } catch (std::exception& e) { - pri->cancel(); - report_issue(IssueType::ERR, e.what(), _(L("Exception occured"))); - } - - print_->progressindicator = pbak; - scale_back(); - -// }); -} - -const PrintConfig &PrintController::config() const -{ - return print_->config; -} -#endif - void ProgressIndicator::message_fmt( - const wxString &fmtstr, ...) { + const std::string &fmtstr, ...) { std::stringstream ss; va_list args; va_start(args, fmtstr); @@ -438,6 +93,11 @@ void AppController::arrange_model() { using Coord = libnest2d::TCoord<libnest2d::PointImpl>; + if(arranging_.load()) return; + + // to prevent UI reentrancies + arranging_.store(true); + unsigned count = 0; for(auto obj : model_->objects) count += obj->instances.size(); @@ -451,8 +111,8 @@ void AppController::arrange_model() // Set the range of the progress to the object count pind->max(count); - pind->on_cancel([](){ - std::cout << "Cannot be cancelled!" << std::endl; + pind->on_cancel([this](){ + arranging_.store(false); }); } @@ -466,7 +126,7 @@ void AppController::arrange_model() for(auto& v : bedpoints) bed.append(Point::new_scale(v(0), v(1))); - if(pind) pind->update(0, _(L("Arranging objects..."))); + if(pind) pind->update(0, L("Arranging objects...")); try { arr::BedShapeHint hint; @@ -478,24 +138,30 @@ void AppController::arrange_model() bed, hint, false, // create many piles not just one pile - [pind, count](unsigned rem) { + [this, pind, count](unsigned rem) { if(pind) - pind->update(count - rem, _(L("Arranging objects..."))); - }); + pind->update(count - rem, L("Arranging objects...")); + + process_events(); + }, [this] () { return !arranging_.load(); }); } catch(std::exception& e) { std::cerr << e.what() << std::endl; report_issue(IssueType::ERR, - _(L("Could not arrange model objects! " - "Some geometries may be invalid.")), - _(L("Exception occurred"))); + L("Could not arrange model objects! " + "Some geometries may be invalid."), + L("Exception occurred")); } // Restore previous max value if(pind) { pind->max(pmax); - pind->update(0, _(L("Arranging done."))); + pind->update(0, arranging_.load() ? L("Arranging done.") : + L("Arranging canceled.")); + pind->on_cancel(/*remove cancel function*/); } + + arranging_.store(false); } } |