Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lanierd/hydra 1054 #169

Merged
merged 9 commits into from
Sep 16, 2024
22 changes: 21 additions & 1 deletion lib/flowViewport/sceneIndex/fvpDefaultMaterialSceneIndex.cpp
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Github is erroring out saying that "You need to add a comment indicating the requested change.", even though I've done exactly that. Hoping that this additional comment will help.

Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,33 @@
#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 VtArray<TfToken> const compliantPrimitives = { HdPrimTypeTokens->cone,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: would be slightly better as an std::set, with the check using either std::set::find() or std::set::count().

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 std::find(compliantPrimitives.cbegin(), compliantPrimitives.cend(), primType)
!= compliantPrimitives.cend();
lanierd-adsk marked this conversation as resolved.
Show resolved Hide resolved
}
}

// static
Expand Down Expand Up @@ -68,7 +88,7 @@ HdSceneIndexPrim DefaultMaterialSceneIndex::GetPrim(const SdfPath& primPath) con
bool DefaultMaterialSceneIndex::_ShouldWeApplyTheDefaultMaterial(const HdSceneIndexPrim& prim)const
{
// Only for meshes so far
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment needs to be adjusted

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());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we know when this happens? Is this for non-Dag nodes? Does this indicate missing functionality, missing logic, or a bug?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had this with Bifrost nodes and also when selecting the default material set. But the problem is that wer get dag nodes with no type and no name, we should try detect useful dag nodes that need to be translated as some may not need to be treated.

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