How to associate a modifier to a string stored in an array?


#1

So I’m trying to make a tool which collects all the modifiers in the scene, adds them into an array as a string. That array is used for a listbox to show the modifiers as the items.

Now I wanna make it so that I can just select the modifier from the listbox and then turn them on and off. But I am unable to figure out how I’d even get the right modifier based on what I’m selecting in the listbox since the items in the listbox are strings and now the actual modifiers.

Here is what I’ve got up until now…

clearListener() 
try(destroyDialog modifierR)catch()
rollout modifierR "ModifierTest"(
    
    group "Select Modifier"(
		listbox modifierListLb "" width:150 across:2
		button mdRefreshBt "🗘" offset:[36,0]
    )
    group "Manage"(
        button onModifierBt "Modifier On" width:(modifierR.width/2-14) across: 2 offset:[5,0]
        button offModifierBt "Modifier Off" width:(modifierR.width/2-14) offset:[10,0]
    )
	
	
    fn getPolyMods modClass =(
        PolyMods=#()
        for obj in selection do(
            for md in obj.modifiers do(
                if classOf md==modClass then(
                    append PolyMods md
                )
            )
        )
        PolyMods
    )
	fn getTheList =(
		theList=#()
		theList
	)
	fn getObjModList =(
		objModList=#()
		objModList
	)
	
	
	on modifierListLb selected nameIndex do (
		print modifierListLb.items[nameIndex]
-- 		select (getNodeByName (modifierListLb.items[nameIndex]))
-- 		print selection
	)
	on modifierR open do(
		theList = getTheList()
		objModList = getObjModList()
		for obj in selection do(
			for m in obj.modifiers do(
				appendIfUnique theList ((classof m) as String)
				appendIfUnique objModList m
			)
		)
		modifierListLB.items=theList
	)
	on  mdRefreshBt pressed do(
		theList=getTheList()
		objModList = getObjModList()
		for obj in selection do(
			for m in obj.modifiers do(
				appendIfunique theList ((classof m) as String)
				appendIfUnique objModList m
			)
		)
		modifierListLB.items=theList
		print theList
	)
    on setMditerationsBt pressed do(
--         print mdIterationsSp.value
        Polymods = getPolyMods TurboSmooth
-- 		print PolyMods
		for i = 1 to Polymods.count do(
			Polymods[i].iterations = mdIterationsSp.value
-- 			print Polymods[i].iterations
		)
    )
    on onModifierBt pressed do(
		theList = getTheList()
		objModList = getObjModList()
		for i = 1 to objModList.count do(
			if classOf objModList[i] == (modifierListLB.items[nameIndex]) then(
				print (modifierListLB.items[nameIndex])
				objModList[i].enabled = true
			)
		)
    )
    on offModifierBt pressed do(
        PolyMods=getPolyMods TurboSmooth
        for i = 1 to PolyMods.count do(
                PolyMods[i].enabled = false
        )
    )
)
CreateDialog modifierR width:200

#2

Have you tried Mod Zorb? Does all of this and more. http://www.scriptspot.com/3ds-max/scripts/modifier-modifier-zorb

Otherwise, possibly you can make an array of the objects with the modifiers at the same time, then refer to them by index number. If you made it when you made the list box, the indexes should be the same on both arrays.

Or make the array with the strings a multidimensional array, so it stores both the string and the object and can refer to the associated object when selecting the item in the list box.


#3

Because you only collect and display modifiers from one (selected) node and do not sort the list, the index of the selected item directly corresponds to the modifier index in the node’s modifier list.

$.modifiers[modifierR.modifierListLb.selection]

#4

Since you are using the modifiers class (and not the actual modifiers names) as the listbox items names, you can use that same string to find the modifier. Something like this:

try destroyDialog ::RO_MODIFIERS_TEST catch()

rollout RO_MODIFIERS_TEST "" width:152 height:198
(
	listbox lb_modifiers "Modifiers:" width:136 height:10 pos:[8,8]
	
	button bt_update  "🗘"  width:24 height:24 pos:[8,166]
	button bt_mod_on  "On"  width:48 height:24 pos:[40,166]
	button bt_mod_off "Off" width:48 height:24 pos:[96,166]
	
	fn BuildModifiersList =
	(
		pModsList = #()
		
		for obj in selection do
		(
			for k in obj.modifiers do append pModsList (classof k as string)
		)
		
		lb_modifiers.items = makeuniquearray pModsList
	)
	
	fn SetModifierState state =
	(
		modclass = execute lb_modifiers.selected
		
		for obj in selection do
		(
			for k in obj.modifiers where classof k == modclass do k.enabled = state
		)
		
		select selection
	)
	
	on RO_MODIFIERS_TEST open do BuildModifiersList()
	
	on bt_update pressed do BuildModifiersList()
	
    on bt_mod_on pressed do SetModifierState true
	
    on bt_mod_off pressed do SetModifierState false
)

createdialog RO_MODIFIERS_TEST