From 773116b777fa771420c884f7ec38b03c7587c340 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Fri, 26 Mar 2021 18:22:53 +0100 Subject: [PATCH] Allow auto-rotation of objects not completely inside bed. Don't use SLAPrintObject as the input for optimization. Use ModelObject and pass the print config to the optimization in RotoptimizeJob::prepare() --- src/libslic3r/SLA/Rotfinder.cpp | 37 ++++++++++++++--------- src/libslic3r/SLA/Rotfinder.hpp | 42 ++++++++++++++++++++------ src/slic3r/GUI/Jobs/RotoptimizeJob.cpp | 24 ++++++++++----- src/slic3r/GUI/Jobs/RotoptimizeJob.hpp | 11 ++++--- 4 files changed, 77 insertions(+), 37 deletions(-) diff --git a/src/libslic3r/SLA/Rotfinder.cpp b/src/libslic3r/SLA/Rotfinder.cpp index 89de1cf83..6e8a0ce6b 100644 --- a/src/libslic3r/SLA/Rotfinder.cpp +++ b/src/libslic3r/SLA/Rotfinder.cpp @@ -6,6 +6,7 @@ #include #include +#include #include "libslic3r/SLAPrint.hpp" #include "libslic3r/PrintConfig.hpp" @@ -192,10 +193,10 @@ XYRotation from_transform3f(const Transform3f &tr) return {rot3.x(), rot3.y()}; } -inline bool is_on_floor(const SLAPrintObject &mo) +inline bool is_on_floor(const SLAPrintObjectConfig &cfg) { - auto opt_elevation = mo.config().support_object_elevation.getFloat(); - auto opt_padaround = mo.config().pad_around_object.getBool(); + auto opt_elevation = cfg.support_object_elevation.getFloat(); + auto opt_padaround = cfg.pad_around_object.getBool(); return opt_elevation < EPSILON || opt_padaround; } @@ -282,9 +283,8 @@ std::array find_min_score(Fn &&fn, It from, It to, StopCond &&stopfn) } // namespace -Vec2d find_best_misalignment_rotation(const SLAPrintObject & po, - float accuracy, - RotOptimizeStatusCB statuscb) +Vec2d find_best_misalignment_rotation(const ModelObject & mo, + const RotOptimizeParams ¶ms) { static constexpr unsigned MAX_TRIES = 1000; @@ -293,14 +293,16 @@ Vec2d find_best_misalignment_rotation(const SLAPrintObject & po, // We will use only one instance of this converted mesh to examine different // rotations - TriangleMesh mesh = po.model_object()->raw_mesh(); + TriangleMesh mesh = mo.raw_mesh(); mesh.require_shared_vertices(); // To keep track of the number of iterations int status = 0; // The maximum number of iterations - auto max_tries = unsigned(accuracy * MAX_TRIES); + auto max_tries = unsigned(params.accuracy() * MAX_TRIES); + + auto &statuscb = params.statuscb(); // call status callback with zero, because we are at the start statuscb(status); @@ -338,9 +340,8 @@ Vec2d find_best_misalignment_rotation(const SLAPrintObject & po, return {rot[0], rot[1]}; } -Vec2d find_least_supports_rotation(const SLAPrintObject & po, - float accuracy, - RotOptimizeStatusCB statuscb) +Vec2d find_least_supports_rotation(const ModelObject & mo, + const RotOptimizeParams ¶ms) { static const unsigned MAX_TRIES = 1000; @@ -349,14 +350,16 @@ Vec2d find_least_supports_rotation(const SLAPrintObject & po, // We will use only one instance of this converted mesh to examine different // rotations - TriangleMesh mesh = po.model_object()->raw_mesh(); + TriangleMesh mesh = mo.raw_mesh(); mesh.require_shared_vertices(); // To keep track of the number of iterations unsigned status = 0; // The maximum number of iterations - auto max_tries = unsigned(accuracy * MAX_TRIES); + auto max_tries = unsigned(params.accuracy() * MAX_TRIES); + + auto &statuscb = params.statuscb(); // call status callback with zero, because we are at the start statuscb(status); @@ -370,8 +373,14 @@ Vec2d find_least_supports_rotation(const SLAPrintObject & po, return ! statuscb(-1); }; + SLAPrintObjectConfig pocfg; + if (params.print_config()) + pocfg.apply(*params.print_config(), true); + + pocfg.apply(mo.config.get()); + // Different search methods have to be used depending on the model elevation - if (is_on_floor(po)) { + if (is_on_floor(pocfg)) { std::vector inputs = get_chull_rotations(mesh, max_tries); max_tries = inputs.size(); diff --git a/src/libslic3r/SLA/Rotfinder.hpp b/src/libslic3r/SLA/Rotfinder.hpp index c0007944a..77a39016d 100644 --- a/src/libslic3r/SLA/Rotfinder.hpp +++ b/src/libslic3r/SLA/Rotfinder.hpp @@ -8,13 +8,39 @@ namespace Slic3r { +class ModelObject; class SLAPrintObject; class TriangleMesh; +class DynamicPrintConfig; namespace sla { using RotOptimizeStatusCB = std::function; +class RotOptimizeParams { + float m_accuracy = 1.; + const DynamicPrintConfig *m_print_config = nullptr; + RotOptimizeStatusCB m_statuscb = [](int) { return true; }; + +public: + + RotOptimizeParams &accuracy(float a) { m_accuracy = a; return *this; } + RotOptimizeParams &print_config(const DynamicPrintConfig *c) + { + m_print_config = c; + return *this; + } + RotOptimizeParams &statucb(RotOptimizeStatusCB cb) + { + m_statuscb = std::move(cb); + return *this; + } + + float accuracy() const { return m_accuracy; } + const DynamicPrintConfig * print_config() const { return m_print_config; } + const RotOptimizeStatusCB &statuscb() const { return m_statuscb; } +}; + /** * The function should find the best rotation for SLA upside down printing. * @@ -31,17 +57,13 @@ using RotOptimizeStatusCB = std::function; * * @return Returns the rotations around each axis (x, y, z) */ -Vec2d find_best_misalignment_rotation( - const SLAPrintObject& modelobj, - float accuracy = 1.0f, - RotOptimizeStatusCB statuscb = [] (int) { return true; } - ); +Vec2d find_best_misalignment_rotation(const ModelObject &modelobj, + const RotOptimizeParams & = {}); -Vec2d find_least_supports_rotation( - const SLAPrintObject& modelobj, - float accuracy = 1.0f, - RotOptimizeStatusCB statuscb = [] (int) { return true; } - ); +Vec2d find_least_supports_rotation(const ModelObject &modelobj, + const RotOptimizeParams & = {}); + +double find_Z_fit_to_bed_rotation(const ModelObject &mo, const BoundingBox &bed); } // namespace sla } // namespace Slic3r diff --git a/src/slic3r/GUI/Jobs/RotoptimizeJob.cpp b/src/slic3r/GUI/Jobs/RotoptimizeJob.cpp index 05b141131..04144112e 100644 --- a/src/slic3r/GUI/Jobs/RotoptimizeJob.cpp +++ b/src/slic3r/GUI/Jobs/RotoptimizeJob.cpp @@ -7,6 +7,7 @@ #include "libslic3r/SLAPrint.hpp" #include "slic3r/GUI/Plater.hpp" +#include "libslic3r/PresetBundle.hpp" #include "slic3r/GUI/GUI_App.hpp" #include "libslic3r/AppConfig.hpp" @@ -29,25 +30,32 @@ void RotoptimizeJob::prepare() m_accuracy = std::max(0.f, std::min(m_accuracy, 1.f)); m_method_id = std::max(size_t(0), std::min(get_methods_count() - 1, m_method_id)); + + m_default_print_cfg = wxGetApp().preset_bundle->full_config(); } void RotoptimizeJob::process() { int obj_idx = m_plater->get_selected_object_idx(); - if (obj_idx < 0 || int(m_plater->sla_print().objects().size()) <= obj_idx) + if (obj_idx < 0) return; ModelObject *o = m_plater->model().objects[size_t(obj_idx)]; - const SLAPrintObject *po = m_plater->sla_print().objects()[size_t(obj_idx)]; - if (!o || !po) return; + if (!o) return; - Vec2d r = Methods[m_method_id].findfn(*po, m_accuracy, [this](int s) { - if (s > 0 && s < 100) - update_status(s, _(L("Searching for optimal orientation"))); + auto params = + sla::RotOptimizeParams{} + .accuracy(m_accuracy) + .print_config(&m_default_print_cfg) + .statucb([this](int s) { + if (s > 0 && s < 100) + update_status(s, _(L("Searching for optimal orientation"))); - return !was_canceled(); - }); + return !was_canceled(); + }); + + Vec2d r = Methods[m_method_id].findfn(*o, params); double mindist = 6.0; // FIXME diff --git a/src/slic3r/GUI/Jobs/RotoptimizeJob.hpp b/src/slic3r/GUI/Jobs/RotoptimizeJob.hpp index dfec2d6a6..cb9a96b56 100644 --- a/src/slic3r/GUI/Jobs/RotoptimizeJob.hpp +++ b/src/slic3r/GUI/Jobs/RotoptimizeJob.hpp @@ -4,18 +4,16 @@ #include "PlaterJob.hpp" #include "libslic3r/SLA/Rotfinder.hpp" +#include "libslic3r/PrintConfig.hpp" namespace Slic3r { -class SLAPrintObject; - namespace GUI { class RotoptimizeJob : public PlaterJob { - using FindFn = std::function; + using FindFn = std::function; struct FindMethod { std::string name; FindFn findfn; }; @@ -26,6 +24,9 @@ class RotoptimizeJob : public PlaterJob size_t m_method_id = 0; float m_accuracy = 0.75; + + DynamicPrintConfig m_default_print_cfg; + protected: void prepare() override;