当前位置:首页>软件教程>maya教程>教程内容

mel语初解之一-基础和界面篇(3)

来源: 作者:admin 学习:20369人次

如何判断选择的是面,还是点,还是边呢?如下:

// 多边形点
string $vertices[] = `filterExpand -ex 1 -sm 31`;
// 多边形边
string $edges[] = `filterExpand -ex 1 -sm 32`;
// 多边形面
string $faces[] = `filterExpand -ex 1 -sm 34`;

// 如果框选很多,要想获取其中的nurbs和polygon物体,-sm可以出现不止一次。
string $polygons[] = `filterExpand -sm 10 -sm 12`;

选择一些多边形物体的面,下面的代码输出面的名称:
global proc printObjNameSheet()
{
int $num;
string $faces[] = `filterExpand -sm 34`;

string $output = "\n*******************\n";
$output += "一共选择了";
$num = `size $faces`;
$output += $num + "个面\n它们是:\n";

print $output;
print $faces;
}
printObjNameSheet;

"filterExpand -ex/expand"的用法
关于filterExpand -ex/expand的用法,如果懒得看help,看下面的吧:
Object Type / Mask
Handle 0
Nurbs Curves 9
Nurbs Surfaces 10
Nurbs Curves On Surface 11
Polygon 12
Locator XYZ 22
Orientation Locator 23
Locator UV 24
Control Vertices (CVs) 28
Edit Points 30
Polygon Vertices 31
Polygon Edges 32
Polygon Face 34
Polygon UVs 35
Subdivision Mesh Points 36
Subdivision Mesh Edges 37
Subdivision Mesh Faces 38
Curve Parameter Points 39
Curve Knot 40
Surface Parameter Points 41
Surface Knot 42
Surface Range 43
Trim Surface Edge 44
Surface Isoparms 45
Lattice Points 46
Particles 47
Scale Pivots 49
Rotate Pivots 50
Select Handles 51
Subdivision Surface 68
Polygon Vertex Face 70
NURBS Surface Face 72
Subdivision Mesh UVs 73

前面的准备就绪,现在来继续myFullMoon的新版。

实例6:myFullMoon3.0
前面提到过升级"myFullMoon"的时候图标命令依旧,只要改"myFullMoon.mel"文件就行了。
现在打开"myFullMoon.mel"文件,用下面的代码替换掉原来的代码:

// myFullMoon3.0
global proc myFullMoon()
{
string $polygons[] = `filterExpand -sm 12`;
// 如果选择了多个多边形物体,只对第一个进行操作
string $polygon = $polygons[0];

select -r $polygon;
ConvertSelectionToFaces; // 转换为选择面模式

polyExtrudeFacet -ch 1 -kft 1
-pvx -3.926295877 -pvy -1.118658066 -pvz 4.649739981
-translateX -7.5 -ty 0 -tz 0
-rx 0 -ry 0 -rz 0
-scaleX -1 -sy 1 -sz 1
-ran 0 -divisions 1 -off 0 -ltz 0 -ws 0
-ltx 0 -lty 0
-lrx 0 -lry 0 -lrz 0
-lsx 1 -lsy 1 -lsz 1
-ldx 1 -ldy 0 -ldz 0
-w 0
-gx 0 -gy -1 -gz 0
-att 0
-mx 0 -my 0 -mz 0;

polyNormal -normalMode 0 -ch 1;

polySmooth -mth 0 -dv 1 -c 1
-kb 1 -ksb 1 -khe 0 -kt 1
-sl 1 -dpe 1 -ps 0.1 -ro 1 -ch 1;
select -cl ;
}

现在这些代码还不会生效,直到你关闭再重新打开Maya。要想让mel文件里的代码立即生效,需要Source Script。有三种方法可以Source Script:
1. 选择mel编辑器菜单File->Source Script...,打开"myFullMoon.mel"文件。
2. 把"myFullMoon.mel"文件直接拖放到Maya视图窗口中。
3. 使用"source"命令。

"source"命令的用法:
通过"source"命令可以执行mel文件中的代码。例如:
source "c:/temp/myFullMoon.mel";
或:
source "c:\\temp\\myFullMoon.mel";

如果你的mel文件是放在Maya的Script目录(我的文档\e:\My Documents\maya\4.5(5.0)\scripts),"source"命令可以不指定路径:
source "myFullMoon.mel";

Source了"myFullMoon.mel"之后,就可以试试了。
选中以前那个半边脸模型,给它改个名字,再按"myFullMoon"命令的Shelf图标,可以看到新代码起作用了。

当然现在又来了新的问题,还记得以前用的模型宽度是7.5吧,每个模型的宽度是不同的,模型宽度也应该是个变量。要想获得模型宽度,需要用到边界框(Bounding Box),获取边界框是以后要做的事情,我把它放到建模部分讲。

前面讲了很多东西,你可能还要慢慢消化。不过如果你真的能把前面讲的都理解了,相信你的mel已经入门了。从下一课开始,我来讲用mel编写界面的方法。

Maya帮助文档中把编写界面的mel命令称为ELF命令。
"Most ELF commands create and modify UI elements. " [Maya Help docs]
大部分ELF命令创建和修改UI元素。

"ELF","UI"这么多缩写真的很让人感到厌烦。
"ELF" - Extended Layer Framework(扩展层框架)
这个词汇有点多余,我会尽可能少提到它。

"UI" - User Interface(用户界面)
用户界面的含义相信大多数人都知道,用户界面又称人机界面,实现用户与计算机之间得通信,以控制计算机或进行用户和计算机之间得数据传送得系统部件。具体的说,我们平常使用的窗口、菜单、按钮等都是用户界面的元素。
"界面"
我们平常所说的界面都是指“用户界面”,因为程序员是少数派,用户才是上帝,所以用户们从来不怕直接说界面会被别人误解为“应用程序设计界面”。我后面也把用户界面简称为界面,希望不要给我纠正。

[注]
"API" - Application Programming Interface
有几种不同译法:应用程序界面,应用程序设计界面,应用程序接口。这是一种专门给程序员使用的界面或接口,例如Maya API。

现在来编写一个窗口。用mel编写一个窗口就像创建一个球或者方块那么简单。

"window"命令 (创建窗口)
在命令行输入"window"(打字的候要小心,不要让视窗变成寡妇window-widow)然后回车,一个窗口就创建好了。不要因为没看到有什么变化而认为我在欺骗你,"window"命令创建的窗口在默认情况下是不可见的,换句话说,"window"命令的"-vis/-visible"的默认参数值为0(或false),也就是说直接输入"window"命令和输入"window -visible false"是等效的。

"showWindow"命令 (显示窗口)
要想创建可以看得到的窗口,有两种方法。一种方法是在创建窗口时用"window -visible true",另一种方法是创建窗口后执行"showWindow"命令。这时我会推荐你用第二种方法,"showWindow"的好处是既显示窗口,又把这个窗口推到所有窗口的最前面。

好,现在就在命令行输入"showWindow"并回车,一个窗口便显示了出来。

唯一的命名
因为你可以创建很多个窗口,因此如果想完全控制每个窗口,就必须给每个窗口指定一个唯一的命名。执行下面两句命令:
-----------------------------------------
window -t "我的测试窗" myTestWin;
showWindow myTestWin;
-----------------------------------------
这里"myTestWin"就是窗口的名字。
"-t/-title"的用途想必不用我多作解释了吧?

当一个窗口创建时,会另人想到另一个问题,就是怎么把它销毁(删除)。点窗口右上角标题栏上的那个"×"可以关闭窗口,然而关闭窗口却蕴含着两层意思。在大多数情况下,关闭窗口可以销毁窗口,有少数情况,关闭窗口以后窗口只是处于不可见状态,窗口并没被销毁,你随时可以用"showWindow"命令来显示它。用"-ret/-retain"标志创建的窗口就属于这种少数情况。

"deleteUI"命令 (销毁界面元素)
要想让彻底销毁窗口,使用"deleteUI"命令。"deleteUI"可以销毁任何界面元素,包括布局、控件和菜单。在命令行输入"deleteUI myTestWin"并回车,"myTestWin"就被销毁了。

为方便以后对于这个窗口代码的调用,我们来编写一个函数。
-----------------------------------------
global proc myTest()
{
if(`window -ex myTestWin`) // 如果myTestWin窗口已经存在了
deleteUI myTestWin; // 就把myTestWin销毁

window -t "我的测试窗" myTestWin;
showWindow myTestWin;
}
myTest;

"if"语句
这里用到了if语句,我觉得if语句是最容易理解的语句,把"if"直译成"如果"就可以理解。if后面那个小括号里的代码表示的只能是一个布尔值,是(1, true)或否(0, false)。当表示否时,可以在前面加一个叹号,"!"可以直译成"不"。例如:
if(!`window -ex myTestWin`) // 表示如果myTestWin窗口不存在
也就是:
if(`window -ex myTestWin` == false) // `window -ex myTestWin`的返回值为0

现在只是编写了一个空的窗口,要是想往窗口中添加一些按钮或者文本框什么的怎么办呢?

控件,布局
按钮或者文本框这些东东统称控件(control),mel摆放控件的特色是使用布局(layout)。在不同的布局中,控件摆放的方法不同,比如竖布局(columnLayout)中的控件都是一个挨一个竖着摆放的,而横布局(rowLayout)中的控件都是横着排列的。

"window"命令之后必须有一个布局,这个布局作为窗口的主布局,其它控件或布局都放置在这个主布局之中。

层级关系
由于布局之中既可以放布局又可以放控件,因此布局与控件,布局与布局之间构成了一种层级关系(父子关系)。例如,布局columnLayout2在布局columnLayout1之中,columnLayout1称为columnLayout2的父布局(Parents),columnLayout2称为columnLayout1的子布局(Children)。

"setParent"命令 (指定当前布局)
默认的,刚刚创建的布局为当前布局,新建的布局或控件都建在当前布局中。要想使以前创建的布局成为当前布局,使用setParent命令:"setParent 布局名"。要想使上一级布局(父布局)成为当前布局,使用"setParent .."。

"columnLayout"命令 (竖布局)
对于不在乎界面美观的人来说,学会一个竖布局差不多就足够了。
竖布局中的控件都是一个挨一个竖着摆放的,请看下面的代码:
-------------------------------------------------------------
global proc myTest()
{
if(`window -ex myTestWin`)
deleteUI myTestWin;

window -t "我的测试窗" myTestWin;
columnLayout -adj 1; // 主布局
text -l "圆锥名称";
// 和控制窗口一样,要想控制控件,也要给控件一个唯一的命名。
// 这里文本框(textField)控件的名字为"myConeNameFld"
textField -tx "cone" myConeNameFld;
button -l "创建圆锥" -c "cone";
button -l "删除" -c "delete";

showWindow myTestWin;
}
myTest;
-------------------------------------------------------------
执行这段代码,不要关掉生成的窗口。
"text"命令 (静态文本)
"textField"命令 (文本框)
"button"命令 (按钮)

这里用到三个关于界面的mel命令:"text","textField","button"。
根据生成的窗口你就可以猜到这三个命令的意思。
"text"为静态文本,"textField"为文本框,"button"为按钮。
"-l/-label"可能是界面命令中最明显、最容易理解的标志了,意思是界面元素的标签。
"-tx/-text"是文本框中的文字。
"-c/-command"是要执行的mel命令,注意这个命令是一个字符串,一般要用引号引起来。
"-adj"决定是否自动调整布局内控件的宽度。

"-q/-query"(查询)和"-e/-edit"(编辑)标志
这是两个非常特殊又非常有用的标志,所有的界面命令都用到这两个标志。
"-q/-query" 表示查询的意思,你可以通过它获得某一标志的数值。
"-e/-edit" 表示编辑的意思,你可以通过它修改某一标志的数值。

下面举例说明它们的用法:
在刚才创建的窗口的文本框中随便输入几个字,在命令行输入"textField -q -tx myConeNameFld"并回车,可以在输出窗口中看到文本框中的字。
在命令行输入"textField -e -tx "change" myConeNameFld"并回车,文本框中的字就变成了"change"。前面说过"deleteUI"可以销毁任何界面元素,在命令行输入"deleteUI myConeNameFld"并回车,文本框消失了。

获取本框中的文字
编写按钮命令

要想创建的圆锥根据本框中的文字来命名,使用下面的代码:
-----------------------------------------
// 先编写一个函数(createCone),然后在按钮命令中调用这个函数。
global proc createCone()
{
string $name = `textField -q -tx myConeNameFld`; // 获取文本框中的文字
cone -name $name; // 用文本框中的文字为名称创建圆锥
}

global proc myTest()
{
if(`window -ex myTestWin`)
deleteUI myTestWin;

window -t "竖布局(columnLayout)测试窗" myTestWin;
columnLayout -adj 1;
text -l "圆锥名称";
textField -tx "cone" myConeNameFld;
button -l "创建圆锥" -c "createCone"; // 按钮命令中调用createCone函数
button -l "删除" -c "delete";

showWindow myTestWin;
}
myTest;
-----------------------------------------
改一下文本框中的字,按"创建圆锥"按钮,这时创建的圆锥是按照文本框中的文字命名的。注意,对物体命名时不能使用标点符号,不能使用大多数的中文字,具体原因在后面讲到如何用mel判断物体名称是否合法时再解释。

下面讲几个常用布局:

"rowColumnLayout"命令 (横竖布局)
控件横竖排列的布局:
-----------------------------------------
global proc myTest()
{
if(`window -ex myTestWin`) deleteUI myTestWin;

window -t "横竖布局(rowColumnLayout)测试窗" myTestWin;
rowColumnLayout -nc 3 -cw 1 60 -cw 2 80 -cw 3 100; // 横竖布局
button; button; textField;
button; textField; button;
button;

showWindow myTestWin;
}
myTest;
-----------------------------------------
"-nc/numberOfColumns"指定一共有几列。
"-cw/columnWidth"指定某一列的宽度。
"-cw 1 60"第一列的宽度为60像素。
"-cw 2 80"第二列的宽度为80像素。以此类推。

"scrollLayout"命令 (滚动布局)
滚动布局中只能放布局,不能放控件。
滚动布局可以给它的子布局加上滚动条。
-----------------------------------------
global proc myTest()
{
if(`window -ex myTestWin`) deleteUI myTestWin;

window -t "滚动布局(scrollLayout)测试窗" myTestWin;
scrollLayout;
columnLayout;
button;button;button;button;button;
button;button;button;button;button;

showWindow myTestWin;
}
myTest;

"frameLayout"命令 (边框布局)
边框布局中只能放布局,不能放控件。
下面的代码提供几种不同风格的边框:
-----------------------------------------
global proc myTest()
{
if(`window -ex myTestWin`) deleteUI myTestWin;

window -t "边框布局(frameLayout)测试窗" myTestWin;
columnLayout -adjustableColumn true;
// 第一种:可折叠边框
// 你熟悉的Attribute Editor和Tool Settings等窗口就是用的这种边框
frameLayout -label "Collapsable" -collapsable on -borderStyle "etchedIn"; // 可折叠
columnLayout;
text -l "-cl/collapse 0 -折叠";
text -l "-cl/collapse 1 -展开";
setParent ..;
setParent ..;
// 其它几种标签在边框线的位置不同,边框线的风格不同,如图。
// 第二种:
frameLayout -label "Buttons" -labelAlign "top" -borderStyle "in";
columnLayout;
button; button;
setParent ..;
setParent ..;
// 第三种:
frameLayout -label "Scroll Bars" -labelAlign "center" -borderStyle "out";
columnLayout;
intSlider; intSlider;
setParent ..;
setParent ..;
// 第四种:
frameLayout -label "Fields" -labelAlign "center" -borderStyle "etchedIn";
columnLayout;
intField; intField;
setParent ..;
setParent ..;
// 第五种:
frameLayout -label "Check Boxes" -labelAlign "bottom" -borderStyle "etchedOut";
columnLayout;
checkBox; checkBox;
setParent ..;
setParent ..;

showWindow myTestWin;
}
myTest;
-----------------------------------------
"-cll/collapsable"边框是否可折叠。
"-cl/collapse"如果边框可折叠,现在是否折叠。
"-bs/borderStyle"边框线的风格,可用值为:"in", "out", "etchedIn", 或 "etchedOut"。
"labelAlign"边框标签的对齐方式,可用值为:are "top", "center", 或 "bottom"。

"paneLayout"命令 (窗格布局)
窗格布局一个很明显的特点就是有分隔线分隔窗格面板,你可以移动分隔线来调整窗格面板的大小。Maya的四视图就是用了这个布局的,还有mel编辑器也是。
-----------------------------------------
global proc myTest()
{
if(`window -ex myTestWin`) deleteUI myTestWin;

window -t "窗格布局(paneLayout)测试窗" myTestWin;
paneLayout -configuration "quad";
button;
textScrollList -append "one" -append "two" -append "three";
scrollField;
scrollLayout;
columnLayout;
button; button; button;
showWindow myTestWin;
}
myTest;
-----------------------------------------
"-cn/configuration"pane的组合方式,可用值为:"single", "horizontal2", "vertical2", "horizontal3", "vertical3", "top3", "left3", "bottom3", "right3", "horizontal4", "vertical4", "top4", "left4", "bottom4", "right4", "quad"。

"tabLayout"命令 (标签布局)
标签布局中只能放布局,不能放控件。标签布局中可以放多个并列的子布局,当鼠标点到某一标签时,就显示与此标签对应的子布局。对于控件很多的面板,标签布局无疑是最好的选择。
-----------------------------------------
global proc myTest()
{
if(`window -ex myTestWin`) deleteUI myTestWin;

window -t "标签布局(tabLayout)测试窗" myTestWin;
string $tabs = `tabLayout`;
string $child1 = `columnLayout -adj 1`; // 标签1
button; button; button;
setParent ..;

string $child2 = `rowColumnLayout -numberOfColumns 2`; // "标签2"
button; button; button;
setParent ..;

tabLayout -edit
-tabLabel $child1 "标签1" -tabLabel $child2 "标签2"
$tabs;

showWindow myTestWin;
}
myTest;
-----------------------------------------
string $tabs = `tabLayout`;
这句的意思获取tabLayout命令的返回值,存到变量$tabs里。
前面说过界面元素要有一个唯一的命名,如果你没有给它命名,Maya会自动给它一个命名。界面命令的返回值就是界面元素的名称,因此用获取命令返回值的方法就可以获得界面元素的名称。(string $变量 = `界面命令`;)

string $child1 = `columnLayout -adj 1`;
这句也是同样的道理。

"formLayout"命令 (表单布局)
表单布局是最强大、最复杂、最具有可塑性的布局。这种布局可以随意把控件放到任何你想要的地方,也可以根据窗口的缩放即时缩放指定的控件。如果你很注重界面舒适美观的话,它就是你必然的选择。
-----------------------------------------
global proc myTest()
{
if(`window -ex myTestWin`) deleteUI myTestWin;

window -t "表单布局(formLayout)测试窗" myTestWin;

// 创建表单布局和布局中的控件
string $form = `formLayout`;
string $b1 = `button -label "按钮1"`;
string $b2 = `button -label "按钮2"`;
string $b3 = `button -label "按钮3"`;

// 分别描述每个按钮的上下左右位置
formLayout -edit
// 按钮1
-attachForm $b1 "top" 5 // 顶部距离表单5个像素
-attachForm $b1 "left" 5 // 左边距离表单5个像素
-attachForm $b1 "bottom" 5 // 底部距离表单5个像素
-attachPosition $b1 "right" 0 75 // 右边距离表单的75%
// 按钮2
-attachForm $b2 "top" 5 // 顶部距离表单5个像素
-attachControl $b2 "left" 5 $b1 // 左边距离"按钮1"5个像素
-attachNone $b2 "bottom" // 底部为默认值
-attachForm $b2 "right" 5 // 右边距离表单5个像素
// 按钮3
-attachControl $b3 "top" 5 $b2 // 顶部距离"按钮2"5个像素
-attachControl $b3 "left" 5 $b1 // 左边距离"按钮1"5个像素
-attachNone $b3 "bottom" // 底部为默认值
-attachForm $b3 "right" 5 // 右边距离表单5个像素
$form;

showWindow myTestWin;
}
myTest;
-----------------------------------------
当你拉大或缩小这个窗口时,"按钮1"的宽度总是占整个窗口的75%。

编写表单布局一般分为两步:
1.创建表单布局和布局中的控件。
2.分别描述每个按钮的上下左右位置。
"-af/attachForm" 距离表单多少个像素。
"-ac/attachControl" 距离控件多少个像素。
"-ap/attachPosition" 距离表单的几(-numberOfDivisions)分之几多少个像素。
"-nd/numberOfDivisions" 把表单分成多少份,好用于"-ap/attachPosition"。默认值为100。

学习 · 提示

  • 一定要打开PS,跟着教程做一遍,做完的图到这交作业:提交作业
  • 建议练习时,大家自己找素材,尽量不要用教程提供的素材。
  • 教程有看不懂的地方,可以到论坛发帖提问:新手求助
  • 加官方微信,随时随地,想学就能学:ps_bbs,或扫右侧二维码!
  • 关注我们学更多,每天都有新教程:新浪微博 抖音视频 微信小程序
- 发评论 | 交作业 -
最新评论
42017-01-13 04:08
42017-01-13 03:52
挺牛逼的
2016-03-14 07:30
超赞的文章
陈军波2015-12-14 12:59
竟然没人评论

关注大神微博加入>>

网友求助,请回答!