Scripting to wiring parameters?


#1

I am coming from Maya, and using 3Dmax 2014 for a project.

I am using a script to hide/unhide some layers according to a slider UI object value.

I am not sure how to connect this interaction other than using wiring parameter.
In order to use the slider.value parameter, I had to plug it to some null object just for the sake of having a place to write my function.

Because of “reasons” (explained below) I am trying to hardcode the function inside wiring parameters. It partially works, but I am curious why I can’t run more than one function (or subfunctions). Below, is the code:

layers = #(
	
	"a_arm",
	"a_body"

	) as string

global layersLs = execute layers


fn main i = (
 if(i>0) then ( -- i wanted to put below in a function
  -- unhide()
  for i = 1 to layersLs.count do 
  (
   l= LayerManager.getLayerFromName layersLs[i]
   l.ishidden = false
  )

 )else (
  --same here: hide()
  for i = 1 to layersLs.count do 
  (
   l= LayerManager.getLayerFromName layersLs[i]
   l.ishidden = true
  )

 )
)

/*
fn  unhide = (
 for i = 1 to layersLs.count do 
  (
   l= LayerManager.getLayerFromName layersLs[i]
   l.ishidden = false
  )
)
*/

main( X_position ) -- wire to anything just as excuse to run a function 

10 -- return any value to a dummy object

Originally I had made a maxScript file, and wiring parameters was just calling that custom function while slider was being manipulated. But every time I reset max, I have to run that script again, and I couldn’t manage a way to open it with an specific scene (not with max, just the scene which uses that function).


#2

Your question is not simple, that’s probably why people in this forum still didn’t answer it.
It needs some explanation of how MAX system works. Your case depending on what you want to do might be pretty complicated.

In short, talking in “maya” terms visible/hidden state of layer (or node) is not an ‘attribute’ (plug), it’s a property. And it can’t be wired (in animatable meaning).

If you want to wire (in maya’s term it’s ‘connect’) anything it has to be a SunAnim (which is enable for having controller).

Layer doesn’t have ‘animatable’ way to hide/show instead of a node, which has ‘visibility’ controller.

So, you have better specify what you exactly want to do…
you have two options:

  1. make an extra UI solution to hide/show layers (not animatable)
  2. wire a node visibility with a UI control (animatable)

What do you want to do more likely?


#3
try(destroydialog LayerVisRol) catch()
rollout LayerVisRol "Layer Vis" width:191
(
	local layer_names = #(#arms, #body)
	
	checkbutton layer_vis_bt "Hide" width:182 align:#left offset:[-8,0]
	
	on layer_vis_bt changed state do
	(
		layers = for name in layer_names collect (layermanager.getLayerFromName name)
		if layers.count > 0 do layers.ishidden = state
			
		layer_vis_bt.text = if state then "Show" else "Hide"
	)
)
createdialog LayerVisRol

this is an example how to do task 1…
the main problem of this method is - there is no backward connection. The button ‘doesn’t know’ the state of layers (as well as layers don’t know the button’s state). That means it’s not a real connection (wiring)
But every time when you check/uncheck the button it changes the layers visibility state


#4

so, this solution might work well for scene editing pipeline for example. but can’t be used for animation (or rendering), where visibility state changes during the time.


#5

Thanks for the support!

Originally I just wanted to create some UI slider to hide/unhide sets of layers.

Not intended to be animated, but to help switching complex objects to a proxy version by hiding\unhiding objects accordingly to the slider value.

I will try your method when I go back to the machine. Thanks again for the support!


#6

It confuses me. The hide/show layer is toggle method - off/on. Why do you need a slider that assumes a smooth transition from the initial value to the final (min / max) ?


#7

Sorry for the confusion.
The mesh is a complex machine which many layers. Some set of layers (“layerA”, “layerB”, “layerC”) displays when slider value is == 0. Other set of layers displays when slider value is == 1, and so on. It is just to save the time to find the layers visually on the layer manager, select, hide or unhide.


#8

ok. let’s look at the task again:
we have a splider
the slider’s integer value is a layers visibility stage

at every stage only corresponding layers are visible
OR
all stages before current including current are visible, all after are still hidden

what is yours scenario?


#9

Hello Denis, sorry for the super late reply.

Pipeline was crazy so I had to figure out with whatever I had available. I am surprised how Max still have many room to improve, even in 2019, and all depended on someone’s script or plugin to save the day.

The task was,
the machine I was working had versions depending on country. Some some items would display or not, also materials would change, textures, but most of the structure and rig was preserved in all versions.

The slider would represent each different version. That means some layers would be visible for all versions while some layers would be visible only for specific versions.

I wanted to create some friendly UI with sliders and using wire parameters - because that is what I had access at that time -, but in the end I had to learn how to write some script (not friendly at all, but worked).