Scripting Basics (Comparing - Part 1)

Table of contents

Scripting Language Support

Maya uses a proprietary scripting language called MEL. It has a C-like syntax.

XSI supports VBScript, JScript (which is similar to JavaScript), Python and PerlScript. Most script writers use VBScript or JScript. These are common languages used to create web pages so information about syntax and sample code is freely available on the Internet. JScript is similar, but not exactly the same language as JavaScript or JScript.Net.

Advanced script writers may also find Python to be very appealing because it has advanced programming functionality and there are many powerful libraries freely available that can be used directly from within XSI.

Mel Versus JScript

Although XSI supports VBScript, PythonScript and PerlScript, it is JScript that people who are familiar with MEL will be most comfortable using. Both derive from “C” syntax so even without having a deep understanding of the language it is easy to start reading and writing JScript scripts. For this reason all the examples in this article are written in Jscript.



   //MEL (Maya)
   int $i ;
   for ( $i = 0 ; $i < 3 ; $i++ )	
             print ( $i + "\n") ;
   
   $i = 5 * ( 2 - 4 ) ;
   
   /* Check what we got */
   if ( $i == -10 )
   {	
              print "It is -10" ;
   }
   //Jscript (XSI)
   for ( $i = 0 ; $i < 3 ; $i++ )
           LogMessage( $i ) ; // Already includes a \n
   
   $i = 5 * ( 2 - 4 ) ;
   
   /* Check what we got */
   if ( $i == -10 )
   {
           LogMessage( "It is -10" ) ;
   }
   


Some important differences:

  • JScript variables do not need to have the $ sign (but you are free to use it if you wish).
  • String constants in JScript code always need to be placed in double quotes. MEL is not picky when passing object names and other strings to commands.
  • JScript variables are never declared with a type. They set their type according to whatever data that you assign them but they can change type if you later assign a different type. This is in contrast to MEL in which the type is optional but will stick to whatever type it is initially set.



   //MEL (Maya)
   $myvar = 78 ;
   print ($myvar + "\n");
   $myvar = 13.1 ;
   print ($myvar + "\n"); // Will print 13
   
   //Jscript (XSI)
   myvar = 78 ;
   LogMessage( myvar ) ;
   
   myvar = 13.1 ;
   LogMessage( myvar ) ; // Will print 13.1
  • JScript variables are global by default, so unless the “var” keyword is used some strange results can result. However global variables in XSI are only scoped to the actually script file, not to the entire application as they are in Maya.
  • JScript supports arrays and strings as a type of object. There are a lot of powerful methods available on these objects.




   int $myarray[] = { 10, 11, 12 } ;
   for ( $i = 0 ; $i < size( $myarray ) ; $i++ 
   )
   {	
          print( $myarray[$i] + "\n" ) ;
   }
   // Flush all
   clear($myarray) ;
   
   // Change a value
   $myarray[0] = 6 ;
   
   // The array only expects integers so
   // this produces a warning
   $myarray[1] = "not a number" ;
   
   // Automatic resizing to 10 elements
   $myarray[9] = 10 ;
   
   
   
   
   
   
   
   
      
   $myarray = new Array( 10, 11, 12 ) ;
   for ( $i = 0 ; $i < $myarray.length ; $i++ 
   )
   {
          LogMessage( $myarray[$i] ) ;
   }
   
   // Flush all
   $myarray.length = 0 ;
   
   // Change a value
   $myarray[0] = 6 ;
   
   // elements in a JScript can be any type
   $myarray[1] = "not a number" ;
   
   // Automatic resizing to 10 elements
   $myarray[9] = 10 ;
   
   // You can even create arrays of arrays
   $myarray[2] = new Array( "apple", "grape" ) ;
   
   LogMessage( $myarray[2][1] ) ; // Access grape
   
   // There are also useful methods like
   // join, concat, sort and splice


  • JScript has no built in vector or matrix objects. However XSI has a math library that lets you create Vector, 3x3 Matrix and 4x4 Matrix objects. Also the GridData object is available for dealing with arbitrary sized 2-D arrays.




   vector $a = <<0.1,0.2,0.3>> ;
   
   // read the y value (0.2)
   int $a_yval = ($a.y) ;
   
   //change y value
   $a = <<$a.x, 0.9, $a.z>> ;
   
   //swap values around
   $a = <<$a.z,$a.y,$a.x>> ;
   
   //shortcut to get length
   float $alength = $a ;
   
   //Prints:  "Length of <<0.3,0.9,0.1>> is 0.9539392014"
   print("Length of <<" + ($a.x) + "," + ($a.y) + "," 	+ ($a.z) + ">> is " + $alength) ;
   
   
  
   
   
   
     
   a = XSIMath.CreateVector3() ;
   
   a.x = 0.1 ;
   a.y = 0.2 ;
   a.z = 0.3 ;
   
   // read the y value (0.2)
   a_yval = a.y ;
   
   //change y value
   a.y = 0.9 ;
   
   //swap values around
   temp = a.x ;
   a.x = a.z ;
   a.z = temp ;
   
   //XSI vector object supports
   //lots of functionality
   alength = a.Length() ;
   
   //Prints:  "Length of <<0.3,0.9,0.1>> is 0.9539392014169457"
   Logmessage("Length of <<" + a.x + "," + a.y + "," 	+ a.z + ">> is " + alength) ;


  • JScript variables are case sensitive, but commands and object model methods are not.

Mel Versus VBScript

Many of the examples in the XSI scripting reference material, plus most of the built-in scripts are written in VBScript. While JScript is probably a better language for people familiar with MEL, it can also be useful to read up on VBScript syntax, at least to the level of being able to easily read the bountiful collection of existing examples. Just an hour or two of study should be all that is required.

Local Procedures

Once a script gets reasonably large it becomes necessary to break it down into “procedures” that are stored in the same script and serve as “helper functions”. Practically every language has this concept, with names like “routine” and “function” meaning the same thing as a MEL procedure. The syntax is very similar between MEL and JScript.




   // Local procedure
   proc float TestProc( float $arg1, float $arg2 )
   {
          if ( $arg2 == 0.0 )	
          {
                print( "Invalid arg!\n" ) ;		
                return 0.0 ;	
          }
          
          return $arg1 / $arg2 ;
   }
   
   print( TestProc( 0.5, 0.1 ) ) ;
   print( TestProc( 0.5, 0.0 ) ) ;
   
   
   
   
   
   
   
   
   
   
   
   
   // Local procedure
   
   function TestProc( arg1, arg2 )
   {
          if ( arg2 == 0.0 )
          {
                  print( "Invalid arg!" ) ;
                  return 0.0 ;
          }
   
          return arg1 / arg2 ;
   
   }
   
   print( TestProc( 0.5, 0.1 ) ) ;
   print( TestProc( 0.5, 0.0 ) ) ;
   
   // If you are really used to
   // calling print instead of
   // LogMessage just write a little
   // procedure like this!
   
   function print( in_text )
   {
          LogMessage( in_text ) ;
   }   


Procedures, as defined in the examples above, are only available to other code in the same script file. Hence it is called a “local procedure”. The vast majority of functions will be local, but some code is so useful you will want to make it available “globally” in the system. The solution for achieving this is described in the next section.

Global Procedures

In MEL script you can mark a procedure with a global keyword and it will be available to other scripts. You normally have to manually “source” the script file to get it to load but once sourced it will be remembered during the entire Maya session.

In XSI you can explicitly call any procedure inside any script file using the method Application.ExecuteScript(). This method is a little awkward for the caller because you need to know the full path of the script and package the arguments into an array. It is more convenient and powerful to package the procedures as Custom Commands. In XSI calling a custom command is exactly the same syntax as calling a local procedure, which is also the same syntax to call a built-in XSI command. Creating a custom command is normally done by creating a self-installing plug-in.




   // Global procedure
   Global proc float 
   TestProc( float $arg1, float $arg2 )
   {	
          if ( $arg2 == 0.0 )	
          {	
                 print( "Invalid arg!\n" ) ;
                 return 0.0 ;
          }
          
          return $arg1 / $arg2 ;
   }
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   // Custom command implemented as a 
   // self-installed plugin
   function XSILoadPlugin( in_reg )
   {
        in_reg.Name = "TestProc Plug-in";
        in_reg.RegisterCommand( "TestProc","TestProc" );
        return true;
   
   }
   
   function TestProc_Init( io_Context )
   {
        var oCmd = io_Context.Source;	
        oCmd.SetFlag( siNoLogging );	
        oCmd.ReturnValue = true;	
        
        var oArgs = oCmd.Arguments;	
        oArgs.Add( "arg1",siArgumentInput );	
        oArgs.Add( "arg2",siArgumentInput );		
        
        return true;
   
   }
   function TestProc_Execute( arg1,arg2 )
   {
        if ( arg2 == 0.0 )
        {
              LogMessage( "Invalid arg!" ) ;
              return 0.0 ;	
        }
        
        return arg1 / arg2 ;
   }


Clearly it requires more set-up code inside XSI to create the equivalent of a global procedure. Fortunately there is a Wizard available to generate all this set-up code for you. Also, once established as a custom command you can assign a procedure to a menu item or a toolbar easily and XSI can perform validation and conversion operations on the procedure arguments. If you wish, the custom command can be logged in the script history when it is executed. Custom commands can be implemented in any supported language and can be called by any supported language. For example a library implemented in Python is available to VBScript coders.

Finding Script files

As mentioned previously, the MEL source command will load a script and execute it. It will also add any procedures that are marked as global into the list of available procs. It is not necessary to specify the full path for MEL scripts when calling source because Maya will search in specific locations of the user directory. Also, this search path can be extended using an environment variable.

Jcript files in XSI are stored in *.js files. It is best to implement the script as a self-installing plug-in and to store it in the \Application\Plugins sub-directory of the user or workgroup location. If this convention is followed XSI will automatically load the script at start-up and make its contents available. Additional search locations can be added using an environment variable.

Both products provide a Plug-in Manager dialog for controlling the loading of script files. When writing self-installing plug-ins inside XSI it is also important to look in the Script History window to get any error messages, for example those arising from syntax errors.

Object Oriented XSI Scripting

One area that could be interesting and new for MEL script-writers is the JScript support for defining objects. Although JScript objects aren’t as “object-oriented” as C++ or other more “serious” languages, it is an interesting tool for architecting huge scripts. A common way to introduce objects into scripting is to write an XSI custom command that, rather than returning a simple number or string returns a JScript object. This object has its own data and member functions. This approach can reduce the number of custom commands that need to be created to expose a large set of functionality.

Python also has powerful language constructs.

And on the Windows platform it is possible to extend the XSI Object Model by creating COM objects (with C++ or even the .Net Framework).

Exception Handling

JScript supports exception handling via the try/catch construct. Normally when a script error occurs the execution of the script will halt. However in some cases it is necessary to write code that might fail in some cases. For example a plug-in that reads a file might prefer to show a meaningful message box to the user if the file is missing, rather than just stopping with an obscurely technical error message. The try/catch mechanism provides a powerful way of achieving this.

Script Editor

The XSI script editor is more of a conventional text file editor than the Maya script editor. Both have a script history pane that shows which commands have been executed and other output strings. However, unlike the Maya script editor, executing a script does not erase it from the editor. And each time a script is edited XSI starts with a clean scripting environment, so any variables or procedures that were previously executed are forgotten (unless they are installed as custom commands).

Although you can only have one instance of the Script Editor view, you can work on multiple files at the same time by opening them inside the “Text Editor” view. Starting with v5.0, XSI includes a special layout called the Tools Development Environment that makes it easy to work on multiple script files at the same time.

Most script projects can be completed directly inside XSI, but for very large script projects you may prefer to use an external text editor such as Microsoft Visual Studio or SciTE.

A fast way to introduce simple scripts into the user interface is to drag them from the script editor to a toolbar. This creates a button on the toolbar and embedds the script code into the toolbar.

See also


This page was last modified 18:45, 30 Aug 2007.
This page has been accessed 21343 times.

© Copyright 2009 Autodesk Inc. All Rights Reserved. Privacy Policy | Legal Notices and Trademarks | Report Piracy