瀏覽代碼

Add function to update a point cloud (#3468)

* Add function to update a point cloud

* code review

---------

Co-authored-by: Andreas Voigt <andreas.voigt@optonic.com>
Co-authored-by: Falko Schindler <falko@zauberzeug.com>
Voigta 9 月之前
父節點
當前提交
245c2021ea
共有 3 個文件被更改,包括 23 次插入3 次删除
  1. 5 0
      nicegui/elements/scene.js
  2. 6 0
      nicegui/elements/scene_objects.py
  3. 12 3
      website/documentation/content/scene_documentation.py

+ 5 - 0
nicegui/elements/scene.js

@@ -388,6 +388,11 @@ export default {
       if (!this.objects.has(object_id)) return;
       this.objects.get(object_id).geometry = texture_geometry(coords);
     },
+    set_points(object_id, position, color) {
+      const geometry = this.objects.get(object_id).geometry;
+      geometry.setAttribute("position", new THREE.Float32BufferAttribute(position.flat(), 3));
+      geometry.setAttribute("color", new THREE.Float32BufferAttribute(color.flat(), 3));
+    },
     move_camera(x, y, z, look_at_x, look_at_y, look_at_z, up_x, up_y, up_z, duration) {
       if (this.camera_tween) this.camera_tween.stop();
       this.camera_tween = new TWEEN.Tween([

+ 6 - 0
nicegui/elements/scene_objects.py

@@ -329,3 +329,9 @@ class PointCloud(Object3D):
         :param point_size: size of the points (default: 1.0)
         """
         super().__init__('point_cloud', points, colors, point_size)
+
+    def set_points(self, points: List[List[float]], colors: List[List[float]]) -> None:
+        """Change the points and colors of the point cloud."""
+        self.args[0] = points
+        self.args[1] = colors
+        self.scene.run_method('set_points', self.id, points, colors)

+ 12 - 3
website/documentation/content/scene_documentation.py

@@ -142,15 +142,24 @@ def immediate_updates() -> None:
 @doc.demo('Rendering point clouds', '''
     You can render point clouds using the `point_cloud` method.
     The `points` argument is a list of point coordinates, and the `colors` argument is a list of RGB colors (0..1).
+    You can update the cloud using its `set_points()` method.
 ''')
 def point_clouds() -> None:
     import numpy as np
 
-    with ui.scene().classes('w-full h-64') as scene:
+    def generate_data(frequency: float = 1.0):
         x, y = np.meshgrid(np.linspace(-3, 3), np.linspace(-3, 3))
-        z = np.sin(x) * np.cos(y) + 1
+        z = np.sin(x * frequency) * np.cos(y * frequency) + 1
         points = np.dstack([x, y, z]).reshape(-1, 3)
-        scene.point_cloud(points=points, colors=points, point_size=0.1)
+        colors = points / [6, 6, 2] + [0.5, 0.5, 0]
+        return points, colors
+
+    with ui.scene().classes('w-full h-64') as scene:
+        points, colors = generate_data()
+        point_cloud = scene.point_cloud(points, colors, point_size=0.1)
+
+    ui.slider(min=0.1, max=3, step=0.1, value=1) \
+        .on_value_change(lambda e: point_cloud.set_points(*generate_data(e.value)))
 
 
 @doc.demo('Wait for Initialization', '''