MAYA MEL 基础
1 MEL代码基础
1.1数据类型
<1>int
存放整数,一般为32位,有些平台可能为64位,默认值为0
<2>float
存放实数,类似于C中的double类型,一般为64位,但是有些平台可能也不一样,默认值为0.0
<3>string:字符串
用双引号包围起来,字符串的基本操作有:连接(使用”+”号将两个字符串连接),求长(使用size函数计算长度),分割(使用tokenize函数将字符串分割子字符串),默认值为空字符串。跟C中的字符串风格类似。
<4>vector:矢量
用于存放3个float型数据,一般用于存放顶点坐标,可以使用.x,.y,.z属性读取其中的3个数据,但是不能单独对其中的一项赋值。默认值<<0.0,0.0,0.0>>
<5>array:数组
使用具体的类型定义一个数组,用法和C中的一样使用方括号([])进行定义,使用 size函数获得数组的长度,使用下标访问数据,第一个数据的下标为0。
跟C不同的是MEL中的数组长度可以动态改变,将数组长度作为下标对其赋值,数组长度加1并存储这个新元素。假如越界的下标比数组长度还大,对这个下标的元素赋值,则数组的长度为新下标减1,中间未赋值的元素为这个数组类型的默认值。
使用clear函数清空数组
<6>matrix:矩阵
是一个二维矩阵,存放float类型的数据,使用C中的二维数组访问方式,第一个数据的下标为[0][0],矩阵的大小定义之后不能再改变。
矩阵初始化示例:
matrix$mat[2][4] = <<1,2,3,4;5,6,7,8>>;//没行用分号分隔
使用whatIs可以查询变量或函数的类型
1.2 变量定义及类型转换
(DataType) $varName;
每个变量名前面都要带一个美元符($),定义变量可以不设定变量类型,而是直接声明,它的类型根据后面给它所赋的值来确定。
假如一个变量使用一个类型确定后(定义时未使用类型名时由系统确定),在后面给它赋值不同类型的值都会尝试转换为定义时的类型。所以在赋值的时候要注意变量的类型,不然可能会发生数据截断。
MEL数据类型转换之间的规则
原类型 |
转换类型 |
示例 |
int |
float |
float $i = 3; //Result: $i = 3.0 |
int |
vector |
vector $v = 3; //Result: $v = <<3.0,3.0,3.0>> |
float |
int |
int $i = 3.45; //Result: $i = 3; |
float |
vector |
vector $v = 3.45; //Result: $v = <<3.45,3.45,3.45>> |
vector |
int |
int $i = <<1,2,3>> //Result:$i=3;为矢量长度整数部分 |
vector |
float |
float $i = <<1,2,3>> //Result:$i=3.7416;为矢量长度 |
1.3 运算符
赋值运算符: =
算术运算符:+ - * / %(求余) ^(两个矢量的叉乘,v1^v2)
两个矢量用*相乘为它们的点乘
布尔运算符
true, yes, on, 1
false, no, off, 0
假如将布尔变量用于算术运算,可以发现它使用vector进行计算
比较运算符 < > <= == !=
逻辑运算符 || && !
运算符的优先级跟C中的一样
1.4 代码块
每条代码使用分号结束,每个语句块使用大括号分割,有如下可以使用的循环
for ,while ,do while,switch
和c一样
for in
for($elems in $vals) …可以对数组,向量等数据类型使用这类遍历
1.5 过程
相当于C中的函数,定义形式如下
proc returnType procName(DataType 1val1,DataType2 val2,…)
要使用关键字proc,下面是一个示例
proc int sumTwo(int $val1,int $val2)
{
int $sum = $val1+$val2;
return $sum;
}
int $t = sumTwo(3,5);
print $t;
//Result:8
当一个定义好的过程使用CTRL+ENTER提交到MEL系统中后,同一文件中的代码就能调用它了。
1.6 全局变量
为了可以在不同的MEL文件中进行数据交互,可以使用全局变量实现。定义了全局变量后,就可以在Maya内随时访问它。定义形式如下:
global DataType $valName;
相对于普通变量的定义在前面添加了一个global关键字。要访问全局变量,需要先声明这个全局量,假如前面定义了一个$fileName的string类型全局变量,现在要访问它:
global string $fileName ;//首先声明
$fileName = “e:/proj1/skinning.mb”;
假如这处没有使用global关键字,则$fileName会被当做是一个局部变量。
全局变量一般在定义的时候初始化,在定义后不能再做初始化,而是只能先作一个声明,然后再操作这个全局变量。
使用命令env可以查看当前MAYA中定义的所有全局变量。
1.7 全局过程
也是使用关键字global定义全局过程。定义后可以在Maya中任意调用
在ScriptEditor中定义的变量和过程都自动是全局的,所以要想定义的变量和过程可撤销,应该在最外部使用花括号({})。
2 MEL命令
学习MEL编程的根本目的就是为了使用这些内部命令,MAYA提供了许多的MEL命令,网上有一个MEL reference,可以查询MEL的所有命令
<1> help <commandName>
要查询某个命令的具体用法,最简单的办法是在命令行或命令编辑器中输入help commandName
<2> 执行命令
commandName args;
可以写在MEL程序中,或直接写在命令行、命令编辑器中
<3> 命令返回值
许多命令都有一个返回值,使用左引用符号(``,TAB键上方)或eval函数
如:
$clusters = `ls -type "skinCluster"`;
string $cmd = “4 + 9”;
int sum = eval($cmd);
3 MEL文件加载
MEL文件自动保存的时候被存放到maya/scripts文件夹下。运行MEL文件中的过程有两种方式。
<1>直接调用
将过程定义为全局的过程,存放到默认文件夹下,文件名为过程名.mel,下次maya启动后就可以直接调用这个过程了
<2>源化后调用
使用source命令将mel文件源化,就是将其加载到maya中,然后就可以调用这个mel文件的任意过程了。这种做法对应的mel文件中的过程也要是全局的,但不必使过程名和mel文件相同,示例:
source "e:/kfq/mel/mel_test.mel";
test_proc;
使用getenv MAYA_SCRIPT_PATH可以获得Maya的脚本路径。Maya在默认的情况会搜寻这些路径下的脚本,假如要添加自己的路径,可以在Maya.env文件添加MAYA_SCRIPT_PATH = my_custom_path(使用正斜杠将文件夹分开)。Maya.env可以通过命令about -environmentFile查询获得。
MAYA每次启动的时候,都会运行脚本目录下面的名为userSetup(.mel,.py)的文件。
4 示例程序:
<1>分割字符串
比如取出一个三角形面的三个顶点的索引
select -rMesh.f[i];
string $face[] = `polyInfo -faceToVertex`;//得到的结果为:FACE 727: 529 530 531
string $buffer[];
tokenize$ face[0] " " $buffer;
执行这段代码得到的结果为以空格分割的几个字符串,存放到了数组buffer中
<2>将选中的顶点输出到文件
proc outputsel(string $fileName,$string $regionName)
{
string $sels[] = `ls -selection`;
string $strTotal;
$fileId = `fopen $fileName "a"`;
for($i=0;$i<size($sels);++$i)
{
string $buffer[];
tokenize $sels[$i] "." $buffer;
string $str = `substring $buffer[1] 5(size($buffer[1])-1)`;
string $buffer1[];
tokenize $str ":" $buffer1;
if(size($buffer1)>1)
{
int $start = int($buffer1[0]);
int $end = int($buffer1[1]);
for($k=$start;$k<=$end;++$k)
{
$strTotal = $strTotal +string($k)+"\n";
}
}
else
{
$strTotal = $strTotal +$buffer1[0]+"\n";
}
}
fprint $fileId $strTotal;
}