前回頂点群と頂点群の配列順を合わせるって言うMELを作ったが
頂点群同士の座標が似ているもので頂点群Aに頂点群Bが配列順を合わせるというもの
だいぶ誤作動しているので研究中
座標じゃなくてベクトルの比較するほうがいいのかもしれない。
2014年11月30日日曜日
2014年11月29日土曜日
選択したノードの移動値を量子化する
作っているようで作っていなかった移動回転スケールの値を量子化するMEL
/*
SYNOPSIS
選択したノードのsrt値を量子化する
I quantize the value of the selected node
INPUTS
Nothing
RETURNS
Nothing
Quantizing
*/
global proc float yjp_DPoint(float $val,float $k)
{
$val *= 1 / $k;
$val = floor($val + 0.5);
$val *= $k;
return $val;
}
global proc doSRT_Quantize()
{
string $sel[] = `ls -sl`;
if(`size$sel` < 1)
{
warning("no ");
return ;
}
int $n;
float $new[];
for ($n=0;$n<size($sel);$n++)
{
float $T = `floatField -q -v SRT_QThresholdField`;
if(`checkBox -q -v SRT_QtranslateBox`)
{
$new[0] = yjp_DPoint(`getAttr($sel[$n] +".tx")` , $T);
$new[1] = yjp_DPoint(`getAttr($sel[$n] +".ty")` , $T);
$new[2] = yjp_DPoint(`getAttr($sel[$n] +".tz")` , $T);
setAttr($sel[$n]+".t") $new[0] $new[1] $new[2];
}
if(`checkBox -q -v SRT_QrotateBox`)
{
$new[0] = yjp_DPoint(`getAttr($sel[$n] +".rx")` , $T);
$new[1] = yjp_DPoint(`getAttr($sel[$n] +".ry")` , $T);
$new[2] = yjp_DPoint(`getAttr($sel[$n] +".rz")` , $T);
setAttr($sel[$n]+".r") $new[0] $new[1] $new[2];
}
if(`checkBox -q -v SRT_QscaleBox`)
{
$new[0] = yjp_DPoint(`getAttr($sel[$n] +".sx")` , $T);
$new[1] = yjp_DPoint(`getAttr($sel[$n] +".sy")` , $T);
$new[2] = yjp_DPoint(`getAttr($sel[$n] +".sz")` , $T);
setAttr($sel[$n]+".s") $new[0] $new[1] $new[2];
}
}
return ;
}
global proc yjp_SRT_Quantize()
{
if(`window -q -ex yjp_SRT_QuantizeWindow`)
{
deleteUI yjp_SRT_QuantizeWindow;
}
window -wh 100 100 -s 1 -t "yjp_SRT_Quantize 1.0" yjp_SRT_QuantizeWindow;
columnLayout -adjustableColumn true;
floatField -w 95 -h 22 -v 0.001 SRT_QThresholdField;
checkBox -l "translate"-v 1 SRT_QtranslateBox;
checkBox -l "rotate"-v 1 SRT_QrotateBox;
checkBox -l "scale"-v 0 SRT_QscaleBox;
button -h 25 -w 100 -l "Quantize" -c "doSRT_Quantize";
setParent ..;
window -e -wh 100 100 yjp_SRT_QuantizeWindow;
showWindow yjp_SRT_QuantizeWindow;
}
/*
SYNOPSIS
選択したノードのsrt値を量子化する
I quantize the value of the selected node
INPUTS
Nothing
RETURNS
Nothing
Quantizing
*/
global proc float yjp_DPoint(float $val,float $k)
{
$val *= 1 / $k;
$val = floor($val + 0.5);
$val *= $k;
return $val;
}
global proc doSRT_Quantize()
{
string $sel[] = `ls -sl`;
if(`size$sel` < 1)
{
warning("no ");
return ;
}
int $n;
float $new[];
for ($n=0;$n<size($sel);$n++)
{
float $T = `floatField -q -v SRT_QThresholdField`;
if(`checkBox -q -v SRT_QtranslateBox`)
{
$new[0] = yjp_DPoint(`getAttr($sel[$n] +".tx")` , $T);
$new[1] = yjp_DPoint(`getAttr($sel[$n] +".ty")` , $T);
$new[2] = yjp_DPoint(`getAttr($sel[$n] +".tz")` , $T);
setAttr($sel[$n]+".t") $new[0] $new[1] $new[2];
}
if(`checkBox -q -v SRT_QrotateBox`)
{
$new[0] = yjp_DPoint(`getAttr($sel[$n] +".rx")` , $T);
$new[1] = yjp_DPoint(`getAttr($sel[$n] +".ry")` , $T);
$new[2] = yjp_DPoint(`getAttr($sel[$n] +".rz")` , $T);
setAttr($sel[$n]+".r") $new[0] $new[1] $new[2];
}
if(`checkBox -q -v SRT_QscaleBox`)
{
$new[0] = yjp_DPoint(`getAttr($sel[$n] +".sx")` , $T);
$new[1] = yjp_DPoint(`getAttr($sel[$n] +".sy")` , $T);
$new[2] = yjp_DPoint(`getAttr($sel[$n] +".sz")` , $T);
setAttr($sel[$n]+".s") $new[0] $new[1] $new[2];
}
}
return ;
}
global proc yjp_SRT_Quantize()
{
if(`window -q -ex yjp_SRT_QuantizeWindow`)
{
deleteUI yjp_SRT_QuantizeWindow;
}
window -wh 100 100 -s 1 -t "yjp_SRT_Quantize 1.0" yjp_SRT_QuantizeWindow;
columnLayout -adjustableColumn true;
floatField -w 95 -h 22 -v 0.001 SRT_QThresholdField;
checkBox -l "translate"-v 1 SRT_QtranslateBox;
checkBox -l "rotate"-v 1 SRT_QrotateBox;
checkBox -l "scale"-v 0 SRT_QscaleBox;
button -h 25 -w 100 -l "Quantize" -c "doSRT_Quantize";
setParent ..;
window -e -wh 100 100 yjp_SRT_QuantizeWindow;
showWindow yjp_SRT_QuantizeWindow;
}
2014年11月26日水曜日
頂点群と頂点群の配列を合わせる
頂点から頂点に渡す情報が正しくないといけないと思ったので考えて見ました。
はじめは座標を比べていたので他のMELを参考にベクトルで距離を取得することにした。
距離取得が球になったし、なにより凄く早くなったのがいい。
次は頂点の繋っている4頂点の座標を比べてみた。
これで間違って取得してきた頂点もある程度除外されるようになった。
全頂点を検索するので多少遅くなるけど、
最短距離の頂点から関連頂点の処理をすることで
しきい値指定が必要なくなった。
まだミスがあるので、もう一段階、関連する頂点を比較するといいのかもしれない。
//yjp_pMatchVtxArray(Aメッシュの頂点配列,Bメッシュ頂点配列)
//Aメッシュの頂点リストとBメッシュの頂点リストを比べて
//Aメッシュの頂点リストと同じ座標の頂点をBメッシュから探して
//Aメッシュの頂点配列と同じ順にする
global proc string[] yjp_pMatchVtxArray(string $sourcevtx[], string $targetvtx[])
{
int $n,$m,$c;
float $Credible;
int $amount = 0;
string $vtx[];
string $vtxlink_u[],$vtxlink_l[],$vtxlink_r[],$vtxlink_d[];
vector $xyzA,$xyzB;
vector $posAlink[4],$posBlink[4];
float $posA[],$posB[];
float $posAlink_u[3],$posAlink_l[3],$posAlink_r[3],$posAlink_d[3];
float $posBlink_u[3],$posBlink_l[3],$posBlink_r[3],$posBlink_d[3];
float $dis[2];
float $Length[];
float $Lengthsort[];
float $startTime = `timerX`;
progressWindow
-t "Compare vertex ..."
-pr $amount
-st "Search: ..."
-ii 0;
for ($n=0;$n<size($targetvtx);$n++)
{
$posA = `pointPosition $targetvtx[$n]`;
$xyzA = <<$posA[0],$posA[1],$posA[2]>>;
//隣接する頂点
$vtxlink_u = `pickWalk -d up $targetvtx[$n]`;
$vtxlink_l = `pickWalk -d left $targetvtx[$n]`;
$vtxlink_r = `pickWalk -d right $targetvtx[$n]`;
$vtxlink_d = `pickWalk -d down $targetvtx[$n]`;
$posA = `pointPosition $targetvtx[$n]`;
$xyzA = <<$posA[0],$posA[1],$posA[2]>>;
$posAlink_u = `pointPosition $vtxlink_u[0]`;
$posAlink_l = `pointPosition $vtxlink_l[0]`;
$posAlink_r = `pointPosition $vtxlink_r[0]`;
$posAlink_d = `pointPosition $vtxlink_d[0]`;
//隣接する頂点の座標配列
$posAlink[0] = << $posAlink_u[0],$posAlink_u[1],$posAlink_u[2]>>;
$posAlink[1] = << $posAlink_l[0],$posAlink_l[1],$posAlink_l[2]>>;
$posAlink[2] = << $posAlink_r[0],$posAlink_r[1],$posAlink_r[2]>>;
$posAlink[3] = << $posAlink_d[0],$posAlink_d[1],$posAlink_d[2]>>;
//print ("targetvtx " + $targetvtx[$n] +"\n");
int $che = 0;
for ($m=0;$m<size($sourcevtx);$m++)
{
$posB = `pointPosition $sourcevtx[$m]`;
$xyzB = <<$posB[0],$posB[1],$posB[2]>>;
$dis[0] = abs(mag($xyzA-$xyzB));
$Length[$m] = $dis[0];
//print ($sourcevtx[$m] + " dis "+$dis[0] +"\n");
}
//$sourcevtxの最小距離でソート
$Lengthsort = `sort $Length`;
int $s ;
float $maxlink[];
string $Finalvtx[];
for ($m=0;$m<size($Lengthsort)/4;$m++)
{
$s = `floatArrayFind $Lengthsort[$m] 0 $Length`;
//print ("Length_s" + $Length[$s] + "\n") ;
//print ("Length_s" + $sourcevtx[$s] + "\n") ;
if ($sourcevtx[$s] == ""){break;}
$vtxlink_u = `pickWalk -d up $sourcevtx[$s]`;
$vtxlink_l = `pickWalk -d left $sourcevtx[$s]`;
$vtxlink_r = `pickWalk -d right $sourcevtx[$s]`;
$vtxlink_d = `pickWalk -d down $sourcevtx[$s]`;
//隣接する頂点
$posBlink_u = `pointPosition $vtxlink_u[0]`;
$posBlink_l = `pointPosition $vtxlink_l[0]`;
$posBlink_r = `pointPosition $vtxlink_r[0]`;
$posBlink_d = `pointPosition $vtxlink_d[0]`;
//隣接する頂点の座標配列
$posBlink[0] = << $posBlink_u[0],$posBlink_u[1],$posBlink_u[2]>>;
$posBlink[1] = << $posBlink_l[0],$posBlink_l[1],$posBlink_l[2]>>;
$posBlink[2] = << $posBlink_r[0],$posBlink_r[1],$posBlink_r[2]>>;
$posBlink[3] = << $posBlink_d[0],$posBlink_d[1],$posBlink_d[2]>>;
//頂点の隣接する頂点座標の近似チェック
$Credible = 0;
for ($c=0;$c<size($posBlink);$c++)
{
$dis[0] = abs(mag($posAlink[$c]-$posBlink[$c]));
$Credible += $dis[0];
}
$maxlink[$m] = $Credible / size($posBlink);
print ($sourcevtx[$s] + " " + $maxlink[$m] +"\n");
$Finalvtx[$m] = $sourcevtx[$s];
}
float $Finallink[] = `sort $maxlink`;
$s = `floatArrayFind $Finallink[0] 0 $maxlink`;
$vtx[size($vtx)] = $Finalvtx[$s];
//print ("sourcevtx " + $Finalvtx[$s] +"\n");
stringArrayRemoveAtIndex($s, $Finalvtx);
$amount += 1;
progressWindow -edit -max (size($targetvtx)) -pr $amount -st ("Compare vertex: " + $targetvtx[$n]);
}
progressWindow -ep;
float $totalTime = `timerX -startTime $startTime`;
print("Execution time: " + $totalTime + " seconds.\n");
return ($vtx);
}
はじめは座標を比べていたので他のMELを参考にベクトルで距離を取得することにした。
距離取得が球になったし、なにより凄く早くなったのがいい。
次は頂点の繋っている4頂点の座標を比べてみた。
これで間違って取得してきた頂点もある程度除外されるようになった。
全頂点を検索するので多少遅くなるけど、
最短距離の頂点から関連頂点の処理をすることで
しきい値指定が必要なくなった。
まだミスがあるので、もう一段階、関連する頂点を比較するといいのかもしれない。
//yjp_pMatchVtxArray(Aメッシュの頂点配列,Bメッシュ頂点配列)
//Aメッシュの頂点リストとBメッシュの頂点リストを比べて
//Aメッシュの頂点リストと同じ座標の頂点をBメッシュから探して
//Aメッシュの頂点配列と同じ順にする
global proc string[] yjp_pMatchVtxArray(string $sourcevtx[], string $targetvtx[])
{
int $n,$m,$c;
float $Credible;
int $amount = 0;
string $vtx[];
string $vtxlink_u[],$vtxlink_l[],$vtxlink_r[],$vtxlink_d[];
vector $xyzA,$xyzB;
vector $posAlink[4],$posBlink[4];
float $posA[],$posB[];
float $posAlink_u[3],$posAlink_l[3],$posAlink_r[3],$posAlink_d[3];
float $posBlink_u[3],$posBlink_l[3],$posBlink_r[3],$posBlink_d[3];
float $dis[2];
float $Length[];
float $Lengthsort[];
float $startTime = `timerX`;
progressWindow
-t "Compare vertex ..."
-pr $amount
-st "Search: ..."
-ii 0;
for ($n=0;$n<size($targetvtx);$n++)
{
$posA = `pointPosition $targetvtx[$n]`;
$xyzA = <<$posA[0],$posA[1],$posA[2]>>;
//隣接する頂点
$vtxlink_u = `pickWalk -d up $targetvtx[$n]`;
$vtxlink_l = `pickWalk -d left $targetvtx[$n]`;
$vtxlink_r = `pickWalk -d right $targetvtx[$n]`;
$vtxlink_d = `pickWalk -d down $targetvtx[$n]`;
$posA = `pointPosition $targetvtx[$n]`;
$xyzA = <<$posA[0],$posA[1],$posA[2]>>;
$posAlink_u = `pointPosition $vtxlink_u[0]`;
$posAlink_l = `pointPosition $vtxlink_l[0]`;
$posAlink_r = `pointPosition $vtxlink_r[0]`;
$posAlink_d = `pointPosition $vtxlink_d[0]`;
//隣接する頂点の座標配列
$posAlink[0] = << $posAlink_u[0],$posAlink_u[1],$posAlink_u[2]>>;
$posAlink[1] = << $posAlink_l[0],$posAlink_l[1],$posAlink_l[2]>>;
$posAlink[2] = << $posAlink_r[0],$posAlink_r[1],$posAlink_r[2]>>;
$posAlink[3] = << $posAlink_d[0],$posAlink_d[1],$posAlink_d[2]>>;
//print ("targetvtx " + $targetvtx[$n] +"\n");
int $che = 0;
for ($m=0;$m<size($sourcevtx);$m++)
{
$posB = `pointPosition $sourcevtx[$m]`;
$xyzB = <<$posB[0],$posB[1],$posB[2]>>;
$dis[0] = abs(mag($xyzA-$xyzB));
$Length[$m] = $dis[0];
//print ($sourcevtx[$m] + " dis "+$dis[0] +"\n");
}
//$sourcevtxの最小距離でソート
$Lengthsort = `sort $Length`;
int $s ;
float $maxlink[];
string $Finalvtx[];
for ($m=0;$m<size($Lengthsort)/4;$m++)
{
$s = `floatArrayFind $Lengthsort[$m] 0 $Length`;
//print ("Length_s" + $Length[$s] + "\n") ;
//print ("Length_s" + $sourcevtx[$s] + "\n") ;
if ($sourcevtx[$s] == ""){break;}
$vtxlink_u = `pickWalk -d up $sourcevtx[$s]`;
$vtxlink_l = `pickWalk -d left $sourcevtx[$s]`;
$vtxlink_r = `pickWalk -d right $sourcevtx[$s]`;
$vtxlink_d = `pickWalk -d down $sourcevtx[$s]`;
//隣接する頂点
$posBlink_u = `pointPosition $vtxlink_u[0]`;
$posBlink_l = `pointPosition $vtxlink_l[0]`;
$posBlink_r = `pointPosition $vtxlink_r[0]`;
$posBlink_d = `pointPosition $vtxlink_d[0]`;
//隣接する頂点の座標配列
$posBlink[0] = << $posBlink_u[0],$posBlink_u[1],$posBlink_u[2]>>;
$posBlink[1] = << $posBlink_l[0],$posBlink_l[1],$posBlink_l[2]>>;
$posBlink[2] = << $posBlink_r[0],$posBlink_r[1],$posBlink_r[2]>>;
$posBlink[3] = << $posBlink_d[0],$posBlink_d[1],$posBlink_d[2]>>;
//頂点の隣接する頂点座標の近似チェック
$Credible = 0;
for ($c=0;$c<size($posBlink);$c++)
{
$dis[0] = abs(mag($posAlink[$c]-$posBlink[$c]));
$Credible += $dis[0];
}
$maxlink[$m] = $Credible / size($posBlink);
print ($sourcevtx[$s] + " " + $maxlink[$m] +"\n");
$Finalvtx[$m] = $sourcevtx[$s];
}
float $Finallink[] = `sort $maxlink`;
$s = `floatArrayFind $Finallink[0] 0 $maxlink`;
$vtx[size($vtx)] = $Finalvtx[$s];
//print ("sourcevtx " + $Finalvtx[$s] +"\n");
stringArrayRemoveAtIndex($s, $Finalvtx);
$amount += 1;
progressWindow -edit -max (size($targetvtx)) -pr $amount -st ("Compare vertex: " + $targetvtx[$n]);
}
progressWindow -ep;
float $totalTime = `timerX -startTime $startTime`;
print("Execution time: " + $totalTime + " seconds.\n");
return ($vtx);
}
2014年11月21日金曜日
ウエイトミラー考え中
グローバル座標で頂点の位置がX反転した状態と近いものを検索して
ウエイトをコピーしていたが完璧にコピーできない。
空間チェックだけでは少しずれるとダメ。
補助ジョイントなどが重なっていてもダメ。
メッシュがUの形状や密集しているところは間違ったコピーをしてしまう。
ミラーだけではなく、バックアップしたメッシュからウエイトをコピーするとかしたい。
今後はDoraに頼らなくてもいい様にしたい。
ジョイントも頂点も繋がりも見たほうがいいかも知れない。
頂点数の違いがあってもコピーできるようにしたいなー。
ウエイトをコピーしていたが完璧にコピーできない。
空間チェックだけでは少しずれるとダメ。
補助ジョイントなどが重なっていてもダメ。
メッシュがUの形状や密集しているところは間違ったコピーをしてしまう。
ミラーだけではなく、バックアップしたメッシュからウエイトをコピーするとかしたい。
今後はDoraに頼らなくてもいい様にしたい。
ジョイントも頂点も繋がりも見たほうがいいかも知れない。
頂点数の違いがあってもコピーできるようにしたいなー。
2014年11月19日水曜日
不要な中間オブジェクトがたくさん隠されている
intermediateObjectでアトリビュートを見ていたが、エラーを出すメッシュが現れた。
スクリプトエディターでリザルトを見てみると 1 1 1
intだけど配列?になってる。
しかもlistRelativesで表示するメッシュをselectしても存在しないとエラー。
ハイパーグラフで見るといるんだけどね。
中間オブジェクトを削除したかっただけなので検索したら以下のページを発見。
実行すると綺麗に消えました。
http://area.autodesk.jp/column/tutorial/maya_atoz/about_node/index-2.html
70個ぐらい削除されて驚き。
この不要メッシュのせいでバインド関係でエラーが出る事があるみたいです。
スクリプトエディターでリザルトを見てみると 1 1 1
intだけど配列?になってる。
しかもlistRelativesで表示するメッシュをselectしても存在しないとエラー。
ハイパーグラフで見るといるんだけどね。
中間オブジェクトを削除したかっただけなので検索したら以下のページを発見。
実行すると綺麗に消えました。
http://area.autodesk.jp/column/tutorial/maya_atoz/about_node/index-2.html
70個ぐらい削除されて驚き。
この不要メッシュのせいでバインド関係でエラーが出る事があるみたいです。
2014年11月18日火曜日
バインドされたメッシュをセパレートする
と言う事で作っていたらデタッチセパレートがいらなくなってしまった。
分割したメッシュの両方にウエイトがコピーされますよ
マージするMELも作ったので後日
/*
ちぎりたいフェースを選択して実行
スキンクラスタがあればウエイトも維持
使用しているプロシージャ
yjp_DuplicateMeshSkin
yjp_doImitateBind
yjp_meshUnlook
*/
global proc yjp_SeparateMeshWeight()
{
string $origFaceSel[] = `filterExpand -ex 1 -sm 34`;
print ($origFaceSel[0] + "\n") ;
if(!`gmatch $origFaceSel[0] "*.f*"`)
{
print ("フェースを選択してください" + "\n") ;
return;
}
string $temp[];
string $FaceNum[] ;
string $Amesh;
int $n;
for ($n=0 ; $n < size($origFaceSel) ; $n++)
{
tokenize $origFaceSel[$n] "." $temp;
$FaceNum[$n] = $temp[1];
//print ($FaceNum[$n] + "\n") ;
}
string $origObjShape[] = `listRelatives -p $origFaceSel`;
string $origObj[] = `listRelatives -p $origObjShape`;
string $parents[] = `listRelatives -p $origObj[0]`;
////////スキンクラスター取得
string $scf = `findRelatedSkinCluster $origObj[0]`;
if( size($scf))
{
////////バインドされているジョイントを取得
string $jointlistnameA[] = `listConnections -type "joint" ($scf +".matrix")`;
//最大インフルエンス取得
int $maxInf = `getAttr ($scf + ".maxInfluences")`;
//ソースメッシュウエイトを保存
select -r $origObj[0];
//ウエイト保存のため複製
$Amesh = `yjp_DuplicateMeshSkin`;
}
//Aメッシュ複製
string $newmeshA[] = `duplicate -n ($origObj[0] + "_A") -rr $origObj[0]`;
//Bメッシュ複製
string $newmeshB[] = `duplicate -n ($origObj[0] + "_B") -rr $origObj[0]`;
//Aメッシュ選択フェース以外削除
string $FaceA[];
for ($n=0 ; $n < size($FaceNum) ; $n++)
{
$FaceA[$n] = $newmeshA[0] + "." + $FaceNum[$n];
}
select -r $FaceA;
InvertSelection;
delete;
//Bメッシュ選択フェース削除
string $FaceB[];
for ($n=0 ; $n < size($FaceNum) ; $n++)
{
$FaceB[$n] = $newmeshB[0] + "." + $FaceNum[$n];
}
select -r $FaceB;
delete;
if( size($scf))
{
//ソースメッシュと同じバインドを複製メッシュに摘要
yjp_doImitateBind $origObj[0] $newmeshA[0];
select -r $newmeshA[0];
//ウエイトコピー
$scs = `findRelatedSkinCluster $Amesh`;
$sct = `findRelatedSkinCluster $newmeshA[0]`;
copySkinWeights -ss $scs -ds $sct -noMirror;
select -r $newmeshA[0];
//不要なインフルエンスの除去
removeUnusedInfluences;
//ソースメッシュと同じバインドを複製メッシュに摘要
yjp_doImitateBind $origObj[0] $newmeshB[0];
select -r $newmeshB[0];
//ウエイトコピー
$scs = `findRelatedSkinCluster $Amesh`;
$sct = `findRelatedSkinCluster $newmeshB[0]`;
copySkinWeights -ss $scs -ds $sct -noMirror;
print ("ウエイトコピー" +"\n");
select -r $newmeshB[0];
//不要なインフルエンスの除去
removeUnusedInfluences;
delete $Amesh;
}
delete $origObj[0];
rename $newmeshB[0] $origObj[0];
select -r $newmeshA[0];
}
分割したメッシュの両方にウエイトがコピーされますよ
マージするMELも作ったので後日
/*
ちぎりたいフェースを選択して実行
スキンクラスタがあればウエイトも維持
使用しているプロシージャ
yjp_DuplicateMeshSkin
yjp_doImitateBind
yjp_meshUnlook
*/
global proc yjp_SeparateMeshWeight()
{
string $origFaceSel[] = `filterExpand -ex 1 -sm 34`;
print ($origFaceSel[0] + "\n") ;
if(!`gmatch $origFaceSel[0] "*.f*"`)
{
print ("フェースを選択してください" + "\n") ;
return;
}
string $temp[];
string $FaceNum[] ;
string $Amesh;
int $n;
for ($n=0 ; $n < size($origFaceSel) ; $n++)
{
tokenize $origFaceSel[$n] "." $temp;
$FaceNum[$n] = $temp[1];
//print ($FaceNum[$n] + "\n") ;
}
string $origObjShape[] = `listRelatives -p $origFaceSel`;
string $origObj[] = `listRelatives -p $origObjShape`;
string $parents[] = `listRelatives -p $origObj[0]`;
////////スキンクラスター取得
string $scf = `findRelatedSkinCluster $origObj[0]`;
if( size($scf))
{
////////バインドされているジョイントを取得
string $jointlistnameA[] = `listConnections -type "joint" ($scf +".matrix")`;
//最大インフルエンス取得
int $maxInf = `getAttr ($scf + ".maxInfluences")`;
//ソースメッシュウエイトを保存
select -r $origObj[0];
//ウエイト保存のため複製
$Amesh = `yjp_DuplicateMeshSkin`;
}
//Aメッシュ複製
string $newmeshA[] = `duplicate -n ($origObj[0] + "_A") -rr $origObj[0]`;
//Bメッシュ複製
string $newmeshB[] = `duplicate -n ($origObj[0] + "_B") -rr $origObj[0]`;
//Aメッシュ選択フェース以外削除
string $FaceA[];
for ($n=0 ; $n < size($FaceNum) ; $n++)
{
$FaceA[$n] = $newmeshA[0] + "." + $FaceNum[$n];
}
select -r $FaceA;
InvertSelection;
delete;
//Bメッシュ選択フェース削除
string $FaceB[];
for ($n=0 ; $n < size($FaceNum) ; $n++)
{
$FaceB[$n] = $newmeshB[0] + "." + $FaceNum[$n];
}
select -r $FaceB;
delete;
if( size($scf))
{
//ソースメッシュと同じバインドを複製メッシュに摘要
yjp_doImitateBind $origObj[0] $newmeshA[0];
select -r $newmeshA[0];
//ウエイトコピー
$scs = `findRelatedSkinCluster $Amesh`;
$sct = `findRelatedSkinCluster $newmeshA[0]`;
copySkinWeights -ss $scs -ds $sct -noMirror;
select -r $newmeshA[0];
//不要なインフルエンスの除去
removeUnusedInfluences;
//ソースメッシュと同じバインドを複製メッシュに摘要
yjp_doImitateBind $origObj[0] $newmeshB[0];
select -r $newmeshB[0];
//ウエイトコピー
$scs = `findRelatedSkinCluster $Amesh`;
$sct = `findRelatedSkinCluster $newmeshB[0]`;
copySkinWeights -ss $scs -ds $sct -noMirror;
print ("ウエイトコピー" +"\n");
select -r $newmeshB[0];
//不要なインフルエンスの除去
removeUnusedInfluences;
delete $Amesh;
}
delete $origObj[0];
rename $newmeshB[0] $origObj[0];
select -r $newmeshA[0];
}
2014年11月17日月曜日
バインドメッシュを複製するやつ
前に作ったImitateBindを他の処理で使いやすくしました
global proc yjp_doImitateBind(string $sourceobj , string $targetobj )
{
string $scs = `findRelatedSkinCluster $sourceobj`;
string $sct = `findRelatedSkinCluster $targetobj`;
if( size($scs) == 0 )return;
if( size($sct))return;
string $jointlistname[] = `listConnections -type "joint" ($scs +".matrix")`;
int $maxInf = `getAttr ($scs + ".maxInfluences")`;
select $targetobj;
//アトリビュートをアンロック
yjp_meshUnlook $targetobj;
//フリーズ
FreezeTransformations ;
string $scnext[] = `skinCluster -mi $maxInf -omi true -dr 4 -rui 0 -tsb $jointlistname $targetobj`;
//copySkinWeights -ss $scs -ds $scnext[0] -ia "closestJoint" -ia "oneToOne";
select $sourceobj $targetobj;
copySkinWeights -noMirror -surfaceAssociation closestPoint -influenceAssociation closestJoint -influenceAssociation oneToOne;
select $targetobj;
return ;
}
以下はyjp_doImitateBindを使ってバインドを保持したままメッシュを複製します
思いのほか簡単。
global proc string yjp_DuplicateMeshSkin()
{
string $objs[] = `ls -sl`;
if( size($objs) == 0)return(0);
//メッシュ複製
string $newmeshA[] = `duplicate -n ($objs[0] + "_dup") -rr $objs[0]`;
yjp_doImitateBind $objs[0] $newmeshA[0];
return ($newmeshA[0]);
}
バインドメッシュ同士のコンバインとセパレートもyjp_doImitateBindをつかってます
一応アトリビュートのアンロックプロシージャ
global proc yjp_meshUnlook(string $selectName)
{
setAttr -lock 0 ($selectName + ".tx");
setAttr -lock 0 ($selectName + ".ty");
setAttr -lock 0 ($selectName + ".tz");
setAttr -lock 0 ($selectName + ".rx");
setAttr -lock 0 ($selectName + ".ry");
setAttr -lock 0 ($selectName + ".rz");
setAttr -lock 0 ($selectName + ".sx");
setAttr -lock 0 ($selectName + ".sy");
setAttr -lock 0 ($selectName + ".sz");
}
global proc yjp_doImitateBind(string $sourceobj , string $targetobj )
{
string $scs = `findRelatedSkinCluster $sourceobj`;
string $sct = `findRelatedSkinCluster $targetobj`;
if( size($scs) == 0 )return;
if( size($sct))return;
string $jointlistname[] = `listConnections -type "joint" ($scs +".matrix")`;
int $maxInf = `getAttr ($scs + ".maxInfluences")`;
select $targetobj;
//アトリビュートをアンロック
yjp_meshUnlook $targetobj;
//フリーズ
FreezeTransformations ;
string $scnext[] = `skinCluster -mi $maxInf -omi true -dr 4 -rui 0 -tsb $jointlistname $targetobj`;
//copySkinWeights -ss $scs -ds $scnext[0] -ia "closestJoint" -ia "oneToOne";
select $sourceobj $targetobj;
copySkinWeights -noMirror -surfaceAssociation closestPoint -influenceAssociation closestJoint -influenceAssociation oneToOne;
select $targetobj;
return ;
}
以下はyjp_doImitateBindを使ってバインドを保持したままメッシュを複製します
思いのほか簡単。
global proc string yjp_DuplicateMeshSkin()
{
string $objs[] = `ls -sl`;
if( size($objs) == 0)return(0);
//メッシュ複製
string $newmeshA[] = `duplicate -n ($objs[0] + "_dup") -rr $objs[0]`;
yjp_doImitateBind $objs[0] $newmeshA[0];
return ($newmeshA[0]);
}
バインドメッシュ同士のコンバインとセパレートもyjp_doImitateBindをつかってます
一応アトリビュートのアンロックプロシージャ
global proc yjp_meshUnlook(string $selectName)
{
setAttr -lock 0 ($selectName + ".tx");
setAttr -lock 0 ($selectName + ".ty");
setAttr -lock 0 ($selectName + ".tz");
setAttr -lock 0 ($selectName + ".rx");
setAttr -lock 0 ($selectName + ".ry");
setAttr -lock 0 ($selectName + ".rz");
setAttr -lock 0 ($selectName + ".sx");
setAttr -lock 0 ($selectName + ".sy");
setAttr -lock 0 ($selectName + ".sz");
}
2014年11月15日土曜日
先生達のお勧めMEL
ミラーMELを更新したときに書いたdetachseparate
以下のサイトでDLできます。DLするには登録しないとあきません。
http://www.creativecrash.com/maya/script/detachseparate-mel
あとこちらにあるDoraSkinWeightImpExp.melです
http://dorayuki.com/
これが無いと何もできません。
さすがに作る気になれないくらいの大作。
ありがとうございます。
次回はDoraSkinWeightImpExp.melを利用した。コンバインとセパレートを上げましょうか。
安定しているのでこのまま残しておきますが、DoraSkinWeightImpExp.melを使用しなくてもできるように改造しておきたいところです。
以下のサイトでDLできます。DLするには登録しないとあきません。
http://www.creativecrash.com/maya/script/detachseparate-mel
あとこちらにあるDoraSkinWeightImpExp.melです
http://dorayuki.com/
これが無いと何もできません。
さすがに作る気になれないくらいの大作。
ありがとうございます。
次回はDoraSkinWeightImpExp.melを利用した。コンバインとセパレートを上げましょうか。
安定しているのでこのまま残しておきますが、DoraSkinWeightImpExp.melを使用しなくてもできるように改造しておきたいところです。
2014年11月14日金曜日
オリジナルウエイトミラーはまだできない
ウエイトミラー作ってみたけど、なんだか遅いし標準機能と同じ様なコピーミスがある。
対称の頂点やジョイントが取得できていないからだと思う。
補助ジョイントなどがあるともっとエラーが発生する。
ジョイントの指定をしないとエラーは回避できそうに無い。
更に、一度設定したら記憶して欲しい。ジョイントのノートに書くか。
それでもコピーできない箇所があれば補完するとか。
あと処理速度が気になるので探索法を習得しないといけないかもしれない。
ジョイントもX値でソートしたほうが検索が早いだろうか。
あとはPYTHONで書けば多少早くなるだろうし覚えておきたい。
PYTHONリファレンスが届いたので明日からまずはMELで完成させてからPYTHONで移植してみようと思う。処理速度の確認もしてみたい。
対称の頂点やジョイントが取得できていないからだと思う。
補助ジョイントなどがあるともっとエラーが発生する。
ジョイントの指定をしないとエラーは回避できそうに無い。
更に、一度設定したら記憶して欲しい。ジョイントのノートに書くか。
それでもコピーできない箇所があれば補完するとか。
あと処理速度が気になるので探索法を習得しないといけないかもしれない。
ジョイントもX値でソートしたほうが検索が早いだろうか。
あとはPYTHONで書けば多少早くなるだろうし覚えておきたい。
PYTHONリファレンスが届いたので明日からまずはMELで完成させてからPYTHONで移植してみようと思う。処理速度の確認もしてみたい。
2014年11月11日火曜日
完璧なウエイトミラーを考え中
ウエイトミラーが全然使えないから良い感じのを作ってみようと思う。
バインドされたメッシュ同士のセパレートとコンバインが作れたので、次回アップします。
2015では標準でスキン有りコンバインがあるみたいですけど。
もうちょっとペイントのスムーズが使えたらいいのですけどねー。
ペイントウエイトの時にジョイントのホールドが自動になったら楽かなー。
バインドされたメッシュ同士のセパレートとコンバインが作れたので、次回アップします。
2015では標準でスキン有りコンバインがあるみたいですけど。
もうちょっとペイントのスムーズが使えたらいいのですけどねー。
ペイントウエイトの時にジョイントのホールドが自動になったら楽かなー。
2014年11月3日月曜日
今頃ミラーMEL
作ったの2007年です。
20141103久しぶりに更新かなりバグってました。
(さらに141104更新またバグってました。)
変数名がテキトウで、マージもしないし、レンダリングしたらフェース反転してる。
変更内容
VertexCenterボタンで選択した頂点で反転軸の位置を決める事ができます。
UVのセンターも一緒に取得します。
ボーダーエッジのみマージする機能追加
UVの反転機能も追加
UVもマージしてます。
マージした時に法線もソフトにしちゃいました。
SeparateMirrorが不安定で左右対称の移動回転をしたかった様子。
そんなに使わないので切りました。
Maya2015が届いているのに2013ばっかりいじっている。
こんな機能は実装されているだろうし
探せば同じ機能は沢山の方が作っているだろう。
まあ勉強です。
20141103久しぶりに更新かなりバグってました。
(さらに141104更新またバグってました。)
変数名がテキトウで、マージもしないし、レンダリングしたらフェース反転してる。
変更内容
VertexCenterボタンで選択した頂点で反転軸の位置を決める事ができます。
UVのセンターも一緒に取得します。
ボーダーエッジのみマージする機能追加
UVの反転機能も追加
UVもマージしてます。
マージした時に法線もソフトにしちゃいました。
SeparateMirrorが不安定で左右対称の移動回転をしたかった様子。
そんなに使わないので切りました。
そこでdetachSeparateという拾い物のMELを使わしてもらってます。
すいません。手を抜きました。Maya2015が届いているのに2013ばっかりいじっている。
こんな機能は実装されているだろうし
探せば同じ機能は沢山の方が作っているだろう。
まあ勉強です。
/* yjp_Mirror2.0
*
* NAME
*
*
* SYNOPSIS
* 指定する原点を境にミラーコピーさせる機能を2種類
* 1:オブジェクトの反転コピー
* 2:同メッシュの反転コピー
* 2007/12/16
* 2014/11/03
*
* INPUTS
* Nothing
*
* RETURNS
* Nothing
*
* detachSeparate
*/
global proc yjp_PartsMirror()
{
string $selobj[] = `ls -sl`;
print ($selobj[0] +"\n");
if(`size$selobj` == 0){return ;}
float $pivpos[];
string $rootnode[];
//親ノード取得
$rootnode = `listRelatives -p $selobj[0]`;
print ($rootnode[0] +"\n");
//トランスフォームのピボット情報取得
$pivpos = `xform -q -a -ws -piv $selobj[0]`;
yjp_PartsMirrorMesh;
detachSeparate;
string $dsobj[] = `ls -sl`;
//XYZの選択
if(`radioButtonGrp -q -sl yjpMirrorBox` == 1)
{
$pivpos[0] = $pivpos[0] * -1;
}
else if(`radioButtonGrp -q -sl yjpMirrorBox` == 2)
{
$pivpos[1] = $pivpos[1] * -1;
}
else if(`radioButtonGrp -q -sl yjpMirrorBox` == 3)
{
$pivpos[2] = $pivpos[2] * -1;
}
xform -ws -piv $pivpos[0] $pivpos[1] $pivpos[2] ;
DeleteHistory;
return ;
}
global proc yjp_PartsMirrorMesh()
{
string $selobj[] = `ls -sl`;
if(`size$selobj` == 0){return ;}
float $xyz[];
float $centerV[] = `floatFieldGrp -q -v yjp_MirrorwinCenterField`;
float $centerUV[] = `floatFieldGrp -q -v yjp_MirrorwinUVCenterField`;
int $Merge = `checkBoxGrp -q -value1 mergeCeck`;
int $mirrorUVu = `checkBoxGrp -q -value1 UVmirrorCeck`;
int $mirrorUVv = `checkBoxGrp -q -value2 UVmirrorCeck`;
if(`radioButtonGrp -q -sl yjpMirrorBox` == 1)
{
$xyz = {-1.0,1.0,1.0};
}
else if(`radioButtonGrp -q -sl yjpMirrorBox` == 2)
{
$xyz = {1.0,-1.0,1.0};
}
else if(`radioButtonGrp -q -sl yjpMirrorBox` == 3)
{
$xyz = {1.0,1.0,-1.0};
}
ConvertSelectionToFaces;
polyChipOff -ch 1 -kft 1 -dup 1 -off 0 -pvt $centerV[0] $centerV[1] $centerV[2] -s $xyz[0] $xyz[1] $xyz[2];
polyNormal -normalMode 0;
//select -r $selobj;
$selobj = `ls -sl`;
string $temp[];
tokenize $selobj[0] "." $temp;
if ($Merge == 1 )
{
select -r $temp[0];
polySelectConstraint -t 0x0001 -w 1 -bo 1 -m 3;
polyMergeVertex -d 0.01;
SoftPolyEdgeElements 1;
resetPolySelectConstraint;
}
select -r $selobj;
if (($mirrorUVu == 1) || ($mirrorUVv == 1))
{
PolySelectConvert 4;
$tempUV = `ls -sl`;
}
if ($mirrorUVu == 1 )
{
polyEditUV -pu $centerUV[0] -pv $centerUV[1] -su -1.0 -sv 1.0 ;
}
if ($mirrorUVv == 1 )
{
polyEditUV -pu $centerUV[0] -pv $centerUV[1] -su 1.0 -sv -1.0 ;
}
GrowPolygonSelectionRegion;
polyMergeUV -d 0.01;
select -r $temp[0];
DeleteHistory;
select -r $selobj;
return;
}
global proc yjp_MirrorCenter()
{
string $selobj[] = `ls -sl`;
if(`size$selobj` == 0){return ;}
float $vc[] = `xform -q -a -ws -t $selobj[0]`;
floatFieldGrp -e -value1 $vc[0] -value2 $vc[1] -value3 $vc[2] yjp_MirrorwinCenterField;
PolySelectConvert 4;
$selobj = `ls -sl`;
$vc = `polyEditUV -q $selobj[0]`;
floatFieldGrp -e -value1 $vc[0] -value2 $vc[1] yjp_MirrorwinUVCenterField;
}
global proc yjp_Mirror()
{
if(`window -q -ex yjp_Mirrorwin`)
{
deleteUI yjp_Mirrorwin ;
}
window -wh 210 200 -tb 1 -tlb 0 -t "yjpMirror2.0" yjp_Mirrorwin ;
columnLayout -w 130;
floatFieldGrp -numberOfFields 3
-label "center"
-pre 4
-cw4 40 50 50 50
-value1 0.000 -value2 0.000 -value3 0.000 yjp_MirrorwinCenterField;
floatFieldGrp -numberOfFields 2
-label "UVcenter"
-pre 4
-cw3 50 50 50
-value1 0.500 -value2 0.000 yjp_MirrorwinUVCenterField;
rowColumnLayout -nc 2 -cw 1 100 -cw 2 100 ;
button -w 100 -h 25 -l "VertexCenter" -c "yjp_MirrorCenter" ;
button -w 100 -h 25 -l "center 0"
-c "floatFieldGrp -e -value1 0 -value2 0 -value3 0 yjp_MirrorwinCenterField;floatFieldGrp -e -value1 0.5 -value2 0 yjp_MirrorwinUVCenterField" ;
setParent..;
radioButtonGrp -cw 1 40 -cw 2 40 -cw 3 40 -sl 1
-numberOfRadioButtons 3
-labelArray3 "X" "Y" "Z"
yjpMirrorBox;
checkBoxGrp -numberOfCheckBoxes 1 -cw2 60 50 -label "merge" -value1 true mergeCeck;
checkBoxGrp -numberOfCheckBoxes 2 -cw3 60 50 50
-label "UV mmirror"
-l1 U
-l2 V
-value1 0 -value2 0 UVmirrorCeck;
rowColumnLayout -nc 2 -cw 1 100 -cw 2 100;
button -w 100 -h 25 -l "FaceMirror" -c yjp_PartsMirrorMesh ;
button -w 100 -h 25 -l "SeparateMirror" -c yjp_PartsMirror ;
setParent..;
button -w 200 -h 25 -l "Close" -c ("deleteUI -window yjp_Mirrorwin") ;
setParent..;
showWindow yjp_Mirrorwin ;
window -e -wh 210 180 yjp_Mirrorwin ;
}
2014年11月2日日曜日
outUV.tgaをフォトショップで読み込むjsxを考えてみたが
UV画像を読み込む事が多いので
現在選択している画像にUVレイヤーを作り、半透明、差の絶対値にする。
本当はimagesフォルダのoutUVを読みにいきたいけどなぜかエラー
str.split("/")でエラーが出てる。意味が分からないのでテクスチャーをsourceimagesに入れる事に
現在選択している画像にUVレイヤーを作り、半透明、差の絶対値にする。
本当はimagesフォルダのoutUVを読みにいきたいけどなぜかエラー
str.split("/")でエラーが出てる。意味が分からないのでテクスチャーをsourceimagesに入れる事に
//アクティブになっている(最前面の)ドキュメントを指定する
var docObj = activeDocument;
//アクティブドキュメントのパス
var str = activeDocument.path;
//patharr = str.split("/");
//配列の個数
//n = patharr.length ;
//alert(n);
//Path = "";
//階層を1つ上に上がる
//for (var i = 1; i<(n-1); i++)
//{
// Path = patharr[i] +"/";
//}
//画像を読み込む
var fileObj = new File(str + "/outUV.tga");
open(fileObj);
fileObj = activeDocument;
//選択範囲
activeDocument.selection.selectAll();
//アクティブレイヤーコピー
activeDocument.activeLayer.copy();
//alert(docObj);
activeDocument = docObj;
var layObj = activeDocument.artLayers.add();
//alert(layObj);
activeDocument.artLayers[0].name = "uv";
docObj.activeLayer = docObj.layers["uv"];
activeDocument.selection.selectAll();
activeDocument.paste();
//透明度
layObj.opacity = 10;
layObj.blendMode = BlendMode.DIFFERENCE ;
//保存せずに閉じる
activeDocument = fileObj;
activeDocument.close(SaveOptions.DONOTSAVECHANGES);
間違っているのに何で動いてるのかわからない。
登録:
投稿 (Atom)