Skip to content

Commit

Permalink
Merge pull request #9 from Carifio24/ui-layer-types
Browse files Browse the repository at this point in the history
Support multiple layer types in tool UI, fix colormap bug
  • Loading branch information
Carifio24 authored Dec 23, 2023
2 parents 76fa899 + 39cd884 commit a97cd05
Show file tree
Hide file tree
Showing 9 changed files with 183 additions and 316 deletions.
2 changes: 2 additions & 0 deletions glue_ar/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from glue_ar.export_scatter import *
from glue_ar.export_volume import *
from glue_ar.tools import *

def setup():
Expand Down
2 changes: 1 addition & 1 deletion glue_ar/export.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def export_gl(plotter, filepath, with_alpha=True):

if glb or with_alpha:
gl = GLTF.load(gltf_path)
if with_alpha:
if with_alpha and gl.model.materials is not None:
for material in gl.model.materials:
material.alphaMode = "BLEND"
export_gl_by_extension(gl, filepath)
Expand Down
126 changes: 126 additions & 0 deletions glue_ar/export_dialog.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import os

from echo import SelectionCallbackProperty
from echo.qt import autoconnect_callbacks_to_qt, connect_checkable_button, connect_float_text

from glue.config import DictRegistry
from glue.core.data_combo_helper import ComboHelper
from glue.core.state_objects import State
from glue_qt.utils import load_ui
from qtpy.QtGui import QDoubleValidator, QIntValidator


from qtpy.QtWidgets import QCheckBox, QDialog, QHBoxLayout, QLabel, QLineEdit
from qtpy.QtGui import QIntValidator, QDoubleValidator


__all__ = ['ar_layer_export', 'ARExportDialog']


def display_name(prop):
return prop.replace("_", " ").capitalize()


class ARExportLayerOptionsRegistry(DictRegistry):

def add(self, layer_state_cls, layer_options_state):
if not issubclass(layer_options_state, State):
raise ValueError("Layer options must be a glue State type")
self._members[layer_state_cls] = layer_options_state

def __call__(self, layer_state_cls):
def adder(export_state_class):
self.add(layer_state_cls, export_state_class)
return adder


ar_layer_export = ARExportLayerOptionsRegistry()


class ARExportDialogState(State):

filetype = SelectionCallbackProperty()
layer = SelectionCallbackProperty()

def __init__(self, viewer_state):

super(ARExportDialogState, self).__init__()

self.filetype_helper = ComboHelper(self, 'filetype')
self.filetype_helper.choices = ['glTF', 'OBJ']

self.layers = [state for state in viewer_state.layers if state.visible]
self.layer_helper = ComboHelper(self, 'layer')
self.layer_helper.choices = [state.layer.label for state in self.layers]


class ARExportDialog(QDialog):

def __init__(self, parent=None, viewer_state=None):

super(ARExportDialog, self).__init__(parent=parent)

self.viewer_state = viewer_state
self.state = ARExportDialogState(self.viewer_state)
self.ui = load_ui('export_dialog.ui', self, directory=os.path.dirname(__file__))

layers = [state for state in self.viewer_state.layers if state.visible]
self.state_dictionary = {
layer.layer.label: ar_layer_export.members[type(layer)]()
for layer in layers
}

self._connections = autoconnect_callbacks_to_qt(self.state, self.ui)
self._layer_connections = []

self.ui.button_cancel.clicked.connect(self.reject)
self.ui.button_ok.clicked.connect(self.accept)

self.state.add_callback('layer', self._update_layer_ui)

self._update_layer_ui(self.state.layer)

def _widgets_for_property(self, instance, property, display_name):
value = getattr(instance, property)
t = type(value)
if t is bool:
widget = QCheckBox()
widget.setChecked(value)
widget.setText(display_name)
self._layer_connections.append(connect_checkable_button(instance, property, widget))
return [widget]
elif t in [int, float]:
label = QLabel()
prompt = f"{display_name}:"
label.setText(prompt)
widget = QLineEdit()
validator = QIntValidator() if t is int else QDoubleValidator()
widget.setText(str(value))
widget.setValidator(validator)
self._layer_connections.append(connect_float_text(instance, property, widget))
return [label, widget]

def _clear_layout(self, layout):
if layout is not None:
while layout.count():
item = layout.takeAt(0)
widget = item.widget()
if widget is not None:
widget.deleteLater()
else:
self._clear_layout(item.layout())

def _clear_layer_layout(self):
self._clear_layout(self.ui.layer_layout)

def _update_layer_ui(self, layer):
self._clear_layer_layout()
self._layer_connections = []
state = self.state_dictionary[layer]
for property in state.callback_properties():
row = QHBoxLayout()
name = display_name(property)
widgets = self._widgets_for_property(state, property, name)
for widget in widgets:
row.addWidget(widget)
self.ui.layer_layout.addRow(row)
58 changes: 16 additions & 42 deletions glue_ar/export_volume.ui → glue_ar/export_dialog.ui
Original file line number Diff line number Diff line change
Expand Up @@ -14,55 +14,13 @@
<string>Export 3D Volume</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_filetype_message">
<property name="text">
<string>Select the export filetype</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QComboBox" name="combosel_filetype"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_settings_message">
<property name="text">
<string>Set the export settings for each layer</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QListWidget" name="listsel_layer"/>
</item>
<item row="4" column="0">
<widget class="QWidget" name="widget_2" native="true">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QCheckBox" name="bool_use_gaussian_filter">
<property name="text">
<string>Use Gaussian filter</string>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="widget_3" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_smoothing_iterations">
<property name="text">
<string>Smoothing iterations</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="valuetext_smoothing_iterations"/>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item row="5" column="0">
<widget class="QWidget" name="widget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
Expand Down Expand Up @@ -96,6 +54,22 @@
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QComboBox" name="combosel_filetype"/>
</item>
<item row="3" column="0">
<widget class="QListWidget" name="listsel_layer"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_filetype_message">
<property name="text">
<string>Select the export filetype</string>
</property>
</widget>
</item>
<item row="4" column="0">
<layout class="QFormLayout" name="layer_layout"/>
</item>
</layout>
</widget>
<resources/>
Expand Down
76 changes: 6 additions & 70 deletions glue_ar/export_scatter.py
Original file line number Diff line number Diff line change
@@ -1,77 +1,13 @@
import os

from qtpy.QtWidgets import QDialog, QListWidgetItem

from echo import CallbackProperty
from glue.core.state_objects import State
from glue.core.data_combo_helper import ComboHelper
from glue_qt.utils import load_ui
from glue_ar.export_dialog import ar_layer_export
from glue_vispy_viewers.scatter.layer_state import ScatterLayerState

from echo import CallbackProperty, SelectionCallbackProperty
from echo.qt import autoconnect_callbacks_to_qt
__all__ = ["ARScatterExportOptions"]

__all__ = ["ExportScatterDialog"]

# Note that this class only holds the state that is
# currently displayed in the dialog. In particular,
# this means that `theta_resolution` and `phi_resolution`
# represent the resolutions for `layer`
class ExportScatterDialogState(State):
@ar_layer_export(ScatterLayerState)
class ARScatterExportOptions(State):

filetype = SelectionCallbackProperty()
layer = SelectionCallbackProperty()
theta_resolution = CallbackProperty(8)
phi_resolution = CallbackProperty(8)

def __init__(self, viewer_state):

super(ExportScatterDialogState, self).__init__()

self.filetype_helper = ComboHelper(self, 'filetype')
self.filetype_helper.choices = ['glTF', 'OBJ']

self.layers = [state for state in viewer_state.layers if state.visible]
self.layer_helper = ComboHelper(self, 'layer')
self.layer_helper.choices = [state.layer.label for state in self.layers]


class ExportScatterDialog(QDialog):

def __init__(self, parent=None, viewer_state=None):

super(ExportScatterDialog, self).__init__(parent=parent)

self.viewer_state = viewer_state
self.state = ExportScatterDialogState(self.viewer_state)
self.ui = load_ui('export_scatter.ui', self, directory=os.path.dirname(__file__))

layers = [state for state in self.viewer_state.layers if state.visible]
self.info_dictionary = {
layer.layer.label: {
"theta_resolution": 8,
"phi_resolution": 8
} for layer in layers
}

for layer in layers:
item = QListWidgetItem(layer.layer.label)
self.ui.listsel_layer.addItem(item)

self._connections = autoconnect_callbacks_to_qt(self.state, self.ui)

self.ui.button_cancel.clicked.connect(self.reject)
self.ui.button_ok.clicked.connect(self.accept)

self.state.add_callback('theta_resolution', self._on_theta_resolution_change)
self.state.add_callback('phi_resolution', self._on_phi_resolution_change)
self.state.add_callback('layer', self._on_layer_change)

def _on_theta_resolution_change(self, resolution):
self.info_dictionary[self.state.layer]["theta_resolution"] = int(resolution)

def _on_phi_resolution_change(self, resolution):
self.info_dictionary[self.state.layer]["phi_resolution"] = int(resolution)

def _on_layer_change(self, layer):
self.state.theta_resolution = self.info_dictionary[layer]["theta_resolution"]
self.state.phi_resolution = self.info_dictionary[layer]["phi_resolution"]

Loading

0 comments on commit a97cd05

Please sign in to comment.