MaxScriptの勉強 その5 よく使いそうなコマンドとか。

まだまだ続くmaxscript。

よく使いそうなコマンドと、調べるのにちょっと手間取った細かいコマンドメモ。

文字列置換 substituteString <source> <from> <to>

source のなかの fromの文字列を toに変換して返す。 mel でいうところの substitute

指定の文字で文字列を分割    filterString <string> <token_string>

stringを token_stringで分割して配列で返す。 melでいうところのtokenize pythonでいうところの string.split(“token_string”)
filterStringの場合は、token_stringに複数のパターンを入れることが可能
a-i-u_e_o “-_” とすると  #(“a”,”i”,”u”,”e”,”o”) になる。なにげに便利。

コマンド実行 execute <string>

melで言うところの eval
<stirng> に書かれたコマンドを評価して返す。

maxの言語を判定 sysinfo.GetMaxLanguage()
戻り値は配列。英語なら
#(9, 1, “ENU”, “英語 (米国)”, “en-US”)
のように帰ってくる。
Maxは言語ファイルがかなり深いところにあるせいで、言語によって処理を分けるときがけっこうだるい。
2013からはマルチ言語対応になったっぽいけど。
3DCGツールの日本語化なんて、どうせ日本語が日本語じゃないんだし 英語版でいいじゃん(´・ω・`)

その他、スクリプト関係の仕様メモ。
Max起動時に、自動的にmaxスクリプトを実行する方法

<MAX InstallPath>/Scripts/Startup の中に .ms ファイルを突っ込んでおく

実行しないまでも、自分で作ったコマンドを使えるようにする方法

Customize > Configure System Paths の、AdditionalScripts で設定していあるフォルダにスクリプトを置く。
デフォルトでは、 C:/user/<username>/AppData/Local/Autodesk/3dsmax/2012 – 64bit/enu(日本語maxならjpn)/scripts
ここと、おそらく、 <MAXInstallPath>/Scripts でもOKかと。

mayaの場合、 所定のところに置かれた userSetup.mel or .py  しか読み込んでくれないので
そこのところは、maxは非常に親切仕様。
しかし、置いとけば勝手に実行してくれるといたずらしほうd・・・

MaxScriptの勉強 その4 maxのメニューをいじる

まだまだ続くMaxScript勉強。

MenuMan コア インタフェース を使用すると、メニュー マネージャへのアクセスが可能になり、メニューを新規に作成したり、既存のメニューやクアッドメニュー、
およびそれらのサブメニューやメニュー項目にアクセスしたり、それらのメニューのロード、保存、登録、および登録解除を行うこともできます。

とのことなので、いろいろ試してみた。

maxのMenuは、インストールされているフォルダのなかのUIフォルダ内に、メニューの設定ファイルが置いてあり、そのファイルを読み込んでメニューを作成しているようだ。

menuMan.getMenuFile()

で、現在読み込まれている .mnuファイルがフルパスで取得できる。

弄りたいメニューを探す

<Interface:menu> = menuMan.findMenu <menuName>

戻り値はmixinインターフェースのポインタ ない場合はundefined
操作方法は、<Interface>のメソッドを使う。詳細はHelpのMenuMan コア インタフェース > Mixin インタフェース: menuMan.getMenu(…)

menuを作る

 <Interface:menuItem> = menuMan.createActionItem macroScriptName macroScriptCategory

押した時に、何かしらのアクションを起こしたい場合、 アクションの内容を macroScriptで記述してセットして
上記のコマンドでボタンに対してBindする。

マクロの書き方は

macroScript macroScriptNamecategory:”macroScriptCategory“(…)

マクロの記述自体は、基本MaxScriptと共通
.msファイル内に一緒にmacroScriptを記述することもできる。
(その他オプションやら細かいことはまたいずれちゃんと勉強) 

作ったメニューを追加する

<Interface:menu>.addItem <Interface:menuItem> position

ポジションは、<Interface:menu>の何番目に挿入するかを指定する。
一番最後なら -1

menu内に含まれるmenuItemのPositionIDを調べるコマンドを書いてみた。
見つからないときは -1 を返す。

if のところを return i とかにすると ** system exception **になるのの原因がいまいちよくわからない(´・ω・`)
けどとりあえずできたのでよし。

menuの再描画

menuMan.updateMenuBar()

addItemしたら、再描画。
再描画すると addItemで追加したItemが指定のMenuに追加される。

Installフォルダ/Scripts/Startup 直下に msファイルを入れておくと、Maxが起動した時にスクリプトがロードできるっぽいので
追加するコマンド類をmsファイルに入れてここに突っ込んでおいてロードするか
MacroScriptをセットして、Max起動時にMacroが動くようにするかすれば良い…のかな。このへんはまた明日調べる予定。

maxscriptは、mel以上に資料が少ない(´・ω・`)

MaxScriptの勉強 その3 UIを作る

引き続きMaxScriptの勉強。

UIを作るときは、 MaxScript > Visual MAXScriptを使うと GUIで、手軽にUIを作成することができる。
ただ、UIがおおかったりする場合は、手で書いたほうが早いのかもしれない。

Rolloutを作る
melでいうところのLayoutのようなもの(だと解釈)
この中に、Widgetや Eventコマンドなどを記述する。

rollout <rolloutName> “rolloutTitle” width:val height:val
(
<widget>
<EventCommand>
)
<widget> 部分には、 Button や Label editText のようなWidgetを記述してRollout上に配置する。
例はbuttonだが、基本どのwidgetも引数は同じ。

button <widgetName> <Caption> pos:[x,y] width:val height:val

widgetNameは、値をSetしたりGetしたりするときに使用するWidgetの名前。
Captionは、見出し posは配置する座標 widget height は widget自体の大きさを設定する。

<eventCommand>は、押した時 値が変わった時 などに実行されるコマンドを記述する。

例として、checkboxが変わった時の書き方
on <objectName> changed <state> do ( command)

<objectName> は、イベントを指定したいWidgetの名前

<state> は、イベントの返り値(changedの場合は、checkButtonのOn Offが Boolで帰ってくる)
イベントの種類は、各Widgetごとに異なるので、 Visual MAXScriptのEventタブで対応しているものを確認する。
または、VisualMaxScriptでも EventScriptは記述できる。

Windowを作る

 UI = newRolloutFloater “<windowTitle>” width:val height:val

を実行すると、widthとheightで指定した大きさの 空のUIが作成される。
そこに rollout(mayaで言うところのLayout?)を配置する。

addRollout <rolloutName> <uiName>

uiName は、Rolloutを載せたいWindowを指定
<rolloutName> は、予め設定しておいたRolloutの名前を入れる。

<rolloutName> 含めて、Widgetの名前は重複できないので かならずかぶらない名前をそれぞれ指定する。

Widgetの値を取得・設定する

Widgetの値を取ってきたい場合は、アトリビュートへの値のセット同様に

<rolloutName>.<widgetName>.<attribute>  =  val
のようにする。
Eventを書くときは
<widgetName>.<attibute> = val
値を取得したい場合は、 = の左右が逆になる。

(maxscriptの場合、何かの値にアクセスする場合、フォルダの階層をたどるように . で、取得したいAttributeにアクセスしにいく。
eventは rolloutを記述している階層からになるので <widget>.<attribute> その外側からだと、 階層がひとつ上がるので <rolloutName>.<widget>.<attribute>に。
. を 「~の中にある」 と言い換えるとわかりやすいのかも。) 

記述的には、melよりはるかに楽でわかりやすいけど デフォルトで使えるwidgetの数があんまりないのが玉に瑕。

例) ファイルを選択して editTextにセットする セットされた値を取得して、Labelに表示するSample。

getSaveFileName が、Dialogを表示してSaveフォルダとファイル名を設定して返すコマンド、 types: ~ で、保存できる形式を限定。
substituteString は、正規表現を使用して文字列を置換する。
getSaveFileName の戻り値は C:abcd.bat のように で帰ってきてしまうのでプログラム的に都合が悪いので / に変換。
VisualMAXScriptも、はじめは使いにくいと思ったけど、なれるとサクサクUI作れるのが良いね。

MaxScriptの勉強 その2 テキストファイルへの書き出し

前回に続いて maxscript の勉強メモ

maxscriptからtxtファイルへ書き出す方法
ファイルを開く
foo = opneFile mode: ” “
mode: の後にどういうタイプで開くのか書く
ファイルを閉じる
close foo
読み込み
readLine foo
で、一行だけ読み込み。
複数行を読みたい時は
while eof fileID == false do append arr (readLine fileID)
でできた。
eof は、読み込もうとしている fileがEndOfFileの時は true になるので、
falseの間 whileでループさせて 配列 arr に読み込んだ行をセットする
その他に、1文字づつ取り出したりなどのコマンドがある模様。けど、とりあえず使わないので後回し。
書き込み
print “value” to: foo
あるいは
format “formatString” value to: foo
print でStringを書き出そうとすると、ダブルクォートで囲われて出力されてしまう模様。
(対処法探し中)
formatは、Cのprintfと使い方は同じ。 formatString のなかの % が、その後ろの value で置き換わる。こちらならダブルクォートでは囲われない 1文字づつ取り出して配列に入れる関数を書いてみた。

maxScriptの場合、関数の戻り値は 一番最後に評価されたコマンド or Return <expr> 速度的に、returnを使うと遅くなるので避けたほうが良いらしいが、この場合は仕方ない。

if や for の書き方は他と随分違うのでちょっと戸惑うけど、その辺は慣れの問題。
あと、maxscriptのHelpがすこぶる読みにくくて どこに何が書いてあるのかを漁るのが厄介で、コマンドとか自分のやりたい機能を探すだけで時間を食われるのがもどかしい…