--SMIV (Show Maps In Viewports) Macroscript
--MAX R3 Version 2.3
--Started: 3/23/1999
--Edited:  3/1/2000 
--by Borislav Petrov
--bobo@email.archlab.tuwien.ac.at
--http://gfxcentral.com/bobo/
---------------------------------------
--WHAT'S NEW?
--*v2.1: Composite,Mask and Mix Map support added for first-sub-level maps
--*v2.2: Blend Sub-Material support
--*v2.2: Specify Sub-Material number 
--*v2.3: Support for Double-Sided etc. Material with one or two Sub-Materials. 
--*v2.3: Should work with 3rd party materials using a .Material1 and/or .Material2 Sub-Mats.

---------------------------------------


macroScript SMIV category:"Bobo_s Tools" tooltip:"Show Maps in Viewports" Icon:#("bobomacro",2)
(
-----------------------
--Init some variables--
-----------------------
local smiv_main					--floater and rollout variables
global smiv_nf

--------------------------
--Define Utility Rollout--
--------------------------
rollout smiv_main "Show Maps In VPort"
(
group "Affect Materials in:"
(
checkbutton use_scene "Scene" checked:true width:56 align:#left across:2 highlightcolor:([200,255,200] as color) height:18 offset:[-4,0]
checkbutton use_selection "Selection" checked:false width:56 align:#right highlightcolor:([255,205,200] as color) height:18 offset:[3,0]
dropdownlist map_type items:#("ANY Channel","Ambient","Diffuse","Specular","Glossiness","SpecularLevel","Self Illum.","Opacity","Filter","Bump","Reflection","Refraction","Displacement","Color","Metalness","DiffuseLevel","Diff.Roughness") selection:1 width:116 align:#center
spinner composite_number "Sub-Map #" range:[1,1000,1] type:#integer fieldwidth:35 offset:[3,0]
radiobuttons multi_number labels:#("Mat 1", "Mat 2") columns:2  align:#center

)

button activate "Turn ON" checked:true width:60 across:2 align:#left height:20 offset:[-8,0]
button deactivate "Turn OFF" checked:false width:60 align:#right height:20 offset:[8,0]



on use_selection changed state do
(
use_scene.checked = not state
)

on use_scene changed state do
(
use_selection.checked = not state
)

------------------------------------
--Function to turn textures on/off--
------------------------------------
fn check_material current_mat onoff_mode =
(


	if classof current_mat == Multimaterial then					--if the material is a Multi/Sub
		(
		nums = current_mat.numsubs									--get number of sub-materials
		for i = 1 to nums do
			(
			append m_array current_mat[i]							--put into array for later check
			)
		)
		else
		(
	
		if classof current_mat == Blend then						--If the current material is Blend,
		(
		main_current_mat = current_mat								--copy it into the main material variable
		if multi_number.state == 1 then 							--depending on the radio button state
			(
			current_mat = main_current_mat.map1						--get Material 1 (map1)
			)
			else
			(
			current_mat = main_current_mat.map2						--...or Material 2 (map2)
			)
		)
		else
		(
		main_current_mat = undefined								--if it is not Blend, set main material var to undefined
		)

		test_for_submat1 = undefined								--init two variables to test for two sub-materials
		test_for_submat2 = undefined
		try															--start an error trap
			(
			test_for_submat1 = current_mat.material1				--try to get material1 
			test_for_submat2 = current_mat.material2				--try to get material2
			)
		catch														--catch the error if any of them is missing
			(
			)
	
		if test_for_submat1 == undefined and test_for_submat2 == undefined then 	--if both were missing do nothing
			(
			)
			else
			(
			main_current_mat = current_mat											--if at least one was there, get main material
			if multi_number.state == 1 and test_for_submat1 != undefined then current_mat = current_mat.material1	--and get a sub-material depending on Radio Button.
			if multi_number.state == 2 and test_for_submat2 != undefined then current_mat = current_mat.material2
			)

	
		if map_type.selection != 1 then 		--in case a channel is specified
			(
			loop_st = map_type.selection   		--loop start and end equal to spec. channel
			loop_end = map_type.selection  	
			)
			else
			(
			loop_st = 2 						--loop through all channels
			loop_end = 17
			)
		for j = loop_end to loop_st by -1 do	--loop through channels (see above)
		(	
		tex_map = undefined						--reset variable
		try
		(
		case j of								--select channel
		(
		2: tex_map =current_mat.ambientMap
		3: tex_map =current_mat.diffuseMap
		4: tex_map =current_mat.specularMap
		5: tex_map =current_mat.glossinessMap	
		6: tex_map =current_mat.SpecularLevelMap	
		7: tex_map =current_mat.selfillumMap
		8: tex_map =current_mat.opacityMap
		9: tex_map =current_mat.filterMap
		10: tex_map =current_mat.bumpMap
		11: tex_map =current_mat.reflectionMap
		12: tex_map =current_mat.refractionMap
		13: tex_map =current_mat.displacementMap
		14: tex_map =current_mat.color
		15: tex_map =current_mat.metalness
		16: tex_map =current_mat.DiffuseLevelMap	
		17: tex_map =current_mat.DiffuseRoughnessMap
		)--end case 
		)catch()													--error trap in case a channel name has been changed again ;o)
		if tex_map != undefined then 								--if a channel has a texture
		(
		if classof tex_map == CompositeTexturemap then
		(
		if composite_number.value > tex_map.mapList.count then 
		(
		comp_number = tex_map.mapList.count 
		)
		else 
		(
		comp_number = composite_number.value 
		)
		tex_map = tex_map.mapList[comp_number]
		)

		if classof tex_map == Mix then
		(
		if composite_number.value == 1 then tex_map = tex_map.map1
		if composite_number.value == 2 then tex_map = tex_map.map2
		if composite_number.value > 2 then tex_map = tex_map.mask
		)

		if classof tex_map == Mask then
		(
		if composite_number.value > 1 then 
		(
		tex_map = tex_map.mask
		)
		else 
		(
		tex_map = tex_map.map
		)
		)
		if main_current_mat == undefined then
		(
		showTextureMap current_mat tex_map onoff_mode			--texture on/off
		)
		else
		(
		showTextureMap main_current_mat tex_map onoff_mode		--texture on/off with a Top Material (like Blend,DoubleSided etc.)
		)

		)	
		)
	)	
	
)--end function

fn on_off_maps binary_mode =
(
m_array = #()														--Init array to store materials

if use_scene.checked then											--if Affect Materials In Scene is checked
	(
	node_array = $* as array										--get all objects in the scene into array
	)
	else
	(
	node_array = selection as array									--or get only selected into array
	)
	
for i = 1 to node_array.count do 									--loop through node array
	(
	if node_array[i].material != undefined then 
		(
			append m_array node_array[i].material					--if there is a material, store into material array
		)
	)

current_pos = 0														--set a counter to 0
while current_pos < m_array.count do								--loop until # of checked materials is lower than # of materials to check
(																	--NOTE that the # of materials to check increases dynamicly with Multi/Sub
current_pos += 1													--increase counter (# of checked materials)
check_material m_array[current_pos] binary_mode						--call Function to check material
)--end while
max views redraw 													--redraw all viewports to update textures display
)--end fn

on activate pressed do												--Turn ON was pressed
(
on_off_maps on
)--end on pressed

on deactivate pressed do												--Turn OFF was pressed
(
on_off_maps off
)--end on pressed



)--end rollout

if smiv_nf != undefined then closeRolloutFloater smiv_nf					--close existing rollout

smiv_nf = newRolloutFloater "SMIV v2.3" 160 208 20 100						--Create new floater
addrollout smiv_main smiv_nf												--add rollout to floater

)--end script