hub/venv/lib/python3.7/site-packages/trimesh/viewer/notebook.py

112 lines
3.0 KiB
Python
Raw Normal View History

"""
notebook.py
-------------
Render trimesh.Scene objects in HTML
and jupyter notebooks using three.js
"""
import os
import base64
# for our template
from .. import util
from .. import resources
def scene_to_html(scene):
"""
Return HTML that will render the scene using
GLTF/GLB encoded to base64 loaded by three.js
Parameters
--------------
scene : trimesh.Scene
Source geometry
Returns
--------------
html : str
HTML containing embedded geometry
"""
# fetch HTML template from ZIP archive
# it is bundling all of three.js so compression is nice
base = util.decompress(
resources.get('viewer.template.zip', decode=False),
file_type='zip')['viewer.html.template'].read().decode('utf-8')
scene.camera
# get export as bytes
data = scene.export(file_type='glb')
# encode as base64 string
encoded = base64.b64encode(data).decode('utf-8')
# replace keyword with our scene data
result = base.replace('$B64GLTF', encoded)
return result
def scene_to_notebook(scene, height=500, **kwargs):
"""
Convert a scene to HTML containing embedded geometry
and a three.js viewer that will display nicely in
an IPython/Jupyter notebook.
Parameters
-------------
scene : trimesh.Scene
Source geometry
Returns
-------------
html : IPython.display.HTML
Object containing rendered scene
"""
# keep as soft dependency
from IPython import display
# convert scene to a full HTML page
as_html = scene_to_html(scene=scene)
# escape the quotes in the HTML
srcdoc = as_html.replace('"', '"')
# embed this puppy as the srcdoc attr of an IFframe
# I tried this a dozen ways and this is the only one that works
# display.IFrame/display.Javascript really, really don't work
# note trailing space to avoid IPython's pointless hardcoded warning
embedded = display.HTML(
'<iframe srcdoc="{srcdoc}" '
'width="100%" height="{height}px" '
'style="border:none;"></iframe> '.format(
srcdoc=srcdoc,
height=height))
return embedded
def in_notebook():
"""
Check to see if we are in an IPython or Jypyter notebook.
Returns
-----------
in_notebook : bool
Returns True if we are in a notebook
"""
try:
# function returns IPython context, but only in IPython
ipy = get_ipython() # NOQA
# we only want to render rich output in notebooks
# in terminals we definitely do not want to output HTML
name = str(ipy.__class__).lower()
terminal = 'terminal' in name
# spyder uses ZMQshell, and can appear to be a notebook
spyder = '_' in os.environ and 'spyder' in os.environ['_']
# assume we are in a notebook if we are not in
# a terminal and we haven't been run by spyder
notebook = (not terminal) and (not spyder)
return notebook
except BaseException:
return False