【3dsMAX】MAXScriptでPythonつかってみた part01【MaxPlus:初級編】
2015/11/16
Tag: 3dsmax,MaxPlus,MaxScript,python,script
みなさんはじめまして。今年入社した新米TD市川です。
そんな私もついにDF TALKを執筆させて頂く事になりました!温かい目で見ていただければ幸いです。
はじめに
今回紹介していく内容は、MAXにおけるPythonの扱い方の紹介です。
Mayaを使っている人にとっては馴染み深いPythonですが、MAXも2014から実装されて、かれこれ2年以上の月日が経ちましたね。それからバージョンも上がり、2015ではDF_TALKで紹介することも多いPySideが扱えるようになりました。弊社では最近になって2015を導入しましたので、これを一つのきっかけにと、MAXをテーマに取り上げています。
MAXScriptでPythonを実行してみよう!
MAXScriptでPythonを実行する方法は二通りあります。
①Python形式の文字列を実行
python.Execute("print 'Hello Python'") --もしくは python.Execute "print 'Hello Python'"
この時注意が必要なのはMAXにおける文字列についてです。
MAXScriptでは「”(ダブルクォーテーション)」で括ったもは文字列、
「’(シングルクォーテーション)」で括ったものはオブジェクトなどを表すときに使います。
Pythonでは「”」と「’」をどちらとも文字列として扱えるので、MAXScript上での取扱いには注意が必要です。
②Pythonファイルを指定して実行
python.ExecuteFile("pythonファイルのパス") --もしくは python.ExecuteFile "pythonファイルのパス"
この実行方法ではPythonファイルが必要なので簡単なスクリプトをPython形式で保存して実行してみましょう。
ではさっそく①の方法で実行してみました。
実行の仕方は、上部メニューから、[MAXScript->MAXScript Listener]もしくはショートカットキーの[F11]でListenerウィンドウを開きます。ピンク色の部分(マクロ レコーダ)にソースを貼り付け、Enterキーを押します。
下の白色の部分(出力)にメッセージが表示されました。
無事に実行できたでしょうか?
pythonでMAXScriptを実行してみよう!
ようやくタイトルにあった「MaxPlus」の登場です。MaxPlusとはPython内でMAXScriptを使用するためのAPIになります。
ここでお気づきの方もいるかとは思いますが、MAXScriptでPythonを実行して、さらにその中でMAXScriptを実行するのが基本的な運用方法となります。…ややこしいですね。
そしてさらにややこしいのはその使い方にも見られます。
以下のスクリプトをPython形式で保存し、新規シーンで実行してみましょう。
# -*- coding: utf-8 -*- # MaxPlusの読み込み。 import MaxPlus # 指定されたオブジェクトを作成。今回はボックス。 boxObject = MaxPlus.Factory.CreateGeomObject(MaxPlus.ClassIds.Box) # 指定されたノードを作成。 boxNode = MaxPlus.Factory.CreateNode(boxObject, 'testObject')
シーンの原点に「testObject」という名前のボックスが1つ出来たと思います。
オブジェクトとノード
ボックスを一つ作るだけのはずなのに結構長い文章を書かなければなりません。
Mayaでスクリプトを書いたことがある人であれば、なおさら感じることだと思います。
先ほどのスクリプトを見てみましょう。
処理の中で2回呼び出されている「Factory」というクラスがありますね。このクラスは何かを作るときに使用するのですが、なぜ1つのボックスを作るのに2回も実行しなければいけないのでしょうか?
まず「オブジェクト」についてみていきましょう。
新規シーンにして、上のスクリプトを少し変更したこちらを実行して下さい。
# -*- coding: utf-8 -*- import MaxPlus boxObject = MaxPlus.Factory.CreateGeomObject(MaxPlus.ClassIds.Box) # 同じ処理を三回。 for i in range(3): boxNode = MaxPlus.Factory.CreateNode(boxObject, 'testObject')
今度はボックスが3つ作られると思います。この状態はモデルを複製したときの「Instance(インスタンス)※」にあたります。
つまり、編集した情報を共有している状態となります。
※インスタンスについては以下のHelpを参照して下さい。
3dsMax Help:コピー、インスタンス、参照を作成する
試しにパラメーターをいじって確認してみて下さい。…せっかくなのでそれもプログラムでやってみましょう。
先ほど作成したノードからオブジェクトを取得しパラメーターを変更してみます。以下のスクリプトを実行して下さい。
# -*- coding: utf-8 -*- import MaxPlus # 先ほど作ったノードを取得。 boxNode = MaxPlus.INode.GetINodeByName('testObject') # ノードからオブジェクトを取得。 boxObject = boxNode.GetObject() # オブジェクト内にあるParameterBlockの各アトリビュート値を変更。 boxObject.ParameterBlock.LengthSegs.Value = 5 boxObject.ParameterBlock.WidthSegs.Value = 5 boxObject.ParameterBlock.HeightSegs.Value = 5
こちらが実行結果です。結果が判りやすいようにボックスはずらしてあります。
作成したボックス全ての分割が増えていると思います。Modifierを割り当てた場合も共有されます。
ここでなんとなく「編集情報はオブジェクトの中にある」ということがわかったと思います。
では次に「ノード」はどういったものなんでしょう?
プログラムを使って確認してみましょう。新規シーンにして実行してみて下さい。
# -*- coding: utf-8 -*- import MaxPlus boxObject = MaxPlus.Factory.CreateGeomObject(MaxPlus.ClassIds.Box) # 分割数を増やします。 boxObject.ParameterBlock.LengthSegs.Value = 5 boxObject.ParameterBlock.WidthSegs.Value = 5 boxObject.ParameterBlock.HeightSegs.Value = 5 for i in range(3): # 名前に数字を付けて差別化。 boxNode = MaxPlus.Factory.CreateNode(boxObject, 'testObject'+str(i)) # スケールをかけて段々大きくする。 boxNode.Scaling = MaxPlus.Point3(i+1, i+1, i+1) # 位置を見やすいように100刻みで増やす。 boxNode.Position = MaxPlus.Point3(i*100, 0, 0)
こちらが実行結果です。
ボックスが横に並んで表示され、今度は名前も、大きさも違うと思います。これらの変更はノードから行っています。
つまり「位置や大きさなどの表示情報はノードの中にある」ということがわかります。
再度オブジェクトについて確認すると一度しか分割数を変更していませんが全て変更されていますね。
もし全部別々に編集したい場合は2行目~6行目をループの中に入れてあげれば別々に編集できるボックスを作ることが出来ます。
遠回りしてしまいましたが、ボックス一つを作るのにあれだけ書く理由がわかっていただけたでしょうか?
MaxPlusをもっと使ってみよう!
ここまで読んでいただければボックスを好きなように並べて大きさも変えられるようになりました。
というわけで、ひたすら沢山のボックスを並べてみましょう。今回は個別に編集するのでオブジェクトはループの中で作ります。
# -*- coding: utf-8 -*- import MaxPlus for j in range(10): for i in range(10): x = i * 30 y = j * 30 boxObject = MaxPlus.Factory.CreateGeomObject(MaxPlus.ClassIds.Box) boxNode = MaxPlus.Factory.CreateNode(boxObject, 'testObject_%s_%s'%(str(i), str(j))) boxNode.Position = MaxPlus.Point3(x, y, 0) # 偶数の場合はなにもしない。 if ((i+j)%2) == 0: continue # 奇数の場合はmeshsmoothをかける。 smoothModifier = MaxPlus.Factory.CreateObjectModifier(MaxPlus.ClassIds.meshsmooth) boxNode.AddModifier(smoothModifier) # ついでにスケールもかけて位置を調整。 boxNode.Scaling = MaxPlus.Point3(1.5, 1.5, 1.5) boxNode.Position = MaxPlus.Point3(x, y, -6.25) # 分割数も増やしてみる。 boxObject.ParameterBlock.LengthSegs.Value = 5 boxObject.ParameterBlock.WidthSegs.Value = 5 boxObject.ParameterBlock.HeightSegs.Value = 5
全部で100個のボックスが出来たと思います。
ただ並べるだけではつまらないので1つおきにモディファイアの「meshsmooth」を使い、位置や大きさを調整しました。
こちらが実行結果です。
マテリアルを設定していないのでデフォルトの色がまばらに付いてしまっていますね。
せっかくなのでこちらも設定してみましょう。
# -*- coding: utf-8 -*- import MaxPlus for j in range(10): for i in range(10): x = i * 30 y = j * 30 boxObject = MaxPlus.Factory.CreateGeomObject(MaxPlus.ClassIds.Box) boxNode = MaxPlus.Factory.CreateNode(boxObject, 'testObject_%s_%s'%(str(i), str(j))) boxNode.Position = MaxPlus.Point3(x, y, 0) # マテリアル作成 r = (float(j + 1) / 10.0) g = (float(i + j + 2) / 20.0) b = (float(i + 1) / 10.0) defaultMaterial = MaxPlus.Factory.CreateDefaultStdMat() defaultMaterial.Diffuse = MaxPlus.Color(r, g, b) # 作成したマテリアルを設定 boxNode.Material = defaultMaterial if ((i+j)%2) == 0: continue smoothModifier = MaxPlus.Factory.CreateObjectModifier(MaxPlus.ClassIds.meshsmooth) boxNode.AddModifier(smoothModifier) boxNode.Scaling = MaxPlus.Point3(1.5, 1.5, 1.5) boxNode.Position = MaxPlus.Point3(x, y, -6.25) boxObject.ParameterBlock.LengthSegs.Value = 5 boxObject.ParameterBlock.WidthSegs.Value = 5 boxObject.ParameterBlock.HeightSegs.Value = 5
こちらが実行結果です。
今度はついでにグラデーションを付けてみました。
RGBの順番を入れ替えたり数値の出し方を変えたりして遊んでみて下さい。
あとがき
ここまでお付き合い頂き、ありがとうございました。
MAXScriptもMaxPlusも始めはわかりづらい所が多いとは思いますが、使っていくうちに愛着がわいてきたり、こなかったり。
今回は初めて取り扱うものであったため基礎的な部分だけになってしまいましたが、
これをきっかけに「MAXでPythonを使ってみようかな?」と思っていただければ幸いです。
次回はもう少し実用的な部分に触れてみようかと思います。
本記事内で公開している全ての手法・コードの有用性、安全性について、当方は一切の保証を与えるものではありません。
これらのコードを使用したことによって引き起こる直接的、間接的な損害に対し、当方は一切責任を負うものではありません。
自己責任でご使用ください。
コメント
コメントフォーム