discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

is color an actual operator module ?

JJ
jon jonbondy.com
Fri, Aug 8, 2025 12:34 PM

Thank you, Jordan

Jon

On 8/8/2025 8:30 AM, Jordan Brown wrote:
On 8/8/2025 4:36 AM, Jon Bondy wrote:

What is the community getting for this INCREDIBLE level of effort?

To be fair, a lot of the issues that I commented on were already there.  I didn't try to distinguish, since much of my goal was to give my opinions on what did and did not make good reference material.

  1. perhaps this should be controlled in a manner similar to the development of the software itself, with a GIT-like system of problem descriptions and resolutions.

Perhaps, but there's value to the fact that making small corrections is very light-weight.

Probably the biggest thing is to write something that gives guidelines for writing the documentation, e.g. in no particular order:

  • What belongs in the reference section, and what belongs in the tutorial section?
  • If you're thinking of a large change, talk to people first.
  • If you don't know the truth, ask for help.
  • What kinds of examples should you give, and how many?
  • Remember the interaction with cheat sheets, including cheat sheets for older releases.
  • What is the style for each section?  What does an entry for a function look like?
  • There should be an official glossary.
  • Where is transclusion appropriate?  When is it appropriate to split something off into a new page?

The documentation certainly could use work, but the first requirement for any change is that it's right.

Thank you, Jordan Jon On 8/8/2025 8:30 AM, Jordan Brown wrote: On 8/8/2025 4:36 AM, Jon Bondy wrote: What is the community getting for this INCREDIBLE level of effort? To be fair, a lot of the issues that I commented on were already there. I didn't try to distinguish, since much of my goal was to give my opinions on what did and did not make good reference material. 4) perhaps this should be controlled in a manner similar to the development of the software itself, with a GIT-like system of problem descriptions and resolutions. Perhaps, but there's value to the fact that making small corrections is very light-weight. Probably the biggest thing is to write something that gives guidelines for writing the documentation, e.g. in no particular order: * What belongs in the reference section, and what belongs in the tutorial section? * If you're thinking of a large change, talk to people first. * If you don't *know* the truth, ask for help. * What kinds of examples should you give, and how many? * Remember the interaction with cheat sheets, including cheat sheets for older releases. * What is the style for each section? What does an entry for a function look like? * There should be an official glossary. * Where is transclusion appropriate? When is it appropriate to split something off into a new page? The documentation certainly could use work, but the first requirement for any change is that it's right.
JB
Jordan Brown
Fri, Aug 8, 2025 12:36 PM
  1. perhaps this should be controlled in a manner similar to the
    development of the software itself, with a GIT-like system of
    problem descriptions and resolutions.

By the way, it's entirely appropriate to use github issues to report
documentation issues, even though we don't use github to manage the
documentation.

>>> 4) perhaps this should be controlled in a manner similar to the >>> development of the software itself, with a GIT-like system of >>> problem descriptions and resolutions. >>> By the way, it's entirely appropriate to use github issues to report documentation issues, even though we don't use github to manage the documentation.
JJ
jon jonbondy.com
Fri, Aug 8, 2025 12:37 PM

Perhaps I can frame this differently.

Why would we want to exercise [rigid?] control over the software source code, and exercise no [explicit] control over the documentation?

What is the appropriate level of documentation control, and how should it be managed?

Jon

On 8/8/2025 8:30 AM, Jordan Brown wrote:
On 8/8/2025 4:36 AM, Jon Bondy wrote:

What is the community getting for this INCREDIBLE level of effort?

To be fair, a lot of the issues that I commented on were already there.  I didn't try to distinguish, since much of my goal was to give my opinions on what did and did not make good reference material.

  1. perhaps this should be controlled in a manner similar to the development of the software itself, with a GIT-like system of problem descriptions and resolutions.

Perhaps, but there's value to the fact that making small corrections is very light-weight.

Probably the biggest thing is to write something that gives guidelines for writing the documentation, e.g. in no particular order:

  • What belongs in the reference section, and what belongs in the tutorial section?
  • If you're thinking of a large change, talk to people first.
  • If you don't know the truth, ask for help.
  • What kinds of examples should you give, and how many?
  • Remember the interaction with cheat sheets, including cheat sheets for older releases.
  • What is the style for each section?  What does an entry for a function look like?
  • There should be an official glossary.
  • Where is transclusion appropriate?  When is it appropriate to split something off into a new page?

The documentation certainly could use work, but the first requirement for any change is that it's right.

Perhaps I can frame this differently. Why would we want to exercise [rigid?] control over the software source code, and exercise no [explicit] control over the documentation? What is the appropriate level of documentation control, and how should it be managed? Jon On 8/8/2025 8:30 AM, Jordan Brown wrote: On 8/8/2025 4:36 AM, Jon Bondy wrote: What is the community getting for this INCREDIBLE level of effort? To be fair, a lot of the issues that I commented on were already there. I didn't try to distinguish, since much of my goal was to give my opinions on what did and did not make good reference material. 4) perhaps this should be controlled in a manner similar to the development of the software itself, with a GIT-like system of problem descriptions and resolutions. Perhaps, but there's value to the fact that making small corrections is very light-weight. Probably the biggest thing is to write something that gives guidelines for writing the documentation, e.g. in no particular order: * What belongs in the reference section, and what belongs in the tutorial section? * If you're thinking of a large change, talk to people first. * If you don't *know* the truth, ask for help. * What kinds of examples should you give, and how many? * Remember the interaction with cheat sheets, including cheat sheets for older releases. * What is the style for each section? What does an entry for a function look like? * There should be an official glossary. * Where is transclusion appropriate? When is it appropriate to split something off into a new page? The documentation certainly could use work, but the first requirement for any change is that it's right.
JB
Jordan Brown
Fri, Aug 8, 2025 1:41 PM

Why would we want to exercise [rigid?] control over the software
source code, and exercise no [explicit] control over the documentation?

Because the blast radius is larger when mistakes are made modifying the
source code.

If you make a typo in the documentation, it's ... a typo.  If you make a
typo in the source, the program doesn't build, or crashes, or quietly
misbehaves.

If you add a feature to the program that we later regret, it's hard to
back it out because people may have come to depend on it. It isn't
possible to depend on an erroneous comment in documentation.

What is the appropriate level of documentation control, and how should
it be managed?

That is a very good question.

I suspect that one aspect of the answer is that our source gatekeepers
(basically, Torsten and Marius; there are a few other authorized people
but they are rarely active) are fully loaded, and I don't think they
want to take over as documentation gatekeepers too.  We'd need several
documentation gatekeepers.

Another question that I don't know the answer to is what level of
control Wikibooks lets us have.

> Why would we want to exercise [rigid?] control over the software > source code, and exercise no [explicit] control over the documentation? > Because the blast radius is larger when mistakes are made modifying the source code. If you make a typo in the documentation, it's ... a typo.  If you make a typo in the source, the program doesn't build, or crashes, or quietly misbehaves. If you add a feature to the program that we later regret, it's hard to back it out because people may have come to depend on it. It isn't possible to depend on an erroneous comment in documentation. > What is the appropriate level of documentation control, and how should > it be managed? > That is a very good question. I suspect that one aspect of the answer is that our source gatekeepers (basically, Torsten and Marius; there are a few other authorized people but they are rarely active) are fully loaded, and I don't think they want to take over as documentation gatekeepers too.  We'd need several documentation gatekeepers. Another question that I don't know the answer to is what level of control Wikibooks lets us have.
RW
Raymond West
Fri, Aug 8, 2025 2:07 PM

If it ain't broke, work on until it is.😉

The attraction of openscad is it's relatively small set of functions.
I've done everything I need with raw openscad (with the help from a few
folk on here). Bosl2 is there for those who want an easier answer. It
seems that some folk are wanting it to do things that were never
designed into openscad functionality. For those folk, learn fusion,
blender, whatever.

The terminology in parts is a tad incorrect, cubes are more than
squares, cylinders are more than cylinders, and you will never see a
true circle on any digital display. Also, the language is initially
awkward, and the solids can often have unwanted holes, but if you spend
the time and effort you get used to it.

My comment is related to openscad as a whole, not specific to 2d, but as
nothing in the real world is 2d...

Best wishes,

Ray

On 08/08/2025 12:36, Jon Bondy via Discuss wrote:

What is the community getting for this INCREDIBLE level of effort?

I think we should

  1. revert the documentation back to prior to when Vulcan started
    changing things

  2. make a list of problems with the documentation (an explicit,
    reviewable requirements list from which we can make controlled changes
    to the documentation)

  3. make small, localized changes that can be validated with minimal
    effort.

  4. perhaps this should be controlled in a manner similar to the
    development of the software itself, with a GIT-like system of problem
    descriptions and resolutions.

The people who really contribute to OpenSCAD are few, perhaps less
than half a dozen.  To force them to spend their time working on a
project THAT DOES NOT NEED TO BE DONE, and is not going well, will
slow down development and bug fixes that DO need to be done.

It is clear to me that having an OpenSCAD novice working on the
documentation is not a great idea.   Good intentions but bad results.

Vulcan: if you REALLY want to help this community, use OpenSCAD
actively (every day) for a year, making complex designs, and then come
back.

Is there anyone (or any group) that is in control of the documentation
Wiki?  If not, we need such an entity.  If so, someone needs to take
control of this project.

Again, if I'm wrong, I apologize.  But I have been getting private
messages agreeing with me.

Jon

On 8/8/2025 4:08 AM, Jordan Brown via Discuss wrote:

[ I'll spend the effort to fix up this laptop configuration, again,
sorry for the duplicates. ]

Two Dimensional Modelling

0% developed  as of November 17, 2009
https://en.wikibooks.org/wiki/Help:Development_stages2D
Primitives
https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/2D_Primitives

All 2D primitives can be transformed with 3D transformations.

Really bad place to start.  Yes, you can transform them with 3D
transforms, but if you do then the results can be weird. It should be
discouraged; you should almost always work with 2D transforms when
working with a 2D subassembly.

Also, maybe we should talk about the primitives before we talk about
what you can do with them.

 They are usually used as part of a 3D extrusion.

Yeah, eventually.  But again this doesn't seem appropriate for a "2D
primitives" section.  Maybe for an overview section above that.

 Although they are infinitely thin, they are rendered with a 1-unit
thickness.

Again, maybe in an overview section.

Note: Trying to subtract with|difference()|from 3D object will
lead to unexpected results in final rendering.

The real rule is "don't mix 2D objects with 3D objects and 3D
operations".  It isn't necessary or appropriate to say very much
about what will happen if you do.  Some cases will yield errors,
while others will do something weird.  We don't want the
documentation to nail down any particular behavior, because there are
reasons that we might want to change the behavior in these cases.

Ref, e.g., OEP 7 "Mixed Dimension Geometry Support"
https://github.com/openscad/openscad/wiki/OEP7%3A-Mixed-Dimension-Geometry-Support.

 Square Object Module

By default this module draws a unit square in the first quadrant,
(+X,+Y), starting at the origin [0,0]. Its four lines have no
thickness but the shape is drawn as a 1 unit high, filled plane.

The second sentence should probably just go away:

  • The first part "its four lines have no thickness" is both
    misleading - the lines have no independent existence - and
    incorrect; when rendered they do have thickness.
  • The second half (drawn as 1 unit high) restates something already
    said in above.

The module's arguments may be written in the order|<size>,
center=<bool>|without being named, but the names may be used as
shown in the examples:

There needs to be (but probably isn't) enough documentation
convention that this need not be said.

Parameters

size
has two forms:/single value/or/vector/
single - non-negative float, length of all four sides

Should use the word "number" rather than the word "float". OpenSCAD
does not have distinct floating point and integer types; it has only
numbers.

center
boolean, default false, to set the shape's position in the X-Y plane

CenterWhen|false|, as it is by default, the shape will be drawn
from its first point at (0,0) in the First Quadrant, (+X,+Y). With
center set to|true|the shape is drawn centered on the origin.

These two paragraphs should be merged.

 Circle Object Module

By default this module draws a unit circle centered on the origin
[0,0] as a pentagon with its starting point on the X-axis at X=1.
Its lines have no thickness but the shape is drawn as a 1 unit high,
filled plane.

The part of the first sentence starting "as a pentagon ..." should go
away.  It's true, but it really belongs as part of the description of
$fa/$fs.

Again, the second sentence should just go away.

Somewhere it should say "Circles are approximated as regular
polygons; see <reference to $fa/$fs/$fn> for the details of the
polygons generated."

The argument|radius|may be given without being named, but
the|r|and|d|arguments must be named.

There is no "radius" argument.  There are r and d.

Again, we should have a documentation convention so that we don't
have to repeat positional/named rules, but the behavior here is that
r can be supplied as the first argument, but d must be named.

(Technically, if you say "circle(undef, 10)" the 10 is the second  it
creates a 10-unit-diameter circle.  I would say that the fact that
this works is a minor bug.)

$fa
Special Variable
$fs
Special Variable
$fn
Special Variable

Theses should be described only to the extent of pointing at the
general description of $fa/$fs/$fn.

The default circle displays as a pentagram as that is the minimum
number of fragments used to approximate a curved shape calculated
from the default values for $fs and $fa. To have it draw as a smooth
shape increase the $fn value, the minimum number of fragments to
draw, to 20 or more (best $fn < 128).

This is just bad.  First, everything here should be covered in the
description of $fa/$fs/$fn.  Second, using $fn to control the
resolution of a circle is generally the wrong answer; you are better
off setting $fa and $fs.  Finally, specific advice on $fn values is a
bad idea, because the "looks smooth" value varies dramatically with
size.  A 20-gon is okay for a medium-small circle; a 72-gon is not
good enough for a 100-unit circle.

An alternative method to draw a very smooth circle scale is to scale
down a very large circle.

scale( 0.001 ) circle(200);

This should just go away; it confuses the issue.

Another way to solve the lack of a built-in module for regular
polygons is to write a custom one:module regular_polygon()
https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/example_module_regular_polygon()

I wouldn't include this.  Using polygon() is harder than using
circle(), and anybody who's capable of using it should have little
trouble simulating circle().

convexity
Integer, default=1 - complex edge geometry may require a higher
value value to preview correctly.

Should include a link to a general discussion of convexity. Probably
should not even mention the default; that should be covered in the
general discussion.

Points ParameterA list of X-Y coordinates in this form:

[[1, 1], [1, 4], [3, 4], [3, 1], [1, 1]]

which defines four points and makes it explicit that the last one is
the same as the first.

Including the first point twice is not strictly necessary as this:

[[1, 1], [1, 4], [3, 4], [3, 1]]

gives the same result.

This seems like it should be simplified.  In the absence of a paths
parameter, the last point always connects to the first, because
polygons are always closed.

Paths Parameter

This optional parameter is a nested vector of paths.

A "path" is a list of index values that reference points in
the|points|vector. It can explicitly describe a closed loop by its
last index being the same as its first, as in:

[1, 2, 3, 4, 1]

but this is equivalent to:

[1, 2, 3, 4]

Again, this seems like unnecessary complexity; the last point always
connects to the first.

Notice that the points vector is simple list,

No, it's a list of lists.

 while each path is a separate vector.

Yes... points and paths are the same order. They are both lists of lists.

 This means that paths, that are lists of references to points, have
to "know" which points it needs to include.

While it's true that paths need to "know" the indexes they connect, I
don't see how that follows from the previous sentences.

 This can be an issue if the polygon is assembled from a number of
shapes at run time as the order of adding shapes affects their
point's index values.

It's true that this is something that you must handle, but I don't
think that a reference manual needs to discuss it.

 .Convexity

Formatting error:  this title is merged with the previous paragraph.
(But should be deleted, see below.)

Shapes with a lot of detail in their edges may need the convexity
parameter increased to preview correctly. See Convexity

Already discussed, should be deleted.

Example With Multiple Holes

[Note:Requires version2015.03] (for use of|concat()|)

https://en.wikibooks.org/wiki/File:OpenSCAD_romboid_with_holes.jpg

We are using "a" for the point lists and "b" for their paths:

a0 = [[0,0],[100,0],[130,50],[30,50]];    // outer boundary
b0 = [1,0,3,2];
a1 = [[20,20],[40,20],[30,30]];            // hole 1
b1 = [4,5,6];
a2 = [[50,20],[60,20],[40,30]];            // hole 2
b2 = [7,8,9];
a3 = [[65,10],[80,10],[80,40],[65,40]];    // hole 3
b3 = [10,11,12,13];
a4 = [[98,10],[115,40],[85,40],[85,10]];  // hole 4
b4 = [14,15,16,17];
a  = concat( a0,a1,a2,a3,a4 ); // merge all points into "a"
b  = [b0,b1,b2,b3,b4]; // place all paths into a vector
polygon(a,b);
//alternate
polygon(a,[b0,b1,b2,b3,b4]);

The "alternate" at the end of the example seems unnecessary - of
course you can use either a particular expression or a variable that
has been set to that expression.

2D to 3D by Extrusion

A polygon may be the basis for an extrusion, just as any of the 2D
primitives can. Thisexample script
https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/example_module_2D_to_3D_extrusionmay
be used to draw the shape in this image:

Yes, a polygon can be used as the basis for extrusion, just as any of
the 2D primitives can.  That means that you do not need a specific
example of that case.

 Import a 2D Shape From a DXF

[Deprecated:import_dxf() will be removed in a future release. Use
Useimport() Object Module
https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#importinstead.
instead*]*

As a deprecated feature, this should be pushed to the bottom.

Read a DXF file and create a 2D shape.

Example

linear_extrude(height = 5, center = true)
import_dxf(file = "example009.dxf", layer = "plate");

Example with Import()

linear_extrude(height = 5, center = true)
import(file = "example009.dxf", layer = "plate");

The second should perhaps be titled "Replacement example with
import()".  Note also that since OpenSCAD is case sensitive the word
"import" should not be capitalized.

Text is a big enough topic that it should probably have its own page,
with just a brief mention and cross-reference here.

I see that it has its own page and is transcluded here.  It should
not be transcluded, because that makes it harder to just read everything.

Text in OpenSCAD

Being able to use text objects as a part of a model is valuable in a
lot of design solutions.

Delete this sentence.  This is reference material, not sales
material.  The user already knows whether or not it's valuable to them.

The fontsavailable to use in a script
https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Text#Fonts_in_OpenSCADare
from the system that OpenSCAD is running in with the addition of
those explicitly added by the script itself.

And OpenSCAD includes several.  (And this duplicates a more extensive
discussion below.)

 text() Object Module

The|text()|object module draws a single string of text as a 2D
geometric object, using fonts installed on the local system or
provided as separate font file.

provided as +a+ separate font file

The shape starts at the origin and is drawn along the positive X axis.

By default, ...

(because halign and valign change things)

text
String. A single line ofany character allowed
https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Characters_Strings#Characters.*Limitation:*non-printable
ASCII characters like newline and tab rendered as placeholders

Delete the second sentence.  If it's a string, it's allowed. As for
being a single line and treatment of non-printable characters, need
to phrase that as a current restriction, not as a permanent behavior

  • it would be good if we could eventually provide more support there,
    and we wouldn't want to be prevented from adding that support by
    compatibility concerns.  Ref
    https://github.com/openscad/openscad/issues/5018 for the desire for
    multi-line text.

font
aformatted string
https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Text#Parameterswith
default font of "Liberation Sans:style=Regular"

"formatted string" is a poor phrase there.  Better would be something
like "String.  A font specification with ...".

Also I see that this is a link over to a separate Text page. A
separate Text page is good, as discussed above, but it shouldn't be
duplicated here.

size
non-negative decimal, default=10. The generated text has a
height above the baseline of approximately this value, varying
for different fonts but typically being slightly smaller.

The "decimal" part should be "number".  (It isn't even sensible to
talk about a base.)

I don't feel the need for the "non-negative" part.  (It should
probably also be non-zero.)  Unless we have a special meaning for a
negative size, we should be able to let people figure out for
themselves that if they make a silly request they will get a silly
answer.

Current behavior is ... interesting... though when you think about it
unsurprising:  the text is mirrored in X and Y, leading to it being
effectively rotated 180 degrees.  Unless we really want to keep that
behavior, we should probably make it be an error instead.  Until and
unless we decide that we want to keep that behavior, we should not
document it.

There needs to be a footnote about size.  Because of an arithmetic
error in the implementation (issue #4304
https://github.com/openscad/openscad/issues/4304), the "size"
parameter does not correspond to a typical font size specification. 
It is a coincidence that the arithmetic error approximately cancels
out the usual ratio between the specified font size and the size of a
capital letter, making "size" approximately specify the size of a
capital letter in a typical Western font.  However, since the result
is useful, and the error has been in place since the beginning, we
really can't fix it.  Maybe at some point we can introduce an
alternative parameter that specifies a more conventional font size,
eg PR#4306 https://github.com/openscad/openscad/pull/4306.

spacing
float, default=1. Multiplicative factor that increases or
decreases spacing between characters.

"float" should be "number".

language
String. The language of the text (e.g., "en", "ar", "ch").
Default is "en".
script
String, default="latin". The script of the text (e.g. "latin",
"arabic", "hani").

Somebody needs to figure out what these actually do.

$fn
higher values generate smoother curves (refer toSpecial
Variables
https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Other_Language_Features#special_variables)

This should refer to $fa, $fs, and $fn... and really you shouldn't be
using $fn here.

   Font & Style Parameter

The "name" of a font is a string starting with its|logical font
name|and|variation|,

I don't see variation as a separate part of the specification.

Also, use of the "typewriter" font here is inappropriate; neither of
these is a language keyword or language component. Either use plain
text or perhaps italics.

 optionally followed by a colon (":") separated list of font
specifications like a|style|selection, and a set of zero or
more|features|.

We should include a list of the name=value specifications supported,
or refer to external (fontconfig?) documentation.

Again, "features" is not a keyword and should not be in typewriter font.

The common variations in a font family are|sans|and|serif|though
many others will be seen in the list of fonts available. Each font
variation can be drawn with a/style/to support textual emphasis.

I think those are part of the font name, and that there they are
usually capitalized.  I'm a bit torn on whether they should be in
typewriter font.

The default, upright appearance is usually called "Regular" with
"Bold", "Italic", and "Bold Italic" being the other three styles
commonly included in a font. In general the styles offered by a font
may only be known by using the platform's font configuration tools
or theOpenSCAD font list dialog
https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Text#Fonts_in_Openscad.

This should explicitly tie to the "style=" parameter.

The fontfeatures property is appended to the|font name|after the

"fontfeatures" should be in typewriter font because it is a keyword.

"font name" should not be in typewriter font because it is not a
keyword.

optional style parameter. Its value is a semi-colon separated list
of feature codes, each prefixed by a plus, "+", to indicate that it
is being added,

Should end with a colon, not a comma.

font = "Linux Libertine G:style=Regular:fontfeatures=+smcp;+onum");

Size Parameter

Text size is normally given in points, and a point is 1/72 of an
inch high. The formula to convert thesizevalue to "points" is|pt =
size/3.937|, so asizeargument of 3.05 is about 12 points.

This is incorrect, because OpenSCAD is unitless.  "size" specifies
some dimension of the font, in OpenSCAD units.  See the discussion
above about exactly what dimension it measures. (OpenSCAD units are
typically interpreted as millimeters, but that's up to the user and
the consuming program; it is not part of OpenSCAD's definitions.)

There should be no reference to "points" except perhaps to disclaim
that anything is measured in points.

Note: Character size the distance from ascent to descent, not from
ascent to baseline.

Ref the arithmetic error mentioned above and the long discussion in
issue #4304, this is incorrect.  "size" should have measured
approximately the font ascent plus descent, but instead measures
(even more approximately) the font ascent.

One of these four names must be given as a string to
the|valign|parameter.

Since the valign parameter itself is optional, the word "must" seems
inappropriate.  Perhaps "The valign parameter may be set to one of
these four words".

top
The text is aligned so the top of the tallest character in your
text is at the given Y coordinate.

There is no "given Y coordinate".  The top of the tallest character
in your text is at the X axis, Y=0.

center
The text is aligned with the center of the bounding box at the
given Y coordinate.

Again, at Y=0.

baseline
The text is aligned with the font baseline at the given Y
coordinate.

Again, at Y=0.

bottom
The text is aligned so the bottom of the lowest-reaching
character in your text is at the given Y coordinate.

Again, at Y=0.

Note: only the "baseline" vertical alignment option will ensure
correct alignment of texts that use mix of fonts and sizes.

This overlaps a lot with the last sentence of the definition of
"baseline" and should probably be merged with it.

One of these three names must be given as a string to
the|halign|parameter.

Again, the word "must" seems inappropriate.

left
The text is aligned with the left side of the bounding box at
the given X coordinate.
center
The text is aligned with the center of the bounding box at the
given X coordinate.
right
The text is aligned with the right of the bounding box at the
given X coordinate.

None of these are correct.  The alignment is based on spacing, not on
the bounding box.  For most letters, "left" will position the ink
slightly to the right of X=0.  (For a size=10 M in Liberation Sans,
it's about 1.1 units right of X=0.)  I'd need to do more research to
figure out the exactly correct wording.

And for all of them, there is no "given [XY] coordinate". Positioning
is relative to the origin.

Spacing Parameter

Characters in a text element have the size dictated by their glyph
in the font being used. As such their size in X and Y is fixed. Each
glyph also has fixed|advance|values (it is a vector [a,b],
seetextmetrics
https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Text#textmetrics)
for the offset to the origin of the next character. The position of
each following character is the|advance.x|value multiplied by
the|space|value. Obviously letters in the string can be stretched
out when the factor is greater than 1, and can be made to overlap
when|space|is a fraction closer to zero, but interestingly, using a
negative value spaces each letter in the opposite of
the|direction|parameter.

This is more or less correct, but what it doesn't say is that
"spacing" is almost completely useless for a proportionally spaced
font, for two reasons.  Ref
https://github.com/openscad/openscad/issues/3859 .

  • It does not take ligatures into account; it spaces a ligature as
    a single glyph, yielding text that looks like "d i ffi c u l t".
  • Because it's a multiplier on the advance value, and because the
    advance value is larger for a wide glyph than it is for a narrow
    glyph, spacing between narrow glyphs and wide glyphs is radically
    different.  "IIIMMM" demonstrates this problem.

The "spacing" parameter should probably be downplayed, and should
probably be deprecated.

   Text Examples

Simulating Formatted Text

Needs to define what it means by "formatted".

When text needs to be drawn as if it was formatted it is possible to
use translate() to space lines of text vertically. Fonts that
descend below the baseline need to be spaced apart vertically by
about|1.4size|to not overlap. Some word processing programs use a
more generous spacing of|1.6
size|for "single spacing" and double
spacing can use|3.2*size|.

fontmetrics() can supply more correct values for the particular font.

But really this is advice, not reference material.

 Fonts in OpenSCAD

The fonts available for use in a script are thosed:

  • registered in the local system
  • included in the OpenSCAD installation
  • imported at run-time by a program

A call to fontmetrics() using only default settings shows the
installation's standard font and settings:

Any reference to fontmetrics() needs a "requires release XXX" note,
which at the moment is still "requires development snapshot".  But
really this should be at most a reference to the fontmetrics() section.

{
nominal = {
ascent = 12.5733;
descent = -2.9433;
};
max = {
ascent = 13.6109; descent = -4.2114;
};
interline = 15.9709;
font = {
family = "Liberation Sans";
style = "Regular";
};
}

Wherever this ends up, the indentation needs work.  It should match
the indentation style used in the examples.

None of the platforms OpenSCAD is available on include the
Liberation font family so having it as part of the app's
installation, and making it the default font, avoids problems of
font availability.

"None" is an awfully broad statement about a moving target. It would
be better to say "To avoid problems of font availability, OpenSCAD
includes the Liberation font family as part of its installation, and
has Liberation Sans as the default font.".

Note: It was previously noted in the docs that fonts may be added
to the installation by drag-and-drop of a font file into the editor
window, but as of version 2025 Snapshot this isnotthe case

That isn't what it said.  It said:

 You can drag a font in the font list, into the editor window to
 use in the text() statement.

I can't readily check a 2025 build at the moment, but as of Oct 2024
the it does exactly as described:  dragging a font from the OpenSCAD
font list into the editor window drops its name in the editor
window.  If that is no longer the case, it's a bug.

In general, don't say things like this.  If the documentation said X,
and you find that X is not true, then one of the following is true:

  • You didn't understand, and X is indeed true.  (And maybe the
    documentation needs to be clearer.)
  • X is false, and it's a bug.  (The bug should be fixed, not the
    documentation.)
  • X is false, and has always been false, and it was always a
    documentation error.  (And the documentation needs to be fixed.)
  • Indeed, X used to be true and is no longer true, and it's an
    intentional change, and nobody updated the documentation.  This
    is a very rare case, because it often means a compatibility
    problem or feature regression.

Regardless, the right answer is to file an issue to get the actual
answer.

In the following sample code a True Type Font, Andika, has been
added to the system fonts using its Font Management service.

We shouldn't talk about adding fonts to the system.  That's not our
problem.

But also, that's not what the sample does.  It adds a font to
OpenSCAD
, and has nothing to do with the platform font mechanisms.

Supported font file formats areTrueType
https://en.wikipedia.org/wiki/TrueTypefonts (.ttf) andOpenType
https://en.wikipedia.org/wiki/OpenTypefonts (
.otf). Once a file
is registered to the project the details of the fonts in it may be
seen in the font list dialog (see image) so that the logical font
names, variations, and their available styles are available for use
in the project.

This says "see image", but doesn't indicate which image.

And:  OpenSCAD doesn't have the notion of "projects" or "registered
to the project".

 3D Text by Extrusion

This is true of all 2D objects and so does not need to be mentioned. 
Delete.

position
a vector [X,Y], the origin of the first glyph, thus the
lower-left corner of the drawn text.

No, it's not the origin of the first glyph, or at least that's a
confusing phrase to use.  A glyph is usually positioned slightly to
the right of the origin, and if it's a descender then it's below the
origin, and some characters (e.g. quotes) are well above the origin. 
A more correct statement would be that it's the lower left corner of
the bounding box of the text.

If one is going to talk about the origin of a glyph, it should be the
point on the baseline to at the left edge of the advance... which
this isn't.

size
a vector [a,b], the size of the generated text.

Should be [x,y].  [a,b] doesn't tell you what "a" and "b" mean.

ascent
positive float, the amount that the text extends above the baseline.

Use the word "number" rather than "float".

It's not always positive; for a glyph entirely below the baseline
(like underscore in Liberation Sans) it's negative. (I'm not sure
that's truly the right definition, but it's the current behavior.)

descent
negative float, the amount that the text extends below the baseline.

Not always negative; for a glyph that is entirely above the baseline
(like apostrophe in Liberation Sans) it's positive. Again, I'm not
sure that's the right definition, but it's the current behavior.

offset
a vector default [0, 0], the lower-left corner of the box
containing the text, including inter-glyph spacing before the
first glyph.

There is no default; this is a value that's returned to you.

This is not the correct definition (and it wasn't correct in the
original that I wrote).  It's the position of the origin of the text,
after adjusting for halign and valign.  For normal LTR text, the X
coordinate is the X coordinate at the left edge of the first glyph's
advance, and the Y component is the Y coordinate of the baseline.

advance
a vector default [153.09, 0], amount of space to leave to any
following text.

There is no default (and certainly not that one!).

The original definition ("the "other end" of the text, the point at
which additional text should be positioned.") wasn't great, but was
more correct.  I would say "The point at which additional text should
be positioned, relative to the text's origin as reported by 'offset'.".

This example displays the text metrics for the default font used by
OpenSCAD:

"text metrics for ... font" is a non sequitur.  Text metrics measure
a particular string.  (And "used by OpenSCAD" is unnecessary; the
entire document is in that context.)

And it's incorrect; the default font is Liberation Sans and this
example uses Liberation Serif.

Better would be:

 This example displays the text metrics for "Hello, World!" for
 Liberation Serif with size=20:

https://en.wikibooks.org/wiki/File:OpenSCAD_textmetrics.pngUsing
textmetrics() to draw a box around text

s="Hello, World!";
size=20;
font="Liberation Serif";

translate([0,0,1])
text("Hello, World!",size=size,font=font);

Should use "s" instead of repeating the string.  (And this is in my
original, sigh.)

displays (formatted for readability):

The original "yields" is better, because it might or might not be
displayed.

ECHO:{
position=[0.7936,-4.2752];
size=[149.306,23.552];
ascent=19.2768;
descent=-4.2752;
offset=[0,0];
advance=[153.09,0];
}

The indentation should match the examples, with the close brace at
the left margin.

   fontmetrics()

size
Decimal, optional. The size of the font, as described above
for|text()|.

Replace "decimal" with "number".

0% developed  as of November 17, 2009
https://en.wikibooks.org/wiki/Help:Development_stages3D to 2D
Projection
https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/3D_to_2D_Projection

Using the|projection()|function, you can create 2d drawings from 3d
models,

So far so good.

 and export them to the dxf format.

This part should be deleted.  There are any number of things you
might do with a 2D projection of a 3D object.  Exporting to DXF is
only one.

 It works by projecting a 3D model to the (x,y) plane, with z at 0.
If|cut=true|, only points with z=0 are considered (effectively
cutting the object), with|cut=false|(/the default/), points above
and below the plane are considered as well (creating a proper
projection).

Example: Consider example002.scad, that comes with OpenSCAD.

https://en.wikibooks.org/wiki/File:Openscad_projection_example_2x.png

Then you can do a 'cut' projection, which gives you the 'slice' of
the x-y plane with z=0.

Doing the non-default case as the first example seems wrong; I would
swap the two examples.

Another Example

You can also use projection to get a 'side view' of an object.

This example seems unnecessary for a reference manual.  It's a
straightforward combination of the features described.

Links:

Seems inappropriate for a reference manual.  Also, doesn't seem more
complicated at all.

0% developed  as of November 17, 2009
https://en.wikibooks.org/wiki/Help:Development_stages2D to 3D
Extrusion
https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/2D_to_3D_Extrusion

Extrusion https://en.wikipedia.org/wiki/Extrusionis the process of
creating an object with a fixed cross-sectional profile. OpenSCAD
provides two commands

"Commands" isn't the right word.  "Modules" is more correct, but
"operations" is probably best.

Both extrusion methods work on a (possibly disjointed) 2D shape
normally drawn in the relevant plane (see below).

The old description of the behavior of extrusion for 2D objects that
have been moved off the Z=0 plane is an example of something that
should never have been documented.  It's not a particularly useful
behavior, and we might eventually want a different behavior.  At
most, it should have said "don't do that".

It should probably say "drawn on the Z=0 plane".

This child object is first projected onto the X-Y plane along the Z
axis to create the starting face of the extrusion.

Delete.  We shouldn't document that behavior.

The start face is duplicated at the Z position given by the height
parameter to create the extrusion's end face. The extrusion is then
formed by creating a surface that joins each point along the edges
of the two faces.

That's a seriously incomplete description, because it's only true
with all of the parameters at their defaults.

Or, in other words, the 2D shape may be ... a 2D shape.

Delete the whole sentence.

The 2D shape may have a Z value that moves it out of the X-Y plane,
and it may even be rotated out of parallel with it. As stated above,
the extrusion's starting face is the projection of the 2D shape onto
the X-Y plane, which, if it is rotated, will have the effect of
fore-shortening it normal to the axis of the rotation.

Delete.

Using a 3D object as the extrusion's child will cause a compile time
error.

Factually incorrect.  It's not a compile-time error; it's a run-time
error.

Also, we just said that the child must be a 2D shape.  Exact behavior
when that requirement is violated need not be (and probably should
not be) specified.

Delete.

Including a 3D object in a composition of 2D objects (formed using
boolean combinations on them) will be detected, the 3D object(s)
will be deleted from it and the remaining 2D objects will be the
basis for projecting their shape onto the X-Y plane.

We need not (and generally should not) specify the behavior in error
conditions.  Delete.

 Parameters For Linear Extrusion

There are no required parameters. The default operation is to
extrude the child by 100 units vertically from the X-Y Plane,
centered on the [0,0] origin.

"centered" is at best meaningless (because it's extruded wherever the
child is, without respect to the origin) and at worst incorrect
(because the default is to extrude into +Z, not to center in Z).
Delete that last phrase.

  1. height
    a non-negative integer, default 100, giving the length of the
    extrusion

Doesn't have to be an integer.

I don't know how strong a pattern we have for specifying parameters,
but they shouldn't be numbered.  (Except maybe if they are usable as
positional parameters - which don't match these numbers.)

  1. v - twist axis vector
    a vector of 3 signed decimal values, default [0,0,1], used as an
    eigen vector specifying the axis of rotation for the
    twist.[Note:Requires versionDevelopment snapshot]

I can't say that I truly understand eigenvectors, but I don't think
this is one.  The "signed" part is unnecessary, because all numbers
are signed, and the "decimal" part is meaningless because abstract
numbers have no base.

"v" is a vector of three numbers that controls the vector along which
the extrusion is done.

It has an interesting interaction with "height".  If both are
specified, height is used as the length of the extrusion, along the
direction that v points, and v's magnitude is ignored.  If only v is
specified, it is used to control both the direction and length of the
extrusion.

Saying that it's the axis of rotation for twist is sort of right, but
maybe needs more explanation.  Normally when you think of an axis of
rotation, you're rotating along the plane perpendicular to that
axis.  Here, though, it is perhaps more correct to say that it
controls the origin of the rotation. At each slice, the 2D shape is
rotated around Z, with the origin being the XY position of the
extrusion vector.

  1. center
    a boolean, default false, that, when true, causes the resulting
    solid to be vertically centered at the X-Y plane.

"at the Z=0 plane" would be a bit more obvious.

  1. convexity
    a non-negative integer, default 1, giving a measure of the
    complexity of the generated surface. See the Section on
    Convexity later on this page.

Should include a link... which should not be pointing at this page,
no matter which page we're talking about.

  1. twist
    a signed decimal,

a number

  180 degrees is a half twist, 360 is all the way around, and so on.

Unnecessary, delete.

  1. scale
    either : a non-negative, decimal value,

a non-negative number

 minimum 0.0,

Implied by "non-negative", delete.

  that specifies the factor by which the end face should be
 scaled up, or down, in size from that of the start face.

All scaling is either up or down.  Just "should be scaled".

 or : an [x,y] vector that scales the extrusion in the X and Y
 directions separately.

Delete the colon.

  1. slices
    a non-negative integer for the number of rows of polygons that
    the extr.

Needs help.

h
a named parameter, synonym to height

Just list it in the same block as height.

$fn $fs $fa
Special Parameters - given as named parameters.

They have standard special-variable semantics, which means they can
be specified in the context or in the call.  They should be
mentioned, but perhaps not as parameters per se.  I believe they only
affect twisted extrusions, so maybe they should be mentioned there.

   Center

This parameter affects only affects the vertical position or the
extrusion. Its X-Y position is always that of the projection that
sets its starting face.

"or" should be "of".

This is a nice comment, but doesn't say what the parameter does.

"When true, the extrusion is centered vertically around Z=0." seems
adequate to me, without any further comment, but a subsequent comment
about not affecting X and Y would be OK.

   Scale

This is multiplicative factor that affects the size of extrusion's
end face. As such 1.0 means no change, a value greater than one
expands the end face, and a value between 0.001 and less than 1
shrinks it.

"As such" is unnecessary.

I don't know where 0.001 came from.  I would say "a value less than 1
shrinks it".

 A value of 0.0 causes the end face to degenerate to a point,
turning the extrusion into a pyramid, cone, or complex pointy shape
according to what the starting shape is.

I'd say this is unnecessary.

Using the vector form sets the scale factor in the X and Y
directions separately

   Twist

Twist is applied, by default, as a rotation about the Z Axis.

As discussed above, twist is always around Z.  What v controls is the
origin of that rotation.

When the start face is at the origin a twist creates a spiral out of
any corners in the child shape. If the start face is translated away
from the origin the twist creates a spring shape.

I don't know if it's truly useful to try to describe the various
shapes that can result from twisting.

One thing that might be worth explicitly mentioning is that you can't
practically use linear_extrude to generate threads. You can come
temptingly close, but they won't be shaped right.  (It is actually
possible to get right, but requires an unobvious base shape.)

A positive twist rotates clockwise, negative twist the opposite.

Huh.  I basically never use twist, so I never noticed that it's
backwards from rotate.  That seems very wrong... and it's way too
late to fix it.  It might be worth mentioning this difference.

   Twist Axis Vector

The second parameter is an [x,y,z] eigen vector that specifies the
axis of rotation of the applied twist.

Suggest referring to it by name instead of by position.

 The ratios of the three dimensional values to their respective
coordinate axes specify the tilt away from the default axis,
[0,0,1], the Z-Axis. For instance, v=[cos(45),0,1] tilts the
extrusion at 45 degrees to the X axis.

It's actually a skew rather than a tilt.

The start and end faces are always normal to the Z-axis, even when
the twist axis is tilted. The extruded and twisted surfaces are thus
distorted from what might be expected in an extruded shape. The more
expected result may be achieved by applying a rotation to then
twisted extrusion on the Z Axis to tilt it into the desired position.

It's best not to make assumptions about what the user expects. 
Describe the operation, and describe it carefully. Do not describe
how to do things that are straightforward combinations of operations.


Note that the documentation does not discuss which happens first: 
twist or scale.  I don't believe it matters when using the same
scaling for X and Y, but matters a great deal with using different
scaling on the two axes.  It twists and then scales, which can mean
(for instance) that a shape that started out rectangular turns into a
parallelogram.  There's an argument that this is not the useful
behavior, and that scale-and-then-twist is more useful since it
retains the general shape throughout the extrusion.  I've started a
discussion a few times about maybe changing this, but I don't think
it ever came to a conclusion.  It might be best not to document this
without that conclusion.

   $fn, $fa, $fs Special Parameters

The special variables must be given as named parameters and are
applied to the extrusion, overriding the global setting. When the
same special variables are set on the base shape its values override
their use as parameters on the extrusion.

None of this is really accurate.

The special variables have standard special-variable behavior, which
means that you can specify them in the context or in the particular
call, and they apply to that context (including a specific call) and
everything that that is called from that context.  There is no
"global setting" that is special.

What matters for the linear_extrude (and in particular for twisted
extrusions) is the setting that it sees.

If the child 2D shape also uses these variables, what matters for
it is what it sees... which, absent an inner setting, will be the
same as what linear_extrude sees.

Thus, either:

 linear_extrude(height=10, twist=20, $fn=100) circle(10);

or

 $fn=100; linear_extrude(height=10, twist=20) circle(10);

will yield a high-resolution twist of a high-resolution circle.

On the other hand, either

 linear_extrude(height=10, twist=20, $fn=100) circle(10, $fn=3);

or

 $fn=100; linear_extrude(height=10, twist=20) circle(10, $fn=3);

will yield a high-resolution twist of a low-resolution circle - a
triangle.

   Extrusion From Imported DXF

Does not need to be discussed.  You can linear_extrude any 2D shape,
and an import of a DXF yields a 2D shape.

     A Unit Circle with No Twist

I don't think all of these examples are necessary.

Generate an extrusion from a circle 2 units along the X Axis from
the origin,

unit circle

centered vertically on the X-Y plane, with no twist. The extrusion
appears to have a pentagonal cross-section because the extrusion's
child is a 2D circle with the default value for $fn.

It doesn't appear to have a pentagonal cross-section.  It does
have a pentagonal cross-section.

The same circle, but made into a spiral by 500 degrees of
counter-clockwise twist.

If you look carefully, this example demonstrates why you can't make
threads.  As you twist it more, it becomes thinner and thinner in Z. 
The problem is that the cross-section of a thread is a strange shape.

     Mesh Refinement

The slices parameter defines the number of intermediate points along
the Z axis of the extrusion.

I am not sure of the exactly right way to describe this, because of
fence post errors.

"slices" controls the number of 3D "chunks" that make up the
extrusion.  The total number of instances of the original 2D object
is slices+1.

Its default increases with the value of twist.

It's some function of that and $fa/$fs/$fn.  I don't know what the
function is or exactly how to describe it.

Additional the segments parameter

Addition -> Additionally

Segments need to be a multiple of the polygon's fragments to have an
effect (6 or 9.. for a circle($fn=3), 8,12.. for a square() ).

I don't know what the actual behavior is, but that's not it. For more
complex shapes (I experimented with a right triangle) intermediate
values do have an effect.

Thespecial variables
https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Other_Language_Features$fn,
$fs and $fa can also be used to improve the output. If slices is not
defined, its value is taken from the defined $fn value.

Again, I don't know what the behavior is, but that's not it.
Increasing $fn does increase the number of slices, but it isn't
simply used as the number of slices.

$fa/$fs/$fn seem to control both slices and segments.

   Using with imported SVG

Does not need to be separately discussed.

 rotate_extrude() Operator Module

Rotational extrusion spins a 2D shape around the Z-axis to form a
solid which has rotational symmetry. One way to think of this
operation is to imagine a Potter's wheel placed on the X-Y plane
with its axis of rotation pointing up towards +Z. Then place the
to-be-made object on this virtual Potter's wheel (possibly extending
down below the X-Y plane towards -Z). The to-be-made object is the
cross-section of the object on the X-Y plane (keeping only the right
half, X >= 0). That is the 2D shape that will be fed to
rotate_extrude() as the child in order to generate this solid. Note
that the object started on the X-Y plane but is tilted up (rotated
+90 degrees about the X-axis) to extrude.

I'm not sure that this is the best possible explanation.

Since a 2D shape is rendered by OpenSCAD on the X-Y plane, an
alternative way to think of this operation is as follows: spins a 2D
shape around the Y-axis to form a solid. The resultant solid is
placed so that its axis of rotation lies along the Z-axis.

That's the way that I always think of it, though I mentally rotate it
to vertical before spinning it.

Just like the linear_extrude, the extrusion is always performed on
the projection of the 2D polygon to the XY plane.

Again, we should not document this behavior.

Transformations like rotate, translate, etc. applied to the 2D
polygon before extrusion modify the projection of the 2D polygon to
the XY plane and therefore also modify the appearance of the final
3D object.

  • A translation in Z of the 2D polygon has no effect on the result
    (as also the projection is not affected).
  • A translation in X increases the diameter of the final object.
  • A translation in Y results in a shift of the final object in Z
    direction.
  • A rotation about the X or Y axis distorts the cross section of
    the final object, as also the projection to the XY plane is
    distorted.

This is perhaps good stuff, if the part about projecting is removed.

Don't get confused, as OpenSCAD displays 2D polygons with a certain
height in the Z direction, so the 2D object (with its height)
appears to have a bigger projection to the XY plane. But for the
projection to the XY plane and also for the later extrusion only the
base polygon without height is used.

Once you get rid of the part about projecting this goes away too.

You cannot use rotate_extrude to produce a helix or screw thread.
Doing this properly can be difficult, so it's best to find a thread
library to make them for you.

This kind of comment can be valuable, but I'm not sure it belongs in
a reference manual.  If it is in a reference manual, it should be
in a clear and separate section (of the description of the particular
feature) marked "Application Notes" or something like that, to make
it clear that it's not part of the description of the feature.

If the shape spans the X axis a warning appears in the console
windows and the rotate_extrude() is ignored.

Don't talk about what window something appears in, because not
everybody uses the OpenSCAD GUI.

Don't talk about what happens "after" the error.

Just say that it's an error, period.

(And, BTW, this particular one is something that I think should not
be an error; I think that the result should be as if you split the 2D
shape in half, rotationally extruded both, and unioned them.  That
is, take the shape, sweep it 360 degrees, and anything it sweeps
through (whether once or twice) is part of the result.)

 If the 2D shape touches the Y axis, i.e. at x=0, itmustbe a line
that touches, not a point, as a point results in a zero thickness 3D
object, which is invalid and results in a CGAL error.

This may have been addressed with Manifold.

 *convexity* : If the extrusion fails for a non-trival 2D shape,
 try setting the convexity parameter (the default is not 10, but
 10 is a "good" value to try). See explanation further down.

Just point at the general discussion of convexity.  (Which should not
be on this page.)

And the extrusion does not "fail".  In fact, the artifacts may be
quite subtle.

 *start*[Note:Requires versionDevelopment snapshot] : Defaults to
 0 if*angle*is specified, and 180 if not. Specifies the starting
 angle of the extrusion, counter-clockwise from the positive X axis.

start was part of an effort to align rotational extrusion behavior
with the behavior of other round things.  I don't remember all of the
details, but there are few reasons why it isn't equivalent to
rotating the result.

 *$fa* : minimum angle (in degrees) of each fragment.
 *$fs* : minimum circumferential length of each fragment.
 *$fn* :*fixed*number of fragments in 360 degrees. Values of 3 or
 more override $fa and $fs

     $fa, $fs and $fn must be named parameters.click here for
     more details,
     <https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Other_Language_Features>.

Do not describe these in detail here.  Refer to a general description
of them elsewhere.

Do not ever, ever, say "click here".  Any text that would not make
sense when printed is wrong.

   Rotate Extrude on Imported DXF

Delete.

Increasing the number of fragments composing the 2D shape improves
the quality of the mesh, but takes longer to render.

Unnecessary.

rotate_extrude(convexity = 10)
translate([2, 0, 0])
circle(r = 1, $fn = 100);

This example is unnecessary; this is a description of rotate_extrude,
not circle()

The number of fragments used by the extrusion can also be increased.

rotate_extrude(convexity = 10, $fn = 100)
translate([2, 0, 0])
circle(r = 1, $fn = 100);

Use $fs and $fa here.  In fact, supply them at the top level.  And
this case doesn't require specifying convexity (though I'm not sure
why not).  Also, for circles this small high resolution is not
practical; make them bigger to make the example more real. Thus:

 $fa = 1;
 $fs = 1;
 rotate_extrude()
      translate([20, 0, 0])
          circle(r = 10);

That's really the best practice.  You almost never want to use $fn if
your intent is to create a circle.

(Minor exception that is itself something of a bug:  if you're trying
to force the number of sides to be a multiple of 4.  But that
shouldn't be discussed here.)

Using the parameter angle (with OpenSCAD versions 2016.xx), a hook
can be modeled .

https://en.wikibooks.org/wiki/File:Hook.pngOpenSCAD - a hook

eps = 0.01;
translate([eps, 60, 0])
rotate_extrude(angle=270, convexity=10)
translate([40, 0]) circle(10);
rotate_extrude(angle=90, convexity=10)
translate([20, 0]) circle(10);
translate([20, eps, 0])
rotate([90, 0, 0]) cylinder(r=10, h=80+eps);

Delete.

     Extruding a Polygon

Delete.

   Description of extrude parameters

Why are we repeating these here?  Don't, especially because there is
little commonality between linear_extrude and rotate_extrude.

 0% developed  as of November 17, 2009
 <https://en.wikibooks.org/wiki/Help:Development_stages>DXF
 Extrusion
 <https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/DXF_Extrusion>

Delete.

This should get more content.  At the current state of things it can
probably all go on the 2D page, but if it gets much more complex it
might want its own page with a brief summary and reference here.


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

If it ain't broke, work on until it is.😉 The attraction of openscad is it's relatively small set of functions. I've done everything I need with raw openscad (with the help from a few folk on here). Bosl2 is there for those who want an easier answer. It seems that some folk are wanting it to do things that were never designed into openscad functionality. For those folk, learn fusion, blender, whatever. The terminology in parts is a tad incorrect, cubes are more than squares, cylinders are more than cylinders, and you will never see a true circle on any digital display. Also, the language is initially awkward, and the solids can often have unwanted holes, but if you spend the time and effort you get used to it. My comment is related to openscad as a whole, not specific to 2d, but as nothing in the real world is 2d... Best wishes, Ray On 08/08/2025 12:36, Jon Bondy via Discuss wrote: > > What is the community getting for this INCREDIBLE level of effort? > > I think we should > > 1) revert the documentation back to prior to when Vulcan started > changing things > > 2) make a list of problems with the documentation (an explicit, > reviewable requirements list from which we can make controlled changes > to the documentation) > > 3) make small, localized changes that can be validated with minimal > effort. > > 4) perhaps this should be controlled in a manner similar to the > development of the software itself, with a GIT-like system of problem > descriptions and resolutions. > > The people who really contribute to OpenSCAD are few, perhaps less > than half a dozen.  To force them to spend their time working on a > project THAT DOES NOT NEED TO BE DONE, and is not going well, will > slow down development and bug fixes that DO need to be done. > > It is clear to me that having an OpenSCAD novice working on the > documentation is not a great idea.   Good intentions but bad results. > > Vulcan: if you REALLY want to help this community, use OpenSCAD > actively (every day) for a year, making complex designs, and then come > back. > > Is there anyone (or any group) that is in control of the documentation > Wiki?  If not, we need such an entity.  If so, someone needs to take > control of this project. > > Again, if I'm wrong, I apologize.  But I have been getting private > messages agreeing with me. > > Jon > > > On 8/8/2025 4:08 AM, Jordan Brown via Discuss wrote: >> >> [ I'll spend the effort to fix up this laptop configuration, again, >> sorry for the duplicates. ] >> >> >>> Two Dimensional Modelling >>> >>> >>> 0% developed  as of November 17, 2009 >>> <https://en.wikibooks.org/wiki/Help:Development_stages>2D >>> Primitives >>> <https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/2D_Primitives> >>> >>> All 2D primitives can be transformed with 3D transformations. >>> >> >> Really bad place to start.  Yes, you can transform them with 3D >> transforms, but if you do then the results can be weird. It should be >> discouraged; you should almost always work with 2D transforms when >> working with a 2D subassembly. >> >> Also, maybe we should talk about the primitives before we talk about >> what you can do with them. >> >> >>>  They are usually used as part of a 3D extrusion. >>> >> >> Yeah, eventually.  But again this doesn't seem appropriate for a "2D >> primitives" section.  Maybe for an overview section *above* that. >> >> >>>  Although they are infinitely thin, they are rendered with a 1-unit >>> thickness. >>> >> >> Again, maybe in an overview section. >> >> >>> *Note*: Trying to subtract with|difference()|from 3D object will >>> lead to unexpected results in final rendering. >>> >> >> The real rule is "don't mix 2D objects with 3D objects and 3D >> operations".  It isn't necessary or appropriate to say very much >> about what will happen if you do.  Some cases will yield errors, >> while others will do something weird.  We don't want the >> documentation to nail down any particular behavior, because there are >> reasons that we might want to change the behavior in these cases. >> >> Ref, e.g., OEP 7 "Mixed Dimension Geometry Support" >> <https://github.com/openscad/openscad/wiki/OEP7%3A-Mixed-Dimension-Geometry-Support>. >> >> >>> Square Object Module >>> >>> By default this module draws a unit square in the first quadrant, >>> (+X,+Y), starting at the origin [0,0]. Its four lines have no >>> thickness but the shape is drawn as a 1 unit high, filled plane. >>> >> >> The second sentence should probably just go away: >> >> * The first part "its four lines have no thickness" is both >> misleading - the lines have no independent existence - and >> incorrect; when rendered they *do* have thickness. >> * The second half (drawn as 1 unit high) restates something already >> said in above. >> >> >>> The module's arguments may be written in the order|<size>, >>> center=<bool>|without being named, but the names may be used as >>> shown in the examples: >>> >> >> There needs to be (but probably isn't) enough documentation >> convention that this need not be said. >> >> >>> *Parameters* >>> >>> size >>> has two forms:/single value/or/vector/ >>> single - non-negative float, length of all four sides >>> >> Should use the word "number" rather than the word "float". OpenSCAD >> does not have distinct floating point and integer types; it has only >> numbers. >> >> >>> center >>> boolean, default false, to set the shape's position in the X-Y plane >>> >>> *Center*When|false|, as it is by default, the shape will be drawn >>> from its first point at (0,0) in the First Quadrant, (+X,+Y). With >>> center set to|true|the shape is drawn centered on the origin. >>> >> >> These two paragraphs should be merged. >> >> >>> Circle Object Module >>> >>> By default this module draws a unit circle centered on the origin >>> [0,0] as a pentagon with its starting point on the X-axis at X=1. >>> Its lines have no thickness but the shape is drawn as a 1 unit high, >>> filled plane. >>> >> The part of the first sentence starting "as a pentagon ..." should go >> away.  It's true, but it really belongs as part of the description of >> $fa/$fs. >> >> Again, the second sentence should just go away. >> >> Somewhere it should say "Circles are approximated as regular >> polygons; see <reference to $fa/$fs/$fn> for the details of the >> polygons generated." >> >> >>> The argument|radius|may be given without being named, but >>> the|r|and|d|arguments must be named. >>> >> There is no "radius" argument.  There are r and d. >> >> Again, we should have a documentation convention so that we don't >> have to repeat positional/named rules, but the behavior here is that >> r can be supplied as the first argument, but d must be named. >> >> (Technically, if you say "circle(undef, 10)" the 10 is the second  it >> creates a 10-unit-diameter circle.  I would say that the fact that >> this works is a minor bug.) >> >> >>> $fa >>> Special Variable >>> $fs >>> Special Variable >>> $fn >>> Special Variable >>> >> Theses should be described only to the extent of pointing at the >> general description of $fa/$fs/$fn. >> >>> The default circle displays as a pentagram as that is the minimum >>> number of fragments used to approximate a curved shape calculated >>> from the default values for $fs and $fa. To have it draw as a smooth >>> shape increase the $fn value, the minimum number of fragments to >>> draw, to 20 or more (best $fn < 128). >>> >> This is just bad.  First, everything here should be covered in the >> description of $fa/$fs/$fn.  Second, using $fn to control the >> resolution of a circle is generally the wrong answer; you are better >> off setting $fa and $fs.  Finally, specific advice on $fn values is a >> bad idea, because the "looks smooth" value varies dramatically with >> size.  A 20-gon is okay for a medium-small circle; a 72-gon is not >> good enough for a 100-unit circle. >> >>> An alternative method to draw a very smooth circle scale is to scale >>> down a very large circle. >>> >>> scale( 0.001 ) circle(200); >> >> This should just go away; it confuses the issue. >> >> >>> Another way to solve the lack of a built-in module for regular >>> polygons is to write a custom one:module regular_polygon() >>> <https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/example_module_regular_polygon()> >>> >> I wouldn't include this.  Using polygon() is harder than using >> circle(), and anybody who's capable of using it should have little >> trouble simulating circle(). >> >> >>> convexity >>> Integer, default=1 - complex edge geometry may require a higher >>> value value to preview correctly. >>> >> >> Should include a link to a general discussion of convexity. Probably >> should not even mention the default; that should be covered in the >> general discussion. >> >> >>> *Points Parameter*A list of X-Y coordinates in this form: >>> >>> [[1, 1], [1, 4], [3, 4], [3, 1], [1, 1]] >>> >>> which defines four points and makes it explicit that the last one is >>> the same as the first. >>> >>> Including the first point twice is not strictly necessary as this: >>> >>> [[1, 1], [1, 4], [3, 4], [3, 1]] >>> >>> gives the same result. >>> >> >> This seems like it should be simplified.  In the absence of a paths >> parameter, the last point always connects to the first, because >> polygons are always closed. >> >> >>> *Paths Parameter* >>> >>> This optional parameter is a nested vector of paths. >>> >>> A "path" is a list of index values that reference points in >>> the|points|vector. It can explicitly describe a closed loop by its >>> last index being the same as its first, as in: >>> >>> [1, 2, 3, 4, 1] >>> >>> but this is equivalent to: >>> >>> [1, 2, 3, 4] >> >> >> Again, this seems like unnecessary complexity; the last point always >> connects to the first. >> >> >>> Notice that the points vector is simple list, >>> >> No, it's a list of lists. >> >>>  while each path is a separate vector. >>> >> Yes... points and paths are the same order. They are both lists of lists. >> >>>  This means that paths, that are lists of references to points, have >>> to "know" which points it needs to include. >>> >> While it's true that paths need to "know" the indexes they connect, I >> don't see how that follows from the previous sentences. >> >>>  This can be an issue if the polygon is assembled from a number of >>> shapes at run time as the order of adding shapes affects their >>> point's index values. >>> >> It's true that this is something that you must handle, but I don't >> think that a reference manual needs to discuss it. >> >> >>>  .*Convexity* >>> >> >> Formatting error:  this title is merged with the previous paragraph. >> (But should be deleted, see below.) >> >> >>> Shapes with a lot of detail in their edges may need the convexity >>> parameter increased to preview correctly. See Convexity >>> >> Already discussed, should be deleted. >> >>> *Example With Multiple Holes* >>> >>> [Note:Requires version2015.03] (for use of|concat()|) >>> >>> <https://en.wikibooks.org/wiki/File:OpenSCAD_romboid_with_holes.jpg> >>> >>> We are using "a" for the point lists and "b" for their paths: >>> >>> a0 = [[0,0],[100,0],[130,50],[30,50]]; // outer boundary >>> b0 = [1,0,3,2]; >>> a1 = [[20,20],[40,20],[30,30]]; // hole 1 >>> b1 = [4,5,6]; >>> a2 = [[50,20],[60,20],[40,30]]; // hole 2 >>> b2 = [7,8,9]; >>> a3 = [[65,10],[80,10],[80,40],[65,40]]; // hole 3 >>> b3 = [10,11,12,13]; >>> a4 = [[98,10],[115,40],[85,40],[85,10]]; // hole 4 >>> b4 = [14,15,16,17]; >>> a = concat( a0,a1,a2,a3,a4 ); // merge all points into "a" >>> b = [b0,b1,b2,b3,b4]; // place all paths into a vector >>> polygon(a,b); >>> //alternate >>> polygon(a,[b0,b1,b2,b3,b4]); >> >> >> The "alternate" at the end of the example seems unnecessary - of >> course you can use either a particular expression or a variable that >> has been set to that expression. >> >> >>> *2D to 3D by Extrusion* >>> >>> A polygon may be the basis for an extrusion, just as any of the 2D >>> primitives can. Thisexample script >>> <https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/example_module_2D_to_3D_extrusion>may >>> be used to draw the shape in this image: >>> >> >> Yes, a polygon can be used as the basis for extrusion, just as any of >> the 2D primitives can.  That means that you do *not* need a specific >> example of that case. >> >> >>> Import a 2D Shape From a DXF >>> >>> [Deprecated:import_dxf() will be removed in a future release. Use >>> Useimport() Object Module >>> <https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#import>instead. >>> instead*]* >>> >> As a deprecated feature, this should be pushed to the bottom. >> >>> Read a DXF file and create a 2D shape. >>> >>> *Example* >>> >>> linear_extrude(height = 5, center = true) >>> import_dxf(file = "example009.dxf", layer = "plate"); >>> >>> *Example with Import()* >>> >>> linear_extrude(height = 5, center = true) >>> import(file = "example009.dxf", layer = "plate"); >> >> >> The second should perhaps be titled "Replacement example with >> import()".  Note also that since OpenSCAD is case sensitive the word >> "import" should not be capitalized. >> >> >>> 0% developed  as of November 17, 2009 >>> <https://en.wikibooks.org/wiki/Help:Development_stages>Text >>> <https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Text> >>> >> Text is a big enough topic that it should probably have its own page, >> with just a brief mention and cross-reference here. >> >> I see that it *has* its own page and is transcluded here.  It should >> not be transcluded, because that makes it harder to just read everything. >> >>> >>> Text in OpenSCAD >>> >>> Being able to use text objects as a part of a model is valuable in a >>> lot of design solutions. >>> >> Delete this sentence.  This is reference material, not sales >> material.  The user already knows whether or not it's valuable to them. >> >> >>> The fontsavailable to use in a script >>> <https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Text#Fonts_in_OpenSCAD>are >>> from the system that OpenSCAD is running in with the addition of >>> those explicitly added by the script itself. >>> >> >> And OpenSCAD includes several.  (And this duplicates a more extensive >> discussion below.) >> >> >>> text() Object Module >>> >>> The|text()|object module draws a single string of text as a 2D >>> geometric object, using fonts installed on the local system or >>> provided as separate font file. >>> >> provided as +a+ separate font file >> >> >>> The shape starts at the origin and is drawn along the positive X axis. >>> >> >> By default, ... >> >> (because halign and valign change things) >> >> >>> text >>> String. A single line ofany character allowed >>> <https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Characters_Strings#Characters>.*Limitation:*non-printable >>> ASCII characters like newline and tab rendered as placeholders >>> >> Delete the second sentence.  If it's a string, it's allowed. As for >> being a single line and treatment of non-printable characters, need >> to phrase that as a current restriction, not as a permanent behavior >> - it would be good if we could eventually provide more support there, >> and we wouldn't want to be prevented from adding that support by >> compatibility concerns.  Ref >> https://github.com/openscad/openscad/issues/5018 for the desire for >> multi-line text. >> >>> font >>> aformatted string >>> <https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Text#Parameters>with >>> default font of "Liberation Sans:style=Regular" >>> >> >> "formatted string" is a poor phrase there.  Better would be something >> like "String.  A font specification with ...". >> >> Also I see that this is a link over to a separate Text page. A >> separate Text page is good, as discussed above, but it shouldn't be >> duplicated here. >> >> >>> size >>> non-negative decimal, default=10. The generated text has a >>> height above the baseline of approximately this value, varying >>> for different fonts but typically being slightly smaller. >>> >> The "decimal" part should be "number".  (It isn't even sensible to >> talk about a base.) >> >> I don't feel the need for the "non-negative" part.  (It should >> probably also be non-zero.)  Unless we have a special meaning for a >> negative size, we should be able to let people figure out for >> themselves that if they make a silly request they will get a silly >> answer. >> >> Current behavior is ... interesting... though when you think about it >> unsurprising:  the text is mirrored in X and Y, leading to it being >> effectively rotated 180 degrees.  Unless we really want to keep that >> behavior, we should probably make it be an error instead.  Until and >> unless we decide that we want to keep that behavior, we should *not* >> document it. >> >> There needs to be a footnote about size.  Because of an arithmetic >> error in the implementation (issue #4304 >> <https://github.com/openscad/openscad/issues/4304>), the "size" >> parameter does not correspond to a typical font size specification.  >> It is a coincidence that the arithmetic error approximately cancels >> out the usual ratio between the specified font size and the size of a >> capital letter, making "size" approximately specify the size of a >> capital letter in a typical Western font.  However, since the result >> *is* useful, and the error has been in place since the beginning, we >> really can't fix it.  Maybe at some point we can introduce an >> alternative parameter that specifies a more conventional font size, >> eg PR#4306 <https://github.com/openscad/openscad/pull/4306>. >> >> >>> spacing >>> float, default=1. Multiplicative factor that increases or >>> decreases spacing between characters. >>> >> "float" should be "number". >> >>> language >>> String. The language of the text (e.g., "en", "ar", "ch"). >>> Default is "en". >>> script >>> String, default="latin". The script of the text (e.g. "latin", >>> "arabic", "hani"). >>> >> >> Somebody needs to figure out what these actually do. >> >> >>> $fn >>> higher values generate smoother curves (refer toSpecial >>> Variables >>> <https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Other_Language_Features#special_variables>) >>> >> >> This should refer to $fa, $fs, and $fn... and really you shouldn't be >> using $fn here. >> >> >>> Font & Style Parameter >>> >>> The "name" of a font is a string starting with its|logical font >>> name|and|variation|, >>> >> I don't see variation as a separate part of the specification. >> >> Also, use of the "typewriter" font here is inappropriate; neither of >> these is a language keyword or language component. Either use plain >> text or perhaps italics. >> >> >>>  optionally followed by a colon (":") separated list of font >>> specifications like a|style|selection, and a set of zero or >>> more|features|. >>> >> >> We should include a list of the name=value specifications supported, >> or refer to external (fontconfig?) documentation. >> >> Again, "features" is not a keyword and should not be in typewriter font. >> >> >>> The common variations in a font family are|sans|and|serif|though >>> many others will be seen in the list of fonts available. Each font >>> variation can be drawn with a/style/to support textual emphasis. >>> >> >> I think those are part of the font name, and that there they are >> usually capitalized.  I'm a bit torn on whether they should be in >> typewriter font. >> >> >>> The default, upright appearance is usually called "Regular" with >>> "Bold", "Italic", and "Bold Italic" being the other three styles >>> commonly included in a font. In general the styles offered by a font >>> may only be known by using the platform's font configuration tools >>> or theOpenSCAD font list dialog >>> <https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Text#Fonts_in_Openscad>. >>> >> >> This should explicitly tie to the "style=" parameter. >> >> >>> The fontfeatures property is appended to the|font name|after the >>> >> >> "fontfeatures" should be in typewriter font because it is a keyword. >> >> "font name" should not be in typewriter font because it is *not* a >> keyword. >> >> >>> optional style parameter. Its value is a semi-colon separated list >>> of feature codes, each prefixed by a plus, "+", to indicate that it >>> is being added, >>> >> >> Should end with a colon, not a comma. >> >> >>> font = "Linux Libertine G:style=Regular:fontfeatures=+smcp;+onum"); >>> >>> *Size Parameter* >>> >>> Text size is normally given in points, and a point is 1/72 of an >>> inch high. The formula to convert the*size*value to "points" is|pt = >>> size/3.937|, so a*size*argument of 3.05 is about 12 points. >>> >> >> This is incorrect, because OpenSCAD is unitless.  "size" specifies >> some dimension of the font, in OpenSCAD units.  See the discussion >> above about exactly what dimension it measures. (OpenSCAD units are >> *typically* interpreted as millimeters, but that's up to the user and >> the consuming program; it is not part of OpenSCAD's definitions.) >> >> There should be no reference to "points" except perhaps to *disclaim* >> that anything is measured in points. >> >>> *Note*: Character size the distance from ascent to descent, not from >>> ascent to baseline. >>> >> Ref the arithmetic error mentioned above and the long discussion in >> issue #4304, this is incorrect.  "size" *should have* measured >> approximately the font ascent plus descent, but instead measures >> (even more approximately) the font ascent. >> >>> One of these four names must be given as a string to >>> the|valign|parameter. >>> >> Since the valign parameter itself is optional, the word "must" seems >> inappropriate.  Perhaps "The valign parameter may be set to one of >> these four words". >> >>> top >>> The text is aligned so the top of the tallest character in your >>> text is at the given Y coordinate. >>> >> >> There is no "given Y coordinate".  The top of the tallest character >> in your text is at the X axis, Y=0. >> >>> center >>> The text is aligned with the center of the bounding box at the >>> given Y coordinate. >>> >> >> Again, at Y=0. >> >> >>> baseline >>> The text is aligned with the font baseline at the given Y >>> coordinate. >>> >> Again, at Y=0. >>> >>> bottom >>> The text is aligned so the bottom of the lowest-reaching >>> character in your text is at the given Y coordinate. >>> >> >> Again, at Y=0. >> >> >>> *Note*: only the "baseline" vertical alignment option will ensure >>> correct alignment of texts that use mix of fonts and sizes. >>> >> This overlaps a lot with the last sentence of the definition of >> "baseline" and should probably be merged with it. >> >>> One of these three names must be given as a string to >>> the|halign|parameter. >>> >> >> Again, the word "must" seems inappropriate. >> >> >>> left >>> The text is aligned with the left side of the bounding box at >>> the given X coordinate. >>> center >>> The text is aligned with the center of the bounding box at the >>> given X coordinate. >>> right >>> The text is aligned with the right of the bounding box at the >>> given X coordinate. >>> >> >> None of these are correct.  The alignment is based on spacing, not on >> the bounding box.  For most letters, "left" will position the ink >> slightly to the right of X=0.  (For a size=10 M in Liberation Sans, >> it's about 1.1 units right of X=0.)  I'd need to do more research to >> figure out the exactly correct wording. >> >> And for all of them, there is no "given [XY] coordinate". Positioning >> is relative to the origin. >> >>> *Spacing Parameter* >>> >>> Characters in a text element have the size dictated by their glyph >>> in the font being used. As such their size in X and Y is fixed. Each >>> glyph also has fixed|advance|values (it is a vector [a,b], >>> seetextmetrics >>> <https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Text#textmetrics>) >>> for the offset to the origin of the next character. The position of >>> each following character is the|advance.x|value multiplied by >>> the|space|value. Obviously letters in the string can be stretched >>> out when the factor is greater than 1, and can be made to overlap >>> when|space|is a fraction closer to zero, but interestingly, using a >>> negative value spaces each letter in the opposite of >>> the|direction|parameter. >>> >> >> This is more or less correct, but what it doesn't say is that >> "spacing" is almost completely useless for a proportionally spaced >> font, for two reasons.  Ref >> https://github.com/openscad/openscad/issues/3859 . >> >> * It does not take ligatures into account; it spaces a ligature as >> a single glyph, yielding text that looks like "d i ffi c u l t". >> * Because it's a multiplier on the advance value, and because the >> advance value is larger for a wide glyph than it is for a narrow >> glyph, spacing between narrow glyphs and wide glyphs is radically >> different.  "IIIMMM" demonstrates this problem. >> >> The "spacing" parameter should probably be downplayed, and should >> probably be deprecated. >> >>> >>> Text Examples >>> >>> *Simulating Formatted Text* >>> >> Needs to define what it means by "formatted". >>> >>> When text needs to be drawn as if it was formatted it is possible to >>> use translate() to space lines of text vertically. Fonts that >>> descend below the baseline need to be spaced apart vertically by >>> about|1.4*size|to not overlap. Some word processing programs use a >>> more generous spacing of|1.6*size|for "single spacing" and double >>> spacing can use|3.2*size|. >>> >> fontmetrics() can supply more correct values for the particular font. >> >> But really this is advice, not reference material. >> >> >>> Fonts in OpenSCAD >>> >>> The fonts available for use in a script are thosed: >>> >>> * registered in the local system >>> * included in the OpenSCAD installation >>> * imported at run-time by a program >>> >>> A call to fontmetrics() using only default settings shows the >>> installation's standard font and settings: >>> >> >> Any reference to fontmetrics() needs a "requires release XXX" note, >> which at the moment is still "requires development snapshot".  But >> really this should be at most a reference to the fontmetrics() section. >> >>> { >>> nominal = { >>> ascent = 12.5733; >>> descent = -2.9433; >>> }; >>> max = { >>> ascent = 13.6109; descent = -4.2114; >>> }; >>> interline = 15.9709; >>> font = { >>> family = "Liberation Sans"; >>> style = "Regular"; >>> }; >>> } >> >> Wherever this ends up, the indentation needs work.  It should match >> the indentation style used in the examples. >> >> >>> None of the platforms OpenSCAD is available on include the >>> Liberation font family so having it as part of the app's >>> installation, and making it the default font, avoids problems of >>> font availability. >>> >> "None" is an awfully broad statement about a moving target. It would >> be better to say "To avoid problems of font availability, OpenSCAD >> includes the Liberation font family as part of its installation, and >> has Liberation Sans as the default font.". >> >>> *Note*: It was previously noted in the docs that fonts may be added >>> to the installation by drag-and-drop of a font file into the editor >>> window, but as of version 2025 Snapshot this is*not*the case >>> >> >> That isn't what it said.  It said: >> >> You can drag a font in the font list, into the editor window to >> use in the text() statement. >> >> I can't readily check a 2025 build at the moment, but as of Oct 2024 >> the it does exactly as described:  dragging a font from the OpenSCAD >> font list into the editor window drops its name in the editor >> window.  If that is no longer the case, it's a bug. >> >> In general, don't say things like this.  If the documentation said X, >> and you find that X is not true, then one of the following is true: >> >> * You didn't understand, and X is indeed true.  (And maybe the >> documentation needs to be clearer.) >> * X is false, and it's a bug.  (The bug should be fixed, not the >> documentation.) >> * X is false, and has always been false, and it was always a >> documentation error.  (And the documentation needs to be fixed.) >> * Indeed, X used to be true and is no longer true, and it's an >> intentional change, and nobody updated the documentation.  This >> is a very rare case, because it often means a compatibility >> problem or feature regression. >> >> Regardless, the right answer is to file an issue to get the actual >> answer. >> >>> In the following sample code a True Type Font, Andika, has been >>> added to the system fonts using its Font Management service. >>> >> >> We shouldn't talk about adding fonts to the system.  That's not our >> problem. >> >> But also, that's not what the sample does.  It adds a font *to >> OpenSCAD*, and has nothing to do with the platform font mechanisms. >> >> >>> Supported font file formats areTrueType >>> <https://en.wikipedia.org/wiki/TrueType>fonts (*.ttf) andOpenType >>> <https://en.wikipedia.org/wiki/OpenType>fonts (*.otf). Once a file >>> is registered to the project the details of the fonts in it may be >>> seen in the font list dialog (see image) so that the logical font >>> names, variations, and their available styles are available for use >>> in the project. >>> >> This says "see image", but doesn't indicate *which* image. >> >> And:  OpenSCAD doesn't have the notion of "projects" or "registered >> to the project". >> >>> >>> 3D Text by Extrusion >>> >> >> This is true of all 2D objects and so does not need to be mentioned.  >> Delete. >> >> >>> position >>> a vector [X,Y], the origin of the first glyph, thus the >>> lower-left corner of the drawn text. >>> >> No, it's not the origin of the first glyph, or at least that's a >> confusing phrase to use.  A glyph is usually positioned slightly to >> the right of the origin, and if it's a descender then it's below the >> origin, and some characters (e.g. quotes) are well above the origin.  >> A more correct statement would be that it's the lower left corner of >> the bounding box of the text. >> >> If one is going to talk about the origin of a glyph, it should be the >> point on the baseline to at the left edge of the advance... which >> this isn't. >> >> >>> size >>> a vector [a,b], the size of the generated text. >>> >> Should be [x,y].  [a,b] doesn't tell you what "a" and "b" mean. >> >>> ascent >>> positive float, the amount that the text extends above the baseline. >>> >> Use the word "number" rather than "float". >> >> It's not always positive; for a glyph entirely below the baseline >> (like underscore in Liberation Sans) it's negative. (I'm not sure >> that's truly the right definition, but it's the current behavior.) >> >>> descent >>> negative float, the amount that the text extends below the baseline. >>> >> >> Not always negative; for a glyph that is entirely above the baseline >> (like apostrophe in Liberation Sans) it's positive. Again, I'm not >> sure that's the right definition, but it's the current behavior. >> >> >>> offset >>> a vector default [0, 0], the lower-left corner of the box >>> containing the text, including inter-glyph spacing before the >>> first glyph. >>> >> >> There is no default; this is a value that's returned to you. >> >> This is not the correct definition (and it wasn't correct in the >> original that I wrote).  It's the position of the origin of the text, >> after adjusting for halign and valign.  For normal LTR text, the X >> coordinate is the X coordinate at the left edge of the first glyph's >> advance, and the Y component is the Y coordinate of the baseline. >> >> >>> advance >>> a vector default [153.09, 0], amount of space to leave to any >>> following text. >>> >> There is no default (and certainly not that one!). >> >> The original definition ("the "other end" of the text, the point at >> which additional text should be positioned.") wasn't great, but was >> more correct.  I would say "The point at which additional text should >> be positioned, relative to the text's origin as reported by 'offset'.". >> >>> This example displays the text metrics for the default font used by >>> OpenSCAD: >>> >> "text metrics for ... font" is a non sequitur.  Text metrics measure >> a particular string.  (And "used by OpenSCAD" is unnecessary; the >> entire document is in that context.) >> >> And it's incorrect; the default font is Liberation Sans and this >> example uses Liberation Serif. >> >> Better would be: >> >> This example displays the text metrics for "Hello, World!" for >> Liberation Serif with size=20: >> >>> <https://en.wikibooks.org/wiki/File:OpenSCAD_textmetrics.png>Using >>> textmetrics() to draw a box around text >>> >>> s="Hello, World!"; >>> size=20; >>> font="Liberation Serif"; >> >>> translate([0,0,1]) >>> text("Hello, World!",size=size,font=font); >> >> >> Should use "s" instead of repeating the string.  (And this is in my >> original, sigh.) >> >> >>> displays (formatted for readability): >>> >> The original "yields" is better, because it might or might not be >> displayed. >> >>> ECHO:{ >>> position=[0.7936,-4.2752]; >>> size=[149.306,23.552]; >>> ascent=19.2768; >>> descent=-4.2752; >>> offset=[0,0]; >>> advance=[153.09,0]; >>> } >> >> The indentation should match the examples, with the close brace at >> the left margin. >> >>> >>> fontmetrics() >>> >> >>> size >>> Decimal, optional. The size of the font, as described above >>> for|text()|. >>> >> Replace "decimal" with "number". >> >>> >>> 0% developed  as of November 17, 2009 >>> <https://en.wikibooks.org/wiki/Help:Development_stages>3D to 2D >>> Projection >>> <https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/3D_to_2D_Projection> >>> >>> Using the|projection()|function, you can create 2d drawings from 3d >>> models, >>> >> So far so good. >>> >>>  and export them to the dxf format. >>> >> This part should be deleted.  There are any number of things you >> might do with a 2D projection of a 3D object.  Exporting to DXF is >> only one. >> >>>  It works by projecting a 3D model to the (x,y) plane, with z at 0. >>> If|cut=true|, only points with z=0 are considered (effectively >>> cutting the object), with|cut=false|(/the default/), points above >>> and below the plane are considered as well (creating a proper >>> projection). >>> >>> *Example*: Consider example002.scad, that comes with OpenSCAD. >>> >>> <https://en.wikibooks.org/wiki/File:Openscad_projection_example_2x.png> >>> >>> Then you can do a 'cut' projection, which gives you the 'slice' of >>> the x-y plane with z=0. >>> >> >> Doing the non-default case as the first example seems wrong; I would >> swap the two examples. >> >>> *Another Example* >>> >>> You can also use projection to get a 'side view' of an object. >>> >> This example seems unnecessary for a reference manual.  It's a >> straightforward combination of the features described. >> >>> Links: >>> >>> * More complicated example >>> <http://www.gilesbathgate.com/2010/06/extracting-2d-mendel-outlines-using-openscad/>from >>> Giles Bathgate's blog >>> >> >> Seems inappropriate for a reference manual.  Also, doesn't seem more >> complicated at all. >> >> >>> 0% developed  as of November 17, 2009 >>> <https://en.wikibooks.org/wiki/Help:Development_stages>2D to 3D >>> Extrusion >>> <https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/2D_to_3D_Extrusion> >>> >>> Extrusion <https://en.wikipedia.org/wiki/Extrusion>is the process of >>> creating an object with a fixed cross-sectional profile. OpenSCAD >>> provides two commands >>> >> >> "Commands" isn't the right word.  "Modules" is more correct, but >> "operations" is probably best. >> >> >>> Both extrusion methods work on a (possibly disjointed) 2D shape >>> normally drawn in the relevant plane (see below). >>> >> >> The old description of the behavior of extrusion for 2D objects that >> have been moved off the Z=0 plane is an example of something that >> should never have been documented.  It's not a particularly useful >> behavior, and we might eventually want a different behavior.  At >> most, it should have said "don't do that". >> >> It should probably say "drawn on the Z=0 plane". >> >> >>> This child object is first projected onto the X-Y plane along the Z >>> axis to create the starting face of the extrusion. >>> >> >> Delete.  We shouldn't document that behavior. >> >> >>> The start face is duplicated at the Z position given by the height >>> parameter to create the extrusion's end face. The extrusion is then >>> formed by creating a surface that joins each point along the edges >>> of the two faces. >>> >> >> That's a seriously incomplete description, because it's only true >> with all of the parameters at their defaults. >> >> >>> The 2D shape may be any2D primitive shape >>> <https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/2D_Primitives>, >>> a2d polygon >>> <https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/2D_Primitives#Polygon>, >>> animported 2D drawing >>> <https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/2D_Primitives#Importing_a_2D_Drawing>, >>> or aboolean combination >>> <https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/CSG_Modelling>of >>> them. >>> >> Or, in other words, the 2D shape may be ... a 2D shape. >> >> Delete the whole sentence. >> >> >>> The 2D shape may have a Z value that moves it out of the X-Y plane, >>> and it may even be rotated out of parallel with it. As stated above, >>> the extrusion's starting face is the projection of the 2D shape onto >>> the X-Y plane, which, if it is rotated, will have the effect of >>> fore-shortening it normal to the axis of the rotation. >>> >> >> Delete. >> >> >>> Using a 3D object as the extrusion's child will cause a compile time >>> error. >>> >> >> Factually incorrect.  It's not a compile-time error; it's a run-time >> error. >> >> Also, we just said that the child must be a 2D shape.  Exact behavior >> when that requirement is violated need not be (and probably should >> not be) specified. >> >> Delete. >> >>> Including a 3D object in a composition of 2D objects (formed using >>> boolean combinations on them) will be detected, the 3D object(s) >>> will be deleted from it and the remaining 2D objects will be the >>> basis for projecting their shape onto the X-Y plane. >>> >> We need not (and generally should not) specify the behavior in error >> conditions.  Delete. >> >> >>> Parameters For Linear Extrusion >>> >>> There are no required parameters. The default operation is to >>> extrude the child by 100 units vertically from the X-Y Plane, >>> centered on the [0,0] origin. >>> >> "centered" is at best meaningless (because it's extruded wherever the >> child is, without respect to the origin) and at worst incorrect >> (because the default is to extrude into +Z, not to center in Z). >> Delete that last phrase. >> >>> 1) height >>> a non-negative integer, default 100, giving the length of the >>> extrusion >>> >> Doesn't have to be an integer. >> >> I don't know how strong a pattern we have for specifying parameters, >> but they shouldn't be numbered.  (Except maybe if they are usable as >> positional parameters - which don't match these numbers.) >> >> >>> 2) v - twist axis vector >>> a vector of 3 signed decimal values, default [0,0,1], used as an >>> eigen vector specifying the axis of rotation for the >>> twist.[Note:Requires versionDevelopment snapshot] >>> >> I can't say that I truly understand eigenvectors, but I don't think >> this is one.  The "signed" part is unnecessary, because all numbers >> are signed, and the "decimal" part is meaningless because abstract >> numbers have no base. >> >> "v" is a vector of three numbers that controls the vector along which >> the extrusion is done. >> >> It has an interesting interaction with "height".  If both are >> specified, height is used as the length of the extrusion, along the >> direction that v points, and v's magnitude is ignored.  If only v is >> specified, it is used to control both the direction and length of the >> extrusion. >> >> Saying that it's the axis of rotation for twist is sort of right, but >> maybe needs more explanation.  Normally when you think of an axis of >> rotation, you're rotating along the plane perpendicular to that >> axis.  Here, though, it is perhaps more correct to say that it >> controls the *origin* of the rotation. At each slice, the 2D shape is >> rotated around Z, with the origin being the XY position of the >> extrusion vector. >> >>> 3) center >>> a boolean, default false, that, when true, causes the resulting >>> solid to be vertically centered at the X-Y plane. >>> >> "at the Z=0 plane" would be a bit more obvious. >> >>> 4) convexity >>> a non-negative integer, default 1, giving a measure of the >>> complexity of the generated surface. See the Section on >>> Convexity later on this page. >>> >> Should include a link... which should not be pointing at this page, >> no matter which page we're talking about. >> >>> 5) twist >>> a signed decimal, >>> >> a number >> >> >>>  180 degrees is a half twist, 360 is all the way around, and so on. >>> >> Unnecessary, delete. >> >> >>> 6) scale >>> either : a non-negative, decimal value, >>> >> a non-negative number >> >>> minimum 0.0, >>> >> >> Implied by "non-negative", delete. >> >> >>>  that specifies the factor by which the end face should be >>> scaled up, or down, in size from that of the start face. >>> >> All scaling is either up or down.  Just "should be scaled". >> >> >>> or : an [x,y] vector that scales the extrusion in the X and Y >>> directions separately. >>> >> >> Delete the colon. >> >> >>> 7) slices >>> a non-negative integer for the number of rows of polygons that >>> the extr. >>> >> Needs help. >> >> >>> h >>> a named parameter, synonym to height >>> >> >> Just list it in the same block as height. >> >> >>> $fn $fs $fa >>> Special Parameters - given as named parameters. >>> >> >> They have standard special-variable semantics, which means they can >> be specified in the context or in the call.  They should be >> mentioned, but perhaps not as parameters per se.  I believe they only >> affect twisted extrusions, so maybe they should be mentioned there. >> >> >>> Center >>> >>> This parameter affects only affects the vertical position or the >>> extrusion. Its X-Y position is always that of the projection that >>> sets its starting face. >>> >> "or" should be "of". >> >> This is a nice comment, but doesn't say what the parameter *does*. >> >> "When true, the extrusion is centered vertically around Z=0." seems >> adequate to me, without any further comment, but a subsequent comment >> about not affecting X and Y would be OK. >> >> >>> Scale >>> >>> This is multiplicative factor that affects the size of extrusion's >>> end face. As such 1.0 means no change, a value greater than one >>> expands the end face, and a value between 0.001 and less than 1 >>> shrinks it. >>> >> "As such" is unnecessary. >> >> I don't know where 0.001 came from.  I would say "a value less than 1 >> shrinks it". >> >>>  A value of 0.0 causes the end face to degenerate to a point, >>> turning the extrusion into a pyramid, cone, or complex pointy shape >>> according to what the starting shape is. >>> >> I'd say this is unnecessary. >> >> >>> Using the vector form sets the scale factor in the X and Y >>> directions separately >>> >>> >>> Twist >>> >>> Twist is applied, by default, as a rotation about the Z Axis. >>> >> As discussed above, twist is always around Z.  What v controls is the >> origin of that rotation. >> >> >>> When the start face is at the origin a twist creates a spiral out of >>> any corners in the child shape. If the start face is translated away >>> from the origin the twist creates a spring shape. >>> >> I don't know if it's truly useful to try to describe the various >> shapes that can result from twisting. >> >> One thing that might be worth explicitly mentioning is that you can't >> practically use linear_extrude to generate threads. You can come >> temptingly close, but they won't be shaped right.  (It is actually >> possible to get right, but requires an unobvious base shape.) >> >> >>> A positive twist rotates clockwise, negative twist the opposite. >>> >> >> Huh.  I basically never use twist, so I never noticed that it's >> backwards from rotate.  That seems very wrong... and it's way too >> late to fix it.  It might be worth mentioning this difference. >> >> >>> Twist Axis Vector >>> >>> The second parameter is an [x,y,z] eigen vector that specifies the >>> axis of rotation of the applied twist. >>> >> >> Suggest referring to it by name instead of by position. >> >> >>>  The ratios of the three dimensional values to their respective >>> coordinate axes specify the tilt away from the default axis, >>> [0,0,1], the Z-Axis. For instance, v=[cos(45),0,1] tilts the >>> extrusion at 45 degrees to the X axis. >>> >> >> It's actually a skew rather than a tilt. >> >> >>> The start and end faces are always normal to the Z-axis, even when >>> the twist axis is tilted. The extruded and twisted surfaces are thus >>> distorted from what might be expected in an extruded shape. The more >>> expected result may be achieved by applying a rotation to then >>> twisted extrusion on the Z Axis to tilt it into the desired position. >>> >> It's best not to make assumptions about what the user expects.  >> Describe the operation, and describe it carefully. Do not describe >> how to do things that are straightforward combinations of operations. >> >> --- >> >> Note that the documentation does not discuss which happens first:  >> twist or scale.  I don't believe it matters when using the same >> scaling for X and Y, but matters a great deal with using different >> scaling on the two axes.  It twists and then scales, which can mean >> (for instance) that a shape that started out rectangular turns into a >> parallelogram.  There's an argument that this is *not* the useful >> behavior, and that scale-and-then-twist is more useful since it >> retains the general shape throughout the extrusion.  I've started a >> discussion a few times about maybe changing this, but I don't think >> it ever came to a conclusion.  It might be best not to document this >> without that conclusion. >> >> >>> $fn, $fa, $fs Special Parameters >>> >>> The special variables must be given as named parameters and are >>> applied to the extrusion, overriding the global setting. When the >>> same special variables are set on the base shape its values override >>> their use as parameters on the extrusion. >>> >> None of this is really accurate. >> >> The special variables have standard special-variable behavior, which >> means that you can specify them in the context or in the particular >> call, and they apply to that context (including a specific call) and >> everything that that is called from that context.  There is no >> "global setting" that is special. >> >> What matters for the linear_extrude (and in particular for twisted >> extrusions) is the setting that *it* sees. >> >> If the child 2D shape *also* uses these variables, what matters for >> it is what *it* sees... which, absent an inner setting, will be the >> same as what linear_extrude sees. >> >> Thus, either: >> >> linear_extrude(height=10, twist=20, $fn=100) circle(10); >> >> or >> >> $fn=100; linear_extrude(height=10, twist=20) circle(10); >> >> will yield a high-resolution twist of a high-resolution circle. >> >> On the other hand, either >> >> linear_extrude(height=10, twist=20, $fn=100) circle(10, $fn=3); >> >> or >> >> $fn=100; linear_extrude(height=10, twist=20) circle(10, $fn=3); >> >> will yield a high-resolution twist of a low-resolution circle - a >> triangle. >> >>> >>> Extrusion From Imported DXF >>> >> Does not need to be discussed.  You can linear_extrude any 2D shape, >> and an import of a DXF yields a 2D shape. >> >>> >>> A Unit Circle with No Twist >>> >> >> I don't think all of these examples are necessary. >> >> >>> Generate an extrusion from a circle 2 units along the X Axis from >>> the origin, >>> >> unit circle >> >>> centered vertically on the X-Y plane, with no twist. The extrusion >>> appears to have a pentagonal cross-section because the extrusion's >>> child is a 2D circle with the default value for $fn. >>> >> >> It doesn't *appear* to have a pentagonal cross-section.  It *does* >> have a pentagonal cross-section. >> >>> The same circle, but made into a spiral by 500 degrees of >>> counter-clockwise twist. >>> >> >> If you look carefully, this example demonstrates why you can't make >> threads.  As you twist it more, it becomes thinner and thinner in Z.  >> The problem is that the cross-section of a thread is a strange shape. >> >> >>> Mesh Refinement >>> >>> The slices parameter defines the number of intermediate points along >>> the Z axis of the extrusion. >>> >> >> I am not sure of the exactly right way to describe this, because of >> fence post errors. >> >> "slices" controls the number of 3D "chunks" that make up the >> extrusion.  The total number of instances of the original 2D object >> is slices+1. >> >>> Its default increases with the value of twist. >>> >> >> It's some function of that and $fa/$fs/$fn.  I don't know what the >> function is or exactly how to describe it. >> >> >>> Additional the segments parameter >>> >> Addition -> Additionally >> >> >>> Segments need to be a multiple of the polygon's fragments to have an >>> effect (6 or 9.. for a circle($fn=3), 8,12.. for a square() ). >>> >> >> I don't know what the actual behavior is, but that's not it. For more >> complex shapes (I experimented with a right triangle) intermediate >> values do have an effect. >> >> >>> Thespecial variables >>> <https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Other_Language_Features>$fn, >>> $fs and $fa can also be used to improve the output. If slices is not >>> defined, its value is taken from the defined $fn value. >>> >> >> Again, I don't know what the behavior is, but that's not it. >> Increasing $fn does increase the number of slices, but it isn't >> simply used as the number of slices. >> >> $fa/$fs/$fn seem to control both slices and segments. >> >>> >>> Using with imported SVG >>> >> >> Does not need to be separately discussed. >> >> >>> rotate_extrude() Operator Module >>> >>> Rotational extrusion spins a 2D shape around the Z-axis to form a >>> solid which has rotational symmetry. One way to think of this >>> operation is to imagine a Potter's wheel placed on the X-Y plane >>> with its axis of rotation pointing up towards +Z. Then place the >>> to-be-made object on this virtual Potter's wheel (possibly extending >>> down below the X-Y plane towards -Z). The to-be-made object is the >>> cross-section of the object on the X-Y plane (keeping only the right >>> half, X >= 0). That is the 2D shape that will be fed to >>> rotate_extrude() as the child in order to generate this solid. Note >>> that the object started on the X-Y plane but is tilted up (rotated >>> +90 degrees about the X-axis) to extrude. >>> >> >> I'm not sure that this is the best possible explanation. >> >> >>> Since a 2D shape is rendered by OpenSCAD on the X-Y plane, an >>> alternative way to think of this operation is as follows: spins a 2D >>> shape around the Y-axis to form a solid. The resultant solid is >>> placed so that its axis of rotation lies along the Z-axis. >>> >> >> That's the way that I always think of it, though I mentally rotate it >> to vertical before spinning it. >> >> >>> Just like the linear_extrude, the extrusion is always performed on >>> the projection of the 2D polygon to the XY plane. >>> >> >> Again, we should not document this behavior. >> >> >>> Transformations like rotate, translate, etc. applied to the 2D >>> polygon before extrusion modify the projection of the 2D polygon to >>> the XY plane and therefore also modify the appearance of the final >>> 3D object. >>> >>> * A translation in Z of the 2D polygon has no effect on the result >>> (as also the projection is not affected). >>> * A translation in X increases the diameter of the final object. >>> * A translation in Y results in a shift of the final object in Z >>> direction. >>> * A rotation about the X or Y axis distorts the cross section of >>> the final object, as also the projection to the XY plane is >>> distorted. >>> >> >> This is perhaps good stuff, if the part about projecting is removed. >> >> >>> Don't get confused, as OpenSCAD displays 2D polygons with a certain >>> height in the Z direction, so the 2D object (with its height) >>> appears to have a bigger projection to the XY plane. But for the >>> projection to the XY plane and also for the later extrusion only the >>> base polygon without height is used. >>> >> >> Once you get rid of the part about projecting this goes away too. >> >> >>> You cannot use rotate_extrude to produce a helix or screw thread. >>> Doing this properly can be difficult, so it's best to find a thread >>> library to make them for you. >>> >> >> This kind of comment can be valuable, but I'm not sure it belongs in >> a reference manual.  If it *is* in a reference manual, it should be >> in a clear and separate section (of the description of the particular >> feature) marked "Application Notes" or something like that, to make >> it clear that it's *not* part of the description of the feature. >> >> >>> If the shape spans the X axis a warning appears in the console >>> windows and the rotate_extrude() is ignored. >>> >> Don't talk about what window something appears in, because not >> everybody uses the OpenSCAD GUI. >> >> Don't talk about what happens "after" the error. >> >> Just say that it's an error, period. >> >> (And, BTW, this particular one is something that I think should not >> be an error; I think that the result should be as if you split the 2D >> shape in half, rotationally extruded both, and unioned them.  That >> is, take the shape, sweep it 360 degrees, and anything it sweeps >> through (whether once or twice) is part of the result.) >> >> >>>  If the 2D shape touches the Y axis, i.e. at x=0, it*must*be a line >>> that touches, not a point, as a point results in a zero thickness 3D >>> object, which is invalid and results in a CGAL error. >>> >> >> This may have been addressed with Manifold. >> >> >>> *convexity* : If the extrusion fails for a non-trival 2D shape, >>> try setting the convexity parameter (the default is not 10, but >>> 10 is a "good" value to try). See explanation further down. >>> >> >> Just point at the general discussion of convexity.  (Which should not >> be on this page.) >> >> And the extrusion does not "fail".  In fact, the artifacts may be >> quite subtle. >> >> >>> *start*[Note:Requires versionDevelopment snapshot] : Defaults to >>> 0 if*angle*is specified, and 180 if not. Specifies the starting >>> angle of the extrusion, counter-clockwise from the positive X axis. >>> >> >> start was part of an effort to align rotational extrusion behavior >> with the behavior of other round things.  I don't remember all of the >> details, but there are few reasons why it isn't equivalent to >> rotating the result. >> >> >>> *$fa* : minimum angle (in degrees) of each fragment. >>> *$fs* : minimum circumferential length of each fragment. >>> *$fn* :*fixed*number of fragments in 360 degrees. Values of 3 or >>> more override $fa and $fs >>> >>> $fa, $fs and $fn must be named parameters.click here for >>> more details, >>> <https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Other_Language_Features>. >>> >> Do not describe these in detail here.  Refer to a general description >> of them elsewhere. >> >> Do not ever, ever, say "click here".  Any text that would not make >> sense when printed is wrong. >> >> >>> Rotate Extrude on Imported DXF >>> >> >> Delete. >> >> >>> Increasing the number of fragments composing the 2D shape improves >>> the quality of the mesh, but takes longer to render. >>> >> >> Unnecessary. >> >> >>> rotate_extrude(convexity = 10) >>> translate([2, 0, 0]) >>> circle(r = 1, $fn = 100); >> >> This example is unnecessary; this is a description of rotate_extrude, >> not circle() >> >>> The number of fragments used by the extrusion can also be increased. >>> >>> rotate_extrude(convexity = 10, $fn = 100) >>> translate([2, 0, 0]) >>> circle(r = 1, $fn = 100); >> >> >> Use $fs and $fa here.  In fact, supply them at the top level.  And >> this case doesn't require specifying convexity (though I'm not sure >> why not).  Also, for circles this small high resolution is not >> practical; make them bigger to make the example more real. Thus: >> >> $fa = 1; >> $fs = 1; >> rotate_extrude() >> translate([20, 0, 0]) >> circle(r = 10); >> >> That's really the best practice.  You almost never want to use $fn if >> your intent is to create a circle. >> >> (Minor exception that is itself something of a bug:  if you're trying >> to force the number of sides to be a multiple of 4.  But that >> shouldn't be discussed here.) >> >> >>> Using the parameter angle (with OpenSCAD versions 2016.xx), a hook >>> can be modeled . >>> >>> <https://en.wikibooks.org/wiki/File:Hook.png>OpenSCAD - a hook >>> >>> eps = 0.01; >>> translate([eps, 60, 0]) >>> rotate_extrude(angle=270, convexity=10) >>> translate([40, 0]) circle(10); >>> rotate_extrude(angle=90, convexity=10) >>> translate([20, 0]) circle(10); >>> translate([20, eps, 0]) >>> rotate([90, 0, 0]) cylinder(r=10, h=80+eps); >> >> >> Delete. >> >> >>> Extruding a Polygon >>> >> >> Delete. >> >> >>> Description of extrude parameters >>> >> >> Why are we repeating these here?  Don't, especially because there is >> little commonality between linear_extrude and rotate_extrude. >> >> >>> 0% developed  as of November 17, 2009 >>> <https://en.wikibooks.org/wiki/Help:Development_stages>DXF >>> Extrusion >>> <https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/DXF_Extrusion> >>> >> >> Delete. >> >>> >>> Import 2D >>> >>> Import 2D Shapes >>> <https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Import_2D> >>> >> >> This should get more content.  At the current state of things it can >> probably all go on the 2D page, but if it gets much more complex it >> might want its own page with a brief summary and reference here. >> >> >> >> _______________________________________________ >> 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
JB
Jordan Brown
Fri, Aug 8, 2025 6:55 PM

On 8/8/2025 1:08 AM, Jordan Brown via Discuss wrote:

Note: It was previously noted in the docs that fonts may be added
to the installation by drag-and-drop of a font file into the editor
window, but as of version 2025 Snapshot this isnotthe case

That isn't what it said.  It said:

 You can drag a font in the font list, into the editor window to
 use in the text() statement.

I can't readily check a 2025 build at the moment, but as of Oct 2024
the it does exactly as described:  dragging a font from the OpenSCAD
font list into the editor window drops its name in the editor window. 
If that is no longer the case, it's a bug.

Confirmed working in a build today on Windows.  If it doesn't work, it's
a bug.

On 8/8/2025 1:08 AM, Jordan Brown via Discuss wrote: >> >> *Note*: It was previously noted in the docs that fonts may be added >> to the installation by drag-and-drop of a font file into the editor >> window, but as of version 2025 Snapshot this is*not*the case >> > That isn't what it said.  It said: > > You can drag a font in the font list, into the editor window to > use in the text() statement. > > I can't readily check a 2025 build at the moment, but as of Oct 2024 > the it does exactly as described:  dragging a font from the OpenSCAD > font list into the editor window drops its name in the editor window.  > If that is no longer the case, it's a bug. > Confirmed working in a build today on Windows.  If it doesn't work, it's a bug.
V
vulcan_@mac.com
Sat, Aug 9, 2025 1:02 AM

Jon Bondy wrote:

I, for one, find what Vulcan is doing to be terrifying.  And I do not
have the patience to read all of the new documentation, over and over
again, trying to figure out what else has been broken.

Terrifying?  Really?  it is a wiki with version control. How can anything i might do be terrifying?
I might misunderstand a thing and write something misleading .. which someone would eventually notice and fix .. that is the absolute worst situation that i could create.

Repeating  … it is a wiki with version control .. just revert my work out and your docs are back under your control, ‘cause i will never contribute again.

and given the communities difficulty with a newcomer trying to contribute maybe that is what i should do

I don't doubt that Vulcan's intentions are good, but I wonder if there
really is a problem that needs solving. 

There were problems .. lots of them. When i started exploring scad i found that pretty much every module and function I wanted to use was under documented, even confusing in places .. I am a good tech writer and i like to contribute where i can .. so once my examples and test scripts showed me how to improve things in the docs  i thought to contribute my insights back to the community

I also wonder whether the
community would be better off with an experienced OpenSCAD programmer
making the changes.

that would be the community’s choice to make .. but my impression is that the experienced OpenSCAD programmers are quite busy with new features and maintenance so documentation is well down the priority list. But okay, if newcomers are not welcome then lock down the permissions so only the Chosen Few can update the docs and again, the issue is solved.

I understand that the documentation should be accessible to an OpenSCAD
newbie, but I am not sure that these changes will produce the best product.

As stated .. all i need is to be able to READ the docs .. i don’t need to contribute, and i don’t need to be on the wrong side of a turf war

There are other tool sets i can do my 3D printing with

Jon Bondy wrote: > > > I, for one, find what Vulcan is doing to be terrifying.  And I do not > have the patience to read all of the new documentation, over and over > again, trying to figure out what else has been broken. Terrifying? Really? it is a wiki with version control. How can anything i might do be terrifying?\ I might misunderstand a thing and write something misleading .. which someone would eventually notice and fix .. that is the absolute worst situation that i could create. Repeating … it *is a wiki with version control* .. just revert my work out and your docs are back under your control, ‘cause i will never contribute again. and given the communities difficulty with a newcomer trying to contribute maybe that is what i should do > I don't doubt that Vulcan's intentions are good, but I wonder if there > really is a problem that needs solving.  There were problems .. lots of them. When i started exploring scad i found that pretty much every module and function I wanted to use was under documented, even confusing in places .. I am a good tech writer and i like to contribute where i can .. so once my examples and test scripts showed me how to improve things in the docs i thought to contribute my insights back to the community > I also wonder whether the > community would be better off with an experienced OpenSCAD programmer > making the changes. that would be the community’s choice to make .. but my impression is that the experienced OpenSCAD programmers are quite busy with new features and maintenance so documentation is well down the priority list. But okay, if newcomers are not welcome then lock down the permissions so only the Chosen Few can update the docs and again, the issue is solved. > I understand that the documentation should be accessible to an OpenSCAD > newbie, but I am not sure that these changes will produce the best product. As stated .. all i *need* is to be able to READ the docs .. i don’t *need* to contribute, and i don’t *need* to be on the wrong side of a turf war There are other tool sets i can do my 3D printing with
V
vulcan_@mac.com
Sat, Aug 9, 2025 1:04 AM

Jon Bondy wrote:

What is the community getting for this INCREDIBLE level of effort?

I think we should

  1. revert the documentation back to prior to when Vulcan started
    changing things

good .. you do that .. i am out

Jon Bondy wrote: > What is the community getting for this INCREDIBLE level of effort? > > I think we should > > 1. revert the documentation back to prior to when Vulcan started > changing things good .. you do that .. i am out
V
vulcan_@mac.com
Sat, Aug 9, 2025 1:07 AM

Jordan, thanks for your patient help and feedback .. i have learned a lot about functional language programming .. a sort of programming that i knew nothing about before coming to OpenSCAD

Jeff Hayes

Jordan, thanks for your patient help and feedback .. i have learned a lot about functional language programming .. a sort of programming that i knew nothing about before coming to OpenSCAD — Jeff Hayes
JB
Jon Bondy
Sat, Aug 9, 2025 1:10 AM

I did not find the documentation to be confusing.

Experienced OpenSCAD programmers are spending their time responding and
reacting to the content you are creating.  I am not convinced that this
is the best use of their time.

This is not a turf war.  This is about how to get quality documentation
with the minimum of effort from all involved.

Perhaps others should comment.  I have had my say.  If I am all alone,
then I will not comment further.

Jon

On 8/8/2025 9:02 PM, vulcan_--- via Discuss wrote:

Jon Bondy wrote:

 I, for one, find what Vulcan is doing to be terrifying.  And I do
 not have the patience to read all of the new documentation, over
 and over again, trying to figure out what else has been broken.

Terrifying? Really? it is a wiki with version control. How can
anything i might do be terrifying?
I might misunderstand a thing and write something misleading .. which
someone would eventually notice and fix .. that is the absolute worst
situation that i could create.

Repeating … it /is a wiki with version control/ .. just revert my work
out and your docs are back under your control, ‘cause i will never
contribute again.

and given the communities difficulty with a newcomer trying to
contribute maybe that is what i should do

 I don't doubt that Vulcan's intentions are good, but I wonder if
 there really is a problem that needs solving.

There were problems .. lots of them. When i started exploring scad i
found that pretty much every module and function I wanted to use was
under documented, even confusing in places .. I am a good tech writer
and i like to contribute where i can .. so once my examples and test
scripts showed me how to improve things in the docs i thought to
contribute my insights back to the community

 I also wonder whether the community would be better off with an
 experienced OpenSCAD programmer making the changes.

that would be the community’s choice to make .. but my impression is
that the experienced OpenSCAD programmers are quite busy with new
features and maintenance so documentation is well down the priority
list. But okay, if newcomers are not welcome then lock down the
permissions so only the Chosen Few can update the docs and again, the
issue is solved.

 I understand that the documentation should be accessible to an
 OpenSCAD newbie, but I am not sure that these changes will produce
 the best product.

As stated .. all i /need/ is to be able to READ the docs .. i don’t
/need/ to contribute, and i don’t /need/ to be on the wrong side of a
turf war

There are other tool sets i can do my 3D printing with


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 did not find the documentation to be confusing. Experienced OpenSCAD programmers are spending their time responding and reacting to the content you are creating.  I am not convinced that this is the best use of their time. This is not a turf war.  This is about how to get quality documentation with the minimum of effort from all involved. Perhaps others should comment.  I have had my say.  If I am all alone, then I will not comment further. Jon On 8/8/2025 9:02 PM, vulcan_--- via Discuss wrote: > > Jon Bondy wrote: > > > > I, for one, find what Vulcan is doing to be terrifying.  And I do > not have the patience to read all of the new documentation, over > and over again, trying to figure out what else has been broken. > > Terrifying? Really? it is a wiki with version control. How can > anything i might do be terrifying? > I might misunderstand a thing and write something misleading .. which > someone would eventually notice and fix .. that is the absolute worst > situation that i could create. > > Repeating … it /is a wiki with version control/ .. just revert my work > out and your docs are back under your control, ‘cause i will never > contribute again. > > and given the communities difficulty with a newcomer trying to > contribute maybe that is what i should do > > I don't doubt that Vulcan's intentions are good, but I wonder if > there really is a problem that needs solving. > > There were problems .. lots of them. When i started exploring scad i > found that pretty much every module and function I wanted to use was > under documented, even confusing in places .. I am a good tech writer > and i like to contribute where i can .. so once my examples and test > scripts showed me how to improve things in the docs i thought to > contribute my insights back to the community > > I also wonder whether the community would be better off with an > experienced OpenSCAD programmer making the changes. > > that would be the community’s choice to make .. but my impression is > that the experienced OpenSCAD programmers are quite busy with new > features and maintenance so documentation is well down the priority > list. But okay, if newcomers are not welcome then lock down the > permissions so only the Chosen Few can update the docs and again, the > issue is solved. > > I understand that the documentation should be accessible to an > OpenSCAD newbie, but I am not sure that these changes will produce > the best product. > > As stated .. all i /need/ is to be able to READ the docs .. i don’t > /need/ to contribute, and i don’t /need/ to be on the wrong side of a > turf war > > There are other tool sets i can do my 3D printing with > > > _______________________________________________ > 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