From 8f03c8de4e113c2250af48e22897339d564b8fdb Mon Sep 17 00:00:00 2001 From: Michael Helfrich Date: Thu, 10 Feb 2022 21:05:00 -0500 Subject: Prevent SuperSlicer from crashing due to a lack of a $USER env. This was replicated from https://github.com/prusa3d/PrusaSlicer/commit/d57d3f99d0874c09700e1a4b780caa14fe788d6e. --- src/slic3r/GUI/RemovableDriveManager.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index d226e4288..edb9e807d 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -201,9 +201,7 @@ namespace search_for_drives_internal struct stat buf; stat(path.c_str(), &buf); uid_t uid = buf.st_uid; - std::string username(std::getenv("USER")); - struct passwd *pw = getpwuid(uid); - if (pw != 0 && pw->pw_name == username) + if (getuid() == uid) out.emplace_back(DriveData{ boost::filesystem::basename(boost::filesystem::path(path)), path }); } } @@ -243,7 +241,7 @@ std::vector RemovableDriveManager::search_for_removable_drives() cons search_for_drives_internal::search_path("/media/*", "/media", current_drives); //search_path("/Volumes/*", "/Volumes"); - std::string path(std::getenv("USER")); + std::string path = wxGetUserId().ToUTF8().data(); std::string pp(path); //search /media/USERNAME/* folder -- cgit v1.2.3 From 2b908bc196b4a71cd4c49f16a8283a34924babc7 Mon Sep 17 00:00:00 2001 From: Stephen Hurd Date: Fri, 28 Jan 2022 23:45:27 -0500 Subject: Add support for libspnav When using a 3DXonnexion mouse on Linux or FreeBSD systems, USB HID mode is being used. This means only one program can be running at a time with Space Mouse support, and potentially means permissions issues for USB devices. This patch uses libspnav if available to avoid these issues. This also has the advantage of not relying on the device driver to be updated in Slic3r/Prusa Slicer/Super Slicer whenever a new device is supported. --- CMakeLists.txt | 15 ++++++++ src/slic3r/CMakeLists.txt | 4 ++ src/slic3r/GUI/Mouse3DController.cpp | 74 +++++++++++++++++++++++++++++++++++- 3 files changed, 92 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 00c7e171f..23ec0717c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -475,6 +475,21 @@ if(OpenVDB_FOUND) slic3r_remap_configs(Blosc::blosc RelWithDebInfo Release) endif() +find_path(SPNAV_INCLUDE_DIR spnav.h) +if (SPNAV_INCLUDE_DIR) + find_library(HAVE_SPNAV spnav) + if (HAVE_SPNAV) + add_definitions(-DHAVE_SPNAV) + add_library(libspnav SHARED IMPORTED) + target_link_libraries(libspnav INTERFACE spnav) + message(STATUS "SPNAV library found") + else() + message(STATUS "SPNAV library NOT found, Spacenavd not supported") + endif() +else() + message(STATUS "SPNAV library NOT found, Spacenavd not supported") +endif() + set(TOP_LEVEL_PROJECT_DIR ${PROJECT_SOURCE_DIR}) function(prusaslicer_copy_dlls target) if ("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8") diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index 3beacae68..4824f8541 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -283,6 +283,10 @@ if (SLIC3R_PCH AND NOT SLIC3R_SYNTAXONLY) add_precompiled_header(libslic3r_gui pchheader.hpp FORCEINCLUDE) endif () +if (HAVE_SPNAV) + target_link_libraries(libslic3r_gui spnav) +endif() + # We need to implement some hacks for wxWidgets and touch the underlying GTK # layer and sub-libraries. This forces us to use the include locations and # link these libraries. diff --git a/src/slic3r/GUI/Mouse3DController.cpp b/src/slic3r/GUI/Mouse3DController.cpp index fb14d9676..8afe49253 100644 --- a/src/slic3r/GUI/Mouse3DController.cpp +++ b/src/slic3r/GUI/Mouse3DController.cpp @@ -17,7 +17,9 @@ #include //unofficial linux lib -//#include +#ifdef HAVE_SPNAV +#include +#endif // WARN: If updating these lists, please also update resources/udev/90-3dconnexion.rules @@ -709,6 +711,31 @@ void Mouse3DController::shutdown() // Main routine of the worker thread. void Mouse3DController::run() { +#ifdef HAVE_SPNAV + if (spnav_open() == -1) { + // Give up. + BOOST_LOG_TRIVIAL(error) << "Unable to open connection to spacenavd"; + return; + } + m_connected = true; + + for (;;) { + { + std::scoped_lock lock(m_params_ui_mutex); + if (m_stop) + break; + if (m_params_ui_changed) { + m_params = m_params_ui; + m_params_ui_changed = false; + } + } + this->collect_input(); + } + + m_connected = false; + // Finalize the spnav library + spnav_close(); +#else // Initialize the hidapi library int res = hid_init(); if (res != 0) { @@ -753,6 +780,7 @@ void Mouse3DController::run() // Finalize the hidapi library hid_exit(); +#endif } bool Mouse3DController::connect_device() @@ -1042,8 +1070,51 @@ void Mouse3DController::disconnect_device() } } +// Convert a signed 16bit word from a 3DConnexion mouse HID packet into a double coordinate, apply a dead zone. +static double convert_spnav_input(int value) +{ + return (double)value/100; +} + void Mouse3DController::collect_input() { +#ifdef HAVE_SPNAV + // Read packet, block maximum 100 ms. That means when closing the application, closing the application will be delayed by 100 ms. + int fd = spnav_fd(); + + if (fd != -1) { + fd_set fds; + struct timeval tv = {.tv_sec = 0, .tv_usec = 100000}; + + FD_ZERO(&fds); + FD_SET(fd, &fds); + if (select(fd + 1, &fds, NULL, NULL, &tv) == 1) { + spnav_event ev = {}; + switch (spnav_poll_event(&ev)) { + case SPNAV_EVENT_MOTION: { + Vec3d translation(-convert_spnav_input(ev.motion.x), convert_spnav_input(ev.motion.y), -convert_spnav_input(ev.motion.z)); + if (!translation.isApprox(Vec3d::Zero())) { +std::cout << "Motion: X: " << ev.motion.x << ", Y: " << ev.motion.y << ", Z: " << ev.motion.z << std::endl; + m_state.append_translation(translation, m_params.input_queue_max_size); + } + Vec3f rotation(convert_spnav_input(ev.motion.rx), convert_spnav_input(ev.motion.ry), -convert_spnav_input(ev.motion.rz)); + if (!rotation.isApprox(Vec3f::Zero())) { +std::cout << "Motion: rX: " << ev.motion.rx << ", rY: " << ev.motion.ry << ", rZ: " << ev.motion.rz << std::endl; + m_state.append_rotation(rotation, m_params.input_queue_max_size); + } + break; + } + case SPNAV_EVENT_BUTTON: + if (ev.button.press) + m_state.append_button((unsigned int)ev.button.bnum, m_params.input_queue_max_size); + break; + } + wxGetApp().plater()->set_current_canvas_as_dirty(); + // ask for an idle event to update 3D scene + wxWakeUpIdle(); + } + } +#else DataPacketRaw packet = { 0 }; // Read packet, block maximum 100 ms. That means when closing the application, closing the application will be delayed by 100 ms. int res = hid_read_timeout(m_device, packet.data(), packet.size(), 100); @@ -1052,6 +1123,7 @@ void Mouse3DController::collect_input() this->disconnect_device(); } else this->handle_input(packet, res, m_params, m_state); +#endif } #ifdef _WIN32 -- cgit v1.2.3