mirror of
https://git.mirrors.martin98.com/https://github.com/SoftFever/OrcaSlicer.git
synced 2025-08-16 20:25:54 +08:00
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()
This commit is contained in:
parent
5443f77489
commit
773116b777
@ -6,6 +6,7 @@
|
|||||||
#include <libslic3r/Execution/ExecutionSeq.hpp>
|
#include <libslic3r/Execution/ExecutionSeq.hpp>
|
||||||
|
|
||||||
#include <libslic3r/Optimize/BruteforceOptimizer.hpp>
|
#include <libslic3r/Optimize/BruteforceOptimizer.hpp>
|
||||||
|
#include <libslic3r/Optimize/NLoptOptimizer.hpp>
|
||||||
|
|
||||||
#include "libslic3r/SLAPrint.hpp"
|
#include "libslic3r/SLAPrint.hpp"
|
||||||
#include "libslic3r/PrintConfig.hpp"
|
#include "libslic3r/PrintConfig.hpp"
|
||||||
@ -192,10 +193,10 @@ XYRotation from_transform3f(const Transform3f &tr)
|
|||||||
return {rot3.x(), rot3.y()};
|
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_elevation = cfg.support_object_elevation.getFloat();
|
||||||
auto opt_padaround = mo.config().pad_around_object.getBool();
|
auto opt_padaround = cfg.pad_around_object.getBool();
|
||||||
|
|
||||||
return opt_elevation < EPSILON || opt_padaround;
|
return opt_elevation < EPSILON || opt_padaround;
|
||||||
}
|
}
|
||||||
@ -282,9 +283,8 @@ std::array<double, N> find_min_score(Fn &&fn, It from, It to, StopCond &&stopfn)
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
Vec2d find_best_misalignment_rotation(const SLAPrintObject & po,
|
Vec2d find_best_misalignment_rotation(const ModelObject & mo,
|
||||||
float accuracy,
|
const RotOptimizeParams ¶ms)
|
||||||
RotOptimizeStatusCB statuscb)
|
|
||||||
{
|
{
|
||||||
static constexpr unsigned MAX_TRIES = 1000;
|
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
|
// We will use only one instance of this converted mesh to examine different
|
||||||
// rotations
|
// rotations
|
||||||
TriangleMesh mesh = po.model_object()->raw_mesh();
|
TriangleMesh mesh = mo.raw_mesh();
|
||||||
mesh.require_shared_vertices();
|
mesh.require_shared_vertices();
|
||||||
|
|
||||||
// To keep track of the number of iterations
|
// To keep track of the number of iterations
|
||||||
int status = 0;
|
int status = 0;
|
||||||
|
|
||||||
// The maximum number of iterations
|
// 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
|
// call status callback with zero, because we are at the start
|
||||||
statuscb(status);
|
statuscb(status);
|
||||||
@ -338,9 +340,8 @@ Vec2d find_best_misalignment_rotation(const SLAPrintObject & po,
|
|||||||
return {rot[0], rot[1]};
|
return {rot[0], rot[1]};
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec2d find_least_supports_rotation(const SLAPrintObject & po,
|
Vec2d find_least_supports_rotation(const ModelObject & mo,
|
||||||
float accuracy,
|
const RotOptimizeParams ¶ms)
|
||||||
RotOptimizeStatusCB statuscb)
|
|
||||||
{
|
{
|
||||||
static const unsigned MAX_TRIES = 1000;
|
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
|
// We will use only one instance of this converted mesh to examine different
|
||||||
// rotations
|
// rotations
|
||||||
TriangleMesh mesh = po.model_object()->raw_mesh();
|
TriangleMesh mesh = mo.raw_mesh();
|
||||||
mesh.require_shared_vertices();
|
mesh.require_shared_vertices();
|
||||||
|
|
||||||
// To keep track of the number of iterations
|
// To keep track of the number of iterations
|
||||||
unsigned status = 0;
|
unsigned status = 0;
|
||||||
|
|
||||||
// The maximum number of iterations
|
// 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
|
// call status callback with zero, because we are at the start
|
||||||
statuscb(status);
|
statuscb(status);
|
||||||
@ -370,8 +373,14 @@ Vec2d find_least_supports_rotation(const SLAPrintObject & po,
|
|||||||
return ! statuscb(-1);
|
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
|
// Different search methods have to be used depending on the model elevation
|
||||||
if (is_on_floor(po)) {
|
if (is_on_floor(pocfg)) {
|
||||||
|
|
||||||
std::vector<XYRotation> inputs = get_chull_rotations(mesh, max_tries);
|
std::vector<XYRotation> inputs = get_chull_rotations(mesh, max_tries);
|
||||||
max_tries = inputs.size();
|
max_tries = inputs.size();
|
||||||
|
@ -8,13 +8,39 @@
|
|||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
|
class ModelObject;
|
||||||
class SLAPrintObject;
|
class SLAPrintObject;
|
||||||
class TriangleMesh;
|
class TriangleMesh;
|
||||||
|
class DynamicPrintConfig;
|
||||||
|
|
||||||
namespace sla {
|
namespace sla {
|
||||||
|
|
||||||
using RotOptimizeStatusCB = std::function<bool(int)>;
|
using RotOptimizeStatusCB = std::function<bool(int)>;
|
||||||
|
|
||||||
|
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.
|
* The function should find the best rotation for SLA upside down printing.
|
||||||
*
|
*
|
||||||
@ -31,17 +57,13 @@ using RotOptimizeStatusCB = std::function<bool(int)>;
|
|||||||
*
|
*
|
||||||
* @return Returns the rotations around each axis (x, y, z)
|
* @return Returns the rotations around each axis (x, y, z)
|
||||||
*/
|
*/
|
||||||
Vec2d find_best_misalignment_rotation(
|
Vec2d find_best_misalignment_rotation(const ModelObject &modelobj,
|
||||||
const SLAPrintObject& modelobj,
|
const RotOptimizeParams & = {});
|
||||||
float accuracy = 1.0f,
|
|
||||||
RotOptimizeStatusCB statuscb = [] (int) { return true; }
|
|
||||||
);
|
|
||||||
|
|
||||||
Vec2d find_least_supports_rotation(
|
Vec2d find_least_supports_rotation(const ModelObject &modelobj,
|
||||||
const SLAPrintObject& modelobj,
|
const RotOptimizeParams & = {});
|
||||||
float accuracy = 1.0f,
|
|
||||||
RotOptimizeStatusCB statuscb = [] (int) { return true; }
|
double find_Z_fit_to_bed_rotation(const ModelObject &mo, const BoundingBox &bed);
|
||||||
);
|
|
||||||
|
|
||||||
} // namespace sla
|
} // namespace sla
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "libslic3r/SLAPrint.hpp"
|
#include "libslic3r/SLAPrint.hpp"
|
||||||
|
|
||||||
#include "slic3r/GUI/Plater.hpp"
|
#include "slic3r/GUI/Plater.hpp"
|
||||||
|
#include "libslic3r/PresetBundle.hpp"
|
||||||
|
|
||||||
#include "slic3r/GUI/GUI_App.hpp"
|
#include "slic3r/GUI/GUI_App.hpp"
|
||||||
#include "libslic3r/AppConfig.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_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_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()
|
void RotoptimizeJob::process()
|
||||||
{
|
{
|
||||||
int obj_idx = m_plater->get_selected_object_idx();
|
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;
|
return;
|
||||||
|
|
||||||
ModelObject *o = m_plater->model().objects[size_t(obj_idx)];
|
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) {
|
auto params =
|
||||||
if (s > 0 && s < 100)
|
sla::RotOptimizeParams{}
|
||||||
update_status(s, _(L("Searching for optimal orientation")));
|
.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
|
double mindist = 6.0; // FIXME
|
||||||
|
|
||||||
|
@ -4,18 +4,16 @@
|
|||||||
#include "PlaterJob.hpp"
|
#include "PlaterJob.hpp"
|
||||||
|
|
||||||
#include "libslic3r/SLA/Rotfinder.hpp"
|
#include "libslic3r/SLA/Rotfinder.hpp"
|
||||||
|
#include "libslic3r/PrintConfig.hpp"
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
class SLAPrintObject;
|
|
||||||
|
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
|
|
||||||
class RotoptimizeJob : public PlaterJob
|
class RotoptimizeJob : public PlaterJob
|
||||||
{
|
{
|
||||||
using FindFn = std::function<Vec2d(const SLAPrintObject & po,
|
using FindFn = std::function<Vec2d(const ModelObject & mo,
|
||||||
float accuracy,
|
const sla::RotOptimizeParams ¶ms)>;
|
||||||
sla::RotOptimizeStatusCB statuscb)>;
|
|
||||||
|
|
||||||
struct FindMethod { std::string name; FindFn findfn; };
|
struct FindMethod { std::string name; FindFn findfn; };
|
||||||
|
|
||||||
@ -26,6 +24,9 @@ class RotoptimizeJob : public PlaterJob
|
|||||||
|
|
||||||
size_t m_method_id = 0;
|
size_t m_method_id = 0;
|
||||||
float m_accuracy = 0.75;
|
float m_accuracy = 0.75;
|
||||||
|
|
||||||
|
DynamicPrintConfig m_default_print_cfg;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void prepare() override;
|
void prepare() override;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user