Skip to content

Technical Details

tobi edited this page Aug 4, 2026 · 11 revisions

Technical Details

This page documents the internal mechanics of the Ramses-Fusion integration.

Architecture

Ramses-Fusion is built on three layers:

  1. Ramses API (ramses lib): The core library communicating with the Ramses Daemon.
  2. Fusion Host (fusion_host.py): A specialized implementation of the RamHost class. It translates pipeline commands (Save, Open, Render) into Fusion-specific actions.
  3. Application Controller (Ramses-Fusion.py): Manages the UI state and orchestrates workflows between the user and the Host.

Metadata Persistence

The plugin ensures that every composition "knows" where it belongs. It embeds Ramses UUIDs into the Fusion composition metadata using comp.SetData():

  • Ramses.ItemUUID: The unique ID of the Shot or Asset.
  • Ramses.ProjectUUID: The unique ID of the Project.

This metadata is checked against the active Ramses Client project every time the UI refreshes.

  • Identity Resilience: If a file is moved or renamed outside of Ramses, the plugin uses this metadata as a fail-safe fallback. It will attempt to recover the Shot/Asset identity from the DB using the embedded UUID, ensuring the plugin remains functional even if the file path is unregistered.
  • Mismatch Protection: If the UUIDs don't match the current project, the panel displays a PROJECT MISMATCH warning.

Ramses API Monkey-Patching

To resolve critical limitations in the core Ramses Python library without modifying third-party files, the plugin applies several "monkey-patches" to the ramses module during initialization in fusion_host.py.

1. Robust Identity Matching

  • The Issue: The default Ramses library uses strict regex and 10-character limits for project/item names. This often leads to "Version Not Found" errors on Windows if names are long or if paths have mixed casing.
  • The Fix: RamFileManager methods (like getLatestVersionFilePath) are patched to use a robust identity resolver. It strips version blocks (e.g., _WIP001) from the filename and uses the resulting "base identity" with case-insensitive comparisons to find related versions.

2. Transactional Threading

  • The Issue: Background threading in file operations occasionally caused race conditions during the "Split Publish" workflow.
  • The Fix: The RamFileManager.copy method is patched to disable background threads by default, ensuring all file operations are synchronous and transactional.

3. State Propagation during Publish

  • The Issue: Standard Ramses publishing creates archived versions using the "old" state (e.g., WIP) even if the user is currently updating the status to "DONE".
  • The Fix: RamHost.publish is patched to accept a target state. This state is propagated to the archived filename and metadata immediately, ensuring the approved version on disk matches the approved status in the database.

4. Dry Path Resolution (FS Silence)

  • The Issue: Querying publish or version paths in the standard API has the side-effect of automatically creating directories on disk, leading to hundreds of empty _published subfolders during UI refreshes.
  • The Fix: lib/ramses_patches.py installs a permanent wrapper around os.makedirs that obeys a thread-local flag, plus a DisableMakedirs context manager to raise it. Read-only lookups run inside with DisableMakedirs(): and cannot create anything; directories are created only during a confirmed Save or Publish. The flag is thread-local rather than a swapped function object so that concurrent (and nested) blocks cannot clobber each other's state.

What used to be here

Two patches were removed once the vendored SDK was updated to Ramses-Py d19ce44, because upstream fixed the underlying defects: metadata preservation (the SDK no longer deletes metadata entries whose file is temporarily missing) and daemon error handling (online() no longer leaks socket exceptions). They were dropped rather than left in place — a patch that replaces a method wholesale keeps overriding upstream forever, hiding any later improvement to it. The behaviour is still covered by tests, which now assert it of the SDK itself. apply() currently installs nothing and remains only as the hook for the next patch. See UPSTREAM_SDK_FINDINGS.md in the repository for the defects that are still open upstream.

Project Context & Security

Ramses-Fusion enforces a strict "Active Project" context to prevent data corruption and pipeline spillover.

  • Integrity over Convenience: While Fusion allows opening any file, the plugin will only allow pipeline actions (Save, Publish, Import) if the file's internal metadata matches the project currently active in the Ramses Client.
  • Why this matters: In a multi-project studio, it is easy to accidentally publish a shot from "Project A" into the directory structure of "Project B" if they share similar step names (e.g., Compositing). The UUID check makes this human error technically impossible.
  • Metadata Recovery: If a file loses its identity (e.g., exported as a new version manually), the Setup Scene tool can re-inject the active project's UUIDs, re-binding the file to the pipeline.

Render Anchors

The _PREVIEW and _FINAL nodes (called "Anchors") are the glue between Fusion and the Ramses pipeline.

Render Anchors

  • Automated Placement: When you click Setup Scene, the plugin looks for the ActiveTool in your flow and places the anchors exactly two grid units below it.
  • Path Management: The file paths for these nodes are dynamically managed. Every time the scene is saved or setup, the plugin recalculates the correct path based on the current Version and Step configuration, and updates the Clip input of the anchors.
  • Configuration Hierarchy: To ensure consistency, the plugin configures these nodes using the following priority:
    1. Step YAML: Custom settings defined in the Ramses Step Configuration (via the Render Wizard).
    2. Studio Defaults: If no YAML is found, the plugin enforces a studio standard (Apple ProRes 422 for Previews, 422 HQ for Finals).
  • Safe Rendering: By default, these nodes are set to PassThrough (disabled). The plugin only enables them during the automated Preview or Publish processes, ensuring you don't accidentally overwrite pipeline data during manual renders.
  • Output Frame Numbering: When a step's YAML contains source_numbering, the plugin also manages the Saver's Set Sequence Start inputs: true numbers rendered files from the source plate's first frame (resolved per shot from the plate Loader or the latest published plate), false enforces comp-time numbering, and an absent key leaves the Saver untouched. See Step Configuration.

Render Verification & Integrity

Unlike the standard API which assumes a render is successful if the process finishes, Ramses-Fusion implements a Transactional Verification layer:

  • Post-Render Check: After Fusion reports a successful render, the plugin executes _verify_render_output.
  • Integrity Validation: It verifies that the file exists on disk and has a non-zero file size.
  • Completeness, not just presence: A sequence is counted, not sampled. Checking only that some frame exists passed a render that died partway through: the folder is full of perfectly valid EXRs, the publish is marked complete, and the gap surfaces at delivery. expectedFrameCount derives the frame count from the comp's render range and the count must match.
  • Sequence Awareness: The padding placeholder between dots (.0000., .####., .%04d.) is located by regex and replaced with \d+ in an anchored pattern, so a neighbouring render sharing the stem cannot be counted towards this one. (A glob * here was too loose — it matched things like SH010.preview.exr.)
  • One directory read: The count comes from a single os.scandir pass rather than a glob plus a stat per match. Renders land on a synced network share, where every stat is a round trip: a 300-frame sequence costs ~600 of them the obvious way. Measured at 18 ms versus 0.5 ms on a local SSD, and the gap widens on the share. os.scandir carries the file size on the entry, so the non-empty check is free.
  • Atomic Abort: If verification fails (e.g., due to a full disk or network lag), the plugin aborts the entire publish transaction. No backup is created, and the database status remains unchanged, preventing "Ghost Publishes."

Note

The unset-range sentinel. Fusion reports an unset render range as -1000000000, not as nil. compRenderRange resolves COMPN_RenderStart/End, treats that sentinel as unset, falls back to the global range, and returns (None, None) if neither is set — in which case the frame count is 0 and the completeness check is skipped rather than failing every render on a comp that has no explicit render range.

Validation & Sequence Overrides

When performing a Scene Setup or Publish Validation, the plugin follows a specific hierarchy for technical settings:

  1. Sequence Settings: If the item is a Shot, the plugin first checks its parent Sequence for resolution, FPS, and Pixel Aspect Ratio overrides.
  2. Project Settings: If no sequence override exists, it falls back to the global Project settings.
  3. Local Settings: The plugin's own settings (e.g., "Comp Start Frame") are used to determine timeline offsets.

Offering the repair

Validation does not only report; it records which findings it can fix, as a set of repair keys (currently format — the frame range and format — and anchors — missing render anchors).

  • On a hard error with a repair available, the dialog's confirm button reads Fix It and names what it will change.
  • On a soft mismatch, the repair is offered as a ticked checkbox alongside the warning.
  • After repairing, the plugin re-runs validation rather than assuming the fix took. A repair that silently failed must not wave the publish through.

UI Header Logic

The "Hero" header in the panel provides real-time status:

  • Clickable Refresh: The entire header is a button. Clicking it triggers a full UI refresh and re-syncs with the Ramses Client. A subtle refresh icon (↻) in the top-right corner hints at this functionality.
  • Priority: Displays suffixes based on Ramses priority levels:
    • ! (Yellow) for Priority 1.
    • !! (Orange) for Priority 2 (Urgent).
    • !!! (Red) for Priority 3+ (Critical).
  • Status Badges: Shows the shortName of the current state (e.g., "WIP", "REV") using the exact color defined in the Ramses database.

Role-Based Access Control

The Step Configuration (YAML settings) is protected to prevent accidental pipeline changes:

  • It is enabled for users with the LEAD role or higher.
  • It is automatically enabled for all users if the system detects it is a "Single User" environment (only one user exists in the Ramses database).
  • It is disabled for standard artists in multi-user studio environments.