What is Maya?

MAYA is one the best 3D package used for digital content creation, to make computer animations, movies, games, and so on...
MAYA is based on a script language, called MEL (for 'Maya Embedded Language'). This language is used to:

References:

  • MAYA Web site: Go!
  • MAYA documentation online: Go!

    What is Jaya?

    Description:

    Project JAYA (for JAVA MAYA) intends to provide a MEL interpreter and a MEL-to-bytecode compiler that may be the starting point to build a fully-featured MAYA-like package, in Java!

    At this point, JAYA has its own interpreter and compiler, called JMEL, that fully interprets and compiles MEL-written files.
    JAYA has been build mainly from two packages:

    Both packages are completely written is Java. In fact, JAYA is a PURE 100% Java product and is intended to be executed on any plateform with a Java virtual machine (with version 1.1.2 or higher).

    Writing MEL commands:

    To invoke the MEL script environnement, enter:

       java jmel.Main
    
    JMEL starts and tries to invoke a welcome command called printBanner, as does BeanShell. If it finds such a command (in fact, a class named PrintBanner and implementing the Script interface, as explained here), JMEL invokes the command (in fact, it calls its exec method) and displays (for example):
    java jmel.Main
    //******************
    // JMel 0.1 - by RVA
    //******************
    jmel>
    
    From this point, the user can enter any MEL instructions that are immediately interpreted and executed by the program.
    For example:
    jmel> int $i = 1                     
    jmel> $i++; print "$i = " + $i + "\n"        // notice: character ';' is optional at the end of the last MEL instruction //
    $i = 2
    jmel> 
    
    (here print is a reserved keyword that prints its string argument on the standard output).

    The JMEL interpreter has no option to save the instructions and is only intended to test simple commands.

    Compiling MEL files:

    To invoke the MEL compiler, enter:

       java jmel.Main -O1/-O2 [options] <MEL source files to be compiled>
    

    where possible options include:

      -O1                       Generate class file
      -O2                       Generate class file (with full opimization for commands)
    
    These first three options are specific to compilation and execution of MEL scripts.
      -g                        Generate all debugging info
      -g:none                   Generate no debugging info
      -g:{lines,vars,source}    Generate only some debugging info
      -verbose                  Output messages about what the compiler is doing
      -deprecation              Output source locations where deprecated APIs are used
      -classpath <path>         Specify where to find user class files
      -sourcepath <path>        Specify where to find input source files
      -bootclasspath <path>     Override location of bootstrap class files
      -extdirs <dirs>           Override location of installed extensions
      -d <directory>            Specify where to place generated class files
      -target <release>         Generate class files for specific VM version
    
    These options are used by the MEL compiler to search for libraries and generate Java bytecode.

    '-O1' generates Java bytecode that invoke JAYA commands called from the MEL file with arguments expressed as string values. It is useful for testing and debugging.
    '-O2' generates Java bytecode that is fully optimized: a JAYA command is invoked by generating all its property accessors and finally by calling its exec method. The Jaya command is supposed to be fully tested and its .class file available somewhere.
    For further information, see below

    For example:

    java jmel.Main -O2 myScript.mel                 
    
    generates (if no error is found) a Java class file named myScript.class in the same directory as myScript.mel.

    Testing compiled MEL scripts:

    To invoke a compiled MEL script, enter:

       java jmel.Main -test <class name> [<args>]
    
    The class is loaded and executed if a static method called exec is found. The optional arguments are passed to the exec method and parsed to test the match.

    References:

  • MEL language reference: Go! Or Go!
  • BeanShell script interpreter: Go!
  • Java SUN compiler: Go!

    How does it work?

    What is a MAYA command?

    Typically, the MAYA documentation provide for each MAYA command:

  • a description of what the command must be used for,
  • the command syntax (the synopsis),
  • the options if any (the flags),
  • examples of use.

    The examples are instructions that may be included within a MEL script file or entered in the MEL command shell.

    For example:
    Command isTrue is documented as described below.

    NAME

    isTrue

    SYNOPSIS

    isTrue <condition to be tested>

    RETURN VALUE

    0 or 1

    DESCRIPTION

    This commmand returns the state of the named condition.
    If the condition is true, it returns 1. Otherwise it returns 0.

    FLAGS

    none

    EXAMPLES

    isTrue SomethingSelected;
    // Result: 1 //
    

    What is a JAYA command?

    The power of Java is be able to analyse a .class file that contain the bytecode (the binary instructions) of a Java program (called a class) to dynamically know what are the fields of that class, its methods, and how to invoke them.
    This principle is typically used by JavaBeans, that are Java classes where the syntax of some methods defines itself what are called 'properties'.
    A property, named for example myprop, has generally a getMyprop and/or a setMyprop method, that respectively returns the value of myprop, and affects its value.

    For example:

    public class MyClass
    {
    	private String myprop;
    	
    	// The 'getter' method
    	public String getMyprop() { 
    		return myprop;
    	}
    	
    	// The 'setter' method
    	public void setMyprop(String value) { 
    		myprop = value;
    	}
    }                
    
    The idea in JAYA is to use any Java class as a potential JAYA command, by invoking setter methods in one command call.
    So we may enter:
    jmel> myClass -myprop "hello"
    
    and JAYA:
  • first instantiates a new MyClass object by invoking its default constructor,
  • looks for a setMyprop method (by default, properties are supposed to be affected in a JAYA command invocation),
  • tests whether the provided argument is of the right type,
  • then invoke the setMyprop method of the new MyClass object if the argument matches.

    How to create a JAYA command?

    Two interfaces are defined in JAYA: the Script interface and the Commandable interface.

    The Script interface

    The Script interface is defined as:

    package jmel.script;
    
    public interface Script
    {
    	...
    }
    
    Although it defines no method, a class implementing the Script interface **MUST** provide a static exec method, that is invoked when the command name is entered in JAYA script.

    For example we can implement the command isTrue described above like this:

    package jmel.script;
    
    public class IsTrue implements Script
    {
    	public static boolean exec(boolean condition) {
    		return condition;
    	}
    }
    
    Note #1: by convention, Java class names are prefixed by an uppercase character.
    Note #2: a boolean in MEL is an integer that takes values 1 (for true) and 0 (for false).
    Note #3: the example simplifies the MAYA isTrue command. In fact, the argument should be a true Condition object.

    That's it!

    The Commandable interface

    The Commandable interface is defined as:

    package jmel.script;
    
    public interface Commandable
    {
    	public static final ReturnValue returnValue = new ReturnValue();
    	public void exec();
    }
    
    where the ReturnValue class is defined as:
    
    public class ReturnValue
    {
    	private Object value;
    	public Object get() { return value; }
    	public void set(Object value) { this.value = value; }
    }
    

    The ReturnValue class provides an uniform way for a command to return a value, by invoking its set method.

    If a command has its own flags, it must implement the Commandable interface.

    For example:

    import jmel.script.*;
    
    public class MyCmd implements Commandable
    {
    	private int mycount;
    	public MyCmd(int count) { mycount = count; }
    	
    	private String myprop;
    	public void setMyprop(String value) { myprop = value; }
    	
    	public void exec()
    	{
    		returnValue.set(new Integer(mycount));
    	}
    }         
    
    The myCmd command must be provided a integer value to be instantiated:
    jmel> myCmd 1;
    jmel> int $i=`myCmd 1`;       // here $i contains the return value provided in the exec method
    jmel> myCmd -myprop "me" 1;   // an instance is created and its method 'setMyprop' is invoked with "me" as an argument
    
    To query or edit a value, the MEL flags '-q/-query' and '-e/-edit' must be used.

    For example:

    jmel> string $myClassInstanceName = `myClass`;
    jmel> myClass -e -myprop "hello" $myClassInstanceName
    

    So... what is the job?

    From now on, the job is to create the hundreds of MAYA commands in Java. Some are really simple to implement, others are really tricky. That's the challenge!
    So I need very different skills:
  • people that are interested to create User Interface commands,
  • people that are interested to create 3D manipulation commands,
  • people that are interested to create shading commands,
  • etc...

    The list of MAYA commands is given here.