MAXScriptを覚えよう!~入門編~
2014/2/17
こんにちは。FILCOのキーボードを購入してから、カチャカチャしてるのが楽しくて仕方ない山城です。
今回はDF_Talkでは初めて?と思われるMAXScriptについて書きたいなと思います。
他のSoftでは大半がPythonをサポートしている中、3dsMaxでは頑なにPythonの採用をしていませんでした…なぜ!?
そんなMaxも2014でついにPythonが扱えるようになったのですが、現状2014をメインに使っているかというとそうではない所が大半だと思います。
弊社でも2012と2013がメインで2014は殆ど使用していない為、スクリプトを書こう思っても、やはりMAXScriptという独自の言語を新たに学ばないといけなくなってしまいます。
しかしMAXScriptは他の言語と比べるとかなり癖が強い言語…正直私も最初に触ったときは「何じゃこりゃ!」と思いました。
今では慣れてきたせいかあまり思わなくなって来てしまったのですが(笑)
そんなMAXScriptを少しでも分かって貰えるように、今回はMAXScriptの入門編として基本的な所から、VRayへのアクセス方法などを書いていきたいなと思います。
まず初めに
MAXScriptが他の言語と違う大きな点があります。
ご存知の方も居るかも知れませんが、MAXScript内では小文字と大文字の区別はされません。
ModelもmodelもMODELも全部同じ変数になってしまうのです…なんでやねーん
最初はこれに気がつかないで変なエラー出しまくっていた事も…
逆に他の言語では基本的に区別されますのでMAXScriptに慣れてしまうと注意が必要かもしれません。
そして個人的にですが、やりにくい点があったのでご紹介。
関数の書き方や呼び出し方が少し変わっていて基本的には()は使いません。
下の関数ではファイルのパスを渡して、書かれているテキスト内容を一行読み込んでreturnする関数です。
function GetFirstLine FilePath= ( f = openFile FilePath rLine = readLine f return rLine ) firstline = GetFirstLine "F:\\yamashiro\\Test.txt"
Pythonだと[def GetFirstLine(FilePath):]という書き方になると思うのですが、この言語では「関数名(スペース)引数」というようにスペース区切りになります。
また引数が複数あった場合も(,コンマ)区切りではなくスペース区切りになるのですが、引数が存在しない場合はGetFirstLine()のような記述になる為()を付けないとエラーが出ます。ちょっとややこしいですよね
またフォルダ階層の区切りは「\\」もしくは「/」になります。
Pythonや他の言語に慣れてしまうとスペースで区切られている辺が読みにくく…文字によってはスペースが分かりにくいものもあるので読み間違いをすることも良くあります(汗)
他にも独特な書き方をする所は多いのですが、大きな違いとしてはこの辺かなと思います。
■ログの表示方法
Maxでは操作したログを表示させることが出来ます。
全てが出るわけではないのですが…ログが見たいという場合は、メニューバーにある「MaxScript」という欄からMaxScriptListenerを開いてください。
開いたらListenerのメニューにあるMacroRecorderのEnableをオンにするとListenerの下の部分にログが表示されます!
※Enableをオンにしているのに表示されなかった場合は、プラグインでKrakatoaが入っていると不具合でログが出ないことがありますので、一度外してから再起動を行なってみて下さい。
それではMAXScriptについて基本的な所から説明をしていきたいと思います。
オブジェクトの作成&取得方法
オブジェクトの作成方法とシーン内に存在しているオブジェクトの取得方法です。
-- これでコメントになります。 -- Boxの作成 mybox = box() mybox.name = "Box001" -- Sphereの作成 mySp = Sphere() mySp.name = "Sphere001" -- 選択されているオブジェクトの取得 $ -- 名前指定でオブジェクト取得 $Box001 -- Boxと名前が付くオブジェクト取得 $Box* -- Boxと名前が付くオブジェクト取得をfor文でやってみる BoxList = #() -- Object全てを取得 SceneObject = objects for i=1 to SceneObject.count do ( Target = findString SceneObject[i].Name "Box" if Target != undefined then append BoxList SceneObject[i] )
「$」だけだと選択中のオブジェクトの取得になり「$モデル名」でも取得でき、これはGroupなども同じように取得することが出来ます。
他にもselectionでも現在選択されているオブジェクトの取得が出来、またobjectsと記述するとシーン内の全てのオブジェクトを取得することが出来ます。
オブジェクトの取得が出来ましたので、今度は個々が持っているプロパティの取得をしてみたいと思います。
オブジェクトのプロパティを見る
-- Box001が持っているPropertiyを返す showProperties $Box001 -- showPropertiesと同じようにPropertiyを見ることが出来ます。 show $Box001 -- showPropertiesの内容をリストで返す getPropNames $Box001
こんな感じでオブジェクトのプロパティ全てを返してくれます。
Boxが持っているものだとこんな感じで返って来ます。
.height : float
.length : float
.lengthsegs : integer
.width : float
.widthsegs : integer
.mapcoords : boolean
.heightsegs : integer
.realWorldMapSize : boolean
プロパティ名とその型が上記のように返って来ます。
スクリプトの実行結果はMaxScriptListenerに記載されますのでそちらをご確認下さい。
プロパティへのアクセス&モディファイヤの登録
モディファイヤをオブジェクトに登録し、プロパティにアクセスする方法です。
-- Scene内のオブジェクトの取得 for obj in SceneObject do ( -- オブジェクトのクラスを取得 objClass = classof obj -- classがBoxだったらBendモディファイヤを追加 if objClass == Box then ( newbend = Bend() -- BendのAngleに値を代入 newbend.BendAngle = 25.0 addModifier obj newbend ) )
「オブジェクト名.プロパティ」で取得、設定が出来ます。
上記ではモディファイヤのプロパティに数値を入れていますが、Boxのheightに30を入れようとすると
「Box.height = 30.0」という書き方になります。
またMAXScriptでfor文とif文を書くとPythonで言う「:」はdoとthenになりますのでご注意下さい。
PythonとMAXScriptを行き来しているとこれを忘れて数分悩む事が良くあります…
こんな感じで基本的なことばかり書いてきましたが(何かの役にたってくれると良いです…)
ここからはMaxのプラグインで入れている方も多い、VRayへのMaxScriptからのアクセス方法を簡単に紹介したいと思います。
今回はレンダリング設定、マテリアルの作成などを書いて見ます。
VRayレンダラーの設定/取得
レンダラーの変更と現在のレンダラーの取得方法になります。
-- レンダラー設定。今回はVRayのクラスを渡します。 renderers.current = V_Ray_Adv_2_10_01() -- レンダラーの取得 vr=renderers.current -- レンダラーのクラスが見たい場合は下記を実行 RendererClass.classes
レンダリングの設定もマテリアルもカレントレンダラーがVRayに設定されていないと、スクリプトも同様で使用することが出来ません。
なのでVrayを使用したい場合はまず初めにカレントレンダラーをVRayに変更する必要があります。
環境によってバージョンも違うと思いますので、クラス名が分からないという場合はRendererClass.classesを使ってレンダークラスのリストを取得してください。
VRayレンダリング設定
カレントレンダラー(VRay)が取得出来ましたので、パラメーターにアクセスをして設定を変更していきます。
VRayに限らずレンダリング設定のパラメーターは数がもの凄く多いので使いそうな場所だけを抜粋!
-- 解像度の設定(これは共通設定になります) renderHeight = 640 renderWidth = 480 rendSaveFile = true rendOutputFilename = "F:\\yamashiro\\rendOutput" -- VRayを取得 vr=renderers.current -- プロパティを見たい場合は[show vr]で全プロパティが見れます。 -- VRay Frame Bufferをオンにする vr.output_on = true -- Clobal switchesへアクセス vr.options_hiddenLights = false vr.options_overrideMtl_on = false -- Image samplerへアクセス vr.filter_on = true vr.filter_kernel = Area() vr.filter_size = 1.5 --ColorMappingへアクセス -- colorMapping_typeはリストになっている為int値を渡します。 vr.colorMapping_type = 0 vr.colorMapping_darkMult = 1.0 vr.colorMapping_brightMult = 1.0 vr.colorMapping_gamma = 1.1 vr.colorMapping_subpixel = true -- Indirect illumination(GI)へアクセス vr.gi_on = true vr.gi_refractCaustics = true vr.gi_reflectCaustics = false -- gi_secondary_typeはリストになっている為int値を渡します。 vr.gi_secondary_type = 2 vr.gi_secondary_multiplier = 1.0 vr.gi_saturation = 1.0 vr.gi_ao_amount = 1.0
こんな感じでレンダリング時の設定を行なうことが出来ます。
「レンダリングの基本設定を固定したい」などの場合は、上記のようなスクリプトで設定した物をMaxのStartupフォルダにMAXScript(.msファイル)を入れることで起動時に設定することも出来ます。
しかしどこに入れればいいのか分からない場合、Max内には記号パスと呼ばれる環境変数が用意されています。
-- 3dsMaxのインストールディレクトリ pathConfig.resolvePathSymbols "$max" -- 起動時にロードのスタートアップスクリプトのディレクトリ pathConfig.resolvePathSymbols "$startupScripts" -- 自動バックアップのディレクトリ pathConfig.resolvePathSymbols $autoback
上記のやり方で様々なディレクトリの取得が出来ます。これはユーザー側でカスタマイズすることも出来るので良くアクセスするパスを追加しておくと便利かも知れません。
VRayマテリアルの作成
続いてVRayマテリアルを作成してオブジェクトにコネクションを行なうスクリプトを書いてみたいと思います。
function CreateVRayMtl = ( -- テクスチャーを取得 bMap = openBitMap "F:\\yamashiro\\texture\\Box.jpg" -- VRayMtlの設定 vMtl = VRayMtl() vMtl.name = "BoxMtl" vMtl.reflection_subdivs = 8 vMtl.reflection_glossiness = 1.0 -- VRayMtlのdiffuseにbitmaptextureを接続 vMtl.texmap_diffuse = bitmaptexture() -- 取得したテクスチャーを設定する vMtl.texmap_diffuse.bitmap = bMap return vMtl ) -- レンダラーをVRayに設定 renderers.current = V_Ray_Adv_2_30_01() -- Boxの作成 mybox = box() mybox.length = 100 mybox.width = 100 mybox.height = 100 -- Omnilightの作成(作成時に設定することも出来ます。) mylight = omnilight pos:[0,-100,150] vrMtl = CreateVRayMtl() -- Boxに作成したマテリアルをコネクションする mybox.material = vrMtl
上記のスクリプトではVRayMtlを使用し各種設定をした物をオブジェクトに繋げていますが、先に「mybox.material = VRayMtl()」というように代入してからマテリアルの設定をすることも出来ます。
例えばVRay以外のマテリアルでスタンダードマテリアルとブレンドマテリアルをオブジェクトにコネクションしたい場合は
-- ブレンドマテリアルをコネクション mybox.material = Blend() -- スタンダードマテリアルをコネクション mybox.material = Standard() -- ディフューズカラーを設定 mybox.material.diffuse = color 255 0 255
と書くことで繋げることも出来ます。
クラス名は基本的にマテリアルエディターに表示されている名前と同じなので「マテリアル名()」という書き方をすれば大丈夫ですが、たまに違う物もありますのでご注意下さい。
使い所があるのか微妙な物ばかり紹介してきましたが、少しは「MAXScriptってこんな感じなのね!」と分かって頂けると良いです。
次回はDotNetを使用したMAXScriptのツールやUI周りのお話でも出来ればなーと思います!
最後までお付き合い頂きありがとう御座いました。
※免責事項※
本記事内で公開している全ての手法・コードの有用性、安全性について、当方は一切の保証を与えるものではありません。
これらのコードを使用したことによって引き起こる直接的、間接的な損害に対し、当方は一切責任を負うものではありません。
自己責任でご使用ください
[…] https://dftalk.jp/cp-bin/wordpress/?p=11583 […]
Posted at 2014.08.4 12:02 by デジタル・フロンティア-Digital Frontier | DF TALK | MAXScriptで効率UP!! ~Fume&ThinkingParticles編~