Controlling Node Visibility with Custom Attributes

Jan 20, 2009 by     No Comments    Posted under: 3dsMax, Characters, Maxscript, Rigging

This was a small attribute inspired after reading Paul Neale’s article on Weak Referencing in 3dsMax. It allows you to store references to nodes within the attribute and then globally control their visibility in a scene. The only thing to note is that obviously, if you are hiding a node that the attribute is on, you will no longer have the dialog showing but you can just place this on a root node or dummy object too. On the visibility attribute, use the set button to specify the nodes you want to control the visibility of. There are three separate groups for mesh, rig and control objects.

Weak References are great for character animators because you can store a load of information about objects in a rig without having the issue of referring to it explicitly by name, nor do you have dependency issues as it stores the node with some jiggery pokery between the RefTargMonitorRefMaker and NodeTransformMonitor classes. Without going into it anymore than that, you can specify a reference in a custom attribute and refer to it via Maxscript like CustomAttribute.Weasel_RootBone.node. This will return the node.

You specify a Weak Reference by using a parameter block in the custom attribute. This must be set to the #maxobject type. If you want to store an array of nodes you should use the #maxobjecttab type. In the reset character utility above i have used a #maxobject to store the rootnode, and a #maxobjecttab to store the other bones.

Look at the code below and you will see the parameter declared in the first section of the attribute. You can obviously set all these things via script but these utilities are a more manageable front end in case you need to add anything to the character afterwards.

parameters main
RigVisNodes type:#MaxObjectTab tabSize:0 tabSizeVariable:true
MeshVisNodes type:#MaxObjectTab tabSize:0 tabSizeVariable:true
CtrlObjsNodes type:#MaxObjectTab tabSize:0 tabSizeVariable:true
HideCVisUI type:#boolean default:false
RigVisHidden type:#boolean default:false
MeshVisHidden type:#boolean default:false
CtrlObjsVisHidden type:#boolean default:false

Once you have the UI working as you like, you can alter these to any purpose you want. I have added a turbosmooth control that allows you to globally set the viewport/render state of the added nodes, as well as a skin pose utility that takes a custom rig and stores allows you to reset the whole rig back to a default position. In the case of storing the visibility nodes, it goes like this –

if VisObjs != undefined do
MeshVisNodes = #() -- resets the #maxobjecttab array
for i in Visobjs do append MeshVisNodes(nodeTransformMonitor node:i forwardTransformChangeMsgs:false)

It is worth researching the types available in the parameter block, as others can be very useful also. I have used the #boolean option to store the UI state of the attribute and this means once minimized, it stays like that when run subsequent times. This keeps everything local to the attribute and eliminates the need for ini files to store settings.

Using the boolean switch could just as easily be applied to the state of a checkbutton – swapping of materials or changing the spline base recomb option on a hair and fur modifier for example. This state is stored within the attribute.

Improvements you can make

Currently, the attribute doesn’t check if the node has been hidden manually. This could be done with a callback but I haven’t implemented it yet. The problem is that you might have to press the button again to toggle the objectset to the state you want.

To add to an object

Select it and run the script, it will apply it to the currently selected stack item.

Where to look in the Maxscript Help for further information

Scripted Plug-in Clauses

Weak References To Nodes in the Expression/Script Controller