Notifications
Clear all

[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

Haha, did not notice since all my materials were gray anyway

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?

1 Reply
(@polytools3d)
Joined: 11 months ago

Posts: 0

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
	
 )
Page 4 / 4