# Exporting steps/actions with a 3D Studio Max plugin

I'm trying to figure out how this plugin works behind the scenes. Do you know if there is any 3ds-max API function (maxscript/c++/python) which allows to record the action history somehow?

You could claim there is the max-recorder... in fact, this one does "almost" what I want... but the idea would be writing a plugin to export the max actions to my own custom format.

Example:

1) I create a cube with certain parameters
2) I select it
3) I apply a modifier with certain parameters


Imaginary output:

output = [
{"action":"create_cube", "params":{"name":"cube1", "size":10, "tess_x":2, "tess_y":3, ...},
{"action":"select_mesh", "params":{"name":"select_mesh1" "selection": "cube1", ...},
{"action":"subdivide", "params": {"name":"subdivide1", "type": "catmull-clark", ...},
...
]


PS: I haven't been able to contact that author's plugin to get some info about it, otherwise I wouldn't be asking ;-)

The plugin you have linked to doesn't seem to record command actions. Instead it records the modifier stack and allows the export of all animated parametric values. For example a cube of 1x1x1 is created on frame 1 but on frame 10 the cubes width is adjusted to 10. The exporter captures the animation of that data and allows playback of that animated value on a procedurally generated cube. 3D Studio Max works consistently in this way: every parameter presented to the user can be animated. Furthermore, each object primitive can have a stack of modifiers on top - modifiers such as noise, subdivision, wave, taper, etc. These modifiers also have animatable parameters which the exporter supports. Finally, 3D Studio Max also allows modifiers to be stacked, so a noise modifier can stack on a cube, and a wave on the noise, etc. Each parameter can be animated independently. Materials are the same. As are lights, cameras and other elements in the scene.

Consider your original output in these terms:

1) I create a cube with certain parameters
2) I select it
3) I apply a modifier with certain parameters


Imaginary output:

object = {  name : 'cube1',
transform : { pos=[0,0,0], rot=[0,0,0,1], scale=[1,1,1] },
stack = [ { create_cube : { x : 10, y : 10, z : 10, tess_x:2, ... } }
{ subdivide : { type: catmull-clark, ... } },
animation = [
{ frame : 10, param : 'create_cube.x', 20 }
]
}


I added an example of the animation -- targeting specific parameters.

In your engine you would essentially be evaluating the entire stack every time it changes -- this is how 3D Studio Max works internally.

If I were trying to make a 64k demo it would be the cheapest way to get great art variety for cheap and would look super cool too. Obviously you do not want the complexity of modifiers to be too great, for performance reasons.

So I guess my answer to your question is that no - theres no easy way to export action history, but I think that's not what you want to do here. You want to export the object stack, animate specific parameters, and evaluate the stack in engine.

• After few months I've come back to your answer and nowadays I understand a little bit better how 3ds max behaves so what you answer here makes sense... right now I've got this related question though, any idea? ;) – BPL Dec 19 '18 at 2:06

Short answer - See the Node Event System here.

Long answer - First, the MaxScript Macro Recorder in 3ds Max does something like this. It outputs a script which can potentially be replayed to achieve the same results as a sequence of UI operations. However, MaxScript exposure is incomplete, so many operations are not recorded, thus playback of the script is often not possible. Macro Recorder useful more as a training and inspection tool when learning about the MaxScript for features in the product.

Second, more realistically, to output a sequence of operations, you would have to listen for many events, such as with the Node Event System, and then provide recording logic for each event. It would be difficult/impossible to record every single parameter change. Some areas of the UI may be connected directly to the internal data, without an exposed API layer. That means some UI operations can never be repeated programmatically, and you'd have to record mouse operations to detect them, a big mess.

Still, it's quite feasible to record basic information, like when objects are created, moved, or their geometry is (somehow) changed, using the Node Event System. It's exposed in MaxScript and the SDK.

• Interesting, ty, I wasn't aware about the Node Event System at all. Just for the record, the big idea would be recording events just for a little subset of max commands. One use-case would be my engine using the json to create 3d meshes on the CPU by using CPU 3d mesh operators but another much more interesting use-case would be using the same json to be compiled/optimized into glsl code using SDF primitives. For instance, imagine you've created this animated scene in max, the exporter would generate the glsl code itself (no hardcoding) – BPL May 17 '18 at 13:46
• As mentioned by @Steven, you can record animation by looking at the animation keyframes on an object's transform. In MaxScript just say at time t myVal=myObj.transform for an object position at a given scene time. Documentation is here. You might want to capture changes as they're happening in real time, through, to use 3ds Max for live performance, or VJ'ing. Otherwise, all exporters pretty much operate by walking through the keyframe values. – MichaelsonBritt May 17 '18 at 14:39
• Thinking about this ... Yes, maybe it's possible create a collection of modifiers and transform controllers in 3ds Max, which accept glsl script code, entered on-the-fly, to perform their operations. Thus you could see animation in the viewport which maps directly to a real-time shader. I see some challenges, but I'm definitely interested in projects combining the "live visual arts" scene with 3ds Max. – MichaelsonBritt May 17 '18 at 14:53
• Maybe you're interested on this other related question as well? – BPL Dec 19 '18 at 2:08