だけど、いちいちノードひとつずつコンストレイントを設定するのは面倒だし、場合によってはポイント・オリエントコンストレイントを設定して…、ポイントコンストレイントはオフセット設定は切り…、など、いちいち細かな設定をひとつずつ行うのは時間ばかりかかって、大変です。
コネクションにしても、コネクションエディタでやるのか、ハイパーシェードでやるのか…、どちらにせよ、何らかのウインドウを開いて、いちいち設定…。結構うっとうしいです。
ちょうど今週、インフルエンザで家にこもったので(笑)、以下のようなmelツールを作成しました。
--------------------------------
①複数選択から、各種コンストレイントを1ボタンで一括設定できる
②計算式のない、単純なコネクションを同様に1ボタンで一括設定できる。
③ついでに各種ジョイントアトリビュートも同様に1ボタンで一括設定できる。
--------------------------------
他にも、割とジョイントアトリビュートの、rotateOderを再設定することがあるので、ついでに機能を追加。また、スケール対応なんかもすると、segmentScaleCompensateもいじったりするので、これも追加。
あと、蛇足ですが、ついでのついでに、ジョイントRadiusも一括設定できるように追加。
(…まぁ、Radiusは一括選択後、チャンネルボックスから設定すればいいんですけど…)
--------------------------------
以下ソース
使用の場合は、スクリプトエディタにコピーして、シェルフなどに登録して使用してください。
あとは自由に改造していただいてかまいません。
/*
------------------------------------
Constraint/Connection/Joint Edit mel
------------------------------------
*/
if(`window -q -exists CCJ_Setting`)deleteUI CCJ_Setting;
window -s 0 CCJ_Setting;
columnLayout -adj 1;
string $F_LAYOUT = `frameLayout -bs "in" -cll 1 -cl 0 -l "<CONSTRAINT SET>"`;
columnLayout -adj 1 -co "left" 1;
rowLayout -nc 3 -cw3 110 110 110;
string $POC = `checkBox -label "Poin Constraint"`;
string $ORC = `checkBox -label "Orient Constraint"`;
string $SCC = `checkBox -label "Scale Constraint"`;
setParent..;
rowLayout -nc 3 -cw2 110 110 -cat 3 "left" 20;
string $PVC = `checkBox -label "poleVec Constraint"`;
string $PAC = `checkBox -label "Parent Constraint"`;
button -w 80 -l "Done" -c ("CONSTRAINT_SET(\"" + $F_LAYOUT + "\")");
setParent..;
frameLayout -cll 1 -cl 1 -l "Option Setting";
rowLayout -nc 4 -cw 1 80 -cat 2 "left" 0;
text -al "left" -l "Target Attribute";
string $CONST_X = `checkBox -label "X" -v 1`;
string $CONST_Y = `checkBox -label "Y" -v 1`;
string $CONST_Z = `checkBox -label "Z" -v 1`;
setParent..;
rowLayout -nc 2 -cw 1 80 -cat 2 "left" 0;
text -l "Maintain Offset";
string $CONST_OFST = `checkBox -v 1 -l ""`;
setParent..;
rowLayout -nc 3 -cw 1 80 -cat 2 "left" 0;
text -al "left" -l "SetTarget Mode";
radioCollection;
string $TGT_MODE = `radioButton -label "Even-Odd" -sl`;
radioButton -label "Harf-Harf";
setParent..;
setParent..;
setParent..;
setParent..;
//コンストレイントセットのレイアウト情報を格納する
frameLayout -e -docTag
($POC + ";" + $ORC + ";" + $SCC + ";" + $PVC + ";" + $PAC
+ "&" + $CONST_X + ";" + $CONST_Y + ";" + $CONST_Z
+ "&" + $CONST_OFST + ";" + $TGT_MODE)
$F_LAYOUT;
string $CNCT_F = `frameLayout -bs "in" -cll 1 -cl 0 -l "<CONNECTION SET>"`;
columnLayout -adj 1 -co "left" 1;
rowLayout -nc 4 -rat 1 "top" 0 -rat 2 "top" 0 -rat 3 "top" 0 -rat 4 "top" 0;
frameLayout -w 80 -h 84 -bs "in" -l "Attribute";
columnLayout ;
string $CNCT_T = `checkBox -label "translate"`;
string $CNCT_R = `checkBox -label "rotate"`;
string $CNCT_S = `checkBox -label "scale"`;
setParent..;
setParent..;
frameLayout -w 78 -h 84 -bs "in" -l "source";
columnLayout -adj 1;
string $CNCT_X = `checkBox -label "X"`;
separator;
string $CNCT_Y = `checkBox -label "Y"`;
separator;
string $CNCT_Z = `checkBox -label "Z"`;
setParent..;
setParent..;
frameLayout -w 80 -h 84 -bs "in" -l "target";
columnLayout ;
string $TGT_X = `optionMenu -w 60`;
menuItem -l "X" -p $TGT_X;
menuItem -l "Y" -p $TGT_X;
menuItem -l "Z" -p $TGT_X;
optionMenu -e -sl 1 $TGT_X;
string $TGT_Y = `optionMenu -w 60`;
menuItem -l "X" -p $TGT_Y;
menuItem -l "Y" -p $TGT_Y;
menuItem -l "Z" -p $TGT_Y;
optionMenu -e -sl 2 $TGT_Y;
string $TGT_Z = `optionMenu -w 60`;
menuItem -l "X" -p $TGT_Z;
menuItem -l "Y" -p $TGT_Z;
menuItem -l "Z" -p $TGT_Z;
optionMenu -e -sl 3 $TGT_Z;
setParent..;
setParent..;
columnLayout -adj 1;
text -l " SetTarget Mode";
radioCollection;
string $CNCT_TGT_MODE = `radioButton -label "Even-Odd" -sl`;
radioButton -label "Harf-Harf";
separator;
button -w 80 -l "Done" -c ("CONNECTION_SET(\"" + $CNCT_F + "\")");
setParent..;
setParent..;
setParent..;
setParent..;
frameLayout -e -docTag
($CNCT_T + ";" + $CNCT_R + ";" + $CNCT_S + "&" +
$CNCT_X + ";" + $CNCT_Y + ";" + $CNCT_Z + "&" +
$TGT_X + ";" + $TGT_Y + ";" + $TGT_Z + "&" +
$CNCT_TGT_MODE)
$CNCT_F;
string $JOINT_EDIT_F = `frameLayout -cll 1 -cl 0 -l "<JOINT EDIT SET>"`;
columnLayout -adj 1 -co "left" 1;
rowLayout -nc 2 -cat 2 "left" 5 -rat 2 "top" 1;
frameLayout -lv 0 -bs "etchedIn";
columnLayout -co "both" 5;
rowLayout -nc 2 -cw 1 80;
string $JON_RAD_YN = `checkBox -l "Radius"`;
string $JON_RAD = `floatField -w 60 -v 1.0 `;
setParent..;
rowLayout -nc 2 -cw 1 80;
string $JON_ROD_YN = `checkBox -l "Rotate Oder"`;
string $JON_ROD = `optionMenu -w 60`;
menuItem -l "XYZ" -p $JON_ROD;
menuItem -l "YZX" -p $JON_ROD;
menuItem -l "ZXY" -p $JON_ROD;
menuItem -l "XZY" -p $JON_ROD;
menuItem -l "YXZ" -p $JON_ROD;
menuItem -l "ZYX" -p $JON_ROD;
optionMenu -e -sl 1 $JON_ROD;
setParent..;
string $JON_SEG = `checkBox -v 1 -l "Segment Scale Compensate"`;
setParent..;
setParent..;
button -w 80 -l "Done" -c ("JOINT_EDIT_CMD(\"" + $JOINT_EDIT_F + "\")");
setParent..;
setParent..;
setParent..;
frameLayout -e -docTag
($JON_RAD_YN + ";" + $JON_RAD + ";" + $JON_ROD_YN + ";" + $JON_ROD + ";" + $JON_SEG)
$JOINT_EDIT_F;
setParent..;
showWindow CCJ_Setting;
//-----------------------------------------------
//ロックアトリビュートを検出
global proc vector CHECK_ATTR_LOCK(string $ATTR){
vector $LOCKSTATE =<<0,0,0>>;
if (`getAttr -l ($ATTR + "x")`)$LOCKSTATE = $LOCKSTATE + <<1,0,0>>;
if (`getAttr -l ($ATTR + "y")`)$LOCKSTATE = $LOCKSTATE + <<0,1,0>>;
if (`getAttr -l ($ATTR + "z")`)$LOCKSTATE = $LOCKSTATE + <<0,0,1>>;
return $LOCKSTATE;
}
//-----------------------------------------------
global proc string SET_TGT_LIST(string $RADIO_BUTTON){
//ソースノード・ターゲットノードの選択
string $LIST[] = `ls -sl`;
string $SCE_NODE_LIST[];
string $TGT_NODE_LIST[];
if(`radioButton -q -sl $RADIO_BUTTON` == 1){
int $i = 0;
int $j = 0;
int $k = 0;
for($i = 0; $i < size($LIST)-1;$i = $i +2){
$SCE_NODE_LIST[$j] = $LIST[$i];
$TGT_NODE_LIST[$k] = $LIST[$i +1];
$j++;
$k++;
}
}
else{
int $i = 0;
int $j = 0;
int $k = 0;
for($i = 0; $i < size($LIST);++$i){
if($i < (size($LIST)/2)){
$SCE_NODE_LIST[$j] = $LIST[$i];
$j++;
}
else{
$TGT_NODE_LIST[$k] = $LIST[$i];
$k++;
}
}
}
string $SCE_NODE_STR = stringArrayToString($SCE_NODE_LIST,";");
string $TGT_NODE_STR = stringArrayToString($TGT_NODE_LIST,";");
string $RETURN_STR = $SCE_NODE_STR + "&" + $TGT_NODE_STR;
return $RETURN_STR;
}
//-----------------------------------------------
//一括コンストレイント処理
global proc CONSTRAINT_SET(string $F_LAYOUT){
//レイアウト情報の格納
string $LAYOUT_INFO[] = stringToStringArray(`frameLayout -q -docTag $F_LAYOUT`,"&");
string $CNST_INFO[] = stringToStringArray($LAYOUT_INFO[0],";");
string $SKIP_INFO[] = stringToStringArray($LAYOUT_INFO[1],";");
string $OPTN_INFO[] = stringToStringArray($LAYOUT_INFO[2],";");
//-----------------------
//ソースノード・ターゲットノードの選択
string $LIST[] = `ls -sl`;
string $SCE_TGT_LIST[] = stringToStringArray(`SET_TGT_LIST($OPTN_INFO[1])`,"&");
string $SCE_NODE_LIST[] = stringToStringArray($SCE_TGT_LIST[0],";");
string $TGT_NODE_LIST[] = stringToStringArray($SCE_TGT_LIST[1],";");
//-------------------
//ターゲットアトリビュートの取得
vector $TGT_ATTR = <<0,0,0>>;
if(`checkBox -q -v $SKIP_INFO[0]` == 1)$TGT_ATTR = $TGT_ATTR + <<1,0,0>>;
if(`checkBox -q -v $SKIP_INFO[1]` == 1)$TGT_ATTR = $TGT_ATTR + <<0,1,0>>;
if(`checkBox -q -v $SKIP_INFO[2]` == 1)$TGT_ATTR = $TGT_ATTR + <<0,0,1>>;
//ポイントコンストレイント処理
if(`checkBox -q -v $CNST_INFO[0]`){
string $TGT_NODE;
int $i = 0;
for($TGT_NODE in $TGT_NODE_LIST){
//ロックアトリビュートを除外する
vector $LOCKSTATE = `eval ("CHECK_ATTR_LOCK(\"" + $TGT_NODE + ".t\")")`;
if($LOCKSTATE < <<1,1,1>>){
vector $SKIP_ATTR = $TGT_ATTR - $LOCKSTATE;
//コンストレイント文を変数定義する
string $EVAL_STRING = "pointConstraint -weight 1";
if(`checkBox -q -v $OPTN_INFO[0]` == 1) $EVAL_STRING = $EVAL_STRING + " -mo";
if($SKIP_ATTR.x <1) $EVAL_STRING = $EVAL_STRING + " -sk x";
if($SKIP_ATTR.y <1) $EVAL_STRING = $EVAL_STRING + " -sk y";
if($SKIP_ATTR.z <1) $EVAL_STRING = $EVAL_STRING + " -sk z";
$EVAL_STRING = $EVAL_STRING + " " + $SCE_NODE_LIST[$i] + " " + $TGT_NODE + ";";
eval $EVAL_STRING;
}
else{
print $TGT_NODE;
print " : pointConstraint Skipped...\n";
}
++$i;
}
}
//オリエントコンストレイント処理
if(`checkBox -q -v $CNST_INFO[1]`){
string $TGT_NODE;
int $i = 0;
for($TGT_NODE in $TGT_NODE_LIST){
//ロックアトリビュートを除外する
vector $LOCKSTATE = `eval ("CHECK_ATTR_LOCK(\"" + $TGT_NODE + ".r\")")`;
if($LOCKSTATE < <<1,1,1>>){
vector $SKIP_ATTR = $TGT_ATTR - $LOCKSTATE;
//コンストレイント文を変数定義する
string $EVAL_STRING = "orientConstraint -weight 1";
if(`checkBox -q -v $OPTN_INFO[0]` == 1) $EVAL_STRING = $EVAL_STRING + " -mo";
if($SKIP_ATTR.x <1) $EVAL_STRING = $EVAL_STRING + " -sk x";
if($SKIP_ATTR.y <1) $EVAL_STRING = $EVAL_STRING + " -sk y";
if($SKIP_ATTR.z <1) $EVAL_STRING = $EVAL_STRING + " -sk z";
$EVAL_STRING = $EVAL_STRING + " " + $SCE_NODE_LIST[$i] + " " + $TGT_NODE + ";";
eval $EVAL_STRING;
}
else{
print $TGT_NODE;
print " : orinetConstraint Skipped...\n";
}
++$i;
}
}
//スケールコンストレイント処理
if(`checkBox -q -v $CNST_INFO[2]`){
string $TGT_NODE;
int $i = 0;
for($TGT_NODE in $TGT_NODE_LIST){
//ロックアトリビュートを除外する
vector $LOCKSTATE = `eval ("CHECK_ATTR_LOCK(\"" + $TGT_NODE + ".s\")")`;
if($LOCKSTATE < <<1,1,1>>){
vector $SKIP_ATTR = $TGT_ATTR - $LOCKSTATE;
//コンストレイント文を変数定義する
string $EVAL_STRING = "scaleConstraint -weight 1";
if(`checkBox -q -v $OPTN_INFO[0]` == 1) $EVAL_STRING = $EVAL_STRING + " -mo";
if($SKIP_ATTR.x <1) $EVAL_STRING = $EVAL_STRING + " -sk x";
if($SKIP_ATTR.y <1) $EVAL_STRING = $EVAL_STRING + " -sk y";
if($SKIP_ATTR.z <1) $EVAL_STRING = $EVAL_STRING + " -sk z";
$EVAL_STRING = $EVAL_STRING + " " + $SCE_NODE_LIST[$i] + " " + $TGT_NODE + ";";
eval $EVAL_STRING;
}
else{
print $TGT_NODE;
print " : scaleConstraint Skipped...\n";
}
++$i;
}
}
//ポルベクコンストレイント処理
if(`checkBox -q -v $CNST_INFO[3]`){
string $TGT_NODE;
int $i = 0;
for($TGT_NODE in $TGT_NODE_LIST){
//コンストレイント文を変数定義する
string $EVAL_STRING = "poleVectorConstraint -weight 1";
$EVAL_STRING = $EVAL_STRING + " " + $SCE_NODE_LIST[$i] + " " + $TGT_NODE + ";";
eval $EVAL_STRING;
++$i;
}
}
//ペアレントコンストレイント処理
if(`checkBox -q -v $CNST_INFO[4]`){
string $TGT_NODE;
int $i = 0;
for($TGT_NODE in $TGT_NODE_LIST){
string $EVAL_STRING = "parentConstraint -weight 1";
if(`checkBox -q -v $OPTN_INFO[0]` == 1) $EVAL_STRING = $EVAL_STRING + " -mo";
//ロックアトリビュートを除外する
//移動アトリビュートチェック
int $ALL_LOCK_FLUG = 0;
vector $LOCKSTATE = `eval ("CHECK_ATTR_LOCK(\"" + $TGT_NODE + ".t\")")`;
if($LOCKSTATE < <<1,1,1>>) ++$ALL_LOCK_FLUG;
vector $SKIP_ATTR = $TGT_ATTR - $LOCKSTATE;
if($SKIP_ATTR.x <1) $EVAL_STRING = $EVAL_STRING + " -st x";
if($SKIP_ATTR.y <1) $EVAL_STRING = $EVAL_STRING + " -st y";
if($SKIP_ATTR.z <1) $EVAL_STRING = $EVAL_STRING + " -st z";
//回転アトリビュートチェック
$LOCKSTATE = `eval ("CHECK_ATTR_LOCK(\"" + $TGT_NODE + ".r\")")`;
if($LOCKSTATE < <<1,1,1>>) ++$ALL_LOCK_FLUG;
vector $SKIP_ATTR = $TGT_ATTR - $LOCKSTATE;
if($SKIP_ATTR.x <1) $EVAL_STRING = $EVAL_STRING + " -sr x";
if($SKIP_ATTR.y <1) $EVAL_STRING = $EVAL_STRING + " -sr y";
if($SKIP_ATTR.z <1) $EVAL_STRING = $EVAL_STRING + " -sr z";
if($ALL_LOCK_FLUG > 0){
$EVAL_STRING = $EVAL_STRING + " " + $SCE_NODE_LIST[$i] + " " + $TGT_NODE + ";";
eval $EVAL_STRING;
}
else{
print $TGT_NODE;
print " : parentConstraint Skipped...\n";
}
++$i;
}
}
}
//-----------------------------------------------
//コネクション 処理
global proc CONNECTION_SET(string $F_LAYOUT){
//レイアウト情報の格納
string $LAYOUT_INFO[] = stringToStringArray(`frameLayout -q -docTag $F_LAYOUT`,"&");
string $ATTR_INFO[] = stringToStringArray($LAYOUT_INFO[0],";");
string $SCE_INFO[] = stringToStringArray($LAYOUT_INFO[1],";");
string $TGT_INFO[] = stringToStringArray($LAYOUT_INFO[2],";");
string $SLCT_INFO[] = stringToStringArray($LAYOUT_INFO[3],";");
//-----------------------
//ソースノード・ターゲットノードの選択
string $LIST[] = `ls -sl`;
string $SCE_TGT_LIST[] = stringToStringArray(`SET_TGT_LIST($SLCT_INFO[0])`,"&");
string $SCE_NODE_LIST[] = stringToStringArray($SCE_TGT_LIST[0],";");
string $TGT_NODE_LIST[] = stringToStringArray($SCE_TGT_LIST[1],";");
//-------------------
//ターゲットアトリビュートの取得
vector $TGT_ATTR = <<0,0,0>>;
if(`checkBox -q -v $SCE_INFO[0]` == 1)$TGT_ATTR = $TGT_ATTR + <<1,0,0>>;
if(`checkBox -q -v $SCE_INFO[1]` == 1)$TGT_ATTR = $TGT_ATTR + <<0,1,0>>;
if(`checkBox -q -v $SCE_INFO[2]` == 1)$TGT_ATTR = $TGT_ATTR + <<0,0,1>>;
string $TGT_X = `optionMenu -q -v $TGT_INFO[0]`;
string $TGT_Y = `optionMenu -q -v $TGT_INFO[1]`;
string $TGT_Z = `optionMenu -q -v $TGT_INFO[2]`;
//translate コネクション
if(`checkBox -q -v $ATTR_INFO[0]`){
string $TGT_NODE;
int $i = 0;
for($TGT_NODE in $TGT_NODE_LIST){
//ロックアトリビュートを除外する
vector $LOCKSTATE = `eval ("CHECK_ATTR_LOCK(\"" + $TGT_NODE + ".t\")")`;
if($LOCKSTATE < <<1,1,1>>){
vector $SKIP_ATTR = $TGT_ATTR - $LOCKSTATE;
if($SKIP_ATTR.x > 0)connectAttr -f ($SCE_NODE_LIST[$i] + ".tx") ($TGT_NODE + ".translate" + $TGT_X);
if($SKIP_ATTR.y > 0)connectAttr -f ($SCE_NODE_LIST[$i] + ".ty") ($TGT_NODE + ".translate" + $TGT_Y);
if($SKIP_ATTR.z > 0)connectAttr -f ($SCE_NODE_LIST[$i] + ".tz") ($TGT_NODE + ".translate" + $TGT_Z);
}
++$i;
}
}
//rotate コネクション
if(`checkBox -q -v $ATTR_INFO[1]`){
string $TGT_NODE;
int $i = 0;
for($TGT_NODE in $TGT_NODE_LIST){
//ロックアトリビュートを除外する
vector $LOCKSTATE = `eval ("CHECK_ATTR_LOCK(\"" + $TGT_NODE + ".r\")")`;
if($LOCKSTATE < <<1,1,1>>){
vector $SKIP_ATTR = $TGT_ATTR - $LOCKSTATE;
if($SKIP_ATTR.x > 0)connectAttr -f ($SCE_NODE_LIST[$i] + ".rx") ($TGT_NODE + ".rotate" + $TGT_X);
if($SKIP_ATTR.y > 0)connectAttr -f ($SCE_NODE_LIST[$i] + ".ry") ($TGT_NODE + ".rotate" + $TGT_Y);
if($SKIP_ATTR.z > 0)connectAttr -f ($SCE_NODE_LIST[$i] + ".rz") ($TGT_NODE + ".rotate" + $TGT_Z);
}
++$i;
}
}
//scale コネクション
if(`checkBox -q -v $ATTR_INFO[2]`){
string $TGT_NODE;
int $i = 0;
for($TGT_NODE in $TGT_NODE_LIST){
//ロックアトリビュートを除外する
vector $LOCKSTATE = `eval ("CHECK_ATTR_LOCK(\"" + $TGT_NODE + ".s\")")`;
if($LOCKSTATE < <<1,1,1>>){
vector $SKIP_ATTR = $TGT_ATTR - $LOCKSTATE;
if($SKIP_ATTR.x > 0)connectAttr -f ($SCE_NODE_LIST[$i] + ".sx") ($TGT_NODE + ".scale" + $TGT_X);
if($SKIP_ATTR.y > 0)connectAttr -f ($SCE_NODE_LIST[$i] + ".sy") ($TGT_NODE + ".scale" + $TGT_Y);
if($SKIP_ATTR.z > 0)connectAttr -f ($SCE_NODE_LIST[$i] + ".sz") ($TGT_NODE + ".scale" + $TGT_Z);
}
++$i;
}
}
}
//-----------------------------------------------
//ジョイントアトリビュート エディット
global proc JOINT_EDIT_CMD(string $JOINT_EDIT_F){
//レイアウト情報の格納
string $LAYOUT_INFO[] = stringToStringArray(`frameLayout -q -docTag $JOINT_EDIT_F`,";");
string $TGT_JOINT_LIST[] = `ls -sl -type "joint"`;
string $TGT_JOINT;
for($TGT_JOINT in $TGT_JOINT_LIST){
if(`checkBox -q -v $LAYOUT_INFO[0]`){
setAttr ($TGT_JOINT + ".radius") `floatField -q -v $LAYOUT_INFO[1]`;
}
if(`checkBox -q -v $LAYOUT_INFO[2]`){
setAttr($TGT_JOINT + ".rotateOrder") (`optionMenu -q -sl $LAYOUT_INFO[3]` - 1);
}
setAttr($TGT_JOINT + ".segmentScaleCompensate")`checkBox -q -v $LAYOUT_INFO[4]`;
}
}
-----------------------------------
<蛇足ながら解説>
一括コンストレイントで、以下のところで、ロックアトリビュートの検出を行っています。
//-----------------------------------------------
//ロックアトリビュートを検出
global proc vector CHECK_ATTR_LOCK(string $ATTR){
vector $LOCKSTATE =<<0,0,0>>;
if (`getAttr -l ($ATTR + "x")`)$LOCKSTATE = $LOCKSTATE + <<1,0,0>>;
if (`getAttr -l ($ATTR + "y")`)$LOCKSTATE = $LOCKSTATE + <<0,1,0>>;
if (`getAttr -l ($ATTR + "z")`)$LOCKSTATE = $LOCKSTATE + <<0,0,1>>;
return $LOCKSTATE;
}
これは、対象のアトリビュートの途中までのstringを渡してやれば、x、y、zに関してロックされているかどうかをチェックして、vectorを返すプロシージャです。
今回、アトリビュートの有効・無効を0・1のvectorの値で管理しています。
(x:ロック y:アンロック z:ロック ・・・なら、結果は<<1,0,1>>・・・というわけです。)
実は今までにも何度か一括コンストレインmelを組んだことがあり、単純にアトリビュートごとに処理する方法を数パターン試したのですが、いずれもソースが長くなって、見直すのが面倒なことに。。。
そこで、ここ最近、vector形式で管理する方法にしてみたのですが、これが割りと楽で、ソースもシンプルになりました。
たとえば、最終的に、処理を行うアトリビュートを決めるソースの部分では…、
vector $SKIP_ATTR = $TGT_ATTR - $LOCKSTATE;
この一文だけですんじゃうわけです。ウヒヒ…って感じです。
vector形式で管理すると、このように3つの値をまとめて処理できるため、シンプルで便利だなという印象を持ってます。
もちろん、もっといいほかの方法もあるのかも知れませんが…、それは追々。。。
そんな訳で、このmelToolはロックアトリビュートを自動スキップするので、そこで処理がとまることはない…と思われます。
-----------------------------------
初めまして。
返信削除欲しいと思っていた機能のmelをご公開されていてとても助かります。
初心者的な質問で誠に恐縮なのですが、
こちらを実行するときの設定にある、
SetTargetModeの「Even-Odd」と「Harf-Harf」は何に影響を与えるものでしょうか。
もしよろしければご教授いただけますと幸いです。
どうぞよろしくお願いいたします。