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"); }
R
Rudolf
Fri, Nov 21, 2025 3:01 PM

For the bevel case you get a better result by using the roof() operator.
And from this there is a more or less stony path to calculate sloped
slices to get a better approximation ...

intersection()
{
  scale([1,1,2])
  roof(method = "straight", convexity=10)
  D()
  {
    offset(.5)txt();
    offset(-2)txt();
  }
  cube([400, 400, 3], center=true);
}

Am 31.10.2025 um 19:30 schrieb Jordan Brown via Discuss:

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");
}


OpenSCAD mailing list
To unsubscribe send an email todiscuss-leave@lists.openscad.org

For the bevel case you get a better result by using the roof() operator. And from this there is a more or less stony path to calculate sloped slices to get a better approximation ... intersection() {   scale([1,1,2])   roof(method = "straight", convexity=10)   D()   {     offset(.5)txt();     offset(-2)txt();   }   cube([400, 400, 3], center=true); } Am 31.10.2025 um 19:30 schrieb Jordan Brown via Discuss: > 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"); > } > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email todiscuss-leave@lists.openscad.org
JB
Jon Bondy
Fri, Nov 21, 2025 4:31 PM

I can't find "roof" in the OpenSCAD cheat sheet, and you show no
importing or including of other files, so I am mystified.

Jon

On 11/21/2025 10:01 AM, Rudolf via Discuss wrote:

For the bevel case you get a better result by using the roof()
operator. And from this there is a more or less stony path to
calculate sloped slices to get a better approximation ...

intersection()
{
  scale([1,1,2])
  roof(method = "straight", convexity=10)
  D()
  {
    offset(.5)txt();
    offset(-2)txt();
  }
  cube([400, 400, 3], center=true);
}

Am 31.10.2025 um 19:30 schrieb Jordan Brown via Discuss:

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");
}


OpenSCAD mailing list
To unsubscribe send an email todiscuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email todiscuss-leave@lists.openscad.org

--
This email has been checked for viruses by AVG antivirus software.
www.avg.com

I can't find "roof" in the OpenSCAD cheat sheet, and you show no importing or including of other files, so I am mystified. Jon On 11/21/2025 10:01 AM, Rudolf via Discuss wrote: > > For the bevel case you get a better result by using the roof() > operator. And from this there is a more or less stony path to > calculate sloped slices to get a better approximation ... > > intersection() > { >   scale([1,1,2]) >   roof(method = "straight", convexity=10) >   D() >   { >     offset(.5)txt(); >     offset(-2)txt(); >   } >   cube([400, 400, 3], center=true); > } > > Am 31.10.2025 um 19:30 schrieb Jordan Brown via Discuss: >> 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"); >> } >> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email todiscuss-leave@lists.openscad.org > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email todiscuss-leave@lists.openscad.org -- This email has been checked for viruses by AVG antivirus software. www.avg.com
MM
Michael Marx (spintel)
Sat, Nov 22, 2025 12:04 AM

https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/WIP


From: Jon Bondy via Discuss [mailto:discuss@lists.openscad.org]
Sent: Saturday, November 22, 2025 3:32 AM
To: parkinbot@digitaldocument.de; OpenSCAD general discussion Mailing-list
Cc: Jon Bondy
Subject: [OpenSCAD] Re: rounded/beveled raised text

I can't find "roof" in the OpenSCAD cheat sheet, and you show no importing or including of other files, so I am mystified.

Jon

https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/WIP _____ From: Jon Bondy via Discuss [mailto:discuss@lists.openscad.org] Sent: Saturday, November 22, 2025 3:32 AM To: parkinbot@digitaldocument.de; OpenSCAD general discussion Mailing-list Cc: Jon Bondy Subject: [OpenSCAD] Re: rounded/beveled raised text I can't find "roof" in the OpenSCAD cheat sheet, and you show no importing or including of other files, so I am mystified. Jon
JB
Jon Bondy
Sat, Nov 22, 2025 2:38 AM

Thanks.

I notice that the documentation is still referring to the named items in
OpenSCAD as "variables".  Small wonder so many new users crash headlong
into this misunderstanding.

Is there any nomenclature we can use instead of "variable"? Identifier? 
Even "constant" might be better

Jon

On 11/21/2025 7:04 PM, Michael Marx (spintel) via Discuss wrote:

https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/WIP


*From:*Jon Bondy via Discuss [mailto:discuss@lists.openscad.org]
Sent: Saturday, November 22, 2025 3:32 AM
To: parkinbot@digitaldocument.de; OpenSCAD general discussion
Mailing-list
Cc: Jon Bondy
Subject: [OpenSCAD] Re: rounded/beveled raised text

I can't find "roof" in the OpenSCAD cheat sheet, and you show no
importing or including of other files, so I am mystified.

Jon


OpenSCAD mailing list
To unsubscribe send an email todiscuss-leave@lists.openscad.org

--
This email has been checked for viruses by AVG antivirus software.
www.avg.com

Thanks. I notice that the documentation is still referring to the named items in OpenSCAD as "variables".  Small wonder so many new users crash headlong into this misunderstanding. Is there any nomenclature we can use instead of "variable"? Identifier?  Even "constant" might be better Jon On 11/21/2025 7:04 PM, Michael Marx (spintel) via Discuss wrote: > > https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/WIP > > ------------------------------------------------------------------------ > > *From:*Jon Bondy via Discuss [mailto:discuss@lists.openscad.org] > *Sent:* Saturday, November 22, 2025 3:32 AM > *To:* parkinbot@digitaldocument.de; OpenSCAD general discussion > Mailing-list > *Cc:* Jon Bondy > *Subject:* [OpenSCAD] Re: rounded/beveled raised text > > I can't find "roof" in the OpenSCAD cheat sheet, and you show no > importing or including of other files, so I am mystified. > > Jon > > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email todiscuss-leave@lists.openscad.org -- This email has been checked for viruses by AVG antivirus software. www.avg.com
FH
Father Horton
Sat, Nov 22, 2025 2:40 AM

In functional programming, they’re called variables, despite their
immutability. I think we are stuck with the term.

On Fri, Nov 21, 2025 at 8:38 PM Jon Bondy via Discuss <
discuss@lists.openscad.org> wrote:

Thanks.

I notice that the documentation is still referring to the named items in
OpenSCAD as "variables".  Small wonder so many new users crash headlong
into this misunderstanding.

Is there any nomenclature we can use instead of "variable"?  Identifier?
Even "constant" might be better

Jon

On 11/21/2025 7:04 PM, Michael Marx (spintel) via Discuss wrote:

https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/WIP


From: Jon Bondy via Discuss [mailto:discuss@lists.openscad.org
discuss@lists.openscad.org]
Sent: Saturday, November 22, 2025 3:32 AM
To: parkinbot@digitaldocument.de; OpenSCAD general discussion
Mailing-list
Cc: Jon Bondy
Subject: [OpenSCAD] Re: rounded/beveled raised text

I can't find "roof" in the OpenSCAD cheat sheet, and you show no importing
or including of other files, so I am mystified.

Jon


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

http://www.avg.com/email-signature?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=emailclient
Virus-free.www.avg.com
http://www.avg.com/email-signature?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=emailclient
<#m_-2447831226980711899_DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2>


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

In functional programming, they’re called variables, despite their immutability. I think we are stuck with the term. On Fri, Nov 21, 2025 at 8:38 PM Jon Bondy via Discuss < discuss@lists.openscad.org> wrote: > Thanks. > > I notice that the documentation is still referring to the named items in > OpenSCAD as "variables". Small wonder so many new users crash headlong > into this misunderstanding. > > Is there any nomenclature we can use instead of "variable"? Identifier? > Even "constant" might be better > > Jon > > > On 11/21/2025 7:04 PM, Michael Marx (spintel) via Discuss wrote: > > https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/WIP > > > ------------------------------ > > *From:* Jon Bondy via Discuss [mailto:discuss@lists.openscad.org > <discuss@lists.openscad.org>] > *Sent:* Saturday, November 22, 2025 3:32 AM > *To:* parkinbot@digitaldocument.de; OpenSCAD general discussion > Mailing-list > *Cc:* Jon Bondy > *Subject:* [OpenSCAD] Re: rounded/beveled raised text > > > > I can't find "roof" in the OpenSCAD cheat sheet, and you show no importing > or including of other files, so I am mystified. > > Jon > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org > > > > <http://www.avg.com/email-signature?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=emailclient> > Virus-free.www.avg.com > <http://www.avg.com/email-signature?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=emailclient> > <#m_-2447831226980711899_DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2> > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org
JB
Jordan Brown
Sat, Nov 22, 2025 6:33 AM

On 11/21/2025 6:40 PM, Father Horton via Discuss wrote:

In functional programming, they’re called variables, despite their
immutability. I think we are stuck with the term. 

Perhaps more importantly, different runs through the same snippet of the
program may have different values for the same name.

for (i = [0:10]) echo(i);
function inc(j) = j + 1;
module kube(k) cube(k);

Are i, j, and k variables or constants?

(OpenSCAD behavior actually aligns with the C/C++ "const" modifier, but
I think that expecting OpenSCAD users to be familiar with C or C++ is a 
stretch.)

On 11/21/2025 6:40 PM, Father Horton via Discuss wrote: > In functional programming, they’re called variables, despite their > immutability. I think we are stuck with the term.  Perhaps more importantly, different runs through the same snippet of the program may have different values for the same name. for (i = [0:10]) echo(i); function inc(j) = j + 1; module kube(k) cube(k); Are i, j, and k variables or constants? (OpenSCAD behavior actually aligns with the C/C++ "const" modifier, but I think that expecting OpenSCAD users to be familiar with C or C++ is a  stretch.)
JB
Jon Bondy
Sat, Nov 22, 2025 12:14 PM

If those working in functional programming choose to call immutable
values "variables", that is unfathomable and incorrect, but I don't
think we need to adopt or encourage that misleading nomenclature.

I agree that SOME of the named values that we use are actually
variables, while most of them are immutable.  This, of course, only adds
to the confusion.  We could attempt to manage this in the documentation
by specifically calling THOSE values "variables", and noting the
difference.  I assume that none of the proposed language changes will
create actual variables, but I could be wrong.

The term "named constant", however awkward, seems to capture how
OpenSCAD works, and does not require a knowledge of C or Pascal or
Modula2, all of which have "const"s.

If we keep writing documentation referring to named constants as if they
were variables, then we should not be surprised by on ongoing confusion
by new adapters, and perhaps by some who give up on OpenSCAD because of
their confusion and frustration.  If that is an acceptable penalty to
pay for the simplicity of the term "variable", then let's proceed with
no change

Jon

On 11/22/2025 1:33 AM, Jordan Brown via Discuss wrote:

On 11/21/2025 6:40 PM, Father Horton via Discuss wrote:

In functional programming, they’re called variables, despite their
immutability. I think we are stuck with the term.

Perhaps more importantly, different runs through the same snippet of
the program may have different values for the same name.

 for (i = [0:10]) echo(i);
 function inc(j) = j + 1;
 module kube(k) cube(k);

Are i, j, and k variables or constants?

(OpenSCAD behavior actually aligns with the C/C++ "const" modifier,
but I think that expecting OpenSCAD users to be familiar with C or C++
is a  stretch.)


OpenSCAD mailing list
To unsubscribe send an email todiscuss-leave@lists.openscad.org

--
This email has been checked for viruses by AVG antivirus software.
www.avg.com

If those working in functional programming choose to call immutable values "variables", that is unfathomable and incorrect, but I don't think we need to adopt or encourage that misleading nomenclature. I agree that SOME of the named values that we use are actually variables, while most of them are immutable.  This, of course, only adds to the confusion.  We could attempt to manage this in the documentation by specifically calling THOSE values "variables", and noting the difference.  I assume that none of the proposed language changes will create actual variables, but I could be wrong. The term "named constant", however awkward, seems to capture how OpenSCAD works, and does not require a knowledge of C or Pascal or Modula2, all of which have "const"s. If we keep writing documentation referring to named constants as if they were variables, then we should not be surprised by on ongoing confusion by new adapters, and perhaps by some who give up on OpenSCAD because of their confusion and frustration.  If that is an acceptable penalty to pay for the simplicity of the term "variable", then let's proceed with no change Jon On 11/22/2025 1:33 AM, Jordan Brown via Discuss wrote: > On 11/21/2025 6:40 PM, Father Horton via Discuss wrote: >> In functional programming, they’re called variables, despite their >> immutability. I think we are stuck with the term. > > Perhaps more importantly, different runs through the same snippet of > the program may have different values for the same name. > > for (i = [0:10]) echo(i); > function inc(j) = j + 1; > module kube(k) cube(k); > > Are i, j, and k variables or constants? > > (OpenSCAD behavior actually aligns with the C/C++ "const" modifier, > but I think that expecting OpenSCAD users to be familiar with C or C++ > is a  stretch.) > > > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email todiscuss-leave@lists.openscad.org -- This email has been checked for viruses by AVG antivirus software. www.avg.com
KC
Kevin Cole
Sat, Nov 22, 2025 12:44 PM

variable:

  1. Able to be varied
  2. Likely to vary
  3. Having no fixed quantitative value

immutable:

  1. Unable to be changed without exception.
  2. Not able to be altered in the memory after its value is set
    initially. Constants are immutable.

perverse:

  1. Things which are unable to be changed, yet able to be varied.
  2. Being pedantic and rigid rather than clear

I'd vote for named constant, or perhaps read-only key.... There's
already a common understanding by most computer users that files can
be made read-only after creation... So, presenting the idea that
certain items can be assigned a value and then set as read-only -- and
possibly being changed back, with effort, to writable, is not quite as
perverse as "unchangeable changeable" entities. (Maybe something other
than "key" but, with associative arrays, "dictionaries", etc, the idea
of key-value pairs is another relatively common idiom.)

variable: 1. Able to be varied 2. Likely to vary 3. Having no fixed quantitative value immutable: 1. Unable to be changed without exception. 2. Not able to be altered in the memory after its value is set initially. Constants are immutable. perverse: 1. Things which are unable to be changed, yet able to be varied. 2. Being pedantic and rigid rather than clear I'd vote for named constant, or perhaps read-only key.... There's already a common understanding by most computer users that files can be made read-only after creation... So, presenting the idea that certain items can be assigned a value and then set as read-only -- and possibly being changed back, with effort, to writable, is not quite as perverse as "unchangeable changeable" entities. (Maybe something other than "key" but, with associative arrays, "dictionaries", etc, the idea of key-value pairs is another relatively common idiom.)