From b799b57eed088406ae2be82d34f3d342a87fbd1c Mon Sep 17 00:00:00 2001 From: Daniel Dresser Date: Thu, 21 Nov 2024 17:28:29 -0800 Subject: [PATCH] TweakPlug : Experimental refactor --- include/Gaffer/TweakPlug.h | 9 ++++ include/Gaffer/TweakPlug.inl | 93 ++++++++++++++++++++++++++++++++++++ src/Gaffer/TweakPlug.cpp | 88 ++-------------------------------- 3 files changed, 107 insertions(+), 83 deletions(-) diff --git a/include/Gaffer/TweakPlug.h b/include/Gaffer/TweakPlug.h index ab67d21cb5..1c949f3be2 100644 --- a/include/Gaffer/TweakPlug.h +++ b/include/Gaffer/TweakPlug.h @@ -123,6 +123,15 @@ class GAFFER_API TweakPlug : public Gaffer::ValuePlug MissingMode missingMode = MissingMode::Error ) const; + template< typename T > + static void applyNumericTweakValue( + const T &source, + const T &tweak, + T &dest, + TweakPlug::Mode mode, + const std::string &tweakName + ); + private : Gaffer::ValuePlug *valuePlugInternal(); diff --git a/include/Gaffer/TweakPlug.inl b/include/Gaffer/TweakPlug.inl index 57a195f603..cd71526a3c 100644 --- a/include/Gaffer/TweakPlug.inl +++ b/include/Gaffer/TweakPlug.inl @@ -38,6 +38,8 @@ #include "Gaffer/PlugAlgo.h" +#include "IECore/TypeTraits.h" + #include "fmt/format.h" namespace Gaffer @@ -179,4 +181,95 @@ bool TweaksPlug::applyTweaks( return tweakApplied; } +template +T vectorAwareMin( const T &v1, const T &v2 ) +{ + if constexpr( IECore::TypeTraits::IsVec::value || IECore::TypeTraits::IsColor::value ) + { + T result; + for( size_t i = 0; i < T::dimensions(); ++i ) + { + result[i] = std::min( v1[i], v2[i] ); + } + return result; + } + else + { + return std::min( v1, v2 ); + } +} + +template +T vectorAwareMax( const T &v1, const T &v2 ) +{ + if constexpr( IECore::TypeTraits::IsVec::value || IECore::TypeTraits::IsColor::value ) + { + T result; + for( size_t i = 0; i < T::dimensions(); ++i ) + { + result[i] = std::max( v1[i], v2[i] ); + } + return result; + } + else + { + return std::max( v1, v2 ); + } +} + +template< typename T > +void TweakPlug::applyNumericTweakValue( + const T &source, + const T &tweak, + T &dest, + TweakPlug::Mode mode, + const std::string &tweakName +) +{ + if constexpr( + ( std::is_arithmetic_v && !std::is_same_v< T, bool > ) || + IECore::TypeTraits::IsVec::value || + IECore::TypeTraits::IsColor::value + ) { + switch( mode ) + { + case TweakPlug::Add : + dest = source + tweak; + break; + case TweakPlug::Subtract : + dest = source - tweak; + break; + case TweakPlug::Multiply : + dest = source * tweak; + break; + case TweakPlug::Min : + dest = vectorAwareMin( source, tweak ); + break; + case TweakPlug::Max : + dest = vectorAwareMax( source, tweak ); + break; + case TweakPlug::ListAppend : + case TweakPlug::ListPrepend : + case TweakPlug::ListRemove : + case TweakPlug::Replace : + case TweakPlug::Remove : + case TweakPlug::Create : + case TweakPlug::CreateIfMissing : + // These cases are unused - we handle them outside of numericTweak. + // But the compiler gets unhappy if we don't handle some cases. + assert( false ); + break; + } + } + else + { + throw IECore::Exception( + fmt::format( + "Cannot apply tweak with mode {} to \"{}\" : Data type {} not supported.", + modeToString( mode ), tweakName, "foo" //sourceData->typeName() + ) + ); + } +} + } // namespace Gaffer diff --git a/src/Gaffer/TweakPlug.cpp b/src/Gaffer/TweakPlug.cpp index 7a1fb169f3..e9fd5c81ae 100644 --- a/src/Gaffer/TweakPlug.cpp +++ b/src/Gaffer/TweakPlug.cpp @@ -63,50 +63,6 @@ using namespace Gaffer; namespace { -/// \todo - if these make sense, I guess they should be pushed back to cortex - -// IsColorTypedData -template< typename T > struct IsColorTypedData : boost::mpl::and_< TypeTraits::IsTypedData, TypeTraits::IsColor< typename TypeTraits::ValueType::type > > {}; - -// SupportsArithmeticData -template< typename T > struct SupportsArithData : boost::mpl::or_< TypeTraits::IsNumericSimpleTypedData, TypeTraits::IsVecTypedData, IsColorTypedData> {}; - -template -T vectorAwareMin( const T &v1, const T &v2 ) -{ - if constexpr( TypeTraits::IsVec::value || TypeTraits::IsColor::value ) - { - T result; - for( size_t i = 0; i < T::dimensions(); ++i ) - { - result[i] = std::min( v1[i], v2[i] ); - } - return result; - } - else - { - return std::min( v1, v2 ); - } -} - -template -T vectorAwareMax( const T &v1, const T &v2 ) -{ - if constexpr( TypeTraits::IsVec::value || TypeTraits::IsColor::value ) - { - T result; - for( size_t i = 0; i < T::dimensions(); ++i ) - { - result[i] = std::max( v1[i], v2[i] ); - } - return result; - } - else - { - return std::max( v1, v2 ); - } -} - template vector tweakedList( const std::vector &source, const std::vector &tweak, TweakPlug::Mode mode ) { @@ -317,48 +273,14 @@ void TweakPlug::applyNumericTweak( using DataType = typename std::remove_pointer::type; - if constexpr( SupportsArithData::value ) { - + if constexpr( TypeTraits::IsTypedData< DataType >::value ) + { const DataType *sourceDataCast = runTimeCast( sourceData ); const DataType *tweakDataCast = runTimeCast( tweakData ); - switch( mode ) - { - case TweakPlug::Add : - data->writable() = sourceDataCast->readable() + tweakDataCast->readable(); - break; - case TweakPlug::Subtract : - data->writable() = sourceDataCast->readable() - tweakDataCast->readable(); - break; - case TweakPlug::Multiply : - data->writable() = sourceDataCast->readable() * tweakDataCast->readable(); - break; - case TweakPlug::Min : - data->writable() = vectorAwareMin( sourceDataCast->readable(), tweakDataCast->readable() ); - break; - case TweakPlug::Max : - data->writable() = vectorAwareMax( sourceDataCast->readable(), tweakDataCast->readable() ); - break; - case TweakPlug::ListAppend : - case TweakPlug::ListPrepend : - case TweakPlug::ListRemove : - case TweakPlug::Replace : - case TweakPlug::Remove : - case TweakPlug::Create : - case TweakPlug::CreateIfMissing : - // These cases are unused - we handle them outside of numericTweak. - // But the compiler gets unhappy if we don't handle some cases. - assert( false ); - break; - } - } - else - { - throw IECore::Exception( - fmt::format( - "Cannot apply tweak with mode {} to \"{}\" : Data type {} not supported.", - modeToString( mode ), tweakName, sourceData->typeName() - ) + applyNumericTweakValue( + sourceDataCast->readable(), tweakDataCast->readable(), data->writable(), + mode, tweakName ); } }