[Closed] Grabbing The Material Preview
it’s only because the image is small. in general the difference is huge. after i knew about locking bits my “bitmap” life changed
Working with a “locked” bitmap is generally much faster than the common pixel operations, but that is not always the case. Many Bitmap and Graphics operations are just as fast as implementing them with LockBits().
And of course, the larger the image the bigger the difference.
A last function that will create an array of materials either from the Editor or the Scene.
(
/*
MAX 2013+
MakeMaterialsThumbnails()
Returns an array with materials names, classes and thumbnails.
The materials can be from the Material Editor or from the Scene.
#( #(name, class, bitmap) )
#( #("01 - Default", "Standard", BitMap:) )
MakeMaterialsThumbnails type:<name> size:<int>
type: #scene, #editor
size: 0=24x24, 1=32x32, 2=88x88
*/
fn MakeMaterialsThumbnails type:#scene size:2 =
(
iGlobal = (dotnetClass "Autodesk.Max.GlobalInterface").Instance
IntPtr = dotnetClass "System.IntPtr"
case type of
(
#scene:
(
sceneMtls = iGlobal.CoreInterface.SceneMtls
materials = for j = 0 to sceneMtl.NumSubs-1 collect sceneMtls.Item[dotnetObject IntPtr j]
)
#editor: materials = for j = 0 to 23 collect iGlobal.CoreInterface.GetMtlSlot j
default: return messagebox "Invalid Type"
)
case size of
(
0: pStampSize = (dotnetclass "Autodesk.Max.PostageStampSize").Tiny -- 24x24
1: pStampSize = (dotnetclass "Autodesk.Max.PostageStampSize").Small -- 32x32
2: pStampSize = (dotnetclass "Autodesk.Max.PostageStampSize").Large -- 88x88
default: return messagebox "Invalid Size"
)
result = #()
if iGlobal != undefined do
(
for mtl in materials do
(
pStamp = mtl.CreatePStamp pStampSize true
bytes = pStamp.Image
size = pStamp.Width
bm = bitmap size size
step = size*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 bm [0, size-=1] row
)
append result #(mtl.Name, mtl.ClassName, bm)
pStamp.Dispose()
mtl.Dispose()
)
)
return result
)
mtls = MakeMaterialsThumbnails type:#editor size:2
)
Thank you Jorge, Haarvard, Denis and Klunk for your input, it is great stuff. :bowdown:
This solution is much. much better.
Thank you Jorge, Haarvard, Denis, Klunk and LoneRobot!
Jorge, is it possible to make your last script for 2012 as well?
The .Net Wrapper was released with Max 2013. It was also available for Max 2012 with a Subscription Pack but I don’t know if these features were implemented in that release.
@PolyTools3D
Is it possible to instead access and render a material thumbnail from loadTempMaterialLibrary instead of iGlobal.CoreInterface.SceneMtls or iGlobal.CoreInterface.GetMtlSlot
GetMtlSlot() is already implemented in the last code.
I haven’t tried loadTempMaterialLibrary(), but as long as you can get a pointer to a material from it, I see no issue in creating a preview of the material.
BTW, there might be other ways to do it in later Max versions with updated .Net API.
Here is a simplified code to create just 1 slot preview:
(
fn MakeMaterialThumbnail slot:0 size:2 =
(
iGlobal = (dotnetClass "Autodesk.Max.GlobalInterface").Instance
IntPtr = dotnetClass "System.IntPtr"
case size of
(
0: pStampSize = (dotnetclass "Autodesk.Max.PostageStampSize").Tiny -- 24x24
1: pStampSize = (dotnetclass "Autodesk.Max.PostageStampSize").Small -- 32x32
2: pStampSize = (dotnetclass "Autodesk.Max.PostageStampSize").Large -- 88x88
default: return messagebox "Invalid Size"
)
mtl = iGlobal.CoreInterface.GetMtlSlot slot
pStamp = mtl.CreatePStamp pStampSize true
bytes = pStamp.Image
size = pStamp.Width
bm = bitmap size size
step = size*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 bm [0, size-=1] row
)
pStamp.Dispose()
mtl.Dispose()
return bm
)
mtl = MakeMaterialThumbnail slot:3 size:2
display mtl
)