void ColorProcessor::compute( Gaffer::ValuePlug *output, const Gaffer::Context *context ) const { if( output == colorDataPlug() ) { FloatVectorDataPtr r, g, b; { ContextPtr tmpContext = new Context( *context, Context::Borrowed ); Context::Scope scopedContext( tmpContext.get() ); tmpContext->set( ImagePlug::channelNameContextName, string( "R" ) ); r = inPlug()->channelDataPlug()->getValue()->copy(); tmpContext->set( ImagePlug::channelNameContextName, string( "G" ) ); g = inPlug()->channelDataPlug()->getValue()->copy(); tmpContext->set( ImagePlug::channelNameContextName, string( "B" ) ); b = inPlug()->channelDataPlug()->getValue()->copy(); } processColorData( context, r.get(), g.get(), b.get() ); ObjectVectorPtr result = new ObjectVector(); result->members().push_back( r ); result->members().push_back( g ); result->members().push_back( b ); static_cast<ObjectPlug *>( output )->setValue( result ); return; } ImageProcessor::compute( output, context ); }
void ColorProcessor::compute( Gaffer::ValuePlug *output, const Gaffer::Context *context ) const { if( output == colorDataPlug() ) { ConstStringVectorDataPtr channelNamesData; { ImagePlug::GlobalScope globalScope( context ); channelNamesData = inPlug()->channelNamesPlug()->getValue(); } const vector<string> &channelNames = channelNamesData->readable(); const string &layerName = context->get<string>( g_layerNameKey ); FloatVectorDataPtr rgb[3]; { ImagePlug::ChannelDataScope channelDataScope( context ); int i = 0; for( const auto &baseName : { "R", "G", "B" } ) { string channelName = ImageAlgo::channelName( layerName, baseName ); if( ImageAlgo::channelExists( channelNames, channelName ) ) { channelDataScope.setChannelName( channelName ); rgb[i] = inPlug()->channelDataPlug()->getValue()->copy(); } else { rgb[i] = ImagePlug::blackTile()->copy(); } i++; } } processColorData( context, rgb[0].get(), rgb[1].get(), rgb[2].get() ); ObjectVectorPtr result = new ObjectVector(); result->members().push_back( rgb[0] ); result->members().push_back( rgb[1] ); result->members().push_back( rgb[2] ); static_cast<ObjectPlug *>( output )->setValue( result ); return; } ImageProcessor::compute( output, context ); }
IECore::ConstCompoundObjectPtr ShaderAssignment::computeProcessedAttributes( const ScenePath &path, const Gaffer::Context *context, IECore::ConstCompoundObjectPtr inputAttributes ) const { CompoundObjectPtr result = inputAttributes->copy(); const Shader *shader = shaderPlug()->source<Plug>()->ancestor<Shader>(); if( shader ) { // Shader::state() returns a const object, so that in the future it may // come from a cached value. we're putting it into our result which, once // returned, will also be treated as const and cached. for that reason the // temporary const_cast needed to put it into the result is justified - // we never change the object and nor can anyone after it is returned. ObjectVectorPtr state = boost::const_pointer_cast<ObjectVector>( shader->state() ); if( state->members().size() ) { result->members()["shader"] = state; } } return result; }
IECore::ConstCompoundObjectPtr AppleseedShaderAdaptor::computeAttributes( const ScenePath &path, const Gaffer::Context *context, const GafferScene::ScenePlug *parent ) const { ConstCompoundObjectPtr inputAttributes = inPlug()->attributesPlug()->getValue(); const ObjectVector *shaderNetwork = inputAttributes->member<const ObjectVector>( g_oslShaderAttributeName ); if( !shaderNetwork || shaderNetwork->members().empty() ) { return inputAttributes; } const Shader *rootShader = runTimeCast<const Shader>( shaderNetwork->members().back().get() ); if( !rootShader ) { return inputAttributes; } OSLQuery::Parameter *firstOutput = firstOutputParameter( rootShader->getName() ); // Build an adapter network if we can. bool prependInputNetwork = true; vector<ShaderPtr> adapters; if( firstOutput && firstOutput->isclosure ) { ShaderPtr material = new Shader( "material/as_material_builder", "osl:surface" ); material->parameters()[g_bsdfParameterName] = new StringData( "link:adapterInputHandle." + firstOutput->name.string() ); adapters.push_back( material ); } else if( firstOutput && firstOutput->type == TypeDesc::TypeColor ) { ShaderPtr emission = new Shader( "surface/as_emission_surface", "osl:shader" ); emission->parameters()["Color"] = new StringData( "link:adapterInputHandle." + firstOutput->name.string() ); emission->parameters()[g_handleParameterName] = new StringData( "adapterEmissionHandle" ); ShaderPtr material = new Shader( "material/as_material_builder", "osl:surface" ); material->parameters()[g_bsdfParameterName] = new StringData( "link:adapterEmissionHandle.BSDF" ); adapters.push_back( emission ); adapters.push_back( material ); } else if( firstOutput && ( firstOutput->type == TypeDesc::TypeFloat || firstOutput->type == TypeDesc::TypeInt ) ) { ShaderPtr colorBuild = new Shader( "color/as_color_build", "osl:shader" ); StringDataPtr colorLink = new StringData( "link:adapterInputHandle." + firstOutput->name.string() ); colorBuild->parameters()["R"] = colorLink; colorBuild->parameters()["G"] = colorLink; colorBuild->parameters()["B"] = colorLink; colorBuild->parameters()[g_handleParameterName] = new StringData( "adapterColorBuildHandle" ); ShaderPtr emission = new Shader( "surface/as_emission_surface", "osl:shader" ); emission->parameters()["Color"] = new StringData( "link:adapterColorBuildHandle.ColorOut" ); emission->parameters()[g_handleParameterName] = new StringData( "adapterEmissionHandle" ); ShaderPtr material = new Shader( "material/as_material_builder", "osl:surface" ); material->parameters()[g_bsdfParameterName] = new StringData( "link:adapterEmissionHandle.BSDF" ); adapters.push_back( colorBuild ); adapters.push_back( emission ); adapters.push_back( material ); } else if( firstOutput && firstOutput->type == TypeDesc::TypeVector ) { ShaderPtr vectorSplit = new Shader( "vector/as_vector_split", "osl:shader" ); vectorSplit->parameters()["Vector"] = new StringData( "link:adapterInputHandle." + firstOutput->name.string() ); vectorSplit->parameters()[g_handleParameterName] = new StringData( "adapterVectorSplit" ); ShaderPtr colorBuild = new Shader( "color/as_color_build", "osl:shader" ); colorBuild->parameters()["R"] = new StringData( "link:adapterVectorSplit.X" ); colorBuild->parameters()["G"] = new StringData( "link:adapterVectorSplit.Y" ); colorBuild->parameters()["B"] = new StringData( "link:adapterVectorSplit.Z" ); colorBuild->parameters()[g_handleParameterName] = new StringData( "adapterColorBuildHandle" ); ShaderPtr emission = new Shader( "surface/as_emission_surface", "osl:shader" ); emission->parameters()["Color"] = new StringData( "link:adapterColorBuildHandle.ColorOut" ); emission->parameters()[g_handleParameterName] = new StringData( "adapterEmissionHandle" ); ShaderPtr material = new Shader( "material/as_material_builder", "osl:surface" ); material->parameters()[g_bsdfParameterName] = new StringData( "link:adapterEmissionHandle.BSDF" ); adapters.push_back( vectorSplit ); adapters.push_back( colorBuild ); adapters.push_back( emission ); adapters.push_back( material ); } else { // Shader has no output, or an output we can't map sensibly. // Make an "error" shader. ShaderPtr emission = new Shader( "surface/as_emission_surface", "osl:shader" ); emission->parameters()["Color"] = new Color3fData( Imath::Color3f( 1, 0, 0 ) ); emission->parameters()[g_handleParameterName] = new StringData( "adapterEmissionHandle" ); ShaderPtr material = new Shader( "material/as_material_builder", "osl:surface" ); material->parameters()[g_bsdfParameterName] = new StringData( "link:adapterEmissionHandle.BSDF" ); adapters.push_back( emission ); adapters.push_back( material ); prependInputNetwork = false; // We don't need the original shaders at all } // Make a new network with the adapter network // appended onto the input network ObjectVectorPtr adaptedNetwork = new ObjectVector(); if( prependInputNetwork ) { adaptedNetwork->members() = shaderNetwork->members(); // Shallow copy for speed - do not modify in place! ShaderPtr rootShaderCopy = rootShader->copy(); rootShaderCopy->parameters()[g_handleParameterName] = new StringData( "adapterInputHandle" );; adaptedNetwork->members().back() = rootShaderCopy; } std::copy( adapters.begin(), adapters.end(), back_inserter( adaptedNetwork->members() ) ); // Place the new network into the "osl:surface" attribute // and remove the "osl:shader" attribute. CompoundObjectPtr outputAttributes = new CompoundObject; outputAttributes->members() = inputAttributes->members(); // Shallow copy for speed - do not modify in place! outputAttributes->members()[g_oslSurfaceAttributeName] = adaptedNetwork; outputAttributes->members().erase( g_oslShaderAttributeName ); return outputAttributes; }
IECore::ObjectPtr Group::computeMapping( const Gaffer::Context *context ) const { /// \todo It might be more optimal to make our own Object subclass better tailored /// for passing the information we want. CompoundObjectPtr result = new CompoundObject(); InternedStringVectorDataPtr childNamesData = new InternedStringVectorData(); vector<InternedString> &childNames = childNamesData->writable(); result->members()["__GroupChildNames"] = childNamesData; ObjectVectorPtr forwardMappings = new ObjectVector; result->members()["__GroupForwardMappings"] = forwardMappings; boost::regex namePrefixSuffixRegex( "^(.*[^0-9]+)([0-9]+)$" ); boost::format namePrefixSuffixFormatter( "%s%d" ); set<InternedString> allNames; for( ScenePlugIterator it( inPlugs() ); it != it.end(); ++it ) { ConstInternedStringVectorDataPtr inChildNamesData = (*it)->childNames( ScenePath() ); CompoundDataPtr forwardMapping = new CompoundData; forwardMappings->members().push_back( forwardMapping ); const vector<InternedString> &inChildNames = inChildNamesData->readable(); for( vector<InternedString>::const_iterator cIt = inChildNames.begin(), ceIt = inChildNames.end(); cIt!=ceIt; cIt++ ) { InternedString name = *cIt; if( allNames.find( name ) != allNames.end() ) { // uniqueify the name /// \todo This code is almost identical to code in GraphComponent::setName(), /// is there a sensible place it can be shared? The primary obstacle is that /// each use has a different method of storing the existing names. string prefix = name; int suffix = 1; boost::cmatch match; if( regex_match( name.value().c_str(), match, namePrefixSuffixRegex ) ) { prefix = match[1]; suffix = boost::lexical_cast<int>( match[2] ); } do { name = boost::str( namePrefixSuffixFormatter % prefix % suffix ); suffix++; } while( allNames.find( name ) != allNames.end() ); } allNames.insert( name ); childNames.push_back( name ); forwardMapping->writable()[*cIt] = new InternedStringData( name ); CompoundObjectPtr entry = new CompoundObject; entry->members()["n"] = new InternedStringData( *cIt ); entry->members()["i"] = new IntData( it.base() - inPlugs()->children().begin() ); result->members()[name] = entry; } } return result; }