discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

Curved/bent conical tubing

P
Parkinbot
Thu, Mar 2, 2017 3:53 PM

Ronaldo wrote

That is what I got from a similar process:

nice! Here some minimalistic "free style" interpolation code for playing
around.

use
<Naca_sweep.scad>
// http://www.thingiverse.com/thing:1208001
use
<splines.scad>
// http://www.thingiverse.com/thing:1208001

d = 2; // tube diameter
N=300; // interpolation points

// interpolation data for outer skin
A = [//Tx, Ty, Tz, rad, Rx, Ry
[0,  42, -100, 10,  0,    0 ], // mouthpiece part
[0,  42, -60,  10,  0,    0 ],
[0,  42, 0,    12,  0,    0 ],
[0,  42, 80,  15,  -5,  -20],  // start loop
[40, 40, 120,  15, -20,  -90],  // 90°
[80, 25, 75,  17, -30, -180],  // 180°
[60, 12, 0,    19, -10, -240],  // 270°
[0,  5,  25,  20,  0, -360],  // end loop
[0,  0,  100,  26,  0, -370],  // cone start
[20, 0,  200,  40,  0, -370],  // cone shift
[60, 0,  300,  70,  0, -420],  // cone shift and bend
[68, 0,  310, 100,  0, -422],  // cone end
[69, 0,  311, 100,  0, -422],  // cone border
];

// view raw data
// sweep(gen_dat(A, N/3), showslices = true);

// inner skin data: reverse A with modified tube diameter
B = [for(i=[len(A)-1:-1:0]) [for(j=[0:len(A[0])-1]) A[i][j]-(j==3?d:0)]];

outer = gen_dat(nSpline(A,N), N/3);    // outer skin
inner = gen_dat(nSpline(B,N), N/3);    // inner skin
sweep(concat(outer, inner), close = true, slices = true);

function gen_dat(S, N=100) =
[ for (i=[0:len(S)-1])
let(dat = Tz_(S[i][2], // apply Tz
Rx_(S[i][4], // apply Rx
Ry_(S[i][5], // apply Ry
circle_(S[i][3], N))))) // generate circle data using rad
T_(S[i][0], S[i][1], 0, dat)]; // apply Tx and Ty

function circle_(r=10, N=30) = [for (i=[0:N-1]) [rsin(i360/N),
rcos(i360/N), 0]];

http://forum.openscad.org/file/n20696/looped_horn.png

--
View this message in context: http://forum.openscad.org/Curved-bent-conical-tubing-tp20686p20696.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

Ronaldo wrote > That is what I got from a similar process: nice! Here some minimalistic "free style" interpolation code for playing around. > use > <Naca_sweep.scad> > // http://www.thingiverse.com/thing:1208001 > use > <splines.scad> > // http://www.thingiverse.com/thing:1208001 > > d = 2; // tube diameter > N=300; // interpolation points > > > // interpolation data for outer skin > A = [//Tx, Ty, Tz, rad, Rx, Ry > [0, 42, -100, 10, 0, 0 ], // mouthpiece part > [0, 42, -60, 10, 0, 0 ], > [0, 42, 0, 12, 0, 0 ], > [0, 42, 80, 15, -5, -20], // start loop > [40, 40, 120, 15, -20, -90], // 90° > [80, 25, 75, 17, -30, -180], // 180° > [60, 12, 0, 19, -10, -240], // 270° > [0, 5, 25, 20, 0, -360], // end loop > [0, 0, 100, 26, 0, -370], // cone start > [20, 0, 200, 40, 0, -370], // cone shift > [60, 0, 300, 70, 0, -420], // cone shift and bend > [68, 0, 310, 100, 0, -422], // cone end > [69, 0, 311, 100, 0, -422], // cone border > ]; > > // view raw data > // sweep(gen_dat(A, N/3), showslices = true); > > // inner skin data: reverse A with modified tube diameter > B = [for(i=[len(A)-1:-1:0]) [for(j=[0:len(A[0])-1]) A[i][j]-(j==3?d:0)]]; > > outer = gen_dat(nSpline(A,N), N/3); // outer skin > inner = gen_dat(nSpline(B,N), N/3); // inner skin > sweep(concat(outer, inner), close = true, slices = true); > > function gen_dat(S, N=100) = > [ for (i=[0:len(S)-1]) > let(dat = Tz_(S[i][2], // apply Tz > Rx_(S[i][4], // apply Rx > Ry_(S[i][5], // apply Ry > circle_(S[i][3], N))))) // generate circle data using rad > T_(S[i][0], S[i][1], 0, dat)]; // apply Tx and Ty > > function circle_(r=10, N=30) = [for (i=[0:N-1]) [r*sin(i*360/N), > r*cos(i*360/N), 0]]; <http://forum.openscad.org/file/n20696/looped_horn.png> -- View this message in context: http://forum.openscad.org/Curved-bent-conical-tubing-tp20686p20696.html Sent from the OpenSCAD mailing list archive at Nabble.com.
P
pieterbos
Thu, Mar 2, 2017 7:55 PM

Very nice looking horn designs and nice tricks for creating shapes with very
little code!

I managed to get the basic shape with the skin with circles with holes as
input, but as soon as I attach other parts I keep getting the same error as
I got before. F12 shows no purple vertices.

So for now differencing two solid shapes created with skin() works and it
renders in just a few minutes. Perhaps I'll try the naca sweep later - it
looks very useful!

For the bell I currently use a straight profile, by creating a curve (list
of points) made from a combination of bessel curves, cones and cylinders.
I create a wall from the curve by translating along the normal vectors. Then
I apply rotate_extrude.

I can input the bessel curve parameters directly in the ART acoustics
simulator, giving me impedance curves. And there's a brass synthesizer
called NESS brass that I can actually input the profile and many other input
parameters that outputs sound. Nice for checking how in tune it is and

Your examples provide the benefit of allowing arbitrary shapes. I could
probably use it to make a trombone bell that's bent so it fits in my
printers 250x213x200mm volume and print it all in one part.

--
View this message in context: http://forum.openscad.org/Curved-bent-conical-tubing-tp20686p20699.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

Very nice looking horn designs and nice tricks for creating shapes with very little code! I managed to get the basic shape with the skin with circles with holes as input, but as soon as I attach other parts I keep getting the same error as I got before. F12 shows no purple vertices. So for now differencing two solid shapes created with skin() works and it renders in just a few minutes. Perhaps I'll try the naca sweep later - it looks very useful! For the bell I currently use a straight profile, by creating a curve (list of points) made from a combination of bessel curves, cones and cylinders. I create a wall from the curve by translating along the normal vectors. Then I apply rotate_extrude. I can input the bessel curve parameters directly in the ART acoustics simulator, giving me impedance curves. And there's a brass synthesizer called NESS brass that I can actually input the profile and many other input parameters that outputs sound. Nice for checking how in tune it is and Your examples provide the benefit of allowing arbitrary shapes. I could probably use it to make a trombone bell that's bent so it fits in my printers 250x213x200mm volume and print it all in one part. -- View this message in context: http://forum.openscad.org/Curved-bent-conical-tubing-tp20686p20699.html Sent from the OpenSCAD mailing list archive at Nabble.com.
P
pieterbos
Thu, Mar 2, 2017 9:14 PM

So it works and renders - thanks a lot for your help! the entire thing
preview rendered now looks like this:

http://forum.openscad.org/file/n20700/Screen_Shot_2017-03-02_at_21.png

The thing attached to the tuning slide is for printing without supports.
Let's hope that engraved text will print well and that it's sturdy enough :)

--
View this message in context: http://forum.openscad.org/Curved-bent-conical-tubing-tp20686p20700.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

So it works and renders - thanks a lot for your help! the entire thing preview rendered now looks like this: <http://forum.openscad.org/file/n20700/Screen_Shot_2017-03-02_at_21.png> The thing attached to the tuning slide is for printing without supports. Let's hope that engraved text will print well and that it's sturdy enough :) -- View this message in context: http://forum.openscad.org/Curved-bent-conical-tubing-tp20686p20700.html Sent from the OpenSCAD mailing list archive at Nabble.com.
R
Ronaldo
Thu, Mar 2, 2017 11:26 PM

Parkinbot wrote

nice! Here some minimalistic "free style" interpolation code for playing
around.

Parkinbot: the minimalistic magician! :)

I tip my hat to your style but I am not able to adopt it. We have different
approaches. I am trying to create more sophisticated tools that require a
minimum amount of data to build a model. You start from a very basic but
powerful tools (sweep.scad, spline.scad, shortcuts, etc) and code the
generation of lots of data in a very concise (sometimes hard to read :) )
form. Your approach requires more understanding of the modeling process
resorting to a few flexible tools. Mine resorts to more specialized but less
flexible functions.

To shape a sax, for instance (I have modeled it before the bugle), I started
with a minimum of data:

//*  sax shape
sax_path = [ [0,0,28],
[18,0,22.5],
[27,0,16],
[28.5,0,13],
[29,0,0],
[29,0,-15],
[29,0,-30],
[29,0,-45],
[30,0,-56],
[41,0,-56],
[44,0,-45],
[44,0,-30],
[44.2,0,-18],
[50,0,-11],
[50,0,-11],
];
sax_rads = [ 1.8, 2, 3.3, 3.7, 4, 4.2, 4.4, 4.6, 6.0, 6.5, 6.3, 6.3, 6.3,
8.7, 12];

sax_rim_size = 1;

The sax_path defines a spine for the sax and the sax_rads controls the
radiuses of the outer sax surface at each point in the path. There is no
user data to position the circles in the space except its center - the spine
points. To position the circles I  have used the technique found in Linde's
sweep.scad, that is: find the spine tangent at each point and define the
circle plane as the one orthogonal to the tangent and passing about the
point (mapShapes2Path() bellow).

To define the surface, the positioned circles are taking as control points
of a B-spline. I tried with a spline interpolator first and gave up because
it is very hard to set the input data to get the shape you have in mind.
Spline interpolator usually oscillates more than the input data and produces
unexpected shapes.

So I have switched to B-splines. They are simpler to compute then
interpolator splines and easy to model with after you are used to it. That
was the result:

http://forum.openscad.org/file/n20703/sax.png
http://forum.openscad.org/file/n20703/Sax2.png

In the image, the (translated) spine is represented in red and the
positioned circles in yellow. The small yellow blocks near the spine are the
sax_path positions. The blue blocks are the first points of each circle
showing that the surface twist is minimum. As it is apparent from the side
view, the dimensions of the shape does not equals the circle radiuses. But
the relation between the shape and the input circles is more predictable.

The code generating this model is relatively straightforward.

// the circular shapes - ctrl points of the spline
lshp = [ for(rad=rads) circle(r=rad) ];

// the inner surface radiuses
irads = [for(rad=rads) rad-0.5];

// the inner surface circular shapes
ilshp = [ for(rad=irads) circle(r=rad) ];

// the spine line of the sax
pts  = BSplineCurve(path,3);

// maps the circles of the outer and inner surfaces to 3D space
shps  = mapShapes2Path(lshp, path, cl=false);
ishps = mapShapes2Path(ilshp, path, cl=false);
// reverts the inner shape to concatenate it with the outer one
rishps = reverse(ishps);

// the outer shape
outer = loftBS(shps, n=floor(ln($fn)),cl=true);
// the inner shape
inner = loftBS(rishps, n=floor(ln($fn)), cl=true);
// the horn rim
horn_rim = _loftSurfacesG1(outer,inner,h1=rim_size,h2=rim_size,nu=20);

// the full model mesh
inout = concat(outer,horn_rim,inner,[outer[0]] );

// build the mesh polyhedron
color("gold")
mesh(inout);

This is a test code. My intention is to wrap almost all the code above in a
function.

Far from minimalistic though.

--
View this message in context: http://forum.openscad.org/Curved-bent-conical-tubing-tp20686p20703.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

Parkinbot wrote > nice! Here some minimalistic "free style" interpolation code for playing > around. Parkinbot: the minimalistic magician! :) I tip my hat to your style but I am not able to adopt it. We have different approaches. I am trying to create more sophisticated tools that require a minimum amount of data to build a model. You start from a very basic but powerful tools (sweep.scad, spline.scad, shortcuts, etc) and code the generation of lots of data in a very concise (sometimes hard to read :) ) form. Your approach requires more understanding of the modeling process resorting to a few flexible tools. Mine resorts to more specialized but less flexible functions. To shape a sax, for instance (I have modeled it before the bugle), I started with a minimum of data: //* sax shape sax_path = [ [0,0,28], [18,0,22.5], [27,0,16], [28.5,0,13], [29,0,0], [29,0,-15], [29,0,-30], [29,0,-45], [30,0,-56], [41,0,-56], [44,0,-45], [44,0,-30], [44.2,0,-18], [50,0,-11], [50,0,-11], ]; sax_rads = [ 1.8, 2, 3.3, 3.7, 4, 4.2, 4.4, 4.6, 6.0, 6.5, 6.3, 6.3, 6.3, 8.7, 12]; sax_rim_size = 1; The sax_path defines a spine for the sax and the sax_rads controls the radiuses of the outer sax surface at each point in the path. There is no user data to position the circles in the space except its center - the spine points. To position the circles I have used the technique found in Linde's sweep.scad, that is: find the spine tangent at each point and define the circle plane as the one orthogonal to the tangent and passing about the point (mapShapes2Path() bellow). To define the surface, the positioned circles are taking as control points of a B-spline. I tried with a spline interpolator first and gave up because it is very hard to set the input data to get the shape you have in mind. Spline interpolator usually oscillates more than the input data and produces unexpected shapes. So I have switched to B-splines. They are simpler to compute then interpolator splines and easy to model with after you are used to it. That was the result: <http://forum.openscad.org/file/n20703/sax.png> <http://forum.openscad.org/file/n20703/Sax2.png> In the image, the (translated) spine is represented in red and the positioned circles in yellow. The small yellow blocks near the spine are the sax_path positions. The blue blocks are the first points of each circle showing that the surface twist is minimum. As it is apparent from the side view, the dimensions of the shape does not equals the circle radiuses. But the relation between the shape and the input circles is more predictable. The code generating this model is relatively straightforward. > // the circular shapes - ctrl points of the spline > lshp = [ for(rad=rads) circle(r=rad) ]; > > // the inner surface radiuses > irads = [for(rad=rads) rad-0.5]; > > // the inner surface circular shapes > ilshp = [ for(rad=irads) circle(r=rad) ]; > > // the spine line of the sax > pts = BSplineCurve(path,3); > > // maps the circles of the outer and inner surfaces to 3D space > shps = mapShapes2Path(lshp, path, cl=false); > ishps = mapShapes2Path(ilshp, path, cl=false); > // reverts the inner shape to concatenate it with the outer one > rishps = reverse(ishps); > > // the outer shape > outer = loftBS(shps, n=floor(ln($fn)),cl=true); > // the inner shape > inner = loftBS(rishps, n=floor(ln($fn)), cl=true); > // the horn rim > horn_rim = _loftSurfacesG1(outer,inner,h1=rim_size,h2=rim_size,nu=20); > > // the full model mesh > inout = concat(outer,horn_rim,inner,[outer[0]] ); > > // build the mesh polyhedron > color("gold") > mesh(inout); This is a test code. My intention is to wrap almost all the code above in a function. Far from minimalistic though. -- View this message in context: http://forum.openscad.org/Curved-bent-conical-tubing-tp20686p20703.html Sent from the OpenSCAD mailing list archive at Nabble.com.
P
Parkinbot
Fri, Mar 3, 2017 11:28 AM

Ronaldo wrote

I tip my hat to your style but I am not able to adopt it. We have
different approaches.

Ronaldo, what you showed is again a very nice design. Basically we follow
the same way and I perfectly agree with you about programming styles. I also
almost hate it to read other peoples code, especially when the code is
lenghty, badly structured, and uses variable names like
"the_inner_diameter_of_the_upper_part" are used that mess up the code
outline. A few days ago I downloaded some pulley design code having a very
high like count, because I wanted to save time. In the end I spent more than
three hours to understand what's going on until I finally got to the point I
wanted to adopt it to my needs. Thus my intention here is to give simplistic
examples and approaches for adressing complex problems, and to show up
coding styles that go beyond the usual aggregates of union, intersection,
difference, translation, scale and rotation. Refinement should/can be done
after selecting the right approach. Starting with a wrong approach, is like
buying too cheap. You will be annoyed sooner or later.

I also agree that B-splines are much more intuitive and carefree in use,
because they don't overshoot. I haven't implemented them yet, because I
hardly ever need interpolation. Of course it makes up a good approach to
keep the interpolation scheme interchangeable. So we should put our stuff
together one day to compose a good interpolation library using a common
interface. But for now I won't spend time on that, until I really get hands
on the vertex data of OpenSCAD objects.

--
View this message in context: http://forum.openscad.org/Curved-bent-conical-tubing-tp20686p20707.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

Ronaldo wrote > I tip my hat to your style but I am not able to adopt it. We have > different approaches. Ronaldo, what you showed is again a very nice design. Basically we follow the same way and I perfectly agree with you about programming styles. I also almost hate it to read other peoples code, especially when the code is lenghty, badly structured, and uses variable names like "the_inner_diameter_of_the_upper_part" are used that mess up the code outline. A few days ago I downloaded some pulley design code having a very high like count, because I wanted to save time. In the end I spent more than three hours to understand what's going on until I finally got to the point I wanted to adopt it to my needs. Thus my intention here is to give simplistic examples and approaches for adressing complex problems, and to show up coding styles that go beyond the usual aggregates of union, intersection, difference, translation, scale and rotation. Refinement should/can be done after selecting the right approach. Starting with a wrong approach, is like buying too cheap. You will be annoyed sooner or later. I also agree that B-splines are much more intuitive and carefree in use, because they don't overshoot. I haven't implemented them yet, because I hardly ever need interpolation. Of course it makes up a good approach to keep the interpolation scheme interchangeable. So we should put our stuff together one day to compose a good interpolation library using a common interface. But for now I won't spend time on that, until I really get hands on the vertex data of OpenSCAD objects. -- View this message in context: http://forum.openscad.org/Curved-bent-conical-tubing-tp20686p20707.html Sent from the OpenSCAD mailing list archive at Nabble.com.