Skip to content

Commit

Permalink
Merge pull request #5738 from johnhaddon/box2fVectorDataPlug
Browse files Browse the repository at this point in the history
TypedObjectPlug : Add Box2fVectorDataPlug
  • Loading branch information
johnhaddon authored Mar 19, 2024
2 parents f6eda88 + be78bd9 commit 39a7839
Show file tree
Hide file tree
Showing 9 changed files with 158 additions and 1 deletion.
9 changes: 9 additions & 0 deletions Changes.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
1.4.x.x (relative to 1.4.0.0b4)
=======

API
---

- TypedObjectPlug : Added Python bindings for the default values of the `defaultValue` constructor argument.
- Box2fVectorDataPlug : Added new plug type for storing arrays of Box2f.

Fixes
-----

- PlugAlgo : Updated `canSetValueFromData()`, `setValueFromData()` and `getValueAsData()` with support for missing types.

1.4.0.0b4 (relative to 1.4.0.0b3)
=========
Expand Down
1 change: 1 addition & 0 deletions include/Gaffer/TypeIds.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ enum TypeId
Color4fVectorDataPlugTypeId = 110106,
OptionalValuePlugTypeId = 110107,
CollectTypeId = 110108,
Box2fVectorDataPlugTypeId = 110109,

LastTypeId = 110159,

Expand Down
3 changes: 3 additions & 0 deletions include/Gaffer/TypedObjectPlug.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ extern template class TypedObjectPlug<IECore::Color3fVectorData>;
extern template class TypedObjectPlug<IECore::Color4fVectorData>;
extern template class TypedObjectPlug<IECore::M44fVectorData>;
extern template class TypedObjectPlug<IECore::M33fVectorData>;
extern template class TypedObjectPlug<IECore::Box2fVectorData>;
extern template class TypedObjectPlug<IECore::ObjectVector>;
extern template class TypedObjectPlug<IECore::CompoundObject>;
extern template class TypedObjectPlug<IECore::CompoundData>;
Expand All @@ -156,6 +157,7 @@ using Color3fVectorDataPlug = TypedObjectPlug<IECore::Color3fVectorData>;
using Color4fVectorDataPlug = TypedObjectPlug<IECore::Color4fVectorData>;
using M44fVectorDataPlug = TypedObjectPlug<IECore::M44fVectorData>;
using M33fVectorDataPlug = TypedObjectPlug<IECore::M33fVectorData>;
using Box2fVectorDataPlug = TypedObjectPlug<IECore::Box2fVectorData>;
using ObjectVectorPlug = TypedObjectPlug<IECore::ObjectVector>;
using CompoundObjectPlug = TypedObjectPlug<IECore::CompoundObject>;
using AtomicCompoundDataPlug = TypedObjectPlug<IECore::CompoundData>;
Expand All @@ -175,6 +177,7 @@ IE_CORE_DECLAREPTR( Color3fVectorDataPlug );
IE_CORE_DECLAREPTR( Color4fVectorDataPlug );
IE_CORE_DECLAREPTR( M44fVectorDataPlug );
IE_CORE_DECLAREPTR( M33fVectorDataPlug );
IE_CORE_DECLAREPTR( Box2fVectorDataPlug );
IE_CORE_DECLAREPTR( ObjectVectorPlug );
IE_CORE_DECLAREPTR( CompoundObjectPlug );
IE_CORE_DECLAREPTR( AtomicCompoundDataPlug );
Expand Down
19 changes: 18 additions & 1 deletion include/GafferBindings/TypedObjectPlugBinding.inl
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,23 @@ typename T::Ptr construct(
return result;
}

template<typename T>
typename T::ValueType::Ptr typedObjectPlugDefaultValue()
{
using ValueType = typename T::ValueType;
if constexpr( std::is_abstract_v<ValueType> )
{
// Can't construct `Object` so can't provide a default value.
/// \todo Really we want to use `is_default_constructible_v` but
/// that fails inexplicably for a bunch of TypedData types.
return nullptr;
}
else
{
return new ValueType;
}
}

} // namespace Detail

template<typename T, typename TWrapper>
Expand All @@ -135,7 +152,7 @@ TypedObjectPlugClass<T, TWrapper>::TypedObjectPlugClass( const char *docString )
(
boost::python::arg_( "name" )=Gaffer::GraphComponent::defaultName<T>(),
boost::python::arg_( "direction" )=Gaffer::Plug::In,
boost::python::arg_( "defaultValue" ),
boost::python::arg_( "defaultValue" )=Detail::typedObjectPlugDefaultValue<T>(),
boost::python::arg_( "flags" )=Gaffer::Plug::Default
)
)
Expand Down
34 changes: 34 additions & 0 deletions python/GafferTest/PlugAlgoTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -927,6 +927,40 @@ def testCanSetPlugFromValueWithType( self ) :
Gaffer.PlugAlgo.setValueFromData( plug, data )
)

def testDataConversionsForAllTypes( self ) :

import GafferScene
import GafferImage

for plugType in Gaffer.ValuePlug.__subclasses__() :

valueType = getattr( plugType, "ValueType", None )
if valueType is None :
continue

if issubclass( valueType, IECore.Data ) :
dataType = valueType
elif valueType is float :
dataType = IECore.FloatData
else :
try :
dataType = IECore.DataTraits.dataTypeFromElementType( valueType )
except TypeError :
continue

with self.subTest( plugType = plugType ) :

plug = plugType()
data = dataType()
self.assertTrue( Gaffer.PlugAlgo.canSetValueFromData( plug, None ) )
self.assertTrue( Gaffer.PlugAlgo.canSetValueFromData( plug, data ) )
self.assertTrue( Gaffer.PlugAlgo.setValueFromData( plug, data ) )
if issubclass( valueType, IECore.Data ) :
self.assertEqual( plug.getValue(), data )
else :
self.assertEqual( plug.getValue(), data.value )
self.assertEqual( Gaffer.PlugAlgo.getValueAsData( plug ), data )

def testDependsOnCompute( self ) :

add = GafferTest.AddNode()
Expand Down
12 changes: 12 additions & 0 deletions python/GafferTest/TypedObjectPlugTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ def testValueType( self ) :
self.assertTrue( Gaffer.M33fVectorDataPlug.ValueType is IECore.M33fVectorData )
self.assertTrue( Gaffer.V2iVectorDataPlug.ValueType is IECore.V2iVectorData )
self.assertTrue( Gaffer.V3iVectorDataPlug.ValueType is IECore.V3iVectorData )
self.assertTrue( Gaffer.Box2fVectorDataPlug.ValueType is IECore.Box2fVectorData )
self.assertTrue( Gaffer.ObjectVectorPlug.ValueType is IECore.ObjectVector )
self.assertTrue( Gaffer.AtomicCompoundDataPlug.ValueType is IECore.CompoundData )

Expand Down Expand Up @@ -364,5 +365,16 @@ def testStringVectorDataPlugWithStringInput( self ) :

self.assertEqual( node["user"]["stringVector"].getValue(), IECore.StringVectorData( output ) )

def testDefaultDefaultValue( self ) :

p = Gaffer.StringVectorDataPlug()
self.assertEqual( p.defaultValue(), IECore.StringVectorData() )

p = Gaffer.M44fVectorDataPlug()
self.assertEqual( p.defaultValue(), IECore.M44fVectorData() )

with self.assertRaisesRegex( ValueError, "Default value must not be None" ) :
Gaffer.ObjectPlug()

if __name__ == "__main__":
unittest.main()
78 changes: 78 additions & 0 deletions src/Gaffer/PlugAlgo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,10 @@ ValuePlugPtr createPlugFromData( const std::string &name, Plug::Direction direct
{
return typedObjectValuePlug( name, direction, flags, static_cast<const M33fVectorData *>( value ) );
}
case Box2fVectorDataTypeId :
{
return typedObjectValuePlug( name, direction, flags, static_cast<const Box2fVectorData *>( value ) );
}
case PathMatcherDataTypeId :
{
PathMatcherDataPlugPtr valuePlug = new PathMatcherDataPlug(
Expand Down Expand Up @@ -505,6 +509,8 @@ IECore::DataPtr getValueAsData( const ValuePlug *plug )
return static_cast<const M44fVectorDataPlug *>( plug )->getValue()->copy();
case M33fVectorDataPlugTypeId :
return static_cast<const M33fVectorDataPlug *>( plug )->getValue()->copy();
case Box2fVectorDataPlugTypeId :
return static_cast<const Box2fVectorDataPlug *>( plug )->getValue()->copy();
case SplineffPlugTypeId :
return new SplineffData( static_cast<const SplineffPlug *>( plug )->getValue().spline() );
case SplinefColor3fPlugTypeId :
Expand All @@ -515,6 +521,14 @@ IECore::DataPtr getValueAsData( const ValuePlug *plug )
return new M44fData( static_cast<const M44fPlug *>( plug )->getValue() );
case M33fPlugTypeId :
return new M33fData( static_cast<const M33fPlug *>( plug )->getValue() );
case AtomicBox2fPlugTypeId :
return new Box2fData( static_cast<const AtomicBox2fPlug *>( plug )->getValue() );
case AtomicBox3fPlugTypeId :
return new Box3fData( static_cast<const AtomicBox3fPlug *>( plug )->getValue() );
case AtomicBox2iPlugTypeId :
return new Box2iData( static_cast<const AtomicBox2iPlug *>( plug )->getValue() );
case AtomicCompoundDataPlugTypeId :
return static_cast<const AtomicCompoundDataPlug *>( plug )->getValue()->copy();
case NameValuePlugTypeId :
case OptionalValuePlugTypeId : {
CompoundDataPtr result = new CompoundData;
Expand Down Expand Up @@ -597,6 +611,18 @@ bool setNumericPlugValue( PlugType *plug, const Data *value )
}
}

template<typename PlugType>
bool setTypedPlugValue( PlugType *plug, const Data *value )
{
using DataType = IECore::TypedData<typename PlugType::ValueType>;
if( auto typedValue = runTimeCast<const DataType>( value ) )
{
plug->setValue( typedValue->readable() );
return true;
}
return false;
}

template<typename PlugType>
bool setTypedDataPlugValue( PlugType *plug, const Data *value )
{
Expand Down Expand Up @@ -753,6 +779,18 @@ bool canSetNumericPlugValue( const Data *value )
}
}

template<typename PlugType>
bool canSetTypedPlugValue( const Data *value )
{
if( !value )
{
return true; // Data type not specified, so it could be a match
}

using DataType = IECore::TypedData<typename PlugType::ValueType>;
return runTimeCast<const DataType>( value );
}

template<typename PlugType>
bool canSetTypedDataPlugValue( const Data *value )
{
Expand Down Expand Up @@ -869,11 +907,31 @@ bool canSetValueFromData( const ValuePlug *plug, const IECore::Data *value )
return canSetTypedDataPlugValue<V2fVectorDataPlug>( value );
case Gaffer::V2iVectorDataPlugTypeId:
return canSetTypedDataPlugValue<V2iVectorDataPlug>( value );
case Gaffer::M33fVectorDataPlugTypeId:
return canSetTypedDataPlugValue<M33fVectorDataPlug>( value );
case Gaffer::M44fVectorDataPlugTypeId:
return canSetTypedDataPlugValue<M44fVectorDataPlug>( value );
case Gaffer::Box2fVectorDataPlugTypeId:
return canSetTypedDataPlugValue<Box2fVectorDataPlug>( value );
case Gaffer::AtomicCompoundDataPlugTypeId:
return canSetTypedDataPlugValue<AtomicCompoundDataPlug>( value );
case Gaffer::PathMatcherDataPlugTypeId:
return canSetTypedDataPlugValue<PathMatcherDataPlug>( value );
case Gaffer::Box3fPlugTypeId:
case Gaffer::Box3iPlugTypeId:
case Gaffer::Box2fPlugTypeId:
case Gaffer::Box2iPlugTypeId:
return canSetBoxPlugValue( value );
case Gaffer::M33fPlugTypeId:
return canSetTypedPlugValue<M33fPlug>( value );
case Gaffer::M44fPlugTypeId:
return canSetTypedPlugValue<M44fPlug>( value );
case Gaffer::AtomicBox2fPlugTypeId:
return canSetTypedPlugValue<AtomicBox2fPlug>( value );
case Gaffer::AtomicBox3fPlugTypeId:
return canSetTypedPlugValue<AtomicBox3fPlug>( value );
case Gaffer::AtomicBox2iPlugTypeId:
return canSetTypedPlugValue<AtomicBox2iPlug>( value );
default:
return false;
}
Expand Down Expand Up @@ -938,6 +996,16 @@ bool setValueFromData( ValuePlug *plug, const IECore::Data *value )
return setTypedDataPlugValue( static_cast<Color3fVectorDataPlug *>( plug ), value );
case Gaffer::Color4fVectorDataPlugTypeId:
return setTypedDataPlugValue( static_cast<Color4fVectorDataPlug *>( plug ), value );
case Gaffer::M33fVectorDataPlugTypeId:
return setTypedDataPlugValue( static_cast<M33fVectorDataPlug *>( plug ), value );
case Gaffer::M44fVectorDataPlugTypeId:
return setTypedDataPlugValue( static_cast<M44fVectorDataPlug *>( plug ), value );
case Gaffer::Box2fVectorDataPlugTypeId:
return setTypedDataPlugValue( static_cast<Box2fVectorDataPlug *>( plug ), value );
case Gaffer::AtomicCompoundDataPlugTypeId:
return setTypedDataPlugValue( static_cast<AtomicCompoundDataPlug *>( plug ), value );
case Gaffer::PathMatcherDataPlugTypeId:
return setTypedDataPlugValue( static_cast<PathMatcherDataPlug *>( plug ), value );
case Gaffer::Box3fPlugTypeId:
return setBoxPlugValue( static_cast<Box3fPlug *>( plug ), value );
case Gaffer::Box3iPlugTypeId:
Expand All @@ -946,6 +1014,16 @@ bool setValueFromData( ValuePlug *plug, const IECore::Data *value )
return setBoxPlugValue( static_cast<Box2fPlug *>( plug ), value );
case Gaffer::Box2iPlugTypeId:
return setBoxPlugValue( static_cast<Box2iPlug *>( plug ), value );
case Gaffer::M33fPlugTypeId:
return setTypedPlugValue( static_cast<M33fPlug *>( plug ), value );
case Gaffer::M44fPlugTypeId:
return setTypedPlugValue( static_cast<M44fPlug *>( plug ), value );
case Gaffer::AtomicBox2fPlugTypeId:
return setTypedPlugValue( static_cast<AtomicBox2fPlug *>( plug ), value );
case Gaffer::AtomicBox3fPlugTypeId:
return setTypedPlugValue( static_cast<AtomicBox3fPlug *>( plug ), value );
case Gaffer::AtomicBox2iPlugTypeId:
return setTypedPlugValue( static_cast<AtomicBox2iPlug *>( plug ), value );
default:
return false;
}
Expand Down
2 changes: 2 additions & 0 deletions src/Gaffer/TypedObjectPlug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ GAFFER_PLUG_DEFINE_TEMPLATE_TYPE( Gaffer::Color3fVectorDataPlug, Color3fVectorDa
GAFFER_PLUG_DEFINE_TEMPLATE_TYPE( Gaffer::Color4fVectorDataPlug, Color4fVectorDataPlugTypeId )
GAFFER_PLUG_DEFINE_TEMPLATE_TYPE( Gaffer::M44fVectorDataPlug, M44fVectorDataPlugTypeId )
GAFFER_PLUG_DEFINE_TEMPLATE_TYPE( Gaffer::M33fVectorDataPlug, M33fVectorDataPlugTypeId )
GAFFER_PLUG_DEFINE_TEMPLATE_TYPE( Gaffer::Box2fVectorDataPlug, Box2fVectorDataPlugTypeId )
GAFFER_PLUG_DEFINE_TEMPLATE_TYPE( Gaffer::ObjectVectorPlug, ObjectVectorPlugTypeId )
GAFFER_PLUG_DEFINE_TEMPLATE_TYPE( Gaffer::CompoundObjectPlug, CompoundObjectPlugTypeId )
GAFFER_PLUG_DEFINE_TEMPLATE_TYPE( Gaffer::AtomicCompoundDataPlug, AtomicCompoundDataPlugTypeId )
Expand Down Expand Up @@ -163,6 +164,7 @@ template class TypedObjectPlug<IECore::Color3fVectorData>;
template class TypedObjectPlug<IECore::Color4fVectorData>;
template class TypedObjectPlug<IECore::M44fVectorData>;
template class TypedObjectPlug<IECore::M33fVectorData>;
template class TypedObjectPlug<IECore::Box2fVectorData>;
template class TypedObjectPlug<IECore::ObjectVector>;
template class TypedObjectPlug<IECore::CompoundObject>;
template class TypedObjectPlug<IECore::CompoundData>;
Expand Down
1 change: 1 addition & 0 deletions src/GafferModule/TypedObjectPlugBinding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ void GafferModule::bindTypedObjectPlug()
GafferBindings::TypedObjectPlugClass<Gaffer::Color4fVectorDataPlug>();
GafferBindings::TypedObjectPlugClass<Gaffer::M44fVectorDataPlug>();
GafferBindings::TypedObjectPlugClass<Gaffer::M33fVectorDataPlug>();
GafferBindings::TypedObjectPlugClass<Gaffer::Box2fVectorDataPlug>();
GafferBindings::TypedObjectPlugClass<Gaffer::ObjectVectorPlug>();
GafferBindings::TypedObjectPlugClass<Gaffer::CompoundObjectPlug>();
GafferBindings::TypedObjectPlugClass<Gaffer::AtomicCompoundDataPlug>();
Expand Down

0 comments on commit 39a7839

Please sign in to comment.