Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

initial proof of concept for space navigator 3d mouse support #413

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 83 additions & 2 deletions cq_editor/widgets/occt_widget.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from sys import platform

import sys

from PyQt5.QtWidgets import QWidget, QApplication
from PyQt5.QtCore import pyqtSlot, pyqtSignal, Qt, QEvent
from PyQt5.QtCore import pyqtSlot, pyqtSignal, Qt, QEvent, QTimer

import OCP

Expand All @@ -12,6 +12,12 @@
from OCP.AIS import AIS_InteractiveContext, AIS_DisplayMode
from OCP.Quantity import Quantity_Color

# pyspacemouse is an optional dependency, so don't fail if it isn't present
try:
import pyspacemouse
except:
pass


ZOOM_STEP = 0.9

Expand Down Expand Up @@ -41,6 +47,33 @@ def __init__(self,parent=None):

#Trihedorn, lights, etc
self.prepare_display()

self._spacemouse_connected = False
if 'pyspacemouse' in sys.modules:
# TODO: this currently checks for 3d mouse presence once at
# initialization, which means that if you plug in your mouse after
# starting cq-editor it won't work. We should instead periodically
# check to see if a mouse was newly-connected.

# TODO: the callback-based approach seems better than polling, but
# it didn't work. Probably something threading-related. The
# callback api works for me in a standalone script.
#
# self._spacemouse_connected = pyspacemouse.open(callback=self.spacemouse_callback, dof_callback=self.spacemouse_dof_callback, button_callback=self.spacemouse_button_callback)

self._spacemouse_connected = pyspacemouse.open()
if self._spacemouse_connected:
print("3DConnexion SpaceNavigator 3d mouse detected")
print(self._spacemouse_connected)

# setup a timer to periodically read the 3d mouse state and
# update the view
self._spacemouse_timer = QTimer(self)
self._spacemouse_timer.setInterval(10) # milliseconds
self._spacemouse_timer.setSingleShot(False)
self._spacemouse_timer.timeout.connect(self._update_from_spacemouse)
self._spacemouse_timer.start()


def prepare_display(self):

Expand Down Expand Up @@ -171,3 +204,51 @@ def _get_window_osx(self,wid):
from OCP.Cocoa import Cocoa_Window

return Cocoa_Window(wid.ascapsule())

# def spacemouse_callback(self, state):
# print("spacemouse_callback: ", state)

# def spacemouse_dof_callback(self, state):
# print("spacemouse_dof_callback: ", state)

# def spacemouse_button_callback(self, state):
# print("spacemouse_button_callback: ", state)

# called periodically to read new values from the 3d mouse and update the
# view
def _update_from_spacemouse(self):
state = pyspacemouse.read()
# print(state)

# axis values less than this are ignored
threshold = 0.05

if abs(state.y) > threshold:
# if state.y < 0:
self.view.SetZoom(1-state.y/20)

# TODO: roll and pitch should also factor into rotation
# if abs(state.yaw) > threshold:
# angle_rad = state.yaw
# # TODO: this rotates about the "current axis". Whatever the current
# # axis is, it doesn't seem to be what we want
# self.view.Rotate(angle_rad,False)

pan_x = 0
pan_y = 0
if abs(state.x) > threshold:
pan_x = int(state.x*100)
if abs(state.z) > threshold:
pan_y = int(state.z*100)
if pan_x != 0 or pan_y != 0:
self.view.Pan(pan_x, pan_y, theToStart=True)


# Override QWidget.destroy to cleanup 3d mouse connection
# TODO: this doesn't seem to get called... use __del__() instead?
def destroy(self, destroyWindow, destroySubWindows):
super().destroy(destroyWindow, destroySubWindows)
print("DEBUG: OcctWidget.destroy() called")
if self._spacemouse_connected:
pyspacemouse.close()
self._spacemouse_timer.stop()