Fornjot

early-stage b-rep CAD kernel, written in Rust

Why Fornjot is Using Boundary Representation

Fornjot uses a technique called boundary representation (or b-rep, for short). This is the traditional technique, used by many of the big commercial CAD packages, and it wasn't my first choice. In this note, I'd like to explain where I started with Fornjot, and why I ended up with b-rep.

What triggered my years-long work on CAD software was Jamie Wong's article about ray marching and signed distance functions. I quickly came up with the idea of applying this technique to CAD, a topic that had started to interest me around the same time.

Falling in love with signed distance functions

I really liked signed distance functions (also known as signed distance fields, implicit functions, function representation; or by their short-hands, SDF or f-rep), for a few reasons:

As it turned out, I was not the only one to have that idea, but that only encouraged me that the concept had merit. The following years (starting in 2018, I think) I was working on CAD experiments in the background, on and off.

I started getting more serious about my CAD work some time in 2021. I did a serious push to get something to work end-to-end, basically specifying a very simple model, then exporting that model to a 3MF file for 3D printing. I tried different approaches during that phase, some based on signed distance functions, some not.

Falling out of love

In the end, after some pretty intense work trying to get signed distance functions to work for me, I came to the conclusion that they were just the wrong approach for my problem. I basically found that all the reasons I like them in the beginning were nullified:

In the end, I spent a lot of effort and never got a great result. Others have had better success, but that doesn't change the fact that with signed distance functions, advanced CAD modeling features are a complete unknown. As far as I can tell, no one has ever created an SDF-based CAD program with more than just basic features. For all I know, it's impossible.

A new way

All that ended when I created a new prototype based on boundary representation (b-rep). Boundary representation defines solid models by their boundaries, i.e. the vertices, edges, and faces that make up the border between model and not model.

Suddenly things started clicking for me. It's the version of Fornjot that I'm still working on, and that I intend to take all the way to a useful piece of CAD software (and, if I can, beyond). But why am I betting Fornjot's future on boundary representation? I think there are three main reasons:

Getting Fornjot to a point where it is really useful as a CAD program will take a long time, and a huge amount of work. But I'm confident now that I've chosen the right path to at least make that practical.

A third approach

For the sake of completeness, I should note that I'm aware of a third approach: Generating triangle meshes directly from your primitives and operate on those triangle meshes to manipulate and combine them into more complex models.

I haven't studied this approach deeply, but I don't want to go down that route. First, getting those triangle mesh algorithms right is probably complicated. Second, it's unclear to me how fast those algorithms can be. Third, selecting a feature of the model with the intent of manipulating it is probably complicated to support (a round edge is represented by many small triangle edges, for example, so knowing what to select when the user clicks there is unclear).

We'll have to see if I made the right choice. But I can already say, for the first time since starting my work on CAD software, I feel really confident that I'm on a good path to create something really useful. Not just another experiment.