From eed1e18f5740111d724223c1eda28879ccb2114f Mon Sep 17 00:00:00 2001 From: Kyle Scott Date: Thu, 8 Feb 2024 15:20:56 -0800 Subject: [PATCH 1/5] adding support for array parameters as vectordata --- include/Gaffer/PlugAlgo.h | 4 ++ src/Gaffer/PlugAlgo.cpp | 61 +++++++++++++++++++++++++++ src/GafferArnold/ParameterHandler.cpp | 25 +++++++++++ src/GafferScene/Shader.cpp | 20 ++++++--- 4 files changed, 104 insertions(+), 6 deletions(-) diff --git a/include/Gaffer/PlugAlgo.h b/include/Gaffer/PlugAlgo.h index d69d292aef9..9102a7056e8 100644 --- a/include/Gaffer/PlugAlgo.h +++ b/include/Gaffer/PlugAlgo.h @@ -50,6 +50,7 @@ namespace Gaffer IE_CORE_FORWARDDECLARE( GraphComponent ) IE_CORE_FORWARDDECLARE( ValuePlug ) +IE_CORE_FORWARDDECLARE( ArrayPlug ) namespace PlugAlgo { @@ -86,6 +87,9 @@ GAFFER_API ValuePlugPtr createPlugFromData( const std::string &name, Plug::Direc /// Returns a Data value from a plug. GAFFER_API IECore::DataPtr getValueAsData( const ValuePlug *plug ); +/// Returns a VectorData value from an array plug. +GAFFER_API IECore::DataPtr getArrayAsVectorData( const ArrayPlug *plug ); + /// Sets the value of an existing plug to the specified data. /// Returns `true` on success and `false` on failure. GAFFER_API bool setValueFromData( ValuePlug *plug, const IECore::Data *value ); diff --git a/src/Gaffer/PlugAlgo.cpp b/src/Gaffer/PlugAlgo.cpp index 1d0bf6424fd..7c6ab968f72 100644 --- a/src/Gaffer/PlugAlgo.cpp +++ b/src/Gaffer/PlugAlgo.cpp @@ -48,6 +48,7 @@ #include "Gaffer/TransformPlug.h" #include "Gaffer/TypedObjectPlug.h" #include "Gaffer/ValuePlug.h" +#include "Gaffer/ArrayPlug.h" #include "IECore/SplineData.h" @@ -532,6 +533,66 @@ IECore::DataPtr getValueAsData( const ValuePlug *plug ) } +IECore::DataPtr getArrayAsVectorData( const ArrayPlug *plug ) +{ + size_t size = plug->children().size(); + if ( !size ) + { + return nullptr; + } + auto *childPlug = plug->getChild( 0 ); + int i = 0; + switch(static_cast(childPlug->typeId())) + { + case FloatPlugTypeId : + { + FloatVectorDataPtr data = new FloatVectorData(); + data->writable().resize( size ); + for( Plug::InputIterator it( plug ); !it.done(); ++it, ++i ) + { + data->writable()[i] = static_cast( it->get() )->getValue(); + } + return data; + } + case IntPlugTypeId : + { + IntVectorDataPtr data = new IntVectorData(); + data->writable().resize( size ); + for( Plug::InputIterator it( plug ); !it.done(); ++it, ++i ) + { + data->writable()[i] = static_cast( it->get() )->getValue(); + } + return data; + } + case Color3fPlugTypeId : + { + Color3fVectorDataPtr data = new Color3fVectorData(); + data->writable().resize( size ); + for( Plug::InputIterator it( plug ); !it.done(); ++it, ++i ) + { + data->writable()[i] = static_cast( it->get() )->getValue(); + } + return data; + } + case Color4fPlugTypeId : + { + Color4fVectorDataPtr data = new Color4fVectorData(); + data->writable().resize( size ); + for( Plug::InputIterator it( plug ); !it.done(); ++it, ++i ) + { + data->writable()[i] = static_cast( it->get() )->getValue(); + } + return data; + } + default : + throw IECore::Exception( + fmt::format( "Plug \"{}\" has unsupported type \"{}\"", childPlug->getName().string(), childPlug->typeName() ) + ); + } + +} + + IECore::DataPtr extractDataFromPlug( const ValuePlug *plug ) { return getValueAsData( plug ); diff --git a/src/GafferArnold/ParameterHandler.cpp b/src/GafferArnold/ParameterHandler.cpp index 5119d65f5bd..36e0dc690a9 100644 --- a/src/GafferArnold/ParameterHandler.cpp +++ b/src/GafferArnold/ParameterHandler.cpp @@ -45,6 +45,7 @@ #include "Gaffer/ScriptNode.h" #include "Gaffer/StringPlug.h" #include "Gaffer/TypedPlug.h" +#include "Gaffer/ArrayPlug.h" #include "IECore/MessageHandler.h" @@ -146,6 +147,26 @@ Gaffer::Plug *setupNumericPlug( const AtNodeEntry *node, const AtParamEntry *par return plug.get(); } +template +Gaffer::Plug *setupArrayPlug( const IECore::InternedString ¶meterName, Gaffer::GraphComponent *plugParent, Gaffer::Plug::Direction direction ) +{ + PlugType *existingPlug = plugParent->getChild( parameterName ); + + if( + existingPlug && + existingPlug->direction() == direction + ) + { + existingPlug->setFlags( Gaffer::Plug::Dynamic, false ); + return existingPlug; + } + + typename PlugType::Ptr plug = new PlugType( parameterName, direction, nullptr, 1, std::numeric_limits::max(), Plug::Flags::Default, false ); + PlugAlgo::replacePlug( plugParent, plug ); + + return plug.get(); +} + Gaffer::Plug *setupPlug( const IECore::InternedString ¶meterName, Gaffer::GraphComponent *plugParent, Gaffer::Plug::Direction direction ) { Plug *existingPlug = plugParent->getChild( parameterName ); @@ -572,6 +593,10 @@ Gaffer::Plug *ParameterHandler::setupPlug( const AtNodeEntry *node, const AtPara ); break; + case AI_TYPE_ARRAY : + plug = setupArrayPlug( AiParamGetName( parameter ).c_str(), plugParent, direction); + break; + } if( !plug ) diff --git a/src/GafferScene/Shader.cpp b/src/GafferScene/Shader.cpp index b3e0839e5f2..d26a3423dc7 100644 --- a/src/GafferScene/Shader.cpp +++ b/src/GafferScene/Shader.cpp @@ -430,12 +430,7 @@ class Shader::NetworkBuilder } else if( const Gaffer::ArrayPlug *array = IECore::runTimeCast( parameter ) ) { - int i = 0; - for( Plug::InputIterator it( array ); !it.done(); ++it, ++i ) - { - IECore::InternedString childParameterName = parameterName.string() + "[" + std::to_string( i ) + "]"; - addParameter( it->get(), childParameterName, shader, connections ); - } + addParameter( parameter, parameterName, shader, connections ); } else { @@ -617,6 +612,15 @@ class Shader::NetworkBuilder { addSplineParameterComponentConnections< SplinefColor4fPlug >( (const SplinefColor4fPlug*)parameter, parameterName, connections ); } + else if ( (Gaffer::TypeId)parameter->typeId() == ArrayPlugTypeId ) + { + int i = 0; + for ( Plug::InputIterator it( parameter ); !it.done(); ++it, ++i ) + { + IECore::InternedString inputName = parameterName.string() + "[" + std::to_string( i ) + "]"; + addParameterComponentConnections( it->get(), inputName, connections ); + } + } } template< typename T > @@ -1059,6 +1063,10 @@ IECore::DataPtr Shader::parameterValue( const Gaffer::Plug *parameterPlug ) cons { return Gaffer::PlugAlgo::getValueAsData( valuePlug ); } + else if( auto arrayPlug = IECore::runTimeCast( parameterPlug ) ) + { + return Gaffer::PlugAlgo::getArrayAsVectorData( arrayPlug ); + } return nullptr; } From eb76316bd5effbeb28da38507bcd81dd9d385f89 Mon Sep 17 00:00:00 2001 From: Kyle Scott Date: Wed, 28 Feb 2024 11:59:14 -0800 Subject: [PATCH 2/5] adding support for connections of other data types --- src/GafferScene/Shader.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/GafferScene/Shader.cpp b/src/GafferScene/Shader.cpp index d26a3423dc7..0fb8f1b4931 100644 --- a/src/GafferScene/Shader.cpp +++ b/src/GafferScene/Shader.cpp @@ -621,6 +621,19 @@ class Shader::NetworkBuilder addParameterComponentConnections( it->get(), inputName, connections ); } } + else + { + const Gaffer::Plug *effectiveParameter = this->effectiveParameter( parameter ); + if( effectiveParameter && isOutputParameter( effectiveParameter ) ) + { + IECore::InternedString inputName = parameterName.string(); + + connections.push_back( { + outputParameterForPlug( effectiveParameter ), + { IECore::InternedString(), inputName } + } ); + } + } } template< typename T > From 9634b89a26c3a189973673c9a843fb84df512e4a Mon Sep 17 00:00:00 2001 From: Kyle Scott Date: Wed, 22 May 2024 16:15:51 -0700 Subject: [PATCH 3/5] adding remaining array types --- src/Gaffer/PlugAlgo.cpp | 52 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/src/Gaffer/PlugAlgo.cpp b/src/Gaffer/PlugAlgo.cpp index 7c6ab968f72..6b35113f0e0 100644 --- a/src/Gaffer/PlugAlgo.cpp +++ b/src/Gaffer/PlugAlgo.cpp @@ -584,9 +584,59 @@ IECore::DataPtr getArrayAsVectorData( const ArrayPlug *plug ) } return data; } + case StringPlugTypeId : + { + StringVectorDataPtr data = new StringVectorData(); + data->writable().resize( size ); + for( Plug::InputIterator it( plug ); !it.done(); ++it, ++i ) + { + data->writable()[i] = static_cast( it->get() )->getValue(); + } + return data; + } + case BoolPlugTypeId : + { + BoolVectorDataPtr data = new BoolVectorData(); + data->writable().resize( size ); + for( Plug::InputIterator it( plug ); !it.done(); ++it, ++i ) + { + data->writable()[i] = static_cast( it->get() )->getValue(); + } + return data; + } + case V2fPlugTypeId : + { + V2fVectorDataPtr data = new V2fVectorData(); + data->writable().resize( size ); + for( Plug::InputIterator it( plug ); !it.done(); ++it, ++i ) + { + data->writable()[i] = static_cast( it->get() )->getValue(); + } + return data; + } + case V3fPlugTypeId : + { + V3fVectorDataPtr data = new V3fVectorData(); + data->writable().resize( size ); + for( Plug::InputIterator it( plug ); !it.done(); ++it, ++i ) + { + data->writable()[i] = static_cast( it->get() )->getValue(); + } + return data; + } + case M44fPlugTypeId : + { + M44fVectorDataPtr data = new M44fVectorData(); + data->writable().resize( size ); + for( Plug::InputIterator it( plug ); !it.done(); ++it, ++i ) + { + data->writable()[i] = static_cast( it->get() )->getValue(); + } + return data; + } default : throw IECore::Exception( - fmt::format( "Plug \"{}\" has unsupported type \"{}\"", childPlug->getName().string(), childPlug->typeName() ) + fmt::format( "ArrayPlug \"{}\" has unsupported child type \"{}\"", plug->getName().string(), childPlug->typeName() ) ); } From c902277e555b1e3ab2f2badd268fb687ab45442b Mon Sep 17 00:00:00 2001 From: Kyle Scott Date: Wed, 2 Oct 2024 19:54:33 -0700 Subject: [PATCH 4/5] adding type to created arnold array --- src/GafferArnold/ParameterHandler.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/GafferArnold/ParameterHandler.cpp b/src/GafferArnold/ParameterHandler.cpp index 066b45ff8f1..7628979acbe 100644 --- a/src/GafferArnold/ParameterHandler.cpp +++ b/src/GafferArnold/ParameterHandler.cpp @@ -152,10 +152,9 @@ Gaffer::Plug *setupNumericPlug( const AtNodeEntry *node, const AtParamEntry *par return plug.get(); } -template -Gaffer::Plug *setupArrayPlug( const IECore::InternedString ¶meterName, Gaffer::GraphComponent *plugParent, Gaffer::Plug::Direction direction ) +Gaffer::Plug *setupArrayPlug( const IECore::InternedString ¶meterName, Gaffer::GraphComponent *plugParent, Gaffer::Plug::Direction direction, int arrayType ) { - PlugType *existingPlug = plugParent->getChild( parameterName ); + Plug *existingPlug = plugParent->getChild( parameterName ); if( existingPlug && @@ -165,8 +164,8 @@ Gaffer::Plug *setupArrayPlug( const IECore::InternedString ¶meterName, Gaffe existingPlug->setFlags( Gaffer::Plug::Dynamic, false ); return existingPlug; } - - typename PlugType::Ptr plug = new PlugType( parameterName, direction, nullptr, 1, std::numeric_limits::max(), Plug::Flags::Default, false ); + Plug *arrayTypePlug = ParameterHandler::setupPlug(parameterName, arrayType, plugParent, direction ); + ArrayPlugPtr plug = new ArrayPlug( parameterName, direction, arrayTypePlug, 0, std::numeric_limits::max(), Plug::Flags::Default, false ); PlugAlgo::replacePlug( plugParent, plug ); return plug.get(); @@ -599,7 +598,8 @@ Gaffer::Plug *ParameterHandler::setupPlug( const AtNodeEntry *node, const AtPara break; case AI_TYPE_ARRAY : - plug = setupArrayPlug( AiParamGetName( parameter ).c_str(), plugParent, direction); + int arrayType = AiParamGetSubType(parameter); + plug = setupArrayPlug( AiParamGetName( parameter ).c_str(), plugParent, direction, arrayType); break; } From 77420aab8bcc1b041b55c7b36ba40934f421c5a5 Mon Sep 17 00:00:00 2001 From: Kyle Scott Date: Wed, 2 Oct 2024 20:14:18 -0700 Subject: [PATCH 5/5] minimizing calls to writable for efficiency --- src/Gaffer/PlugAlgo.cpp | 45 ++++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/src/Gaffer/PlugAlgo.cpp b/src/Gaffer/PlugAlgo.cpp index e54583e1f18..f8ea4353291 100644 --- a/src/Gaffer/PlugAlgo.cpp +++ b/src/Gaffer/PlugAlgo.cpp @@ -564,90 +564,99 @@ IECore::DataPtr getArrayAsVectorData( const ArrayPlug *plug ) case FloatPlugTypeId : { FloatVectorDataPtr data = new FloatVectorData(); - data->writable().resize( size ); + auto &writable = data->writable(); + writable.resize( size ); for( Plug::InputIterator it( plug ); !it.done(); ++it, ++i ) { - data->writable()[i] = static_cast( it->get() )->getValue(); + writable[i] = static_cast( it->get() )->getValue(); } return data; } case IntPlugTypeId : { IntVectorDataPtr data = new IntVectorData(); - data->writable().resize( size ); + auto &writable = data->writable(); + writable.resize( size ); for( Plug::InputIterator it( plug ); !it.done(); ++it, ++i ) { - data->writable()[i] = static_cast( it->get() )->getValue(); + writable[i] = static_cast( it->get() )->getValue(); } return data; } case Color3fPlugTypeId : { Color3fVectorDataPtr data = new Color3fVectorData(); - data->writable().resize( size ); + auto &writable = data->writable(); + writable.resize( size ); for( Plug::InputIterator it( plug ); !it.done(); ++it, ++i ) { - data->writable()[i] = static_cast( it->get() )->getValue(); + writable[i] = static_cast( it->get() )->getValue(); } return data; } case Color4fPlugTypeId : { Color4fVectorDataPtr data = new Color4fVectorData(); - data->writable().resize( size ); + auto &writable = data->writable(); + writable.resize( size ); for( Plug::InputIterator it( plug ); !it.done(); ++it, ++i ) { - data->writable()[i] = static_cast( it->get() )->getValue(); + writable[i] = static_cast( it->get() )->getValue(); } return data; } case StringPlugTypeId : { StringVectorDataPtr data = new StringVectorData(); - data->writable().resize( size ); + auto &writable = data->writable(); + writable.resize( size ); for( Plug::InputIterator it( plug ); !it.done(); ++it, ++i ) { - data->writable()[i] = static_cast( it->get() )->getValue(); + writable[i] = static_cast( it->get() )->getValue(); } return data; } case BoolPlugTypeId : { BoolVectorDataPtr data = new BoolVectorData(); - data->writable().resize( size ); + auto &writable = data->writable(); + writable.resize( size ); for( Plug::InputIterator it( plug ); !it.done(); ++it, ++i ) { - data->writable()[i] = static_cast( it->get() )->getValue(); + writable[i] = static_cast( it->get() )->getValue(); } return data; } case V2fPlugTypeId : { V2fVectorDataPtr data = new V2fVectorData(); - data->writable().resize( size ); + auto &writable = data->writable(); + writable.resize( size ); for( Plug::InputIterator it( plug ); !it.done(); ++it, ++i ) { - data->writable()[i] = static_cast( it->get() )->getValue(); + writable[i] = static_cast( it->get() )->getValue(); } return data; } case V3fPlugTypeId : { V3fVectorDataPtr data = new V3fVectorData(); - data->writable().resize( size ); + auto &writable = data->writable(); + writable.resize( size ); for( Plug::InputIterator it( plug ); !it.done(); ++it, ++i ) { - data->writable()[i] = static_cast( it->get() )->getValue(); + writable[i] = static_cast( it->get() )->getValue(); } return data; } case M44fPlugTypeId : { M44fVectorDataPtr data = new M44fVectorData(); - data->writable().resize( size ); + auto &writable = data->writable(); + writable.resize( size ); for( Plug::InputIterator it( plug ); !it.done(); ++it, ++i ) { - data->writable()[i] = static_cast( it->get() )->getValue(); + writable[i] = static_cast( it->get() )->getValue(); } return data; }