Files
wtd-libreflow-addon/CLAUDE.md
T
NDemaerschalkandClaude Opus 5.5 6ec2b228ae Scene Manager: named LODs
{lod} in SCENE_MANAGER_LOD_COLLECTION now matches any name (COL_bob_LODhigh
as well as COL_bob_LOD0). SCENE_MANAGER_LODS (high, mid, low) sets the
button order and the LOD shown on load; unlisted LODs follow, numbers in
order, then names A-Z. It replaces SCENE_MANAGER_DEFAULT_LOD. The LOD of
Selected buttons get their own line.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 16:46:36 +01:00

6.6 KiB

Melvile Tools: notes for Claude

Blender add-on (Blender 5.2) for the Melvile pipeline at Walking The Dog: Sanity Check, Rename, Shot Manager and Scene Manager panels in the 3D View sidebar (WTD tab). README.md is the user guide: keep it up to date with every user-visible change.

Layout and conventions

  • config.py: every production value (prefixes, formats, patterns, modes). Values are read at run time (config.X, never copied at import) because a studio JSON file can override them (add-on preferences "Config Override", or WTD_SANITY_CONFIG). New tunable values go here, with a comment, and in the README's Configuration table.
  • ui/panel.py: all panels. Operators live with their tool (rename.py, shot_viewer.py, scene_manager/, ui/operators.py for the Sanity Check).
  • checks/: sanity checks, auto-registered (see README > For developers).
  • __init__.py deletes cached submodules on reload, so Reload Scripts picks up every file.
  • Versions: blender_manifest.toml and bl_info in __init__.py (keep both in sync).
  • Style: match the surrounding code; short docstrings, few comments, no heavy abstractions.

Working with the user

  • Commits: when asked, create a branch from master, commit there (end with the Co-Authored-By line), and give the user the merge / push / branch-delete commands: they run them themselves. Only commit straight on master when told to.
  • Real Blender API facts beat memory: probe in headless Blender before relying on an API.

Testing

Blender binary: macOS /Applications/Blender.app/Contents/MacOS/Blender, Windows blender.exe from the install folder. Import the add-on in tests by putting the folder that contains this repo on sys.path and importing the repo folder name (see dev/test_scene_manager.py).

  • Headless: blender -b --factory-startup --python-exit-code 1 --python <script> -- <args>. Timers do not run in background mode: pump background jobs by hand (scene_manager.ipc._poll()).
  • UI: run Blender with a window (--factory-startup <file.blend> --python <script>, a .blend argument avoids the splash), drive it with bpy.app.timers, take screenshots with bpy.ops.screen.screenshot_area, quit with bpy.ops.wm.quit_blender(). A sidebar tab (region.active_panel_category) can only be set once the region has been drawn.
  • Scene Manager without Libreflow (dev/):
    1. blender -b --factory-startup --python dev/make_test_assets.py -- <workdir>
    2. python dev/fake_libreflow.py <workdir> (keep running; restart for a clean state)
    3. blender -b --factory-startup --python-exit-code 1 --python dev/test_scene_manager.py -- <workdir> (60 checks, "All checks passed"). /_test/publish and /_test/download simulate a new publish and a requested revision reaching this site. The fake server follows the real wtdcmds replies; check them against the real Libreflow when one is available.

External pieces

  • Libreflow wtdcmds extension (commands used by the Scene Manager), on the share: WG/_Dev/GIT/ndemaerschalk/_MELVILE/libreflow_dev_utils/dev/src/wtdcmds/ (src/libreflow/extensions/wtdcmds/wtd_cmds.py, BLENDER_ADDON_BRIEF.md). Server address/token: ~/.kabaret/ipc/server.json (config LIBREFLOW_SERVER_FILE).
  • Add Camera Rigs extension: bpy.ops.object.build_camera_rig(mode=...) builds the Shot Manager cameras. It finds its rigs by the rig_id custom property, not by name.
  • tools_ops.py "Get Oid" uses the separate kabaret Blender client (bpy.ops.kabaret.cmds_call).

Design notes (found by testing)

  • Shot Manager: shots are timeline markers bound to cameras, in one scene. Setting scene.frame_current does not switch the camera (only frame_set does): set scene.camera explicitly.
  • Scene Manager: tags live on bpy.types.Library only. Library overrides lose custom properties when they resync, so instances are traced back to their library (empty → instance_collection.library, override → override_library.reference.library).
  • library.reload() invalidates every Python reference to linked and override data: look IDs up again afterwards. In Blender 5.2 it also replaces the Library itself (renamed after its file, custom properties gone): library.update() finds it by path and restores the name and tags.
  • Removing a library leaves the libraries it linked indirectly (e.g. Blender's geometry_nodes_essentials.blend): remove_unused_libraries() drops the ones whose data is no longer used, never a managed library.
  • LODs are child collections of the asset collection (COL_{asset}_LOD{lod}, any name, ordered by SCENE_MANAGER_LODS, then numbers, then names; the first is the default). Overrides switch by hide_viewport/hide_render on the LOD override collections: Blender stores them as override properties (kept through save, reload and resync) and hidden LODs are not evaluated. Collection instances instance the LOD collection itself. A second override's collections are renamed (.001): match LODs on override_library.reference.name.
  • "Shot Manager" is the user-facing name of what the code calls shot_viewer (module, operators, SHOT_VIEWER_* config keys kept for existing override files).
  • Background requests (scene_manager.ipc.run) hand results back through a timer; in callbacks, find scenes by name (bpy.context.scene is not reliable in timers).

Real Libreflow (first run, 2026-10-27)

  • Kitsu asset types: main_character, secondary_character, tertiary_character, main_props, secondary_props, set_props, vehicles, bg_location, bg_set, skies, setdress_bank. The fake server uses the same names.
  • Paths come back as Windows paths with backslashes; comment can be null.
  • Set dressing publishes (setdress_low) hold a whole layout scene: the set is the environments collection, next to lights, cameras, characters, _unused.
  • Tested live: connection, context, casting, load (instance and override), version switch and update, remove, assetize errors, one request (car_paul modeling.blend v001 → Requested). Not tested: an actual assetize publish (it writes to production). New wtdcmds commands need every Libreflow session restarted (a running one keeps the old code and answers 404).

Open points

  • Override vs instance per asset type (SCENE_MANAGER_LINK_MODES), and the file patterns of sets (setdress_low seen on one asset only): confirm with production.
  • The server picks the first file matching a pattern even when it is not on this site, while another matching file is (e.g. car_paul: modeling/modeling.blend v001 not available, modeling/tes_modeling.blend v002 available).
  • Values marked TODO in config.py wait for production specs.