indigo 9d61819636 Update README to reflect Material Editor, Timeline/Curve Editor, and OCIO color management
README hadn't been touched since the early layer/viewport-only stage of
the project: it still described the removed LayerPanel, omitted the
Material Editor / MaterialPreviewRenderer / NodeThumbnailCache /
CurveEditorPanel / TimelinePanel entirely, and its Tests section
claimed ctest works even though BUILD_TESTS is OFF in every preset
(the two test executables have stale USD include paths, per
CLAUDE.md). Refreshes the feature list, architecture tree, and build
docs to match current source, and adds a screenshot gallery for the
Material Editor, Curve Editor, quad viewport, and MaterialX import.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-11 17:45:04 +08:00
2026-06-13 08:45:16 +08:00
2026-07-11 11:08:59 +08:00
2026-06-03 09:00:11 +08:00
2026-06-03 09:00:11 +08:00
2026-06-27 18:41:41 +08:00

USD Layer Manager

A C++17 / Windows desktop application providing a Maya-style USD scene and look-dev editor using OpenUSD v25.05, ImGui 1.92.7 (docking branch), and OpenGL 3.3 (via GLAD). Users can open, edit, and save USD files, manage layered stage overrides, inspect and edit prim properties, author UsdShade material graphs with a live shader-ball preview, animate with a Bezier curve editor, and interact with 3D scenes through a multi-viewport Hydra renderer with OCIO color management.

Screenshot

Features

  • Layer Stack ManagementStageEditorPanel: create, reorder, mute/unmute sublayers, set the edit target, add existing files as sublayers, with full undo support
  • Scene Hierarchy — Browse prim tree with per-type SVG icons; create, delete, rename, reparent, and group prims; add/replace references
  • Property Editor — Maya Channel Box-style attribute editing with type-aware drag inputs, color pickers, and undoable transforms
  • Material Editor — Hypershade-style node-graph editor for UsdShade/MaterialX networks (MaterialEditorPanel): material browser, drag-to-connect node canvas, per-node/per-pin display modes, Sdr-driven node creation menu and enum dropdowns, colorSpace authoring on texture inputs, and a live shader-ball preview (MaterialPreviewRenderer) with its own renderer/HDRI/preview-shape controls. In-canvas node thumbnails (NodeThumbnailCache) show texture previews and per-node shader-ball renders, amortized across frames and re-rendered until progressive delegates (Arnold/Cycles/Embree) fully converge
  • Timeline & Curve Editor — Transport controls with loop/bounce and Auto-Key (TimelinePanel); a Maya-style F-curve editor (CurveEditorPanel) with Bezier round-trip to USD time samples; Playblast export to MP4 via MovieEncoder (libavcodec)
  • 3D Viewport — Hydra rendering via UsdImagingGLEngine into an offscreen FBO; switchable render delegates (Storm, Embree, Arnold, Cycles); OCIO-based color management (sRGB or full display/view/look pipeline) applied as a post-Hydra GL pass; grid overlay; selection bounding boxes; camera/light wireframes
  • Multi-Viewport — Single, horizontal split, vertical split, and quad layouts; per-tile camera, render delegate, and AOV; Space to maximize/restore
  • Camera Control — Free orbital camera (tumble/truck/dolly) or drive from USD camera prims; auto near/far clipping; frame selection; correct camera prim orientation for Y-up and Z-up stages
  • Transform Gizmo — Pure ImDrawList-based manipulator (translate/rotate/scale) in object or world space
  • Undo/Redo — Full command history (ICommand subclasses under src/core/commands/) covering prim creation/deletion/reparenting/grouping, attribute edits, transform changes, shader-node creation/connection, and layer operations; Ctrl+Z / Ctrl+Y hotkeys; Edit menu integration
  • Multi-select — Rectangular selection in viewport with cross-panel syncing
Material Editor (Arnold) Curve Editor Quad Viewport (4 delegates) MaterialX import
Material Editor Curve Editor Quad Viewport MaterialX

Dependencies

Dependency Version Notes
OpenUSD v25.05 Prebuilt; found via FindOpenUSD.cmake
Dear ImGui v1.92.7 Docking branch; Win32 + OpenGL3 backends
GLAD OpenGL 3.3 core loader
Python 3.12 Required by OpenUSD runtime (python312.dll)

Optional Render Delegates

Delegate Renderer Version Variable Notes
hdEmbree Embree 4.4.1 HDEMBREE_USD_ROOT USD build with PXR_ENABLE_EMBREE_PLUGIN=ON; set EMBREE_LOCATION if Embree DLLs are not in HDEMBREE_USD_ROOT/bin
hdArnold Arnold 7.4.0 (MtoA 5.5.0) HDARNOLD_ROOT, ARNOLD_LOCATION arnold-usd install dir + MtoA root for ai.dll
hdCycles Cycles 5.2.0 WITH_CYCLES=ON Built from source under third_party/cycles via ExternalProject; requires MSVC

All delegate paths are pre-configured in CMakePresets.json.

Build

Prerequisites

  • Visual Studio 17 2022 (MSVC v143) with C++17 support
  • CMake 3.20+
  • Python 3.12 installed at %LOCALAPPDATA%\Programs\Python\Python312\

Steps

cmake --preset default
cmake --build build --config Release
cmake --install build --config Release

The installed executable lives in install/bin/.

Presetsdefault (Release, WITH_CYCLES=ON, all render delegates), debug (Debug), release (RelWithDebInfo, installs), no-tests (Release). All presets currently build with BUILD_TESTS=OFF.

Building with Cycles

WITH_CYCLES=ON is set in the default preset. The first build compiles Blender Cycles from third_party/cycles via ExternalProject — expect a significantly longer initial build. Subsequent builds are incremental.

Cycles runtime dependencies (embree4.dll, openvdb.dll, OpenImageDenoise.dll, tbb12.dll, etc.) are automatically deployed to the output directory by a post-build step. CRT DLLs bundled inside the Cycles install are excluded to avoid version conflicts with the app's own MSVC runtime.

Tests

There is currently no working test runner: BUILD_TESTS is OFF in every preset. The two test executables (ViewportDisplayTest, RendererDiagnosticTest) have stale USD include paths and don't build — fix those before turning BUILD_TESTS on.

Architecture

src/
├── main.cpp                  — Entry point (plugin path init, app lifecycle)
├── core/                     — USD business logic (no UI dependency)
│   ├── UsdStageManager       — Stage open/create/save/close lifecycle
│   ├── LayerManager          — Layer stack introspection and mutation
│   ├── PropertyManager       — Property read/write via edit target with undo
│   ├── MaterialManager       — UsdShade graph introspection + Sdr node-type/enum discovery
│   ├── CommandHistory        — Undo/redo stack for ICommand instances
│   ├── UsdSceneRenderer      — Hydra rendering + picking + overlays + OCIO color correction
│   ├── ViewportCamera        — Free / USD-camera-driven orbital camera
│   └── commands/             — ICommand subclasses for all mutable operations
│       ├── TransformCommand          — Undoable translate/rotate/scale
│       ├── CreatePrimCommand         — Undoable prim creation (with camera orientation)
│       ├── DeletePrimCommand         — Undoable prim deletion (SdfCopySpec snapshot)
│       ├── RenamePrimCommand         — Undoable prim rename
│       ├── ReparentPrimCommand       — Undoable reparent via UsdNamespaceEditor
│       ├── GroupPrimsCommand         — Group selected prims under a new Xform
│       ├── AttributeSetCommand       — Type-agnostic undoable attribute writes
│       ├── AddReferenceCommand       — Undoable reference addition
│       ├── ReplaceReferenceCommand   — Undoable reference replacement
│       ├── CreateShaderNodeCommand   — Undoable UsdShadeShader creation (Material Editor)
│       ├── ConnectShaderAttrsCommand — Undoable shader input↔output connection
│       ├── DisconnectShaderAttrCommand — Undoable shader connection removal
│       └── LayerCommands             — Create, remove, reorder sublayers
├── ui/                       — ImGui panels and application shell
│   ├── Application            — App shell (owns managers/panels, docking, menus)
│   ├── ImGuiContext            — Win32+OpenGL+ImGui initialization and loop
│   ├── ViewportPanel           — Viewport container (layout, divider drag, maximize)
│   ├── ViewportTile            — Single viewport tile (camera, rendering, overlays, picking)
│   ├── SceneHierarchyPanel     — Prim tree browser with context menus
│   ├── PropertyPanel           — Attribute/transform editor (channel box-style)
│   ├── StageEditorPanel        — Layer stack editor (edit target, dirty state, drag-drop ordering)
│   ├── TimelinePanel           — Transport controls, loop/bounce, frame scrub, Playblast
│   ├── CurveEditorPanel        — Maya-style F-curve editor (Bezier ↔ USD time samples)
│   ├── MaterialEditorPanel     — Hypershade-style UsdShade node-graph editor
│   ├── MaterialPreviewRenderer — Shader-ball preview: independent Hydra instance + scratch stage
│   ├── NodeThumbnailCache      — Async texture decode + amortized shader-ball thumbnails for the node canvas
│   ├── TransformManipulator    — ImDrawList gizmo (move/rotate/scale)
│   ├── IconManager             — SVG icon rasterization via NanoSVG
│   └── NodeEditor/             — Vendored/patched imgui-node-editor
└── utils/                    — Cross-cutting utilities
    ├── Logger                — Thread-safe logging (file + console); also sinks USD TF_WARN/TF_ERROR
    ├── FileDialog            — Win32 file open/save dialogs
    ├── PathUtils             — Exe-relative path resolution
    ├── OcioConfigParser      — Enumerates displays/views/colorspaces/looks from the active OCIO config
    ├── MovieEncoder          — Streams RGBA frames to H.264/MP4 via libavcodec (Playblast)
    └── GLExt                 — GLAD extension initialization

Key Design Patterns

  • Command Pattern — All mutable USD operations go through ICommandCommandHistory for undo/redo
  • Panel-Manager Separation — UI panels hold pointers to core managers but contain no USD layer/prim logic
  • Callback Wiring — Cross-panel communication via std::function callbacks (e.g. viewport pick → hierarchy select → property panel update)
  • Render-Delegate PlugabilityUsdSceneRenderer can switch Hydra render plugins at runtime
  • Own Color Correction Pass — Hydra's HdxColorCorrectionTask is bypassed; a file-local ViewportColorCorrector (inside UsdSceneRenderer.cpp) applies sRGB/OCIO as a fullscreen GL pass after Hydra renders linear (see docs/adr/0001-viewport-color-correction.md)
  • Gizmo as 2D OverlayTransformManipulator uses pure ImDrawList calls (no GL resources), same approach as ImGuizmo

Project Configuration

Config Purpose
cmake/modules/FindOpenUSD.cmake OpenUSD SDK discovery
cmake/modules/FindImgui.cmake ImGui source integration
cmake/modules/FindGlad.cmake GLAD loader setup
CMakePresets.json Build presets (VS 17 2022, x64)
docs/adr/ Architecture decision records
AGENTS.md AI agent build/architecture guide
.kilo/ Kilo AI configuration (commands, agents, skills)
openspec/changes/ Feature proposals and implementation tracking

Development Workflow

This project uses OpenSpec for feature development:

  1. Propose — Create a new change under openspec/changes/<name>/ with proposal.md, design.md, specs/, and tasks.md
  2. Implement — Work through checkbox-tracked tasks in tasks.md
  3. Archive — Move completed changes to openspec/archive/ when done

Use Kilo's openspec-* skills to streamline this workflow.

Runtime Requirements

  • Python 3.12 — OpenUSD requires python312.dll at runtime. CMake copies it to the output directory via POST_BUILD commands.
  • USD Plugin Path — The app scans <exe_dir>/usd/ for plugInfo.json and registers plugins via pxr::PlugRegistry.
  • Render delegate DLLs — hdEmbree, hdArnold, and hdCycles each bring their own runtime dependencies (Embree, Arnold SDK, Cycles libs). CMake POST_BUILD steps deploy all required DLLs next to the executable automatically.

Contributing

Before writing any OpenUSD API call, verify the API exists in the actual SDK:

findstr /r /s "FunctionName" third_party\OpenUSD_v25.05\include\

Always build and install before manually verifying a change:

cmake --build build --config Release
cmake --install build --config Release

License

See LICENSE file for details.

S
Description
USD Layer Manager for USD Scene Editing
Readme 12 MiB
Languages
C++ 96.6%
CMake 3.4%