discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

spiral_extrude() module

HJ
Hugo Jackson
Wed, Feb 27, 2019 3:59 AM

With chat of libraries and the like, I thought I would provide a module that I wrote that I’ve found very helpful in my own work.
I call it “spiral_extrude” and it’s a linear/rotate extrude hybrid.
It’s particularly useful for bolt threads, or perhaps for anyone who wants to model balusters.
It works kind of like the twist parameter in linear extrude except that each spiral extrusion is stitched to the earlier layer forming a closed watertight polyhedron.
(At least I HOPE it does).
Before I release it into the wild (i.e. thingiverse) I’d appreciate feedback… particularly performance improvements, efficiencies or oversights… and then again,  if someone identifies that some existing OpenSCAD functionality does this already and my module is redundant, that would be good to know too. :)
spiral_extrude() does require a set of profile points, but I hope that’s not too much of a drawback. As far as I could determine, there’s no way accomplish the spiral stitching with OpenSCAD 2d objects.
Here’s a picture of the examples produced by the module followed by the code…

/*
spiral_extrude(height, profilePoints, radius, pitch)

from a set of xy points that define a profile, e.g.
	[[0,0], [0,.4],[1,1], [1, 1.4], [0,2]]				
produce an spiral extruded polyhedron with the specified pitch and radius and of length height along the z axis.

NOTE:
	- profilePoints[0] must be on origin [0,0]
	- profilePoints y co-ordinates must be positive and in ascending order

procedure:
	- for each point in the profile generate a 3d point by adding a z value equal to the
	vertical offset for each segment in the spiral. Number of segments in each rotation
	is equal to $fn.
	
	- add a base [0,0,0] and top [0,0,height] origin point for stitching
	faces for a bottom and top cap
	
	- sealing the polyhedron requires two operations
		1) creating triangular faces from the base and top origin points to all ajacent points
			in the bottom and top row respectively
		2) creating a vertical 'sealing' face to connect the base and top origin point to
			each point in the profile in the first and last segment

*/

kClockwise = 1;
kCounterClockwise = -1;

// extrude in clockwise or counterclockwise manner
$spiralVector = kClockwise;
$fn = 100;

// return the maximum value in nth position of vectors v in matrix m
// recursive function
function m_max_v_nth(m, n, _index = 0, _max = 0) =
_index >= len(m)
? _max
: _index == 0
? m_max_v_nth(m, n, 1, m[0][n])
: m_max_v_nth(m, n, _index + 1, max(_max, m[_index][n]));

// return 3d pt of x rotated by angle a with z of z
// a = angle of rotation
function xza2xyz(x,z,a) = [cos(a) * x, sin(a) * x, z];

function points_in_origin(profilePoints, zIncrement, xOffset) =
let(angle = 360 / $fn * $spiralVector)
[for(segment = [0:$fn - 1])
xza2xyz(profilePoints[0][0] + xOffset, profilePoints[0][1] + (zIncrement * segment), segment * angle) ];

function points_in_rotation(segments, profilePoints, zIncrement, xOffset) =
let(angle = 360 / $fn * $spiralVector)
[for(segment = [0:segments])
for(point = [1:len(profilePoints)-1])
xza2xyz(profilePoints[point][0] + xOffset, profilePoints[point][1] + (zIncrement * segment), segment * angle)];

module spiral_extrude(height, profilePoints, radius, pitch) {
defaultWidth = m_max_v_nth(profilePoints,0);
// calculate any additional x offset to increase the diameter of the extrusion
xOffset =
is_undef(radius)
? 0
: defaultWidth < radius
? radius - defaultWidth
: 0;
// calculate any addtitional y offset to pad the profile to the stated pitch
defaultPitch = m_max_v_nth(profilePoints,1);
pHeight =
is_undef(pitch)
? defaultPitch
: max(pitch, defaultPitch);
rotations = ceil(height / pHeight) + 2;
zIncrement = pHeight / $fn;
pPointCount = len(profilePoints);
pPointLimit = pPointCount - 1;
pFaceCount = pPointLimit;
pFaceLimit = pFaceCount - 1;

segCount = $fn * rotations;
segLimit = segCount - 1;

pp = points_in_rotation(segCount, profilePoints, zIncrement, xOffset);
bp = points_in_origin(profilePoints, zIncrement, xOffset);
// concat all points adding the top bottom and top origin points
allPoints = concat(pp, bp, [[0,0,0], [0,0,segCount * zIncrement + pHeight]]);

ppIndex = 0;
bpIndex = len(pp);
bottomOriginIndex = bpIndex + len(bp);
topOriginIndex = bottomOriginIndex + 1;

// eoPPindex = bpIndex - 1;

ppCount = len(pp);

lastProfilePointPos = ppCount - 1;
firstTopCapPointPos = lastProfilePointPos - ($fn * pPointLimit);

fnLimit = $fn - 1;

af = 
	[
		for(segment = [0:segLimit])
			for(face = [0:pFaceLimit])
				let(faces =
					face == 0
						?
							[
								segment < $fn
									? ppCount + segment		
									: (segment - fnLimit) * pFaceCount - 1 
								,
	
								segment * pFaceCount + face,	
								(segment + 1) * pFaceCount + face,
	
								segment < fnLimit
									? ppCount + segment + 1
									: (segment - fnLimit) * pFaceCount + pFaceLimit
							]
						: // face != 0
							[
								segment * pFaceCount + face - 1,
								segment * pFaceCount + face,
								(segment + 1) * pFaceCount + face,
								(segment + 1) * pFaceCount + face - 1
							]
				)			
				for(i = [0:1])
					i == 0
						? [faces[1], faces[2], faces[3]] // 0,1,2 ... 0,2,3
						: [faces[3], faces[0], faces[1]]
	];
	
bottomCap =
	[for(f = [0:$fn - 1])
		[
			bottomOriginIndex,
			bpIndex + f,
			f == $fn - 1
				? ppIndex + pPointLimit - 1
				: bpIndex + f + 1
			
		]
	];

topCap =
	[for(f = [firstTopCapPointPos:pPointLimit:lastProfilePointPos - 1])
		[
			topOriginIndex,
			f + pPointLimit,
			f
		]
	];

topSeal =
	let(startPos = lastProfilePointPos - pPointCount + 1)
	[for(f = [0:pPointLimit - 1])
		[ 
			f == 0
				? startPos - $fn * pPointLimit + pPointLimit
				: startPos + f
			,
			startPos + f + 1,
			topOriginIndex,
		]
	];
	
bottomSeal =
		[
			for(f = [0:pPointLimit - 1])
				[
					f,
					f == 0
						? ppCount
						: f - 1,
					bottomOriginIndex, 
				]
		];			

allFaces = concat(af, bottomCap, topCap, topSeal, bottomSeal);

polyhedron(points = allPoints, faces = allFaces);

}

module spiral_extrude_examples() {
circlePoints = [[0, 0], [6.18034, 0.9789], [11.7557, 3.8197], [16.1803, 8.2443], [19.0211, 13.8197], [20, 20], [19.0211, 26.1803], [16.1803, 31.7557], [11.7557, 36.1803], [6.18034, 39.0211], [0, 40]];
topPoints = [[10,0],[12,1],[11,2],[11,3],[13,4],[10,5]];
threadPoints = [[10.9175, 0], [10.9175, 0.5], [12, 1.125], [12, 1.375], [10.9175, 2]];

// polygon(circlePoints);

translate([-100,0,0])
	spiral_extrude(200,circlePoints);

translate([-15,0,0])
	spiral_extrude(200,circlePoints, radius = 40);

translate([120,0,0])
	spiral_extrude(200,circlePoints, radius = 80);


translate([0,180,0]) {
translate([-100,0,0])
	spiral_extrude(200,topPoints);
translate([-25,0,0])
	spiral_extrude(200,topPoints, radius = 20, pitch = 10);
translate([80,0,0])
	spiral_extrude(200,topPoints, radius = 50, pitch = 20);
}

translate([0,-180,0]) {
translate([-100,0,0])
	spiral_extrude(200,threadPoints);
translate([-25,0,0])
	spiral_extrude(200,threadPoints, radius = 20);
translate([80,0,0])
	spiral_extrude(200,threadPoints, radius = 40);
}

}

spiral_extrude_examples();

With chat of libraries and the like, I thought I would provide a module that I wrote that I’ve found very helpful in my own work. I call it “spiral_extrude” and it’s a linear/rotate extrude hybrid. It’s particularly useful for bolt threads, or perhaps for anyone who wants to model balusters. It works kind of like the twist parameter in linear extrude except that each spiral extrusion is stitched to the earlier layer forming a closed watertight polyhedron. (At least I HOPE it does). Before I release it into the wild (i.e. thingiverse) I’d appreciate feedback… particularly performance improvements, efficiencies or oversights… and then again, if someone identifies that some existing OpenSCAD functionality does this already and my module is redundant, that would be good to know too. :) spiral_extrude() does require a set of profile points, but I hope that’s not too much of a drawback. As far as I could determine, there’s no way accomplish the spiral stitching with OpenSCAD 2d objects. Here’s a picture of the examples produced by the module followed by the code… /* spiral_extrude(height, profilePoints, radius, pitch) from a set of xy points that define a profile, e.g. [[0,0], [0,.4],[1,1], [1, 1.4], [0,2]] produce an spiral extruded polyhedron with the specified pitch and radius and of length height along the z axis. NOTE: - profilePoints[0] must be on origin [0,0] - profilePoints y co-ordinates must be positive and in ascending order procedure: - for each point in the profile generate a 3d point by adding a z value equal to the vertical offset for each segment in the spiral. Number of segments in each rotation is equal to $fn. - add a base [0,0,0] and top [0,0,height] origin point for stitching faces for a bottom and top cap - sealing the polyhedron requires two operations 1) creating triangular faces from the base and top origin points to all ajacent points in the bottom and top row respectively 2) creating a vertical 'sealing' face to connect the base and top origin point to each point in the profile in the first and last segment */ kClockwise = 1; kCounterClockwise = -1; // extrude in clockwise or counterclockwise manner $spiralVector = kClockwise; $fn = 100; // return the maximum value in nth position of vectors v in matrix m // recursive function function m_max_v_nth(m, n, _index = 0, _max = 0) = _index >= len(m) ? _max : _index == 0 ? m_max_v_nth(m, n, 1, m[0][n]) : m_max_v_nth(m, n, _index + 1, max(_max, m[_index][n])); // return 3d pt of x rotated by angle a with z of z // a = angle of rotation function xza2xyz(x,z,a) = [cos(a) * x, sin(a) * x, z]; function points_in_origin(profilePoints, zIncrement, xOffset) = let(angle = 360 / $fn * $spiralVector) [for(segment = [0:$fn - 1]) xza2xyz(profilePoints[0][0] + xOffset, profilePoints[0][1] + (zIncrement * segment), segment * angle) ]; function points_in_rotation(segments, profilePoints, zIncrement, xOffset) = let(angle = 360 / $fn * $spiralVector) [for(segment = [0:segments]) for(point = [1:len(profilePoints)-1]) xza2xyz(profilePoints[point][0] + xOffset, profilePoints[point][1] + (zIncrement * segment), segment * angle)]; module spiral_extrude(height, profilePoints, radius, pitch) { defaultWidth = m_max_v_nth(profilePoints,0); // calculate any additional x offset to increase the diameter of the extrusion xOffset = is_undef(radius) ? 0 : defaultWidth < radius ? radius - defaultWidth : 0; // calculate any addtitional y offset to pad the profile to the stated pitch defaultPitch = m_max_v_nth(profilePoints,1); pHeight = is_undef(pitch) ? defaultPitch : max(pitch, defaultPitch); rotations = ceil(height / pHeight) + 2; zIncrement = pHeight / $fn; pPointCount = len(profilePoints); pPointLimit = pPointCount - 1; pFaceCount = pPointLimit; pFaceLimit = pFaceCount - 1; segCount = $fn * rotations; segLimit = segCount - 1; pp = points_in_rotation(segCount, profilePoints, zIncrement, xOffset); bp = points_in_origin(profilePoints, zIncrement, xOffset); // concat all points adding the top bottom and top origin points allPoints = concat(pp, bp, [[0,0,0], [0,0,segCount * zIncrement + pHeight]]); ppIndex = 0; bpIndex = len(pp); bottomOriginIndex = bpIndex + len(bp); topOriginIndex = bottomOriginIndex + 1; // eoPPindex = bpIndex - 1; ppCount = len(pp); lastProfilePointPos = ppCount - 1; firstTopCapPointPos = lastProfilePointPos - ($fn * pPointLimit); fnLimit = $fn - 1; af = [ for(segment = [0:segLimit]) for(face = [0:pFaceLimit]) let(faces = face == 0 ? [ segment < $fn ? ppCount + segment : (segment - fnLimit) * pFaceCount - 1 , segment * pFaceCount + face, (segment + 1) * pFaceCount + face, segment < fnLimit ? ppCount + segment + 1 : (segment - fnLimit) * pFaceCount + pFaceLimit ] : // face != 0 [ segment * pFaceCount + face - 1, segment * pFaceCount + face, (segment + 1) * pFaceCount + face, (segment + 1) * pFaceCount + face - 1 ] ) for(i = [0:1]) i == 0 ? [faces[1], faces[2], faces[3]] // 0,1,2 ... 0,2,3 : [faces[3], faces[0], faces[1]] ]; bottomCap = [for(f = [0:$fn - 1]) [ bottomOriginIndex, bpIndex + f, f == $fn - 1 ? ppIndex + pPointLimit - 1 : bpIndex + f + 1 ] ]; topCap = [for(f = [firstTopCapPointPos:pPointLimit:lastProfilePointPos - 1]) [ topOriginIndex, f + pPointLimit, f ] ]; topSeal = let(startPos = lastProfilePointPos - pPointCount + 1) [for(f = [0:pPointLimit - 1]) [ f == 0 ? startPos - $fn * pPointLimit + pPointLimit : startPos + f , startPos + f + 1, topOriginIndex, ] ]; bottomSeal = [ for(f = [0:pPointLimit - 1]) [ f, f == 0 ? ppCount : f - 1, bottomOriginIndex, ] ]; allFaces = concat(af, bottomCap, topCap, topSeal, bottomSeal); polyhedron(points = allPoints, faces = allFaces); } module spiral_extrude_examples() { circlePoints = [[0, 0], [6.18034, 0.9789], [11.7557, 3.8197], [16.1803, 8.2443], [19.0211, 13.8197], [20, 20], [19.0211, 26.1803], [16.1803, 31.7557], [11.7557, 36.1803], [6.18034, 39.0211], [0, 40]]; topPoints = [[10,0],[12,1],[11,2],[11,3],[13,4],[10,5]]; threadPoints = [[10.9175, 0], [10.9175, 0.5], [12, 1.125], [12, 1.375], [10.9175, 2]]; // polygon(circlePoints); translate([-100,0,0]) spiral_extrude(200,circlePoints); translate([-15,0,0]) spiral_extrude(200,circlePoints, radius = 40); translate([120,0,0]) spiral_extrude(200,circlePoints, radius = 80); translate([0,180,0]) { translate([-100,0,0]) spiral_extrude(200,topPoints); translate([-25,0,0]) spiral_extrude(200,topPoints, radius = 20, pitch = 10); translate([80,0,0]) spiral_extrude(200,topPoints, radius = 50, pitch = 20); } translate([0,-180,0]) { translate([-100,0,0]) spiral_extrude(200,threadPoints); translate([-25,0,0]) spiral_extrude(200,threadPoints, radius = 20); translate([80,0,0]) spiral_extrude(200,threadPoints, radius = 40); } } spiral_extrude_examples();
P
Parkinbot
Wed, Feb 27, 2019 2:32 PM

Seems to work. The only problem I found in my short testing was a purple part
at the top, in F12 view for

spiral_extrude(200,circlePoints, radius = 40, pitch = 100);

Ok, the interface is a bit funky. Usually one would expect the pitch
parameter to scale the thread form itself not just the space in-between.
Additionally one might want to find a parameter for choosing the number of
threads to be able to also design multi-start threads. I know this is
difficult to implement.

Have a look at my  threading lib https://www.thingiverse.com/thing:1659079
. It is a very lazy approach that uses a minimum amount of code as it builds
on a general sweep() and lets union() do the dirty work.

--
Sent from: http://forum.openscad.org/

Seems to work. The only problem I found in my short testing was a purple part at the top, in F12 view for spiral_extrude(200,circlePoints, radius = 40, pitch = 100); Ok, the interface is a bit funky. Usually one would expect the pitch parameter to scale the thread form itself not just the space in-between. Additionally one might want to find a parameter for choosing the number of threads to be able to also design multi-start threads. I know this is difficult to implement. Have a look at my threading lib <https://www.thingiverse.com/thing:1659079> . It is a very lazy approach that uses a minimum amount of code as it builds on a general sweep() and lets union() do the dirty work. -- Sent from: http://forum.openscad.org/
HJ
Hugo Jackson
Wed, Feb 27, 2019 6:11 PM

Thanks for your input… I don’t know why I didn’t find your threading lib when I decided to write my module… I could have saved myself some time.
As for my implementation of pitch…here’s what happened. One of the things I use this library for is creating channels to hold LED light strips. So while the profile of the channel doesn’t change, the spacing between channels is usually more dynamic,  but when I use the module for threads, I’m dynamically calculating the tooth profile points for the required pitch and don’t want my module to adjust it.
And yes, I avoided more than one start just because the complexity of multi-threads was more intimidating that I was up for when I originally wrote the module.
Anyway, now that I know that your lib is already out there, my offering doesn’t offer any improvement so rather than posting it to thingiverse and muddying the waters I’ll hold back.
Thanks again for taking a look at it.
FYI… your thingiverse threading lib throws up three warnings with the current OpenSCAD release candidate:
WARNING: variable full not specified as parameter, in file Threading.scad, line 38
WARNING: len() parameter could not be converted, in file Naca_sweep.scad, line 115
WARNING: len() parameter could not be converted, in file Naca_sweep.scad, line 127

On Feb 27, 2019, at 6:32 AM, Parkinbot rudolf@digitaldocument.de wrote:

Seems to work. The only problem I found in my short testing was a purple part
at the top, in F12 view for

spiral_extrude(200,circlePoints, radius = 40, pitch = 100);

Ok, the interface is a bit funky. Usually one would expect the pitch
parameter to scale the thread form itself not just the space in-between.
Additionally one might want to find a parameter for choosing the number of
threads to be able to also design multi-start threads. I know this is
difficult to implement.

Have a look at my  threading lib https://www.thingiverse.com/thing:1659079
. It is a very lazy approach that uses a minimum amount of code as it builds
on a general sweep() and lets union() do the dirty work.

--
Sent from: http://forum.openscad.org/


OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

Thanks for your input… I don’t know why I didn’t find your threading lib when I decided to write my module… I could have saved myself some time. As for my implementation of pitch…here’s what happened. One of the things I use this library for is creating channels to hold LED light strips. So while the profile of the channel doesn’t change, the spacing between channels is usually more dynamic, but when I use the module for threads, I’m dynamically calculating the tooth profile points for the required pitch and don’t want my module to adjust it. And yes, I avoided more than one start just because the complexity of multi-threads was more intimidating that I was up for when I originally wrote the module. Anyway, now that I know that your lib is already out there, my offering doesn’t offer any improvement so rather than posting it to thingiverse and muddying the waters I’ll hold back. Thanks again for taking a look at it. FYI… your thingiverse threading lib throws up three warnings with the current OpenSCAD release candidate: WARNING: variable full not specified as parameter, in file Threading.scad, line 38 WARNING: len() parameter could not be converted, in file Naca_sweep.scad, line 115 WARNING: len() parameter could not be converted, in file Naca_sweep.scad, line 127 > On Feb 27, 2019, at 6:32 AM, Parkinbot <rudolf@digitaldocument.de> wrote: > > Seems to work. The only problem I found in my short testing was a purple part > at the top, in F12 view for > > spiral_extrude(200,circlePoints, radius = 40, pitch = 100); > > Ok, the interface is a bit funky. Usually one would expect the pitch > parameter to scale the thread form itself not just the space in-between. > Additionally one might want to find a parameter for choosing the number of > threads to be able to also design multi-start threads. I know this is > difficult to implement. > > Have a look at my threading lib <https://www.thingiverse.com/thing:1659079> > . It is a very lazy approach that uses a minimum amount of code as it builds > on a general sweep() and lets union() do the dirty work. > > > > > > -- > Sent from: http://forum.openscad.org/ > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
HJ
Hugo Jackson
Wed, Feb 27, 2019 6:59 PM

I just realized that implementing multi-starts is actually a pretty trivial task… I guess my intimidation by the concept clouded my thinking as all that’s really required is to duplicate my profile points for each start greater than 1 and adding an additional y offset to each point in the copied points. duh.

On Feb 27, 2019, at 10:11 AM, Hugo Jackson hugo@apres.net wrote:

Thanks for your input… I don’t know why I didn’t find your threading lib when I decided to write my module… I could have saved myself some time.
As for my implementation of pitch…here’s what happened. One of the things I use this library for is creating channels to hold LED light strips. So while the profile of the channel doesn’t change, the spacing between channels is usually more dynamic,  but when I use the module for threads, I’m dynamically calculating the tooth profile points for the required pitch and don’t want my module to adjust it.
And yes, I avoided more than one start just because the complexity of multi-threads was more intimidating that I was up for when I originally wrote the module.
Anyway, now that I know that your lib is already out there, my offering doesn’t offer any improvement so rather than posting it to thingiverse and muddying the waters I’ll hold back.
Thanks again for taking a look at it.
FYI… your thingiverse threading lib throws up three warnings with the current OpenSCAD release candidate:
WARNING: variable full not specified as parameter, in file Threading.scad, line 38
WARNING: len() parameter could not be converted, in file Naca_sweep.scad, line 115
WARNING: len() parameter could not be converted, in file Naca_sweep.scad, line 127

On Feb 27, 2019, at 6:32 AM, Parkinbot <rudolf@digitaldocument.de mailto:rudolf@digitaldocument.de> wrote:

Seems to work. The only problem I found in my short testing was a purple part
at the top, in F12 view for

spiral_extrude(200,circlePoints, radius = 40, pitch = 100);

Ok, the interface is a bit funky. Usually one would expect the pitch
parameter to scale the thread form itself not just the space in-between.
Additionally one might want to find a parameter for choosing the number of
threads to be able to also design multi-start threads. I know this is
difficult to implement.

Have a look at my  threading lib <https://www.thingiverse.com/thing:1659079 https://www.thingiverse.com/thing:1659079>
. It is a very lazy approach that uses a minimum amount of code as it builds
on a general sweep() and lets union() do the dirty work.

--
Sent from: http://forum.openscad.org/ http://forum.openscad.org/


OpenSCAD mailing list
Discuss@lists.openscad.org mailto:Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

I just realized that implementing multi-starts is actually a pretty trivial task… I guess my intimidation by the concept clouded my thinking as all that’s really required is to duplicate my profile points for each start greater than 1 and adding an additional y offset to each point in the copied points. duh. > On Feb 27, 2019, at 10:11 AM, Hugo Jackson <hugo@apres.net> wrote: > > Thanks for your input… I don’t know why I didn’t find your threading lib when I decided to write my module… I could have saved myself some time. > As for my implementation of pitch…here’s what happened. One of the things I use this library for is creating channels to hold LED light strips. So while the profile of the channel doesn’t change, the spacing between channels is usually more dynamic, but when I use the module for threads, I’m dynamically calculating the tooth profile points for the required pitch and don’t want my module to adjust it. > And yes, I avoided more than one start just because the complexity of multi-threads was more intimidating that I was up for when I originally wrote the module. > Anyway, now that I know that your lib is already out there, my offering doesn’t offer any improvement so rather than posting it to thingiverse and muddying the waters I’ll hold back. > Thanks again for taking a look at it. > FYI… your thingiverse threading lib throws up three warnings with the current OpenSCAD release candidate: > WARNING: variable full not specified as parameter, in file Threading.scad, line 38 > WARNING: len() parameter could not be converted, in file Naca_sweep.scad, line 115 > WARNING: len() parameter could not be converted, in file Naca_sweep.scad, line 127 > > >> On Feb 27, 2019, at 6:32 AM, Parkinbot <rudolf@digitaldocument.de <mailto:rudolf@digitaldocument.de>> wrote: >> >> Seems to work. The only problem I found in my short testing was a purple part >> at the top, in F12 view for >> >> spiral_extrude(200,circlePoints, radius = 40, pitch = 100); >> >> Ok, the interface is a bit funky. Usually one would expect the pitch >> parameter to scale the thread form itself not just the space in-between. >> Additionally one might want to find a parameter for choosing the number of >> threads to be able to also design multi-start threads. I know this is >> difficult to implement. >> >> Have a look at my threading lib <https://www.thingiverse.com/thing:1659079 <https://www.thingiverse.com/thing:1659079>> >> . It is a very lazy approach that uses a minimum amount of code as it builds >> on a general sweep() and lets union() do the dirty work. >> >> >> >> >> >> -- >> Sent from: http://forum.openscad.org/ <http://forum.openscad.org/> >> >> _______________________________________________ >> OpenSCAD mailing list >> Discuss@lists.openscad.org <mailto:Discuss@lists.openscad.org> >> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
P
Parkinbot
Wed, Feb 27, 2019 7:21 PM

thanks, I know about the warnings. I'll revise the code as soon as the
release is out and I find time for it.

--
Sent from: http://forum.openscad.org/

thanks, I know about the warnings. I'll revise the code as soon as the release is out and I find time for it. -- Sent from: http://forum.openscad.org/
P
Parkinbot
Wed, Feb 27, 2019 7:26 PM

I wouldn't call that what you do "muddying the water". It is a clean bottom
up approach. As far as I remember there are some more threading libs out
there and people will adopt what they like more.
It is always good to have a choice.

--
Sent from: http://forum.openscad.org/

I wouldn't call that what you do "muddying the water". It is a clean bottom up approach. As far as I remember there are some more threading libs out there and people will adopt what they like more. It is always good to have a choice. -- Sent from: http://forum.openscad.org/
NH
nop head
Wed, Feb 27, 2019 7:38 PM

I wish len() would be reverted to accept scalars and return undef as it is
documented to do in the wiki. I.e. scalars are valid input to len(). Not
only does it break existing libraries but the solution is not backwards
compatible and is longer and slower.

On Wed, 27 Feb 2019 at 19:32, Parkinbot rudolf@digitaldocument.de wrote:

I wouldn't call that what you do "muddying the water". It is a clean bottom
up approach. As far as I remember there are some more threading libs out
there and people will adopt what they like more.
It is always good to have a choice.

--
Sent from: http://forum.openscad.org/


OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

I wish len() would be reverted to accept scalars and return undef as it is documented to do in the wiki. I.e. scalars are valid input to len(). Not only does it break existing libraries but the solution is not backwards compatible and is longer and slower. On Wed, 27 Feb 2019 at 19:32, Parkinbot <rudolf@digitaldocument.de> wrote: > I wouldn't call that what you do "muddying the water". It is a clean bottom > up approach. As far as I remember there are some more threading libs out > there and people will adopt what they like more. > It is always good to have a choice. > > > > > -- > Sent from: http://forum.openscad.org/ > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
RD
Revar Desmera
Wed, Feb 27, 2019 10:01 PM

Yes!  I've had to change to testing v[0]==undef and that doesn't work for empty vectors.

  • Revar

On Feb 27, 2019, at 11:38 AM, nop head nop.head@gmail.com wrote:

I wish len() would be reverted to accept scalars and return undef as it is documented to do in the wiki. I.e. scalars are valid input to len(). Not only does it break existing libraries but the solution is not backwards compatible and is longer and slower.

On Wed, 27 Feb 2019 at 19:32, Parkinbot <rudolf@digitaldocument.de mailto:rudolf@digitaldocument.de> wrote:
I wouldn't call that what you do "muddying the water". It is a clean bottom
up approach. As far as I remember there are some more threading libs out
there and people will adopt what they like more.
It is always good to have a choice.

--
Sent from: http://forum.openscad.org/ http://forum.openscad.org/


OpenSCAD mailing list
Discuss@lists.openscad.org mailto:Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

Yes! I've had to change to testing v[0]==undef and that doesn't work for empty vectors. - Revar > On Feb 27, 2019, at 11:38 AM, nop head <nop.head@gmail.com> wrote: > > I wish len() would be reverted to accept scalars and return undef as it is documented to do in the wiki. I.e. scalars are valid input to len(). Not only does it break existing libraries but the solution is not backwards compatible and is longer and slower. > > On Wed, 27 Feb 2019 at 19:32, Parkinbot <rudolf@digitaldocument.de <mailto:rudolf@digitaldocument.de>> wrote: > I wouldn't call that what you do "muddying the water". It is a clean bottom > up approach. As far as I remember there are some more threading libs out > there and people will adopt what they like more. > It is always good to have a choice. > > > > > -- > Sent from: http://forum.openscad.org/ <http://forum.openscad.org/> > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org <mailto:Discuss@lists.openscad.org> > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org <http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org> > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
NH
nop head
Wed, Feb 27, 2019 10:58 PM

Yes I have: function Len(x) = is_list(x) ? len(x) : 0;

But why do I need it when it has always been a documented feature of len
that it returns undef for scalars? That means len should accept scalar
arguments without giving a warning.

On Wed, 27 Feb 2019 at 22:02, Revar Desmera revarbat@gmail.com wrote:

Yes!  I've had to change to testing v[0]==undef and that doesn't work for
empty vectors.

  • Revar

On Feb 27, 2019, at 11:38 AM, nop head nop.head@gmail.com wrote:

I wish len() would be reverted to accept scalars and return undef as it is
documented to do in the wiki. I.e. scalars are valid input to len(). Not
only does it break existing libraries but the solution is not backwards
compatible and is longer and slower.

On Wed, 27 Feb 2019 at 19:32, Parkinbot rudolf@digitaldocument.de wrote:

I wouldn't call that what you do "muddying the water". It is a clean
bottom
up approach. As far as I remember there are some more threading libs out
there and people will adopt what they like more.
It is always good to have a choice.

--
Sent from: http://forum.openscad.org/


OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

Yes I have: function Len(x) = is_list(x) ? len(x) : 0; But why do I need it when it has always been a documented feature of len that it returns undef for scalars? That means len should accept scalar arguments without giving a warning. On Wed, 27 Feb 2019 at 22:02, Revar Desmera <revarbat@gmail.com> wrote: > Yes! I've had to change to testing v[0]==undef and that doesn't work for > empty vectors. > > - Revar > > > On Feb 27, 2019, at 11:38 AM, nop head <nop.head@gmail.com> wrote: > > I wish len() would be reverted to accept scalars and return undef as it is > documented to do in the wiki. I.e. scalars are valid input to len(). Not > only does it break existing libraries but the solution is not backwards > compatible and is longer and slower. > > On Wed, 27 Feb 2019 at 19:32, Parkinbot <rudolf@digitaldocument.de> wrote: > >> I wouldn't call that what you do "muddying the water". It is a clean >> bottom >> up approach. As far as I remember there are some more threading libs out >> there and people will adopt what they like more. >> It is always good to have a choice. >> >> >> >> >> -- >> Sent from: http://forum.openscad.org/ >> >> _______________________________________________ >> OpenSCAD mailing list >> Discuss@lists.openscad.org >> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >> > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org > > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >