浏览代码

Improve performance of 3D scenes by initializing all objects at once (#3022)

* introduce "init" message to send 3d objects more efficiently

* send data for all objects at once
Falko Schindler 1 年之前
父节点
当前提交
ec74e6a735
共有 3 个文件被更改,包括 44 次插入12 次删除
  1. 30 0
      nicegui/elements/scene.js
  2. 1 2
      nicegui/elements/scene.py
  3. 13 10
      nicegui/elements/scene_object3d.py

+ 30 - 0
nicegui/elements/scene.js

@@ -435,6 +435,36 @@ export default {
       }
       this.camera.updateProjectionMatrix();
     },
+    init_objects(data) {
+      for (const [
+        type,
+        id,
+        parent_id,
+        args,
+        name,
+        color,
+        opacity,
+        side,
+        x,
+        y,
+        z,
+        R,
+        sx,
+        sy,
+        sz,
+        visible,
+        draggable,
+      ] of data) {
+        this.create(type, id, parent_id, ...args);
+        this.name(id, name);
+        this.material(id, color, opacity, side);
+        this.move(id, x, y, z);
+        this.rotate(id, R);
+        this.scale(id, sx, sy, sz);
+        this.visible(id, visible);
+        this.draggable(id, draggable);
+      }
+    },
   },
 
   props: {

+ 1 - 2
nicegui/elements/scene.py

@@ -170,8 +170,7 @@ class Scene(Element,
         self.is_initialized = True
         with self.client.individual_target(e.args['socket_id']):
             self.move_camera(duration=0)
-            for obj in self.objects.values():
-                obj.send()
+            self.run_method('init_objects', [obj.data for obj in self.objects.values()])
 
     async def initialized(self) -> None:
         """Wait until the scene is initialized."""

+ 13 - 10
nicegui/elements/scene_object3d.py

@@ -42,16 +42,19 @@ class Object3D:
         self._name()
         return self
 
-    def send(self) -> None:
-        """Send the object to the client."""
-        self._create()
-        self._name()
-        self._material()
-        self._move()
-        self._rotate()
-        self._scale()
-        self._visible()
-        self._draggable()
+    @property
+    def data(self) -> List[Any]:
+        """Data to be sent to the frontend."""
+        return [
+            self.type, self.id, self.parent.id, self.args,
+            self.name,
+            self.color, self.opacity, self.side_,
+            self.x, self.y, self.z,
+            self.R,
+            self.sx, self.sy, self.sz,
+            self.visible_,
+            self.draggable_,
+        ]
 
     def __enter__(self) -> Self:
         self.scene.stack.append(self)