Files
UsdLayerManager/CLAUDE.md
T
indigo e2a4961ebe Upgrade to OpenUSD 25.11 (Python 3.12) and fix Arnold/Embree regressions
Build against OpenUSD 25.11 built from source with Python 3.12, OCIO 2.2.1,
OpenVDB, Ptex and Embree, replacing the 25.05/py311 mix.

Build system:
- CMAKE_PREFIX_PATH -> third_party/OpenUSD-v25.11; HDARNOLD_ROOT ->
  hdArnold-v25.11. hdEmbree is bundled in the USD build now, so
  HDEMBREE_USD_ROOT is no longer needed.
- FindOpenUSD: drop usd_ndr (ndr was merged into sdr in 25.11).
- hdArnold plugin renames: ndrArnold -> nodeRegistryArnold, plus the new
  usdImagingArnold plugin.
- Glob the version-suffixed OpenColorIO_*.dll instead of hardcoding 2_1.
- Drop the python311.dll workaround; USD and Cycles now share Python 3.12.
- Cycles: deploy OpenColorIO_2_5.dll (needed by its bundled OpenImageIO) and
  stop the debug-DLL filter from eating IlmThread.dll -- the regex `d[.]dll$`
  also matched legitimate Release DLLs.

Runtime fixes:
- cullStyle now defaults to Nothing, matching usdview (viewSettingsDataModel
  cullBackfaces=False). BackUnlessDoubleSided drops back faces on geometry
  that isn't authored doubleSided, which hdEmbree applies to occlusion rays
  too, so interiors shaded as single-sided.
- Set HDARNOLD_osl_includepath (and PXR_MTLX_STDLIB_SEARCH_PATHS) in main.cpp
  before the plugin DLL pre-load. hdArnold compiles MaterialX via generated
  OSL that begins with #include "mx_funcs.h"; without an include path Arnold
  fails with "fatal error: 'mx_funcs.h' file not found". It must be set before
  any plugin loads because TF_DEFINE_ENV_SETTING caches the value when
  hdArnold.dll registers its settings.
- Deploy the MaterialX standard library next to the executable.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-03 10:02:00 +08:00

6.8 KiB
Raw Blame History

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.


Build

Prerequisites: MSVC 2022, CMake ≥ 3.20, Python 3.12 at %LOCALAPPDATA%\Programs\Python\Python312.
OpenUSD 25.11 is expected at third_party/OpenUSD-v25.11 (set via CMAKE_PREFIX_PATH in the preset).

# Configure (one-time; downloads ACES 1.2 OCIO config ~124 MB on first run)
cmake --preset default

# Build Release (copies all USD/DLL dependencies to build/Release/)
cmake --build build --config Release

# Install to install/bin/
cmake --build build --config Release --target install

The default preset (in CMakePresets.json) enables WITH_CYCLES=ON and HDARNOLD_ROOT for the maintainer's machine. hdEmbree is bundled directly in the third_party/OpenUSD-v25.11 build (built with --embree), so no separate HDEMBREE_USD_ROOT is needed. For a minimal build without optional render delegates, configure manually:

cmake -B build -G "Visual Studio 17 2022" `
  -DCMAKE_PREFIX_PATH="third_party/OpenUSD-v25.11" `
  -DIMGUI_DIR="third_party/imgui-1.92.7" `
  -DWITH_CYCLES=OFF

No test runnerBUILD_TESTS=OFF by default. Tests (ViewportDisplayTest, RendererDiagnosticTest) have stale USD include paths; do not enable without fixing them first.


Architecture

Entry point: src/main.cpp — sets PXR_PLUGINPATH_NAME, pre-flight loads each plugin DLL via LoadLibraryA (skips missing deps gracefully), then hands off to Application.

Application (src/ui/Application.h/.cpp) — owns all top-level managers and ImGui panels. Drives the main loop: Update()RenderUI(). Persists viewport settings to %APPDATA%\UsdLayerManager\viewport_settings.ini.

Core managers (all in src/core/):

  • UsdStageManager — opens/closes/saves USD stages; single source of truth for the active UsdStageRefPtr.
  • LayerManager — enumerates and manipulates SdfLayer stack (mute, set edit target, add/remove sublayers).
  • PropertyManager — reads/writes prim attributes; drives PropertyPanel.
  • CommandHistory — undo/redo stack; all mutating operations go through commands in src/core/commands/.

Viewport rendering pipeline (the most complex subsystem):

  • ViewportPanel (src/ui/) — container for 14 ViewportTile instances, handles split layout and shared selection.
  • ViewportTile — owns one ViewportCamera + one UsdSceneRenderer. Renders into an ImGui child window by passing the scene texture as an ImGui image.
  • UsdSceneRenderer (src/core/) — wraps UsdImagingGLEngine (Hydra/Storm). Renders into a GlfDrawTarget (offscreen RGBA16F FBO). All GL overlay drawing (grid, axis, bbox, camera/light wireframes) happens here while the draw-target FBO is bound.
  • ViewportColorCorrectorfile-local class inside UsdSceneRenderer.cpp (pimpl). Applies sRGB or OCIO color correction as a fullscreen GL pass after Hydra renders linear. Hydra's own HdxColorCorrectionTask is bypassed (colorCorrectionMode = "disabled" always passed to Hydra). See docs/adr/0001-viewport-color-correction.md.

OCIO config: $OCIO is set at startup (in Application.cpp) to resources/OpenColorIO-Configs/aces_1.2/config.ocio (downloaded at CMake configure time). The OcioConfigParser utility (src/utils/) wraps the OCIO C++ API to enumerate displays/views/colorspaces for the UI.

UI panels (all src/ui/):

  • StageEditorPanel — edit target, dirty state, drag-drop sublayer ordering.
  • SceneHierarchyPanel — prim tree with type icons.
  • PropertyPanel — attribute inspector/editor.
  • TimelinePanel — transport controls, loop/bounce, frame scrub.
  • CurveEditorPanel — Maya-style F-curve editor with Bezier round-trip to USD time samples.

GL loader: glad (generated loader in src/utils/GLExt.h). Do not call GL functions before gladLoadGL.

Logging: LOG_INFO / LOG_WARNING / LOG_ERROR macros (src/utils/Logger.h). USD diagnostics (TF_WARN, TF_ERROR) are routed to the same logger via a TfDiagnosticMgr::Delegate installed in UsdSceneRenderer::InitRenderer().

DLL layout (Windows):

  • Exe + all USD/OCIO/FFmpeg DLLs live in build/Release/.
  • Hydra plugin DLLs live in build/Release/usd/ (so plugInfo.json's LibraryPath "../<name>.dll" resolves correctly).

12-rule template

These rules apply to every task in this project unless explicitly overridden. Bias: caution over speed on non-trivial work. Use judgment on trivial tasks.

Rule 1 — Think Before Coding

State assumptions explicitly. If uncertain, ask rather than guess. Present multiple interpretations when ambiguity exists. Push back when a simpler approach exists. Stop when confused. Name what's unclear.

Rule 2 — Simplicity First

Minimum code that solves the problem. Nothing speculative. No features beyond what was asked. No abstractions for single-use code. Test: would a senior engineer say this is overcomplicated? If yes, simplify.

Rule 3 — Surgical Changes

Touch only what you must. Clean up only your own mess. Don't "improve" adjacent code, comments, or formatting. Don't refactor what isn't broken. Match existing style.

Rule 4 — Goal-Driven Execution

Define success criteria. Loop until verified. Don't follow steps. Define success and iterate. Strong success criteria let you loop independently.

Rule 5 — Use the model only for judgment calls

Use me for: classification, drafting, summarization, extraction. Do NOT use me for: routing, retries, deterministic transforms. If code can answer, code answers.

Rule 6 — Token budgets are not advisory

Per-task: 4,000 tokens. Per-session: 30,000 tokens. If approaching budget, summarize and start fresh. Surface the breach. Do not silently overrun.

Rule 7 — Surface conflicts, don't average them

If two patterns contradict, pick one (more recent / more tested). Explain why. Flag the other for cleanup. Don't blend conflicting patterns.

Rule 8 — Read before you write

Before adding code, read exports, immediate callers, shared utilities. "Looks orthogonal" is dangerous. If unsure why code is structured a way, ask.

Rule 9 — Tests verify intent, not just behavior

Tests must encode WHY behavior matters, not just WHAT it does. A test that can't fail when business logic changes is wrong.

Rule 10 — Checkpoint after every significant step

Summarize what was done, what's verified, what's left. Don't continue from a state you can't describe back. If you lose track, stop and restate.

Rule 11 — Match the codebase's conventions, even if you disagree

Conformance > taste inside the codebase. If you genuinely think a convention is harmful, surface it. Don't fork silently.

Rule 12 — Fail loud

"Completed" is wrong if anything was skipped silently. "Tests pass" is wrong if any were skipped. Default to surfacing uncertainty, not hiding it.