# A few sample MEL scripts

Creation of a torus by revolving a circle
```global proc int  nurbsTorus( float \$minorRadius,
int \$minorSections,
int \$majorSections)
{
int \$ec = 0;
int \$circleCreated = 1;
int \$torusCreated = 0;

// 1. Create the generating circle with -ch false on the XZ plane

string \$genCircle[];

if( catch( \$genCircle = `circle -ch false -nr 0 0 1 -c \$xc 0.0 0.0 -s \$minorSections -d 3 -r \$minorRadius` ))
\$circleCreated = 0;

// 2. revolve the circle about the +Z axis, -ch false

string \$torus[];
if( \$circleCreated == 1 )
{
\$torusCreated = 1;
if( catch( \$torus = `revolve -ch 0 -s \$majorSections -p 0 0 0 -axis 0 1 0 \$genCircle[0]` ) )
{
\$torusCreated = 0;
}
}

if( \$circleCreated == 1 )
delete \$genCircle[0];

if( \$torusCreated )
select -r \$torus[0];

return \$torusCreated;
}

```

An octahedron
```//
// Description : Given the length of edge, construct an octahedron
//

// Find the radius of circle encompasing the polygon.
//
proc float boundingCircleRadius( int \$n, float \$x )
//
//	Description:
//		\$n = number of sides on the polygon.
//		\$x = length of the polygon.
//
{
float \$angle = 360.0 / \$n ;

float \$den = 2.0 * ( 1.0 - \$cosx ) ;
\$rad = \$x / sqrt(\$den) ;
}

proc float[] createRegularPolygonX( int \$n, float \$r )
{
int \$i ;
float \$x[] ;
float \$angle = 360.0 / \$n ;

for( \$i = 0 ; \$i < \$n ; \$i++ ) {
float \$a = \$i * \$angle ;
\$x[\$i] =  \$r * cos(deg_to_rad(\$a)) ;
}
return \$x ;
}

proc float[] createRegularPolygonY( int \$n,float \$r )
{
int \$i ;
float \$x[] ;
float \$angle = 360.0 / \$n ;
for( \$i = 0 ; \$i < \$n ; \$i++ ) {
float \$a = \$i * \$angle ;
\$x[\$i] =  \$r * sin(deg_to_rad(\$a)) ;
}
return \$x ;
}

global proc int polyOctahedron( float \$len )
{

int \$n = 4 ;
float \$r = boundingCircleRadius( \$n, \$len ) ;

float \$x[] = createRegularPolygonX( \$n, \$r ) ;
float \$y[] = createRegularPolygonY( \$n, \$r ) ;

float \$p1x, \$p1y, \$p1z ;
float \$p2x, \$p2y, \$p2z ;

// top half.
//
\$p1x = 0.0 ;
\$p1y = 0.0 ;
\$p1z = sqrt( \$len*\$len - \$r*\$r);

float \$z = 0.0 ;
string \$facet1[] ;
\$facet1 = `polyCreateFacet -ch 0 -p \$p1x \$p1y \$p1z -p \$x[0] \$y[0] \$z -p \$x[1] \$y[1] \$z` ;

string \$facet2[] ;
\$facet2 = `polyCreateFacet -ch 0 -p \$p1x \$p1y \$p1z -p \$x[1] \$y[1] \$z -p \$x[2] \$y[2] \$z` ;

string \$facet3[] ;
\$facet3 = `polyCreateFacet -ch 0 -p \$p1x \$p1y \$p1z -p \$x[2] \$y[2] \$z -p \$x[3] \$y[3] \$z` ;

string \$facet4[] ;
\$facet4 = `polyCreateFacet -ch 0 -p \$p1x \$p1y \$p1z -p \$x[3] \$y[3] \$z -p \$x[0] \$y[0] \$z` ;

// bottom half.
//
\$p2x = 0.0 ;
\$p2y = 0.0 ;
\$p2z = -1.0 * \$p1z;

string \$facet5[] ;
\$facet5 = `polyCreateFacet -ch 0 -p \$x[0] \$y[0] \$z -p \$p2x \$p2y \$p2z -p \$x[1] \$y[1] \$z` ;

string \$facet6[] ;
\$facet6 = `polyCreateFacet -ch 0 -p \$x[1] \$y[1] \$z -p \$p2x \$p2y \$p2z -p \$x[2] \$y[2] \$z` ;

string \$facet7[] ;
\$facet7 = `polyCreateFacet -ch 0 -p \$x[2] \$y[2] \$z -p \$p2x \$p2y \$p2z -p \$x[3] \$y[3] \$z` ;

string \$facet8[] ;
\$facet8 = `polyCreateFacet -ch 0 -p \$x[3] \$y[3] \$z -p \$p2x \$p2y \$p2z -p \$x[0] \$y[0] \$z` ;

string \$octa[] ;
\$octa = `polyUnite -ch 0 \$facet1[0] \$facet2[0] \$facet3[0] \$facet4[0] \$facet5[0] \$facet6[0] \$facet7[0] \$facet8[0]` ;

select -r \$octa[0] ;
return 0 ;

}
```

Paint random strokes on a surface
```global proc paintRandom( int \$udensity, int \$vdensity, float \$strokeLength, float \$randOffset,
float \$sampleDensity, float \$surfaceOffsetMin, float \$surfaceOffsetMax, int \$doClip )
{
string \$selected[] = `ls -sl -dag -type nurbsSurface`;
string \$sel;

if( size( \$selected ) <= 0  )
{
warning( "No Nurbs surfaces are currently selected for painting.\n");
return;
}
int \$uspan, \$vspan;
float \$u,\$v,\$minU, \$minV, \$rangeU, \$rangeV;
string \$cmdK = "-k 0 -k 1 ";
string \$newStrokes[], \$newStroke[];
int \$numNewStrokes = 0;
if( \$udensity < 1 )
\$udensity = 1;
if( \$vdensity < 1 )
\$vdensity = 1;

float \$uscale = 1.0/(float)\$udensity;
float \$vscale = 1.0/(float)\$vdensity;
rand( \$uscale ); // the first rand is sometimes bad
for( \$sel in \$selected )
{
\$minU = getAttr( \$sel+".minValueU" );
\$minV = getAttr( \$sel+".minValueV" );
\$rangeU = getAttr( \$sel+".maxValueU" ) - \$minU;
\$rangeV = getAttr( \$sel+".maxValueV" ) - \$minV;
for( \$uspan = 0; \$uspan < \$udensity; \$uspan++ )
{
for( \$vspan = 0; \$vspan < \$vdensity; \$vspan++ )
{
\$u = (float)(\$uspan)/(float)(\$udensity);
\$v = (float)(\$vspan)/(float)(\$vdensity);
\$u += (0.5 + (rand( 1 )-0.5) * \$randOffset) * \$uscale;
\$v += (0.5 + (rand( 1 )-0.5) * \$randOffset) * \$vscale;
// \$u2 = rand( \$uscale );
// \$v2 = rand( \$vscale );
\$u2 = rand( 2 ) - 1;
\$v2 = rand( 2 ) - 1;
\$length = sqrt( \$u2*\$u2 + \$v2*\$v2 );
if( \$length == 0 )
continue;
\$length = \$strokeLength / \$length;
\$u2 = \$u + \$u2*\$length*\$uscale;
\$v2 = \$v + \$v2*\$length*\$vscale;
if( \$doClip )
{
if( \$u > 1 )
\$u = 1;
else if( \$u < 0 )
\$u = 0;

if( \$v > 1 )
\$v = 1;
else if( \$v < 0 )
\$v = 0;

if( \$u2 > 1 )
\$u2 = 1;
else if( \$u2 < 0 )
\$u2 = 0;

if( \$v2 > 1 )
\$v2 = 1;
else if( \$v2 < 0 )
\$v2 = 0;
// TODO: modulate sampleDensity based on length change with clipping
}
string \$cmd = ("curveOnSurface -d 1 -uv " + (\$u*\$rangeU + \$minU) + " " + (\$v*\$rangeV + \$minV)
+ " -uv "+ (\$u2*\$rangeU + \$minU) +" "+ (\$v2*\$rangeV + \$minV)
+ " "+ \$cmdK + \$sel);
eval \$cmd;
convertCurvesToStrokes;
\$newStroke =  `ls -sl -dag -type stroke`;
\$newStrokes[ \$numNewStrokes ] = \$newStroke[0];
\$numNewStrokes++;
}
}
}
float \$offsetRange = \$surfaceOffsetMax -\$surfaceOffsetMin;
rand( \$offsetRange ); // the first rand is sometimes bad
for( \$i = 0; \$i < \$numNewStrokes; \$i++)
{
setAttr ( \$newStrokes[\$i] + ".sampleDensity" ) \$sampleDensity;
setAttr ( \$newStrokes[\$i] + ".seed" ) \$i;
setAttr ( \$newStrokes[\$i] + ".surfaceOffset" ) (\$surfaceOffsetMin + rand( \$offsetRange ));
}
}

```

Create a chain
```global proc chain (int \$num)
{
//Diable cycle check warnings.
//NOT NECESSARY
cycleCheck -e off;

//create the cyclinder and a starting sphere
polyCylinder -ax 1 0 0;
scale -r 4 1 1;
sphere -p 6 0 0;
duplicate;
move -r 3 0 0;

//duplicate with smart transform, this moves each sphere
//apart from the previous duplicate with equal spacing.
//\$num-1 is used since one sphere already exists from the above commands
//also add the dynamic hinge constraints
for (\$i = 1; \$i < (\$num-1); \$i++)
duplicate -st;

select -r pCylinder1 nurbsSphere1;
constrain -hinge -o 0 0 0 -i 0;
select pCylinder1;
setAttr "rigidBody1.active" 0;

for (\$i = 1; \$i < \$num; \$i++)
{
select ("nurbsSphere" + \$i);
select -tgl ("nurbsSphere" + (\$i + 1));
constrain -hinge -o 0 0 0 -i 0;
}

select -r rigidHingeConstraint1;
move -r 1 0 0 ;
gravity -pos 0 0 0 -m 9.8 -dx 0 -dy -1 -dz 0;

//Connect the spheres to gravity
select "nurbsSphere*";
string \$listSpheres[] =  `ls -sl`;
connectDynamic -f gravityField1 \$listSpheres;

for (\$i = 1; \$i < (\$num + 1); ++\$i)
{
setAttr ("rigidBody" + \$i + ".standIn") 2;
setAttr ("rigidBody" + \$i + ".bounciness") 0.1;
setAttr ("rigidBody" + \$i + ".damping") 0.2;
}
}

```

UI
```// This is the "callback" procedure, ie. one that does useful
// work when the user interacts with the UI
global proc exportSeriesCommand()
{
// Get values off the UI - note that we are able to UNIQUELY identify our
// widget by specifying window-name|layout-name|widget-name.
string \$filehdr = `textFieldGrp -q -tx "exportSeriesWindow|params|filehdr"`;
float \$start = `floatSliderGrp -q -v "exportSeriesWindow|params|start"`;
float \$end = `floatSliderGrp -q -v "exportSeriesWindow|params|end"`;

// Feebback to user
print("Will export " + \$filehdr + " between frames " + \$start + " and " + \$end +"\n");

// Go on to export...
// ...
}// exportSeriesCommand()

// This proc creates the UI
global proc exportSeriesWin()
{
if(`window -exists exportSeriesWindow`)
return;

// create window [shell]
window -t "Export a series of objs.." exportSeriesWindow;
columnLayout params; // good idea to name our layouts