Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions lib/mayaUsd/nodes/sceneRenderSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,26 @@ bool setActiveSettingPath(const std::string& ufePath)
return node->setActiveSettingsPath(ufePath);
}

std::string getCurrentRenderer()
{
MayaUsd::UsdSettingsNode* node
= MayaUsd::UsdSceneSettingsManager::getNodeForNodeName(kRenderSettingsNodeName);
if (!node) {
return {};
}
return node->currentRenderer();
}

bool setCurrentRenderer(const std::string& rendererName)
{
MayaUsd::UsdSettingsNode* node
= MayaUsd::UsdSceneSettingsManager::getNodeForNodeName(kRenderSettingsNodeName);
if (!node) {
return false;
}
return node->setCurrentRenderer(rendererName);
}

const PXR_NS::TfToken& externalCameraAttrName() { return kExternalCameraAttrName; }

bool setRenderSettingsCamera(
Expand Down
8 changes: 8 additions & 0 deletions lib/mayaUsd/nodes/sceneRenderSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ MAYAUSD_CORE_PUBLIC std::string getActiveSettingPath();
//! if the singleton node is unavailable or the plug write fails.
MAYAUSD_CORE_PUBLIC bool setActiveSettingPath(const std::string& ufePath);

//! Hydra renderer plugin name that drives USD Hydra rendering for the scene,
//! or an empty string when none has been chosen.
MAYAUSD_CORE_PUBLIC std::string getCurrentRenderer();

//! Author the Hydra renderer plugin name on the render-settings singleton.
//! Returns false if the singleton node is unavailable or the plug write fails.
MAYAUSD_CORE_PUBLIC bool setCurrentRenderer(const std::string& rendererName);

//! Name of the custom string attribute that records the UFE path of a camera
//! that does not live on the same stage as the render-settings prim
//! (e.g. a Maya native camera shape, or a camera in another USD stage).
Expand Down
26 changes: 26 additions & 0 deletions lib/mayaUsd/nodes/usdSettingsNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const MString UsdSettingsNode::typeName("UsdDefaultSettings");
MObject UsdSettingsNode::serializedRootLayerAttr;
MObject UsdSettingsNode::serializedSessionLayerAttr;
MObject UsdSettingsNode::activeSettingsPathAttr;
MObject UsdSettingsNode::currentRendererAttr;

/* static */
void* UsdSettingsNode::creator() { return new UsdSettingsNode(); }
Expand Down Expand Up @@ -84,6 +85,18 @@ MStatus UsdSettingsNode::initialize()
status = addAttribute(activeSettingsPathAttr);
CHECK_MSTATUS_AND_RETURN_IT(status);

// Hydra renderer plugin name persisted on the node to select which Hydra
// backend is used for USD rendering. Hidden/internal: reads/writes go
// through the typed accessors.
currentRendererAttr = typedAttrFn.create(
"currentRenderer", "crn", MFnData::kString, defaultStringDataObj, &status);
CHECK_MSTATUS_AND_RETURN_IT(status);
typedAttrFn.setStorable(true);
typedAttrFn.setHidden(true);
typedAttrFn.setInternal(true);
status = addAttribute(currentRendererAttr);
CHECK_MSTATUS_AND_RETURN_IT(status);

return status;
}

Expand Down Expand Up @@ -119,6 +132,19 @@ bool UsdSettingsNode::setActiveSettingsPath(const std::string& ufePath)
return status == MS::kSuccess;
}

std::string UsdSettingsNode::currentRenderer() const
{
MPlug plug(thisMObject(), currentRendererAttr);
return plug.asString().asChar();
}

bool UsdSettingsNode::setCurrentRenderer(const std::string& rendererName)
{
MPlug plug(thisMObject(), currentRendererAttr);
MStatus status = plug.setString(MString(rendererName.c_str()));
return status == MS::kSuccess;
}

void UsdSettingsNode::ensureStage() const
{
if (_stage) {
Expand Down
8 changes: 8 additions & 0 deletions lib/mayaUsd/nodes/usdSettingsNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class MAYAUSD_CORE_PUBLIC UsdSettingsNode
static MObject serializedRootLayerAttr;
static MObject serializedSessionLayerAttr;
static MObject activeSettingsPathAttr;
static MObject currentRendererAttr;

static void* creator();
static MStatus initialize();
Expand All @@ -85,6 +86,13 @@ class MAYAUSD_CORE_PUBLIC UsdSettingsNode
//! false on plug-write failure.
bool setActiveSettingsPath(const std::string& ufePath);

//! Hydra renderer plugin name that drives USD Hydra rendering for the
//! scene, or an empty string when no renderer has been chosen.
std::string currentRenderer() const;

//! Author the Hydra renderer plugin name. Returns false on plug-write failure.
bool setCurrentRenderer(const std::string& rendererName);

// Serialization (called by UsdSceneSettingsManager scene callbacks)
void serializeToAttributes();
void deserializeFromAttributes();
Expand Down
4 changes: 4 additions & 0 deletions lib/mayaUsd/python/wrapSceneRenderSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ void wrapSceneRenderSettings()
.staticmethod("getActiveRenderSettingsPath")
.def("setActiveRenderSettingsPath", &MayaUsd::SceneRenderSettings::setActiveSettingPath)
.staticmethod("setActiveRenderSettingsPath")
.def("getCurrentRenderer", &MayaUsd::SceneRenderSettings::getCurrentRenderer)
.staticmethod("getCurrentRenderer")
.def("setCurrentRenderer", &MayaUsd::SceneRenderSettings::setCurrentRenderer)
.staticmethod("setCurrentRenderer")
.def(
"externalCameraAttrName",
+[]() { return MayaUsd::SceneRenderSettings::externalCameraAttrName().GetString(); })
Expand Down
58 changes: 58 additions & 0 deletions test/lib/mayaUsd/nodes/testSceneRenderSettings.py
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,64 @@ def testActiveSettingsPathResetOnFileNew(self):
UsdDefaultRenderSettings.getActiveRenderSettingsPath(),
defaultPath)

# ------------------------------------------------------------------
# Hydra renderer selection (currentRenderer)
# ------------------------------------------------------------------

def testCurrentRendererDefault(self):
'''Default currentRenderer is empty; no Hydra renderer is chosen yet.'''
nodeName = UsdDefaultRenderSettings.find()
self.assertEqual(UsdDefaultRenderSettings.getCurrentRenderer(), '')
self.assertEqual(
cmds.getAttr(nodeName + '.currentRenderer'), '')

def testCurrentRendererSetter(self):
'''Writing through the helper updates every read path.'''
rendererName = 'HdStormRendererPlugin'
self.assertTrue(
UsdDefaultRenderSettings.setCurrentRenderer(rendererName))

self.assertEqual(
UsdDefaultRenderSettings.getCurrentRenderer(), rendererName)
nodeName = UsdDefaultRenderSettings.find()
self.assertEqual(
cmds.getAttr(nodeName + '.currentRenderer'), rendererName)

def testCurrentRendererRoundTrip(self):
'''A custom currentRenderer survives a save/open cycle.'''
rendererName = 'SomeCustomRenderer'
self.assertTrue(
UsdDefaultRenderSettings.setCurrentRenderer(rendererName))

tmpDir = tempfile.mkdtemp(prefix='testSceneRenderSettings_')
try:
tmpFile = os.path.join(tmpDir, 'currentRendererRoundTrip.ma')
cmds.file(rename=tmpFile)
cmds.file(save=True, type='mayaAscii')
cmds.file(new=True, force=True)
cmds.file(tmpFile, open=True, force=True)

self.assertEqual(
UsdDefaultRenderSettings.getCurrentRenderer(),
rendererName)
finally:
cmds.file(new=True, force=True)
shutil.rmtree(tmpDir, ignore_errors=True)

def testCurrentRendererResetOnFileNew(self):
'''File > New restores the empty default value.'''
self.assertEqual(UsdDefaultRenderSettings.getCurrentRenderer(), '')

rendererName = 'TemporaryRenderer'
self.assertTrue(
UsdDefaultRenderSettings.setCurrentRenderer(rendererName))
self.assertEqual(
UsdDefaultRenderSettings.getCurrentRenderer(), rendererName)

cmds.file(new=True, force=True)

self.assertEqual(UsdDefaultRenderSettings.getCurrentRenderer(), '')

# ------------------------------------------------------------------
# Locked-node invariant
# ------------------------------------------------------------------
Expand Down
Loading