discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

rounded/beveled raised text

JB
Jordan Brown
Fri, Oct 31, 2025 5:27 PM

Every once in a while I need rounded raised text, and reinvent this. 
What I've written below isn't truly general-purpose, but it's adaptable
to a number of needs.

And the actual application is seasonal.

font = "Cooper Black";
size = 40;
content = "EEN";
t1 = 1;
t2 = 3;
h = 3;
layer = 0.3;
n = ceil(h/layer);

function f(y) = sqrt(1-y*y);

module offset_extrude(h, r, n) {
for (i = [1:n]) {
linear_extrude(h/n*i) {
// map 1:n to r:0
thisR = r * f((i-1)/(n-1));
offset(thisR)
children();
}
}
}

offset_extrude(h=h, r=(t2-t1)/2, n=n) difference() {
offset(t1/2) txt();
offset(-t1/2) txt();
}

module txt() {
text(content, font=font, size=size, spacing=0.97);
}

Every once in a while I need rounded raised text, and reinvent this.  What I've written below isn't truly general-purpose, but it's adaptable to a number of needs. And the actual application is seasonal. font = "Cooper Black"; size = 40; content = "EEN"; t1 = 1; t2 = 3; h = 3; layer = 0.3; n = ceil(h/layer); function f(y) = sqrt(1-y*y); module offset_extrude(h, r, n) { for (i = [1:n]) { linear_extrude(h/n*i) { // map 1:n to r:0 thisR = r * f((i-1)/(n-1)); offset(thisR) children(); } } } offset_extrude(h=h, r=(t2-t1)/2, n=n) difference() { offset(t1/2) txt(); offset(-t1/2) txt(); } module txt() { text(content, font=font, size=size, spacing=0.97); }
JB
Jordan Brown
Fri, Oct 31, 2025 6:30 PM

I should probably have included an image to show what I meant.

or, with a different function:

This version is a little more general, accepting the profile function as
an explicit argument to offset_extrude().

font = "Cooper Black";
size = 40;
size2 = 30;
content = "EEN";
content2 = "Happy";
t1 = 1;
t2 = 3;
h = 3;
layer = 0.1;
n = ceil(h/layer);

// Functions to map a Z value 0..1 to an offset value 0..1.
rounded = function (z) sqrt(1-z*z);
bevel45 = function(z) 1-z;

module offset_extrude(h, r, n, f) {
for (i = [1:n]) {
linear_extrude(h/n*i) {
// map 1:n to r:0
thisR = r * f((i-1)/(n-1));
offset(thisR)
children();
}
}
}

offset_extrude(h=h, r=(t2-t1)/2, n=n, f=rounded) {
translate([0, 0]) text(content2, font=font, size=size2, halign="center", valign="bottom", spacing=0.9);
difference() {
offset(t1/2) txt();
offset(-t1/2) txt();
}
}

module txt() {
text(content, font=font, size=size, spacing=0.97, halign="center", valign="top");
}

I should probably have included an image to show what I meant. or, with a different function: This version is a little more general, accepting the profile function as an explicit argument to offset_extrude(). font = "Cooper Black"; size = 40; size2 = 30; content = "EEN"; content2 = "Happy"; t1 = 1; t2 = 3; h = 3; layer = 0.1; n = ceil(h/layer); // Functions to map a Z value 0..1 to an offset value 0..1. rounded = function (z) sqrt(1-z*z); bevel45 = function(z) 1-z; module offset_extrude(h, r, n, f) { for (i = [1:n]) { linear_extrude(h/n*i) { // map 1:n to r:0 thisR = r * f((i-1)/(n-1)); offset(thisR) children(); } } } offset_extrude(h=h, r=(t2-t1)/2, n=n, f=rounded) { translate([0, 0]) text(content2, font=font, size=size2, halign="center", valign="bottom", spacing=0.9); difference() { offset(t1/2) txt(); offset(-t1/2) txt(); } } module txt() { text(content, font=font, size=size, spacing=0.97, halign="center", valign="top"); }