Seexpr

Arithmetic expressions appear in almost every animation system ever created. Being able to embed an expression language in a piece of custom software allows an amazing degree of artistic freedom. At Disney artists have enjoyed using expressions because they allow just enough flexibility without being overwhelming to non-programmer users. Developers have enjoyed them too for quick prototyping and deployment of fixes to production needs.

History

At Disney there have been various expression languages. SeExpr started as a language for our procedural geometry instancing tool, XGen. Work was done to generalize it into something that could be used in other contexts. Later it was integrated into paint3d, our texture painting facility, which opened the door to procedural synthesis. More recently, we have integrated it as a way of defining procedural controls to physical dynamical simulations and render time particle instancing.

Expressions can be seen as a way of allowing customization of inner loops. This is contrast to scripting which is mostly aimed at gluing large parts of code base together. So in this sense, C++ forms the center of your application, python could be used to put pieces of it together, and SeExpr is used to customize tight inner loops.

Major Features

  • Arithmetic expression of scalar/vector types
  • Large library of builtin functions
  • Extensible variables and functions (including with DSOs)
  • Simple to embed in any program
  • High-level UI components to manipulate and visualize expressions, including:
    • an expression editor, with auto-completion
    • a panel for control widgets, eg, sliders, ramp widgets, color widgets
    • an image previewer
    • an expression library browser

Get Started

Demos

We have packaged several demo applications with SeExpr to show some potential uses. We include a simple ASCII graphing calculator (.mov), a Qt graphing calculator (.mov), and a RenderMan shader and shadeop (.mov) to access expressions. These are all available in the src/demos directory of the source tree.

asciigraph segraph shadeop
asciiGraph (.mov) segraph (.mov) shadeop (.mov)

Artistic control is very important for film making. Expressions though essentially a mathematical concept can readily be used to create artist directed procedural content. One key we found was creating an interface around the expression language that automatically exposed parameters on defined variables. For example on the right you see a color ramp, slider, and spline ramp that are all automatically generated from just typing the expression below. Also, libraries of expressions are created by expert users and shared with other users. We have included in src/demos a simple Qt image editor (.mov) to illustrate this functionality. Another demonstration of the expression editor can be seen in this video (YouTube) at time 3:18. Also take a look at our custom editor (.mov) and more library (.mov) in action.

editor editor library
simple editor (.mov) custom editor (.mov) library (.mov)

Usage Example

SeExpr can be used in many evaluation contexts, and in each context it may have different bound variables, different customizable functions. As an example, a programmer could allow a user to generate an image by evaluating an expression at each point of the image and binding a u and v variable for the u,v parameter of the image. Then the user could write

Noise Driving Color Interpolation

$val=noise(10*$u,10*$v);
$color=ccurve($val,
    0.000, [1.000, 1.000, 0.498], 4,
    0.590, [0.333, 0.000, 0.000], 4,
    0.665, [1.000, 1.000, 0.000], 4);

$color
$val=voronoi(5*[$u,$v,.5],4,.6,.2);
$color=ccurve($val,
    0.000, [0.141, 0.059, 0.051], 4,
    0.185, [0.302, 0.176, 0.122], 4,
    0.301, [0.651, 0.447, 0.165], 4,
    0.462, [0.976, 0.976, 0.976], 4);
$color

Ray Tracing Sphere

This is an example of something you probably should not do with expressions. At the same time it is sometimes nice to prototype functions and techniques in expressions because of the interactivity.

$Cs=[1.000, 0.000, 1.000]; # Sphere Color
$L1=norm([-1.3,-.3,0]); # Light Direction 1
$L2=norm([.8,-1,-1]); # Light Direction 2
$sp=[0.000, 0.000, -3.000]; # Sphere center
$d=norm([$u-.5,$v-.5,-1]); # ray direction
$o=[0.000, 0.000, 0.000]; # ray origin
$r=1.000; # sphere radius
# quadratic coefficients
$a=dot($d,$d);
$ominussp=$o-$sp;
$b=2*dot($d,$ominussp);
$c=dot($ominussp,$ominussp)-$r*$r;
# discriminant
$disc=$b*$b-4*$a*$c;
$color=0.000;
if($disc>0){ # two hit case
  # minimum ray parameter
  $t=min((-$b+sqrt($disc))/(2*$a),(-$b-sqrt($disc))/(2*$a))[0];
  if($t>=0){ # if we are in front of camera
      $Pintersect=$o+$d*$t;  # point of intersection
      $N=norm($Pintersect-$sp); # intersection normal
      # lighting
      $H1=(-$L1+-$d)/length($L1+$d);
      $color=max(dot($N,-$L1),0)*($Cs*.3+.5*max(0,dot($H1,$N))^80);
      $H2=(-$L2+-$d)/length($L2+$d);
      $color+=max(dot($N,-$L2),0)*($Cs*.3+.5*max(0,dot($H2,$N))^80);
   }
}
# return color
$color

Future Plans

Recently we have been exploring a LLVM backend for native compilation on both GPUs and CPUs. We are also looking at adding a limited set of new language features.