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

HYDRA-762 - Investigate why the tumbling performance of USD scene is slower than corresponding Maya Scene under Hydra Storm #91

Merged
merged 4 commits into from
Mar 6, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,7 @@ const HdRetainedContainerDataSourceHandle sSelectedDisplayStyleDataSource
HdRetainedContainerDataSource::New(
HdLegacyDisplayStyleSchemaTokens->reprSelector,
HdRetainedTypedSampledDataSource<VtArray<TfToken>>::New(
{ HdReprTokens->refinedWireOnSurf, HdReprTokens->wireOnSurf, TfToken() })));

const HdRetainedContainerDataSourceHandle sUnselectedDisplayStyleDataSource
= HdRetainedContainerDataSource::New(
HdLegacyDisplayStyleSchemaTokens->displayStyle,
HdRetainedContainerDataSource::New(
HdLegacyDisplayStyleSchemaTokens->reprSelector,
HdRetainedTypedSampledDataSource<VtArray<TfToken>>::New(
{ HdReprTokens->refined, HdReprTokens->refined, TfToken() })));
{ HdReprTokens->refinedWireOnSurf, TfToken(), TfToken() })));

const HdDataSourceLocator reprSelectorLocator(
HdLegacyDisplayStyleSchemaTokens->displayStyle,
Expand Down Expand Up @@ -88,10 +80,10 @@ WireframeSelectionHighlightSceneIndex::GetPrim(const SdfPath &primPath) const
// index to convert implicit surfaces (e.g. USD cube / cone / sphere /
// capsule primitive types) to meshes.
if (!isExcluded(primPath) && prim.primType == HdPrimTypeTokens->mesh) {
prim.dataSource = HdOverlayContainerDataSource::New(
{ prim.dataSource, _selection->HasFullySelectedAncestorInclusive(primPath) ?
sSelectedDisplayStyleDataSource :
sUnselectedDisplayStyleDataSource });
if (_selection->HasFullySelectedAncestorInclusive(primPath)) {
prim.dataSource = HdOverlayContainerDataSource::New(
{ prim.dataSource, sSelectedDisplayStyleDataSource });
}
}
return prim;
}
Expand Down
1 change: 1 addition & 0 deletions test/lib/mayaUsd/render/mayaToHydra/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ set(INTERACTIVE_TEST_SCRIPT_FILES
cpp/testFlowViewportAPIAddPrims.py
cpp/testUsdStageLayerMuting.py
cpp/testFlowViewportAPIFilterPrims.py
cpp/testSceneCorrectness.py
cpp/testPrimInstancing.py
)

Expand Down
1 change: 1 addition & 0 deletions test/lib/mayaUsd/render/mayaToHydra/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ target_sources(${TARGET_NAME}
testUsdStageLayerMuting.cpp
testMeshAdapterTransform.cpp
testFlowViewportAPIFilterPrims.cpp
testSceneCorrectness.cpp
testPrimInstancing.cpp
)

Expand Down
136 changes: 136 additions & 0 deletions test/lib/mayaUsd/render/mayaToHydra/cpp/testSceneCorrectness.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
// Copyright 2024 Autodesk
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include "testUtils.h"

#include <pxr/imaging/hd/tokens.h>

#include <gtest/gtest.h>

#include <stack>

PXR_NAMESPACE_USING_DIRECTIVE

namespace {

struct DataSourceEntry
{
pxr::TfToken name;
pxr::HdDataSourceBaseHandle dataSource;
};

void VerifyDataSource(DataSourceEntry rootDataSourceEntry)
{
// Traverse the hierarchy and verify
std::stack<DataSourceEntry> dataSourceStack({ rootDataSourceEntry });
while (!dataSourceStack.empty()) {
DataSourceEntry dataSourceEntry = dataSourceStack.top();

// Verify representation selector's correctness
if (dataSourceEntry.name == "reprSelector") {
if (auto sampledDataSource
= pxr::HdSampledDataSource::Cast(dataSourceEntry.dataSource)) {

pxr::VtValue value = sampledDataSource->GetValue(0.0f);
if (value.IsHolding<pxr::VtArray<pxr::TfToken>>()) {
auto array = value.UncheckedGet<pxr::VtArray<pxr::TfToken>>();

int numPointReprs = 0;
int numWireReprs = 0;
int numSurfReprs = 0;

// Count representations in use
for (size_t j = 0; j < array.size(); ++j) {
pxr::TfToken reprName(array[j]);

if (reprName == pxr::HdReprTokens->hull ||
reprName == pxr::HdReprTokens->smoothHull ||
reprName == pxr::HdReprTokens->refined) {
++numSurfReprs;
} else if (reprName == pxr::HdReprTokens->refinedWire ||
reprName == pxr::HdReprTokens->wire) {
++numWireReprs;
} else if (reprName == pxr::HdReprTokens->refinedWireOnSurf ||
reprName == pxr::HdReprTokens->wireOnSurf) {
++numWireReprs;
++numSurfReprs;
} else if (reprName == pxr::HdReprTokens->points) {
++numPointReprs;
}
}

// Verify that we don't draw the same geometry more than once
EXPECT_LE(numPointReprs, 1);
EXPECT_LE(numWireReprs, 1);
EXPECT_LE(numSurfReprs, 1);
}
}
}

// Prepare next step
dataSourceStack.pop();
if (auto containerDataSource
= pxr::HdContainerDataSource::Cast(dataSourceEntry.dataSource)) {
pxr::TfTokenVector childNames = containerDataSource->GetNames();
for (auto itChildNames = childNames.rbegin(); itChildNames != childNames.rend();
itChildNames++) {
pxr::TfToken dataSourceName = *itChildNames;
pxr::HdDataSourceBaseHandle dataSource = containerDataSource->Get(dataSourceName);
if (dataSource) {
dataSourceStack.push({ dataSourceName, dataSource });
}
}
} else if (
auto vectorDataSource = pxr::HdVectorDataSource::Cast(dataSourceEntry.dataSource)) {
for (size_t iElement = 0; iElement < vectorDataSource->GetNumElements(); iElement++) {
size_t reversedElementIndex = vectorDataSource->GetNumElements() - 1 - iElement;
pxr::TfToken dataSourceName = pxr::TfToken(std::to_string(reversedElementIndex));
pxr::HdDataSourceBaseHandle dataSource
= vectorDataSource->GetElement(reversedElementIndex);
if (dataSource) {
dataSourceStack.push({ dataSourceName, dataSource });
}
}
}
}
}

} // namespace

TEST(HydraScene, testHydraSceneCorrectness)
{
// Retrieve the scene index
const SceneIndicesVector& sceneIndices = GetTerminalSceneIndices();
EXPECT_TRUE(!sceneIndices.empty());
pxr::HdSceneIndexBasePtr sceneIndex = sceneIndices.front();

// Traverse the hierarchy
std::stack<pxr::SdfPath> primPathsStack({ pxr::SdfPath::AbsoluteRootPath() });
while (!primPathsStack.empty()) {
pxr::SdfPath primPath = primPathsStack.top();
pxr::HdSceneIndexPrim prim = sceneIndex->GetPrim(primPath);

// Verify the data source
VerifyDataSource({ primPath.GetNameToken(), prim.dataSource });

// Prepare next step
primPathsStack.pop();
pxr::SdfPathVector childPaths = sceneIndex->GetChildPrimPaths(primPath);
for (auto itChildPaths = childPaths.rbegin(); itChildPaths != childPaths.rend();
itChildPaths++) {
primPathsStack.push(*itChildPaths);
}
}
}
50 changes: 50 additions & 0 deletions test/lib/mayaUsd/render/mayaToHydra/cpp/testSceneCorrectness.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Copyright 2024 Autodesk
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import maya.cmds as cmds

import fixturesUtils
import mtohUtils
import unittest

import testUtils
from testUtils import PluginLoaded

class TestSceneCorrectness(mtohUtils.MayaHydraBaseTestCase):
# MayaHydraBaseTestCase.setUpClass requirement.
_file = __file__

def loadUsdScene(self):
import usdUtils
usdScenePath = testUtils.getTestScene('testStagePayloadsReferences', 'cube.usda')
usdUtils.createStageFromFile(usdScenePath)
self.setHdStormRenderer()

@unittest.skipUnless(mtohUtils.checkForMayaUsdPlugin(), "Requires Maya USD Plugin.")
def test_HydraFromUsdSceneCorrectness(self):
self.loadUsdScene()
cmds.select(all=True)
cmds.refresh()
with PluginLoaded('mayaHydraCppTests'):
cmds.mayaHydraCppTest(f="HydraScene.testHydraSceneCorrectness")

def test_HydraFromMayaSceneCorrectness(self):
self.makeCubeScene(camDist=6)
cmds.select(all=True)
cmds.refresh()
with PluginLoaded('mayaHydraCppTests'):
cmds.mayaHydraCppTest(f="HydraScene.testHydraSceneCorrectness")

if __name__ == '__main__':
fixturesUtils.runTests(globals())
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ bool hasSelectionHighlight(const HdSceneIndexPrim& prim)
return false;
}

static VtArray<TfToken> expected({HdReprTokens->refinedWireOnSurf, HdReprTokens->wireOnSurf, TfToken()});
static VtArray<TfToken> expected({HdReprTokens->refinedWireOnSurf, TfToken(), TfToken()});

return taDs->GetValue(0) == expected;
}
Expand Down