Notifications
Clear all

[Closed] Grabbing The Material Preview

my thought exactly …thats why smart people invent smart proof…

1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

could you post any sample of your smart proof?

pot.transform.controller = prs()

look at your own code…
http://forums.cgsociety.org/showpost.php?p=7889075&postcount=6

it’s only one simple assignment. but i can give you at least four different cases where it can’t work. does it need “foolproof”.
can anyone show ‘smart proof’ for this line?

	t_bmp = try (openbitmap arrImg[i]) catch()
	bmp_w = t_bmp.width
	bmp_h = t_bmp.height

it’s another sample of your code… which shows how a “proofing” converts to mistake.

I tried to follow Klvnk’s lead and Im almost there. The PStamp object has an Image property which is a byte array with size of 3 * Height * Width of the image, all good in the hood i thought, but I cant convert the array into a picture. I looked at the array in visual studio and it looks fine to me, don’t know what’s wrong.


        fn MtlPreview mtlIndex size =
	(
		glob = (dotnetClass "Autodesk.Max.GlobalInterface").Instance
		if glob != undefined then
		(
			mtl = glob.COREInterface14.GetMtlSlot mtlIndex
			if mtl != undefined then
			(
				pStamp = mtl.CreatePStamp size true
				bytes = dotnet.ValueToDotnetObject pStamp.Image (dotnetClass "system.byte[]")
				imgConverter = dotnetObject "System.Drawing.ImageConverter"
				img = imgConverter.ConvertFrom bytes
				
				/*
				ms = dotNetObject "System.IO.MemoryStream" bytes
				bm = dotNetObject "System.Drawing.Bitmap" ms 
				ms.dispose()
				*/

			)
		)
	)
	
	MtlPreview 0 (dotnetclass "Autodesk.Max.PostageStampSize").LargeSize

http://stackoverflow.com/questions/6782489/create-bitmap-from-a-byte-array-of-pixel-data

look this solution… it’s probably how i would do.

as i know there is no built-in .net solution for creating an image from raw pixel data (array of bytes)

You’re right, denisT, thanks!

This works:

(
	fn MtlPreview mtlIndex size =
	(
		glob = (dotnetClass "Autodesk.Max.GlobalInterface").Instance
		if glob != undefined then
		(
                        bm = undefined
			mtl = glob.COREInterface14.GetMtlSlot mtlIndex
			if mtl != undefined then
			(
				pStamp = mtl.CreatePStamp size true
				bytes = dotnet.ValueToDotnetObject pStamp.Image (dotnetClass "system.byte[]")
				bm = dotnetObject "System.Drawing.Bitmap" pStamp.Width pStamp.Height
				
				bmData = bm.LockBits \ 
					(dotnetObject "System.Drawing.Rectangle" 0 0 pStamp.Width pStamp.Height) \
					(dotnetClass "System.Drawing.Imaging.ImageLockMode").WriteOnly \
					(dotnetClass "System.Drawing.Imaging.PixelFormat").Format24bppRgb
				
				ptr = dotnetObject "System.IntPtr" bmData.Scan0
				
				(dotnetClass "System.Runtime.Interopservices.Marshal").Copy bytes 0 ptr bytes.Length
				bm.UnlockBits(bmData)

                                pStamp.Dispose()

			)
                    --mtl.Dispose() ?
                   
                    bm
		)
	)
	
	MtlPreview 0 (dotnetclass "Autodesk.Max.PostageStampSize").Large
)

Here is the enum for the size argument:

public enum PostageStampSize
    {
        Small = 0,
        Large = 1,
        Tiny = 2,
        TinySize = 24,
        SmallSize = 32,
        LargeSize = 88,
    }

if you LockBits the copying will be much faster.

I’m not following you here. I am using the lockbits-method. It is where I defined the format of the image as well.

1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

ah… sorry. i missed this part in your code. my bad

Thank you håvard!
Images are flipped in Y axis. You may want to add:

bm.RotateFlip (dotNetClass "System.Drawing.RotateFlipType").RotateNoneFlipY

Here is a similar function but returns a MaxScript bitmap. The material index is 0 based.
The performance is almost the same as using LockBits() with a .Net bitmap.

(
   	fn GetMaterialThumbnail mMatIdx mSize =
   	(
   		iGlobal = (dotnetClass "Autodesk.Max.GlobalInterface").Instance
   		if iGlobal != undefined do
   		(
   			iMaterial = iGlobal.CoreInterface.GetMtlSlot mMatIdx
   			
   			if iMaterial != undefined do
   			(
   				pStamp = iMaterial.CreatePStamp mSize 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()
   				iMaterial.Dispose()
   			)
   		)
   		return bm
   	)
   	
   	thumbnail = GetMaterialThumbnail 0 (dotnetclass "Autodesk.Max.PostageStampSize").Large
   	--display thumbnail
   )
Page 3 / 4