Method selection implemented
This commit is contained in:
parent
4eb13a407f
commit
0194094afa
6 changed files with 181 additions and 18 deletions
|
@ -92,9 +92,9 @@ Transform3f to_transform3f(const XYRotation &rot)
|
|||
|
||||
} // namespace
|
||||
|
||||
Vec2d find_best_rotation(const SLAPrintObject & po,
|
||||
float accuracy,
|
||||
std::function<bool(int)> statuscb)
|
||||
Vec2d find_best_misalignment_rotation(const SLAPrintObject & po,
|
||||
float accuracy,
|
||||
std::function<bool(int)> statuscb)
|
||||
{
|
||||
static const unsigned MAX_TRIES = 1000;
|
||||
|
||||
|
@ -156,12 +156,4 @@ Vec2d find_best_rotation(const SLAPrintObject & po,
|
|||
return {rot[0], rot[1]};
|
||||
}
|
||||
|
||||
double get_model_supportedness(const SLAPrintObject &po, const Transform3f &tr)
|
||||
{
|
||||
TriangleMesh mesh = po.model_object()->raw_mesh();
|
||||
mesh.require_shared_vertices();
|
||||
|
||||
return get_model_supportedness(mesh, tr);
|
||||
}
|
||||
|
||||
}} // namespace Slic3r::sla
|
||||
|
|
|
@ -9,9 +9,12 @@
|
|||
namespace Slic3r {
|
||||
|
||||
class SLAPrintObject;
|
||||
class TriangleMesh;
|
||||
|
||||
namespace sla {
|
||||
|
||||
using RotOptimizeStatusCB = std::function<bool(int)>;
|
||||
|
||||
/**
|
||||
* The function should find the best rotation for SLA upside down printing.
|
||||
*
|
||||
|
@ -28,14 +31,13 @@ namespace sla {
|
|||
*
|
||||
* @return Returns the rotations around each axis (x, y, z)
|
||||
*/
|
||||
Vec2d find_best_rotation(
|
||||
Vec2d find_best_misalignment_rotation(
|
||||
const SLAPrintObject& modelobj,
|
||||
float accuracy = 1.0f,
|
||||
std::function<bool(int)> statuscb = [] (int) { return true; }
|
||||
RotOptimizeStatusCB statuscb = [] (int) { return true; }
|
||||
);
|
||||
|
||||
double get_model_supportedness(const SLAPrintObject &mesh,
|
||||
const Transform3f & tr);
|
||||
|
||||
|
||||
} // namespace sla
|
||||
} // namespace Slic3r
|
||||
|
|
|
@ -7,9 +7,10 @@
|
|||
|
||||
#include "slic3r/GUI/GUI_App.hpp"
|
||||
#include "slic3r/GUI/GUI.hpp"
|
||||
#include "slic3r/GUI/Plater.hpp"
|
||||
#include "libslic3r/PresetBundle.hpp"
|
||||
|
||||
#include "libslic3r/SLA/Rotfinder.hpp"
|
||||
#include "slic3r/GUI/Jobs/RotoptimizeJob.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
@ -204,6 +205,23 @@ void GLGizmoRotate3D::on_render_input_window(float x, float y, float bottom_limi
|
|||
{
|
||||
if (wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() != ptSLA)
|
||||
return;
|
||||
|
||||
RotoptimzeWindow popup{m_imgui, m_rotoptimizewin_state, {x, y, bottom_limit}};
|
||||
}
|
||||
|
||||
void GLGizmoRotate3D::load_rotoptimize_state()
|
||||
{
|
||||
std::string accuracy_str =
|
||||
wxGetApp().app_config->get("rotoptimize", "accuracy");
|
||||
|
||||
std::string method_str =
|
||||
wxGetApp().app_config->get("rotoptimize", "method_id");
|
||||
|
||||
if (!accuracy_str.empty())
|
||||
m_rotoptimizewin_state.accuracy = std::stof(accuracy_str);
|
||||
|
||||
if (!method_str.empty())
|
||||
m_rotoptimizewin_state.method_id = std::stoi(method_str);
|
||||
}
|
||||
|
||||
void GLGizmoRotate::render_circle() const
|
||||
|
@ -436,6 +454,9 @@ GLGizmoRotate3D::GLGizmoRotate3D(GLCanvas3D& parent, const std::string& icon_fil
|
|||
{
|
||||
m_gizmos[i].set_group_id(i);
|
||||
}
|
||||
|
||||
std::cout << "Load rotopt state" << std::endl;
|
||||
load_rotoptimize_state();
|
||||
}
|
||||
|
||||
bool GLGizmoRotate3D::on_init()
|
||||
|
@ -492,5 +513,57 @@ void GLGizmoRotate3D::on_render() const
|
|||
m_gizmos[Z].render();
|
||||
}
|
||||
|
||||
const char * GLGizmoRotate3D::RotoptimzeWindow::options[RotoptimizeJob::get_methods_count()];
|
||||
bool GLGizmoRotate3D::RotoptimzeWindow::options_valid = false;
|
||||
|
||||
GLGizmoRotate3D::RotoptimzeWindow::RotoptimzeWindow(ImGuiWrapper * imgui,
|
||||
State & state,
|
||||
const Alignment &alignment)
|
||||
: m_imgui{imgui}
|
||||
{
|
||||
imgui->begin(_L("Optimize orientation"), ImGuiWindowFlags_NoMove |
|
||||
ImGuiWindowFlags_AlwaysAutoResize |
|
||||
ImGuiWindowFlags_NoCollapse);
|
||||
|
||||
// adjust window position to avoid overlap the view toolbar
|
||||
float win_h = ImGui::GetWindowHeight();
|
||||
float x = alignment.x, y = alignment.y;
|
||||
y = std::min(y, alignment.bottom_limit - win_h);
|
||||
ImGui::SetWindowPos(ImVec2(x, y), ImGuiCond_Always);
|
||||
|
||||
ImGui::PushItemWidth(200.f);
|
||||
|
||||
size_t methods_cnt = RotoptimizeJob::get_methods_count();
|
||||
if (!options_valid) {
|
||||
for (size_t i = 0; i < methods_cnt; ++i)
|
||||
options[i] = RotoptimizeJob::get_method_names()[i].c_str();
|
||||
|
||||
options_valid = true;
|
||||
}
|
||||
|
||||
int citem = state.method_id;
|
||||
if (ImGui::Combo(_L("Choose method").c_str(), &citem, options, methods_cnt) ) {
|
||||
state.method_id = citem;
|
||||
wxGetApp().app_config->set("rotoptimize", "method_id", std::to_string(state.method_id));
|
||||
}
|
||||
|
||||
float accuracy = state.accuracy;
|
||||
if (imgui->slider_float(_L("Accuracy/Speed"), &accuracy, 0.01f, 1.f, "%.1f")) {
|
||||
state.accuracy = accuracy;
|
||||
wxGetApp().app_config->set("rotoptimize", "accuracy", std::to_string(state.accuracy));
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
if ( imgui->button(_L("Optimize")) ) {
|
||||
wxGetApp().plater()->optimize_rotation();
|
||||
}
|
||||
}
|
||||
|
||||
GLGizmoRotate3D::RotoptimzeWindow::~RotoptimzeWindow()
|
||||
{
|
||||
m_imgui->end();
|
||||
}
|
||||
|
||||
} // namespace GUI
|
||||
} // namespace Slic3r
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define slic3r_GLGizmoRotate_hpp_
|
||||
|
||||
#include "GLGizmoBase.hpp"
|
||||
#include "../Jobs/RotoptimizeJob.hpp"
|
||||
|
||||
|
||||
namespace Slic3r {
|
||||
|
@ -136,6 +137,39 @@ protected:
|
|||
}
|
||||
|
||||
void on_render_input_window(float x, float y, float bottom_limit) override;
|
||||
|
||||
private:
|
||||
|
||||
class RotoptimzeWindow {
|
||||
ImGuiWrapper *m_imgui = nullptr;
|
||||
|
||||
static const char * options [];
|
||||
static bool options_valid;
|
||||
|
||||
public:
|
||||
|
||||
struct State {
|
||||
float accuracy = 1.f;
|
||||
int method_id = 0;
|
||||
};
|
||||
|
||||
struct Alignment { float x, y, bottom_limit; };
|
||||
|
||||
RotoptimzeWindow(ImGuiWrapper * imgui,
|
||||
State & state,
|
||||
const Alignment &bottom_limit);
|
||||
|
||||
~RotoptimzeWindow();
|
||||
|
||||
RotoptimzeWindow(const RotoptimzeWindow&) = delete;
|
||||
RotoptimzeWindow(RotoptimzeWindow &&) = delete;
|
||||
RotoptimzeWindow& operator=(const RotoptimzeWindow &) = delete;
|
||||
RotoptimzeWindow& operator=(RotoptimzeWindow &&) = delete;
|
||||
};
|
||||
|
||||
RotoptimzeWindow::State m_rotoptimizewin_state = {};
|
||||
|
||||
void load_rotoptimize_state();
|
||||
};
|
||||
|
||||
} // namespace GUI
|
||||
|
|
|
@ -8,8 +8,29 @@
|
|||
|
||||
#include "slic3r/GUI/Plater.hpp"
|
||||
|
||||
#include "slic3r/GUI/GUI_App.hpp"
|
||||
#include "libslic3r/AppConfig.hpp"
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
void RotoptimizeJob::prepare()
|
||||
{
|
||||
std::string accuracy_str =
|
||||
wxGetApp().app_config->get("rotoptimize", "accuracy");
|
||||
|
||||
std::string method_str =
|
||||
wxGetApp().app_config->get("rotoptimize", "method_id");
|
||||
|
||||
if (!accuracy_str.empty())
|
||||
m_accuracy = std::stof(accuracy_str);
|
||||
|
||||
if (!method_str.empty())
|
||||
m_method_id = std::stoi(method_str);
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
void RotoptimizeJob::process()
|
||||
{
|
||||
int obj_idx = m_plater->get_selected_object_idx();
|
||||
|
@ -21,7 +42,7 @@ void RotoptimizeJob::process()
|
|||
|
||||
if (!o || !po) return;
|
||||
|
||||
Vec2d r = sla::find_best_rotation(*po, 0.75f, [this](int s) {
|
||||
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")));
|
||||
|
||||
|
|
|
@ -3,17 +3,58 @@
|
|||
|
||||
#include "PlaterJob.hpp"
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
#include "libslic3r/SLA/Rotfinder.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
class SLAPrintObject;
|
||||
|
||||
namespace GUI {
|
||||
|
||||
class RotoptimizeJob : public PlaterJob
|
||||
{
|
||||
using FindFn = std::function<Vec2d(const SLAPrintObject & po,
|
||||
float accuracy,
|
||||
sla::RotOptimizeStatusCB statuscb)>;
|
||||
|
||||
struct FindMethod { std::string name; FindFn findfn; };
|
||||
|
||||
static inline const FindMethod Methods[] = {
|
||||
{ L("Best misalignment"), sla::find_best_misalignment_rotation },
|
||||
{ L("Least supports"), sla::find_best_misalignment_rotation }
|
||||
};
|
||||
|
||||
size_t m_method_id = 0;
|
||||
float m_accuracy = 0.75;
|
||||
protected:
|
||||
|
||||
void prepare() override;
|
||||
|
||||
public:
|
||||
|
||||
RotoptimizeJob(std::shared_ptr<ProgressIndicator> pri, Plater *plater)
|
||||
: PlaterJob{std::move(pri), plater}
|
||||
{}
|
||||
|
||||
void process() override;
|
||||
void finalize() override;
|
||||
|
||||
static constexpr size_t get_methods_count() { return std::size(Methods); }
|
||||
static const auto & get_method_names()
|
||||
{
|
||||
static bool m_method_names_valid = false;
|
||||
static std::array<std::string, std::size(Methods)> m_method_names;
|
||||
|
||||
if (!m_method_names_valid) {
|
||||
|
||||
for (size_t i = 0; i < std::size(Methods); ++i)
|
||||
m_method_names[i] = _utf8(Methods[i].name);
|
||||
|
||||
m_method_names_valid = true;
|
||||
}
|
||||
|
||||
return m_method_names;
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace Slic3r::GUI
|
||||
|
|
Loading…
Reference in a new issue