Discussion:
[OpenSCAD] Twisted Torus
Zacariaz
2018-09-25 23:35:21 UTC
Permalink
I am new here and frankly I haven't got the slightest clue how this system
works, so I'm just gonna post my question, and if I'm doing something wrong,
I apologize in advance.

In short, I feel like I got the hang of openscad, even though it is still
fairly new to me. I have however stumbled upon a problem that is beyond me,
trying to make a model of the twisted torus, and well, I have succeeded,
sort of, but I'm think there must be a better way, as this is not at all
viable.

twistedTorus( 25, 50 );
#translate( [50, 0, 0] ) rotate( [90, 180, 0] ) twistedTorus( 25, 50 );

module twistedTorus( r1, r2, t )
{
for( i = [0:1:360] )
{
rotate( [90, 0, i] )
{
translate( [r2, 0, 0] )
{
rotate( [0, 0, i] )
{
difference()
{
circle( r1 );
translate( [0, -r1, 0] ) square( [r1, 2*r1] );
}
}
}
}
}
}

Also I apologize for all the curly bracket, but I like to keep things in
order, inconvenient though it may be. ;)
The issue should be evident. The model is only a facsimile, and a bad one at
that. It is very resource intensive to render even in it's current form and
if you want to step it up a notch to something useful, you've got to find a
better way, which is why I'm asking here, how to attach this problem.

You could say that what I need is rotate_extrude_with_a_twist(), but I don't
see how.


Best regards.



--
Sent from: http://forum.openscad.org/
Ezra Reynolds
2018-09-26 00:24:05 UTC
Permalink
The quick answer is that you are mixing 2D (square, circle) and 3D.
OpenScad treats 2D shapes as having a slight thickness for rendering
purposes, but when creating an actual model the model will be blank
because a square or circle does not exist in 3D space.

Adding a linear_extrude (1) (or some other thickness) will give the
torus-slice a thickness, which is then (SLOWLY) added together to make a
shape. I say "SLOWLY" because it is going to be resource-intensive;
OpenScad is slow on boolean operations, and it always performs a
top-level union; so you have at least 360 boolean operations it has to
calculate.

This could be sped up by having fewer, but thicker, slices. The true
wizards here can come up with some variant that uses list comprehension
to generate a polyhedron that will render in blazing speed, but that is
outside my skill.

Side note, the matching brace style is known as Allman style or BSD
style. I prefer this style myself, although brace style is one of the
Great Religious Flame War topics among programmers.

-------------------------------

Here is your code, with a slice size of 10 (affects both the loop and
the linear_extrude). Renders in decent time on my machine. The finer
resolution you go the slower it will be.

------------------------



twistedTorus( 25, 50 );

module twistedTorus( r1, r2, t )
{
for( i = [0:10:360] )
{
rotate( [90, 0, i] )
{
translate( [r2, 0, 0] )
{
rotate( [0, 0, i] )
{
linear_extrude(10) difference()
{
circle( r1 );
translate( [0, -r1, 0] ) square( [r1, 2*r1] );
}
}
}
}
}
}


------------------------------
Post by Zacariaz
twistedTorus( 25, 50 );
#translate( [50, 0, 0] ) rotate( [90, 180, 0] ) twistedTorus( 25, 50 );
module twistedTorus( r1, r2, t )
{
for( i = [0:1:360] )
{
rotate( [90, 0, i] )
{
translate( [r2, 0, 0] )
{
rotate( [0, 0, i] )
{
difference()
{
circle( r1 );
translate( [0, -r1, 0] ) square( [r1, 2*r1] );
}
}
}
}
}
}
Also I apologize for all the curly bracket, but I like to keep things in
order, inconvenient though it may be.;)
The issue should be evident. The model is only a facsimile, and a bad one at
that. It is very resource intensive to render even in it's current form and
if you want to step it up a notch to something useful, you've got to find a
better way, which is why I'm asking here, how to attach this problem.
You could say that what I need is rotate_extrude_with_a_twist(), but I don't
see how.
doug moen
2018-09-26 02:32:39 UTC
Permalink
There is no "rotate_extrude_with_a_twist" in OpenSCAD, and there's no way
to define new CSG operators with this kind of behaviour from inside the
OpenSCAD language. So you are left with building the model by assembling a
large number of small pieces. An expert would use polyhedron(), as Ezra
said, and then it will be fast.

I make these kinds of models using Curv, which has a richer set of CSG
operators, including "twist" and "bend". Here's my standard twisted torus
in Curv. Note that this has a square cross section. It works by making a
tall skinny box, twisting it around the Z axis, then bending it around 360°
into a torus.

let
twisted_torus(d1, d2, ntwists) =
box(d1,d1,d2)
twist (90*ntwists*deg/d2)
rotate {angle: 90*deg, axis: Y_axis}
bend {};
in
twisted_torus(1, 10, 4)

which looks like this:


Your design has a semi-circle as a cross section. I'd make that by starting
with a cylinder, cutting away half the cylinder so that it has a
semi-circle cross section, then twist and bend as before.

let
twisted_torus(d1, d2, ntwists) =
difference( cylinder{d: d1, h: d2}, box{xmin: 0} )
twist (360*ntwists*deg/d2)
rotate {angle: 90*deg, axis: Y_axis}
bend {};
in
twisted_torus(25, 50, 1)



Curv works differently from OpenSCAD. Shapes are represented internally as
mathematical functions, not as triangle meshes, and curved surfaces are
rendered on the screen at "infinite" resolution. You don't get a triangle
mesh until you export an STL file. This representation makes Curv good for
curved organic shapes, and non-affine transformations like twist and bend
are easier to implement.

You should be aware that Curv is a one-man hobby project on github. Mac and
Linux only (no Windows), and you build your own executable by following the
build instructions. https://github.com/doug-moen/curv

Doug Moen
Parkinbot
2018-09-26 06:55:05 UTC
Permalink
A moebius strip is a good exercise to explore and compare basic and advanced
OpenScad programming techniques.
There are many examples out there (in Thingiverse) where people define a
moebius with polyhedron in a more or less direct way. Also have a look at
these.

The approach I am showing here uses a more general library, which is a very
mighty instrument for many other applications.

Two basic techniques you can use for such a thing are explained in
https://www.thingiverse.com/thing:900137/files where you also find the
Naca_sweep lib used in the following code. As it would be a special case for
sweep() to connect a moebius structure into a ring with some (e.g. 0.5)
windings my code uses the trick to union two half moebius rings. Thus it
creates an affine representation of the two halfrings and lets the library
function sweep() do all the "hard" work.

The lib contains the definitions of sweep() as well as the affine
counterparts of translate() and rotate() Rx_(), and so on.



use <Naca_sweep.scad> // https://www.thingiverse.com/thing:900137/files

sweep(moebius(twist=1.5));
sweep(moebius(twist=1.5, start=180, end=360));

function moebius(r=100, start=0, step=1, end = 180, twist=0.5) =
[for(i=[start:step:end])
Rz_(i,
Tx_(r,
Rx_(90,
Rz_(i*twist, square())
)))];

function square(x=50, y=10) =
[[-x/2, -y/2, 0],
[-x/2, y/2, 0],
[x/2, y/2, 0],
[x/2, -y/2, 0]];



--
Sent from: http://forum.openscad.org/
Parkinbot
2018-10-04 07:03:47 UTC
Permalink
Ok, the full solution is:

use <Naca_sweep.scad> // https://www.thingiverse.com/thing:900137/files

twistedTorus( 25, 50 );
#translate( [-100, 0, 0] ) rotate( [90, 180, 0] ) twistedTorus( 25, 50 );

module twistedTorus(r1,r2,N=30)
{
sweep(moebius(r1=100, r2=50, twist=1));
sweep(moebius(r1=100, r2=50, twist=1, start=180, end=360, N=N));
}

function moebius(r1=100, r2=50, start=0, end = 180, N=30, twist=0.5) =
[for(j=[0:N]) let(i= start+j*(end-start)/N)
Rz_(i,
Tx_(-r1,
Rx_(90,
Rz_(i*twist, halfcirc(r2))
)))];

function halfcirc(r=50, N=30) = [for(i=[0:N]) let(w=180/N*i) r*[sin(w),
cos(w), 0]];



--
Sent from: http://forum.openscad.org/
Ronaldo Persiano
2018-10-05 22:09:22 UTC
Permalink
Pakinbot,

Your sweep.scad alleviates all the burden of defining the faces of the
polyhedron enveloping the section vertices. It is very general and allows
that lofts may be build provided that the user computes all the section
positions and orientation in the space. For simple cases of tubular forms -
that is, all sections are equal - as the present case of twisted torus, the
user computation of the section positions could be avoided by a generic
process good enough for most cases. The strategy of that generic process is
to define the section positions in the planes "orthogonal to the sweep
path" translated to each path point. That is the strategy behind Oskar
Linde sweep.scad found in the list-comprehension-demos.

I guess that a code that computes the section positions for this case would
answer the needs of lots of modeling cases. As an example, the twisted
torus model might have the following simple expression:

use <Naca_sweep.scad> // https://www.thingiverse.com/thing:900137/files

twistedTorus( 25, 50 );
translate( [-50, 0, 0] ) rotate( [90, 180, 0] ) twistedTorus( 25, 50 );

module twistedTorus(r1,r2,N=30)
{
path1 = halfcirc(r2, N);
path2 = Rz_(180, path1);
sect = Rz_(-90, halfcirc(r1));
half1 = sweep_sections(path1, sect, 180);
half2 = sweep_sections(path2, sect, 180);
sweep(half1);
sweep(half2);
}

function halfcirc(r=50, N=30) =
[for(i=[0:N]) let(w=180/N*i) r*[sin(w),cos(w), 0]];


where sweep_sections is the generic function that generates the list of
sections in position.

Loosely based on the Linde's sweep ideas, I have coded sweep_sections as:

// list of total rotations from p[0] to each p[i]
function totRots(n,lrot, Rz=identity(), M=[identity()]) =
len(M)>n ?
M :
totRots( n, lrot, Rz, concat(M, [lrot[len(M)-1]*M[len(M)-1]*Rz] ));

function sweep_sections(path, section, twist) =
let(p = path,
np = len(p),
Rz = rotZ(twist/(np-1)), // matriz of twist rotation between steps
// tangents to the path p
tgts = [[0,0,1],
-3*p[0] + 4*p[1] - p[2],
for(i=[1:np-2]) p[i+1]-p[i-1],
3*p[np-1] - 4*p[np-2] + p[np-3]
],
// rotation between two steps
lrot = [for(i=[0:np-1])frotFromTo(tgts[i], tgts[i+1])],
// list of total rotations from p[0] to each p[i]
rots = [for(i=0, Mi=identity(); i<=len(lrot); Mi= lrot[i]*Mi*Rz,
i=i+1) Mi] ) // same as totRots(len(p), lrot, Rz)
[for(i=[0:len(p)-1]) transl(transf(section,rots[i+1]),p[i])];


I have resorted to the "C-like for" in its code for simplicity but the
recursive function totRots may be used instead.

The definition above requires a number of useful helper functions I have in
my libraries:

// reflection matrix of direction v
function fmirror(v) =
norm(v)==0 ? [[1,0,0],[0,1,0],[0,0,1]] :
let(u = v/norm(v))
[ [1,0,0] - 2*u[0]*u, [0,1,0] - 2*u[1]*u, [0,0,1] - 2*u[2]*u ];

// rotation matrix of the minimum rotation
// bringing di to do
function frotFromTo(di,do) =
norm(di-do)==0 || norm(di)==0 || norm(do)==0 ?
[[1,0,0],[0,1,0],[0,0,1]] :
fmirror(do/norm(do)+di/norm(di)) * fmirror(di);

function identity() = [[1,0,0],[0,1,0],[0,0,1]];

// translation of a sequence of points
function transl(pts, d) = [for(pt=pts) pt+d];

// Z rotation matrix
function rotZ(ang) = let(c=cos(ang), s=sin(ang))
[[c,s,0],[-s,c,0],[0,0,1]];

// transform of a list of points by a 3x3 matrix
function transf(pts,M) = [for(pt=pts) M*pt];
Parkinbot
2018-10-06 08:09:46 UTC
Permalink
Post by Ronaldo Persiano
For simple cases of tubular forms -
that is, all sections are equal - as the present case of twisted torus, the
user computation of the section positions could be avoided by a generic
process good enough for most cases.
This is true and the orthogonal approach can make things easy in certain
cases. But is a somehow oriented half circle (which is a one-liner) still a
simple case?
When I played around with the "original" sweep mentioned by you, I found it
quite difficult to define the right transformation paths and I still find it
a bit callenging.
Therefore I prefer the most general solution as it has a very easy logic:
1. define a (optionally parametrized) 2D-shape in XY-plane
2. map the shape to the desired path using affine operations an iteration
variable

To a man who has hammer the whole world looks like a nail.

For the discussed twisted half circle torus my sweep indeed supports a
"close" parameter that can be used to close tori with integral twists making
the half tori union obsolete.

twistedTorus( 25, 50 );
#translate( [-100.1, 0, 0] ) rotate( [90, 180, 0] ) twistedTorus( 25, 50 );

module twistedTorus(r1,r2,N=30)
sweep(moebius(r1=100, r2=50, end= 360, twist=1), close = true);




--
Sent from: http://forum.openscad.org/
Zacariaz
2018-10-06 23:30:08 UTC
Permalink
So I've finally put together a working module. It is by no means perfect, but
it'll do for my needs I think. In any case it's about the best I can achieve
at this point.

/*
r1: radius 1
r2: radius 2
ca: circle angle, i.e. 180 for a half circle and 360 for a full circle
seg: number of segments
*/
function flatten(l) = [ for (a = l) for (b = a) b ] ;

module twistedTorus( r1, r2, ca, seg )
{
s2 = round(2*(r1+r2)*3.14/(2*r1*3.14)*seg);
p = flatten(
[
for( ta = [0:360/s2:359] )
[
[
-sin(ta)*r2,
cos(ta)*r2,
0
],
for( i = [ta:360/seg:ca+ta] )
[
-sin(ta)*(cos(i)*r1+r2),
cos(ta)*(cos(i)*r1+r2),
sin(i)*r1
]
]

]);
f1 =
[
for( i = [0:len(p)-1])
[
i,
(i+1)%len(p),
(i+seg/(360/ca)+2)%len(p),
]
];
f2 =
[
for( i = [0:len(p)-1])
[
(i+1)%len(p),
(i+seg/(360/ca)+3)%len(p),
(i+seg/(360/ca)+2)%len(p)
]
];
polyhedron( points = p, faces = concat(f1,f2) );
}

twistedTorus(25.4/4, 25.4/2, 180, 60);



--
Sent from: http://forum.openscad.org/
Ronaldo Persiano
2018-10-08 23:39:46 UTC
Permalink
Nice done. Just 3 cents:
a) there is a predefined variable PI in the language;
b) it is usually advisable to avoid a float as increment of a for;
c) the computation of the polyhedron vertices could be simply:

p =
[
for( ta = [0:360/s2:359] )
for( i = [ta:360/seg:ca+ta] )
[
-sin(ta)*(cos(i)*r1+r2),
cos(ta)*(cos(i)*r1+r2),
sin(i)*r1
]
];
Zacariaz
2018-10-09 14:52:21 UTC
Permalink
Post by Ronaldo Persiano
a) there is a predefined variable PI in the language;
b) it is usually advisable to avoid a float as increment of a for;
p =
[
for( ta = [0:360/s2:359] )
for( i = [ta:360/seg:ca+ta] )
[
-sin(ta)*(cos(i)*r1+r2),
cos(ta)*(cos(i)*r1+r2),
sin(i)*r1
]
];
As for your first point, good to know. Don't know how I've missed it, but in
this case it doesn't actually matter as it cancels out. It was more for
explanatory purposes.

Secondly I get what you're saying, and believe you me I've ha a lot of
trouble getting the for loops in openscad to behave. The first for loop
defining p pretty much explain the issue.
When working with integers, there really is not issue, because you can
always just say
for( [begin:step:end-1] )
to get the actual range you're looking for, but if your step is not and
integer, in this case 360/s, you need to go to extremes ot make it work,
like
for( [0:360/s:360-360/s] )
which can course problems due to floating point "errors", and don't even get
me started on the case that the loop doesn't start at 0, in which case
you'll have to ensure that you start at a multiple of 360/s, which is pretty
much impossible, when working with floating point values.
I actually did plan to ask what to do in such situations, because it goes
without saying that sometimes 360 iterations just isn't enough to achieve
the desired resolution, so to speak.
Personally I'm used to the C syntax and would much rather have written
for( i = 0; round( i, 3 ) < 360; i += 360/s ) // 3 decimals should be ample
resolution.
and I don't see how to achieve the same effect with openscad syntax, without
going to extremes.

Lastly, what about the center point? I know it isn't strictly needed when
splitting the torus in 2, but I do believe it increases the quality, and it
certainly is need if you wish to split it into 3 or more, or simply use some
arbitrary angle.
Or am I missing something?

And also thanks. To be honest, I can't help to be a little bit proud of
myself. Regardless, I do plan to try again from scratch, to see if I can't
do a better job of it.



--
Sent from: http://forum.openscad.org/
Tim V. Shaporev
2018-10-09 16:11:44 UTC
Permalink
How many steps do you want in a loop?

for (i=[0:N-1]) [ cos(360*i/N),

or

for (i=[1:N]) [ cos(360*(i-1)/N),

something like that...
Post by Zacariaz
Post by Ronaldo Persiano
a) there is a predefined variable PI in the language;
b) it is usually advisable to avoid a float as increment of a for;
p =
[
for( ta = [0:360/s2:359] )
for( i = [ta:360/seg:ca+ta] )
[
-sin(ta)*(cos(i)*r1+r2),
cos(ta)*(cos(i)*r1+r2),
sin(i)*r1
]
];
As for your first point, good to know. Don't know how I've missed it, but in
this case it doesn't actually matter as it cancels out. It was more for
explanatory purposes.
Secondly I get what you're saying, and believe you me I've ha a lot of
trouble getting the for loops in openscad to behave. The first for loop
defining p pretty much explain the issue.
When working with integers, there really is not issue, because you can
always just say
for( [begin:step:end-1] )
to get the actual range you're looking for, but if your step is not and
integer, in this case 360/s, you need to go to extremes ot make it work,
like
for( [0:360/s:360-360/s] )
which can course problems due to floating point "errors", and don't even get
me started on the case that the loop doesn't start at 0, in which case
you'll have to ensure that you start at a multiple of 360/s, which is pretty
much impossible, when working with floating point values.
I actually did plan to ask what to do in such situations, because it goes
without saying that sometimes 360 iterations just isn't enough to achieve
the desired resolution, so to speak.
Personally I'm used to the C syntax and would much rather have written
for( i = 0; round( i, 3 ) < 360; i += 360/s ) // 3 decimals should be ample
resolution.
and I don't see how to achieve the same effect with openscad syntax, without
going to extremes.
Lastly, what about the center point? I know it isn't strictly needed when
splitting the torus in 2, but I do believe it increases the quality, and it
certainly is need if you wish to split it into 3 or more, or simply use some
arbitrary angle.
Or am I missing something?
And also thanks. To be honest, I can't help to be a little bit proud of
myself. Regardless, I do plan to try again from scratch, to see if I can't
do a better job of it.
--
Sent from: http://forum.openscad.org/
_______________________________________________
OpenSCAD mailing list
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
.
Ronaldo Persiano
2018-10-17 17:26:44 UTC
Permalink
Post by Zacariaz
Secondly I get what you're saying, and believe you me I've ha a lot of
trouble getting the for loops in openscad to behave. The first for loop
defining p pretty much explain the issue.
A simple form of a list comprehension for loop without floating point
increments would be:

[ let(N=round(s) for( i=[0:N], ang = 360*i/N) ...]

which is equivalent to:

[ let(N=round(s) for( i=[0:N] let( ang = 360*i/N) ...]

A third form is available with snapshot OpenSCAD versions - the C-like for
form:

[ let(N=round(s) for(i=0, ang=0; i <= round(s) ; i=i+1, ang = 360*i/N)
...]

Lastly, what about the center point? I know it isn't strictly needed when
Post by Zacariaz
splitting the torus in 2, but I do believe it increases the quality, and it
certainly is need if you wish to split it into 3 or more, or simply use some
arbitrary angle.
You are right. My simplification of your code for the vertex computation
applies only for your original model.
klusacek
2018-12-01 01:22:05 UTC
Permalink
This post might be inappropriate. Click to display it.
Michael Frey
2018-12-01 13:23:35 UTC
Permalink
Post by klusacek
I have encountered a similar problem, solving it by a quick and dirty hack to
the openscad source code. Note, however, that you can easily create
self-intersecting surface, so use it with care.
http://atrey.karlin.mff.cuni.cz/~klusacek/openscad/index.html
Interesting. Two points I am going to comment on:

* a few comments about the patch
* the observation that render can be faster then preview

--------

Looking at the patch file, I am confused why it has a makefile.

In my understanding, the makefile is automatically generated using qmake.

Also note that you can ignore the object folder. Those are also generated.

objects/comment_lexer.hxx is - if my memory serves me right - by GNU bison.

I think the patch could be a lot smaller when only patching the files
that needed patching.


On a side note: Why not use git?

We are on github:

    https://github.com/openscad/openscad

and the .gitignore file

    https://github.com/openscad/openscad/blob/master/.gitignore

is pretty good at preventing adding or diffing autogenerate files.

Using git would also allow you to open a pull request, so that we can
look into it if we want to adopt this patch into the official build..

I would be interested in seeing if there are any issues with our
regression tests.

When you open a pull request, those are run automatically for our major
platforms.


/For models with complicated CSG structure, the preview rendering
can easily last longer than the CGAL rendering./

/It often overloads the graphics card, leaving user interface
unresponsive for several minutes./

/I use external editor, using auto reload and preview function./

/Unfortunately, auto reload always turns rendering into F5 mode
everytime I save the file in editor, which //
//lock up the user interface for several minutes in case of complex
models. /

Very very interesting. We could add an "Automatic Load and Render"
option or something like it.

The complicated thing about that would be, that leaving the wrong one on
for the wrong model would waste time.

For the case where render is faster then preview, something like

    assert($preview ? false : true, "Render is faster then preview -
please press F6");
    cube(); //just a silly example

would help.

With kind regards,

Michael Frey
nop head
2018-12-01 18:00:47 UTC
Permalink
Yes I don't like the fact auto reload doesn't remember you have done F6. I
think it should remember the mode and do an automatic F6. I.e. you make
changes and the preview changes. Then you press F6 and get the CGAL render.
Then you make more changes it should update the CGAL view, not flip back to
preview.

If F5 is too slow I add a render() call to my code to force the CGAL
render, even when F5 is pressed.
Post by klusacek
I have encountered a similar problem, solving it by a quick and dirty hack to
the openscad source code. Note, however, that you can easily create
self-intersecting surface, so use it with care.
The patch can be found here:http://atrey.karlin.mff.cuni.cz/~klusacek/openscad/index.html
- a few comments about the patch
- the observation that render can be faster then preview
--------
Looking at the patch file, I am confused why it has a makefile.
In my understanding, the makefile is automatically generated using qmake.
Also note that you can ignore the object folder. Those are also generated.
objects/comment_lexer.hxx is - if my memory serves me right - by GNU bison.
I think the patch could be a lot smaller when only patching the files that
needed patching.
On a side note: Why not use git?
https://github.com/openscad/openscad
and the .gitignore file
https://github.com/openscad/openscad/blob/master/.gitignore
is pretty good at preventing adding or diffing autogenerate files.
Using git would also allow you to open a pull request, so that we can look
into it if we want to adopt this patch into the official build..
I would be interested in seeing if there are any issues with our
regression tests.
When you open a pull request, those are run automatically for our major
platforms.
*For models with complicated CSG structure, the preview rendering can
easily last longer than the CGAL rendering.*
*It often overloads the graphics card, leaving user interface unresponsive
for several minutes.*
*I use external editor, using auto reload and preview function.*
*Unfortunately, auto reload always turns rendering into F5 mode everytime
I save the file in editor, which *
* lock up the user interface for several minutes in case of complex
models. *
Very very interesting. We could add an "Automatic Load and Render" option
or something like it.
The complicated thing about that would be, that leaving the wrong one on
for the wrong model would waste time.
For the case where render is faster then preview, something like
assert($preview ? false : true, "Render is faster then preview -
please press F6");
cube(); //just a silly example
would help.
With kind regards,
Michael Frey
_______________________________________________
OpenSCAD mailing list
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Rogier Wolff
2018-12-03 16:37:12 UTC
Permalink
Post by nop head
Yes I don't like the fact auto reload doesn't remember you have done F6. I
think it should remember the mode and do an automatic F6. I.e. you make
changes and the preview changes. Then you press F6 and get the CGAL render.
Then you make more changes it should update the CGAL view, not flip back to
preview.
The idea about the "preview" is that it's fast. It's a preview.

The idea about the F6 "render" is that it's probably slow.

These things don't always hold. When your model is simple, even the F6
render is fast. When your model is quite complex (or simple, but has
an intersect-with-the-XY-plane), even F5/preview will be slow.

But WHEN those rules hold, THEN it is often preferable to quickly show
the preview, than to spend ages doing the render.

It depends a bit on if, for your application, the preview is good
enough or not. In my workflow, the "render" is only done once, just
before I export-to-STL.

If you end up needing to go to the render and not the preview because
of some issue, then maybe indeed you'd want your suggested behaviour.

I use a separate editor and the "automatic reload and preview"
feature. Each time I hit "save" I would like the screen to update
quickly to show what I've changed. Even when I have just exported say
a sub-assembly to STL. So I would object to automatically keeping the
"render mode".

As the intersect=true is very slow even in preview mode, I would find
a feature that allows me to enable the intersect only when doing the
cgal render. That would, in my case, make the rendering "as expected":
I'd get a "thin" 3D object rendered quickly(*) and I have to wait for the
cgal render that allows export.

Roger.

(*) I'm not doing a complex intersection with a complex object. My
original object is a simple thin extrusion of the 2D object that I now
have as the destination. All planes of the object intersect the XY
plane at right angles, or don't intersect at all because they are
parallel. (and those last ones all lie in precisely two planes, Z=-2
and Z=+2).
Post by nop head
If F5 is too slow I add a render() call to my code to force the CGAL
render, even when F5 is pressed.
Post by klusacek
I have encountered a similar problem, solving it by a quick and dirty hack to
the openscad source code. Note, however, that you can easily create
self-intersecting surface, so use it with care.
The patch can be found here:http://atrey.karlin.mff.cuni.cz/~klusacek/openscad/index.html
- a few comments about the patch
- the observation that render can be faster then preview
--------
Looking at the patch file, I am confused why it has a makefile.
In my understanding, the makefile is automatically generated using qmake.
Also note that you can ignore the object folder. Those are also generated.
objects/comment_lexer.hxx is - if my memory serves me right - by GNU bison.
I think the patch could be a lot smaller when only patching the files that
needed patching.
On a side note: Why not use git?
https://github.com/openscad/openscad
and the .gitignore file
https://github.com/openscad/openscad/blob/master/.gitignore
is pretty good at preventing adding or diffing autogenerate files.
Using git would also allow you to open a pull request, so that we can look
into it if we want to adopt this patch into the official build..
I would be interested in seeing if there are any issues with our
regression tests.
When you open a pull request, those are run automatically for our major
platforms.
*For models with complicated CSG structure, the preview rendering can
easily last longer than the CGAL rendering.*
*It often overloads the graphics card, leaving user interface unresponsive
for several minutes.*
*I use external editor, using auto reload and preview function.*
*Unfortunately, auto reload always turns rendering into F5 mode everytime
I save the file in editor, which *
* lock up the user interface for several minutes in case of complex
models. *
Very very interesting. We could add an "Automatic Load and Render" option
or something like it.
The complicated thing about that would be, that leaving the wrong one on
for the wrong model would waste time.
For the case where render is faster then preview, something like
assert($preview ? false : true, "Render is faster then preview -
please press F6");
cube(); //just a silly example
would help.
With kind regards,
Michael Frey
_______________________________________________
OpenSCAD mailing list
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
_______________________________________________
OpenSCAD mailing list
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
--
** ***@BitWizard.nl ** http://www.BitWizard.nl/ ** +31-15-2049110 **
** Delftechpark 11 2628 XJ Delft, The Netherlands. KVK: 27239233 **
*-- BitWizard writes Linux device drivers for any device you may have! --*
The plan was simple, like my brother-in-law Phil. But unlike
Phil, this plan just might work.
David Klusacek
2018-12-03 20:33:04 UTC
Permalink
Post by Rogier Wolff
Post by nop head
Yes I don't like the fact auto reload doesn't remember you have done F6. I
think it should remember the mode and do an automatic F6. I.e. you make
changes and the preview changes. Then you press F6 and get the CGAL render.
Then you make more changes it should update the CGAL view, not flip back to
preview.
The idea about the "preview" is that it's fast. It's a preview.
Yes, but it is not always fast. There are occasions when it is not only slow
--- it literally hangs up the machine for many minutes, which is outrageous.
Post by Rogier Wolff
It depends a bit on if, for your application, the preview is good
enough or not. In my workflow, the "render" is only done once, just
before I export-to-STL.
I would of course like to use it that way. But my models tend to be so
complex that F5 in the end lasts longer than F6, and when it finishes it
displays all those z-buffer artifacts that it is of little use anyway. And,
more importantly, anytime I try to move the model with a mouse, I have to
wait for a new frame all that long time again. On the other hand, after
rendering it with F6 once, it can then be moved and rotated fluently.
Post by Rogier Wolff
I use a separate editor and the "automatic reload and preview"
feature. Each time I hit "save" I would like the screen to update
quickly to show what I've changed. Even when I have just exported say
a sub-assembly to STL. So I would object to automatically keeping the
"render mode".
That's not what I've suggested. I suggest that the render mode should stick
to what you were using the last time. If you were in F5 mode, auto reload
would display it in F5 again. It should start in F6 because F5 is not
interruptible and may hang the machine up. So if you wanted your model shown
using F5 from the beginning you would just click on that red x icon to stop
F6 rendering and then press F5. An inconvenience, I know, but that's nothing
when compared to having to wait 20 minutes before it allows me to pres F6,
having whole machine unusable all that time.
Post by Rogier Wolff
(*) I'm not doing a complex intersection with a complex object. My
original object is a simple thin extrusion of the 2D object that I now
have as the destination. All planes of the object intersect the XY
plane at right angles, or don't intersect at all because they are
parallel. (and those last ones all lie in precisely two planes, Z=-2
and Z=+2).
My models tend to be larger. I'm also not a fan of optimizing then number of
boolean operations so that it would render quickly. Nice execise, I admint
but I want to specify the shape as quickly as possible, have it
parametrized, and easily modifiable to have it printed as quickly as
possible.

By the way --- I suppose the main use of openscad is in 3D printing on
RepRap style printers, isn't it? Why then the `Export to STL’-function is
hidden in a submenu, even not having a keyboard shortcut? This is the last
step and most if not all previous steps have their hot keys. So perhaps this
one would deserve it too.

Regards,

-- DK
Florian Kirsch
2018-12-03 21:11:38 UTC
Permalink
_______________________________________________
OpenSCAD mailing list
***@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
nop head
2018-12-03 21:59:09 UTC
Permalink
It isn't normal for F5 to take longer than F6 to do booleans. Normally it
is many orders of magnitude faster. Either there is something unusual about
your model or your graphics card is very slow.

Just wrap it it in render() if you always want it to use CGAL. Then F5 and
F6 will do the same except F5 is not uninterruptible.
Post by David Klusacek
Post by David Klusacek
I would of course like to use it that way. But my models tend to be so
complex that F5 in the end lasts longer than F6 [...].
So if you wanted your model shown
using F5 from the beginning you would just click on that red x icon to
stop
Post by David Klusacek
F6 rendering and then press F5. An inconvenience, I know, but that's
nothing
Post by David Klusacek
when compared to having to wait 20 minutes before it allows me to pres
F6,
Post by David Klusacek
having whole machine unusable all that time.
20 minutes is obviously an insane amount of time for a 'preview'.
Would it help in any way if rendering with OpenCSG would be cancelable?
What kind of API should it provide to support that?
Florian
_______________________________________________
OpenSCAD mailing list
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
David Klusacek
2018-12-04 02:38:02 UTC
Permalink
I'm sending one of my problematic models in the attachment. I've tried it on
several recent computers, all of them having difficulty to render it using
F5 (it assumes my rotate_extrude() patch so the shape will render slightly
differently in your openscad but it should be comparably difficult model).

Thanks for pointing out the render() module, I didn't know about it. Never
the less I've already patched my copy of openscad to start in F6 and be
mode-sticky.

Regards,

-- DK
Post by nop head
It isn't normal for F5 to take longer than F6 to do booleans. Normally it
is many orders of magnitude faster. Either there is something unusual about
your model or your graphics card is very slow.
Just wrap it it in render() if you always want it to use CGAL. Then F5 and
F6 will do the same except F5 is not uninterruptible.
Post by David Klusacek
Post by David Klusacek
I would of course like to use it that way. But my models tend to be so
complex that F5 in the end lasts longer than F6 [...].
So if you wanted your model shown
using F5 from the beginning you would just click on that red x icon to
stop
Post by David Klusacek
F6 rendering and then press F5. An inconvenience, I know, but that's
nothing
Post by David Klusacek
when compared to having to wait 20 minutes before it allows me to pres
F6,
Post by David Klusacek
having whole machine unusable all that time.
20 minutes is obviously an insane amount of time for a 'preview'.
Would it help in any way if rendering with OpenCSG would be cancelable?
What kind of API should it provide to support that?
Florian
_______________________________________________
OpenSCAD mailing list
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
_______________________________________________
OpenSCAD mailing list
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
David Klusacek
2018-12-03 22:26:56 UTC
Permalink
Post by David Klusacek
Post by David Klusacek
So if you wanted your model shown
using F5 from the beginning you would just click on that red x icon to
stop
Post by David Klusacek
F6 rendering and then press F5. An inconvenience, I know, but that's
nothing
Post by David Klusacek
when compared to having to wait 20 minutes before it allows me to pres
F6,
Post by David Klusacek
having whole machine unusable all that time.
20 minutes is obviously an insane amount of time for a 'preview'.
Would it help in any way if rendering with OpenCSG would be cancelable?
What kind of API should it provide to support that?
Yes, but I doubt you can do anything once the program starts sending all the
triangles to the video card. The computer hangs because the GPU does not
accept any requests from the X server during that time. I tried that on
windows too, there only the openscad window stops responding and draws
nothing in F5 mode. Whereas X-server hangs but after very long time it
really displays the model.

I didn't study the sources so closely but I suspect that the reason for this
behaviour might be that all the triangles are sent to the card in a single GL
call.


David
Florian Kirsch
2018-12-03 22:54:28 UTC
Permalink
_______________________________________________
OpenSCAD mailing list
***@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
David Klusacek
2018-12-04 02:38:46 UTC
Permalink
Post by David Klusacek
I didn't study the sources so closely but I suspect that the reason for this
behaviour might be that all the triangles are sent to the card in a single GL
call.
OpenCSG is a multipass approach and switches forth and back to different
render buffers. Hence I think that a way to cancel could make sense.
Then it should be easily interruptible.

David
nop head
2018-12-04 09:20:39 UTC
Permalink
On my laptop I get this:

OpenSCAD 2018.11.29.ci630
http://www.openscad.org

Copyright (C) 2009-2018 The OpenSCAD Developers

This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your option)
any later version.

Loaded design 'C:/Users/ChrisP/Downloads/dklapka.scad'.

Used file cache size: 1 files

Compiling design (CSG Tree generation)...

Compiling design (CSG Products generation)...

ERROR: all points for rotate_extrude() must have the same X coordinate sign
(range is -0.70 -> 60.00)

ERROR: all points for rotate_extrude() must have the same X coordinate sign
(range is -0.66 -> 57.00)

ERROR: all points for rotate_extrude() must have the same X coordinate sign
(range is -0.66 -> 57.00)

ERROR: all points for rotate_extrude() must have the same X coordinate sign
(range is -4.00 -> 5.00)

ERROR: all points for rotate_extrude() must have the same X coordinate sign
(range is -5.00 -> 4.00)

Geometries in cache: 92

Geometry cache size in bytes: 29842128

CGAL Polyhedrons in cache: 15

CGAL cache size in bytes: 32565088

Compiling design (CSG Products normalization)...

Compiling background (1 CSG Trees)...

Normalized CSG tree has 466 elements

Compile and preview finished.

Total rendering time: 0 hours, 0 minutes, 51 seconds

Parsing design (AST generation)...

Compiling design (CSG Tree generation)...

Rendering Polygon Mesh using CGAL...

Geometries in cache: 337

Geometry cache size in bytes: 47071496

CGAL Polyhedrons in cache: 129

CGAL cache size in bytes: 902469008

Total rendering time: 0 hours, 10 minutes, 45 seconds

Top level object is a 3D object:

Simple: no

Vertices: 12277

Halfedges: 61390

Edges: 30695

Halffacets: 36844

Facets: 18422

Volumes: 3

WARNING: Object may not be a valid 2-manifold and may need repair!

Rendering finished.

So F5 is 51s and F6 nearly 11 minutes. I.e. much longer than F5 as
expected. However after F5 the GUI is very sluggish. The reason it is so
slow is the unusually high values for $fn of 180, 360 and 720. Setting it
to 32 make F5 three seconds and F6 33 seconds.

You could set $fn to a lower value for F5 using $ preview but for FDM style
printing you don't need it set that high. Better to set $fs and $fa.

$fs = 0.25;
$fa = $preview ? 6 : 1;

Produces a responsive preview and a smooth render.

You also have very high values for convexity, 10, 20, 30 and 50. That has
no effect on F6 but will slow down F5. The end result doesn't look like it
has convexity in double figures.



On Tue, 4 Dec 2018 at 02:21, David Klusacek <
Post by Ronaldo Persiano
Post by David Klusacek
I didn't study the sources so closely but I suspect that the reason
for this
Post by David Klusacek
behaviour might be that all the triangles are sent to the card in a
single GL
Post by David Klusacek
call.
OpenCSG is a multipass approach and switches forth and back to
different
render buffers. Hence I think that a way to cancel could make sense.
Then it should be easily interruptible.
David
_______________________________________________
OpenSCAD mailing list
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
MichaelAtOz
2018-12-06 02:11:30 UTC
Permalink
Post by David Klusacek
By the way --- I suppose the main use of openscad is in 3D printing on
RepRap style printers, isn't it?
You would be surprised on the wide use OpenSCAD get put to.
In addition to my Reprap style 3D printing, I use high quality printers via
eg Shapeways for functional parts and jewelry.
I make graphics for printed T-shirts.
Templates for woodwork etc.
Art.
Graphical documentation.
Design for solar thermal systems (that probably sounds more impressive than
reality)

Others do laser printing.
Very esoteric mathematical visualisations.

Everyone free to chime in with other uses.
Post by David Klusacek
Why then the `Export to STL’-function is
hidden in a submenu, even not having a keyboard shortcut? This is the last
step and most if not all previous steps have their hot keys. So perhaps this
one would deserve it too.
It does have the clickable icon tho.



-----
Admin - email* me if you need anything, or if I've done something stupid...

* click on my MichaelAtOz label, there is a link to email me.

Unless specifically shown otherwise above, my contribution is in the Public Domain; to the extent possible under law, I have waived all copyright and related or neighbouring rights to this work. Obviously inclusion of works of previous authors is not included in the above.

The TPP is no simple “trade agreement.” Fight it! http://www.ourfairdeal.org/ time is running out!
--
Sent from: http://forum.openscad.org/

David Klusacek
2018-12-02 14:07:45 UTC
Permalink
As for the makefile -- when I used qmake to generate it, it included
QtMultimedia lib (or something like that) in the list of libraries against
which it should link. I lack this one on my system and it was not needed by
openscad anyway, but I have to delete it from the generated Makefile (as I
didn't figure out where did it come from) to get rid of compilation error. I
just then forgot to delete the Makefile before making the patch. So, please,
ignore it.

As for the git: Unfortunately, my schedule is quite tight, so I only posted
the patch. Already posting an info to the mailing list was quite
intimidating and time consuming (I had to create an account, play a captcha
for a considerable time (are these still effective today when deepnets
already matched human performance?) and then ask the administrator for the
right to post). I guess that pushing this to the mainline would take more
time than I currently have. Also, I doubt if this patch would be generally
appreciated by all, as it introduces a built-in shape that could possibly
intersect itself.

I just needed to draw that shape so I did it and made it public. Feel free
to use it, or make it git pushable (in which case I would remove the `caps’
parameter as it could be possibly computed from the others).
Post by Michael Frey
The complicated thing about that would be, that leaving the wrong one on
for the wrong model would waste time.
I'm quite happy with the 'sticky preview' I just have. It is starting in F6
mode and then remembers whatever mode I was using, when it comes to reload.

The reason to start in F6 is that in the beginning, when the model is simple
(think of several cubes), F6 does not hurt that much anyway. Moreover it can
be always interrupted, which cannot be said about F5 mode which effectively
hangs up the machine for several tens of minutes, in case of larger models
(100k+ facets, deep CSG structure). So from my point of view F6 is less
harmful, because only the openscad is working and I can use the computer for
other things, wheres F5 cannot be interrupted and can overload the graphics
card, which in Linux causes that the X server temporarily stops redrawing
the user interface and I cannot do anything. At the same time CPU is idle.
With AMD drivers it even caused the video card driver restarts (several
times a second) so I changed the card to nVidia and used their binary blob
drivers. These are better, but still I have to wait about 20 minutes or
more, which is simply unacceptable.

So I'm generally fine with F6, the only thing that bugs me is that it lacks
colors and that the model disappears from the screen on reload long before
it is computed. It would be much better if it stayed there all the time so
that I could look at the old version (and be able to rotate it), while the
new one is being rendered (maybe the old one might be in grey color to avoid
confusion).
Post by Michael Frey
For the case where render is faster then preview, something like
___ assert($preview ? false : true, "Render is faster then preview -
please press F6");
___ cube(); //just a silly example
This approach does not solve anything because if the model would be
complicated, I would have to wait for 20 minutes before openscad realizes
I've pressed F6. And I would have to be very cautious in doing so in order
it would not want to redraw the screen again (such as if I moved the
openscad window before it finished rendering) --- in that case it would cost
another 20 minutes.


My feeling is that this is caused by two things. First -- it seems to me
(correct me if I'm wrong) that the CSG tree is converted to a disjunctive
normal form (formula like this a&!b&c | a&b&!c | ..., where a,b,c are
primitive objects, & is intersection, | is union, ! is negation). This by
itself can cause exponential blow up.

The second suspicion is that all the generated triangles are sent to the
graphics in a single display list. The card then tries to process this beast
and does not react to much simple requests from the X-server until it
finishes the rendering.


With kind regards,

David Klusacek
Post by Michael Frey
Post by klusacek
I have encountered a similar problem, solving it by a quick and dirty hack to
the openscad source code. Note, however, that you can easily create
self-intersecting surface, so use it with care.
http://atrey.karlin.mff.cuni.cz/~klusacek/openscad/index.html
* a few comments about the patch
* the observation that render can be faster then preview
--------
Looking at the patch file, I am confused why it has a makefile.
In my understanding, the makefile is automatically generated using qmake.
Also note that you can ignore the object folder. Those are also generated.
objects/comment_lexer.hxx is - if my memory serves me right - by GNU bison.
I think the patch could be a lot smaller when only patching the files
that needed patching.
On a side note: Why not use git?
___ https://github.com/openscad/openscad
and the .gitignore file
___ https://github.com/openscad/openscad/blob/master/.gitignore
is pretty good at preventing adding or diffing autogenerate files.
Using git would also allow you to open a pull request, so that we can
look into it if we want to adopt this patch into the official build..
I would be interested in seeing if there are any issues with our
regression tests.
When you open a pull request, those are run automatically for our major
platforms.
/For models with complicated CSG structure, the preview rendering
can easily last longer than the CGAL rendering./
/It often overloads the graphics card, leaving user interface
unresponsive for several minutes./
/I use external editor, using auto reload and preview function./
/Unfortunately, auto reload always turns rendering into F5 mode
everytime I save the file in editor, which //
//lock up the user interface for several minutes in case of complex
models. /
Very very interesting. We could add an "Automatic Load and Render"
option or something like it.
would help.
With kind regards,
Michael Frey
_______________________________________________
OpenSCAD mailing list
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Loading...