### Unwrap a polyhedron

G
gilboonet
Wed, Mar 31, 2021 12:40 PM

Hello, I'm trying to unfold a polyhedron using OpenSCAD. It's something that
is at the core of my cardboard craft, I first wrote it using OpenJSCAD v1
and since 2 years now I'm using a vanilla JavaScript version, but I'm aware
that OpenSCAD is not JavaScript and I need to get close to OpenSCAD concepts
and forget iterative coding in order to make good use of recursion.

I use Wings3d to export a 3d model as polyhedron data (using its export to
I have two arrays, points[] and polygons[]

With those arrays I'm able to get 3d triangles of each polygons of the
polyhedron (function getFacePoints()).

To transform those 3d triangles into 2d triangles, I use a neat formula from
Stack overflow (function 2dize()).

Next step is to start from one face, then look for its neighbors (they share
2 points), rotate each neighbor triangle if needed, then continue for each
new triangle. Later it will be useful to do that recursively and check at
each step for triangles intersection, later again check if the net still
fits into page, and it will be done.

Do you think such process is possible with OpenSCAD ?

I'm now looking for a way to find a face neighbors. I will continue the post
if I find a way to do so.

--

Hello, I'm trying to unfold a polyhedron using OpenSCAD. It's something that is at the core of my cardboard craft, I first wrote it using OpenJSCAD v1 and since 2 years now I'm using a vanilla JavaScript version, but I'm aware that OpenSCAD is not JavaScript and I need to get close to OpenSCAD concepts and forget iterative coding in order to make good use of recursion. I use Wings3d to export a 3d model as polyhedron data (using its export to .jscad) I have two arrays, points[] and polygons[] With those arrays I'm able to get 3d triangles of each polygons of the polyhedron (function getFacePoints()). To transform those 3d triangles into 2d triangles, I use a neat formula from Stack overflow (function 2dize()). Next step is to start from one face, then look for its neighbors (they share 2 points), rotate each neighbor triangle if needed, then continue for each new triangle. Later it will be useful to do that recursively and check at each step for triangles intersection, later again check if the net still fits into page, and it will be done. Do you think such process is possible with OpenSCAD ? I'm now looking for a way to find a face neighbors. I will continue the post if I find a way to do so. <http://forum.openscad.org/file/t3103/Capture_d%E2%80%99%C3%A9cran_de_2021-03-31_13-59-15.png> -- Sent from: http://forum.openscad.org/
N
NateTG
Wed, Mar 31, 2021 2:12 PM

It is possible to do something like that using OpenSCAD, but I'm not sure why
you'd want to do to that.  If you have:

points=[ [...],[...],...];
faces=[ [...],[...],...];

As suitable for use in the polyhedron built-in, then you can do something
like:

halfedges=[
for (i=[0:len(faces)-1])
for(j=[i:len(faces[i])-i])
[
faces[i][j]*len(points)+faces[i][(j+1)%len(faces[i]),
i
]
]

Which will produce a list of [index,face] pairs.  Then if you want to know
which face is on the other side of an edge that goes from a to b, you can
then use:

facelist=search (b*len(points)+a,halfedges)

To find the face the other side.

If you continue to pursue the project, checking for overlap will probably be
one of the more painful parts.

--

It is possible to do something like that using OpenSCAD, but I'm not sure why you'd want to do to that. If you have: points=[ [...],[...],...]; faces=[ [...],[...],...]; As suitable for use in the polyhedron built-in, then you can do something like: halfedges=[ for (i=[0:len(faces)-1]) for(j=[i:len(faces[i])-i]) [ faces[i][j]*len(points)+faces[i][(j+1)%len(faces[i]), i ] ] Which will produce a list of [index,face] pairs. Then if you want to know which face is on the other side of an edge that goes from a to b, you can then use: facelist=search (b*len(points)+a,halfedges) To find the face the other side. If you continue to pursue the project, checking for overlap will probably be one of the more painful parts. -- Sent from: http://forum.openscad.org/
A
arnholm@arnholm.org
Wed, Mar 31, 2021 2:43 PM

On 2021-03-31 16:12, NateTG wrote:

It is possible to do something like that using OpenSCAD, but I'm not
sure why you'd want to do to that.

I agree. I have done it in C++ and would not try to use any scripting
language to do it.

Carsten Arnholm

On 2021-03-31 16:12, NateTG wrote: > It is possible to do something like that using OpenSCAD, but I'm not > sure why you'd want to do to that. I agree. I have done it in C++ and would not try to use any scripting language to do it. Carsten Arnholm
G
gilboonet
Wed, Mar 31, 2021 3:58 PM

cacb wrote

On 2021-03-31 16:12, NateTG wrote:

It is possible to do something like that using OpenSCAD, but I'm not
sure why you'd want to do to that.

I agree. I have done it in C++ and would not try to use any scripting
language to do it.

Carsten Arnholm

Why I'm doing this with scripting tools is because I'm not experienced
enough to code 3d in C++ (I'm a 51 years old craftsman not a CS specialist
nor professional), but I'm working on this since 2015 in order to have
something like Pepakura, and it works well, I managed to have the automatic
version unwrap a 2000 triangles model (took hours) that I successfully built
on cardboard (took 2 weeks). My primary goal is to unwrap furniture clothe
so I won't need more than 2000 triangles most of times. The fact is that
automatic unwrapping is very slow with javaScript, for the moment I'm using
a strategy that works nicely : I paint my volume so that it has groups of
faces that I unwrap separately, it considerably improves the speed, but I'm
now hoping that OpenSCAD could help me more. At first I wanted to use
TensorFlow but I didn't understand how it works.

I'm already impressed by the speed, the sensation of power that OpenSCAD
gives. I will try to understand the code that NateTG gave me, it is so much
simple than what I did, but I'm afraid that I need to take little steps not
to lose tack of what I'm doing.

I managed to have the faces neighbors using search(), now I need to start
basic unwrapping without checking for overlap. On the OpenJSCAD version,
what I did to check overlap was very foolish, I built a 2g geometry with all
faces already unwrapped and check if this geometry and the current one
intersects, takes very long but works. On vanilla JavaScript I tried lots of
things but none worked, so this version is only semi-automatic. Yesterday I
used it to unwrap the hand model that I'm using here.

--

cacb wrote > On 2021-03-31 16:12, NateTG wrote: >> It is possible to do something like that using OpenSCAD, but I'm not >> sure why you'd want to do to that. > > I agree. I have done it in C++ and would not try to use any scripting > language to do it. > > Carsten Arnholm Why I'm doing this with scripting tools is because I'm not experienced enough to code 3d in C++ (I'm a 51 years old craftsman not a CS specialist nor professional), but I'm working on this since 2015 in order to have something like Pepakura, and it works well, I managed to have the automatic version unwrap a 2000 triangles model (took hours) that I successfully built on cardboard (took 2 weeks). My primary goal is to unwrap furniture clothe so I won't need more than 2000 triangles most of times. The fact is that automatic unwrapping is very slow with javaScript, for the moment I'm using a strategy that works nicely : I paint my volume so that it has groups of faces that I unwrap separately, it considerably improves the speed, but I'm now hoping that OpenSCAD could help me more. At first I wanted to use TensorFlow but I didn't understand how it works. I'm already impressed by the speed, the sensation of power that OpenSCAD gives. I will try to understand the code that NateTG gave me, it is so much simple than what I did, but I'm afraid that I need to take little steps not to lose tack of what I'm doing. I managed to have the faces neighbors using search(), now I need to start basic unwrapping without checking for overlap. On the OpenJSCAD version, what I did to check overlap was very foolish, I built a 2g geometry with all faces already unwrapped and check if this geometry and the current one intersects, takes very long but works. On vanilla JavaScript I tried lots of things but none worked, so this version is only semi-automatic. Yesterday I used it to unwrap the hand model that I'm using here. <http://forum.openscad.org/file/t3103/Capture_d%E2%80%99%C3%A9cran_de_2021-03-31_17-10-41.png> -- Sent from: http://forum.openscad.org/
RP
Ronaldo Persiano
Thu, Apr 1, 2021 12:31 AM

This subject has been discussed here. See:

This subject has been discussed here. See: http://forum.openscad.org/flattening-curved-surfaces-tp19727.html
G
gilboonet
Thu, Apr 1, 2021 7:34 AM

Ronaldo wrote

This subject has been discussed here. See:

Thank you, I remember I read that thread several times while I was looking
for a way to optimize my script. To unfold the concerned  shape, I saved it
to STL, then opened it in Wings3d, select the 4 surfaces separately and
colored their faces in order to have them group, then export it to OBJ where
the data (vertices, faces, groups) can be easily read. It took about 2
minutes to unfold them all with a vanilla js script. So I hope it will be at
think that it won't be possible (or at best it will be hard) to write an
automatic version as I didn't find a way to have an OpenSCAD script make
conditional actions based on an intersection result (I only need to check if
the intersection return something), but for the moment I will try to write
the rotation of a neighbor triangle.

--

RP
Ronaldo Persiano
Thu, Apr 1, 2021 1:00 PM

... but for the moment I will try to write the rotation of a neighbor
triangle.

This little magic code may do the job:

function unit(v) = v/norm(v);

module connect(a,b,c,d) {
translate(c)
mirror(unit(a-b)+unit(c-d))
mirror(a-b)
translate(-a)
children();
}

t1 = [ [3,2], [13,6], [1,12] ];
t2 = [ [-3,2], [-13,6], [-1,5] ];

color("gray") {
polygon(t1);
polygon(t2);
}

color("magenta")
connect(t2[1],t2[2],t1[1],t1[2]) polygon(t2);

color("blue")
connect(t2[0],t2[1],t1[0],t1[1]) polygon(t2);

> > ... but for the moment I will try to write the rotation of a neighbor > triangle. > > This little magic code may do the job: function unit(v) = v/norm(v); module connect(a,b,c,d) { translate(c) mirror(unit(a-b)+unit(c-d)) mirror(a-b) translate(-a) children(); } t1 = [ [3,2], [13,6], [1,12] ]; t2 = [ [-3,2], [-13,6], [-1,5] ]; color("gray") { polygon(t1); polygon(t2); } color("magenta") connect(t2[1],t2[2],t1[1],t1[2]) polygon(t2); color("blue") connect(t2[0],t2[1],t1[0],t1[1]) polygon(t2);
G
gilboonet
Thu, Apr 1, 2021 1:09 PM

Ronaldo wrote

... but for the moment I will try to write the rotation of a neighbor
triangle.
This little magic code may do the job:

Thank you again, I will look at your code that seems interesting, I failed
to use mirror to attach neighbors on OpenJSCAD. I managed to have my first
neighbor rotation done using the logic I developed on my other versions. And
now I'm kind of stuck as I must update data of that neighbor that I rotated
and it's something that I'm not sure is possible within OpenSCAD logic. It I
can update those points I will only need to keep on doing the same with
other neighbors, otherwise for each new neighbor I will need to do
everything again ?

--

Ronaldo wrote >> ... but for the moment I will try to write the rotation of a neighbor >> triangle. >> This little magic code may do the job: Thank you again, I will look at your code that seems interesting, I failed to use mirror to attach neighbors on OpenJSCAD. I managed to have my first neighbor rotation done using the logic I developed on my other versions. And now I'm kind of stuck as I must update data of that neighbor that I rotated and it's something that I'm not sure is possible within OpenSCAD logic. It I can update those points I will only need to keep on doing the same with other neighbors, otherwise for each new neighbor I will need to do everything again ? <http://forum.openscad.org/file/t3103/Capture_d%E2%80%99%C3%A9cran_de_2021-04-01_14-57-51.png> -- Sent from: http://forum.openscad.org/
N
NateTG
Thu, Apr 1, 2021 1:28 PM

gilboonet wrote

... It took about 2 minutes to unfold them all with a vanilla js script.
So I hope it will be at
me
think that it won't be possible (or at best it will be hard) to write an
automatic version as I didn't find a way to have an OpenSCAD script make
conditional actions based on an intersection result ...

OpenSCAD tends to be pretty slow.  In general, I would expect JavaScript to
do the same things more quickly.  So if "unfold" is taking to too long in
JS, it might be useful to check whether you're doing the "unfold" in a
particularly inefficient way.

One of the biggest frustrations that I have with OpenSCAD is that there's no
good for user code to take advantage of the geometry engine.

--

gilboonet wrote > ... It took about 2 minutes to unfold them all with a vanilla js script. > So I hope it will be at > least 2 times faster with OpenSCAD. Sadly, what I've read from now makes > me > think that it won't be possible (or at best it will be hard) to write an > automatic version as I didn't find a way to have an OpenSCAD script make > conditional actions based on an intersection result ... OpenSCAD tends to be pretty slow. In general, I would expect JavaScript to do the same things more quickly. So if "unfold" is taking to too long in JS, it might be useful to check whether you're doing the "unfold" in a particularly inefficient way. One of the biggest frustrations that I have with OpenSCAD is that there's no good for user code to take advantage of the geometry engine. -- Sent from: http://forum.openscad.org/
G
gilboonet
Thu, Apr 1, 2021 1:57 PM

NateTG wrote

OpenSCAD tends to be pretty slow.  In general, I would expect JavaScript
to
do the same things more quickly.  So if "unfold" is taking to too long in
JS, it might be useful to check whether you're doing the "unfold" in a
particularly inefficient way.

The way I currently unfold is simplistic, I start from a face, then if you
click on "auto" button it unfold closest neighbor and keep on till there's
nothing to do, it is  here
https://github.com/gilboonet/gilboonet.github.io/tree/master/depl_edit  .
I planned to make something more complex but I didn't manage to have a solid
overlap detection function, so I didn't go further. What do you mean by an
inefficient way ? Is there a way to weight an unfold path efficiency ? (a
tree to climb up and down till every faces are unfold ?) I hope that