Symmetric chamfered extrusion in OpenSCAD

enjoy the quality of the smooth, smooth taper

I like using OpenSCAD, but it has some limitations. While you can linear_extrude() 2D paths into 3D shapes, you can’t get a proper tapered/chamfered extrusion of anything but simple shapes that are symmetric about the origin:

// this is symmetrical …
linear_extrude(height=20, scale=2)square(10, center=true);

// but shift the same square off the origin and this happens …
linear_extrude(height=20, scale=2)translate([20, 20])square(10, center=true);

There are lots of partial attempts at fixing this, many of which end up with ugly results. Some of them even mess up the top surface, which is precisely what I wanted to avoid. My code uses the computationally-intensive minkowski() sum function to replace every vertex of a 2D shape with a many-sided pyramid.

Minkowski sums effectively replace every vertex with another shape, here making a rounded cube from a cube and a sphere:

minkowski() {
cube(10);
sphere(4);
}

One feature of OpenSCAD’s implementation of the Minkowski sum is that the operator takes into account the second shape’s position relative to the origin. So if I take the same cube and apply the minkowski() operator with the same sphere moved away from the origin, I get:

// the same cube, but shifted by the power of minkowski()!
minkowski() {
cube(10);
translate([-15,-15,-15])sphere(4);
}

So I can approximate a tapered extrusion by turning a 2d path into a very thin 3d plate (OpenSCAD’s 2D and 3D subsystems can never meet in the same output) and using a pyramid as the second argument to the operator:

// the component parts, before minkowski()

// thin extrusion of 2D path
linear_extrude(height=0.001)text(“S”, size=24, font=”EB Garamond:style=12 Italic”);

// a 30 degree pyramid with its apex at the origin
rotate_extrude()polygon([ [0,0] , [4, -8], [0, -8] ]);

You get:

minkowski() {
// thin extrusion of 2D path
linear_extrude(height=0.001)text(“S”, size=24, font=”EB Garamond:style=12 Italic”);
// a 30 degree pyramid with its apex at the origin
rotate_extrude()polygon([ [0,0] , [4, -8], [0, -8] ]);
}

In reality, you’d probably use a smaller taper angle, but the example is short rather than pretty. If you’re really picky about correctness, the process leaves the thin extrusion as parallel walls at the bottom of the shape, shown grossly exaggerated here for effect:

hugely exaggerated vertical profile

If you’re working in consumer-grade 3D printing and are using the standard 1 unit = 1 mm scale, the residual parallel section would only be 1 µm thick and way below any realistic layer height. Feel free to remove it, but be warned that this process creates so many facets that the difference() required to remove it will be very time-consuming for no visible difference.

Here’s the code: chamfer_extrude.scad – make sure to rename the txt extension to scad. Or, if you’d prefer, here’s a link to a gist: scruss/chamfer_extrude.scad

Put it in your OpenSCAD library folder, then you can use it like this:

include <chamfer_extrude.scad>; 

chamfer_extrude(height=4, angle=15, $fn=16)text("S", size=24, font="EB Garamond:style=12 Italic", $fn=64);
way smooth s

The library just adds some expected utility and tidiness to the above process. The source includes documentation and examples.

8 comments

  1. you can uses rotate_extrude($fn=8)polygon([ …]);
    to force an 8-sided pyramid, that saves time, and should be still looking great.
    alternate way to generate the pyramid (but neither faster nor slower):
    cylinder(r1=1, r2=0, h=10, center=true, $fn=8);

  2. Hi Jürgen — I recommend setting $fn in the module’s arguments rather than setting it to a fixed value of 8. If you’re making something with a hexagonal base, $fn=8 won’t be ideal. I still recommend keeping it at 12 or below otherwise the Minkowski sum gets really slow.

    I like the idea of using a tapered cylinder, though. It might save a bit of time and could avoid some of rotate_extrude()’s quirks

  3. I tried running this too, and found that in true minkowski spirit, it sets back the clocks a fair bit and lets you wait. What if you do a whole sign like this I wonder….
    This is why I stay away from minkowski like the plague, even though I truly like openscad, a lot. I do all my stuff in openscad but until somebody comes up with a slightly better way of doing these fillets or chamfers, my designs will look like a minecraft landscape, well mostly

  4. ? What if you do a whole sign like this I wonder….

    I create signs using this routine all the time. They only take a few minutes to render on this old 4 GHz i7. The trick is not to turn on model rendering on save

  5. Hi. Scruss.

    How about make extrude upside down (CUP style instead of pyramidal — your S sign), I mean, wider on top and narrower on bottom.

    I tried to given negative angle, but seems not work.

  6. Hello Scruss,

    I have been testing your very nice module tonight in OpenSCAD, and it seems to be working really well. So thank you for making it.

    One thing that I don’t understand however (and maybe I am wrong here since I don’t have a ton of experience working with CAD)..

    It seems like an almost impossible task to find any application, code based or GUI based, that can do “tapered text” like your script does.
    I’m not really sure I understand why this particular feature is so hard to do, but everything I have tried so far, from Fusion 360 to Inshape to SolidWorks.. None of them seem able to do this effect without making a big fuss and producing loads of errors.

    Is there anything special about text that makes it so hard to extrude it at an angle? I have tried all kinds of tricks such as drafts, chamfers etc., but nothing seems to just work for this type of task?

  7. Thanks, Lars. It’s a hard problem, so it’s unlikely that any simple solution will “just work”. Classic linear extrusion with scaling — perhaps what you thought you could do — distorts the result depending on how far away the target point is in 3D from the origin. Consequently, it’s useless for anything except regular shapes centred on the origin. Text is anything but regular, so the results won’t be great.

    My code is inefficient, slow, and generates a bunch of unnecessary nodes. But it does tend to produce some kind of useful result eventually.

Leave a comment

Your email address will not be published. Required fields are marked *