ON-BLOG

CGのこと、あれこれ書いてます。

ファイル、フォルダコピー(同期)をエクセル参照して

エクセルで指定したフォルダ間をコピーするツールです。
※エクセルを使用したWSHツールです。
おそらく今後必要になりそうだったので、先行して作成しました。
あとエラー処理、オープンオフィスの対応がありますが
とりあえずこれで色々試してみたいです。

こちらは往々にこちらを参考させて頂きました。

JScriptでのScripting.FileSystemObjectオブジェクト TIPS - Qiita

まずはコード

//指定ファイルのエクセル、セルB2[コピー元]H2[コピー先]に記載されているパスを元に
//フォルダをコピーするツール。
//現在はコピー先のフォルダ、ファイルを一旦削除しています。
//要はフォルダ間を同期する感じです。
//エクセルのセルを増やせばコピーするフォルダが増えます。
//フォルダがなければ、強制的にフォルダを作成します。
//以下注意事項があります。
//1.B2、H2のセルは必ず列で埋めて下さい。間があるとエラーになります。
//2.列に空白は作らないください。これもエラーになります。
//3.一個上のフォルダまで有無は確認しますが、それ以上はエラーとなります。

var fso = new ActiveXObject("Scripting.FileSystemObject");
var Shell = new ActiveXObject("Shell.Application");
var excelApp = WScript.CreateObject("Excel.Application");
var Book = excelApp.Workbooks.Open("C:\\Users\\tommy_on\\Desktop\\Copypath.xls");
var Sheet = Book.WorkSheets("Sheet1");
var usedRange	= Sheet.UsedRange;
var bottom	= usedRange.Rows(usedRange.Rows.Count).Row;//列の一番下取得

for (var i=2; i<bottom+1; i++)
{
	var end_B_cells = Sheet.Cells(i,2).value;
	var end_H_cells = Sheet.Cells(i,8).value;
	var Floder = Shell.NameSpace(end_H_cells);
	if(!fso.FolderExists(end_H_cells))
		{
			ParentFolder(end_H_cells);
		}
	else
		{
		var DelItems = Floder.Items();
		for(var j = 0 ; j<DelItems.count; j++)
			{
				var SetItem = DelItems.Item(j);
				if(SetItem.IsFolder == true)
					{
					fso.DeleteFolder(SetItem,true);
					}
				else if(SetItem.IsFile == true)
					{
					fso.DeleteFile(SetItem,true);
					}
			}
		}
	fso.CopyFolder(end_B_cells, end_H_cells);
}

function ParentFolder(end_H_cells) 
	{
    if (!fso.FolderExists(end_H_cells))
    	{
			if (fso.GetParentFolderName(end_H_cells))
				{
				// フォルダが存在しなかったので、親フォルダ生成
				createFolder(fso.GetParentFolderName(end_H_cells));
				fso.CreateFolder(end_H_cells);
				}
        }
    }
Book.Close();
fso = null;
excelApp.Quit();
excelApp = null;

こんな感じです。
流れとしては、
まずはコピー元とコピー先を記入したエクセルが必要です。
こんな感じ
f:id:tommy_on:20150125001249p:plain
フォルダ的はこんな感じです。
f:id:tommy_on:20150125001929p:plain
エクセルのセル【B1以降】【H1以降】を参照して
コピーする感じです。

この環境ができれば、あとは上記コードのエクセルパスを変更後
JSで保存して実行すれば、BパスからHパスへフォルダ、ファイルがコピーされてると思います。
コードのコメント欄に書いてますが
注意事項があります。
1.B2、H2のセルは必ず列で埋めて下さい。間があるとエラーになります。
→BとHに必ずセルが埋まっている事が前提になっています。ないとエラーで止まりますので・・

2.列に空白は作らないください。これもエラーになります。
→使用している、列を取得している為、間に空白があるとそこが最後の列として扱われます。

3.一個上のフォルダまで有無は確認しますが、それ以上はエラーとなります。
→これは仕様です。もっと親を伸ばすことはできますが、しません。

こんな感じでした。
ではコードで手こずった部分をメモ変わりに書いていきます。

まずは、列の取得。
今回はB,Hで使用している列数ですね。

var usedRange	= Sheet.UsedRange;
var bottom	= usedRange.Rows(usedRange.Rows.Count).Row;//列の一番下取得

「UsedRange」で使用しているセルを取得し、「Rows.Count」で一番までカウントしてます。
これによって一番のセルまで取れてる訳ですね。
これはめちゃくちゃハマりました。
ってかこれであってるか未だに自信ありません。

あとFolderExitで親フォルダも無い時の挙動です。
これはおもっきり上記リンクを参考にさせてもらってます。

function ParentFolder(end_H_cells) 
	{
    if (!fso.FolderExists(end_H_cells))
    	{
			if (fso.GetParentFolderName(end_H_cells))
				{
				// フォルダが存在しなかったので、親フォルダ生成
				createFolder(fso.GetParentFolderName(end_H_cells));
				fso.CreateFolder(end_H_cells);
				}
        }
    }

SIでも同様のことやってたんですが
なぜか上手くいかなったので参考にさせてもらってます。
内容は非常に簡単で
「親フォルダ取得」→「無かった作成」→「フォルダを取得」
を繰り返しているだけ。

まぁ一応苦戦したので、忘れないように・・・


とまぁこんな感じで作成しました。
今後はエラー処理を入れ込みがいるかな?
あと、この手のツールC#でアプリケーションとして作成したいですね。

以上です。

動画をGIFにコンバート

最近時間ができたんで、動画をGIFにコンバートするツールを考えてました。
当初はAEのバッチか、PSのアクションで実行をでするつもりだったんですが
最近めっきりFFMPEGを使ってなかったので、FFMPEGで作成するツール
を作ってみました。
往々にして下記のサイトを参考にしてます。

ffmpeg と ImageMagick で動画をアニメGIF 変換


でできたコードがこれ。

//////////////////////////////////////////
@echo off
:nextfile
if "%~s1"=="" goto end
if exist %~s1 C:\Users\tommy_on\Documents\ffmpeg-20140723-git-a613257-win64-static\bin\ffmpeg.exe -i "%~s1" -s 270x216 -an -r 15 -pix_fmt rgb24 -f gif "%~d1%~p1%~n1.gif"
shift
goto nextfile
:end
pause
//////////////////////////////////////////

//で囲まれてる部分をメモ帳とかにコピペして
「.bat」で保存すれば、OKです。
※C:\の部分は自身のFFMPEGがあるパスに変更してください。

あとは動画をこの batファイルにドロップすればGIFができます。
上記のコードではだいぶ色とコマが落ちているので
大きいサイズには向きません。現状は270×216ですね。
なので、大きいサイズの場合は上記リンクを参考にしてください。


あ、大事なこと書いてませんね。
もちろんFFMPEGがないと実行できないので、適当に落としてきてくださいね。
あと上記コードもそのバージョンでフォルダ名などは書き換えてください。

以上。

あ、こんな感じになります。
サンプル↓
f:id:tommy_on:20150123002740g:plain
SIで適当に書き出しました。
元サイズが1000ぐらいかな?

まぁリファレンス資料の一覧に使っていこうかな?

AE UI位置について

aeでuiの位置などで教授用に作成した画像。
結構質問あるんだと痛感。
まずはウィンドウサイズについて。

こんな感じでウィンドウ作りますよね。

var window_make = new Window("dialog","Dialog",[0,0,250,130]);
window_make.show();

このとき、【[0,0,250,130]】この部分で位置を調節しています。
こんな感じです。↓
f:id:tommy_on:20150119114700j:plain

このダイアログに要素を追加するにはこんな感じ。

var window_make = new Window("dialog","Dialog",[0,0,150,130]);
var text_edit = window_make.add("edittext",[10,10,150-10,65]);
window_make.show();

f:id:tommy_on:20150119120929j:plain

要はhtmlとほぼ一緒です。笑
難しく考えるようなことではないんですよね。
ただ、QTとかなれると、超面倒なんすよね。
だからadobeのデザインアプリケーション使うんすよね。


ってかここ見たら、オールOK。

After Effectsユーザーのための、プログラミング入門 その10 後編 AE_Dialogs_due C#コントロール集 AEスクリプトのUIデザイン at AEP Project


以上。

SOFTIMAGEとMAYAで使用するPythonスクリプト超入門②~番外編~※改訂版

今回は配列を見ていきましょう。
そもそもPythonでは配列に種類があり、それが下記の、
「list」
「tuple」
「dict」
の3つがあるみたいです。
それぞれ違う意味があるので、
一つ一つみていきましょう。

「list」とは
→あらゆるオブジェクトを複数要素を持つことが出来る
シーケンス型のオブジェクト
要はなんでも格納できる(多種との混合も可能)配列って事なんですかね?
コマンド的には下記のイメージ。

list = [u"晴れ", u"曇", u"雨",]
Application.Logmessage(u"今日は"+list[0])
Application.Logmessage(u"今日は"+list[1])
Application.Logmessage(u"今日は"+list[2])
# INFO : 今日は晴れ
# INFO : 今日は雲
# INFO : 今日は雨

f:id:tommy_on:20111130012616j:plain


こんな感じ。
要素を[ ]中の数で、インデックスで管理するんです。
わかりやすいですね!



続いて
「tuple」とは
→list型と似てるが、メソッドが用意されていない為、要素に対して変更を行い。
 要素内の記述には[ ]ではなく、( )で記述する。
 ・これは使う意味あるんかな?メモリ的な利点があるのかな?
  スクリプトレベルでは使わないかも。。。。
一応コマンド

tuple = (u"晴れ", u"曇", u"雨")
Application.Logmessage(u"今日は"+tuple[0])
Application.Logmessage(u"今日は"+tuple[1])
Application.Logmessage(u"今日は"+tuple[2])

# INFO : 今日は晴れ
# INFO : 今日は雲
# INFO : 今日は雨

f:id:tommy_on:20140601190140j:plain



ほとんどlistと変わらんぞ。。
あとはこれらの要素に対して、変更が行えない点があるとの事。
まぁ中々使わないかも。。

ちなみに!
修正してて知った事が↓
f:id:tommy_on:20140601190152j:plain

Python賢い!!




最後に
「dict」とは
→こちらもlist型と似てるが、各要素には順序が無い(インデックスが無い)。なので、各要素には別に
 キーと呼ばれる識別子が割り振られ、それを指定することで要素を取り出せる。
 ・要は配列の取得の仕方が違うって事ですね。これ色々と用途ありそうですね。

dict = {"hare":u"晴れ", "kumori":u"曇り", "ame":u"雨"}
Application.Logmessage(u"今日は"+dict["hare"])
Application.Logmessage(u"今日は"+dict["kumori"])
Application.Logmessage(u"今日は"+dict["ame"])

# INFO : 今日は晴れ
# INFO : 今日は雲
# INFO : 今日は雨

f:id:tommy_on:20111130013433j:plain



Listより汎用性が高い気がします。
あと管理もし易い?かもですね。

ってな感じで、Pythonの配列の簡単な説明をしてみました。
イメージ的にはこんな感じw
f:id:tommy_on:20140601190229j:plain


この配列、はじめに要素を列挙できますが、もちろん途中でも要素を追加できます。(tupleは除く)
コマンド的にはこんな感じ↓

list = [u"晴れ", u"曇", u"雨",]
Application.Logmessage(u"今日は"+list[0])
Application.Logmessage(u"今日は"+list[1])
Application.Logmessage(u"今日は"+list[2])

list.append(u"雪")
Application.Logmessage(u"今日は"+list[3])

Application.Logmessage(str(list).decode("unicode-escape"))

# INFO : 今日は晴れ
# INFO : 今日は曇
# INFO : 今日は雨
# INFO : 今日は雪
# INFO : [u'晴れ', u'曇', u'雨', u'雪']

f:id:tommy_on:20140601190325j:plain

.append(u"雪")

で要素を追加しているわけです。

「Application.Logmessage(str(list).decode("unicode-escape"))

で配列の中身をデコードし、日本語で配列の中身を表示しています。
そうしないと、恐らく
「# INFO : [u'\u6674\u308c', u'\u66c7', u'\u96e8', u'\u96ea']」
こんな感じに、文字コード化していると思います。
これをまたUnicodeにデコードしてるわけです。

他にも要素の追加方法はありますが、今回は単純にこれだけ。




ちなみにJscriptだと、

var tenki = new Array("晴れ","曇り","雨");
Logmessage("今日の天気は"+tenki[0]);
Logmessage("今日の天気は"+tenki[1]);
Logmessage("今日の天気は"+tenki[2]);

tenki.push("雪");
Logmessage("今日の天気は"+tenki[3]);

jscriptだと、「new Array」を使用します。
概要的にはほとんど変わりないかと思いますが、
「.append」が「.push」になったりとメソッドが全然違いますので、ご注意ください。


では最後に超簡単な実例を。↓
ヌル三つ選んで、一つ一つリネームするだけのスクリプトです。
ほんとうに少しだけ、応用です!!

oSel = Application.Getvalue("Selectionlist")
Application.Logmessage(oSel)
list = []
for i in oSel:
   Application.Logmessage(u"これを配列に追加 "+str(i)+u" します")
   list.append(str(i))
Application.Logmessage(list[0])
Application.Logmessage(list[1])
Application.Logmessage(list[2])
Application.DeselectAll()
Application.SetValue(list[0]+".Name", "First", "")
Application.SetValue(list[1]+".Name", "Second", "")
Application.SetValue(list[2]+".Name", "Therd", "")

f:id:tommy_on:20140601190316j:plain

単純に選択したモノをForで回して、配列へ追加してます。
その後、配列の1つ目2つ目3つ目の名前を変更しています。

続いてMAYA編
これも文法的に同じなので、コードの紹介だけ。
説明は上文を閲覧ください。
まずは「list」から。

list = [u"晴れ", u"曇", u"雨",]
print(u"今日は"+list[0])
print(u"今日は"+list[1])
print(u"今日は"+list[2])

f:id:tommy_on:20140601205556p:plain
全く同じですね。
続いて「tuple」

tuple = (u"晴れ", u"曇", u"雨")
print(u"今日は"+tuple[0])
print(u"今日は"+tuple[1])
print(u"今日は"+tuple[2])

f:id:tommy_on:20140601205608p:plain
続いて「dict」

dict = {"hare":u"晴れ", "kumori":u"曇り", "ame":u"雨"}
print(u"今日は"+dict["hare"])
print(u"今日は"+dict["kumori"])
print(u"今日は"+dict["ame"])

やっぱ同じですね。



ではSI編と同じく、要素の追加について↓
>|python|
list = [u"晴れ", u"曇", u"雨",]
print(u"今日は"+list[0])
print(u"今日は"+list[1])
print(u"今日は"+list[2])

list.append(u"雪")
print(u"今日は"+list[3])

print(str(list).decode("unicode-escape"))

f:id:tommy_on:20140601205615p:plain
はい。これでも同じです。

続いて、この配列に要素を列挙
コマンド的にはこんな感じ↓
f:id:tommy_on:20140601205705p:plain

続いて、サンプル
オブジェクトを三つ選んで、一つ一つリネームするだけのスクリプトです。
これはSI編とはかなり違いますね。

import maya.cmds as mc

Sel = mc.ls(sl = True)
print Sel

list = []
for i in Sel:
    print(u"これを配列に追加 "+str(i)+u" します")
    list.append(str(i))


mc.select(deselect = True)
print(list[0]+".Name", "First", "")
print(list[1]+".Name", "Second", "")
print(list[2]+".Name", "Therd", "")

f:id:tommy_on:20140601210606p:plain

Python文法自体は一緒ですが、MAYAコマンドを扱うところが
完全に違いますが、これは前回からの続きでみると、
あまり難しいことは行ってませんね。




まぁ配列はここまで。。

次は実際のスクリプトを作成するために、
簡易なフローチャートを作成いきたいと思います。

SOFTIMAGEとMAYAで使用するPythonスクリプト超入門②~後編~※改訂版

では前回に引き続き超入門編の後編を。

前回ではログから作成する手順とIF文を使用したスクリプトを紹介しましたが、
今回は反復処理(FOR文)の説明をしていきたいと思います。


そもそもFOR文とは?WIKIさん↓


条件が真の間だけ与えられた文の実行を繰り返す
指定した条件が当てはまる間、処理ブロック内のステートメントを繰り返し実行する

う~ん以外と分かりずらい。
簡単にいうと指定した数だけ処理を繰り返すという事です。
イメージでいうと

「リンゴを10個食べる」という事を。
「リンゴを10個分(10回)の食べる」という行動を回数にして繰り返しすることです。
あれ?わかりずらい?
まぁ気にせずコマンドにうつってみます。
上記の事を記述すると、

for i in range(10):
       Application.Logmessage(u"リンゴ"+str(i+1)+u"個食った")

f:id:tommy_on:20111128000045j:plain

こんな感じになります。
ある程度画像に書いてますが、簡単に説明を。


一行目

for i in range(10):

はいこれ!
いきなりfor文!
私的な考えでざっくりいうと、
「for」で変数「i」個分「in」で含めてそれを「range(10)」で()内に記述されている回数だけ繰り返す。
て感じなんですけど、これじゃ、イミフですよね(-。-;
じゃ~一個ずつ意味を見ていきましょう。

「for」
これは一番上で記述されている通り、
「繰り返し実行する」というステートメントです。
ただしPythonの場合はシーケンス型で反復処理をするみたいです。
要は数で反復するのでは無く、
「文字やリストをシーケンス=集まりとして順々に処理」していくとの事。


「i」
これで、繰り返し実行する際の、現在のカウント数を格納しています。
要はカウンターです。


「in」
実はこれ書いてる時に、初めて知りました。
(in演算子ではないです)
なんであまり分かっていません。。。
ただ、PythonではFor文とセットで成り立ってるみたいです。
意味的には「含む」等があるみたいです。


「range(10)」
上記で記述した、
「文字やリストをシーケンス=集まりとして順々に処理」
という所で、現状のままだと、数値を扱えない状態です。
それを対応する為、組み込み関数の「range」を使用します。
これはこのままの意味で、「長さ」や「数列」という意味です。
今回では(10)と記述されているので、
0から始まり、10になるまで処理するという形になります。
range 0 1 2 3 4 5 6 7 8 9  =10 
←────────────→
数値 0 1 2 3 4 5 6 7 8 9  =10
矢印にある範囲を指定します。



こんな感じでFor文は処理しています。
ざつくりまとめると、
「for i in」で変数(i)が、「range(10)」で10になるまでという形になります。
※少し自信無し。。。。



これを反復処理して、インデントで下げた
二行目

Application.Logmessage(u"リンゴ"+str(i+1)+u"個食った")

おなじみのコマンドでログに出力しています。
ただし少しいつもと違う所がありますね。
それはメッセージの中身で、
(u"リンゴ"+str(i+1)+u"個食った")
まずは中身で見れる、「+」の記号です。
これは文字列の結合になります。
すごい解りやすいですよね。
もっと簡単にいうと、
(u"あ"+u"い"+u"う"+u"え"+u"お")
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
「あいうえお」
となります。文字をくっつけるんですね。


次に
「str(i+1)」
という部分です。
これ以外と引っかかりましたw
っていうのも、Jscriptだと、変数(i)の数値データとの文字列の「結合」は
自動で変換してくれていたからです。
なかなかその仕様がわからず苦労しましたw
ってことで、ほぼ上に書いてますが、
ここでは変数(i)の数値データを、strを使用して文字列へ変換しています。
この「str」は「String」のことです。
まぁこんな感じで、文字と数値の扱いには要注意ですね。



あ、ちなみにjscriptでは、

for (var i=0;i<10;i++)
{
Logmessage("リンゴ"+(i+1)+"個食った");
}

PythonのFor文の方がコンパクトですね。
Jscriptの場合は変数(i)の宣言が始まりますし。
あと上記にも書きましたが、PythonのFor文はシーケンス型なんで、
「abcdefg」等の文字列もそのまま反復処理できるのは強みですね。


ってかFor文のサンプルがあまりにも実践離れしてますね。。。。
ちなみに超簡単な実践で使えそうな物はこんな感じですかね?

for i in range(100):
Application.CreatePrim("Cube", "MeshSurface", "Cube_TEST"+str(i+1), "")

f:id:tommy_on:20111128015829j:plain


立方体を100個作成するスクリプトですw
りんごとほとんど変わりないですが、ご了承下さいww
まぁしかし変わらずともSOFTIMAGE内ではきちんと上記の様に、一応自動化できているわけです。
要は基礎の理解力が大事なんですよ!多分!

続いてMAYA編へいきましょう。
まずはForの基本から。

for i in range(10):
    print(u"リンゴ"+str(i+1)+u"個食った")

f:id:tommy_on:20140601185302p:plain
Logmessage以外全くかわりないですよね。
これがPython使う利点でもありますが。

じゃーこれを少し実践的に
立方体を10個リネームして作成するといったコードですね。

import maya.cmds as mc
for i in range(10):
    mc.polyCube(name="kyuuuu1")

f:id:tommy_on:20140601185309p:plain

これもSI版とほとんど変わらないです。
各所コマンドだけはSIと変わりますが、それ以外の文法はそのまま使えるのが、よくわかりますね。


まぁこんな感じでスクリプトで一番使うであろう、
コマンドモデル、IF文、For文の使い方を書いてきました。
次は配列(リスト)忘れてた。。。


では…

SOFTIMAGEとMAYAで使用するPythonスクリプト超入門②~中編~※改訂版

次によく使うIF文の説明をしていきたいと思います。
そもそもIF分とは?WIKIさん↓

「もし~だったら」という条件を示す文。

条件に合致する場合に処理される真文、条件に合わない場合に処理される偽文で構成されている。


要は指定した事に対して、正解か外れかと判定する文です。
簡単な例でいうと、
今日の天気でいうと、大阪は雨だったので、
もし今日雨だったらTrue =本当って意味
違うならFalse =嘘って意味
f:id:tommy_on:20111125031113j:plain


というように真偽によって分岐させるわけです。
簡単にいうとですよ!!

これをスクリプトに置き換えると、

today = "ame"
if today == "ame":
Application.Logmessage(u"正解!")
else:
Application.Logmessage(u"残念!今日は雨でした")

みたいになりますね。


ちなみにより実践で書くと、
以前作成したオブジェクト「Cube_TEST」の名前が、
同じ「Cube_TEST」かどうかの条件文を書いてみます。

oSel = Application.Selection(0)

Application.Logmessage(oSel)
if oSel.name == "Cube_TEST":
Application.Logmessage(u"正解")
else:
Application.Logmessage(u"残念")

f:id:tommy_on:20111125033336j:plain
※インデントに注意!

こんな感じです。
少しややこしくなりましたね。
これはIF文以外に
「選択している物」を取得した為です。

その辺り5分程度で見繕った画像用意したんで、こっちで説明してみます。
変な画ですが、そこはご愛嬌w
では細かく説明していきます。

一行目

oSel = Application.Selection(0)

ここでは変数という箱を用意し、選択物を変数(箱)に格納します。
f:id:tommy_on:20111127053623j:plain
Selection(0)で1番目に選択した物として格納。


二行目

Application.Logmessage(oSel)

おなじみログに選択した物(変数で格納した物)を文字で出力しています。

三行目

if oSel.name == "Cube_TEST":

でましたIF文!
ifと宣言し、その後に先程宣言した変数「oSel」の名前を「.name」で取得します
さらに条件分として、「==」を使い「変数の名前と一致したら」という条件をつけます。
その後判定になる材料「"Cube_TEST"」を記述します。
これで、「変数の名前が"Cube_TEST"と一致したら」という形になりました。
f:id:tommy_on:20111127061532j:plain


ちなみにこの「==」はほかにもいっぱいあります。
数学で学んだ、「<や>も」使用できます。
そして、最後に「:」で絞めて条件文の完成です。
その後条件にあった場合の、処理を記述していきます。

四行目と六行目

Application.Logmessage(u"正解")
Application.Logmessage(u"残念")

ここで条件に一致処理を記述します。
内容は簡単なもので、IFが正しければ、ログに(正解)
間違いならば、ログに(残念)と記述します。

五行目

else:

elseとは「でなければ」や「そのほか」等の意味ですね。
これが無いと嘘の場合の処理が記述できません。
なので、ここではIFで弾かれた物=嘘の物を振り分けます。

以上こんな感じです
大丈夫ですかね?



あ、ちなみにjscriptでは、

var oSel = Selection(0);
Logmessage(oSel);
if (oSel.name == "Cube_TEST")
{
Logmessage("正解");
}
else
{
Logmessage("残念");
}

まぁ毎度ですが、ほとんど変わりはありませんね。
jscriptはインデント式ではないので、その辺りは人によってはこっちの方がいいかも知れません。
あとifの条件式は()で囲まれ、
実行文は{}の括弧で中身を書きます。
各処理の後に「;」を打っています。





ちなみに分岐として、
「elif」もあります。
※「elseif」の略。
これはさらに条件分を追記できます。
簡単に説明すると、
ifだけだと、

もし正解(一致)だったらTrue =本当って意味
違うならFalse =嘘って意味

こんなイメージですよね。

elifとなると
こんな感じのイメージなります。

もし正解(一致)だったらtrue =本当って意味
もしくはこちらでも正解(一致)だったらtrue =本当って意味
違うならfalse =嘘って意味

みたいにさらに条件分を追加し、さらに篩いにかけれます。
要は深く条件事に処理できるようになるって事です。
さっきのコマンドから少し変えて記述してみると、

oSel = Application.Selection(0)
Application.Logmessage(oSel)
if oSel.name == "Cube_TEST":
Application.Logmessage(u"正解")
elif oSel.name == "Cube":
Application.Logmessage(u"これでも正解")
else:
Application.Logmessage(u"残念")

みたいに、選んだモノに対しての条件を、記述する数だけ、篩い掛けれるようになりました。
※サンプルでは一回のelif

あ、jscriptでは↓

var oSel = Selection(0);
Logmessage(oSel);
if (oSel.name == "Cube_TEST")
{
Logmessage("正解");
}
elseif (oSel.name == "Cube")
{
Logmessage("これでも正解");
}
else
{
Logmessage("残念");



まぁ変わりといえば、「elif」が略さずに、「elseif」になったところでしょうか。
あとpythonと比べると、
少し長くなりましたね。


続いて、MAYA編

基本SIと変わりません。
なので、SI編と同じコードで
「オブジェクト「Cube_TEST」の名前が、
同じ「Cube_TEST」かどうかの条件文を…」
こちらをMAYAで書いてみます。

import maya.cmds as mc
Sel = mc.ls( sl = True)[0]

if Sel == "Cube_TEST":
    print (u"正解")
else:
    print (u"不正解")

f:id:tommy_on:20140601171941p:plain

細かい説明はSi側と同じなので、省きます。
インデント「Tabキー」ですね。
これがないとエラーがでるので、注意が必要です。

あと、気になる点でいうと、

Sel = mc.ls( sl = True)[0]
if Sel == "Cube_TEST":

ここでシェイプのタイプとか取れないのかな?
まぁ地道に調べていきます。


まぁこんな感じで書いていった条件文ですが、
ほかにも多種記述の仕方がありますが、Python対応が少ないので、割愛します。
※Swicth文なども未対応です。。。

と次にスクリプトで一番使ってるであろう、反復処理について記述します。
ですが、長くなったので、またまた一旦ここで切ります。
続く.....

SOFTIMAGEとMAYAで使用するPythonスクリプト超入門②~前編~※改訂版

では前回に引き続きPythonのお勉強を。
今後は一週間おきに更新できればと思います。


早速スクリプトを作成していきたいと思います。
一番簡単な所から今回はキューブを出してみます。
コマンド的にはこんな感じ↓

Application.CreatePrim("Cube", "MeshSurface", "Cube_TEST", "")

f:id:tommy_on:20140513222617j:plain


初心者だとこの様なコマンドでも?となるかと思います。

※私もなってました。。。。
この様なコマンドは一回処理を実行して、スクリプトエディタ内のログに出力するのが一番の近道です。※SI版に限るかも…
SOFTIMAGEにはGUI上で実行した処理をコマンドとしてログに残すことができます。
それを有効に使用するんですね。
※これもSI版に限るかも…

では、実際下記のフローで実行してみます。
MODEL→取得→プリミティブ→ポリゴンメッシュ→立方体
すると下記のログが出力されるかと思います。

Application.CreatePrim("Cube", "MeshSurface", "", "")

f:id:tommy_on:20140513222720j:plain


もう上記とほぼ一緒ですよねw
こんな感じで、入門時は、実際に実行してログを参照するのが一番良いと思います。


ちなみにこのコマンドの違いは

「"Cube_TEST"」が足されている事です。

これはSDKを参照すると、この""の部分では作成したオブジェクトの名前を指定するとあります。
ここに入力することでオブジェクトの名前を指定できます。
f:id:tommy_on:20140513222744j:plain

では「一応」簡単に説明。
「Application.CreatePrim」でプリミティブを作成します。というコマンドになります。
この「CreatePrim」という文字列を選択し、F1キーを押すとこのコマンドについてSDKガイドが開かれます。
※上記の画像
そこを参照すると
各()内の説明が記述されています。
ひとつひとつみていきましょう。

("Cube", "MeshSurface", "Cube_TEST", "")

まずは一つ目の括弧""でジオメトリを指定します。
現状は「Cube」ですが、ここを「Sphere」にすると球が作成されます。
他にも
「cone」
「disc」
等の種類があります。


2つ目の括弧""でジオメトリのタイプを指定します。
ここを「NurbsSurface」にすればNURBSの立方体を作成します。



3つ目の括弧""で作成するオブジェクトの名前を指定します。
今回は「Cube_TEST」です。2バイト(日本語は)も「u」を付ける事で使用可能ですが、
なるべく英文字で作業して下さい。


4つ目の括弧""は今回は未記述ですが、
作成するオブジェクトの親を指定します。
ここを「Camera_Root」とすると、この子供に立方体が作成されます。
f:id:tommy_on:20140513222813j:plain

複数階層以下に作成する場合は
"Model.1.2"
みたいに「.」コンマで区切って指定してくださいね。


何回も記述しますが、このようにSDKガイドを見ながらコマンドを理解して、
記述して下さい。

ちなみにJscriptではこんな感じ↓

CreatePrim("Cube", "MeshSurface", "Cube_TEST", null);

Applicationが省略された事と、
Pythonでは最後の括弧が空白だったのに対して、
Jscriptでは同じ空白という意味の「null」を使用しています。
まぁそれ以外ほとんど違いはありませんね。


ではログを使いながらスクリプトを記述する方法は、これで大丈夫だと思います。

ではここからはMAYA編に入ります。
maya版では前回のものを踏襲してますね。

まずはコード。
立方体を作成します。

import maya 
maya.cmds.polyCube()

これだけです。
printからは少し変わってますね。
maya.cmdsがキーです。
そのコマンドの後にpolyCube()という、コマンドを呼び出しています。
これだけですね。
ちなみに、スフィアなら
「polySphere()」
円柱なら
「polyCylinder()」
というようにコマンドが変わります。

またオブジェクトの名前を指定して、モデルを作成することもできます。

import maya
maya.cmds.polySphere()

Sel = maya.cmds.ls( sl=True )[0]
maya.cmds.rename(Sel,'kyuuu')

少し長くなりましたね。
※ちょっと悩みました。。
「Sel = maya.cmds.ls( sl=True )[0]」
ここので変数「Sel」に1番目に選択したオブジェクトを格納し、
※オブジェクト作成後は強制的に作成したオブジェクトが選択されます。
「maya.cmds.rename(Sel,'kyuuu')」
ここで変数「Sel」のオブジェクトをリネームしております。
こんな感じでオブジェクトの名前も変更できますね。

あと、上のコードだと、少し文字が多くなりますよね?
特に「maya.cmds」辺りがめんどうなんですが、これ変数?として、
割り当てて、文字数減らせますね。
こんな感じ。

import maya as mc
mc.polySphere()

Sel = mc.ls( sl=True )[0]
mc.rename(Sel,'kyuuu')

短くなりました。

import maya as mc
mc.polySphere()

ここで「maya.cmds」を「mc」として扱ってます。
これ地味ですが、何百行のコードになってくると
大きいですよ。。

次は条件文である、「IF文」について書いていきたいと思います。

では。。