From 9b474140d2468fb5c1ef94e57ce32ccdb1d0b3a7 Mon Sep 17 00:00:00 2001 From: Carifio24 Date: Mon, 18 Dec 2023 14:01:43 -0500 Subject: [PATCH 1/3] Fix an issue with the scatter export path. --- glue_ar/tools.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/glue_ar/tools.py b/glue_ar/tools.py index 8598eeb..f0c644e 100644 --- a/glue_ar/tools.py +++ b/glue_ar/tools.py @@ -1,5 +1,5 @@ import os -from os.path import basename, splitext +from os.path import join, split, splitext import pyvista as pv @@ -48,9 +48,9 @@ def activate(self): data = mesh_info.pop("data") plotter.add_mesh(data, **mesh_info) - base = basename(export_path) + dir, base = split(export_path) name, _ = splitext(base) - html_path = f"{name}.html" + html_path = join(dir, f"{name}.html") export_gl(plotter, export_path, with_alpha=True) export_modelviewer(html_path, base, "Testing visualization") From 77cb93df898d5ea9caad275f80af24fe5f92a632 Mon Sep 17 00:00:00 2001 From: Carifio24 Date: Mon, 18 Dec 2023 17:04:49 -0500 Subject: [PATCH 2/3] Add volume UI and make tweaks to scatter UI. --- glue_ar/export_scatter.ui | 172 +++++++++++++------------------------- glue_ar/export_volume.ui | 103 +++++++++++++++++++++++ 2 files changed, 163 insertions(+), 112 deletions(-) create mode 100644 glue_ar/export_volume.ui diff --git a/glue_ar/export_scatter.ui b/glue_ar/export_scatter.ui index 481b672..48b1d95 100644 --- a/glue_ar/export_scatter.ui +++ b/glue_ar/export_scatter.ui @@ -7,21 +7,76 @@ 0 0 327 - 414 + 416 Export 3D Scatter - - - + + + Select the export filetype - + + + + + + + Select the export settings for each layer + + + + + + + + + + + 0 + 0 + + + + <html><head/><body>The resolution values affect how many points are used to draw each sphere. Higher values mean better resolution, but a larger exported file. The total number of points per sphere is <div>2 + (phi_resolution - 2) * theta_resolution</div></body></html> + + + true + + + + + + + + + + Theta resolution: + + + + + + + Phi resolution: + + + + + + + + + + + + + @@ -54,113 +109,6 @@ - - - - - - - Theta resolution: - - - - - - - Phi resolution: - - - - - - - - - - - - - - - - Qt::Horizontal - - - - 33 - 20 - - - - - - - - - - - Qt::Horizontal - - - - 38 - 20 - - - - - - - - - - - Select the export settings for each layer - - - - - - - - 0 - 0 - - - - <html><head/><body>The resolution values affect how many points are used to draw each sphere. Higher values mean better resolution, but a larger exported file. The total number of points per sphere is <div>2 + (phi_resolution - 2) * theta_resolution</div></body></html> - - - true - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - diff --git a/glue_ar/export_volume.ui b/glue_ar/export_volume.ui new file mode 100644 index 0000000..7029f6a --- /dev/null +++ b/glue_ar/export_volume.ui @@ -0,0 +1,103 @@ + + + Dialog + + + + 0 + 0 + 321 + 414 + + + + Export 3D Volume + + + + + + Select the export filetype + + + + + + + + + + Set the export settings for each layer + + + + + + + + + + + + + Use Gaussian filter + + + + + + + + + + Smoothing iterations + + + + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 110 + 20 + + + + + + + + Cancel + + + + + + + Export + + + + + + + + + + + From 84cd81c3ac829b2b4769fa7247180aa2a548897f Mon Sep 17 00:00:00 2001 From: Carifio24 Date: Mon, 18 Dec 2023 17:52:47 -0500 Subject: [PATCH 3/3] Clean up a few minor issues. --- glue_ar/export_volume.ui | 6 +++--- glue_ar/tools.py | 37 +++++++++++++++++++++++++++++-------- glue_ar/volume.py | 23 ++++++++++++----------- 3 files changed, 44 insertions(+), 22 deletions(-) diff --git a/glue_ar/export_volume.ui b/glue_ar/export_volume.ui index 7029f6a..214102d 100644 --- a/glue_ar/export_volume.ui +++ b/glue_ar/export_volume.ui @@ -55,7 +55,7 @@ - + @@ -80,14 +80,14 @@ - + Cancel - + Export diff --git a/glue_ar/tools.py b/glue_ar/tools.py index f0c644e..a0ac45a 100644 --- a/glue_ar/tools.py +++ b/glue_ar/tools.py @@ -10,6 +10,7 @@ from glue.viewers.common.tool import Tool from glue_ar.export_scatter import ExportScatterDialog +from glue_ar.export_volume import ExportVolumeDialog from glue_ar.scatter import scatter_layer_as_multiblock from glue_ar.export import export_gl, export_modelviewer from glue_ar.volume import create_meshes @@ -36,7 +37,7 @@ def activate(self): if result == QDialog.Rejected: return - export_path, _ = compat.getsavefilename(parent=self.viewer, basedir=f"scatter.{dialog.state.filetype}".lower()) + export_path, _ = compat.getsavefilename(parent=self.viewer, basedir=f"scatter.{dialog.state.filetype.lower()}") if not export_path: return @@ -49,11 +50,13 @@ def activate(self): plotter.add_mesh(data, **mesh_info) dir, base = split(export_path) - name, _ = splitext(base) + name, ext = splitext(base) html_path = join(dir, f"{name}.html") - export_gl(plotter, export_path, with_alpha=True) - - export_modelviewer(html_path, base, "Testing visualization") + if ext: + export_gl(plotter, export_path, with_alpha=True) + export_modelviewer(html_path, base, "Testing visualization") + else: + plotter.export_obj(export_path) @viewer_tool @@ -64,10 +67,28 @@ class GLVolumeExportTool(Tool): tool_tip = "Export the current view to a glB file" def activate(self): + + dialog = ExportVolumeDialog(parent=self.viewer, viewer_state=self.viewer.state) + result = dialog.exec_() + if result == QDialog.Rejected: + return + + export_path, _ = compat.getsavefilename(parent=self.viewer, basedir=f"volume.{dialog.state.filetype.lower()}") + if not export_path: + return + plotter = pv.Plotter() - meshes = create_meshes(self.viewer.state, use_gaussian_filter=True, smoothing_iteration_count=10) + layer_states = [state for state in self.viewer.state.layers if state.visible] + meshes = create_meshes(self.viewer.state, layer_states, dialog.info_dictionary) for data in meshes.values(): mesh = data.pop("mesh") plotter.add_mesh(mesh, color=data["color"], opacity=data["opacity"]) - export_gl(plotter, "volume.gltf", with_alpha=True) # Do we want alpha for volume renderings? - export_modelviewer("volume.html", "volume.gltf", "Testing visualization") + + dir, base = split(export_path) + name, ext = splitext(base) + html_path = join(dir, f"{name}.html") + if ext == 'glTF': + export_gl(plotter, export_path, with_alpha=True) # Do we want alpha for volume renderings? + export_modelviewer(html_path, base, "Testing visualization") + else: + plotter.export_obj(export_path) diff --git a/glue_ar/volume.py b/glue_ar/volume.py index 9a1036c..c649921 100644 --- a/glue_ar/volume.py +++ b/glue_ar/volume.py @@ -8,7 +8,7 @@ # For the 3D volume viewer # This is largely lifted from Luca's plugin -def create_meshes(viewer_state, layer_states=None, use_gaussian_filter=False, smoothing_iteration_count=0): +def create_meshes(viewer_state, layer_states, parameters): meshes = {} @@ -28,7 +28,7 @@ def create_meshes(viewer_state, layer_states=None, use_gaussian_filter=False, sm target_cid=layer_state.attribute ) - meshes[layer_state.layer.uuid] = { + meshes[layer_state.layer.label] = { "data": data, "color": layer_color(layer_state), "opacity": layer_state.alpha, @@ -46,10 +46,10 @@ def create_meshes(viewer_state, layer_states=None, use_gaussian_filter=False, sm subset_state=layer_state.layer.subset_state ) - datacube = meshes[parent.uuid]["data"] + datacube = meshes[parent.label]["data"] data = subcube * datacube - meshes[layer_state.layer.uuid] = { + meshes[layer_state.layer.label] = { "data": data, "isomin": isomin_for_layer(viewer_state, layer_state), "opacity": layer_state.alpha, @@ -58,17 +58,17 @@ def create_meshes(viewer_state, layer_states=None, use_gaussian_filter=False, sm } # Delete sublayer data from parent data - if parent.uuid in meshes: - parent_data = meshes[parent.uuid]["data"] + if parent.label in meshes: + parent_data = meshes[parent.label]["data"] parent_data = invert(subcube) * parent_data - meshes[parent.uuid]["data"] = parent_data + meshes[parent.label]["data"] = parent_data - for item in meshes.values(): + for label, item in meshes.items(): data = item["data"] isomin = item["isomin"] - if use_gaussian_filter: + if parameters[label]["gaussian_filter"]: data = gaussian_filter(data, 1) # Conventions between pyvista and glue data storage @@ -82,8 +82,9 @@ def create_meshes(viewer_state, layer_states=None, use_gaussian_filter=False, sm grid.point_data["values"] = data.flatten(order="F") isodata = grid.contour([isomin]) - if smoothing_iteration_count > 0: - isodata = isodata.smooth(n_iter=smoothing_iteration_count) + iterations = parameters[label]["smoothing_iterations"] + if iterations > 0: + isodata = isodata.smooth(n_iter=iterations) item["mesh"] = isodata