void ParameterHandler::setKnobProperties( const IECore::Parameter *parameter, DD::Image::Knob_Callback f, DD::Image::Knob *knob ) const { const CompoundObject *userData = parameter->userData(); const CompoundObject *ui = userData->member<CompoundObject>( "UI" ); int flags = 0; if( ui ) { const BoolData *visible = ui->member<BoolData>( "visible" ); if( visible && !visible->readable() ) { flags |= Knob::INVISIBLE; } } SetFlags( f, flags ); Tooltip( f, parameter->description() ); if( f.makeKnobs() ) { const CompoundObject *nuke = userData->member<CompoundObject>( "nuke" ); if( nuke ) { const StringData *defaultExpression = nuke->member<StringData>( "defaultExpression" ); if( defaultExpression ) { if( knob->from_script( defaultExpression->readable().c_str() ) ) { knob->changed(); } } } } }
void VecParameterHandler<T>::knobs( const IECore::Parameter *parameter, const char *knobName, DD::Image::Knob_Callback f ) { const T *vecParameter = static_cast<const T *>( parameter ); if( f.makeKnobs() ) { typename T::ValueType defaultValue = vecParameter->typedDefaultValue(); for( unsigned i=0; i<T::ValueType::dimensions(); i++ ) { m_storage[i] = defaultValue[i]; } } std::string label = knobLabel( parameter ); if( T::ValueType::dimensions()==2 ) { m_knob = XY_knob( f, m_storage, knobName, label.c_str() ); SetFlags( f, DD::Image::Knob::NO_PROXYSCALE | DD::Image::Knob::NO_HANDLES ); } else { assert( T::ValueType::dimensions()==3 ); m_knob = XYZ_knob( f, m_storage, knobName, label.c_str() ); } setKnobProperties( parameter, f, m_knob ); }
void Color3fParameterHandler::knobs( const IECore::Parameter *parameter, const char *knobName, DD::Image::Knob_Callback f ) { const Color3fParameter *color3fParameter = static_cast<const Color3fParameter *>( parameter ); if( f.makeKnobs() ) { m_storage = color3fParameter->typedDefaultValue(); } std::string label = knobLabel( parameter ); m_knob = Color_knob( f, &m_storage.x, knobName, label.c_str() ); setKnobProperties( parameter, f, m_knob ); }
void StringParameterHandler::knobs( const IECore::Parameter *parameter, const char *knobName, DD::Image::Knob_Callback f ) { if( f.makeKnobs() ) { m_storage = static_cast<const StringParameter *>( parameter )->typedDefaultValue().c_str(); } m_knob = knob( parameter, knobName, f, &m_storage ); /// we have a lot of procedurals which do their own variable expansion using a SubstitutedDict, /// and the variables in the strings confuse nuke no end, so we're disabling expressions for now. /// \todo Can we do better and allow the two to coexist? SetFlags( f, DD::Image::Knob::NO_ANIMATION ); setKnobProperties( parameter, f, m_knob ); }
void FloatParameterHandler::knobs( const IECore::Parameter *parameter, const char *knobName, DD::Image::Knob_Callback f ) { const FloatParameter *floatParameter = static_cast<const FloatParameter *>( parameter ); if( f.makeKnobs() ) { m_storage = floatParameter->numericDefaultValue(); } std::string label = knobLabel( parameter ); DD::Image::IRange range( floatParameter->minValue(), floatParameter->maxValue() ); m_knob = Float_knob( f, &m_storage, range, knobName, label.c_str() ); DD::Image::SetFlags( f, DD::Image::Knob::FORCE_RANGE ); if( !(floatParameter->hasMinValue() && floatParameter->hasMaxValue()) ) { DD::Image::ClearFlags( f, DD::Image::Knob::SLIDER ); } setKnobProperties( parameter, f, m_knob ); }
void ClassParameterHandler::classChooserKnob( const IECore::Parameter *parameter, const char *knobName, DD::Image::Knob_Callback f ) { std::string classChooserName = string( knobName ) + "__classChooser"; static const char *emptyMenu[] = { " ", "", 0 }; DD::Image::Knob *classChooser = PyPulldown_knob( f, emptyMenu, classChooserName.c_str(), "No class loaded" ); if( !f.makeKnobs() ) { // making the menu is slow, and only needs doing when we're making knobs (not storing for instance), // so early out now to avoid massive slowdown. return; } vector<string> menuItems; menuItems.push_back( " " ); menuItems.push_back( "" ); std::string label = "No class loaded"; IECorePython::ScopedGILLock gilLock; try { // get current class name, and set label from it boost::python::object pythonParameter( ParameterPtr( const_cast<Parameter *>( parameter ) ) ); boost::python::tuple classInfo = extract<boost::python::tuple>( pythonParameter.attr( "getClass" )( true ) ); std::string className = extract<const char *>( classInfo[1] )(); if( className != "" ) { int classVersion = extract<int>( classInfo[2] )(); label = className + " v" + lexical_cast<string>( classVersion ); } // if there is a current class, then add a menu item // to allow it to be removed. std::string parameterPath = knobName + 5; // naughty! we're not meant to know the knob name format replace_all( parameterPath, "_", "']['" ); boost::format setClassFormat( "with IECoreNuke.FnParameterisedHolder( nuke.thisNode() ).parameterModificationContext() as parameters :" " parameters['%s'].setClass( '%s', %d )" ); if( className!="" ) { menuItems.push_back( "Remove" ); menuItems.push_back( ( setClassFormat % parameterPath % "" % 0 ).str() ); } // find alternative classes which could be loaded std::string classNameFilter = "*"; const CompoundObject *userData = parameter->userData(); if( const CompoundObject *ui = userData->member<CompoundObject>( "UI" ) ) { if( const StringData *classNameFilterData = ui->member<StringData>( "classNameFilter" ) ) { classNameFilter = classNameFilterData->readable(); } } std::string searchPathEnvVar = extract<const char *>( classInfo[3] )(); object ieCore = import( "IECore" ); object classLoader = ieCore.attr( "ClassLoader" ).attr( "defaultLoader" )( searchPathEnvVar ); object classNames = classLoader.attr( "classNames" )( classNameFilter ); // and build menu items to allow each of the alternative classes to be loaded int numClasses = len( classNames ); for( int i=0; i<numClasses; i++ ) { string className = extract<string>( classNames[i] )(); object classVersions = classLoader.attr( "versions" )( object( classNames[i] ) ); int numVersions = len( classVersions ); for( int j=0; j<numVersions; j++ ) { string versionString = extract<const char *>( classVersions[j].attr( "__str__" )() )(); if( numVersions > 1 ) { /// \todo We need to make this menu nice and hierarchical. /// We need the nuke boys to sort that out though. menuItems.push_back( className + " v" + versionString ); } else { menuItems.push_back( className ); } menuItems.push_back( ( setClassFormat % parameterPath % className % versionString ).str() ); } } } catch( boost::python::error_already_set ) { PyErr_Print(); } catch( const std::exception &e ) { msg( Msg::Error, "ClassParameterHandler::classChooserKnob", e.what() ); } classChooser->label( label.c_str() ); classChooser->enumerationKnob()->menu( menuItems ); }