discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

How to get an outline of a 2D object?

R
rickan
Mon, Nov 23, 2020 2:34 PM

Close enough?

Maybe the curves (vs corners) added by the negative offset are unwanted?
Might be suited to a milling machine or router but maybe sharp corners are
wanted to show off very narrow kerf cutter.

module sign(){
text("Boobies!",100);
square([520,5]);
}

//engrave
color([0,0,0])
translate([0,0,1])
sign();

//Fill the holes
module fill(){
offset(20)
sign();
}

//Cut
offset(-10) fill();

--
Sent from: http://forum.openscad.org/

Close enough? Maybe the curves (vs corners) added by the negative offset are unwanted? Might be suited to a milling machine or router but maybe sharp corners are wanted to show off very narrow kerf cutter. module sign(){ text("Boobies!",100); square([520,5]); } //engrave color([0,0,0]) translate([0,0,1]) sign(); //Fill the holes module fill(){ offset(20) sign(); } //Cut offset(-10) fill(); -- Sent from: http://forum.openscad.org/
R
rickan
Mon, Nov 23, 2020 2:44 PM

If this is close enough, now the problem is finding the minimum offset for
fill().

Setting os=9.5 below does not work.

os=10;

module sign(){
text("Boobies!",100);
square([520,5]);
}

//engrave
color([0,0,0])
translate([0,0,1])
sign();

//Fill the holes
module fill(){
offset(10 + os)
sign();
}

//Cut
offset(-os) fill();

--
Sent from: http://forum.openscad.org/

If this is close enough, now the problem is finding the minimum offset for fill(). Setting os=9.5 below does not work. os=10; module sign(){ text("Boobies!",100); square([520,5]); } //engrave color([0,0,0]) translate([0,0,1]) sign(); //Fill the holes module fill(){ offset(10 + os) sign(); } //Cut offset(-os) fill(); -- Sent from: http://forum.openscad.org/
TP
Torsten Paul
Mon, Nov 23, 2020 4:51 PM

On 23.11.20 13:37, Ronaldo Persiano wrote:

The char "@" for instance cannot be correctly processed

That's a good example. What would a built-in outline() function
do exactly? Using just the outer most polygon would fill only
the inner hole but still leave the tail.

ciao,
Torsten.

On 23.11.20 13:37, Ronaldo Persiano wrote: > The char "@" for instance cannot be correctly processed That's a good example. What would a built-in outline() function do exactly? Using just the outer most polygon would fill only the inner hole but still leave the tail. ciao, Torsten.
R
rickan
Mon, Nov 23, 2020 5:58 PM

I have just written a quick and dirty PostScript (PS) program which will
remove the inner paths in a text string. (But the procedures used are not
allowed for all fonts, and there are probably strange fonts for which my
algorithm won't work because it relies on the characters' outer path being
drawn first followed by the inner paths and the bounding boxes of the inner
paths being inside the bounding boxes of the outer paths.)

I converted the result to SVG using ps2svg and imported it into OpenSCAD.

Using this with OpenSCAD text() is not straight forward because PS and
OpenSCAD scale fonts differently, i.e. you can specify the exact same font
in GhostScript and OpenSCAD (at least on my system) and scale them to the
same size and they do not match because PS scales them for line spacing and
OpenSCAD scales them omitting the descenders so that capital letters come
out close to the size specified.  But I have posted a program on this forum
which will calculate a good approximation of the OpenSCAD scale factor in PS
and scale the font in PS accordingly.
http://forum.openscad.org/3D-keychains-and-cutting-out-the-whitespace-of-text-tp30493p30505.html

http://forum.openscad.org/file/t1112/filtext.png

The PS file to remove inner paths from a text string, filtext.ps, follows:

/Helvetica findfont 1 scalefont setfont

/cbbox[0 0 0 0]def

/bbinside{ % [bounding box] -- true if inside cbbox
aload pop
cbbox 3 get lt{
cbbox 2 get lt{
cbbox 1 get gt{
cbbox 0 get gt{
true
}{
false
}ifelse
}{
pop
false
}ifelse
}{
pop pop
false
}ifelse
}{
pop pop pop
false
}ifelse
}def

/pathclosed true def
/pathstarted false def
/outerpath[]def

/startpath{
pathstarted{
(Warning! redundant moveto encountered.\n)print
}{
[3 1 roll
}ifelse
/moveto load
/pathclosed false def
/pathstarted true def
}def

/extendpath{
/lineto load
}def

/nocurves{
(Warning! There should be no curvto ops. use flattenpath.\n)print
}def

/checkpath{
/closepath load]
/testpath exch def
gsave %{
newpath
testpath cvx exec /testbox[pathbbox]def testbox bbinside not{
/outerpath [outerpath aload pop testpath aload pop]def
/cbbox testbox def
}if
grestore %}
/pathclosed true def
/pathstarted false def
}def

/fillstring{
false charpath flattenpath
{startpath}{extendpath}{nocurves}{checkpath}pathforall
cleartomark
newpath
}def

100 dup scale % change to suit. This is 100 72/inch units
1 11 2 div translate % Comment this line to put the text at the origin
.005 setlinewidth
0 0 moveto
(Boobies!) fillstring
outerpath cvx exec
stroke

--
Sent from: http://forum.openscad.org/

I have just written a quick and dirty PostScript (PS) program which will remove the inner paths in a text string. (But the procedures used are not allowed for all fonts, and there are probably strange fonts for which my algorithm won't work because it relies on the characters' outer path being drawn first followed by the inner paths and the bounding boxes of the inner paths being inside the bounding boxes of the outer paths.) I converted the result to SVG using ps2svg and imported it into OpenSCAD. Using this with OpenSCAD text() is not straight forward because PS and OpenSCAD scale fonts differently, i.e. you can specify the exact same font in GhostScript and OpenSCAD (at least on my system) and scale them to the same size and they do not match because PS scales them for line spacing and OpenSCAD scales them omitting the descenders so that capital letters come out close to the size specified. But I have posted a program on this forum which will calculate a good approximation of the OpenSCAD scale factor in PS and scale the font in PS accordingly. <http://forum.openscad.org/3D-keychains-and-cutting-out-the-whitespace-of-text-tp30493p30505.html> <http://forum.openscad.org/file/t1112/filtext.png> The PS file to remove inner paths from a text string, filtext.ps, follows: /Helvetica findfont 1 scalefont setfont /cbbox[0 0 0 0]def /bbinside{ % [bounding box] -- true if inside cbbox aload pop cbbox 3 get lt{ cbbox 2 get lt{ cbbox 1 get gt{ cbbox 0 get gt{ true }{ false }ifelse }{ pop false }ifelse }{ pop pop false }ifelse }{ pop pop pop false }ifelse }def /pathclosed true def /pathstarted false def /outerpath[]def /startpath{ pathstarted{ (Warning! redundant moveto encountered.\n)print }{ [3 1 roll }ifelse /moveto load /pathclosed false def /pathstarted true def }def /extendpath{ /lineto load }def /nocurves{ (Warning! There should be no curvto ops. use flattenpath.\n)print }def /checkpath{ /closepath load] /testpath exch def gsave %{ newpath testpath cvx exec /testbox[pathbbox]def testbox bbinside not{ /outerpath [outerpath aload pop testpath aload pop]def /cbbox testbox def }if grestore %} /pathclosed true def /pathstarted false def }def /fillstring{ false charpath flattenpath {startpath}{extendpath}{nocurves}{checkpath}pathforall cleartomark newpath }def 100 dup scale % change to suit. This is 100 72/inch units 1 11 2 div translate % Comment this line to put the text at the origin .005 setlinewidth 0 0 moveto (Boobies!) fillstring outerpath cvx exec stroke -- Sent from: http://forum.openscad.org/
RW
Ray West
Mon, Nov 23, 2020 6:53 PM

Just my two penn'orth - the result depends on the style of font, and the
characters used. In most cases you will need to make some manual
adjustment, in particular for punctuation, lower case letters such as 
i, j, and any language with accents. If it is a question of making
signs, and you are leaving the backing in place, then no need for the
base-line (square) and If there is the base line, then no need for the
backing.

You could try it with  more 'difficult letters', adjust the size of the
binding line, etc., and view from afar, say -

module sign(){
    text("rnmg@jie423s!ILl71PBRFCG=-_:;",100);
    square([2050,9]);
}

Best wishes,

Ray

On 23/11/2020 11:12, Troberg wrote:

Another example where this would be nice, and where the inside geometry isn't
defined by me, so I can't "reverse engineer" my code to remove the holes. A
very typical laser cutter example:

Say that you are making a sign, with some text, and a baseline to hold the
characters together. So, basically, a union of a square and some text. Very
common laser cutting task.

You want to engrave the letters, but cut the outline of the object (with a
slight offset), but you don't want any holes in it.

I can't reverse engineer the font, a hull() would just make a mess of
everything, using offset to remove holes would destroy the outline as well.
The only way I can figure out to make it work is if there were some kind of
built-in outline() module.

--
Sent from: http://forum.openscad.org/


OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

Just my two penn'orth - the result depends on the style of font, and the characters used. In most cases you will need to make some manual adjustment, in particular for punctuation, lower case letters such as  i, j, and any language with accents. If it is a question of making signs, and you are leaving the backing in place, then no need for the base-line (square) and If there is the base line, then no need for the backing. You could try it with  more 'difficult letters', adjust the size of the binding line, etc., and view from afar, say - module sign(){     text("rnmg@jie423s!ILl71PBRFCG=-_:;",100);     square([2050,9]); } Best wishes, Ray On 23/11/2020 11:12, Troberg wrote: > Another example where this would be nice, and where the inside geometry isn't > defined by me, so I can't "reverse engineer" my code to remove the holes. A > very typical laser cutter example: > > Say that you are making a sign, with some text, and a baseline to hold the > characters together. So, basically, a union of a square and some text. Very > common laser cutting task. > > You want to engrave the letters, but cut the outline of the object (with a > slight offset), but you don't want any holes in it. > > I can't reverse engineer the font, a hull() would just make a mess of > everything, using offset to remove holes would destroy the outline as well. > The only way I can figure out to make it work is if there were some kind of > built-in outline() module. > > > > -- > Sent from: http://forum.openscad.org/ > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org