ScriptSpot

Forum topic · Scripts Wanted

Change map type?

By er.cchadw.ck@gmail.com · 2014-02-18

Description

After selecting a bunch of Bitmap Maps in the Slate Material Editor, I would like to convert them to RGB Multiply maps, keeping the original bitmap in the Color 1 slot.

I enabled the Macro Recorder, but the command it spits out refers to each specific material and bitmap path:
meditMaterials[9].diffuseMap = RGB_Multiply MAP1:( Bitmaptexture fileName:"c:\project\scene\texturefile.tga")

How do I make this more generic?

I'm also looking for a quick way to instance a specific bitmap into the Color 2 slot of every RGB Multiply, if possible.

This is for a custom game engine which requires lightmaps to be provided via RGB Multiply.

Thanks for any help!

Eric

Comments (14)

er.cchadw.ck@gmail.com · 2014-02-19

This is excellent! Thank you once again.

Is there an easy way for the first function to delete the named view? I get an error when trying to run it on a 2nd object in the same session.

#1 fn

barigazy · 2014-02-19

Adding one line will fix that. You can change name of view also.

fn selectionStdMatsToSME objs newViewName: = if objs.count != 0 do
(
local objsStdMats = #()
for o in objs where o.mat != null do
(
if isKindOf o.mat Standard then append objsStdMats o.mat else
(
join objsStdMats (getClassInstances Standard target:o.mat)
)
)
if objsStdMats.count != 0 do
(
sme.DeleteView (sme.GetViewByName newViewName) off
local newSMEView = sme.GetView (sme.CreateView newViewName)
for m = 1 to objsStdMats.count do newSMEView.CreateNode objsStdMats[m] [(m-1)*500,0]
)
)
selectionStdMatsToSME selection newViewName:"bga"

er.cchadw.ck@gmail.com · 2014-02-21

Aha, sme.DeleteView thank you!

I am curious how to add a bitmap dialog to this script, so I can use a GUI to pick a new lightmap instead of editing the script each time.

I adapted this sample from an Autodesk help tutorial, but it returns an error (-- Type error: copy requires BitMap, got: undefined). And besides I'm not quite sure where to insert it into the existing script.


    theOpenBitmap= selectBitmap()
    if theOpenBitmap != undefined do
    (
      copy theOpenBitmap lightmap2
      close theOpenBitmap
    )

barigazy · 2014-02-21

Concept that you used returns bitmap. Then you need to create bitmaptexture.
So can be used like this


lightMap2 = if (bmap = selectBitmap()) != null do (BitmapTex bitmap:bmap ; close bmap)

I prefere to use file name string using another concept

lightMap2 = if (str = getOpenFileName caption:"Pick Light Map") != null do (BitmapTex dilename:str)

#2fn part3

barigazy · 2014-02-21


fn convertToMultiply smeViewName: mapSlotName: lightMap2: overwrite: =
(
if (view = trackViewNodes[#sme][smeViewName]) != null do
(
if (smeNodes = view.numsubs) != 0 do
(
lightMap2 = if lightMap2 == unsupplied do (getOpenFileName caption:"Pick Light Map")
lightMap2 = if lightMap2 != null do BitmapTex filename:lightMap2
for n = 1 to smeNodes where isKindOf (mat = view[n].reference) Standard do
(
if (map = getProperty mat mapSlotName) != null do
(
if isKindOf map RGB_Multiply then
(
if overwrite then map.map2 = lightMap2 else (if lightMap2 != null do map.map2 = lightMap2)
)
else
(
rgbMulty = RGB_Multiply map1:map
if overwrite then rgbMulty.map2 = lightMap2 else (if lightMap2 != null do rgbMulty.map2 = lightMap2)
setProperty mat mapSlotName rgbMulty
)
)
)
)
)
)
-- this concept use ei. display the standard 3ds Max file open dialog to pick light map
convertToMultiply smeViewName:"bga" mapSlotName:#diffusemap overwrite:true
--or you can use this to not show open dialog and use filename
convertToMultiply smeViewName:"bga" mapSlotName:#diffusemap lightMap2:@"c:\mapfolder\light_map.jpg" overwrite:true

Thanks barigazy!Now I am

er.cchadw.ck@gmail.com · 2014-03-14

Thanks barigazy!

Now I am trying to set the lightMap2 to use UV map channel 2. Looking through the MXS help file, there's an argument

<textureMap.coordinates>.mapChannel Integer

but I must not be getting the syntax correct, as it seems to always return an error. How should I format this?

barigazy · 2014-03-14


lightMap2.coords.mapChannel = 2

er.cchadw.ck@gmail.com · 2014-03-14

Yay! Thanks again!

#2fn

barigazy · 2014-02-18

fn arguments:
smeViewName -- name of newly created sme view
mapSlotName -- map slot name ei. property name
putInMap2 -- if this argument is true them MAP1 will be instanced in MAP2 slot in RGB_Multiply map


fn convertToMultiply smeViewName: mapSlotName: putInMap2: =
(
	if (view = trackViewNodes[#sme][smeViewName]) != null do
	(
		if (smeNodes = view.numsubs) != 0 do
		(
			for n = 1 to smeNodes where isKindOf (mat = view[n].reference) Standard do
			(
				if (map = getProperty mat mapSlotName) != null do
				(
					if isKindOf map RGB_Multiply then (if map.map1 != null and map.map2 == null and putInMap2 do map.map2 = map.map1)
					else (setProperty mat mapSlotName (RGB_Multiply map1:map map2:(if putInMap2 then map else null)))
				)
			)
		)
	)
)
convertToMultiply smeViewName:"bga" mapSlotName:#diffusemap putInMap2:false

Enjoy ;)

er.cchadw.ck@gmail.com · 2014-02-19

This is excellent! Thanks so much for helping me with this.

The 2nd function isn't quite correct for my situation... I'm trying to add a new bitmap to the material tree, in the Color 2 slot of each RGB Multiply.

I can certainly wire this in by hand, but it's tedious.

This new bitmap gets shared by all the materials on the object (it's a lighting map, baked in Render To Texture).

The existing bitmaps all use UV channel 1, but the new one uses UV channel 2.

I wonder... do I need to invoke a file selection dialog? Or is there a better way to choose this bitmap? Maybe have it already loaded in SME?

If it helps, the file name for the new bitmap always starts with the string "lightmap_" (sans quotes), but there can be two or more of these in the folder (e.g. one for the "wall" model, one for the "floor" model).

Thanks again!

Edit... here's what the end result should look like. The map on the left is the new lighting map that uses UV 2.

#2fn part2

barigazy · 2014-02-19

Ok lets try like this
If you supplied "lightMap2" argument with filename then map will be added in map2 slot. Also you have "overwrite" option to overwrite map in MAP2 slot if already exsists.

fn convertToMultiply smeViewName: mapSlotName: lightMap2: overwrite: =
(
if (view = trackViewNodes[#sme][smeViewName]) != null do
(
if (smeNodes = view.numsubs) != 0 do
(
local lightMap2 = if lightMap2 != unsupplied then BitmapTex filename:lightMap2 else null
for n = 1 to smeNodes where isKindOf (mat = view[n].reference) Standard do
(
if (map = getProperty mat mapSlotName) != null do
(
if isKindOf map RGB_Multiply then
(
if overwrite then map.map2 = lightMap2 else (if lightMap2 != null do map.map2 = lightMap2)
)
else
(
rgbMulty = RGB_Multiply map1:map
if overwrite then rgbMulty.map2 = lightMap2 else (if lightMap2 != null do rgbMulty.map2 = lightMap2)
setProperty mat mapSlotName rgbMulty
)
)
)
)
)
)
convertToMultiply smeViewName:"bga" mapSlotName:#diffusemap lightMap2:@"c:\mapfolder\light_map.jpg" overwrite:true

er.cchadw.ck@gmail.com · 2014-02-18

btw, I'm using Max 2012.

barigazy · 2014-02-18

I wil separate this solution in two functions:

#1 first function will helps you to fill new SME view with materials of selected objects by filtering only standard materijal.
This way you can operate only on materials in specified SME View.
You can delete unwanted materijal or maps or even add some new before you assigne RGB_Multiply map

#2 With second function you will be able to:
-- assigne RGB_Multiply map in specified map slot
-- add previous map in MAP1 slot of RGB_Multiply
-- add MAP1 to MAP2 slot as instance

#1 fn

barigazy · 2014-02-18

Select some scene objects and run this fn
fn arguments:
objs - array of objects (selection)
newViewName - name of new SME View which will be created


fn selectionStdMatsToSME objs newViewName: = if objs.count != 0 do
(
	local objsStdMats = #()
	for o in objs where o.mat != null do
	(
		if isKindOf o.mat Standard then append objsStdMats o.mat else
		(
			join objsStdMats (getClassInstances Standard target:o.mat)
		)
	)
	if objsStdMats.count != 0 do
	(
		local newSMEView = sme.GetView (sme.CreateView newViewName)
		for m = 1 to objsStdMats.count do newSMEView.CreateNode objsStdMats[m] [(m-1)*500,0]
	)
)
selectionStdMatsToSME selection newViewName:"bga"