Skip to content

Instantly share code, notes, and snippets.

@cecilemuller
Created January 3, 2019 14:35
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cecilemuller/057d5ccdcbe8964d9babc6b339986bf5 to your computer and use it in GitHub Desktop.
Save cecilemuller/057d5ccdcbe8964d9babc6b339986bf5 to your computer and use it in GitHub Desktop.
Maxscript: get the Material Editor thumbnail for an arbitrary material
-- Reads the 88x88 thumbnail from Material Editor for an arbitrary material.
-- Note that it renders faster when the material editor is closed,
-- so you could call `MatEditor.Close()` first.
--
-- Parameters:
-- mat: a material instance (StandardMaterial, Universal_Material, etc..)
--
-- Returns:
-- a Bitmap or `undefined`
--
fn getMaterialThumbnail mat = (
local thumb = undefined
local iGlobal = (dotnetClass "Autodesk.Max.GlobalInterface").Instance
if iGlobal != undefined then (
local IntPtr = dotnetClass "System.IntPtr"
local pStampSize = (dotnetclass "Autodesk.Max.PostageStampSize").Large
local backupMat = meditMaterials[1]
meditMaterials[1] = mat
local matRef = iGlobal.CoreInterface.GetMtlSlot 0
local pStamp = matRef.CreatePStamp pStampSize true
local bytes = pStamp.Image
local size = pStamp.Width
thumb = bitmap size size gamma:0.5
local step = size * 3
for y = 1 to bytes.count by step do (
local row = for x = y to (y + step - 1) by 3 collect [bytes[x + 2], bytes[x + 1], bytes[x]]
setpixels thumb [0, size -= 1] row
)
pStamp.Dispose()
matRef.Dispose()
meditMaterials[1] = backupMat
)
return thumb
)
@RafalZera
Copy link

That's actually great, works flawlessly. Seems that by using dotnet you can do anything in max. Maybe it's time to grasp the basics.

@theacb
Copy link

theacb commented Nov 28, 2023

I converted this to python, if that is useful to anyone.

import pymxs

rt = pymxs.runtime

def get_material_thumbnail(mat):
    """
    Reads the 88x88 thumbnail from Material Editor for an arbitrary material.
    Note that it renders faster when the material editor is closed,
    so you could call `rt.MatEditor.Close()` first.

    Originally written (in Maxscript) by Cecile Muller
    https://github.com/cecilemuller

    :param mat: a material instance (StandardMaterial, Universal_Material, etc..)
    :return: a Bitmap or None
    """
    thumb = None
    iGlobal = (rt.dotnetClass("Autodesk.Max.GlobalInterface")).Instance

    if iGlobal is not None:
        pStampSize = (rt.dotnetclass("Autodesk.Max.PostageStampSize")).Large

        backupMat = rt.meditMaterials[0]
        rt.meditMaterials[0] = mat
        matRef = iGlobal.CoreInterface.GetMtlSlot(0)

        pStamp = matRef.CreatePStamp(pStampSize, True)
        i_dat = pStamp.Image
        size = pStamp.Width
        thumb = rt.bitmap(size, size, gamma=0.5)

        step = size * 3

        row_ind = size - 1
        for y in range(0, i_dat.count, step):
            row = []
            for x in range(y, y + step - 1, 3):
                row.append(rt.color(i_dat[x + 2], i_dat[x + 1], i_dat[x]))
            rt.setpixels(thumb, rt.point2(0, row_ind), row)
            row_ind -= 1

        pStamp.Dispose()
        matRef.Dispose()
        rt.meditMaterials[0] = backupMat

    return thumb

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment