From a7accc3fb35d1bcf5d2e50fb727a14b62f46b122 Mon Sep 17 00:00:00 2001 From: Andrew Kaufman Date: Tue, 8 Mar 2022 10:29:08 -0800 Subject: [PATCH 1/6] IE Config : Account for no suitable appleseed Backport of b42c34e000141c473d8bebd1d2e84e76c99443e8 --- config/ie/buildAll | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config/ie/buildAll b/config/ie/buildAll index 671a05ec8b..42e26c8256 100755 --- a/config/ie/buildAll +++ b/config/ie/buildAll @@ -117,6 +117,9 @@ if platform in ( "cent7.x86_64", ) : appleseedCompilerMap[compilerVersion].append( appleseedVersion ) for pythonVersion in IEEnv.activeVersions( IEEnv.registry["apps"]["python"] ) : build( [ "COMPILER_VERSION="+compilerVersion, "PYTHON_VERSION="+pythonVersion, "APPLESEED_VERSION="+appleseedVersion, "DL_VERSION=UNDEFINED" ] ) + for appleseedCompiler, versions in appleseedCompilerMap.items() : + if len(versions) == 0 : + appleseedCompilerMap[appleseedCompiler].append( "UNDEFINED" ) for mayaVersion in IEEnv.activeAppVersions( "maya" ) : compilerVersion = IEEnv.registry["apps"]["maya"][mayaVersion][platform]["compilerVersion"] From 4cb888dc54c5bf8a005f0e195ce74f06686c0336 Mon Sep 17 00:00:00 2001 From: John Haddon Date: Tue, 22 Mar 2022 11:03:24 +0000 Subject: [PATCH 2/6] CurvesAlgo : Support V2f fully in `resamplePrimitiveVariable()` It was previously unsupported for vertex->varying and varying->vertex conversions. --- src/IECoreScene/CurvesAlgo.cpp | 19 +++++++++++++------ test/IECoreScene/CurvesAlgoTest.py | 18 ++++++++++++++++++ 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/IECoreScene/CurvesAlgo.cpp b/src/IECoreScene/CurvesAlgo.cpp index 6dbc820f6e..a04f0aab43 100644 --- a/src/IECoreScene/CurvesAlgo.cpp +++ b/src/IECoreScene/CurvesAlgo.cpp @@ -52,14 +52,16 @@ namespace // PrimitiveEvaluator only supports certain types -template< typename T > struct IsPrimitiveEvaluatableTypedData : boost::mpl::and_< +template< typename T > +struct IsPrimitiveEvaluatableTypedData : boost::mpl::and_< TypeTraits::IsNumericBasedVectorTypedData, boost::mpl::or_< - TypeTraits::IsVec3::type >, - boost::is_same< typename TypeTraits::VectorValueType::type, float >, - boost::is_same< typename TypeTraits::VectorValueType::type, int >, - TypeTraits::IsColor3::type > -> + TypeTraits::IsVec2::type>, + TypeTraits::IsVec3::type>, + boost::is_same::type, float>, + boost::is_same::type, int>, + TypeTraits::IsColor3::type> + > > {}; @@ -69,6 +71,11 @@ static T evalPrimVar( PrimitiveEvaluator::Result *result, const PrimitiveVariabl throw Exception( "PrimvarResamplerCache : This should never be called because of IsPrimitiveEvaluatableTypedData" ); } +template<> +Imath::V2f evalPrimVar( PrimitiveEvaluator::Result *result, const PrimitiveVariable &primVar ) +{ + return result->vec2PrimVar( primVar ); +} template<> Imath::V3f evalPrimVar( PrimitiveEvaluator::Result *result, const PrimitiveVariable &primVar ) diff --git a/test/IECoreScene/CurvesAlgoTest.py b/test/IECoreScene/CurvesAlgoTest.py index ff2cc89089..d9ce5f3c11 100644 --- a/test/IECoreScene/CurvesAlgoTest.py +++ b/test/IECoreScene/CurvesAlgoTest.py @@ -1195,6 +1195,24 @@ def testBezierCurvesFaceVaryingToVarying( self ) : # endregion + def testV2fVaryingToVertex( self ) : + + curves = IECoreScene.CurvesPrimitive( + IECore.IntVectorData( [ 4 ] ), IECore.CubicBasisf.catmullRom(), False, + IECore.V3fVectorData( [ imath.V3f( i ) for i in range( 0, 4 ) ] ) + ) + + uv = IECoreScene.PrimitiveVariable( + IECoreScene.PrimitiveVariable.Interpolation.Varying, + IECore.V2fVectorData( [ imath.V2f( 0 ), imath.V2f( 1 ) ] ) + ) + curves["uv"] = uv + + IECoreScene.CurvesAlgo.resamplePrimitiveVariable( curves, uv, IECoreScene.PrimitiveVariable.Interpolation.Vertex ) + self.assertTrue( curves.arePrimitiveVariablesValid() ) + self.assertEqual( uv.interpolation, IECoreScene.PrimitiveVariable.Interpolation.Vertex ) + self.assertEqual( len( uv.data ), 4 ) + class CurvesAlgoDeleteCurvesTest ( unittest.TestCase ): def createLinearCurves(self): From 0f929c3335715388b5a9db743efcb93aa4e90c0f Mon Sep 17 00:00:00 2001 From: John Haddon Date: Tue, 22 Mar 2022 11:40:59 +0000 Subject: [PATCH 3/6] IECoreUSD::DataAlgo : Add support for `SdfAssetPath` --- contrib/IECoreUSD/src/IECoreUSD/DataAlgo.cpp | 8 +++++++- contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py | 14 ++++++++++++++ .../test/IECoreUSD/data/assetPathAttribute.usda | 9 +++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 contrib/IECoreUSD/test/IECoreUSD/data/assetPathAttribute.usda diff --git a/contrib/IECoreUSD/src/IECoreUSD/DataAlgo.cpp b/contrib/IECoreUSD/src/IECoreUSD/DataAlgo.cpp index b34981db6c..e5de4b5755 100644 --- a/contrib/IECoreUSD/src/IECoreUSD/DataAlgo.cpp +++ b/contrib/IECoreUSD/src/IECoreUSD/DataAlgo.cpp @@ -139,6 +139,11 @@ IECore::DataPtr dataFromArray( const pxr::VtValue &value, GeometricData::Interpr return d; } +IECore::DataPtr dataFromSdfAssetPath( const pxr::VtValue &value, GeometricData::Interpretation interpretation, bool arrayAccepted ) +{ + return new StringData( value.Get().GetResolvedPath() ); +} + static const std::map g_fromVtValueConverters = { // Numeric types @@ -202,7 +207,8 @@ static const std::map(), &dataFromValue }, { TfType::Find>(), &dataFromArray }, { TfType::Find(), &dataFromValue }, - { TfType::Find>(), &dataFromArray } + { TfType::Find>(), &dataFromArray }, + { TfType::Find(), &dataFromSdfAssetPath } }; diff --git a/contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py b/contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py index 8e705f2ad9..227a4f575f 100644 --- a/contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py +++ b/contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py @@ -2938,5 +2938,19 @@ def testHoudiniVaryingLengthArrayPrimVar( self ) : ) ) + def testAssetAttributes( self ) : + + root = IECoreScene.SceneInterface.create( + os.path.join( os.path.dirname( __file__ ), "data", "assetPathAttribute.usda" ), + IECore.IndexedIO.OpenMode.Read + ) + xform = root.child( "xform" ) + + self.assertEqual( xform.attributeNames(), [ "render:testAsset" ] ) + self.assertEqual( + xform.readAttribute( "render:testAsset", 0 ), + IECore.StringData( os.path.join( os.path.dirname( __file__ ), "data", "cube.usda" ) ) + ) + if __name__ == "__main__": unittest.main() diff --git a/contrib/IECoreUSD/test/IECoreUSD/data/assetPathAttribute.usda b/contrib/IECoreUSD/test/IECoreUSD/data/assetPathAttribute.usda new file mode 100644 index 0000000000..d9d495e534 --- /dev/null +++ b/contrib/IECoreUSD/test/IECoreUSD/data/assetPathAttribute.usda @@ -0,0 +1,9 @@ +#usda 1.0 + +def Xform "xform" +{ + + asset primvars:testAsset = @./cube.usda@ + +} + From b74da8cb684409bdcf8fd22e735577e6a96f828e Mon Sep 17 00:00:00 2001 From: John Haddon Date: Tue, 22 Mar 2022 14:29:39 +0000 Subject: [PATCH 4/6] IECoreUSD::ShaderAlgo : Remove indentation for namespace --- .../IECoreUSD/src/IECoreUSD/ShaderAlgo.cpp | 139 +++++++++--------- 1 file changed, 70 insertions(+), 69 deletions(-) diff --git a/contrib/IECoreUSD/src/IECoreUSD/ShaderAlgo.cpp b/contrib/IECoreUSD/src/IECoreUSD/ShaderAlgo.cpp index baadb00781..38355c1962 100644 --- a/contrib/IECoreUSD/src/IECoreUSD/ShaderAlgo.cpp +++ b/contrib/IECoreUSD/src/IECoreUSD/ShaderAlgo.cpp @@ -46,95 +46,96 @@ namespace { - pxr::TfToken g_adapterLabelToken( IECoreScene::ShaderNetworkAlgo::componentConnectionAdapterLabel().string() ); - IECore::InternedString readShaderNetworkWalk( const pxr::SdfPath &anchorPath, const pxr::UsdShadeShader &usdShader, IECoreScene::ShaderNetwork &shaderNetwork ) +pxr::TfToken g_adapterLabelToken( IECoreScene::ShaderNetworkAlgo::componentConnectionAdapterLabel().string() ); + +IECore::InternedString readShaderNetworkWalk( const pxr::SdfPath &anchorPath, const pxr::UsdShadeShader &usdShader, IECoreScene::ShaderNetwork &shaderNetwork ) +{ + IECore::InternedString handle( usdShader.GetPath().MakeRelativePath( anchorPath ).GetString() ); + + if( shaderNetwork.getShader( handle ) ) { - IECore::InternedString handle( usdShader.GetPath().MakeRelativePath( anchorPath ).GetString() ); + return handle; + } - if( shaderNetwork.getShader( handle ) ) + pxr::TfToken id; + std::string shaderName = "defaultsurface"; + std::string shaderType = "surface"; + if( usdShader.GetShaderId( &id ) ) + { + std::string name = id.GetString(); + size_t colonPos = name.find( ":" ); + if( colonPos != std::string::npos ) { - return handle; + std::string prefix = name.substr( 0, colonPos ); + name = name.substr( colonPos + 1 ); + if( prefix == "arnold" ) + { + prefix = "ai"; + } + shaderType = prefix + ":shader"; } + shaderName = name; + } - pxr::TfToken id; - std::string shaderName = "defaultsurface"; - std::string shaderType = "surface"; - if( usdShader.GetShaderId( &id ) ) + IECore::CompoundDataPtr parametersData = new IECore::CompoundData(); + IECore::CompoundDataMap ¶meters = parametersData->writable(); + std::vector< std::tuple< IECore::InternedString, pxr::UsdShadeConnectableAPI, IECore::InternedString > > connections; + std::vector< pxr::UsdShadeInput > inputs = usdShader.GetInputs(); + for( pxr::UsdShadeInput &i : usdShader.GetInputs() ) + { + pxr::UsdShadeConnectableAPI usdSource; + pxr::TfToken usdSourceName; + pxr::UsdShadeAttributeType usdSourceType; + + if( IECore::DataPtr d = IECoreUSD::DataAlgo::fromUSD( pxr::UsdAttribute( i ) ) ) { - std::string name = id.GetString(); - size_t colonPos = name.find( ":" ); - if( colonPos != std::string::npos ) - { - std::string prefix = name.substr( 0, colonPos ); - name = name.substr( colonPos + 1 ); - if( prefix == "arnold" ) - { - prefix = "ai"; - } - shaderType = prefix + ":shader"; - } - shaderName = name; + parameters[ i.GetBaseName().GetString() ] = d; } - IECore::CompoundDataPtr parametersData = new IECore::CompoundData(); - IECore::CompoundDataMap ¶meters = parametersData->writable(); - std::vector< std::tuple< IECore::InternedString, pxr::UsdShadeConnectableAPI, IECore::InternedString > > connections; - std::vector< pxr::UsdShadeInput > inputs = usdShader.GetInputs(); - for( pxr::UsdShadeInput &i : usdShader.GetInputs() ) + if( i.GetConnectedSource( &usdSource, &usdSourceName, &usdSourceType ) ) { - pxr::UsdShadeConnectableAPI usdSource; - pxr::TfToken usdSourceName; - pxr::UsdShadeAttributeType usdSourceType; + connections.push_back( { i.GetBaseName().GetString(), usdSource, usdSourceName.GetString() } ); + } + } - if( IECore::DataPtr d = IECoreUSD::DataAlgo::fromUSD( pxr::UsdAttribute( i ) ) ) - { - parameters[ i.GetBaseName().GetString() ] = d; - } + parametersData = boost::const_pointer_cast< IECore::CompoundData >( IECoreScene::ShaderNetworkAlgo::collapseSplineParameters( parametersData ) ); - if( i.GetConnectedSource( &usdSource, &usdSourceName, &usdSourceType ) ) - { - connections.push_back( { i.GetBaseName().GetString(), usdSource, usdSourceName.GetString() } ); - } - } + IECoreScene::ShaderPtr newShader = new IECoreScene::Shader( shaderName, shaderType, parametersData ); + pxr::VtValue metadataValue; + if( usdShader.GetPrim().GetMetadata( g_adapterLabelToken, &metadataValue ) && metadataValue.Get() ) + { + newShader->blindData()->writable()[ IECoreScene::ShaderNetworkAlgo::componentConnectionAdapterLabel() ] = new IECore::BoolData( true ); + } + shaderNetwork.addShader( handle, std::move( newShader ) ); - parametersData = boost::const_pointer_cast< IECore::CompoundData >( IECoreScene::ShaderNetworkAlgo::collapseSplineParameters( parametersData ) ); + for( const auto &c : connections ) + { + IECore::InternedString attributeName; + pxr::UsdShadeConnectableAPI usdSource; + IECore::InternedString sourceAttributeName; + std::tie( attributeName, usdSource, sourceAttributeName ) = c; + IECore::InternedString sourceHandle = readShaderNetworkWalk( anchorPath, pxr::UsdShadeShader( usdSource.GetPrim() ), shaderNetwork ); - IECoreScene::ShaderPtr newShader = new IECoreScene::Shader( shaderName, shaderType, parametersData ); - pxr::VtValue metadataValue; - if( usdShader.GetPrim().GetMetadata( g_adapterLabelToken, &metadataValue ) && metadataValue.Get() ) + if( sourceAttributeName == "DEFAULT_OUTPUT" ) { - newShader->blindData()->writable()[ IECoreScene::ShaderNetworkAlgo::componentConnectionAdapterLabel() ] = new IECore::BoolData( true ); + shaderNetwork.addConnection( IECoreScene::ShaderNetwork::Connection( + { sourceHandle, "" }, + { handle, attributeName } + ) ); } - shaderNetwork.addShader( handle, std::move( newShader ) ); - - for( const auto &c : connections ) + else { - IECore::InternedString attributeName; - pxr::UsdShadeConnectableAPI usdSource; - IECore::InternedString sourceAttributeName; - std::tie( attributeName, usdSource, sourceAttributeName ) = c; - IECore::InternedString sourceHandle = readShaderNetworkWalk( anchorPath, pxr::UsdShadeShader( usdSource.GetPrim() ), shaderNetwork ); - - if( sourceAttributeName == "DEFAULT_OUTPUT" ) - { - shaderNetwork.addConnection( IECoreScene::ShaderNetwork::Connection( - { sourceHandle, "" }, - { handle, attributeName } - ) ); - } - else - { - shaderNetwork.addConnection( IECoreScene::ShaderNetwork::Connection( - { sourceHandle, sourceAttributeName }, - { handle, attributeName } - ) ); - } + shaderNetwork.addConnection( IECoreScene::ShaderNetwork::Connection( + { sourceHandle, sourceAttributeName }, + { handle, attributeName } + ) ); } - - return handle; } + return handle; +} + } // namespace pxr::UsdShadeOutput IECoreUSD::ShaderAlgo::writeShaderNetwork( const IECoreScene::ShaderNetwork *shaderNetwork, pxr::UsdPrim shaderContainer ) From 96ba92d2451b716e136afac804d5e3325a0b99a1 Mon Sep 17 00:00:00 2001 From: John Haddon Date: Tue, 22 Mar 2022 14:46:34 +0000 Subject: [PATCH 5/6] IECoreUSD::ShaderAlgo : Handle connections to exposed material inputs --- .../IECoreUSD/src/IECoreUSD/ShaderAlgo.cpp | 19 +++++++++--- .../IECoreUSD/test/IECoreUSD/USDSceneTest.py | 15 ++++++++++ .../IECoreUSD/data/exposedShaderInput.usda | 30 +++++++++++++++++++ 3 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 contrib/IECoreUSD/test/IECoreUSD/data/exposedShaderInput.usda diff --git a/contrib/IECoreUSD/src/IECoreUSD/ShaderAlgo.cpp b/contrib/IECoreUSD/src/IECoreUSD/ShaderAlgo.cpp index 38355c1962..be1dbe5a82 100644 --- a/contrib/IECoreUSD/src/IECoreUSD/ShaderAlgo.cpp +++ b/contrib/IECoreUSD/src/IECoreUSD/ShaderAlgo.cpp @@ -88,14 +88,25 @@ IECore::InternedString readShaderNetworkWalk( const pxr::SdfPath &anchorPath, co pxr::TfToken usdSourceName; pxr::UsdShadeAttributeType usdSourceType; - if( IECore::DataPtr d = IECoreUSD::DataAlgo::fromUSD( pxr::UsdAttribute( i ) ) ) + pxr::UsdAttribute valueAttribute = i; + if( i.GetConnectedSource( &usdSource, &usdSourceName, &usdSourceType ) ) { - parameters[ i.GetBaseName().GetString() ] = d; + if( !usdSource.IsContainer() ) + { + connections.push_back( { i.GetBaseName().GetString(), usdSource, usdSourceName.GetString() } ); + } + else + { + // Connected to an exposed input on the material container. We don't + // have an equivalent in IECoreScene::ShaderNetwork yet, so just take + // the parameter value from the exposed input. + valueAttribute = usdSource.GetInput( usdSourceName ); + } } - if( i.GetConnectedSource( &usdSource, &usdSourceName, &usdSourceType ) ) + if( IECore::DataPtr d = IECoreUSD::DataAlgo::fromUSD( pxr::UsdAttribute( valueAttribute ) ) ) { - connections.push_back( { i.GetBaseName().GetString(), usdSource, usdSourceName.GetString() } ); + parameters[ i.GetBaseName().GetString() ] = d; } } diff --git a/contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py b/contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py index 227a4f575f..bae30b0584 100644 --- a/contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py +++ b/contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py @@ -2952,5 +2952,20 @@ def testAssetAttributes( self ) : IECore.StringData( os.path.join( os.path.dirname( __file__ ), "data", "cube.usda" ) ) ) + def testExposedShaderInput( self ) : + + root = IECoreScene.SceneInterface.create( + os.path.join( os.path.dirname( __file__ ), "data", "exposedShaderInput.usda" ), + IECore.IndexedIO.OpenMode.Read + ) + sphere = root.child( "model" ).child( "sphere" ) + + self.assertEqual( sphere.attributeNames(), [ "surface" ] ) + network = sphere.readAttribute( "surface", 0 ) + + self.assertEqual( network.size(), 1 ) + self.assertEqual( network.getOutput(), "surface" ) + self.assertEqual( network.getShader( "surface" ).parameters["diffuse_roughness"].value, 0.75 ) + if __name__ == "__main__": unittest.main() diff --git a/contrib/IECoreUSD/test/IECoreUSD/data/exposedShaderInput.usda b/contrib/IECoreUSD/test/IECoreUSD/data/exposedShaderInput.usda new file mode 100644 index 0000000000..d4d66f7d1f --- /dev/null +++ b/contrib/IECoreUSD/test/IECoreUSD/data/exposedShaderInput.usda @@ -0,0 +1,30 @@ +#usda 1.0 + +def "model" +{ + + def Sphere "sphere" + { + rel material:binding = + } + + def Scope "materials" + { + + def Material "material1" + { + + float inputs:exposedRoughness = 0.75 + token outputs:surface.connect = + + def Shader "surface" + { + uniform token info:id = "arnold:standard_surface" + float inputs:diffuse_roughness.connect = + token outputs:DEFAULT_OUTPUT + } + } + + } + +} From 4114baec556ff5d13e4d93b2205b112deced9d54 Mon Sep 17 00:00:00 2001 From: John Haddon Date: Tue, 22 Mar 2022 16:29:44 +0000 Subject: [PATCH 6/6] USDSceneTest : Pander to Windows In which both forward slashes and back slashes can be used as path separators, and USD's `GetResolvedPath()` uses the former and Python's `os.path.join()` uses the latter. And in which [filesystems are case insensitive by default](https://docs.microsoft.com/en-us/windows/wsl/case-sensitivity), with the additional exciting feature that they can be made case-sensitive on a directory-by-directory basis. What could go wrong? --- contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py b/contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py index bae30b0584..dfb2448f99 100644 --- a/contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py +++ b/contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py @@ -2948,8 +2948,8 @@ def testAssetAttributes( self ) : self.assertEqual( xform.attributeNames(), [ "render:testAsset" ] ) self.assertEqual( - xform.readAttribute( "render:testAsset", 0 ), - IECore.StringData( os.path.join( os.path.dirname( __file__ ), "data", "cube.usda" ) ) + os.path.normcase( os.path.normpath( xform.readAttribute( "render:testAsset", 0 ).value ) ), + os.path.normcase( os.path.join( os.path.dirname( __file__ ), "data", "cube.usda" ) ) ) def testExposedShaderInput( self ) :