OpenSCAD the Programmers Solid 3D CAD Modeller
openscad.org
openscad.org
The more powerful option is something built on the open-source Open Cascade geometry kernel: FreeCAD, cadquery, or build123d. This also gives you interop with the broader CAD ecosystem by enabling you to import and export STEP files. (Your favorite LLM can advise you on or drive these options as well.)
The awful thing about OpenSCAD is that one's capabilities in it are bounded by one's fluency in using math to place or stretch cubes, spheres, and cylinders.
- Geometry: https://www.goodreads.com/book/show/58059196-make
- Trigonometry: https://www.goodreads.com/book/show/123127774-make
- Calculus: https://www.goodreads.com/book/show/61739368-make
https://www.makershed.com/products/make-physics?variant=5041...
I went ahead and placed an order.
Hopefully it will arrive in a reasonable timeframe.
If you want to make a complex gear that has to mate with another gear you can do this in two ways: you can start with two discs intersecting at the right angle and then to chop out the teeth so the resulting object will be a gear and then you could subtract via a similar operation from the other disc to end up with two mating gears.
The - in my view much more effecient - alternative is to start off with just the supports as the discs and then to parametrically add the gear teeth onto the supports taking into account all of the clearances and the contact faces. This will get you much better gears because you are parametrically describing the surfaces that really matter and it will allow you to do nice things such as small fillets on everything to make the object far closer to what eventually will roll out of your manufacturing process (machining, 3D printing). It is a bit more work to define all of the parameters but the end result is much better and far less likely to have imperfections because you are generating what you want, not removing what you don't want. OpenSCAD can be used for sculpting, but that's not the best way of using it.
but what made me use scad was reliability. i knew the time i put writting in vim would translate (heh) into a viable stl file i could send to manufacturing. while with both other options half the time was dealing with bugs and crashes and bad exports.
but how did i miss some convenience tools indeed. most could be solved with opensource methods (e.g. bevel, joiners with easing, threads)
to be honest, my anger was much heavier on solidworks for being so expensive (i had a student licensw tho) and buggy.
And then the worse is better trap gets them and they don't even bother looking for true programmatic CAD like build123d.
I think that's an unfair assessment. It has rough spots (as I'm sure all CAD software does) but it's functional and UX is improving rapidly with every release. It feels like it's built up a lot of momentum since I picked it up a few years ago.
It can do everything I need it to do. I mostly use the Part Design workbench, Part, Sketcher, Assembly, Lattice2, Fasteners, Spreadsheet; occasionally Curves and Curved Shapes workbenches. If I run into an issue the solution is almost always easy to find on their wiki, on Youtube, or by asking in their Discord server - the community is friendly and helpful in my experience.
Mango Jelly's overview of some of the biggest new features: https://www.youtube.com/watch?v=WdTyFHY-5r4
I actually still use the freecad gui because it’s cheaper but I can totally see how someone new might just wanna use the MCP.
I tried to follow along w/ a book which was purportedly for 1.1, but it turned out to actually cover 1.0
The wiki tells you what the tools do. For learning how to use those tools to model something, YouTube channels like Mango Jelly's are a better bet. The pace of FreeCAD development has definitely picked up since the 1.0 release
In the past when I've looked there were a _lot_ of pages tagged as needing to be updated to 1.1 --- a quick search seems to indicate that enough pages have been updated that I couldn't quickly find any tagged as needing that for 26.3 which is a marked improvement.
I'm not patient enough for videos (though I have watched a fair number, they're just not clicking) --- I do far better with traditional documentation where I can walk through things at my own pace --- but I need for said docs to correspond with the UI of the application I'm trying to learn (hence my disappointment in the afore-mentioned text).
What I've found pretty handy for learning FreeCAD is finding an existing model and messing around with it to see how the original creator did stuff. That's where I started with my pinball cabinet. Once you get the basics down it is much easier to pick up on new features, many of which are enhancements to existing functionality.
That's an interesting approach, and I'll definitely keep it in mind --- maybe 26.3 will finally be the version where I learn FreeCAD.
I will note that I was moderately successful w/ Dune 3D on the basis of its quite nice textual documentation:
That said, it's pretty easy to just output an STL from OpenSCAD, open it in a 3D CAM tool (Kiri:Moto is a free option, MeshCAM (ob. discl., I work for a distributor) paid) and get toolpaths.
Folks have worked up various other approaches --- I've been using PythonSCAD to output a DXF which can then be used for making toolpaths:
Don't get me wrong, I love it myself and use it as much as possible simply because it's outstanding to be able to express a complete design in 1k of plain text which is readable, diffable, gittable.
You can get a lot done, and some things you can do even easier and simpler than anything else, and you can work-around some things, and you can get a good-enough almost-what-you-want other times, and it's practically ideal for certain classes of jobs as long as you're willing to live within the limits.
But "live within the limits" is not something a general purpose tool gets to say.
You can get some fillets easy sometimes if the geometry just happens to lend itself to some boolean op like making a rounded corner hollow box by hulling 8 spheres (which you can populate effortlessly with translate,copy,mirror) and then cutting another smaller copy. Voila, all kinds of interior and exterior fillets in like 10-15 short lines of plain text code. And the whole thing fully parameterized with dead simple variables sitting off by themselves with human descriptive names at the top of the file.
But that does not mean anything. That's a choice showcase example, and all the other infinite real life cases are somewhere between agonizing to code, to agonizing to code and agonizing for the computer (minkowski), to flat impossible.
I love openscad but this implication that it's just a matter of using it right is false.
Writing now about it, I think I could do it with a torus, where the radius of its cross section is the small radius, the torus radius is the large one, take two of them, add two cylinders to only keep one quarter edge and then take a quarter of the resulting bevelled disk.
If I have to build points up by hand, why not skip OpenSCAD and directly write python scripts that create your OBJ files? The point of OpenSCAD et.al. is to programmatically create geometry. Making exactly that easier is a feature in my eyes. And that means you provide/support multiple modeling paradigms that can expressively combined.
OpenSCAD is super cool and my go-to for simple things, but for anything more involved than a cube or cylinder with some cutouts I tend to revert to "normal" CAD programs.
As a long-time OpenSCAD user, I don't disagree with you but would also point out that LLMs can now make it very easy to do a lot of this sort of thing while still using OpenSCAD.
I actually find Gemini/agy to be the best of the ones I've tried when it comes to working with OpenSCAD code. And I don't recommend trying to use LLMs to one-shot geometry of anything complicated, but they are great for things like "take this OpenSCAD code and generate a fillet along these edges, abstract the fillet into its own module and make it parametric so I can easily modify the radius".
Granted, selecting a few faces or edges in a GUI CAD program and clicking a button is even easier than that, but only once you've spent a lot of time learning how to use the CAD GUI (which, IMO, are nearly universally very unintuitive until you've spent a lot of time working with them).
One use case I was interested in: coming up with a (simple) box with cavity in it, and having this CNC'd. (For a simple custom keyboard shell).
Although OpenScad can express the geometry of the geometry without difficulty, it was burdensome to export the .step file that the CNC manufacturer wanted. To my understanding, CSG's model is just fundamentally different than what .step wanted. And re-using the geometry for a technical drawing to communicate e.g. threading wasn't something OpenScad could handle smoothly.
I haven't quite ported this to build123d. But, from a cursory look asking an LLM to do port my code, I was given the impression that it could manage the task. (Certainly build123d was better suited to technical drawings).
I absolutely despise STL as a format and think it doesn't have any place it should be used.I have a hard time taking OpenSCAD seriously due to this.
Also, in many cases, extruding an SVG works wonders. Just design the flat projection in something like Inkscape, interactively, and then import and extrude. You can do this for many shapes, then combine or subtract, etc.
But the other thing is, I have found that in many cases I don't need fillets at all; when printing small parts on a consumer-grade 3D printer, the relatively low precision of the printer is enough to round the edges.
Never tried OpenSCAD, maybe I’m old fashioned but graphic workflow works better for me.
- treat the CSG as merely a 3D preview, output a DXF, use a traditional CAM tool to create toolpaths from that file --- I did work up support for arcs, and am looking into more general curve support
On the plus side, I like these things about OpenSCAD:
* The software is open source, so price or pirating are not barriers, you can use it as much as you want on any computer you want for as long as you want, and it can never be taken away from you.
* The program is small and easy to download, not some multi-gigabyte sprawling software package.
* I think you learn to declare variables for parameters very early on, and it feels natural to make every design parametric from the start.
* The textual nature of 3D models means that I can use Git version control, diff between versions, and leverage similar developer-oriented tools that I use for general programming. I suspect that CAD programs that use binary file formats will have to come with their own diff tool and version control system.
* By reading source code, it's possible to follow the thought process of how a 3D model is constructed, and carefully make modifications in the middle of a chain of operations that later operations depend on. In point-and-click CAD, it's not clear to me if it's possible to change things in the middle of a chain.
* The Manifold renderer is so much faster than the old CGAL, resulting in reasonable human-interactive cycle times.
* I ended up writing my own library to cover a bunch of common shapes / use-cases. It does take some effort the first time, but then I keep reusing the results.
This guy publishes simple tutorials on how to deal with the unintuitive FreeCAD parametric design workflow:
https://www.youtube.com/@4axisprinting/videos
If you have a long-term project... storing the exact FreeCAD version installer in the artifacts folder for precise compatibility is wise. =3
(I recommend CQ-editor for an easy install: https://github.com/CadQuery/CQ-editor/releases/)
It's a similar idea to OpenSCAD, but embedded in Python and using a better geometry kernel. Want to fillet a box in OpenSCAD? Sure, either take the convex hull of 8 spheres, or the minkowski sum of a box and a sphere. Want to fillet a box in CadQuery? .edges().fillet()
Now I'm hearing some protests about Python, but consider this example OpenSCAD code:
x = 1;
echo(x);
x = 2;
In most languages you would expect this to print "1". In OpenSCAD, the last assignment wins and it prints "2". x = 1;
a = 2;
echo(x);
x = a;
Errors out with "line 1: a is not defined", because the override is implemented as is the tokens were present wherever the first declaration is. (If anybody looks up me, you'll see I've made a bunch of contributions and bitched about this particular thing which really fucks up a bunch of optimizations you'd want to do)Many CAD programs incorporate parametric modeling, scripting languages, or Scratch-like "block programming" tools for when you actually need flexibility for a specific assembly. But that's where it belongs: an add-on for an interactive modeler. You don't need to write code draw a helix, but if you need a variable number of scaled copies, there's a parametric tool for that.
I guess these tools may be useful to LLMs because it's cheaper for them to generate a program than to perform computer-use tasks in a UI. But I wouldn't recommend humans to start with OpenSCAD.
I use https://replicad.xyz by the way, in Typescript. No affiliation, just a happily productive user of a fantastic MIT-licensed project. I don't use LLMs at all, for better or worse.
Ps. Replicad does make you write code to draw a helix, but it's just sketchHelix(pitch, height, radius)
The most important thing about OpenSCAD for programmers to remember is that it looks as if you are programming but really you are describing geometry and objects so things like variables and such do not quite work in the way you would expect from a programmers point of view.
To put it another way, it's a purely functional language in a very strict way that takes some getting used to.
Some of the things developed in the project I used to modify my commercial PnP to use the Siemens feeders (Bilsef's controller board). [1]
So a project that came from our project is being used to mod my machine to make more boards for the original project :) Circle of opensource.
If you have any posts related to your mods that you can share I would like to read them to see more about what people are doing.
[1] https://www.robosprout.com/a-story-of-right-to-repair-hackin...
I'm a novice at OpenSCAD still despite doing a bunch of small projects with it recently. Can you give an example of this happening? Most of the confusing stuff so far has been geometry breaking my brain and not some kind of scope issue.
This can lead to extremely annoying bugs because your brain is wired to read and understand this stuff sequentially rather than all at once. I've stared at some page of OpenSCAD code for a long time before realizing that it was yet another one of those footguns.
I bought a 3D printer (which is basically simpler and more reliable than a 2D inkjet printer by now: it's send the file, put the filament, and 3D print and it just works) recently and already fixed shitload of stuff around the house with 3D printed parts.
I even did "print in place" pieces where you add a pause a a certain layer, insert "stuff" (like say a 3D metal angle) into your print, then finish your print. Effectively creating parts that are both plastic and metal.
Now the language itself in OpenSCAD is kinda really bad: you can define variables inside of other functions and then use them everywhere. You can redefine already defined variables and you'll get zero warning. The language itself is really pretty WTF.
But you get modelling for free as a programmer. And LLMs are okay'ish at it for simple stuff.
I'd recommend people to use the BOSL2 library for OpenSCAD:
https://github.com/BelfrySCAD/BOSL2/wiki
It's really not hard.
If you love programming and like to DIY stuff around the house, buying a 3D printer and learning some OpenSCAD is a no-brainer.
OpenSCAD ain't the only option: many people like Fusion (for example). But as I'm a dev, OpenSCAD just feels natural to me.
Check out my repos of OpenSCAD objects at https://github.com/jeffbarr/OpenSCADObjects and Truchet Tilings at https://github.com/jeffbarr/TruchetTilings .
My code kind of looks like the C that I wrote in the 1980s, with lots of braces and careful indenting -- not sure if that is a bug or a feature.
As another commenter noted, use the latest nightly build for best results.
As an example, the dentist's square code looks quite reasonable to me (I'm a python programmer by choice):
"""
dentist_square.py
=================
CADQuery port of ``dentist_square.scad`` -- a "quad from the dentist's office":
four small hollow squares in a 2x2 grid plus one larger hollow square in the
centre, each with a thin rim on top.
"""
import os
import sys
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import cq_common as C
# ---------------------------------------------------------------------------
# Parameters (from dentist_square.scad)
# ---------------------------------------------------------------------------
_EDGE_WIDTH = 3.5
_SMALL_SQUARE_WD = 18.5
_SMALL_SQUARE_H = 2
_BIG_SQUARE_WD = 28.5
_BIG_SQUARE_H = 2.6
_SMALL_SQUARE_SPACE = 22.5
_RIM_WIDTH = 0.4
def hollow_square(wd, h, edge_width):
"""A hollow square: a ``wd x wd`` box with a centred hole of
``wd - 2*edge_width``."""
outer = C.cube(wd, wd, h, centered=False)
inner = C.cube(wd - 2 * edge_width, wd - 2 * edge_width, h + 0.01, centered=False)
inner = C.translate(inner, (edge_width, edge_width, 0.0))
return C.difference(outer, inner)
def hollow_square_with_rim(wd, h, edge_width, rim_width):
"""A hollow square with a thin rim (a second, thinner hollow square) on top."""
base = hollow_square(wd, h, edge_width)
rim = C.translate(hollow_square(wd, 0.2, rim_width), (0, 0, h))
return C.union(base, rim)
def four_hollow_squares(wd, h, space, edge_width, rim_width):
shapes = []
for x in range(2):
for y in range(2):
sq = hollow_square_with_rim(wd, h, edge_width, rim_width)
shapes.append(C.translate(sq, (x * space, y * space, 0.0)))
return C.union(*shapes)
def five_square(small_wd, big_wd, small_h, big_h, space, edge_width, rim_width):
center = (space + small_wd) / 2.0
four = four_hollow_squares(small_wd, small_h, space, edge_width, rim_width)
big = C.translate(
hollow_square_with_rim(big_wd, big_h, edge_width, rim_width),
(center - big_wd / 2.0, center - big_wd / 2.0, 0.0),
)
return C.union(four, big)
def main():
return five_square(
_SMALL_SQUARE_WD, _BIG_SQUARE_WD, _SMALL_SQUARE_H, _BIG_SQUARE_H,
_SMALL_SQUARE_SPACE, _EDGE_WIDTH, _RIM_WIDTH,
)
if __name__ == "__main__":
shape = main()
out_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "stl")
os.makedirs(out_dir, exist_ok=True)
path = os.path.join(out_dir, "dentist_square.stl")
C.export_stl(shape, path)
print(f"Exported {path} (volume {shape.Volume():.2f} mm^3)")https://github.com/yuechen-li-dev/Aetheris/
Not an OpenCascade wrapper, it's based off my own experimental BREP geometry kernel. So, fillets/chamfers work, booleans works fairly robustly, surfacing, sheet metal, etc all works decently, it exports STEP AP242 by default.
Haven't had time to get the AIs to write a more up to date documentation and polish the language server. Not the easiest thing to use right now, so, using it through Codex/Claude Code or CLI is probably the easiest way to get started.
Still working on the webUI currently, in case someone want to DIY the UI. Note that the WASM compilation path is still unoptimized and way slower than the RyuJIT C# compilation though.
I'm not going to pretend this is easy: I actually quit multiple times for this project because I ran into the same walls that everyone else ran to: arbitrary 3D boolean operations is HARD,(Surprisingly, I actually didn't have that much trouble with fillets/chamfers because I kept them pretty bounded) and the approach I've finally taken to solve it is pretty insane. Essentially, the final architecture is more like "LLVM for 3D objects" compiler stack than it is traditional BREP kernel. Would love to talk about the technical deep dives if people want to hear it.
Also, feel free to write UI wrappers around it, because I'm pretty bad at UI design myself.
It doesn’t need to be perfect on edge cases just translate back “reasonable” models.
Should be something that is fairly easy to eval etc.
I wish there was an easier way, but I've spent weeks during the course of the project working on and failing to solve a similar problem (SDF to BREP) and concluded finally that there just isn't an easier way to do this fully automated without AI.
You can ask your LLM to try it with one of the OCCT wrappers or with my thing, I think Aetheris is slightly better because we added more STEP diagnostic tools like ray query depth detection and SVG sectional view during the course of development.
Here're are some SIGGRAPH 2026 papers attempting BREP recovery, if you are interested. None of their automated approaches seem to work reliably, and they can only recover generic NURBS instead of analytical geometries like circles/cones/torii, etc.
https://github.com/AutodeskAILab/DualBrep https://github.com/yilinliu77/Brepler https://rilpraa0110.github.io/Img2CADSeq/
Also prone to robustness and quality issues. You're better off outputing a BREP directly.
The bigger issue is that OpenCascade is error tolerant to a fault, which allows it to import a lot more legacy geometries, but it also means that it silently exports a lot more bad geometries much more often than commercial kernels
So, there's a reason why commercial solutions don't really use OpenCascade over ACIS/Parasolid for authoring.
I have built FluidCAD[1] to overcome the issues of CAD by code, less mental effort to design by providing visual guidance. Slowly it became more of a hybrid CAD experience (mouse or code driven), almost all features now can be done by mouse and the code is generated for you. It'll pick the right selection filters for you.
Build123d could really benefit from being able to add features interactively (including explicit constraints) and options like freecad and Onshape could really benefit from explicitly representing the model as code.
Build123d seems to require a lot of coding to calculate constraints and positions that could be more easily expressed using something like the solvespace constraint engine and some construction lines.
If you want the same script support, but also have an actual tool that can take over when your model is no longer symmetrical, free CAD works v well.
You can enable OpenSCAD support, but I really don't think it's more efficient at getting me to my final geometry.
It's not as bad as it looks, it's all automatic except adding colors which takes about 2 minutes.
It's exactly the same as "regular" programming: you have ways to abstract things (projections, imported components, linked copied components), there needs to be a reasonable architecture (the way dimensions and constraints are flowing off each other), it's possible to write "tests" (driven dimensions are a kind of a test if you squint). It's just not explicit text, which throws people off.
Parametric CAD, in my view, is a perfect example of ``visual programming'', you have variables, iteration/patterning reducing repetition, composability of objects/sketches again reducing repetition, modularity of design though a hierarchy of assemblies. The alignment between programming principles and CAD modelling principles, while not immediately obvious, are very much there. An elegantly designed CAD model is just as beautiful (in its construction) as elegantly written code.
Yet I tried alternatives and found them way too complex with their UI. I have a FreeCAD tutorial bookmarked so when I find a dozen hours to learn it I will. In the meantime when I need something simple and quick, OpenSCAD gets me there.
I'll have to add this to my backlog of experiments to try when I have unused tokens near a reset...
If you just need to tweak the dimensions in the script, or are satisfied with describing the changes to the LLM and having it modify the script, there isn't much difference in practice between a generated OpenSCAD script and a Blender python script.
I made a rust-implementation of openscad called openrscad (https://openrscad.com). It still has some rough edges, but runs quite fast both on desktop and in the browser
As noted, use the Nightly builds from: https://openscad.org/downloads.html#snapshots
When working with kids, it's well worth keeping: https://www.blockscad3d.com/editor/ in mind, or for folks who like to draw connections: https://github.com/derkork/openscad-graph-editor
Eventually, someone will note that its programming model limits variables and so forth --- for folks who want a more traditional language choice there are a number of options, notably for Python:
For me, modeling is just as much about figuring out the shape and features of an object as it is producing a STEP. I would love to model an object in a GUI then re-edit the file with code and re-render with a library, not the least reason being that GUI tools render multiple orders of magnitude faster.
[0] https://github.com/mwood77/osww [1] https://imgur.com/a/bWent0K
Soft-fork which bolts on Python:
So here is my shameless plug "sograph": https://imgur.com/a/u1n2Grg
I should consider a Show HN instead, but it is too early to release yet.
https://github.com/derkork/openscad-graph-editor
(though you'd want to import BOSL2 to do fillets and so forth)
https://news.ycombinator.com/item?id=49960138
there have been a lot of free CAD tools being developed (many of them posted about here), but no one seems to have tried the traditional interactive interface approach w/o at least a text-based layer. My suspicions on this would be:
- adding the text-based description allows using an LLM to create models
- Fusion 360 and OnShape have taken up most of the oxygen in the room for '"free" traditionally interactive CAD'
- the UI is _hard_ --- poster child for this see the marketing for Plasticity XYZ (which seems to be a derivation of Moment of Inspiration 3D)
I’m thinking of something like finite element analysis… but, I guess since the shapes in OpenSCAD are defined through this constructive geometry system, can things be better/more mathematically defined general purpose “discretize the PDEs over my mesh” type solutions?
Now there is a method called Isogeometric Analysis (IGA) that was meant to improve this. It uses NURBS functions (just like CAD) for the shape functions of traditional FEM. The idea was that now, if you have NURBS describing the CAD geometry you can skip meshing and just directly calculate on the real geometry. But it did not catch on. The reason being basically, as far as I remember, was that most CAD geometries of interest are not pure NURBS. But they are operations of NURBS (think cube minus some other cube - trimmed surfaces). And IGA has problems with that.
This is a problem that openSCAD will probably also not be able to overcome. Maybe at times it might be easier to create NURBS geometries without trimmed surfaces. But most probably that cannot be done in most cases of real world significance.
I have to disagree somewhat. Engineers rarely run a single simulation, rather they do convergence studies. For some problems, it might be fine to refine while keeping the same geometry (since you have no arbitrarily accurate continuous representation), but not all.
So, yes, you can run toy simulations on any mesh, but I don't think any serious shop will consider a workflow where CAD is completely inaccessible.
There are some ways around it but the cure might be worse than (or rather just as sophisticated as) the poison. Like extrapolating what the geometry might be with high-order elements or fitting NURBs.
https://github.com/joewalnes/toybrick
LLMs are excellent at building OpenSCAD models. The tutorial (written in the before-times) will help understanding of the key concepts of OpenSCAD: primitives, transformations, and constructive solid geometry.
People keep saying I should use other kernels for fillets and stuff, but from my testing AI is just not as good with, for example build123d as it is with OpenSCAD.
[0]: grandpacad.com
The only difference between that and openscad is human readability imo. Openscad may be more designed for humans to program and read while CAD save files are just hard to read.
Human readability is only a human problem though. Your LLM in theory if trained on enough CAD data should not have this problem.
https://old.reddit.com/r/3Dprinting/comments/1hrpusu/i_am_fu...