Lsystem
A Lsystem for Rib and Mel


return to main index

contents
    system architecture
    graphical output - maya
    graphical output - rib
    scripts - string generation
    scripts - string interpretation
    auxilliary mel resources
    extending the Lsystem

Download LCode.zip



Introduction

This tutorial provides a starting point for coding an Lsystem using the TCL scripting language. The Lsystem can output either a rib stream for rendering with a RenderMan complient renderer or a mel script that can be sourced by Maya - either directly using Maya's script window, or indirectly using mel's commandPort procedure.

The TCL scripts supplied with this tutorial can be run (with a couple of minor edits) from the command line as follows,

    prompt$ tclsh LControl.tcl
    or
    prompt$ tclsh LControl.tcl tree.dat

The output of the Lsystem, whether rib or mel, is determined by information supplied by an input data (text) file called an Lscript. If a data file is not specified, the Lsystem will use a default script file called default.dat. An example data file is shown on the right. Figures 1 & 2 show graphics derived from the rib and mel output produced by tree.dat.




tree.dat

axiom "G"
generations 5
rule G "4{>zG}{<zG}4G"
rule 4 "44"
  
angle 17
scale 0.9


Figure 1 - output via rib


Figure 2 - output via mel


System Architecture

The TCL and other scripts that implement the Lsystem are shown in figure 3. LControl.tcl, as its name suggests, is the script that coordinates the operation of the scripts that comprise the Lsystem. LControl.tcl uses LScriptReader.tcl to parse the input data file from which it builds a database of parameter values that are stored in a tcl array. The database is passed to LGenerator.tcl where, after a process of string rewriting, a long sequence of characters, an Lstring, is returned to LControl. During the string rewriting phase, an Lsystem (at least as far as the one currently under discussion is concerned) makes no judgements about what graphics will be eventually displayed.

Depending on the users choice, the Lstring is post-processed by LMel.tcl, LMan.tcl. or LManProcedural.tcl. The details of LManProcedural are dealt with in a separate tutorial (RenderMan Procedural Primitive). During the interpretation phase decisions are made concerning how an Lstring will be "turned into" a 3D object(s).



Figure 3
Lsystem Architecture


Scripts - String Generation


Three scripts take care of reading a Lscript and generating a Lstring.
    LControl.tcl
    LScriptReader.tcl and
    LGenerator.tcl

The first line of code of LControl.tcl must be edited so that it can reference the other TCL scripts. If you wish to see the Lstring produced by the Lsystem swap the comments on these lines of code (lines 7 and 8 from the end of LControl.tcl)

    render [generate script] script "temp"
    #puts "[generate script]"

Assuming you have the three scripts in the directory specified by the source proc on the first line of code of LControl.tcl and the directory also has a copy of default.dat (see the top of this page) you should be able to run LControl.tcl either from the command line or from within Cutter - figure 4.

Figure 4


Scripts - String Interpretation

The characters in an Lstring are (usually) interpreted as commands that create 3D objects. Although the next set of TCL scripts generate output for two very different graphics environments, they share one guiding principle and that is of growth. In general, when an object has been "put" into a scene the current coordinate system is translated to the "top" of the object. This ensures the next object will appear to extend or grow from the end of the previous shape.


Three scripts take care of interpreting a Lscript and generating a graphic using Maya or RenderMan.
    LMel.tcl
    LMayaPort.tcl and
    LMan.tcl

Graphical Output - Maya

A Lstring interpreted by LMel.tcl produces a mel script named "temp.mel". Using Maya's script window "temp.mel" can be sourced in the normal way ie.

    source "FULL_PATH/temp.mel;

Alternatively, if LControl.tcl is calling on the services of LMayaPort.tcl (refer to the last 3 lines of LControl.tcl) it is possible to run the entire Lsystem from Maya's script window ie.

    commandPort -n ":2222"; // run this only once

then,

    // windows
    system ("tclsh PATH_TO_YOUR_LCODE_DIRECTORY/LControl.tcl");

or

    // linux/osx
    system ("usr/bin/tclsh PATH_TO_YOUR_LCODE_DIRECTORY/LControl.tcl");


Where PATH_TO_YOUR_LCODE_DIRECTORY should point to the directory in which the tcl scripts are located. There is no need to source temp.mel because LMayaPort.tcl will "tell" Maya to do so via communications on port 2222 (or any port number the user wishes to use).

Graphical Output - Rib

A RenderMan rib stream can be generated in two ways,
      LMan.tcl writes the stream to an archive rib file, or
      LManProcedural.tcl pipes the stream directly into a renderer.

rib archives, often called pre-baked ribs, are a convenient way of instancing complex geometry - see Pre-baked ribs I & II. Generating a RenderMan procedural primitive is very fast because, ignoring virtual memory paging, the hard disk is not accessed. It is suited to situations where an Lsystem is undergoing small changes on a frame by frame basis. LManProcedural.tcl is explained in renderman procedural primitives.


Additional Mel Resources

For mel output, the script LMelProcs.mel should be copied into your Lsystem working directory. This script is source'd by temp.mel. It contains a few procs that manage the way shapes are parented to each other. In particular, this script implements a push & popable stack that enables branching structures to be created by the Lsystem.

LMelProcs.mel implements three procs that can be called to create objects - a straight line "curve", a cone and a user defined shape. Other addXxxTo() procedures can be added to LMelProcs but they may not be necessary because the general purpose proc addShapeTo can be referenced directly from an Lscript. For example, if the tree.dat script shown at the head of this page is edited as follows...


axiom "G"
generations 4
rule G "6{>zG}{<zG}6G"
rule 6 "66"
  
angle 17
scale 0.9
statement 6 {\$tnode = addShapeTo(\$tnode, \"cylinder -hr 4 -ax 0 1 0 -r 0.05;\", 0.1, 0.1);}
# OR
#statement 6 {\$tnode = addShapeTo(\$tnode, \"torus -hr 0.5 -ax 0 0 1 -r 0.09;\", 0.1, 0.1);}

a "tree" will be made from cylinders or torii - figure 5 and 6.



Figure 5


Figure 6


Extending the LSystem

Here are some suggestions for extending the Lsystem.

Shapes
    0    "Disk"
    1    "Cone"  <<-- done
    2    "Cylinder"
    3    "Sphere"
    4    "Curve" <<-- done
    5    "Polygon"
    6    "Torus"
  
 Transformations 
    >    "Positive rotation"     <<-- done
    <    "Negative rotation"     <<-- done     
    R    "Reverse direction"     <<-- done
    @    "Reverse the rotation"
    s    "Scale x, y and z"      <<-- done
    S    "Scale will be inverted"<<-- done
    +    "Moves will be positive"<<-- done
    -    "Moves will be negative"<<-- done
    T    "Turn 180.0    1 0 0"

Attributes    
    %    "Reverse Attribute"
    O    "Opacity +/- value" 
    r    "Red +/- value"
    g    "Green +/- value"
    b    "Blue +/- value"

In addition to extending the list of characters that control object creation, placement and coloration, it is also worth including some special control characters that effect the way that LGenerator performs string rewriting. For example, the following characters are already implemented but others could be added.

    ~    apply the rule randomly                        <<-- done
    *    apply the rule ONLY on the last rewrite        <<-- done
    !    do NOT apply the rule on the final rewriting   <<-- done

The tilde rule modification character enables the same rule to have several substitutions ie.

    "~a"     "xxy2"
    "~a"     "xyyy2"

The tilde character, in the example shown above, says, "sometimes use "xxy2" and sometimes use "xyyy2". The decision is made on a random basis.




© 2002- Malcolm Kesson. All rights reserved.