diff options
author | tamasmeszaros <meszaros.q@gmail.com> | 2019-12-16 20:49:44 +0300 |
---|---|---|
committer | tamasmeszaros <meszaros.q@gmail.com> | 2019-12-16 20:49:44 +0300 |
commit | bb3b39016fa9381506e1594cd46f361c6d348fd6 (patch) | |
tree | a7254e8706b46172179a49203a2c656f5b7415a7 /sandboxes | |
parent | d14ff000e0a2e647d5b77fd0b8615c590914a389 (diff) |
Add ctl and fix applying opencsg params on the fly.
Diffstat (limited to 'sandboxes')
-rw-r--r-- | sandboxes/opencsg/Canvas.hpp | 52 | ||||
-rw-r--r-- | sandboxes/opencsg/GLScene.cpp | 61 | ||||
-rw-r--r-- | sandboxes/opencsg/GLScene.hpp | 122 | ||||
-rw-r--r-- | sandboxes/opencsg/main.cpp | 122 |
4 files changed, 204 insertions, 153 deletions
diff --git a/sandboxes/opencsg/Canvas.hpp b/sandboxes/opencsg/Canvas.hpp index 17fd8f044..424579945 100644 --- a/sandboxes/opencsg/Canvas.hpp +++ b/sandboxes/opencsg/Canvas.hpp @@ -40,58 +40,6 @@ public: } 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()); } }; diff --git a/sandboxes/opencsg/GLScene.cpp b/sandboxes/opencsg/GLScene.cpp index 02a4b7991..1cfccb3b1 100644 --- a/sandboxes/opencsg/GLScene.cpp +++ b/sandboxes/opencsg/GLScene.cpp @@ -133,7 +133,7 @@ void Scene::set_print(uqptr<SLAPrint> &&print) m_print = std::move(print); // Notify displays - call(&Display::on_scene_updated, m_displays); + call(&Listener::on_scene_updated, m_listeners, *this); } BoundingBoxf3 Scene::get_bounding_box() const @@ -383,13 +383,18 @@ void Display::set_active(long width, long 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) m_camera->set_screen(width, height); m_size = {width, height}; + repaint(); +} + +void Display::repaint() +{ clear_screen(); m_camera->view(); @@ -400,23 +405,34 @@ void Display::repaint(long width, long height) swap_buffers(); } -void Display::on_scroll(long v, long d, MouseInput::WheelAxis wa) +void Controller::on_scene_updated(const Scene &scene) { - m_wheel_pos += v / d; + const SLAPrint *print = scene.get_print(); + if (!print) return; - m_camera->set_zoom(m_wheel_pos); + 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); - m_scene->on_scroll(v, d, wa); + 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; - repaint(m_size.x(), m_size.y()); + call_cameras(&Camera::set_zoom, m_wheel_pos); + call(&Display::repaint, m_displays); } -void Display::on_moved_to(long x, long y) +void Controller::on_moved_to(long x, long y) { if (m_left_btn) { - m_camera->rotate((Vec2i{x, y} - m_mouse_pos).cast<float>()); - repaint(); + call_cameras(&Camera::rotate, (Vec2i{x, y} - m_mouse_pos).cast<float>()); + call(&Display::repaint, m_displays); } + m_mouse_pos = {x, y}; } @@ -424,30 +440,27 @@ void Display::apply_csgsettings(const CSGSettings &settings) { using namespace OpenCSG; - bool update = m_csgsettings.get_convexity() != settings.get_convexity(); + bool needupdate = m_csgsettings.get_convexity() != settings.get_convexity(); m_csgsettings = settings; setOption(AlgorithmSetting, m_csgsettings.get_algo()); setOption(DepthComplexitySetting, m_csgsettings.get_depth_algo()); 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(); } -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; - { - 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(); for (const SLAPrintObject *po : print->objects()) { @@ -499,12 +512,6 @@ void Display::on_scene_updated() repaint(); } -void Display::set_scene(shptr<Scene> scene) -{ - m_scene = scene; - m_scene->add_display(shared_from_this()); -} - void Camera::view() { glMatrixMode(GL_MODELVIEW); diff --git a/sandboxes/opencsg/GLScene.hpp b/sandboxes/opencsg/GLScene.hpp index a127ab90b..5a4afb396 100644 --- a/sandboxes/opencsg/GLScene.hpp +++ b/sandboxes/opencsg/GLScene.hpp @@ -223,8 +223,8 @@ public: private: OpenCSG::Algorithm m_csgalg = OpenCSG::Algorithm::Automatic; - OpenCSG::DepthComplexityAlgorithm m_depth_algo = OpenCSG::DepthComplexityAlgorithm::NoDepthComplexitySampling; - OpenCSG::Optimization m_optim = OpenCSG::Optimization::OptimizationDefault; + OpenCSG::DepthComplexityAlgorithm m_depth_algo = OpenCSG::NoDepthComplexitySampling; + OpenCSG::Optimization m_optim = OpenCSG::OptimizationDefault; bool m_enable = true; unsigned int m_convexity = DEFAULT_CONVEXITY; @@ -244,21 +244,44 @@ public: unsigned get_convexity() const { return m_convexity; } void set_convexity(unsigned c) { m_convexity = c; } }; - -class Display : public std::enable_shared_from_this<Display>, - public MouseInput::Listener + +class Scene +{ + 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: + Collection<wkptr<Listener>> m_listeners; +}; + +class Display : public Scene::Listener { 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; - bool m_initialized = false, m_left_btn = false, m_right_btn = false; + bool m_initialized = false; CSGSettings m_csgsettings; - shptr<Camera> m_camera; - struct SceneCache { Collection<shptr<Primitive>> primitives; Collection<Primitive *> primitives_free; @@ -272,64 +295,79 @@ protected: unsigned covexity); } m_scene_cache; + shptr<Camera> m_camera; + public: - Display(shptr<Scene> scene = nullptr, shptr<Camera> camera = nullptr) - : m_scene(scene) - , m_camera(camera ? camera : std::make_shared<PerspectiveCamera>()) + + explicit Display(shptr<Camera> camera = nullptr) + : m_camera(camera ? camera : std::make_shared<PerspectiveCamera>()) {} - - virtual void swap_buffers() = 0; - virtual void set_active(long width, long height); + Camera * camera() { return m_camera.get(); } - virtual void repaint(long width, long height); - void repaint() { repaint(m_size.x(), m_size.y()); } + virtual void swap_buffers() = 0; + 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; } - void set_scene(shptr<Scene> scene); - shptr<Scene> get_scene() { return m_scene; } + virtual void repaint(); 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; } 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 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; + Collection<wkptr<Display>> m_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: - Scene(); - ~Scene(); + void set_scene(shptr<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) { m_displays.emplace_back(disp); cleanup(m_displays); } - void set_print(uqptr<SLAPrint> &&print); - const SLAPrint * get_print() const { return m_print.get(); } + void on_scene_updated(const Scene &scene) override; - BoundingBoxf3 get_bounding_box() const; - -private: + 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; } - Collection<wkptr<Display>> m_displays; -}; + void on_scroll(long v, long d, MouseInput::WheelAxis wa) override; + void on_moved_to(long x, long y) override; + void move_clip_plane(double z) { call_cameras(&Camera::set_clip_z, z); } +}; }} // namespace Slic3r::GL #endif // GLSCENE_HPP diff --git a/sandboxes/opencsg/main.cpp b/sandboxes/opencsg/main.cpp index ddd4bf33e..d01687428 100644 --- a/sandboxes/opencsg/main.cpp +++ b/sandboxes/opencsg/main.cpp @@ -31,49 +31,31 @@ using namespace Slic3r::GL; class MyFrame: public wxFrame { - std::shared_ptr<Canvas> m_canvas; - std::shared_ptr<Slic3r::GUI::ProgressStatusBar> m_stbar; - std::unique_ptr<Slic3r::GUI::Job> m_ui_job; + shptr<Scene> m_scene; // Model + shptr<Canvas> m_canvas; // View + shptr<Controller> m_ctl; // Controller + + shptr<Slic3r::GUI::ProgressStatusBar> m_stbar; + uqptr<Slic3r::GUI::Job> m_ui_job; class SLAJob: public Slic3r::GUI::Job { MyFrame *m_parent; std::unique_ptr<Slic3r::SLAPrint> m_print; std::string m_fname; public: - - SLAJob(MyFrame *frame, const std::string &fname) + SLAJob(MyFrame *frame, const std::string &fname) : Slic3r::GUI::Job{frame->m_stbar} , m_parent{frame} , m_fname{fname} - { - } - - 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(); - } + {} + + void process() override; protected: 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( wxString::Format("Model %s loaded.", m_fname)); } @@ -84,6 +66,8 @@ public: private: + void bind_canvas_events_to_controller(); + void OnExit(wxCommandEvent& /*event*/) { RemoveChild(m_canvas.get()); @@ -108,7 +92,8 @@ private: const wxSize ClientSize = GetClientSize(); 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 Bind(wxEVT_IDLE, [this](wxIdleEvent &evt) { @@ -159,9 +144,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_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, wxDefaultPosition, wxDefaultSize, wxWANTS_CHARS | wxFULL_REPAINT_ON_RESIZE); + m_ctl->add_display(m_canvas); wxPanel *control_panel = new wxPanel(this); auto controlsizer = new wxBoxSizer(wxHORIZONTAL); @@ -234,7 +224,7 @@ MyFrame::MyFrame(const wxString &title, const wxPoint &pos, const wxSize &size): Bind(wxEVT_SHOW, &MyFrame::OnShown, this, GetId()); 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 &){ @@ -283,5 +273,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(); } |