void ArnoldShader::loadShader( const std::string &shaderName, bool keepExistingValues ) { IECoreArnold::UniverseBlock arnoldUniverse( /* writable = */ false ); const AtNodeEntry *shader = AiNodeEntryLookUp( AtString( shaderName.c_str() ) ); if( !shader ) { throw Exception( str( format( "Shader \"%s\" not found" ) % shaderName ) ); } Plug *parametersPlug = this->parametersPlug()->source<Plug>(); if( !keepExistingValues ) { parametersPlug->clearChildren(); if( Plug *out = outPlug() ) { removeChild( out ); } } const bool isLightShader = AiNodeEntryGetType( shader ) == AI_NODE_LIGHT; namePlug()->setValue( AiNodeEntryGetName( shader ) ); int aiOutputType = AI_TYPE_POINTER; string type = "ai:light"; if( !isLightShader ) { const CompoundData *metadata = ArnoldShader::metadata(); const StringData *shaderTypeData = static_cast<const StringData*>( metadata->member<IECore::CompoundData>( "shader" )->member<IECore::Data>( "shaderType" ) ); if( shaderTypeData ) { type = "ai:" + shaderTypeData->readable(); } else { type = "ai:surface"; } if( type == "ai:surface" ) { aiOutputType = AiNodeEntryGetOutputType( shader ); } } if( !keepExistingValues && type == "ai:lightFilter" ) { attributeSuffixPlug()->setValue( shaderName ); } typePlug()->setValue( type ); ParameterHandler::setupPlugs( shader, parametersPlug ); ParameterHandler::setupPlug( "out", aiOutputType, this, Plug::Out ); }
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() ); } }