After a few tough weeks with project deadlines, studying mathematics, going to Birthday gigs and Dynosnores (Adult sleep over at the National History Museum London – I highly recommend it) eating all my time, I thought I’d unwind on this thankfully miserable Sunday afternoon by getting my teeth stuck into something one of my colleagues wished he could do with 3dsMax.
A while back I created a script which created a 3DView for each phase in the project, then exported all the Elements in that phase to FBX. The purpose, as you can imagine, was to speed up the workflow to programs like 3dsMax/Unity or other 3D Graphics software so we could do high quality Construction Sequence renders/animations. The script I wrote only exported just the FBX files as that was our current workflow at the time (I was only just speeding up what was already being done), however, one of the guys at work asked whether it was possible to import them all into 3dsMax at once?
Me, having a similar track of thought when writing the FBX exporter nodes/script, but getting very busy at the time I wrote it, let the idea drop. But with this renewed interest I decided to pick it up again, dust it off and give it my full attention as it sounded like a challenge and I hadn’t seen it done through Dynamo.
I had a bit of a think and had an idea that might actually work that is pretty simple. 3dsMax has the ability to be launched via CMD and you can piggyback a MAXScript on startup through the CMD (See this link for details). I have seen Maxymo (a very cool interop tool between Dynamo/Max using Sockets by Wassim Jabi- See video below), but this wasn’t quite the right tool for the Job – although it is really cool.
So, coming back to the CMD approach and MAXScript, I knew this was possibly the best approach for my needs as I’ve heard of MAXScripts that do something along the lines of which I’m trying to achieve. However, how does one write in MAXScript?!?! I’ve never use it before and I don’t like just using any old code from the internet when I could give it a go myself. How hard could it be right?!?
Well, Autodesk have their MAXScript help file, which at first was a little baffling as I didn’t quite understand the syntax or even what functionality I could get from it. Fortunately, I could achieve near what I was after. The problem that I stumbled into quite early on was that the “Link FBX” classes are not exposed through MAXScript (similar to Revit’s Suite Workflow Commands). That’s a shame. You can Import an FBX but I wanted to keep all Revit Element Geometry in their respective Phases, but the ImportFile method will just Import the Geometry and merge with the scene stripping it of its heirarchy of ImportInstance so it was one massive list of Elements. To get around this I thought I would instead simply convert them all to .max files then XRef them all into a “Master.max” file for rendering. This method worked perfectly for my needs (although there may be better ways to do this that suit your particular workflow). I can now update the model, run the script, overwrite all (or some of) the .max Links to the “Master.max” and Render.
But the cool thing about all of this (and more the point of this post) is that it is all done in Dynamo. No touching max at all – even for the MAXScript. MAXScript .ms files are simply .txt files with .ms extension which means we can treat the whole script simply as one long string. I will show you how this all works now…
The FBX Exporter Script…
This is a script I did a while back to speed up FBX Exports by Revit Phase.
The Import into 3dsMax file script…
This is the Import to 3dsMax script. I will break this down step-by-step how this is working…
First Part – Getting things ready…
- Specify the Root Directory where all my FBX files are and where I will save the .max and .ms files.
- Get all FBX files in the Root Directory.
- Create new .max filepaths for when I save the FBX files as .max counterparts.
Second Part – Writing MAXScript…
- Write first section of MAXScript Body to Import FBX from FilePath, Save as a .max file, Clear the Undo Buffer and Reset the current .max file. Clearing the Undo Buffer ensures that the need-to-save is False by tricking 3dsMax into thinking nothing has happened. Even though I did just save, I found that max was still flagging the need to save and this was the recommended workaround. The ResetMAXFile method is clearing the current 3dsMax file to what is was like when I opened it – useful feature.
- Write the second section of the MAXScript Body to Save a new .max file called “Master.max”, then XRef in all the newly created .max files, then Save.
(Note: This builds a List of commands as a Single Level List object – we will address this in the next step)
Third Part – Building MAXScript from List of Strings
- Collect MAXScript Commands from the first section of the MAXScript Body (making sure lists are flattened).
- Append the second section of the MAXScript Body to the first section (making sure lists are flattened).
- Convert List of Strings to one String with carriage returns at end of each index of List.
- Write .ms file from single String Object (Optional “QuitMax” appended to end of String Object if specified so 3dsMax will close when MAXScript has completed).
Fourth (and last) Part – Open 3dsMax and Run MAXScript…
- Use CMD to open 3dsMax and run the MAXScript we just created.
(Note: Dynamo will be non-responsive while 3dsMax is running but will come back once 3dsMax is closed – There are probably ways to get around this but I thought that this will stop the user making changes and relaunching another instance of 3dsMax by mistake)
Now, this could be made better further. I intend to merge the two scripts (export to FBX, Import into 3dsMax) into one script and where a “Master.max” file exists then just reload the XRefs instead. Also, you could use MAXScript to Render scenes as you build them, I didn’t do this with this script, but it should be pretty simple. Another cool thing I was thinking was to automate dollying of Revit Camera Location so when rendering in 3dsMax you could have a new Camera Angle for each Render. Lastly, you can also specify an existing .max file to work on when writing to CMD, this is great if you have a template you like to use or if you have an existing file you want to update/render out. I don’t know MAXScript at all to be honest, first time I’ve used it (but not too tricky). If you are any good with MAXScript I’m sure you could think of some other cool things to do with it and this workflow. I’d be interested to know what other ideas there are!
Anyway, I hope you found this article enlightening in some way and that you may use it and develop it further.