Adventures With Macros

Since I suck at measuring things I decided to make a set of gauges to help me verify my work. I wanted a set that ranged from 20mm to 79mm in 1mm increments and I wanted them embossed with text showing their sizes. Oh, and a hole so I could keep them in order on a loop of string. And filleted, of course, because smooth is good.

Time to learn macros!

The Mac version of Rhino is not as macro friendly as the Windows version. You don’t have a built-in MacroEditor, for instance.

Macros are text lists of Rhino commands. To run a macro, you select text, then paste it into the Rhino command box. Or you can use Rhino’s ReadCommandFile command to read a text file. Macros are not dynamic, They don’t support variables. To get variables you need a scripting language which can spit out text files containing commands matched with the right numbers.

I’m not yet ready to learn Python, which is one interface for Rhino macros, but I can manage AppleScript so I set out to generate a set of macro files in AppleScript.

Days later I achieved my goal – a printed set of perfect gauges – but it was not easy. Here are some things I learned (some obvious, but I have a talent for wrong approaches):

Rhino expects lines in macro text files to end in linefeed+carriage return, just like Windows text files. If you paste a normal Apple text file into Rhino nothing happens because the file doesn’t contain linefeeds.

If you make a mistake in a macro, Rhino stops processing the macro file. Error reporting is minimal.

When a macro command doesn’t work double check the Rhino commands help file. Then triple check it. Sometimes Rhino expects three values for a point (origin of a rectangle, for instance). Sometimes two (second parameter for a rectangle, for instance).

Points gave me headaches. You can shorthand a point at the origin with a simple “0” but I found it better to always write it “0,0,0” to remind me that it is, in fact, three values. Why would I get confused? Because circles and rectangles are two-dimensional. I would forget about the Z axis.

Selection commands – SelLast and SelName, for instance – add to the current selection.

Sometimes you think something is selected but it’s not. Make a circle. It’s not selected. You have to use SelLast for further processing. Feeding your macro one line at a time into Rhino is illuminating.

Sometimes a command wants parameters (BooleanIntersection) and sometimes a command can operate on selected objects with no parameters (BooleanUnion).

Some commands require input with a _Pause parameter (FilletEdge, TextObject).

_-PlanarSrf is not the same as -_PlanarSrf. The second version is an error.

If you paste a ginormous macro into the Rhino command field all hell breaks loose. Actually, your Views are reduced to two, you lose proper perspective and you’ll never do that again. The solution is to close the file and shorten your macro. This is a bug in Rhino 5.0.2 and will hopefully one day disappear.

Two pages were hugely helpful during development: Command Macros and Scripting and A Basic Tutorial on Creating Macros. Also Python Scripting for Rhino and Grasshopper.


Hi Pete-

Running SelLast with a dash in front allows you to modify this behavior. but yeah, general Sel* commands do not replace the current selection.

Also, w0,0,0 forces the World origin (or World - as opposed to local CPlane - coordinates in general).


Hmm, interesting, I wrote the following quick macro in TextEdit (on Mac):

!_ Box 0,0,0 10 _Enter _Enter

Copying and pasting this directly into the command line would not create the box until I hit Enter in Rhino - then it would execute; if I saved the file on the desktop from TextEdit, and ran it via ReadCommandFile, it worked immediately… Funny “bug”.

Normally, if there is no third coordinate, it is interpreted as “0”.

! _Circle 10,10 25

Works fine. The plane of the circle will be whichever is active when the macro is launched, however, so to make certain where the circle is going to be created, it’s better to force world coordinates and use all 3 values - and then you still have to make sure the correct view CPlane is active before running.

! _Circle w10,10,0 25

After you play with complicated macros for awhile, it will increase your desire to learn some scripting… :stuck_out_tongue_winking_eye: