diff --git a/Changes.md b/Changes.md index 6e6ad0b6a4..79d9b20e94 100644 --- a/Changes.md +++ b/Changes.md @@ -1,6 +1,11 @@ 1.4.x.x (relative to 1.4.14.0) ======= +Improvements +------------ + +- Arnold : Added support for Int64Data and UInt64Data custom attributes, allowing USD's `instanceId` to be used as a custom attribute in the Instancer node. Warnings are emitted if values are out of range for Arnold's 32 bit ints. + Fixes ----- diff --git a/python/IECoreArnoldTest/ParameterAlgoTest.py b/python/IECoreArnoldTest/ParameterAlgoTest.py index 0f189affc9..0fe1cf6fb1 100644 --- a/python/IECoreArnoldTest/ParameterAlgoTest.py +++ b/python/IECoreArnoldTest/ParameterAlgoTest.py @@ -144,5 +144,23 @@ def testVectorIntData( self ) : IECoreArnold.ParameterAlgo.setParameter( n, "customV3i", IECore.V3iData( imath.V3i( 3, 4, 5 ) ) ) self.assertEqual( arnold.AiNodeGetVec( n, "customV3i" ), arnold.AtVector( 3, 4, 5 ) ) + def testInt64Data( self ) : + + with IECoreArnold.UniverseBlock( writable = True ) as universe : + + n = arnold.AiNode( universe, "ginstance" ) + with IECore.CapturingMessageHandler() as mh : + IECoreArnold.ParameterAlgo.setParameter( n, "customInt64", IECore.Int64Data( 1 ) ) + IECoreArnold.ParameterAlgo.setParameter( n, "customUInt64", IECore.UInt64Data( 2 ) ) + IECoreArnold.ParameterAlgo.setParameter( n, "customInt64OutOfRange", IECore.Int64Data( 2 ** 31 ) ) + IECoreArnold.ParameterAlgo.setParameter( n, "customUInt64OutOfRange", IECore.UInt64Data( 2 ** 32 ) ) + + self.assertEqual( arnold.AiNodeGetInt( n, "customInt64" ), 1 ) + self.assertEqual( arnold.AiNodeGetUInt( n, "customUInt64" ), 2 ) + + self.assertEqual( len( mh.messages ), 2 ) + self.assertEqual( mh.messages[0].message, 'Int64Data value 2147483648 is out of range for parameter "customInt64OutOfRange"' ) + self.assertEqual( mh.messages[1].message, 'UInt64Data value 4294967296 is out of range for parameter "customUInt64OutOfRange"' ) + if __name__ == "__main__": unittest.main() diff --git a/src/IECoreArnold/ParameterAlgo.cpp b/src/IECoreArnold/ParameterAlgo.cpp index b00de67793..346a7b2998 100644 --- a/src/IECoreArnold/ParameterAlgo.cpp +++ b/src/IECoreArnold/ParameterAlgo.cpp @@ -90,13 +90,37 @@ void setParameterInternal( AtNode *node, AtString name, int parameterType, bool switch( parameterType ) { case AI_TYPE_INT : - if( const IntData *data = dataCast( name, value ) ) + if( const Int64Data *data = runTimeCast( value ) ) + { + int i = static_cast( data->readable() ); + if( i == data->readable() ) + { + AiNodeSetInt( node, name, i ); + } + else + { + msg( Msg::Warning, "setParameter", fmt::format( "Int64Data value {} is out of range for parameter \"{}\"", data->readable(), name ) ); + } + } + else if( const IntData *data = dataCast( name, value ) ) { AiNodeSetInt( node, name, data->readable() ); } break; case AI_TYPE_UINT : - if( const IntData *data = runTimeCast( value ) ) + if( const UInt64Data *data = runTimeCast( value ) ) + { + unsigned int i = static_cast( data->readable() ); + if( i == data->readable() ) + { + AiNodeSetUInt( node, name, i ); + } + else + { + msg( Msg::Warning, "setParameter", fmt::format( "UInt64Data value {} is out of range for parameter \"{}\"", data->readable(), name ) ); + } + } + else if( const IntData *data = runTimeCast( value ) ) { AiNodeSetUInt( node, name, std::max( 0, data->readable() ) ); } @@ -459,9 +483,11 @@ int parameterType( IECore::TypeId dataType, bool &array ) // non-array types case IntDataTypeId : + case Int64DataTypeId : array = false; return AI_TYPE_INT; case UIntDataTypeId : + case UInt64DataTypeId : array = false; return AI_TYPE_UINT; case FloatDataTypeId :