
12

I'm trying to use scadutils 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?


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

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 usecases).
An intro to reference frame calculation can be found here: http://webhome.cs.uvic.ca/~blob/courses/305/notes/pdf/refframes.pdfIdeas 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/openscadhttp://openscad.org  https://flattr.com/thing/121566


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_[i1] ])
);
function construct_transform_path(path) = let(
l = len(path),
tangents = [ for (i=[0:l1]) tangent_path(path, i)],
local_rotations = torsion_minimizing_rotations(concat([[0,0,1]],tangents)),
rotations = accumulate_rotations(concat(local_rotations))
) [ for (i = [0:l1]) 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


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


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_[i1] ])
);
function construct_transform_path(path) = let(
l = len(path),
tangents = [ for (i=[0:l1]) tangent_path(path, i)],
local_rotations = construct_torsion_minimizing_rotations(concat([[0,0,1]],tangents)),
rotations = accumulate_rotations(concat(local_rotations))
) [ for (i = [0:l1]) construct_rt(rotations[i], path[i]) ];
/Oskar

Administrator

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/openscadhttp://openscad.org  https://flattr.com/thing/121566


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.


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.


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 selfintersecting geometry. I'd try dividing the shape into nonintersecting segments and union() them together.
/Oskar


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!


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:parts1])
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 onesided 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


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 <scadutils/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:1step]) ball_radius*f(t*360)];
path_transforms = construct_transform_path(path);
sweep(shape(), path_transforms, true);
}


Thank you again, Oskar. I'll look into this option also, if I can't get the crash to stop.

Administrator

On Sep 29, 2014, at 16:27 PM, Oskar < [hidden email]> wrote:
> That is most likely due to selfintersecting geometry. I'd try dividing the
> shape into nonintersecting segments and union() them together.
>
The crash is not related to the shape being selfintersecting, 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.pngThe 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/polysetutils.cc:169
#12 0x00000001000fb428 in PolysetUtils::tessellate_faces(PolySet const&, PolySet&) at openscad/src/polysetutils.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/openscadhttp://openscad.org  https://flattr.com/thing/121566

Administrator

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/openscadhttp://openscad.org  https://flattr.com/thing/121566


Thanks!
I tried the fastfix 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, smootherlooking functions export just fine.

Administrator

On Sep 30, 2014, at 16:05 PM, Laura Taalman < [hidden email]> wrote:
> I tried the fastfix 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 selfintersecting of tight corners.
Again it’s not actually the selfintersection itself that causes the crash, but the fact that we try to triangulate nonplanar 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.pngThis 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/openscadhttp://openscad.org  https://flattr.com/thing/121566

12
