Files
UsdLayerManager/src/core/commands/DeletePrimCommand.cpp
T
indigo 038450a1ca Vendor node editor in-tree; add material presets; debug drag regression
Move the imgui-node-editor subset the build actually compiles from
third_party/imgui-node-editor to src/ui/NodeEditor (version-controlled,
MIT LICENSE included). FindImguiNodeEditor.cmake points at the new
location; CMakeLists excludes src/ui/NodeEditor from UI_SOURCES so it
isn't compiled twice.

Material editor presets: a Presets menu (disabled with no open material)
builds a UsdPreviewSurface + UsdUVTexture graph fed by an st primvar
reader, or a MaterialX standard_surface + image graph fed by a texcoord
node. Each is one idempotent, undoable command that re-normalizes layout.
Create Material becomes an icon button. New nodes route through
FindFreeCanvasSpot so a creation never lands on top of an existing node
(overlapping nodes fight over the editor hit test and become undraggable).

Shader-ball preview: pick a previewable output (terminal or 3/4-component
color-like) instead of always the first output, so scalar-only nodes keep
the whole-material preview rather than failing Storm codegen. Per-shape
camera frame-fit margins and auto-clip framing.

Fixes: DeletePrimCommand::Undo recreates missing destination ancestors
before SdfCopySpec (parent material may have been deleted after the
command ran). ConfigWindowsMoveFromTitleBarOnly stops a content-area drag
in the node canvas from moving the whole Material Editor window.

Temporary (marked for removal once the node-editor drag regression is
diagnosed): main.cpp mirrors LOG_INFO to %APPDATA%\UsdLayerManager\
debug.log; a g_AxNodeEditorDebugLog hook in the vendored editor plus a
[NodeGraph] event-trace block in RenderNodeGraphCanvas dump click/drag/
selection/position-save state.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 22:35:23 +08:00

78 lines
2.9 KiB
C++

#include "DeletePrimCommand.h"
#include "../../utils/Logger.h"
#include <pxr/usd/sdf/copyUtils.h>
#include <pxr/usd/sdf/primSpec.h>
namespace UsdLayerManager {
DeletePrimCommand::DeletePrimCommand(pxr::UsdStageRefPtr stage,
const pxr::SdfPath& primPath)
: m_stage(stage)
, m_primPath(primPath)
, m_description("Delete " + primPath.GetString())
{
if (!stage) return;
pxr::SdfLayerHandle rootLayer = stage->GetRootLayer();
if (!rootLayer) return;
// Only capture if the spec exists on the root layer.
if (!rootLayer->HasSpec(primPath)) {
LOG_ERROR("DeletePrimCommand: no spec found for " + primPath.GetString());
return;
}
m_savedLayer = pxr::SdfLayer::CreateAnonymous(".usda");
if (!m_savedLayer) return;
// Ensure the parent path hierarchy exists in the saved layer.
pxr::SdfPath parentPath = primPath.GetParentPath();
while (!parentPath.IsAbsoluteRootPath() && !m_savedLayer->HasSpec(parentPath)) {
pxr::SdfPrimSpec::New(m_savedLayer,
parentPath.GetName(),
pxr::SdfSpecifierOver);
parentPath = parentPath.GetParentPath();
}
if (pxr::SdfCopySpec(rootLayer, primPath, m_savedLayer, primPath)) {
m_specWasSaved = true;
} else {
LOG_ERROR("DeletePrimCommand: SdfCopySpec failed for " + primPath.GetString());
}
}
void DeletePrimCommand::Execute() {
if (!m_stage) return;
try {
if (!m_stage->RemovePrim(m_primPath))
LOG_ERROR("DeletePrimCommand: RemovePrim failed for " + m_primPath.GetString());
} catch (const std::exception& e) {
LOG_ERROR(std::string("DeletePrimCommand::Execute error: ") + e.what());
}
}
void DeletePrimCommand::Undo() {
if (!m_stage || !m_specWasSaved || !m_savedLayer) {
LOG_ERROR("DeletePrimCommand::Undo: cannot restore — spec was not saved");
return;
}
pxr::SdfLayerHandle rootLayer = m_stage->GetRootLayer();
if (!rootLayer) return;
try {
// The destination ancestors may be gone by now (e.g. the parent
// material was itself deleted after this command ran) — SdfCopySpec
// fails with "No spec ... when trying to set field 'primChildren'"
// when the parent spec is missing, so recreate the chain first.
pxr::SdfPath parentPath = m_primPath.GetParentPath();
if (!parentPath.IsAbsoluteRootPath() && !rootLayer->GetPrimAtPath(parentPath))
pxr::SdfCreatePrimInLayer(rootLayer, parentPath);
if (!pxr::SdfCopySpec(m_savedLayer, m_primPath, rootLayer, m_primPath))
LOG_ERROR("DeletePrimCommand::Undo: SdfCopySpec failed for " + m_primPath.GetString());
} catch (const std::exception& e) {
LOG_ERROR(std::string("DeletePrimCommand::Undo error: ") + e.what());
}
}
} // namespace UsdLayerManager