Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pyqtgraph replacement in webgl upgrade #1636

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 17 additions & 4 deletions tools/Python/mcdisplay/webgl/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,28 @@ set(WORK "${PROJECT_BINARY_DIR}/work")
# Configure fallback script
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/mcdisplay.in" "${WORK}/${P}display" @ONLY)

# Main script, including rename mc/mxdisplay
# Dist
install(
PROGRAMS "${PROJECT_SOURCE_DIR}/mcdisplay.py"
DIRECTORY "${PROJECT_SOURCE_DIR}/dist"
DESTINATION "${DEST_TOOLDIR}/${TOOLS_NAME}"
RENAME "${P}display.py"
)


# Node modules
install(
DIRECTORY "${PROJECT_SOURCE_DIR}/node_modules"
DESTINATION "${DEST_TOOLDIR}/${TOOLS_NAME}"
)

# Main script, including rename mc/mxdisplay
install(
PROGRAMS "${PROJECT_SOURCE_DIR}/mcdisplay.py"
DESTINATION "${DEST_TOOLDIR}/${TOOLS_NAME}"
RENAME "${P}display.py"
)

# Other .py infrastructure
foreach(NAME mcdisplay.js Lut.js OrbitControls.js dat.gui.min.js jquery.min.js three.min.js template.html __init__.py)
foreach(NAME start-vite.js package.json mcdisplay.js Lut.js OrbitControls.js dat.gui.min.js jquery.min.js three.min.js template.html __init__.py)
install(
FILES "${PROJECT_SOURCE_DIR}/${NAME}"
DESTINATION "${DEST_TOOLDIR}/${TOOLS_NAME}"
Expand Down
3,946 changes: 3,946 additions & 0 deletions tools/Python/mcdisplay/webgl/dist/assets/index-l7INFY-H.js

Large diffs are not rendered by default.

107 changes: 74 additions & 33 deletions tools/Python/mcdisplay/webgl/mcdisplay.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,27 @@
'''
mcdisplay webgl script.
'''
import os
import sys
import logging
import json
import subprocess
import webbrowser
import time
from pathlib import Path
from http.server import HTTPServer, SimpleHTTPRequestHandler
import threading
import socket


sys.path.append(str(Path(__file__).resolve().parent.parent.parent))

from mccodelib import mccode_config
from mccodelib.mcdisplayutils import McDisplayReader
from mccodelib.instrgeom import Vector3d
from mccodelib.utils import get_file_text_direct
from threading import Thread
from shutil import copy as shutil_copy, copytree, ignore_patterns

class SimpleWriter(object):
''' a minimal, django-omiting "glue file" writer tightly coupled to some comments in the file template.html '''
Expand Down Expand Up @@ -86,7 +95,7 @@ def _write_html(instrument, html_filepath, first=None, last=None, invcanvas=Fals

def write_browse(instrument, raybundle, dirname, instrname, nobrowse=None, first=None, last=None, invcanvas=None, **kwds):
''' writes instrument definitions to html/ js '''
from shutil import copy as shutil_copy
print("Launching WebGL...")
def copy(a, b):
shutil_copy(str(a), str(b))

Expand All @@ -97,42 +106,74 @@ def copy(a, b):
if not dest.exists():
dest.mkdir(parents=True)

# copy mcdisplay.js to _mcdisplay.js
copy(source.joinpath('mcdisplay.js'), dest.joinpath('_mcdisplay.js'))
# copy JavaScript files without name changes
for file in ('three.min', 'dat.gui.min', 'OrbitControls', 'Lut', 'jquery.min'):
copy(source.joinpath(f'{file}.js'), dest.joinpath(f'{file}.js'))

# write html
html_filepath = str(dest.joinpath('index.html'))
_write_html(instrument, html_filepath, first=first, last=last, invcanvas=invcanvas)

# write instrument
json_instr = 'MCDATA_instrdata = %s;' % json.dumps(instrument.jsonize(), indent=0)
file_save(json_instr, dest.joinpath('_instr.js'))

# write particles
json_particles = 'MCDATA_particledata = %s;' % json.dumps(raybundle.jsonize(), indent=0)
file_save(json_particles, dest.joinpath('_particles.js'))
# Copy the app files
copytree(source.joinpath('dist'), dest.joinpath('dist'))

# Workaround for allowing non-relative paths to instrname
# see https://github.com/McStasMcXtrace/McCode/issues/1426
temp_instrname = Path(instrname)
instrname = temp_instrname.name
# Copy package.json from source to dest
package_json_source = source.joinpath('package.json')
package_json_dest = dest.joinpath('dist/package.json')
shutil_copy(package_json_source, package_json_dest)

# copy McCode instrument (this *may* be a binary!)
shutil_copy(instrname, str(dest.joinpath(instrname)))

# exit if nobrowse flag has been set
# Copy node_modules from source to dist
node_modules_source = source.joinpath('node_modules')
node_modules_dest = dest.joinpath('dist/node_modules')
copytree(node_modules_source, node_modules_dest, dirs_exist_ok=True, ignore=ignore_patterns('*.log', '*.cache'))

# Ensure execute permissions for vite binary
vite_bin = node_modules_dest.joinpath('.bin/vite')
os.chmod(vite_bin, 0o755)

# Copy start-vite.js script to destination
start_vite_source = source.joinpath('start-vite.js')
start_vite_dest = dest.joinpath('dist/start-vite.js')
shutil_copy(start_vite_source, start_vite_dest)

# Write instrument
json_instr = '%s' % json.dumps(instrument.jsonize(), indent=2)
file_save(json_instr, dest.joinpath('dist/instrument.json'))

# Write particles
json_particles = '%s' % json.dumps(raybundle.jsonize(), indent=2)
file_save(json_particles, dest.joinpath('dist/particles.json'))

# Exit if nobrowse flag has been set
if nobrowse is not None and nobrowse:
return

# open a web-browser in a cross-platform way
try:
subprocess.Popen('%s %s' % (mccode_config.configuration['BROWSER'], html_filepath), shell=True)
except Exception as e:
raise Exception('Os-specific open browser: %s' % e.__str__())


destdist = dest.joinpath('dist')

# Function to run npm commands and capture port
def run_npm_and_capture_port(port_container):
try:
proc = subprocess.Popen(["npm","run","dev"], cwd=str(destdist), stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
for line in proc.stdout:
print(line)
if 'Local:' in line:
parts = line.strip().split(' ')
for part in parts:
if part.startswith('http://localhost:'):
port = part.split(':')[-1].rstrip('/')
port_container['port'] = port
return
except subprocess.CalledProcessError as e:
print(f"npm run dev failed: {e}")
return None

# Container to hold the port information
port_container = {'port': None}

# Start npm and capture the port in a separate thread
npm_thread = Thread(target=lambda: run_npm_and_capture_port(port_container))
npm_thread.start()
npm_thread.join()

# If a port was found, open the browser
if port_container['port']:
print("Opening browser...")
webbrowser.open(f"http://localhost:{port_container['port']}/")
else:
print("Failed to determine the localhost port")

def file_save(data, filename):
''' saves data for debug purposes '''
with open(filename, 'w') as f:
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file not shown.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file not shown.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file not shown.
Empty file.
Loading