diff --git a/include/IECore/CompoundParameter.h b/include/IECore/CompoundParameter.h index a7956e661e..793aa157e1 100644 --- a/include/IECore/CompoundParameter.h +++ b/include/IECore/CompoundParameter.h @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////// // -// Copyright (c) 2007-2012, Image Engine Design Inc. All rights reserved. +// Copyright (c) 2007-2013, Image Engine Design Inc. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are @@ -71,11 +71,17 @@ class CompoundParameter : public Parameter /// of all the child objects. /// \threading It is not safe to call this from multiple concurrent threads. virtual const Object *defaultValue() const; + /// \deprecated Use getPresets instead. + virtual const PresetsContainer &presets() const; /// If true was passed to adoptChildPresets at construction, then update the presets /// with the intersection of the presets of all the child parameters, otherwise returns - /// an empty container. Please note that the map returned may differ between one call + /// an empty container or the presets defined by setPresets(). + /// Please note that the map returned may differ between one call /// to presets() and the next. - virtual const PresetsContainer &presets() const; + virtual const PresetsContainer &getPresets() const; + /// Defines presets for this Parameter. + /// Throws an exception if true was passed to adoptChildPresets at construction. + virtual void setPresets( const PresetsContainer &presets ); /// Implemented to return true only if all children have presetsOnly() true and /// true was passed to adoptChildPresets at construction. virtual bool presetsOnly() const; diff --git a/include/IECore/Parameter.h b/include/IECore/Parameter.h index 8ca9ba656c..63e5e964f5 100644 --- a/include/IECore/Parameter.h +++ b/include/IECore/Parameter.h @@ -78,8 +78,12 @@ class Parameter : public RunTimeTyped const std::string &description() const; /// Returns the default value for this parameter. virtual const Object *defaultValue() const; - /// Returns the presets for this parameter. + /// \deprecated Use getPresets instead. virtual const PresetsContainer &presets() const; + /// Returns the presets for this parameter. + virtual const PresetsContainer &getPresets() const; + /// Overrides the presets for this parameter. + virtual void setPresets( const PresetsContainer &presets ); /// Returns true if this parameter only accepts /// parameters present as presets. virtual bool presetsOnly() const; diff --git a/src/IECore/CompoundParameter.cpp b/src/IECore/CompoundParameter.cpp index f8de7ca07b..d1c4785088 100644 --- a/src/IECore/CompoundParameter.cpp +++ b/src/IECore/CompoundParameter.cpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////// // -// Copyright (c) 2007-2012, Image Engine Design Inc. All rights reserved. +// Copyright (c) 2007-2013, Image Engine Design Inc. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are @@ -73,14 +73,19 @@ const Object *CompoundParameter::defaultValue() const } const Parameter::PresetsContainer &CompoundParameter::presets() const +{ + return getPresets(); +} + +const Parameter::PresetsContainer &CompoundParameter::getPresets() const { if( !m_adoptChildPresets ) { - return Parameter::presets(); + return Parameter::getPresets(); } // naughty? nah! it gives the right semantics to an outside observer - PresetsContainer &pr = const_cast( Parameter::presets() ); + PresetsContainer &pr = const_cast( Parameter::getPresets() ); pr.clear(); if( !m_namesToParameters.size() ) { @@ -88,12 +93,12 @@ const Parameter::PresetsContainer &CompoundParameter::presets() const } // get a references for each child preset map. - // we only want to call presets() once for + // we only want to call getPresets() once for // each child as the map returned may change between calls. vector childPresets; for( size_t i=0; ipresets()) ); + childPresets.push_back( &(m_parameters[i]->getPresets()) ); } // find the intersection of all the child preset names @@ -146,6 +151,15 @@ const Parameter::PresetsContainer &CompoundParameter::presets() const return pr; } +void CompoundParameter::setPresets( const PresetsContainer &presets ) +{ + if (m_adoptChildPresets) + { + throw Exception( "CompoundParameter cannot override presets when initialized with adoptChildPresets to true."); + } + Parameter::setPresets(presets); +} + bool CompoundParameter::presetsOnly() const { if( !m_adoptChildPresets || !m_parameters.size() ) diff --git a/src/IECore/Parameter.cpp b/src/IECore/Parameter.cpp index 88084c0827..aaa19ab3d7 100644 --- a/src/IECore/Parameter.cpp +++ b/src/IECore/Parameter.cpp @@ -92,10 +92,20 @@ const Object *Parameter::defaultValue() const } const Parameter::PresetsContainer &Parameter::presets() const +{ + return getPresets(); +} + +const Parameter::PresetsContainer &Parameter::getPresets() const { return m_presets; } +void Parameter::setPresets( const PresetsContainer &presets ) +{ + m_presets = presets; +} + bool Parameter::presetsOnly() const { return m_presetsOnly; @@ -145,7 +155,7 @@ bool Parameter::valueValid( const Object *value, std::string *reason ) const { return true; } - const PresetsContainer &pr = presets(); + const PresetsContainer &pr = getPresets(); for( PresetsContainer::const_iterator it = pr.begin(); it!=pr.end(); it++ ) { if( it->second->isEqualTo( value ) ) @@ -201,7 +211,7 @@ void Parameter::setValidatedValue( ObjectPtr value ) void Parameter::setValue( const std::string &presetName ) { - const PresetsContainer &pr = presets(); + const PresetsContainer &pr = getPresets(); PresetsContainer::const_iterator it; for( it=pr.begin(); it != pr.end(); it++ ) @@ -251,7 +261,7 @@ std::string Parameter::getCurrentPresetName() const // didn't have to do a copy of the value. but that breaks with CompoundParameter // as it builds the value dynamically in getValue(). const Object *currentValue = getValue(); - const PresetsContainer &pr = presets(); + const PresetsContainer &pr = getPresets(); PresetsContainer::const_iterator it; for( it=pr.begin(); it!=pr.end(); it++ ) { diff --git a/src/IECoreMaya/FromMayaMeshConverter.cpp b/src/IECoreMaya/FromMayaMeshConverter.cpp index 0f75f868f6..2191083b4d 100644 --- a/src/IECoreMaya/FromMayaMeshConverter.cpp +++ b/src/IECoreMaya/FromMayaMeshConverter.cpp @@ -601,10 +601,10 @@ IECore::PrimitivePtr FromMayaMeshConverter::doPrimitiveConversion( MFnMesh &fnMe unsigned int interpolationIndex = interpolationPlug.asInt(MDGContext::fsNormal, &st); if ( st ) { - if ( interpolationIndex < m_interpolation->presets().size() - 1 ) + if ( interpolationIndex < m_interpolation->getPresets().size() - 1 ) { // convert interpolation index to the preset value - interpolation = staticPointerCast< StringData >( m_interpolation->presets()[interpolationIndex].second )->readable(); + interpolation = staticPointerCast< StringData >( m_interpolation->getPresets()[interpolationIndex].second )->readable(); } else { diff --git a/src/IECoreMaya/ToMayaMeshConverter.cpp b/src/IECoreMaya/ToMayaMeshConverter.cpp index e61f121af7..4623d05ea1 100644 --- a/src/IECoreMaya/ToMayaMeshConverter.cpp +++ b/src/IECoreMaya/ToMayaMeshConverter.cpp @@ -495,7 +495,7 @@ bool ToMayaMeshConverter::setMeshInterpolationAttribute( MObject &object, std::s int interpolationValue = 0; FromMayaMeshConverter fromMaya(object); - const IECore::Parameter::PresetsContainer &presets = fromMaya.interpolationParameter()->presets(); + const IECore::Parameter::PresetsContainer &presets = fromMaya.interpolationParameter()->getPresets(); IECore::Parameter::PresetsContainer::const_iterator it; if ( interpolation != "default" ) diff --git a/src/IECoreNuke/PresetsOnlyParameterHandler.cpp b/src/IECoreNuke/PresetsOnlyParameterHandler.cpp index 0d2f34dcaa..4e26c1575e 100644 --- a/src/IECoreNuke/PresetsOnlyParameterHandler.cpp +++ b/src/IECoreNuke/PresetsOnlyParameterHandler.cpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////// // -// Copyright (c) 2010-2011, Image Engine Design Inc. All rights reserved. +// Copyright (c) 2010-2013, Image Engine Design Inc. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are @@ -49,7 +49,8 @@ void PresetsOnlyParameterHandler::knobs( const IECore::Parameter *parameter, con if( f.makeKnobs() ) { m_names.clear(); - for( Parameter::PresetsContainer::const_iterator it = parameter->presets().begin(); it!=parameter->presets().end(); it++ ) + const Parameter::PresetsContainer &presets = parameter->getPresets(); + for( Parameter::PresetsContainer::const_iterator it = presets.begin(); it!=presets.end(); it++ ) { if( it->second->isEqualTo( parameter->defaultValue() ) ) { @@ -79,12 +80,12 @@ void PresetsOnlyParameterHandler::setParameterValue( IECore::Parameter *paramete { presetIndex = (int)m_knob->get_value(); } - parameter->setValue( parameter->presets()[m_storage].second ); + parameter->setValue( parameter->getPresets()[m_storage].second ); } void PresetsOnlyParameterHandler::setKnobValue( const IECore::Parameter *parameter ) { - const Parameter::PresetsContainer &presets = parameter->presets(); + const Parameter::PresetsContainer &presets = parameter->getPresets(); std::string currentPresetName = parameter->getCurrentPresetName(); size_t presetIndex = 0; for( Parameter::PresetsContainer::const_iterator it = presets.begin(); it!=presets.end(); it++, presetIndex++ ) diff --git a/src/IECorePython/ParameterBinding.cpp b/src/IECorePython/ParameterBinding.cpp index ab12b75476..4b25c4eb85 100644 --- a/src/IECorePython/ParameterBinding.cpp +++ b/src/IECorePython/ParameterBinding.cpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////// // -// Copyright (c) 2007-2010, Image Engine Design Inc. All rights reserved. +// Copyright (c) 2007-2013, Image Engine Design Inc. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are @@ -75,10 +75,10 @@ static void validate( Parameter &that, ObjectPtr value ) that.validate( value.get() ); } -static dict presets( Parameter &that ) +static dict getPresets( Parameter &that ) { dict result; - const Parameter::PresetsContainer &p = that.presets(); + const Parameter::PresetsContainer &p = that.getPresets(); for( Parameter::PresetsContainer::const_iterator it=p.begin(); it!=p.end(); it++ ) { result[it->first] = it->second->copy(); @@ -86,10 +86,15 @@ static dict presets( Parameter &that ) return result; } +static void setPresets( Parameter &p, const object &presets ) +{ + p.setPresets( parameterPresets( presets ) ); +} + static boost::python::tuple presetNames( const Parameter &that ) { boost::python::list result; - const Parameter::PresetsContainer &p = that.presets(); + const Parameter::PresetsContainer &p = that.getPresets(); for( Parameter::PresetsContainer::const_iterator it=p.begin(); it!=p.end(); it++ ) { result.append( it->first ); @@ -100,7 +105,7 @@ static boost::python::tuple presetNames( const Parameter &that ) static boost::python::tuple presetValues( const Parameter &that ) { boost::python::list result; - const Parameter::PresetsContainer &p = that.presets(); + const Parameter::PresetsContainer &p = that.getPresets(); for( Parameter::PresetsContainer::const_iterator it=p.begin(); it!=p.end(); it++ ) { result.append( it->second->copy() ); @@ -161,7 +166,9 @@ void bindParameter() .def( "validate", (void (Parameter::*)() const)&Parameter::validate ) .def( "validate", &validate ) .add_property( "presetsOnly", &Parameter::presetsOnly ) - .def( "presets", &presets, "Returns a dictionary containing presets for the parameter." ) + .def( "presets", &getPresets, "Deprecated function. Use getPresets() instead." ) + .def( "getPresets", &getPresets, "Returns a dictionary containing presets for the parameter." ) + .def( "setPresets", &setPresets, "Sets the presets for the parameter from a dictionary." ) .def( "presetNames", &presetNames, "Returns a tuple containing the names of all presets for the parameter." ) .def( "presetValues", &presetValues, "Returns a tuple containing the values of all presets for the parameter." ) .def( "userData", &userData ) diff --git a/test/IECore/CompoundParameterTest.py b/test/IECore/CompoundParameterTest.py index 50feab9df7..03135919bf 100644 --- a/test/IECore/CompoundParameterTest.py +++ b/test/IECore/CompoundParameterTest.py @@ -179,7 +179,7 @@ def testPresets( self ) : self.assertEqual( p.presetsOnly, True ) - pr = p.presets() + pr = p.getPresets() self.assertEqual( len( pr ), 3 ) self.assert_( "one" in pr.keys() ) self.assert_( "two" in pr.keys() ) @@ -191,6 +191,7 @@ def testPresets( self ) : p.setValue( "four" ) self.assertEqual( p.getCurrentPresetName(), "four" ) + self.assertRaises( RuntimeError, p.setPresets, [] ) # CompoundParameter created with adoptChildPresets=True does not allow overriding presets p = CompoundParameter( name = "c", @@ -220,7 +221,7 @@ def testPresets( self ) : ) self.assertEqual( p.presetsOnly, False ) - self.assertEqual( len( p.presets() ), 0 ) + self.assertEqual( len( p.getPresets() ), 0 ) def testLateValidation( self ) : @@ -346,18 +347,18 @@ def testAddParametersPresets( self ) : members = [] ) - self.assertEqual( p.presets(), {} ) + self.assertEqual( p.getPresets(), {} ) p.addParameter( IntParameter( name = "i", description = "d", defaultValue = 10, presets = ( ( "one", 1 ), ( "two", 2 ) ) ) ) - self.assertEqual( len( p.presets() ), 2 ) - self.assertEqual( p.presets(), { "one" : CompoundObject( { "i" : IntData( 1 ) } ), "two" : CompoundObject( { "i" : IntData( 2 ) } ) } ) + self.assertEqual( len( p.getPresets() ), 2 ) + self.assertEqual( p.getPresets(), { "one" : CompoundObject( { "i" : IntData( 1 ) } ), "two" : CompoundObject( { "i" : IntData( 2 ) } ) } ) fParam = FloatParameter( name = "f", description = "d", defaultValue = 20, presets = ( ( "one", 1 ), ) ) p.addParameter( fParam ) - self.assertEqual( len( p.presets() ), 1 ) - self.assertEqual( p.presets(), { "one" : CompoundObject( { "i" : IntData( 1 ), "f" : FloatData( 1 ) } ) } ) + self.assertEqual( len( p.getPresets() ), 1 ) + self.assertEqual( p.getPresets(), { "one" : CompoundObject( { "i" : IntData( 1 ), "f" : FloatData( 1 ) } ) } ) p.insertParameter( IntParameter( name = "x", description = "x", defaultValue = 10 ), fParam ) self.assertEqual( p.keys(), [ "i", "x", "f" ] ) @@ -586,7 +587,7 @@ def testAdoptChildPresets( self ) : ], ) - self.assertEqual( len( c.presets() ), 2 ) + self.assertEqual( len( c.getPresets() ), 2 ) self.assertEqual( c.presetsOnly, True ) # no adoption of presets @@ -618,7 +619,7 @@ def testAdoptChildPresets( self ) : adoptChildPresets = False, ) - self.assertEqual( len( c.presets() ), 0 ) + self.assertEqual( len( c.getPresets() ), 0 ) self.assertEqual( c.presetsOnly, False ) # no adoption of presets without use of keyword parameters @@ -652,10 +653,35 @@ def testAdoptChildPresets( self ) : False, ) - self.assertEqual( len( c.presets() ), 0 ) + self.assertEqual( len( c.getPresets() ), 0 ) self.assertEqual( c.presetsOnly, False ) self.assertEqual( c.userData()["ud"].value, 10 ) + # when adoptChildPresets we can also set presets explicitly... + c['a'].setValue("one") + c['b'].setValue("two") + p1 = c.getValue().copy() + c['a'].setValue("two") + c['b'].setValue("one") + p2 = c.getValue().copy() + c.setValue( c.defaultValue ) + + c.setPresets( + [ + ( "p1", p1 ), + ( "p2", p2 ), + ] + ) + pr = c.getPresets() + self.assertEqual( len( pr ), 2 ) + self.assertEqual( pr["p1"], p1 ) + self.assertEqual( pr["p2"], p2 ) + self.assertEqual( c.presetNames(), ( "p1", "p2" ) ) + c.setValue("p1") + self.assertEqual( c.getValue(), p1 ) + c.setValue("p2") + self.assertEqual( c.getValue(), p2 ) + def testDerivingInPython( self ) : class DerivedCompoundParameter( CompoundParameter ) : diff --git a/test/IECore/EXRImageWriter.py b/test/IECore/EXRImageWriter.py index 37d4884d28..94a5f1618e 100644 --- a/test/IECore/EXRImageWriter.py +++ b/test/IECore/EXRImageWriter.py @@ -223,11 +223,11 @@ def testCompressionParameter( self ): img = r.read() w = Writer.create( img, "test/IECore/data/exrFiles/output.exr" ) - w['compression'].setValue( w['compression'].presets()['zip'] ) + w['compression'].setValue( w['compression'].getPresets()['zip'] ) w.write() w = EXRImageWriter() - w['compression'].setValue( w['compression'].presets()['zip'] ) + w['compression'].setValue( w['compression'].getPresets()['zip'] ) def testBlindDataToHeader( self ) : diff --git a/test/IECore/Parameters.py b/test/IECore/Parameters.py index 5a154b9c51..0b7a5bc8c5 100644 --- a/test/IECore/Parameters.py +++ b/test/IECore/Parameters.py @@ -98,7 +98,7 @@ def testPresets( self ) : presetsOnly = True, ) - pr = p.presets() + pr = p.getPresets() self.assertEqual( len( pr ), 4 ) self.assertEqual( pr["p1"], FloatData( 40 ) ) self.assertEqual( pr["p2"], IntData( 60 ) ) @@ -127,13 +127,32 @@ def testPresets( self ) : presetsOnly = True, ) - pr = p.presets() + pr = p.getPresets() self.assertEqual( len( pr ), 4 ) self.assertEqual( pr["p1"], FloatData( 40 ) ) self.assertEqual( pr["p2"], IntData( 60 ) ) self.assertEqual( pr["p3"], CompoundData() ) self.assertEqual( pr["p4"], FloatData( 20 ) ) + # overriding presets + + p.setPresets( [] ) + self.assertEqual( p.getPresets(), dict() ) + + p.setPresets( + [ + ( "p5", FloatData( 40 ) ), + ( "p1", IntData( 60 ) ), + ] + ) + pr = p.getPresets() + self.assertEqual( len( pr ), 2 ) + self.assertEqual( pr["p5"], FloatData( 40 ) ) + self.assertEqual( pr["p1"], IntData( 60 ) ) + self.assertEqual( p.presetNames(), ("p5", "p1") ) + p.setValue("p1") + self.assertEqual( p.getValue(), IntData(60) ) + def testOrderedPresets( self ) : p = Parameter( @@ -296,12 +315,27 @@ def testPresets( self ) : ) ) - pr = p.presets() + pr = p.getPresets() self.assertEqual( len( pr ), 3 ) self.assertEqual( pr["one"], IntData( 1 ) ) self.assertEqual( pr["two"], IntData( 2 ) ) self.assertEqual( pr["three"], IntData( 3 ) ) + # overriding presets + p.setPresets( + [ + ( "four", IntData( 4 ) ), + ( "one", IntData( 1 ) ), + ] + ) + pr = p.getPresets() + self.assertEqual( len( pr ), 2 ) + self.assertEqual( pr["four"], IntData( 4 ) ) + self.assertEqual( pr["one"], IntData( 1 ) ) + self.assertEqual( p.presetNames(), ("four", "one") ) + p.setValue("four") + self.assertEqual( p.getValue(), IntData(4) ) + def testOrderedPresets( self ) : p = IntParameter( @@ -387,7 +421,7 @@ def testPresets( self ) : presetsOnly = True, ) - pr = p.presets() + pr = p.getPresets() self.assertEqual( len( pr ), 3 ) self.assertEqual( pr["one"], V3fData( V3f( 1 ) ) ) self.assertEqual( pr["two"], V3fData( V3f( 2 ) ) ) @@ -396,6 +430,21 @@ def testPresets( self ) : p.setValue( "one" ) self.assertEqual( p.getValue(), V3fData( V3f( 1 ) ) ) + # overriding presets + p.setPresets( + [ + ( "four", V3fData( V3f(4) ) ), + ( "one", V3fData( V3f(1) ) ), + ] + ) + pr = p.getPresets() + self.assertEqual( len( pr ), 2 ) + self.assertEqual( pr["four"], V3fData( V3f(4) ) ) + self.assertEqual( pr["one"], V3fData( V3f(1) ) ) + self.assertEqual( p.presetNames(), ("four", "one") ) + p.setValue("four") + self.assertEqual( p.getValue(), V3fData(V3f(4)) ) + def testPresetsOnly( self ) : p = V3fParameter( @@ -536,7 +585,7 @@ def test( self ) : p.setValue( StringData( "100" ) ) self.assertEqual( p.getValue(), StringData( "100" ) ) - pr = p.presets() + pr = p.getPresets() self.assertEqual( len( pr ), 2 ) self.assert_( "100" in pr.keys() ) self.assert_( "200" in pr.keys() ) @@ -775,6 +824,20 @@ def testOrderedPresets( self ) : self.assertEqual( p.presetNames(), ( "p1", "p2", "p3", "p4" ) ) self.assertEqual( p.presetValues(), ( FloatData( 40 ), IntData( 60 ), CompoundData(), FloatData( 20 ) ) ) + # overriding presets + p.setPresets( + [ + ( "four", V3fData( V3f(4) ) ), + ( "one", V3fData( V3f(1) ) ), + ] + ) + pr = p.getPresets() + self.assertEqual( len( pr ), 2 ) + self.assertEqual( pr["four"], V3fData( V3f(4) ) ) + self.assertEqual( pr["one"], V3fData( V3f(1) ) ) + self.assertEqual( p.presetNames(), ("four", "one") ) + p.setValue("four") + self.assertEqual( p.getValue(), V3fData(V3f(4)) ) class TestTypedObjectParameter( unittest.TestCase ) : @@ -818,7 +881,7 @@ def testPresets( self ) : presetsOnly = True, ) - pr = p.presets() + pr = p.getPresets() self.assertEqual( len( pr ), 3 ) self.assertEqual( pr["one"], mesh1 ) self.assertEqual( pr["two"], mesh2 )