Exemplo n.º 1
0
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 );
}
Exemplo n.º 2
0
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 );
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 5
0
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;
}