mirror of
https://github.com/NGSolve/netgen.git
synced 2024-12-25 05:20:34 +05:00
wip - move code from webgui_jupyter_widgets project to Netgen
This commit is contained in:
parent
b808d84957
commit
75372b0695
@ -20,7 +20,7 @@ install(FILES
|
||||
__main__.py __init__.py
|
||||
meshing.py csg.py geom2d.py stl.py gui.py NgOCC.py occ.py
|
||||
read_gmsh.py read_meshio.py
|
||||
webgui.py
|
||||
webgui.py jupyter.py
|
||||
DESTINATION ${NG_INSTALL_DIR_PYTHON}/${NG_INSTALL_SUFFIX}
|
||||
COMPONENT netgen
|
||||
)
|
||||
|
103
python/jupyter.py
Normal file
103
python/jupyter.py
Normal file
@ -0,0 +1,103 @@
|
||||
import json
|
||||
import os
|
||||
|
||||
import requests
|
||||
from IPython.display import HTML, DisplayHandle, Javascript, display
|
||||
|
||||
_id = 0 # counter for unique id for each generated div element
|
||||
|
||||
# VSCode has a strange meaning of "vh" in jupyter notebooks, use pixels instead
|
||||
_default_height = "500px" if "VSCODE_PID" in os.environ else "50vh"
|
||||
|
||||
_webgui_loaded = False
|
||||
|
||||
|
||||
def load_webgui(url: str = "", embed_code: bool = False):
|
||||
global _webgui_loaded
|
||||
if _webgui_loaded:
|
||||
return
|
||||
_webgui_loaded = True
|
||||
|
||||
url = url or "https://cdn.jsdelivr.net/npm/webgui@0.2.38/dist/webgui.js"
|
||||
|
||||
if embed_code:
|
||||
if url.startswith("http"):
|
||||
webgui_code = requests.get(url).text
|
||||
else:
|
||||
with open(url, "r") as f:
|
||||
webgui_code = f.read()
|
||||
display(HTML(f"<script>{webgui_code}</script>"))
|
||||
else:
|
||||
display(HTML(f"<script src={url}> </script>"))
|
||||
|
||||
|
||||
def render(
|
||||
data, width="100%", height=_default_height, handle: DisplayHandle | None = None
|
||||
):
|
||||
load_webgui()
|
||||
if handle is None:
|
||||
global _id
|
||||
_id += 1
|
||||
id = _id
|
||||
else:
|
||||
id = handle.display_id.split("_")[-1]
|
||||
|
||||
el_id = f"_webgui_root_{id}"
|
||||
|
||||
js_code = _render_js_template.replace("{{data}}", json.dumps(data))
|
||||
js_code = js_code.replace("{{id}}", str(id))
|
||||
js_code = js_code.replace("{{el_id}}", el_id)
|
||||
if handle:
|
||||
# this is a redraw call
|
||||
handle.update(Javascript(js_code))
|
||||
else:
|
||||
# this is a first draw call -> create the root div element for the webgui
|
||||
display(
|
||||
HTML(
|
||||
f'<div class="webgui-widget" id={el_id} style="position: relative; width: {width}; height:{height};" />'
|
||||
)
|
||||
)
|
||||
return display(Javascript(js_code), display_id=f"webgui_render_{id}")
|
||||
|
||||
|
||||
_render_js_template = """
|
||||
{
|
||||
if(window._webgui_scenes === undefined) {
|
||||
window._webgui_scenes = {};
|
||||
}
|
||||
const waitForWebgui = (callback, counter) => {
|
||||
counter = counter || 0;
|
||||
if (window.webgui) {
|
||||
callback();
|
||||
} else {
|
||||
if (counter < 20) {
|
||||
setTimeout(() => {
|
||||
waitForWebgui(callback, counter + 1);
|
||||
}, 200);
|
||||
}
|
||||
else {
|
||||
console.log("Error: Webgui not loaded");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const draw = () => {
|
||||
const data = JSON.parse(`{{data}}`);
|
||||
let scene = window._webgui_scenes[{{id}}];
|
||||
// console.log("have data, scene = ", scene);
|
||||
if(scene === undefined) {
|
||||
console.log("init scene");
|
||||
const root = document.getElementById("{{el_id}}");
|
||||
console.log("root element", root);
|
||||
scene = new webgui.Scene();
|
||||
scene.init(root, data);
|
||||
window._webgui_scenes[{{id}}] = scene;
|
||||
}
|
||||
else {
|
||||
scene.updateRenderData(data);
|
||||
}
|
||||
// console.log("scene", scene);
|
||||
}
|
||||
waitForWebgui(draw);
|
||||
}
|
||||
"""
|
@ -1,17 +1,17 @@
|
||||
import math
|
||||
import numpy as np
|
||||
from time import time
|
||||
import os
|
||||
|
||||
try:
|
||||
import webgui_jupyter_widgets
|
||||
from webgui_jupyter_widgets import BaseWebGuiScene, WebGuiDocuWidget
|
||||
import webgui_jupyter_widgets.widget as wg
|
||||
except ImportError:
|
||||
class BaseWebGuiScene:
|
||||
pass
|
||||
__IPYTHON__
|
||||
_IN_IPYTHON = True
|
||||
|
||||
wg = None
|
||||
from .jupyter import render as _render
|
||||
except NameError:
|
||||
_IN_IPYTHON = False
|
||||
|
||||
def _render(*args, **kwargs):
|
||||
pass
|
||||
|
||||
def encodeData( data, dtype=None, encoding='b64' ):
|
||||
import numpy as np
|
||||
@ -25,18 +25,8 @@ def encodeData( data, dtype=None, encoding='b64' ):
|
||||
else:
|
||||
raise RuntimeError("unknown encoding" + str(encoding))
|
||||
|
||||
from packaging.version import parse
|
||||
|
||||
import netgen.meshing as ng
|
||||
|
||||
if wg is not None and parse(webgui_jupyter_widgets.__version__) >= parse("0.2.18"):
|
||||
_default_width = None
|
||||
_default_height = None
|
||||
else:
|
||||
_default_width = "100%"
|
||||
_default_height = "50vh"
|
||||
|
||||
|
||||
_registered_draw_types = {}
|
||||
|
||||
|
||||
@ -217,7 +207,7 @@ def GetData(mesh, args, kwargs):
|
||||
d[name] = pnew
|
||||
return d
|
||||
|
||||
class WebGLScene(BaseWebGuiScene):
|
||||
class WebGLScene:
|
||||
class Widget:
|
||||
def __init__(self):
|
||||
self.value = {}
|
||||
@ -228,6 +218,7 @@ class WebGLScene(BaseWebGuiScene):
|
||||
self.args = args
|
||||
self.kwargs = kwargs
|
||||
self.encoding = "b64"
|
||||
self.handle = None
|
||||
|
||||
def Redraw(self, *args, **kwargs):
|
||||
if args or kwargs:
|
||||
@ -238,7 +229,8 @@ class WebGLScene(BaseWebGuiScene):
|
||||
self.obj = new_scene.obj
|
||||
self.args = new_scene.args
|
||||
self.kwargs = new_scene.kwargs
|
||||
super().Redraw()
|
||||
_render(self.GetData(), handle=self.handle)
|
||||
# super().Redraw()
|
||||
|
||||
def GetData(self, set_minmax=True):
|
||||
self.kwargs["encoding"] = self.encoding
|
||||
@ -389,8 +381,6 @@ def _get_draw_default_args():
|
||||
settings={},
|
||||
fullscreen=False,
|
||||
scale=1.0,
|
||||
width=_default_width,
|
||||
height=_default_height,
|
||||
)
|
||||
|
||||
|
||||
@ -399,27 +389,29 @@ def Draw(obj, *args, show=True, **kwargs):
|
||||
kwargs_with_defaults.update(kwargs)
|
||||
|
||||
scene = WebGLScene(obj, args, kwargs_with_defaults)
|
||||
if show and wg is not None and wg._IN_IPYTHON:
|
||||
if wg._IN_GOOGLE_COLAB:
|
||||
from IPython.display import display, HTML
|
||||
|
||||
html = scene.GenerateHTML()
|
||||
display(HTML(html))
|
||||
return
|
||||
else:
|
||||
import webgui_jupyter_widgets as wjw
|
||||
from packaging.version import parse
|
||||
|
||||
# render scene using widgets.DOMWidget
|
||||
if parse(wjw.__version__) < parse("0.2.15"):
|
||||
scene.Draw()
|
||||
else:
|
||||
scene.Draw(
|
||||
kwargs_with_defaults["width"], kwargs_with_defaults["height"]
|
||||
)
|
||||
if "filename" in kwargs_with_defaults:
|
||||
scene.GenerateHTML(filename=kwargs_with_defaults["filename"])
|
||||
scene.handle = _render(scene.GetData())
|
||||
return scene
|
||||
# if show and wg is not None and wg._IN_IPYTHON:
|
||||
# if wg._IN_GOOGLE_COLAB:
|
||||
# from IPython.display import display, HTML
|
||||
#
|
||||
# html = scene.GenerateHTML()
|
||||
# display(HTML(html))
|
||||
# return
|
||||
# else:
|
||||
# import webgui_jupyter_widgets as wjw
|
||||
# from packaging.version import parse
|
||||
#
|
||||
# # render scene using widgets.DOMWidget
|
||||
# if parse(wjw.__version__) < parse("0.2.15"):
|
||||
# scene.Draw()
|
||||
# else:
|
||||
# scene.Draw(
|
||||
# kwargs_with_defaults["width"], kwargs_with_defaults["height"]
|
||||
# )
|
||||
# if "filename" in kwargs_with_defaults:
|
||||
# scene.GenerateHTML(filename=kwargs_with_defaults["filename"])
|
||||
# return scene
|
||||
|
||||
async def _MakeScreenshot(data, png_file, width=1200, height=600):
|
||||
"""Uses playwright to make a screenshot of the given html file."""
|
||||
|
Loading…
Reference in New Issue
Block a user