I was doing some work on tire dynamics while planning a vehicle physics engine. In the course of that project I wanted to visualize some triangles. Easy right? If you saw my previous post about learning Blender you’d think that would be especially easy for me. But strangely, it was not.

In Blender you can make an equilateral "circle" with 3 sides. You can make an icosahedral sphere (made of triangles) or a triangular fan or a cone made of triangles. You can create triangles out of rectangles with quads_convert_to_tris() or poke() and then delete the triangles you didn’t want. But simply generating a lone arbitrary triangle is weirdly hard to achieve. It is weird because from a computer science standpoint, 3d computer modeled geometry is composed only of triangles.

How about three 2d lines? Amazingly, no. Blender is also not at all ideal for modeling a simple pair of endpoints connected by a line. Weird, right? I was actually so blown away to learn this that it kicked off an odyssey of heroic software engineering designed to sort this out once and for all. That odyssey is today’s story!

I had been working on learning the arcane art of controlling Blender with Python. That topic was exactly as confusing and muddled as I expected for such a baroque piece of software. But doable. And speaking of baroque, after some experiments with Blender’s Python console, I started to have a dangerously stupid idea…

It turns out that I, Chris Edwards, have written a geometric modeler. It is called GeoGad, short for Geometry Gadget. I started this project in 2004 and until about 2014 it was really only a programming language. Yes, that’s right, a programming language. A delightful Turing complete bad-ass programming language that I’ve used pretty much every day since 2004. I know it’s bad-ass because it was heavily inspired by HP calculator RPL and if you think that was not bad-ass, you’re an idiot.

The GeoGad logo is a triangle. And yes, GeoGad’s mascot is a sloth (Motto — Slow but happy and lovable).

In 2014, I added the geometry model and its functions to the language. In my system, geometry can only consist of simple lines and triangles. The lines are visible and the triangles exist only to provide occlusion reference i.e. allow for hidden line removal. And that hidden line removal was done by a Unix command line rendering engine called to2d. That C++ program is the most obscure rendering engine in the world because I wrote that too. While developing the geometry capabilities of GeoGad, I would pipe the raw geometry model to to2d and then dump the resulting 2d vectors in a file formatted as SVG. I could have a browser constantly polling and reloading this output and there was a display system. But that was not very user friendly, even for users like me who have different ideas about what friendly means.

At this point in the story:

• I wanted to do some simple geometry that is overly complicated in Blender and which GeoGad is especially good at.

• I was playing around with Blender’s Python interpreter.

• GeoGad is written in Python.

Hmmm…… Could I maybe run GeoGad inside Blender? It turns out, the answer is yes! Check out this screenshot.

This shows how I tell the Blender Python interpreter where GeoGad lives by editing the sys.path variable. Now this Blender Python can import the important components of the GeoGad system (you can see these exact components in a similar project, dated 6 years after mine, by Peter Norvig, Google’s Director of Research).

With GeoGad’s code ready to run there was just one problem — the Blender Python interpreter did not implement the Python input command. This means I couldn’t just run GeoGad interactively like I normally do. It may be possible to hook up interactive input to some GUI element, but for now I simply define a function gg() that takes as input a string of GeoGad code. And it’s ready to use! I start by running the GeoGad version command to demonstrate that everything is hooked up.

The next couple of commands import GeoGad’s memory model output code. If I’m running a text only version of GeoGad, I don’t ever need to send the memory model (the geometry) anywhere special. But the real point here is to actually control Blender. So this passes a hint to the output code about where it can use Blender functions.

And finally, I demonstrate a classic programming language test.

0 1 |[dup2 +::!] 18 repeat

Can you figure out what that complete GeoGad program does? The answer and a nice comparison to other languages can be found here.

I’ve been making this look easy, but in reality, this has been a real grind. The first obstacle was that Blender, sensibly, uses Python3. In 2004 there was no Python3 and I took this opportunity to convert the entire GeoGad code base from Python2. The next ordeal was figuring out Blender’s interface functions and what might work. Blender uses a list of points and refers to them by their position; I use a dictionary of points and refer to them by numeric ID. My way allows everything to work without changes if some points are removed from the collection. The funny thing is that both ways are the same until some points are removed. I spent quite a while figuring that out while sometimes it would work and sometimes I would get a Blender seg fault.