當(dāng)前位置:首頁>軟件教程>maya教程>教程內(nèi)容

mel語初解之二-多邊型建模

來源: 作者:七月冰兒 學(xué)習(xí):4168人次

眾所周知,maya的多邊形建模能力是不如人意的,因此這時(shí)mel會(huì)派上很大的用場。相信很多人都用過一些輔助性的建模工具,例如MJPolyTools、BPT、icePolyTools...我在教程中會(huì)對這些程序的關(guān)鍵功能的編寫方法作出詳細(xì)說明,希望大家能在掌握這些功能的基礎(chǔ)之上編寫出自己稱心如意的Poly工具。

現(xiàn)在繼續(xù)mel的教程,如果你對mel還一無所知的話,請看mel語初解之一-基礎(chǔ)和界面篇:
http://www.theoat.com.cn/photoshop/jiaocheng/106791.html

眾所周知,maya的多邊形建模能力是不如人意的,因此這時(shí)mel會(huì)派上很大的用場。相信很多人都用過一些輔助性的建模工具,例如MJPolyTools、BPT、icePolyTools、CPS、drawSplit、rockGen...我在教程中會(huì)對這些程序的關(guān)鍵功能的編寫方法作出詳細(xì)說明,希望大家能在掌握這些功能的基礎(chǔ)之上編寫出自己稱心如意的Poly工具。

mel作為腳本語言使用非常方便,在工作中會(huì)很容易地把你的一些簡單想法付諸實(shí)踐。

在講Poly建模之前,需要復(fù)習(xí)一下以前的知識(shí)。

首先要復(fù)習(xí)一下數(shù)組(Array):一群變量放到了一起,這群變量就成了一個(gè)數(shù)組變量。不過這些變量不是隨便放的,每個(gè)變量都有一個(gè)房間,每個(gè)房間都有順次的門牌號(hào),我們就是根據(jù)門牌號(hào)來訪問任何一個(gè)數(shù)組成員的。請看這個(gè)字符串?dāng)?shù)組的例子:

選擇幾個(gè)場景中的物體。

// 獲取場景中的每一個(gè)物體,分別放入數(shù)組$objects的每個(gè)房間中
string $objects[] = `ls -sl`;

這時(shí)數(shù)組的狀態(tài)如圖所示。$objects可以看作是公寓的名稱,[]里的紅色數(shù)字為房間的門牌號(hào),也叫作索引號(hào)(index)。數(shù)組的索引號(hào)總是從0開始的。也就是說$objects[0]為數(shù)組的第一個(gè)成員,它的值為"pSphere1";而$objects[1]為數(shù)組的第二個(gè)成員,他的值為"pCube1";以此類推。

我們可以從數(shù)組中取值,例如:
string $obj = $objects[0];
// 此時(shí)變量$obj的值為"pSphere1"

也可以給數(shù)組的成員賦值,例如:
$objects[1] = "pBox1";
// 此時(shí)數(shù)組$objects的值為{"pSphere1", "pBox1", "pCone1"}

要想遍歷數(shù)組中的每個(gè)成員,可以用for語句,有兩種方法。

// 方法一
string $objects[] = `ls -sl`;
for ($i = 0; $i < size($objects); $i++)
{
string $obj = $objects[$i];
// do something ...
}

// 方法二
string $objects[] = `ls -sl`;
for ($obj in $objects)
{
// do something ...
}
[注] mel的for...in語句和JavaScript有所不同,$obj是字符串,指的是
當(dāng)前的數(shù)組成員,等同于"string $obj = $objects[$i];"

再復(fù)習(xí)一下函數(shù)(Function):

如果你編寫比較復(fù)雜的程序,就會(huì)發(fā)現(xiàn)有很多經(jīng)常用到的語句,這些語句經(jīng)常以相同的組合出現(xiàn)。這樣的語句編寫起來有些麻煩,看起來也不太直觀。為了提高工作效率,增加可讀性,我們可以使用函數(shù)把它們封裝起來。下面舉例說明。

還記得前面講過的filterExpand獲取多邊形面的方法吧?

string $faces[] = `filterExpand -ex 1 -sm 34`;

對初學(xué)者來說,看到"-sm 34"后,總是很難聯(lián)想到多邊形的面。當(dāng)然你可以用maya的全局變量$gSelectMeshFaces來替代34,不過這樣做有些麻煩。我們編一個(gè)新的函數(shù)來做與上面代碼同樣的事情。

proc string[] getSelFaces()
{
return `filterExpand -ex true -sm 34`;
}
// [注] Sel為Selected的縮寫

有了這個(gè)函數(shù),我們以后再獲取多邊形的面時(shí),就可以這樣寫:string $faces[] = `getSelFaces`;

也可以這樣寫:string $faces[] = getSelFaces();

return為返回的意思,proc后面的字代表返回值的類型,return后面的字(變量或表達(dá)式)代表返回值,也就是函數(shù)的輸出值。

對初學(xué)者來說,看到"-sm 34"后,總是很難聯(lián)想到多邊形的面。當(dāng)然你可以用maya的全局變量$gSelectMeshFaces來替代34,不過這樣做有些麻煩。我們編一個(gè)新的函數(shù)來做與上面代碼同樣的事情。

proc string[] getSelFaces()
{
return `filterExpand -ex true -sm 34`;
}
// [注] Sel為Selected的縮寫

有了這個(gè)函數(shù),我們以后再獲取多邊形的面時(shí),就可以這樣寫:string $faces[] = `getSelFaces`;

也可以這樣寫:string $faces[] = getSelFaces();

return為返回的意思,proc后面的字代表返回值的類型,return后面的字(變量或表達(dá)式)代表返回值,也就是函數(shù)的輸出值。

再看一個(gè)例子:

proc string[] getPolySel(string $type)
{
if ($type == "vert")
return `filterExpand -ex true -sm 31`;

if ($type == "edge")
return `filterExpand -ex true -sm 32`;

if ($type == "face")
return `filterExpand -ex true -sm 34`;

// 假如輸入?yún)?shù)是非預(yù)期的,就返回一個(gè)空數(shù)組
string $null[];
return $null;
}
想要獲取多邊形的面時(shí),可以這樣寫: string $faces[] = getSelFaces("face");

或: string $faces[] = `getPolySel "face"`;

這回用到了函數(shù)的輸入?yún)?shù)(string $type),根據(jù)輸入?yún)?shù)的不同,產(chǎn)成不同的返回值。

一個(gè)函數(shù)可以既沒有輸入?yún)?shù)也沒有返回值,也可以只有其一。參數(shù)可以是多個(gè),返回值只能是一個(gè)。

return語句執(zhí)行之后,后面的語句將不再執(zhí)行。例如:
 

proc myProc()
{
// 獲取選擇的物體
string $objects[] = `ls -sl`;
// 如果什么都沒選擇,就返回(什么也不做)。
if (!size($objects))
return;

// do something ...
}
proc myProc()
{
// 獲取選擇的物體
string $objects[] = `ls -sl`;
// 如果什么都沒選擇,就返回(什么也不做)。
if (!size($objects))
return;

// do something ...
}

或: string $faces[] = `getPolySel "face"`;

這回用到了函數(shù)的輸入?yún)?shù)(string $type),根據(jù)輸入?yún)?shù)的不同,產(chǎn)成不同的返回值。

一個(gè)函數(shù)可以既沒有輸入?yún)?shù)也沒有返回值,也可以只有其一。參數(shù)可以是多個(gè),返回值只能是一個(gè)。

return語句執(zhí)行之后,后面的語句將不再執(zhí)行。例如:
 

proc myProc()
{
// 獲取選擇的物體
string $objects[] = `ls -sl`;
// 如果什么都沒選擇,就返回(什么也不做)。
if (!size($objects))
return;

// do something ...
}
proc myProc()
{
// 獲取選擇的物體
string $objects[] = `ls -sl`;
// 如果什么都沒選擇,就返回(什么也不做)。
if (!size($objects))
return;

// do something ...
}

global procproc的區(qū)別

proc是局部函數(shù),局部函數(shù)只能在編寫這個(gè)函數(shù)的mel文件中使用,不能在其他mel文件中使用,不能作為菜單和按鈕命令,不占用內(nèi)存空間。

global proc是全局函數(shù),沒有proc那些局限。使用全局函數(shù)應(yīng)注意,函數(shù)名不能與Maya中已有的全局函數(shù)或mel命令相同,否則會(huì)把原來的覆蓋掉,可以通過使用函數(shù)名前綴來避免重復(fù)命名。關(guān)于全局函數(shù)的使用,最好了解一些Maya的運(yùn)行方式。Maya啟動(dòng)時(shí)一般只把指定scripts路徑中的*.mel文件名(*)載入內(nèi)存,這樣Maya運(yùn)行時(shí)就可以調(diào)用這個(gè)文件中的同名函數(shù),而當(dāng)調(diào)用這個(gè)同名函數(shù)時(shí),這個(gè)mel文件中的所有全局函數(shù)將被載入內(nèi)存,直到Maya退出。

如果還不明白,那就統(tǒng)統(tǒng)使用global proc好了,沒什么大不了的。

下面提供幾個(gè)多邊形建模常用到的函數(shù),因?yàn)楹竺娼?jīng)常用到,所以應(yīng)該熟練掌握,至少對于每個(gè)函數(shù)做什么事要很清楚。
// 獲取選擇的多邊形頂點(diǎn)
proc string[] getSelVerts()
{
return `filterExpand -ex true -sm 31`;
}

// 獲取選擇的多邊形邊
proc string[] getSelEdges()
{
return `filterExpand -ex true -sm 32`;
}

// 獲取選擇的多邊形面
proc string[] getSelFaces()
{
return `filterExpand -ex true -sm 34`;
}

// 獲取選擇的多邊形UV點(diǎn)
proc string[] getSelUVs()
{
return `filterExpand -ex true -sm 35`;
}

用法范例:

// 獲取選擇的所有面,存放到數(shù)組$faces[]中
string $faces[] = getSelFaces();
    這四個(gè)函數(shù)是maya內(nèi)置的,也是菜單命令,經(jīng)常用到。

// 菜單命令:Edit Polygons->Selection->Convert Selection to Vertices
// 轉(zhuǎn)換當(dāng)前選擇為頂點(diǎn)

ConvertSelectionToVertices();

// 菜單命令:Edit Polygons->Selection->Convert Selection to Edges
// 轉(zhuǎn)換當(dāng)前選擇為邊

ConvertSelectionToEdges();

// 菜單命令:Edit Polygons->Selection->Convert Selection to Faces
// 轉(zhuǎn)換當(dāng)前選擇為面

ConvertSelectionToFaces();

// 菜單命令:Edit Polygons->Selection->Convert Selection to UVs
// 轉(zhuǎn)換當(dāng)前選擇為UV點(diǎn)

ConvertSelectionToUVs();

用法范例:

// 獲取選擇的所有面,存放到數(shù)組$faces[]中
string $faces[] = getSelFaces();
    這四個(gè)函數(shù)是maya內(nèi)置的,也是菜單命令,經(jīng)常用到。

// 菜單命令:Edit Polygons->Selection->Convert Selection to Vertices
// 轉(zhuǎn)換當(dāng)前選擇為頂點(diǎn)

ConvertSelectionToVertices();

// 菜單命令:Edit Polygons->Selection->Convert Selection to Edges
// 轉(zhuǎn)換當(dāng)前選擇為邊

ConvertSelectionToEdges();

// 菜單命令:Edit Polygons->Selection->Convert Selection to Faces
// 轉(zhuǎn)換當(dāng)前選擇為面

ConvertSelectionToFaces();

// 菜單命令:Edit Polygons->Selection->Convert Selection to UVs
// 轉(zhuǎn)換當(dāng)前選擇為UV點(diǎn)

ConvertSelectionToUVs();

這四個(gè)函數(shù)在maya的scripts/others目錄中,可以直接調(diào)用。

// 轉(zhuǎn)換當(dāng)前選擇為頂點(diǎn),并獲取這些頂點(diǎn)的名稱
global proc string[] getVerts()
{
select -r `polyListComponentConversion -tv`;
string $result[]=`filterExpand -ex true -sm 31`;
return $result;
}

// 轉(zhuǎn)換當(dāng)前選擇為邊,并獲取這些點(diǎn)的名稱
global proc string[] getEdges()
{
select -r `polyListComponentConversion -te`;
string $result[]=`filterExpand -ex true -sm 32`;
return $result;
}

// 轉(zhuǎn)換當(dāng)前選擇為面,并獲取這些面的名稱
global proc string[] getFaces()
{
select -r `polyListComponentConversion -tf`;
string $result[]=`filterExpand -ex true -sm 34`;
return $result;
}

// 轉(zhuǎn)換當(dāng)前選擇為UV點(diǎn),并獲取這些UV點(diǎn)的名稱
global proc string[] getUVs()
{
string $uvs[];
$uvs=`polyListComponentConversion -tuv`;
if (size($uvs) == 0) return $uvs;
select -r $uvs;
string $result[]=`filterExpand -ex true -sm 35`;
return $result;
}
// 根據(jù)點(diǎn)、邊、面、UV點(diǎn)的名稱得出多邊形的名稱
// 例如多邊形一條邊的名稱為"pSphere1.e[637]",則這個(gè)多邊形的
// 名稱為"pSphere1"

proc string getBaseName(string $item)
{
string $buffer[];
if ($item != "")
{
tokenize($item, ".", $buffer);
}
return $buffer[0];
}

用法范例:

string $polyName = getBaseName("pSphere1.e[637]");

// 返回值:pSphere1
// 根據(jù)點(diǎn)、邊、面、UV點(diǎn)的名稱得出它們的索引號(hào)
// 例如多邊形一條邊的名稱為"pSphere1.e[637]",則這個(gè)多邊形的
// 索引號(hào)為637

proc int getIndex(string $indexString)
{
string $buffer[];
tokenize($indexString, "[]", $buffer);
int $index = (int)$buffer[1];
return $index;
}

用法范例:

int $index = getIndex("pSphere1.e[637]");
// 返回值:637

首先介紹一個(gè)有用的函數(shù)(intersectStringArray)。這個(gè)函數(shù)可以找到兩個(gè)數(shù)組的共同部分,比如數(shù)組1為{"兔子", "老虎", "山羊", "蟲子"},數(shù)組2為{"蟲子", "刀子", "梳子", "兔子", "珠子"},你可以獲得一個(gè)新數(shù)組包含它們的共同部分{"兔子", "蟲子"}。

// 獲得兩個(gè)數(shù)組的共同部分
proc string[] intersectStringArray(string $array1[], string $array2[])
{
global string $m_arrayIntersector;
if ($m_arrayIntersector == "")
$m_arrayIntersector = `stringArrayIntersector`;

stringArrayIntersector -edit -intersect $array1 $m_arrayIntersector;
stringArrayIntersector -edit -intersect $array2 $m_arrayIntersector;
string $result[] = `stringArrayIntersector -query $m_arrayIntersector`;
stringArrayIntersector -edit -reset $m_arrayIntersector;
return $result;
}
    [注] global string代表一個(gè)全局字符串變量,以前講過全局變量應(yīng)當(dāng)盡量避免命名沖突。maya中的全局變量都是以
小寫字母"g"開頭,為避免沖突,本教程中的全局變量一律使用"m_"作為前綴。
    前面介紹過的函數(shù)可以看作是工具函數(shù),這些函數(shù)幾乎在以后的每個(gè)程序中都要用到。如果編寫某一功能,還需要編寫
一些有針對性的專用函數(shù),F(xiàn)在我們來編一個(gè)多邊形的導(dǎo)角功能,來看看一個(gè)完整的程序是怎樣完成的。

			
			
		

學(xué)習(xí) · 提示

  • 一定要打開PS,跟著教程做一遍,做完的圖到這交作業(yè):提交作業(yè)
  • 建議練習(xí)時(shí),大家自己找素材,盡量不要用教程提供的素材。
  • 教程有看不懂的地方,可以到論壇發(fā)帖提問:新手求助
  • 加官方微信,隨時(shí)隨地,想學(xué)就能學(xué):ps_bbs,或掃右側(cè)二維碼!
  • 關(guān)注我們學(xué)更多,每天都有新教程:新浪微博 抖音視頻 微信小程序
- 發(fā)評(píng)論 | 交作業(yè) -
最新評(píng)論
暫無評(píng)論,交個(gè)作業(yè)支持一下吧~

關(guān)注大神微博加入>>

網(wǎng)友求助,請回答!