Compare commits
2 Commits
e5d7967455
...
8f309e5440
| Author | SHA1 | Date | |
|---|---|---|---|
| 8f309e5440 | |||
| a62764397c |
@@ -10,7 +10,7 @@ Collapsed=0
|
|||||||
|
|
||||||
[Window][Scene Hierarchy]
|
[Window][Scene Hierarchy]
|
||||||
Pos=0,22
|
Pos=0,22
|
||||||
Size=296,655
|
Size=285,655
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000001,0
|
DockId=0x00000001,0
|
||||||
|
|
||||||
@@ -20,43 +20,43 @@ Size=121,48
|
|||||||
Collapsed=0
|
Collapsed=0
|
||||||
|
|
||||||
[Window][Viewport]
|
[Window][Viewport]
|
||||||
Pos=298,22
|
Pos=287,22
|
||||||
Size=1499,1003
|
Size=1286,1003
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000007,0
|
DockId=0x00000007,0
|
||||||
|
|
||||||
[Window][Property Panel]
|
[Window][Property Panel]
|
||||||
Pos=1799,22
|
Pos=1575,22
|
||||||
Size=121,1093
|
Size=345,1093
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000006,0
|
DockId=0x00000006,0
|
||||||
|
|
||||||
[Window][Stage Info]
|
[Window][Stage Info]
|
||||||
Pos=0,22
|
Pos=0,22
|
||||||
Size=296,655
|
Size=285,655
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000001,1
|
DockId=0x00000001,1
|
||||||
|
|
||||||
[Window][Stage Editor]
|
[Window][Stage Editor]
|
||||||
Pos=0,679
|
Pos=0,679
|
||||||
Size=296,436
|
Size=285,436
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000002,0
|
DockId=0x00000002,0
|
||||||
|
|
||||||
[Window][Timeline]
|
[Window][Timeline]
|
||||||
Pos=298,1027
|
Pos=287,1027
|
||||||
Size=1499,88
|
Size=1286,88
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000008,0
|
DockId=0x00000008,0
|
||||||
|
|
||||||
[Docking][Data]
|
[Docking][Data]
|
||||||
DockSpace ID=0x08BD597D Window=0x1BBC0F80 Pos=0,22 Size=1920,1093 Split=X
|
DockSpace ID=0x08BD597D Window=0x1BBC0F80 Pos=0,22 Size=1920,1093 Split=X
|
||||||
DockNode ID=0x00000005 Parent=0x08BD597D SizeRef=1141,637 Split=X
|
DockNode ID=0x00000005 Parent=0x08BD597D SizeRef=1573,637 Split=X
|
||||||
DockNode ID=0x00000003 Parent=0x00000005 SizeRef=296,637 Split=Y Selected=0xB8729153
|
DockNode ID=0x00000003 Parent=0x00000005 SizeRef=285,637 Split=Y Selected=0xB8729153
|
||||||
DockNode ID=0x00000001 Parent=0x00000003 SizeRef=289,381 Selected=0xB8729153
|
DockNode ID=0x00000001 Parent=0x00000003 SizeRef=289,381 Selected=0xB8729153
|
||||||
DockNode ID=0x00000002 Parent=0x00000003 SizeRef=289,254 Selected=0xBE78FE5F
|
DockNode ID=0x00000002 Parent=0x00000003 SizeRef=289,254 Selected=0xBE78FE5F
|
||||||
DockNode ID=0x00000004 Parent=0x00000005 SizeRef=1499,637 Split=Y Selected=0xC450F867
|
DockNode ID=0x00000004 Parent=0x00000005 SizeRef=1286,637 Split=Y Selected=0xC450F867
|
||||||
DockNode ID=0x00000007 Parent=0x00000004 SizeRef=850,547 CentralNode=1 Selected=0xC450F867
|
DockNode ID=0x00000007 Parent=0x00000004 SizeRef=850,547 CentralNode=1 Selected=0xC450F867
|
||||||
DockNode ID=0x00000008 Parent=0x00000004 SizeRef=850,88 Selected=0x4F89F0DC
|
DockNode ID=0x00000008 Parent=0x00000004 SizeRef=850,88 Selected=0x4F89F0DC
|
||||||
DockNode ID=0x00000006 Parent=0x08BD597D SizeRef=121,637 Selected=0xFA2314A6
|
DockNode ID=0x00000006 Parent=0x08BD597D SizeRef=345,637 Selected=0xFA2314A6
|
||||||
|
|
||||||
|
|||||||
@@ -157,6 +157,24 @@ bool LayerManager::SetEditTarget(const std::string& identifier) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LayerManager::CreateNewSublayer(const std::string& absolutePath) {
|
||||||
|
if (!m_stage) return false;
|
||||||
|
SdfLayerHandle rootLayer = m_stage->GetRootLayer();
|
||||||
|
if (!rootLayer) return false;
|
||||||
|
|
||||||
|
auto newLayer = SdfLayer::CreateNew(absolutePath);
|
||||||
|
if (!newLayer) {
|
||||||
|
LOG_ERROR("Failed to create layer file: " + absolutePath);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
newLayer->Save();
|
||||||
|
|
||||||
|
rootLayer->InsertSubLayerPath(absolutePath, 0);
|
||||||
|
m_stage->SetEditTarget(newLayer);
|
||||||
|
Refresh();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool LayerManager::IsLayerMuted(const std::string& layerIdentifier) const {
|
bool LayerManager::IsLayerMuted(const std::string& layerIdentifier) const {
|
||||||
if (m_stage) {
|
if (m_stage) {
|
||||||
return m_stage->IsLayerMuted(layerIdentifier);
|
return m_stage->IsLayerMuted(layerIdentifier);
|
||||||
|
|||||||
@@ -44,6 +44,9 @@ public:
|
|||||||
// Edit target
|
// Edit target
|
||||||
bool SetEditTarget(const std::string& identifier);
|
bool SetEditTarget(const std::string& identifier);
|
||||||
|
|
||||||
|
// Create a new USD file on disk, insert as sublayer, and activate as edit target.
|
||||||
|
bool CreateNewSublayer(const std::string& absolutePath);
|
||||||
|
|
||||||
// Muting
|
// Muting
|
||||||
void MuteLayer(const std::string& layerIdentifier);
|
void MuteLayer(const std::string& layerIdentifier);
|
||||||
void UnmuteLayer(const std::string& layerIdentifier);
|
void UnmuteLayer(const std::string& layerIdentifier);
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ bool Application::Initialize(const std::string& windowTitle, int width, int heig
|
|||||||
m_sceneHierarchyPanel = std::make_unique<SceneHierarchyPanel>();
|
m_sceneHierarchyPanel = std::make_unique<SceneHierarchyPanel>();
|
||||||
m_sceneHierarchyPanel->SetPropertyManager(m_propertyManager.get());
|
m_sceneHierarchyPanel->SetPropertyManager(m_propertyManager.get());
|
||||||
m_sceneHierarchyPanel->SetCommandHistory(&m_commandHistory);
|
m_sceneHierarchyPanel->SetCommandHistory(&m_commandHistory);
|
||||||
|
m_sceneHierarchyPanel->SetLayerManager(m_layerManager.get());
|
||||||
m_viewportPanel = std::make_unique<ViewportPanel>();
|
m_viewportPanel = std::make_unique<ViewportPanel>();
|
||||||
m_viewportPanel->SetCommandHistory(&m_commandHistory);
|
m_viewportPanel->SetCommandHistory(&m_commandHistory);
|
||||||
m_propertyPanel = std::make_unique<PropertyPanel>();
|
m_propertyPanel = std::make_unique<PropertyPanel>();
|
||||||
|
|||||||
@@ -119,6 +119,63 @@ void SceneHierarchyPanel::Render() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── Edit-target layer switcher ────────────────────────────────────
|
||||||
|
{
|
||||||
|
struct LayerEntry { SdfLayerHandle layer; std::string label; };
|
||||||
|
std::vector<LayerEntry> layers;
|
||||||
|
|
||||||
|
auto sessionLayer = m_stage->GetSessionLayer();
|
||||||
|
if (sessionLayer)
|
||||||
|
layers.push_back({ sessionLayer, "Session" });
|
||||||
|
|
||||||
|
auto rootLayer = m_stage->GetRootLayer();
|
||||||
|
if (rootLayer) {
|
||||||
|
std::string name = rootLayer->IsAnonymous()
|
||||||
|
? "anonymous"
|
||||||
|
: std::filesystem::path(rootLayer->GetIdentifier()).filename().string();
|
||||||
|
layers.push_back({ rootLayer, "Root: " + name });
|
||||||
|
|
||||||
|
for (const auto& subPath : rootLayer->GetSubLayerPaths()) {
|
||||||
|
auto sub = SdfLayer::FindOrOpenRelativeToLayer(rootLayer, subPath);
|
||||||
|
if (!sub) continue;
|
||||||
|
std::string subName = sub->IsAnonymous()
|
||||||
|
? sub->GetIdentifier()
|
||||||
|
: std::filesystem::path(sub->GetIdentifier()).filename().string();
|
||||||
|
layers.push_back({ SdfLayerHandle(sub), subName });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string currentLabel = "\xe2\x80\x94"; // em dash
|
||||||
|
auto etLayer = m_stage->GetEditTarget().GetLayer();
|
||||||
|
if (etLayer) {
|
||||||
|
for (const auto& e : layers) {
|
||||||
|
if (e.layer && e.layer->GetIdentifier() == etLayer->GetIdentifier()) {
|
||||||
|
currentLabel = e.label;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::SetNextItemWidth(-1.0f);
|
||||||
|
if (ImGui::BeginCombo("##layerswitch", currentLabel.c_str(),
|
||||||
|
ImGuiComboFlags_HeightRegular)) {
|
||||||
|
for (const auto& e : layers) {
|
||||||
|
bool isCurrent = (e.layer && etLayer &&
|
||||||
|
e.layer->GetIdentifier() == etLayer->GetIdentifier());
|
||||||
|
if (ImGui::Selectable(e.label.c_str(), isCurrent)) {
|
||||||
|
if (m_layerManager)
|
||||||
|
m_layerManager->SetEditTarget(e.layer->GetIdentifier());
|
||||||
|
else
|
||||||
|
m_stage->SetEditTarget(UsdEditTarget(e.layer));
|
||||||
|
}
|
||||||
|
if (isCurrent)
|
||||||
|
ImGui::SetItemDefaultFocus();
|
||||||
|
}
|
||||||
|
ImGui::EndCombo();
|
||||||
|
}
|
||||||
|
ImGui::Spacing();
|
||||||
|
}
|
||||||
|
|
||||||
auto paths = m_propertyManager->GetPrimPaths();
|
auto paths = m_propertyManager->GetPrimPaths();
|
||||||
if (paths.empty()) {
|
if (paths.empty()) {
|
||||||
ImGui::TextDisabled("No prims in stage");
|
ImGui::TextDisabled("No prims in stage");
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "../core/PropertyManager.h"
|
#include "../core/PropertyManager.h"
|
||||||
#include "../core/CommandHistory.h"
|
#include "../core/CommandHistory.h"
|
||||||
|
#include "../core/LayerManager.h"
|
||||||
#include "IconManager.h"
|
#include "IconManager.h"
|
||||||
#include <pxr/usd/usd/stage.h>
|
#include <pxr/usd/usd/stage.h>
|
||||||
#include <pxr/usd/sdf/path.h>
|
#include <pxr/usd/sdf/path.h>
|
||||||
@@ -24,6 +25,7 @@ public:
|
|||||||
|
|
||||||
void SetPropertyManager(PropertyManager* manager);
|
void SetPropertyManager(PropertyManager* manager);
|
||||||
void SetCommandHistory(CommandHistory* history) { m_commandHistory = history; }
|
void SetCommandHistory(CommandHistory* history) { m_commandHistory = history; }
|
||||||
|
void SetLayerManager(LayerManager* lm) { m_layerManager = lm; }
|
||||||
void SetStage(UsdStageRefPtr stage);
|
void SetStage(UsdStageRefPtr stage);
|
||||||
void SetIconManager(IconManager* iconManager) { m_iconManager = iconManager; }
|
void SetIconManager(IconManager* iconManager) { m_iconManager = iconManager; }
|
||||||
void Render();
|
void Render();
|
||||||
@@ -74,6 +76,7 @@ private:
|
|||||||
|
|
||||||
PropertyManager* m_propertyManager;
|
PropertyManager* m_propertyManager;
|
||||||
CommandHistory* m_commandHistory = nullptr;
|
CommandHistory* m_commandHistory = nullptr;
|
||||||
|
LayerManager* m_layerManager = nullptr;
|
||||||
IconManager* m_iconManager = nullptr;
|
IconManager* m_iconManager = nullptr;
|
||||||
UsdStageRefPtr m_stage;
|
UsdStageRefPtr m_stage;
|
||||||
|
|
||||||
|
|||||||
@@ -7,10 +7,7 @@
|
|||||||
|
|
||||||
namespace UsdLayerManager {
|
namespace UsdLayerManager {
|
||||||
|
|
||||||
StageEditorPanel::StageEditorPanel() {
|
StageEditorPanel::StageEditorPanel() {}
|
||||||
m_newLayerPath[0] = '\0';
|
|
||||||
m_newLayerName[0] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
StageEditorPanel::~StageEditorPanel() {}
|
StageEditorPanel::~StageEditorPanel() {}
|
||||||
|
|
||||||
@@ -51,9 +48,12 @@ void StageEditorPanel::Render() {
|
|||||||
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (iconBtn("##createNew", Icon::FilePlus, "+N")) {
|
if (iconBtn("##createNew", Icon::FilePlus, "+N")) {
|
||||||
m_showCreateDialog = true;
|
std::string path = FileDialog::SaveFile(
|
||||||
m_newLayerPath[0] = '\0';
|
"USD Files (*.usd;*.usda;*.usdc)\0*.usd;*.usda;*.usdc\0All Files (*.*)\0*.*\0",
|
||||||
strcpy_s(m_newLayerName, "new_layer.usd");
|
"Create New Sublayer",
|
||||||
|
"usd");
|
||||||
|
if (!path.empty() && m_layerManager)
|
||||||
|
m_layerManager->CreateNewSublayer(path);
|
||||||
}
|
}
|
||||||
if (ImGui::IsItemHovered()) ImGui::SetTooltip("Create New Sublayer");
|
if (ImGui::IsItemHovered()) ImGui::SetTooltip("Create New Sublayer");
|
||||||
|
|
||||||
@@ -62,7 +62,6 @@ void StageEditorPanel::Render() {
|
|||||||
auto allLayers = m_layerManager->GetLayerStack();
|
auto allLayers = m_layerManager->GetLayerStack();
|
||||||
if (allLayers.empty()) {
|
if (allLayers.empty()) {
|
||||||
ImGui::TextDisabled("No stage loaded");
|
ImGui::TextDisabled("No stage loaded");
|
||||||
if (m_showCreateDialog) ShowCreateLayerDialog();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,7 +81,6 @@ void StageEditorPanel::Render() {
|
|||||||
|
|
||||||
RenderSublayerList(sublayers);
|
RenderSublayerList(sublayers);
|
||||||
|
|
||||||
if (m_showCreateDialog) ShowCreateLayerDialog();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -350,43 +348,5 @@ void StageEditorPanel::RenderSublayerContextMenu(int i,
|
|||||||
ImGui::EndPopup();
|
ImGui::EndPopup();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
void StageEditorPanel::ShowCreateLayerDialog() {
|
|
||||||
ImGui::SetNextWindowSize(ImVec2(400, 150), ImGuiCond_Always);
|
|
||||||
ImGui::OpenPopup("Create Sublayer");
|
|
||||||
|
|
||||||
if (ImGui::BeginPopupModal("Create Sublayer", &m_showCreateDialog)) {
|
|
||||||
ImGui::Text("Layer Name:");
|
|
||||||
ImGui::InputText("##name", m_newLayerName, sizeof(m_newLayerName));
|
|
||||||
|
|
||||||
ImGui::Spacing();
|
|
||||||
ImGui::Text("Save Path:");
|
|
||||||
ImGui::InputText("##path", m_newLayerPath, sizeof(m_newLayerPath));
|
|
||||||
|
|
||||||
ImGui::Spacing();
|
|
||||||
|
|
||||||
if (ImGui::Button("Create", ImVec2(120, 0))) {
|
|
||||||
std::string path;
|
|
||||||
if (m_newLayerPath[0] != '\0')
|
|
||||||
path = std::string(m_newLayerPath) + "/" + m_newLayerName;
|
|
||||||
else
|
|
||||||
path = m_newLayerName;
|
|
||||||
|
|
||||||
if (!path.empty()) {
|
|
||||||
if (m_commandHistory)
|
|
||||||
m_commandHistory->Push(std::make_unique<LayerCreateCommand>(
|
|
||||||
m_layerManager, "./" + path));
|
|
||||||
else
|
|
||||||
m_layerManager->CreateSublayer("./" + path);
|
|
||||||
m_showCreateDialog = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ImGui::SameLine();
|
|
||||||
if (ImGui::Button("Cancel", ImVec2(120, 0)))
|
|
||||||
m_showCreateDialog = false;
|
|
||||||
|
|
||||||
ImGui::EndPopup();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace UsdLayerManager
|
} // namespace UsdLayerManager
|
||||||
|
|||||||
@@ -23,15 +23,11 @@ private:
|
|||||||
void RenderFixedLayers(const std::vector<LayerInfo>& layers);
|
void RenderFixedLayers(const std::vector<LayerInfo>& layers);
|
||||||
void RenderSublayerList(const std::vector<LayerInfo>& sublayers);
|
void RenderSublayerList(const std::vector<LayerInfo>& sublayers);
|
||||||
void RenderSublayerContextMenu(int i, const std::vector<LayerInfo>& sublayers);
|
void RenderSublayerContextMenu(int i, const std::vector<LayerInfo>& sublayers);
|
||||||
void ShowCreateLayerDialog();
|
|
||||||
|
|
||||||
LayerManager* m_layerManager = nullptr;
|
LayerManager* m_layerManager = nullptr;
|
||||||
CommandHistory* m_commandHistory = nullptr;
|
CommandHistory* m_commandHistory = nullptr;
|
||||||
IconManager* m_iconManager = nullptr;
|
IconManager* m_iconManager = nullptr;
|
||||||
int m_selectedIdx = -1;
|
int m_selectedIdx = -1;
|
||||||
bool m_showCreateDialog = false;
|
|
||||||
char m_newLayerPath[256];
|
|
||||||
char m_newLayerName[128];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace UsdLayerManager
|
} // namespace UsdLayerManager
|
||||||
|
|||||||
Reference in New Issue
Block a user