From 17de6ff51a7a1cab9cb90ec877f57ea44729fe80 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Tue, 17 Dec 2019 16:26:06 +0100 Subject: [PATCH 01/10] Fix linking of OpenVDB in debug mode on multi conf generators. --- cmake/modules/FindOpenVDB.cmake | 50 +++++++++++++++++++++++++++------ deps/CMakeLists.txt | 1 + 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/cmake/modules/FindOpenVDB.cmake b/cmake/modules/FindOpenVDB.cmake index 3400fa786..e000b05dd 100644 --- a/cmake/modules/FindOpenVDB.cmake +++ b/cmake/modules/FindOpenVDB.cmake @@ -215,20 +215,44 @@ 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} ) - list(APPEND OpenVDB_LIB_COMPONENTS ${OpenVDB_${COMPONENT}_LIBRARY}) - if(OpenVDB_${COMPONENT}_LIBRARY) - set(OpenVDB_${COMPONENT}_FOUND TRUE) - else() - set(OpenVDB_${COMPONENT}_FOUND FALSE) - endif() + 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}) + + if(OpenVDB_${COMPONENT}_LIBRARY_RELEASE AND ${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}}) + + list(APPEND OpenVDB_LIB_COMPONENTS ${OpenVDB_${COMPONENT}_LIBRARY}) + + if(OpenVDB_${COMPONENT}_LIBRARY) + set(OpenVDB_${COMPONENT}_FOUND TRUE) + else() + set(OpenVDB_${COMPONENT}_FOUND FALSE) + endif() + endif () endforeach() if(UNIX AND OPENVDB_USE_STATIC_LIBS) @@ -487,7 +511,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 +518,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" diff --git a/deps/CMakeLists.txt b/deps/CMakeLists.txt index 5e6d28b58..3e6f70e42 100644 --- a/deps/CMakeLists.txt +++ b/deps/CMakeLists.txt @@ -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}) From 558529146cae7b031bedb97cc389fdab8b9cef3d Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Tue, 17 Dec 2019 16:27:28 +0100 Subject: [PATCH 02/10] Fix opencsg example on Win32 --- sandboxes/opencsg/CMakeLists.txt | 12 ++++++++--- sandboxes/opencsg/GLScene.cpp | 35 ++++++++++++++++---------------- sandboxes/opencsg/GLScene.hpp | 3 +++ sandboxes/opencsg/main.cpp | 34 +++++++++++++++++++------------ 4 files changed, 51 insertions(+), 33 deletions(-) diff --git a/sandboxes/opencsg/CMakeLists.txt b/sandboxes/opencsg/CMakeLists.txt index 651fbe82f..cf66867a5 100644 --- a/sandboxes/opencsg/CMakeLists.txt +++ b/sandboxes/opencsg/CMakeLists.txt @@ -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 GLScene.hpp GLScene.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,17 @@ 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) +# 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 + ) diff --git a/sandboxes/opencsg/GLScene.cpp b/sandboxes/opencsg/GLScene.cpp index 1cfccb3b1..2c3d1ffcd 100644 --- a/sandboxes/opencsg/GLScene.cpp +++ b/sandboxes/opencsg/GLScene.cpp @@ -5,11 +5,11 @@ #include -#ifdef __APPLE__ -#include -#else -#include -#endif +//#ifdef __APPLE__ +//#include +//#else +//#include +//#endif #include @@ -63,7 +63,7 @@ void renderfps () { static int msec = 0; last = msec; - msec = glutGet(GLUT_ELAPSED_TIME); +// msec = glutGet(GLUT_ELAPSED_TIME); if (last / 1000 != msec / 1000) { float correctedFps = fps * 1000.0f / float(msec - ancient); @@ -82,9 +82,9 @@ void renderfps () { glRasterPos2f(-1.0f, -1.0f); glDisable(GL_LIGHTING); std::string s = fpsStream.str(); - for (unsigned int i=0; iset_screen(width, height); + set_screen_size(width, height); } void Display::set_screen_size(long width, long height) @@ -389,8 +392,6 @@ void Display::set_screen_size(long width, long height) m_camera->set_screen(width, height); m_size = {width, height}; - - repaint(); } void Display::repaint() diff --git a/sandboxes/opencsg/GLScene.hpp b/sandboxes/opencsg/GLScene.hpp index 68cc59b01..62863dc0b 100644 --- a/sandboxes/opencsg/GLScene.hpp +++ b/sandboxes/opencsg/GLScene.hpp @@ -303,6 +303,8 @@ public: : m_camera(camera ? camera : std::make_shared()) {} + ~Display() override; + Camera * camera() { return m_camera.get(); } virtual void swap_buffers() = 0; @@ -370,5 +372,6 @@ public: 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 c2f8a74aa..3f764fe62 100644 --- a/sandboxes/opencsg/main.cpp +++ b/sandboxes/opencsg/main.cpp @@ -8,7 +8,7 @@ // For compilers that support precompilation, includes "wx/wx.h". #include #ifndef WX_PRECOMP - #include +#include #endif #include @@ -31,7 +31,7 @@ using namespace Slic3r::GL; class Canvas: public wxGLCanvas, public Slic3r::GL::Display { - std::unique_ptr m_context; + shptr m_context; public: void set_active(long w, long h) override @@ -54,6 +54,12 @@ public: m_context.reset(ctx); } + + ~Canvas() override + { + m_scene_cache.clear(); + m_context.reset(); + } }; class MyFrame: public wxFrame @@ -95,11 +101,11 @@ private: void bind_canvas_events_to_controller(); - void OnExit(wxCommandEvent& /*event*/) + void OnClose(wxCloseEvent& /*event*/) { RemoveChild(m_canvas.get()); - m_canvas->Destroy(); - Close( true ); + m_canvas.reset(); + Destroy(); } void OnOpen(wxCommandEvent &/*evt*/) @@ -117,10 +123,7 @@ private: void OnShown(wxShowEvent&) { const wxSize ClientSize = GetClientSize(); - m_canvas->set_active(ClientSize.x, ClientSize.y); - - m_canvas->set_screen_size(ClientSize.x, ClientSize.y); - m_canvas->repaint(); + m_canvas->set_active(ClientSize.x, ClientSize.y); // Do the repaint continuously Bind(wxEVT_IDLE, [this](wxIdleEvent &evt) { @@ -179,8 +182,9 @@ MyFrame::MyFrame(const wxString &title, const wxPoint &pos, const wxSize &size): 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); auto slider_sizer = new wxBoxSizer(wxVERTICAL); auto console_sizer = new wxBoxSizer(wxVERTICAL); @@ -247,7 +251,9 @@ MyFrame::MyFrame(const wxString &title, const wxPoint &pos, const wxSize &size): SetSizer(sizer); Bind(wxEVT_MENU, &MyFrame::OnOpen, this, wxID_OPEN); - Bind(wxEVT_MENU, &MyFrame::OnExit, this, wxID_EXIT); + Bind(wxEVT_CLOSE_WINDOW, &MyFrame::OnClose, this); + Bind(wxEVT_MENU, [this](wxCommandEvent &) { Close(true); }, wxID_EXIT); + Bind(wxEVT_SHOW, &MyFrame::OnShown, this, GetId()); Bind(wxEVT_SLIDER, [this, slider](wxCommandEvent &) { @@ -334,7 +340,7 @@ void MyFrame::bind_canvas_events_to_controller() m_canvas->Bind(wxEVT_PAINT, [this](wxPaintEvent &) { // This is required even though dc is not used otherwise. - wxPaintDC dc(this); + wxPaintDC dc(m_canvas.get()); // Set the OpenGL viewport according to the client size of this // canvas. This is done here rather than in a wxSizeEvent handler @@ -347,7 +353,7 @@ void MyFrame::bind_canvas_events_to_controller() m_canvas->set_screen_size(ClientSize.x, ClientSize.y); m_canvas->repaint(); - }); + }, m_canvas->GetId()); } void MyFrame::SLAJob::process() @@ -370,3 +376,5 @@ void MyFrame::SLAJob::process() m_print->process(); } + +//int main() {} From 4e27faa236ae3ac8eeb603e638ae3db5f6ee027f Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Tue, 17 Dec 2019 16:53:45 +0100 Subject: [PATCH 03/10] Only consider openvdb debug if necessary. Add REQUIRED to openvdb --- CMakeLists.txt | 3 +-- cmake/modules/FindOpenVDB.cmake | 4 +++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f489e46c4..26619e459 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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() diff --git a/cmake/modules/FindOpenVDB.cmake b/cmake/modules/FindOpenVDB.cmake index e000b05dd..84b5f4116 100644 --- a/cmake/modules/FindOpenVDB.cmake +++ b/cmake/modules/FindOpenVDB.cmake @@ -235,7 +235,9 @@ foreach(COMPONENT ${OpenVDB_FIND_COMPONENTS}) if (_is_multi) list(APPEND OpenVDB_LIB_COMPONENTS ${OpenVDB_${COMPONENT}_LIBRARY_RELEASE} ${OpenVDB_${COMPONENT}_LIBRARY_DEBUG}) - if(OpenVDB_${COMPONENT}_LIBRARY_RELEASE AND ${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) From e25cd1ce1a2051d5ec61568120beb5fc340eafb7 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Tue, 17 Dec 2019 17:08:43 +0100 Subject: [PATCH 04/10] Grab the release in debug mode if there is no debug when not on msvc --- cmake/modules/FindOpenVDB.cmake | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cmake/modules/FindOpenVDB.cmake b/cmake/modules/FindOpenVDB.cmake index 84b5f4116..7bc44bebb 100644 --- a/cmake/modules/FindOpenVDB.cmake +++ b/cmake/modules/FindOpenVDB.cmake @@ -247,6 +247,10 @@ foreach(COMPONENT ${OpenVDB_FIND_COMPONENTS}) 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) From acfaff3741380f81bd67f1cffb2e307f5f1c5802 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Tue, 17 Dec 2019 18:39:01 +0100 Subject: [PATCH 05/10] Dont use glut for fps measure. --- sandboxes/opencsg/CMakeLists.txt | 3 +- sandboxes/opencsg/GLScene.cpp | 58 ++++++++++++++++++++------------ 2 files changed, 38 insertions(+), 23 deletions(-) diff --git a/sandboxes/opencsg/CMakeLists.txt b/sandboxes/opencsg/CMakeLists.txt index cf66867a5..145912431 100644 --- a/sandboxes/opencsg/CMakeLists.txt +++ b/sandboxes/opencsg/CMakeLists.txt @@ -11,7 +11,7 @@ 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) + find_package(GLUT REQUIRED) include(${wxWidgets_USE_FILE}) @@ -22,6 +22,7 @@ target_compile_definitions(opencsg_example PRIVATE ${wxWidgets_DEFINITIONS}) target_link_libraries(opencsg_example ${wxWidgets_LIBRARIES} OpenCSG::opencsg GLEW::GLEW + GLUT::GLUT OpenGL::GL #-lXrandr -lXext -lX11 ) diff --git a/sandboxes/opencsg/GLScene.cpp b/sandboxes/opencsg/GLScene.cpp index 2c3d1ffcd..9df3b601e 100644 --- a/sandboxes/opencsg/GLScene.cpp +++ b/sandboxes/opencsg/GLScene.cpp @@ -1,3 +1,5 @@ +#include + #include "GLScene.hpp" #include #include @@ -5,11 +7,11 @@ #include -//#ifdef __APPLE__ -//#include -//#else -//#include -//#endif +#ifdef __APPLE__ +#include +#else +#include +#endif #include @@ -56,23 +58,36 @@ 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; + using Clock = std::chrono::high_resolution_clock; + using Duration = Clock::duration; + using TimePoint = Clock::time_point; - last = msec; -// msec = glutGet(GLUT_ELAPSED_TIME); - if (last / 1000 != msec / 1000) { + static std::ostringstream fpsStream; + static int frames = 0; + static TimePoint last = Clock::now(); + + static const double resolution = 0.01; + static double fps = 0.; + + auto to_sec = [](Duration d) -> double { + return d.count() * double(Duration::period::num) / Duration::period::den; + }; + + ++frames; + + TimePoint msec = Clock::now(); + double seconds = to_sec(msec - last); + if (seconds >= resolution) { + last = msec; + + fps = 0.5 * (fps + frames / seconds); - float correctedFps = fps * 1000.0f / float(msec - ancient); fpsStream.str(""); - fpsStream << "fps: " << correctedFps << std::ends; + fpsStream << "fps: " << std::setprecision(4) << fps << std::ends; - ancient = msec; - fps = 0; + frames = 0; } + glDisable(GL_DEPTH_TEST); glLoadIdentity(); glMatrixMode(GL_PROJECTION); @@ -82,15 +97,14 @@ void renderfps () { glRasterPos2f(-1.0f, -1.0f); glDisable(GL_LIGHTING); std::string s = fpsStream.str(); -// for (unsigned int i=0; i Date: Wed, 18 Dec 2019 12:00:28 +0100 Subject: [PATCH 06/10] Separate fps counter and remove glut dependency --- sandboxes/opencsg/CMakeLists.txt | 3 -- sandboxes/opencsg/GLScene.cpp | 68 ++------------------------------ sandboxes/opencsg/GLScene.hpp | 64 ++++++++++++++++++++++++++++++ sandboxes/opencsg/main.cpp | 6 +++ 4 files changed, 73 insertions(+), 68 deletions(-) diff --git a/sandboxes/opencsg/CMakeLists.txt b/sandboxes/opencsg/CMakeLists.txt index 145912431..a6256250d 100644 --- a/sandboxes/opencsg/CMakeLists.txt +++ b/sandboxes/opencsg/CMakeLists.txt @@ -11,10 +11,8 @@ 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}) @@ -22,7 +20,6 @@ target_compile_definitions(opencsg_example PRIVATE ${wxWidgets_DEFINITIONS}) target_link_libraries(opencsg_example ${wxWidgets_LIBRARIES} OpenCSG::opencsg GLEW::GLEW - GLUT::GLUT OpenGL::GL #-lXrandr -lXext -lX11 ) diff --git a/sandboxes/opencsg/GLScene.cpp b/sandboxes/opencsg/GLScene.cpp index 9df3b601e..5744e8be7 100644 --- a/sandboxes/opencsg/GLScene.cpp +++ b/sandboxes/opencsg/GLScene.cpp @@ -1,5 +1,3 @@ -#include - #include "GLScene.hpp" #include #include @@ -7,12 +5,6 @@ #include -#ifdef __APPLE__ -#include -#else -#include -#endif - #include #ifndef NDEBUG @@ -54,60 +46,8 @@ inline void glAssertRecentCall() { } namespace Slic3r { namespace GL { Scene::Scene() = default; - Scene::~Scene() = default; -void renderfps () { - using Clock = std::chrono::high_resolution_clock; - using Duration = Clock::duration; - using TimePoint = Clock::time_point; - - static std::ostringstream fpsStream; - static int frames = 0; - static TimePoint last = Clock::now(); - - static const double resolution = 0.01; - static double fps = 0.; - - auto to_sec = [](Duration d) -> double { - return d.count() * double(Duration::period::num) / Duration::period::den; - }; - - ++frames; - - TimePoint msec = Clock::now(); - double seconds = to_sec(msec - last); - if (seconds >= resolution) { - last = msec; - - fps = 0.5 * (fps + frames / seconds); - - fpsStream.str(""); - fpsStream << "fps: " << std::setprecision(4) << fps << std::ends; - - frames = 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; iview(); render_scene(); - renderfps(); +// renderfps(); + m_fps_counter.update(); swap_buffers(); } diff --git a/sandboxes/opencsg/GLScene.hpp b/sandboxes/opencsg/GLScene.hpp index 62863dc0b..4fd524af2 100644 --- a/sandboxes/opencsg/GLScene.hpp +++ b/sandboxes/opencsg/GLScene.hpp @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -211,6 +212,60 @@ public: void set_clip_z(double z) { m_clip_z = z; } }; +class FpsCounter { + vector> 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() + { + ++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; + } + } + + void add_listener(std::function 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 PerspectiveCamera: public Camera { public: @@ -296,6 +351,7 @@ protected: } m_scene_cache; shptr m_camera; + FpsCounter m_fps_counter; public: @@ -323,6 +379,14 @@ public: virtual void clear_screen(); virtual void render_scene(); + + template 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 Controller : public std::enable_shared_from_this, diff --git a/sandboxes/opencsg/main.cpp b/sandboxes/opencsg/main.cpp index 3f764fe62..28aa89f6d 100644 --- a/sandboxes/opencsg/main.cpp +++ b/sandboxes/opencsg/main.cpp @@ -240,6 +240,12 @@ MyFrame::MyFrame(const wxString &title, const wxPoint &pos, const wxSize &size): auto optimization_select = add_combobox("Optimization", { "Default", "ForceOn", "On", "Off" }); depth_select->Disable(); + auto fpstext = new wxStaticText(control_panel, wxID_ANY, ""); + console_sizer->Add(fpstext, 0, wxALL, 5); + m_canvas->get_fps_counter().add_listener([fpstext](double fps) { + fpstext->SetLabel(wxString::Format("fps: %.2f", fps) ); + }); + controlsizer->Add(slider_sizer, 0, wxEXPAND); controlsizer->Add(console_sizer, 1, wxEXPAND); From fafc2a35100ca4bb63b6f153da8d7c20bac58625 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Wed, 18 Dec 2019 16:24:41 +0100 Subject: [PATCH 07/10] Recording and playback works --- sandboxes/opencsg/GLScene.cpp | 21 ++- sandboxes/opencsg/GLScene.hpp | 45 ++---- sandboxes/opencsg/main.cpp | 287 ++++++++++++++++++++++++++-------- 3 files changed, 254 insertions(+), 99 deletions(-) diff --git a/sandboxes/opencsg/GLScene.cpp b/sandboxes/opencsg/GLScene.cpp index 5744e8be7..dcd121709 100644 --- a/sandboxes/opencsg/GLScene.cpp +++ b/sandboxes/opencsg/GLScene.cpp @@ -352,7 +352,6 @@ void Display::repaint() m_camera->view(); render_scene(); -// renderfps(); m_fps_counter.update(); swap_buffers(); @@ -508,4 +507,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 diff --git a/sandboxes/opencsg/GLScene.hpp b/sandboxes/opencsg/GLScene.hpp index 4fd524af2..d99652897 100644 --- a/sandboxes/opencsg/GLScene.hpp +++ b/sandboxes/opencsg/GLScene.hpp @@ -165,7 +165,6 @@ public: }; bool enable_multisampling(bool e = true); -void renderfps(); class Primitive : public OpenCSG::Primitive { @@ -190,8 +189,6 @@ public: } }; -class Scene; - class Camera { protected: Vec2f m_rot = {0., 0.}; @@ -212,6 +209,20 @@ 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> m_listeners; @@ -232,25 +243,7 @@ class FpsCounter { public: - void 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; - } - } + void update(); void add_listener(std::function lst) { @@ -266,12 +259,6 @@ public: double get_mesure_window_size() const { return m_window_size; } }; -class PerspectiveCamera: public Camera { -public: - - void set_screen(long width, long height) override; -}; - class CSGSettings { public: static const constexpr unsigned DEFAULT_CONVEXITY = 10; @@ -397,7 +384,7 @@ class Controller : public std::enable_shared_from_this, Vec2i m_mouse_pos, m_mouse_pos_rprev, m_mouse_pos_lprev; bool m_left_btn = false, m_right_btn = false; - shptr m_scene; + shptr m_scene; vector> m_displays; // Call a method of Camera on all the cameras of the attached displays diff --git a/sandboxes/opencsg/main.cpp b/sandboxes/opencsg/main.cpp index 28aa89f6d..8050ae792 100644 --- a/sandboxes/opencsg/main.cpp +++ b/sandboxes/opencsg/main.cpp @@ -53,6 +53,23 @@ public: } m_context.reset(ctx); + + 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(); + + set_screen_size(ClientSize.x, ClientSize.y); + repaint(); + }); } ~Canvas() override @@ -62,6 +79,93 @@ public: } }; +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 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 { shptr m_scene; // Model @@ -69,12 +173,14 @@ class MyFrame: public wxFrame shptr m_ctl; // Controller shptr m_stbar; - uqptr m_ui_job; + + RecorderMouseInput m_mouse; class SLAJob: public Slic3r::GUI::Job { MyFrame *m_parent; std::unique_ptr m_print; std::string m_fname; + public: SLAJob(MyFrame *frame, const std::string &fname) : Slic3r::GUI::Job{frame->m_stbar} @@ -84,8 +190,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)); @@ -94,52 +201,53 @@ class MyFrame: public wxFrame } }; + uqptr m_ui_job; + public: MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size); -private: - - void bind_canvas_events_to_controller(); - - void OnClose(wxCloseEvent& /*event*/) - { - RemoveChild(m_canvas.get()); - m_canvas.reset(); - Destroy(); + void load_model(const std::string &fname) { + m_ui_job = std::make_unique(this, fname); + m_ui_job->start(); } - void OnOpen(wxCommandEvent &/*evt*/) + void play_back_mouse(const std::string &events_fname) { - wxFileDialog dlg(this, "Select project file", - wxEmptyString, wxEmptyString, "*.3mf"); - - if (dlg.ShowModal() == wxID_OK) - { - m_ui_job = std::make_unique(this, dlg.GetPath().ToStdString()); - m_ui_job->start(); + std::fstream stream(events_fname, std::fstream::in); + + if (stream.good()) { + std::string model_name; + std::getline(stream, model_name); + load_model(model_name); + m_mouse.load(stream); + m_mouse.play(); } } - void OnShown(wxShowEvent&) - { - const wxSize ClientSize = GetClientSize(); - m_canvas->set_active(ClientSize.x, ClientSize.y); - - // Do the repaint continuously - Bind(wxEVT_IDLE, [this](wxIdleEvent &evt) { - m_canvas->repaint(); - evt.RequestMore(); - }); - } + void bind_canvas_events(MouseInput &msinput); }; class App : public wxApp { MyFrame *m_frame; + public: bool OnInit() override { + + std::string fname; + std::string command; + + if (argc > 2) { + command = argv[1]; + fname = argv[2]; + } + m_frame = new MyFrame("PrusaSlicer OpenCSG Demo", wxDefaultPosition, wxSize(1024, 768)); - m_frame->Show( true ); + if (command == "play") { + m_frame->Show( true ); + m_frame->play_back_mouse(fname); + m_frame->Close( true ); + } else m_frame->Show( true ); return true; } @@ -246,6 +354,9 @@ MyFrame::MyFrame(const wxString &title, const wxPoint &pos, const wxSize &size): fpstext->SetLabel(wxString::Format("fps: %.2f", 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); @@ -256,11 +367,26 @@ 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_CLOSE_WINDOW, &MyFrame::OnClose, this); + 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, &MyFrame::OnShown, this, GetId()); + Bind(wxEVT_SHOW, [this, ms_toggle](wxShowEvent &) { + const wxSize ClientSize = GetClientSize(); + m_canvas->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())); @@ -312,54 +438,73 @@ MyFrame::MyFrame(const wxString &title, const wxPoint &pos, const wxSize &size): } }); - 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 (m_canvas->camera()) reset(*m_canvas->camera()); + 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"; + m_mouse.save(stream); + } + } + } + }); + + // Do the repaint continuously + m_canvas->Bind(wxEVT_IDLE, [this](wxIdleEvent &evt) { + if (m_canvas->IsShown()) m_canvas->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(), - evt.GetWheelAxis() == wxMOUSE_WHEEL_VERTICAL ? - Slic3r::GL::MouseInput::waVertical : - Slic3r::GL::MouseInput::waHorizontal); + 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(m_canvas.get()); - - // 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(); - }, m_canvas->GetId()); + + ms.add_listener(m_ctl); } void MyFrame::SLAJob::process() @@ -380,7 +525,11 @@ void MyFrame::SLAJob::process() update_status(status.percent, status.text); }); - m_print->process(); + try { + m_print->process(); + } catch(std::exception &e) { + update_status(0, wxString("Exception during processing: ") + e.what()); + } } //int main() {} From bf44da0e37a2ffafa8a2a40fac79e9820b6cdd18 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Thu, 19 Dec 2019 01:55:46 +0100 Subject: [PATCH 08/10] Make it work with mesa sw renderer --- sandboxes/opencsg/main.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sandboxes/opencsg/main.cpp b/sandboxes/opencsg/main.cpp index 8050ae792..c7be06855 100644 --- a/sandboxes/opencsg/main.cpp +++ b/sandboxes/opencsg/main.cpp @@ -2,6 +2,8 @@ #include #include +#include "GLScene.hpp" + #include #include @@ -18,8 +20,6 @@ #include #include -#include "GLScene.hpp" - #include "libslic3r/Model.hpp" #include "libslic3r/Format/3mf.hpp" #include "libslic3r/SLAPrint.hpp" @@ -68,7 +68,7 @@ public: const wxSize ClientSize = GetClientSize(); set_screen_size(ClientSize.x, ClientSize.y); - repaint(); +// repaint(); }); } @@ -280,7 +280,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(); m_ctl = std::make_shared(); @@ -509,7 +509,7 @@ void MyFrame::bind_canvas_events(MouseInput &ms) 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); @@ -521,7 +521,7 @@ 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); }); From 8126cdd50762c43b632c243e8a875c0c00c66aff Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Thu, 19 Dec 2019 14:51:38 +0100 Subject: [PATCH 09/10] Add command line options. Rename GLScene to Engine --- sandboxes/opencsg/CMakeLists.txt | 2 +- sandboxes/opencsg/{GLScene.cpp => Engine.cpp} | 20 +- sandboxes/opencsg/{GLScene.hpp => Engine.hpp} | 55 ++--- sandboxes/opencsg/main.cpp | 195 ++++++++++++------ 4 files changed, 175 insertions(+), 97 deletions(-) rename sandboxes/opencsg/{GLScene.cpp => Engine.cpp} (97%) rename sandboxes/opencsg/{GLScene.hpp => Engine.hpp} (98%) diff --git a/sandboxes/opencsg/CMakeLists.txt b/sandboxes/opencsg/CMakeLists.txt index a6256250d..600ef7884 100644 --- a/sandboxes/opencsg/CMakeLists.txt +++ b/sandboxes/opencsg/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.0) project(OpenCSG-example) -add_executable(opencsg_example WIN32 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) diff --git a/sandboxes/opencsg/GLScene.cpp b/sandboxes/opencsg/Engine.cpp similarity index 97% rename from sandboxes/opencsg/GLScene.cpp rename to sandboxes/opencsg/Engine.cpp index dcd121709..590faa296 100644 --- a/sandboxes/opencsg/GLScene.cpp +++ b/sandboxes/opencsg/Engine.cpp @@ -1,4 +1,4 @@ -#include "GLScene.hpp" +#include "Engine.hpp" #include #include #include @@ -48,7 +48,7 @@ namespace Slic3r { namespace GL { Scene::Scene() = default; Scene::~Scene() = default; -void Display::render_scene() +void CSGDisplay::render_scene() { GLfloat color[] = {1.f, 1.f, 0.f, 0.f}; glsafe(::glColor4fv(color)); @@ -95,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 Display::SceneCache::add_mesh(const TriangleMesh &mesh) +shptr CSGDisplay::SceneCache::add_mesh(const TriangleMesh &mesh) { auto p = std::make_shared(); p->load_mesh(mesh); @@ -111,9 +111,9 @@ shptr Display::SceneCache::add_mesh(const TriangleMesh &mesh) return p; } -shptr Display::SceneCache::add_mesh(const TriangleMesh &mesh, - OpenCSG::Operation o, - unsigned c) +shptr CSGDisplay::SceneCache::add_mesh(const TriangleMesh &mesh, + OpenCSG::Operation o, + unsigned c) { auto p = std::make_shared(o, c); p->load_mesh(mesh); @@ -388,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; @@ -404,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; diff --git a/sandboxes/opencsg/GLScene.hpp b/sandboxes/opencsg/Engine.hpp similarity index 98% rename from sandboxes/opencsg/GLScene.hpp rename to sandboxes/opencsg/Engine.hpp index d99652897..5e7030523 100644 --- a/sandboxes/opencsg/GLScene.hpp +++ b/sandboxes/opencsg/Engine.hpp @@ -1,5 +1,5 @@ -#ifndef GLSCENE_HPP -#define GLSCENE_HPP +#ifndef SLIC3R_OCSG_EXMP_ENGINE_HPP +#define SLIC3R_OCSG_EXMP_ENGINE_HPP_HPP #include #include @@ -322,21 +322,6 @@ protected: Vec2i m_size; bool m_initialized = false; - CSGSettings m_csgsettings; - - struct SceneCache { - vector> primitives; - vector primitives_free; - vector primitives_csg; - - void clear(); - - shptr add_mesh(const TriangleMesh &mesh); - shptr add_mesh(const TriangleMesh &mesh, - OpenCSG::Operation op, - unsigned covexity); - } m_scene_cache; - shptr m_camera; FpsCounter m_fps_counter; @@ -359,13 +344,8 @@ public: 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; - virtual void clear_screen(); - virtual void render_scene(); + virtual void render_scene() {} template void set_fps_counter(_FpsCounter &&fpsc) { @@ -376,6 +356,33 @@ public: FpsCounter &get_fps_counter() { return m_fps_counter; } }; +class CSGDisplay : public Display { +protected: + CSGSettings m_csgsettings; + + struct SceneCache { + vector> primitives; + vector primitives_free; + vector primitives_csg; + + void clear(); + + shptr add_mesh(const TriangleMesh &mesh); + shptr add_mesh(const TriangleMesh &mesh, + OpenCSG::Operation op, + unsigned covexity); + } m_scene_cache; + +public: + + const CSGSettings & get_csgsettings() const { return m_csgsettings; } + void apply_csgsettings(const CSGSettings &settings); + + void render_scene() override; + + void on_scene_updated(const Scene &scene) override; +}; + class Controller : public std::enable_shared_from_this, public MouseInput::Listener, public Scene::Listener @@ -425,4 +432,4 @@ public: }; }} // namespace Slic3r::GL -#endif // GLSCENE_HPP +#endif // SLIC3R_OCSG_EXMP_ENGINE_HPP diff --git a/sandboxes/opencsg/main.cpp b/sandboxes/opencsg/main.cpp index c7be06855..1352e1ba0 100644 --- a/sandboxes/opencsg/main.cpp +++ b/sandboxes/opencsg/main.cpp @@ -2,7 +2,7 @@ #include #include -#include "GLScene.hpp" +#include "Engine.hpp" #include @@ -19,6 +19,7 @@ #include #include #include +#include #include "libslic3r/Model.hpp" #include "libslic3r/Format/3mf.hpp" @@ -29,31 +30,47 @@ using namespace Slic3r::GL; -class Canvas: public wxGLCanvas, public Slic3r::GL::Display +class Canvas: public wxGLCanvas { - shptr m_context; + class OCSGRenderer: public Slic3r::GL::CSGDisplay { + Canvas *m_canvas; + shptr m_context; + public: + + 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); + return; + } + + 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 m_ocsgdisplay = std::make_shared(this); + + shptr m_display = m_ocsgdisplay; + 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 Canvas(Args &&...args): wxGLCanvas(std::forward(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_PAINT, [this](wxPaintEvent &) { // This is required even though dc is not used otherwise. wxPaintDC dc(this); @@ -67,16 +84,14 @@ public: // another canvas is repainted. const wxSize ClientSize = GetClientSize(); - set_screen_size(ClientSize.x, ClientSize.y); -// repaint(); + m_display->set_screen_size(ClientSize.x, ClientSize.y); }); } - - ~Canvas() override - { - m_scene_cache.clear(); - m_context.reset(); - } + + shptr get_display() const { return m_display; } + void set_display(shptr d) { m_display = d; } + + shptr get_ocsg_display() const { return m_ocsgdisplay; } }; enum EEvents { LCLK_U, RCLK_U, LCLK_D, RCLK_D, DDCLK, SCRL, MV }; @@ -204,7 +219,7 @@ class MyFrame: public wxFrame uqptr m_ui_job; 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); void load_model(const std::string &fname) { m_ui_job = std::make_unique(this, fname); @@ -224,29 +239,76 @@ public: } } + Canvas * canvas() { return m_canvas.get(); } + const Canvas * canvas() const { return m_canvas.get(); } + void bind_canvas_events(MouseInput &msinput); }; +static const std::vector CSG_ALGS = {"Auto", "Goldfeather", "SCS"}; +static const std::vector CSG_DEPTH = {"Off", "OcclusionQuery", "On"}; +static const std::vector CSG_OPT = { "Default", "ForceOn", "On", "Off" }; + class App : public wxApp { - MyFrame *m_frame; + MyFrame *m_frame = nullptr; public: bool OnInit() override { - std::string fname; - std::string command; + wxCmdLineParser parser(argc, argv); - if (argc > 2) { - command = argv[1]; - fname = argv[2]; - } - - m_frame = new MyFrame("PrusaSlicer OpenCSG Demo", wxDefaultPosition, wxSize(1024, 768)); + 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); - if (command == "play") { + 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 &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); + m_frame->play_back_mouse(fname.ToStdString()); m_frame->Close( true ); + } else m_frame->Show( true ); return true; @@ -255,7 +317,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; @@ -289,7 +352,10 @@ MyFrame::MyFrame(const wxString &title, const wxPoint &pos, const wxSize &size): m_canvas = std::make_shared(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); @@ -310,7 +376,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 &&list) + (const wxString &label, const std::vector &list) { auto widget = new wxComboBox(control_panel, wxID_ANY, list[0], wxDefaultPosition, wxDefaultSize, @@ -343,14 +409,14 @@ 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_fps_counter().add_listener([fpstext](double fps) { + m_canvas->get_ocsg_display()->get_fps_counter().add_listener([fpstext](double fps) { fpstext->SetLabel(wxString::Format("fps: %.2f", fps) ); }); @@ -367,6 +433,13 @@ MyFrame::MyFrame(const wxString &title, const wxPoint &pos, const wxSize &size): sizer->Add(control_panel, 0, wxEXPAND); SetSizer(sizer); + 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(); @@ -384,7 +457,7 @@ MyFrame::MyFrame(const wxString &title, const wxPoint &pos, const wxSize &size): Bind(wxEVT_SHOW, [this, ms_toggle](wxShowEvent &) { const wxSize ClientSize = GetClientSize(); - m_canvas->set_active(ClientSize.x, ClientSize.y); + m_canvas->get_display()->set_active(ClientSize.x, ClientSize.y); enable_multisampling(ms_toggle->GetValue()); }); @@ -394,13 +467,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, @@ -408,33 +481,33 @@ 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); } }); @@ -445,7 +518,7 @@ MyFrame::MyFrame(const wxString &title, const wxPoint &pos, const wxSize &size): } if (record_btn->GetValue()) { - if (m_canvas->camera()) reset(*m_canvas->camera()); + if (auto c = m_canvas->get_display()->camera()) reset(*c); m_ctl->on_scene_updated(*m_scene); m_mouse.record(true); } else { @@ -468,7 +541,7 @@ MyFrame::MyFrame(const wxString &title, const wxPoint &pos, const wxSize &size): // Do the repaint continuously m_canvas->Bind(wxEVT_IDLE, [this](wxIdleEvent &evt) { - if (m_canvas->IsShown()) m_canvas->repaint(); + if (m_canvas->IsShown()) m_canvas->get_display()->repaint(); evt.RequestMore(); }); From bb8a6b898f9a3f1becc3e6b9e841dfd6f0653a01 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Thu, 19 Dec 2019 15:26:04 +0100 Subject: [PATCH 10/10] Save and load window size. Add fps average output. --- sandboxes/opencsg/main.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/sandboxes/opencsg/main.cpp b/sandboxes/opencsg/main.cpp index 1352e1ba0..95e00b366 100644 --- a/sandboxes/opencsg/main.cpp +++ b/sandboxes/opencsg/main.cpp @@ -218,6 +218,8 @@ class MyFrame: public wxFrame uqptr m_ui_job; + double m_fps_avg = 0.; + public: MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size, const Slic3r::GL::CSGSettings &settings); @@ -234,6 +236,11 @@ public: std::string model_name; std::getline(stream, model_name); load_model(model_name); + + int w, h; + stream >> w >> h; + SetSize(w, h); + m_mouse.load(stream); m_mouse.play(); } @@ -243,6 +250,8 @@ public: 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 CSG_ALGS = {"Auto", "Goldfeather", "SCS"}; @@ -308,6 +317,7 @@ public: 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 ); @@ -416,8 +426,9 @@ MyFrame::MyFrame(const wxString &title, const wxPoint &pos, const wxSize &size, 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([fpstext](double fps) { - fpstext->SetLabel(wxString::Format("fps: %.2f", fps) ); + 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"); @@ -533,6 +544,8 @@ MyFrame::MyFrame(const wxString &title, const wxPoint &pos, const wxSize &size, if (stream.good()) { stream << m_ui_job->get_project_fname() << "\n"; + wxSize winsize = GetSize(); + stream << winsize.x << " " << winsize.y << "\n"; m_mouse.save(stream); } }