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

投稿者: | 2016/03/26

今回はマテリアルのサムネイル取得について。
残念ながら標準の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
)

引数mtlにはMaterialオブジェクトを、オプション引数sizeには3種類のサイズ名(#large, #small, #tiny)を指定できます。
それぞれのサイズは以下のようになります。

  • #large: 88px
  • #small: 32px
  • #tiny: 24px

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

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

関数の使用

上記関数を使用して、実際にサムネイルを取得すると以下のようになります。

thumbnail = createMtlThumb $.material size:#large
display thumbnail

2行目のdisplay関数は、取得したBitmapをフレームバッファに表示する関数です。

最後に

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

コメントを残す

メールアドレスが公開されることはありません。