Merge branch 'tm_opencsg' into lm_tm_hollowing

This commit is contained in:
tamasmeszaros 2019-12-17 13:08:51 +01:00
commit 39fbb31db2
5 changed files with 245 additions and 214 deletions

View File

@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.0)
project(OpenCSG-example) project(OpenCSG-example)
add_executable(opencsg_example main.cpp GLScene.hpp GLScene.cpp Canvas.hpp add_executable(opencsg_example main.cpp GLScene.hpp GLScene.cpp
${CMAKE_CURRENT_SOURCE_DIR}/../../src/slic3r/GUI/ProgressStatusBar.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../../src/slic3r/GUI/ProgressStatusBar.cpp
${CMAKE_CURRENT_SOURCE_DIR}/../../src/slic3r/GUI/I18N.hpp ${CMAKE_CURRENT_SOURCE_DIR}/../../src/slic3r/GUI/I18N.hpp
${CMAKE_CURRENT_SOURCE_DIR}/../../src/slic3r/GUI/I18N.cpp) ${CMAKE_CURRENT_SOURCE_DIR}/../../src/slic3r/GUI/I18N.cpp)

View File

@ -1,100 +0,0 @@
#ifndef CANVAS_HPP
#define CANVAS_HPP
#include <memory>
// For compilers that support precompilation, includes "wx/wx.h".
#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
#include <wx/glcanvas.h>
#include <wx/msgdlg.h>
#include "GLScene.hpp"
namespace Slic3r { namespace GL {
class Canvas: public wxGLCanvas, public Slic3r::GL::Display
{
std::unique_ptr<wxGLContext> m_context;
public:
void set_active(long w, long h) override
{
SetCurrent(*m_context);
Slic3r::GL::Display::set_active(w, h);
}
void swap_buffers() override { SwapBuffers(); }
template<class...Args>
Canvas(Args &&...args): wxGLCanvas(std::forward<Args>(args)...)
{
auto ctx = new wxGLContext(this);
if (!ctx || !ctx->IsOK()) {
wxMessageBox("Could not create OpenGL context.", "Error",
wxOK | wxICON_ERROR);
return;
}
m_context.reset(ctx);
Bind(
wxEVT_MOUSEWHEEL,
[this](wxMouseEvent &evt) {
on_scroll(evt.GetWheelRotation(), evt.GetWheelDelta(),
evt.GetWheelAxis() == wxMOUSE_WHEEL_VERTICAL ?
Slic3r::GL::MouseInput::waVertical :
Slic3r::GL::MouseInput::waHorizontal);
},
GetId());
Bind(
wxEVT_MOTION,
[this](wxMouseEvent &evt) {
on_moved_to(evt.GetPosition().x, evt.GetPosition().y);
},
GetId());
Bind(
wxEVT_RIGHT_DOWN,
[this](wxMouseEvent & /*evt*/) { on_right_click_down(); },
GetId());
Bind(
wxEVT_RIGHT_UP,
[this](wxMouseEvent & /*evt*/) { on_right_click_up(); },
GetId());
Bind(
wxEVT_LEFT_DOWN,
[this](wxMouseEvent & /*evt*/) { on_left_click_down(); },
GetId());
Bind(
wxEVT_LEFT_UP,
[this](wxMouseEvent & /*evt*/) { on_left_click_up(); },
GetId());
Bind(wxEVT_PAINT, [this](wxPaintEvent &) {
// This is required even though dc is not used otherwise.
wxPaintDC dc(this);
// Set the OpenGL viewport according to the client size of this
// canvas. This is done here rather than in a wxSizeEvent handler
// because our OpenGL rendering context (and thus viewport setting) is
// used with multiple canvases: If we updated the viewport in the
// wxSizeEvent handler, changing the size of one canvas causes a
// viewport setting that is wrong when next another canvas is
// repainted.
const wxSize ClientSize = GetClientSize();
repaint(ClientSize.x, ClientSize.y);
}, GetId());
}
};
}} // namespace Slic3r::GL
#endif // CANVAS_HPP

View File

@ -133,7 +133,7 @@ void Scene::set_print(uqptr<SLAPrint> &&print)
m_print = std::move(print); m_print = std::move(print);
// Notify displays // Notify displays
call(&Display::on_scene_updated, m_displays); call(&Listener::on_scene_updated, m_listeners, *this);
} }
BoundingBoxf3 Scene::get_bounding_box() const BoundingBoxf3 Scene::get_bounding_box() const
@ -383,13 +383,18 @@ void Display::set_active(long width, long height)
m_camera->set_screen(width, height); m_camera->set_screen(width, height);
} }
void Display::repaint(long width, long height) void Display::set_screen_size(long width, long height)
{ {
if (m_size.x() != width || m_size.y() != height) if (m_size.x() != width || m_size.y() != height)
m_camera->set_screen(width, height); m_camera->set_screen(width, height);
m_size = {width, height}; m_size = {width, height};
repaint();
}
void Display::repaint()
{
clear_screen(); clear_screen();
m_camera->view(); m_camera->view();
@ -400,23 +405,34 @@ void Display::repaint(long width, long height)
swap_buffers(); swap_buffers();
} }
void Display::on_scroll(long v, long d, MouseInput::WheelAxis wa) void Controller::on_scene_updated(const Scene &scene)
{
const SLAPrint *print = scene.get_print();
if (!print) return;
auto bb = scene.get_bounding_box();
double d = std::max(std::max(bb.size().x(), bb.size().y()), bb.size().z());
m_wheel_pos = long(2 * d);
call_cameras(&Camera::set_zoom, m_wheel_pos);
call(&Display::on_scene_updated, m_displays, scene);
}
void Controller::on_scroll(long v, long d, MouseInput::WheelAxis /*wa*/)
{ {
m_wheel_pos += v / d; m_wheel_pos += v / d;
m_camera->set_zoom(m_wheel_pos); call_cameras(&Camera::set_zoom, m_wheel_pos);
call(&Display::repaint, m_displays);
m_scene->on_scroll(v, d, wa);
repaint(m_size.x(), m_size.y());
} }
void Display::on_moved_to(long x, long y) void Controller::on_moved_to(long x, long y)
{ {
if (m_left_btn) { if (m_left_btn) {
m_camera->rotate((Vec2i{x, y} - m_mouse_pos).cast<float>()); call_cameras(&Camera::rotate, (Vec2i{x, y} - m_mouse_pos).cast<float>());
repaint(); call(&Display::repaint, m_displays);
} }
m_mouse_pos = {x, y}; m_mouse_pos = {x, y};
} }
@ -424,30 +440,27 @@ void Display::apply_csgsettings(const CSGSettings &settings)
{ {
using namespace OpenCSG; using namespace OpenCSG;
bool update = m_csgsettings.get_convexity() != settings.get_convexity(); bool needupdate = m_csgsettings.get_convexity() != settings.get_convexity();
m_csgsettings = settings; m_csgsettings = settings;
setOption(AlgorithmSetting, m_csgsettings.get_algo()); setOption(AlgorithmSetting, m_csgsettings.get_algo());
setOption(DepthComplexitySetting, m_csgsettings.get_depth_algo()); setOption(DepthComplexitySetting, m_csgsettings.get_depth_algo());
setOption(DepthBoundsOptimization, m_csgsettings.get_optimization()); setOption(DepthBoundsOptimization, m_csgsettings.get_optimization());
if (update) on_scene_updated(); if (needupdate) {
for (OpenCSG::Primitive * p : m_scene_cache.primitives_csg)
if (p->getConvexity() > 1)
p->setConvexity(m_csgsettings.get_convexity());
}
repaint(); repaint();
} }
void Display::on_scene_updated() void Display::on_scene_updated(const Scene &scene)
{ {
const SLAPrint *print = m_scene->get_print(); const SLAPrint *print = scene.get_print();
if (!print) return; if (!print) return;
{
auto bb = m_scene->get_bounding_box();
double d = std::max(std::max(bb.size().x(), bb.size().y()), bb.size().z());
m_wheel_pos = long(2 * d);
m_camera->set_zoom(m_wheel_pos);
}
m_scene_cache.clear(); m_scene_cache.clear();
for (const SLAPrintObject *po : print->objects()) { for (const SLAPrintObject *po : print->objects()) {
@ -499,12 +512,6 @@ void Display::on_scene_updated()
repaint(); repaint();
} }
void Display::set_scene(shptr<Scene> scene)
{
m_scene = scene;
m_scene->add_display(shared_from_this());
}
void Camera::view() void Camera::view()
{ {
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);

View File

@ -21,16 +21,16 @@ template<class T> using uqptr = std::unique_ptr<T>;
template<class T> using wkptr = std::weak_ptr<T>; template<class T> using wkptr = std::weak_ptr<T>;
template<class T, class A = std::allocator<T>> template<class T, class A = std::allocator<T>>
using Collection = std::vector<T, A>; using vector = std::vector<T, A>;
template<class L> void cleanup(Collection<std::weak_ptr<L>> &listeners) { template<class L> void cleanup(vector<std::weak_ptr<L>> &listeners) {
auto it = std::remove_if(listeners.begin(), listeners.end(), auto it = std::remove_if(listeners.begin(), listeners.end(),
[](auto &l) { return !l.lock(); }); [](auto &l) { return !l.lock(); });
listeners.erase(it, listeners.end()); listeners.erase(it, listeners.end());
} }
template<class F, class L, class...Args> template<class F, class L, class...Args>
void call(F &&f, Collection<std::weak_ptr<L>> &listeners, Args&&... args) { void call(F &&f, vector<std::weak_ptr<L>> &listeners, Args&&... args) {
for (auto &l : listeners) for (auto &l : listeners)
if (auto p = l.lock()) ((p.get())->*f)(std::forward<Args>(args)...); if (auto p = l.lock()) ((p.get())->*f)(std::forward<Args>(args)...);
} }
@ -57,7 +57,7 @@ public:
}; };
private: private:
Collection<wkptr<Listener>> m_listeners; vector<wkptr<Listener>> m_listeners;
public: public:
virtual ~MouseInput() = default; virtual ~MouseInput() = default;
@ -104,9 +104,9 @@ public:
// Vertices and their normals, interleaved to be used by void // Vertices and their normals, interleaved to be used by void
// glInterleavedArrays(GL_N3F_V3F, 0, x) // glInterleavedArrays(GL_N3F_V3F, 0, x)
Collection<float> vertices_and_normals_interleaved; vector<float> vertices_and_normals_interleaved;
Collection<int> triangle_indices; vector<int> triangle_indices;
Collection<int> quad_indices; vector<int> quad_indices;
// When the geometry data is loaded into the graphics card as Vertex // When the geometry data is loaded into the graphics card as Vertex
// Buffer Objects, the above mentioned std::vectors are cleared and the // Buffer Objects, the above mentioned std::vectors are cleared and the
@ -223,8 +223,8 @@ public:
private: private:
OpenCSG::Algorithm m_csgalg = OpenCSG::Algorithm::Automatic; OpenCSG::Algorithm m_csgalg = OpenCSG::Algorithm::Automatic;
OpenCSG::DepthComplexityAlgorithm m_depth_algo = OpenCSG::DepthComplexityAlgorithm::NoDepthComplexitySampling; OpenCSG::DepthComplexityAlgorithm m_depth_algo = OpenCSG::NoDepthComplexitySampling;
OpenCSG::Optimization m_optim = OpenCSG::Optimization::OptimizationDefault; OpenCSG::Optimization m_optim = OpenCSG::OptimizationDefault;
bool m_enable = true; bool m_enable = true;
unsigned int m_convexity = DEFAULT_CONVEXITY; unsigned int m_convexity = DEFAULT_CONVEXITY;
@ -244,25 +244,48 @@ public:
unsigned get_convexity() const { return m_convexity; } unsigned get_convexity() const { return m_convexity; }
void set_convexity(unsigned c) { m_convexity = c; } void set_convexity(unsigned c) { m_convexity = c; }
}; };
class Display : public std::enable_shared_from_this<Display>, class Scene
public MouseInput::Listener {
uqptr<SLAPrint> m_print;
public:
class Listener {
public:
virtual ~Listener() = default;
virtual void on_scene_updated(const Scene &scene) = 0;
};
Scene();
~Scene();
void set_print(uqptr<SLAPrint> &&print);
const SLAPrint * get_print() const { return m_print.get(); }
BoundingBoxf3 get_bounding_box() const;
void add_listener(shptr<Listener> listener)
{
m_listeners.emplace_back(listener);
cleanup(m_listeners);
}
private:
vector<wkptr<Listener>> m_listeners;
};
class Display : public Scene::Listener
{ {
protected: protected:
shptr<Scene> m_scene;
long m_wheel_pos = 0;
Vec2i m_mouse_pos, m_mouse_pos_rprev, m_mouse_pos_lprev;
Vec2i m_size; Vec2i m_size;
bool m_initialized = false, m_left_btn = false, m_right_btn = false; bool m_initialized = false;
CSGSettings m_csgsettings; CSGSettings m_csgsettings;
shptr<Camera> m_camera;
struct SceneCache { struct SceneCache {
Collection<shptr<Primitive>> primitives; vector<shptr<Primitive>> primitives;
Collection<Primitive *> primitives_free; vector<Primitive *> primitives_free;
Collection<OpenCSG::Primitive *> primitives_csg; vector<OpenCSG::Primitive *> primitives_csg;
void clear(); void clear();
@ -272,64 +295,80 @@ protected:
unsigned covexity); unsigned covexity);
} m_scene_cache; } m_scene_cache;
shptr<Camera> m_camera;
public: public:
Display(shptr<Scene> scene = nullptr, shptr<Camera> camera = nullptr)
: m_scene(scene) explicit Display(shptr<Camera> camera = nullptr)
, m_camera(camera ? camera : std::make_shared<PerspectiveCamera>()) : m_camera(camera ? camera : std::make_shared<PerspectiveCamera>())
{} {}
Camera * camera() { return m_camera.get(); }
virtual void swap_buffers() = 0; virtual void swap_buffers() = 0;
virtual void set_active(long width, long height); virtual void set_active(long width, long height);
virtual void set_screen_size(long width, long height);
Vec2i get_screen_size() const { return m_size; }
virtual void repaint(long width, long height); virtual void repaint();
void repaint() { repaint(m_size.x(), m_size.y()); }
void set_scene(shptr<Scene> scene);
shptr<Scene> get_scene() { return m_scene; }
bool is_initialized() const { return m_initialized; } bool is_initialized() const { return m_initialized; }
void on_scroll(long v, long d, MouseInput::WheelAxis wa) override;
void on_moved_to(long x, long y) override;
void on_left_click_down() override { m_left_btn = true; }
void on_left_click_up() override { m_left_btn = false; }
void on_right_click_down() override { m_right_btn = true; }
void on_right_click_up() override { m_right_btn = false; }
void move_clip_plane(double z) { m_camera->set_clip_z(z); }
const CSGSettings & get_csgsettings() const { return m_csgsettings; } const CSGSettings & get_csgsettings() const { return m_csgsettings; }
void apply_csgsettings(const CSGSettings &settings); void apply_csgsettings(const CSGSettings &settings);
virtual void on_scene_updated(); void on_scene_updated(const Scene &scene) override;
virtual void clear_screen(); virtual void clear_screen();
virtual void render_scene(); virtual void render_scene();
}; };
class Scene: public MouseInput::Listener class Controller : public std::enable_shared_from_this<Controller>,
public MouseInput::Listener,
public Scene::Listener
{ {
uqptr<SLAPrint> m_print; long m_wheel_pos = 0;
Vec2i m_mouse_pos, m_mouse_pos_rprev, m_mouse_pos_lprev;
bool m_left_btn = false, m_right_btn = false;
shptr<Scene> m_scene;
vector<wkptr<Display>> m_displays;
// Call a method of Camera on all the cameras of the attached displays
template<class F, class...Args>
void call_cameras(F &&f, Args&&... args) {
for (wkptr<Display> &l : m_displays)
if (auto disp = l.lock()) if (disp->camera())
(disp->camera()->*f)(std::forward<Args>(args)...);
}
public: public:
Scene(); void set_scene(shptr<Scene> scene)
~Scene(); {
m_scene = scene;
m_scene->add_listener(shared_from_this());
}
const Scene * get_scene() const { return m_scene.get(); }
void add_display(shptr<Display> disp) void add_display(shptr<Display> disp)
{ {
m_displays.emplace_back(disp); m_displays.emplace_back(disp);
cleanup(m_displays); cleanup(m_displays);
} }
void set_print(uqptr<SLAPrint> &&print); void on_scene_updated(const Scene &scene) override;
const SLAPrint * get_print() const { return m_print.get(); }
BoundingBoxf3 get_bounding_box() const; void on_left_click_down() override { m_left_btn = true; }
void on_left_click_up() override { m_left_btn = false; }
void on_right_click_down() override { m_right_btn = true; }
void on_right_click_up() override { m_right_btn = false; }
void on_scroll(long v, long d, MouseInput::WheelAxis wa) override;
void on_moved_to(long x, long y) override;
private: void move_clip_plane(double z) { call_cameras(&Camera::set_clip_z, z); }
Collection<wkptr<Display>> m_displays;
}; };
}} // namespace Slic3r::GL }} // namespace Slic3r::GL
#endif // GLSCENE_HPP #endif // GLSCENE_HPP

View File

@ -15,9 +15,9 @@
#include <wx/tglbtn.h> #include <wx/tglbtn.h>
#include <wx/combobox.h> #include <wx/combobox.h>
#include <wx/spinctrl.h> #include <wx/spinctrl.h>
#include <wx/msgdlg.h>
#include <wx/glcanvas.h> #include <wx/glcanvas.h>
#include "Canvas.hpp"
#include "GLScene.hpp" #include "GLScene.hpp"
#include "libslic3r/Model.hpp" #include "libslic3r/Model.hpp"
@ -29,51 +29,60 @@
using namespace Slic3r::GL; using namespace Slic3r::GL;
class Canvas: public wxGLCanvas, public Slic3r::GL::Display
{
std::unique_ptr<wxGLContext> m_context;
public:
void set_active(long w, long h) override
{
SetCurrent(*m_context);
Slic3r::GL::Display::set_active(w, h);
}
void swap_buffers() override { SwapBuffers(); }
template<class...Args>
Canvas(Args &&...args): wxGLCanvas(std::forward<Args>(args)...)
{
auto ctx = new wxGLContext(this);
if (!ctx || !ctx->IsOK()) {
wxMessageBox("Could not create OpenGL context.", "Error",
wxOK | wxICON_ERROR);
return;
}
m_context.reset(ctx);
}
};
class MyFrame: public wxFrame class MyFrame: public wxFrame
{ {
std::shared_ptr<Canvas> m_canvas; shptr<Scene> m_scene; // Model
std::shared_ptr<Slic3r::GUI::ProgressStatusBar> m_stbar; shptr<Canvas> m_canvas; // View
std::unique_ptr<Slic3r::GUI::Job> m_ui_job; shptr<Controller> m_ctl; // Controller
shptr<Slic3r::GUI::ProgressStatusBar> m_stbar;
uqptr<Slic3r::GUI::Job> m_ui_job;
class SLAJob: public Slic3r::GUI::Job { class SLAJob: public Slic3r::GUI::Job {
MyFrame *m_parent; MyFrame *m_parent;
std::unique_ptr<Slic3r::SLAPrint> m_print; std::unique_ptr<Slic3r::SLAPrint> m_print;
std::string m_fname; std::string m_fname;
public: public:
SLAJob(MyFrame *frame, const std::string &fname)
SLAJob(MyFrame *frame, const std::string &fname)
: Slic3r::GUI::Job{frame->m_stbar} : Slic3r::GUI::Job{frame->m_stbar}
, m_parent{frame} , m_parent{frame}
, m_fname{fname} , m_fname{fname}
{ {}
}
void process() override;
void process() override
{
using Status = Slic3r::PrintBase::SlicingStatus;
Slic3r::DynamicPrintConfig cfg;
auto model = Slic3r::Model::read_from_file(m_fname, &cfg);
m_print = std::make_unique<Slic3r::SLAPrint>();
m_print->apply(model, cfg);
Slic3r::PrintBase::TaskParams params;
params.to_object_step = Slic3r::slaposHollowing;
m_print->set_task(params);
m_print->set_status_callback([this](const Status &status) {
update_status(status.percent, status.text);
});
m_print->process();
}
protected: protected:
void finalize() override void finalize() override
{ {
m_parent->m_canvas->get_scene()->set_print(std::move(m_print)); m_parent->m_scene->set_print(std::move(m_print));
m_parent->m_stbar->set_status_text( m_parent->m_stbar->set_status_text(
wxString::Format("Model %s loaded.", m_fname)); wxString::Format("Model %s loaded.", m_fname));
} }
@ -84,6 +93,8 @@ public:
private: private:
void bind_canvas_events_to_controller();
void OnExit(wxCommandEvent& /*event*/) void OnExit(wxCommandEvent& /*event*/)
{ {
RemoveChild(m_canvas.get()); RemoveChild(m_canvas.get());
@ -108,7 +119,8 @@ private:
const wxSize ClientSize = GetClientSize(); const wxSize ClientSize = GetClientSize();
m_canvas->set_active(ClientSize.x, ClientSize.y); m_canvas->set_active(ClientSize.x, ClientSize.y);
m_canvas->repaint(ClientSize.x, ClientSize.y); m_canvas->set_screen_size(ClientSize.x, ClientSize.y);
m_canvas->repaint();
// Do the repaint continuously // Do the repaint continuously
Bind(wxEVT_IDLE, [this](wxIdleEvent &evt) { Bind(wxEVT_IDLE, [this](wxIdleEvent &evt) {
@ -159,9 +171,14 @@ MyFrame::MyFrame(const wxString &title, const wxPoint &pos, const wxSize &size):
WX_GL_MIN_ALPHA, 8, WX_GL_DEPTH_SIZE, 8, WX_GL_STENCIL_SIZE, 8, WX_GL_MIN_ALPHA, 8, WX_GL_DEPTH_SIZE, 8, WX_GL_STENCIL_SIZE, 8,
WX_GL_SAMPLE_BUFFERS, GL_TRUE, WX_GL_SAMPLES, 4, 0}; WX_GL_SAMPLE_BUFFERS, GL_TRUE, WX_GL_SAMPLES, 4, 0};
m_scene = std::make_shared<Scene>();
m_ctl = std::make_shared<Controller>();
m_ctl->set_scene(m_scene);
m_canvas = std::make_shared<Canvas>(this, wxID_ANY, attribList, m_canvas = std::make_shared<Canvas>(this, wxID_ANY, attribList,
wxDefaultPosition, wxDefaultSize, wxDefaultPosition, wxDefaultSize,
wxWANTS_CHARS | wxFULL_REPAINT_ON_RESIZE); wxWANTS_CHARS | wxFULL_REPAINT_ON_RESIZE);
m_ctl->add_display(m_canvas);
wxPanel *control_panel = new wxPanel(this); wxPanel *control_panel = new wxPanel(this);
auto controlsizer = new wxBoxSizer(wxHORIZONTAL); auto controlsizer = new wxBoxSizer(wxHORIZONTAL);
@ -234,7 +251,7 @@ MyFrame::MyFrame(const wxString &title, const wxPoint &pos, const wxSize &size):
Bind(wxEVT_SHOW, &MyFrame::OnShown, this, GetId()); Bind(wxEVT_SHOW, &MyFrame::OnShown, this, GetId());
Bind(wxEVT_SLIDER, [this, slider](wxCommandEvent &) { Bind(wxEVT_SLIDER, [this, slider](wxCommandEvent &) {
m_canvas->move_clip_plane(double(slider->GetValue())); m_ctl->move_clip_plane(double(slider->GetValue()));
}); });
ms_toggle->Bind(wxEVT_TOGGLEBUTTON, [this, ms_toggle](wxCommandEvent &){ ms_toggle->Bind(wxEVT_TOGGLEBUTTON, [this, ms_toggle](wxCommandEvent &){
@ -283,5 +300,73 @@ MyFrame::MyFrame(const wxString &title, const wxPoint &pos, const wxSize &size):
} }
}); });
m_canvas->set_scene(std::make_shared<Slic3r::GL::Scene>()); bind_canvas_events_to_controller();
}
void MyFrame::bind_canvas_events_to_controller()
{
m_canvas->Bind(wxEVT_MOUSEWHEEL, [this](wxMouseEvent &evt) {
m_ctl->on_scroll(evt.GetWheelRotation(), evt.GetWheelDelta(),
evt.GetWheelAxis() == wxMOUSE_WHEEL_VERTICAL ?
Slic3r::GL::MouseInput::waVertical :
Slic3r::GL::MouseInput::waHorizontal);
});
m_canvas->Bind(wxEVT_MOTION, [this](wxMouseEvent &evt) {
m_ctl->on_moved_to(evt.GetPosition().x, evt.GetPosition().y);
});
m_canvas->Bind(wxEVT_RIGHT_DOWN, [this](wxMouseEvent & /*evt*/) {
m_ctl->on_right_click_down();
});
m_canvas->Bind(wxEVT_RIGHT_UP, [this](wxMouseEvent & /*evt*/) {
m_ctl->on_right_click_up();
});
m_canvas->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent & /*evt*/) {
m_ctl->on_left_click_down();
});
m_canvas->Bind(wxEVT_LEFT_UP, [this](wxMouseEvent & /*evt*/) {
m_ctl->on_left_click_up();
});
m_canvas->Bind(wxEVT_PAINT, [this](wxPaintEvent &) {
// This is required even though dc is not used otherwise.
wxPaintDC dc(this);
// Set the OpenGL viewport according to the client size of this
// canvas. This is done here rather than in a wxSizeEvent handler
// because our OpenGL rendering context (and thus viewport setting) is
// used with multiple canvases: If we updated the viewport in the
// wxSizeEvent handler, changing the size of one canvas causes a
// viewport setting that is wrong when next another canvas is
// repainted.
const wxSize ClientSize = m_canvas->GetClientSize();
m_canvas->set_screen_size(ClientSize.x, ClientSize.y);
m_canvas->repaint();
});
}
void MyFrame::SLAJob::process()
{
using Status = Slic3r::PrintBase::SlicingStatus;
Slic3r::DynamicPrintConfig cfg;
auto model = Slic3r::Model::read_from_file(m_fname, &cfg);
m_print = std::make_unique<Slic3r::SLAPrint>();
m_print->apply(model, cfg);
Slic3r::PrintBase::TaskParams params;
params.to_object_step = Slic3r::slaposHollowing;
m_print->set_task(params);
m_print->set_status_callback([this](const Status &status) {
update_status(status.percent, status.text);
});
m_print->process();
} }