1、打开脚本编辑器
可以通过选择Window > General Editors > script Editor或者点击Maya窗口右下部的script Editor图标打开脚本编辑器。
脚本编辑器提供以下菜单选项:
Open script--打开脚本程序
Source script--把一个脚本程序文件作为源文件
Save Selected--保存脚本程序
Execute--执行脚本程序
Clear History--清除历史
Clear Input--清除输入
Echo All Commands--返回所有指令的返回值
Show Line Numbers--显示行号
Show Stack Trace--显示堆栈跟踪
编辑命令
下表列出了在脚本编辑器中有效的键盘命令。(在表达式编辑器和一些输入框中它们也是有效的。) 命令 定义 平台
Ctrl+c Copy IRIX、Windows
Ctrl+x Cut IRIX、Windows
Ctrl+v Paste IRIX、Windows
Ctrl+k 删除到本行末 IRIX
Ctrl+d 删除下一个字符 IRIX
Ctrl+a 移动光标到行首 IRIX
Ctrl+e 移动光标到行末 IRIX
Ctrl+a 选择编辑框中的所有文字 Windows
-------------------------------------------------------------------
2、打开一个脚本程序
我们可以打开一个脚本程序以便检查、执行或找出它的问题。打开一个脚本程序时并不执行它。
只是在脚本编辑器的输入栏里简单地把它显示出来。
要执行显示在脚本编辑器的输入栏里的一些或者全部脚本程序,可以用鼠标选择它,然后按键盘的数字Enter键。
当你想把一些或者全部内容拖拉到柜架上并在那里产生一个图标时,打开一个脚本程序就是非常有用的。
可以点击该图标执行这个程序。
为了打开一个脚本文件:
1--从脚本语言编辑器中选择File > Open script。出现一个文件浏览器。
2--选择要打开的脚本文件。
-------------------------------------------------------------------
把一个脚本程序作为源文件
把一个MEL脚本程序文件作为源文件,执行所有的MEL指令并声明包含在该脚本程序文件中的所有的全局过程。
如果你在一个脚本程序文件中修改了一个程序,Maya 并不把这个改变登记给该程序,直到你把它的程序文件作为源文件。
这是因为Maya把执行了的程序保存到了存储器中。当你把一个脚本程序文件作为源文件时,Maya再次读该脚本程序文件里的那个程序。
为了把一个脚本程序作为源文件:
1--从脚本语言编辑器中选择File > Open script。出现一个文件浏览器。
2--选择要打开的脚本文件。
把一个脚本程序作为源文件之后,该文件里的所有MEL指令会执行。该脚本程序中的所有全局过程会被声明,但并不被执行。
MEL指令是按照它们出现在文件中的顺序执行的,并且应当没有错误。如果产生了一个错误,执行会中断并不再装载更多的程序。
当你把一个MEL脚本程序作为源文件之后,不声明或者不执行局部过程。
但是,如果你是通过在脚本编辑器或指令行里输入而声明了一个局部过程,该过程会被声明为全局过程,你可以在任何时候执行它。
执行一个程序可以通过执行一个MEL指令实现。当你想把一个脚本程序作为源文件,并具有执行该文件中的程序的作用时,这是很有用的。
为了这样做,要首先声明该程序,然后声明通过一个文件浏览器执行该程序的指令。
-------------------------------------------------------------------
4、保存脚本文字
使用File > Save Selected指令从脚本编辑器保存脚本文字。可以从指令输入(底部)将文字高亮化,
也可以通过脚本编辑器的状态信息(顶部)部分。Maya 将会把高亮的文字部分保存到你说明的目录里的一个 .mel 文件中。
-------------------------------------------------------------------
5、执行一个脚本程序
当你想执行一个预先已经源化了的脚本程序时,可以在脚本编辑器的指令输入栏(底部)输入该程序的名字,然后进行下面工作中的一种:
按 Ctrl + Enter 键;
或者
按数字键盘的 Enter 键;
或者
从脚本编辑器里选择 Edit > Execute。
也可以使用这些指令执行一个在脚本编辑器里已经打开了的脚本程序的定义。如果MEL脚本定义没有出现失败,
则该定义是从脚本编辑器的底部移到顶部。否则该定义不会移动,并且在顶部会显示出一个错误信息。
提示:
可以首先选取MEL script的一部分然后只执行这一部分(Ctrl+Enter)。 它不会删除其它部分。
-------------------------------------------------------------------
6、清除状态信息
要清除状态信息(脚本编辑器的顶部),从脚本编辑器里选择Edit > Clear History。这将会删除掉所有的状态信息文字。
使用这个指令时应当小心一些,因为没有办法撤消它。
-------------------------------------------------------------------
7、清除指令输入
要清除指令输入文字(脚本编辑器的顶部), 从脚本编辑器里选择Edit > Clear Input。这将会删除掉所有的指令输入文字。
使用这个指令时应当小心一些,因为没有办法撤消它。
-------------------------------------------------------------------
8、响应一个指令
当你用Maya工作时,对应的MEL指令常常出现在脚本编辑器的顶部。缺省情况下,只有那最重要的指令才会显示。
你可以在脚本编辑器里选择Edit > Echo All Commands ,虚拟地显示与你的Maya作用相关的所有指令。
它可以帮助你学习哪些MEL指令触发作用。
在你的Maya的作用之间并不是总有一对一的对应关系,这些指令返回响应到脚本编辑器里。
如果你使用一个脚本程序去打开属性编辑器,一些MEL指令出现在脚本编辑器里(响应是打开的):
buildObjectEdMenu MayaWindow│menu4│menuItem56;
editSelected;
editMenuUpdate MayaWindow│menu2;
但是,只有以下的MEL指令需要引入属性编辑器:
editSelected;
同时,对于一些作用来说,也不总是会将MEL指令的响应返回到脚本编辑器里。如,当你选择了一个属性编辑器时,
脚本编辑器的顶部没有返回任何信息。
要关闭返回信息,从脚本编辑器里再次选择 Edit > Echo All Commands。
-------------------------------------------------------------------
9、显示程序中的语句行号
如果你在执行一个长的程序时由于错误而出现了问题,可以打开脚本程序的行号,你就可以更容易地找到错误。
要显示错误指令的行号,从脚本编辑器里选择Edit > Show Line Numbers。当你打开了Show Line Numbers选项,
Maya 在脚本编辑器状态信息框(顶部)的旁边显示脚本程序的行号。
要关掉行号,在脚本编辑器菜单里再次选择Edit > Show Line Numbers。
Maya将显示行号的设置保存下来作为以后使用。如果打开了行号,当下一次你运行Maya时它们会出现在脚本编辑器里。
-------------------------------------------------------------------
10、显示堆栈跟踪
如果你用埋入的脚本程序文件执行一个脚本程序时出现了问题,打开堆栈跟踪选项显示文件结构中的脚本程序错误。
要显示一个脚本文件的堆栈跟踪,在脚本编辑器里选择Edit > Show Stack Trace。Maya会在一个窗口里显示堆栈跟踪,
在脚本编辑器里显示一个错误信息
[page]
使用脚本语言结点
一个脚本语言结点是一个包括了一个MEL脚本语言程序的结点。
当该结点产生或者当该结点被破坏时,该程序被执行,它取决于脚本结点的类型。
本章包括以下内容:1、了解脚本语言结点;2、产生脚本语言结点;3、测试脚本语言;4、编辑脚本语言结点;
5、设立脚本语言结点的执行;6、删除脚本语言结点。
--------------------------------------------------------------------------------
1、了解脚本语言结点
脚本语言结点是把一个MEL脚本语言程序存储到一个Maya场景文件中的一种方法。
脚本语言结点也包含了用于产生用户界面的所有MEL指令,并被用MAYA文件保存。
你可以用不同的方法执行脚本语言程序。可以指明一个脚本程序结点执行它的程序:
当该结点是从一个文件中读出的;
在渲染一桢图像的之前或者之后;
在渲染一个动画的之前或者之后。
当一个文件关闭着时使用File > Open或者File > New
一个脚本语言程序结点有三个属性:
Before、After和Type。决定于脚本程序的类型,当执行该程序时,说明Before和After属性。
-------------------------------------------------------------------
2、产生脚本语言结点
可以使用表达式编辑器产生脚本语言结点。
为了产生一个脚本语言结点:
1--选择Window > Expression Editor。
2--在Expression Editor中选择Select Filter > By script Node Name。
任何现存的script Nodes显示在script Nodes表中。
3--在Expression Editor的script window中输入脚本程序。
4--在script Node Name框中输入一个名字。
5--定义你想要使脚本成为一个之前或者之后的脚本程序。
6--点击Create键。
这产生脚本结点。现在你可以定义它的类型。
7--从Execute On 下拉菜单里选择以下的一个脚本程序结点类型:
Demand
当你使用scriptNode指令,隐含地需求它时,运行脚本文件(看在线指令文件的scriptNode指令的信息)。
忽略这种类型的脚本文件的之前和之后的属性。
Open/Close
如果你已经指定了该脚本文件作为之前的脚本文件,当以批处理模式读文件时脚本被执行。如果你把它
作为之后的脚本文件,当文件被关闭或者没有以图示用户界面模式提供,或者当该结点被删除时,它被执行。
GUI Open/Close
如果你已经指定了该脚本文件作为之前的脚本文件,当以图示用户界面模式运行MAYA,在读文件时脚本文件
被执行。如果你把它作为之后的脚本文件,当文件被关闭,或者没有以图示用户界面模式提供,或者当该结
点被删除时,它被执行。
UI Configuration (内部)
之前的脚本文件包括了用户界面设置的信息。它是由Maya或者一个plug-in为了保存面板排列和编辑状态信息
而自动的产生的。当你打开一个文件时,这个脚本结点执行它的脚本文件。在执行之后,该结点被删除掉。之
后的脚本是不会运行的。如果一个文件被提供或被输入,这个结点将会不存在。
软件渲染
如果你选派好脚本作为之前的脚本,脚本的执行在一个动画之前被渲染。如果你选派好脚本作为之后的脚本,
脚本的执行在一个动画之后被渲染。
软件桢渲染
如果你选派好脚本作为之前的脚本,脚本的执行在一个桢之前被渲染。如果你选派好脚本作为之后的脚本,脚
本的执行在一个桢之后被渲染。
8--点击Edit键给脚本结点赋类型。
9--如果你想增加另外一个脚本结点,点击New script Node键。
script窗口和script Node Name框被清除,你可以输入一个新的脚本结点。
-------------------------------------------------------------------
3、测试脚本程序
可以使用表达式编辑器对脚本程序进行测试。
为测试一个脚本程序:
1--选择Window > Expression Editor。
2--在表达式编辑器中选择Select Filter > By script Node Name。
3--在script window中输入脚本程序,或从script Nodes 表中。
4--点击Test script键。
错误显示在脚本语言编辑器中。
-------------------------------------------------------------------
4、编辑脚本语言结点
可以使用表达式编辑器对脚本语言结点进行编辑。
为了对脚本语言的编辑定义一个编辑器:
1--选择Window > Expression Editor。
2--在表达式编辑器中选择Select Filter > By script Node Name。
3--从编辑器下拉菜单中选择一个编辑器。
为了编辑一个脚本语言结点:
1--选择Window > Expression Editor。
2--在表达式编辑器中选择Select Filter > By script Node Name。
3--选择你想在script Nodes list中要编辑的脚本语言结点。
4--在script window中编辑该脚本语言结点。
5--如果你想撤消你的改变,点击Reload。Maya重装原来的脚本语言结点。
6--为了清理script window,点击Clear键。
-------------------------------------------------------------------
5、设立脚本语言结点的执行
为了设立脚本语言结点的执行:
1--选择File > Open Scene。或选择File > Open然后在Open Scene window中点击Options。
2--点击复选框将Execute script Nodes打开或者关闭。
[page]
一、了解 MEL
MEL (Maya埋入式语言)为Maya提供了基础。Maya界面的几乎每一个要点都是在MEL指令和脚本程序上建立的。由于Maya给出了对于MEL自身的完全的访问,你可以扩展和定制Maya。通过MEL,你可以进一步开发Maya使它成为你和你的项目的独特而创新的环境。
为有效地使用Maya,你并不非得精通MEL。但是,熟悉MEL可以加深你使用Maya的专业能力。使用MEL的许多方面可以由只有很少编程经验或者没有经验者所使用。喜欢MEL并不非得喜欢编程。 有一些方法,它们可以使你获得MEL的好处而不必考虑编程的细节。一旦当你进行了产生MEL脚本语言的尝试,你会发现MEL可以给你提供可以想象到的最先进的数字化画图的方法。
为了获得Maya的输出,大部分可以使用MEL来做。这里是你可以使用MEL来工作的一些例子: ·使用MEL指令脱开Maya的用户界面,快速地产生热键,访问更深的要点。
·给属性输入准确的值,脱开由界面强制引起的拘谨的限制。
·对特定的场景自定义界面,对一个特定的项目改变缺省设置。
·产生MEL程序和执行用户建模、动画、动态和渲染任务的脚本程序。
如何使用本教程
本教程叙述如何学习和使用Maya埋入式语言(MEL)。如果你初次接触MEL,本教材帮助你在使用MEL指令和脚本程序方面开始起步。一旦当你开始开发MEL程序的时候,本教材将继续帮助你,讲解如何能够使你获得用MEL产生的更多的指令、宏、程序和用户界面元素的输出。
本教材假定你对Maya已经有了基本的了解。如果你完全是新开始学习Maya,请看一下学习Maya的教材,并对在Using Maya documentation set中描述的要点进行开发。 应该熟悉Maya的在线文件(见Online documentation)。特别是应该使你自己熟悉MEL Command Reference和DG Node Reference。
本教材的各处都有许多有关的MEL指令和程序码的例子。要运行例子程序,你可以把它们粘贴到Maya的脚本语言编辑器(script Editor)里,并选择Edit > Execute就可以了。使自己进一步地熟悉脚本语言编辑器的要点,执行脚本程序,并把程序保存到Maya的script目录中的一个文件中,可以参考Maya文件和用户指南中的适当章节。
如何学习更多的MEL内容
为了学习更多的MEL内容,可以通过以下途径:
·在线文件
·训练课程
·网站资源
在线文件
本教材提供了一个使用MEL指令、程序和脚本语言的总的概览。有关特定的MEL指令的详细信息,请参阅MEL Command Reference。
当你学习MEL时,你会发现你需要学习更多的有关Maya的相关图节点(dependency graph node)的内容。在线的DG Node Reference文件详细地描述了Maya的相关图节点。
训练课程
为了学习更多的有关Maya和MEL的内容,请考虑学习Alias│Wavefront的训练课程。这些课程向你介绍MEL指令和脚本语言程序,还可以向你提供最主要的内容的深层知识。要学习更多有关MEL的内容,可以先从MEL基本教程开始。
在Alias│Wavefront的网站aliaswavefront.com(Express Link to Training)中的课程安排和描述是有效的。关于课程的有效性、价格和登录的最新的信息,可发Email给training-info@aw.sgi.com,电话是416-874-8760或1-877-927-7478 (option 4),或FAX 416-369-6131。
网站资源
Alias│Wavefront的Assistant Online提供了许多有关Maya的教材,包括含有产生MEL脚本程序的教材。
更多信息可以访问Alias│Wavefront网站:aliaswavefront.com。
另外,Highend3D的highend3d.com网站介绍了MEL 脚本程序并连接到更多的有关MEL和Maya的信息。
为了获得MEL和Maya的大部分的输出,请开发和利用这些训练课程和网站资源。
--------------------------------------------------------------------------------
二、MEL要点
使用MEL的要点包括了使用MEL指令和产生MEL程序。
本章包括以下内容:指令、程序、Maya Gems共三个部分。本期介绍MAYA脚本语言MEL的指令。
分为以下三个部分:1、了解指令;2、MEL指令文件;3、使用指令。
1、了解指令
MEL包括了涉及使用Maya的所有方面的全范围的指令。使用MEL指令的一些典型的例子包括快速产生物体、精确移动物体和对物体进行更有效的控制。如,可以使用下述的一个MEL指令产生一个半径准确的为27.5 单位的叫做 bigBoy 的一个球体:
sphere -radius 27.5 -name bigBoy;
随后你还可以再输入一条MEL指令将bigBoy绕Z轴旋转90度:
rotate -r 0 0 90 bigBoy;
另一个例子,假定你在用结点工具产生一个结点,你想把这个结点沿着X轴方向移动5个单位。你可以执行以下的MEL指令,而不需要打断结点的产生:
move -r 5 0 0;
2、MEL指令文件
Maya的在线库(Online Library)描述了每一条指令,提供了用法、格式、返回值和例子的信息。MEL的指令参考在线文件(Command Reference online documentation)提供了以字母顺序排列的指令,也以功能方式加以组织。
3、使用指令
包括内容有:输入指令、使用指令行、获得指令返回值、指令模式和指令在表达式中。
⑴、输入指令
Maya提供了一些输入MEL指令的方法;使用脚本语言编辑器(script Editor)或者指令行(Command Line)是最常用的方法。你也可以在脚本程序文件、Maya ASCII(.ma)文件、工具柜图标(shelf icons)、热键以及表达式中执行指令。但是最常用的还是在脚本语言编辑器中输入指令。
无论如何输入指令,所有的MEL指令必须用一个分号结束。以下是MEL 指令的一些例子:
sphere -name roundy;
setAttr roundy.translateX 7;
whatIs ls;
help ls;
ls -typ nurbsSurface;
⑵、使用指令行
可以使用指令行输入MEL指令。如果指令行没有出现,在MAYA主菜单中选择Options > Command Line使指令行出现。
虽然在指令行和脚本语言编辑器中都可以输入指令,但两者之间有一些重要的区别:
你可以从指令行,使用数字键盘或字符键盘的Enter键输入指令。而脚本语言编辑器只能用数字键盘的Enter键。
指令行只有一行,执行一个MEL指令。为了输入更多的MEL指令,指令之间可以?quot;;"分开。
指令行仅将结果的最后一行显示到右边。而脚本语言编辑器显示所有的结果。
⑶、获得指令返回值
Many MEL指令返回一个值。为了抓取这个返回值,可以用单引号或者eval指令。
使用单引号获得指令返回值
用单引号"`"将指令前后标注出来可以返回指令的输出。随后你可以把这个输出赋给一个变量并在脚本语言编辑器中显示它。
例
string $a[];
$a = `particle -p 5 0 5 -name Sun`;
print($a);
第一条语句定义了一个名为$a的阵列。第二条语句执行引号中的MEL指令,并把指令的输出赋给$a。第三条指令把$a的内容显示给脚本语言编辑器,如下:
Sun
SunShape
可以对任何一个MEL指令保存和显示其结果。返回值的类型是由你使用的指令决定的。在以上例子中,粒子命令返回一个字符串阵列。所以,等式左边的变量符号也须要是接受这个返回值的字符串阵列的类型。
使用eval指令获得指令返回值
eval指令执行一个命令,也让你抓取返回值。它比起单引号有一个优点,因为你可以从一个字符串建立一个指令。象单引号方式那样,也可以把输出赋给一个变量并显示它。
例
string $command = "sphere";
eval($command + " -r 5");
第一条语句把字符串sphere标注给变量$command。第二条指令给字符串sphere添加 -r 5,并执行完整的指令sphere -r 5。它产生一个半径为5个格子单位的球体。
有关eval指令的更多的信息,见掌管指令的在线文件。
⑷、指令模式
MEL指令选项典型地在以下一种或多种模式中起作用:query、编辑和产生。Query模式是用于找出一些事件的值;编辑模式是用于改变一些事件的值;产生模式是产生一些事件。在在线MEL指令参考中,指令选项的描述包括一个Q、E或C以指示query模式、编辑模式、产生模式。
⑸、指令在表达式中
可以在一个表达式中执行MEL指令和序列。但是,如果你执行以下的指令你的场景会产生故障:
断开或连接属性
删除或产生物体或者其他项
在一个表达式中播放你的动画不会撤消MEL指令的执行。例如,如果你的表达式执行MEL指令产生了一对球体,播放这段动画时并不删除原来的球体。再次播放该场景时会产生另一对球体。
不过你可以通过选择Edit > Undo撤消MEL指令,但是如果你的场景有故障时,它将会不工作。还要注意,你可以只撤消Queue尺寸的设置所允许的许多运算。为设立Queue 尺寸,选择Options > General Preferences。
当你从指令行执行一个指令时,状态信息出现在脚本语言编辑器中和指令行的响应区域里。当在一个表达式中执行指令时,不显示这个信息。 关于表达式的更多的内容,请参考Using Maya: Expressions。
--------------------------------------------------------------------------------
[page]
三、概述MAYA脚本语言
本章包括以下内容:1、了解脚本语言;2、设立脚本语言环境。
1、了解脚本语言
编写脚本语言程序是产生Maya埋入式语言(MEL)脚本程序的过程。一个脚本语言程序是一个MEL指令或者MEL序列的集。通过产生脚本语言程序,你可以利用Maya的用户界面使执行任务自动化,可以获得"under the hood"访问Maya所有的各个部分,还可以对界面进行扩展和自定义。
2、设立脚本语言环境
为了设立脚本语言环境,需要考虑以下内容:
⑴、脚本语言文件
⑵、建立脚本语言路径
⑶、在脚本语言程序中使用程序
⑴、脚本语言文件
一个MEL脚本文件(*.mel)是一个包含MEL指令、MEL程序或者二者都有的文件。典型地,是用一个MEL脚本文件执行一系列的指令。如,可以写一个脚本程序以产生一个墙形状的物体,然后再给它施加一个砖的纹理。
可以用一个文字编辑器写一个MEL脚本文件然后把它保存到磁盘的一个文件中。MEL脚本文件使用文件扩展名 .mel。可以把脚本文件用于不同的场景中和不同的工作期间中。当执行一个MEL脚本文件时,它并不变成为场景的一个部分,因此如果你要想重复它的作用时,应该每次都执行该脚本程序。
⑵、建立脚本文件路径
在缺省状态下,Maya在你的scripts目录中查找MEL脚本文件。
在缺省状态下,这个目录定义在你的login名下。例子如下:
(IRIX) ~elvis/maya/scripts
(Windows NT) C:\Aw\Elvis\maya\scripts
使你的脚本文件可以运行的最简单的方法是把它们放在上述路径里。
注意你的scripts目录缺省地包含了一些脚本文件。它们以menu_作为名字的开始,用于Maya内部。
你可以给MAYA用于查找脚本文件的缺省路径增加目录。
为脚本文件路径增加一个目录(在IRIX中):
1--在一个IRIX shell中,设立环境变量MAYA_script_PATH给附加目录的路径。
2--从这个shell启动MAYA。
为脚本文件路径增加一个目录(在Windows NT中):
1--使用Windows NT Explorer或者My Computer,显示Maya NT bin目录的内容。
缺省时是C:\Aw\MayaX.X\bin。
2--双击MayaEnvironment.exe启动该程序。
这样显示出了你的home、project、plug-in、script和bitmap目录的路径。该路径包括在安装期间产生的缺省路径和你后来定义的任何路径。不能改变缺省路径。
对于plug-in、script和bitmap路径,用分号(;)分离路径,这些项可以定位。
在这个窗口中禁止编辑路径。但你可以用以下的步骤代替。
重要事项:
如果你的计算机上安装了Maya NT的多个版本,你会看到一个版本的路径。版本号是在窗口的标题栏里。为了看另外的版本的路径,点击Previous或Next。为了保存一个版本的路径,点击Save。如果你的计算机只装了一个版本,这些键会变暗。
3--点击Maya script Path框旁边的Change键。
注意,如果你改变了Home路径,这就按照新的home路径改变了project、plug-in、 script和bitmap路径。会询问你是否想这样做。点击Cancel可以放弃这个改变。
4--在Change Setting窗口中输入(或者编辑)一个路径。
一般地,可以增加缺省路径,但是不能重置它们。当你定义路径时使用左斜线或者右斜线。
为了定义一个远程路径,可以将一个隐含目录与你的计算机上的一个驱动器字符对应起来。细节请看你的Windows NT文件。
如果需要输入多个路径,使用分号把这些路径分离开。
如果要使用一个文件浏览器从别的文件系统查找和选择一个路径,点击Browse。
为了返回到你原来的缺省路径中,点击Restore Default。这对于当你定义了一个不正确的路径或者想删除废弃的路径是非常有用的。
5--点击OK。
例子(IRIX)
为了给scripts路径增加~/maya/scripts/clipFX and remote/X/scripts目录,在启动MAYA之前给IRIX增加以下目录:
setenv MAYA_script_PATH ~/maya/scripts/clipFX:/remote/X/scripts
随后Maya将能够在~/maya/scripts, ~/maya/scripts/clipFX, 或者/remote/X/scripts中找到你的脚本文件。
⑶、在脚本文件中使用程序
你可以在MEL脚本文件中使用全局和局部程序。全局程序在它们的文件外边是可见的;局部程序仅在它们的文件内部是可见的。
如果Maya遇到一个没有定义的指令,它会为找到一个与该指令有相同基名的MEL脚本文件搜索脚本路径。当它找到该文件之后,它在该文件中会声明所有的全局MEL程序。任何具有与该指令有相同基名的全局程序会被执行。
如,假定你在运行一个sayWhat指令。因为没有这样的一个sayWhat指令,Maya会在它的所有的script路径中对一个叫做sayWhat或者sayWhat.mel的文件进行搜索。如果在一个script目录中,它找到了有以下内容的sayWhat.mel脚本文件:
proc red5() {print("red5 standing by...\n");}
global proc sayWhat() {print("sayWhat online\n");}
global proc GoGo() {print("GoGo online\n");}
然后全局程序sayWhat和GoGo被声明,并执行sayWhat程序。结果是:
sayWhat online
因为GoGo全局程序已经声明过了;现在就可以在指令行中或者在脚本语言编辑器中输入GoGo运行它。
使用MAYA内部脚本文件
Maya有一些用于它的用户界面和其他运算细节的MEL脚本文件。你可以在Alias│Wavefront中查找这些脚本文件,学习专业脚本程序作者的这些技术。这些脚本文件是在由缺省定义的以下述目录开始的目录中:
(IRIX) /usr/aw/mayaX.X/scripts
(Windows NT) C:\Aw\MayaX.X\scripts
其中X.X是Maya的版本号。
注意:
不要在这个目录中修改或者插入脚本文件;该目录是保留Maya用户界面工作用的脚本文件的。改变这些文件可能会影响Maya的操作。
如果你想在这个目录中修改脚本程序以改变Maya的界面,先要把它们拷贝到你的局部scripts目录中。如果你的局部scripts目录中有与Maya内部script文件目录中相同名字的脚本文件,那你的局部scripts目录中的文件会被运行。
使用脚本语言编辑器
[page]
6、删除脚本语言结点
可以使用表达式编辑器删除脚本语言结点。
为了删除一个脚本语言结点:
1--S选择Window > Expression Editor。
2--在表达式编辑器中选择Select Filter > By script Node Name。
3--选择你想在script Nodes list中要删除的脚本语言结点。
4--点击Delete按键
定义数据
本章描述MEL的数据类型它们之间的转换:1、变量;2、常数;3、数据类型转换;4、限制。
--------------------------------------------------------------------------------
1、变量
所有变量名以$开始。变量名不包括空格和特殊字符。你可以使用下划线和数字作为变量名但开头不能是数字。
识别大小写,如$temp不同于$Temp。
例:
int $radical7Mark; // 有效
int HEYchief; // ERROR: 开头缺"$"
int $ nine; // ERROR: 开头不是"$"
int $_VAL_ID___AIT_; // 有效
int $howdyYa`ll; // ERROR: 含有无效字符
int $1Bill; // ERROR: 开头不能是数字
有以下五种变量类型:
类型 意义 例子
int 整数 (...-2, -1, 0, 1, 2...)10, -5, 和 0
float 小数 392.6, 7.0, and -2.667
string 一个或更多的字符 "Whats up, chief?"
vector 三个浮点数 <<3,?7.7,?9.1>>
matrix 浮点数阵列 <<1.1, 2, 3; 6.7, 5, 4.9>>
以上类型除matrix外,都可以是一个阵列。如,一个三元素的整数阵列是一个跟一个的三个整数。
声明和标注变量
声明一个变量是说明变量的名字和类型;标注一个变量是给已生命的变量一个专有的值。下例是将声明和标注合为一步:
int $temp = 3;
float $Temp = 222.222;
string $tEmp = "Heya kid.";
vector $teMp = <<1, 2.7, 3.2>>;
matrix $temP[2][3] = <<4.5, 1, 0.2; -13, 9911, 0.007>>;
当生命矩阵变量时,必须包括二维阵列的尺寸。
下例说明对整型、浮点、字符串和矢量阵列型变量阵列的声明和标注:
int $TEmp[5] = {100, 1000, -70, 2, 9822};
float $TeMp[4] = {43.3, -10.7, 0, 82.5};
string $TemP[3] = {"Lord", "Flies", "cool brown fox2."};
vector $tEMp[2] = {<<0, 0, 0>>, <<0.01, -2, 16>>};
如果一个变量被声明但未被标注,它的所有的值是0;字串变量则?quot; "。
float $teMP; // 赋值: 0;
string $TEMp[3]; // 赋值: {"", "", ""};
vector $TEmP[2]; // 赋值: {<<0, 0, 0>>, <<0, 0, 0>>};
matrix $TeMP[3][2]; // 赋值: <<0, 0; 0, 0; 0, 0>>;
如果一个变量被声明或者被使用而没有定义它的类型,它被隐含声明为将要赋值给它的那种类型。
$tEMP = 0.0; // 浮点数
string $TEMP[]; // 零元素字符串阵列
$trip = "heya Buddy"; // 字符串
$rip = {1, 2, 3, 4}; // 四元素整型阵列
$lip = <<1, 2.1; 3, 4>>; // 2X2 矩阵
$flixp = $TEMP; // 零元素字符串阵列
注意值0.0是一个浮点数,而一个0值是一个整型数。这决定了在隐含声明时是产生一个浮点数还是产生一个整型数。
不建议使用隐含声明,因为它不象变量的隐含声明那样的清楚。
保留字
MEL的保留字可以是一个变量类型、控制逻辑或是表达一个值。以下是MEL的保留字:
break case continue default do else
false float for global if in
int matrix no off on proc
return string switch true vector while
yes
数据类型关键字
int float vector string matrix
布尔常数关键字
yes no on off true false
流动控制关键字
if else for while do in break continue default switch case
其他关键字
global return source catch alias proc
保留字也区分大小写。所以int是整型,Int不是。实际上alias、source、catch 也是保留字,但它们起指令作用,
因此没有被包括在上述表内。
字符串
字符串可用"+"运算连接。
string $what = "Whale";
string $title = "Great" + " White " + $what;
这将使title变量的内容为Great White Whale。
[page]
矢量
为寻址一个vector的各个成分,使用"."。
vector $LOS = <<1, 2, 7>>;
float $firstComponent = $LOS.x; // 赋值为 1
float $secondComponent = $LOS.y; // 赋值为 2
float $thirdComponent = $LOS.z; // 赋值为 7
标注矢量的成分:
vector $LOCK = <<7, -4, 9>>;
$LOCK = <<$LOCK.x, $LOCK.y, 3>>; // Assigned <<7, -4, 3>>
但不能直接给一个成分标数字:
$LOCK.z = 3000; // 错误
但是通常当访问一个矢量成分时,你应该象下面例子那样围绕它使用括号:
例子:
print $LOCK.x; // 错误
print($LOCK.x);
setAttr persp.scaleX $LOS.x; // 错误
setAttr persp.scaleX ($LOS.x);
阵列
你可以声明一个int, float, string或vector类型的阵列。阵列的第一个序号为0
string $array[3] = {"first\n", "second\n", "third\n"};
print($array[0]); // 显示 "first\n"
print($array[1]); // 显示 "second\n"
print($array[2]); // 显示 "third\n"
阵列尺寸可以自动地增加。
int $scores[]; // 声明为一个0元素阵列
$scores[150] = 3; // 现在是151元素阵列
$scores[200] = 5; // 现在是201元素阵列 但最好不要声明过大的没用的阵列,因为它要占内存:
int $bigBoy[];
$bigBoy[123456789] = 2; // 危险
要除去一个阵列的所有元素可使用clear功能。要查看阵列的尺寸可使用size。
string $hats[3] = {"blue", "red", "black"};
print("There were " + size($hats) + " hats.\n");
clear($hats);
print("But now there are " + size($hats) + ".\n");
以上指令的输出是:
There were 3 hats.
But now there are 0.
矩阵
可以把一个矩阵想象为一个浮点阵列的阵列,或是一个浮点数据的二维阵列。矩阵产生后,它的尺寸不能改变。
企图寻址一个矩阵的不存在的元素将会出现错误。在产生矩阵时必须定义它的尺寸。
matrix $a1[][] = <<1; 4>>; // 错误: 没有说明尺寸
matrix $a2[][]; // 错误: 没有说明尺寸
matrix $a3[2][1]; // 有效: 产生 <<0; 0>>;
$a3[0][1] = 7; // 错误: 元素不存在
$a3[1][0] = 9; // 有效
声明而未标注值的矩阵,其所有元素都为0。
matrix $a4[2][4] = <<-3.4, 6, 201, 0.7; 4, 2, 9.3, 1001>>;
如果矩阵表示一个二维阵列,则第一个索引表示列;地二个索引表示行:
matrix $a4[2][4]column 0column 1column 2column 3
row 0-3.462010.7row 1429.31001
如果你把矩阵设想为一个身列的阵列,则第一个索引表示阵列,第二个索引该阵列里的索引:
matrix $a4[2][4]index 0index 1index 2index 3
float array 0-3.462010.7float array 1429.31001
物体属性
属性是场景中的物体的特征或参数。在Maya中可以用许多方法建立属性-属性编辑器、MEL程序、工具盒工具或表达式。
你可以设立属性去控制在工作空间中看到的虚拟的事情。
如,一个NURBS球具有属性scaleX, scaleY, scaleZ, rotateX, 等等。
物体属性名
物体属性名具有如下格式:
objectName.attributeName
其中objectName是物体的名字,attributeName是该物体的属性名。属性名中不要使用空格或特殊字符,可以用下划线。
产生一个名字为Brawl的球:
sphere -name Brawl;
可以获取它的属性的一个值:
float $yScale = `getAttr Brawl.scaleY`;
Brawl.scaleY是Brawl物体的scaleY属性的全名。
路径
如果两个物体具有不同的父物体,它们可以有相同的名字。当说明有相同名字的物体时必须使用路径:
pathname│objectname
其中pathname物体的父物体。管道字符(│)用于区分路径。
sphere -name doughnutHole;
group -name GroupA;
sphere -p 3 0 0 -name doughnutHole;
现在我们有两个叫做doughnutHole的物体,但一个有父物体GroupA,另一个没有父物体。以下指令产生一个错误,
因为Maya不知道哪个doughnutHole物体要设立scaleY属性:
setAttr doughnutHole.scaleY 3.3; // ERROR: 哪个?
你必须输入属性的路径:
setAttr GroupA│doughnutHole.scaleY 3.3;
setAttr │doughnutHole.scaleY 0.3;
你可以说明物体的所有路径,用管道符进行区分:
group -name GroupB GroupA;
setAttr │GroupB│GroupA│doughnutHole.scaleY 1;
物体属性的可能的数据类型
每个属性有特定的数据类型。几何体, 粒子物体, Maya中的其他项都具有这些数据类型的属性:
数据类型 意义 属性例 数据例
浮点小数 numbers Ball.translateX 2.6, 7.0, -9.1int
整数 (...-1, 0, 1, 2...) BallShape.spansU -289, 33, 0
boolean 0或1 Ball.visibilityon, off, yes, no, 1, 0, true, false
考虑一个由以下指令产生的叫做Fire的粒子物体:
particle -name Fire -position 7 0 7;
它可以具有以下另外的数据类型:
数据类型 意义 属性例 数据例
vector array 矢量阵列 FireShape.position
{<<3.2,?7.7,?9.1>>, <<7,?10,?2.2>>}
double array 浮点阵列 numbersFireShape.lifespan 1.333 1.666
你可以使用getParticleAttr和setParticleAttr指令设立矢量的元素或一个粒子系统的双阵列。
float $Tmp[] =
`getParticleAttr -at position FireShape.pt[0]`;
vector $particlePosition = <<$Tmp[0], $Tmp[1], $Tmp[2]>>;
setParticleAttr -at position -vv 0 0 7 FireShape.pt[0];
对于矢量阵列数据类型,Maya用一个阵列的单元素对物体的每一部分表达指定的属性。
注意,pt[0] 表达产生FireShape的第一部分的索引。每个元素是由三个浮点数构成的。
在一个双阵列中,Maya用一个浮点数对每一部分表达特定的属性。
重要事项:在表达式中,你可以使用一个等于符号(=)设立或得到一个变量或属性的值。
在MEL语句中,只可以使用(=)设立或得到一个变量值。
使用MEL setAttr、getAttr、setParticleAttr、getParticleAttr指令设立或得到一个属性值。
全局和局部变量 典型地,你将使用在一个单序列里的变量这些变量叫做局部变量(local variables),
因为它们只出现在局部过程里:
float $tester;
如果你产生一个相同名字的局部变量在两个序列里,两个变量被分离并且相互无关。
如:假定你在两个序列中产生一个取名为$tester的变量。标注或修改$tester变量的一个值不影响在其他里的值。
如果你想在一个序列里产生并动画一个变量,也要把它使用于该序列之外,
你可以把它声明为一个全局变量(global variable)。
global float $counter;
你就可以用其它MEL指令和语句读该变量。当你要扩大该变量的使用范围时,
应再次进行声明。 global float $crash = 8;
global proc holy()
{
$crash = 7;
print($crash + "\n");
}
print($crash + "\n"); // 结果:8
holy(); // 结果:7
print($crash + "\n"); // 结果:8
尽管看起来使用了全局浮点型的crash,实际上使用了一个隐含产生的局部整型变量
(看例子: 隐含声明(Implicit declaration))。
global float $slash = 8;
global proc moly()
{
global float $slash;
$slash = 7;
print($slash + "\n");
}
print($slash + "\n"); // 结果:8
moly(); // 结果:7
print($slash + "\n"); // 结果:7
当你用了一个单指令声明了一个全局变量并给它标注了一个值,该标注仅发生在由Maya第一次读指令的时候。
被定义了的序列中的全局变量是被读的。
global proc proof()
{
global float $fight = 7;
$fight = 2;
print($fight + "\n");
}
知道该序列的proof被读入,变量fight没有声明。换言之,Maya还没有觉察到它的变量的存在。
但是,一旦该序列被读入和被定义,该变量fight被声明为一个全局浮点型并被赋值为7。
该声明之后,该全局变量对所有的MEL指令都是可见的。即它可被任何MEL指令修改。
但是,当proof被执行后,fight被赋值为2。
如:在proof被定义后,以下指令将产生给出的结果:
print($fight + "\n"); // Result: 7
proof; // Result: 2
print($fight + "\n"); // Result: 2
如果两个序列对相同的全局变量声明和标注一个值会出现什么情况?看以下两个脚本文件:
(假定放在你的脚本目录中):
脚本文件: crush.mel
global proc crush()
{
global float $sight = 7;
print $sight;
}
脚本文件: groove.mel
global proc groove()
{
global float $sight = 9;
print $sight;
}
一个值标注到一个全局变量仅仅是在第一次Maya读每个脚本文件时。
crush(); // Result: 7
groove(); // Result: 9
crush(); // Result: 9
[page]
2、常数
MEL中的常数只有布尔常数(Boolean constants)。它实际上是整型数,值为1或者为0。
关键字true, on, 和yes具有值1;关键字false, off 和 no具有值0。
-------------------------------------------------------------------
3、数据类型转换
转换为
-------------------------------------------------------------------
int float string vector matrix
-------------------------------------------------------------------
int ($i) perfect perfect perfect <<$i, $i, $i>> none
float ($f) without perfect perfect <<$f, $f, $f>> none
fraction
string without perfect if perfect perfect if none
fraction starts with starts with
if starts number, vector or
with number else 0 floats with
,else 0 remaining
elements 0
vector length of length of 3 floats perfect perfect
vector vector separated for [1][3]
without by a space matrix,
fraction else none
matrix for [1][3] for [1][3] none for [1][3] perfect
matrix or matrix or matrix or
smaller, smaller, smaller,
length of length of perfect with
matrix matrix remaining
without elements 0
fraction
-------------------------------------------------------------------
一个标量类型(scalar type)是一个非阵列型。从阵列到标量或从标量到阵列型没有转换。
int $ski = 1.8; // 赋值:1
vector $crads = 1.7; // 赋值:<<1.7, 1.7, 1.7>>
int $wild = " 3.44 dogs"; // 赋值:3
vector $wrd = " 8 2.2 cat"; // 赋值:<<8, 2.2, 0>>
int $my = <<1, 2, 3>>; // 赋值:3
string $oo = <<6, 2.2, 1>>; // 赋值:"6 2.2 1"
matrix $so[1][3] = $wrd; // 赋值:<<8, 2.2, 0>>
float $mole = <<0.3, 0.4>>; // 赋值:0.5
vector $ole = <<2, 7.7>>; // 赋值:<<2, 7.7, 0>>
自动转换
Maya的自动类型转换使我们可以不考虑它们的状态以及不考虑是否是能接受的类型。以下是它们的规则:
--Strings 支配其他所有类型。
--Vectors 支配floats。
--Floats 支配ints。
--如果一个算子为整型,另一个为浮点型,MEL将整型转换为浮点型。
--在vector和matrix之间,左边的类型起支配作用。
--赋值时,有左边的类型支配。
在一个赋值操作中,右边的类型被转换到左边的类型。前四条规则在右手的计算期间施用于子表达式;
最终的转换发生在给左边赋值时。 下表是自动类型转换的规则。
-------------------------------------------------------------------
运算 结果的数据类型
-------------------------------------------------------------------
int 运算子 float float
float 运算子 int float
int 运算子 vector vector
vector 运算子 float vector
vector 运算子 matrix vector
matrix 运算子 vector matrix
matrix 运算子 string string
string 运算子 int string
-------------------------------------------------------------------
$var1 = 7 + 1.3; // 类型: float (8.3)
$var2 = 7.9 + 2; // 类型: float (9.9)
$var3 = 2 + <<4, 5, 6>>; // 类型: vector <<6, 7, 8>>
$var4 = 0007 + " Lives!"; // 类型: string ("7 Lives!")
在最后的例子中,0007是值7的整型,它被转换为一个字符串并与"Lives!"合并。
结果是一个字符串,它显式声明var4为值是"7 Lives!"的字符串类型。
显式转换
有两个显式方法把一个类型的值转换给另一个。最常用的方法是在该值前面用括号说明:
$Z = (vector) "<<1, 2, 3>>";// Type: vector (<<1, 2, 3>>)
$cools = (float) 7; // Type: float (7)
$ools = (string) 47.554; // Type: string ("47.554")
你也可以采用跟随括号来实现显式转换:
$ly = vector("<<1, 2, 3>>"); // Type: vector (<<1, 2, 3>>)
$ooly = int(3.67); // Type: int (3)
-------------------------------------------------------------------
[page]
4、限制
整数除法的舍弃
当Maya对常数和没有声明数据类型的变量运行算术运算时,它按照表现形式推测数据类型。如以下指令:
float $where = 1/2; // Result: 0
Maya推测1和2是整型数,因为它们没有小数点。该表达式用整数1除以整数2。
其整数结果是0而余数是1。 Maya不保留该余数。
由于变量是浮点的,Maya将整数值0转换为浮点数0 (相同值)。
为得到该值的小数成分,需要将一个整数转换为浮点:
float $there = 1/2.0; // 结果: 0.5
或
float $youGo = float(1)/2;
精度和最大数长
对于一个字串、矩阵或阵列,最大尺寸仅取决于你的计算机的存储器的有效容量。
但是,浮点和整型有精度和最大长度的限制。
一个整数的最大长度与C 语言中是一样的,决定于机器。
大部分计算机中它的范围是-2,147,483,648到2,147,483,647。
一个浮点数的最大长度和精度与C语言中的双精度数是一样的,也取决于机器。
浮点有精度限制,在长计算里会积累取舍误差。但它的精度很高(大约15位的精度), 取舍通常不会成问题。
超限折返(Range wrap-around)
变量有范围限制。如果超出这个范围,会产生不期望的后果。
int $mighty = 2147483647 + 1; // Result: -2147483648
int $radical = -2147483648 - 1; // Result: 2147483647
int $buddy = 2147483648; // Result: -2147483648
int $man = 2147483647 + 2; // Result: -2147483647
当超出了变量的最大范围,变量的值转折为变量的最小值;反之,若超出最小范围,会转为最大值。
float $GG = 1.5 + 1000000000 * 3; // Result: -1294967294.5
在这个例子中,按照优先顺序先做乘法。因为是两个整数相乘,所以其结果还是一个整数。
因为它的值超过了整型数的最大范围,所以该值被折返。
另一个例子:
$GG = 1.5 + 1000000000 * 3;
$GG = 1.5 + 3000000000; // 超出整型最大范围
$GG = 1.5 + 3000000000 + (2147483648) - (2147483648.0);
$GG = 1.5 + 3000000000 + (-2147483648) - (2147483648.0);
$GG = 1.5 + 3000000000 - 4294967296;
$GG = 1.5 + -1294967296;
$GG = -1294967294.5;
编写语句
语句说明程序如何发挥运算作用。本章内容有:1、了解指令和运算;2、赋值;3、算法;4、比较;5、条件;6、运算顺序;7、成组运算。
--------------------------------------------------------------------------------
1、了解指令和运算
指令用运算作用或比较数据。有四种运算类型:
--赋值
--运算
--比较
--条件
大部分运算使用一个值在运算的左边,一个值在右边。如果这两个值的类型不同,如果可能,一个值将被转换为另一个值。
运算在同类间进行。
-------------------------------------------------------------------
2、赋值
赋值运算用等号(=)表达。左边的变量将被赋予右边的值:
float $counter = 5.3;
声明一个浮点变量,赋给它一个值5.3。
赋值运算的结果是类型和值赋予等号左边的变量。其结果可被当作同值同类型的常数。
float $owl;
float $hotdog = ($owl = 5.3) + 6;
第而行中浮点$owl被赋值为5.3而$hotdog被赋值为11.3。
赋值链
int $i1, $i2, $i3, $i4;
$i1 = $i2 = $i3 = $i4 = 6; // 所有变量都被赋值为6
-------------------------------------------------------------------
3、算法
可以使用以下运算符号进行加、减、乘、比较以及完成变量的其他作用。
符号 意义 数据类型
+ plus int, float, string, vector, matrix
- minus或negation int, float, vector, matrix
* for int, float, matrix
: multiply for vector
: dot product int, float, vector, matrix
/ divided by int, float, vector
% remainder of division int, float, vector
^ cross product vector
矩阵型可以用于取模modulus(%)和除divide?(/)运算。但是右边必须是个整型或浮点作为算子。更多信息看Matrices。
整数和浮点数
对于整型和浮点属性和变量,遵循基本的数学运算规则。取模(%)运算在编程语言中通常有效。
int $card = 7 % 3; // Result: 1
float $bus = 0.5 % 3; // Result: 0.5
字串
对字串可使用+运算,见Strings。
矢量
矢量变量间的运算,算法^计算矢量的*积,算法*计算点积。对所有其他的运算,一个矢量的每个分量与其他矢量的各个成分进行运算。
vector $Vo = <<3, 9, 5>> + <<9, 2, 3>>; // <<12, 11, 8>>
vector $Vu = <<2, 3, 4>> - <<1, 2, 3>>; // <<1, 1, 1>>
vector $me = <<2, 3, 2>> / <<1, 2, 5>>; // <<2, 1.5, 0.4>>
vector $rf = <<12, 3, 9>> % <<4, 2, 5>>; // <<0, 1, 4>>
点积返回一个浮点。点积常常概念化为两个变量矢量被它们之间角度的余弦所乘之积的长度的积。
vector $V1 = <<4, 6, 8>>;
vector $V2 = <<2, 2, 2>>;
float $F1 = $V1 * $V2; // 36 (点积)
点积运算(*)的结果可用以下方程进行计算:
$F1 = ($V1.x * $V2.x) + ($V1.y * $V2.y) + ($V1.z * $V2.z);
一个矢量与一个整型或一个浮点间的运算把整型或浮点转换为矢量,* 运算是不同的。
*运算的结果是矢量的每个成分被整数或浮点数相乘。
vector $tak = 3.2 * <<1, 3, -5>>; // <<3.2, 9.6, -16>>
vector $sak = <<0, 1.2, 9.1>> * 5; // <<0, 6, 45.5>>
运算^只能运算于矢量类型。它表达了*积运算,返回一个矢量。
vector $V3 = <<2, 0, 0>>;
vector $V4 = <<0, 3, 0>>;
vector $V5 = $V3 ^ $V4; // <<0, 0, 6>> (*积)
*积矢量的方向是法线指向两个变量矢量。该矢量的幅度是两个矢量的长度之积。可用如下方程计算结果:
$V5 = <<(($V3.y * $V4.z) - ($V3.z * $V4.y)),
(($V3.z * $V4.x) - ($V3.x * $V4.z)),
(($V3.x * $V4.y) - ($V3.y * $V4.x))>>;
矩阵
可以在每个矩阵的相应元素之间只进行加或减。矩阵必须具有相同的行数和列数。
matrix $Va[1][4] = <<2, 0, 0, 2>>;
matrix $Vb[1][4] = <<6, 3, 7, 5>>;
matrix $Vc[1][4] = $Va + $Vb; // <<8, 3, 7, 7>>
matrix $Vd[1][4] = $Va - $Vb; // <<-4, -3, -7, -3>>
矩阵相乘时,左矩阵的列数应该等于右矩阵的行数。结果的矩阵具有与左矩阵相同的行数和与右矩阵相同的列数。
matrix $Ve[2][4] = <<4, 1, 1, 2; 3, 4, 5, 8>>;
matrix $Vf[4][3] = <<7, 6, 0; 7, 5, 4; 2, 1, 6; 2, 0, 2>>;
matrix $Vg[2][3] = $Ve * $Vf; // <<41, 30, 14; 75, 43, 62>>
当右边的项是一个标量时,取模和除法算符使用该标量作为右边的项对矩阵的每一个元素进行运算。以下的例子展示出了这一点:
matrix $Vh[1][4] = <<4, 9, 5, 2>> % 3; // <<1, 0, 2, 2>>
matrix $Vi[1][4] = <<1, 2, 8, 4>> / 2; // <<0.5, 1, 4, 2>>
略写
在语句描述中你常常会分配一个变量,它的值与其它一些值进行了运算。略写运算提供了一种简单而又快速的方法。
你可以对int, float和vector数据类型的运算进行略写。
这些算符并没有提供附加的功能或者提高运算速度,但是可以节省你宝贵的输入时间。
例如,可以不写成:
$bus = $bus + 3.5;
而可以写成:
$bus += 3.5;
这两条语句做相同的事情,但是第二条输入的少。对于任何计算符,可以将以下格式: 变量 = 变量 算符 值
写成:
变量 算符= 值
下表示出了这种形式的所有的略写算符、它们的扩展格式和它们的值。
这些算符只对int、float和vector类型定义。但是, += 算符也对string类型定义。
略写格式 扩展格式 值
-------------------------------------------------------------
变量 += 值 变量 = 变量 + 值 变量 + 值
变量 -= 值 变量 = 变量 - 值 变量 - 值
变量 *= 值 变量 = 变量 * 值 变量 * 值
变量 /= 值 变量 = 变量 / 值 变量 / 值
变量 %= 值 变量 = 变量 % 值 变量 % 值
-------------------------------------------------------------
float $mice = 25.3;
$mice -= 6; // $mice = $mice - 6;
$mice %= 4; // $mice = $mice % 4;
$mice /= 3; // $mice = $mice / 3;
vector $kick = <<2, 3, 4>>;
$kick += <<7, 5, 1>>; // $kick = $kick + <<7, 5, 1>>
也有一个 ^= 算符,它仅仅是对vector定义的。该运算计算一个做矢量和右矢量operand的点积。
vector $ice = <<1, 2, 3>>;
$ice ^= <<2, 4, 4>>; // $ice = $ice ^ <<2, 4, 4>>
增量和减量
有一些略写算符可以用于对floats和ints进行加1和减1的运算。下表列出了这些算符、它们的扩展格式以及值。
略写格式 扩展格式 值
-------------------------------------------------------------
变量++ 变量= 变量+ 1 变量
变量-- 变量= 变量- 1 变量
++变量 变量= 变量+ 1 变量+ 1
--变量 变量= 变量- 1 变量- 1
-------------------------------------------------------------
当增量或减量略写算符加到变量前面时,想象该增量或减量发生在该语句执行之前。
但是,当该算符加到了变量的后面,想象该增量或减量发生在该语句被执行之后。
float $eel = 32.3;
float $crab = $eel++; // $crab = 32.3; $eel = 33.3;
$crab = $eel--; // $crab = 33.3; $eel = 32.3;
$crab = --$eel; // $crab = 31.3; $eel = 31.3;
$crab = ++$eel; // $crab = 32.3; $eel = 32.3;
注意:如果有多个增量或减量略写算符作用在同一语句的相同的变量上,则算符的运算顺序是无法预知的。应当避免这种情况。
-------------------------------------------------------------------
4、比较
比较运算用于逻辑和关系表达式。
逻辑运算
逻辑的基础是语句是否为真或者假。逻辑算符决定一个语句是真还是假,然后执行相应的语句。
可以将int、float和vector数据类型用于逻辑算符。
每种类型的值对应于真和假。一个 int 或 float 值当它的值转换成整型时是0则被认为是假。
一个矢量的幅度值当它的值转换成整型时是0则被认为是假。转换成所有其它的值则都被认为是真。
下表显示三中逻辑算符的符号和逻辑意义:
符号 逻辑为真,如果:
-------------------------------------------------------------
││ 或 不管左边或者右边为真
&& 和 左边或者右边都为真
! 非 右边为假
-------------------------------------------------------------
if (0 ││ 1) print("true\n"); // True
if (0 && 1) print("true\n"); // False
if (2 && <<3, 7.7, 9>>) print("true\n"); // True
if (! 5.39 && 7) print("true\n"); // False
if (<<0, 0, 0>> ││ 0) print("true\n"); // False
if (! <<0, 0, 0>>) print("true\n"); // True