Skip to content

Commit

Permalink
Merge pull request #30 from Carifio24/refactor
Browse files Browse the repository at this point in the history
Refactor package and add meshoptimizer as compression option
  • Loading branch information
Carifio24 authored Jul 7, 2024
2 parents e15f96a + 67e34db commit 9714968
Show file tree
Hide file tree
Showing 24 changed files with 251 additions and 231 deletions.
30 changes: 21 additions & 9 deletions glue_ar/__init__.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,41 @@
from glue_ar.export_scatter import * # noqa
from glue_ar.export_volume import * # noqa
from glue_ar.tools import * # noqa
from glue_ar.common.scatter_export_options import * # noqa
from glue_ar.common.volume_export_options import * # noqa


def setup_qt():
try:
from glue_vispy_viewers.scatter.qt.scatter_viewer import VispyScatterViewer
except ImportError:
from glue_vispy_viewers.scatter.scatter_viewer import VispyScatterViewer
VispyScatterViewer.tools = [t for t in VispyScatterViewer.tools] + ["ar"]

from glue_ar.qt.export_tool import QtARExportTool # noqa

VispyScatterViewer.subtools = {
**VispyScatterViewer.subtools,
"save": VispyScatterViewer.subtools["save"] + ["save:ar"]
}
VispyScatterViewer.subtools["ar"] = ["ar:qr"]

try:
from glue_vispy_viewers.volume.qt.volume_viewer import VispyVolumeViewer
except ImportError:
from glue_vispy_viewers.volume.volume_viewer import VispyVolumeViewer
VispyVolumeViewer.tools = [t for t in VispyVolumeViewer.tools] + ["ar"]
VispyVolumeViewer.subtools = {
**VispyVolumeViewer.subtools,
"save": VispyVolumeViewer.subtools["save"] + ["save:ar"]
}
VispyVolumeViewer.subtools["ar"] = ["ar:qr"]

try:
from glue_ar.qt.qr_tool import ARLocalQRTool # noqa
VispyScatterViewer.tools = [t for t in VispyScatterViewer.tools] + ["ar"]
VispyVolumeViewer.tools = [t for t in VispyVolumeViewer.tools] + ["ar"]
VispyScatterViewer.subtools["ar"] = ["ar:qr"]
VispyVolumeViewer.subtools["ar"] = ["ar:qr"]
except ImportError:
pass


def setup_jupyter():
from glue_ar.jupyter.export_tool import JupyterARExportTool # noqa
from glue_vispy_viewers.scatter.jupyter import JupyterVispyScatterViewer
from glue_vispy_viewers.volume.jupyter import JupyterVispyVolumeViewer
JupyterVispyScatterViewer.tools = [t for t in JupyterVispyScatterViewer.tools] + ["save:ar_jupyter"]
Expand All @@ -37,10 +45,14 @@ def setup_jupyter():
def setup():
try:
setup_qt()
except ImportError:
except ImportError as e:
print("Qt setup error")
print(e)
pass

try:
setup_jupyter()
except ImportError:
except ImportError as e:
print("Jupyter setup error")
print(e)
pass
File renamed without changes
29 changes: 0 additions & 29 deletions glue_ar/common.py

This file was deleted.

44 changes: 31 additions & 13 deletions glue_ar/export.py → glue_ar/common/export.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,17 @@
from glue_vispy_viewers.scatter.scatter_viewer import Vispy3DScatterViewerState
from glue_vispy_viewers.volume.layer_state import VolumeLayerState

from glue_ar.scatter import scatter_layer_as_multiblock
from glue_ar.common.scatter import scatter_layer_as_multiblock
from glue_ar.utils import bounds_3d_from_layers, xyz_bounds
from glue_ar.volume import bounds_3d, meshes_for_volume_layer
from glue_ar.common.volume import bounds_3d, meshes_for_volume_layer


GLTF_PIPELINE_FILEPATH = join(dirname(abspath(__file__)), "js",
"node_modules", "gltf-pipeline",
"bin", "gltf-pipeline.js")
NODE_MODULES_DIR = join(abspath(join(dirname(abspath(__file__)), "..")),
"js", "node_modules")


GLTF_PIPELINE_FILEPATH = join(NODE_MODULES_DIR, "gltf-pipeline", "bin", "gltf-pipeline.js")
GLTFPACK_FILEPATH = join(NODE_MODULES_DIR, "gltfpack", "cli.js")


def export_meshes(meshes, output_path):
Expand All @@ -32,10 +35,27 @@ def export_meshes(meshes, output_path):
raise ValueError("Unsupported extension!")


def compress_gl(filepath):
def compress_gltf_pipeline(filepath):
run(["node", GLTF_PIPELINE_FILEPATH, "-i", filepath, "-o", filepath, "-d"], capture_output=True)


def compress_gltfpack(filepath):
run(["node", GLTFPACK_FILEPATH, "-i", filepath, "-o", filepath], capture_output=True)


COMPRESSORS = {
"draco": compress_gltf_pipeline,
"meshoptimizer": compress_gltfpack
}


def compress_gl(filepath, method="draco"):
compressor = COMPRESSORS.get(method, None)
if compressor is None:
raise ValueError("Invalid compression method specified")
compressor(filepath)


def export_gl_by_extension(exporter, filepath):
_, ext = splitext(filepath)
if ext == ".glb":
Expand All @@ -52,7 +72,7 @@ def export_gl_by_extension(exporter, filepath):
# matters into our own hands.
# We want alphaMode as BLEND
# see https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#alpha-coverage
def export_gl(plotter, filepath, with_alpha=True, compress=True):
def export_gl(plotter, filepath, with_alpha=True, compression="draco"):
path, ext = splitext(filepath)
gltf_path = filepath
glb = ext == ".glb"
Expand All @@ -66,8 +86,8 @@ def export_gl(plotter, filepath, with_alpha=True, compress=True):
for material in gl.model.materials:
material.alphaMode = "BLEND"
export_gl_by_extension(gl, filepath)
if compress:
compress_gl(filepath)
if compression != "none":
compress_gl(filepath, method=compression)
if glb:
remove(gltf_path)

Expand Down Expand Up @@ -212,15 +232,13 @@ def create_plotter(viewer, state_dictionary):
return plotter


def export_to_ar(viewer, filepath, state_dict, compress=True):
def export_to_ar(viewer, filepath, state_dict, compression="draco"):
dir, base = split(filepath)
name, ext = splitext(base)
plotter = create_plotter(viewer, state_dict)
html_path = join(dir, f"{name}.html")
if ext in [".gltf", ".glb"]:
export_gl(plotter, filepath, with_alpha=True, compress=compress)
if compress:
compress_gl(filepath)
export_gl(plotter, filepath, with_alpha=True, compression=compression)
export_modelviewer(html_path, base, viewer.state.title)
else:
plotter.export_obj(filepath)
44 changes: 44 additions & 0 deletions glue_ar/common/export_state.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
from echo import SelectionCallbackProperty
from glue.config import DictRegistry
from glue.core.data_combo_helper import ComboHelper
from glue.core.state_objects import State


__all__ = ['ar_layer_export']


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()
compression = SelectionCallbackProperty(True)

def __init__(self, layers):

super(ARExportDialogState, self).__init__()

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

self.compression_helper = ComboHelper(self, 'compression')
self.compression_helper.choices = ['None', 'Draco', 'Meshoptimizer']

self.layers = layers
self.layer_helper = ComboHelper(self, 'layer')
self.layer_helper.choices = [state.layer.label for state in self.layers]
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from echo import CallbackProperty
from glue.core.state_objects import State
from glue_ar.export_dialog import ar_layer_export
from glue_ar.common.export_state import ar_layer_export
from glue_vispy_viewers.scatter.layer_state import ScatterLayerState

__all__ = ["ARScatterExportOptions"]
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from echo import CallbackProperty
from glue.core.state_objects import State
from glue_ar.export_dialog import ar_layer_export
from glue_ar.common.export_state import ar_layer_export
from glue_vispy_viewers.volume.layer_state import VolumeLayerState

__all__ = ["ARVolumeExportOptions"]
Expand Down
9 changes: 3 additions & 6 deletions glue_ar/tools/jupyter.py → glue_ar/jupyter/export_tool.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import os
from os import getcwd
from os.path import exists

from glue.config import viewer_tool
from glue.viewers.common.tool import Tool

from glue_ar.export import export_to_ar
from glue_ar.common.export import export_to_ar
from glue_ar.utils import AR_ICON

import ipyvuetify as v # noqa
from ipywidgets import HBox, Layout # noqa
Expand All @@ -15,9 +15,6 @@
__all__ = ["JupyterARExportTool"]


AR_ICON = os.path.abspath(os.path.join(os.path.dirname(__file__), "ar"))


@viewer_tool
class JupyterARExportTool(Tool):
icon = AR_ICON
Expand Down Expand Up @@ -92,4 +89,4 @@ def on_no_click(button, event, data):
self.viewer.output_widget.clear_output()

def save_figure(self, filepath):
export_to_ar(self.viewer, filepath, state_dict={}, compress=True)
export_to_ar(self.viewer, filepath, state_dict={}, compression="draco")
47 changes: 6 additions & 41 deletions glue_ar/export_dialog.py → glue_ar/qt/export_dialog.py
Original file line number Diff line number Diff line change
@@ -1,58 +1,21 @@
import os

from echo import CallbackProperty, 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 glue_ar.common.export_state import ARExportDialogState, ar_layer_export

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


__all__ = ['ar_layer_export', 'ARExportDialog']
__all__ = ['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()
draco = CallbackProperty(True)

def __init__(self, layers):

super(ARExportDialogState, self).__init__()

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

self.layers = layers
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=None):
Expand Down Expand Up @@ -99,6 +62,8 @@ def _widgets_for_property(self, instance, property, display_name):
widget.setValidator(validator)
self._layer_connections.append(connect_float_text(instance, property, widget))
return [label, widget]
else:
return []

def _clear_layout(self, layout):
if layout is not None:
Expand Down Expand Up @@ -127,4 +92,4 @@ def _update_layer_ui(self, layer):

def _on_filetype_change(self, filetype):
gl = filetype.lower() in ["gltf", "glb"]
self.ui.bool_draco.setVisible(gl)
self.ui.combosel_compression.setVisible(gl)
Loading

0 comments on commit 9714968

Please sign in to comment.