Three-Dimensional Prints with Blender and OpenStreetMap
Table of Contents
Summary⌗
I used blender-osm
and Freestyle to render three-dimensional geodata from OpenStreetMap to a pen plotter.
Here is the finished product, a 11in x 17in print on vellum. (Click through for high resolution.)
![](images/full.jpeg)
Here is an overview of the data pipeline I used to generate this print:
┌─────────────┐
│OpenStreetMap│
└┬────────────┘
│
┌▼──────────┐
│blender-osm│
└┬──────────┘
│
┌▼──────┐
│Blender│
└┬──────┘
│
┌▼─────────────────────┐
│Freestyle SVG Exporter│
└┬─────────────────────┘
│
┌▼──────┐
│AxiDraw│
└───────┘
OpenStreetMap⌗
OpenStreetMap is a Wikipedia-style repository of map data. I have used it before to download and print map data with a pen plotter. It contains high-quality, free, volunteered and compiled 2D and 3D geodata about the real world.
blender-osm⌗
blender-osm
is a plugin written by prochitecture
which imports geodata from OSM into Blender, a free 3D computer graphics software suite.
After installing the plugin and using it to create a new document, blender-osm
links the user to an area selection website which makes it simple to select an area of the map to download.
![](images/blender-osm-selection.png)
We can copy/paste the lat/long area selection (in this case, a string like -74.02041,40.73327,-73.98792,40.75015
) into the blender-osm
interface and select which map layers to import (buildings, forests, water, etc.)
Blender⌗
We end up with a detailed 3D model…
![](images/blender-nyc-overhead.png)
…but of course it looks better in perspective.
![](images/blender-nyc-perspective.png)
I knew I wanted to draw a multicolor print, so I grouped the downloaded layers by pen color. All the buildings went in one group, all primary roads in another, etc. Later I print these layers on the plotter one by one, swapping out the pen in between layers.
![](images/blender-nyc-groups.png)
Using separate object collections means we can toggle on/off items by layer in the Blender UI. Here is a render of the map with only 3D buildings visible:
![](images/blender-nyc-buildings-only.png)
and another render of the map with only primary and secondary highways visible:
![](images/blender-nyc-roads-1-only.png)
and another render of the map with only pedestrian roads visible.
![](images/blender-nyc-roads-2-only.png)
Of course, we can render this for any combination of the layers.
The result is a 3D model in Blender which can be exported as a raster image or as an animation. But the pen plotter expects vector data, so we have to use a plugin.
Freestyle SVG Exporter⌗
Freestyle is a Blender plugin which plots the edges of visible objects as SVG lines.
This is perfect for pen plotting, since pen plotters expect vector input.
Freestyle is very powerful but a bit hard to use. First I enabled it like so:
![](images/blender-freestyle-enable.png)
Then I played with the settings until it handled crease angles in the way I expected.
![](images/blender-freestyle-settings.png)
I also applied a Bezier filter which gave the finished edges a cartoonish curve.
![](images/blender-freestyle-settings-2.png)
It’s hard to tell the effects of these settings until Blender actually renders the scene to SVG.
Camera⌗
Finally I played with the camera location and perspective settings until I had a scene composition I liked. The focal length of the virtual camera makes a big difference:
It is also possible to swap out a perspective camera for an orthographic one, which looks isometric like a video game. This is a nice effect but I felt it gave the scene some undesirable flatness.
![](images/focal-orthographic.png)
SVG⌗
The default exported PNG has both the raster image and the overlaid vector lines, which makes it easy to see why Freestyle drew lines in certain places.
![](images/png-export.png)
The default exported SVG is what we eventually send to the plotter.
![](images/svg-export.png)
Layers⌗
We can pop into the SVG file and separate the layers manually, since AxiDraw requires printing one SVG file at a time and cannot filter by layer. Here is the layer for buildings-only:
![](images/svg-export-buildings.png)
roads-only:
![](images/svg-export-roads.png)
and highways-only:
![](images/svg-export-highways.png)
Blender rendered these all in the same pass, so objects in the foreground correctly block objects in the background.
Foreground:
![](images/frustrum-foreground.png)
Background:
![](images/frustrum-background.png)
AxiDraw⌗
That’s pretty much it. We can send each layer to the plotter one at a time, swapping out pen colors, and we know that objects in the foreground will appear to obscure objects in the background. Here is the final product:
![](images/full.jpeg)