Skip to content

Commit

Permalink
HYDRA-1054 : Fix material assignment not working in our code, a fix w…
Browse files Browse the repository at this point in the history
…hich is in USD 24.08 will be needed to fully validate this

* HYDRA-1054 : Fix material assignment not working in our code, a fix which is in USD 24.08 will be needed to fully validate this.

* Add unit test for default material on usd procedural prims

* Fix scene version

* Fix compilation with prior versions of USD and fix the test scene as cone and cilynder_1 are not supported on OSX for USD 24.05

* Update test image

* Make the tests work on OSX for USD versions prior to 24.05

* Fix a comment from code review

* Using std::set

* Update lib/flowViewport/sceneIndex/fvpDefaultMaterialSceneIndex.cpp
  • Loading branch information
lanierd-adsk authored Sep 16, 2024
1 parent 378f0f0 commit 6756a66
Show file tree
Hide file tree
Showing 6 changed files with 299 additions and 9 deletions.
22 changes: 20 additions & 2 deletions lib/flowViewport/sceneIndex/fvpDefaultMaterialSceneIndex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,32 @@
#include <pxr/imaging/hd/materialBindingsSchema.h>
#include <pxr/imaging/hd/containerDataSourceEditor.h>
#include <pxr/imaging/hd/retainedDataSource.h>
#include <pxr/usd/usdGeom/tokens.h>

namespace FVP_NS_DEF {

PXR_NAMESPACE_USING_DIRECTIVE

namespace{
static const TfToken purposes[] = { HdMaterialBindingsSchemaTokens->allPurpose };

// Support implicit surfaces from USD as well, not only meshes
bool _IsDefaultMaterialCompliantPrimitive(const TfToken& primType)
{
static std::set<TfToken> const compliantPrimitives = { HdPrimTypeTokens->cone,
HdPrimTypeTokens->cylinder,
HdPrimTypeTokens->cylinder_1,
HdPrimTypeTokens->cube,
HdPrimTypeTokens->sphere,
HdPrimTypeTokens->capsule,
HdPrimTypeTokens->capsule_1,
#if HD_API_VERSION >= 67 // USD 24.05+
UsdGeomTokens->TetMesh,
#endif
UsdGeomTokens->Plane,
HdPrimTypeTokens->mesh};
return compliantPrimitives.count(primType) == 1;
}
}

// static
Expand Down Expand Up @@ -67,8 +86,7 @@ HdSceneIndexPrim DefaultMaterialSceneIndex::GetPrim(const SdfPath& primPath) con

bool DefaultMaterialSceneIndex::_ShouldWeApplyTheDefaultMaterial(const HdSceneIndexPrim& prim)const
{
// Only for meshes so far
if (HdPrimTypeTokens->mesh != prim.primType) {
if (! _IsDefaultMaterialCompliantPrimitive(prim.primType)) {
return false;
}

Expand Down
5 changes: 5 additions & 0 deletions lib/mayaHydra/hydraExtensions/mixedUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ SdfPath DagPathToSdfPath(
const bool stripNamespaces)
{
std::string name = dagPath.fullPathName().asChar();
if ( name.empty() ) {
MFnDependencyNode dep(dagPath.node());
TF_WARN("Empty fullpath name for DAG object : %s of type : %s", dep.name().asChar(), dep.typeName().asChar());
return SdfPath();
}
SanitizeNameForSdfPath(name, stripNamespaces);
SdfPath usdPath(name);

Expand Down
19 changes: 12 additions & 7 deletions lib/mayaHydra/hydraExtensions/sceneIndex/registration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,9 @@ class PathInterfaceSceneIndex : public Fvp::PathInterfaceSceneIndexBase
auto secondSegment = appPath.getSegments()[1];
const auto lastComponentString = secondSegment.components().back().string();
const bool lastComponentIsNumeric = lastComponentString.find_first_not_of(digits) == std::string::npos;
const size_t lastComponentIndex = secondSegment.size() - 1;

for (size_t iSecondSegment = 0; iSecondSegment < secondSegment.size(); iSecondSegment++) {
for (size_t iComponent = 0; iComponent < secondSegment.size(); iComponent++) {
// Native instancing : if the current prim path points to a native instance, repath to the prototype
// before appending the following UFE components
HdSceneIndexPrim prim = GetInputSceneIndex()->GetPrim(primPath);
Expand All @@ -155,16 +156,20 @@ class PathInterfaceSceneIndex : public Fvp::PathInterfaceSceneIndexBase
instanceSelection = {instancerPath, prototypeIndex, {instanceSchema.GetInstanceIndex()->GetTypedValue(0)}};
}

auto targetChildPath = primPath.AppendChild(TfToken(secondSegment.components()[iSecondSegment].string()));
auto targetChildPath = primPath.AppendChild(TfToken(secondSegment.components()[iComponent].string()));
auto actualChildPaths = GetInputSceneIndex()->GetChildPrimPaths(primPath);
if (std::find(actualChildPaths.begin(), actualChildPaths.end(), targetChildPath) != actualChildPaths.end()) {
// Append if the new path is valid
primPath = primPath.AppendChild(TfToken(secondSegment.components()[iSecondSegment].string()));
primPath = targetChildPath;
}
else if (iSecondSegment == secondSegment.size() - 1) {
// Point instancing : instance selection. The path should end with a number corresponding to the selected instance,
// and the remainder of the path points to the point instancer.
if (TF_VERIFY(lastComponentIsNumeric, "Expected number as final UFE path component but got an invalid path instead.")) {
else if (iComponent == lastComponentIndex) {
// If the last component is a number, we are dealing with an instance selection.
// But there are other cases like when you assign a USD Preview surface material to a usd prim, it has a shader prim in the material
// which doesn't appear in the hydra hierarchy but is actually present and we end up in this case as well.
if (lastComponentIsNumeric) {
// Point instancing : instance selection. The path should end with a number
// corresponding to the selected instance,
// and the remainder of the path points to the point instancer.
HdSceneIndexPrim instancerPrim = GetInputSceneIndex()->GetPrim(primPath);
HdInstancerTopologySchema instancerTopologySchema = HdInstancerTopologySchema::GetFromParent(instancerPrim.dataSource);
auto instanceIndicesByPrototype = instancerTopologySchema.GetInstanceIndices();
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 15 additions & 0 deletions test/lib/mayaUsd/render/mayaToHydra/testMayaDefaultMaterial.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,21 @@ def test_MayaDefaultMaterial(self):
cmds.modelEditor(panel, edit=True, useDefaultMaterial=True)
cmds.refresh()
self.assertSnapshotClose("defaultMaterial" + ".png", self.IMAGE_DIFF_FAIL_THRESHOLD, self.IMAGE_DIFF_FAIL_PERCENT)

def test_MayaDefaultMaterialUsdPrims(self):
# open a Maya scene with usd prims (sphere, capsule, cube, cylinder ...)
testFile = mayaUtils.openTestScene(
"testDefaultMaterial",
"testMayaDefaultMaterial_Usd_proceduralShapes.ma", useTestSettings=False)
cmds.refresh()

#Cone and cylinder_1 are not supported on OSX with USD 24.05 so they are not in our test scene

#Use Default Material
panel = mayaUtils.activeModelPanel()
cmds.modelEditor(panel, edit=True, useDefaultMaterial=True)
cmds.refresh()
self.assertSnapshotClose("defaultMaterialUsdPrims" + ".png", self.IMAGE_DIFF_FAIL_THRESHOLD, self.IMAGE_DIFF_FAIL_PERCENT)

if __name__ == '__main__':
fixturesUtils.runTests(globals())
Loading

0 comments on commit 6756a66

Please sign in to comment.