discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

Equivalent of offset for a list of points?

SP
Sanjeev Prabhakar
Tue, Apr 12, 2022 1:36 PM

I think that's a good idea
We need to find the length of points at each stage e.g. it is 3600.
So 3600/25 should be the number of points considered at each stage and
discard others.
Calculate the offset and rotate these points 25 times.
Should theoretically work

On Tue, 12 Apr 2022, 16:18 Adrian Mariano, avm4@cornell.edu wrote:

It sounds like something is eating asterisk symbols for you.  Not sure
why that would happen.  When I look at what I posted it looks correct.
That line should have an asterisk after the R.  I'll try including the
code as an attachment here.

With regards to symmetry, I can only speak about what I see in your
existing model.  Your equations are complex, so I haven't tried to
understand them.  Right now you have a lot of symmetry: at each stage
it looks like 25 fold rotational symmetry.  That means in principle
you can make the model 25^2 faster by exploiting this, which would be
a huge win.  I think it would be fairly easy to do actually.  At each
stage, instead of computing the whole curve, compute 1/25 of the
curve, plus some extra points.  Then do an offset (closed=false).
Remove the extra points, which are there to prevent end effects, and
then rotate the remaining points around 24 times (zrot can do that)
and concatenate the result.  Because this makes the offset very much
shorter it will make the calculation enormously faster and enable that
very fine sampling you want.  Of course, you need a way to figure out
or know the symmetry, which is always going to be possible if you have
a fixed representation and you're exploring parameters, but it won't
be so easy if you're changing the equations in more significant ways
as you explore.  Note that if you have a rotational evolution you
have to come back to where you started, so it's natural for symmetry
to arise.  Exploiting vertical symmetry makes less of a difference.

On Tue, Apr 12, 2022 at 3:02 AM roald.baudoux@brutele.be wrote:

In the definition of R two multiplications were missing.

let(R=(rad+a+(pauw(sin(j *f1+phase1),0.5)*0.5+0.5)depth1i/stages

+(pauw(sin(j*f2+phase2),0.5)0.5+0.5)depth2(1-i/stages)))

should be:

let(R=(rad+a+(pauw(sin(j *f1+phase1),0.5)*0.5+0.5)depth1i/stages

+(pauw(sin(j*f2+phase2),0.5)*0.5+0.5)*depth2(1-i/stages)))

I suppose there's also something missing in:

R[sin(j),cos(j)]

because it triggers an error message. But what?


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


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

I think that's a good idea We need to find the length of points at each stage e.g. it is 3600. So 3600/25 should be the number of points considered at each stage and discard others. Calculate the offset and rotate these points 25 times. Should theoretically work On Tue, 12 Apr 2022, 16:18 Adrian Mariano, <avm4@cornell.edu> wrote: > It sounds like something is eating asterisk symbols for you. Not sure > why that would happen. When I look at what I posted it looks correct. > That line should have an asterisk after the R. I'll try including the > code as an attachment here. > > With regards to symmetry, I can only speak about what I see in your > existing model. Your equations are complex, so I haven't tried to > understand them. Right now you have a lot of symmetry: at each stage > it looks like 25 fold rotational symmetry. That means in principle > you can make the model 25^2 faster by exploiting this, which would be > a huge win. I think it would be fairly easy to do actually. At each > stage, instead of computing the whole curve, compute 1/25 of the > curve, plus some extra points. Then do an offset (closed=false). > Remove the extra points, which are there to prevent end effects, and > then rotate the remaining points around 24 times (zrot can do that) > and concatenate the result. Because this makes the offset very much > shorter it will make the calculation enormously faster and enable that > very fine sampling you want. Of course, you need a way to figure out > or know the symmetry, which is always going to be possible if you have > a fixed representation and you're exploring parameters, but it won't > be so easy if you're changing the equations in more significant ways > as you explore. Note that if you have a rotational evolution you > have to come back to where you started, so it's natural for symmetry > to arise. Exploiting vertical symmetry makes less of a difference. > > On Tue, Apr 12, 2022 at 3:02 AM <roald.baudoux@brutele.be> wrote: > > > > In the definition of R two multiplications were missing. > > > > let(R=(rad+a+(pauw(sin(j *f1+phase1),0.5)*0.5+0.5)*depth1*i/stages > > > +(pauw(sin(j*f2+phase2),0.5)0.5+0.5)depth2(1-i/stages))) > > > > should be: > > > > let(R=(rad+a+(pauw(sin(j *f1+phase1),0.5)*0.5+0.5)*depth1*i/stages > > > +(pauw(sin(j*f2+phase2),0.5)*0.5+0.5)*depth2(1-i/stages))) > > > > I suppose there's also something missing in: > > > > R[sin(j),cos(j)] > > > > because it triggers an error message. But what? > > > > _______________________________________________ > > OpenSCAD mailing list > > To unsubscribe send an email to discuss-leave@lists.openscad.org > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
RB
roald.baudoux@brutele.be
Tue, Apr 12, 2022 5:46 PM

Obviously, running the code proposed by Adrian is as slow as mine as soon as I use an angular resolution of 0.1 degree. The rendering has been running for 8 hours already and it is still at the CSG tree generation step. Also, the RAM is slowly nibbled away (reaching 88% of the installed 32GB at the moment).

Currently the only way I have found to work with this resolution with a decent time is to render a solid model and then hollow it out in another app (MeshLab).

Obviously, running the code proposed by Adrian is as slow as mine as soon as I use an angular resolution of 0.1 degree. The rendering has been running for 8 hours already and it is still at the CSG tree generation step. Also, the RAM is slowly nibbled away (reaching 88% of the installed 32GB at the moment). Currently the only way I have found to work with this resolution with a decent time is to render a solid model and then hollow it out in another app (MeshLab).
AM
Adrian Mariano
Wed, Apr 13, 2022 4:13 AM

I got sucked into adding support for symmetry.  What took 10 minutes
before takes 24 seconds.  I can preview the model at the ridiculous
and unnecessarily small 0.1 angle spacing in 2.5 minutes.  One other
important change: it turns out skin() is quite slow, I think because
it checks its input for uniformity and possibly does some resampling.
I switched to vnf_vertex_array, which is the core method.  It is much
faster.

On Tue, Apr 12, 2022 at 1:46 PM roald.baudoux@brutele.be wrote:

Obviously, running the code proposed by Adrian is as slow as mine as soon as I use an angular resolution of 0.1 degree. The rendering has been running for 8 hours already and it is still at the CSG tree generation step. Also, the RAM is slowly nibbled away (reaching 88% of the installed 32GB at the moment).

Currently the only way I have found to work with this resolution with a decent time is to render a solid model and then hollow it out in another app (MeshLab).


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

I got sucked into adding support for symmetry. What took 10 minutes before takes 24 seconds. I can preview the model at the ridiculous and unnecessarily small 0.1 angle spacing in 2.5 minutes. One other important change: it turns out skin() is quite slow, I think because it checks its input for uniformity and possibly does some resampling. I switched to vnf_vertex_array, which is the core method. It is much faster. On Tue, Apr 12, 2022 at 1:46 PM <roald.baudoux@brutele.be> wrote: > > Obviously, running the code proposed by Adrian is as slow as mine as soon as I use an angular resolution of 0.1 degree. The rendering has been running for 8 hours already and it is still at the CSG tree generation step. Also, the RAM is slowly nibbled away (reaching 88% of the installed 32GB at the moment). > > Currently the only way I have found to work with this resolution with a decent time is to render a solid model and then hollow it out in another app (MeshLab). > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org
JB
Jordan Brown
Wed, Apr 13, 2022 4:31 AM

On 4/12/2022 10:46 AM, roald.baudoux@brutele.be wrote:

Currently the only way I have found to work with this resolution with
a decent time is to render a solid model and then hollow it out in
another app (MeshLab).

You might be able to use a slicer. Design a solid model, then set the
slicer to 0% infill, zero top layers, and perimeters as desired.

Here's what it looks like in PrusaSlicer with 3 perimeters:

On 4/12/2022 10:46 AM, roald.baudoux@brutele.be wrote: > > Currently the only way I have found to work with this resolution with > a decent time is to render a solid model and then hollow it out in > another app (MeshLab). > You might be able to use a slicer. Design a solid model, then set the slicer to 0% infill, zero top layers, and perimeters as desired. Here's what it looks like in PrusaSlicer with 3 perimeters:
JB
Jordan Brown
Wed, Apr 13, 2022 5:35 AM

Another thing to think about is that you can design at a lower
resolution than you will eventually want.  When I set stages=50,
stage_height=5, and angle_step=1, I get a preview in ~6 seconds.[*] 
It's rough, but it conveys the shape reasonably well.  When you're happy
with the shape, then set things for higher resolution.

[*] My desktop is almost ten years old and wasn't high-end even when
new.
Another thing to think about is that you can design at a lower resolution than you will eventually want.  When I set stages=50, stage_height=5, and angle_step=1, I get a preview in ~6 seconds.[*]  It's rough, but it conveys the shape reasonably well.  When you're happy with the shape, *then* set things for higher resolution. [*] My desktop is almost ten years old and wasn't high-end even when new.
SP
Sanjeev Prabhakar
Wed, Apr 13, 2022 8:00 AM

I have written a new function surf_offset(prism,d) for this

include <sprabhakar2006/

dependencies.scad>
function surf_offset(prism,d)=
[for(i=[0:len(prism)-1])[for(j=[0:len(prism[0])-1])
let(
j_plus=j<len(prism[0])-1?j+1:0,
p0=prism[i][j],
p1=i<len(prism)-1?prism[i][]j_plus:prism[i-1][j],
p2=i<len(prism)-1?prism[i+1][j]:prism[i][j_plus],
v1=p1-p0,v2=p2-p0,
u1=uv(v1),u2=uv(v2),
p3=cross(u1,u2)*d
)p0+p3
]];

stages =200;

stage_height = 1.25;

rad = 50;

f1 = 25;

f2 = 25;

phase1 = 0;

phase2 = 180;

height_depth=5;

depth1 = 20;

depth2 = 20;

thickness = 2;

bottom_thickness = 3;

myslices = 5;

angle_step=1;

// generate outer points

points_base = [for (i = [0:1:stages]) let(f = pow(sin(i/stages * 120),2) *
7 + 1, var = 1 , a=((sin((i/stages360f)%360) * 0.5 + 0.5) * (var *
height_depth))) [for(j = [0:angle_step:360-angle_step]) [sin(j) *
(rad+a+(pauw(sin(j *f1+phase1),0.5)*0.5+0.5)depth1i/stages+(pauw(sin(j
*f2+phase2),0.5)*0.5+0.5)depth2(1-i/stages)), cos(j) *(rad+a+(pauw(sin(j
*f1+phase1),0.5)*0.5+0.5)depth1i/stages+(pauw(sin(j
*f2+phase2),0.5)0.5+0.5)depth2(1-i/stages)),istage_height]]];

points_base_e=surf_offset(points_base,-2);

swp_prism_h(points_base,points_base_e);

with 1 deg angle step it takes 20 sec

with 0.1 deg angle step it took 3 minutes 34 sec

I am working now on a 7 year old computer windows laptop

On Wed, 13 Apr 2022, 11:06 Jordan Brown, openscad@jordan.maileater.net
wrote:

Another thing to think about is that you can design at a lower resolution
than you will eventually want.  When I set stages=50, stage_height=5, and
angle_step=1, I get a preview in ~6 seconds.[*]  It's rough, but it conveys
the shape reasonably well.  When you're happy with the shape, then set
things for higher resolution.

[*] My desktop is almost ten years old and wasn't high-end even when new.


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

I have written a new function surf_offset(prism,d) for this include <sprabhakar2006/ dependencies.scad> function surf_offset(prism,d)= [for(i=[0:len(prism)-1])[for(j=[0:len(prism[0])-1]) let( j_plus=j<len(prism[0])-1?j+1:0, p0=prism[i][j], p1=i<len(prism)-1?prism[i][]j_plus:prism[i-1][j], p2=i<len(prism)-1?prism[i+1][j]:prism[i][j_plus], v1=p1-p0,v2=p2-p0, u1=uv(v1),u2=uv(v2), p3=cross(u1,u2)*d )p0+p3 ]]; stages =200; stage_height = 1.25; rad = 50; f1 = 25; f2 = 25; phase1 = 0; phase2 = 180; height_depth=5; depth1 = 20; depth2 = 20; thickness = 2; bottom_thickness = 3; myslices = 5; angle_step=1; // generate outer points points_base = [for (i = [0:1:stages]) let(f = pow(sin(i/stages * 120),2) * 7 + 1, var = 1 , a=((sin((i/stages*360*f)%360) * 0.5 + 0.5) * (var * height_depth))) [for(j = [0:angle_step:360-angle_step]) [sin(j) * (rad+a+(pauw(sin(j *f1+phase1),0.5)*0.5+0.5)*depth1*i/stages+(pauw(sin(j *f2+phase2),0.5)*0.5+0.5)*depth2*(1-i/stages)), cos(j) *(rad+a+(pauw(sin(j *f1+phase1),0.5)*0.5+0.5)*depth1*i/stages+(pauw(sin(j *f2+phase2),0.5)*0.5+0.5)*depth2*(1-i/stages)),i*stage_height]]]; points_base_e=surf_offset(points_base,-2); swp_prism_h(points_base,points_base_e); with 1 deg angle step it takes 20 sec with 0.1 deg angle step it took 3 minutes 34 sec I am working now on a 7 year old computer windows laptop On Wed, 13 Apr 2022, 11:06 Jordan Brown, <openscad@jordan.maileater.net> wrote: > Another thing to think about is that you can design at a lower resolution > than you will eventually want. When I set stages=50, stage_height=5, and > angle_step=1, I get a preview in ~6 seconds.[*] It's rough, but it conveys > the shape reasonably well. When you're happy with the shape, *then* set > things for higher resolution. > > [*] My desktop is almost ten years old and wasn't high-end even when new. > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
SP
Sanjeev Prabhakar
Wed, Apr 13, 2022 11:11 AM

there seems to be a syntax error in my last mail

correct one is here:

include <dependencies.scad>

function
surf_offset(prism,d)=[for(i=[0:len(prism)-1])[for(j=[0:len(prism[0])-1])let(j_plus=j<len(prism[0])-1?j+1:0,p0=prism[i][j],p1=i<len(prism)-1?prism[i][j_plus]:prism[i-1][j],p2=i<len(prism)-1?prism[i+1][j]:prism[i][j_plus],v1=p1-p0,v2=p2-p0,u1=uv(v1),u2=uv(v2),
p3=cross(u1,u2)*d )p0+p3]];

stages =200;

stage_height = 1.25;

rad = 50;

f1 = 25;

f2 = 25;

phase1 = 0;

phase2 = 180;

height_depth=5;

depth1 = 20;

depth2 = 20;

thickness = 2;

bottom_thickness = 3;

myslices = 5;

angle_step=0.1;

// generate outer points

points_base = [for (i = [0:1:stages]) let(f = pow(sin(i/stages * 120),2) *
7 + 1, var = 1 , a=((sin((i/stages360f)%360) * 0.5 + 0.5) * (var *
height_depth))) [for(j = [0:angle_step:360-angle_step]) [sin(j) *
(rad+a+(pauw(sin(j *f1+phase1),0.5)*0.5+0.5)depth1i/stages+(pauw(sin(j
*f2+phase2),0.5)*0.5+0.5)depth2(1-i/stages)), cos(j) *(rad+a+(pauw(sin(j
*f1+phase1),0.5)*0.5+0.5)depth1i/stages+(pauw(sin(j
*f2+phase2),0.5)0.5+0.5)depth2(1-i/stages)),istage_height]]];

points_base_e=surf_offset(points_base,2);

swp_prism_h(points_base,points_base_e);

function pauw(x,p)=sign(x)*abs(x)^p;

there seems to be a syntax error in my last mail correct one is here: include <dependencies.scad> function surf_offset(prism,d)=[for(i=[0:len(prism)-1])[for(j=[0:len(prism[0])-1])let(j_plus=j<len(prism[0])-1?j+1:0,p0=prism[i][j],p1=i<len(prism)-1?prism[i][j_plus]:prism[i-1][j],p2=i<len(prism)-1?prism[i+1][j]:prism[i][j_plus],v1=p1-p0,v2=p2-p0,u1=uv(v1),u2=uv(v2), p3=cross(u1,u2)*d )p0+p3]]; stages =200; stage_height = 1.25; rad = 50; f1 = 25; f2 = 25; phase1 = 0; phase2 = 180; height_depth=5; depth1 = 20; depth2 = 20; thickness = 2; bottom_thickness = 3; myslices = 5; angle_step=0.1; // generate outer points points_base = [for (i = [0:1:stages]) let(f = pow(sin(i/stages * 120),2) * 7 + 1, var = 1 , a=((sin((i/stages*360*f)%360) * 0.5 + 0.5) * (var * height_depth))) [for(j = [0:angle_step:360-angle_step]) [sin(j) * (rad+a+(pauw(sin(j *f1+phase1),0.5)*0.5+0.5)*depth1*i/stages+(pauw(sin(j *f2+phase2),0.5)*0.5+0.5)*depth2*(1-i/stages)), cos(j) *(rad+a+(pauw(sin(j *f1+phase1),0.5)*0.5+0.5)*depth1*i/stages+(pauw(sin(j *f2+phase2),0.5)*0.5+0.5)*depth2*(1-i/stages)),i*stage_height]]]; points_base_e=surf_offset(points_base,2); swp_prism_h(points_base,points_base_e); function pauw(x,p)=sign(x)*abs(x)^p; >>
AM
Adrian Mariano
Wed, Apr 13, 2022 11:24 AM

Sanjeev, your code may be fast but it doesn't actually work.  There seem to
be two problems, not counting the misplaced bracket.  One is that it fails
render (F6) when I add cube(120) to the model.  I assume this is because it
doesn't take into account that the offset surface will intersect itself.
Being able to do offset in 3d would be great, but offset in 2d with correct
handling of self-intersection is already difficult, and checking for
self-intersection is quadratic time.  Going to a surface offset means
quadratic time over the whole surface point set, which will be horribly
slow.  And then actually fixing the self-intersections will be very
difficult to code.  Compare run time in openscad primitives of offset() and
minkowski().  I really don't understand how doing any operation in 3d can
be faster than 2d, so that behavior is puzzling.  It definitely seems to be
fast.

The other problem I noticed with your version is that it does something
strange to the bottom, so the result isn't actually flat on the bottom.
That's presumably because you're using normals to the surface and they
point slightly down, so your inside is not aligned with your outside.  It
wouldn't be printable in that form.  It could be fixed with an
intersection, though that will add run time.  Also, the model is supposed
to be a container---there should be a bottom layer, which you are not
including.

The version I posted that exploits symmetry uses a correct offset which
offsets by the right amount (unlike yours) and which deals properly with
the self-intersection of the offset curve so that the resulting model
doesn't have self-intersection.  It previews in 2.5 minutes with 0.1 step
size.  I tried to render but OpenSCAD crashed, maybe not enough RAM?

Jordan, I agree that a step size of 1 degree is not enough.  When I looked
at 0.5 degrees I thought it looked adequate.  In any case, my latest code
produces a model in a reasonable time even with 0.1 degree, so assuming
sufficient resources to render, it should be possible to use a very tiny
step size.

On Wed, Apr 13, 2022 at 4:00 AM Sanjeev Prabhakar sprabhakar2006@gmail.com
wrote:

I have written a new function surf_offset(prism,d) for this

include <sprabhakar2006/

dependencies.scad>
function surf_offset(prism,d)=
[for(i=[0:len(prism)-1])[for(j=[0:len(prism[0])-1])
let(
j_plus=j<len(prism[0])-1?j+1:0,
p0=prism[i][j],
p1=i<len(prism)-1?prism[i][]j_plus:prism[i-1][j],
p2=i<len(prism)-1?prism[i+1][j]:prism[i][j_plus],
v1=p1-p0,v2=p2-p0,
u1=uv(v1),u2=uv(v2),
p3=cross(u1,u2)*d
)p0+p3
]];

stages =200;

stage_height = 1.25;

rad = 50;

f1 = 25;

f2 = 25;

phase1 = 0;

phase2 = 180;

height_depth=5;

depth1 = 20;

depth2 = 20;

thickness = 2;

bottom_thickness = 3;

myslices = 5;

angle_step=1;

// generate outer points

points_base = [for (i = [0:1:stages]) let(f = pow(sin(i/stages * 120),2) *
7 + 1, var = 1 , a=((sin((i/stages360f)%360) * 0.5 + 0.5) * (var *
height_depth))) [for(j = [0:angle_step:360-angle_step]) [sin(j) *
(rad+a+(pauw(sin(j *f1+phase1),0.5)*0.5+0.5)depth1i/stages+(pauw(sin(j
*f2+phase2),0.5)*0.5+0.5)depth2(1-i/stages)), cos(j) *(rad+a+(pauw(sin(j
*f1+phase1),0.5)*0.5+0.5)depth1i/stages+(pauw(sin(j
*f2+phase2),0.5)0.5+0.5)depth2(1-i/stages)),istage_height]]];

points_base_e=surf_offset(points_base,-2);

swp_prism_h(points_base,points_base_e);

with 1 deg angle step it takes 20 sec

with 0.1 deg angle step it took 3 minutes 34 sec

I am working now on a 7 year old computer windows laptop

On Wed, 13 Apr 2022, 11:06 Jordan Brown, openscad@jordan.maileater.net
wrote:

Another thing to think about is that you can design at a lower resolution
than you will eventually want.  When I set stages=50, stage_height=5, and
angle_step=1, I get a preview in ~6 seconds.[*]  It's rough, but it conveys
the shape reasonably well.  When you're happy with the shape, then set
things for higher resolution.

[*] My desktop is almost ten years old and wasn't high-end even when new.


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


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

Sanjeev, your code may be fast but it doesn't actually work. There seem to be two problems, not counting the misplaced bracket. One is that it fails render (F6) when I add cube(120) to the model. I assume this is because it doesn't take into account that the offset surface will intersect itself. Being able to do offset in 3d would be great, but offset in 2d with correct handling of self-intersection is already difficult, and checking for self-intersection is quadratic time. Going to a surface offset means quadratic time over the whole surface point set, which will be horribly slow. And then actually fixing the self-intersections will be very difficult to code. Compare run time in openscad primitives of offset() and minkowski(). I really don't understand how doing any operation in 3d can be faster than 2d, so that behavior is puzzling. It definitely seems to be fast. The other problem I noticed with your version is that it does something strange to the bottom, so the result isn't actually flat on the bottom. That's presumably because you're using normals to the surface and they point slightly down, so your inside is not aligned with your outside. It wouldn't be printable in that form. It could be fixed with an intersection, though that will add run time. Also, the model is supposed to be a container---there should be a bottom layer, which you are not including. The version I posted that exploits symmetry uses a correct offset which offsets by the right amount (unlike yours) and which deals properly with the self-intersection of the offset curve so that the resulting model doesn't have self-intersection. It previews in 2.5 minutes with 0.1 step size. I tried to render but OpenSCAD crashed, maybe not enough RAM? Jordan, I agree that a step size of 1 degree is not enough. When I looked at 0.5 degrees I thought it looked adequate. In any case, my latest code produces a model in a reasonable time even with 0.1 degree, so assuming sufficient resources to render, it should be possible to use a very tiny step size. On Wed, Apr 13, 2022 at 4:00 AM Sanjeev Prabhakar <sprabhakar2006@gmail.com> wrote: > I have written a new function surf_offset(prism,d) for this > > include <sprabhakar2006/ > > dependencies.scad> > function surf_offset(prism,d)= > [for(i=[0:len(prism)-1])[for(j=[0:len(prism[0])-1]) > let( > j_plus=j<len(prism[0])-1?j+1:0, > p0=prism[i][j], > p1=i<len(prism)-1?prism[i][]j_plus:prism[i-1][j], > p2=i<len(prism)-1?prism[i+1][j]:prism[i][j_plus], > v1=p1-p0,v2=p2-p0, > u1=uv(v1),u2=uv(v2), > p3=cross(u1,u2)*d > )p0+p3 > ]]; > > > stages =200; > > stage_height = 1.25; > > rad = 50; > > f1 = 25; > > f2 = 25; > > phase1 = 0; > > phase2 = 180; > > height_depth=5; > > depth1 = 20; > > depth2 = 20; > > thickness = 2; > > bottom_thickness = 3; > > myslices = 5; > > angle_step=1; > > // generate outer points > > points_base = [for (i = [0:1:stages]) let(f = pow(sin(i/stages * 120),2) * > 7 + 1, var = 1 , a=((sin((i/stages*360*f)%360) * 0.5 + 0.5) * (var * > height_depth))) [for(j = [0:angle_step:360-angle_step]) [sin(j) * > (rad+a+(pauw(sin(j *f1+phase1),0.5)*0.5+0.5)*depth1*i/stages+(pauw(sin(j > *f2+phase2),0.5)*0.5+0.5)*depth2*(1-i/stages)), cos(j) *(rad+a+(pauw(sin(j > *f1+phase1),0.5)*0.5+0.5)*depth1*i/stages+(pauw(sin(j > *f2+phase2),0.5)*0.5+0.5)*depth2*(1-i/stages)),i*stage_height]]]; > > points_base_e=surf_offset(points_base,-2); > > swp_prism_h(points_base,points_base_e); > > with 1 deg angle step it takes 20 sec > > with 0.1 deg angle step it took 3 minutes 34 sec > > I am working now on a 7 year old computer windows laptop > > On Wed, 13 Apr 2022, 11:06 Jordan Brown, <openscad@jordan.maileater.net> > wrote: > >> Another thing to think about is that you can design at a lower resolution >> than you will eventually want. When I set stages=50, stage_height=5, and >> angle_step=1, I get a preview in ~6 seconds.[*] It's rough, but it conveys >> the shape reasonably well. When you're happy with the shape, *then* set >> things for higher resolution. >> >> [*] My desktop is almost ten years old and wasn't high-end even when new. >> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org >> > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
SP
Sanjeev Prabhakar
Wed, Apr 13, 2022 12:02 PM

Hi Adrian

Since the offset of so many stages is excessively time consuming.
Calculated the normals with 3 adjacent points here to achieve the
objective.

In the first and the last stage there would be some mismatch, but maybe not
significant.

By removing the option of "stop on first warning" f6 render done
successfully.

Not tried rendering along with cube,  but an stl file can be generated with
this. Although the size of the stl file is huge 141mb

So it is assumed, this can be printed

Apart from this there could be several self intersecting sections and
presently  don't know how to cure them.

But anyways it was a good learning exercise

On Wed, 13 Apr 2022, 16:54 Adrian Mariano, avm4@cornell.edu wrote:

Sanjeev, your code may be fast but it doesn't actually work.  There seem
to be two problems, not counting the misplaced bracket.  One is that it
fails render (F6) when I add cube(120) to the model.  I assume this is
because it doesn't take into account that the offset surface will intersect
itself.  Being able to do offset in 3d would be great, but offset in 2d
with correct handling of self-intersection is already difficult, and
checking for self-intersection is quadratic time.  Going to a surface
offset means quadratic time over the whole surface point set, which will be
horribly slow.  And then actually fixing the self-intersections will be
very difficult to code.  Compare run time in openscad primitives of
offset() and minkowski().  I really don't understand how doing any
operation in 3d can be faster than 2d, so that behavior is puzzling.  It
definitely seems to be fast.

The other problem I noticed with your version is that it does something
strange to the bottom, so the result isn't actually flat on the bottom.
That's presumably because you're using normals to the surface and they
point slightly down, so your inside is not aligned with your outside.  It
wouldn't be printable in that form.  It could be fixed with an
intersection, though that will add run time.  Also, the model is supposed
to be a container---there should be a bottom layer, which you are not
including.

The version I posted that exploits symmetry uses a correct offset which
offsets by the right amount (unlike yours) and which deals properly with
the self-intersection of the offset curve so that the resulting model
doesn't have self-intersection.  It previews in 2.5 minutes with 0.1 step
size.  I tried to render but OpenSCAD crashed, maybe not enough RAM?

Jordan, I agree that a step size of 1 degree is not enough.  When I looked
at 0.5 degrees I thought it looked adequate.  In any case, my latest code
produces a model in a reasonable time even with 0.1 degree, so assuming
sufficient resources to render, it should be possible to use a very tiny
step size.

On Wed, Apr 13, 2022 at 4:00 AM Sanjeev Prabhakar <
sprabhakar2006@gmail.com> wrote:

I have written a new function surf_offset(prism,d) for this

include <sprabhakar2006/

dependencies.scad>
function surf_offset(prism,d)=
[for(i=[0:len(prism)-1])[for(j=[0:len(prism[0])-1])
let(
j_plus=j<len(prism[0])-1?j+1:0,
p0=prism[i][j],
p1=i<len(prism)-1?prism[i][]j_plus:prism[i-1][j],
p2=i<len(prism)-1?prism[i+1][j]:prism[i][j_plus],
v1=p1-p0,v2=p2-p0,
u1=uv(v1),u2=uv(v2),
p3=cross(u1,u2)*d
)p0+p3
]];

stages =200;

stage_height = 1.25;

rad = 50;

f1 = 25;

f2 = 25;

phase1 = 0;

phase2 = 180;

height_depth=5;

depth1 = 20;

depth2 = 20;

thickness = 2;

bottom_thickness = 3;

myslices = 5;

angle_step=1;

// generate outer points

points_base = [for (i = [0:1:stages]) let(f = pow(sin(i/stages * 120),2)

  • 7 + 1, var = 1 , a=((sin((i/stages360f)%360) * 0.5 + 0.5) * (var *
    height_depth))) [for(j = [0:angle_step:360-angle_step]) [sin(j) *
    (rad+a+(pauw(sin(j *f1+phase1),0.5)*0.5+0.5)depth1i/stages+(pauw(sin(j
    *f2+phase2),0.5)*0.5+0.5)depth2(1-i/stages)), cos(j) *(rad+a+(pauw(sin(j
    *f1+phase1),0.5)*0.5+0.5)depth1i/stages+(pauw(sin(j
    *f2+phase2),0.5)0.5+0.5)depth2(1-i/stages)),istage_height]]];

points_base_e=surf_offset(points_base,-2);

swp_prism_h(points_base,points_base_e);

with 1 deg angle step it takes 20 sec

with 0.1 deg angle step it took 3 minutes 34 sec

I am working now on a 7 year old computer windows laptop

On Wed, 13 Apr 2022, 11:06 Jordan Brown, openscad@jordan.maileater.net
wrote:

Another thing to think about is that you can design at a lower
resolution than you will eventually want.  When I set stages=50,
stage_height=5, and angle_step=1, I get a preview in ~6 seconds.[*]  It's
rough, but it conveys the shape reasonably well.  When you're happy with
the shape, then set things for higher resolution.

[*] My desktop is almost ten years old and wasn't high-end even when new.


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


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


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

Hi Adrian Since the offset of so many stages is excessively time consuming. Calculated the normals with 3 adjacent points here to achieve the objective. In the first and the last stage there would be some mismatch, but maybe not significant. By removing the option of "stop on first warning" f6 render done successfully. Not tried rendering along with cube, but an stl file can be generated with this. Although the size of the stl file is huge 141mb So it is assumed, this can be printed Apart from this there could be several self intersecting sections and presently don't know how to cure them. But anyways it was a good learning exercise On Wed, 13 Apr 2022, 16:54 Adrian Mariano, <avm4@cornell.edu> wrote: > Sanjeev, your code may be fast but it doesn't actually work. There seem > to be two problems, not counting the misplaced bracket. One is that it > fails render (F6) when I add cube(120) to the model. I assume this is > because it doesn't take into account that the offset surface will intersect > itself. Being able to do offset in 3d would be great, but offset in 2d > with correct handling of self-intersection is already difficult, and > checking for self-intersection is quadratic time. Going to a surface > offset means quadratic time over the whole surface point set, which will be > horribly slow. And then actually fixing the self-intersections will be > very difficult to code. Compare run time in openscad primitives of > offset() and minkowski(). I really don't understand how doing any > operation in 3d can be faster than 2d, so that behavior is puzzling. It > definitely seems to be fast. > > The other problem I noticed with your version is that it does something > strange to the bottom, so the result isn't actually flat on the bottom. > That's presumably because you're using normals to the surface and they > point slightly down, so your inside is not aligned with your outside. It > wouldn't be printable in that form. It could be fixed with an > intersection, though that will add run time. Also, the model is supposed > to be a container---there should be a bottom layer, which you are not > including. > > The version I posted that exploits symmetry uses a correct offset which > offsets by the right amount (unlike yours) and which deals properly with > the self-intersection of the offset curve so that the resulting model > doesn't have self-intersection. It previews in 2.5 minutes with 0.1 step > size. I tried to render but OpenSCAD crashed, maybe not enough RAM? > > Jordan, I agree that a step size of 1 degree is not enough. When I looked > at 0.5 degrees I thought it looked adequate. In any case, my latest code > produces a model in a reasonable time even with 0.1 degree, so assuming > sufficient resources to render, it should be possible to use a very tiny > step size. > > On Wed, Apr 13, 2022 at 4:00 AM Sanjeev Prabhakar < > sprabhakar2006@gmail.com> wrote: > >> I have written a new function surf_offset(prism,d) for this >> >> include <sprabhakar2006/ >> >> dependencies.scad> >> function surf_offset(prism,d)= >> [for(i=[0:len(prism)-1])[for(j=[0:len(prism[0])-1]) >> let( >> j_plus=j<len(prism[0])-1?j+1:0, >> p0=prism[i][j], >> p1=i<len(prism)-1?prism[i][]j_plus:prism[i-1][j], >> p2=i<len(prism)-1?prism[i+1][j]:prism[i][j_plus], >> v1=p1-p0,v2=p2-p0, >> u1=uv(v1),u2=uv(v2), >> p3=cross(u1,u2)*d >> )p0+p3 >> ]]; >> >> >> stages =200; >> >> stage_height = 1.25; >> >> rad = 50; >> >> f1 = 25; >> >> f2 = 25; >> >> phase1 = 0; >> >> phase2 = 180; >> >> height_depth=5; >> >> depth1 = 20; >> >> depth2 = 20; >> >> thickness = 2; >> >> bottom_thickness = 3; >> >> myslices = 5; >> >> angle_step=1; >> >> // generate outer points >> >> points_base = [for (i = [0:1:stages]) let(f = pow(sin(i/stages * 120),2) >> * 7 + 1, var = 1 , a=((sin((i/stages*360*f)%360) * 0.5 + 0.5) * (var * >> height_depth))) [for(j = [0:angle_step:360-angle_step]) [sin(j) * >> (rad+a+(pauw(sin(j *f1+phase1),0.5)*0.5+0.5)*depth1*i/stages+(pauw(sin(j >> *f2+phase2),0.5)*0.5+0.5)*depth2*(1-i/stages)), cos(j) *(rad+a+(pauw(sin(j >> *f1+phase1),0.5)*0.5+0.5)*depth1*i/stages+(pauw(sin(j >> *f2+phase2),0.5)*0.5+0.5)*depth2*(1-i/stages)),i*stage_height]]]; >> >> points_base_e=surf_offset(points_base,-2); >> >> swp_prism_h(points_base,points_base_e); >> >> with 1 deg angle step it takes 20 sec >> >> with 0.1 deg angle step it took 3 minutes 34 sec >> >> I am working now on a 7 year old computer windows laptop >> >> On Wed, 13 Apr 2022, 11:06 Jordan Brown, <openscad@jordan.maileater.net> >> wrote: >> >>> Another thing to think about is that you can design at a lower >>> resolution than you will eventually want. When I set stages=50, >>> stage_height=5, and angle_step=1, I get a preview in ~6 seconds.[*] It's >>> rough, but it conveys the shape reasonably well. When you're happy with >>> the shape, *then* set things for higher resolution. >>> >>> [*] My desktop is almost ten years old and wasn't high-end even when new. >>> >>> _______________________________________________ >>> OpenSCAD mailing list >>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org >> > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
NH
nop head
Wed, Apr 13, 2022 2:56 PM

Isn't offset just a matter of drawing circles around each vertex and
calculating the joining tangents. Something I have done in the NopSCADlib
rounded polygon.

If the vertex is concave then the tangents cross in front of the circle so
that intersection becomes the new vertex. So that is extra code.

I think this is how Skeinforge does offsets. Not particularly slow in
Python.

On Wed, 13 Apr 2022 at 13:02, Sanjeev Prabhakar sprabhakar2006@gmail.com
wrote:

Hi Adrian

Since the offset of so many stages is excessively time consuming.
Calculated the normals with 3 adjacent points here to achieve the
objective.

In the first and the last stage there would be some mismatch, but maybe
not significant.

By removing the option of "stop on first warning" f6 render done
successfully.

Not tried rendering along with cube,  but an stl file can be generated
with this. Although the size of the stl file is huge 141mb

So it is assumed, this can be printed

Apart from this there could be several self intersecting sections and
presently  don't know how to cure them.

But anyways it was a good learning exercise

On Wed, 13 Apr 2022, 16:54 Adrian Mariano, avm4@cornell.edu wrote:

Sanjeev, your code may be fast but it doesn't actually work.  There seem
to be two problems, not counting the misplaced bracket.  One is that it
fails render (F6) when I add cube(120) to the model.  I assume this is
because it doesn't take into account that the offset surface will intersect
itself.  Being able to do offset in 3d would be great, but offset in 2d
with correct handling of self-intersection is already difficult, and
checking for self-intersection is quadratic time.  Going to a surface
offset means quadratic time over the whole surface point set, which will be
horribly slow.  And then actually fixing the self-intersections will be
very difficult to code.  Compare run time in openscad primitives of
offset() and minkowski().  I really don't understand how doing any
operation in 3d can be faster than 2d, so that behavior is puzzling.  It
definitely seems to be fast.

The other problem I noticed with your version is that it does something
strange to the bottom, so the result isn't actually flat on the bottom.
That's presumably because you're using normals to the surface and they
point slightly down, so your inside is not aligned with your outside.  It
wouldn't be printable in that form.  It could be fixed with an
intersection, though that will add run time.  Also, the model is supposed
to be a container---there should be a bottom layer, which you are not
including.

The version I posted that exploits symmetry uses a correct offset which
offsets by the right amount (unlike yours) and which deals properly with
the self-intersection of the offset curve so that the resulting model
doesn't have self-intersection.  It previews in 2.5 minutes with 0.1 step
size.  I tried to render but OpenSCAD crashed, maybe not enough RAM?

Jordan, I agree that a step size of 1 degree is not enough.  When I
looked at 0.5 degrees I thought it looked adequate.  In any case, my latest
code produces a model in a reasonable time even with 0.1 degree, so
assuming sufficient resources to render, it should be possible to use a
very tiny step size.

On Wed, Apr 13, 2022 at 4:00 AM Sanjeev Prabhakar <
sprabhakar2006@gmail.com> wrote:

I have written a new function surf_offset(prism,d) for this

include <sprabhakar2006/

dependencies.scad>
function surf_offset(prism,d)=
[for(i=[0:len(prism)-1])[for(j=[0:len(prism[0])-1])
let(
j_plus=j<len(prism[0])-1?j+1:0,
p0=prism[i][j],
p1=i<len(prism)-1?prism[i][]j_plus:prism[i-1][j],
p2=i<len(prism)-1?prism[i+1][j]:prism[i][j_plus],
v1=p1-p0,v2=p2-p0,
u1=uv(v1),u2=uv(v2),
p3=cross(u1,u2)*d
)p0+p3
]];

stages =200;

stage_height = 1.25;

rad = 50;

f1 = 25;

f2 = 25;

phase1 = 0;

phase2 = 180;

height_depth=5;

depth1 = 20;

depth2 = 20;

thickness = 2;

bottom_thickness = 3;

myslices = 5;

angle_step=1;

// generate outer points

points_base = [for (i = [0:1:stages]) let(f = pow(sin(i/stages * 120),2)

  • 7 + 1, var = 1 , a=((sin((i/stages360f)%360) * 0.5 + 0.5) * (var *
    height_depth))) [for(j = [0:angle_step:360-angle_step]) [sin(j) *
    (rad+a+(pauw(sin(j *f1+phase1),0.5)*0.5+0.5)depth1i/stages+(pauw(sin(j
    *f2+phase2),0.5)*0.5+0.5)depth2(1-i/stages)), cos(j) *(rad+a+(pauw(sin(j
    *f1+phase1),0.5)*0.5+0.5)depth1i/stages+(pauw(sin(j
    *f2+phase2),0.5)0.5+0.5)depth2(1-i/stages)),istage_height]]];

points_base_e=surf_offset(points_base,-2);

swp_prism_h(points_base,points_base_e);

with 1 deg angle step it takes 20 sec

with 0.1 deg angle step it took 3 minutes 34 sec

I am working now on a 7 year old computer windows laptop

On Wed, 13 Apr 2022, 11:06 Jordan Brown, openscad@jordan.maileater.net
wrote:

Another thing to think about is that you can design at a lower
resolution than you will eventually want.  When I set stages=50,
stage_height=5, and angle_step=1, I get a preview in ~6 seconds.[*]  It's
rough, but it conveys the shape reasonably well.  When you're happy with
the shape, then set things for higher resolution.

[*] My desktop is almost ten years old and wasn't high-end even when
new.


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


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


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


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

Isn't offset just a matter of drawing circles around each vertex and calculating the joining tangents. Something I have done in the NopSCADlib rounded polygon. If the vertex is concave then the tangents cross in front of the circle so that intersection becomes the new vertex. So that is extra code. I think this is how Skeinforge does offsets. Not particularly slow in Python. On Wed, 13 Apr 2022 at 13:02, Sanjeev Prabhakar <sprabhakar2006@gmail.com> wrote: > Hi Adrian > > Since the offset of so many stages is excessively time consuming. > Calculated the normals with 3 adjacent points here to achieve the > objective. > > In the first and the last stage there would be some mismatch, but maybe > not significant. > > By removing the option of "stop on first warning" f6 render done > successfully. > > Not tried rendering along with cube, but an stl file can be generated > with this. Although the size of the stl file is huge 141mb > > So it is assumed, this can be printed > > Apart from this there could be several self intersecting sections and > presently don't know how to cure them. > > But anyways it was a good learning exercise > > > On Wed, 13 Apr 2022, 16:54 Adrian Mariano, <avm4@cornell.edu> wrote: > >> Sanjeev, your code may be fast but it doesn't actually work. There seem >> to be two problems, not counting the misplaced bracket. One is that it >> fails render (F6) when I add cube(120) to the model. I assume this is >> because it doesn't take into account that the offset surface will intersect >> itself. Being able to do offset in 3d would be great, but offset in 2d >> with correct handling of self-intersection is already difficult, and >> checking for self-intersection is quadratic time. Going to a surface >> offset means quadratic time over the whole surface point set, which will be >> horribly slow. And then actually fixing the self-intersections will be >> very difficult to code. Compare run time in openscad primitives of >> offset() and minkowski(). I really don't understand how doing any >> operation in 3d can be faster than 2d, so that behavior is puzzling. It >> definitely seems to be fast. >> >> The other problem I noticed with your version is that it does something >> strange to the bottom, so the result isn't actually flat on the bottom. >> That's presumably because you're using normals to the surface and they >> point slightly down, so your inside is not aligned with your outside. It >> wouldn't be printable in that form. It could be fixed with an >> intersection, though that will add run time. Also, the model is supposed >> to be a container---there should be a bottom layer, which you are not >> including. >> >> The version I posted that exploits symmetry uses a correct offset which >> offsets by the right amount (unlike yours) and which deals properly with >> the self-intersection of the offset curve so that the resulting model >> doesn't have self-intersection. It previews in 2.5 minutes with 0.1 step >> size. I tried to render but OpenSCAD crashed, maybe not enough RAM? >> >> Jordan, I agree that a step size of 1 degree is not enough. When I >> looked at 0.5 degrees I thought it looked adequate. In any case, my latest >> code produces a model in a reasonable time even with 0.1 degree, so >> assuming sufficient resources to render, it should be possible to use a >> very tiny step size. >> >> On Wed, Apr 13, 2022 at 4:00 AM Sanjeev Prabhakar < >> sprabhakar2006@gmail.com> wrote: >> >>> I have written a new function surf_offset(prism,d) for this >>> >>> include <sprabhakar2006/ >>> >>> dependencies.scad> >>> function surf_offset(prism,d)= >>> [for(i=[0:len(prism)-1])[for(j=[0:len(prism[0])-1]) >>> let( >>> j_plus=j<len(prism[0])-1?j+1:0, >>> p0=prism[i][j], >>> p1=i<len(prism)-1?prism[i][]j_plus:prism[i-1][j], >>> p2=i<len(prism)-1?prism[i+1][j]:prism[i][j_plus], >>> v1=p1-p0,v2=p2-p0, >>> u1=uv(v1),u2=uv(v2), >>> p3=cross(u1,u2)*d >>> )p0+p3 >>> ]]; >>> >>> >>> stages =200; >>> >>> stage_height = 1.25; >>> >>> rad = 50; >>> >>> f1 = 25; >>> >>> f2 = 25; >>> >>> phase1 = 0; >>> >>> phase2 = 180; >>> >>> height_depth=5; >>> >>> depth1 = 20; >>> >>> depth2 = 20; >>> >>> thickness = 2; >>> >>> bottom_thickness = 3; >>> >>> myslices = 5; >>> >>> angle_step=1; >>> >>> // generate outer points >>> >>> points_base = [for (i = [0:1:stages]) let(f = pow(sin(i/stages * 120),2) >>> * 7 + 1, var = 1 , a=((sin((i/stages*360*f)%360) * 0.5 + 0.5) * (var * >>> height_depth))) [for(j = [0:angle_step:360-angle_step]) [sin(j) * >>> (rad+a+(pauw(sin(j *f1+phase1),0.5)*0.5+0.5)*depth1*i/stages+(pauw(sin(j >>> *f2+phase2),0.5)*0.5+0.5)*depth2*(1-i/stages)), cos(j) *(rad+a+(pauw(sin(j >>> *f1+phase1),0.5)*0.5+0.5)*depth1*i/stages+(pauw(sin(j >>> *f2+phase2),0.5)*0.5+0.5)*depth2*(1-i/stages)),i*stage_height]]]; >>> >>> points_base_e=surf_offset(points_base,-2); >>> >>> swp_prism_h(points_base,points_base_e); >>> >>> with 1 deg angle step it takes 20 sec >>> >>> with 0.1 deg angle step it took 3 minutes 34 sec >>> >>> I am working now on a 7 year old computer windows laptop >>> >>> On Wed, 13 Apr 2022, 11:06 Jordan Brown, <openscad@jordan.maileater.net> >>> wrote: >>> >>>> Another thing to think about is that you can design at a lower >>>> resolution than you will eventually want. When I set stages=50, >>>> stage_height=5, and angle_step=1, I get a preview in ~6 seconds.[*] It's >>>> rough, but it conveys the shape reasonably well. When you're happy with >>>> the shape, *then* set things for higher resolution. >>>> >>>> [*] My desktop is almost ten years old and wasn't high-end even when >>>> new. >>>> >>>> _______________________________________________ >>>> OpenSCAD mailing list >>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>>> >>> _______________________________________________ >>> OpenSCAD mailing list >>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org >> > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >