Skip to content

Commit 8f9212d

Browse files
gselzertlambert03
andauthored
feat: Use handles to compute viewer range (#38)
* feat: Use handles to compute viewer range * Reimplement handle-based range in backends --------- Co-authored-by: Talley Lambert <[email protected]>
1 parent 3ee756c commit 8f9212d

File tree

1 file changed

+31
-17
lines changed

1 file changed

+31
-17
lines changed

src/ndv/viewer/_backends/_vispy.py

+31-17
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,6 @@ class VispyViewerCanvas(PCanvas):
447447

448448
def __init__(self) -> None:
449449
self._canvas = scene.SceneCanvas(size=(600, 600))
450-
self._current_shape: tuple[int, ...] = ()
451450
self._last_state: dict[Literal[2, 3], Any] = {}
452451

453452
central_wdg: scene.Widget = self._canvas.central_widget
@@ -494,12 +493,10 @@ def add_image(
494493
img = scene.visuals.Image(data, parent=self._view.scene)
495494
img.set_gl_state("additive", depth_test=False)
496495
img.interactive = True
497-
if data is not None:
498-
self._current_shape, prev_shape = data.shape, self._current_shape
499-
if not prev_shape:
500-
self.set_range()
501496
handle = VispyImageHandle(img)
502497
self._elements[img] = handle
498+
if data is not None:
499+
self.set_range()
503500
if cmap is not None:
504501
handle.cmap = cmap
505502
return handle
@@ -512,12 +509,10 @@ def add_volume(
512509
)
513510
vol.set_gl_state("additive", depth_test=False)
514511
vol.interactive = True
515-
if data is not None:
516-
self._current_shape, prev_shape = data.shape, self._current_shape
517-
if len(prev_shape) != 3:
518-
self.set_range()
519512
handle = VispyImageHandle(vol)
520513
self._elements[vol] = handle
514+
if data is not None:
515+
self.set_range()
521516
if cmap is not None:
522517
handle.cmap = cmap
523518
return handle
@@ -536,6 +531,7 @@ def add_roi(
536531
self._elements[h] = VispyHandleHandle(h, handle)
537532
if vertices:
538533
handle.vertices = vertices
534+
self.set_range()
539535
handle.color = color
540536
handle.border_color = border_color
541537
return handle
@@ -551,19 +547,37 @@ def set_range(
551547
552548
When called with no arguments, the range is set to the full extent of the data.
553549
"""
554-
if len(self._current_shape) >= 2:
555-
if x is None:
556-
x = (0, self._current_shape[-1])
557-
if y is None:
558-
y = (0, self._current_shape[-2])
559-
if z is None and len(self._current_shape) == 3:
560-
z = (0, self._current_shape[-3])
550+
_x = [0.0, 0.0]
551+
_y = [0.0, 0.0]
552+
_z = [0.0, 0.0]
553+
554+
for handle in self._elements.values():
555+
if isinstance(handle, VispyImageHandle):
556+
shape = handle.data.shape
557+
_x[1] = max(_x[1], shape[0])
558+
_y[1] = max(_y[1], shape[1])
559+
if len(shape) > 2:
560+
_z[1] = max(_z[1], shape[2])
561+
elif isinstance(handle, VispyRoiHandle):
562+
for v in handle.vertices:
563+
_x[0] = min(_x[0], v[0])
564+
_x[1] = max(_x[1], v[0])
565+
_y[0] = min(_y[0], v[1])
566+
_y[1] = max(_y[1], v[1])
567+
if len(v) > 2:
568+
_z[0] = min(_z[0], v[2])
569+
_z[1] = max(_z[1], v[2])
570+
571+
x = cast(tuple[float, float], _x) if x is None else x
572+
y = cast(tuple[float, float], _y) if y is None else y
573+
z = cast(tuple[float, float], _z) if z is None else z
574+
561575
is_3d = isinstance(self._camera, scene.ArcballCamera)
562576
if is_3d:
563577
self._camera._quaternion = DEFAULT_QUATERNION
564578
self._view.camera.set_range(x=x, y=y, z=z, margin=margin)
565579
if is_3d:
566-
max_size = max(self._current_shape)
580+
max_size = max(x[1], y[1], z[1])
567581
self._camera.scale_factor = max_size + 6
568582

569583
def canvas_to_world(

0 commit comments

Comments
 (0)