Ronaldo Persiano rcmpersiano at gmail.com
Fri Jan 5 15:23:18 EST 2018

```First of all, the path_shape_transforms() I defined before may be
simpler defined
by:

function path_shape_transforms(path, shape_transf, closed=false, tangts) =
let( rt = construct_transform_path(path, closed=false, tangts) )
[for (i = [0:len(rt)-1]) rt[i]*shape_transf[i] ];

Now I want to discuss your question on how to deal with a hollow sweep. My
approach to that is the following:
a) build a skin for the outer surface without cap in a suitable form;
b) build a skin for the inner surface without cap in the same form;
c) build a skin (a polygon) connecting one end of the first skin with one
end of the other skin;
d) do the same with the other end;
e) aggregate those four skins in one polyhedron call.

The suitable form I use for all skins is a polyhedron data format: a pair
of a point list and a facet list. The first two skins are built by
sweep_polyhedron()
(a function you find in my fork code) without caps. The last two skins may
also be built by sweep_polyhedron() applying a round if necessary but it
may be just a annular surface connecting two sections.The last process, I
called the aggregate, is a very general module that receives a list of
polyhedron data, process them and make a call to the polyhedron primitive.

module buildPolyhedron(polys, convexity = 10) {

function _accum_sum(l, offs=0, res=[]) =

len(res) == len(l) ?

res :

_accum_sum(l, offs+l[len(res)], concat(res, [ offs+l[len(res)]
] ));

function acc_len( f ) =

concat([0], _accum_sum([ for(fi=f) len(fi) ]));

vertlist = [for(p=polys, pt=p[0]) pt]; // collect all verts from
polyhedra

vertlen  = [for(p=polys) p[0] ];

acclen   = acc_len(vertlen);

facets   = [ for(i=[0:len(polys)-1], f=polys[i][1] ) [ for(v=f)
acclen[i]+v ] ];

echo(acclen);

polyhedron(

points = vertlist,

faces  = facets,

convexity = convexity

);

}

2018-01-05 17:22 GMT-02:00 Ronaldo Persiano <rcmpersiano at gmail.com>:

> If understood correctly your code, your variable my_path is a prebuilt
> transform path for sweep that does not include the necessary rotations of
> the sections to make them orthogonal to the path. That is why the sections
> are all parallel to plane xy after sweep.
>
> In the following code, I separate the path from the shape transform
> sequence you want to apply at each path point. And I define a
> function path_shape_transforms(), based on construct_transform_path(),
> that takes in account a shape transform sequence besides the path itself.
>
> bottom_w = 120;
> top_w = 3;
> height = 120;
> steps = 360;
>
> pathstep = height/steps;
> delt = top_w - bottom_w;
>
> path = [ for (i=[0:steps]) [18*sin(i), 18-18*cos(i*0.7),     36*sin(i/2)]
> ];
>
> shtransf = [ for (i=[0:steps])
>     scaling([11 * (1.2 - i/steps), 11 * (1.2 - i/steps), 1]) *
>     rotation([0,0, steps]) ];
>
> square_points = square(1);
> circle_points = circle(r=0.5, \$fn=60);
>
> ptrans = path_shape_transforms(path, shtransf);
>
> sweep(circle_points, ptrans);
>
> function path_shape_transforms(path, shape_transf, closed=false, tangts) =
>    let( l = len(path),
>         tangents = tangts==undef ? tangent_path(path, closed) : tangts,
>         local_rotations = minimizing_rotations(concat([[0,0,1]],
> tangents)),
>         rotations = accumulate_rotations(local_rotations),
>         twist = closed ? calculate_twist(rotations[0], rotations[l-1]) : 0
> ,
>         rt = [ for (i = [0:l-1]) construct_rt(rotations[i], path[i]) *
> rotation( [0, 0, twist*i/(l-1)] ) ] )
>     [for (i = [0:l-1]) rt[i]*shape_transf[i] ];
>
> function square(l) =
>   [ [-l/2,-l/2], [-l/2,l/2], [l/2,l/2], [l/2,-l/2] ];
>
> function circle(r) =
>   [for(i=[0:\$fn-1]) [cos(360*i/\$fn),sin(360*i/\$fn)] ];
>
>
>
> ​
>
> 2018-01-05 15:21 GMT-02:00 jon <jon at jonbondy.com>:
>
>> I want to make horns similar to those shown in the first screen capture,
>> below.
>>
>> I started out with sweep() but could not see how to incorporate scaling
>> into that approach.  I hacked the sweep.scad module so that the global
>> shape() function was called inside sweep() (rather than passing the output
>> of shape() into sweep() as a parameter), so that I could return shapes
>> which scaled during the sweep.
>>
>> That approach (although ugly/hacky) worked to some extent.  But since
>> what I really wanted was a hollow horn, things fell apart when I tried to
>> create two horns with different scales, so that I could subtract the inner
>> from the outer.  With only one global shape() function available, the only
>> way I could see to make this work was to duplicate the sweep() code so that
>> I could use two global shape() functions.  I felt as if I was heading
>> towards hacking hell.  Simple use of scale() failed because I need the path
>> to remain unscaled while the object that is being swept is scaled.
>>
>> I tried to use Ronaldo's sweep-with-easing approach (although I never
>> understood what "easing" was).  The result is unacceptable because the
>> shapes used are always horizontal: they do not rotate to stay orthogonal to
>> the path.  Perhaps this is due to errors in my approach (code is below).
>>
>> In addition, I was unable to get the horn shapes to have caps on the ends.
>>
>> I gave up on hollow horns, and made them solid, figuring that I would be
>> able to hollow them out with MeshMixer (annoying, but acceptable).  But the
>> STLs created were so damaged that neither MeshMixer nor NetFabb were able
>> to repair them.
>>
>> I feel as if I am flailing about randomly.  Perhaps one of you can point
>> me in a more productive direction.
>>
>> Thanks!
>>
>> Jon
>>
>>
>>
>> bottom_w = 120;
>> top_w = 3;
>> height = 120;
>> steps = 360;
>>
>> pathstep = height/steps;
>> delt = top_w - bottom_w;
>>
>> square_points = square(1);
>> circle_points = circle(r=0.5, \$fn=60);
>>
>> sweep(circle_points, my_path);
>>
>> my_path = [ for (i=[0:steps])
>>     translation([18*sin(i), 18-18*cos(i*0.7),     36*sin(i/2)]) *
>>     scaling([11 * (1.2 - i/steps), 11 * (1.2 - i/steps), 1]) *
>>     rotation([0,0, steps]) ];
>>
>>
>>
>>
>> --
>> Sent from my desktop computer.
>> I do not receive emails while away from my desk,
>> nor do I receive texts on my main phone number
>> (which is a land line).
>> If you know that I am on the road, please text me.
>> If you know that I am home, please email me.
>>
>>
>> _______________________________________________
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
-------------- next part --------------
A non-text attachment was scrubbed...
Name: jeiboandnhdkpfdo.png
Type: image/png
Size: 44943 bytes
Desc: not available
-------------- next part --------------
A non-text attachment was scrubbed...
Name: horn.PNG
Type: image/png
Size: 32738 bytes
Desc: not available