Skip to content

Commit

Permalink
HYDRA-764 : Add prim instancing unit test (#33)
Browse files Browse the repository at this point in the history
* HYDRA-764 : Create minimalized version of ALab workbench scene

* HYDRA-764 : Further simplify the USD scene

* HYDRA-764 : Convert geometry usdc file to usda and remove some meshes

* HYDRA-764 : Replace workbench with simple cube

* HYDRA-764 : Have just the root Xform reference the cube in the scene file

* HYDRA-674 : Rename Xform and mesh in cube.usda

* HYDRA-764 : First working test

* HYDRA-764 : Extract USD stage load from file logic into utils

* HYDRA-764 : Add extra checks in scene hierarchy

* HYDRA-764 : Comment scene file

* HYDRA-764 : Cleanup unused imports and includes

* HYDRA-764 : Rename root prim

* HYDRA-764 : Move usdUtils import inside a function called after MayaUSD is loaded

* HYDRA-764 : Remove incorrect comment in usda scene file

* HYDRA-764 : Rename scene file
  • Loading branch information
debloip-adsk authored Jan 18, 2024
1 parent 6dbf905 commit dd5cf14
Show file tree
Hide file tree
Showing 7 changed files with 153 additions and 0 deletions.
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 @@ -25,6 +25,7 @@ set(TEST_SCRIPT_FILES
cpp/testFlowViewportAPIAddPrims.py
cpp/testUsdStageLayerMuting.py
cpp/testFlowViewportAPIFilterPrims.py
cpp/testPrimInstancing.py
)

# Test use of mesh adapter code for mesh support, using environment variable.
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 @@ -26,6 +26,7 @@ target_sources(${TARGET_NAME}
testUsdStageLayerMuting.cpp
testMeshAdapterTransform.cpp
testFlowViewportAPIFilterPrims.cpp
testPrimInstancing.cpp
)

# -----------------------------------------------------------------------------
Expand Down
68 changes: 68 additions & 0 deletions test/lib/mayaUsd/render/mayaToHydra/cpp/testPrimInstancing.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright 2023 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>

PXR_NAMESPACE_USING_DIRECTIVE

namespace {
FindPrimPredicate findInstanceableCubePredicate = PrimNamePredicate("instanceableCube");
HdDataSourceLocator instancerLocator = HdDataSourceLocator(TfToken("instance"), TfToken("instancer"));
} // namespace

TEST(PrimInstancing, testUsdPrimInstancing)
{
// Get the terminal scene index
const auto& sceneIndices = GetTerminalSceneIndices();
ASSERT_GT(sceneIndices.size(), 0u);
SceneIndexInspector inspector(sceneIndices.front());

// Find the instanceable cube prim
PrimEntriesVector instanceableCubePrims = inspector.FindPrims(findInstanceableCubePredicate);
ASSERT_EQ(instanceableCubePrims.size(), 1u);
HdSceneIndexPrim instanceableCubePrim = instanceableCubePrims.front().prim;

// Retrieve the instancer data source
auto instancerDataSource = HdTypedSampledDataSource<SdfPath>::Cast(
HdContainerDataSource::Get(instanceableCubePrim.dataSource, instancerLocator));
ASSERT_TRUE(instancerDataSource);

// Ensure the instancer prim exists and is populated
SdfPath instancerPath = instancerDataSource->GetTypedValue(0);
auto findInstancerPredicate
= [instancerPath](const HdSceneIndexBasePtr& sceneIndex, const SdfPath& primPath) -> bool {
return primPath == instancerPath;
};
PrimEntriesVector instancerPrims = inspector.FindPrims(findInstancerPredicate);
ASSERT_EQ(instancerPrims.size(), 1u);
HdSceneIndexPrim instancerPrim = instancerPrims.front().prim;
ASSERT_EQ(instancerPrim.primType, HdPrimTypeTokens->instancer);
ASSERT_NE(instancerPrim.dataSource, nullptr);

// Ensure the reference cube prim exists and is populated
auto findCubePredicate
= [instancerPath](const HdSceneIndexBasePtr& sceneIndex, const SdfPath& primPath) -> bool {
return primPath.HasPrefix(instancerPath) && primPath.GetName() == "cubeMesh";
};
PrimEntriesVector cubePrims = inspector.FindPrims(findCubePredicate);
ASSERT_EQ(cubePrims.size(), 1u);
HdSceneIndexPrim cubePrim = cubePrims.front().prim;
ASSERT_EQ(cubePrim.primType, HdPrimTypeTokens->mesh);
ASSERT_NE(cubePrim.dataSource, nullptr);
}
42 changes: 42 additions & 0 deletions test/lib/mayaUsd/render/mayaToHydra/cpp/testPrimInstancing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Copyright 2023 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 TestPrimInstancing(mtohUtils.MayaHydraBaseTestCase):
# MayaHydraBaseTestCase.setUpClass requirement.
_file = __file__

def loadUsdScene(self):
import usdUtils
usdScenePath = testUtils.getTestScene('testPrimInstancing', 'instanceableCube.usda')
usdUtils.createStageFromFile(usdScenePath)
self.setHdStormRenderer()
cmds.refresh()

@unittest.skipUnless(mtohUtils.checkForMayaUsdPlugin(), "Requires Maya USD Plugin.")
def test_UsdPrimInstancing(self):
self.loadUsdScene()
with PluginLoaded('mayaHydraCppTests'):
cmds.mayaHydraCppTest(f="PrimInstancing.testUsdPrimInstancing")

if __name__ == '__main__':
fixturesUtils.runTests(globals())
14 changes: 14 additions & 0 deletions test/testSamples/testPrimInstancing/cube.usda
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#usda 1.0
(
defaultPrim = "cube"
)

def Xform "cube"
{
def Mesh "cubeMesh"
{
int[] faceVertexCounts = [4, 4, 4, 4, 4, 4]
int[] faceVertexIndices = [0, 1, 3, 2, 2, 3, 5, 4, 4, 5, 7, 6, 6, 7, 1, 0, 1, 7, 5, 3, 6, 0, 2, 4]
point3f[] points = [(-0.5, -0.5, 0.5), (0.5, -0.5, 0.5), (-0.5, 0.5, 0.5), (0.5, 0.5, 0.5), (-0.5, 0.5, -0.5), (0.5, 0.5, -0.5), (-0.5, -0.5, -0.5), (0.5, -0.5, -0.5)]
}
}
11 changes: 11 additions & 0 deletions test/testSamples/testPrimInstancing/instanceableCube.usda
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#usda 1.0
(
defaultPrim = "instanceableCube"
)

def Xform "instanceableCube" (
instanceable = true
prepend references = @cube.usda@
)
{
}
16 changes: 16 additions & 0 deletions test/testUtils/usdUtils.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
Helper functions regarding USD that will be used throughout the test.
"""

import maya.mel as mel

import mayaUsd.ufe
import mayaUsd.lib
import mayaUsd_createStageWithNewLayer
Expand All @@ -31,6 +33,20 @@

usdSeparator = '/'

def createStageFromFile(filePath: str):
"""
Creates a USD stage from a given path to a USD file.
Args:
filePath (str): The file path to the USD file to load.
Returns :
A string representing the UFE path to the stage's proxy shape node
"""
# Source the corresponding mel file, otherwise the procedure isn't available
mel.eval('source \"mayaUsd_createStageFromFile.mel\"')
loadStageCmd = f'mayaUsd_createStageFromFilePath(\"{filePath}\")'
# Replace backslashes with forward slashes to avoid them being interpreted
loadStageCmd = loadStageCmd.replace('\\', '/')
return mel.eval(loadStageCmd)

def createUfePathSegment(usdPath):
"""
Expand Down

0 comments on commit dd5cf14

Please sign in to comment.