Add Hypershade-style Material Editor with node graph and shader-ball preview
Browser column lists all scene materials plus a searchable create-node list; Show Graph (or double-click) loads a material into the node-graph work area. The graph shows the entire network including MaterialX (.mtlx) node graphs, resolving connections through NodeGraph boundaries via UsdShadeUtils::GetValueProducingAttributes, with layered auto-layout for nodes lacking authored uiPosition. Canvas navigates viewport-style (Alt+MMB pan / Alt+RMB zoom) and TAB opens a Nuke-style search popup. Selecting a node shows a typed property editor (live-apply, one undo command per edit) and previews that node's output on the shader ball. The preview renders through its own Hydra engine into a scratch stage that composes the material via a reference to the source root layer (so referenced .mtlx materials work), re-renders until progressive delegates (Arnold/Cycles/Embree) converge, and lights with HDR dome presets (External/Room/Interior/Sunset; CC0 Poly Haven EXRs fetched at CMake configure). texture:format is authored latlong explicitly - left automatic, hdArnold falls back to Arnold's angular fisheye default - and hdCycles gets a -90 X pole rotation to match Storm's +Y-pole sampling. Mutations go through new ICommand subclasses (create shader node, connect/disconnect attrs). imgui-node-editor is vendored (gitignored) with a local one-line patch: c_ScrollButtonIndex 1->2 for MMB pan. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
#include "DisconnectShaderAttrCommand.h"
|
||||
#include "../../utils/Logger.h"
|
||||
#include <pxr/usd/usdShade/shader.h>
|
||||
#include <pxr/usd/usdShade/connectableAPI.h>
|
||||
#include <pxr/base/tf/token.h>
|
||||
|
||||
namespace UsdLayerManager {
|
||||
|
||||
DisconnectShaderAttrCommand::DisconnectShaderAttrCommand(pxr::UsdStageRefPtr stage,
|
||||
const pxr::SdfPath& destNode,
|
||||
const std::string& destInput)
|
||||
: m_stage(stage)
|
||||
, m_destNode(destNode)
|
||||
, m_destInput(destInput)
|
||||
, m_description("Disconnect " + destNode.GetName() + "." + destInput)
|
||||
{
|
||||
if (!stage) return;
|
||||
|
||||
pxr::UsdShadeShader destShader(stage->GetPrimAtPath(destNode));
|
||||
if (!destShader) return;
|
||||
|
||||
pxr::UsdShadeInput input = destShader.GetInput(pxr::TfToken(destInput));
|
||||
if (!input) return;
|
||||
|
||||
for (const auto& source : pxr::UsdShadeConnectableAPI::GetConnectedSources(input)) {
|
||||
if (!source.IsValid()) continue;
|
||||
m_hadConnection = true;
|
||||
m_sourceNode = source.source.GetPrim().GetPath();
|
||||
m_sourceOutput = source.sourceName.GetString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DisconnectShaderAttrCommand::Execute() {
|
||||
if (!m_stage) return;
|
||||
try {
|
||||
pxr::UsdShadeShader destShader(m_stage->GetPrimAtPath(m_destNode));
|
||||
if (!destShader) return;
|
||||
pxr::UsdShadeInput input = destShader.GetInput(pxr::TfToken(m_destInput));
|
||||
if (!input) return;
|
||||
pxr::UsdShadeConnectableAPI::DisconnectSource(input);
|
||||
} catch (const std::exception& e) {
|
||||
LOG_ERROR(std::string("DisconnectShaderAttrCommand::Execute error: ") + e.what());
|
||||
}
|
||||
}
|
||||
|
||||
void DisconnectShaderAttrCommand::Undo() {
|
||||
if (!m_stage || !m_hadConnection) return;
|
||||
try {
|
||||
pxr::UsdShadeShader destShader(m_stage->GetPrimAtPath(m_destNode));
|
||||
pxr::UsdShadeShader sourceShader(m_stage->GetPrimAtPath(m_sourceNode));
|
||||
if (!destShader || !sourceShader) return;
|
||||
|
||||
pxr::UsdShadeInput input = destShader.GetInput(pxr::TfToken(m_destInput));
|
||||
pxr::UsdShadeOutput output = sourceShader.GetOutput(pxr::TfToken(m_sourceOutput));
|
||||
if (input && output)
|
||||
pxr::UsdShadeConnectableAPI::ConnectToSource(input, output);
|
||||
} catch (const std::exception& e) {
|
||||
LOG_ERROR(std::string("DisconnectShaderAttrCommand::Undo error: ") + e.what());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace UsdLayerManager
|
||||
Reference in New Issue
Block a user