diff --git a/README.md b/README.md index 8ad328c..ce53e3d 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,12 @@ git clone https://github.com/XuanYu-github/comfyui-PlyPreview.git ![加载与刷新 PLY 列表示例](Figure2.png) +### Preview Gaussian 节点键盘操作 +- 点击预览区域以获取焦点后,W/S/A/D 平移视角(前/后/左/右)。 +- Q/E 水平旋转(Q 左旋,E 右旋)。 +- R/F 俯仰旋转(R 上仰,F 下俯)。 +- 鼠标左键拖拽旋转,右键拖拽平移,滚轮缩放。 + ## 依赖 - ComfyUI(默认已启用 DOM widgets)。 - Python:`plyfile`、`numpy`(缺失时 `pip install plyfile numpy`)。 diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..b88fc98 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,37 @@ +[project] +name = "comfyui-PlyPreview" +description = "Gaussian Splat PLY loader + preview nodes for ComfyUI. Forked from GeometryPack and repackaged to avoid upstream overwrites. Includes front-end viewer (gsplat.js) bundled locally." +version = "1.1.0" +license = {file = "LICENSE"} +# classifiers = [ +# # For OS-independent nodes (works on all operating systems) +# "Operating System :: OS Independent", +# +# # OR for OS-specific nodes, specify the supported systems: +# "Operating System :: Microsoft :: Windows", # Windows specific +# "Operating System :: POSIX :: Linux", # Linux specific +# "Operating System :: MacOS", # macOS specific +# +# # GPU Accelerator support. Pick the ones that are supported by your extension. +# "Environment :: GPU :: NVIDIA CUDA", # NVIDIA CUDA support +# "Environment :: GPU :: AMD ROCm", # AMD ROCm support +# "Environment :: GPU :: Intel Arc", # Intel Arc support +# "Environment :: NPU :: Huawei Ascend", # Huawei Ascend support +# "Environment :: GPU :: Apple Metal", # Apple Metal support +# ] + +dependencies = ["numpy>=1.23", "plyfile>=1.0.3"] + +[project.urls] +Repository = "https://github.com/XuanYu-github/comfyui-PlyPreview" +# Used by Comfy Registry https://registry.comfy.org +Documentation = "https://github.com/XuanYu-github/comfyui-PlyPreview/wiki" +"Bug Tracker" = "https://github.com/XuanYu-github/comfyui-PlyPreview/issues" + +[tool.comfy] +PublisherId = "xuanyu" +DisplayName = "comfyui-PlyPreview" +Icon = "" +includes = [] +# "requires-comfyui" = ">=1.0.0" # ComfyUI version compatibility + diff --git a/web/js/gaussian_preview.js b/web/js/gaussian_preview.js index d71ffb7..8890b43 100644 --- a/web/js/gaussian_preview.js +++ b/web/js/gaussian_preview.js @@ -33,8 +33,14 @@ app.registerExtension({ const json = await resp.json(); const files = Array.isArray(json.files) && json.files.length > 0 ? json.files : ["No PLY files found"]; if (widget) { - widget.options.values = files; - widget.value = files[0]; + // Update dropdown choices and keep current selection if still present + widget.options = { ...(widget.options || {}), values: files }; + if (!files.includes(widget.value)) { + widget.value = files[0]; + widget.callback?.(widget.value); + } + // Force UI redraw + widget.computeSize?.(); this.setDirtyCanvas(true); app.graph.setDirtyCanvas(true, true); } @@ -46,10 +52,13 @@ app.registerExtension({ this.refreshPlyList = refreshList; refreshList(); - // Add in-node refresh button instead of relying on context menu - this.addWidget("button", "Refresh PLY list", () => this.refreshPlyList && this.refreshPlyList(), { + // Hint label: user must right-click "Reload Node" to refresh PLY list + const hintEl = document.createElement("div"); + hintEl.style.cssText = "font-size:10px;color:#888;text-align:center;padding:4px 8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;"; + hintEl.textContent = "Right-click → Refresh Node to load new PLY files"; + this.addDOMWidget("ply_hint", "PLY_HINT", hintEl, { serialize: false, - width: 180, + hideOnZoom: false, }); return r; diff --git a/web/js/gsplat-bundle.js b/web/js/gsplat-bundle.js index 902d885..d01a3a5 100644 --- a/web/js/gsplat-bundle.js +++ b/web/js/gsplat-bundle.js @@ -2024,7 +2024,7 @@ void main () { constructor(t = null, n = null) { this._backgroundColor = new dt(); const i = t || document.createElement("canvas"); - t || (i.style.display = "block", i.style.boxSizing = "border-box", i.style.width = "100%", i.style.height = "100%", i.style.margin = "0", i.style.padding = "0", document.body.appendChild(i)), i.style.background = this._backgroundColor.toHexString(), this._canvas = i, this._gl = i.getContext("webgl2", { antialias: false }); + t || (i.style.display = "block", i.style.boxSizing = "border-box", i.style.width = "100%", i.style.height = "100%", i.style.margin = "0", i.style.padding = "0", document.body.appendChild(i)), i.style.background = this._backgroundColor.toHexString(), this._canvas = i, this._gl = i.getContext("webgl2", { antialias: false, preserveDrawingBuffer: true }); const e = n || []; n || e.push(new Nt()), this._renderProgram = new Ct(this, e); const A = [this._renderProgram]; diff --git a/web/viewer_gaussian.html b/web/viewer_gaussian.html index faca78a..479ffd5 100644 --- a/web/viewer_gaussian.html +++ b/web/viewer_gaussian.html @@ -169,6 +169,7 @@ try { scene = new SPLAT.Scene(); camera = new SPLAT.Camera(); + // WebGLRenderer - preserveDrawingBuffer enabled in gsplat-bundle.js renderer = new SPLAT.WebGLRenderer(canvas); controls = new SPLAT.OrbitControls(camera, canvas);