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 c73932b40f6..084ba328762 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/DataAlgo.h" #include "IECore/SplineData.h" @@ -549,6 +550,125 @@ 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(); + auto &writable = data->writable(); + writable.resize( size ); + for( Plug::InputIterator it( plug ); !it.done(); ++it, ++i ) + { + writable[i] = static_cast( it->get() )->getValue(); + } + return data; + } + case IntPlugTypeId : + { + IntVectorDataPtr data = new IntVectorData(); + auto &writable = data->writable(); + writable.resize( size ); + for( Plug::InputIterator it( plug ); !it.done(); ++it, ++i ) + { + writable[i] = static_cast( it->get() )->getValue(); + } + return data; + } + case Color3fPlugTypeId : + { + Color3fVectorDataPtr data = new Color3fVectorData(); + auto &writable = data->writable(); + writable.resize( size ); + for( Plug::InputIterator it( plug ); !it.done(); ++it, ++i ) + { + writable[i] = static_cast( it->get() )->getValue(); + } + return data; + } + case Color4fPlugTypeId : + { + Color4fVectorDataPtr data = new Color4fVectorData(); + auto &writable = data->writable(); + writable.resize( size ); + for( Plug::InputIterator it( plug ); !it.done(); ++it, ++i ) + { + writable[i] = static_cast( it->get() )->getValue(); + } + return data; + } + case StringPlugTypeId : + { + StringVectorDataPtr data = new StringVectorData(); + auto &writable = data->writable(); + writable.resize( size ); + for( Plug::InputIterator it( plug ); !it.done(); ++it, ++i ) + { + writable[i] = static_cast( it->get() )->getValue(); + } + return data; + } + case BoolPlugTypeId : + { + BoolVectorDataPtr data = new BoolVectorData(); + auto &writable = data->writable(); + writable.resize( size ); + for( Plug::InputIterator it( plug ); !it.done(); ++it, ++i ) + { + writable[i] = static_cast( it->get() )->getValue(); + } + return data; + } + case V2fPlugTypeId : + { + V2fVectorDataPtr data = new V2fVectorData(); + auto &writable = data->writable(); + writable.resize( size ); + for( Plug::InputIterator it( plug ); !it.done(); ++it, ++i ) + { + writable[i] = static_cast( it->get() )->getValue(); + } + return data; + } + case V3fPlugTypeId : + { + V3fVectorDataPtr data = new V3fVectorData(); + auto &writable = data->writable(); + writable.resize( size ); + for( Plug::InputIterator it( plug ); !it.done(); ++it, ++i ) + { + writable[i] = static_cast( it->get() )->getValue(); + } + return data; + } + case M44fPlugTypeId : + { + M44fVectorDataPtr data = new M44fVectorData(); + auto &writable = data->writable(); + writable.resize( size ); + for( Plug::InputIterator it( plug ); !it.done(); ++it, ++i ) + { + writable[i] = static_cast( it->get() )->getValue(); + } + return data; + } + default : + throw IECore::Exception( + fmt::format( "ArrayPlug \"{}\" has unsupported child type \"{}\"", plug->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 ca2426542ac..7628979acbe 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" @@ -151,6 +152,25 @@ Gaffer::Plug *setupNumericPlug( const AtNodeEntry *node, const AtParamEntry *par return plug.get(); } +Gaffer::Plug *setupArrayPlug( const IECore::InternedString ¶meterName, Gaffer::GraphComponent *plugParent, Gaffer::Plug::Direction direction, int arrayType ) +{ + Plug *existingPlug = plugParent->getChild( parameterName ); + + if( + existingPlug && + existingPlug->direction() == direction + ) + { + existingPlug->setFlags( Gaffer::Plug::Dynamic, false ); + return existingPlug; + } + 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(); +} + Gaffer::Plug *setupPlug( const IECore::InternedString ¶meterName, Gaffer::GraphComponent *plugParent, Gaffer::Plug::Direction direction ) { Plug *existingPlug = plugParent->getChild( parameterName ); @@ -577,6 +597,11 @@ Gaffer::Plug *ParameterHandler::setupPlug( const AtNodeEntry *node, const AtPara ); break; + case AI_TYPE_ARRAY : + int arrayType = AiParamGetSubType(parameter); + plug = setupArrayPlug( AiParamGetName( parameter ).c_str(), plugParent, direction, arrayType); + break; + } if( !plug ) diff --git a/src/GafferScene/Shader.cpp b/src/GafferScene/Shader.cpp index 2bfba0f01a2..9d6896fd6aa 100644 --- a/src/GafferScene/Shader.cpp +++ b/src/GafferScene/Shader.cpp @@ -464,12 +464,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 { @@ -651,6 +646,28 @@ 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 ); + } + } + 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 > @@ -1095,6 +1112,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; }