Pen plotters are an attractive tool and toy for anyone interested in computer graphics or generative art. The simple machines draw with a pen or pencil on paper under the control of computer code. Possessing infinite patience, such machines can build up complex imagery defined by digital information or rule systems.
Thanks to products like the AxiDraw and open source designs like BrachioGraph it's easier than ever to get started playing with pen plotters to bring generative graphics into the real world. But once the have the pen plotter what are you going to have it draw? It can be interesting to render mathematical entities like fractals and geometric patterns, but what if you want to create complex graphics and have precise artistic control over the design? One option is to use Blender, the 3D creation tool, to create your design and then convert it to what a pen plotting system can draw.
Creating a 3D Model in Blender
It's outside the scope of this article to explain how to use Blender, but if you are just starting out there are many good tutorials out there to look through. If you have tried it in the past and found it hard to use then I recommend giving it another look because the 2.8 release overhauls the UI to make it easier to use.
Let's have a simple scene to use for demonstration:
Here I've started with a sphere and then run it through Blender's cloth simulation. With gravity turned off, some vertices added to a pinned group, and a shrinking factor applied, the sphere turns into a sort of spiky ball. I added a decimation modifier to get rid of some visual repetition and to reduce the number of lines that the pen plotter is going to need to draw later. As a last touch I created a hair particle system with the density driven from the vertex group that I used to pin the cloth simulation to get the lines shooting out from the spikes.
Though my result is not particularly special I had two pieces of inspiration in mind when I was making it that I do think are worth sharing:
On the left is a sculpture by Tomás Saraceno called New Connectome. On the right is an example of the rope trick effect - some microseconds after a nuclear detonation the visible light radiation is so intense that nearby objects, like the guy wires supporting the tower for the bomb, are heated to plasma ahead of the growing main fireball.
Rendering SVGs from Blender
Normally Blender is used with a rendering engine that produces an image made up of pixels. One way to get a vector image suitable to send to a plotter is to trace this rendered image. But that sacrifices a lot of control and can introduce strange artifacts due to the image tracing algorithm used. A much better option is to use the Freestyle rendering engine which is specifically designed for rendering vector images instead of pixel images.
To enable Freestyle you will need to go to the Render Properties tab and check its box. Out of the box it does not export SVGs. That functionality must be enabled via a built-in add-on called Freestyle SVG Exporter. To enable an add-on go to Edit>Preferences>Add-ons.
With both boxes checked and something in view of your virtual camera you can start rendering to SVGs. Just hit render and Blender will first render an image of your scene as usual but will then follow up with the lines generated by Freestyle. Your SVG will be in the output directory specified in the Output Properties tab next to the rendered pixel image.
You might get a strange result on your first attempt with a haphazard selection of lines because of the default rules that Freestyle uses to identify lines in your scene that it should draw. Head over to the View Layer Properties tab and scroll down to the Freestyle Line Set section to adjust those rules.
In my experience the process of getting Freestyle to render the exact lines that you want is fairly finicky and unintuitive. But through experimentation you can usually end up with what you want. Some tricks and info I've found helpful:
- To get only specific edges to render: If you are in edit mode with some edges selected and hit ctrl-E you can select "Mark Freestyle Edge". Then create a line set that selects by edge type with the "Edge Mark" option selected.
- Freestyle will not render edges that are not part of faces. If you want standalone lines you can turn the geometry into curves and then use the bevel option with a tiny triangle or other shape to sleeve your lines with faces. A downside is that you will then need to delete the extra lines in the final SVG or the plotter will go over them repeatedly.
For this render I wanted to try putting something in the "middle" of the shape in the physical plot so I generated two different SVGs using separate line sets. The first was all of the lines visible from the front and the suspension wires. The second was the lines on the back side. That way I could first plot the hidden lines, then add my manual intervention, and then plot the second SVG to finish the work.
Optimizing SVGs for Plotting
SVGs are "scalable vector graphics", so they have the vectors that we can translate to the motion of the plotter. But plotters have specific constraints due to the nature of the physical drawing process that they carry out:
- Speed and acceleration affect the accuracy and graphical qualities of the plotted artwork. For example a ball point pen moving fast may make a lighter mark than the same pen moving slowly because the ink on the tip is depleted faster than it is replenished.
- The order that the vectors are drawn in can have a very large effect on how long the plotting takes and how the resulting image looks. The plotter cannot instantaneously jump between the end of one line and the start of another, so it spends some of its time just moving and not actually drawing. We can reduce the time that plotting an image takes by optimizing the order the vectors are drawn in to minimize the travel time.
The first constraint has aesthetic implications so there is not one standard approach to take but it does imply that we will at least want control over the speed and acceleration of the motion that the plotter uses to render our image.
The second constraint represents a problem to solve. Usually we will want to minimize the time that it takes to plot our image because even fairly simple images can take hours to plot if they have many lines.
We can reduce the plotting time by sorting the paths such that a path which ends where another path starts is placed just before the second path. Once the paths are sorted we can then merge the connected paths so the plotter can just follow the entire merged path without lifting the pen. This simple approach isn't guaranteed to produce an optimal time because the order of the resulting "chunks" also determines the overall time, and there can be multiple ways to chunk the image. Interestingly, this problem is the traveling salesperson problem in disguise. Solving it optimally can be very computationally expensive for complex images. Thankfully usually it's fine to just solve for "good enough".
A good tool that can optimize our SVGs is vpype. It's a Python utility designed with plotting in mind that has a chain-able command syntax for doing operations on SVGs.
Here's an example invocation that will take the SVG from Freestyle and generate a plotter-optimized and resized SVG:
vpype read render.svg scaleto 50cm 50cm linemerge --tolerance 1mm linesort write plot.svg show --colorful
Plotting the SVGs!
I'm using a painting machine created by the artist Jeff Leonard but this step will look similar on an AxiDraw or pen plotter. Jeff's machine is controlled by an Arduino so I wrote some firmware to execute plotting commands received over serial and a small Python program to generate those commands from an SVG and send them.
During the plotting process I was controlling the height of the brush with a knob to try to keep the line width consistent, or at least keep the brush in contact with the paper. And I was pushing a button every once in a while to pump more watered-down ink into the brush head. Here's what the plotting process looked like:
And here's the resulting plot:
Where to Go Next
Ordered an AxiDraw v3! Working on a small dev environment for generative plotter art, including a Blender import function. 😀✏️ pic.twitter.com/vPjqmFIN5h— Matt DesLauriers (@mattdesl) January 30, 2017