Hacker News new | ask | show | jobs
by GistNoesis 1697 days ago
They are based on two different algorithms, but both should guarantee a topologically correct solid if implemented correctly.

OpenSCAD is based on constructive geometry, which means the compute complexity scales up mainly along the complexity of the CSG tree which can get very big, but the number of triangles is quite low and independent of the resolution. This is not rasterized but the operation on CSG trees partition the space and the number of regions to consider may grow very quickly and this algorithm is very prone to numerical instabilities, like z-fighting between regions.

ImplicitCAD on the other hand is based on signed distance fields rendered with an pruned octtree marching cube. The algorithm is simpler and more stable numerically. The internal representation is of perfect resolution, but to get a triangulated output you need a number of triangles which grows proportionally to the surface of your object expressed in precision required units. But if you skip this triangulation process, using a custom slicer to generate the toolpaths or a ray tracing renderer to visualize it, you can have perfect resolution for very cheap.

The alternative is BRep, but this is a surface representation which don't bring the same topological guarantees, (like non-self intersection).

1 comments

That's very cool, thank you for explaining it to me. I'm curious if there's any downsides to such a scheme for representing solids compared to BREP, and the kinds of primitives it supports. E.g how easily can it represent a loft between two arbitrary faces - it's not immediately clear how to represent that with a SDF (but my SDF-foo is admittedly not very strong).

These are questions that I'm sure will be answered by me reading the documentation more closely.

With two arbitrary faces on the same axis (say z), at locations z1 and z2 and the shape of each face being represented by the functions a(x,y) and b(x,y), you can get a loft SDF L(x,y,z) between a and b by the following math (this is not correct syntax for any tool I know but should make it clear what's happening):

if(z<z1) L=a(x,y)

elif(z>z2) L=b(x,y)

else L=((z-z1)/(z2-z1))*a(x,y)+((z2-z)/(z2-z1))*b(x,y)

For way way more info, you might like https://iquilezles.org/www/articles/distfunctions/distfuncti...

Thank you, however, this is but one kind of loft operations done that are common in CAD. Often you want to control the tangency between the connected profiles, or connect profiles that aren’t parallel, or use a center guiderail (arbitrary spline), or use multiple guiderails along specific vertexes on the profiles.

It’s these complex cases that I understand how to approach with a kernel based around face patches, less so how one could achieve it with an SDF

None of those cases are complicated - your SDF can be defined piecewise so you can have as many control points as you want. There's no fundamental difference between SDF and brep in terms of expressiveness - just breps define undirected surfaces and SDFs define volumes. Whether your tool (based on whichever underlying geometry approach) allows you to do what you want to do with them is another story.
This mostly makes sense to me.

I've been looking at the CAD space for a while, and it seems like tools exist at either extreme of the spectrum from "Point, click, drag" UI and "only code to describe the model" UIs. Rhino might be the exception here, but it's very expensive, and doesn't have the parametric / history preserving properties I'm looking for.

I think both of these extremes have drawbacks, so I've been toying with hybrid solutions that involve both a code editor and a 3D interactive pane. The code is still the source of truth, but the system allows you to interactively draw sketches, apply constraints, select faces etc, and then convert your UI interactions back into their equivalent code.

I've been playing with different ways of representing the models (and how that would inform the "language" the model is described with, and the sorts of operations it would support), but that's a whole different problem that I don't want to get mired in, so I'm looking for the simplest thing that gets the job done.

SDFs are looking like a reasonable solution here, but it's hard to look away when OpenCascade is just sitting there...