Skip to content

Commit

Permalink
Improve performance of 3D scenes by initializing all objects at once (#…
Browse files Browse the repository at this point in the history
…3022)

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

* send data for all objects at once
  • Loading branch information
falkoschindler authored May 6, 2024
1 parent d6236c0 commit ec74e6a
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 12 deletions.
30 changes: 30 additions & 0 deletions nicegui/elements/scene.js
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down
3 changes: 1 addition & 2 deletions nicegui/elements/scene.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,7 @@ def _handle_init(self, e: GenericEventArguments) -> None:
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."""
Expand Down
23 changes: 13 additions & 10 deletions nicegui/elements/scene_object3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,19 @@ def with_name(self, name: str) -> Self:
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)
Expand Down

0 comments on commit ec74e6a

Please sign in to comment.