mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-05-24 22:58:08 +00:00
When comparing outputs from 3D generations, it's very hard to see small differences since the camera always resets. This adds an option to lock the camera, so only the model refreshes. ## Summary Adds an opt-in per-node toggle that preserves the current camera view (position, target, zoom, camera type) across model loads in Load3D / Load3DAnimation nodes, instead of resetting to default framing. ## Changes - **What**: New `retainViewOnReload?: boolean` field on `CameraConfig`, a `Load3d.setRetainViewOnReload()` setter wired through the existing `useLoad3d` camera-config watcher, capture/restore logic in `Load3d._loadModelInternal`, and a lock-icon toggle button in `CameraControls.vue` below the FOV slider. Preference persists via the existing `node.properties['Camera Config']` mechanism. ## Review Focus - **First-load semantics**: retain only kicks in once a model has successfully loaded at least once (`hasLoadedModel` flag), so the default `setupForModel` framing wins on a fresh node. `clearModel()` resets the flag so the next load also reframes. - **Restore order vs. `SceneModelManager.setupModel`**: the scene model manager unconditionally calls `setupForModel` during a load, which clobbers the camera. The restore in `_loadModelInternal` runs *after* the load completes, on top of that framing. - **Camera-type mismatch**: if the saved state's `cameraType` differs from the currently active camera, `toggleCamera()` runs before `setCameraState()` so the perspective/orthographic camera being restored is actually the active one. Covered by a dedicated test. - **Scope**: only wired through `useLoad3d` (LiteGraph node controls). The full-page viewer (`useLoad3dViewer` / `ViewerCameraControls`) is deliberately not extended — the modal is mostly a one-shot view-and-close flow, so retain there would add surface area for an uncommon use case. - **Failed loads**: `hasLoadedModel` only flips inside `if (modelManager.currentModel)`, so a load that produces no model leaves the flag where it was. Captured camera state is still applied on top, which effectively no-ops since nothing reset it. ## Video https://github.com/user-attachments/assets/880d6ad1-28a9-4413-83a3-8323d05d904a