Making Macro Maker: A Maker's Memoir
A while ago I was doing a series of repetitive actions in Blender - not an uncommon occurrence - and as usual, I began to think of a Python script that I could write to do this task for me...
But I write a lot of scripts. And the add-ons I write are often project specific and therefore limited in use. Plus, this task was about manipulating object's and their data and applying modifiers and joining objects and moving them and setting their origins and removing doubles and and...and that sounded like a terrible amount of effort.
I thought to myself that it would be so much simpler if I could simply take the actions I was already doing - which were pretty straightforward when done through the UI - and just record them. Other software has this functionality: Word and a few of the other Office products have 'Macros' while Adobe's offering is 'Actions'. Both produce the same results: record a sequence of tasks, save it and then play those actions back any time on the selected content.
I looked into whether Blender had any similar functionality. I knew it didn't really have anything like that built-in. Common advice is to pull down the Info Editor window, copy the actions that are listed there and paste them into the Text Editor and run them. This does technically work, but this workflow is itself repetitive.
There's even an add-on that comes with Blender called 'Macros Recorder', which does automatically record a series steps to a text file and inserts it into a script ready to be run. But that add-on doesn't have the nicest of UIs and at best I would describe it as 'cryptic', even though, once worked out, it is quite simple to use. Nevertheless, when comparing these options* with Word's macros or Photoshop's actions, they fall somewhat short, which tempted me to make my own add-on.
*I've just found another add-on, here.
Now, you may be thinking "But weren't you complaining earlier that you right a lot of add-ons?" and the answer is "Yes", or at least "Yes, but..." I do write a lot of add-ons and I have, in the past, sometimes got caught up in writing an add-on as a bit of a distraction instead of just getting on with whatever task the add-on is meant to be helping with, but, if the add-on is helpful to many projects instead of just one and if I can see that maybe this add-on would be popular and useful enough to potentially sell, then I give in and allow myself to have a bit of a play with some code.
The result of this playing is Macro Maker, the add-on I wrote:
Not exactly the most exciting screenshot, I'll give you that, but it gets across the basic idea. So far the add-on has the following functionality:
- Record 'Macro Steps' (where each step is an action you take) 'live', i.e. each 'step' is shown as you make it:
- The ability to delete steps if you make a mistake.
- The option of editing options. In the GIF above I edit the 'Angle' of the rotation.
- Saving macros to an external file so they're accessible to any blend file you open.
- Manage and delete saved macros from a separate panel.
- And, most importantly, the ability to click a button to replay the macro. You can also set the macro to run on each selected object individually. You could, for example, have a macro with the Cursor to Selection command as one of its steps. By default, the cursor would go to the centre of the selection of objects, but you might want the cursor to go to each individual object instead.
One important thing to note is that it's only possible to detect 'actions' i.e. Blender's operators - basically anything that's a button or a tool from a menu. It can't automatically detect property changes. So you could add an Array modifier, but you couldn't set its Count property. I've got around this by providing an entry in the right-click context menu for properties called 'Add Property to macro':
This adds the property to the macro. I can understand that might seem a bit fiddly, but I don't think there's a way around it.
Here's the most up-to-date screenshot of the UI, showing a few recorded macros:
However - and this is a rather large 'however' - I'm not going to do any more work on it, at least not for the minute. It works pretty well, I'm able to use it for some tasks, but it still needs a lot of work. For example, I can't:
- Use tools that are combinations of two other tools, e.g. inserting an edge loop actually runs two different operators. Firstly, it inserts a loop - the first operator - then secondly it starts the edge slide tool. Side note: confusingly, Blender refers to these types of operators as...macros.
- Detect which context the macro was recorded in. Was it recorded in Edit Mode? Then you shouldn't be able to run it in Object Mode etc.
- What if the operators requires certain conditions to be met and they aren't? E.g., you can't join two objects if only one is selected. How do I pass those error messages on to the user?
- A pretty major one: you can't yet edit existing macros. There are some I've recorded which I would really like to extend - the only option at the minute is to re-record them in their entirety.
- I've also never really tested it on anything but the 3D View, so it's pretty focused around objects at the minute, despite the fact it should work in every area of Blender, which also means detecting which area a macro expects to be run in to avoid running something in the 3D View which was intended for the VSE.
- Properties on the object can be recorded, but I can't yet record properties on an object's materials or modifiers.
There are also a few technical things that need to be changed, but I think for the most part it would just take time. As for why I'm not continuing to work on it, the answer is 2.8. Blender is undergoing heavy development. Heavy enough that the very specific Python APIs I'm using might not even exist when 2.8 is finished (I'm already having to prepare for the fact that my existing add-ons, including the one I sell will have to be updated, as some critical parts of the API are changing), so I'm going to wait until 2.8 is out before I work on it again.
There is also a slightly different problem which makes me slightly wary of further development. From talking to a few people on Twitter about the add-on, I'm slightly worried people haven't thought about how macros actually work (in any software, not just my add-on) and they may have difficulty in adapting their current way of thinking when trying to use the add-on.
Let's say I want to record a macro that takes the selected vertices in Edit Mode, adds them to a new Vertex Group, adds a new Mask modifier and assigns that newly created Vertex Group to the modifier. The steps would look something like this (having already selected the vertices):
- Add a new Vertex Group.
- Click 'Assign' under the Vertex Group.
- Add a new Mask modifier.
- Choose the new Vertex Group on the Mask modifier.
This looks pretty straightforward, but there are actually a few problems with this that would stop the macro working under some (maybe most) circumstances. The macro would work fine up until step '4': "Choose the new Vertex Group". It sounds simple, but how would the macro know which modifier to add the Vertex Group to? I don't yet have this part of property recording working yet, but when trying to choose the Vertex Group, it would likely look for a Mask modifier with the same name as when the macro was recorded. So what happens when the macro is run a second time or if there's already a Mask modifier? The new modifier would have '.001' appended to the end of its name and the macro, not being able to find a mask modifier with the correct name, would fail.
The important thing to realise is that when dealing with lists, the add-on will likely look for something to have the same name each time, whether that's a modifier in a list of modifiers or a Vertex Group in a list of vertex groups. Potentially, this could be fixed by having an option when recording a property to always look for the property on the last item in the list. I'll only know if this is an option once I resume development. Even then I have a feeling that wouldn't solve all the problems.
So, to conclude, I'll start working on Macro Maker again when 2.8 is released and I'll see if the APIs I need are still intact. There's also the problem that the toolbar as it exists now, where the add-on is placed, doesn't exist in 2.8, but I've heard that the developers are going to make sure the new UI supports 'UI heavy' add-ons by updating the UIs of the add-ons that are distributed with Blender, so hopefully there will be a solution for add-ons that require constantly visible columns for their layouts.
In the wake of ceasing to work on this add-on, I've been working on a personal Lego project, which I'll probably talk about in the next post, but judging by my past release schedule for blog posts, that won't be for another 6 months.