From 165be143df4d6ea3e664c4b773bf47da875846a5 Mon Sep 17 00:00:00 2001 From: Eric Mehl Date: Thu, 9 May 2024 14:32:01 -0400 Subject: [PATCH] TestLight : Use shader as source of parameters --- include/GafferSceneTest/TestLight.h | 16 ++++ python/GafferSceneTest/SceneAlgoTest.py | 10 +-- python/GafferSceneTest/SceneReaderTest.py | 4 +- src/GafferSceneTest/TestLight.cpp | 87 ++++++++++++------- .../GafferSceneTestModule.cpp | 4 +- 5 files changed, 84 insertions(+), 37 deletions(-) diff --git a/include/GafferSceneTest/TestLight.h b/include/GafferSceneTest/TestLight.h index 6cd57bd4436..af7228c1455 100644 --- a/include/GafferSceneTest/TestLight.h +++ b/include/GafferSceneTest/TestLight.h @@ -37,9 +37,11 @@ #pragma once #include "GafferSceneTest/Export.h" +#include "GafferSceneTest/TestShader.h" #include "GafferSceneTest/TypeIds.h" #include "GafferScene/Light.h" +#include "GafferScene/ShaderPlug.h" namespace GafferSceneTest { @@ -54,11 +56,25 @@ class GAFFERSCENETEST_API TestLight : public GafferScene::Light GAFFER_NODE_DECLARE_TYPE( GafferSceneTest::TestLight, TestLightTypeId, GafferScene::Light ); + void affects( const Gaffer::Plug *input, AffectedPlugsContainer &outputs ) const override; + + void loadShader( const std::string &shaderName ); + protected : void hashLight( const Gaffer::Context *context, IECore::MurmurHash &h ) const override; IECoreScene::ConstShaderNetworkPtr computeLight( const Gaffer::Context *context ) const override; + private : + + TestShader *shaderNode(); + const TestShader *shaderNode() const; + + GafferScene::ShaderPlug *shaderInPlug(); + const GafferScene::ShaderPlug *shaderInPlug() const; + + static size_t g_firstPlugIndex; + }; } // namespace GafferSceneTest diff --git a/python/GafferSceneTest/SceneAlgoTest.py b/python/GafferSceneTest/SceneAlgoTest.py index 412ec3bb546..814056c5cc3 100644 --- a/python/GafferSceneTest/SceneAlgoTest.py +++ b/python/GafferSceneTest/SceneAlgoTest.py @@ -1564,11 +1564,11 @@ def testParameterHistoryWithShaderTweaks( self ) : history = GafferScene.SceneAlgo.history( tweaks["out"]["attributes"], "/group/light" ) attributeHistory = GafferScene.SceneAlgo.attributeHistory( history, "light" ) - self.__assertParameterHistory( attributeHistory, [], tweaks["out"], "/group/light", "light", "light", "exposure", 2.0, 1 ) - self.__assertParameterHistory( attributeHistory, [ 0 ], tweaks["in"], "/group/light", "light", "light", "exposure", 0.0, 1 ) - self.__assertParameterHistory( attributeHistory, [ 0, 0 ], group["out"], "/group/light", "light", "light", "exposure", 0.0, 1 ) - self.__assertParameterHistory( attributeHistory, [ 0, 0, 0 ], group["in"][0], "/light", "light", "light", "exposure", 0.0, 1 ) - self.__assertParameterHistory( attributeHistory, [ 0, 0, 0, 0 ], testLight["out"], "/light", "light", "light", "exposure", 0.0, 0 ) + self.__assertParameterHistory( attributeHistory, [], tweaks["out"], "/group/light", "light", "__shader", "exposure", 2.0, 1 ) + self.__assertParameterHistory( attributeHistory, [ 0 ], tweaks["in"], "/group/light", "light", "__shader", "exposure", 0.0, 1 ) + self.__assertParameterHistory( attributeHistory, [ 0, 0 ], group["out"], "/group/light", "light", "__shader", "exposure", 0.0, 1 ) + self.__assertParameterHistory( attributeHistory, [ 0, 0, 0 ], group["in"][0], "/light", "light", "__shader", "exposure", 0.0, 1 ) + self.__assertParameterHistory( attributeHistory, [ 0, 0, 0, 0 ], testLight["out"], "/light", "light", "__shader", "exposure", 0.0, 0 ) def testAttributeHistoryWithMissingAttribute( self ) : diff --git a/python/GafferSceneTest/SceneReaderTest.py b/python/GafferSceneTest/SceneReaderTest.py index e5d8e79e1dd..912fce9fd17 100644 --- a/python/GafferSceneTest/SceneReaderTest.py +++ b/python/GafferSceneTest/SceneReaderTest.py @@ -616,12 +616,12 @@ def testExplicitUSDDefaultLights( self ) : light1 = GafferSceneTest.TestLight() light1["name"].setValue( "light1" ) - light1["lightShaderName"].setValue( "SphereLight" ) # USDScene requires valid USD light type + light1.loadShader( "SphereLight" ) # USDScene requires valid USD light type light1["parameters"]["intensity"] = Gaffer.FloatPlug( defaultValue = 1 ) # USD expects float, not colour light1["defaultLight"].setValue( False ) light2 = GafferSceneTest.TestLight() - light2["lightShaderName"].setValue( "SphereLight" ) + light2.loadShader( "SphereLight" ) light2["parameters"]["intensity"] = Gaffer.FloatPlug( defaultValue = 1 ) light2["name"].setValue( "light2" ) diff --git a/src/GafferSceneTest/TestLight.cpp b/src/GafferSceneTest/TestLight.cpp index cbdfe03648c..9c0f49691b3 100644 --- a/src/GafferSceneTest/TestLight.cpp +++ b/src/GafferSceneTest/TestLight.cpp @@ -42,54 +42,83 @@ #include "IECoreScene/Shader.h" using namespace Gaffer; +using namespace GafferScene; using namespace GafferSceneTest; GAFFER_NODE_DEFINE_TYPE( TestLight ) +size_t TestLight::g_firstPlugIndex = 0; + TestLight::TestLight( const std::string &name ) : Light( name ) { - addChild( new StringPlug( "lightShaderName", Plug::In, "testLight" ) ); - parametersPlug()->addChild( new Color3fPlug( "intensity" ) ); - parametersPlug()->addChild( new FloatPlug( "exposure" ) ); - parametersPlug()->addChild( new BoolPlug( "__areaLight" ) ); + storeIndexOfNextChild( g_firstPlugIndex ); + + addChild( new TestShader( "__shader" ) ); + addChild( new ShaderPlug( "__shaderIn", Plug::In, Plug::Default & ~Plug::Serialisable ) ); + + /// \todo Remove this when merging to `main` after changing `TestShader` to not load a + /// default shader. We need it for now to remove the child plugs resulting from loading + /// `simpleShader` in the `TestShader` constructor. + shaderNode()->parametersPlug()->clearChildren(); + + shaderNode()->typePlug()->setValue( "light" ); + shaderNode()->parametersPlug()->setFlags( Plug::AcceptsInputs, true ); + shaderNode()->parametersPlug()->setInput( parametersPlug() ); + + shaderInPlug()->setInput( shaderNode()->outPlug() ); + + shaderNode()->loadShader( "simpleLight" ); } TestLight::~TestLight() { } -void TestLight::hashLight( const Gaffer::Context *context, IECore::MurmurHash &h ) const +TestShader *TestLight::shaderNode() { - for( ValuePlug::Iterator it( parametersPlug() ); !it.done(); ++it ) - { - (*it)->hash( h ); - } + return getChild( g_firstPlugIndex ); } -IECoreScene::ConstShaderNetworkPtr TestLight::computeLight( const Gaffer::Context *context ) const +const TestShader *TestLight::shaderNode() const { - IECoreScene::ShaderPtr shader = new IECoreScene::Shader( getChild( "lightShaderName" )->getValue(), "light" ); + return getChild( g_firstPlugIndex ); +} - for( const auto &c : ValuePlug::Range( *parametersPlug() ) ) +ShaderPlug *TestLight::shaderInPlug() +{ + return getChild( g_firstPlugIndex + 1 ); +} + +const ShaderPlug *TestLight::shaderInPlug() const +{ + return getChild( g_firstPlugIndex + 1 ); +} + +void TestLight::loadShader( const std::string &shaderName ) +{ + shaderNode()->loadShader( shaderName ); + shaderNode()->typePlug()->setValue( "light" ); + shaderInPlug()->setInput( shaderNode()->outPlug() ); +} + +void TestLight::affects( const Plug *input, AffectedPlugsContainer &outputs ) const +{ + Light::affects( input, outputs ); + + if( input == shaderInPlug() ) { - IECore::DataPtr data = PlugAlgo::getValueAsData( c.get() ); - if( auto compoundData = IECore::runTimeCast( data.get() ) ) - { - auto enabledData = compoundData->member( "enabled" ); - if( enabledData && enabledData->readable() ) - { - shader->parameters()[ c->getName() ] = compoundData->member( "value" ); - } - } - else - { - shader->parameters()[ c->getName() ] = data; - } + outputs.push_back( outPlug()->attributesPlug() ); } +} - IECoreScene::ShaderNetworkPtr network = new IECoreScene::ShaderNetwork(); - network->addShader( "light", std::move( shader ) ); - network->setOutput( { "light" } ); - return network; +void TestLight::hashLight( const Gaffer::Context *context, IECore::MurmurHash &h ) const +{ + h.append( shaderInPlug()->attributesHash() ); +} + +IECoreScene::ConstShaderNetworkPtr TestLight::computeLight( const Gaffer::Context *context ) const +{ + IECore::ConstCompoundObjectPtr shaderAttributes = shaderInPlug()->attributes(); + return shaderAttributes->member( "light" ); } diff --git a/src/GafferSceneTestModule/GafferSceneTestModule.cpp b/src/GafferSceneTestModule/GafferSceneTestModule.cpp index 31a1cd2c2cf..e9a7d1c55da 100644 --- a/src/GafferSceneTestModule/GafferSceneTestModule.cpp +++ b/src/GafferSceneTestModule/GafferSceneTestModule.cpp @@ -67,7 +67,9 @@ BOOST_PYTHON_MODULE( _GafferSceneTest ) GafferBindings::DependencyNodeClass(); GafferBindings::NodeClass(); - GafferBindings::NodeClass(); + GafferBindings::NodeClass() + .def( "loadShader", &TestLight::loadShader ) + ; GafferBindings::NodeClass(); def( "traverseScene", &traverseSceneWrapper );