Currently trying to perform an annotation procedure with my mouse. Basically, in my custom annotation mode, rotation of the world is disabled so I can perform custom annotations with the mouse (as of now, only record the world coordinates via ray tracing, so I track the coordinates and resize objects dynamically later on). Reason is that I do not want the world to rotate while I am drawing my own annotations. That would mess up the custom annotations.
- Left Press Event
- Left Mouse Release Event
- Mouse Move Left Button
- Double Click
Adding an observer during annotation mode for all those for events, seems to work (rotations is effectively disabled with mouse movements, for example when left clicking and dragging).
However, when I double click and release, and left click and drag again, the world suddenly rotates again and coordinates are no longer printed, which is not intended; it is like it is disabling my annotation mode, while other mouse events do not do it. Only double clicking seems to do it. To enable this custom annotation mode, I have to enable it again to handle my custom mouse events.
In other words, the observer is NOT able to observe the double clicks, but seems to reset the interactor style when double clicking? The logic to enter the double click is detected properly, however. But not by VTK.
from coordinates import Coordinates
import time
class MouseHandler:
def __init__(self, plotter, annotation_handler):
self.plotter = plotter
self.annotation_handler = annotation_handler
self.coordinates = Coordinates(plotter)
self.is_dragging = False
self.start_world_pos = None
self.end_world_pos = None
self.last_click_time = 0
self.click_interval = 0.5 # 0.5 seconds for double click
def left_button_press(self, obj, event):
current_click_time = time.time()
if current_click_time - self.last_click_time <= self.click_interval:
# Detected a double click
self.left_button_double_click(obj, event)
self.is_dragging = False
else:
# Handle as a single click
if self.annotation_handler.annotation_mode:
self.is_dragging = True
self.drag_start_world_pos = self.coordinates.screen_to_world(self.plotter.interactor.GetEventPosition())
print(f"Start Dragging at World Position {self.drag_start_world_pos}")
self.last_click_time = current_click_time
def mouse_move(self, obj, event):
if self.annotation_handler.annotation_mode and self.is_dragging:
current_screen_pos = self.plotter.interactor.GetEventPosition()
current_world_pos = self.coordinates.screen_to_world(current_screen_pos)
# Retain the Z-coordinate from the drag start position
drag_world_pos = (current_world_pos[0], current_world_pos[1], self.drag_start_world_pos[2])
print(f"Dragging at World Position: {drag_world_pos}")
def left_button_release(self, obj, event):
if self.annotation_handler.annotation_mode and self.is_dragging:
self.is_dragging = False
current_screen_pos = self.plotter.interactor.GetEventPosition()
current_world_pos = self.coordinates.screen_to_world(current_screen_pos)
# Final position with the same Z-level as the start position
end_drag_world_pos = (current_world_pos[0], current_world_pos[1], self.drag_start_world_pos[2])
print(f"End Dragging at World Position: {end_drag_world_pos}")
self.drag_start_world_pos = None
def left_button_double_click(self, obj, event):
print("Double click detected")
from mouse_handler import MouseHandler
import vtk
class AnnotationHandler:
def __init__(self, plotter):
self.plotter = plotter
self.annotation_mode = False
self.mouse_handler = MouseHandler(plotter, self)
self.default_interactor_style = self.plotter.interactor.GetInteractorStyle()
self.custom_interactor_style = CustomInteractorStyle(self.mouse_handler)
def toggle_annotation_mode(self):
if self.annotation_mode:
self.disable_annotation_mode()
else:
self.enable_annotation_mode()
self.annotation_mode = not self.annotation_mode
def enable_annotation_mode(self):
print("Enabling annotation mode")
self.plotter.interactor.SetInteractorStyle(self.custom_interactor_style)
def disable_annotation_mode(self):
print("Disabling annotation mode")
self.plotter.interactor.SetInteractorStyle(self.default_interactor_style)
class CustomInteractorStyle(vtk.vtkInteractorStyleTrackballCamera):
def __init__(self, mouse_handler):
super(CustomInteractorStyle, self).__init__()
self.mouse_handler = mouse_handler
self.AddObserver("LeftButtonPressEvent", self.mouse_handler.left_button_press, 1.0)
self.AddObserver("MouseMoveEvent", self.mouse_handler.mouse_move, 1.0)
self.AddObserver("LeftButtonReleaseEvent", self.mouse_handler.left_button_release, 1.0)
self.AddObserver("LeftButtonDoubleClickEvent", self.mouse_handler.left_button_double_click, 1.0)
In my main.py;
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
# Load the UI
uic.loadUi('main.ui', self)
self.plotter3D = QtInteractor(self.AllView)
layout = QtWidgets.QVBoxLayout()
layout.addWidget(self.plotter3D.interactor)
self.AllView.setLayout(layout)
self.plotter3D.set_background('black')
self.plotter3D.add_axes()
self.color_gradient_applied = False
self.current_lidar_data = None
self.annotation_handler = AnnotationHandler(self.plotter3D)
self.mouse_handler = MouseHandler(self.plotter3D, self.annotation_handler)
self.Annotate.clicked.connect(self.annotate)
def annotate(self):
# Toggle Custom Annotation Mode to perform custom mouse events
self.annotation_handler.toggle_annotation_mode()
Thank you for your support.