From 9fa969cf18b63be6e0708d7befb9dd339942ebc0 Mon Sep 17 00:00:00 2001 From: John Haddon Date: Tue, 5 Dec 2023 10:44:40 +0000 Subject: [PATCH] PlugAlgo : Convert all numeric types for `BoolPlug`, `IntPlug` and `FloatPlug` This addresses the problem raised in https://groups.google.com/g/gaffer-dev/c/9Ba1eaG1oeg, where AttributeQuery is failing to query a DoubleData attribute. --- Changes.md | 8 +++++ python/GafferSceneTest/AttributeQueryTest.py | 16 +++++++++ python/GafferTest/PlugAlgoTest.py | 29 ++++++++++++++++ src/Gaffer/PlugAlgo.cpp | 36 ++++++++++++++++++++ 4 files changed, 89 insertions(+) diff --git a/Changes.md b/Changes.md index 209b79e7cf8..3bf5ace7dc2 100644 --- a/Changes.md +++ b/Changes.md @@ -1,7 +1,15 @@ 1.3.x.x (relative to 1.3.8.0) ======= +Fixes +----- + +- AttributeQuery, OptionQuery, PrimitiveVariableQuery, ShaderQuery : Added support for querying values of all numeric data types, whereas before queries were limited to `bool`, `int` and `float` values. + +API +--- +- PlugAlgo : `setPlugFromData()` now supports conversions from all numeric data types to `BoolPlug`, `IntPlug` and `FloatPlug` values. 1.3.8.0 (relative to 1.3.7.0) ======= diff --git a/python/GafferSceneTest/AttributeQueryTest.py b/python/GafferSceneTest/AttributeQueryTest.py index 7124aa00551..df91bb4c1ed 100644 --- a/python/GafferSceneTest/AttributeQueryTest.py +++ b/python/GafferSceneTest/AttributeQueryTest.py @@ -1334,6 +1334,22 @@ def testShaderOutput( self ) : self.assertEqual( q["value"].getValue(), v.attributes()["test:shader"] ) + def testQueryDoubleData( self ) : + + sphere = GafferScene.Sphere() + + attributes = GafferScene.CustomAttributes() + attributes["in"].setInput( sphere["out"] ) + attributes["extraAttributes"].setValue( IECore.CompoundObject( { "test" : IECore.DoubleData( 2.5 ) } ) ) + + query = GafferScene.AttributeQuery() + query.setup( Gaffer.FloatPlug() ) + query["scene"].setInput( attributes["out"] ) + query["location"].setValue( "/sphere" ) + query["attribute"].setValue( "test" ) + + self.assertTrue( query["exists"].getValue() ) + self.assertEqual( query["value"].getValue(), 2.5 ) if __name__ == "__main__": unittest.main() diff --git a/python/GafferTest/PlugAlgoTest.py b/python/GafferTest/PlugAlgoTest.py index d6ec26a5b2e..3e1d5ef41fe 100644 --- a/python/GafferTest/PlugAlgoTest.py +++ b/python/GafferTest/PlugAlgoTest.py @@ -1070,5 +1070,34 @@ def testFindSource( self ) : ).isSame( node2["product"] ) ) + def testNumericDataConversions( self ) : + + for data in [ + IECore.HalfData( 2.5 ), + IECore.DoubleData( 2.5 ), + IECore.CharData( "a" ), + IECore.UCharData( 11 ), + IECore.ShortData( -101 ), + IECore.UShortData( 102 ), + IECore.UIntData( 405 ), + IECore.Int64Data( -1001 ), + IECore.UInt64Data( 1002 ), + ] : + + for plugType in [ + Gaffer.IntPlug, + Gaffer.FloatPlug, + Gaffer.BoolPlug, + ] : + + with self.subTest( data = data, plugType = plugType ) : + + plug = plugType() + self.assertTrue( Gaffer.PlugAlgo.canSetValueFromData( plug, data ) ) + + Gaffer.PlugAlgo.setValueFromData( plug, data ) + value = ord( data.value ) if isinstance( data, IECore.CharData ) else data.value + self.assertEqual( plug.getValue(), plugType.ValueType( value ) ) + if __name__ == "__main__": unittest.main() diff --git a/src/Gaffer/PlugAlgo.cpp b/src/Gaffer/PlugAlgo.cpp index e0db579dd9a..1d0bf6424fd 100644 --- a/src/Gaffer/PlugAlgo.cpp +++ b/src/Gaffer/PlugAlgo.cpp @@ -554,12 +554,39 @@ bool setNumericPlugValue( PlugType *plug, const Data *value ) { switch( value->typeId() ) { + case HalfDataTypeId : + plug->setValue( static_cast( value )->readable() ); + return true; case FloatDataTypeId : plug->setValue( static_cast( value )->readable() ); return true; + case DoubleDataTypeId : + plug->setValue( static_cast( value )->readable() ); + return true; + case CharDataTypeId : + plug->setValue( static_cast( value )->readable() ); + return true; + case UCharDataTypeId : + plug->setValue( static_cast( value )->readable() ); + return true; + case ShortDataTypeId : + plug->setValue( static_cast( value )->readable() ); + return true; + case UShortDataTypeId : + plug->setValue( static_cast( value )->readable() ); + return true; case IntDataTypeId : plug->setValue( static_cast( value )->readable() ); return true; + case UIntDataTypeId : + plug->setValue( static_cast( value )->readable() ); + return true; + case Int64DataTypeId : + plug->setValue( static_cast( value )->readable() ); + return true; + case UInt64DataTypeId : + plug->setValue( static_cast( value )->readable() ); + return true; case BoolDataTypeId : plug->setValue( static_cast( value )->readable() ); return true; @@ -706,8 +733,17 @@ bool canSetNumericPlugValue( const Data *value ) switch( value->typeId() ) { + case HalfDataTypeId : case FloatDataTypeId : + case DoubleDataTypeId : + case CharDataTypeId : + case UCharDataTypeId : + case ShortDataTypeId : + case UShortDataTypeId : case IntDataTypeId : + case UIntDataTypeId : + case Int64DataTypeId : + case UInt64DataTypeId : case BoolDataTypeId : return true; default :