Skip to content

Commit

Permalink
Merge pull request #17 from Carifio24/local-qr-code
Browse files Browse the repository at this point in the history
Add tool for displaying local QR code for AR view
  • Loading branch information
Carifio24 authored Jan 2, 2024
2 parents f99999d + 2ab5041 commit 06abeb0
Show file tree
Hide file tree
Showing 14 changed files with 260 additions and 85 deletions.
6 changes: 4 additions & 2 deletions glue_ar/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ def setup():
from glue_qt.config import qt_client

from glue_vispy_viewers.scatter.scatter_viewer import VispyScatterViewer
VispyScatterViewer.tools += ["ar:scatter-gl"]
VispyScatterViewer.tools += ["ar"]
VispyScatterViewer.subtools["ar"] = ["ar:export", "ar:qr"]

from glue_vispy_viewers.volume.volume_viewer import VispyVolumeViewer
VispyVolumeViewer.tools += ["ar:volume-gl"]
VispyVolumeViewer.tools += ["ar"]
VispyVolumeViewer.subtools["ar"] = ["ar:export", "ar:qr"]
2 changes: 1 addition & 1 deletion glue_ar/export.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def export_gl(plotter, filepath, with_alpha=True):
plotter.export_gltf(gltf_path)

if glb or with_alpha:
gl = GLTF.load(gltf_path)
gl = GLTF.load_gltf(gltf_path)
if with_alpha and gl.model.materials is not None:
for material in gl.model.materials:
material.alphaMode = "BLEND"
Expand Down
14 changes: 7 additions & 7 deletions glue_ar/export_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,31 +42,31 @@ class ARExportDialogState(State):
filetype = SelectionCallbackProperty()
layer = SelectionCallbackProperty()

def __init__(self, viewer_state):
def __init__(self, layers):

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.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_state=None):
def __init__(self, parent=None, viewer=None):

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

self.viewer_state = viewer_state
self.state = ARExportDialogState(self.viewer_state)
self.viewer = viewer
layers = [layer for layer in self.viewer.layers if layer.enabled and layer.state.visible]
self.state = ARExportDialogState(layers)
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)]()
layer.layer.label: ar_layer_export.members[type(layer.state)]()
for layer in layers
}

Expand Down
Binary file added glue_ar/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
42 changes: 42 additions & 0 deletions glue_ar/qr.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import os
from io import BytesIO
from PIL import Image
import socket
import segno


GLUE_LOGO = os.path.abspath(os.path.join(os.path.dirname(__file__), "logo.png"))
GLUE_RED = "#eb1c24"


def get_local_ip():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.settimeout(0)
try:
# doesn't even have to be reachable
s.connect(('10.254.254.254', 1))
IP = s.getsockname()[0]
except Exception:
IP = '127.0.0.1'
finally:
s.close()
return IP


def create_qr(url):
qr = segno.make_qr(url)
out = BytesIO()
qr.save(out, kind="png", scale=7, dark=GLUE_RED, light="white")
out.seek(0)
img = Image.open(out)
img = img.convert("RGB")
width, height = img.size
logo_max_size = height // 3
logo_img = Image.open(GLUE_LOGO)
# Resize the logo to logo_max_size
logo_img.thumbnail((logo_max_size, logo_max_size), Image.Resampling.LANCZOS)
# Calculate the center of the QR code
box = ((width - logo_img.size[0]) // 2, (height - logo_img.size[1]) // 2)
img.paste(logo_img, box)
return img

19 changes: 19 additions & 0 deletions glue_ar/qr_dialog.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from os.path import dirname

from PIL.ImageQt import ImageQt
from glue_qt.utils import load_ui
from qtpy.QtWidgets import QDialog, QSizePolicy
from qtpy.QtGui import QPixmap


class QRDialog(QDialog):

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

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

self.img = ImageQt(img)
self.pix = QPixmap.fromImage(self.img)
self.ui = load_ui("qr_dialog.ui", self, directory=dirname(__file__))
self.ui.label_image.setPixmap(self.pix)
self.setFixedSize(300, 325)
64 changes: 64 additions & 0 deletions glue_ar/qr_dialog.ui
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>315</width>
<height>351</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>View in AR</string>
</property>
<widget class="QLabel" name="label_message">
<property name="geometry">
<rect>
<x>9</x>
<y>9</y>
<width>300</width>
<height>32</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Note: This QR code will only work for devices
connected to the same network as this computer</string>
</property>
</widget>
<widget class="QLabel" name="label_image">
<property name="geometry">
<rect>
<x>10</x>
<y>50</y>
<width>300</width>
<height>300</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
</widget>
</widget>
<resources/>
<connections/>
</ui>
3 changes: 3 additions & 0 deletions glue_ar/scatter.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ def scatter_layer_as_multiblock(viewer_state, layer_state,
else:
mask = None

theta_resolution = int(theta_resolution)
phi_resolution = int(phi_resolution)
fixed_color = layer_state.color_mode == "Fixed"
data = xyz_for_layer(viewer_state, layer_state,
preserve_aspect=viewer_state.native_aspect,
Expand All @@ -121,6 +123,7 @@ def scatter_layer_as_multiblock(viewer_state, layer_state,
factor = max((abs(b[1] - b[0]) for b in bounds))
if layer_state.size_mode == "Fixed":
radius = layer_state.size_scaling * sqrt((layer_state.size)) / (10 * factor)
print(radius)
spheres = [pv.Sphere(center=p, radius=radius,
phi_resolution=phi_resolution,
theta_resolution=theta_resolution) for p in data]
Expand Down
19 changes: 19 additions & 0 deletions glue_ar/server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from os.path import split

from http.server import SimpleHTTPRequestHandler
from socketserver import TCPServer

def create_handler(directory):

class ARHttpRequestHandler(SimpleHTTPRequestHandler):

def __init__(self, *args, **kwargs):
super().__init__(*args, directory=directory, **kwargs)

return ARHttpRequestHandler


def run_ar_server(port, directory):
handler_cls = create_handler(directory)
server = TCPServer(("", port), handler_cls)
return server
Loading

0 comments on commit 06abeb0

Please sign in to comment.