HYDRA-1760 : Support translation of maya extension attributes to hydra for lights, cameras and meshes#398
HYDRA-1760 : Support translation of maya extension attributes to hydra for lights, cameras and meshes#398lanierd-adsk wants to merge 8 commits intodevfrom
Conversation
…ts, cameras and meshes
| MIndexBuffer* indices = geom->indexBuffer(0); | ||
| if (indices) { | ||
| int indexCount = indices->size(); | ||
| vertexIndices.resize(indexCount); |
There was a problem hiding this comment.
Redundant with the line :
vertexIndices.assign(indicesData, indicesData + indexCount);
There was a problem hiding this comment.
Pull request overview
This PR extends Maya→Hydra primvar translation and dirtying behavior to better support extension/plugin attributes (notably Arnold ai*) across meshes, cameras, and lights, and adds/updates test coverage to validate translation + dirty-notice behavior.
Changes:
- Refactors adapter dirtying to centralize “primvar dirty on attribute change” logic and reduce duplicate notifications (camera/light/mesh/render item).
- Updates attribute extraction to optionally include broader attribute sets (for light/plugin attrs) and to skip default-valued attributes.
- Adds new C++ + Python tests (and golden files) for mesh/camera/light primvars and Maya node attribute dirtying.
Reviewed changes
Copilot reviewed 38 out of 39 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| test/lib/mayaUsd/render/mayaToHydra/cpp/testUtils.h | Adds shared test helpers for prim lookup, optionVar reading, DAG-path parsing, and scene-index traversal. |
| test/lib/mayaUsd/render/mayaToHydra/cpp/testUtils.cpp | Implements new helpers; improves text comparison normalization and exposes dump output path helper. |
| test/lib/mayaUsd/render/mayaToHydra/cpp/testMeshPrimvars.py | New Python harness to build a mesh scene and run new C++ primvar/dirtying tests. |
| test/lib/mayaUsd/render/mayaToHydra/cpp/testMeshPrimvars.cpp | New mesh primvar dirtying + param-attr list consistency tests. |
| test/lib/mayaUsd/render/mayaToHydra/cpp/testMayaNodesAttributesDirtying.py | Renames/expands dirtying tests for mesh/camera/light/material and light params. |
| test/lib/mayaUsd/render/mayaToHydra/cpp/testMayaNodesAttributesDirtying.cpp | New, more detailed dirty-notice validation for extension attrs and light params. |
| test/lib/mayaUsd/render/mayaToHydra/cpp/testMayaNodesAttributes.py | Renames test class; adds scene setup including an Arnold light; adds new C++ test entrypoints. |
| test/lib/mayaUsd/render/mayaToHydra/cpp/testLightPrimvars.py | New Python harness for Arnold light primvar translation + dirtying tests. |
| test/lib/mayaUsd/render/mayaToHydra/cpp/testLightPrimvars.cpp | New C++ tests for light primvar translation/dirtying and param-attr list consistency. |
| test/lib/mayaUsd/render/mayaToHydra/cpp/testCustomAttributes.cpp | Reworks tests to validate “default values don’t emit primvars” and primvar removal on reset; adds camera compound test and cross-node reset test. |
| test/lib/mayaUsd/render/mayaToHydra/cpp/testCustomAttributeTypes.cpp | Switches to shared CreatePrimPredicate; updates comment for renamed Python test. |
| test/lib/mayaUsd/render/mayaToHydra/cpp/testCameraPrimvars.py | New Python harness for camera primvar dirtying + param-attr list consistency tests. |
| test/lib/mayaUsd/render/mayaToHydra/cpp/testCameraPrimvars.cpp | New camera primvar dirtying + param-attr list consistency tests. |
| test/lib/mayaUsd/render/mayaToHydra/cpp/testCamera.cpp | Uses shared CreatePrimPredicate. |
| test/lib/mayaUsd/render/mayaToHydra/cpp/testCustomAttributeDirtying.cpp | Removes old dirtying test file (replaced by new suites). |
| test/lib/mayaUsd/render/mayaToHydra/cpp/MayaNodesAttributesTest/* | Adds golden reference outputs + README for primvar serialization comparisons. |
| test/lib/mayaUsd/render/mayaToHydra/cpp/CMakeLists.txt | Registers new C++ test sources (mesh/camera/light/dirtying). |
| test/lib/mayaUsd/render/mayaToHydra/CMakeLists.txt | Registers new interactive Python tests; updates renamed scripts; adds mesh-adapter test script. |
| lib/mayaHydra/hydraExtensions/mixedUtils.h | Renames and extends attribute extraction API to support “include all (non-builtin) attrs” option. |
| lib/mayaHydra/hydraExtensions/mixedUtils.cpp | Implements expanded attribute collection and default filtering (incl. plugin default workarounds). |
| lib/mayaHydra/hydraExtensions/adapters/renderItemAdapter.cpp | Adjusts attribute-changed callback to avoid duplicates for camera/light render items and to gate on kAttributeSet. |
| lib/mayaHydra/hydraExtensions/adapters/nurbsCurveAdapter.cpp | Routes attribute changes through the new primvar-dirty helper. |
| lib/mayaHydra/hydraExtensions/adapters/meshAdapterTestUtils.h | New test-only API to expose mesh param attribute list. |
| lib/mayaHydra/hydraExtensions/adapters/meshAdapter.cpp | Adds mesh param attribute list, improves dirty callback handling for compound attrs, and updates primvar dirtying behavior. |
| lib/mayaHydra/hydraExtensions/adapters/lightAdapter.h | Adds primvar inclusion override + param-attr test API + primvar dirtying hooks. |
| lib/mayaHydra/hydraExtensions/adapters/lightAdapter.cpp | Refactors callbacks to reduce redundant notifications and to distinguish param vs primvar-only attrs. |
| lib/mayaHydra/hydraExtensions/adapters/cameraAdapter.h | Adds param-attr test API and primvar dirtying hook. |
| lib/mayaHydra/hydraExtensions/adapters/cameraAdapter.cpp | Refactors callbacks to combine param+primvar dirtying and handle reset-to-default updates. |
| lib/mayaHydra/hydraExtensions/adapters/adapter.h | Introduces shared primvar-dirty helpers and param-attribute set utilities. |
| lib/mayaHydra/hydraExtensions/adapters/adapter.cpp | Implements shared helpers, integrates new attribute extraction, and consolidates dirty-bit emission. |
| lib/mayaHydra/hydraExtensions/adapters/CMakeLists.txt | Adds new mesh adapter test utils header to build. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| MObject attrObj = nodeFn.attribute(i); | ||
| MFnAttribute attrFn(attrObj); | ||
| auto attrName = attrFn.name().asChar(); | ||
| MPlug attrPlug(node, attrObj); | ||
| MStatus plugStatus; | ||
| MPlug attrPlug = FindPlugWithFallback(nodeFn, attrFn.name(), plugStatus); | ||
| if (!plugStatus || attrPlug.isNull()) |
| static std::unordered_set<std::string> s; | ||
| static bool init = false; | ||
| if (!init) { | ||
| for (const char* name : names) { | ||
| s.insert(name); | ||
| } | ||
| init = true; | ||
| } |
| const MString cmd = "setAttr -type \"" + typeName + "\" \"" + attrName + "\" 0 0 0"; | ||
| ASSERT_EQ(MGlobal::executeCommand(cmd), MStatus::kSuccess); | ||
|
|
||
| const double x = elementPlug.child(0).asDouble(); | ||
| const double y = elementPlug.child(1).asDouble(); | ||
| const double z = elementPlug.child(2).asDouble(); | ||
| if (std::abs(x) > 1e-9 || std::abs(y) > 1e-9 || std::abs(z) > 1e-9) { |
There was a problem hiding this comment.
Pull request overview
This PR extends Maya→Hydra primvar translation/dirtying to better support mesh, camera, and light attributes (including plugin attributes like Arnold ai*), and adds/updates a substantial set of C++/Python tests plus golden reference outputs.
Changes:
- Refactors attribute collection for primvar translation (new
GetAttributesFromNode+ default-value skipping). - Reworks adapter dirtying behavior for cameras/lights/meshes to reduce duplicate notifications and ensure primvars update/removal on reset-to-default.
- Adds new primvar/dirtying C++ tests with Python scene setup and golden reference outputs; updates test utilities to support these patterns.
Reviewed changes
Copilot reviewed 38 out of 39 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| test/lib/mayaUsd/render/mayaToHydra/cpp/testUtils.h | Adds reusable prim-finding helpers and path/optionVar utilities for new tests. |
| test/lib/mayaUsd/render/mayaToHydra/cpp/testUtils.cpp | Implements new test helpers; normalizes output/reference comparison behavior. |
| test/lib/mayaUsd/render/mayaToHydra/cpp/testMeshPrimvars.py | New Python harness to build a mesh scene for C++ primvar/dirtying tests. |
| test/lib/mayaUsd/render/mayaToHydra/cpp/testMeshPrimvars.cpp | New C++ tests for mesh primvar dirtying and param-attr list consistency. |
| test/lib/mayaUsd/render/mayaToHydra/cpp/testMayaNodesAttributesDirtying.py | Renames/expands test script and routes to new C++ test suite. |
| test/lib/mayaUsd/render/mayaToHydra/cpp/testMayaNodesAttributesDirtying.cpp | New C++ dirtying tests for mesh/camera/light/material attributes. |
| test/lib/mayaUsd/render/mayaToHydra/cpp/testMayaNodesAttributes.py | Renames test class and adds a scene variant including an Arnold light. |
| test/lib/mayaUsd/render/mayaToHydra/cpp/testLightPrimvars.py | New Python harness to build an Arnold light scene for C++ tests. |
| test/lib/mayaUsd/render/mayaToHydra/cpp/testLightPrimvars.cpp | New C++ tests for light primvar translation/dirtying and param-attr list consistency. |
| test/lib/mayaUsd/render/mayaToHydra/cpp/testCameraPrimvars.py | New Python harness to build a camera scene for C++ tests. |
| test/lib/mayaUsd/render/mayaToHydra/cpp/testCameraPrimvars.cpp | New C++ tests for camera primvar dirtying and param-attr list consistency. |
| test/lib/mayaUsd/render/mayaToHydra/cpp/testCustomAttributes.cpp | Updates/extends custom-attribute tests (default suppression + reset behavior). |
| test/lib/mayaUsd/render/mayaToHydra/cpp/testCustomAttributeTypes.cpp | Switches to shared prim predicate; updates test reference to renamed Python file. |
| test/lib/mayaUsd/render/mayaToHydra/cpp/testCamera.cpp | Uses shared CreatePrimPredicate helper. |
| test/lib/mayaUsd/render/mayaToHydra/cpp/MayaNodesAttributesTest/light_primvar_aiColorTemperature_modified.txt | New golden output for light primvar test. |
| test/lib/mayaUsd/render/mayaToHydra/cpp/MayaNodesAttributesTest/cube_primvar_aiSubdivIterations_modified.txt | New golden output for mesh primvar test. |
| test/lib/mayaUsd/render/mayaToHydra/cpp/MayaNodesAttributesTest/cube_primvar_aiSubdivIterations_fresh.txt | Updates golden output formatting/whitespace. |
| test/lib/mayaUsd/render/mayaToHydra/cpp/MayaNodesAttributesTest/cube_primvar_aiAutobumpVisibility_modified.txt | New golden output for mesh primvar test. |
| test/lib/mayaUsd/render/mayaToHydra/cpp/MayaNodesAttributesTest/cube_primvar_aiAutobumpVisibility_fresh.txt | Updates golden output formatting/whitespace. |
| test/lib/mayaUsd/render/mayaToHydra/cpp/MayaNodesAttributesTest/cube_primvar_absent.txt | New golden output representing “primvar absent”. |
| test/lib/mayaUsd/render/mayaToHydra/cpp/MayaNodesAttributesTest/camera_primvar_aiUScale_modified.txt | New golden output for camera primvar test. |
| test/lib/mayaUsd/render/mayaToHydra/cpp/MayaNodesAttributesTest/camera_primvar_aiLookAt_modified.txt | New golden output for camera compound primvar test. |
| test/lib/mayaUsd/render/mayaToHydra/cpp/MayaNodesAttributesTest/README.md | Documents golden-file usage and comparison behavior. |
| test/lib/mayaUsd/render/mayaToHydra/cpp/CMakeLists.txt | Adds new C++ test sources; replaces removed dirtying test file. |
| test/lib/mayaUsd/render/mayaToHydra/CMakeLists.txt | Registers new interactive Python test scripts and mesh-adapter test list updates. |
| lib/mayaHydra/hydraExtensions/mixedUtils.h | Renames/extends exported attribute-gathering API for primvar translation. |
| lib/mayaHydra/hydraExtensions/mixedUtils.cpp | Implements expanded attribute gathering with default suppression and skip list. |
| lib/mayaHydra/hydraExtensions/adapters/renderItemAdapter.cpp | Adjusts attribute-change callback logic for primvar dirtying (skip cameras/lights). |
| lib/mayaHydra/hydraExtensions/adapters/nurbsCurveAdapter.cpp | Switches to new primvar-dirty helper path. |
| lib/mayaHydra/hydraExtensions/adapters/meshAdapterTestUtils.h | New exported helper for mesh adapter param-attribute list unit testing. |
| lib/mayaHydra/hydraExtensions/adapters/meshAdapter.cpp | Adds param-attr list exposure + adjusts dirtying logic to reduce duplicates. |
| lib/mayaHydra/hydraExtensions/adapters/lightAdapter.h | Adds primvar/param dirtying overrides and test-only param-attr accessor. |
| lib/mayaHydra/hydraExtensions/adapters/lightAdapter.cpp | Refactors dirtying logic and centralizes light param attribute list. |
| lib/mayaHydra/hydraExtensions/adapters/cameraAdapter.h | Adds primvar dirty gating + test-only param-attr accessor. |
| lib/mayaHydra/hydraExtensions/adapters/cameraAdapter.cpp | Refactors dirtying callbacks to reduce duplicates and ensure primvar updates on reset. |
| lib/mayaHydra/hydraExtensions/adapters/adapter.h | Adds new primvar-dirty helpers and attribute-set utilities for adapters. |
| lib/mayaHydra/hydraExtensions/adapters/adapter.cpp | Switches to new attribute gathering + consolidated dirtying for primvar changes. |
| lib/mayaHydra/hydraExtensions/adapters/CMakeLists.txt | Registers new mesh adapter test utils header in build. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // Populate a dictionary with attribute values for translation to Hydra primvars. | ||
| // When includeAllAttributes is false: only extension and dynamic attributes. | ||
| // When true: all non-builtin attributes (skip default values in both cases). | ||
| void GetAttributesFromNode( | ||
| const MObject& node, PXR_NS::VtDictionary& attrs, bool includeAllAttributes) | ||
| { | ||
| attrs.clear(); | ||
| MStatus status; | ||
| MFnDependencyNode nodeFn(node, &status); | ||
| if (ARCH_UNLIKELY(!status)) { | ||
| return; | ||
| } | ||
|
|
||
| const auto& builtInSkipSet = _GetBuiltInAttributeSkipSet(); | ||
|
|
||
| for (size_t i = 0; i < nodeFn.attributeCount(); i++) { | ||
| MObject attrObj = nodeFn.attribute(i); | ||
| MFnAttribute attrFn(attrObj); | ||
| auto attrName = attrFn.name().asChar(); | ||
| MPlug attrPlug(node, attrObj); | ||
| const MString attrNameStr = attrFn.name(); | ||
| const char* attrName = attrNameStr.asChar(); | ||
| MStatus plugStatus; | ||
| MPlug attrPlug = FindPlugWithFallback(nodeFn, attrNameStr, plugStatus); | ||
| if (!plugStatus || attrPlug.isNull()) | ||
| continue; | ||
| if (attrPlug.isChild()) | ||
| continue; | ||
|
|
||
| if (attrFn.isExtension() || attrFn.isDynamic()) { | ||
| const bool ignoreDefault = attrFn.isDynamic(); | ||
| switch (attrObj.apiType()) { | ||
| const bool isExtOrDynamic = attrFn.isExtension() || attrFn.isDynamic(); | ||
| if (!includeAllAttributes && !isExtOrDynamic) | ||
| continue; | ||
| if (includeAllAttributes && builtInSkipSet.count(attrName) > 0) | ||
| continue; | ||
|
|
| TfToken GetRenderTag() const override; | ||
|
|
||
| MAYAHYDRALIB_API | ||
| bool IncludeAllAttributesInPrimvars() const override { return true; } | ||
|
|
||
| bool ShouldMarkPrimvarDirtyForAttributeChange(const MPlug& plug) const override; | ||
| HdDirtyBits GetExtraDirtyBitsForPrimvarAttributeChange(const MPlug& plug) const override; |
| /// Skips child plugs to avoid duplicate notifications for compound attrs (e.g. color.r). | ||
| /// Override ShouldMarkPrimvarDirtyForAttributeChange to return false when another callback | ||
| /// already marks DirtyPrimvar (e.g. mesh _dirtyBits, light param attr list). |
| const SceneIndicesVector& sceneIndices = GetTerminalSceneIndices(); | ||
| ASSERT_GT(sceneIndices.size(), 0u); | ||
| SceneIndexNotificationsAccumulator notifsAccumulator(sceneIndices.front()); | ||
|
|
||
| auto checkDirty = [&](const std::string& nodeName, double value) { | ||
| const size_t startIndex = notifsAccumulator.GetDirtiedPrimEntries().size(); | ||
| SetAttrAndRefresh(nodeName, value); | ||
| EXPECT_TRUE(FindDirtyPrimWithPrimvarValueSince(notifsAccumulator, startIndex, value)); | ||
| }; |
| * @brief Get attributes from a Maya node for translation to Hydra primvars. | ||
| * | ||
| * This function retrieves all the extension and dynamic attributes of a given Maya node and stores | ||
| * them in a map. The keys of the map are the attribute names, and the values are the attribute values. | ||
| * When includeAllAttributes is false, only extension and dynamic attributes are retrieved. When true, all non-builtin | ||
| * attributes are retrieved (e.g. for lights to translate plugin attributes like Arnold ai*). | ||
| * | ||
| * @param[in] node is the node in the Maya scene graph. | ||
| * @param[out] attrs is a map that will contain the attribute names and their corresponding values. | ||
| * @param[in] includeAllAttributes when true, process all non-builtin attributes; when false, only | ||
| * extension and dynamic attributes. | ||
| */ | ||
| MAYAHYDRALIB_API | ||
| void GetExtensionAndDynamicAttributesFromNode( | ||
| void GetAttributesFromNode( | ||
| const MObject& node, | ||
| PXR_NS::VtDictionary& attrs); | ||
| PXR_NS::VtDictionary& attrs, | ||
| bool includeAllAttributes = false); |
ppt-adsk
left a comment
There was a problem hiding this comment.
Did not look at the tests, but we can start with this.
ppt-adsk
left a comment
There was a problem hiding this comment.
Just a couple more questions.
| #include <string> | ||
| #include <unordered_set> | ||
|
|
||
| PXR_NAMESPACE_OPEN_SCOPE |
There was a problem hiding this comment.
Sorry for the late catch. Why is this in the PXR namespace?
There was a problem hiding this comment.
It's a mistake, I moved it to the maya hydra namespace. Thanks for catching this !
| const VtValue& /* defaultVal */, | ||
| const bool /* hasDefault */, |
There was a problem hiding this comment.
If we don't need these any more, shouldn't we just remove them?
There was a problem hiding this comment.
You're right, some leftovers of iterations
ppt-adsk
left a comment
There was a problem hiding this comment.
Nit-pick, if you could fix would be nice.
No description provided.