Skip to content

Commit

Permalink
Merge pull request #50 from Carifio24/ipyvolume-volume
Browse files Browse the repository at this point in the history
Add support for ipyvolume volume viewer
  • Loading branch information
Carifio24 authored Sep 10, 2024
2 parents 8f3bae9 + b924c95 commit ffe2743
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 13 deletions.
2 changes: 2 additions & 0 deletions glue_ar/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ def setup_jupyter():
pass

from glue_jupyter.ipyvolume.scatter import IpyvolumeScatterView
from glue_jupyter.ipyvolume.volume import IpyvolumeVolumeView
IpyvolumeScatterView.tools = [t for t in IpyvolumeScatterView.tools] + ["save:ar_jupyter"]
IpyvolumeVolumeView.tools = [t for t in IpyvolumeVolumeView.tools] + ["save:ar_jupyter"]


def setup():
Expand Down
1 change: 1 addition & 0 deletions glue_ar/common/export_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ def __call__(self,
multiple: bool = False):
def adder(export_method: Callable):
self.add(layer_state_cls, name, layer_options_state, extensions, multiple, export_method)
return export_method
return adder


Expand Down
14 changes: 12 additions & 2 deletions glue_ar/common/marching_cubes.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def add_isosurface_layer_gltf(builder: GLTFBuilder,
(viewer_state.x_min, viewer_state.x_max),
(viewer_state.z_min, viewer_state.z_max),
)
resolution = viewer_state.resolution
resolution = getattr(viewer_state, 'resolution', None) or getattr(layer_state, 'max_resolution')
x_range = viewer_state.x_max - viewer_state.x_min
y_range = viewer_state.y_max - viewer_state.y_min
z_range = viewer_state.z_max - viewer_state.z_min
Expand Down Expand Up @@ -141,7 +141,7 @@ def add_isosurface_layer_usd(
(viewer_state.x_min, viewer_state.x_max),
(viewer_state.z_min, viewer_state.z_max),
)
resolution = viewer_state.resolution
resolution = getattr(viewer_state, 'resolution', None) or getattr(layer_state, 'max_resolution')
x_range = viewer_state.x_max - viewer_state.x_min
y_range = viewer_state.y_max - viewer_state.y_min
z_range = viewer_state.z_max - viewer_state.z_min
Expand All @@ -164,3 +164,13 @@ def add_isosurface_layer_usd(
points = [tuple((-1 + (index + 0.5) * side) for index, side in zip(pt, clip_sides)) for pt in points]
points = [[p[1], p[0], p[2]] for p in points]
builder.add_mesh(points, triangles, color_components, alpha)


try:
from glue_jupyter.ipyvolume.volume import VolumeLayerState as IPVVolumeLayerState
ar_layer_export.add(IPVVolumeLayerState, "Isosurface", ARIsosurfaceExportOptions,
("gltf", "glb"), False, add_isosurface_layer_gltf)
ar_layer_export.add(IPVVolumeLayerState, "Isosurface", ARIsosurfaceExportOptions,
("usda", "usdc"), False, add_isosurface_layer_usd)
except ImportError:
pass
Empty file.
16 changes: 13 additions & 3 deletions glue_ar/common/voxels.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from glue_ar.common.usd_builder import USDBuilder
from glue_ar.common.volume_export_options import ARVoxelExportOptions
from glue_ar.usd_utils import material_for_color
from glue_ar.utils import BoundsWithResolution, alpha_composite, frb_for_layer, hex_to_components, \
from glue_ar.utils import BoundsWithResolution, alpha_composite, frb_for_layer, get_resolution, hex_to_components, \
isomin_for_layer, isomax_for_layer, layer_color, unique_id, xyz_bounds

from glue_ar.gltf_utils import add_points_to_bytearray, add_triangles_to_bytearray, \
Expand All @@ -26,7 +26,7 @@ def add_voxel_layers_gltf(builder: GLTFBuilder,
options: Iterable[ARVoxelExportOptions],
bounds: Optional[BoundsWithResolution] = None):

resolution = viewer_state.resolution
resolution = get_resolution(viewer_state)
bounds = bounds or xyz_bounds(viewer_state, with_resolution=True)
x_range = viewer_state.x_max - viewer_state.x_min
y_range = viewer_state.y_max - viewer_state.y_min
Expand Down Expand Up @@ -167,7 +167,7 @@ def add_voxel_layers_usd(builder: USDBuilder,
options: Iterable[ARVoxelExportOptions],
bounds: Optional[BoundsWithResolution] = None):

resolution = viewer_state.resolution
resolution = get_resolution(viewer_state)
bounds = bounds or xyz_bounds(viewer_state, with_resolution=True)
x_range = viewer_state.x_max - viewer_state.x_min
y_range = viewer_state.y_max - viewer_state.y_min
Expand Down Expand Up @@ -242,3 +242,13 @@ def add_voxel_layers_usd(builder: USDBuilder,
builder.add_translated_reference(mesh, translation, material)

return builder


try:
from glue_jupyter.ipyvolume.volume import VolumeLayerState as IPVVolumeLayerState
ar_layer_export.add(IPVVolumeLayerState, "Voxel", ARVoxelExportOptions,
("gltf", "glb"), True, add_voxel_layers_gltf)
ar_layer_export.add(IPVVolumeLayerState, "Voxel", ARVoxelExportOptions,
("usda", "usdc"), True, add_voxel_layers_usd)
except ImportError:
pass
5 changes: 2 additions & 3 deletions glue_ar/jupyter/export_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@

from glue.config import viewer_tool
from glue.viewers.common.tool import Tool
from glue_vispy_viewers.volume.qt.volume_viewer import VispyVolumeViewerMixin

from glue_ar.common.export import export_viewer
from glue_ar.jupyter.export_dialog import JupyterARExportDialog
from glue_ar.utils import AR_ICON, xyz_bounds
from glue_ar.utils import AR_ICON, is_volume_viewer, xyz_bounds

import ipyvuetify as v # noqa
from ipywidgets import HBox, Layout # noqa
Expand Down Expand Up @@ -109,7 +108,7 @@ def on_no_click(button, event, data):
self.viewer.output_widget.clear_output()

def save_figure(self, filepath):
bounds = xyz_bounds(self.viewer.state, with_resolution=isinstance(self.viewer, VispyVolumeViewerMixin))
bounds = xyz_bounds(self.viewer.state, with_resolution=is_volume_viewer(self.viewer))
layer_states = [layer.state for layer in self.viewer.layers if layer.enabled and layer.state.visible]
state_dict = self.export_dialog.state_dictionary
export_viewer(viewer_state=self.viewer.state,
Expand Down
41 changes: 36 additions & 5 deletions glue_ar/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@
from glue.viewers.common.viewer import LayerArtist, Viewer

from glue_vispy_viewers.common.layer_state import LayerState, VispyLayerState
from glue_vispy_viewers.volume.volume_viewer import VispyVolumeViewerMixin
from glue_vispy_viewers.volume.layer_state import VolumeLayerState
from glue_vispy_viewers.volume.viewer_state import Vispy3DViewerState
from glue_vispy_viewers.volume.viewer_state import Vispy3DViewerState, Vispy3DVolumeViewerState
from numpy import array, inf, isnan, ndarray

try:
Expand Down Expand Up @@ -81,7 +82,8 @@ def xyz_bounds(viewer_state: Viewer3DState, with_resolution: bool) -> Union[Boun
(viewer_state.y_min, viewer_state.y_max),
(viewer_state.z_min, viewer_state.z_max)]
if with_resolution:
return [(*b, viewer_state.resolution) for b in bounds]
resolution = get_resolution(viewer_state)
return [(*b, resolution) for b in bounds]

return bounds

Expand Down Expand Up @@ -110,7 +112,8 @@ def bounds_3d_from_layers(viewer_state: Viewer3DState,
maxes = [max(max(data[att]), m) for m, att in zip(maxes, atts)]
bounds = [(lo, hi) for lo, hi in zip(mins, maxes)]
if with_resolution:
return [(*b, viewer_state.resolution) for b in bounds]
resolution = get_resolution(viewer_state)
return [(*b, resolution) for b in bounds]

return bounds

Expand Down Expand Up @@ -216,8 +219,9 @@ def frb_for_layer(viewer_state: ViewerState,
data = data_for_layer(layer_or_state)
layer_state = layer_or_state if isinstance(layer_or_state, LayerState) else layer_or_state.state
is_data_layer = data is layer_or_state.layer
target_data = getattr(viewer_state, 'reference_data', data)
data_frb = data.compute_fixed_resolution_buffer(
target_data=viewer_state.reference_data,
target_data=target_data,
bounds=bounds,
target_cid=layer_state.attribute
)
Expand All @@ -226,7 +230,7 @@ def frb_for_layer(viewer_state: ViewerState,
return data_frb
else:
subcube = data.compute_fixed_resolution_buffer(
target_data=viewer_state.reference_data,
target_data=target_data,
bounds=bounds,
subset_state=layer_state.layer.subset_state
)
Expand All @@ -247,3 +251,30 @@ def iterator_count(iter: Iterator) -> int:
Note that this consumes the iterator.
"""
return sum(1 for _ in iter)


def is_volume_viewer(viewer: Viewer) -> bool:
if isinstance(viewer, VispyVolumeViewerMixin):
return True
try:
from glue_jupyter.ipyvolume.volume import IpyvolumeVolumeView
if isinstance(viewer, IpyvolumeVolumeView):
return True
except ImportError:
pass

return False


def get_resolution(viewer_state: Viewer3DState) -> int:
if isinstance(viewer_state, Vispy3DVolumeViewerState):
return viewer_state.resolution

try:
from glue_jupyter.common.state3d import VolumeViewerState
if isinstance(viewer_state, VolumeViewerState):
return max((getattr(state, 'max_resolution', 256) for state in viewer_state.layers), default=256)
except ImportError:
pass

return 256

0 comments on commit ffe2743

Please sign in to comment.