<th id="bwd7y"><progress id="bwd7y"></progress></th>
    <dfn id="bwd7y"></dfn>
        • <b id="bwd7y"></b>

              <noframes id="bwd7y"><menu id="bwd7y"><td id="bwd7y"></td></menu>
              1. 暴雪國(guó)際動(dòng)漫教育
                • 暴雪國(guó)際2024招生簡(jiǎn)章
                • 暴雪國(guó)際2024招生簡(jiǎn)章
                • 暴雪國(guó)際2024招生簡(jiǎn)章
                • 暴雪國(guó)際2024招生簡(jiǎn)章
                在線咨詢 預(yù)約課程 網(wǎng)上報(bào)名
                Maya建模教程

                maya建模教程:多邊型建模篇

                編輯:張闖來(lái)源:暴雪國(guó)際教育發(fā)布時(shí)間:2010-08-03

                再看看每條邊的索引號(hào),也是按照創(chuàng)建時(shí)的順序指定的。一條邊有兩個(gè)點(diǎn),分別為起點(diǎn)和終點(diǎn),這兩個(gè)點(diǎn)決定了邊的構(gòu)造順序。
                mel語(yǔ)初解之二-多邊型建模篇

                使用Edit Polygons->Split Polygon Tool在正方形上切一刀。
                mel語(yǔ)初解之二-多邊型建模篇

                我們看一下polySplit的用法,-ep后面有兩個(gè)參數(shù),第一個(gè)參數(shù)(3)是邊的索引號(hào),第二個(gè)參數(shù)(0.263489)是百分比,如果邊的長(zhǎng)度為1,切割點(diǎn)在邊的0.263489處。

                切割點(diǎn)位置的受到邊的構(gòu)造順序的影響,以polySurface1.e[3]這條邊為例,從邊的起點(diǎn)開(kāi)始,沿著邊的終點(diǎn)方向量出整條邊的約26%的長(zhǎng)度,這個(gè)位置就是切割點(diǎn)的位置。
                mel語(yǔ)初解之二-多邊型建模篇

                 

                使用polySplit的一大難點(diǎn)就是判斷邊的構(gòu)造順序,也就是分清邊的起點(diǎn)和終點(diǎn)。為了做到這一點(diǎn),我們需要用到一個(gè)mel命令 - polyInfo。

                選擇一條邊線(e[3]),在命令行執(zhí)行"polyInfo -ev;",可以看到輸出結(jié)果"// Result: EDGE 3: 3 0 Hard",其中"EDGE 3:"代表邊線(e[3]),3和0分別代表組成這條邊的兩個(gè)點(diǎn)(vtx[3]和vtx[0])的索引號(hào)。注意,這兩個(gè)點(diǎn)的順序不是按大小排列的,而是按照邊線的構(gòu)造順序。
                mel語(yǔ)初解之二-多邊型建模篇

                我們把polyInfo按照自己的需要封裝起來(lái)。主要是用字符處理的方法實(shí)現(xiàn)的,注意這里用到了一個(gè)前面講過(guò)的工具函數(shù)getBaseName()。你會(huì)發(fā)現(xiàn)這個(gè)函數(shù)的用途與getVerts()很像,但getVerts()無(wú)法得知邊線的構(gòu)造順序。

                 

                // 根據(jù)一條邊,得到這條邊的按構(gòu)造順序排列的兩個(gè)端點(diǎn)。
                proc string[] edge2Vertex(string $edge)
                {
                string $verts[], $buffer[];
                string $edgeInfo[] = `polyInfo -ev $edge`;
                int $nbVertex = tokenize($edgeInfo[0], $buffer);

                string $polyName = getBaseName($edge);
                $verts[0] = $polyName + ".vtx[" + $buffer[2] + "]";
                $verts[1] = $polyName + ".vtx[" + $buffer[3] + "]";
                return $verts;
                }


                第二步,我們要找到需要切割的兩條邊。

                我們可以根據(jù)選擇的一條邊,和要切割的那個(gè)面來(lái)判斷。
                mel語(yǔ)初解之二-多邊型建模篇

                選擇一條邊。

                Mel歷史窗中的代碼:
                 

                select -r polySurface1.e[6] ;


                mel語(yǔ)初解之二-多邊型建模篇

                Edit Polygons->Selection->Convert Selection to Vertices,轉(zhuǎn)換成頂點(diǎn)。
                [注] 這一步mel歷史窗中可能看不到變化,按z鍵undo一下就看到了。

                Mel歷史窗中的代碼:

                 

                ConvertSelectionToVertices;


                mel語(yǔ)初解之二-多邊型建模篇

                再選擇Edit Polygons->Selection->Convert Selection to Edges,轉(zhuǎn)換成邊。

                Mel歷史窗中的代碼:

                 

                ConvertSelectionToEdges;


                mel語(yǔ)初解之二-多邊型建模篇

                去掉開(kāi)始那條邊的選擇。

                Mel歷史窗中的代碼:

                 

                select -tgl polySurface1.e[6] ;


                [注] select -d polySurface1.e[6] ;也可。
                 

                現(xiàn)在剩下四條邊,可以用getSelEdges()把它們存到一個(gè)數(shù)組中。
                數(shù)組1:
                {"polySurface1.e[1]",
                "polySurface1.e[3]",
                "polySurface1.e[4]",
                "polySurface1.e[5]"}
                mel語(yǔ)初解之二-多邊型建模篇

                選擇要切割的面。

                Mel歷史窗中的代碼:

                 

                select -r polySurface1.f[1] ;


                getEdges()把屬于面的四條邊存到另一個(gè)數(shù)組中。
                {polySurface1.e[0],
                polySurface1.e[1],
                polySurface1.e[4],
                polySurface1.e[6]}
                mel語(yǔ)初解之二-多邊型建模篇

                用intersectStringArray()可以找到兩個(gè)數(shù)組的共同部分,就是我們將要切割的兩條邊。
                {polySurface1.e[1],
                polySurface1.e[4]}
                mel語(yǔ)初解之二-多邊型建模篇

                 

                把前面Mel歷史窗中記錄下的代碼整理一下,就成了:

                 

                // 已知一個(gè)面,這個(gè)面的一條邊,求與(這個(gè)面的)這條邊相鄰的兩條邊
                proc string[] adjacentEdgesInFace(string $face, string $edge)
                {
                // 獲取所有相鄰的邊線
                select -r $edge;
                ConvertSelectionToVertices();
                ConvertSelectionToEdges();
                select -d $edge;
                string $edges_vert[] = getSelEdges();

                // 獲取已知面的所有邊線
                select -r $face;
                string $edges_face[] = getEdges();

                // 求兩個(gè)數(shù)組的共同部分
                string $edges[] = intersectStringArray($edges_vert, $edges_face);
                return $edges;
                }


                第三步,切割一個(gè)面。

                我們可以先把切割的百分比設(shè)置一個(gè)固定的數(shù)值,設(shè)為0.2(20%)。

                我們可以通過(guò)edge2Vertex()來(lái)得到要切割的一條邊的起點(diǎn)和終點(diǎn),如果起點(diǎn)恰好是當(dāng)初選擇的那條邊線的一個(gè)端點(diǎn)(兩條邊的公共點(diǎn)),那么這條線的構(gòu)造順序是正的,可以直接使用20%;但如果構(gòu)造順序是反的,那就要使用1-20%=80%了。
                mel語(yǔ)初解之二-多邊型建模篇
                 

                這個(gè)函數(shù)應(yīng)該這么寫(xiě):

                 

                proc splitByPercent(string $edge1, string $edge2, string $inputEdge)
                {
                // 預(yù)設(shè)值,百分比為0.2
                float $percent = 0.2;
                float $percent1 = $percent; // 0.2
                float $percent2 = $percent; // 0.2

                // 分別獲得三條邊所包含的頂點(diǎn)
                string $verts1[], $verts2[], $vInput[];
                $vInput = edge2Vertex($inputEdge);
                $verts1 = edge2Vertex($edge1);
                $verts2 = edge2Vertex($edge2);

                // 求$edge1與$inputEdge的公共點(diǎn)
                string $startVert[] = intersectStringArray($verts1, $vInput);
                // 如果公共點(diǎn)不是$edge1的起點(diǎn)
                if ($startVert[0] != $verts1[0])
                // 百分比變?yōu)?0%,即1-0.2
                $percent1 = 1 - $percent;

                // 求$edge2與$inputEdge的公共點(diǎn)
                string $startVert[] = intersectStringArray($verts2, $vInput);
                if ($startVert[0] != $verts2[0])
                $percent2 = 1 - $percent;

                // 獲得兩條邊的索引號(hào)
                string $index1 = getIndex($edge1);
                string $index2 = getIndex($edge2);

                // 準(zhǔn)備命令字符串
                string $cmd = "polySplit -ch on -s 1 ";
                $cmd += "-ep " + $index1 + " " + $percent1 + " ";
                $cmd += "-ep " + $index2 + " " + $percent2 + " ";
                $cmd += ";";

                // 選擇整個(gè)多邊形物體
                string $polyName = getBaseName($edge1);
                select -r $polyName;

                // 執(zhí)行命令
                evalEcho($cmd);
                }

                [注] 使用evalEcho執(zhí)行命令可以把命令字符串在mel歷史窗中顯示出來(lái)。

                第四步,切割邊線兩邊的面。

                有了前面的準(zhǔn)備工作,最后一步就顯得比較容易了。

                 

                global proc myEdgeChamfer()
                {
                // 獲取選擇的一條邊
                string $edges[] = getSelEdges();
                string $inputEdge = $edges[0];

                // 獲取選擇的邊相鄰的兩個(gè)面
                string $faces[] = getFaces();

                // 等比切割第1個(gè)面
                string $splitEdges[];
                $splitEdges = adjacentEdgesInFace($faces[0], $inputEdge);
                splitByPercent($splitEdges[0], $splitEdges[1], $inputEdge);

                // 等比切割第2個(gè)面
                $splitEdges = adjacentEdgesInFace($faces[1], $inputEdge);
                splitByPercent($splitEdges[0], $splitEdges[1], $inputEdge);
                }


                附全部源代碼。

                 

                ///////////////////////////////////////////////////////////
                // myEdgeChamfer.mel
                // myEdgeChamfer v1

                // 獲取選擇的多邊形頂點(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`;
                }

                // 根據(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];
                }

                // 根據(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;
                }

                // 獲得兩個(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;
                }

                ///////////////////////////////////////////////////////////
                // 第一步,根據(jù)一條邊,得到這條邊的按構(gòu)造順序排列的兩個(gè)端點(diǎn)。
                proc string[] edge2Vertex(string $edge)
                {
                string $verts[], $buffer[];
                string $edgeInfo[] = `polyInfo -ev $edge`;
                int $nbVertex = tokenize($edgeInfo[0], $buffer);

                string $polyName = getBaseName($edge);
                $verts[0] = $polyName + ".vtx[" + $buffer[2] + "]";
                $verts[1] = $polyName + ".vtx[" + $buffer[3] + "]";
                return $verts;
                }

                // 已知一個(gè)面,這個(gè)面的一條邊,求與(這個(gè)面的)這條邊相鄰的兩條邊
                proc string[] adjacentEdgesInFace(string $face, string $edge)
                {
                // 獲取所有相鄰的邊線
                select -r $edge;
                ConvertSelectionToVertices();
                ConvertSelectionToEdges();
                select -d $edge;
                string $edges_vert[] = getSelEdges();

                // 獲取已知面的所有邊線
                sele ct -r $face;
                string $edges_face[] = getEdges();

                // 求兩個(gè)數(shù)組的共同部分
                string $edges[] = intersectStringArray($edges_vert, $edges_face);
                return $edges;
                }

                // 第三步,等比切割一個(gè)面
                proc splitByPercent(string $edge1, string $edge2, string $inputEdge)
                {
                // 預(yù)設(shè)值,百分比為0.2
                float $percent = 0.2;
                float $percent1 = $percent; // 0.2
                float $percent2 = $percent; // 0.2

                // 分別獲得三條邊所包含的頂點(diǎn)
                string $verts1[], $verts2[], $vInput[];
                $vInput = edge2Vertex($inputEdge);
                $verts1 = edge2Vertex($edge1);
                $verts2 = edge2Vertex($edge2);

                // 求$edge1與$inputEdge的公共點(diǎn)
                string $startVert[] = intersectStringArray($verts1, $vInput);
                // 如果公共點(diǎn)不是$edge1的起點(diǎn)
                if ($startVert[0] != $verts1[0])
                // 百分比變?yōu)?0%,即1-0.2
                $percent1 = 1 - $percent;

                // 求$edge2與$inputEdge的公共點(diǎn)
                string $startVert[] = intersectStringArray($verts2, $vInput);
                if ($startVert[0] != $verts2[0])
                $percent2 = 1 - $percent;

                // 獲得兩條邊的索引號(hào)
                string $index1 = getIndex($edge1);
                string $index2 = getIndex($edge2);

                // 準(zhǔn)備命令字符串
                string $cmd = "polySplit -ch on -s 1 ";
                $cmd += "-ep " + $index1 + " " + $percent1 + " ";
                $cmd += "-ep " + $index2 + " " + $percent2 + " ";
                $cmd += ";";

                // 選擇整個(gè)多邊形物體
                string $polyName = getBaseName($edge1);
                select -r $polyName;

                // 執(zhí)行命令
                evalEcho($cmd);
                }

                // 第四步,切割選擇的一條邊線兩邊的面。
                global proc myEdgeChamfer()
                {
                // 獲取選擇的一條邊
                string $edges[] = getSelEdges();
                string $inputEdge = $edges[0];

                // 獲取選擇的邊相鄰的兩個(gè)面
                string $faces[] = getFaces();

                // 等比切割第1個(gè)面
                string $splitEdges[];
                $splitEdges = adjacentEdgesInFace($faces[0], $inputEdge);
                splitByPercent($splitEdges[0], $splitEdges[1], $inputEdge);

                // 等比切割第2個(gè)面
                $splitEdges = adjacentEdgesInFace($faces[1], $inputEdge);
                splitByPercent($splitEdges[0], $splitEdges[1], $inputEdge);
                }


                寫(xiě)到大括號(hào)里就成了局部變量。

                寫(xiě)到大括號(hào)外面就是全局變量,不過(guò)這時(shí) float $bb = 5 ; 和 global float $bb = 5 ; 還是有一點(diǎn)點(diǎn)差別的,很容易讓人忽略。就是如果不寫(xiě)global,包含這句代碼的mel文件如果不被source,只是執(zhí)行了mel文件的同名函數(shù),那么$bb載入內(nèi)存時(shí)將不被賦值,這時(shí)$bb的值為 0。所以說(shuō)最好寫(xiě)上global。

                下面我想講一下關(guān)于全局變量和局部變量的區(qū)別吧.
                如何定義全局變量呢,定義全局變量必須在所有自定義函數(shù)的外邊,不能定義在{}里面:
                global int $a;//定義了全局變量,默認(rèn)值是0
                如果要調(diào)用的話:
                proc myfn()
                {
                global int $a;//在調(diào)用全局變量的時(shí)候必須在自己的函數(shù)里面在定義一下
                $a=10;
                .....
                }
                //這樣就是調(diào)用的過(guò)程
                強(qiáng)調(diào)一點(diǎn)的是,要想調(diào)用全局變量就必須在自己的函數(shù)里面在重新定義一邊.不燃的話,你試試看...呵呵

                局部變量就是:
                int $a;// 不加global 的
                但是所有的變量都有生命期的,所謂的生命期就是在一定的范圍內(nèi)有效...
                proc myfn()
                {
                int $a=10;
                if($a<20)
                {
                $a++;
                .........
                print $a;//reslut 11;
                }
                print $a;//result 11,而不是10了
                .........
                }
                這樣就是生命期,如果你在后面還調(diào)用的話,$a就不是10了,就是11了....

                我還想講一下的就是,正如七月冰兒講的一樣,如果想得到幾個(gè)邊的名稱的話,
                你會(huì)發(fā)現(xiàn)所有的名稱都是按照從小到大的順序進(jìn)行排序的來(lái)的,這樣有好處也有壞處,壞處就是有時(shí)后我不想得到是排列之后的名稱,我之想得到不排列的名稱...
                這也是多邊形的切割工具一直很麻煩的原因,總不能想3dmax那樣隨心所欲的進(jìn)行切割了....
                但是辦法是有的,目前我沒(méi)有想好,也許七月冰兒在他以后的版本里會(huì)出現(xiàn)這樣的功能的....
                我也在思索這個(gè)問(wèn)題,其實(shí)大家在使用的過(guò)程當(dāng)中,完全可以作出好多的快捷的功能的,就想在調(diào)權(quán)重值一樣,雖然maya提供了cmeditor,但還是很不方便的...
                以后接著說(shuō),希望大家都能夠參與近來(lái)呀
                 

                假如你有一個(gè)mel文件,文件名為myTest.mel,文件內(nèi)容如下:

                 

                float $bb = 5;
                global proc myTest()
                {
                // do nothing
                }


                啟動(dòng)Maya,使用env命令查看一下當(dāng)前的全局變量,可以發(fā)現(xiàn)此時(shí)變量$bb不存在。當(dāng)執(zhí)行myTest命令時(shí),這時(shí)$bb作為全局變量載入內(nèi)存,再用env命令查看一下,發(fā)現(xiàn)$bb已經(jīng)存在了。但是執(zhí)行print $bb;會(huì)看到結(jié)果為0。

                重新啟動(dòng)Maya,啟動(dòng)后執(zhí)行source myTest.mel;這時(shí)再執(zhí)行print $bb;可以看到輸出了正確的結(jié)果5,這時(shí)$bb已經(jīng)作為全局變量載入了內(nèi)存。

                這就是我說(shuō)的如果不寫(xiě)global,包含這句代碼的mel文件如果不被source,只是執(zhí)行了mel文件的同名函數(shù),那么$bb載入內(nèi)存時(shí)將不被賦值,這時(shí)$bb的值為 0。

                如果你只是(在所有大括號(hào)外面)聲明變量,在函數(shù)中給它賦值,就可以不寫(xiě)global了。比如代碼改成這樣就沒(méi)問(wèn)題了。

                 

                // 在Maya6.0中測(cè)試通過(guò)
                float $bb;
                global proc myTest()
                {
                global float $bb;
                $bb = 5;
                }


                如果想在函數(shù)外面聲明和使用變量,又不想讓Maya當(dāng)作全局變量,可以加大括號(hào),函數(shù)的生命在大括號(hào)結(jié)束時(shí)消亡。例如:
                 

                {
                float $bb;
                ... ...
                }


                關(guān)于全局變量的用法,可以參考junesnow的說(shuō)明,不過(guò)要注意我做的一點(diǎn)更正。
                 


                 

                首頁(yè) 上一頁(yè) 1 2

                上一篇:maya建模教程:利用貫穿動(dòng)態(tài)拉出一造型物

                下一篇:maya建模教程:卡通螞蟻的制作

                草草久久久无码国产专区,国产精品一码二码三码在线,无码综合一区二区三区,在线播放午夜无码毛片
                <th id="bwd7y"><progress id="bwd7y"></progress></th>
                  <dfn id="bwd7y"></dfn>
                      • <b id="bwd7y"></b>

                            <noframes id="bwd7y"><menu id="bwd7y"><td id="bwd7y"></td></menu>