
123

Hi, long time OpenSCAD user, first time poster.
I want to export a model I've designed in OpenSCAD in a form that I can import into a more 'feature rich' CAD package, so I can do some nice renders of it. I've looked at Blender OpenSCAD import scripts, but these seem to be rather limited, and the only other apparent way to export the model, and retain geometry (rather than export as STL), seems to be to export as CSG, and import into FreeCAD  the only tool I've found that can cope with OpenSCAD CSG files.
FreeCAD's CSG import doesn't support OpenSCAD functions such as 'hull' and 'minkowski', which I've used to give my design nice rounded edges. Fortunately, most of my parts are 2D extrusions, as I plan to lasercut most of it, and it's relatively easy to reduce minkowski and hull functions to squares, circles and polygons.
However, FreeCAD (on Mac OS X at least) doesn't seem to like unions of lots of circles, squares and polygons, and drops geometry, creating holes from overlapping parts when I import them. Also, some shapes are difficult to translate into circles and squares alone. So I've come up a script that, to some extent, replicates 2D hull and minkowski with just circles and a polygon. With an input of the points of the shape, it draws a circle of a given radius at each point, then calculates the tangents that connect all the circles, and creates a polygon. With a linear extrusion, FreeCAD seems happy with this. Here's my code so far:
radius = 5;
shape = [ 10,10 , 0,40 , 40,80 , 100,80 , 50,0];
x1 = shape[0];
y1 = shape[1];
x2 = shape[2];
y2 = shape[3];
x3 = shape[4];
y3 = shape[5];
x4 = shape[6];
y4 = shape[7];
x5 = shape[8];
y5 = shape[9];
linear_extrude (height=5)
union () {
translate ([x1,y1]) circle (r=radius);
translate ([x2,y2]) circle (r=radius);
translate ([x3,y3]) circle (r=radius);
translate ([x4,y4]) circle (r=radius);
translate ([x5,y5]) circle (r=radius);
polygon ([
tangent_1 (x1,y1,x2,y2,radius),
tangent_2 (x1,y1,x2,y2,radius),
tangent_1 (x2,y2,x3,y3,radius),
tangent_2 (x2,y2,x3,y3,radius),
tangent_1 (x3,y3,x4,y4,radius),
tangent_2 (x3,y3,x4,y4,radius),
tangent_1 (x4,y4,x5,y5,radius),
tangent_2 (x4,y4,x5,y5,radius),
tangent_1 (x5,y5,x1,y1,radius),
tangent_2 (x5,y5,x1,y1,radius),
]);
}
function tangent_1 (x_1, y_1, x_2, y_2, rad) =
let (
x_delta = x_2x_1,
y_delta = y_2y_1,
theta = atan2(y_delta,x_delta)+360,
xa = x_1+(cos(90+theta)*rad),
ya = y_1+(sin(90+theta)*rad),
xb = xa+x_delta,
yb = ya+y_delta
)
[xa,ya];
function tangent_2 (x_1,y_1,x_2,y_2,rad) =
let (
x_delta = x_2x_1,
y_delta = y_2y_1,
theta = atan2(y_delta,x_delta),
xa = x_1+(cos(90+theta)*rad),
ya = y_1+(sin(90+theta)*rad),
xb = xa+x_delta,
yb = ya+y_delta
)
[xb,yb];
This seems to produce a valid CSG shape, that I can import into FreeCAD, displays correctly, and can be exported as a STEP file to bring into other CAD programs with better rendering engines (Blender/Fusion360 are the ones I've briefly tested).
I'm nearly at my limit of maths/programming, so I'm having difficulty with a few things:
1. I'd really like to be able to put as few (minimum 3) or as many points in for the shape (currently 5), but I can't work out the way of iterating the function through all the points, and then back to the first again.
2. Having a different radius for each point would be nice too (eg shape = [ [x1,y1,r1] , [x2,y2r2], ... ] ), but I think that needs some extra trig to calculate the tangents.
3. Finally, it's not a million miles away from another 'hull' requested feature (I've seen it asked about on the forum before); that of have a point outside the hull, to create an indent into the shape. If you change the shape to:
shape = [ 50,50 , 0,40 , 40,80 , 100,80 , 50,0];
You can see it attempts to draw the indentation, but it gets the tangent wrong, because it needs to use inner tangent lines, rather than outer tangent lines. I think it would be possible to create a script that deals with these (the maths is here: http://www.ambrsoft.com/TrigoCalc/Circles2/Circles2Tangent_.htm ), and points outside the hull could be identified by using 'r', perhaps, then the 'r' circles differenced from the polygon shape, rather than unioned. I could probably use conditional operators ( https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#Conditional_Operator ) or some kind of recursive function ( https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#Recursive_functions ). But then I'm really at the limits of my maths/programming!
Unless you know of any other way of getting a model out of OpenSCAD, while maintaining the geometry, any pointers/help with this script would be greatly appreciated!
Ian S.


Nice job so far Ian. I am hoping to do similar for my printer parts, will read with interest...
Tapped on my mobile phone.
> On 18 Mar 2016, at 10:13, droftarts < [hidden email]> wrote:
>
> Hi, long time OpenSCAD user, first time poster.
>
> I want to export a model I've designed in OpenSCAD in a form that I can
> import into a more 'feature rich' CAD package, so I can do some nice renders
> of it. I've looked at Blender OpenSCAD import scripts, but these seem to be
> rather limited, and the only other apparent way to export the model, and
> retain geometry (rather than export as STL), seems to be to export as CSG,
> and import into FreeCAD  the only tool I've found that can cope with
> OpenSCAD CSG files.
>
> FreeCAD's CSG import doesn't support OpenSCAD functions such as 'hull' and
> 'minkowski', which I've used to give my design nice rounded edges.
> Fortunately, most of my parts are 2D extrusions, as I plan to lasercut most
> of it, and it's relatively easy to reduce minkowski and hull functions to
> squares, circles and polygons.
>
> However, FreeCAD (on Mac OS X at least) doesn't seem to like unions of lots
> of circles, squares and polygons, and drops geometry, creating holes from
> overlapping parts when I import them. Also, some shapes are difficult to
> translate into circles and squares alone. So I've come up a script that, to
> some extent, replicates 2D hull and minkowski with just circles and a
> polygon. With an input of the points of the shape, it draws a circle of a
> given radius at each point, then calculates the tangents that connect all
> the circles, and creates a polygon. With a linear extrusion, FreeCAD seems
> happy with this. Here's my code so far:
>
> radius = 5;
> shape = [ 10,10 , 0,40 , 40,80 , 100,80 , 50,0];
>
> x1 = shape[0];
> y1 = shape[1];
> x2 = shape[2];
> y2 = shape[3];
> x3 = shape[4];
> y3 = shape[5];
> x4 = shape[6];
> y4 = shape[7];
> x5 = shape[8];
> y5 = shape[9];
>
> linear_extrude (height=5)
>
> union () {
> translate ([x1,y1]) circle (r=radius);
> translate ([x2,y2]) circle (r=radius);
> translate ([x3,y3]) circle (r=radius);
> translate ([x4,y4]) circle (r=radius);
> translate ([x5,y5]) circle (r=radius);
>
> polygon ([
> tangent_1 (x1,y1,x2,y2,radius),
> tangent_2 (x1,y1,x2,y2,radius),
> tangent_1 (x2,y2,x3,y3,radius),
> tangent_2 (x2,y2,x3,y3,radius),
> tangent_1 (x3,y3,x4,y4,radius),
> tangent_2 (x3,y3,x4,y4,radius),
> tangent_1 (x4,y4,x5,y5,radius),
> tangent_2 (x4,y4,x5,y5,radius),
> tangent_1 (x5,y5,x1,y1,radius),
> tangent_2 (x5,y5,x1,y1,radius),
> ]);
> }
>
> function tangent_1 (x_1, y_1, x_2, y_2, rad) =
> let (
> x_delta = x_2x_1,
> y_delta = y_2y_1,
> theta = atan2(y_delta,x_delta)+360,
> xa = x_1+(cos(90+theta)*rad),
> ya = y_1+(sin(90+theta)*rad),
> xb = xa+x_delta,
> yb = ya+y_delta
> )
>
> [xa,ya];
>
> function tangent_2 (x_1,y_1,x_2,y_2,rad) =
> let (
> x_delta = x_2x_1,
> y_delta = y_2y_1,
> theta = atan2(y_delta,x_delta),
> xa = x_1+(cos(90+theta)*rad),
> ya = y_1+(sin(90+theta)*rad),
> xb = xa+x_delta,
> yb = ya+y_delta
> )
>
> [xb,yb];
>
> This seems to produce a valid CSG shape, that I can import into FreeCAD,
> displays correctly, and can be exported as a STEP file to bring into other
> CAD programs with better rendering engines (Blender/Fusion360 are the ones
> I've briefly tested).
>
> I'm nearly at my limit of maths/programming, so I'm having difficulty with a
> few things:
> 1. I'd really like to be able to put as few (minimum 3) or as many points in
> for the shape (currently 5), but I can't work out the way of iterating the
> function through all the points, and then back to the first again.
> 2. Having a different radius for each point would be nice too (eg shape = [
> [x1,y1,r1] , [x2,y2r2], ... ] ), but I think that needs some extra trig to
> calculate the tangents.
> 3. Finally, it's not a million miles away from another 'hull' requested
> feature (I've seen it asked about on the forum before); that of have a point
> outside the hull, to create an indent into the shape. If you change the
> shape to:
>
> shape = [ 50,50 , 0,40 , 40,80 , 100,80 , 50,0];
>
> You can see it attempts to draw the indentation, but it gets the tangent
> wrong, because it needs to use inner tangent lines, rather than outer
> tangent lines. I think it would be possible to create a script that deals
> with these (the maths is here:
> http://www.ambrsoft.com/TrigoCalc/Circles2/Circles2Tangent_.htm ), and
> points outside the hull could be identified by using 'r', perhaps, then the
> 'r' circles differenced from the polygon shape, rather than unioned. I
> could probably use conditional operators (
> https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#Conditional_Operator> ) or some kind of recursive function (
> https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#Recursive_functions> ). But then I'm really at the limits of my maths/programming!
>
> Unless you know of any other way of getting a model out of OpenSCAD, while
> maintaining the geometry, any pointers/help with this script would be
> greatly appreciated!
>
> Ian S.
>
>
>
> 
> View this message in context: http://forum.openscad.org/ScripttoreplicatehullandminkoswkiforCSGexportimportintoFreeCADtp16537.html> Sent from the OpenSCAD mailing list archive at Nabble.com.
>
> _______________________________________________
> OpenSCAD mailing list
> [hidden email]
> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org>
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


Just a quick side note  especially for 2D extrusions, the double
offset() command can do an awesome job of rounding corners.
example: offset (r=+5) offset (r=5) square(20);
of course, offset isn't supported in FreeCAD either.
On 3/18/2016 6:13 AM, droftarts wrote:
> Hi, long time OpenSCAD user, first time poster.
>
> I want to export a model I've designed in OpenSCAD in a form that I can
> import into a more 'feature rich' CAD package, so I can do some nice renders
> of it. I've looked at Blender OpenSCAD import scripts, but these seem to be
> rather limited, and the only other apparent way to export the model, and
> retain geometry (rather than export as STL), seems to be to export as CSG,
> and import into FreeCAD  the only tool I've found that can cope with
> OpenSCAD CSG files.
>
> FreeCAD's CSG import doesn't support OpenSCAD functions such as 'hull' and
> 'minkowski', which I've used to give my design nice rounded edges.
> Fortunately, most of my parts are 2D extrusions, as I plan to lasercut most
> of it, and it's relatively easy to reduce minkowski and hull functions to
> squares, circles and polygons.
>
> However, FreeCAD (on Mac OS X at least) doesn't seem to like unions of lots
> of circles, squares and polygons, and drops geometry, creating holes from
> overlapping parts when I import them. Also, some shapes are difficult to
> translate into circles and squares alone. So I've come up a script that, to
> some extent, replicates 2D hull and minkowski with just circles and a
> polygon. With an input of the points of the shape, it draws a circle of a
> given radius at each point, then calculates the tangents that connect all
> the circles, and creates a polygon. With a linear extrusion, FreeCAD seems
> happy with this. Here's my code so far:
>
> radius = 5;
> shape = [ 10,10 , 0,40 , 40,80 , 100,80 , 50,0];
>
> x1 = shape[0];
> y1 = shape[1];
> x2 = shape[2];
> y2 = shape[3];
> x3 = shape[4];
> y3 = shape[5];
> x4 = shape[6];
> y4 = shape[7];
> x5 = shape[8];
> y5 = shape[9];
>
> linear_extrude (height=5)
>
> union () {
> translate ([x1,y1]) circle (r=radius);
> translate ([x2,y2]) circle (r=radius);
> translate ([x3,y3]) circle (r=radius);
> translate ([x4,y4]) circle (r=radius);
> translate ([x5,y5]) circle (r=radius);
>
> polygon ([
> tangent_1 (x1,y1,x2,y2,radius),
> tangent_2 (x1,y1,x2,y2,radius),
> tangent_1 (x2,y2,x3,y3,radius),
> tangent_2 (x2,y2,x3,y3,radius),
> tangent_1 (x3,y3,x4,y4,radius),
> tangent_2 (x3,y3,x4,y4,radius),
> tangent_1 (x4,y4,x5,y5,radius),
> tangent_2 (x4,y4,x5,y5,radius),
> tangent_1 (x5,y5,x1,y1,radius),
> tangent_2 (x5,y5,x1,y1,radius),
> ]);
> }
>
> function tangent_1 (x_1, y_1, x_2, y_2, rad) =
> let (
> x_delta = x_2x_1,
> y_delta = y_2y_1,
> theta = atan2(y_delta,x_delta)+360,
> xa = x_1+(cos(90+theta)*rad),
> ya = y_1+(sin(90+theta)*rad),
> xb = xa+x_delta,
> yb = ya+y_delta
> )
>
> [xa,ya];
>
> function tangent_2 (x_1,y_1,x_2,y_2,rad) =
> let (
> x_delta = x_2x_1,
> y_delta = y_2y_1,
> theta = atan2(y_delta,x_delta),
> xa = x_1+(cos(90+theta)*rad),
> ya = y_1+(sin(90+theta)*rad),
> xb = xa+x_delta,
> yb = ya+y_delta
> )
>
> [xb,yb];
>
> This seems to produce a valid CSG shape, that I can import into FreeCAD,
> displays correctly, and can be exported as a STEP file to bring into other
> CAD programs with better rendering engines (Blender/Fusion360 are the ones
> I've briefly tested).
>
> I'm nearly at my limit of maths/programming, so I'm having difficulty with a
> few things:
> 1. I'd really like to be able to put as few (minimum 3) or as many points in
> for the shape (currently 5), but I can't work out the way of iterating the
> function through all the points, and then back to the first again.
> 2. Having a different radius for each point would be nice too (eg shape = [
> [x1,y1,r1] , [x2,y2r2], ... ] ), but I think that needs some extra trig to
> calculate the tangents.
> 3. Finally, it's not a million miles away from another 'hull' requested
> feature (I've seen it asked about on the forum before); that of have a point
> outside the hull, to create an indent into the shape. If you change the
> shape to:
>
> shape = [ 50,50 , 0,40 , 40,80 , 100,80 , 50,0];
>
> You can see it attempts to draw the indentation, but it gets the tangent
> wrong, because it needs to use inner tangent lines, rather than outer
> tangent lines. I think it would be possible to create a script that deals
> with these (the maths is here:
> http://www.ambrsoft.com/TrigoCalc/Circles2/Circles2Tangent_.htm ), and
> points outside the hull could be identified by using 'r', perhaps, then the
> 'r' circles differenced from the polygon shape, rather than unioned. I
> could probably use conditional operators (
> https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#Conditional_Operator> ) or some kind of recursive function (
> https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#Recursive_functions> ). But then I'm really at the limits of my maths/programming!
>
> Unless you know of any other way of getting a model out of OpenSCAD, while
> maintaining the geometry, any pointers/help with this script would be
> greatly appreciated!
>
> Ian S.
>
>
>
> 
> View this message in context: http://forum.openscad.org/ScripttoreplicatehullandminkoswkiforCSGexportimportintoFreeCADtp16537.html> Sent from the OpenSCAD mailing list archive at Nabble.com.
>
> _______________________________________________
> OpenSCAD mailing list
> [hidden email]
> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org>
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


Thanks, Alex!
A note about the current script:
 The points need to be in a clockwise direction, or it draws the polygon on the wrong side of the circles, as it only calculates the tangent on one side of the circle (out of a possible four tangents)
I did try another approach, which was to draw a polygon from each point, draw a circle on each point, then draw a square of width r*2 between each point, but this caused problems in FreeCAD. As each element (polygon, circles, squares) is stored in the CSG, there were multiple overlapping elements, and FreeCAD seemed to randomly put holes in. A 2D (ie no linear_extrude) output of the above script still doesn't show correctly in FreeCAD (there are some parts that are not coloured in), but the 3D version does show correctly.
Ian


Thanks shadowwynd, and I agree, offest is very useful. I'd tried that approach for this problem, too, before finding it didn't import into FreeCAD either!
Ian S


Hi Stuart,
Here is a general version that takes a list of points and makes a rounded polygon. radius = 5; shape = [ [10,10] , [0,40] , [40,80] , [100,80] , [50,0] ]; linear_extrude (height=5) rounded_polygon(shape, radius);
function next(i) = (i + 1) % len(shape);
function tangents(i) = [tangent(shape[i], shape[next(i)],radius, 0), tangent(shape[i], shape[next(i)],radius, 1)];
function flatten(list) = [for(p = list) for(x = p) x];
module rounded_polygon(points, radius) union () { for(point = shape) translate(point) circle (r = radius);
polygon(flatten([for(i = [0 : len(shape)  1]) tangents(i)])); }
function tangent(p1, p2, rad, side) = let ( x_delta = p2.x  p1.x, y_delta = p2.y  p1.y, theta = atan2(y_delta, x_delta), xa = p1.x +(cos(90 + theta) * rad), ya = p1.y +(sin(90 + theta) * rad), xb = xa + x_delta, yb = ya + y_delta )
side ? [xb, yb] : [xa, ya];
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


Here's a simpler one:
radius = 5; shape = [ [10,10] , [0,40] , [40,80] , [100,80] , [50,0] ]; linear_extrude (height=5) rounded_polygon(shape, radius);
function next(i) = (i + 1) % len(shape);
function tangents(i, side) = tangent(shape[i], shape[next(i)],radius, side);
module rounded_polygon(points, radius) union () { for(point = shape) translate(point) circle (r = radius);
polygon([for(i = [0 : len(shape)  1]) for(side = [0, 1]) tangents(i, side)]); }
function tangent(p1, p2, rad, side) = let ( x_delta = p2.x  p1.x, y_delta = p2.y  p1.y, theta = atan2(y_delta, x_delta), xa = p1.x +(cos(90 + theta) * rad), ya = p1.y +(sin(90 + theta) * rad), xb = xa + x_delta, yb = ya + y_delta )
side ? [xb, yb] : [xa, ya];
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


Hi nophead
Wow! Thanks for the reply, that solves what I need at the moment. I knew there had to be a way to iterate this, but just couldn't see it. That gives me plenty to wrap my head around; I'd perhaps like to extend it to allow for different radii.
I've been spending some time with your Mendel90 OpenSCAD files recently, and have learnt a huge amount from that!
Ian S
P.S. Who's Stuart?!


Here is a multi radii version. It looks right but somebody might want to check my maths as it is much simpler than the link you provided.
$fn = 100;
shape = [ [10, 10, 8], [0, 40, 3], [40, 80, 5], [100, 80, 10], [50, 0, 20] ];
linear_extrude (height = 5) rounded_polygon(shape);
function next(i) = (i + 1) % len(shape);
function tangents(i, side) = tangent(shape[i], shape[next(i)], side);
module rounded_polygon(points, radius) union () { for(i = [0 : len(shape)  1]) translate([shape[i].x, shape[i].y]) #circle(shape[i][2]);
polygon([for(i = [0 : len(shape)  1]) for(side = [0, 1]) tangents(i, side)]); }
function tangent(p1, p2, side) = let ( r1 = p1[2], r2 = p2[2], dx = p2.x  p1.x, dy = p2.y  p1.y, d = sqrt(dx * dx + dy * dy), theta = atan2(dy, dx) + acos((r1  r2) / d), xa = p1.x +(cos(theta) * r1), ya = p1.y +(sin(theta) * r1), xb = p2.x +(cos(theta) * r2), yb = p2.y +(sin(theta) * r2) )
side ? [xb, yb] : [xa, ya];
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


This version seems to handle the negative radii case:
$fn = 100;
shape = [ [10, 10, 8], [0, 40, 3], [40, 50, 10], [100, 80, 10], [50, 0, 20] ];
linear_extrude (height = 5) rounded_polygon(shape);
function next(i) = (i + 1) % len(shape);
function tangents(i, side) = tangent(shape[i], shape[next(i)], side);
module rounded_polygon(points, radius) difference() { union () { for(i = [0 : len(shape)  1]) translate([shape[i].x, shape[i].y]) if(shape[i][2] > 0) circle(shape[i][2]);
polygon([for(i = [0 : len(shape)  1]) for(side = [0, 1]) tangents(i, side)]); } for(i = [0 : len(shape)  1]) translate([shape[i].x, shape[i].y]) if(shape[i][2] < 0) circle(shape[i][2]); }
function tangent(p1, p2, side) = let ( r1 = p1[2], r2 = p2[2], dx = p2.x  p1.x, dy = p2.y  p1.y, d = sqrt(dx * dx + dy * dy), theta = atan2(dy, dx) + acos((r1  r2) / d), xa = p1.x +(cos(theta) * r1), ya = p1.y +(sin(theta) * r1), xb = p2.x +(cos(theta) * r2), yb = p2.y +(sin(theta) * r2) )
side ? [xb, yb] : [xa, ya];
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


Slightly more efficient version that only calls tangent once per corner.
$fn = 100;
shape = [ [10, 10, 8], [0, 40, 3], [40, 50, 10], [100, 80, 10], [50, 0, 20] ];
linear_extrude (height = 5) rounded_polygon(shape);
function next(i) = (i + 1) % len(shape);
function tangents(i, side) = tangent(shape[i], shape[next(i)], side);
module rounded_polygon(points, radius) difference() { union () { for(i = [0 : len(shape)  1]) translate([shape[i].x, shape[i].y]) if(shape[i][2] > 0) circle(shape[i][2]);
polygon([for(i = [0 : len(shape)  1]) for(side = [0, 1]) tangents(i)[side]]); } for(i = [0 : len(shape)  1]) translate([shape[i].x, shape[i].y]) if(shape[i][2] < 0) circle(shape[i][2]); }
function tangent(p1, p2) = let ( r1 = p1[2], r2 = p2[2], dx = p2.x  p1.x, dy = p2.y  p1.y, d = sqrt(dx * dx + dy * dy), theta = atan2(dy, dx) + acos((r1  r2) / d), xa = p1.x +(cos(theta) * r1), ya = p1.y +(sin(theta) * r1), xb = p2.x +(cos(theta) * r2), yb = p2.y +(sin(theta) * r2) )[ [xa, ya], [xb, yb] ];
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


Actually that still called tangent twice, this version calls it once.
$fn = 100;
shape = [ [10, 10, 8], [0, 40, 3], [40, 50, 10], [100, 80, 10], [50, 0, 20] ];
linear_extrude (height = 5) rounded_polygon(shape);
function next(i) = (i + 1) % len(shape);
function tangents(i, side) = tangent(shape[i], shape[next(i)], side);
module rounded_polygon(points, radius) difference() { union () { for(i = [0 : len(shape)  1]) translate([shape[i].x, shape[i].y]) if(shape[i][2] > 0) circle(shape[i][2]);
polygon([for(i = [0 : len(shape)  1]) let(ends = tangents(i)) for(end = [0, 1]) ends[end]]); } for(i = [0 : len(shape)  1]) translate([shape[i].x, shape[i].y]) if(shape[i][2] < 0) circle(shape[i][2]); }
function tangent(p1, p2) = let ( r1 = p1[2], r2 = p2[2], dx = p2.x  p1.x, dy = p2.y  p1.y, d = sqrt(dx * dx + dy * dy), theta = atan2(dy, dx) + acos((r1  r2) / d), xa = p1.x +(cos(theta) * r1), ya = p1.y +(sin(theta) * r1), xb = p2.x +(cos(theta) * r2), yb = p2.y +(sin(theta) * r2) )[ [xa, ya], [xb, yb] ];
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


Fixed all the references to shape instead of points and removed single use functions.
$fn = 100;
shape1 = [ [10, 10, 8], [0, 40, 3], [40, 50, 10], [100, 80, 10], [50, 0, 20] ];
linear_extrude (height = 5) rounded_polygon(shape1);
module rounded_polygon(points, radius) difference() { len = len(points); union () { for(i = [0 : len  1]) translate([points[i].x, points[i].y]) if(points[i][2] > 0) circle(points[i][2]);
polygon([for(i = [0 : len  1]) let(ends = tangent(points[i], points[(i + 1) % len(points)])) for(end = [0, 1]) ends[end]]); } for(i = [0 : len  1]) translate([points[i].x, points[i].y]) if(points[i][2] < 0) circle(points[i][2]); }
function tangent(p1, p2) = let ( r1 = p1[2], r2 = p2[2], dx = p2.x  p1.x, dy = p2.y  p1.y, d = sqrt(dx * dx + dy * dy), theta = atan2(dy, dx) + acos((r1  r2) / d), xa = p1.x +(cos(theta) * r1), ya = p1.y +(sin(theta) * r1), xb = p2.x +(cos(theta) * r2), yb = p2.y +(sin(theta) * r2) )[ [xa, ya], [xb, yb] ];
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


Thanks nophead, awesome stuff! I hope you find it useful too. But, dammit, you're not giving me a chance to use my brain...!
I'll have a sit down over the weekend and see how you've coded this, so I can understand it. One quick question: you use a '%' sign here:
...
let(ends = tangent(points[i], points[(i + 1) % len(points)]))
...
What does that do? I can see it's a 'scalar arithmetical operator' ( https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Mathematical_Operators ) for modulo (so finds the remainder after division of one number by another), but I'm not clear why!
Ian S
P.S. re 'Stuart', you addressed me as Stuart in your first post!


And just to confirm, this exports as a CSG file, and imports nicely into FreeCAD as :
Which exports happily as a STEP file, which Fusion 360 can import and render:
Thanks! I'll try it with some more complex geometry, and see if it still copes.
Ian S


Cleaned up the generated csg by moving the circle translates inside the if and replaced a call of len(points) with len.
$fn = 100;
shape1 = [ [10, 10, 8], [0, 40, 3], [40, 50, 10], [100, 80, 10], [50, 0, 20] ];
linear_extrude (height = 5) rounded_polygon(shape1);
module rounded_polygon(points) difference() { len = len(points); union() { for(i = [0 : len  1]) if(points[i][2] > 0) translate([points[i].x, points[i].y]) circle(points[i][2]);
polygon([for(i = [0 : len  1]) let(ends = tangent(points[i], points[(i + 1) % len])) for(end = [0, 1]) ends[end]]); } for(i = [0 : len  1]) if(points[i][2] < 0) translate([points[i].x, points[i].y]) circle(points[i][2]); }
function tangent(p1, p2) = let( r1 = p1[2], r2 = p2[2], dx = p2.x  p1.x, dy = p2.y  p1.y, d = sqrt(dx * dx + dy * dy), theta = atan2(dy, dx) + acos((r1  r2) / d), xa = p1.x +(cos(theta) * r1), ya = p1.y +(sin(theta) * r1), xb = p2.x +(cos(theta) * r2), yb = p2.y +(sin(theta) * r2) )[ [xa, ya], [xb, yb] ];
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


Looks nice in wood. I suspect you could export the STL to Blender and give it a wood texture and then render it. That would have the advantage of working with anything OpenScad can produce. The Mendel90 printed parts are rendered in Blender for the manual. They are not very pretty but that is just down to the blender template used. I think it adds some random noise to make it look like a photo. I am sure it could texture it with wood and give a photo realistic view. I am not a blender user though, somebody else contributed it.
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


On 18. mars 2016 16:30, droftarts wrote:
Does FreeCAD understand the polyhedron command? If so, OpenSCAD could
have an option to save the final body as a polyhedron to .csg, and you
could then use it in FreeCAD even if you had used Hull and Minkowski.
Carsten Arnholm
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

123
