Notifications
Clear all

[Closed] Creating a Bitmap Fit Script

Hey folks. I’m super new to maxscript, but this has been my dream for many years to write a script that does this. When putting down reference planes I usually make the plane, put the texture on it, put UVW map modifier on it, then do a bitmap fit and go find the source image to get the right aspect ration.

Well I think the script does this automatically now. I will post it below and hopefully you guys can either use it, or give me some information to make it better. I would love to learn some better syntax or more efficient ways to do these things. Thanks!

macroScript Bitmapfit
 category:"pete tools" 
 
 (
 
 nHold = $.name
 	--creates variable to hold current objects name
 	
 wHold = Box()
 	--creates box object and assigns it to variable wHold
 	
 wHold.material = meditMaterials[1]	
 	--applies material in slot 1 to box
 	
 wHold.name = "tempBox" 	
 	--names box tempbox
 
 select  $*nHold*
 	--selects original object
 	
 setMeditMaterial 1($.material)
 	--sets this objects material to slot 1
 	
 diffMap = meditMaterials[1].DiffuseMap 
 	--creates diffmap variable
 	
 myMap = diffMap.bitmap
 	--sets bitmap variable
 	
 myHeight = myMap.height
 	--gets height from bitmap
 
 myWidth = myMap.width
 	--gets width from bitmap
 	
 myUvw = uvwmap()
 	--creates UVW map modifier in a variable
   
 myUvw.length = (myHeight/40)
 	--sets the modifiers height
 	
 myUvw.width = (myWidth/40)
 	--sets the modifiers width
 	
 addmodifier $ myUvw
 	--adds the modifier to your object
 	
 
 	
 select  $*tempBox*
 	--selects temp box
 	
 setMeditMaterial 1($.material)
 	--puts its material back to slot 1
 	
 
 	
 delete $*tempBox*
 	--delets tempbox
 
 )
5 Replies

OKay!!! Version 2 is already out!

In the previous version the length and width of the mapping modifier were determined from the bitmap, which means if you use a larger or smaller bitmap than the size of your plane you will have some scaling issues on the mapping.

I paid some attention to the way Max does this with bitmap fit and notices it seems to inherit the size of the uvw mapping from the size of the plane. I modified the script to do this now, so the scale of the mapping should be relative to the size of your plane. I’m not 100 percent sure if I got it right, but it seems to match the Max uvw mapping in my tests.

So in short the script does this when you have a plane selected with your reference texture applied…

Puts the material you have in slot 1 on a temp object.

Gathers length and width info from the bitmap in the diffuse slot of the material on your reference plane.

Puts a UVW map modifier on your object where length = length of the plane and width = length of the plane * aspect ratio of the bitmap.

Reloads original material from temp object back to slot 1 and deletes temp object.

macroScript Bitmapfit
 category:"pete tools" 
 
 (
 
 nHold = $.name
 	--creates variable to hold current objects name
 	
 wHold = Box()
 	--creates box object and assigns it to variable wHold
 	
 wHold.material = meditMaterials[1]	
 	--applies material in slot 1 to box
 	
 wHold.name = "tempBox" 	
 	--names box tempbox
 
 select  $*nHold*
 	--selects original object
 	
 setMeditMaterial 1($.material)
 	--sets this objects material to slot 1
 	
 diffMap = meditMaterials[1].DiffuseMap 
 	--creates diffmap variable
 	
 myMap = diffMap.bitmap
 	--sets bitmap variable
 	
 myHeight = myMap.height
 	--gets height from bitmap
 
 myWidth = myMap.width
 	--gets width from bitmap
 	
 myUvw = uvwmap()
 	--creates UVW map modifier in a variable
   
   myRatio = float myWidth/ myHeight
   --creates ration between width and height of your bitmap
   
 myUvw.length = ($.length)
 	--sets the modifiers height
 	
 myUvw.width = ($.length * myRatio)
 	--sets the modifiers width
 	
 addmodifier $ myUvw
 	--adds the modifier to your object
 	
 tHold = $.name
 	--creates variable to hold current objects name
 	
 select  $*tempBox*
 	--selects temp box
 	
 setMeditMaterial 1($.material)
 	--puts its material back to slot 1
 	
 select  $*tHold*
 	--selects original object	
 	
 delete $*tempBox*
 	--delets tempbox
 
 )

If you guys have the time, I would like to add a couple things to this. First, i would like it to test if the length of your plane is greater than the width, then run this code. If not, then run the same thing but fix the width of the mapping to the width of the plane, so the entire image is seen on the reference plane. The normal bitmap fit in max doesn’t do this so if you make your image plane taller than it is wide it cuts off your image.

So basically I need the syntax for “If blank is true, then run this code. If not, run this.”

Also, at the end I want it to select the plane again for you but I couldn’t get this to work. Any ideas?

in your case you don’t need to create a temp node and you don’t have to use material editor as material holder.
all that you need is:


( 
 if isvalidnode (theNode = selection[1]) and iskindof theNode.mat Standard do
 (
  if iskindof (diff = theNode.mat.DiffuseMap) BitmapTexture and iskindof diff.bitmap Bitmap do
  (
   uvmod = uvwmap name:"Fit Bitmap" maptype:1 length:(diff.bitmap.height/40.) width:(diff.bitmap.width/40.)
   addmodifier theNode uvmod
  )
 )  
)

or you can do it using try expression without any double-checking:


try
( 
 theNode = selection[1]
 bmp =  theNode.mat.DiffuseMap.bitmap
 uvmod = uvwmap name:"Fit Bitmap" maptype:1 length:(bmp.height/40.) width:(bmp.width/40.)
 addmodifier theNode uvmod
)
catch()

Thanks for the info, I will do a bit of research into these techniques.

Similar to what you have I wrote this awhile back. It fits to the size of the geometry but keeps the ratio of the image true. Works from the material already assigned to the object and any maps found on it and they’re respective map channels.


 for SelObj in Selection do
 	if isProperty SelObj #Material == true do
 	(
 	local tnbms = getclassinstances Bitmaptexture target:SelObj.material
 	local SelObjSizeX = SelObj.max.x - SelObj.min.x
 	if tnbms.count != 0 do
 		for bm in tnbms do
 		(
 		local ImRatio = ((bm.bitmap.width as float) / bm.bitmap.height )
 		addmodifier SelObj ( uvwMap name:(getfilenamefile bm.filename) Length:(SelObjSizeX) width:(SelObjSizeX*ImRatio) mapChannel:bm.coords.mapChannel )
 		)
 	)
 

Thats interesting. So many ways to approach this task, mine clearly being the most crude.