mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	Merge branch 'tm_opencsg' into lm_tm_hollowing
This commit is contained in:
		
						commit
						9363344a6f
					
				
					 7 changed files with 549 additions and 225 deletions
				
			
		|  | @ -409,8 +409,7 @@ if(SLIC3R_STATIC) | |||
|     set(USE_BLOSC TRUE) | ||||
| endif() | ||||
| 
 | ||||
| 
 | ||||
| find_package(OpenVDB 5.0 COMPONENTS openvdb) | ||||
| find_package(OpenVDB 5.0 REQUIRED COMPONENTS openvdb) | ||||
| if(OpenVDB_FOUND) | ||||
|     slic3r_remap_configs(IlmBase::Half RelWithDebInfo Release) | ||||
| endif() | ||||
|  |  | |||
|  | @ -215,13 +215,42 @@ if(UNIX AND OPENVDB_USE_STATIC_LIBS) | |||
| endif() | ||||
| 
 | ||||
| set(OpenVDB_LIB_COMPONENTS "") | ||||
| set(OpenVDB_DEBUG_SUFFIX "d" CACHE STRING "Suffix for the debug libraries") | ||||
| 
 | ||||
| get_property(_is_multi GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) | ||||
| 
 | ||||
| foreach(COMPONENT ${OpenVDB_FIND_COMPONENTS}) | ||||
|   set(LIB_NAME ${COMPONENT}) | ||||
|   find_library(OpenVDB_${COMPONENT}_LIBRARY ${LIB_NAME} lib${LIB_NAME} | ||||
| 
 | ||||
|   find_library(OpenVDB_${COMPONENT}_LIBRARY_RELEASE ${LIB_NAME} lib${LIB_NAME} | ||||
|     PATHS ${_OPENVDB_LIBRARYDIR_SEARCH_DIRS} | ||||
|     PATH_SUFFIXES ${OPENVDB_PATH_SUFFIXES} | ||||
|   ) | ||||
| 
 | ||||
|   find_library(OpenVDB_${COMPONENT}_LIBRARY_DEBUG ${LIB_NAME}${OpenVDB_DEBUG_SUFFIX} lib${LIB_NAME}${OpenVDB_DEBUG_SUFFIX} | ||||
|     PATHS ${_OPENVDB_LIBRARYDIR_SEARCH_DIRS} | ||||
|     PATH_SUFFIXES ${OPENVDB_PATH_SUFFIXES} | ||||
|   ) | ||||
| 
 | ||||
|   if (_is_multi) | ||||
|     list(APPEND OpenVDB_LIB_COMPONENTS ${OpenVDB_${COMPONENT}_LIBRARY_RELEASE} ${OpenVDB_${COMPONENT}_LIBRARY_DEBUG}) | ||||
| 
 | ||||
|     list(FIND CMAKE_CONFIGURATION_TYPES "Debug" _has_debug) | ||||
|      | ||||
|     if(OpenVDB_${COMPONENT}_LIBRARY_RELEASE AND (_has_debug LESS 0 OR OpenVDB_${COMPONENT}_LIBRARY_DEBUG)) | ||||
|       set(OpenVDB_${COMPONENT}_FOUND TRUE) | ||||
|     else() | ||||
|       set(OpenVDB_${COMPONENT}_FOUND FALSE) | ||||
|     endif() | ||||
|   else () | ||||
|     string(TOUPPER "${CMAKE_BUILD_TYPE}" _BUILD_TYPE) | ||||
| 
 | ||||
|     set(OpenVDB_${COMPONENT}_LIBRARY ${OpenVDB_${COMPONENT}_LIBRARY_${_BUILD_TYPE}}) | ||||
| 
 | ||||
|     if (NOT MSVC AND NOT OpenVDB_${COMPONENT}_LIBRARY) | ||||
|       set(OpenVDB_${COMPONENT}_LIBRARY ${OpenVDB_${COMPONENT}_LIBRARY_RELEASE}) | ||||
|     endif () | ||||
| 
 | ||||
|     list(APPEND OpenVDB_LIB_COMPONENTS ${OpenVDB_${COMPONENT}_LIBRARY}) | ||||
| 
 | ||||
|     if(OpenVDB_${COMPONENT}_LIBRARY) | ||||
|  | @ -229,6 +258,7 @@ foreach(COMPONENT ${OpenVDB_FIND_COMPONENTS}) | |||
|     else() | ||||
|       set(OpenVDB_${COMPONENT}_FOUND FALSE) | ||||
|     endif() | ||||
|   endif () | ||||
| endforeach() | ||||
| 
 | ||||
| if(UNIX AND OPENVDB_USE_STATIC_LIBS) | ||||
|  | @ -487,7 +517,6 @@ foreach(COMPONENT ${OpenVDB_FIND_COMPONENTS}) | |||
|   if(NOT TARGET OpenVDB::${COMPONENT}) | ||||
|     add_library(OpenVDB::${COMPONENT} UNKNOWN IMPORTED) | ||||
|     set_target_properties(OpenVDB::${COMPONENT} PROPERTIES | ||||
|       IMPORTED_LOCATION "${OpenVDB_${COMPONENT}_LIBRARY}" | ||||
|       INTERFACE_COMPILE_OPTIONS "${OpenVDB_DEFINITIONS}" | ||||
|       INTERFACE_INCLUDE_DIRECTORIES "${OpenVDB_INCLUDE_DIR}" | ||||
|       IMPORTED_LINK_DEPENDENT_LIBRARIES "${_OPENVDB_HIDDEN_DEPENDENCIES}" # non visible deps | ||||
|  | @ -495,6 +524,17 @@ foreach(COMPONENT ${OpenVDB_FIND_COMPONENTS}) | |||
|       INTERFACE_COMPILE_FEATURES cxx_std_11 | ||||
|    ) | ||||
| 
 | ||||
|   if (_is_multi) | ||||
|     set_target_properties(OpenVDB::${COMPONENT} PROPERTIES  | ||||
|       IMPORTED_LOCATION_RELEASE "${OpenVDB_${COMPONENT}_LIBRARY_RELEASE}" | ||||
|       IMPORTED_LOCATION_DEBUG "${OpenVDB_${COMPONENT}_LIBRARY_DEBUG}" | ||||
|     ) | ||||
|   else () | ||||
|     set_target_properties(OpenVDB::${COMPONENT} PROPERTIES  | ||||
|       IMPORTED_LOCATION "${OpenVDB_${COMPONENT}_LIBRARY}" | ||||
|     ) | ||||
|   endif () | ||||
| 
 | ||||
|    if (OPENVDB_USE_STATIC_LIBS) | ||||
|     set_target_properties(OpenVDB::${COMPONENT} PROPERTIES | ||||
|       INTERFACE_COMPILE_DEFINITIONS "OPENVDB_STATICLIB;OPENVDB_OPENEXR_STATICLIB" | ||||
|  |  | |||
							
								
								
									
										1
									
								
								deps/CMakeLists.txt
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								deps/CMakeLists.txt
									
										
									
									
										vendored
									
									
								
							|  | @ -47,6 +47,7 @@ message(STATUS "PrusaSlicer deps debug build: ${DEP_DEBUG}") | |||
| 
 | ||||
| find_package(Git REQUIRED) | ||||
| 
 | ||||
| get_property(_is_multi GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) | ||||
| 
 | ||||
| function(prusaslicer_add_cmake_project projectname) | ||||
|     cmake_parse_arguments(P_ARGS "" "INSTALL_DIR;BUILD_COMMAND;INSTALL_COMMAND" "CMAKE_ARGS" ${ARGN}) | ||||
|  |  | |||
|  | @ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.0) | |||
| 
 | ||||
| project(OpenCSG-example) | ||||
| 
 | ||||
| add_executable(opencsg_example main.cpp  GLScene.hpp GLScene.cpp  | ||||
| add_executable(opencsg_example WIN32 main.cpp  Engine.hpp Engine.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.cpp) | ||||
|  | @ -11,11 +11,15 @@ find_package(wxWidgets 3.1 REQUIRED COMPONENTS core base gl html) | |||
| find_package(OpenGL REQUIRED) | ||||
| find_package(GLEW REQUIRED) | ||||
| find_package(OpenCSG REQUIRED) | ||||
| find_package(GLUT REQUIRED) | ||||
| include(${wxWidgets_USE_FILE}) | ||||
| 
 | ||||
| 
 | ||||
| target_link_libraries(opencsg_example libslic3r) | ||||
| target_include_directories(opencsg_example PRIVATE ${wxWidgets_INCLUDE_DIRS}) | ||||
| target_compile_definitions(opencsg_example PRIVATE ${wxWidgets_DEFINITIONS}) | ||||
| target_link_libraries(opencsg_example ${wxWidgets_LIBRARIES} GLEW::GLEW OpenCSG::opencsg GLUT::GLUT OpenGL::OpenGL -lXrandr -lXext -lX11) | ||||
| 
 | ||||
| target_link_libraries(opencsg_example ${wxWidgets_LIBRARIES}  | ||||
|     OpenCSG::opencsg  | ||||
|     GLEW::GLEW | ||||
|     OpenGL::GL  | ||||
|     #-lXrandr -lXext -lX11 | ||||
|     ) | ||||
|  |  | |||
|  | @ -1,16 +1,10 @@ | |||
| #include "GLScene.hpp" | ||||
| #include "Engine.hpp" | ||||
| #include <libslic3r/Utils.hpp> | ||||
| #include <libslic3r/SLAPrint.hpp> | ||||
| #include <libslic3r/MTUtils.hpp> | ||||
| 
 | ||||
| #include <GL/glew.h> | ||||
| 
 | ||||
| #ifdef __APPLE__ | ||||
| #include <GLUT/glut.h> | ||||
| #else | ||||
| #include <GL/glut.h> | ||||
| #endif | ||||
| 
 | ||||
| #include <boost/log/trivial.hpp> | ||||
| 
 | ||||
| #ifndef NDEBUG | ||||
|  | @ -52,49 +46,9 @@ inline void glAssertRecentCall() { } | |||
| namespace Slic3r { namespace GL { | ||||
| 
 | ||||
| Scene::Scene() = default; | ||||
| 
 | ||||
| Scene::~Scene() = default; | ||||
| 
 | ||||
| void renderfps () { | ||||
|     static std::ostringstream fpsStream; | ||||
|     static int fps = 0; | ||||
|     static int ancient = 0; | ||||
|     static int last = 0; | ||||
|     static int msec = 0; | ||||
|      | ||||
|     last = msec; | ||||
|     msec = glutGet(GLUT_ELAPSED_TIME); | ||||
|     if (last / 1000 != msec / 1000) { | ||||
|          | ||||
|         float correctedFps = fps * 1000.0f / float(msec - ancient); | ||||
|         fpsStream.str(""); | ||||
|         fpsStream << "fps: " << correctedFps << std::ends; | ||||
|          | ||||
|         ancient = msec; | ||||
|         fps = 0; | ||||
|     } | ||||
|     glDisable(GL_DEPTH_TEST); | ||||
|     glLoadIdentity(); | ||||
|     glMatrixMode(GL_PROJECTION); | ||||
|     glPushMatrix(); | ||||
|     glLoadIdentity(); | ||||
|     glColor3f(0.0f, 0.0f, 0.0f); | ||||
|     glRasterPos2f(-1.0f, -1.0f); | ||||
|     glDisable(GL_LIGHTING); | ||||
|     std::string s = fpsStream.str(); | ||||
|     for (unsigned int i=0; i<s.size(); ++i) { | ||||
|         glutBitmapCharacter(GLUT_BITMAP_8_BY_13, s[i]); | ||||
|     } | ||||
|     glEnable(GL_LIGHTING); | ||||
|     glPopMatrix(); | ||||
|     glMatrixMode(GL_MODELVIEW); | ||||
|     glEnable(GL_DEPTH_TEST); | ||||
|      | ||||
|     ++fps; | ||||
|     glFlush(); | ||||
| } | ||||
| 
 | ||||
| void Display::render_scene() | ||||
| void CSGDisplay::render_scene() | ||||
| { | ||||
|     GLfloat color[] = {1.f, 1.f, 0.f, 0.f}; | ||||
|     glsafe(::glColor4fv(color)); | ||||
|  | @ -141,14 +95,14 @@ BoundingBoxf3 Scene::get_bounding_box() const | |||
|     return m_print->model().bounding_box(); | ||||
| } | ||||
| 
 | ||||
| void Display::SceneCache::clear() | ||||
| void CSGDisplay::SceneCache::clear() | ||||
| { | ||||
|     primitives_csg.clear(); | ||||
|     primitives_free.clear(); | ||||
|     primitives.clear(); | ||||
| } | ||||
| 
 | ||||
| shptr<Primitive> Display::SceneCache::add_mesh(const TriangleMesh &mesh) | ||||
| shptr<Primitive> CSGDisplay::SceneCache::add_mesh(const TriangleMesh &mesh) | ||||
| { | ||||
|     auto p = std::make_shared<Primitive>(); | ||||
|     p->load_mesh(mesh); | ||||
|  | @ -157,7 +111,7 @@ shptr<Primitive> Display::SceneCache::add_mesh(const TriangleMesh &mesh) | |||
|     return p; | ||||
| } | ||||
| 
 | ||||
| shptr<Primitive> Display::SceneCache::add_mesh(const TriangleMesh &mesh, | ||||
| shptr<Primitive> CSGDisplay::SceneCache::add_mesh(const TriangleMesh &mesh, | ||||
|                                                    OpenCSG::Operation  o, | ||||
|                                                    unsigned            c) | ||||
| { | ||||
|  | @ -347,18 +301,18 @@ void Display::clear_screen() | |||
|     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); | ||||
| } | ||||
| 
 | ||||
| Display::~Display() | ||||
| { | ||||
|     OpenCSG::freeResources(); | ||||
| } | ||||
| 
 | ||||
| void Display::set_active(long width, long height) | ||||
| {    | ||||
|     static int argc = 0; | ||||
|      | ||||
|     if (!m_initialized) { | ||||
|         glewInit(); | ||||
|         glutInit(&argc, nullptr); | ||||
|         m_initialized = true; | ||||
|     } | ||||
| 
 | ||||
|     m_size = {width, height}; | ||||
|      | ||||
|     // gray background
 | ||||
|     glClearColor(0.9f, 0.9f, 0.9f, 1.0f); | ||||
| 
 | ||||
|  | @ -380,7 +334,7 @@ void Display::set_active(long width, long height) | |||
|     glEnable(GL_DEPTH_TEST); | ||||
|     glEnable(GL_STENCIL_TEST); | ||||
|      | ||||
|     m_camera->set_screen(width, height); | ||||
|     set_screen_size(width, height); | ||||
| } | ||||
| 
 | ||||
| void Display::set_screen_size(long width, long height) | ||||
|  | @ -389,8 +343,6 @@ void Display::set_screen_size(long width, long height) | |||
|         m_camera->set_screen(width, height); | ||||
|      | ||||
|     m_size = {width, height}; | ||||
|      | ||||
|     repaint(); | ||||
| } | ||||
| 
 | ||||
| void Display::repaint() | ||||
|  | @ -400,7 +352,7 @@ void Display::repaint() | |||
|     m_camera->view(); | ||||
|     render_scene(); | ||||
|      | ||||
|     renderfps();  | ||||
|     m_fps_counter.update(); | ||||
|      | ||||
|     swap_buffers(); | ||||
| } | ||||
|  | @ -436,7 +388,7 @@ void Controller::on_moved_to(long x, long y) | |||
|     m_mouse_pos = {x, y}; | ||||
| } | ||||
| 
 | ||||
| void Display::apply_csgsettings(const CSGSettings &settings) | ||||
| void CSGDisplay::apply_csgsettings(const CSGSettings &settings) | ||||
| { | ||||
|     using namespace OpenCSG; | ||||
|      | ||||
|  | @ -452,11 +404,9 @@ void Display::apply_csgsettings(const CSGSettings &settings) | |||
|             if (p->getConvexity() > 1) | ||||
|                 p->setConvexity(m_csgsettings.get_convexity()); | ||||
|     } | ||||
|      | ||||
|     repaint(); | ||||
| } | ||||
| 
 | ||||
| void Display::on_scene_updated(const Scene &scene) | ||||
| void CSGDisplay::on_scene_updated(const Scene &scene) | ||||
| { | ||||
|     const SLAPrint *print = scene.get_print(); | ||||
|     if (!print) return; | ||||
|  | @ -555,4 +505,24 @@ bool enable_multisampling(bool e) | |||
| 
 | ||||
| MouseInput::Listener::~Listener() = default; | ||||
| 
 | ||||
| void FpsCounter::update() | ||||
| { | ||||
|     ++m_frames; | ||||
|      | ||||
|     TimePoint msec = Clock::now(); | ||||
|      | ||||
|     double seconds_window = to_sec(msec - m_window); | ||||
|     m_fps = 0.5 * m_fps + 0.5 * (m_frames / seconds_window); | ||||
|      | ||||
|     if (to_sec(msec - m_last) >= m_resolution) { | ||||
|         m_last = msec; | ||||
|         for (auto &l : m_listeners) l(m_fps); | ||||
|     } | ||||
|      | ||||
|     if (seconds_window >= m_window_size) { | ||||
|         m_frames = 0; | ||||
|         m_window = msec; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| }} // namespace Slic3r::GL
 | ||||
|  | @ -1,8 +1,9 @@ | |||
| #ifndef GLSCENE_HPP | ||||
| #define GLSCENE_HPP | ||||
| #ifndef SLIC3R_OCSG_EXMP_ENGINE_HPP | ||||
| #define SLIC3R_OCSG_EXMP_ENGINE_HPP_HPP | ||||
| 
 | ||||
| #include <vector> | ||||
| #include <memory> | ||||
| #include <chrono> | ||||
| 
 | ||||
| #include <libslic3r/Geometry.hpp> | ||||
| #include <libslic3r/Model.hpp> | ||||
|  | @ -164,7 +165,6 @@ public: | |||
| }; | ||||
| 
 | ||||
| bool enable_multisampling(bool e = true); | ||||
| void renderfps(); | ||||
| 
 | ||||
| class Primitive : public OpenCSG::Primitive | ||||
| { | ||||
|  | @ -189,8 +189,6 @@ public: | |||
|     } | ||||
| }; | ||||
| 
 | ||||
| class Scene; | ||||
| 
 | ||||
| class Camera { | ||||
| protected: | ||||
|     Vec2f m_rot = {0., 0.}; | ||||
|  | @ -211,12 +209,56 @@ public: | |||
|     void set_clip_z(double z) { m_clip_z = z; } | ||||
| }; | ||||
| 
 | ||||
| inline void reset(Camera &cam) | ||||
| { | ||||
|     cam.set_rotation({0., 0.}); | ||||
|     cam.set_zoom(0.); | ||||
|     cam.set_reference_point({0., 0., 0.}); | ||||
|     cam.set_clip_z(0.); | ||||
| } | ||||
| 
 | ||||
| class PerspectiveCamera: public Camera { | ||||
| public: | ||||
|      | ||||
|     void set_screen(long width, long height) override; | ||||
| }; | ||||
| 
 | ||||
| class FpsCounter { | ||||
|     vector<std::function<void(double)>> m_listeners; | ||||
|      | ||||
|     using Clock = std::chrono::high_resolution_clock; | ||||
|     using Duration = Clock::duration; | ||||
|     using TimePoint = Clock::time_point; | ||||
|      | ||||
|     int m_frames = 0; | ||||
|     TimePoint m_last = Clock::now(), m_window = m_last; | ||||
|      | ||||
|     double m_resolution = 0.1, m_window_size = 1.0; | ||||
|     double m_fps = 0.; | ||||
|      | ||||
|     static double to_sec(Duration d) | ||||
|     { | ||||
|         return d.count() * double(Duration::period::num) / Duration::period::den; | ||||
|     }     | ||||
|      | ||||
| public: | ||||
|      | ||||
|     void update(); | ||||
| 
 | ||||
|     void add_listener(std::function<void(double)> lst) | ||||
|     { | ||||
|         m_listeners.emplace_back(lst); | ||||
|     } | ||||
|      | ||||
|     void clear_listeners() { m_listeners = {}; } | ||||
| 
 | ||||
|     void set_notification_interval(double seconds); | ||||
|     void set_measure_window_size(double seconds); | ||||
|      | ||||
|     double get_notification_interval() const { return m_resolution; } | ||||
|     double get_mesure_window_size() const { return m_window_size; } | ||||
| }; | ||||
| 
 | ||||
| class CSGSettings { | ||||
| public: | ||||
|     static const constexpr unsigned DEFAULT_CONVEXITY = 10; | ||||
|  | @ -280,6 +322,42 @@ protected: | |||
|     Vec2i m_size; | ||||
|     bool m_initialized = false; | ||||
|      | ||||
|     shptr<Camera>  m_camera; | ||||
|     FpsCounter m_fps_counter; | ||||
|      | ||||
| public: | ||||
|      | ||||
|     explicit Display(shptr<Camera> camera = nullptr) | ||||
|         : m_camera(camera ? camera : std::make_shared<PerspectiveCamera>()) | ||||
|     {} | ||||
|      | ||||
|     ~Display() override; | ||||
|      | ||||
|     Camera * camera() { return m_camera.get(); } | ||||
|      | ||||
|     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; } | ||||
|      | ||||
|     virtual void repaint(); | ||||
|      | ||||
|     bool is_initialized() const { return m_initialized; } | ||||
|      | ||||
|     virtual void clear_screen(); | ||||
|     virtual void render_scene() {} | ||||
|      | ||||
|     template<class _FpsCounter> void set_fps_counter(_FpsCounter &&fpsc) | ||||
|     { | ||||
|         m_fps_counter = std::forward<_FpsCounter>(fpsc); | ||||
|     } | ||||
| 
 | ||||
|     const FpsCounter &get_fps_counter() const { return m_fps_counter; } | ||||
|     FpsCounter &get_fps_counter() { return m_fps_counter; } | ||||
| }; | ||||
| 
 | ||||
| class CSGDisplay : public Display { | ||||
| protected: | ||||
|     CSGSettings m_csgsettings; | ||||
|      | ||||
|     struct SceneCache { | ||||
|  | @ -295,32 +373,14 @@ protected: | |||
|                                   unsigned            covexity); | ||||
|     } m_scene_cache; | ||||
|      | ||||
|     shptr<Camera>  m_camera; | ||||
|      | ||||
| public: | ||||
|      | ||||
|     explicit Display(shptr<Camera> camera = nullptr) | ||||
|         : m_camera(camera ? camera : std::make_shared<PerspectiveCamera>()) | ||||
|     {} | ||||
|      | ||||
|     Camera * camera() { return m_camera.get(); } | ||||
|      | ||||
|     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; } | ||||
|      | ||||
|     virtual void repaint(); | ||||
|      | ||||
|     bool is_initialized() const { return m_initialized; } | ||||
|      | ||||
|     const CSGSettings & get_csgsettings() const { return m_csgsettings; } | ||||
|     void apply_csgsettings(const CSGSettings &settings); | ||||
|      | ||||
|     void on_scene_updated(const Scene &scene) override; | ||||
|     void render_scene() override; | ||||
|      | ||||
|     virtual void clear_screen(); | ||||
|     virtual void render_scene(); | ||||
|     void on_scene_updated(const Scene &scene) override; | ||||
| }; | ||||
| 
 | ||||
| class Controller : public std::enable_shared_from_this<Controller>, | ||||
|  | @ -370,5 +430,6 @@ public: | |||
| 
 | ||||
|     void move_clip_plane(double z) { call_cameras(&Camera::set_clip_z, z); } | ||||
| }; | ||||
| 
 | ||||
| }}     // namespace Slic3r::GL
 | ||||
| #endif // GLSCENE_HPP
 | ||||
| #endif // SLIC3R_OCSG_EXMP_ENGINE_HPP
 | ||||
|  | @ -2,13 +2,15 @@ | |||
| #include <utility> | ||||
| #include <memory> | ||||
| 
 | ||||
| #include "Engine.hpp" | ||||
| 
 | ||||
| #include <GL/glew.h> | ||||
| 
 | ||||
| #include <opencsg/opencsg.h> | ||||
| // For compilers that support precompilation, includes "wx/wx.h".
 | ||||
| #include <wx/wxprec.h> | ||||
| #ifndef WX_PRECOMP | ||||
|     #include <wx/wx.h> | ||||
| #include <wx/wx.h> | ||||
| #endif | ||||
| 
 | ||||
| #include <wx/slider.h> | ||||
|  | @ -17,8 +19,7 @@ | |||
| #include <wx/spinctrl.h> | ||||
| #include <wx/msgdlg.h> | ||||
| #include <wx/glcanvas.h> | ||||
| 
 | ||||
| #include "GLScene.hpp" | ||||
| #include <wx/cmdline.h> | ||||
| 
 | ||||
| #include "libslic3r/Model.hpp" | ||||
| #include "libslic3r/Format/3mf.hpp" | ||||
|  | @ -29,23 +30,15 @@ | |||
| 
 | ||||
| using namespace Slic3r::GL; | ||||
| 
 | ||||
| class Canvas: public wxGLCanvas, public Slic3r::GL::Display | ||||
| class Canvas: public wxGLCanvas | ||||
| { | ||||
|     std::unique_ptr<wxGLContext> m_context; | ||||
| public: | ||||
|     class OCSGRenderer: public Slic3r::GL::CSGDisplay { | ||||
|         Canvas *m_canvas; | ||||
|         shptr<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); | ||||
|         OCSGRenderer(Canvas *c): m_canvas{c} { | ||||
|             auto ctx = new wxGLContext(m_canvas); | ||||
|             if (!ctx || !ctx->IsOK()) { | ||||
|                 wxMessageBox("Could not create OpenGL context.", "Error", | ||||
|                              wxOK | wxICON_ERROR); | ||||
|  | @ -54,6 +47,138 @@ public: | |||
|              | ||||
|             m_context.reset(ctx); | ||||
|         } | ||||
|          | ||||
|         void set_active(long w, long h) override | ||||
|         { | ||||
|             m_canvas->SetCurrent(*m_context); | ||||
|             Slic3r::GL::Display::set_active(w, h); | ||||
|         } | ||||
|          | ||||
|         wxGLContext * context() { return m_context.get(); } | ||||
|         const wxGLContext * context() const { return m_context.get(); } | ||||
|          | ||||
|         void swap_buffers() override { m_canvas->SwapBuffers(); } | ||||
|          | ||||
|         ~OCSGRenderer() override { m_scene_cache.clear(); } | ||||
|     }; | ||||
|      | ||||
|     shptr<OCSGRenderer> m_ocsgdisplay = std::make_shared<OCSGRenderer>(this); | ||||
|      | ||||
|     shptr<Slic3r::GL::Display> m_display = m_ocsgdisplay; | ||||
|      | ||||
| public: | ||||
|      | ||||
|     template<class...Args> | ||||
|     Canvas(Args &&...args): wxGLCanvas(std::forward<Args>(args)...) | ||||
|     { | ||||
|         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(); | ||||
|              | ||||
|             m_display->set_screen_size(ClientSize.x, ClientSize.y); | ||||
|         }); | ||||
|     } | ||||
|      | ||||
|     shptr<Slic3r::GL::Display> get_display() const { return m_display; } | ||||
|     void set_display(shptr<Slic3r::GL::Display> d) { m_display = d; } | ||||
|      | ||||
|     shptr<Slic3r::GL::CSGDisplay> get_ocsg_display() const { return m_ocsgdisplay; } | ||||
| }; | ||||
| 
 | ||||
| enum EEvents { LCLK_U, RCLK_U, LCLK_D, RCLK_D, DDCLK, SCRL, MV }; | ||||
| struct Event | ||||
| { | ||||
|     EEvents type; | ||||
|     long    a, b; | ||||
|     Event(EEvents t, long x = 0, long y = 0) : type{t}, a{x}, b{y} {} | ||||
| }; | ||||
| 
 | ||||
| class RecorderMouseInput: public MouseInput { | ||||
|     std::vector<Event> m_events; | ||||
|     bool m_recording = false, m_playing = false; | ||||
|      | ||||
| public: | ||||
|     void left_click_down() override | ||||
|     { | ||||
|         if (m_recording) m_events.emplace_back(LCLK_D); | ||||
|         if (!m_playing) MouseInput::left_click_down(); | ||||
|     } | ||||
|     void left_click_up() override | ||||
|     { | ||||
|         if (m_recording) m_events.emplace_back(LCLK_U); | ||||
|         if (!m_playing) MouseInput::left_click_up(); | ||||
|     } | ||||
|     void right_click_down() override | ||||
|     { | ||||
|         if (m_recording) m_events.emplace_back(RCLK_D); | ||||
|         if (!m_playing) MouseInput::right_click_down(); | ||||
|     } | ||||
|     void right_click_up() override | ||||
|     { | ||||
|         if (m_recording) m_events.emplace_back(RCLK_U); | ||||
|         if (!m_playing) MouseInput::right_click_up(); | ||||
|     } | ||||
|     void double_click() override | ||||
|     { | ||||
|         if (m_recording) m_events.emplace_back(DDCLK); | ||||
|         if (!m_playing) MouseInput::double_click(); | ||||
|     } | ||||
|     void scroll(long v, long d, WheelAxis wa) override | ||||
|     { | ||||
|         if (m_recording) m_events.emplace_back(SCRL, v, d); | ||||
|         if (!m_playing) MouseInput::scroll(v, d, wa); | ||||
|     } | ||||
|     void move_to(long x, long y) override | ||||
|     { | ||||
|         if (m_recording) m_events.emplace_back(MV, x, y); | ||||
|         if (!m_playing) MouseInput::move_to(x, y); | ||||
|     } | ||||
|      | ||||
|     void save(std::ostream &stream) | ||||
|     { | ||||
|         for (const Event &evt : m_events) | ||||
|             stream << evt.type << " " << evt.a << " " << evt.b << std::endl; | ||||
|     } | ||||
|      | ||||
|     void load(std::istream &stream) | ||||
|     { | ||||
|         m_events.clear(); | ||||
|         while (stream.good()) { | ||||
|             int type; long a, b; | ||||
|             stream >> type >> a >> b; | ||||
|             m_events.emplace_back(EEvents(type), a, b); | ||||
|         } | ||||
|     }     | ||||
|      | ||||
|     void record(bool r) { m_recording = r; if (r) m_events.clear(); } | ||||
|      | ||||
|     void play() | ||||
|     { | ||||
|         m_playing = true; | ||||
|         for (const Event &evt : m_events) { | ||||
|             switch (evt.type) { | ||||
|             case LCLK_U: MouseInput::left_click_up(); break; | ||||
|             case LCLK_D: MouseInput::left_click_down(); break; | ||||
|             case RCLK_U: MouseInput::right_click_up(); break; | ||||
|             case RCLK_D: MouseInput::right_click_down(); break; | ||||
|             case DDCLK:  MouseInput::double_click(); break; | ||||
|             case SCRL:   MouseInput::scroll(evt.a, evt.b, WheelAxis::waVertical); break; | ||||
|             case MV:     MouseInput::move_to(evt.a, evt.b); break; | ||||
|             } | ||||
|              | ||||
|             wxSafeYield(); | ||||
|         } | ||||
|         m_playing = false; | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| class MyFrame: public wxFrame | ||||
|  | @ -63,12 +188,14 @@ class MyFrame: public wxFrame | |||
|     shptr<Controller> m_ctl;      // Controller
 | ||||
| 
 | ||||
|     shptr<Slic3r::GUI::ProgressStatusBar> m_stbar; | ||||
|     uqptr<Slic3r::GUI::Job> m_ui_job; | ||||
|      | ||||
|     RecorderMouseInput m_mouse; | ||||
|      | ||||
|     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) | ||||
|             : Slic3r::GUI::Job{frame->m_stbar} | ||||
|  | @ -78,8 +205,9 @@ class MyFrame: public wxFrame | |||
| 
 | ||||
|         void process() override; | ||||
|          | ||||
|     protected: | ||||
|         const std::string & get_project_fname() const { return m_fname; } | ||||
|          | ||||
|     protected: | ||||
|         void finalize() override  | ||||
|         { | ||||
|             m_parent->m_scene->set_print(std::move(m_print)); | ||||
|  | @ -88,55 +216,110 @@ class MyFrame: public wxFrame | |||
|         } | ||||
|     }; | ||||
|      | ||||
|     uqptr<SLAJob> m_ui_job; | ||||
|      | ||||
|     double m_fps_avg = 0.; | ||||
|      | ||||
| public: | ||||
|     MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size); | ||||
|     MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size, const Slic3r::GL::CSGSettings &settings); | ||||
|      | ||||
| private: | ||||
|      | ||||
|     void bind_canvas_events_to_controller(); | ||||
|      | ||||
|     void OnExit(wxCommandEvent& /*event*/)  | ||||
|     { | ||||
|         RemoveChild(m_canvas.get()); | ||||
|         m_canvas->Destroy(); | ||||
|         Close( true ); | ||||
|     } | ||||
|      | ||||
|     void OnOpen(wxCommandEvent &/*evt*/) | ||||
|     { | ||||
|         wxFileDialog dlg(this, "Select project file",  | ||||
|                          wxEmptyString, wxEmptyString, "*.3mf"); | ||||
|          | ||||
|         if (dlg.ShowModal() == wxID_OK) | ||||
|         { | ||||
|             m_ui_job = std::make_unique<SLAJob>(this, dlg.GetPath().ToStdString()); | ||||
|     void load_model(const std::string &fname) { | ||||
|         m_ui_job = std::make_unique<SLAJob>(this, fname); | ||||
|         m_ui_job->start(); | ||||
|     } | ||||
|     } | ||||
|      | ||||
|     void OnShown(wxShowEvent&) | ||||
|     void play_back_mouse(const std::string &events_fname) | ||||
|     { | ||||
|         const wxSize ClientSize = GetClientSize(); | ||||
|         m_canvas->set_active(ClientSize.x, ClientSize.y);  | ||||
|         std::fstream stream(events_fname, std::fstream::in); | ||||
| 
 | ||||
|         m_canvas->set_screen_size(ClientSize.x, ClientSize.y); | ||||
|         m_canvas->repaint(); | ||||
|         if (stream.good()) { | ||||
|             std::string model_name; | ||||
|             std::getline(stream, model_name); | ||||
|             load_model(model_name); | ||||
|              | ||||
|         // Do the repaint continuously
 | ||||
|         Bind(wxEVT_IDLE, [this](wxIdleEvent &evt) { | ||||
|             m_canvas->repaint(); | ||||
|             evt.RequestMore(); | ||||
|         }); | ||||
|             int w, h; | ||||
|             stream >> w >> h; | ||||
|             SetSize(w, h); | ||||
|              | ||||
|             m_mouse.load(stream); | ||||
|             m_mouse.play(); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     Canvas * canvas() { return m_canvas.get(); } | ||||
|     const Canvas * canvas() const { return m_canvas.get(); } | ||||
|      | ||||
|     void bind_canvas_events(MouseInput &msinput); | ||||
|      | ||||
|     double get_fps_average() const { return m_fps_avg; } | ||||
| }; | ||||
| 
 | ||||
| static const std::vector<wxString> CSG_ALGS  = {"Auto", "Goldfeather", "SCS"}; | ||||
| static const std::vector<wxString> CSG_DEPTH = {"Off", "OcclusionQuery", "On"}; | ||||
| static const std::vector<wxString> CSG_OPT   = { "Default", "ForceOn", "On", "Off" }; | ||||
| 
 | ||||
| class App : public wxApp { | ||||
|     MyFrame *m_frame; | ||||
|     MyFrame *m_frame = nullptr; | ||||
|      | ||||
| public: | ||||
|     bool OnInit() override { | ||||
|         m_frame = new MyFrame("PrusaSlicer OpenCSG Demo", wxDefaultPosition, wxSize(1024, 768)); | ||||
|          | ||||
|         wxCmdLineParser parser(argc, argv); | ||||
|          | ||||
|         parser.AddOption("p", "play", "play back file", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL); | ||||
|         parser.AddOption("a", "algorithm", "OpenCSG algorithm [Auto|Goldfeather|SCS]", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL); | ||||
|         parser.AddOption("d", "depth", "OpenCSG depth strategy [Off|OcclusionQuery|On]", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL); | ||||
|         parser.AddOption("o", "optimization", "OpenCSG optimization strategy [Default|ForceOn|On|Off]", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL); | ||||
|         parser.AddOption("c", "convexity", "OpenCSG convexity parameter for generic meshes", wxCMD_LINE_VAL_NUMBER, wxCMD_LINE_PARAM_OPTIONAL); | ||||
|         parser.AddSwitch("", "disable-csg", "Disable csg rendering", wxCMD_LINE_PARAM_OPTIONAL); | ||||
|          | ||||
|         parser.Parse(); | ||||
|          | ||||
|         wxString fname; | ||||
|         bool is_play = parser.Found("play", &fname); | ||||
|          | ||||
|         wxString alg; | ||||
|         parser.Found("algorithm", &alg); | ||||
|          | ||||
|         wxString depth; | ||||
|         parser.Found("depth", &depth); | ||||
|          | ||||
|         wxString opt; | ||||
|         parser.Found("optimization", &opt); | ||||
|          | ||||
|         long convexity = 1; | ||||
|         parser.Found("convexity", &convexity); | ||||
|          | ||||
|         bool csg_off = parser.Found("disable-csg"); | ||||
|          | ||||
|         auto get_idx = [](const wxString &a, const std::vector<wxString> &v) { | ||||
|             auto it = std::find(v.begin(), v.end(), a.ToStdString()); | ||||
|             return it - v.begin(); | ||||
|         }; | ||||
|          | ||||
|         Slic3r::GL::CSGSettings settings; | ||||
|          | ||||
|         if (auto a = get_idx(alg, CSG_ALGS) < OpenCSG::AlgorithmUnused)  | ||||
|             settings.set_algo(OpenCSG::Algorithm(a)); | ||||
|          | ||||
|         if (auto a = get_idx(depth, CSG_DEPTH) < OpenCSG::DepthComplexityAlgorithmUnused)  | ||||
|             settings.set_depth_algo(OpenCSG::DepthComplexityAlgorithm(a)); | ||||
|          | ||||
|         if (auto a = get_idx(opt, CSG_OPT) < OpenCSG::OptimizationUnused)  | ||||
|             settings.set_optimization(OpenCSG::Optimization(a)); | ||||
|          | ||||
|         settings.set_convexity(unsigned(convexity)); | ||||
|         settings.enable_csg(!csg_off); | ||||
|          | ||||
|         m_frame = new MyFrame("PrusaSlicer OpenCSG Demo", wxDefaultPosition, wxSize(1024, 768), settings); | ||||
|          | ||||
|         if (is_play) { | ||||
|             m_frame->Show( true ); | ||||
|             m_frame->play_back_mouse(fname.ToStdString()); | ||||
|             m_frame->Close( true ); | ||||
|             std::cout << m_frame->get_fps_average() << std::endl; | ||||
|              | ||||
|         } else m_frame->Show( true ); | ||||
|          | ||||
|         return true; | ||||
|     } | ||||
|  | @ -144,7 +327,8 @@ public: | |||
| 
 | ||||
| wxIMPLEMENT_APP(App); | ||||
| 
 | ||||
| MyFrame::MyFrame(const wxString &title, const wxPoint &pos, const wxSize &size): | ||||
| MyFrame::MyFrame(const wxString &title, const wxPoint &pos, const wxSize &size,  | ||||
|                  const Slic3r::GL::CSGSettings &settings): | ||||
|     wxFrame(nullptr, wxID_ANY, title, pos, size) | ||||
| { | ||||
|     wxMenu *menuFile = new wxMenu; | ||||
|  | @ -169,7 +353,7 @@ MyFrame::MyFrame(const wxString &title, const wxPoint &pos, const wxSize &size): | |||
|      // glReadPixels would not return the alpha channel on NVIDIA if
 | ||||
|      // not requested when the GL context is created.
 | ||||
|      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>(); | ||||
|  | @ -178,9 +362,13 @@ MyFrame::MyFrame(const wxString &title, const wxPoint &pos, const wxSize &size): | |||
|     m_canvas = std::make_shared<Canvas>(this, wxID_ANY, attribList, | ||||
|                                         wxDefaultPosition, wxDefaultSize, | ||||
|                                         wxWANTS_CHARS | wxFULL_REPAINT_ON_RESIZE); | ||||
|     m_ctl->add_display(m_canvas); | ||||
|      | ||||
|     m_canvas->get_ocsg_display()->apply_csgsettings(settings); | ||||
|      | ||||
|     m_ctl->add_display(m_canvas->get_display()); | ||||
| 
 | ||||
|     wxPanel *control_panel = new wxPanel(this); | ||||
| 
 | ||||
|     auto controlsizer = new wxBoxSizer(wxHORIZONTAL); | ||||
|     auto slider_sizer = new wxBoxSizer(wxVERTICAL); | ||||
|     auto console_sizer = new wxBoxSizer(wxVERTICAL); | ||||
|  | @ -198,7 +386,7 @@ MyFrame::MyFrame(const wxString &title, const wxPoint &pos, const wxSize &size): | |||
|     console_sizer->Add(csg_toggle, 0, wxALL | wxEXPAND, 5); | ||||
|      | ||||
|     auto add_combobox = [control_panel, console_sizer] | ||||
|             (const wxString &label, std::vector<wxString> &&list) | ||||
|             (const wxString &label, const std::vector<wxString> &list) | ||||
|     { | ||||
|         auto widget = new wxComboBox(control_panel, wxID_ANY, list[0], | ||||
|                 wxDefaultPosition, wxDefaultSize, | ||||
|  | @ -231,11 +419,21 @@ MyFrame::MyFrame(const wxString &title, const wxPoint &pos, const wxSize &size): | |||
|      | ||||
|     auto convexity_spin = add_spinctl("Convexity", CSGSettings::DEFAULT_CONVEXITY, 0, 100); | ||||
|      | ||||
|     auto alg_select = add_combobox("Algorithm", {"Auto", "Goldfeather", "SCS"}); | ||||
|     auto depth_select = add_combobox("Depth Complexity", {"Off", "OcclusionQuery", "On"}); | ||||
|     auto optimization_select = add_combobox("Optimization", { "Default", "ForceOn", "On", "Off" }); | ||||
|     auto alg_select = add_combobox("Algorithm", CSG_ALGS); | ||||
|     auto depth_select = add_combobox("Depth Complexity", CSG_DEPTH); | ||||
|     auto optimization_select = add_combobox("Optimization", CSG_OPT); | ||||
|     depth_select->Disable(); | ||||
|      | ||||
|     auto fpstext = new wxStaticText(control_panel, wxID_ANY, ""); | ||||
|     console_sizer->Add(fpstext, 0, wxALL, 5); | ||||
|     m_canvas->get_ocsg_display()->get_fps_counter().add_listener([this, fpstext](double fps) { | ||||
|         fpstext->SetLabel(wxString::Format("fps: %.2f", fps) ); | ||||
|         m_fps_avg = 0.9 * m_fps_avg + 0.1 * fps; | ||||
|     }); | ||||
|      | ||||
|     auto record_btn = new wxToggleButton(control_panel, wxID_ANY, "Record"); | ||||
|     console_sizer->Add(record_btn, 0, wxALL | wxEXPAND, 5); | ||||
|      | ||||
|     controlsizer->Add(slider_sizer, 0, wxEXPAND); | ||||
|     controlsizer->Add(console_sizer, 1, wxEXPAND); | ||||
|      | ||||
|  | @ -246,9 +444,33 @@ MyFrame::MyFrame(const wxString &title, const wxPoint &pos, const wxSize &size): | |||
|     sizer->Add(control_panel, 0, wxEXPAND); | ||||
|     SetSizer(sizer); | ||||
|      | ||||
|     Bind(wxEVT_MENU, &MyFrame::OnOpen, this, wxID_OPEN); | ||||
|     Bind(wxEVT_MENU, &MyFrame::OnExit, this, wxID_EXIT); | ||||
|     Bind(wxEVT_SHOW, &MyFrame::OnShown, this, GetId()); | ||||
|     if (settings.get_algo() > 0) depth_select->Enable(true); | ||||
|     alg_select->SetSelection(settings.get_algo()); | ||||
|     depth_select->SetSelection(settings.get_depth_algo()); | ||||
|     optimization_select->SetSelection(settings.get_optimization()); | ||||
|     convexity_spin->SetValue(int(settings.get_convexity())); | ||||
|     csg_toggle->SetValue(settings.is_enabled()); | ||||
|      | ||||
|     Bind(wxEVT_CLOSE_WINDOW, [this](wxCloseEvent &){ | ||||
|         RemoveChild(m_canvas.get()); | ||||
|         m_canvas.reset(); | ||||
|         Destroy(); | ||||
|     });     | ||||
|      | ||||
|     Bind(wxEVT_MENU, [this](wxCommandEvent &) { | ||||
|         wxFileDialog dlg(this, "Select project file",  wxEmptyString, | ||||
|                          wxEmptyString, "*.3mf", wxFD_OPEN|wxFD_FILE_MUST_EXIST); | ||||
| 
 | ||||
|         if (dlg.ShowModal() == wxID_OK) load_model(dlg.GetPath().ToStdString()); | ||||
|     }, wxID_OPEN); | ||||
|      | ||||
|     Bind(wxEVT_MENU, [this](wxCommandEvent &) { Close(true); }, wxID_EXIT); | ||||
|      | ||||
|     Bind(wxEVT_SHOW, [this, ms_toggle](wxShowEvent &) { | ||||
|         const wxSize ClientSize = GetClientSize(); | ||||
|         m_canvas->get_display()->set_active(ClientSize.x, ClientSize.y); | ||||
|         enable_multisampling(ms_toggle->GetValue()); | ||||
|     }); | ||||
|      | ||||
|     Bind(wxEVT_SLIDER, [this, slider](wxCommandEvent &) { | ||||
|         m_ctl->move_clip_plane(double(slider->GetValue())); | ||||
|  | @ -256,13 +478,13 @@ MyFrame::MyFrame(const wxString &title, const wxPoint &pos, const wxSize &size): | |||
|      | ||||
|     ms_toggle->Bind(wxEVT_TOGGLEBUTTON, [this, ms_toggle](wxCommandEvent &){ | ||||
|         enable_multisampling(ms_toggle->GetValue()); | ||||
|         m_canvas->repaint(); | ||||
|         m_canvas->get_display()->repaint(); | ||||
|     }); | ||||
|      | ||||
|     csg_toggle->Bind(wxEVT_TOGGLEBUTTON, [this, csg_toggle](wxCommandEvent &){ | ||||
|         CSGSettings settings = m_canvas->get_csgsettings(); | ||||
|         CSGSettings settings = m_canvas->get_ocsg_display()->get_csgsettings(); | ||||
|         settings.enable_csg(csg_toggle->GetValue()); | ||||
|         m_canvas->apply_csgsettings(settings); | ||||
|         m_canvas->get_ocsg_display()->apply_csgsettings(settings); | ||||
|     }); | ||||
|      | ||||
|     alg_select->Bind(wxEVT_COMBOBOX, | ||||
|  | @ -270,89 +492,110 @@ MyFrame::MyFrame(const wxString &title, const wxPoint &pos, const wxSize &size): | |||
|     { | ||||
|         int sel = alg_select->GetSelection(); | ||||
|         depth_select->Enable(sel > 0); | ||||
|         CSGSettings settings = m_canvas->get_csgsettings(); | ||||
|         CSGSettings settings = m_canvas->get_ocsg_display()->get_csgsettings(); | ||||
|         settings.set_algo(OpenCSG::Algorithm(sel)); | ||||
|         m_canvas->apply_csgsettings(settings); | ||||
|         m_canvas->get_ocsg_display()->apply_csgsettings(settings); | ||||
|     }); | ||||
|      | ||||
|     depth_select->Bind(wxEVT_COMBOBOX, [this, depth_select](wxCommandEvent &) { | ||||
|         int sel = depth_select->GetSelection(); | ||||
|         CSGSettings settings = m_canvas->get_csgsettings(); | ||||
|         CSGSettings settings = m_canvas->get_ocsg_display()->get_csgsettings(); | ||||
|         settings.set_depth_algo(OpenCSG::DepthComplexityAlgorithm(sel)); | ||||
|         m_canvas->apply_csgsettings(settings); | ||||
|         m_canvas->get_ocsg_display()->apply_csgsettings(settings); | ||||
|     }); | ||||
|      | ||||
|     optimization_select->Bind(wxEVT_COMBOBOX, | ||||
|                               [this, optimization_select](wxCommandEvent &) { | ||||
|         int sel = optimization_select->GetSelection(); | ||||
|         CSGSettings settings = m_canvas->get_csgsettings(); | ||||
|         CSGSettings settings = m_canvas->get_ocsg_display()->get_csgsettings(); | ||||
|         settings.set_optimization(OpenCSG::Optimization(sel)); | ||||
|         m_canvas->apply_csgsettings(settings); | ||||
|         m_canvas->get_ocsg_display()->apply_csgsettings(settings); | ||||
|     }); | ||||
|      | ||||
|     convexity_spin->Bind(wxEVT_SPINCTRL, [this, convexity_spin](wxSpinEvent &) { | ||||
|         CSGSettings settings = m_canvas->get_csgsettings(); | ||||
|         CSGSettings settings = m_canvas->get_ocsg_display()->get_csgsettings(); | ||||
|         int c = convexity_spin->GetValue(); | ||||
|          | ||||
|         if (c > 0) { | ||||
|             settings.set_convexity(unsigned(c)); | ||||
|             m_canvas->apply_csgsettings(settings); | ||||
|             m_canvas->get_ocsg_display()->apply_csgsettings(settings); | ||||
|         } | ||||
|     }); | ||||
|      | ||||
|     bind_canvas_events_to_controller(); | ||||
|     record_btn->Bind(wxEVT_TOGGLEBUTTON, [this, record_btn](wxCommandEvent &) { | ||||
|         if (!m_ui_job) { | ||||
|             m_stbar->set_status_text("No project loaded!"); | ||||
|             return; | ||||
|         } | ||||
|          | ||||
|         if (record_btn->GetValue()) { | ||||
|             if (auto c = m_canvas->get_display()->camera()) reset(*c); | ||||
|             m_ctl->on_scene_updated(*m_scene); | ||||
|             m_mouse.record(true); | ||||
|         } else { | ||||
|             m_mouse.record(false); | ||||
|             wxFileDialog dlg(this, "Select output file", | ||||
|                              wxEmptyString, wxEmptyString, "*.events", | ||||
|                              wxFD_SAVE|wxFD_OVERWRITE_PROMPT); | ||||
|              | ||||
|             if (dlg.ShowModal() == wxID_OK) { | ||||
|                 std::fstream stream(dlg.GetPath().ToStdString(), | ||||
|                                     std::fstream::out); | ||||
|                  | ||||
|                 if (stream.good()) { | ||||
|                     stream << m_ui_job->get_project_fname() << "\n"; | ||||
|                     wxSize winsize = GetSize(); | ||||
|                     stream << winsize.x << " " << winsize.y << "\n"; | ||||
|                     m_mouse.save(stream); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     }); | ||||
|      | ||||
|     // Do the repaint continuously
 | ||||
|     m_canvas->Bind(wxEVT_IDLE, [this](wxIdleEvent &evt) { | ||||
|         if (m_canvas->IsShown()) m_canvas->get_display()->repaint(); | ||||
|         evt.RequestMore(); | ||||
|     }); | ||||
|      | ||||
|     bind_canvas_events(m_mouse); | ||||
| } | ||||
| 
 | ||||
| void MyFrame::bind_canvas_events_to_controller() | ||||
| void MyFrame::bind_canvas_events(MouseInput &ms) | ||||
| { | ||||
|     m_canvas->Bind(wxEVT_MOUSEWHEEL, [this](wxMouseEvent &evt) { | ||||
|         m_ctl->on_scroll(evt.GetWheelRotation(), evt.GetWheelDelta(), | ||||
|     m_canvas->Bind(wxEVT_MOUSEWHEEL, [&ms](wxMouseEvent &evt) { | ||||
|         ms.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_MOTION, [&ms](wxMouseEvent &evt) { | ||||
|         ms.move_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_DOWN, [&ms](wxMouseEvent & /*evt*/) { | ||||
|         ms.right_click_down(); | ||||
|     }); | ||||
| 
 | ||||
|     m_canvas->Bind(wxEVT_RIGHT_UP, [this](wxMouseEvent & /*evt*/) { | ||||
|         m_ctl->on_right_click_up(); | ||||
|     m_canvas->Bind(wxEVT_RIGHT_UP, [&ms](wxMouseEvent & /*evt*/) { | ||||
|         ms.right_click_up(); | ||||
|     }); | ||||
| 
 | ||||
|     m_canvas->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent & /*evt*/) { | ||||
|         m_ctl->on_left_click_down(); | ||||
|     m_canvas->Bind(wxEVT_LEFT_DOWN, [&ms](wxMouseEvent & /*evt*/) { | ||||
|         ms.left_click_down(); | ||||
|     }); | ||||
| 
 | ||||
|     m_canvas->Bind(wxEVT_LEFT_UP, [this](wxMouseEvent & /*evt*/) { | ||||
|         m_ctl->on_left_click_up(); | ||||
|     m_canvas->Bind(wxEVT_LEFT_UP, [&ms](wxMouseEvent & /*evt*/) { | ||||
|         ms.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(); | ||||
|     }); | ||||
|     ms.add_listener(m_ctl); | ||||
| } | ||||
| 
 | ||||
| void MyFrame::SLAJob::process()  | ||||
| { | ||||
|     using Status = Slic3r::PrintBase::SlicingStatus; | ||||
|     using SlStatus = Slic3r::PrintBase::SlicingStatus; | ||||
|      | ||||
|     Slic3r::DynamicPrintConfig cfg; | ||||
|     auto model = Slic3r::Model::read_from_file(m_fname, &cfg); | ||||
|  | @ -364,9 +607,15 @@ void MyFrame::SLAJob::process() | |||
|     params.to_object_step = Slic3r::slaposHollowing; | ||||
|     m_print->set_task(params); | ||||
|      | ||||
|     m_print->set_status_callback([this](const Status &status) { | ||||
|     m_print->set_status_callback([this](const SlStatus &status) { | ||||
|         update_status(status.percent, status.text); | ||||
|     }); | ||||
|      | ||||
|     try { | ||||
|         m_print->process(); | ||||
|     } catch(std::exception &e) { | ||||
|         update_status(0, wxString("Exception during processing: ") + e.what()); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| //int main() {}
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 tamasmeszaros
						tamasmeszaros