原理
通过选择的顶点生成面片,根据面片挤压出盒子。
原理并不复杂,之前做的面片自动匹配插件也有很多相同的地方
但是鉴于连续顶点选择的时候,会有序号相连的情况,为此我特意开发了一个函数来处理这个问题。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| global proc FXTD_seperatePtNum(string $sel[]){ string $str = ""; string $PtStr[] = {}; for($j = 0; $j < size($sel); $j++ ){
$str = `match ":" $sel[$j]`;
if($str == ""){ $PtStr[size($PtStr)] = $sel[$j]; }else{
string $buffer2[]; string $buffer3[]; string $buffer4[]; tokenize `match "[0-9]+]" $sel[$j]` "]" $buffer2; tokenize `match "vtx[[0-9]+:" $sel[$j]` "[" $buffer3;
tokenize $sel[$j] ".vtx" $buffer4; int $temp_1 = $buffer3[1]; int $temp_2 = $buffer2[0];
for($i = 0; $i + $temp_1 <= $temp_2; $i++ ){
$PtStr[size($PtStr)] = ($buffer4[0] + ".vtx[" + ($i + $temp_1) + "]"); }
}
$str = "";
}
$sel = $PtStr; }
$sel = `ls -sl`;
FXTD_seperatePtNum($sel);
float $vtx_position[] = {};
for($j = 0; $j < size($sel); $j++ ) { FXTD_floatPush($vtx_position,`xform -q -ws -t $sel[$j]`); }
string $temp_tri[] = `polyCreateFacet -ch off -tx 1 -s 1 -p $vtx_position[0] $vtx_position[1] $vtx_position[2] -p $vtx_position[3] $vtx_position[4] $vtx_position[5] -p $vtx_position[6] $vtx_position[7] $vtx_position[8]`;
|
2019-10-26 补充
其实ls -fl
可以通过 flattern 参数将这种数组展平(:з」∠)
序号错乱问题
目前这种方案可以解决选点问题,直接生成模型。
然而序号是从小到大排序而非选择的顺序。
这会导致面片错乱的情况。
为了解决这个问题,就需要记录选点的顺序操作。
然而网上找不到相关的资料(MEL真的是太小众了)
于是只好自己去想办法
而我所想到唯一靠谱的方案就是使用scriptjob动态记录选择。
因为理论上每一个选择都需要存储到数组中,从而实现顺序记录。
然而这种方案写起来很痛苦的
终于,最后费了我九牛二虎之力才在CGsociety中找到了2005年的解决方案。
当然原先的解决方案可能年代久远吧,有点问题,我进行了一些修改。
原答案是针对选择边提出的解决方案,其实迁移到其他地方并不困难。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
| global string $selectOrder_edges[]; global string $selectOrder_updateSet; global int $selectOrder_jobNum;
global proc string[] selectOrder () { global string $selectOrder_edges[]; global string $selectOrder_updateSet; global int $selectOrder_jobNum; if ( !`scriptJob -exists $selectOrder_jobNum` || $selectOrder_jobNum == 0 ) { headsUpMessage "开始监听-选择内容";
$selectOrder_edges = {}; string $selEdges[] = `ls -sl`; $selectOrder_updateSet = `sets -n selectOrderSet $selEdges`;
$selectOrder_jobNum = `scriptJob -event SelectionChanged "selectOrder.update"`;
} else {
headsUpMessage "停止监听-选择内容";
delete $selectOrder_updateSet;
scriptJob -kill $selectOrder_jobNum -force; } return $selectOrder_edges; }
global proc selectOrder.update () { global string $selectOrder_edges[]; global string $selectOrder_updateSet; string $selEdges[] = `ls -sl`;
string $tempSet = `sets -n selectOrderSetTemp $selEdges`;
string $diff[] = `sets -sub $tempSet $selectOrder_updateSet`;
$diff = `ls -fl $diff`;
$selectOrder_edges = stringArrayCatenate($selectOrder_edges,$diff);
delete $tempSet; delete $selectOrder_updateSet;
$selectOrder_updateSet = `sets -n selectOrderSet $selEdges`; }
|
这里使用了-fl标签,通过内置flag,完美解决了我上面头疼的序号问题。(:з」∠)
这个方法我测试了一下,确实可以记录操作顺序,但是也有其他的问题。
开启了scriptJob之后撤销就会很麻烦。
每一次都要按一下来开启scriptjob
想到ls 还有-fl 这样的操作,我就想官方会不会已经提供了什么解决方案。
于是我又在官方文档中寻找。
还真的找到了更为简洁的解决方案。
1 2 3 4 5 6
| selectPref -trackSelectionOrder 1;
$sel = `ls -fl -os`;
|
如此开发中所有的坑都已经解决了,剩下的只是界面和挤压面片的操作而已。
总结
MEL真的不好弄,不像JavaScript,资料一大堆。
CG行业现在普遍都用python进行开发了,MEL小众语言被挤得没有生存空间。
但是开发Maya插件始终是离不开MEL的,即便使用pymel,代码的源头还是来自于MEL。