5.4 KiB
Context
The application currently has a SceneHierarchyPanel class (92 lines) that implements a functional tree view of USD prims:
- Uses
PropertyManager::GetPrimPaths()to get all prims - Recursively renders prims with
RenderPrimNode()showing name, type, and selection state - Supports selection highlighting, tooltips with type/path, and double-click/arrow expansion
- Has a callback mechanism (
PrimSelectCallback) for notifying when a prim is selected
However, Application::RenderUI() (lines 94-103) ignores this class and renders an inline placeholder instead:
ImGui::Begin("Scene Hierarchy", nullptr, ImGuiWindowFlags_NoCollapse);
if (m_stageManager->HasStage()) {
ImGui::Text("Stage loaded: %s", m_stageManager->GetRootLayerIdentifier().c_str());
ImGui::Separator();
ImGui::Text("Scene hierarchy will be displayed here");
} else {
ImGui::TextDisabled("No stage loaded");
ImGui::Text("Open a USD file to view scene hierarchy");
}
ImGui::End();
Meanwhile, the LayerPanel class is properly wired in (lines 105-111) and functions correctly:
ImGui::Begin("Layer Panel", nullptr, ImGuiWindowFlags_NoCollapse);
if (m_stageManager->HasStage()) {
m_layerPanel->Render();
} else {
ImGui::TextDisabled("No stage loaded");
}
ImGui::End();
The PropertyPanel class exists as a header only (no .cpp file) and is also rendered as a placeholder.
Goals / Non-Goals
Goals:
- Wire the existing
SceneHierarchyPanelintoApplicationso it functions as a dockable panel - Enhance the panel with prim type icons, visibility/active state indicators, and context menus
- Ensure prim selection drives other panels (Property Panel) via the existing callback mechanism
- Maintain consistency with the existing
LayerPanelwiring pattern
Non-Goals:
- Do not create a new panel class from scratch (the class already exists)
- Do not modify the core USD traversal logic in
PropertyManager(it's already functional) - Do not implement 3D viewport or property editing in this change
- Do not change the docking architecture or ImGui context management
Decisions
1. Wiring Pattern: Follow Existing LayerPanel Approach
Decision: Wire SceneHierarchyPanel exactly like LayerPanel - create instance in Application::Initialize(), call SetPropertyManager(), and invoke Render() in Application::RenderUI().
Rationale:
- Consistency with existing working pattern (
LayerPanel) - Minimal changes required
- Clear separation of concerns (Application manages lifecycle, panel handles rendering)
- Avoids duplicating the placeholder code
Alternatives Considered:
- Inline rendering in Application (current placeholder) - rejected because it duplicates existing functionality
- Creating panel on-demand in RenderUI - rejected because it loses state and breaks consistency
2. Enhancement: Add Visual Indicators for Prim State
Decision: Enhance SceneHierarchyPanel::RenderPrimNode() to show:
- Prim type icons (using Unicode characters or colored text)
- Visibility/inactive state indicators (eye icon or strike-through)
- Reference/instance indicators
- Context menu for common operations (toggle visibility, toggle active)
Rationale:
- Provides immediate visual feedback about prim state without opening property panel
- Matches user expectations from similar tools (Maya Outliner, Unity Hierarchy)
- Leverages existing USD API (
GetVisibility(),GetActive()) - Non-invasive enhancement that builds on solid foundation
Implementation Notes:
- Use
prim.GetVisibility()andprim.GetActive()to determine state - Show icons before prim name: 👁️ (visible), 👁️🗨️ (invisible), ○ (active), ● (inactive)
- Context menu via
ImGui::BeginPopupContextItem()on the tree node
3. Integration: Connect Selection to Property Panel
Decision: Implement the PrimSelectCallback in Application to update the PropertyPanel when selection changes (once PropertyPanel is implemented).
Rationale:
- Leverages existing callback mechanism in SceneHierarchyPanel
- Enables future integration with PropertyPanel
- Follows event-driven pattern already established
- No changes needed to SceneHierarchyPanel itself
Note: PropertyPanel currently doesn't exist as .cpp, so this sets up the foundation for when it's implemented.
4. Performance: Maintain Existing Traversal Approach
Decision: Keep the existing PropertyManager::GetPrimPaths() + recursive traversal approach.
Rationale:
- Already implemented and working
GetPrimPaths()uses efficientUsdPrimRangetraversal- Caching isn't needed for typical scene sizes (<10k prims)
- Premature optimization would complicate the clean implementation
Risks / Trade-offs
[Performance] → Acceptable for typical USD scenes; GetPrimPaths() is O(N) but only called when stage changes or panel refreshes needed.
[UI Clutter] → Added icons and context menus enhance usability without overwhelming the interface; users can ignore extra visual cues if not needed.
[Tight Coupling] → Application now depends on SceneHierarchyPanel class; however, this follows the same pattern as LayerPanel and is acceptable for core UI components.
[Missing PropertyPanel] → Selection callback won't have immediate effect until PropertyPanel is implemented; this is expected and sets up proper integration for future work.
Open Questions
None - the path forward is clear: wire the existing panel, enhance it with visual indicators, and maintain consistency with existing patterns.