[maxScript] custom attributes to aid exporting animtions

It has been pointed out that using object names to drive tools is generally a bad approach and that custom attributes are the way to go.
I’ve done enough name-driven stuff to see the wisdom in this, but I am new to custom data in MAX.

My task: I have a rig system where there is simple ‘export’ skeleton driven by a more complex ‘control’ skeleton.
I only want to export the simple ‘export’ skeleton (to minimize our bone count in the exported FBX data.)

my first impulse is to name the bones with some kind of prefix (EXP_rootBone, EXP_spine01, ,…etc)
and use a script to select by name > export selected

Is this the sort of task that custom attributes can faclilitate? how would this be approached?

would you apply a “export =true” custom attribute to each bone?
or perhaps store a list of export bones in a dummy root node on each rig?
or perhaps store a pointer to some external json/xml data for each rig?

I am not sure what the wise approach is…

Is the export skeleton in a completely separate hierarchy? This is easier if so. Not sure what Max has, but in Maya I tag any top-level things to export with ‘selection sets’ that have custom attributes. The fbx exporter (again, in Maya) will export the entire hierarchy, so you don’t need to select or flag any children, and you don’t need to manage an entire hierarchy… just the top of it. See if you can tag the top of the export hierarchy somehow (custom attribute, or making it part a ‘set’ or ‘tag’ system). Shouldn’t need to do custom bone names.

Yes, the export skeleton is a completely separate hierarchy branch.

I seem to remember ‘include hierarchy’ option from Maya’s FBX export. Sadly Max FBX doesn’t appear to have this.

Your answer did however point me towards a 2009 discussion at CG talk about hierarchy selecting using MaxScript

So using one of the solutions represented there, I guess I can simply include everything to be exported under a single ‘export’ node and use that…

my talent for over-complicating things rears its head again.

Huh, I can’t find the ‘include hierarchy’ option. I don’t think that behavior is optional, but I’m jealous if it is in Max!

Maybe you can just tag the top node, then recurse down through the hierarchy, only selecting joints.

You have a ton of options here it just depends on how your skeletons and how your animation scenes are constructed for exporting.

SelectionSets
You could use selectionSets and put all of your exported objects into a “EXPORT” selectionSet. Major downside to that is selectionSets don’t transfer when you merge files. Not really useful.

Layers
You could use Layers. Layers are object exclusive which means an object can only exist in one layer. Layers also can be moved between scenes along with the objects that are being merged.
Downside is you could end up with multiple skeletons within the same layer name. To get past that you must have a scene manager or namespace all of your layers per character/skeleton for example “CREATURE:EXPORT” or “HUMAN:EXPORT”. I wouldn’t suggest this method.

Object Properties
http://docs.autodesk.com/3DSMAX/14/ENU/MAXScript%20Help%202012//index.html?url=files/GUID-AF1F51D4-449B-4C4D-9F58-85DB145BC0B-745.htm,topicNumber=d28e264901

This was the first bit of object meta-tagging we started doing. The problem with object properties is that is just a string of multiple properties that can be easily broken if updated incorrectly. You can end up having multiple properties on the same line and the getters of those properties will fail. I have built a lot of utilities for writing and modifying these on objects which prevents those errors but you need to remember anytime you write to the object properties you call your custom methods.

AppData
http://docs.autodesk.com/3DSMAX/14/ENU/MAXScript%20Help%202012//index.html?url=files/GUID-5517C84B-95A3-430D-BBF2-D62E638FD77-727.htm,topicNumber=d28e255254

I only just recently found out about this one. It seems clean if not limited. The way you apply values is by index which doesn’t make for easy name value pairing. You could assume that index 1 of appData on an object is the export value but that doesn’t seem ideal.


setAppData $ 1 "Export"
-- OK
getAppData $ 1
-- "Export"

Custom Attributes
We have since moved to applying custom attributes to the objects we wish to export. This is good for many reasons including the fact that we are moving our objects between multiple DCC packages ( max, maya, and motionbuilder ) and the attributes are accessible in each application.

To make sure you don’t need to focus on object names which can be accidentally changed or modified storing a base name on a custom attribute that is read-only is helpful. While the object name may change the name you need for exporting can be queried from the custom attribute if need be. We pack a lot of attributes onto objects for moving between DCC apps and exporting to game. We also have custom objects and modifiers that you can add objects to for exporting. The parameter data in the custom modifier can maintain the list of objects you wish to export and the interface can allow you to add and remove objects when necessary. These move with the characters between scenes so the associations are never lost. This is incredibly useful.

Here is some pseudo code for how we may stamp attributes on individual objects.



--Bone Attributes
v_bone_data = attributes v_bone_data
attribid:#(0x6664296c, 0x5dec7a0)
version:1
(
	parameters bone_data
	(
		bone_name  type:#string  default:"none" 
                bone_export  type:#boolean  default:True
		bone_parent  type:#integer	default:-1  animatable:False
	)
)

-- Apply attribute class to an object
add_attribute = custAttributes.add obj v_bone_data baseobject:True

-- update attribute data
obj.bone_name = obj.name
obj.bone_export = False


ahh disregard this. I’m apparently blind and missed the [maxscript] in the title. I’ve got solutions for Maya… :confused:

Randall -thanks for the response. I’m transitioning form Maya/Python to 3dsMax/Maxscript so It’s nice to see some Max specific tech art info.
(Bookmarking your blog too)

custom attributes in Max seem less straightforward than Maya/Python.
There seems to be more interdependent bits to define -attribid, version, parameters-
the Max help docs require a lot of cross referencing to follow all the intertwined bits.
is there a good holisitc summary of max custom attributes out there somewhere?

Custom attributes aren’t a straight forward name/value pairing that you can set on an object. While it is a bit more complex what’s nice is they are setup kind of like a class object in a way that can have a lot of built in functionality.
Custom attributes first need a parameter definition. This definition can have any number variables or functions with in it. You can also define a rollout that can use these variables to populate the interface. In my example I didn’t provide a UI to the attributes that I created because I don’t want them to show up on the object. I just wanted to access the attributes on the objects through tools so the artist can’t accidentally muck around with them.

Maxscript Reference Example
http://docs.autodesk.com/3DSMAX/14/ENU/MAXScript%20Help%202012//index.html?url=files/GUID-DAB53D18-EE71-4624-8796-87C74C9261E-1623.htm,topicNumber=d28e582296


the_weaponData = attributes weaponData
(
parameters main rollout:params
(
hitPoints type: # float ui:hits default:10
cost type: # float ui:cost default:100
sound type: # string
)
rollout params "Weapon Parameters"
( ... )

Paul Neale has a write up that shows a good use of custom attributes on a modifier. This is pretty much exactly how we store bones for a character that will be exported. We have a modifier similar to this, with a lot more functionality, that sits on top of the Skin modifier in max. When we need to export, we select the character mesh object then hit the export button on this modifier.
http://www.paulneale.com/tutorials/Scripting/weakReferences/weakReferences.htm

Pete Addington/LoneRobot has a some good examples of using custom attributes on his website as well.
http://lonerobot.net/?p=158
http://lonerobot.net/?p=1073

If you have any other specific questions shoot them out.

thanks again, Randall.
Where exactly in an object’s scene do you store the custom attributes?
I’m using dummy objects to build Maya-like groups, so I am thinking of applying the custom attributes to the dummy objects representing the root transform.
I assume one wants to be consistent here, so scripts always know where to look for Custom attribs…

I’ve also seen some examples of applying custom attribs to the scene root using something like

sceneRoot=(refs.dependents rootnode)[1]

but I’m not sure that’s as useful.

We have a scripted plugin modifier that sits on the character mesh itself. You could add an EmptyModifer on your character mesh or if you have a main character controller object that is always visible you could put a modifier on that instead. If you look at the EmptyModifier/AttributeHolder example on Paul’s website you may get a better idea of how much you can do with it. You can rename the actual modifier name by right-clicking and renaming as well.

Additionally, you could just stamp all the bone objects with a custom attribute saying export and just loop the scene objects for that attribute. However, that’s not quite ideal if you have multiple characters in the scene. You could add an additional character asset name attribute to make a distinction as well.

I’d say its worthwhile getting the array of objects on an empty modifier. Once you add buttons to it you can add and remove bones on the fly.

No matter what you choose to tag bones for export I would strongly recommend to use a prefix for them anyway. Specially if you are starting to build a new animation pipeline and/or is short on time.

That way you can easily filter/isolate/select them out using “H” short cut (selection floater) and filtering by their prefix for when stuff blows up and you need to take a quick look at stuff. Layers and selection sets also do the job, but I found out that later in production they are more easily “destroyable” by artists and animators than a simple prefix in the nomenclature.