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

observer method #185

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
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
17 changes: 0 additions & 17 deletions src/compas_viewer/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,9 +236,6 @@ def select_all(viewer: "Viewer"):
if obj.show and not obj.is_locked:
obj.is_selected = True

viewer.ui.sidebar.update()
viewer.renderer.update()


select_all_cmd = Command(title="Select All", callback=select_all)

Expand All @@ -247,9 +244,6 @@ def deselect_all(viewer: "Viewer"):
for obj in viewer.scene.objects:
obj.is_selected = False

viewer.ui.sidebar.update()
viewer.renderer.update()


deselect_all_cmd = Command(title="DeSelect All", callback=deselect_all)

Expand All @@ -275,8 +269,6 @@ def select_object(viewer: "Viewer", event: QMouseEvent):
if selected_obj:
selected_obj.is_selected = True

viewer.ui.sidebar.update()

viewer.renderer.update()


Expand All @@ -295,7 +287,6 @@ def select_multiple(viewer: "Viewer", event: QMouseEvent):
selected_obj = viewer.scene.instance_colors.get(tuple(unique_color[0])) # type: ignore
if selected_obj:
selected_obj.is_selected = True
viewer.ui.sidebar.update()

viewer.renderer.update()

Expand Down Expand Up @@ -343,8 +334,6 @@ def select_window(viewer: "Viewer", event: QMouseEvent):
obj.is_selected = True
continue

viewer.ui.sidebar.update()

viewer.renderer.update()


Expand All @@ -364,8 +353,6 @@ def deselect_object(viewer: "Viewer", event: QMouseEvent):
if selected_obj:
selected_obj.is_selected = False

viewer.ui.sidebar.update()

viewer.renderer.update()


Expand Down Expand Up @@ -394,7 +381,6 @@ def delete_selected():
if obj.is_selected:
viewer.scene.remove(obj)
del obj
viewer.renderer.update()


# =============================================================================
Expand All @@ -411,9 +397,6 @@ def clear_scene(viewer: "Viewer"):
viewer.scene.remove(obj)
del obj

viewer.ui.sidebar.update()
viewer.renderer.update()


clear_scene_cmd = Command(title="Clear Scene", callback=clear_scene)

Expand Down
2 changes: 0 additions & 2 deletions src/compas_viewer/components/sceneform.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,6 @@ def on_item_clicked(self, item, column):
if self.callback and node.is_selected:
self.callback(node)

self.viewer.renderer.update()

def on_item_selection_changed(self):
for item in self.selectedItems():
if self.callback:
Expand Down
34 changes: 34 additions & 0 deletions src/compas_viewer/observer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
from PySide6.QtCore import QTimer

from compas_viewer.base import Base


class Observer(Base):
def __init__(self):
self._observers = set(
(
self.viewer.renderer,
self.viewer.ui.sidebar,
)
)

self.update_timer = QTimer()
self.update_timer.setSingleShot(True)
self.update_timer.timeout.connect(self.update_observers)
self.debounce_interval = 200

def add_observer(self, observer):
if observer not in self._observers:
self._observers.add(observer)

def remove_observer(self, observer):
if observer in self._observers:
self._observers.remove(observer)

def request_update(self):
if not self.update_timer.isActive():
self.update_timer.start(self.debounce_interval)

def update_observers(self):
for observer in self._observers:
observer.update()
26 changes: 22 additions & 4 deletions src/compas_viewer/scene/scene.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from compas.datastructures import Datastructure
from compas.geometry import Geometry
from compas.scene import Scene
from compas_viewer.observer import Observer

from .sceneobject import ViewerSceneObject

Expand Down Expand Up @@ -68,17 +69,21 @@ class ViewerScene(Scene):
def __init__(self, name: str = "ViewerScene", context: str = "Viewer"):
super().__init__(name=name, context=context)

# Observer
self._observer = None

# Primitive
self.objects: list[ViewerSceneObject]
# Selection
self.instance_colors: dict[tuple[int, int, int], ViewerSceneObject] = {}
self._instance_colors_generator = instance_colors_generator()

@property
def viewer(self):
from compas_viewer import Viewer

return Viewer()
def observer(self):
"""Observer: The observer object for the scene."""
if self._observer is None:
self._observer = Observer()
return self._observer

# TODO: These fixed kwargs could be moved to COMPAS core.
def add(
Expand Down Expand Up @@ -183,4 +188,17 @@ def add(
u=u,
**kwargs,
)
self.observer.request_update()
return sceneobject

def remove(self, obj: ViewerSceneObject) -> None:
"""
Remove an object from the scene.

Parameters
----------
obj : :class:`compas_viewer.scene.ViewerSceneObject`
The object to remove.
"""
super().remove(obj)
self.observer.request_update()
23 changes: 22 additions & 1 deletion src/compas_viewer/scene/sceneobject.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from compas_viewer.gl import make_vertex_buffer
from compas_viewer.gl import update_index_buffer
from compas_viewer.gl import update_vertex_buffer
from compas_viewer.observer import Observer
from compas_viewer.renderer.shaders import Shader

# Type template of point/line/face data for generating the buffers.
Expand Down Expand Up @@ -101,6 +102,9 @@ def __init__(
):
# Basic
super().__init__(**kwargs)

self._observer = None

self.show = show
self.show_points = show_points if show_points is not None else False
self.show_lines = show_lines if show_lines is not None else True
Expand All @@ -111,7 +115,7 @@ def __init__(

# Selection
self._is_locked = is_locked
self.is_selected = not is_locked and is_selected
self._is_selected = False

# Visual
self.background: bool = False
Expand All @@ -135,6 +139,23 @@ def __init__(

self._inited = False

@property
def observer(self) -> bool:
"""bool : Whether the scene is requested to be updated."""
if self._observer is None:
self._observer = Observer()
return self._observer

@property
def is_selected(self):
return self._is_selected

@is_selected.setter
def is_selected(self, value):
if self._is_selected != value:
self._is_selected = value
self.observer.request_update()

@property
def is_locked(self):
return self._is_locked
Expand Down
Loading