The control bars are now the ONLY visible controls; the node input widgets
they drive are hidden via a new hideWidgets() util (uiComponents.js). The
widgets keep existing -- values still serialize into the workflow and flow to
Python as inputs -- they just stop rendering on the node body.
- Multi / VTK preview / Batch: `mode` widget hidden (bar Mode selector drives
it). Batch keeps its `index` widget visible (useful for typing an exact
index).
- Dual: `layout`, `mode`, `opacity_1`, `opacity_2` all hidden. Opacity moves
into the bar (shown only for the Overlay layout) and is applied
CLIENT-SIDE: changing it updates the hidden widgets (persistence + next
run) and re-posts to the viewer immediately -- no re-run. render() now
prefers widget values over the last message's, which also fixes the
`|| 1.0` bug that made opacity 0 impossible.
No Python or export-format changes, per direction.
Preview Mesh Dual:
- New control bar with Layout (Side by side | Overlay | Slider) and Mode
(Fields | Texture), two-way synced with the node widgets.
- side_by_side <-> slider reuse the SAME exported files, so that switch is
CLIENT-SIDE: onExecuted was refactored into render(message, layoutOverride)
and the last message is stored -- switching re-renders instantly, no re-run.
Overlay needs the combined export and mode changes the export format, so
those queue a re-run (same cost as editing the widget).
- opacity_1/opacity_2 widgets are hidden unless layout is Overlay (the
hidden-type trick from preview_mesh_batch_render.js), restored when it is.
Preview Mesh (VTK): new bar with Mode (Fields | Texture | Texture (PBR)),
two-way synced, re-runs on change.
Fullscreen: new createFullscreenButton(container) in utils/uiComponents.js
(fullscreens the whole widget so bar controls stay usable; listeners on the
container only, isolation-clean). Wired into Dual, VTK, and Multi bars (in
Multi it sits outside the collapsible group so it survives collapse). The
batch node keeps its own earlier implementation with arrow-key nav.
Note: plain Preview Mesh (three.js, GeomPackPreviewMesh) has no mode input on
the Python side, so there is nothing to select there; the VTK preview is the
one with modes. comfy-3d-viewers was checked for fullscreen prior art -- its
"FullScreen" hits are VTK class names, not browser fullscreen; this is new.
The viewer JS/HTML/bundles are now committed in javascript/ (declared via
pyproject [tool.comfy] web = "javascript") instead of being copied from the
shared comfy-3d-viewers pip package at prestartup. Consequences:
- requirements.txt is now just comfy-env (host env installs nothing else,
per the never-touch-the-host-env principle)
- prestartup_script.py no longer copies viewers or web_src; it keeps only
setup_env() and the input-asset copies
- WEB_DIRECTORY attribute removed; the pyproject declaration is the single
source (served at /extensions/comfyui-geometrypack/, keyed by project name)
- web_src/ deleted; its 6 widgets now live in javascript/js/ as the tracked
source, edited directly
- viewer_pbr.html hardcoded-fallback URL updated to the new mount name
Iframe URLs auto-detect the mount from import.meta.url, so the folder rename
and mount-name change are transparent at runtime.