November 15, 2018 Workshop 15 Notes

MEL + Pixar's Tony DeRose's Split Average Method (interpreted from guest lecture, Virginia Film Festival,11.9.2017)

  1. The Script Editor has two panels -> choose the script editor icon (see green arrow in image below).




  2. Create a polygon cube by using the Polygons menu and shelf icon and see the result.

CreatePolygonCube;
setToolTo CreatePolyCubeCtx;
polyCube -ch on -o on -w 3.739708 -h 2.49654 -d 3.577945 -cuv 4 ;
// Result: pCube1 polyCube1 //

Select and repaste the command editing the values, and hit the “enter” key
CreatePolygonCube;
polyCube -ch on -o on -w 1 -h 1 -d 1 ;
// Result: pCube2 polyCube2 //

  1. Select script and drag to shelf, or use the menu item File/Save select to shelf to generate a shelf command with the result above.
  2. Select shelf item and invoke cube. Note: Drag icon to "trash" symbol to upper right of shelf to remove it.
  3. Note three types of variables:
    1. float – decimals
    2. integer – whole numbers
    3. string – text character sequence. (Note Each variable type can be an array containing several values)
  4. Use random number to create a cube

//create a float variable $r using the rand() command by typing
float $r;
$r = rand(10);
//Edit the cube and use the random number for the cube size
//CreatePolygonCube;
polyCube -w $r -h $r -d $r -ax 0 1 0;

  1. Revisit the same command, but have the position be variable. (Note: cutting and pasting this next set of lines from this web page into the script editor could result in hidden characters being added to the expression editor. Therefore, it is best to retype this by hand.)

float $r, $Gx, $Gy, $Gz;
$r = rand(10);
string $Name[];
//CreatePolygonCube;
$Name = `polyCube -w $r -h $r -d $r -ax 0 1 0`;
$Gx = gauss(10);
$Gy = gauss(10);
$Gz = gauss(10);
move $Gx $Gy $Gz $Name;
            Highlight in scrip editor and keep entering enter key and see results.     


  1. Using a while loop to achieve the same result.

 

float $r, $Gx, $Gy, $Gz;
int $counter=1;
while ($counter++ < 10) {
$r = rand(10);
string $Name[];
//CreatePolygonCube;
           $Name = `polyCube -w $r -h $r -d $r -sx 1 -sy 1 -sz 1 -ax 0 1 0 `; 
           $Gx = gauss(10);
           $Gy = gauss(10);
           $Gz = gauss(10);
move $Gx $Gy $Gz $Name;
                      }

  1. Using a for loop to move all the cubes in a selected group of them.

float $x, $y, $z;
for ($cube in `ls -sl`){
           $x = gauss(1);
           $y = gauss(1);
           $z = gauss(1);
move $x $y $z $cube;
};

  1. Add “if” statement

float $x, $y, $z;
for ($cube in `ls -sl`){
           $x = gauss(2);
           $y = gauss(2);
           $z = gauss(2);
          move $x $y $z $cube;
          if  ($y  > 1) { scale 2 2 2 $cube; }
};

  1. setAttr command

ctrl/ctrl-a on one of the cubes an open attribute editor
select pCubeShape (e.g., pCubeShape5) and the Render Stats section. Uncheck cast shadows yields
setAttr "pCubeShape5.castsShadows" 0;
try using the followwing code for a selected set of cubes:
for ($cube in `ls -sl`){
setAttr ($cube+".castsShadows") 0;
}

  1.  Drag code to shelf/use shelf editor to add name and change icon. (32 x 32 pix)

  2. www.highend3d.com has a number of scripts.

**********************
14. Create a legacy particle emitter, and then use expressions editor under Translate Y attribute box to create the following expression: *

particle1.translateY = 10 * sin(deg_to_rad(sqrt(pow(particle1.translateX,2) + pow(particle1.translateZ,2)) + frame));

* Note: The same technique can be used with respect to an nParticle (e.g., nParticle1.translateY). In the case of an nParicle, the translations along the Y axis are smoother if the gravity attibute of the nucleus (e.g. nucleus1) is set to 0. The expression for an nParticle such as an "nParticle1" is:

nParticle1.translateY = 10 * sin(deg_to_rad(sqrt(pow(nParticle1.translateX,2) + pow(nParticle1.translateZ,2)) + frame));

*****************
15. Writing a procedure for a ball {WE WILL CONTINUE BY REVISITING THIS EXAMPLE]

global proc string moveball2(vector $pt){
float $px = $pt.x;
float $py = $pt.y;
float $pz = $pt.z;
string $balls[1] = `sphere -p $px $py $pz`;
string $myball = $balls[0];
expression -o $myball -s "tz = sin(deg_to_rad(frame)) * 10;";

return $myball;
}

//test 1
vector $pt = <<4, 4, 0>>;
moveball2($pt);

//test 2
vector $pt = <<2, 2, 0>>;
moveball2($pt);

//Procedure to create array of moving spheres

global proc string makeballs(int $rows, int $cols) {
float $spaced = 4.0;
float $xpos = -1 * $cols * 0.5 * $spaced;
float $ypos = -1 * $rows * 0.5 * $spaced;
float $zpos = 0.0;
vector $pt = <<$xpos, $ypos, $zpos>>;

int $i = 0;
int $ii = 0;

while ($i < $rows) {
    while ($ii < $cols) {
        $pt = <<$xpos, $ypos, $zpos>>;
        moveball2($pt);
        $xpos = $xpos + $spaced;
        $ii = $ii + 1;
        print("inner loop \n");
        print("x val & y val " + $xpos + " " + $ypos + "\n");
    }
    print("outer loop \n");
    $ii = 0;
    $i = $i + 1;
    $xpos = -1 * $cols * 0.5 * $spaced;
    $ypos = $ypos + $spaced;
}
return "done";
};

makeballs(2,2);

makeballs(20, 20); 
    
***************************************************

VARIED HEIGHTS BY DISTANCE FROM ORIGIN

global proc string moveball3(vector $pt){
float $px = $pt.x;
float $py = $pt.y;
float $pz = $pt.z;
string $balls[1] = `sphere -p 0 0 0 -r 1`;
move -r $px $py $pz ;
string $myball = $balls[0];

expression -o $myball -s "ty = 10.0 * sin (deg_to_rad (15 * (sqrt (pow (tx, 2) + pow (tz, 2))) + frame));";
return $myball;
}

global proc string makeballs(int $rows, int $cols) {
float $spaced = 4.0;
float $xpos = -1 * $cols * 0.5 * $spaced;
float $ypos = -1 * $rows * 0.5 * $spaced;
float $zpos = 0.0;
vector $pt = <<$xpos, $ypos, $zpos>>;
int $i = 0;
int $ii = 0;
while ($i < $rows) {
     while ($ii < $cols) {
         moveball3($pt); //change procedure in examples below ... makeplanes
        $xpos = $xpos + $spaced;
        $pt = <<$xpos, $ypos, $zpos>>;
        $ii = $ii + 1;
        //print("inner loop \n");
    }
    $ii = 0;
    $i = $i + 1;
    $xpos = -1 * $cols * 0.5 * $spaced;
    $zpos = $zpos + $spaced;
}
return "done";
}

***************************************************

WITH PLANES

global proc string moveplane(vector $pt, float $spaced){
float $px = $pt.x;
float $py = $pt.y;
float $pz = $pt.z;
string $planes[1] = `nurbsPlane -p 0 0 0 -ax 0 1 0 -w $spaced -lr 1 -d 3 -u 1 -v 1 -ch 1`;
move -r $px $py $pz ;
string $myplane = $planes[0];

expression -o $myplane -s "ty = 10.0 * sin (deg_to_rad (15 * (sqrt (pow (tx, 2) + pow (tz, 2))) + frame));";
return $myplane;

}

global proc string makeplanes(int $rows, int $cols) {
float $spaced = 4.0;
float $xpos = -1 * $cols * 0.5 * $spaced;
float $ypos = -1 * $rows * 0.5 * $spaced;
float $zpos = 0.0;
vector $pt = <<$xpos, $ypos, $zpos>>;
int $i = 0;
int $ii = 0;
while ($i < $rows) {
    while ($ii < $cols) {
        moveplane($pt, $spaced);//change procedure from example above ... makeballs
        $xpos = $xpos + $spaced;
        $pt = <<$xpos, $ypos, $zpos>>;
        $ii = $ii + 1;
        //print("inner loop \n");
    }
    $ii = 0;
    $i = $i + 1;
    $xpos = -1 * $cols * 0.5 * $spaced;
    $zpos = $zpos + $spaced;
}
return "done";
};

makeplanes(20, 20);

16. Spiral

vector $pnts[];
string $spiral = "curve ";
float $radius = 4;
float $deltaRadius = 0.2;
float $deltaAngle = 10;
float $angleAccel = 0.0;
float $radAccel = 0.0; //try value of 0.01
float $curAngle = 0;
int $numSpirals = 10;
float $maxDeg = $numSpirals * 360;
for ($i = 0; $curAngle < $maxDeg; $i++) {
float $x = cos(deg_to_rad($curAngle)) * $radius;
float $z = sin(deg_to_rad($curAngle)) * $radius;
$pnts[$i] = <<$x, 0, $z>>;
$spiral += " -p " + $pnts[$i];
$radius += $deltaRadius;
$curAngle += $deltaAngle;
$deltaAngle += $angleAccel;
$deltaRadius += $radAccel;
}

eval($spiral)

 

17. Helix (add $deltaHeight)

vector $pnts[];
string $spiral = "curve ";
float $radius = 4;
float $deltaRadius = 0.2;
float $deltaAngle = 10;
float $deltaHeight = 0.1;
float $angleAccel = 0.0;
float $radAccel = 0.0;
float $curAngle = 0;
int $numSpirals = 10;
float $maxDeg = $numSpirals * 360;
for ($i = 0; $curAngle < $maxDeg; $i++) {
float $x = cos(deg_to_rad($curAngle)) * $radius;
float $z = sin(deg_to_rad($curAngle)) * $radius;
float $y = $i * $deltaHeight;
$pnts[$i] = <<$x, $y, $z>>;
$spiral += " -p " + $pnts[$i];
$radius += $deltaRadius;
$curAngle += $deltaAngle;
$deltaAngle += $angleAccel;
$deltaRadius += $radAccel;
}

eval($spiral)

18. Split Average Method (re: after Lecture by Pixar's Tony DeRose)

Geri's Game

Source: computerhistory.org (From Pixar's Geri's Game Rendering)

Draw a closed one degree curve of four points:

closed one degr curve part 1

global proc vector paramPt(vector $ptA, vector $ptB, float $param){
float $x = $ptA.x + $param * ($ptB.x - $ptA.x);
float $y = $ptA.y + $param * ($ptB.y - $ptA.y);
float $z = $ptA.z + $param * ($ptB.z - $ptA.z);
vector $curPt = <<$x, $y, $z>>;
return $curPt;
}

global proc vector[] split(vector $ptA, vector $ptB){
vector $ptS1 = paramPt($ptA, $ptB, 0.25);
vector $ptS2 = paramPt($ptA, $ptB, 0.75);
vector $splitPts[2];
$splitPts[0] = $ptS1;
$splitPts[1] = $ptS2;
return $splitPts;
}

global proc vector avg(vector $ptA, vector $ptB){
vector $avgPt = paramPt($ptA, $ptB, 0.5);
return $avgPt;
}

global proc vector[] splitPts(vector $ptList[]){
int $lenStart = size($ptList);
int $vecSize = 2 * $lenStart + 1;
vector $splitPoints[];
int $i = 0;
int $j = 0;
while($i < $lenStart){
vector $curPts[2];
vector $ptA = $ptList[$i];
vector $ptB = $ptList[$i + 1];
$curPts = split($ptA, $ptB);
$splitPoints[$j] = $curPts[0];
$splitPoints[$j + 1] =$curPts[1];
$i = $i + 1;
$j = $j + 2;
}
return $splitPoints;
}

global proc vector[] avgPts(vector $ptList[]){
int $lenStart = size($ptList);
vector $avgPts[];
vector $avgPt;
int $i = 0;
while($i < $lenStart - 1){
$avgPt = avg($ptList[$i], $ptList[$i + 1]);
$avgPts[$i] = $avgPt;
$i = $i + 1;
}
$avgPt = avg($ptList[$lenStart -1], $ptList[0]);
$avgPts[$i] = $avgPt;
return $avgPts;
}

global proc vector[] drawClosedPoly(vector $ptList[]){
string $polyLine = "curve -d 1 ";
int $numPts = size($ptList);
for($i = 0; $i < $numPts; $i++){
$polyLine += " -p " + $ptList[$i] ;
}
$polyLine += " -p " + $ptList[0];
eval($polyLine);
return $ptList;
}

global proc vector[] mergePts(vector $splitPoints[], vector $avgPts[]){
vector $mergedPts[];
int $j = 0;
for($i = 0; $i < size($avgPts); $i++){
$mergedPts[$j] = $splitPoints[$i];
$mergedPts[$j + 1] = $avgPts[$i];
$j += 2;
}
return $mergedPts;
}

global proc vector[] splitPts(vector $ptList[]){
int $lenStart = size($ptList);
vector $splitPoints[];
int $i = 0;
int $j = 0;
vector $curPts[];
while($i < $lenStart - 1){
vector $ptA = $ptList[$i];
vector $ptB = $ptList[$i + 1];
$curPts = split($ptA, $ptB);
$splitPoints[$j] = $curPts[0];
$splitPoints[$j + 1] = $curPts[1];
$i = $i + 1;
$j = $j + 2;
}
vector $ptA = $ptList[$i];
vector $ptB = $ptList[0];
$curPts = split($ptA, $ptB);
$splitPoints[$j] = $curPts[0];
$splitPoints[$j + 1] = $curPts[1];
return $splitPoints;
}

global proc int splitAvgPts(vector $ptList[], int $resolution){
vector $spltPts[];
vector $mergedPts[];
vector $tmpPtList[];
$tmpPtList = $ptList;
while ($resolution > 0) {
$spltPts = splitPts($tmpPtList);
$tmpPtList = avgPts($spltPts);
$resolution -= 1;
}
$mergedPts = mergePts($spltPts, $tmpPtList);
drawClosedPoly($mergedPts);
return 1;
}

vector $pt1 = `pointPosition curve1.cv[0]`;
vector $pt2 = `pointPosition curve1.cv[1]`;
vector $pt3 = `pointPosition curve1.cv[2]`;
vector $pt4 = `pointPosition curve1.cv[3]`;

vector $ptList[];
$ptList = {$pt1, $pt2, $pt3, $pt4};

int $resolution = 4;

splitAvgPts($ptList, $resolution);

 

//Result of split average:

splitAvgResult