以前作ったyjp_DuplicateMeshSkinで
バインドされたメッシュを加工し、ヒストリーを消す時にyjp_DuplicateMeshSkinを使う事で
ウエイトが崩れずに済むと聞いて試したら本当に大丈夫だった。
でも中間オブジェクトが複数出来てしまうと・・
見てみると複数できている。
yjp_DetachBindShelfで再バインドしてみると中間オブジェクトを消す処理でエラーが発生している
ちょっと調べてみよう。
2015年2月28日土曜日
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年9月6日土曜日
ShellWeight
■内容
複数頂点と1つのジョイントを選択して実行すると繋がったポリゴンが選択されウエイト1でジョイントとバインドされる
ShellWeight 0 は選択した頂点を1に
ShellWeight 1 は選択した頂点と繋がった頂点を1に
バインドされていない場合バインドもされる。
なぜかエラーが出る事があります。バインドの状況が違うのか原因が分からず。
global proc ShellWeight(int $p)
{
string $Weight_joint[] = `ls -sl -type joint`;
if(!size($Weight_joint)) error "ShellWeight: requires one joint node to be selected.\n";
string $Weight_vtx[] = `ls -sl -type float3`;
if(!size($Weight_vtx)) error "ShellWeight: requires one vertex to be selected.\n";
string $MeshName[];
tokenize $Weight_vtx[0] "." $MeshName ;
string $onevtx = $Weight_vtx[0];
if(`gmatch "*:*" $Weight_vtx[0]`)
{
string $point[];
tokenize $Weight_vtx[0] ":" $point;
$onevtx = $point[0] + "]";
}
string $SelectShape[] = `listRelatives -s $MeshName[0]`;
string $SelectSkinClusterS[] = `listConnections -t skinCluster $SelectShape[0]`;
//バインドされたジョイントかチェック
string $JointInf[] = `skinCluster -q -inf $SelectShape[0]`;
int $found = stringArrayContains($Weight_joint[0], $JointInf);
if($found == 0)
{
//バインドされていなければ実行
skinCluster -e -lw true -wt 0 -ai $Weight_joint[0] $SelectShape[0];
}
skinPercent -tv $Weight_joint[0] 1.0 $SelectSkinClusterS[0] $Weight_vtx[0];
if($p == 0)
{
select $onevtx;
artAttrSkinWeightCopy;
select $Weight_vtx;
}
else if($p == 1)
{
select $Weight_vtx[0];
artAttrSkinWeightCopy;
select $Weight_vtx;
ConvertSelectionToShell;
}
artAttrSkinWeightPaste;
}
複数頂点と1つのジョイントを選択して実行すると繋がったポリゴンが選択されウエイト1でジョイントとバインドされる
ShellWeight 0 は選択した頂点を1に
ShellWeight 1 は選択した頂点と繋がった頂点を1に
バインドされていない場合バインドもされる。
なぜかエラーが出る事があります。バインドの状況が違うのか原因が分からず。
global proc ShellWeight(int $p)
{
string $Weight_joint[] = `ls -sl -type joint`;
if(!size($Weight_joint)) error "ShellWeight: requires one joint node to be selected.\n";
string $Weight_vtx[] = `ls -sl -type float3`;
if(!size($Weight_vtx)) error "ShellWeight: requires one vertex to be selected.\n";
string $MeshName[];
tokenize $Weight_vtx[0] "." $MeshName ;
string $onevtx = $Weight_vtx[0];
if(`gmatch "*:*" $Weight_vtx[0]`)
{
string $point[];
tokenize $Weight_vtx[0] ":" $point;
$onevtx = $point[0] + "]";
}
string $SelectShape[] = `listRelatives -s $MeshName[0]`;
string $SelectSkinClusterS[] = `listConnections -t skinCluster $SelectShape[0]`;
//バインドされたジョイントかチェック
string $JointInf[] = `skinCluster -q -inf $SelectShape[0]`;
int $found = stringArrayContains($Weight_joint[0], $JointInf);
if($found == 0)
{
//バインドされていなければ実行
skinCluster -e -lw true -wt 0 -ai $Weight_joint[0] $SelectShape[0];
}
skinPercent -tv $Weight_joint[0] 1.0 $SelectSkinClusterS[0] $Weight_vtx[0];
if($p == 0)
{
select $onevtx;
artAttrSkinWeightCopy;
select $Weight_vtx;
}
else if($p == 1)
{
select $Weight_vtx[0];
artAttrSkinWeightCopy;
select $Weight_vtx;
ConvertSelectionToShell;
}
artAttrSkinWeightPaste;
}
2014年8月31日日曜日
yjp_DetachBindShelf
これでデタッチするとバックアップオブジェが作られてウエイトがコピーされます。
バインドするシェルフが作られているので、
クリックするとフリーズとヒストリを消してバインドされ
バックアップオブジェからウエイトがコピーされます。
global proc yjp_DetachBindShelf()
{
string $objs[] = `ls -sl`;
if( size($objs) == 0 )return;
string $sc = `findRelatedSkinCluster $objs[0]`;
if( size($sc) == 0 )return;
//バックアップオブジェクト
string $backupobj[] = `duplicate $objs[0]`;
setAttr ($backupobj[0] + ".visibility") 0;
setAttr -lock 0 ($backupobj[0] + ".tx");
setAttr -lock 0 ($backupobj[0] + ".ty");
setAttr -lock 0 ($backupobj[0] + ".tz");
setAttr -lock 0 ($backupobj[0] + ".rx");
setAttr -lock 0 ($backupobj[0] + ".ry");
setAttr -lock 0 ($backupobj[0] + ".rz");
setAttr -lock 0 ($backupobj[0] + ".sx");
setAttr -lock 0 ($backupobj[0] + ".sy");
setAttr -lock 0 ($backupobj[0] + ".sz");
string $jointlistname[] = `listConnections -type "joint" ($sc +".matrix")`;
string $resStr = stringArrayToString($jointlistname, " ");
int $maxInf = `getAttr ($sc + ".maxInfluences")`;
currentTime 0 ;
//バックアップオブジェクトにウエイトコピー
string $yjpscname[] = `skinCluster -mi 1 -omi true -dr 4 -rui true -tsb $jointlistname $backupobj[0]`;
copySkinWeights -ss $sc -ds $yjpscname[0];
//シェルフの処理
string $script = ("select " + $objs[0] + ";\nFreezeTransformations;\nDeleteHistory;\nstring $sc[] = `skinCluster -omi true -dr 4 -rui true -mi " + $maxInf + " -tsb " + $resStr + " " + $objs[0] + "`;\ncopySkinWeights -ss " + $yjpscname[0] + " -ds $sc[0];\ndelete " + $backupobj[0] + ";\n");
select -r $objs[0];
//ここに他のウエイトを保存する処理を追加しておくと便利
//デタッチ
DetachSkin;
textToShelf ($objs[0], $script);
return ;
}
一応、思いついたのができました。
setAttr -lockのところもうちょっと簡単にできないかな。
あとはシェルフ実行したら消したほうがいいが、消し方が分からない。
バインドするシェルフが作られているので、
クリックするとフリーズとヒストリを消してバインドされ
バックアップオブジェからウエイトがコピーされます。
global proc yjp_DetachBindShelf()
{
string $objs[] = `ls -sl`;
if( size($objs) == 0 )return;
string $sc = `findRelatedSkinCluster $objs[0]`;
if( size($sc) == 0 )return;
//バックアップオブジェクト
string $backupobj[] = `duplicate $objs[0]`;
setAttr ($backupobj[0] + ".visibility") 0;
setAttr -lock 0 ($backupobj[0] + ".tx");
setAttr -lock 0 ($backupobj[0] + ".ty");
setAttr -lock 0 ($backupobj[0] + ".tz");
setAttr -lock 0 ($backupobj[0] + ".rx");
setAttr -lock 0 ($backupobj[0] + ".ry");
setAttr -lock 0 ($backupobj[0] + ".rz");
setAttr -lock 0 ($backupobj[0] + ".sx");
setAttr -lock 0 ($backupobj[0] + ".sy");
setAttr -lock 0 ($backupobj[0] + ".sz");
string $jointlistname[] = `listConnections -type "joint" ($sc +".matrix")`;
string $resStr = stringArrayToString($jointlistname, " ");
int $maxInf = `getAttr ($sc + ".maxInfluences")`;
currentTime 0 ;
//バックアップオブジェクトにウエイトコピー
string $yjpscname[] = `skinCluster -mi 1 -omi true -dr 4 -rui true -tsb $jointlistname $backupobj[0]`;
copySkinWeights -ss $sc -ds $yjpscname[0];
//シェルフの処理
string $script = ("select " + $objs[0] + ";\nFreezeTransformations;\nDeleteHistory;\nstring $sc[] = `skinCluster -omi true -dr 4 -rui true -mi " + $maxInf + " -tsb " + $resStr + " " + $objs[0] + "`;\ncopySkinWeights -ss " + $yjpscname[0] + " -ds $sc[0];\ndelete " + $backupobj[0] + ";\n");
select -r $objs[0];
//ここに他のウエイトを保存する処理を追加しておくと便利
//デタッチ
DetachSkin;
textToShelf ($objs[0], $script);
return ;
}
一応、思いついたのができました。
setAttr -lockのところもうちょっと簡単にできないかな。
登録:
投稿 (Atom)