discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

Polyhedron tube with irregular sides -- is it possible ?

R
runsun
Mon, Sep 14, 2015 6:26 AM

I wanna make some tube-like shape with irregular sides, similar like one
below:

http://forum.openscad.org/file/n13813/20150914_irregular_tube_by_extrude.png

This is made with a polygon + linear_extrude out of

pts_out =  [ [0,0],[6,0],[6,5],[0,5] ];
pts_in =  [ [2,1],[5,2], [3,4]];

To make a polyhedron, I convert pts to 3D:

pts =  [[0, 0, 0], [6, 0, 0], [6, 5, 0], [0, 5, 0], [2, 1, 0], [5, 2, 0],
[3, 4, 0], [0, 0, 3], [6, 0, 3], [6, 5, 3], [0, 5, 3], [2, 1, 3], [5, 2,
3], [3, 4, 3]];

Their indices are placed on the extruded shape as follow:

http://forum.openscad.org/file/n13813/150914_irregular_tube_marked.png

I tried several combinations of faces but couldn't get a polyhedron. Here
are two tries:

faces1= [[0, 7, 8, 1], [1, 8, 9, 2], [2, 9, 10, 3], [3, 10, 7, 0], [4, 5,
12, 11], [5, 6, 13, 12], [6, 4, 11, 13], [0, 1, 2, 3], [4, 5, 6], [7, 8,
9, 10], [11, 12, 13]];
polyhedron( points = pts, faces = faces1  );

faces2 = [[0, 7, 8, 1], [1, 8, 9, 2], [2, 9, 10, 3], [3, 10, 7, 0], [4, 5,
12, 11], [5, 6, 13, 12], [6, 4, 11, 13], [0, 1, 2, 3, 4, 5, 6], [7, 8, 9,
10, 11, 12, 13]];
color(undef,0.8)
polyhedron( points = pts , faces = faces2 );


$  Runsun Pan, PhD

$ -- libs: doctest , faces ( git ), offliner ( git );

tips: hash( 1 , 2 ), sweep , var

$ -- Linux Mint 17.1 Rebecca x64  + OpenSCAD 2015.03.15/2015.04.01.nightly

--
View this message in context: http://forum.openscad.org/Polyhedron-tube-with-irregular-sides-is-it-possible-tp13813.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

I wanna make some tube-like shape with irregular sides, similar like one below: <http://forum.openscad.org/file/n13813/20150914_irregular_tube_by_extrude.png> This is made with a polygon + linear_extrude out of > pts_out = [ [0,0],[6,0],[6,5],[0,5] ]; > pts_in = [ [2,1],[5,2], [3,4]]; To make a polyhedron, I convert pts to 3D: > pts = [[0, 0, 0], [6, 0, 0], [6, 5, 0], [0, 5, 0], [2, 1, 0], [5, 2, 0], > [3, 4, 0], [0, 0, 3], [6, 0, 3], [6, 5, 3], [0, 5, 3], [2, 1, 3], [5, 2, > 3], [3, 4, 3]]; Their indices are placed on the extruded shape as follow: <http://forum.openscad.org/file/n13813/150914_irregular_tube_marked.png> I tried several combinations of faces but couldn't get a polyhedron. Here are two tries: > > faces1= [[0, 7, 8, 1], [1, 8, 9, 2], [2, 9, 10, 3], [3, 10, 7, 0], [4, 5, > 12, 11], [5, 6, 13, 12], [6, 4, 11, 13], [0, 1, 2, 3], [4, 5, 6], [7, 8, > 9, 10], [11, 12, 13]]; > polyhedron( points = pts, faces = faces1 ); <http://forum.openscad.org/file/n13813/20150914_irregular_tube_faces1.png> > > faces2 = [[0, 7, 8, 1], [1, 8, 9, 2], [2, 9, 10, 3], [3, 10, 7, 0], [4, 5, > 12, 11], [5, 6, 13, 12], [6, 4, 11, 13], [0, 1, 2, 3, 4, 5, 6], [7, 8, 9, > 10, 11, 12, 13]]; > color(undef,0.8) > polyhedron( points = pts , faces = faces2 ); ----- $ Runsun Pan, PhD $ -- libs: doctest , faces ( git ), offliner ( git ); tips: hash( 1 , 2 ), sweep , var $ -- Linux Mint 17.1 Rebecca x64 + OpenSCAD 2015.03.15/2015.04.01.nightly -- View this message in context: http://forum.openscad.org/Polyhedron-tube-with-irregular-sides-is-it-possible-tp13813.html Sent from the OpenSCAD mailing list archive at Nabble.com.
PF
Peter Falke
Mon, Sep 14, 2015 6:33 AM

​I guess you need to tesselate the face properly.

2015-09-14 8:26 GMT+02:00 runsun runsun@gmail.com:

I wanna make some tube-like shape with irregular sides, similar like one
below:

<
http://forum.openscad.org/file/n13813/20150914_irregular_tube_by_extrude.png

This is made with a polygon + linear_extrude out of

pts_out =  [ [0,0],[6,0],[6,5],[0,5] ];
pts_in =  [ [2,1],[5,2], [3,4]];

To make a polyhedron, I convert pts to 3D:

pts =  [[0, 0, 0], [6, 0, 0], [6, 5, 0], [0, 5, 0], [2, 1, 0], [5, 2, 0],
[3, 4, 0], [0, 0, 3], [6, 0, 3], [6, 5, 3], [0, 5, 3], [2, 1, 3], [5, 2,
3], [3, 4, 3]];

Their indices are placed on the extruded shape as follow:

http://forum.openscad.org/file/n13813/150914_irregular_tube_marked.png

I tried several combinations of faces but couldn't get a polyhedron. Here
are two tries:

faces1= [[0, 7, 8, 1], [1, 8, 9, 2], [2, 9, 10, 3], [3, 10, 7, 0], [4, 5,
12, 11], [5, 6, 13, 12], [6, 4, 11, 13], [0, 1, 2, 3], [4, 5, 6], [7, 8,
9, 10], [11, 12, 13]];
polyhedron( points = pts, faces = faces1  );

faces2 = [[0, 7, 8, 1], [1, 8, 9, 2], [2, 9, 10, 3], [3, 10, 7, 0], [4,

5,

12, 11], [5, 6, 13, 12], [6, 4, 11, 13], [0, 1, 2, 3, 4, 5, 6], [7, 8, 9,
10, 11, 12, 13]];
color(undef,0.8)
polyhedron( points = pts , faces = faces2 );


$  Runsun Pan, PhD

$ -- libs: doctest , faces ( git ), offliner ( git );

tips: hash( 1 , 2 ), sweep , var

$ -- Linux Mint 17.1 Rebecca x64  + OpenSCAD 2015.03.15/2015.04.01.nightly

--
View this message in context:
http://forum.openscad.org/Polyhedron-tube-with-irregular-sides-is-it-possible-tp13813.html
Sent from the OpenSCAD mailing list archive at Nabble.com.


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

--
stempeldergeschichte@googlemail.com karsten@rohrbach.de

P.S. Falls meine E-Mail kürzer ausfällt als Dir angenehm ist:
Ich probiere gerade aus kurze Antworten statt gar keine Antworten zu
schreiben.
Wenn Du gerne mehr lesen möchtest, dann lass es mich bitte wissen.

P.S. In case my e-mail is shorter than you enjoy:
I am currently trying short replies instead of no replies at all.
Please let me know, if you like to read more.

Enjoy!

​I guess you need to tesselate the face properly. 2015-09-14 8:26 GMT+02:00 runsun <runsun@gmail.com>: > I wanna make some tube-like shape with irregular sides, similar like one > below: > > < > http://forum.openscad.org/file/n13813/20150914_irregular_tube_by_extrude.png > > > > This is made with a polygon + linear_extrude out of > > > pts_out = [ [0,0],[6,0],[6,5],[0,5] ]; > > pts_in = [ [2,1],[5,2], [3,4]]; > > To make a polyhedron, I convert pts to 3D: > > > > pts = [[0, 0, 0], [6, 0, 0], [6, 5, 0], [0, 5, 0], [2, 1, 0], [5, 2, 0], > > [3, 4, 0], [0, 0, 3], [6, 0, 3], [6, 5, 3], [0, 5, 3], [2, 1, 3], [5, 2, > > 3], [3, 4, 3]]; > > Their indices are placed on the extruded shape as follow: > > <http://forum.openscad.org/file/n13813/150914_irregular_tube_marked.png> > > I tried several combinations of faces but couldn't get a polyhedron. Here > are two tries: > > > > > > faces1= [[0, 7, 8, 1], [1, 8, 9, 2], [2, 9, 10, 3], [3, 10, 7, 0], [4, 5, > > 12, 11], [5, 6, 13, 12], [6, 4, 11, 13], [0, 1, 2, 3], [4, 5, 6], [7, 8, > > 9, 10], [11, 12, 13]]; > > polyhedron( points = pts, faces = faces1 ); > > <http://forum.openscad.org/file/n13813/20150914_irregular_tube_faces1.png> > > > > > > faces2 = [[0, 7, 8, 1], [1, 8, 9, 2], [2, 9, 10, 3], [3, 10, 7, 0], [4, > 5, > > 12, 11], [5, 6, 13, 12], [6, 4, 11, 13], [0, 1, 2, 3, 4, 5, 6], [7, 8, 9, > > 10, 11, 12, 13]]; > > color(undef,0.8) > > polyhedron( points = pts , faces = faces2 ); > > > > > > ----- > > $ Runsun Pan, PhD > > $ -- libs: doctest , faces ( git ), offliner ( git ); > > tips: hash( 1 , 2 ), sweep , var > > $ -- Linux Mint 17.1 Rebecca x64 + OpenSCAD 2015.03.15/2015.04.01.nightly > > > > > -- > View this message in context: > http://forum.openscad.org/Polyhedron-tube-with-irregular-sides-is-it-possible-tp13813.html > Sent from the OpenSCAD mailing list archive at Nabble.com. > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org > -- stempeldergeschichte@googlemail.com <karsten@rohrbach.de> P.S. Falls meine E-Mail kürzer ausfällt als Dir angenehm ist: Ich probiere gerade aus kurze Antworten statt gar keine Antworten zu schreiben. Wenn Du gerne mehr lesen möchtest, dann lass es mich bitte wissen. P.S. In case my e-mail is shorter than you enjoy: I am currently trying short replies instead of no replies at all. Please let me know, if you like to read more. Enjoy!
R
runsun
Mon, Sep 14, 2015 3:09 PM

Peter Falke wrote

​I guess you need to tesselate the face properly.

That was my very first try. But consider that I want a generalized approach,
in which users can punch any shape of hole on a surface of any shape, this
one doesn't seem to be ideal.

My 2nd try was a function to generate points like this:

http://forum.openscad.org/file/n13824/20150914_irregular_tube_paring.png

It works, but I imagine that it is still far from the objective of "any
shape".

So I thought, we can do polygon of any shape with a hole of any shape like
this:

polygon (points= concate( pts_out,pts_in), faces= [ [0,1,2,3],[4,5,6] ] );

http://forum.openscad.org/file/n13824/20150914_irregular_tube_polygon.png

Shouldn't we be able to use the same way to generate a surface with a hole
in 3D?

So I tried, but it doesn't seem to work.

Maybe we can implement this feature by allowing faces to have this way:

[
...,

[ [0, 1, 2, 3], [4, 5, 6] ]
, [ [7, 8, 9], [10, 11, 12, 13] ]

]

and with this allows for a "punched hole surface" in 3D, thus consistent
with that in 2D ?


$  Runsun Pan, PhD

$ -- libs: doctest , faces ( git ), offliner ( git );

tips: hash( 1 , 2 ), sweep , var

$ -- Linux Mint 17.1 Rebecca x64  + OpenSCAD 2015.03.15/2015.04.01.nightly

--
View this message in context: http://forum.openscad.org/Polyhedron-tube-with-irregular-sides-is-it-possible-tp13813p13824.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

Peter Falke wrote > ​I guess you need to tesselate the face properly. That was my very first try. But consider that I want a generalized approach, in which users can punch any shape of hole on a surface of any shape, this one doesn't seem to be ideal. My 2nd try was a function to generate points like this: <http://forum.openscad.org/file/n13824/20150914_irregular_tube_paring.png> It works, but I imagine that it is still far from the objective of "any shape". So I thought, we can do polygon of any shape with a hole of any shape like this: > polygon (points= concate( pts_out,pts_in), faces= [ [0,1,2,3],[4,5,6] ] ); <http://forum.openscad.org/file/n13824/20150914_irregular_tube_polygon.png> Shouldn't we be able to use the same way to generate a surface with a hole in 3D? So I tried, but it doesn't seem to work. Maybe we can implement this feature by allowing faces to have this way: > [ > ..., * > [ [0, 1, 2, 3], [4, 5, 6] ] > , [ [7, 8, 9], [10, 11, 12, 13] ] * > ] and with this allows for a "punched hole surface" in 3D, thus consistent with that in 2D ? ----- $ Runsun Pan, PhD $ -- libs: doctest , faces ( git ), offliner ( git ); tips: hash( 1 , 2 ), sweep , var $ -- Linux Mint 17.1 Rebecca x64 + OpenSCAD 2015.03.15/2015.04.01.nightly -- View this message in context: http://forum.openscad.org/Polyhedron-tube-with-irregular-sides-is-it-possible-tp13813p13824.html Sent from the OpenSCAD mailing list archive at Nabble.com.
PF
Peter Falke
Mon, Sep 14, 2015 5:24 PM

Why do you want to exclude using the difference() operation?

2015-09-14 17:09 GMT+02:00 runsun runsun@gmail.com:

Peter Falke wrote

​I guess you need to tesselate the face properly.

That was my very first try. But consider that I want a generalized
approach,
in which users can punch any shape of hole on a surface of any shape, this
one doesn't seem to be ideal.

My 2nd try was a function to generate points like this:

http://forum.openscad.org/file/n13824/20150914_irregular_tube_paring.png

It works, but I imagine that it is still far from the objective of "any
shape".

So I thought, we can do polygon of any shape with a hole of any shape like
this:

polygon (points= concate( pts_out,pts_in), faces= [ [0,1,2,3],[4,5,6] ]

);
<http://forum.openscad.org/file/n13824/20150914_irregular_tube_polygon.png

Shouldn't we be able to use the same way to generate a surface with a hole
in 3D?

So I tried, but it doesn't seem to work.

Maybe we can implement this feature by allowing faces to have this way:

[
...,

[ [0, 1, 2, 3], [4, 5, 6] ]
, [ [7, 8, 9], [10, 11, 12, 13] ]

]

and with this allows for a "punched hole surface" in 3D, thus consistent
with that in 2D ?


$  Runsun Pan, PhD

$ -- libs: doctest , faces ( git ), offliner ( git );

tips: hash( 1 , 2 ), sweep , var

$ -- Linux Mint 17.1 Rebecca x64  + OpenSCAD 2015.03.15/2015.04.01.nightly

--
View this message in context:
http://forum.openscad.org/Polyhedron-tube-with-irregular-sides-is-it-possible-tp13813p13824.html
Sent from the OpenSCAD mailing list archive at Nabble.com.


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

Why do you want to exclude using the difference() operation? 2015-09-14 17:09 GMT+02:00 runsun <runsun@gmail.com>: > Peter Falke wrote > > ​I guess you need to tesselate the face properly. > > That was my very first try. But consider that I want a generalized > approach, > in which users can punch any shape of hole on a surface of any shape, this > one doesn't seem to be ideal. > > My 2nd try was a function to generate points like this: > > <http://forum.openscad.org/file/n13824/20150914_irregular_tube_paring.png> > > It works, but I imagine that it is still far from the objective of "any > shape". > > So I thought, we can do polygon of any shape with a hole of any shape like > this: > > > polygon (points= concate( pts_out,pts_in), faces= [ [0,1,2,3],[4,5,6] ] > ); > <http://forum.openscad.org/file/n13824/20150914_irregular_tube_polygon.png > > > > > Shouldn't we be able to use the same way to generate a surface with a hole > in 3D? > > So I tried, but it doesn't seem to work. > > Maybe we can implement this feature by allowing faces to have this way: > > > [ > > ..., > * > > [ [0, 1, 2, 3], [4, 5, 6] ] > > , [ [7, 8, 9], [10, 11, 12, 13] ] > * > > ] > > and with this allows for a "punched hole surface" in 3D, thus consistent > with that in 2D ? > > > > > ----- > > $ Runsun Pan, PhD > > $ -- libs: doctest , faces ( git ), offliner ( git ); > > tips: hash( 1 , 2 ), sweep , var > > $ -- Linux Mint 17.1 Rebecca x64 + OpenSCAD 2015.03.15/2015.04.01.nightly > > > > > -- > View this message in context: > http://forum.openscad.org/Polyhedron-tube-with-irregular-sides-is-it-possible-tp13813p13824.html > Sent from the OpenSCAD mailing list archive at Nabble.com. > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
R
runsun
Mon, Sep 14, 2015 7:48 PM

Peter Falke wrote

Why do you want to exclude using the difference() operation?

It's part of my polyhedron-based lib, in which I'll use the "holed surface"
in different situations, including the irregular-side tube mentioned here.


$  Runsun Pan, PhD

$ -- libs: doctest , faces ( git ), offliner ( git );

tips: hash( 1 , 2 ), sweep , var

$ -- Linux Mint 17.1 Rebecca x64  + OpenSCAD 2015.03.15/2015.04.01.nightly

--
View this message in context: http://forum.openscad.org/Polyhedron-tube-with-irregular-sides-is-it-possible-tp13813p13830.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

Peter Falke wrote > Why do you want to exclude using the difference() operation? It's part of my polyhedron-based lib, in which I'll use the "holed surface" in different situations, including the irregular-side tube mentioned here. ----- $ Runsun Pan, PhD $ -- libs: doctest , faces ( git ), offliner ( git ); tips: hash( 1 , 2 ), sweep , var $ -- Linux Mint 17.1 Rebecca x64 + OpenSCAD 2015.03.15/2015.04.01.nightly -- View this message in context: http://forum.openscad.org/Polyhedron-tube-with-irregular-sides-is-it-possible-tp13813p13830.html Sent from the OpenSCAD mailing list archive at Nabble.com.
DB
don bright
Mon, Sep 14, 2015 10:49 PM

polyhedron() cannot do "faces with holes" currently as far as i know.

However there is a work-around. It is called the Keyhole Polygon...

Basically you take any polygon with a single hole... and pretend you
slice a knife down from the outside of the polygon, straight down, until
you cut into the hole. What you end up with is a single polygon without
any holes. Here is a picture

https://sozvyezdami.files.wordpress.com/2013/04/11.png?w=640

The caveat that the new edges you create by cutting will be coincident
with each other.... and the 'points' or 'nodes' of those new edges will
also be coincident, which can be a problem for some polygon processing
algorithms. However it appears to work on your basic example in
OpenSCAD. Here is your code rewritten to have two 'keyhole' polygons on
top and bottom.

pts =  [[0, 0, 0], [6, 0, 0], [6, 5, 0], [0, 5, 0], [2, 1, 0], [5, 2,
0],
[3, 4, 0], [0, 0, 3], [6, 0, 3], [6, 5, 3], [0, 5, 3], [2, 1, 3], [5, 2,
3], [3, 4, 3]];

faces1= [[0, 7, 8, 1], [1, 8, 9, 2], [2, 9, 10, 3], [3, 10, 7, 0],
[4, 5,12, 11], [5, 6, 13, 12], [6, 4, 11, 13],
[0, 1, 2, 3, 4, 6, 5, 4, 3],
[10, 9, 8, 7, 11, 12, 13, 11, 7]];
polyhedron( points = pts, faces = faces1  );

Also i had to re-order some of the vertices, as viewable in
'View/ThrownTogether' mode within OpenSCAD to make sure there were no
naughty purples. Hope this helps!

-don bright
hmbright@fastmail.fm

polyhedron() cannot do "faces with holes" currently as far as i know. However there is a work-around. It is called the Keyhole Polygon... Basically you take any polygon with a single hole... and pretend you slice a knife down from the outside of the polygon, straight down, until you cut into the hole. What you end up with is a single polygon without any holes. Here is a picture https://sozvyezdami.files.wordpress.com/2013/04/11.png?w=640 The caveat that the new edges you create by cutting will be coincident with each other.... and the 'points' or 'nodes' of those new edges will also be coincident, which can be a problem for some polygon processing algorithms. However it appears to work on your basic example in OpenSCAD. Here is your code rewritten to have two 'keyhole' polygons on top and bottom. pts = [[0, 0, 0], [6, 0, 0], [6, 5, 0], [0, 5, 0], [2, 1, 0], [5, 2, 0], [3, 4, 0], [0, 0, 3], [6, 0, 3], [6, 5, 3], [0, 5, 3], [2, 1, 3], [5, 2, 3], [3, 4, 3]]; faces1= [[0, 7, 8, 1], [1, 8, 9, 2], [2, 9, 10, 3], [3, 10, 7, 0], [4, 5,12, 11], [5, 6, 13, 12], [6, 4, 11, 13], [0, 1, 2, 3, 4, 6, 5, 4, 3], [10, 9, 8, 7, 11, 12, 13, 11, 7]]; polyhedron( points = pts, faces = faces1 ); Also i had to re-order some of the vertices, as viewable in 'View/ThrownTogether' mode within OpenSCAD to make sure there were no naughty purples. Hope this helps! -don bright hmbright@fastmail.fm
R
runsun
Tue, Sep 15, 2015 4:56 AM

Hi Don, interesting approach. I seem to read similar one when reading
Computer Geometry or something a while back, but can't recall what it's for.

This approach seems to simplify the problem significantly. The
re-arrangement of points is not a big issue.

On the other hand, for my application, it might bring up other problems.
What I show in this thread is an extremely simplified example. The actual
tube in my lib could be a complicated one with random curving, etc. To make
a holed surface on the end of a long tube with this approach, the entire
tube will have to be sliced apart.

I also intend to use a holed surface as the merging face when cylinder of
different sides (in polyhedron) linked together. That is, to merge two
polyhedria. It will then be a budding, but not hole-punching/cutting,
process.

Anyway, thx for the idea. I believe it'd turn out useful in the future
development of my lib.


$  Runsun Pan, PhD

$ -- libs: doctest , faces ( git ), offliner ( git );

tips: hash( 1 , 2 ), sweep , var

$ -- Linux Mint 17.1 Rebecca x64  + OpenSCAD 2015.03.15/2015.04.01.nightly

--
View this message in context: http://forum.openscad.org/Polyhedron-tube-with-irregular-sides-is-it-possible-tp13813p13839.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

Hi Don, interesting approach. I seem to read similar one when reading Computer Geometry or something a while back, but can't recall what it's for. This approach seems to simplify the problem significantly. The re-arrangement of points is not a big issue. On the other hand, for my application, it might bring up other problems. What I show in this thread is an extremely simplified example. The actual tube in my lib could be a complicated one with random curving, etc. To make a holed surface on the end of a long tube with this approach, the entire tube will have to be sliced apart. I also intend to use a holed surface as the merging face when cylinder of different sides (in polyhedron) linked together. That is, to merge two polyhedria. It will then be a budding, but not hole-punching/cutting, process. Anyway, thx for the idea. I believe it'd turn out useful in the future development of my lib. ----- $ Runsun Pan, PhD $ -- libs: doctest , faces ( git ), offliner ( git ); tips: hash( 1 , 2 ), sweep , var $ -- Linux Mint 17.1 Rebecca x64 + OpenSCAD 2015.03.15/2015.04.01.nightly -- View this message in context: http://forum.openscad.org/Polyhedron-tube-with-irregular-sides-is-it-possible-tp13813p13839.html Sent from the OpenSCAD mailing list archive at Nabble.com.
R
runsun
Sun, Dec 9, 2018 11:37 PM

Regarding "faces with hole", following up the "keyhole polygon" solution
described by dob bright 3 yrs ago (which is also presented as an "
alternative face description
https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#Alternate_Face_Descriptions
" in the official document ).I found that it could even be used to make a
polyhedron cube with multiple holes, like this:
pts = [[0, 0, 0], [0, 4, 0], [3, 5, 0], [2, 0, 0], [0, 0, 2], [0, 4, 2], [3,
5, 2], [2, 0, 2], [1, 0.5, 0], [0.4, 1.2, 0], [0.5, 2.1, 0], [2, 1.5, 0],
[1, 0.5, 2], [0.4, 1.2, 2], [0.5, 2.1, 2], [2, 1.5, 2], [1.5, 2.5, 0], [0.5,
3.5, 0], [2, 3.5, 0], [1.5, 2.5, 2], [0.5, 3.5, 2], [2, 3.5, 2]];faces =
[[4, 5, 6, 7, 4, 15, 14, 13, 12, 15, 4, 21, 20, 19, 21], [3, 2, 1, 0, 3, 8,
9, 10, 11, 8, 3, 16, 17, 18, 16], [0, 1, 5, 4], [1, 2, 6, 5], [2, 3, 7, 6],
[3, 0, 4, 7], [9, 8, 12, 13], [10, 9, 13, 14], [11, 10, 14, 15], [8, 11, 15,
12], [17, 16, 19, 20], [18, 17, 20, 21], [16, 18, 21,
19]];polyhedron(pts,faces);
http://forum.openscad.org/file/t602/20181209_runsun_multi_hole_surface_1.png
In this case, the top face uses pts[4] as the starting point to cut into the
two holes:
[ 4, 5, 6, 7, 4, 15, 14, 13, 12, 15, 4, 21, 20, 19, 21]
as shown in this figure:
http://forum.openscad.org/file/t602/20181209_runsun_multi_hole_surface_2.png
What surprises me is that the 2 cut lines, 4~15 and 4~21,  go across the
entire holes.Is this normal?

It seems that this approach works in more holes, too:
pts = [[0, 0, 0], [0, 4, 0], [3, 5, 0], [2, 0, 0], [0, 0, 1], [0, 4, 1], [3,
5, 1], [2, 0, 1], [1, 0.5, 0], [0.4, 1.2, 0], [2, 1.5, 0], [1, 0.5, 1],
[0.4, 1.2, 1], [2, 1.5, 1], [0.5, 1.8, 0], [0.5, 2.1, 0], [1.8, 2.2, 0],
[1.5, 2, 0], [0.5, 1.8, 1], [0.5, 2.1, 1], [1.8, 2.2, 1], [1.5, 2, 1], [1,
2.75, 0], [0.5, 3.5, 0], [2, 3.5, 0], [1, 2.75, 1], [0.5, 3.5, 1], [2, 3.5,
1]];faces = [[4, 5, 6, 7, 4, 13, 12, 11, 13, 4, 21, 20, 19, 18, 21, 4, 27,
26, 25, 27], [3, 2, 1, 0, 3, 8, 9, 10, 8, 3, 14, 15, 16, 17, 14, 3, 22, 23,
24, 22], [0, 1, 5, 4], [1, 2, 6, 5], [2, 3, 7, 6], [3, 0, 4, 7], [9, 8, 11,
12], [10, 9, 12, 13], [8, 10, 13, 11], [15, 14, 18, 19], [16, 15, 19, 20],
[17, 16, 20, 21], [14, 17, 21, 18], [23, 22, 25, 26], [24, 23, 26, 27], [22,
24, 27, 25]];polyhedron(pts,faces);
http://forum.openscad.org/file/t602/20181209_runsun_multi_hole_surface_3.png
The top face:
[ 4, 5, 6, 7, 4, 13, 12, 11, 13, 4, 21, 20, 19, 18, 21, 4, 27, 26, 25, 27]
I'd like to know what you experts think about this.


$  Runsun Pan, PhD $ libs: scadx , doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), editor of choice: CudaText  ( OpenSCAD lexer ); $ Tips ; $ Snippets

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

Regarding "faces with hole", following up the "keyhole polygon" solution described by dob bright 3 yrs ago (which is also presented as an " alternative face description <https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#Alternate_Face_Descriptions> " in the official document ).I found that it could even be used to make a polyhedron cube with multiple holes, like this: pts = [[0, 0, 0], [0, 4, 0], [3, 5, 0], [2, 0, 0], [0, 0, 2], [0, 4, 2], [3, 5, 2], [2, 0, 2], [1, 0.5, 0], [0.4, 1.2, 0], [0.5, 2.1, 0], [2, 1.5, 0], [1, 0.5, 2], [0.4, 1.2, 2], [0.5, 2.1, 2], [2, 1.5, 2], [1.5, 2.5, 0], [0.5, 3.5, 0], [2, 3.5, 0], [1.5, 2.5, 2], [0.5, 3.5, 2], [2, 3.5, 2]];faces = [[4, 5, 6, 7, 4, 15, 14, 13, 12, 15, 4, 21, 20, 19, 21], [3, 2, 1, 0, 3, 8, 9, 10, 11, 8, 3, 16, 17, 18, 16], [0, 1, 5, 4], [1, 2, 6, 5], [2, 3, 7, 6], [3, 0, 4, 7], [9, 8, 12, 13], [10, 9, 13, 14], [11, 10, 14, 15], [8, 11, 15, 12], [17, 16, 19, 20], [18, 17, 20, 21], [16, 18, 21, 19]];polyhedron(pts,faces); <http://forum.openscad.org/file/t602/20181209_runsun_multi_hole_surface_1.png> In this case, the top face uses pts[4] as the starting point to cut into the two holes: [ 4, 5, 6, 7, 4, 15, 14, 13, 12, 15, 4, 21, 20, 19, 21] as shown in this figure: <http://forum.openscad.org/file/t602/20181209_runsun_multi_hole_surface_2.png> What surprises me is that the 2 cut lines, *4~15* and *4~21*, go across the entire holes.Is this normal? It seems that this approach works in more holes, too: pts = [[0, 0, 0], [0, 4, 0], [3, 5, 0], [2, 0, 0], [0, 0, 1], [0, 4, 1], [3, 5, 1], [2, 0, 1], [1, 0.5, 0], [0.4, 1.2, 0], [2, 1.5, 0], [1, 0.5, 1], [0.4, 1.2, 1], [2, 1.5, 1], [0.5, 1.8, 0], [0.5, 2.1, 0], [1.8, 2.2, 0], [1.5, 2, 0], [0.5, 1.8, 1], [0.5, 2.1, 1], [1.8, 2.2, 1], [1.5, 2, 1], [1, 2.75, 0], [0.5, 3.5, 0], [2, 3.5, 0], [1, 2.75, 1], [0.5, 3.5, 1], [2, 3.5, 1]];faces = [[4, 5, 6, 7, 4, 13, 12, 11, 13, 4, 21, 20, 19, 18, 21, 4, 27, 26, 25, 27], [3, 2, 1, 0, 3, 8, 9, 10, 8, 3, 14, 15, 16, 17, 14, 3, 22, 23, 24, 22], [0, 1, 5, 4], [1, 2, 6, 5], [2, 3, 7, 6], [3, 0, 4, 7], [9, 8, 11, 12], [10, 9, 12, 13], [8, 10, 13, 11], [15, 14, 18, 19], [16, 15, 19, 20], [17, 16, 20, 21], [14, 17, 21, 18], [23, 22, 25, 26], [24, 23, 26, 27], [22, 24, 27, 25]];polyhedron(pts,faces); <http://forum.openscad.org/file/t602/20181209_runsun_multi_hole_surface_3.png> The top face: [ 4, 5, 6, 7, 4, 13, 12, 11, 13, 4, 21, 20, 19, 18, 21, 4, 27, 26, 25, 27] I'd like to know what you experts think about this. ----- $ Runsun Pan, PhD $ libs: scadx , doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), editor of choice: CudaText ( OpenSCAD lexer );&nbsp;$ Tips ;&nbsp;$ Snippets -- Sent from: http://forum.openscad.org/
P
Parkinbot
Mon, Dec 10, 2018 4:08 AM

Very interesting stuff. Thanks for digging out this hack!
I immediately wanted this for sweep();

A sweep with a "close" attribute doing a single hole without difference() is
already nothing new - you sweep up and down.

sweep([circle(10, 0), circle(10, 20), circle(7, 20), circle(7, 0)], close =
true);
function circle(r=10, z = 0, N=10) = [for(i=[0:N-1]) [rcos(360/Ni),
rsin(360/Ni), z]];

I guess this approach will allow to implement a sweep() allowing for as many
holes as one likes.
I'll have to add a new interface parameter to my sweep() that lets one
supply a list of polygons describing the holes. The first and last face need
the hack, the rest is more or less straight forward.

Being able to sweep objects with multiple holes can speed up rendering of a
lot of stuff. I'm looking forward to have it.

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

Very interesting stuff. Thanks for digging out this hack! I immediately wanted this for sweep(); A sweep with a "close" attribute doing a single hole without difference() is already nothing new - you sweep up and down. sweep([circle(10, 0), circle(10, 20), circle(7, 20), circle(7, 0)], close = true); function circle(r=10, z = 0, N=10) = [for(i=[0:N-1]) [r*cos(360/N*i), r*sin(360/N*i), z]]; I guess this approach will allow to implement a sweep() allowing for as many holes as one likes. I'll have to add a new interface parameter to my sweep() that lets one supply a list of polygons describing the holes. The first and last face need the hack, the rest is more or less straight forward. Being able to sweep objects with multiple holes can speed up rendering of a lot of stuff. I'm looking forward to have it. -- Sent from: http://forum.openscad.org/
NH
nop head
Mon, Dec 10, 2018 9:36 AM

It's happy to preview but doesn't work with a union with a unit cube and F6.

On Mon, 10 Dec 2018 at 04:09, Parkinbot rudolf@digitaldocument.de wrote:

Very interesting stuff. Thanks for digging out this hack!
I immediately wanted this for sweep();

A sweep with a "close" attribute doing a single hole without difference()
is
already nothing new - you sweep up and down.

sweep([circle(10, 0), circle(10, 20), circle(7, 20), circle(7, 0)], close =
true);
function circle(r=10, z = 0, N=10) = [for(i=[0:N-1]) [rcos(360/Ni),
rsin(360/Ni), z]];

I guess this approach will allow to implement a sweep() allowing for as
many
holes as one likes.
I'll have to add a new interface parameter to my sweep() that lets one
supply a list of polygons describing the holes. The first and last face
need
the hack, the rest is more or less straight forward.

Being able to sweep objects with multiple holes can speed up rendering of a
lot of stuff. I'm looking forward to have it.

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


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

It's happy to preview but doesn't work with a union with a unit cube and F6. On Mon, 10 Dec 2018 at 04:09, Parkinbot <rudolf@digitaldocument.de> wrote: > Very interesting stuff. Thanks for digging out this hack! > I immediately wanted this for sweep(); > > A sweep with a "close" attribute doing a single hole without difference() > is > already nothing new - you sweep up and down. > > sweep([circle(10, 0), circle(10, 20), circle(7, 20), circle(7, 0)], close = > true); > function circle(r=10, z = 0, N=10) = [for(i=[0:N-1]) [r*cos(360/N*i), > r*sin(360/N*i), z]]; > > I guess this approach will allow to implement a sweep() allowing for as > many > holes as one likes. > I'll have to add a new interface parameter to my sweep() that lets one > supply a list of polygons describing the holes. The first and last face > need > the hack, the rest is more or less straight forward. > > Being able to sweep objects with multiple holes can speed up rendering of a > lot of stuff. I'm looking forward to have it. > > > > > -- > Sent from: http://forum.openscad.org/ > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
P
Parkinbot
Mon, Dec 10, 2018 10:55 AM

Oh, how stupid I didn't check this little detail :-( . My first approach was
to use a polygon with the same point sequence, but that didn't work, because
my sweep() currently also puts vertical walls along the kerfs. So if CGAL
would cooperate, one could easily implement sweep() to omit those walls.

http://forum.openscad.org/file/t887/sweepwithholes.png

use <Naca_sweep.scad>
a = circle(30, 0, 10, -1);
b = circle(6, 0, 100, 1);

q = prepsweep([a, each forN_(b, 17)]);
sweep([q, Tz_(10, q)]);

function prepsweep(P) = [each P[0], each for(p=[1:len(P)-1]) each [P[p],
[P[p][0]], [P[0][len(P[0])-1]]]];
function forN_(P, r=0, N=6) = [for(i=[0:N-1]) T_(rsin(360/Ni),
rcos(360/Ni), 0, P)];
function circle(r=10, z = 0, N=10, dir=1) = [for(i=[0:N-1])
[rcos(dir360/Ni), rsin(dir360/Ni), z]];

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

Oh, how stupid I didn't check this little detail :-( . My first approach was to use a polygon with the same point sequence, but that didn't work, because my sweep() currently also puts vertical walls along the kerfs. So if CGAL would cooperate, one could easily implement sweep() to omit those walls. <http://forum.openscad.org/file/t887/sweepwithholes.png> use <Naca_sweep.scad> a = circle(30, 0, 10, -1); b = circle(6, 0, 100, 1); q = prepsweep([a, each forN_(b, 17)]); sweep([q, Tz_(10, q)]); function prepsweep(P) = [each P[0], each for(p=[1:len(P)-1]) each [P[p], [P[p][0]], [P[0][len(P[0])-1]]]]; function forN_(P, r=0, N=6) = [for(i=[0:N-1]) T_(r*sin(360/N*i), r*cos(360/N*i), 0, P)]; function circle(r=10, z = 0, N=10, dir=1) = [for(i=[0:N-1]) [r*cos(dir*360/N*i), r*sin(dir*360/N*i), z]]; -- Sent from: http://forum.openscad.org/
P
Parkinbot
Mon, Dec 10, 2018 12:42 PM

A multi-hole sweep can be also implemented straight forward and does not need
this hack. It has to provide its own triangulation of the first and last
faces with holes and just can't rely on CGAL to do it. CGAL gets slow
anyway, when it starts with "trying alternative construction". The rest is
just building the walls like a vectorized sweep.

The new call will be something like:

sweep(outerpolygon_sequence=a, listofholes_sequence=b)

As soon as I find time, I'm gonna try it.

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

A multi-hole sweep can be also implemented straight forward and does not need this hack. It has to provide its own triangulation of the first and last faces with holes and just can't rely on CGAL to do it. CGAL gets slow anyway, when it starts with "trying alternative construction". The rest is just building the walls like a vectorized sweep. The new call will be something like: sweep(outerpolygon_sequence=a, listofholes_sequence=b) As soon as I find time, I'm gonna try it. -- Sent from: http://forum.openscad.org/
N
NateTG
Mon, Dec 10, 2018 6:16 PM

You could just use clockwise-counterclockwise to identify holes.

I did write a triangulation thing for bending text, though there's probably
a better way.

https://gist.github.com/NateTG/b350378c56f436d3996a2107f7cba965

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

You could just use clockwise-counterclockwise to identify holes. I did write a triangulation thing for bending text, though there's probably a better way. https://gist.github.com/NateTG/b350378c56f436d3996a2107f7cba965 -- Sent from: http://forum.openscad.org/
NH
nop head
Mon, Dec 10, 2018 6:45 PM

With a polyhedron counter-clockwise is already used to mean a face facing
the other way, which is different from a hole in a face. E.g. in runsun's
numbered example the bottom face is listed counter-clockwise looking from
the top because it is pointing downwards.

Perhaps the first polygon in the face could be assumed the outward facing
direction and any polygons in the same face that go the opposite direction
to be holes in it.

On Mon, 10 Dec 2018 at 18:17, NateTG nate-openscadforum@pedantic.org
wrote:

You could just use clockwise-counterclockwise to identify holes.

I did write a triangulation thing for bending text, though there's probably
a better way.

https://gist.github.com/NateTG/b350378c56f436d3996a2107f7cba965

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


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

With a polyhedron counter-clockwise is already used to mean a face facing the other way, which is different from a hole in a face. E.g. in runsun's numbered example the bottom face is listed counter-clockwise looking from the top because it is pointing downwards. Perhaps the first polygon in the face could be assumed the outward facing direction and any polygons in the same face that go the opposite direction to be holes in it. On Mon, 10 Dec 2018 at 18:17, NateTG <nate-openscadforum@pedantic.org> wrote: > You could just use clockwise-counterclockwise to identify holes. > > I did write a triangulation thing for bending text, though there's probably > a better way. > > https://gist.github.com/NateTG/b350378c56f436d3996a2107f7cba965 > > > > > > -- > Sent from: http://forum.openscad.org/ > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
R
runsun
Mon, Dec 10, 2018 6:48 PM

Thx for the check, nophead. Wondering how OpenSCAD allows it to render
correctly when it's stand-alone.


$  Runsun Pan, PhD $ libs: scadx , doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), editor of choice: CudaText  ( OpenSCAD lexer ); $ Tips ; $ Snippets

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

Thx for the check, nophead. Wondering how OpenSCAD allows it to render correctly when it's stand-alone. ----- $ Runsun Pan, PhD $ libs: scadx , doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), editor of choice: CudaText ( OpenSCAD lexer );&nbsp;$ Tips ;&nbsp;$ Snippets -- Sent from: http://forum.openscad.org/
NH
nop head
Mon, Dec 10, 2018 7:04 PM

OpenCSG just draws all the triangles and if they cover all the pixels it
looks OK. CGAL on the other hand needs a mainfold mesh, not one with self
intersections in its planes.

On Mon, 10 Dec 2018 at 18:49, runsun runsun@gmail.com wrote:

Thx for the check, nophead. Wondering how OpenSCAD allows it to render
correctly when it's stand-alone.


$  Runsun Pan, PhD $ libs: scadx , doctest , faces ( git ), offline doc (
git ), runscad.py ( 2 , git ), editor of choice: CudaText  ( OpenSCAD lexer
); $ Tips ; $ Snippets

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


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

OpenCSG just draws all the triangles and if they cover all the pixels it looks OK. CGAL on the other hand needs a mainfold mesh, not one with self intersections in its planes. On Mon, 10 Dec 2018 at 18:49, runsun <runsun@gmail.com> wrote: > Thx for the check, nophead. Wondering how OpenSCAD allows it to render > correctly when it's stand-alone. > > > > ----- > > $ Runsun Pan, PhD $ libs: scadx , doctest , faces ( git ), offline doc ( > git ), runscad.py ( 2 , git ), editor of choice: CudaText ( OpenSCAD lexer > );&nbsp;$ Tips ;&nbsp;$ Snippets > > -- > Sent from: http://forum.openscad.org/ > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
NH
nop head
Mon, Dec 10, 2018 7:05 PM

I should add CGAL is avoided if there are no CSG ops.

On Mon, 10 Dec 2018 at 19:04, nop head nop.head@gmail.com wrote:

OpenCSG just draws all the triangles and if they cover all the pixels it
looks OK. CGAL on the other hand needs a mainfold mesh, not one with self
intersections in its planes.

On Mon, 10 Dec 2018 at 18:49, runsun runsun@gmail.com wrote:

Thx for the check, nophead. Wondering how OpenSCAD allows it to render
correctly when it's stand-alone.


$  Runsun Pan, PhD $ libs: scadx , doctest , faces ( git ), offline doc (
git ), runscad.py ( 2 , git ), editor of choice: CudaText  ( OpenSCAD lexer
); $ Tips ; $ Snippets

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


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

I should add CGAL is avoided if there are no CSG ops. On Mon, 10 Dec 2018 at 19:04, nop head <nop.head@gmail.com> wrote: > OpenCSG just draws all the triangles and if they cover all the pixels it > looks OK. CGAL on the other hand needs a mainfold mesh, not one with self > intersections in its planes. > > On Mon, 10 Dec 2018 at 18:49, runsun <runsun@gmail.com> wrote: > >> Thx for the check, nophead. Wondering how OpenSCAD allows it to render >> correctly when it's stand-alone. >> >> >> >> ----- >> >> $ Runsun Pan, PhD $ libs: scadx , doctest , faces ( git ), offline doc ( >> git ), runscad.py ( 2 , git ), editor of choice: CudaText ( OpenSCAD lexer >> );&nbsp;$ Tips ;&nbsp;$ Snippets >> >> -- >> Sent from: http://forum.openscad.org/ >> >> _______________________________________________ >> OpenSCAD mailing list >> Discuss@lists.openscad.org >> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >> >
P
Parkinbot
Mon, Dec 10, 2018 8:06 PM

A triangulation like earcut with holes will be cumbersome to implement in
OpenSCAD. However a fast and viable solution for implementing the multi-hole
sweep is to use a vectorized lazy union sweep for the holes and difference
the result from the sweep of the outer polygon. For export one will have to
use a Boolean operation to do a CGAL check anyway.

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

A triangulation like earcut with holes will be cumbersome to implement in OpenSCAD. However a fast and viable solution for implementing the multi-hole sweep is to use a vectorized lazy union sweep for the holes and difference the result from the sweep of the outer polygon. For export one will have to use a Boolean operation to do a CGAL check anyway. -- Sent from: http://forum.openscad.org/
R
runsun
Mon, Dec 10, 2018 8:13 PM

Just applied the union rendering check on the  alternative face description
https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#Alternate_Face_Descriptions
described in the documentation and found it failed the same way.
nophead wrote

It's happy to preview but doesn't work with a union with a unit cube and
F6.


$  Runsun Pan, PhD $ libs: scadx , doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), editor of choice: CudaText  ( OpenSCAD lexer ); $ Tips ; $ Snippets

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

Just applied the union rendering check on the alternative face description <https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#Alternate_Face_Descriptions> described in the documentation and found it failed the same way. nophead wrote > It's happy to preview but doesn't work with a union with a unit cube and > F6. ----- $ Runsun Pan, PhD $ libs: scadx , doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), editor of choice: CudaText ( OpenSCAD lexer );&nbsp;$ Tips ;&nbsp;$ Snippets -- Sent from: http://forum.openscad.org/
RP
Ronaldo Persiano
Thu, Dec 13, 2018 11:57 AM

You are right: it doesn't work. I created that section based on the
examples of 2D polygons with holes. I had checked it then with F6 but had
not done a full check with a cube union. Sorry by that.

What is strange (or inconsistent) is that 2D polygons with holes render
fine even with a full check.

I have deleted the section from the manual. It can be retrieved from the
wiki history anyway.

Ronaldo

Em seg, 10 de dez de 2018 às 20:14, runsun runsun@gmail.com escreveu:

You are right: it doesn't work. I created that section based on the examples of 2D polygons with holes. I had checked it then with F6 but had not done a full check with a cube union. Sorry by that. What is strange (or inconsistent) is that 2D polygons with holes render fine even with a full check. I have deleted the section from the manual. It can be retrieved from the wiki history anyway. Ronaldo Em seg, 10 de dez de 2018 às 20:14, runsun <runsun@gmail.com> escreveu: > Just applied the union rendering check on the alternative face description > <https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#Alternate_Face_Descriptions> > described in the documentation and found it failed the same way. > > nophead wrote > It's happy to preview but doesn't work with a union with a unit cube and > F6. > > $ <http://forum.openscad.org/mailing_list/MailingListOptions.jtp?forum=1> *Runsun > Pan, PhD* > $ *libs*: scadx <https://bitbucket.org/runsun/scadx>, doctest > <https://github.com/runsun/openscad_doctest>, faces > <http://forum.openscad.org/A-faces-function-for-simple-polyhedrons-td12809.html> > (git <https://github.com/runsun/faces.scad>), offline doc > <http://forum.openscad.org/Use-openscad-offliner-for-offline-documentation-td13096.html> > (git <https://github.com/runsun/openscad_offliner>), runscad.py > <http://forum.openscad.org/Animating-gif-with-3D-rotation-tp14011p14029.html> > (2 <http://forum.openscad.org/Symmetrical-Rotation-tp14062p14075.html>,git > <https://gist.github.com/runsun/995250a8002386ab9abc>), editor of choice: > CudaText > <http://forum.openscad.org/Syntax-highlighting-tp23247p23258.html> ( OpenSCAD > lexer <http://www.thingiverse.com/thing:1237864>); $ Tips > <https://github.com/runsun/OpenSCAD_Tips>; $ Snippets > <https://github.com/runsun/OpenSCAD_Tips/blob/master/snippets.md> > > ------------------------------ > Sent from the OpenSCAD mailing list archive <http://forum.openscad.org/> > at Nabble.com. > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
NH
nop head
Thu, Dec 13, 2018 1:36 PM

The 2D subsystem uses clipper, which is very good at sorting out self
intersections, etc. CGALseems to be the opposite. It just rejects all
non-manifold faces rather than attempting to heal them. However the 2D
problem is simpler. Normally you just reverse the winding order to make
holes or use the odd even rule.

Perhaps when the polyhedron face is considered planar clipper could be used
to clean it up.

On Thu, 13 Dec 2018 at 11:58, Ronaldo Persiano rcmpersiano@gmail.com
wrote:

You are right: it doesn't work. I created that section based on the
examples of 2D polygons with holes. I had checked it then with F6 but had
not done a full check with a cube union. Sorry by that.

What is strange (or inconsistent) is that 2D polygons with holes render
fine even with a full check.

I have deleted the section from the manual. It can be retrieved from the
wiki history anyway.

Ronaldo

Em seg, 10 de dez de 2018 às 20:14, runsun runsun@gmail.com escreveu:

The 2D subsystem uses clipper, which is very good at sorting out self intersections, etc. CGALseems to be the opposite. It just rejects all non-manifold faces rather than attempting to heal them. However the 2D problem is simpler. Normally you just reverse the winding order to make holes or use the odd even rule. Perhaps when the polyhedron face is considered planar clipper could be used to clean it up. On Thu, 13 Dec 2018 at 11:58, Ronaldo Persiano <rcmpersiano@gmail.com> wrote: > You are right: it doesn't work. I created that section based on the > examples of 2D polygons with holes. I had checked it then with F6 but had > not done a full check with a cube union. Sorry by that. > > What is strange (or inconsistent) is that 2D polygons with holes render > fine even with a full check. > > I have deleted the section from the manual. It can be retrieved from the > wiki history anyway. > > Ronaldo > > Em seg, 10 de dez de 2018 às 20:14, runsun <runsun@gmail.com> escreveu: > >> Just applied the union rendering check on the alternative face >> description >> <https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#Alternate_Face_Descriptions> >> described in the documentation and found it failed the same way. >> >> nophead wrote >> It's happy to preview but doesn't work with a union with a unit cube and >> F6. >> >> $ <http://forum.openscad.org/mailing_list/MailingListOptions.jtp?forum=1> *Runsun >> Pan, PhD* >> $ *libs*: scadx <https://bitbucket.org/runsun/scadx>, doctest >> <https://github.com/runsun/openscad_doctest>, faces >> <http://forum.openscad.org/A-faces-function-for-simple-polyhedrons-td12809.html> >> (git <https://github.com/runsun/faces.scad>), offline doc >> <http://forum.openscad.org/Use-openscad-offliner-for-offline-documentation-td13096.html> >> (git <https://github.com/runsun/openscad_offliner>), runscad.py >> <http://forum.openscad.org/Animating-gif-with-3D-rotation-tp14011p14029.html> >> (2 <http://forum.openscad.org/Symmetrical-Rotation-tp14062p14075.html>, >> git <https://gist.github.com/runsun/995250a8002386ab9abc>), editor of >> choice: CudaText >> <http://forum.openscad.org/Syntax-highlighting-tp23247p23258.html> ( OpenSCAD >> lexer <http://www.thingiverse.com/thing:1237864>); $ Tips >> <https://github.com/runsun/OpenSCAD_Tips>; $ Snippets >> <https://github.com/runsun/OpenSCAD_Tips/blob/master/snippets.md> >> >> ------------------------------ >> Sent from the OpenSCAD mailing list archive <http://forum.openscad.org/> >> at Nabble.com. >> _______________________________________________ >> OpenSCAD mailing list >> Discuss@lists.openscad.org >> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >> > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
P
Parkinbot
Fri, Dec 14, 2018 12:58 PM

Since the following code is accepted by CGAL

pts =  [[0, 0], [6, 0], [6, 5], [0, 5], [0, 0], [2, 1], [5, 2], [3, 4], [2,
1]];
linear_extrude(2)
polygon(pts);
cube(1);

and obviously uses triangulation

http://forum.openscad.org/file/t887/hole.png

it shouldn't be too difficult to provide a built-in triangulate2D() function
that uses clipper and returns a [verts, triags] list.

vertsfaceslist = triangulate2D(pts);  // builtin call using clipper
returning a [verts, triags] list
// ... use vertsfaceslist

the prototype could be:

function triangulate2D(polygon, z=undef) = ...

If provided z would add the given value as z coordinate to the verts (vec3
conversion) for intended polyhedron usage. Doesn't this sound like a nice
feature request?

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

Since the following code is accepted by CGAL pts = [[0, 0], [6, 0], [6, 5], [0, 5], [0, 0], [2, 1], [5, 2], [3, 4], [2, 1]]; linear_extrude(2) polygon(pts); cube(1); and obviously uses triangulation <http://forum.openscad.org/file/t887/hole.png> it shouldn't be too difficult to provide a built-in triangulate2D() function that uses clipper and returns a [verts, triags] list. vertsfaceslist = triangulate2D(pts); // builtin call using clipper returning a [verts, triags] list // ... use vertsfaceslist the prototype could be: function triangulate2D(polygon, z=undef) = ... If provided z would add the given value as z coordinate to the verts (vec3 conversion) for intended polyhedron usage. Doesn't this sound like a nice feature request? -- Sent from: http://forum.openscad.org/
RP
Ronaldo Persiano
Sun, Dec 16, 2018 5:08 PM

Parkinbot rudolf@digitaldocument.de wrote:

it shouldn't be too difficult to provide a built-in triangulate2D()
function
that uses clipper and returns a [verts, triags] list.

Clipper library doesn't have any polygon triangulation procedure. According
to @Kintel, OpenScad uses a modified version of libtess2 to triangulate
polygons (see
http://forum.openscad.org/Simple-polygon-triangulation-tp16755p16762.html)
and libtess2 is unable to deal with holes. I have found a polygon
triangulation library supposedly robust and fast that accepts polygons with
holes: poly2tri (
https://doc-snapshots.qt.io/qt5-5.9/qtlocation-attribution-poly2tri.html)
with a BSD 3 license clause. Is that license compatible with OpenScad GPL
license?

Parkinbot <rudolf@digitaldocument.de> wrote: > it shouldn't be too difficult to provide a built-in triangulate2D() > function > that uses clipper and returns a [verts, triags] list. > > Clipper library doesn't have any polygon triangulation procedure. According to @Kintel, OpenScad uses a modified version of libtess2 to triangulate polygons (see http://forum.openscad.org/Simple-polygon-triangulation-tp16755p16762.html) and libtess2 is unable to deal with holes. I have found a polygon triangulation library supposedly robust and fast that accepts polygons with holes: poly2tri ( https://doc-snapshots.qt.io/qt5-5.9/qtlocation-attribution-poly2tri.html) with a BSD 3 license clause. Is that license compatible with OpenScad GPL license?
CA
Carsten Arnholm
Sun, Dec 16, 2018 6:08 PM

On 16.12.2018 18:08, Ronaldo Persiano wrote:

Parkinbot <rudolf@digitaldocument.de mailto:rudolf@digitaldocument.de>
wrote:

 it shouldn't be too difficult to provide a built-in triangulate2D()
 function
 that uses clipper and returns a [verts, triags] list.

Clipper library doesn't have any polygon triangulation procedure.
According to @Kintel, OpenScad uses a modified version of libtess2 to
triangulate polygons (see
http://forum.openscad.org/Simple-polygon-triangulation-tp16755p16762.html)
and libtess2 is unable to deal with holes.

I don't believe this statement is correct, in my experience libtess2
deals with holes quite well, at least for the cases I have seen. Do you
have any examples showing it does not work with holes?

Carsten Arnholm

On 16.12.2018 18:08, Ronaldo Persiano wrote: > Parkinbot <rudolf@digitaldocument.de <mailto:rudolf@digitaldocument.de>> > wrote: > > it shouldn't be too difficult to provide a built-in triangulate2D() > function > that uses clipper and returns a [verts, triags] list. > > > Clipper library doesn't have any polygon triangulation procedure. > According to @Kintel, OpenScad uses a modified version of libtess2 to > triangulate polygons (see > http://forum.openscad.org/Simple-polygon-triangulation-tp16755p16762.html) > and libtess2 is unable to deal with holes. I don't believe this statement is correct, in my experience libtess2 deals with holes quite well, at least for the cases I have seen. Do you have any examples showing it does not work with holes? Carsten Arnholm
P
Parkinbot
Sun, Dec 16, 2018 6:33 PM

Ronaldo wrote

Parkinbot <

rudolf@

> wrote:

Clipper library doesn't have any polygon triangulation procedure.
According
to @Kintel, OpenScad uses a modified version of libtess2 to triangulate
polygons (see
http://forum.openscad.org/Simple-polygon-triangulation-tp16755p16762.html)
and libtess2 is unable to deal with holes.

I was referring to the post of nophead, without checking that.

nophead wrote

The 2D subsystem uses clipper, which is very good at sorting out self
intersections, etc. CGALseems to be the opposite. I

But in the thread you are referring to, the theme was almost planar polygons
in 3D. Here we are talking about the 2D subsystem. And linear_extrude
obviously uses a correct tesselation. Where does it come from?

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

Ronaldo wrote > Parkinbot &lt; > rudolf@ > &gt; wrote: > > Clipper library doesn't have any polygon triangulation procedure. > According > to @Kintel, OpenScad uses a modified version of libtess2 to triangulate > polygons (see > http://forum.openscad.org/Simple-polygon-triangulation-tp16755p16762.html) > and libtess2 is unable to deal with holes. I was referring to the post of nophead, without checking that. nophead wrote > The 2D subsystem uses clipper, which is very good at sorting out self > intersections, etc. CGALseems to be the opposite. I But in the thread you are referring to, the theme was almost planar polygons in 3D. Here we are talking about the 2D subsystem. And linear_extrude obviously uses a correct tesselation. Where does it come from? -- Sent from: http://forum.openscad.org/
NH
nop head
Sun, Dec 16, 2018 7:37 PM

I don't think faces need to be tesselated for CGAL. It can handle polygonal
faces, so all linear_extrude would need to do is join the top and bottom
polygons with quads.

I think the problem with polyhedron is the interface. I.e. it doesn't allow
holes to be expressed in polygonal faces.

On Sun, 16 Dec 2018 at 18:33, Parkinbot rudolf@digitaldocument.de wrote:

Ronaldo wrote

Parkinbot <

rudolf@

> wrote:

Clipper library doesn't have any polygon triangulation procedure.
According
to @Kintel, OpenScad uses a modified version of libtess2 to triangulate
polygons (see

and libtess2 is unable to deal with holes.

I was referring to the post of nophead, without checking that.

nophead wrote

The 2D subsystem uses clipper, which is very good at sorting out self
intersections, etc. CGALseems to be the opposite. I

But in the thread you are referring to, the theme was almost planar
polygons
in 3D. Here we are talking about the 2D subsystem. And linear_extrude
obviously uses a correct tesselation. Where does it come from?

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


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

I don't think faces need to be tesselated for CGAL. It can handle polygonal faces, so all linear_extrude would need to do is join the top and bottom polygons with quads. I think the problem with polyhedron is the interface. I.e. it doesn't allow holes to be expressed in polygonal faces. On Sun, 16 Dec 2018 at 18:33, Parkinbot <rudolf@digitaldocument.de> wrote: > Ronaldo wrote > > Parkinbot &lt; > > > rudolf@ > > > &gt; wrote: > > > > Clipper library doesn't have any polygon triangulation procedure. > > According > > to @Kintel, OpenScad uses a modified version of libtess2 to triangulate > > polygons (see > > > http://forum.openscad.org/Simple-polygon-triangulation-tp16755p16762.html) > > and libtess2 is unable to deal with holes. > > I was referring to the post of nophead, without checking that. > > nophead wrote > > The 2D subsystem uses clipper, which is very good at sorting out self > > intersections, etc. CGALseems to be the opposite. I > > But in the thread you are referring to, the theme was almost planar > polygons > in 3D. Here we are talking about the 2D subsystem. And linear_extrude > obviously uses a correct tesselation. Where does it come from? > > > > > > -- > Sent from: http://forum.openscad.org/ > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
P
Parkinbot
Sun, Dec 16, 2018 9:08 PM

nophead wrote

I don't think faces need to be tesselated for CGAL.

but for polyhedron. And linear_extrude obviously uses a tesselation when it
extrudes a polygon with hole.

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

nophead wrote > I don't think faces need to be tesselated for CGAL. but for polyhedron. And linear_extrude obviously uses a tesselation when it extrudes a polygon with hole. -- Sent from: http://forum.openscad.org/
NH
nop head
Sun, Dec 16, 2018 9:21 PM

What makes you think that? It is definitely tesilated with F5

[image: image.png]

But not with F6, unless it hides it better.

[image: image.png]

On Sun, 16 Dec 2018 at 21:08, Parkinbot rudolf@digitaldocument.de wrote:

nophead wrote

I don't think faces need to be tesselated for CGAL.

but for polyhedron. And linear_extrude obviously uses a tesselation when it
extrudes a polygon with hole.

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


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

What makes you think that? It is definitely tesilated with F5 [image: image.png] But not with F6, unless it hides it better. [image: image.png] On Sun, 16 Dec 2018 at 21:08, Parkinbot <rudolf@digitaldocument.de> wrote: > nophead wrote > > I don't think faces need to be tesselated for CGAL. > > but for polyhedron. And linear_extrude obviously uses a tesselation when it > extrudes a polygon with hole. > > > > -- > Sent from: http://forum.openscad.org/ > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
A
arnholm@arnholm.org
Sun, Dec 16, 2018 9:26 PM

On 2018-12-16 22:21, nop head wrote:

What makes you think that? It is definitely tesilated with F5

But not with F6, unless it hides it better.

Save it to STL or any other format requiring triangles.

Carsten Arnholm

On 2018-12-16 22:21, nop head wrote: > What makes you think that? It is definitely tesilated with F5 > > But not with F6, unless it hides it better. > Save it to STL or any other format requiring triangles. Carsten Arnholm
NH
nop head
Sun, Dec 16, 2018 9:36 PM

Yes but I beleive CGAL objects get tesilated when they are converted to
STL. The can have single facets that are pologons. They aren't triangle
meshes.

On Sun, 16 Dec 2018 at 21:27, arnholm@arnholm.org wrote:

On 2018-12-16 22:21, nop head wrote:

What makes you think that? It is definitely tesilated with F5

But not with F6, unless it hides it better.

Save it to STL or any other format requiring triangles.

Carsten Arnholm


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

Yes but I beleive CGAL objects get tesilated when they are converted to STL. The can have single facets that are pologons. They aren't triangle meshes. On Sun, 16 Dec 2018 at 21:27, <arnholm@arnholm.org> wrote: > On 2018-12-16 22:21, nop head wrote: > > What makes you think that? It is definitely tesilated with F5 > > > > But not with F6, unless it hides it better. > > > > Save it to STL or any other format requiring triangles. > > Carsten Arnholm > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
P
Parkinbot
Sun, Dec 16, 2018 11:40 PM

Sorry nophead,

I meant that I can see that F5 tessellates a polygon with holes for use with
linear_extrude and we could use the underlying functionality to provide a
function that tesselates a 2D polygon given as list.

Btw, I see a F5 tesselation but not a F6 tesselation for

sphere(10);

Maybe OpenSCAD just doesn't display it?

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

Sorry nophead, I meant that I can see that F5 tessellates a polygon with holes for use with linear_extrude and we could use the underlying functionality to provide a function that tesselates a 2D polygon given as list. Btw, I see a F5 tesselation but not a F6 tesselation for sphere(10); Maybe OpenSCAD just doesn't display it? -- Sent from: http://forum.openscad.org/
P
Parkinbot
Mon, Dec 17, 2018 12:03 AM

Parkinbot wrote

Btw, I see a F5 tesselation but not a F6 tesselation for

sphere(10);

Maybe OpenSCAD just doesn't display it?

It looks like it is only displayed when a boolean operation is involved

translate([20, 0, 0])
cube(5);
sphere(10);

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

Parkinbot wrote > Btw, I see a F5 tesselation but not a F6 tesselation for > > sphere(10); > > Maybe OpenSCAD just doesn't display it? It looks like it is only displayed when a boolean operation is involved translate([20, 0, 0]) cube(5); sphere(10); -- Sent from: http://forum.openscad.org/
NH
nop head
Mon, Dec 17, 2018 12:05 AM

If you just have sphere(10) without any CSG ops CGAL is not involved.
OpenScad has its own 3D representation and when that is displayed show
edges does not work.

If you add a unit cube then CGAL generates the union and the final result
is then a CGAL object and show edges works.

[image: image.png]

It is mostly tesselated with triangles but there are some quads and
polgonal poles. Wierd, but that is probably just how it is constructed, not
by using a tessalator.

When you do F5 the tessalation is totally different. I think OpenCSG
tesselates everything to triangles when it displayes.

On Sun, 16 Dec 2018 at 23:40, Parkinbot rudolf@digitaldocument.de wrote:

Sorry nophead,

I meant that I can see that F5 tessellates a polygon with holes for use
with
linear_extrude and we could use the underlying functionality to provide a
function that tesselates a 2D polygon given as list.

Btw, I see a F5 tesselation but not a F6 tesselation for

sphere(10);

Maybe OpenSCAD just doesn't display it?

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


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

If you just have sphere(10) without any CSG ops CGAL is not involved. OpenScad has its own 3D representation and when that is displayed show edges does not work. If you add a unit cube then CGAL generates the union and the final result is then a CGAL object and show edges works. [image: image.png] It is mostly tesselated with triangles but there are some quads and polgonal poles. Wierd, but that is probably just how it is constructed, not by using a tessalator. When you do F5 the tessalation is totally different. I think OpenCSG tesselates everything to triangles when it displayes. On Sun, 16 Dec 2018 at 23:40, Parkinbot <rudolf@digitaldocument.de> wrote: > Sorry nophead, > > I meant that I can see that F5 tessellates a polygon with holes for use > with > linear_extrude and we could use the underlying functionality to provide a > function that tesselates a 2D polygon given as list. > > Btw, I see a F5 tesselation but not a F6 tesselation for > > sphere(10); > > Maybe OpenSCAD just doesn't display it? > > > > -- > Sent from: http://forum.openscad.org/ > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
P
Parkinbot
Mon, Dec 17, 2018 12:18 AM

Ronaldo had noticed it some time ago that CGAL changes tesselation on its own
will.

I created a cube by means of sweep(). So I am sure that it is tesselated in
triags. See how it is displayed by F6 with a unit cube unioned.
http://forum.openscad.org/file/t887/sweep.png

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

Ronaldo had noticed it some time ago that CGAL changes tesselation on its own will. I created a cube by means of sweep(). So I am sure that it is tesselated in triags. See how it is displayed by F6 with a unit cube unioned. <http://forum.openscad.org/file/t887/sweep.png> -- Sent from: http://forum.openscad.org/
NH
nop head
Mon, Dec 17, 2018 12:28 AM

Looks like CGAL de-tesselates triangles in the same plane to make pologons.
That makes it hard to know what the internal representation of anything is.
It used to always be CGAL nef_polyhreda I think but now it switches back
and forth to polysets. When the result is a polyset you don't get all the
vertex / edge info and show edges does not work. Also I think it switches
from rationals to doubles for the vertices.

On Mon, 17 Dec 2018 at 00:19, Parkinbot rudolf@digitaldocument.de wrote:

Ronaldo had noticed it some time ago that CGAL changes tesselation on its
own
will.

I created a cube by means of sweep(). So I am sure that it is tesselated in
triags. See how it is displayed by F6 with a unit cube unioned.
http://forum.openscad.org/file/t887/sweep.png

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


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

Looks like CGAL de-tesselates triangles in the same plane to make pologons. That makes it hard to know what the internal representation of anything is. It used to always be CGAL nef_polyhreda I think but now it switches back and forth to polysets. When the result is a polyset you don't get all the vertex / edge info and show edges does not work. Also I think it switches from rationals to doubles for the vertices. On Mon, 17 Dec 2018 at 00:19, Parkinbot <rudolf@digitaldocument.de> wrote: > Ronaldo had noticed it some time ago that CGAL changes tesselation on its > own > will. > > I created a cube by means of sweep(). So I am sure that it is tesselated in > triags. See how it is displayed by F6 with a unit cube unioned. > <http://forum.openscad.org/file/t887/sweep.png> > > > > > -- > Sent from: http://forum.openscad.org/ > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
P
Parkinbot
Mon, Dec 17, 2018 12:53 AM

Clearly, CGAL is only called when a Boolean operation is present. Thus the
polyset to nef_polyhreda conversion is not necessary for primitives like a
polyhedron and can't be displayed.
When CGAL is called, it seems to try to reduce faces.

Nevertheless there is a tesselation of polygon with holes for F5 and this
one could be exposed to the user.

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

Clearly, CGAL is only called when a Boolean operation is present. Thus the polyset to nef_polyhreda conversion is not necessary for primitives like a polyhedron and can't be displayed. When CGAL is called, it seems to try to reduce faces. Nevertheless there is a tesselation of polygon with holes for F5 and this one could be exposed to the user. -- Sent from: http://forum.openscad.org/
NH
nop head
Mon, Dec 17, 2018 8:09 AM

Yes but I don't think tessalation is the issue with polyhedron. The problem
seems to be the interface to polyhedron has no way to express holes.

It could detect faces that are coplanar with an encolsing face pass them
through clipper to sort out the holes. Or it could allow the keyhole
contruction, detect the loops and remove the extra edges between loops. So
each face becomes a list of loops with counter clockwise ones being holes.

Tessalation should only be needed when the faces are not planar.

On Mon, 17 Dec 2018 at 00:54, Parkinbot rudolf@digitaldocument.de wrote:

Clearly, CGAL is only called when a Boolean operation is present. Thus the
polyset to nef_polyhreda conversion is not necessary for primitives like a
polyhedron and can't be displayed.
When CGAL is called, it seems to try to reduce faces.

Nevertheless there is a tesselation of polygon with holes for F5 and this
one could be exposed to the user.

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


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

Yes but I don't think tessalation is the issue with polyhedron. The problem seems to be the interface to polyhedron has no way to express holes. It could detect faces that are coplanar with an encolsing face pass them through clipper to sort out the holes. Or it could allow the keyhole contruction, detect the loops and remove the extra edges between loops. So each face becomes a list of loops with counter clockwise ones being holes. Tessalation should only be needed when the faces are not planar. On Mon, 17 Dec 2018 at 00:54, Parkinbot <rudolf@digitaldocument.de> wrote: > Clearly, CGAL is only called when a Boolean operation is present. Thus the > polyset to nef_polyhreda conversion is not necessary for primitives like a > polyhedron and can't be displayed. > When CGAL is called, it seems to try to reduce faces. > > Nevertheless there is a tesselation of polygon with holes for F5 and this > one could be exposed to the user. > > > > -- > Sent from: http://forum.openscad.org/ > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
P
Parkinbot
Mon, Dec 17, 2018 10:13 AM

If there is a tesselation, a sweep with more than one hole can be
implemented. Wasn't this at least part the aim?

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

If there is a tesselation, a sweep with more than one hole can be implemented. Wasn't this at least part the aim? -- Sent from: http://forum.openscad.org/
NH
nop head
Mon, Dec 17, 2018 10:23 AM

I don't understand why you think it needs tesselation to represent a
polygonal face with holes in it. OpenSCAD can handle such faces no problem
and tesselates them when triangles are required, such as for STL export.
The issue is that polyhedron can't create faces with holes. It nearly can
with the keyhole method but they are not acceptable to CGAL in that format
as they are not manifold. Simply removing the connections between loops and
ensuring the correct winding order should fix that.

On Mon, 17 Dec 2018 at 10:13, Parkinbot rudolf@digitaldocument.de wrote:

If there is a tesselation, a sweep with more than one hole can be
implemented. Wasn't this at least part the aim?

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


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

I don't understand why you think it needs tesselation to represent a polygonal face with holes in it. OpenSCAD can handle such faces no problem and tesselates them when triangles are required, such as for STL export. The issue is that polyhedron can't create faces with holes. It nearly can with the keyhole method but they are not acceptable to CGAL in that format as they are not manifold. Simply removing the connections between loops and ensuring the correct winding order should fix that. On Mon, 17 Dec 2018 at 10:13, Parkinbot <rudolf@digitaldocument.de> wrote: > If there is a tesselation, a sweep with more than one hole can be > implemented. Wasn't this at least part the aim? > > > > -- > Sent from: http://forum.openscad.org/ > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
P
Parkinbot
Mon, Dec 17, 2018 12:17 PM

nophead wrote

I don't understand why you think it needs tesselation to represent a
polygonal face with holes in it. OpenSCAD can handle such faces no problem
and tesselates them when triangles are required, such as for STL export.
The issue is that polyhedron can't create faces with holes.

The target of a sweep is a polyhedron. For this it interprets a vector of
polygons. The first polygon in this vector defines the starting face, and
the last the end face. Any two consecutive polygons define a piece of wall.

If I have a function that I can use to tesselate the first and last faces, I
can implement a sweep for any tube-like structures with holes, because it is
easy for me to find holes in polygons, but very expensive to implement an
earcut with holes for 2D-polygons.

Alternatively polyhedron could allow me to use (planar) faces with holes. In
this case, polyhedron could use internally the same function that a
linear_extrude obviously uses, when it extrudes a polygon with holes. BUT: I
don't see this coming soon, because it requires a tesselation of almost
planar faces in 3D. To use the suspected given 2D tesselation, the
implementation could employ some coordinate transformation like I just
presented in the other  thread
http://forum.openscad.org/Rotation-question-tp24970p24992.html  , then
project the almost planar face down to xy, and finally find the tesselation
by calling this ominous function. The problem of the "almost planar" will
stay. How will you define it? How much deviation will be allowed. How will
an "alternative construction" work?

However, even if polyhedron will accept polygons with holes some day, it
would be a nice-to-have, to get an explicite tesselation of a polygon with
holes from a built-in OpenSCAD function, just like cross() and norm()
operate over a list of numbers.

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

nophead wrote > I don't understand why you think it needs tesselation to represent a > polygonal face with holes in it. OpenSCAD can handle such faces no problem > and tesselates them when triangles are required, such as for STL export. > The issue is that polyhedron can't create faces with holes. The target of a sweep is a polyhedron. For this it interprets a vector of polygons. The first polygon in this vector defines the starting face, and the last the end face. Any two consecutive polygons define a piece of wall. If I have a function that I can use to tesselate the first and last faces, I can implement a sweep for any tube-like structures with holes, because it is easy for me to find holes in polygons, but very expensive to implement an earcut with holes for 2D-polygons. Alternatively polyhedron could allow me to use (planar) faces with holes. In this case, polyhedron could use internally the same function that a linear_extrude obviously uses, when it extrudes a polygon with holes. BUT: I don't see this coming soon, because it requires a tesselation of almost planar faces in 3D. To use the suspected given 2D tesselation, the implementation could employ some coordinate transformation like I just presented in the other thread <http://forum.openscad.org/Rotation-question-tp24970p24992.html> , then project the almost planar face down to xy, and finally find the tesselation by calling this ominous function. The problem of the "almost planar" will stay. How will you define it? How much deviation will be allowed. How will an "alternative construction" work? However, even if polyhedron will accept polygons with holes some day, it would be a nice-to-have, to get an explicite tesselation of a polygon with holes from a built-in OpenSCAD function, just like cross() and norm() operate over a list of numbers. -- Sent from: http://forum.openscad.org/
P
Parkinbot
Mon, Dec 17, 2018 12:36 PM

nophead wrote

It nearly can with the keyhole method but they are not acceptable to CGAL
in that format
as they are not manifold. Simply removing the connections between loops
and
ensuring the correct winding order should fix that.

This would imply that linear_extrude will not have to recourse to a
tesselation for F5. There is a lot change of involved.

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

nophead wrote > It nearly can with the keyhole method but they are not acceptable to CGAL > in that format > as they are not manifold. Simply removing the connections between loops > and > ensuring the correct winding order should fix that. This would imply that linear_extrude will not have to recourse to a tesselation for F5. There is a lot change of involved. -- Sent from: http://forum.openscad.org/
P
Parkinbot
Mon, Dec 17, 2018 1:00 PM

see what happens to an almost planar face created by an rotate_extrude.
http://forum.openscad.org/file/t887/rot.png

rotate_extrude(angle = 160)
{
translate([10, 0])
difference()
{
square(10, center = true);
square(5, center = true);
}
}
cube(1);

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

see what happens to an almost planar face created by an rotate_extrude. <http://forum.openscad.org/file/t887/rot.png> rotate_extrude(angle = 160) { translate([10, 0]) difference() { square(10, center = true); square(5, center = true); } } cube(1); -- Sent from: http://forum.openscad.org/
NH
nop head
Mon, Dec 17, 2018 2:01 PM

This would imply that linear_extrude will not have to recourse to a

tesselation for F5.
I don't understand why. I am not proposing any changes to linear_extrude.

Anyway it appears that polyhedron will accept faces with holes if they are
tesselated correctly by the user. I exported your curved tube as STL and
then converted it to a polyhedron with this website:
https://jsfiddle.net/Riham/yzvGD/
The result is all triangles but CGAL converts all the planar faces back to
polygons. Only the rotated end face remains partly triangulated due to
floating point inacuracies. I.e. converting it to STL and back has improved
the last segment!

[image: image.png]

On Mon, 17 Dec 2018 at 13:01, Parkinbot rudolf@digitaldocument.de wrote:

see what happens to an almost planar face created by an rotate_extrude.
http://forum.openscad.org/file/t887/rot.png

rotate_extrude(angle = 160)
{
translate([10, 0])
difference()
{
square(10, center = true);
square(5, center = true);
}
}
cube(1);

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


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

> This would imply that linear_extrude will not have to recourse to a tesselation for F5. I don't understand why. I am not proposing any changes to linear_extrude. Anyway it appears that polyhedron will accept faces with holes if they are tesselated correctly by the user. I exported your curved tube as STL and then converted it to a polyhedron with this website: https://jsfiddle.net/Riham/yzvGD/ The result is all triangles but CGAL converts all the planar faces back to polygons. Only the rotated end face remains partly triangulated due to floating point inacuracies. I.e. converting it to STL and back has improved the last segment! [image: image.png] On Mon, 17 Dec 2018 at 13:01, Parkinbot <rudolf@digitaldocument.de> wrote: > see what happens to an almost planar face created by an rotate_extrude. > <http://forum.openscad.org/file/t887/rot.png> > > > rotate_extrude(angle = 160) > { > translate([10, 0]) > difference() > { > square(10, center = true); > square(5, center = true); > } > } > cube(1); > > > > > > -- > Sent from: http://forum.openscad.org/ > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
NH
nop head
Mon, Dec 17, 2018 2:08 PM

Oddly F5 triangulates everything except the sqquare faces of the cube. I
noticed with a sphere F5 does everything except the polar caps, they remain
polygons, wierd!

[image: image.png]

On Mon, 17 Dec 2018 at 14:01, nop head nop.head@gmail.com wrote:

This would imply that linear_extrude will not have to recourse to a

tesselation for F5.
I don't understand why. I am not proposing any changes to linear_extrude.

Anyway it appears that polyhedron will accept faces with holes if they are
tesselated correctly by the user. I exported your curved tube as STL and
then converted it to a polyhedron with this website:
https://jsfiddle.net/Riham/yzvGD/
The result is all triangles but CGAL converts all the planar faces back to
polygons. Only the rotated end face remains partly triangulated due to
floating point inacuracies. I.e. converting it to STL and back has improved
the last segment!

[image: image.png]

On Mon, 17 Dec 2018 at 13:01, Parkinbot rudolf@digitaldocument.de wrote:

see what happens to an almost planar face created by an rotate_extrude.
http://forum.openscad.org/file/t887/rot.png

rotate_extrude(angle = 160)
{
translate([10, 0])
difference()
{
square(10, center = true);
square(5, center = true);
}
}
cube(1);

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


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

Oddly F5 triangulates everything except the sqquare faces of the cube. I noticed with a sphere F5 does everything except the polar caps, they remain polygons, wierd! [image: image.png] On Mon, 17 Dec 2018 at 14:01, nop head <nop.head@gmail.com> wrote: > > This would imply that linear_extrude will not have to recourse to a > tesselation for F5. > I don't understand why. I am not proposing any changes to linear_extrude. > > Anyway it appears that polyhedron will accept faces with holes if they are > tesselated correctly by the user. I exported your curved tube as STL and > then converted it to a polyhedron with this website: > https://jsfiddle.net/Riham/yzvGD/ > The result is all triangles but CGAL converts all the planar faces back to > polygons. Only the rotated end face remains partly triangulated due to > floating point inacuracies. I.e. converting it to STL and back has improved > the last segment! > > [image: image.png] > > > > > > > > On Mon, 17 Dec 2018 at 13:01, Parkinbot <rudolf@digitaldocument.de> wrote: > >> see what happens to an almost planar face created by an rotate_extrude. >> <http://forum.openscad.org/file/t887/rot.png> >> >> >> rotate_extrude(angle = 160) >> { >> translate([10, 0]) >> difference() >> { >> square(10, center = true); >> square(5, center = true); >> } >> } >> cube(1); >> >> >> >> >> >> -- >> Sent from: http://forum.openscad.org/ >> >> _______________________________________________ >> OpenSCAD mailing list >> Discuss@lists.openscad.org >> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >> >
P
Parkinbot
Mon, Dec 17, 2018 2:51 PM

CGAL anyway tesselates and retesselates faces on its will. linear_extrude()
and rotate_extrude() obviously don't use more complex faces respectively use
tesselation. Even sphere and cylinder at least for cones (r1, r2) construct
their faces mostly with triags and not with quads. What, beside a bunch of
options for implementation changes, would you gain by improving polyhedron()
to accept this kind of polygons with holes?

nophead wrote

Oddly F5 triangulates everything except the sqquare faces of the cube. I
noticed with a sphere F5 does everything except the polar caps, they
remain
polygons, wierd!

now look at this. I feed two bending faces defined by "almost planar"
polygons into a sweep. The two faces have a phase shift of 0 and 90 degrees.
Since I rely on the internal tesselation, I have to live with the result.
The upper face is a saddle, the lower face a sinus. (Knowing, what OpenSCAD
will probably do, I could of course change my construction code.)

use <Naca_sweep.scad>
sweep([circle(), Tz_(10, circle())]);
function circle(r = 10, N=100, z=3) =
[for(i=[0:N-1])  [rsin(360/Ni), rcos(360/Ni), zcos(360/Ni*2)]];
cube(1);
http://forum.openscad.org/file/t887/sweep.png

Now you can say. Ok, we allow even for polygons that describe bent faces.
And in the second step, lets also allow faces that close into a ring (or
even to moebius) ... See what I mean? I would prefer to be able to put a
tesselation of my choice into a sweep.

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

CGAL anyway tesselates and retesselates faces on its will. linear_extrude() and rotate_extrude() obviously don't use more complex faces respectively use tesselation. Even sphere and cylinder at least for cones (r1, r2) construct their faces mostly with triags and not with quads. What, beside a bunch of options for implementation changes, would you gain by improving polyhedron() to accept this kind of polygons with holes? nophead wrote > Oddly F5 triangulates everything except the sqquare faces of the cube. I > noticed with a sphere F5 does everything except the polar caps, they > remain > polygons, wierd! now look at this. I feed two bending faces defined by "almost planar" polygons into a sweep. The two faces have a phase shift of 0 and 90 degrees. Since I rely on the internal tesselation, I have to live with the result. The upper face is a saddle, the lower face a sinus. (Knowing, what OpenSCAD will probably do, I could of course change my construction code.) use <Naca_sweep.scad> sweep([circle(), Tz_(10, circle())]); function circle(r = 10, N=100, z=3) = [for(i=[0:N-1]) [r*sin(360/N*i), r*cos(360/N*i), z*cos(360/N*i*2)]]; cube(1); <http://forum.openscad.org/file/t887/sweep.png> Now you can say. Ok, we allow even for polygons that describe bent faces. And in the second step, lets also allow faces that close into a ring (or even to moebius) ... See what I mean? I would prefer to be able to put a tesselation of my choice into a sweep. -- Sent from: http://forum.openscad.org/
P
Parkinbot
Mon, Dec 17, 2018 3:03 PM

sorry I didn't sync the code with the image. This is the code:

use <Naca_sweep.scad>

sweep([circle(), Tz_(10, circle(phi = 90))]);
function circle(r = 10, N=100, z=3, phi=0) =
[for(i=[0:N-1])  [rsin(360/Ni), rcos(360/Ni), zcos(360/Ni*2+phi)]];

cube(1);

Parkinbot wrote

use
<Naca_sweep.scad>
sweep([circle(), Tz_(10, circle())]);
function circle(r = 10, N=100, z=3) =
[for(i=[0:N-1])  [rsin(360/Ni), rcos(360/Ni), zcos(360/Ni*2)]];
cube(1);
<http://forum.openscad.org/file/t887/sweep.png>

sorry I didn't sync the code with the image. This is the code: use <Naca_sweep.scad> sweep([circle(), Tz_(10, circle(phi = 90))]); function circle(r = 10, N=100, z=3, phi=0) = [for(i=[0:N-1]) [r*sin(360/N*i), r*cos(360/N*i), z*cos(360/N*i*2+phi)]]; cube(1); Parkinbot wrote > use > <Naca_sweep.scad> > sweep([circle(), Tz_(10, circle())]); > function circle(r = 10, N=100, z=3) = > [for(i=[0:N-1]) [r*sin(360/N*i), r*cos(360/N*i), z*cos(360/N*i*2)]]; > cube(1); > &lt;http://forum.openscad.org/file/t887/sweep.png&gt; -- Sent from: http://forum.openscad.org/
NH
nop head
Mon, Dec 17, 2018 3:18 PM

would you gain by improving polyhedron() to accept this kind of polygons

with holes?
It is a lot easier to define faces as polygons than it is to tesselate in
user space and feed a lot of triangles to polyhedron, mainly for endcaps,
particialarly with holes.

I agree an OpenSCAD tessalation operation available to the user would also
enable this but since the tesselation gets thrown way and regenerated many
times in OpenSCAD people might complain their tessalation was ignored.

I find the tesselation linear_extrude does ugly in some situations with
twist, e.g. fan blades. I fix it by adding more points along the blade that
are slight purturbed to force more facets and hence the tessalation I want.

module squarish(s, n) {
polygon([
for(i = [0 : n]) [i * s.x / n,  s.y + (i % 2) * eps],
for(i = [0 : n]) [s.x - i * s.x / n, (i % 2) * eps],
]);
}
I think making OpenSCAD preserve tesselation would be an enourmous job
while it use CGAL but fixing polyhedron is a small isolated changed.

On Mon, 17 Dec 2018 at 14:52, Parkinbot rudolf@digitaldocument.de wrote:

CGAL anyway tesselates and retesselates faces on its will. linear_extrude()
and rotate_extrude() obviously don't use more complex faces respectively
use
tesselation. Even sphere and cylinder at least for cones (r1, r2) construct
their faces mostly with triags and not with quads. What, beside a bunch of
options for implementation changes, would you gain by improving
polyhedron()
to accept this kind of polygons with holes?

nophead wrote

Oddly F5 triangulates everything except the sqquare faces of the cube. I
noticed with a sphere F5 does everything except the polar caps, they
remain
polygons, wierd!

now look at this. I feed two bending faces defined by "almost planar"
polygons into a sweep. The two faces have a phase shift of 0 and 90
degrees.
Since I rely on the internal tesselation, I have to live with the result.
The upper face is a saddle, the lower face a sinus. (Knowing, what OpenSCAD
will probably do, I could of course change my construction code.)

use <Naca_sweep.scad>
sweep([circle(), Tz_(10, circle())]);
function circle(r = 10, N=100, z=3) =
[for(i=[0:N-1])  [rsin(360/Ni), rcos(360/Ni), zcos(360/Ni*2)]];
cube(1);
http://forum.openscad.org/file/t887/sweep.png

Now you can say. Ok, we allow even for polygons that describe bent faces.
And in the second step, lets also allow faces that close into a ring (or
even to moebius) ... See what I mean? I would prefer to be able to put a
tesselation of my choice into a sweep.

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


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

> would you gain by improving polyhedron() to accept this kind of polygons with holes? It is a lot easier to define faces as polygons than it is to tesselate in user space and feed a lot of triangles to polyhedron, mainly for endcaps, particialarly with holes. I agree an OpenSCAD tessalation operation available to the user would also enable this but since the tesselation gets thrown way and regenerated many times in OpenSCAD people might complain their tessalation was ignored. I find the tesselation linear_extrude does ugly in some situations with twist, e.g. fan blades. I fix it by adding more points along the blade that are slight purturbed to force more facets and hence the tessalation I want. module squarish(s, n) { polygon([ for(i = [0 : n]) [i * s.x / n, s.y + (i % 2) * eps], for(i = [0 : n]) [s.x - i * s.x / n, (i % 2) * eps], ]); } I think making OpenSCAD preserve tesselation would be an enourmous job while it use CGAL but fixing polyhedron is a small isolated changed. On Mon, 17 Dec 2018 at 14:52, Parkinbot <rudolf@digitaldocument.de> wrote: > CGAL anyway tesselates and retesselates faces on its will. linear_extrude() > and rotate_extrude() obviously don't use more complex faces respectively > use > tesselation. Even sphere and cylinder at least for cones (r1, r2) construct > their faces mostly with triags and not with quads. What, beside a bunch of > options for implementation changes, would you gain by improving > polyhedron() > to accept this kind of polygons with holes? > > > nophead wrote > > Oddly F5 triangulates everything except the sqquare faces of the cube. I > > noticed with a sphere F5 does everything except the polar caps, they > > remain > > polygons, wierd! > > now look at this. I feed two bending faces defined by "almost planar" > polygons into a sweep. The two faces have a phase shift of 0 and 90 > degrees. > Since I rely on the internal tesselation, I have to live with the result. > The upper face is a saddle, the lower face a sinus. (Knowing, what OpenSCAD > will probably do, I could of course change my construction code.) > > use <Naca_sweep.scad> > sweep([circle(), Tz_(10, circle())]); > function circle(r = 10, N=100, z=3) = > [for(i=[0:N-1]) [r*sin(360/N*i), r*cos(360/N*i), z*cos(360/N*i*2)]]; > cube(1); > <http://forum.openscad.org/file/t887/sweep.png> > > > Now you can say. Ok, we allow even for polygons that describe bent faces. > And in the second step, lets also allow faces that close into a ring (or > even to moebius) ... See what I mean? I would prefer to be able to put a > tesselation of my choice into a sweep. > > > > > > -- > Sent from: http://forum.openscad.org/ > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
P
Parkinbot
Mon, Dec 17, 2018 3:24 PM

And another interesting observation:

The iron law to do a sweep() is: Avoid (self) intersection of faces at any
cost. This doesn't seem to apply for intersecting bending faces. While F12
announces a failure, CGAL seems to happily digest it:

use <Naca_sweep.scad>
sweep([circle(), Tz_(5, circle(phi = 180))]);
function circle(r = 10, N=100, z=3, phi=0) =
[for(i=[0:N-1])  [rsin(360/Ni), rcos(360/Ni), zcos(360/Ni*2+phi)]];
cube(1);

http://forum.openscad.org/file/t887/sweep.png

Will this open the path for a representation that lets us ignore (self)
intersections?

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

And another interesting observation: The iron law to do a sweep() is: Avoid (self) intersection of faces at any cost. This doesn't seem to apply for intersecting bending faces. While F12 announces a failure, CGAL seems to happily digest it: use <Naca_sweep.scad> sweep([circle(), Tz_(5, circle(phi = 180))]); function circle(r = 10, N=100, z=3, phi=0) = [for(i=[0:N-1]) [r*sin(360/N*i), r*cos(360/N*i), z*cos(360/N*i*2+phi)]]; cube(1); <http://forum.openscad.org/file/t887/sweep.png> Will this open the path for a representation that lets us ignore (self) intersections? -- Sent from: http://forum.openscad.org/
NH
nop head
Mon, Dec 17, 2018 3:31 PM

Odd CGAL normally throws an exception. Perhaps it gets past if no vertices
colide.

Does it say simple is yes and can you export it to STL?

On Mon, 17 Dec 2018 at 15:24, Parkinbot rudolf@digitaldocument.de wrote:

And another interesting observation:

The iron law to do a sweep() is: Avoid (self) intersection of faces at any
cost. This doesn't seem to apply for intersecting bending faces. While F12
announces a failure, CGAL seems to happily digest it:

use <Naca_sweep.scad>
sweep([circle(), Tz_(5, circle(phi = 180))]);
function circle(r = 10, N=100, z=3, phi=0) =
[for(i=[0:N-1])  [rsin(360/Ni), rcos(360/Ni), zcos(360/Ni*2+phi)]];
cube(1);

http://forum.openscad.org/file/t887/sweep.png

Will this open the path for a representation that lets us ignore (self)
intersections?

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


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

Odd CGAL normally throws an exception. Perhaps it gets past if no vertices colide. Does it say simple is yes and can you export it to STL? On Mon, 17 Dec 2018 at 15:24, Parkinbot <rudolf@digitaldocument.de> wrote: > And another interesting observation: > > The iron law to do a sweep() is: Avoid (self) intersection of faces at any > cost. This doesn't seem to apply for intersecting bending faces. While F12 > announces a failure, CGAL seems to happily digest it: > > use <Naca_sweep.scad> > sweep([circle(), Tz_(5, circle(phi = 180))]); > function circle(r = 10, N=100, z=3, phi=0) = > [for(i=[0:N-1]) [r*sin(360/N*i), r*cos(360/N*i), z*cos(360/N*i*2+phi)]]; > cube(1); > > <http://forum.openscad.org/file/t887/sweep.png> > > Will this open the path for a representation that lets us ignore (self) > intersections? > > > > -- > Sent from: http://forum.openscad.org/ > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
P
Parkinbot
Mon, Dec 17, 2018 3:38 PM

I can export it to STL and import it again without any problems.

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

I can export it to STL and import it again without any problems. -- Sent from: http://forum.openscad.org/
NH
nop head
Mon, Dec 17, 2018 3:42 PM

So possibly self intersecting is fine as long as vertices don't coincide.
The topology is prerved through triangle soup when the vertices are all
unique.

On Mon, 17 Dec 2018 at 15:39, Parkinbot rudolf@digitaldocument.de wrote:

I can export it to STL and import it again without any problems.

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


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

So possibly self intersecting is fine as long as vertices don't coincide. The topology is prerved through triangle soup when the vertices are all unique. On Mon, 17 Dec 2018 at 15:39, Parkinbot <rudolf@digitaldocument.de> wrote: > I can export it to STL and import it again without any problems. > > > > -- > Sent from: http://forum.openscad.org/ > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
P
Parkinbot
Mon, Dec 17, 2018 3:43 PM

it is even getting wierder and wierder:

http://forum.openscad.org/file/t887/sweep.png

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

it is even getting wierder and wierder: <http://forum.openscad.org/file/t887/sweep.png> -- Sent from: http://forum.openscad.org/
RP
Ronaldo Persiano
Mon, Dec 17, 2018 4:25 PM

Does it allow boolean operations???

Parkinbot rudolf@digitaldocument.de wrote:

it is even getting wierder and wierder:

Does it allow boolean operations??? Parkinbot <rudolf@digitaldocument.de> wrote: > it is even getting wierder and wierder: >
P
Parkinbot
Mon, Dec 17, 2018 4:33 PM

Ronaldo wrote

Does it allow boolean operations???

Yes, otherwise F10 wouldn't display a tesselation. Look at the code:

use <Naca_sweep.scad>
sweep([circle(), Tx_(3, circle(phi = 180))]);
function circle(r = 10, N=100, z=3, phi=0) =
[for(i=[0:N-1])  [rsin(360/Ni), rcos(360/Ni), zcos(360/Ni*2+phi)]];
cube(1);

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

Ronaldo wrote > Does it allow boolean operations??? Yes, otherwise F10 wouldn't display a tesselation. Look at the code: use <Naca_sweep.scad> sweep([circle(), Tx_(3, circle(phi = 180))]); function circle(r = 10, N=100, z=3, phi=0) = [for(i=[0:N-1]) [r*sin(360/N*i), r*cos(360/N*i), z*cos(360/N*i*2+phi)]]; cube(1); -- Sent from: http://forum.openscad.org/
RP
Ronaldo Persiano
Tue, Dec 18, 2018 3:44 PM

Yes, I have observed before that a non-manifold polyhedron may be rendered.
The union of the cube with your shape renders without error unless the cube
intersect some self intersection areas of the shape. Try your example with
cube(16), for instance. You will get a CGAL error. And even when the cube
contains all your shape a CGAL error is issued. A strange shape (that
resembles to be a difference) results without error with cube(6).

Yes, I have observed before that a non-manifold polyhedron may be rendered. The union of the cube with your shape renders without error unless the cube intersect some self intersection areas of the shape. Try your example with cube(16), for instance. You will get a CGAL error. And even when the cube contains all your shape a CGAL error is issued. A strange shape (that resembles to be a difference) results without error with cube(6). > >
RP
Ronaldo Persiano
Mon, Jan 7, 2019 2:09 PM

Em seg, 10 de dez de 2018 às 20:07, Parkinbot rudolf@digitaldocument.de
escreveu:

A triangulation like earcut with holes will be cumbersome to implement in
OpenSCAD. However a fast and viable solution for implementing the
multi-hole
sweep is to use a vectorized lazy union sweep for the holes and difference
the result from the sweep of the outer polygon. For export one will have to
use a Boolean operation to do a CGAL check anyway.

Parkinbot,

The earcut method works fine with polygons with holes expressed as a unique
polygonal by bridging the holes and outer polygon by two-way bridges fully
inside the polygon interior. We just need to relax the ear test by
restricting it to the candidate ear interior. I have tested it with my
implementation of the ear method and it worked like a charm.

The remaining problem is to find the two-way bridges that connect all the
borders. The bridges in the runsun example are not allowed because they
cross other polygonal edges. I have found a paper (
https://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf)
that proposes a method to find those bridges. I have implemented the method
with good results. Here are two of them:

[image: PolyHoles2.PNG]
[image: PolyHoles1.PNG]

Find attached my implementation of the bridging method.

Em seg, 10 de dez de 2018 às 20:07, Parkinbot <rudolf@digitaldocument.de> escreveu: > A triangulation like earcut with holes will be cumbersome to implement in > OpenSCAD. However a fast and viable solution for implementing the > multi-hole > sweep is to use a vectorized lazy union sweep for the holes and difference > the result from the sweep of the outer polygon. For export one will have to > use a Boolean operation to do a CGAL check anyway. > > Parkinbot, The earcut method works fine with polygons with holes expressed as a unique polygonal by bridging the holes and outer polygon by two-way bridges fully inside the polygon interior. We just need to relax the ear test by restricting it to the candidate ear interior. I have tested it with my implementation of the ear method and it worked like a charm. The remaining problem is to find the two-way bridges that connect all the borders. The bridges in the runsun example are not allowed because they cross other polygonal edges. I have found a paper ( https://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf) that proposes a method to find those bridges. I have implemented the method with good results. Here are two of them: [image: PolyHoles2.PNG] [image: PolyHoles1.PNG] Find attached my implementation of the bridging method.
P
Parkinbot
Wed, Jan 9, 2019 12:45 PM

Ronaldo,

thanks, this sounds like a progress. Although the no cross restriction will
be difficult to guarantee in general when defining such a polygon, it seems
to be a step forward to implementing a fast multi-hole sweep like for
regular grids with fancy holes as shown in the example code attached. But to
be honest, meanwhile I dislike the implicitness of this representation. When
adding a new hole to a given object one will have to alter the whole polygon
sequence. This is very clumsy and makes me prefer the solution I already
characterized:

Parkinbot wrote

However a fast and viable solution for implementing the multi-hole
sweep is to use a vectorized lazy union sweep for the holes and difference
the result from the sweep of the outer polygon. For export one will have
to
use a Boolean operation to do a CGAL check anyway.

While this approach is a bit slower, it addresses an even larger class of
problems, since the multi-holes may even leave the outer body during the
sweep - which relaxes the no-mutual-intersection rule a bit. And it is easy
to add a new hole, because you just extend the vector describing the holes.

Nevertheless, if OpenSCAD offered a built-in lazy_union() operator, we
wouldn't have to discuss such things at all.

difference()
{
cube([100, 100, 5], center = true);
forXY(10, 10, 10, 10)
linear_extrude(5.01, center = true, twist=45, slices = 20)
square(6, center= true);
}

module forX(dx = 10, N=4) for($i=[0:N-1]) translate([-((N-1)/2-$i)*dx,0, 0])
children();
module forY(dy = 10, M=4) for($i=[0:M-1]) translate([0, -((M-1)/2-$i)*dy])
children();
module forXY(dx = 10, N=4, dy = 10, M=4) forX(dx, N) forY(dy, M) children();

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

Ronaldo, thanks, this sounds like a progress. Although the no cross restriction will be difficult to guarantee in general when defining such a polygon, it seems to be a step forward to implementing a fast multi-hole sweep like for regular grids with fancy holes as shown in the example code attached. But to be honest, meanwhile I dislike the implicitness of this representation. When adding a new hole to a given object one will have to alter the whole polygon sequence. This is very clumsy and makes me prefer the solution I already characterized: Parkinbot wrote > However a fast and viable solution for implementing the multi-hole > sweep is to use a vectorized lazy union sweep for the holes and difference > the result from the sweep of the outer polygon. For export one will have > to > use a Boolean operation to do a CGAL check anyway. While this approach is a bit slower, it addresses an even larger class of problems, since the multi-holes may even leave the outer body during the sweep - which relaxes the no-mutual-intersection rule a bit. And it is easy to add a new hole, because you just extend the vector describing the holes. Nevertheless, if OpenSCAD offered a built-in lazy_union() operator, we wouldn't have to discuss such things at all. difference() { cube([100, 100, 5], center = true); forXY(10, 10, 10, 10) linear_extrude(5.01, center = true, twist=45, slices = 20) square(6, center= true); } module forX(dx = 10, N=4) for($i=[0:N-1]) translate([-((N-1)/2-$i)*dx,0, 0]) children(); module forY(dy = 10, M=4) for($i=[0:M-1]) translate([0, -((M-1)/2-$i)*dy]) children(); module forXY(dx = 10, N=4, dy = 10, M=4) forX(dx, N) forY(dy, M) children(); -- Sent from: http://forum.openscad.org/
RP
Ronaldo Persiano
Wed, Jan 9, 2019 3:54 PM

Em qua, 9 de jan de 2019 às 12:45, Parkinbot rudolf@digitaldocument.de
escreveu:

But to
be honest, meanwhile I dislike the implicitness of this representation.
When
adding a new hole to a given object one will have to alter the whole
polygon
sequence. This is very clumsy and makes me prefer the solution I already
characterized:

I understand your point but I see a very simple and general way to overcome
it.

Suppose we have a lazyUnion operator with the following header:

module lazyUnion(<list of objects>)

where the objects in the parameter list are given in a polyhedron data
format, that is, a pair of vertex list and face list. This module is easy
to be coded by:

  1. concat in one list all vertices of all objects;
  2. displace (by a fixed amount) the indices of the face list of an object
    to agree with the new order of the concatenated vertex list;
  3. call polyhedron with the new vertex list and the concat of the updated
    face list.

Usually we think to lazy-union manifold objects but this may be generalized
to lazy-union a set of surfaces that will enclose one (or many) manifold.
Surely, we need to assure manifoldness of the result to have a proper
object for CGAL. The ground of this generalization is that OpenSCAD
aggregates multiple vertices with the same coordinates as one vertex as I
mentioned 2 years ago (
http://forum.openscad.org/Can-you-sweep-a-object-with-fingers-tp19057p19203.html
).

With that in mind, the sweep of a polygon with holes may be structured as:
a) individually sweep each polygonal border of the outer polygon and of the
holes without their caps returning the result in a polyhedron data format
(a simplification of the current sweep codes);
b) triangulate the sweep ends of polygons with holes and generate its
result in a polyhedron data format;
c) call lazyUnion with the list of the above data.

As a final touch, each function which generates polyhedron data format
should have an additional parameter to promote, when needed, the reversion
of all its faces. This parameter, with default false, may be set true when
a Thrown Together view shows an incorrect orientation of that surface.

lazyUnion thought as such has many other uses as the reference I gave above
illustrates.

When facing cases where the swept holes leak out the outer sweep, then uses
the slower boolean method.

Em qua, 9 de jan de 2019 às 12:45, Parkinbot <rudolf@digitaldocument.de> escreveu: > But to > be honest, meanwhile I dislike the implicitness of this representation. > When > adding a new hole to a given object one will have to alter the whole > polygon > sequence. This is very clumsy and makes me prefer the solution I already > characterized: > I understand your point but I see a very simple and general way to overcome it. Suppose we have a lazyUnion operator with the following header: module lazyUnion(<list of objects>) where the objects in the parameter list are given in a polyhedron data format, that is, a pair of vertex list and face list. This module is easy to be coded by: 1) concat in one list all vertices of all objects; 2) displace (by a fixed amount) the indices of the face list of an object to agree with the new order of the concatenated vertex list; 3) call polyhedron with the new vertex list and the concat of the updated face list. Usually we think to lazy-union manifold objects but this may be generalized to lazy-union a set of surfaces that will enclose one (or many) manifold. Surely, we need to assure manifoldness of the result to have a proper object for CGAL. The ground of this generalization is that OpenSCAD aggregates multiple vertices with the same coordinates as one vertex as I mentioned 2 years ago ( http://forum.openscad.org/Can-you-sweep-a-object-with-fingers-tp19057p19203.html ). With that in mind, the sweep of a polygon with holes may be structured as: a) individually sweep each polygonal border of the outer polygon and of the holes without their caps returning the result in a polyhedron data format (a simplification of the current sweep codes); b) triangulate the sweep ends of polygons with holes and generate its result in a polyhedron data format; c) call lazyUnion with the list of the above data. As a final touch, each function which generates polyhedron data format should have an additional parameter to promote, when needed, the reversion of all its faces. This parameter, with default false, may be set true when a Thrown Together view shows an incorrect orientation of that surface. lazyUnion thought as such has many other uses as the reference I gave above illustrates. When facing cases where the swept holes leak out the outer sweep, then uses the slower boolean method.
P
Parkinbot
Wed, Jan 9, 2019 5:44 PM

Ronaldo

you are right, changing the representation is a typical interface task and
can be easily done within sweep() and transparent to the user.
Collect the first and last faces of the outer manifold and the holes, find
the right polyHoles-polygon to represent it and then use earcut. The rest is
a vectorized sweep.
I haven't had time to play with your algorithm more extensively as I am
short of time being on travel until Sunday. Can you post the current version
of your earcut()? Don't find mine anymore.

I would propose the following interface to keep the "affine" state as long
as possible - and allow for the lazy union of multihole sweeps:

module sweepMH(manifolds)
{
prepdata = sweepMH(manifolds);
polyhedron(prepdata[0], prepdata[1]);
}

function sweepMH(manifolds) =
let(firstface = earcut(polyHole(manifolds)))
let(lastface = earcut(polyHole(manifolds, last=true))
...

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

Ronaldo you are right, changing the representation is a typical interface task and can be easily done within sweep() and transparent to the user. Collect the first and last faces of the outer manifold and the holes, find the right polyHoles-polygon to represent it and then use earcut. The rest is a vectorized sweep. I haven't had time to play with your algorithm more extensively as I am short of time being on travel until Sunday. Can you post the current version of your earcut()? Don't find mine anymore. I would propose the following interface to keep the "affine" state as long as possible - and allow for the lazy union of multihole sweeps: module sweepMH(manifolds) { prepdata = sweepMH(manifolds); polyhedron(prepdata[0], prepdata[1]); } function sweepMH(manifolds) = let(firstface = earcut(polyHole(manifolds))) let(lastface = earcut(polyHole(manifolds, last=true)) ... -- Sent from: http://forum.openscad.org/
RP
Ronaldo Persiano
Thu, Jan 10, 2019 5:03 PM

Parkinbot,

Find attached my last version of the polygon triangulation. I have reviewed
it converting recursions to iterations with C-like for in order to escape
the cycles early as possible. This version of the ear method is adapted to
polygons with two-way bridges. I have also a simple polygon check but it
rejects polygons with bridges. To accept polygon with bridges in that check
requires a whole new set of cumbersome tests. I don't like my
implementation of the check that resort to quick sort to make it somewhat
more efficient but if you want to try it, let me know. Another function
that you may consider, that is included in the same file of the simple
polygon test, is the plane fitting and projection to "flatten" almost
planar 3D polygons converting it in a 2D polygon before the triangulation
is called.

Both polygon triangulation and polygon with holes bridging methods fail if
they receive a non valid input. Without a proper validity check their use
is a blind fly.

Parkinbot, Find attached my last version of the polygon triangulation. I have reviewed it converting recursions to iterations with C-like for in order to escape the cycles early as possible. This version of the ear method is adapted to polygons with two-way bridges. I have also a simple polygon check but it rejects polygons with bridges. To accept polygon with bridges in that check requires a whole new set of cumbersome tests. I don't like my implementation of the check that resort to quick sort to make it somewhat more efficient but if you want to try it, let me know. Another function that you may consider, that is included in the same file of the simple polygon test, is the plane fitting and projection to "flatten" almost planar 3D polygons converting it in a 2D polygon before the triangulation is called. Both polygon triangulation and polygon with holes bridging methods fail if they receive a non valid input. Without a proper validity check their use is a blind fly.
RP
Ronaldo Persiano
Tue, Jan 15, 2019 3:31 AM

It is possible to manipulate the initial runsun model in such way the
polyhedron is acceptable by CGAL and faces with hole do not need to be
triangulated. If enough well placed bridges are added (the number of holes
plus one) a polygon with holes is split in two polygons meeting at the
bridges. The following example, based on the runsun model, illustrates the
principle.

pts = [[0, 0, 0], [0, 4, 0], [3, 5, 0], [2, 0, 0],
[0, 0, 2], [0, 4, 2], [3, 5, 2], [2, 0, 2],
[1, 0.5, 0], [0.4, 1.2, 0], [0.5, 2.1, 0], [2, 1.5, 0],
[1, 0.5, 2], [0.4, 1.2, 2], [0.5, 2.1, 2], [2, 1.5, 2],
[1.5, 2.5, 0], [0.5, 3.5, 0], [2, 3.5, 0],
[1.5, 2.5, 2], [0.5, 3.5, 2], [2, 3.5, 2]];

faces = [[7, 4, 5, 6, 21, 20, 19, 14, 13, 12],  // top blue
[7, 12, 15, 14, 19, 21, 6],            // top red
[3, 2, 18, 16, 10, 11],                // bottom red
[2, 1, 0, 3, 11, 8, 9, 10, 16, 17, 18], // bottom blue
[0, 1, 5, 4], [1, 2, 6, 5], [2, 3, 7, 6],
[3, 0, 4, 7], [9, 8, 12, 13], [10, 9, 13, 14],
[11, 10, 14, 15], [8, 11, 15, 12], [17, 16, 19, 20],
[18, 17, 20, 21], [16, 18, 21, 19]];

The following image of the polyhedron(pts, faces) enhances the top and
bottom partition:

[image: polyWithHoles.PNG]

Intentionally the top and bottom partitions are differents. Note that each
of the faces with holes has 3 bridges that are common to the two polygons
of the partition.

I guess the method I coded to find the bridges is O(m) where m is the
number of holes which is lot better than the triangulation methods. The
original method finds m bridges for m holes in the polygon. It may be
changed to find an additional bridge that split the face in two. I am
working on this now.

The image bellow shows the render of difference between the polyhedron and
a cube.

[image: polyRendered.PNG]

It is possible to manipulate the initial runsun model in such way the polyhedron is acceptable by CGAL and faces with hole do not need to be triangulated. If enough well placed bridges are added (the number of holes plus one) a polygon with holes is split in two polygons meeting at the bridges. The following example, based on the runsun model, illustrates the principle. pts = [[0, 0, 0], [0, 4, 0], [3, 5, 0], [2, 0, 0], [0, 0, 2], [0, 4, 2], [3, 5, 2], [2, 0, 2], [1, 0.5, 0], [0.4, 1.2, 0], [0.5, 2.1, 0], [2, 1.5, 0], [1, 0.5, 2], [0.4, 1.2, 2], [0.5, 2.1, 2], [2, 1.5, 2], [1.5, 2.5, 0], [0.5, 3.5, 0], [2, 3.5, 0], [1.5, 2.5, 2], [0.5, 3.5, 2], [2, 3.5, 2]]; faces = [[7, 4, 5, 6, 21, 20, 19, 14, 13, 12], // top blue [7, 12, 15, 14, 19, 21, 6], // top red [3, 2, 18, 16, 10, 11], // bottom red [2, 1, 0, 3, 11, 8, 9, 10, 16, 17, 18], // bottom blue [0, 1, 5, 4], [1, 2, 6, 5], [2, 3, 7, 6], [3, 0, 4, 7], [9, 8, 12, 13], [10, 9, 13, 14], [11, 10, 14, 15], [8, 11, 15, 12], [17, 16, 19, 20], [18, 17, 20, 21], [16, 18, 21, 19]]; The following image of the polyhedron(pts, faces) enhances the top and bottom partition: [image: polyWithHoles.PNG] Intentionally the top and bottom partitions are differents. Note that each of the faces with holes has 3 bridges that are common to the two polygons of the partition. I guess the method I coded to find the bridges is O(m) where m is the number of holes which is lot better than the triangulation methods. The original method finds m bridges for m holes in the polygon. It may be changed to find an additional bridge that split the face in two. I am working on this now. The image bellow shows the render of difference between the polyhedron and a cube. [image: polyRendered.PNG]
RP
Ronaldo Persiano
Tue, Jan 15, 2019 1:34 PM

Correction: my guess of the order of the bridging method was wrong; I meant
O(n.m) for m holes and n total number of vertices.

Correction: my guess of the order of the bridging method was wrong; I meant O(n.m) for m holes and n total number of vertices.
P
Parkinbot
Wed, Jan 16, 2019 10:47 PM

Ronaldo

first, thanks for the earcut. It works well.

I am also thrilled by your solution to decompose a face with holes into two
(or more?) faces without holes. This is definitely a good approach for
implementing a multihole sweep. Does your algorithm find such a
decomposition for an unlimited number of holes?

As I understand it, the proposed function sweepMH() will now be something
like:

function sweepMH(manifolds) =
let(firstfaces = decompose(polyHole(manifolds)))
let(lastfaces = decompose(polyHole(manifolds, last=true))
...

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

Ronaldo first, thanks for the earcut. It works well. I am also thrilled by your solution to decompose a face with holes into two (or more?) faces without holes. This is definitely a good approach for implementing a multihole sweep. Does your algorithm find such a decomposition for an unlimited number of holes? As I understand it, the proposed function sweepMH() will now be something like: function sweepMH(manifolds) = let(firstfaces = decompose(polyHole(manifolds))) let(lastfaces = decompose(polyHole(manifolds, last=true)) ... -- Sent from: http://forum.openscad.org/
RP
Ronaldo Persiano
Thu, Jan 17, 2019 12:11 PM

Parkinbot,

The polyHoles() code implements the David Eberly method of bridging a
polygon with (any number of) holes in order to apply his earcut
triangulation method  to the resulting (almost) simple polygon. The polygon
polyHoles() returns has no holes but is not really a simple polygon: some
edges of it are traveled twice as you traverse its full cycle. I call those
edges as (two-way) bridges. As CGAL doesn't like polyhedron faces with the
kind of polygons polyHoles produces, my proposal is to write an algorithm
based on the Eberly's one to partition a simple polygon with holes in
(really) simple polygons without holes.

In my last few messages, I have made a set of very naive conjectures about
this problem and its solving algorithm: 1) it is possible to partition the
original polygon with holes in exactly two parts, 2) this partition is done
by m+1 bridges and 3) the order of the solving method would be O(m.n) where
m is the number of holes and n is the total number of vertices. Those
conjectures  are in fact true for convex polygons with convex holes.

For convex holes but non-convex polygons, the number of necessary bridges
may be 2.m and the partition may have m+1 parts. For non-convex holes,
things become very wild! I don't have a guess for the number of parts in
the partition but the number of bridges may increase to something like 2^m
and the complexity grows to O( (2^m).n). Still, my expectancy is that this
approach would be better than triangulation.

I am still working on the method I have in mind to partition a polygon with
many holes in simple polygons without holes. To have a flavor of what would
result in a non-convex case consider the following image:

[image: Poly2holes.PNG]

The red bridges have been obtained by a direct application of
polyHoles(outer,mH). The yellow bridges result from the application of
polyHoles(-outer, -mH). Four bridges partition the original polygon in 3
parts. However, it is possible to partition it in 2 parts with just 3
bridges.

Parkinbot, The polyHoles() code implements the David Eberly method of bridging a polygon with (any number of) holes in order to apply his earcut triangulation method to the resulting (almost) simple polygon. The polygon polyHoles() returns has no holes but is not really a simple polygon: some edges of it are traveled twice as you traverse its full cycle. I call those edges as (two-way) bridges. As CGAL doesn't like polyhedron faces with the kind of polygons polyHoles produces, my proposal is to write an algorithm based on the Eberly's one to partition a simple polygon with holes in (really) simple polygons without holes. In my last few messages, I have made a set of very naive conjectures about this problem and its solving algorithm: 1) it is possible to partition the original polygon with holes in exactly two parts, 2) this partition is done by m+1 bridges and 3) the order of the solving method would be O(m.n) where m is the number of holes and n is the total number of vertices. Those conjectures are in fact true for convex polygons with convex holes. For convex holes but non-convex polygons, the number of necessary bridges may be 2.m and the partition may have m+1 parts. For non-convex holes, things become very wild! I don't have a guess for the number of parts in the partition but the number of bridges may increase to something like 2^m and the complexity grows to O( (2^m).n). Still, my expectancy is that this approach would be better than triangulation. I am still working on the method I have in mind to partition a polygon with many holes in simple polygons without holes. To have a flavor of what would result in a non-convex case consider the following image: [image: Poly2holes.PNG] The red bridges have been obtained by a direct application of polyHoles(outer,mH). The yellow bridges result from the application of polyHoles(-outer, -mH). Four bridges partition the original polygon in 3 parts. However, it is possible to partition it in 2 parts with just 3 bridges.
RP
Ronaldo Persiano
Thu, Jan 17, 2019 12:38 PM

Parkinbot,

The ear-cut triangulation method I have attached before is good only for
the kind of polygons polyHoles generates. It may lead to wrong results
(like degenerated triangles) when an additional vertex is added to some
bridge. So I think it is risky to use it in any other cases. To have a
proper ear-cut triangulation method that works for proper simple polygons
the function isCCW should have the following definition:

function isCCW(a, b, c) = CCW(a,b,c) >= 0 ;

Parkinbot, The ear-cut triangulation method I have attached before is good *only* for the kind of polygons polyHoles generates. It may lead to wrong results (like degenerated triangles) when an additional vertex is added to some bridge. So I think it is risky to use it in any other cases. To have a proper ear-cut triangulation method that works for proper simple polygons the function isCCW should have the following definition: function isCCW(a, b, c) = CCW(a,b,c) >= 0 ;
P
Parkinbot
Thu, Jan 17, 2019 12:40 PM

Ronaldo,
I intuitively unterstand the separation algorithm as follows:

Be P the point set of the outer polygon and I = {P1, P2 ...} the points sets
of the holes.

  1. find first bridge between P and I: calculate all point distances between
    P and I and select the hole P_ containing the point closest to O to build
    the brigde. Remove P_ from I and get I_
  2. find bridge from hole P_ to closest hole in I_: exclude the ingoing
    bridge point from P_, set P_ as P and I_ as I.
  3. if I is not empty go to step 1.

selecting always the shortest distance to build a brige, guarantees that no
other polygon can be cut. Thus we have all bridges exept the last.

The problem: I don't see, why we should be able to find a bridge to the
outer polygon again and I doubt that such a bridge will always exist.

See this example:

P = [[0,0],  [10,0], [10,10], [0,10]];
Q1 = [[2,7.8], [1,7.8], [1,1],  [9,1], [9,9], [1,9], [1,8], [8,8], [8,2],
[2,2], ];
Q2 = [[4,3],  [3,4], [3,3]];

linear_extrude(.1, convexity = 9)
difference()
{
polygon(P);
polygon(Q1);
polygon(Q2);
}

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

Ronaldo, I intuitively unterstand the separation algorithm as follows: Be P the point set of the outer polygon and I = {P1, P2 ...} the points sets of the holes. 1. find first bridge between P and I: calculate all point distances between P and I and select the hole P_ containing the point closest to O to build the brigde. Remove P_ from I and get I_ 2. find bridge from hole P_ to closest hole in I_: exclude the ingoing bridge point from P_, set P_ as P and I_ as I. 3. if I is not empty go to step 1. selecting always the shortest distance to build a brige, guarantees that no other polygon can be cut. Thus we have all bridges exept the last. The problem: I don't see, why we should be able to find a bridge to the outer polygon again and I doubt that such a bridge will always exist. See this example: P = [[0,0], [10,0], [10,10], [0,10]]; Q1 = [[2,7.8], [1,7.8], [1,1], [9,1], [9,9], [1,9], [1,8], [8,8], [8,2], [2,2], ]; Q2 = [[4,3], [3,4], [3,3]]; linear_extrude(.1, convexity = 9) difference() { polygon(P); polygon(Q1); polygon(Q2); } -- Sent from: http://forum.openscad.org/
RP
Ronaldo Persiano
Thu, Jan 17, 2019 1:23 PM

Parkinbot,

polyHoles doesn't try to find a bridge between each hole and the polygon
boundary. Some bridges may connect two holes.
It operates as following:

a) find the hole having the rightmost vertex among all hole vertices;
b) project this vertex to the right to a point in the polygon border;
c) find a vertex of the polygon "near" the projection point whose
connection to the hole vertex of a) is a bridge;
d) redefine the polygon using that bridge and the hole of a) ;
e) remove the hole of a) from the list of holes;
f) recur with the redefined polygon and the updated list of holes.

So, in your example, there would be a bridge from the squared hole to the
polygon border and another one between the two holes.

In the algorithm schema above, item c) is a bit more complex than described.

David Eberly's explanation of the algorithm is very clear and easy to
follow.

Parkinbot, polyHoles doesn't try to find a bridge between each hole and the polygon boundary. Some bridges may connect two holes. It operates as following: a) find the hole having the rightmost vertex among all hole vertices; b) project this vertex to the right to a point in the polygon border; c) find a vertex of the polygon "near" the projection point whose connection to the hole vertex of a) is a bridge; d) redefine the polygon using that bridge and the hole of a) ; e) remove the hole of a) from the list of holes; f) recur with the redefined polygon and the updated list of holes. So, in your example, there would be a bridge from the squared hole to the polygon border and another one between the two holes. In the algorithm schema above, item c) is a bit more complex than described. David Eberly's explanation of the algorithm is very clear and easy to follow.
P
Parkinbot
Thu, Jan 17, 2019 5:20 PM

Ronaldo,

this is exactly what I meant and what I tried to express:
Go from the outer polygon to nearest hole, then from this hole to the
nearest unbridged hole and so on until you reach the last unbridged hole.
To get a full separation into two facets, you have to add a final bridge
from last hole to the outer polygon. And this is not always possible.

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

Ronaldo, this is exactly what I meant and what I tried to express: Go from the outer polygon to nearest hole, then from this hole to the nearest unbridged hole and so on until you reach the last unbridged hole. To get a full separation into two facets, you have to add a final bridge from last hole to the outer polygon. And this is not always possible. -- Sent from: http://forum.openscad.org/
RP
Ronaldo Persiano
Thu, Jan 17, 2019 7:25 PM

We agree. A bipartition with m+1 bridges is assured when the main polygon
and the holes are convex. But, for very intricate geometry of m holes, the
number of parts and number of bridges seem to grow exponentially with m.

In the picture bellow, the main polygon border is white. There are 3 holes,
filled by the colors green, red and blue. One possible set of bridges to
subdivide the polygon in simple polygons are represented in yellow.

[image: spiraledHoles.PNG]

The polygon partition has 6 parts. It is possible to add a fourth spiraled
hole squeezed between all previous holes that will require to double the
number of bridges and will produce the double of parts in the partition.
And so on...

We agree. A bipartition with m+1 bridges is assured when the main polygon and the holes are convex. But, for very intricate geometry of m holes, the number of parts and number of bridges seem to grow exponentially with m. In the picture bellow, the main polygon border is white. There are 3 holes, filled by the colors green, red and blue. One possible set of bridges to subdivide the polygon in simple polygons are represented in yellow. [image: spiraledHoles.PNG] The polygon partition has 6 parts. It is possible to add a fourth spiraled hole squeezed between all previous holes that will require to double the number of bridges and will produce the double of parts in the partition. And so on...
P
Parkinbot
Sat, Jan 19, 2019 4:39 PM

Ronaldo wrote

A bipartition with m+1 bridges is assured when the main polygon
and the holes are convex.

I doubt that, see this arrangement

http://forum.openscad.org/file/t887/bis.png

Of course, some n-partion (or a triangulation in the limit) can be found.

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

Ronaldo wrote > A bipartition with m+1 bridges is assured when the main polygon > and the holes are convex. I doubt that, see this arrangement <http://forum.openscad.org/file/t887/bis.png> Of course, some n-partion (or a triangulation in the limit) can be found. -- Sent from: http://forum.openscad.org/