static IECore::ConstCompoundDataPtr metadataGetter( const std::string &key, size_t &cost ) { cost = 1; if( !key.size() ) { return NULL; } const char *searchPath = getenv( "OSL_SHADER_PATHS" ); OSLQuery query; if( !query.open( key, searchPath ? searchPath : "" ) ) { throw Exception( query.error() ); } CompoundDataPtr metadata = new CompoundData; metadata->writable()["shader"] = convertMetadata( query.metadata() ); CompoundDataPtr parameterMetadata = new CompoundData; metadata->writable()["parameter"] = parameterMetadata; for( size_t i = 0; i < query.nparams(); ++i ) { const OSLQuery::Parameter *parameter = query.getparam( i ); if( parameter->metadata.size() ) { parameterMetadata->writable()[parameter->name] = convertMetadata( parameter->metadata ); } } return metadata; }
static IECore::ConstCompoundDataPtr metadataGetter( const std::string &key, size_t &cost ) { cost = 1; if( !key.size() ) { return NULL; } const char *searchPath = getenv( "OSL_SHADER_PATHS" ); OSLQuery query; if( !query.open( key, searchPath ? searchPath : "" ) ) { throw Exception( query.geterror() ); } CompoundDataPtr metadata = new CompoundData; metadata->writable()["shader"] = convertMetadata( query.metadata() ); CompoundDataPtr parameterMetadata = new CompoundData; metadata->writable()["parameter"] = parameterMetadata; for( size_t i = 0; i < query.nparams(); ++i ) { const OSLQuery::Parameter *parameter = query.getparam( i ); if( parameter->metadata.size() ) { string nameWithoutSuffix; const OSLQuery::Parameter *positionsParameter; const OSLQuery::Parameter *valuesParameter; const OSLQuery::Parameter *basisParameter; // If this parameter is part of a spline, register the metadata onto the spline plug if( findSplineParameters( query, parameter, nameWithoutSuffix, positionsParameter, valuesParameter, basisParameter ) ) { // We merge metadata found on all the parameters that make up the plug, but in no particular order. // If you specify conflicting metadata on the different parameters you may get inconsistent results. CompoundData *prevData = parameterMetadata->member<CompoundData>( nameWithoutSuffix ); CompoundDataPtr data = convertMetadata( parameter->metadata ); if( prevData ) { data->writable().insert( prevData->readable().begin(), prevData->readable().end() ); } parameterMetadata->writable()[nameWithoutSuffix] = data; } else { parameterMetadata->writable()[parameter->name.c_str()] = convertMetadata( parameter->metadata ); } } } return metadata; }
void OSLShader::loadShader( const std::string &shaderName, bool keepExistingValues ) { const char *searchPath = getenv( "OSL_SHADER_PATHS" ); OSLQuery query; if( !query.open( shaderName, searchPath ? searchPath : "" ) ) { throw Exception( query.error() ); } loadShaderParameters( query, parametersPlug(), keepExistingValues ); if( query.shadertype() == "shader" ) { CompoundPlug *existingOut = getChild<CompoundPlug>( "out" ); if( !existingOut || existingOut->typeId() != CompoundPlug::staticTypeId() ) { CompoundPlugPtr outPlug = new CompoundPlug( "out", Plug::Out, Plug::Default | Plug::Dynamic ); setChild( "out", outPlug ); } loadShaderParameters( query, getChild<CompoundPlug>( "out" ), keepExistingValues ); } else { Plug *existingOut = getChild<Plug>( "out" ); if( !existingOut || existingOut->typeId() != Plug::staticTypeId() ) { PlugPtr outPlug = new Plug( "out", Plug::Out, Plug::Default | Plug::Dynamic ); setChild( "out", outPlug ); } } namePlug()->setValue( shaderName ); typePlug()->setValue( "osl:" + query.shadertype() ); m_metadata = NULL; }
void OSLShader::loadShader( const std::string &shaderName, bool keepExistingValues ) { Plug *existingOut = outPlug(); if( shaderName.empty() ) { parametersPlug()->clearChildren(); namePlug()->setValue( "" ); typePlug()->setValue( "" ); if( existingOut ) { existingOut->clearChildren(); } return; } const char *searchPath = getenv( "OSL_SHADER_PATHS" ); OSLQuery query; if( !query.open( shaderName, searchPath ? searchPath : "" ) ) { throw Exception( query.geterror() ); } const bool outPlugHadChildren = existingOut ? existingOut->children().size() : false; if( !keepExistingValues ) { // If we're not preserving existing values then remove all existing // parameter plugs - the various plug creators above know that if a // plug exists then they should preserve its values. parametersPlug()->clearChildren(); if( existingOut ) { existingOut->clearChildren(); } } m_metadata = NULL; namePlug()->setValue( shaderName ); typePlug()->setValue( std::string( "osl:" ) + query.shadertype().c_str() ); const IECore::CompoundData *metadata = OSLShader::metadata(); const IECore::CompoundData *parameterMetadata = NULL; if( metadata ) { parameterMetadata = metadata->member<IECore::CompoundData>( "parameter" ); } loadShaderParameters( query, parametersPlug(), parameterMetadata ); if( !existingOut || existingOut->typeId() != Plug::staticTypeId() ) { PlugPtr outPlug = new Plug( "out", Plug::Out, Plug::Default | Plug::Dynamic ); if( existingOut ) { // We had an out plug but it was the wrong type (we used // to use a CompoundPlug before that was deprecated). Move // over any existing child plugs onto our replacement. for( PlugIterator it( existingOut ); !it.done(); ++it ) { outPlug->addChild( *it ); } } setChild( "out", outPlug ); } if( query.shadertype() == "shader" ) { loadShaderParameters( query, outPlug(), parameterMetadata ); } else { outPlug()->clearChildren(); } if( static_cast<bool>( outPlug()->children().size() ) != outPlugHadChildren ) { // OSLShaderUI registers a dynamic metadata entry which depends on whether or // not the plug has children, so we must notify the world that the value will // have changed. Metadata::plugValueChangedSignal()( staticTypeId(), "out", "nodule:type", outPlug() ); } }