Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/supermerill/SuperSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Hurd <deuce@synchro.net>2022-01-29 07:45:27 +0300
committersupermerill <merill@free.fr>2022-02-13 22:29:00 +0300
commit2b908bc196b4a71cd4c49f16a8283a34924babc7 (patch)
tree28ef5d774838c60745df916e4be329f0cb4c3fe9
parent8f03c8de4e113c2250af48e22897339d564b8fdb (diff)
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.
-rw-r--r--CMakeLists.txt15
-rw-r--r--src/slic3r/CMakeLists.txt4
-rw-r--r--src/slic3r/GUI/Mouse3DController.cpp74
3 files changed, 92 insertions, 1 deletions
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 <bitset>
//unofficial linux lib
-//#include <spnav.h>
+#ifdef HAVE_SPNAV
+#include <spnav.h>
+#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