Abe Ez
Abe Ez

Reputation: 11

PyVista VTK, double clicking seems to reset the Observer?

Currently trying to perform an annotation procedure with my mouse. Basically, in annotation mode, rotation of the interactor is disabled so I can perform custom annotations with the mouse. 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.

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, 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.

The reason is I want to be able to draw my own rectangle to annotate an area.

When I want to select a specific rectangle for example so I can resize it, I want to double click on it. But what happens is that the world starts rotating instead which is not intended. In other words, the observer is NOT able to observe the double clicks, but seems to reset all observers?

From mouse_handler.py;

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 annotation_handler.py;

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)

Different code approaches

Upvotes: 1

Views: 133

Answers (0)

Related Questions