Twisty problem with scad-utils "sweep"

classic Classic list List threaded Threaded
33 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Twisty problem with scad-utils "sweep"

Laura Taalman
I'm trying to use scad-utils and the "sweep" module to make some cool math objects, but I am having a problem with things getting surprisingly twisty. I can't figure out why. I've attached two screenshots where you can see that the path starts twisting around quite sharply (and in addition in the log you can see there was a problem with finding construct_transform_path?). Do you have any advice as to how I could fix this problem?
Reply | Threaded
Open this post in threaded view
|

Re: Twisty problem with scad-utils "sweep"

kintel
Administrator
Hi Laura,

I didn’t see any attachments, but I assume you’re having similar symptoms as with the sweep-path demo:
https://github.com/openscad/list-comprehension-demos/blob/master/sweep-path.scad

In the list comprehension demos, we’ve only implemented one way of interpreting space curves. See here for some more info about what could be done:
https://github.com/openscad/openscad/wiki/OEP1%3A-Generalized-extrusion-module#discretized-space-curves

If you share your design, we might be able to look into this. We need more use-cases anyway to get the sweep function right.

 -Marius

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566
Reply | Threaded
Open this post in threaded view
|

Re: Twisty problem with scad-utils "sweep"

Laura Taalman
Sorry, I forgot to attach the pictures! Here is what I'm running into:



Reply | Threaded
Open this post in threaded view
|

Re: Twisty problem with scad-utils "sweep"

kintel
Administrator

On Sep 25, 2014, at 20:57 PM, Laura Taalman <[hidden email]> wrote:

> Sorry, I forgot to attach the pictures! Here is what I'm running into:
> […]

Thanks. That makes a lot of sense.
This should be fixable by calculating torsion minimizing reference frames for the sweep.

To recap what’s going on:
o sweep() takes a list of transformation matrices as parameter, instantiates the 2D object with each transformation and builds a surface around the result
o construct_transform_path() takes a list of 3D points and return said list of transformation matrices.

To fix this, we need to change construct_transform_path() to calculate these matrices (aka. reference frames) in a more suitable way (this is design dependent, but as mentioned on the wiki, a few standard ways would likely cover most use-cases).
An intro to reference frame calculation can be found here: http://webhome.cs.uvic.ca/~blob/courses/305/notes/pdf/ref-frames.pdf

Ideas or code is welcome :)

Oskar is also working on a native sweep implementation here (early work in progress): https://github.com/openscad/openscad/pull/918

 -Marius

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566
Reply | Threaded
Open this post in threaded view
|

Re: Twisty problem with scad-utils "sweep"

Oskar
In reply to this post by Laura Taalman
Hi Laura,

There is a bug in the construct_transform_path function. Can you try the following replacement?

function construct_torsion_minimizing_rotations(tangents) = [
        for (i = [0:len(tangents)-2])
                rotate_from_to(tangents[i],tangents[i+1])
];

function accumulate_rotations(rotations,acc_=[]) = let(i = len(acc_))
        i ==  len(rotations) ? acc_ :
        accumulate_rotations(rotations,
                i == 0 ? [rotations[0]] : concat(acc_, [ rotations[i] * acc_[i-1] ])
        );

function construct_transform_path(path) = let(
        l = len(path),
        tangents = [ for (i=[0:l-1]) tangent_path(path, i)],
        local_rotations = torsion_minimizing_rotations(concat([[0,0,1]],tangents)),
        rotations = accumulate_rotations(concat(local_rotations))
) [ for (i = [0:l-1]) construct_rt(rotations[i], path[i]) ];

It uses recursion, so it will not work with too small step sizes without a tail recursion optimization patch I run locally. Let me know if it work.

Best,

Oskar
Reply | Threaded
Open this post in threaded view
|

Re: Twisty problem with scad-utils "sweep"

Laura Taalman
Wow, thank you Oskar. I replaced the code for construct_transform_path with the three pieces of code you included. However I get this error when I try to run sweep:

WARNING: Ignoring unknown function 'torsion_minimizing_rotations'.

Apologies if the problem is something obvious that I did wrong when replacing the code. I am definitely in over my head here. Thank you for your help!

Laura
Reply | Threaded
Open this post in threaded view
|

Re: Twisty problem with scad-utils "sweep"

Oskar
Laura Taalman wrote
Wow, thank you Oskar. I replaced the code for construct_transform_path with the three pieces of code you included. However I get this error when I try to run sweep:

WARNING: Ignoring unknown function 'torsion_minimizing_rotations'.
Oops, must remember to test code before posting... Try this (also untested(!)):

function construct_torsion_minimizing_rotations(tangents) = [
        for (i = [0:len(tangents)-2])
                rotate_from_to(tangents[i],tangents[i+1])
];

function accumulate_rotations(rotations,acc_=[]) = let(i = len(acc_))
        i ==  len(rotations) ? acc_ :
        accumulate_rotations(rotations,
                i == 0 ? [rotations[0]] : concat(acc_, [ rotations[i] * acc_[i-1] ])
        );

function construct_transform_path(path) = let(
        l = len(path),
        tangents = [ for (i=[0:l-1]) tangent_path(path, i)],
        local_rotations = construct_torsion_minimizing_rotations(concat([[0,0,1]],tangents)),
        rotations = accumulate_rotations(concat(local_rotations))
) [ for (i = [0:l-1]) construct_rt(rotations[i], path[i]) ];

/Oskar
Reply | Threaded
Open this post in threaded view
|

Re: Twisty problem with scad-utils "sweep"

kintel
Administrator
In reply to this post by Laura Taalman

On Sep 26, 2014, at 12:02 PM, Laura Taalman <[hidden email]> wrote:

> WARNING: Ignoring unknown function 'torsion_minimizing_rotations’.
>
Looks like a typo in Oskar’s code:

If you rename the call to 'torsion_minimizing_rotations()’ to 'construct_torsion_minimizing_rotations()’, you should be one step further.

..and thanks for testing these early teasers. Once the functionality settles a bit, I promise a better API :)

 -Marius

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566
Reply | Threaded
Open this post in threaded view
|

Re: Twisty problem with scad-utils "sweep"

Laura Taalman
In reply to this post by Oskar
YES! This worked, even for very low step size. The result is beautifully smooth, at least for the simpler model that was based on a function equation. (See below for what happened with the other model.) Thank you so much for taking the time to write that new bit of code. Thank you! Here is a picture of what it looks like now:



The model based on data, however, didn't like this code. I got the following errors:

WARNING: Ignoring unknown function 'construct_transform_path'

ERROR: Recursion detected calling function 'accumulate_rotations'

However there were a lot of data points (3800 of them, and some models I'm doing have 10000), so maybe that is the problem you were referring to.
Reply | Threaded
Open this post in threaded view
|

Re: Twisty problem with scad-utils "sweep"

Laura Taalman
Actually, I spoke too soon. The screen output for both F5 and F6 look great, but when I then try to export to STL, then OpenSCAD crashes. Any advice would be appreciated; I've got a FormLabs machine I'm testing out and I wanted to print these as demos for a math workshop.
Reply | Threaded
Open this post in threaded view
|

Re: Twisty problem with scad-utils "sweep"

Oskar
Laura Taalman wrote
Actually, I spoke too soon. The screen output for both F5 and F6 look great, but when I then try to export to STL, then OpenSCAD crashes. Any advice would be appreciated; I've got a FormLabs machine I'm testing out and I wanted to print these as demos for a math workshop.
That is most likely due to self-intersecting geometry. I'd try dividing the shape into non-intersecting segments and union() them together.

/Oskar
Reply | Threaded
Open this post in threaded view
|

Re: Twisty problem with scad-utils "sweep"

Laura Taalman
Thank you, Oskar. I thought that might be the case, but not sure how to split this object to avoid it. Will think about that. Thanks for your very fast reply!
Reply | Threaded
Open this post in threaded view
|

Re: Twisty problem with scad-utils "sweep"

Oskar
Here is a start. It will not give a perfect result however.

segments = round(1/step);
parts = 7;
partsize = ceil(segments/parts);

for (part = [0:parts-1])
        assign(path = [for (s = [part * partsize : min((part+1)*partsize,segments)]) let(t = 360 * s / segments) 10*f(t)])
        assign(path_transforms = construct_transform_path(path))
                sweep(shape(), path_transforms);

The reason is that the function path_tangent in sweep() calculates one-sided tangent estimations at the endpoints. The results don't match perfectly at the start and end of different curves which give rise to cracks at each segment boundary. It is fairly easy to fix. One way would be to rewrite construct_transform_path() slightly to allow explicit specification of the tangents array. You can then easily supply analytically calculated derivatives, f'(t) in the same way as f(t).

Best,

Oskar
Reply | Threaded
Open this post in threaded view
|

Re: Twisty problem with scad-utils "sweep"

kintel
Administrator
In reply to this post by Laura Taalman
On Sep 29, 2014, at 16:11 PM, Laura Taalman <[hidden email]> wrote:

> […] then OpenSCAD crashes. Any advice would be appreciated;

Even if your model is self-intersecting, OpenSCAD shouldn’t crash.
Could you send me such an example together with a description on how you made it crash and any obvious error messages, your OS version and OpenSCAD version?
I can then take a look at the cause of the crash.

Cheers,

 -Marius

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566
Reply | Threaded
Open this post in threaded view
|

Re: Twisty problem with scad-utils "sweep"

Laura Taalman
The code I am using is below. F5 works fine, as does F6. But File/Export/Export as STL lets me choose where to save the file and then immediately crashes after that. No error message except the usual Mac "your program has unexpectedly closed" message.

While testing just now I noticed that the crash happens with step = 0.001 and step = 0.005 but that the model actually exports successfully with step = 0.01. So maybe this is just too fine a mesh?

*****

use <scad-utils/shapes.scad>

////////////////////////////////////////////////////////////////////
// parameters

$fn=48;
step = 0.01; // use 0.005 for draft, 0.001 for final

wire_diameter = 1.2;
wire_radius = wire_diameter/2;

ball_diameter = 15;
ball_radius = ball_diameter/2;

function shape() = circle(wire_radius);

////////////////////////////////////////////////////////////////////
// ball 1

function f(t) =  
 [ cos(7*t)*cos(2*t),
   cos(7*t)*sin(4*t),
   sin(7*t)
 ];

sweeper();

////////////////////////////////////////////////////////////////////
// module for sweeping out the curve

module sweeper(){
        path = [for (t=[0:step:1-step]) ball_radius*f(t*360)];
        path_transforms = construct_transform_path(path);
        sweep(shape(), path_transforms, true);
}
Reply | Threaded
Open this post in threaded view
|

Re: Twisty problem with scad-utils "sweep"

Laura Taalman
In reply to this post by Oskar
Thank you again, Oskar. I'll look into this option also, if I can't get the crash to stop.
Reply | Threaded
Open this post in threaded view
|

Re: Twisty problem with scad-utils "sweep"

kintel
Administrator
In reply to this post by Oskar
On Sep 29, 2014, at 16:27 PM, Oskar <[hidden email]> wrote:

> That is most likely due to self-intersecting geometry. I'd try dividing the
> shape into non-intersecting segments and union() them together.
>
The crash is not related to the shape being self-intersecting, but to degenerate polygons being generated in the case where we stitch together the ends of the shape to create a closed surface:

This can easily be seen on a minimally modified trefoil knot example using your new construct_transform_path() function: http://i.imgur.com/mxsd4s9.png
The old function didn’t have this problem as the end of the swept shape lined up nicely with the beginning.

This triggers an exception since one of the resulting quads cannot be projected into a 2D plane for tessellation:

#8 0x00000001024244ab in CGAL::precondition_fail(char const*, char const*, int, char const*) ()
#9 0x0000000100130186 in CGAL::Sign CGAL::orientation_2 […]
#10 0x00000001000fcef1 in CGAL::Sign CGAL::orientation_2 […]
#11 0x00000001000fa897 in PolysetUtils::triangulate_polygon() at openscad/src/polyset-utils.cc:169
#12 0x00000001000fb428 in PolysetUtils::tessellate_faces(PolySet const&, PolySet&) at openscad/src/polyset-utils.cc:233

TODO:
o Catch the exception, report as an error, lose the shape (just to keep the process from crashing)
o Return some sort of valid triangulation even though the polygon cannot be projected into a plane
o Choose a valid triangulation in the sweep() function
o Figure out how to deal with closed sweeps where the shapes don’t line up
o Figure out if we should deal with closed sweeps of symmetric shapes

 -Marius

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566
Reply | Threaded
Open this post in threaded view
|

Re: Twisty problem with scad-utils "sweep"

kintel
Administrator
In reply to this post by Laura Taalman
On Sep 30, 2014, at 14:06 PM, Laura Taalman <[hidden email]> wrote:

> Thank you again, Oskar. I'll look into this option also, if I can't get the
> crash to stop.
>
Laura: We’ll fix this as soon as possible, but if you’re in a hurry:
Try to remove the last (true) parameter to sweep. This is what makes the swept surface closed and causes the crash. If you play with different formulas and parametrizations, you might be able to find some working combinations which works when putting this parameter back.

 -Marius
 
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566
Reply | Threaded
Open this post in threaded view
|

Re: Twisty problem with scad-utils "sweep"

Laura Taalman
Thanks!

I tried the fast-fix but I still have the crashing problem even with the "true" changed to "false" or removed. I'm not in a "today" kind of hurry but it would be great to be able to use this in a week or two. Any chance of that or any other things I could try?

Thank you very much for all your help. This only happens for particular functions; it is the weird kinkiness of this model that is definitely causing the problems. Nicer, smoother-looking functions export just fine.
Reply | Threaded
Open this post in threaded view
|

Re: Twisty problem with scad-utils "sweep"

kintel
Administrator

On Sep 30, 2014, at 16:05 PM, Laura Taalman <[hidden email]> wrote:

> I tried the fast-fix but I still have the crashing problem even with the
> "true" changed to "false" or removed.

You found another manifestation of the same issue, this time it’s self-intersecting of tight corners.
Again it’s not actually the self-intersection itself that causes the crash, but the fact that we try to triangulate non-planar polygons created where two of the transformed shapes touch or intersect each other.
See your model parametrized from 0.87 to 0.91: http://i.imgur.com/NOamusP.png

This case is harder to fix; even if the tessellation is made more robust, I’m not sure the resulting mesh will be accepted by a slicer.

I don’t have any good ideas off the top of my head for how to fix this. Perhaps Oskar has some nuggets of wisdom to share :)

 -Marius


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566
12