Introduction
There are situations where (primary) geometry in a Maya scene can be used as a source of data
from which secondary geometries can be derived. Such geometry might be
used to augment the original Maya object(s) or the geometry might be "exported" from Maya in
a format that enables it to be rendered by an external (stand-alone)
renderer such as Pixar's prman.
Core Code
This section lists the basic code used by the examples presented in this tutorial
to query geometry.
Several of the sample scripts query a polymesh in order to get the xyz
coordinates of its vertices. The following proc performs the query and assigns
the data to an array of vectors.
global proc getVertices(string $tnode, vector $data[])
{
int $count = size($data);
int $num[] = `polyEvaluate -v $tnode`;
string $shp[] = `listRelatives -shapes $tnode`;
string $shape = $shp[0];
float $pos[];
for($n = 0; $n < $num[0]; $n++) {
$vert = $shape + ".vtx[" + $n + "]";
$pos = `pointPosition -local $vert`;
$data[$count] = <<$pos[0], $pos[1], $pos[2]>>;
$count++;
}
}
It is often necessary to find the interpolated (ie. smoothed) normal at each
vertex of a polymesh. Because the Mel command polyNormalPerVertex returns an array
of the normals for the polygons that "share" a vertex the following procedures are used
to query and return an array of smoothed normals.
global proc vector getAverageNormal(float $norms[])
{
float $x = 0, $y = 0, $z = 0;
int $numComps = size($norms);
int $numNorms = $numComps/3;
if($numNorms == 1)
return <<$norms[0],$norms[1],$norms[2]>>;
for($n = 0; $n < $numComps - 3; $n += 3) {
$x += $norms[$n];
$y += $norms[$n + 1];
$z += $norms[$n + 2];
}
return <<$x/$numNorms, $y/$numNorms, $z/$numNorms >>;
}
global proc getNormals(string $tnode, vector $data[])
{
int $count = size($data);
int $num[] = `polyEvaluate -v $tnode`;
string $shp[] = `listRelatives -shapes $tnode`;
string $shape = $shp[0];
float $norms[];
vector $ave;
for($n = 0; $n < $num[0]; $n++) {
$vert = $shape + ".vtx[" + $n + "]";
$norms = `polyNormalPerVertex -q -xyz $vert`;
$ave = getAverageNormal($norms);
$data[$count] = <<$ave.x, $ave.y, $ave.z>>;
$count++;
}
}
Several of the sample scripts also use the following code, in one form or
another, to write a text file to a directory in the Maya project folder.
The name of the output file, and its file extension, will depend on the use
that will be made of the data.
string $projPath = `workspace -q -rootDirectory`;
string $path = $projPath + "data/temp.mel";
int $fileid = fopen($path, "w");
// Assume "pos" is an array of xyz values...
fprint($fileid, $pos[0] + " " + $pos[1] + " " + $pos[2] + "\n");
fclose $fileid;
Example 3 queries a curve at regular intervals to determine the
coordinates of points along the curve. The next snippet of Mel code demonstrates
the basic technique of performing such a query.
global proc getCurveData(string $tnode, float $step, vector $data[])
{
int $count = size($data);
string $part;
float $pos[];
int $spans = `getAttr ($tnode + ".spans")`;
for($i = 0.0;$i <= 1.0;$i = $i + $step) {
$pos = `pointOnCurve -pr ($i * $spans) -p $tnode`;
$data[$count] = <<$pos[0], $pos[1], $pos[2]>>;
$count++;
}
}
vector $data[];
getCurveData("curve1", 0.005, $data);
for($i = 0; $i < size($data); $i++) {
vector $pos = $data[$i];
print($pos.x + " " + $pos.y + " " + $pos.z + "\n");
}
The next code sample is the Mel equivalent of the python code that queries
particle positions - listings 4.2, 4.4 and 6. It is provided here merely to
demonstrate how such a query is done using Mel.
global proc getParticleData(string $tnode, vector $data[])
{
int $count = size($data);
string $part;
float $pos[];
int $num = `particle -q -ct particle1`;
for($n = 0; $n < $num; $n++) {
$part = $tnode + ".pt[" + $n + "]";
$pos = `getParticleAttr -at position $part`;
$data[$count] = <<$pos[0], $pos[1], $pos[2]>>;
$count++;
}
}
vector $data[];
getParticleData("particle1", $data);
for($i = 0; $i < size($data); $i++) {
vector $pos = $data[$i];
print($pos.x + " " + $pos.y + " " + $pos.z + "\n");
}
|