This project was an introduction to MEL scripting and required us to utilize loops to generate a matrix of shapes. Additionally we were tasked with creating an interface to dynamically update the matrix in a non-destructive way.

Already having some experience with MEL and programming, I wanted to focus more on the aesthetic result of the shape matrix. I eventually settled on a tool to create strings of lights based on a selection set of locators. This seemed presented a sufficient technical challenge for me and also would allow me an excuse to work more with RenderMan shaders and RIBArchives.

Before starting to code, I decided on the dynamic features of the matrix:

- Variable "sag" to the strings of lights

- Scale of the lights

- Random scale offset of the lights

- Random rotation offset of the lights

- Random brightness/color of the lights

Other features were also considered, though I was unsure of a simple way to implement these as real-time adjustable features:

- Distance between the lights

- RIBArchive path

The RIBArchive is applied procedurally by:

```
string $archiveName = "example.rib";
select "lightBulb_*";
string $transNodes[] = `ls -sl -tr`;
for($tNode in $transNodes) {
rmanAddDelayedReadArchiveAttrs;
setAttr -type "string" ($tNode + "Shape.rman__param___draFile") $archiveName;
}
```

The full MEL script can be downloaded here.

Rendering challenges are discussed in detail in my Renderman II Portfolio site.

The biggest challenge for me was dealing with the Maya coordinate systems. Specifically object-space rotations. To preserve interactivity, I was planning on using expressions to link to the UI, but expressions do not allow relative object-space rotations. In most cases the rotation values were already jumbled up from attaching them tangent to a curve point and assigning a random rotation. I instead built a function to evaluate when a slider was changed in the UI that would do the correct rotations of the lights.

Making sure the lights were positioned tangent to curve points also presented a challenge. I used the pointOnCurveInfo node to get the coordinates, tangent vector and normal vector of a specific point on the curve calculated as where a light should be placed. Due to a curve's lack of surface area, sometimes the tangent vectors would roll around the curve up to 180 degrees, placing my object facing in the wrong direction when using a tangent constraint. The changes were unpredictable and changed with the slightest movement of the curve. I opted to use an xform matrix after generating my own rotation values from vector algebra. This ensured the lights were always in the correct orientation but led to a decision to not recompute this information as the curves were updated.

//Simple constraint had rolling tangent problems
string $tCons[] = `tangentConstraint -aim 1 0 0 -u 0 1 0 $curve $bulbObj`;
//Following vector math used to eliminate rolling
vector $upVector = << 0.0, 1.0, 0.0 >>;
float $tangents[] = `getAttr ($newPointOnCurveInfo + ".tangent")`;
vector $tangentVector = `unit << $tangents[0], $tangents[1], $tangents[2] >>`;
vector $normal = `cross $tangentVector $upVector`;
vector $binormal = `cross $tangentVector $normal`;
if(`dot $upVector $binormal` < 0.0) {
$binormal = -$binormal;
$normal = -$normal;
}
$binormal = `unit $binormal`;
$normal = `unit $normal`;
//build transform 4x4 matrix
matrix $tMat[4][4] = <<
($normal.x),($normal.y),($normal.z), 0.0;
($binormal.x),($binormal.y),($binormal.z), 0.0;
($tangentVector.x),($tangentVector.y),($tangentVector.z),0.0;
0,0,0,1 >>;
xform -os -m
($tMat[0][0]) ($tMat[0][1]) ($tMat[0][2]) ($tMat[0][3])
($tMat[1][0]) ($tMat[1][1]) ($tMat[1][2]) ($tMat[1][3])
($tMat[2][0]) ($tMat[2][1]) ($tMat[2][2]) ($tMat[2][3])
($tMat[3][0]) ($tMat[3][1]) ($tMat[3][2]) ($tMat[3][3]) $bulbObj;

Overall, I am very happy with how this project turned out. I experimented with many different approaches to problem-solving with MEL and learned quite a bit. Having mainly focused on the aesthetics of the final render, I am a bit disappointed with my final result, but this was another opportunity to learn some more RenderMan, and provided direction to some later RenderMan II projects and future studies. I do plan to have a noise-free render of these lightbulbs in the future.