Parse


Description

Populates the shader definition with information from the associated file. This is the second pass at parsing the associated file, since the ParseInfo callback first parses it to compile enough information to register the shader definition and populate the preset manager.

This callback is fired when a shader implemented with this parser's language is instantiated.


Applies To

Custom Shaders


Syntax

public class <plugin-item_name>

{

	public bool Parse( Context in_context )

	{

		...

	}

}
CStatus <plugin-item_name>_Parse( CRef& in_context ) 

{ 

	... 

}
function <plugin-item_name>_Parse( in_context ) 

{ 

	... 

}
def <plugin-item_name>_Parse( in_context ):

	...
Function <plugin-item_name>_Parse( in_context )

	...

End Function
sub <plugin-item_name>_Parse 

{ 

	my $in_context = shift; 

}

<plugin-item-name> is the parser name specified in the call to PluginRegistrar.RegisterShaderLanguageParser with any spaces converted to underscores. For example, if you register a parser in a plug-in called "My Parser", the callback function names start with "My_Parser".


Parameters

Parameter Language Type Description
in_context Scripting and C# Context Context.GetAttribute("Definition") returns the ShaderDef.
C++ CRef& Context::GetAttribute("Definition") returns a reference to the ShaderDef.


Context Attributes

Attribute Get/Set Description
Filename Sets a String or CString The full path to the file to pre-parse. ??? What is pre-parsing???
Definition Returns or sets a ShaderDef The shader definition to populate/query.
Errors Returns a String or CString The parser can output parse errors.
Warnings Returns a String or CString The parser can output parse warnings.


Example

SICALLBACK UtShaderLanguageParser_Parse( CRef& in_ctxt  )

{

	XSI::Application app;

	XSI::Factory fact = app.GetFactory();



	/*	For this example, we use a very simple format to define the shader.

		First line represents the prog id.

		Following lines have this format:

			Type space Input space Texturable space PortName

			color|float|boolean|integer|vector2|vector3|vector4 in|out on|off $PortName

		Until a line with a single dot is found.

		Then, 2 strings separated by a space give the MR function name and library.			*/

	XSI::Context ctxt(in_ctxt);

	XSI::CString strFilename = ctxt.GetAttribute( L"FileName" );

	XSI::ShaderDef shaderDef = ctxt.GetAttribute( L"Definition" );



	// We'll just check if our user attribute is there

	{

		XSI::CValue valDune;

		valDune = shaderDef.GetAttributes().GetAttribute( L"{F2EF07FE-1B57-4245-BF08-F5556212BFDF}" );

		assert( !valDune.IsEmpty() );

	}



	std::ifstream in( strFilename.GetAsciiString() );

	if(!in) 

	{

		ctxt.PutAttribute( L"Errors", L"Cannot open file: " + strFilename + L"\n" );

		return CStatus::Fail;

	}



	char buf[255];



	// Skip First Line

	in.getline( buf, 255 );



	XSI::ShaderParamDefOptions optTexturableInput = fact.CreateShaderParamDefOptions();

	optTexturableInput.SetTexturable(true);



	// Port Defs 

	XSI::ShaderStructParamDef currentStructDef;

	while( in.getline( buf, 255 ).eof()==false )

	{

		if( strlen( buf ) > 0 )

		{

			CSIString str(buf);

			std::vector<CSIString> tokens;

			str.Split( L" ", tokens );



			// Strip the enum tokens

			XSI::CValue valEnumValues;

			{

				CSIString strEnumValues;

				std::vector<CSIString>::iterator itEraseStart = tokens.end();

				bool bStartedEnum=false;

				for( std::vector<CSIString>::iterator it=tokens.begin(); it!=tokens.end(); ++it )

				{

					// Skip the enum token

					if( *it == L"enum" )

					{

						

						itEraseStart = it;

						bStartedEnum = true;

					}

					// Gather the enum tokens and remove them from the token list

					else if( bStartedEnum )

					{

						

						std::vector<CSIString> enumTokens;

						it->Split( L"=", enumTokens );

						if( enumTokens.size() == 2 )

						{

							//Replace '_' by ' '

							for( ULONG i=0; i<enumTokens[0].Length(); ++i )

							{

								if( ((LPCWSTR)enumTokens[0])[i] == L'_' )

								{

									enumTokens[0].SetAt( i, L' ' );

								}

							}



							strEnumValues += enumTokens[0];

							strEnumValues += L",";

							strEnumValues += enumTokens[1];

							strEnumValues += L";";

						}

					}

				}

			

				if( bStartedEnum )

				{

					if( itEraseStart!=tokens.end() )

						tokens.erase( itEraseStart, tokens.end() );



					if( !strEnumValues.IsEmpty() )

					{

						valEnumValues = (LPCWSTR)strEnumValues;

					}

				}

			}

			



			if( tokens.size()==1  )

			{

				if( str==L"." )

					break;

				else if( str==L"endstruct")

					currentStructDef=CRef();

			}

			else if( tokens.size()==4 )

			{

				XSI::CString strParamName = (LPCWSTR)tokens[3];

				

				CSIString strType = tokens[0];



				bool bIsInput= tokens[1]==L"in";

				bool bTexturable= tokens[2]==L"on";

				bool bIsArray =false;



				if( strType.Right(2) == L"[]" )

				{

					bIsArray = true;

					strType.TruncateRight(2);

				}

				

				XSI::siShaderParameterType eType = siScalarParameterType;

				if( strType == L"color"  )

					eType = siColorParameterType;

				if( strType == L"float" )

					eType = siScalarParameterType;

				else if( strType == L"vector2" )

					eType = siVector2ParameterType;

				else if( strType == L"vector3" )

					eType = siVectorParameterType;

				else if( strType == L"vector4" )

					eType = siVector4ParameterType;

				else if( strType == L"boolean" )

					eType = siBooleanParameterType;

				else if( strType == L"integer" )

					eType = siIntegerParameterType;

				else if( strType == L"reference" )

					eType = siReferenceParameterType;

				else if ( strType == L"matrix4")

					eType = siMatrixParameterType;

				else if ( strType == L"matrix3")

					eType = siMatrix3ParameterType;

				else if ( strType == L"string")

					eType = siStringParameterType;

				else if ( strType == L"quaternion")

					eType = siQuaternionParameterType;

				else if ( strType == L"fcurve")

					eType = siProfileCurveParameterType;

				else if ( strType == L"gradient")

					eType = siGradientParameterType;

				else if ( strType == L"texture")

					eType = siTextureParameterType;

				else if ( strType == L"tspace")

					eType = siTextureSpaceParameterType;

				else if ( strType == L"struct" && !currentStructDef.IsValid() )

					eType = siStructParameterType;



				// Now add the port.

				XSI::ShaderParamDef paramDef;



				bTexturable &= bIsInput;



				XSI::ShaderParamDefContainer pdefContainer;

				if( currentStructDef.IsValid() )

					pdefContainer = currentStructDef.GetSubParamDefs();

				else if( bIsInput )

					pdefContainer = shaderDef.GetInputParamDefs();

				else

					pdefContainer = shaderDef.GetOutputParamDefs();





				if( !bIsArray )

				{

					paramDef = pdefContainer.AddParamDef( strParamName, eType, bTexturable ? optTexturableInput :CRef() );



					if( eType == siStructParameterType )

					{

						currentStructDef = paramDef;

					}

				}

				else

				{

					paramDef = pdefContainer.AddArrayParamDef( strParamName, eType, bTexturable ? optTexturableInput :CRef() );



					XSI::ShaderArrayParamDef arrayDef = paramDef;

					

					XSI::ShaderParamDef itemDef = arrayDef.GetArrayItemDef();

					

					if( eType == siStructParameterType )

					{

						currentStructDef = itemDef;

					}

				}



				// Set the enum values

				if( !valEnumValues.IsEmpty() )

					paramDef.GetAttributes().SetAttribute( L"PPGPortEnumValues", valEnumValues );

				

				// Set tspace filter

				if( strType==L"tspace" )

				{

					paramDef.GetAttributes().SetAttribute( siPropertyFilterAttribute, (LONG)siUVPropertyFilter );

				}

			}

		}

	}



	if( in.getline( buf, 255 ).eof()==true )

	{

		CSIString str(buf);

		std::vector<CSIString> tokens;

		str.Split( L" ", tokens );

		

		// Fill MR MetaShaderDef

		if( tokens.size()==2 || tokens.size()==3 )

		{

			// Texture type can connect to anything.

			shaderDef.AddType( L"texture" );



			XSI::MetaShaderRendererDef rendererDef = shaderDef.AddRendererDef( L"Mental Ray");

			rendererDef.PutSymbolName( (LPCWSTR)tokens[0] );

			rendererDef.PutCodePath( (LPCWSTR)tokens[1] );



			CValue valVersion;



			if( tokens.size()==2 )

			{

				valVersion=(LONG)1;

			}

			else

			{

				valVersion = (LPCWSTR)tokens[2];

				valVersion.ChangeType( XSI::CValue::siInt8 );

			}



			XSI::AttributeMap rendererOptions = rendererDef.GetRendererOptions();

			rendererOptions.SetAttribute( L"version", valVersion );



			// Hardcoded options by shader types.

			if( tokens[0] == L"sib_uvwgen" )

			{

				rendererOptions.SetAttribute( L"derivative1", L"on" );

				rendererOptions.SetAttribute( L"derivative2", L"on" );

			}

		}

		else

		{

			ctxt.PutAttribute( L"Errors", L"Cannot find the DLL Code Section.\n" );

			in.close();

			return CStatus::Fail;

		}

	}

	else

	{

		ctxt.PutAttribute( L"Errors", L"Cannot find the DLL Code Section.\n" );

		in.close();

		return CStatus::Fail;

	}

	

	in.close();

	return CStatus::OK;

}


See Also