mel語初解之一-基礎(chǔ)和界面篇(3)
如何判斷選擇的是面,還是點,還是邊呢?如下:
// 多邊形點
string $vertices[] = `filterExpand -ex 1 -sm 31`;
// 多邊形邊
string $edges[] = `filterExpand -ex 1 -sm 32`;
// 多邊形面
string $faces[] = `filterExpand -ex 1 -sm 34`;
// 如果框選很多,要想獲取其中的nurbs和polygon物體,-sm可以出現(xiàn)不止一次。
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"的用法
關(guān)于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
前面的準(zhǔn)備就緒,現(xiàn)在來繼續(xù)myFullMoon的新版。
實例6:myFullMoon3.0
前面提到過升級"myFullMoon"的時候圖標(biāo)命令依舊,只要改"myFullMoon.mel"文件就行了。
現(xiàn)在打開"myFullMoon.mel"文件,用下面的代碼替換掉原來的代碼:
// myFullMoon3.0
global proc myFullMoon()
{
string $polygons[] = `filterExpand -sm 12`;
// 如果選擇了多個多邊形物體,只對第一個進行操作
string $polygon = $polygons[0];
select -r $polygon;
ConvertSelectionToFaces; // 轉(zhuǎn)換為選擇面模式
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 ;
}
現(xiàn)在這些代碼還不會生效,直到你關(guān)閉再重新打開Maya。要想讓mel文件里的代碼立即生效,需要Source Script。有三種方法可以Source Script:
1. 選擇mel編輯器菜單File->Source Script...,打開"myFullMoon.mel"文件。
2. 把"myFullMoon.mel"文件直接拖放到Maya視圖窗口中。
3. 使用"source"命令。
"source"命令的用法:
通過"source"命令可以執(zhí)行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圖標(biāo),可以看到新代碼起作用了。
當(dāng)然現(xiàn)在又來了新的問題,還記得以前用的模型寬度是7.5吧,每個模型的寬度是不同的,模型寬度也應(yīng)該是個變量。要想獲得模型寬度,需要用到邊界框(Bounding Box),獲取邊界框是以后要做的事情,我把它放到建模部分講。
前面講了很多東西,你可能還要慢慢消化。不過如果你真的能把前面講的都理解了,相信你的mel已經(jīng)入門了。從下一課開始,我來講用mel編寫界面的方法。
Maya幫助文檔中把編寫界面的mel命令稱為ELF命令。
"Most ELF commands create and modify UI elements. " [Maya Help docs]
大部分ELF命令創(chuàng)建和修改UI元素。
"ELF","UI"這么多縮寫真的很讓人感到厭煩。
"ELF" - Extended Layer Framework(擴展層框架)
這個詞匯有點多余,我會盡可能少提到它。
"UI" - User Interface(用戶界面)
用戶界面的含義相信大多數(shù)人都知道,用戶界面又稱人機界面,實現(xiàn)用戶與計算機之間得通信,以控制計算機或進行用戶和計算機之間得數(shù)據(jù)傳送得系統(tǒng)部件。具體的說,我們平常使用的窗口、菜單、按鈕等都是用戶界面的元素。
"界面"
我們平常所說的界面都是指“用戶界面”,因為程序員是少數(shù)派,用戶才是上帝,所以用戶們從來不怕直接說界面會被別人誤解為“應(yīng)用程序設(shè)計界面”。我后面也把用戶界面簡稱為界面,希望不要給我糾正。
[注]
"API" - Application Programming Interface
有幾種不同譯法:應(yīng)用程序界面,應(yīng)用程序設(shè)計界面,應(yīng)用程序接口。這是一種專門給程序員使用的界面或接口,例如Maya API。
現(xiàn)在來編寫一個窗口。用mel編寫一個窗口就像創(chuàng)建一個球或者方塊那么簡單。
"window"命令 (創(chuàng)建窗口)
在命令行輸入"window"(打字的候要小心,不要讓視窗變成寡婦window-widow)然后回車,一個窗口就創(chuàng)建好了。不要因為沒看到有什么變化而認(rèn)為我在欺騙你,"window"命令創(chuàng)建的窗口在默認(rèn)情況下是不可見的,換句話說,"window"命令的"-vis/-visible"的默認(rèn)參數(shù)值為0(或false),也就是說直接輸入"window"命令和輸入"window -visible false"是等效的。
"showWindow"命令 (顯示窗口)
要想創(chuàng)建可以看得到的窗口,有兩種方法。一種方法是在創(chuàng)建窗口時用"window -visible true",另一種方法是創(chuàng)建窗口后執(zhí)行"showWindow"命令。這時我會推薦你用第二種方法,"showWindow"的好處是既顯示窗口,又把這個窗口推到所有窗口的最前面。
好,現(xiàn)在就在命令行輸入"showWindow"并回車,一個窗口便顯示了出來。
唯一的命名
因為你可以創(chuàng)建很多個窗口,因此如果想完全控制每個窗口,就必須給每個窗口指定一個唯一的命名。執(zhí)行下面兩句命令:
-----------------------------------------
window -t "我的測試窗" myTestWin;
showWindow myTestWin;
-----------------------------------------
這里"myTestWin"就是窗口的名字。
"-t/-title"的用途想必不用我多作解釋了吧?
當(dāng)一個窗口創(chuàng)建時,會另人想到另一個問題,就是怎么把它銷毀(刪除)。點窗口右上角標(biāo)題欄上的那個"×"可以關(guān)閉窗口,然而關(guān)閉窗口卻蘊含著兩層意思。在大多數(shù)情況下,關(guān)閉窗口可以銷毀窗口,有少數(shù)情況,關(guān)閉窗口以后窗口只是處于不可見狀態(tài),窗口并沒被銷毀,你隨時可以用"showWindow"命令來顯示它。用"-ret/-retain"標(biāo)志創(chuàng)建的窗口就屬于這種少數(shù)情況。
"deleteUI"命令 (銷毀界面元素)
要想讓徹底銷毀窗口,使用"deleteUI"命令。"deleteUI"可以銷毀任何界面元素,包括布局、控件和菜單。在命令行輸入"deleteUI myTestWin"并回車,"myTestWin"就被銷毀了。
為方便以后對于這個窗口代碼的調(diào)用,我們來編寫一個函數(shù)。
-----------------------------------------
global proc myTest()
{
if(`window -ex myTestWin`) // 如果myTestWin窗口已經(jīng)存在了
deleteUI myTestWin; // 就把myTestWin銷毀
window -t "我的測試窗" myTestWin;
showWindow myTestWin;
}
myTest;
"if"語句
這里用到了if語句,我覺得if語句是最容易理解的語句,把"if"直譯成"如果"就可以理解。if后面那個小括號里的代碼表示的只能是一個布爾值,是(1, true)或否(0, false)。當(dāng)表示否時,可以在前面加一個嘆號,"!"可以直譯成"不"。例如:
if(!`window -ex myTestWin`) // 表示如果myTestWin窗口不存在
也就是:
if(`window -ex myTestWin` == false) // `window -ex myTestWin`的返回值為0
現(xiàn)在只是編寫了一個空的窗口,要是想往窗口中添加一些按鈕或者文本框什么的怎么辦呢?
控件,布局
按鈕或者文本框這些東東統(tǒng)稱控件(control),mel擺放控件的特色是使用布局(layout)。在不同的布局中,控件擺放的方法不同,比如豎布局(columnLayout)中的控件都是一個挨一個豎著擺放的,而橫布局(rowLayout)中的控件都是橫著排列的。
"window"命令之后必須有一個布局,這個布局作為窗口的主布局,其它控件或布局都放置在這個主布局之中。
層級關(guān)系
由于布局之中既可以放布局又可以放控件,因此布局與控件,布局與布局之間構(gòu)成了一種層級關(guān)系(父子關(guān)系)。例如,布局columnLayout2在布局columnLayout1之中,columnLayout1稱為columnLayout2的父布局(Parents),columnLayout2稱為columnLayout1的子布局(Children)。
"setParent"命令 (指定當(dāng)前布局)
默認(rèn)的,剛剛創(chuàng)建的布局為當(dāng)前布局,新建的布局或控件都建在當(dāng)前布局中。要想使以前創(chuàng)建的布局成為當(dāng)前布局,使用setParent命令:"setParent 布局名"。要想使上一級布局(父布局)成為當(dāng)前布局,使用"setParent .."。
"columnLayout"命令 (豎布局)
對于不在乎界面美觀的人來說,學(xué)會一個豎布局差不多就足夠了。
豎布局中的控件都是一個挨一個豎著擺放的,請看下面的代碼:
-------------------------------------------------------------
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 "創(chuàng)建圓錐" -c "cone";
button -l "刪除" -c "delete";
showWindow myTestWin;
}
myTest;
-------------------------------------------------------------
執(zhí)行這段代碼,不要關(guān)掉生成的窗口。
"text"命令 (靜態(tài)文本)
"textField"命令 (文本框)
"button"命令 (按鈕)
這里用到三個關(guān)于界面的mel命令:"text","textField","button"。
根據(jù)生成的窗口你就可以猜到這三個命令的意思。
"text"為靜態(tài)文本,"textField"為文本框,"button"為按鈕。
"-l/-label"可能是界面命令中最明顯、最容易理解的標(biāo)志了,意思是界面元素的標(biāo)簽。
"-tx/-text"是文本框中的文字。
"-c/-command"是要執(zhí)行的mel命令,注意這個命令是一個字符串,一般要用引號引起來。
"-adj"決定是否自動調(diào)整布局內(nèi)控件的寬度。
"-q/-query"(查詢)和"-e/-edit"(編輯)標(biāo)志
這是兩個非常特殊又非常有用的標(biāo)志,所有的界面命令都用到這兩個標(biāo)志。
"-q/-query" 表示查詢的意思,你可以通過它獲得某一標(biāo)志的數(shù)值。
"-e/-edit" 表示編輯的意思,你可以通過它修改某一標(biāo)志的數(shù)值。
下面舉例說明它們的用法:
在剛才創(chuàng)建的窗口的文本框中隨便輸入幾個字,在命令行輸入"textField -q -tx myConeNameFld"并回車,可以在輸出窗口中看到文本框中的字。
在命令行輸入"textField -e -tx "change" myConeNameFld"并回車,文本框中的字就變成了"change"。前面說過"deleteUI"可以銷毀任何界面元素,在命令行輸入"deleteUI myConeNameFld"并回車,文本框消失了。
獲取本框中的文字
編寫按鈕命令
要想創(chuàng)建的圓錐根據(jù)本框中的文字來命名,使用下面的代碼:
-----------------------------------------
// 先編寫一個函數(shù)(createCone),然后在按鈕命令中調(diào)用這個函數(shù)。
global proc createCone()
{
string $name = `textField -q -tx myConeNameFld`; // 獲取文本框中的文字
cone -name $name; // 用文本框中的文字為名稱創(chuàng)建圓錐
}
global proc myTest()
{
if(`window -ex myTestWin`)
deleteUI myTestWin;
window -t "豎布局(columnLayout)測試窗" myTestWin;
columnLayout -adj 1;
text -l "圓錐名稱";
textField -tx "cone" myConeNameFld;
button -l "創(chuàng)建圓錐" -c "createCone"; // 按鈕命令中調(diào)用createCone函數(shù)
button -l "刪除" -c "delete";
showWindow myTestWin;
}
myTest;
-----------------------------------------
改一下文本框中的字,按"創(chuàng)建圓錐"按鈕,這時創(chuàng)建的圓錐是按照文本框中的文字命名的。注意,對物體命名時不能使用標(biāo)點符號,不能使用大多數(shù)的中文字,具體原因在后面講到如何用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"命令 (邊框布局)
邊框布局中只能放布局,不能放控件。
下面的代碼提供幾種不同風(fēng)格的邊框:
-----------------------------------------
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 ..;
// 其它幾種標(biāo)簽在邊框線的位置不同,邊框線的風(fēng)格不同,如圖。
// 第二種:
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"如果邊框可折疊,現(xiàn)在是否折疊。
"-bs/borderStyle"邊框線的風(fēng)格,可用值為:"in", "out", "etchedIn", 或 "etchedOut"。
"labelAlign"邊框標(biāo)簽的對齊方式,可用值為:are "top", "center", 或 "bottom"。
"paneLayout"命令 (窗格布局)
窗格布局一個很明顯的特點就是有分隔線分隔窗格面板,你可以移動分隔線來調(diào)整窗格面板的大小。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"命令 (標(biāo)簽布局)
標(biāo)簽布局中只能放布局,不能放控件。標(biāo)簽布局中可以放多個并列的子布局,當(dāng)鼠標(biāo)點到某一標(biāo)簽時,就顯示與此標(biāo)簽對應(yīng)的子布局。對于控件很多的面板,標(biāo)簽布局無疑是最好的選擇。
-----------------------------------------
global proc myTest()
{
if(`window -ex myTestWin`) deleteUI myTestWin;
window -t "標(biāo)簽布局(tabLayout)測試窗" myTestWin;
string $tabs = `tabLayout`;
string $child1 = `columnLayout -adj 1`; // 標(biāo)簽1
button; button; button;
setParent ..;
string $child2 = `rowColumnLayout -numberOfColumns 2`; // "標(biāo)簽2"
button; button; button;
setParent ..;
tabLayout -edit
-tabLabel $child1 "標(biāo)簽1" -tabLabel $child2 "標(biāo)簽2"
$tabs;
showWindow myTestWin;
}
myTest;
-----------------------------------------
string $tabs = `tabLayout`;
這句的意思獲取tabLayout命令的返回值,存到變量$tabs里。
前面說過界面元素要有一個唯一的命名,如果你沒有給它命名,Maya會自動給它一個命名。界面命令的返回值就是界面元素的名稱,因此用獲取命令返回值的方法就可以獲得界面元素的名稱。(string $變量 = `界面命令`;)
string $child1 = `columnLayout -adj 1`;
這句也是同樣的道理。
"formLayout"命令 (表單布局)
表單布局是最強大、最復(fù)雜、最具有可塑性的布局。這種布局可以隨意把控件放到任何你想要的地方,也可以根據(jù)窗口的縮放即時縮放指定的控件。如果你很注重界面舒適美觀的話,它就是你必然的選擇。
-----------------------------------------
global proc myTest()
{
if(`window -ex myTestWin`) deleteUI myTestWin;
window -t "表單布局(formLayout)測試窗" myTestWin;
// 創(chuàng)建表單布局和布局中的控件
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" // 底部為默認(rèn)值
-attachForm $b2 "right" 5 // 右邊距離表單5個像素
// 按鈕3
-attachControl $b3 "top" 5 $b2 // 頂部距離"按鈕2"5個像素
-attachControl $b3 "left" 5 $b1 // 左邊距離"按鈕1"5個像素
-attachNone $b3 "bottom" // 底部為默認(rèn)值
-attachForm $b3 "right" 5 // 右邊距離表單5個像素
$form;
showWindow myTestWin;
}
myTest;
-----------------------------------------
當(dāng)你拉大或縮小這個窗口時,"按鈕1"的寬度總是占整個窗口的75%。
編寫表單布局一般分為兩步:
1.創(chuàng)建表單布局和布局中的控件。
2.分別描述每個按鈕的上下左右位置。
"-af/attachForm" 距離表單多少個像素。
"-ac/attachControl" 距離控件多少個像素。
"-ap/attachPosition" 距離表單的幾(-numberOfDivisions)分之幾多少個像素。
"-nd/numberOfDivisions" 把表單分成多少份,好用于"-ap/attachPosition"。默認(rèn)值為100。
學(xué)習(xí) · 提示
相關(guān)教程