3D viewer¶
Requires the viz extra (pip install "longeron[viz]").
A small three.js mesh viewer for baked geometry (anywidget).
Renders the mesh dicts produced by longeron.analysis.geometry
following the house widget pattern (longeron.widgets.replay): Python bakes
the geometry once per configuration into a JSON-string traitlet; the
inline vanilla-JS front-end only paints – it builds three.js buffer
geometries on load and per-interaction work is a camera move plus one
render. Rendering is on-demand (no free-running animation loop), so an
idle viewer costs nothing.
Interaction: drag to orbit, shift-drag or right-drag to pan (the canvas
swallows the context-menu event so JupyterLab’s menu stays out of the
way), scroll to zoom, double-click to re-fit; a subtle overlay hint
names the bindings. The canvas fills the available cell width (a
ResizeObserver re-sizes the renderer and re-fits the camera on host
resizes); width_px/height_px set the aspect ratio and the
fallback width. An optional second mesh (mesh_b_json) renders side
by side at true scale for A/B comparison, with captions from
label/label_b. A mesh dict may carry labels –
{text, anchor} entries as produced by
longeron.analysis.geometry.lineup() – rendered as billboard
sprites above each configuration, so a grid lineup names its cells
in-scene. Updating mesh_json from Python (e.g. observing another
widget’s traitlet) re-bakes the scene in place.
Linked selection: highlight_json (a JSON array of part identity
keys – each part’s key if tagged via
longeron.analysis.geometry.tag_parts(), else its name) pops
the matched meshes with an emissive accent (the JupyterLab selection
blue, read live from --jp-brand-color2) and dims the rest;
"[]" restores every material instantly. A plain click (no drag)
raycasts the scene and reports the hit part’s key on picked_json
("[]" for a background click), so Python can select the
corresponding diagram node –
longeron.analysis.link.link_selection() wires both directions.
Offline tradeoff: the front-end imports three.js (~630 kB) from the jsDelivr CDN at view time – the one exception to the otherwise self-contained widget. Vendoring the library into the package would add those bytes to every install for a demo-grade viewer; on an offline front-end the widget degrades to a printed notice instead of a scene.
Requires the viz extra for anywidget:
pip install "longeron[viz]".
- longeron.widgets.viewer3d.mesh_viewer(mesh, mesh_b=None, *, label='', label_b='', width_px=760, height_px=430)[source]¶
View one baked mesh dict, or two side by side at true scale.
mesh/mesh_bcome fromlongeron.analysis.geometry(or any producer of the same schema). The canvas fills the notebook cell’s width;width_px/height_pxset its aspect ratio (and the fallback width when the host width cannot be measured). Drag to orbit, shift-drag or right-drag to pan, scroll to zoom, double-click to re-fit. Assign a new JSON string to the returned widget’smesh_jsonto swap the scene in place – e.g. from anobservehandler on another widget.Linked selection:
widget.highlight(keys)pops the parts whose identity key (thekeystamped bylongeron.analysis.geometry.tag_parts(), else the partname) is inkeysand dims the rest;widget.highlight()clears. A plain click on a part reports its key on thepicked_jsontraitlet. Seelongeron.analysis.link.link_selection()for wiring both to a diagram.- Return type:
AnyWidget