Skip to content

Commit f006249

Browse files
committed
dynamic scene
1 parent 324b85d commit f006249

5 files changed

Lines changed: 88 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Added
1111

12+
* Added ability to add and remove objects in real-time after viewer starts running.
13+
1214
### Changed
1315

1416
* Made `linewidth` working again through `GeometryShader`.

scripts/dynamic_scene.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
from compas.geometry import Box
2+
from compas_viewer import Viewer
3+
from compas.colors import Color
4+
5+
viewer = Viewer()
6+
7+
boxes = [
8+
Box.from_width_height_depth(1, 1, 1),
9+
Box.from_width_height_depth(2, 2, 0.5),
10+
Box.from_width_height_depth(3, 3, 0.2),
11+
]
12+
13+
obj1 = viewer.scene.add(boxes[0], facecolor=Color.blue())
14+
15+
objects_to_remove = [obj1]
16+
17+
18+
@viewer.on(interval=1000)
19+
def dynamic_update(frame):
20+
"""
21+
This function is called every 1000ms for 6 frames.
22+
"""
23+
print(f"Frame {frame}")
24+
25+
if frame == 1:
26+
print("Adding second box...")
27+
added_object = viewer.scene.add(boxes[1], facecolor=Color.red())
28+
objects_to_remove.append(added_object)
29+
30+
if frame == 2:
31+
print("Adding third box...")
32+
added_object = viewer.scene.add(boxes[2], facecolor=Color.green())
33+
objects_to_remove.append(added_object)
34+
35+
if frame == 4:
36+
print("Removing first box...")
37+
viewer.scene.remove(objects_to_remove.pop(-1))
38+
39+
if frame == 5:
40+
print("Removing second box...")
41+
viewer.scene.remove(objects_to_remove.pop(-1))
42+
43+
if frame == 6:
44+
print("Removing third box...")
45+
viewer.scene.remove(objects_to_remove.pop(-1))
46+
47+
viewer.show()

src/compas_viewer/renderer/renderer.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,22 @@ def init(self):
445445
self.shader_lines.uniformBuffer("settingsBuffer", self.buffer_manager.settings_texture, unit=1)
446446
self.shader_lines.release()
447447

448+
def rebuild_buffers(self):
449+
"""Rebuild the buffers."""
450+
GL.glBindVertexArray(self._vao)
451+
self.buffer_manager.clear()
452+
453+
# Ensure all objects are initialized before adding to buffer
454+
for obj in self.viewer.scene.objects:
455+
if not isinstance(obj, (Group, TagObject)) and not obj._inited:
456+
obj.init()
457+
458+
for obj in self.viewer.scene.objects:
459+
if not isinstance(obj, (Group, TagObject)):
460+
self.buffer_manager.add_object(obj)
461+
self.buffer_manager.create_buffers()
462+
GL.glBindVertexArray(0)
463+
448464
def update_projection(self, w=None, h=None):
449465
"""
450466
Update the projection matrix.

src/compas_viewer/scene/buffermanager.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@ def clear(self) -> None:
281281
self.elements[buffer_type] = np.array([], dtype=np.int32)
282282
self.buffer_ids[buffer_type] = {}
283283

284+
self.objects = {}
284285
self.transforms = []
285286
self.settings = []
286287
self.object_settings_cache = {}

src/compas_viewer/scene/scene.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,12 @@ def add(
177177
u=u,
178178
**kwargs,
179179
)
180+
181+
if self.viewer.running:
182+
self.viewer.renderer.rebuild_buffers()
183+
self.viewer.renderer.update()
184+
self.viewer.ui.sidebar.update()
185+
180186
return sceneobject
181187

182188
def add_group(self, name: str = None, parent: Optional[ViewerSceneObject] = None, **kwargs) -> Group:
@@ -200,3 +206,19 @@ def add_group(self, name: str = None, parent: Optional[ViewerSceneObject] = None
200206
group = Group(name=name, **kwargs)
201207
self.add(group, parent=parent)
202208
return group
209+
210+
def remove(self, sceneobject: ViewerSceneObject):
211+
"""
212+
Remove an scene object from the scene.
213+
214+
Parameters
215+
----------
216+
sceneobject : :class:`compas_viewer.scene.ViewerSceneObject`
217+
The scene object to remove.
218+
"""
219+
super().remove(sceneobject)
220+
221+
if self.viewer.running:
222+
self.viewer.renderer.rebuild_buffers()
223+
self.viewer.renderer.update()
224+
self.viewer.ui.sidebar.update()

0 commit comments

Comments
 (0)