メッシュを追加するたびにスキンウェイトをやりなおす?その必要はないスキンウェイトのコピーはメッシュ単位。

メッシュを追加するたびにスキンウェイトをやりなおす?その必要はないスキンウェイトのコピーはメッシュ単位。

スキンウェイトの情報は.mb/.maシーンデータに入っているからシーンごと読み込むことが重要だ。

1,OldシーンにNewシーンを読み込んでOldキャラとNewキャラをそれぞれグループ化して並べる
2,見にくいけど、グループの座標は同じにしてから、
3,OldキャラとNewキャラを順に選択して、Skin > Edit Smooth Skin > Copy Skin Weights を実行したらうまくいった。

ついでに追加したメッシュが体に添うようなスキニーパンツやフィットしたスーツなら
体から服にスキンをコピーしてあげればびったり添う

曲げても平気

こんなに曲げても大丈夫

明日python書く予定は未定。

jointにSkinClusterがないと起こるエラー

jointにSkinClasterがないとなるエラー

The plug-in has found the following skin definition problems :
Unable to find the bind pose for : / SK_Mannequin / root / pelvis / spine_01 / spine_02 / spine_03 / clavicle_l / upperarm_l / lowerarm_l / hand_l / ring_01_l. No bind poses in the hierarchy containing the object will be exported.
Unable to find the bind pose for : / SK_Mannequin / root / pelvis / spine_01 / spine_02 / spine_03 / clavicle_r / upperarm_r / lowerarm_r / hand_r / middle_01_r / middle_02_r. No bind poses in the hierarchy containing the object will be exported.

これを解決するためにテストした

jointにSkinClusterがないとなるようで

たとえば下のように手のジョイントがSphereの外に突き出ている場合に

手のjointのSkinClusterがない状態になる。この状態でスキンバインドし保存し開きなおしてFBX出力するとエラーが出る。

このようにメッシュが外をカバーできていればエラーが出ない。

メッシュをスケールしjointを覆うだけでなおせる。。 下は読む必要がない。

もっと深堀してみると、、、、

このエラーがでるのは
BindPoseにはSkinClusterが必要だということになる。
SkinClusterなかったら、スキンバインド時にBindPoseは作られるがFBX出力時に怒られる
たぶんこのFBX exporter pluginが
SkinCluster経由で探したBindPoseがみつからないか?
・BindPoseのSkinClusterがないとこの「プラグインは、次のスキン定義の問題を発見しました。」と言っているのでBindPoseのSkin情報がないというのは問題になるみたいだ。


ノードエディタだと正常な場合こうJointノードにバインドポーズがあってBindPose1に接続されてる。

スキンクラスターがないノード
バインドポーズからピンがでていない


・jointのバインドポーズを直接BindPose1へノードエディタでつなげてみる
 →やってみたが、どのワールド行列につないだらよいかわからない。

もう少しシンプルなものでテストしてみたほうがいい。


下の例では
・gotoBindPose;をしても問題が出ない
・チャネルボックスエディタでもノードエディタでもBindPoseを持たないjointが存在。
・SkinClusterがなくても保存して開きなおしてFBX出力してもエラーが出ない。

一辺倒な言葉ではなにも語れないことがわかった。
jointがメッシュからはみ出ているなら 、だって骨が皮からはみ出ているなら問題あるでしょ。
・メッシュをかぶせる
・ジョイントをめり込ませるか
このめんどうな作業をやり直したほうがよさそうだ。

Maya Selected Node All Childs node disconnectAttr Loop

選択したノード以下のすべての接続を解除するループ

import maya.cmds as cmds
selectionNode=cmds.ls(sl=True)
# 指定したノード以下全てを検索
selectionNodes=cmds.ls(selectionNode,dag=1)
for node in selectionNodes:
	try:
		attribute1 =node+"_translateX.output"
		attribute2 =node+".translateX"
		cmds.disconnectAttr(attribute1, attribute2)
	except RuntimeError as err:
		pass
	

	try:
		attribute1 =node+"_translateY.output"
		attribute2 =node+".translateY"
		cmds.disconnectAttr(attribute1, attribute2)
	except RuntimeError as err:
		pass

	try:
		attribute1 =node+"_translateZ.output"
		attribute2 =node+".translateZ"
		cmds.disconnectAttr(attribute1, attribute2)
	except RuntimeError as err:
		pass

	try:
		attribute1 =node+"_rotateX.output"
		attribute2 =node+".rotateX"
		cmds.disconnectAttr(attribute1, attribute2)
	except RuntimeError as err:
		pass

	try:
		attribute1 =node+"_rotateY.output"
		attribute2 =node+".rotateY"
		cmds.disconnectAttr(attribute1, attribute2)
	except RuntimeError as err:
		pass

	try:
		attribute1 =node+"_rotateZ.output"
		attribute2 =node+".rotateZ"
		cmds.disconnectAttr(attribute1, attribute2)
	except RuntimeError as err:
		pass

	try:
		attribute1 =node+"_scaleX.output"
		attribute2 =node+".scaleX"
		cmds.disconnectAttr(attribute1, attribute2)
	except RuntimeError as err:
		pass

	try:
		attribute1 =node+"_scaleY.output"
		attribute2 =node+".scaleY"
		cmds.disconnectAttr(attribute1, attribute2)
	except RuntimeError as err:
		pass

	try:
		attribute1 =node+"_scaleZ.output"
		attribute2 =node+".scaleZ"
		cmds.disconnectAttr(attribute1, attribute2)
	except RuntimeError as err:
		pass

illustrator jsx でレイヤー表示3x5x6=90パターンpng24で書き出し

カラーの展開を納品確認するために90パターンをjsxで再現してpng24で書き出すスクリプトを書いた。

 メインのオブジェクトの色3色(ホワイト、ブラック、グリーン)
 文字5色(ホワイト、ブラック、グレー、グリーン、パープル) 
 背景6色(透明、ホワイト、ブラック、グレー、グリーン、パープル)

がほしいみたいなすごいこと言われて、マジかと思って。作りました。

//var folder = Folder.selectDialog();


//alert(  "filepath= "+filepath);

//var folder =filepath;
var document = app.activeDocument;


//if(document && folder)
if(document)
{  
  var options = new ExportOptionsPNG24();
  options.antiAliasing = true;
  options.transparency = true;
  options.artBoardClipping = true;
  options.verticalScale = 1413.4276;
  options.horizontalScale = 1413.4276;
  
  
  //alert(  "document.layers= "+document.layers);
  //配列グループの中にレイヤー番号を集める

  var kupuTopArr=[];

  for(var i=0; i<document.layers.length; ++i)
  {
	  layerName=document.layers[i].name;
	  if(layerName.indexOf( 'kupu_' )>-1)
		  kupuTopArr.push(i);
  }
  //alert(  "kupuTopArr= "+kupuTopArr);
  
  var kupuUnderArr=[];
  for(var i=0; i<document.layers.length; ++i)
  {
	  layerName=document.layers[i].name;
	  if(layerName.indexOf( 'kupuunder_' )>-1)
		  kupuUnderArr.push(i);
  }
  //alert(  "kupuUnderArr= "+kupuUnderArr);
  
  var fontArr=[];
  for(var i=0; i<document.layers.length; ++i)
  {
	  layerName=document.layers[i].name;
	  if(layerName.indexOf( 'font_' )>-1)
		  fontArr.push(i);
  }
  //alert(  "fontArr= "+fontArr);
  var bgArr=[];
  for(var i=0; i<document.layers.length; ++i)
  {
	  layerName=document.layers[i].name;
	  if(layerName.indexOf( 'bg_' )>-1)
		  bgArr.push(i);
  }
  //alert(  "bgArr= "+bgArr);
  
  //全パターンを出力
  //alert(  "kupuTopArr.length= "+kupuTopArr.length);
  for(var kupuTop_i=0; kupuTop_i<kupuTopArr.length; ++kupuTop_i)
  {
	  //alert(  "kupuTop_i= "+kupuTop_i);
	  
	  //他のkupu_レイヤーを非表示
	  hideArrAllLayers(kupuTopArr)

	  //今回のkupu_レイヤーを表示
	  var kupuTop_Laynum=kupuTopArr[kupuTop_i];
	  //alert(  "kupuTop_Laynum= "+kupuTop_Laynum);
	  document.layers[kupuTop_Laynum].visible = true;
	  
	  //他のkupuunderレイヤーを非表示
	  hideArrAllLayers(kupuUnderArr)

	  //今回のkupuunderレイヤーを表示
	  var kupuUnder_Laynum=kupuUnderArr[kupuTop_i];
	  //alert(  "kupuUnder_Laynum= "+kupuUnder_Laynum);
	  document.layers[kupuUnder_Laynum].visible = true;
	  
	  var kupuTop_Layer_Name=document.layers[kupuTop_Laynum].name+"";
	  //alert(  "kupuTop_Layer_Name= "+kupuTop_Layer_Name);
	  
	  
	  for(var font_i=0; font_i<fontArr.length; ++font_i)
	  {
			//他のfontレイヤーを非表示
			hideArrAllLayers(fontArr)
	  
		    //今回のfontイヤーを表示
			var font_Laynum=fontArr[font_i];
			//alert(  "kupuUnder_Laynum= "+kupuUnder_Laynum);
			document.layers[font_Laynum].visible = true;
			
			var font_Layer_Name=document.layers[font_Laynum].name+"";
			
			
			
			for(var bg_i=0; bg_i<bgArr.length; ++bg_i)
			{
				
				//他のbgレイヤーを非表示
				hideArrAllLayers(bgArr)
		  
				//今回のbgイヤーを表示
				var bg_Laynum=bgArr[bg_i];
				//alert(  "kupuUnder_Laynum= "+kupuUnder_Laynum);
				document.layers[bg_Laynum].visible = true;
				
				var bg_Layer_Name=document.layers[bg_Laynum].name+"";
					
				
			
				//Export -------------------------------------------------------------
				
				filepath=app.activeDocument.path.fsName.toString()+"";
				filepathArr = filepath.split('\\'); // ["apple", "banana", "orange"]
				filepath=filepathArr.join('/');
				
				var makedDirPath = mkdirp(filepath + '/nouhin/'+kupuTop_Layer_Name+'/'+font_Layer_Name+"");
				//alert("makedDirPath= "+makedDirPath);
		  
				var ExportfilePath = makedDirPath+kupuTop_Layer_Name+"_"+font_Layer_Name+"_"+bg_Layer_Name+".png"
				//alert(  "ExportfilePath= "+ExportfilePath);
		  
				var file = new File(ExportfilePath);
				document.exportFile(file,ExportType.PNG24,options);
			}
	  }
	  

	  
	  
	  
  }
  /*
  var n = document.layers.length;
  for(var i=0; i<n; ++i)
  {
    hideAllLayers();
    var layer = document.layers[i];
	alert(  "document.layers["+i+"].name= "+document.layers[i].name);
    layer.visible = true;

    //var file = new File(folder.fsName+"/"+layer.name+".png");
    var file = new File(filepath+"/"+layer.name+".png");

    document.exportFile(file,ExportType.PNG24,options);
  }
  */
  
  showAllLayers();
  
  
  alert(  " 処理が完了しました ");
}

function kupu_white_view(){
  forEach(document.layers, function(layer) {
	if(layer.name=="kupu_white"){
	   layer.visible = true;
	}
    layer.visible = false;
  });
}

function hideArrAllLayers(Arr)
{
	for(var i=0; i<Arr.length; ++i)
    {
		  var Laynum=Arr[i];
		  //alert(  "kupuTop_Laynum= "+kupuTop_Laynum);
		  document.layers[Laynum].visible = false;
	}
}

function hideAllLayers()
{
  forEach(document.layers, function(layer) {
    layer.visible = false;
  });
}

function showAllLayers()
{
  forEach(document.layers, function(layer) {
    layer.visible = true;
  });    
}

function forEach(collection, fn)
{
  var n = collection.length;
  for(var i=0; i<n; ++i)
  {
    fn(collection[i]);
  }
}

function mkdirp(path) {
    var fullPath = "";
    path = path.toString();
    var arr = path.split("/");
    for (var i = 0; i < arr.length; i++) {
        var folderName = arr[i];
        fullPath += folderName + "/";
        var folder = new Folder(fullPath);
        if (!folder.exists) folder.create();
    }
    return fullPath;
}