Skip to content
Merged
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
80 changes: 62 additions & 18 deletions fastplotlib/layouts/_plot_area.py
Original file line number Diff line number Diff line change
Expand Up @@ -607,14 +607,33 @@ def center_scene(self, *, zoom: float = 1.0):
if not len(self._fpl_graphics_scene.children) > 0:
return

# scale all cameras associated with this controller
# else it looks wonky
for camera in self.controller.cameras:
camera.show_object(self._fpl_graphics_scene)
if self.parent.__class__.__name__.endswith("Figure"):
# always use figure._subplots.ravel() in internal fastplotlib code
# otherwise if we use `for subplot in figure`, this could conflict
# with a user's iterator where they are doing `for subplot in figure` !!!
for subplot in self.parent._subplots.ravel():
# scale all cameras associated with this controller
if subplot.camera in self.controller.cameras:
# skip if the scene is empty
if len(subplot._fpl_graphics_scene.children) < 1:
continue

# center the camera in the other subplot w.r.t. the scene in that other subplot!
self._auto_center_scene(
subplot.camera, subplot._fpl_graphics_scene, zoom
)
else:
# just change for this plot area
# this is probably a dock area
self._auto_center_scene(self.camera, self._fpl_graphics_scene, zoom)

# camera.show_object can cause the camera width and height to increase so apply a zoom to compensate
# probably because camera.show_object uses bounding sphere
camera.zoom = zoom
def _auto_center_scene(
self, camera: pygfx.PerspectiveCamera, scene: pygfx.Scene, zoom: float
):
camera.show_object(scene)
# camera.show_object can cause the camera width and height to increase so apply a zoom to compensate
# probably because camera.show_object uses bounding sphere
camera.zoom = zoom

def auto_scale(
self,
Expand Down Expand Up @@ -642,16 +661,43 @@ def auto_scale(
self.center_scene()

if maintain_aspect is None: # if not provided keep current setting
# use the same maintain apsect for all other cameras that this controller manages
# I think this make sense for most use cases, even when the other controllers are
# only managing one or 2 axes
maintain_aspect = self.camera.maintain_aspect

# scale all cameras associated with this controller else it looks wonky
for camera in self.controller.cameras:
camera.maintain_aspect = maintain_aspect
if self.parent.__class__.__name__.endswith("Figure"):
# always use figure._subplots.ravel() in internal fastplotlib code
# otherwise if we use `for subplot in figure`, this could conflict
# with a user's iterator where they are doing `for subplot in figure` !!!
for subplot in self.parent._subplots.ravel():
# skip if the scene is empty
if len(subplot._fpl_graphics_scene.children) < 1:
continue

if len(self._fpl_graphics_scene.children) > 0:
width, height, depth = np.ptp(
self._fpl_graphics_scene.get_world_bounding_box(), axis=0
# scale the camera in the other subplot w.r.t. the scene in that other subplot!
if subplot.camera in self.controller.cameras:
camera = subplot.camera
self._auto_scale_scene(
camera, subplot._fpl_graphics_scene, zoom, maintain_aspect
)
else:
# just change for this plot area, this is probably a dock area
self._auto_scale_scene(
self.camera, self._fpl_graphics_scene, zoom, maintain_aspect
)

def _auto_scale_scene(
self,
camera: pygfx.PerspectiveCamera,
scene: pygfx.Scene,
zoom: float,
maintain_aspect: bool,
):
camera.maintain_aspect = maintain_aspect

if len(scene.children) > 0:
width, height, depth = np.ptp(scene.get_world_bounding_box(), axis=0)
else:
width, height, depth = (1, 1, 1)

Expand All @@ -661,12 +707,10 @@ def auto_scale(
if height < 0.01:
height = 1

# scale all cameras associated with this controller else it looks wonky
for camera in self.controller.cameras:
camera.width = width
camera.height = height
camera.width = width
camera.height = height

camera.zoom = zoom
camera.zoom = zoom

def remove_graphic(self, graphic: Graphic):
"""
Expand Down