예제 #1
0
static void loadShaderParameters( const OSLQuery &query, Gaffer::CompoundPlug *parametersPlug, bool 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.
	
	if( !keepExistingValues )
	{
		parametersPlug->clearChildren();
	}
	
	// make sure we have a plug to represent each parameter, reusing plugs wherever possible.
	
	set<string> validPlugNames;
	for( size_t i = 0; i < query.nparams(); ++i )
	{
		const OSLQuery::Parameter *parameter = query.getparam( i );
		const Plug::Direction direction = parameter->isoutput ? Plug::Out : Plug::In;
		if( direction != parametersPlug->direction() )
		{
			continue;
		} 
		
		if( parameter->name.find( "." ) != string::npos )
		{
			// member of a struct - will be loaded when the struct is loaded
			continue;
		}
		
		const Plug *plug = loadShaderParameter( query, parameter, parametersPlug, keepExistingValues );

		if( plug )
		{
			validPlugNames.insert( parameter->name );
		}
	}
	
	// remove any old plugs which it turned out we didn't need
	
	if( keepExistingValues )
	{
		for( int i = parametersPlug->children().size() - 1; i >= 0; --i )
		{
			GraphComponent *child = parametersPlug->getChild<GraphComponent>( i );
			if( validPlugNames.find( child->getName().string() ) == validPlugNames.end() )
			{
				parametersPlug->removeChild( child );
			}
		}
	}
	
}
예제 #2
0
static Plug *loadStructParameter( const OSLQuery &query, const OSLQuery::Parameter *parameter, Gaffer::CompoundPlug *parent, bool keepExistingValues )
{
	CompoundPlug *result = NULL;

	const string name = plugName( parameter );
	CompoundPlug *existingPlug = parent->getChild<CompoundPlug>( name );
	if( existingPlug )
	{
		if( !keepExistingValues )
		{
			existingPlug->clearChildren();
		}
		result = existingPlug;
	}
	else
	{
		result = new CompoundPlug( name, parent->direction(), Plug::Default | Plug::Dynamic );
	}
	
	for( vector<string>::const_iterator it = parameter->fields.begin(), eIt = parameter->fields.end(); it != eIt; ++it )
	{
		std::string fieldName = parameter->name + "." + *it;
		loadShaderParameter( query, query.getparam( fieldName ), result, keepExistingValues );
	}
	
	// remove any old plugs which it turned out we didn't need
	
	if( keepExistingValues )
	{
		for( int i = result->children().size() - 1; i >= 0; --i )
		{
			GraphComponent *child = result->getChild<GraphComponent>( i );
			if( std::find( parameter->fields.begin(), parameter->fields.end(), child->getName().string() ) == parameter->fields.end() )
			{
				result->removeChild( child );
			}
		}
	}
	
	parent->setChild( name, result );
	
	return result;
}
예제 #3
0
void RenderManShader::loadShaderParameters( const IECore::Shader *shader, Gaffer::CompoundPlug *parametersPlug, bool keepExistingValues )
{	
	const CompoundData *typeHints = shader->blindData()->member<CompoundData>( "ri:parameterTypeHints", true );
	
	const StringVectorData *orderedParameterNamesData = shader->blindData()->member<StringVectorData>( "ri:orderedParameterNames", true );
	const vector<string> &orderedParameterNames = orderedParameterNamesData->readable();
	
	const StringVectorData *outputParameterNamesData = shader->blindData()->member<StringVectorData>( "ri:outputParameterNames", true );
	const vector<string> &outputParameterNames = outputParameterNamesData->readable();
	
	const CompoundData *annotations = shader->blindData()->member<CompoundData>( "ri:annotations", true );
	
	// 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.
	
	if( !keepExistingValues )
	{
		for( int i = parametersPlug->children().size() - 1; i >= 0; --i )
		{
			parametersPlug->removeChild( parametersPlug->getChild<GraphComponent>( i ) );
		}
	}
	
	// make sure we have a plug to represent each parameter, reusing plugs wherever possible.
	
	set<string> validPlugNames;
	for( vector<string>::const_iterator it = orderedParameterNames.begin(), eIt = orderedParameterNames.end(); it != eIt; it++ )
	{
		if( std::find( outputParameterNames.begin(), outputParameterNames.end(), *it ) != outputParameterNames.end() )
		{
			continue;
		}
	
		// splines are represented by two parameters matched by a naming convention, and we map
		// those two parameters to a single SplinePlug.
	
		const bool endsWithValues = ends_with( *it, "Values" );
		const bool endsWithPositions = ends_with( *it, "Positions" );
		if( endsWithPositions || endsWithValues )
		{
			string plugName( *it, 0, it->size() - ( endsWithValues ? 6 : 9 ) );
			if( validPlugNames.find( plugName ) != validPlugNames.end() )
			{
				continue;
			}
			
			// must use a smart pointers here because we may assign the data the parser creates (and which we therefore own)
			ConstFloatVectorDataPtr positions = shader->parametersData()->member<FloatVectorData>( plugName + "Positions" );
			ConstDataPtr values = shader->parametersData()->member<Data>( plugName + "Values" );
			
			if( positions && values )
			{
				const StringData *defaultValuesAnnotation = annotations->member<StringData>( plugName + "Values.defaultValue" );
				const StringData *defaultPositionsAnnotation = annotations->member<StringData>( plugName + "Positions.defaultValue" );

				if( defaultValuesAnnotation )
				{
					DataPtr parsedValues;
					if( values->isInstanceOf( Color3fVectorData::staticTypeId() ) )
					{
						parsedValues = parseColors( defaultValuesAnnotation->readable() );
					}
					else
					{
						parsedValues = parseFloats( defaultValuesAnnotation->readable() );
					}

					if( parsedValues )
					{
						values = parsedValues;
					}
					else
					{
						msg(
							Msg::Warning, "RenderManShader::loadShaderParameters",
							boost::format( "Unable to parse default value \"%s\" for parameter \"%s\"" ) % defaultValuesAnnotation->readable() % ( plugName + "Values" )
						);
					}
				}

				if( defaultPositionsAnnotation )
				{
					FloatVectorDataPtr parsedPositions = parseFloats( defaultPositionsAnnotation->readable() );
					if( parsedPositions )
					{
						positions = parsedPositions;
					}
					else
					{
						msg(
							Msg::Warning, "RenderManShader::loadShaderParameters",
							boost::format( "Unable to parse default value \"%s\" for parameter \"%s\"" ) % defaultPositionsAnnotation->readable() % ( plugName + "Positions" )
						);
					}
				}

				switch( values->typeId() )
				{
					case FloatVectorDataTypeId  :
						loadSplineParameter<SplineffPlug>( parametersPlug, plugName, positions, values );
						break;
					case Color3fVectorDataTypeId :
						loadSplineParameter<SplinefColor3fPlug>( parametersPlug, plugName, positions, values );
						break;
					default :
						msg(
							Msg::Warning, "RenderManShader::loadShaderParameters",
							boost::format( "Spline \"%s\" has unsupported value type \"%s\"" ) % plugName % values->typeName()
						);
				}
				validPlugNames.insert( plugName );
				continue;
			}
			
		}
	
		// the other parameter types map more simply to a single plug each.
	
		const StringData *typeHint = typeHints->member<StringData>( *it, false );
		const Data *defaultValue = shader->parametersData()->member<Data>( *it );
		switch( defaultValue->typeId() )
		{
			case StringDataTypeId :
				if( typeHint && typeHint->readable() == "shader" )
				{
					loadCoshaderParameter( parametersPlug, *it );
				}
				else
				{
					loadParameter<StringPlug>( parametersPlug, *it, static_cast<const StringData *>( defaultValue )->readable() );
				}
				break;
			case FloatDataTypeId :
				loadNumericParameter( parametersPlug, *it, static_cast<const FloatData *>( defaultValue )->readable(), annotations );
				break;
			case Color3fDataTypeId :
				loadCompoundNumericParameter<Color3fPlug>( parametersPlug, *it, static_cast<const Color3fData *>( defaultValue )->readable(), annotations );
				break;
			case V3fDataTypeId :
				loadCompoundNumericParameter<V3fPlug>( parametersPlug, *it, static_cast<const V3fData *>( defaultValue )->readable(), annotations );
				break;
			case StringVectorDataTypeId :
				if( typeHint && typeHint->readable() == "shader" )
				{
					loadCoshaderArrayParameter( parametersPlug, *it, static_cast<const StringVectorData *>( defaultValue ) );
				}
				else
				{
					loadArrayParameter<StringVectorDataPlug>( parametersPlug, *it, defaultValue, annotations );
				}
				break;
			case FloatVectorDataTypeId :
				loadArrayParameter<FloatVectorDataPlug>( parametersPlug, *it, defaultValue, annotations );
				break;
			case Color3fVectorDataTypeId :
				loadArrayParameter<Color3fVectorDataPlug>( parametersPlug, *it, defaultValue, annotations );
				break;
			case V3fVectorDataTypeId :
				loadArrayParameter<V3fVectorDataPlug>( parametersPlug, *it, defaultValue, annotations );
				break;		
			default :
				msg(
					Msg::Warning, "RenderManShader::loadShaderParameters",
					boost::format( "Parameter \"%s\" has unsupported type \"%s\"" ) % *it % defaultValue->typeName()
				);
		}
		
		validPlugNames.insert( *it );
	}
	
	// remove any old plugs which it turned out we didn't need
	
	if( keepExistingValues )
	{
		for( int i = parametersPlug->children().size() - 1; i >= 0; --i )
		{
			GraphComponent *child = parametersPlug->getChild<GraphComponent>( i );
			if( validPlugNames.find( child->getName().string() ) == validPlugNames.end() )
			{
				parametersPlug->removeChild( child );
			}
		}
	}
	
}