MaxScriptTip: マテリアルのサムネイルBitmapを取得する

3月 26, 2016 0
マテリアルのサムネイルBitmap取得について。
標準のMaxScriptではこのような機能は無いようなので、DotNet用のMaxAPIを叩いて作成します。
fn createMtlThumb mtl size:#large =
(
    -- MaxAPIインターフェース作成
    local iGlobal = (dotnetClass "Autodesk.Max.GlobalInterface").Instance
    if iGlobal == undefined do
        return undefined
    
    -- マテリアルを.NET APIマテリアルに変換
    local mtlHandle = dotNetObject "System.UIntPtr" (GetHandleByAnim mtl)
    local iMtl = iGlobal.Animatable.GetAnimByHandle mtlHandle
    if iMtl == undefined do
        return undefined

    -- サムネイルを作成
    local ps = dotnetclass "Autodesk.Max.PostageStampSize"
    local pSize = case size of (#large: ps.Large; #small: ps.Small; #tiny: ps.Tiny)
    local pStamp = iMtl.CreatePStamp pSize true
    
    -- サムネイルをBitmapにコピー
    local bytes = pStamp.Image
    local width = pStamp.Width
    local dstBmp = bitmap width width
    local step = width * 3
    
    for y = 1 to bytes.count by step do
    (
        row = (for x = y to (y + step - 1) by 3 collect [bytes[x + 2], bytes[x + 1], bytes[x]])
        setpixels dstBmp [0, width -= 1] row
    )
    
    -- 開放
    pStamp.Dispose()
    iMtl.Dispose()
    
    return dstBmp
)

thumbnail = createMtlThumb $.material size:#large
display thumbnail
第1引数にはMaterialオブジェクトを、第2引数には#large, #small, #tinyを指定できます。
それぞれのサイズは以下のようになります。
#large: 88px
#small: 32px
#tiny: 24px

戻り値はbitmapオブジェクトです。

上記スクリプトを実行すると選択しているオブジェクトのマテリアルがレンダリングされて、以下のようにフレームバッファに表示されます。

勿論、フレームバッファへの表示はテスト用なので表示する必要はありません。

CreatePStampの第二引数をfalseにするとレンダリングせずに取得する(?)ようですが、キャッシュが無かった時にどうなるかは試してません。
現状ではレンダリングにかかる時間も微々たるものですので、普通にレンダリングする仕様でいいかと思います。


最後に

今回の記事作成にあたり、こちらのスレッドを参考にさせて頂きました。
http://forums.cgsociety.org/archive/index.php?t-1239911.html
ありがとう海外のエロ偉い人。

MaxScriptTip: Maxオブジェクトを一意に特定する

3月 26, 2016 0
MaxはMaya等と違って、オブジェクト名がシーン内で一意であることを保証していません。

当然全くの同名(同パス)オブジェクトが複数シーン内に存在する事になり、オブジェクト名では特定のオブジェクトを必ずしもハンドルする事が出来ません。
MaxScript内で常にオブジェクトのインスタンスを保持出来れば良いのですが、それが出来ないケースもあります。
例えば、.NETと連携させる時やクリップボードに転送する時等…。

そこで今回は、MaxScript内で、インスタンス保持以外の方法で、オブジェクトをハンドルする方法を2つ紹介します。


inode.handleを使う方法

ノードオブジェクト(シーン内に座標系を持って存在しているオブジェクト)はinodeインタフェースのhandleプロパティが使えます。
local handle = $box001.inode.handle
これにより、シーン内のノードを一意に特定出来るハンドルを取得出来ます。
ハンドルからノードを取得するには以下のようにします。
local node = maxOps.getNodeByHandle handle
リファレンスによると、$box001.handleとするよりは$box001.inode.handle等とする方が良いらしいです。
inodeを省略した場合、元々「handle」プロパティを持っているオブジェクト(Teapot等)はうまくハンドルを取得出来ない可能性があるからだそうです。


AnimHandleを使う方法

ノード以外のオブジェクト(マテリアル、モディファイヤ、コントローラ等)をハンドルするにはAnimHandleという仕組みが使えます。
AnimHandleは、文字通りAnimatableオブジェクトに設定出来るハンドルシステムで、シーン内のほぼ全てのオブジェクトのハンドルを取得する事が出来ます。
local mtlHandle = GetHandleByAnim $box001.material
ハンドルからマテリアルを取得するには以下のようにします。
local mtl = GetAnimByHandle mtlHandle
この方法は、うまく使うと.NET APIにオブジェクトを転送する時等にも使えます。
(.NET API内でもGetAnimByHandleは使える為)

ただし、こちらのハンドルはMaxのセッションが終了するとリセットされてしまうみたいなので、外部ファイルに保存しておいて使うような使い方には向きませんね。

どちらを使うかはケースバイケースだと思いますが、知っておくと便利かもしれません。

MaxScriptTip: 簡単なMZPインストーラ作成

3月 06, 2016 0
Maxに簡単にスクリプトをインストール出来る、MZPパッケージの作成方法について。

MZPは一度作ってしまうと何度も使い回せて便利なのですが、最初は何となく取っ付きづらい印象があると思います。
そこで、今回は必要最低限でのMZPパッケージの作り方を説明します。

今回作成するMZPパッケージは以下のファイルで構成されています。

  • マクロファイル (sample.mcr)
  • 暗号化済みスクリプトファイル (sample.mse)
  • mzp.run
  • インストーラスクリプト (install.ms)

マクロファイルとスクリプトファイルをそれぞれ分離したのは、マクロファイルを暗号化出来ないというMaxの仕様の為です。(実際には作れますが、動作しません。)
スクリプトそのものはsample.msに書き、暗号化後、それをマクロから呼び出すというフローを想定しています。

最終的に、上記4つのファイルをZIP形式で圧縮することで、パッケージを作成します。

mzp.run

name "SampleTool"
version 1.00

copy "sample.mcr" to "$userMacros/SampleTool"
copy "sample.mse" to "$userScripts/SampleTool"

run install.ms
drop install.ms

clear temp
mzp.runはMZPパッケージがMaxにドロップされた時、最初に実行されるコマンドファイルです。
ただしコマンドとは言っても、MaxScriptを直接使用するわけではなく、mzp.run専用コマンドを使用します。
各コマンドについて簡単に説明します。

name
ツール名を指定します。
version
ツールバージョンを指定します。必ずしも浮動小数である必要はありません。
copy
パッケージ内のファイルを指定したフォルダにコピー(配置)します。
指定出来るフォルダ名はリファレンスを参照してください。
記号パス名
注意点として、Program Files下のMaxインストールフォルダへファイルをコピーする時、Maxに管理者権限(もしくはフォルダアクセス権)が無いとコピーに失敗します。
その場合、同名の$user~フォルダにインストールする等して回避する必要があります。
また、コピー先にフォルダが無かった場合、自動的に作成されます。
run
.mzpがドラッグ&ドロップ以外の方法で実行された時、指定したスクリプトを実行します。
このコマンドはrun.mzp内で複数回実行する事が出来ます。
drop
.mzpがMaxにドロップされた時実行されます。ただし、.mzpがドロップ以外の方法で実行された時は実行されません。
また、このコマンドはmzp.runにつき1回しか実行出来ません。
clear
.mzpパッケージが一時的に展開されたtempフォルダを削除します。

run, dropを別々に指定しているのは、.mzpの実行のされ方でどちらが呼び出されるかが代わるからです。runは複数回実行出来ますが、dropは出来ないので、基本はinstall.msを呼び出すだけにしておいて、細かい処理はinstall.ms内でやるようにした方がいいかもしれません。

その他いろいろコマンドはありますが、全て説明しているとキリが無いので、詳細はリファレンスを参照してください。
Zip ファイル スクリプト パッケージ

install.ms

(
    local msgTitle = "SampleTool Installer"
    local mcrPath = @"$userMacros/SampleTool/sample.mcr"
    
    if doesFileExist mcrPath then
    (
        fileIn mcrPath
        local msg = "Installation Completed.\n" + \
                    "---------------------------\n" + \
                    "Category: SampleCategory\n" + \
                    "MacroName: SampleTool"
        messageBox msg title:msgTitle beep:false
    )
    else
        messageBox "MacroScript not found." title:msgTitle beep:true
)
mzp.runから呼び出されるインストールスクリプトです。
絶対に必要というわけではないですが、今回はインストール結果の表示の為に使用しています。
インストール先のカテゴリ等表示してあげると親切かもしれません。

インストール後にfileInでマクロをロードしています。
こうすることでMaxの再起動なしに、すぐにマクロを使えるようになります。

sample.mcr

macroScript SampleTool
category:"SampleCategory"
(
    on execute do
    (
        try
            fileIn @"$userScripts/SampleTool/sample.mse"
        catch
            messageBox "Script not found.\nsample.mse" title:"SampleTool"
    )
)
暗号化済みスクリプトを呼び出す為のマクロファイルです。
スクリプトファイルが存在すればfileInで実行し、無ければメッセージボックスを表示します。

sample.mse

暗号化したスクリプトファイルです。
暗号化したスクリプトは単体でツールバー等に登録できないという致命的な問題が有る為、ほぼマクロスクリプトとペアでリリースするのが基本になります。
マクロスクリプトが必要ないケースととしては、スクリプトプラグイン等、startupScriptsに配置してその後呼び出さないスクリプト等があります。


パッケージ作成

最後に作成した4つのファイルを全て選択し、ZIPファイルとして圧縮します。
ここで重要なのはファイルを入れているフォルダではなく、ファイルそのものを選択して圧縮する必要があるという事です。
最後にZIPファイルの拡張子を.mzpに変更して完成です。
Maxにドロップして、無事インストール完了ダイアログが表示されるか、マクロは実行出来るかを確かめてみてください。

MaxScript配布: 法線合成スクリプトTR_BlendNormals

3月 04, 2016 0
法線合成スクリプト、TR_BlendNormalsを公開します。

このスクリプトは3D空間上で法線をサンプリングし、オブジェクトから他のオブジェクトへ法線を転送or合成する事が出来ます。

 割りとよくあるタイプのスクリプトですが、煩わしい設定なしに手軽に利用出来るのが利点です。

また、転送元、転送先ともにポリゴンやメッシュである必要は無く、転送先に「法線編集」モディファイヤさえ適用出来れば動作します。

その他細かい仕様は以下のようになります。

  • 転送先オブジェクトに、既に法線編集モディファイヤが有るか検索します。
    有った場合、そのモディファイヤを転送ターゲットにします。
    (ターゲットにしたくない場合、モディファイヤを非表示にしておいてください。)
    無かった場合、自動的に法線編集モディファイヤを追加します。
  • 転送元オブジェクトは内部的に、一旦Meshへと変換されます。
    よって、Meshに変換可能なオブジェクトであれば、全て転送元に使用できます。
  • 法線のサンプリングは、3Dグローバル空間上で行われます。
    よって、2つのモデルが同一のメッシュ構造をしている必要はありません。
  • 合成率は%で指定する事ができます。
    0%は何もせず、100%は合成せずそのまま転送します。
    1~99%の間では2つのオブジェクト法線が合成されます。

スクリーンショット







ティーポットの形状を維持したまま、影だけを球体からコピーする事が出来ます。
また、板ポリを重ねて作った木の葉に、ボリューム感を持たせるといった使い方も出来ます。

インストール

ダウンロードした.mzpファイルを3dsMaxのビューポート上にドラッグ&ドロップしてください。
Category: TR ToolsにマクロTR_BlendNormalsが追加されます。
3dsMax 2014及び2015日本語版で動作テストしています。

ダウンロード

TR_BlendNormals Ver1.00