mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-05-24 14:45:36 +00:00
> Prerequisite work for improved PLY / 3D Gaussian Splatting support — the per-format loader logic needs to live behind a stable seam before splat-specific fixes (orientation, async-decoder waits, GPU dispose, custom bounds) and capability-driven UX gating can be added without touching `LoaderManager`'s switch every time. ## Summary Pure refactor. Extracts the per-extension switch inside `LoaderManager` into three `ModelAdapter` implementations and wires the manager to dispatch through them. **No behavior change** — same loader code paths, same outputs, same fallbacks. Sixth in the series splitting up the https://github.com/Comfy-Org/ComfyUI_frontend/pull/11495. ## Changes - **What**: - `ModelAdapter.ts` (new): defines the `ModelAdapter` interface (`kind`, `extensions`, `capabilities`, `load`), a `ModelLoadContext` that exposes only the `SceneModelManager` surface adapters need (`setOriginalModel`, `registerOriginalMaterial`, `standardMaterial`, `materialMode`), and a shared `fetchModelData(path, filename)` helper. - `MeshModelAdapter.ts` (new): owns `stl`, `fbx`, `obj`, `gltf`, `glb`. Each branch is a 1:1 lift of the corresponding `case` from `LoaderManager.loadModelInternal` on `main`. - `PointCloudModelAdapter.ts` (new): owns `ply`. Includes the existing `FastPLYLoader` / `PLYLoader` fallback and the `pointCloud` vs mesh branching logic. - `SplatModelAdapter.ts` (new): owns `spz`, `splat`, `ksplat`. Wraps the `SplatMesh` in a `Group` exactly like the previous `loadSplat` did. - `LoaderManager.ts`: now owns just an adapter array (default = the three above) and a small dispatch path. `pickAdapter` matches by extension and routes PLY → splat when the `Comfy.Load3D.PLYEngine` setting is `sparkjs` (preserving the previous routing). `getCurrentAdapter()` is the new public reader used by `Load3d`. - `Load3d.isSplatModel` / `isPlyModel` now query `loaderManager.getCurrentAdapter()?.kind` instead of doing tree-introspection (`containsSplatMesh`) or `instanceof THREE.BufferGeometry` checks. Same return values, decoupled from the model shape. - `LoaderManagerInterface` no longer exposes the per-format loader fields (`gltfLoader`, `objLoader`, etc.); those are now adapter-internal. - `SceneModelManager` is **unchanged** in this PR. Its existing `containsSplatMesh()` traversal and PLY material-mode rebuild stay put; a follow-up PR refactors them once capability gating is in place. ## Review Focus - **Loader equivalence**: the body of every `case` in `main`'s `LoaderManager.loadModelInternal` is now in the corresponding adapter's `load()` method. Easiest way to verify: diff `main`'s `LoaderManager.loadModelInternal` against the four `load()` bodies and confirm each branch's behavior (file fetch + parse + material wiring + group wrapping) is byte-identical. - **Dispatch parity**: `pickAdapter` produces the same routing as `main` — extension match first, then the PLYEngine === 'sparkjs' override hoisted up from inside the old `loadPLY`. - **Capability fields are dormant**: the `ModelAdapterCapabilities` record (`fitToViewer`, `materialModes`, `fitTargetSize`, …) is declared on every adapter but **not consumed anywhere in this PR**. SceneModelManager / Load3d / Load3DControls still read no capability data. The follow-up PR turns these on. - **`setOriginalModel` / `registerOriginalMaterial`**: adapters now go through the `ModelLoadContext` getter rather than reaching into `modelManager` directly. The context's `standardMaterial` and `materialMode` are exposed via getters so a late-bound `materialMode` is read at the actual call site, not snapshotted at context creation. ## Coverage | File | Stmts | Branch | Funcs | Lines | |---|---|---|---|---| | `ModelAdapter.ts` (new) | **100%** | **100%** | **100%** | **100%** | | `MeshModelAdapter.ts` (new) | **100%** | **100%** | **100%** | **100%** | | `PointCloudModelAdapter.ts` (new) | 97.22% | 61.11% | 75% | 97.22% | | `SplatModelAdapter.ts` (new) | **100%** | **100%** | **100%** | **100%** | | `LoaderManager.ts` (modified) | **100%** | 91.17% | 86.66% | **100%** | | `Load3d.ts` (modified) | 6.63% | 0% | 13.68% | 6.7% | All four new files are at or near 100% via dedicated unit tests for each adapter (load happy path, error propagation, extension declarations, capability shape). `LoaderManager.test.ts` exercises the dispatch logic — extension matching, the `ply → splat` sparkjs override, the stale-load discard, the load-context proxying — across 34 cases. The two changed `Load3d.ts` methods (`isSplatModel`, `isPlyModel`) get dedicated tests verifying they read the current adapter's `kind` and fall back to `false` when none is loaded. `Load3d.ts`'s overall 6.7% number is the pre-existing baseline — the existing `Load3d.test.ts` covers façade methods via prototype injection rather than instantiating the class (the constructor needs `THREE.WebGLRenderer`, which happy-dom can't provide). PR-F's surface in `Load3d.ts` is two method bodies, both covered by the new adapter-driven kind queries test. ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-11627-refactor-load3d-introduce-ModelAdapter-abstraction-for-the-loader-switch-34d6d73d3650811b8a1ccc55b45100f2) by [Unito](https://www.unito.io)
Core Extensions
This directory contains the core extensions that provide essential functionality to the ComfyUI frontend.
📚 Full Documentation
The complete documentation for core extensions has been moved to:
Quick Reference
This directory contains built-in extensions that ship with ComfyUI, including:
- Image Processing: maskeditor, uploadImage, saveImageExtraOutput, clipspace
- Graph Management: groupNode, groupNodeManage, groupOptions, rerouteNode, noteNode
- Input Handling: widgetInputs, uploadAudio, webcamCapture, simpleTouchSupport
- UI Enhancements: contextMenuFilter, previewAny, nodeTemplates
- Text Processing: dynamicPrompts, editAttention
- Platform Support: electronAdapter
and more.
See Also
- Extension Development Guide - How to develop extensions
- Extension Documentation Index - Overview of all extension docs
- ComfyExtension Interface - TypeScript interface for extensions