Skip to content

Commit

Permalink
ArnoldShader : Support camera_projection.camera parameter
Browse files Browse the repository at this point in the history
This is just a case of setting the `gaffer.plugType` to "StringPlug" and letting the recently added `NodeParameter` mechanism do the rest in `ArnoldRenderer`.

Also added a nice camera browser using ScenePathPlugValueWidget. I was unsure what to do for this in ArnoldShaderUI, as the "camera" value for "widget" isn't part of the OSL standard. The other option would have been to support three new Gaffer-specific metadata entries for `gaffer.plugValueWidget.type`, `scenePathPlugValueWidget.setNames` and `scenePathPlugValueWidget:setsLabel`. But that seemed quite faffy when we don't have any other use cases for them at present, and "camera" seems like something that could reasonably be supported by other DCCs.
  • Loading branch information
johnhaddon committed Nov 13, 2023
1 parent 8a954c2 commit 62c70e5
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 2 deletions.
2 changes: 2 additions & 0 deletions Changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
Improvements
------------

- ArnoldShader : Improved support for camera projections by exposing the `camera` plug on the `camera_projection` shader.
- Instancer :
- Improved scene generation for encapsulated instancers significantly, with some production scenes now generating 5-7x faster.
- Added `omitDuplicateIds` plug, to determine whether points with duplicate IDs are ignored or should trigger an error.
Expand All @@ -14,6 +15,7 @@ API

- Capsule : Added protected `renderOptions()` and `throwIfNoScene()` methods.
- ScenePath : Added support for passing `nullptr` for the scene.
- ArnoldShaderUI : Added support for `camera` widget type metadata, to add a camera browser to a string parameter.

1.3.6.1 (relative to 1.3.6.0)
=======
Expand Down
3 changes: 2 additions & 1 deletion arnoldPlugins/gaffer.mtd
Original file line number Diff line number Diff line change
Expand Up @@ -1029,7 +1029,8 @@
gaffer.layout.activator.coordSpaceIsPref STRING "parameters['coord_space'].getValue() == 'Pref'"

[attr camera]
gaffer.plugType STRING ""
gaffer.plugType STRING "StringPlug"
widget STRING "camera"

[attr pref_name]
gaffer.layout.activator STRING "coordSpaceIsPref"
Expand Down
10 changes: 10 additions & 0 deletions python/GafferArnoldTest/ArnoldShaderTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -937,5 +937,15 @@ def testLoadQuadLight( self ) :
self.assertTrue( shader["parameters"]["width"].isSetToDefault() )
self.assertTrue( shader["parameters"]["height"].isSetToDefault() )

def testLoadCameraProjection( self ) :

shader = GafferArnold.ArnoldShader()
shader.loadShader( "camera_projection" )

self.assertIn( "camera", shader["parameters"] )
self.assertIsInstance( shader["parameters"]["camera"], Gaffer.StringPlug )
self.assertEqual( shader["parameters"]["camera"].getValue(), "" )
self.assertEqual( shader["parameters"]["camera"].defaultValue(), "" )

if __name__ == "__main__":
unittest.main()
5 changes: 5 additions & 0 deletions python/GafferArnoldUI/ArnoldShaderUI.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,9 +287,14 @@ def __translateNodeMetadata( nodeEntry ) :
"popup" : "GafferUI.PresetsPlugValueWidget",
"mapper" : "GafferUI.PresetsPlugValueWidget",
"filename" : "GafferUI.PathPlugValueWidget",
"camera" : "GafferSceneUI.ScenePathPlugValueWidget",
"null" : "",
}[widget]

if widget == "camera" :
__metadata[paramPath]["scenePathPlugValueWidget:setNames"] = IECore.StringVectorData( [ "__cameras" ] )
__metadata[paramPath]["scenePathPlugValueWidget:setsLabel"] = "Show only cameras"

# Layout section from OSL "page".

page = __aiMetadataGetStr( nodeEntry, paramName, "page" )
Expand Down
20 changes: 19 additions & 1 deletion src/GafferArnold/ParameterHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ using namespace GafferArnold;
namespace
{

const AtString g_emptyArnoldString( "" );
const AtString g_nameArnoldString( "name" );
const AtString g_gafferPlugTypeArnoldString( "gaffer.plugType" );
const AtString g_gafferDefaultArnoldString( "gaffer.default" );
Expand All @@ -70,6 +71,7 @@ const AtString g_FloatPlugArnoldString( "FloatPlug" );
const AtString g_Color3fPlugArnoldString( "Color3fPlug" );
const AtString g_Color4fPlugArnoldString( "Color4fPlug" );
const AtString g_ClosurePlugArnoldString( "ClosurePlug" );
const AtString g_StringPlugArnoldString( "StringPlug" );

const AtString g_quadLightShaderName( "quad_light" );

Expand Down Expand Up @@ -403,6 +405,10 @@ Gaffer::Plug *ParameterHandler::setupPlug( const AtNodeEntry *node, const AtPara
{
parameterType = AI_TYPE_CLOSURE;
}
else if( plugTypeOverride == g_StringPlugArnoldString )
{
parameterType = AI_TYPE_STRING;
}
else
{
msg(
Expand Down Expand Up @@ -512,7 +518,19 @@ Gaffer::Plug *ParameterHandler::setupPlug( const AtNodeEntry *node, const AtPara
case AI_TYPE_STRING :

{
AtString defaultValue = AiParamGetDefault( parameter )->STR();
AtString defaultValue;
if( AiParamGetType( parameter ) == AI_TYPE_STRING )
{
defaultValue = AiParamGetDefault( parameter )->STR();
}
else
{
// We get here when `plugTypeOverride` causes us to treat a
// non-string parameter as a string. In this case, Arnold's
// default value won't be a valid `AtString` so we must
// ignore it.
defaultValue = g_emptyArnoldString;
}
AiMetaDataGetStr( node, name, g_gafferDefaultArnoldString, &defaultValue );
plug = setupTypedPlug<StringPlug>(
node,
Expand Down

0 comments on commit 62c70e5

Please sign in to comment.