今回はマテリアルのサムネイル取得について。
残念ながら、標準の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
最後に
今回の記事作成にあたり、こちらのスレッドを参考にさせて頂きました。
Grabbing The Material Preview
ありがとう海外の偉い人。