Skip to content

Commit 46afd0b

Browse files
Add niivue.scene_extents_min_max method
1 parent 83abf11 commit 46afd0b

File tree

1 file changed

+73
-0
lines changed

1 file changed

+73
-0
lines changed

src/ipyniivue/widget.py

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2808,6 +2808,79 @@ def hover_idx_callback(data):
28082808
"""
28092809
self._register_callback("hover_idx_change", callback, remove=remove)
28102810

2811+
"""
2812+
Custom utils
2813+
"""
2814+
2815+
def scene_extents_min_max(self, is_slice_mm: bool = True) -> tuple:
2816+
"""
2817+
Return the scene's min, max, and range extents in mm or voxel space.
2818+
2819+
Includes both volume and mesh geometry.
2820+
2821+
Parameters
2822+
----------
2823+
is_slice_mm : bool, optional
2824+
If True, returns extents in mm space.
2825+
If False, returns extents in voxel space. Default is True.
2826+
2827+
Returns
2828+
-------
2829+
tuple
2830+
A tuple containing three lists:
2831+
- min_extents: [x, y, z] minimum coordinates
2832+
- max_extents: [x, y, z] maximum coordinates
2833+
- range: [x, y, z] range (max - min) for each dimension
2834+
2835+
Raises
2836+
------
2837+
RuntimeError
2838+
If volumes exist but volume_object_3d_data is not defined.
2839+
2840+
Examples
2841+
--------
2842+
::
2843+
2844+
min_ext, max_ext, range_ext = nv.scene_extents_min_max()
2845+
print(f"Min: {min_ext}, Max: {max_ext}, Range: {range_ext}")
2846+
"""
2847+
mn = np.array([0.0, 0.0, 0.0])
2848+
mx = np.array([0.0, 0.0, 0.0])
2849+
2850+
if len(self.volumes) > 0:
2851+
if not self._volume_object_3d_data:
2852+
raise RuntimeError(
2853+
"_volume_object_3d_data not defined. Canvas needs to be attached."
2854+
)
2855+
2856+
if is_slice_mm:
2857+
mn = np.array(self._volume_object_3d_data.extents_min)
2858+
mx = np.array(self._volume_object_3d_data.extents_max)
2859+
else:
2860+
if (
2861+
self.volumes[0].extents_min_ortho
2862+
and self.volumes[0].extents_max_ortho
2863+
):
2864+
mn = np.array(self.volumes[0].extents_min_ortho)
2865+
mx = np.array(self.volumes[0].extents_max_ortho)
2866+
2867+
if len(self.meshes) > 0:
2868+
if len(self.volumes) < 1:
2869+
if self.meshes[0].extents_min and self.meshes[0].extents_max:
2870+
mn = np.array(self.meshes[0].extents_min)
2871+
mx = np.array(self.meshes[0].extents_max)
2872+
2873+
for mesh in self.meshes:
2874+
if mesh.extents_min and mesh.extents_max:
2875+
mesh_min = np.array(mesh.extents_min)
2876+
mesh_max = np.array(mesh.extents_max)
2877+
mn = np.minimum(mn, mesh_min)
2878+
mx = np.maximum(mx, mesh_max)
2879+
2880+
range_extents = mx - mn
2881+
2882+
return (mn.tolist(), mx.tolist(), range_extents.tolist())
2883+
28112884

28122885
class WidgetObserver:
28132886
"""Creates an observer on the `attribute` of `object` for a `widget`."""

0 commit comments

Comments
 (0)