Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Richard Milewski 2023-04-04 23:55:02 -07:00
commit af59c3c42c
12 changed files with 1414 additions and 832 deletions

View file

@ -28,11 +28,13 @@
// Section: Bezier Curves // Section: Bezier Curves
// Function: bezier_points() // Function: bezier_points()
// Synopsis: Computes one or more specified points along a bezier curve.
// Topics: Bezier Curves
// See Also: bezier_curve(), bezier_curvature(), bezier_tangent(), bezier_derivative(), bezier_points()
// Usage: // Usage:
// pt = bezier_points(bezier, u); // pt = bezier_points(bezier, u);
// ptlist = bezier_points(bezier, RANGE); // ptlist = bezier_points(bezier, RANGE);
// ptlist = bezier_points(bezier, LIST); // ptlist = bezier_points(bezier, LIST);
// Topics: Bezier Curves
// Description: // Description:
// Computes points on a bezier curve with control points specified by `bezier` at parameter values // Computes points on a bezier curve with control points specified by `bezier` at parameter values
// specified by `u`, which can be a scalar or a list. The value `u=0` gives the first endpoint; `u=1` gives the final endpoint, // specified by `u`, which can be a scalar or a list. The value `u=0` gives the first endpoint; `u=1` gives the final endpoint,
@ -176,10 +178,11 @@ function _bezier_matrix(N) =
// Function: bezier_curve() // Function: bezier_curve()
// Synopsis: Computes a number of uniformly distributed points along a bezier curve.
// Topics: Bezier Curves
// See Also: bezier_curve(), bezier_curvature(), bezier_tangent(), bezier_derivative(), bezier_points()
// Usage: // Usage:
// path = bezier_curve(bezier, [splinesteps], [endpoint]); // path = bezier_curve(bezier, [splinesteps], [endpoint]);
// Topics: Bezier Curves
// See Also: bezier_curvature(), bezier_tangent(), bezier_derivative(), bezier_points()
// Description: // Description:
// Takes a list of bezier control points and generates splinesteps segments (splinesteps+1 points) // Takes a list of bezier control points and generates splinesteps segments (splinesteps+1 points)
// along the bezier curve they define. // along the bezier curve they define.
@ -210,12 +213,13 @@ function bezier_curve(bezier,splinesteps=16,endpoint=true) =
// Function: bezier_derivative() // Function: bezier_derivative()
// Synopsis: Evaluates the derivative of the bezier curve at the given point or points.
// Topics: Bezier Curves
// See Also: bezier_curvature(), bezier_tangent(), bezier_points()
// Usage: // Usage:
// deriv = bezier_derivative(bezier, u, [order]); // deriv = bezier_derivative(bezier, u, [order]);
// derivs = bezier_derivative(bezier, LIST, [order]); // derivs = bezier_derivative(bezier, LIST, [order]);
// derivs = bezier_derivative(bezier, RANGE, [order]); // derivs = bezier_derivative(bezier, RANGE, [order]);
// Topics: Bezier Curves
// See Also: bezier_curvature(), bezier_tangent(), bezier_points()
// Description: // Description:
// Evaluates the derivative of the bezier curve at the given parameter value or values, `u`. The `order` gives the order of the derivative. // Evaluates the derivative of the bezier curve at the given parameter value or values, `u`. The `order` gives the order of the derivative.
// The degree of the bezier curve is one less than the number of points in `bezier`. // The degree of the bezier curve is one less than the number of points in `bezier`.
@ -234,12 +238,13 @@ function bezier_derivative(bezier, u, order=1) =
// Function: bezier_tangent() // Function: bezier_tangent()
// Synopsis: Calculates unit tangent vectors along the bezier curve at one or more given positions.
// Topics: Bezier Curves
// See Also: bezier_curvature(), bezier_derivative(), bezier_points()
// Usage: // Usage:
// tanvec = bezier_tangent(bezier, u); // tanvec = bezier_tangent(bezier, u);
// tanvecs = bezier_tangent(bezier, LIST); // tanvecs = bezier_tangent(bezier, LIST);
// tanvecs = bezier_tangent(bezier, RANGE); // tanvecs = bezier_tangent(bezier, RANGE);
// Topics: Bezier Curves
// See Also: bezier_curvature(), bezier_derivative(), bezier_points()
// Description: // Description:
// Returns the unit tangent vector at the given parameter values on a bezier curve with control points `bezier`. // Returns the unit tangent vector at the given parameter values on a bezier curve with control points `bezier`.
// Arguments: // Arguments:
@ -254,12 +259,13 @@ function bezier_tangent(bezier, u) =
// Function: bezier_curvature() // Function: bezier_curvature()
// Synopsis: Returns the curvature values at one or more given positions along a bezier curve.
// Topics: Bezier Curves
// See Also: bezier_tangent(), bezier_derivative(), bezier_points()
// Usage: // Usage:
// crv = bezier_curvature(curve, u); // crv = bezier_curvature(curve, u);
// crvlist = bezier_curvature(curve, LIST); // crvlist = bezier_curvature(curve, LIST);
// crvlist = bezier_curvature(curve, RANGE); // crvlist = bezier_curvature(curve, RANGE);
// Topics: Bezier Curves
// See Also: bezier_tangent(), bezier_derivative(), bezier_points()
// Description: // Description:
// Returns the curvature value for the given parameters `u` on the bezier curve with control points `bezier`. // Returns the curvature value for the given parameters `u` on the bezier curve with control points `bezier`.
// The curvature is the inverse of the radius of the tangent circle at the given point. // The curvature is the inverse of the radius of the tangent circle at the given point.
@ -284,10 +290,11 @@ function bezier_curvature(bezier, u) =
// Function: bezier_closest_point() // Function: bezier_closest_point()
// Usage: // Synopsis: Finds the closest position on a bezier curve to a given point.
// u = bezier_closest_point(bezier, pt, [max_err]);
// Topics: Bezier Curves // Topics: Bezier Curves
// See Also: bezier_points() // See Also: bezier_points()
// Usage:
// u = bezier_closest_point(bezier, pt, [max_err]);
// Description: // Description:
// Finds the closest part of the given bezier curve to point `pt`. // Finds the closest part of the given bezier curve to point `pt`.
// The degree of the curve, N, is one less than the number of points in `curve`. // The degree of the curve, N, is one less than the number of points in `curve`.
@ -333,10 +340,11 @@ function bezier_closest_point(bezier, pt, max_err=0.01, u=0, end_u=1) =
// Function: bezier_length() // Function: bezier_length()
// Usage: // Synopsis: Approximate the length of part of a bezier curve.
// pathlen = bezier_length(bezier, [start_u], [end_u], [max_deflect]);
// Topics: Bezier Curves // Topics: Bezier Curves
// See Also: bezier_points() // See Also: bezier_points()
// Usage:
// pathlen = bezier_length(bezier, [start_u], [end_u], [max_deflect]);
// Description: // Description:
// Approximates the length of the portion of the bezier curve between start_u and end_u. // Approximates the length of the portion of the bezier curve between start_u and end_u.
// Arguments: // Arguments:
@ -370,10 +378,11 @@ function bezier_length(bezier, start_u=0, end_u=1, max_deflect=0.01) =
// Function: bezier_line_intersection() // Function: bezier_line_intersection()
// Usage: // Synopsis: Calculates where a bezier curve intersects a line.
// u = bezier_line_intersection(bezier, line);
// Topics: Bezier Curves, Geometry, Intersection // Topics: Bezier Curves, Geometry, Intersection
// See Also: bezier_points(), bezier_length(), bezier_closest_point() // See Also: bezier_points(), bezier_length(), bezier_closest_point()
// Usage:
// u = bezier_line_intersection(bezier, line);
// Description: // Description:
// Finds the intersection points of the 2D Bezier curve with control points `bezier` and the given line, specified as a pair of points. // Finds the intersection points of the 2D Bezier curve with control points `bezier` and the given line, specified as a pair of points.
// Returns the intersection as a list of `u` values for the Bezier. // Returns the intersection as a list of `u` values for the Bezier.
@ -404,12 +413,13 @@ function bezier_line_intersection(bezier, line) =
// Function: bezpath_points() // Function: bezpath_points()
// Synopsis: Computes one or more specified points along a bezier path.
// Topics: Bezier Paths
// See Also: bezier_points(), bezier_curve()
// Usage: // Usage:
// pt = bezpath_points(bezpath, curveind, u, [N]); // pt = bezpath_points(bezpath, curveind, u, [N]);
// ptlist = bezpath_points(bezpath, curveind, LIST, [N]); // ptlist = bezpath_points(bezpath, curveind, LIST, [N]);
// path = bezpath_points(bezpath, curveind, RANGE, [N]); // path = bezpath_points(bezpath, curveind, RANGE, [N]);
// Topics: Bezier Paths
// See Also: bezier_points(), bezier_curve()
// Description: // Description:
// Extracts from the Bezier path `bezpath` the control points for the Bezier curve whose index is `curveind` and // Extracts from the Bezier path `bezpath` the control points for the Bezier curve whose index is `curveind` and
// computes the point or points on the corresponding Bezier curve specified by `u`. If `curveind` is zero you // computes the point or points on the corresponding Bezier curve specified by `u`. If `curveind` is zero you
@ -424,12 +434,13 @@ function bezpath_points(bezpath, curveind, u, N=3) =
// Function: bezpath_curve() // Function: bezpath_curve()
// Synopsis: Takes a bezier path and converts it into a path of points.
// Topics: Bezier Paths
// See Also: bezier_points(), bezier_curve(), bezpath_points()
// Usage: // Usage:
// path = bezpath_curve(bezpath, [splinesteps], [N], [endpoint]) // path = bezpath_curve(bezpath, [splinesteps], [N], [endpoint])
// Topics: Bezier Paths
// See Also: bezier_points(), bezier_curve()
// Description: // Description:
// Takes a bezier path and converts it into a path of points. // Computes a number of uniformly distributed points along a bezier path.
// Arguments: // Arguments:
// bezpath = A bezier path to approximate. // bezpath = A bezier path to approximate.
// splinesteps = Number of straight lines to split each bezier curve into. default=16 // splinesteps = Number of straight lines to split each bezier curve into. default=16
@ -459,10 +470,11 @@ function bezpath_curve(bezpath, splinesteps=16, N=3, endpoint=true) =
// Function: bezpath_closest_point() // Function: bezpath_closest_point()
// Synopsis: Finds the closest part of a bezier path to a give point.
// Topics: Bezier Paths
// See Also: bezpath_points(), bezpath_curve(), bezier_points(), bezier_curve(), bezier_closest_point()
// Usage: // Usage:
// res = bezpath_closest_point(bezpath, pt, [N], [max_err]); // res = bezpath_closest_point(bezpath, pt, [N], [max_err]);
// Topics: Bezier Paths
// See Also: bezier_points(), bezier_curve(), bezier_closest_point()
// Description: // Description:
// Finds an approximation to the closest part of the given bezier path to point `pt`. // Finds an approximation to the closest part of the given bezier path to point `pt`.
// Returns [segnum, u] for the closest position on the bezier path to the given point `pt`. // Returns [segnum, u] for the closest position on the bezier path to the given point `pt`.
@ -504,10 +516,11 @@ function bezpath_closest_point(bezpath, pt, N=3, max_err=0.01, seg=0, min_seg=un
// Function: bezpath_length() // Function: bezpath_length()
// Usage: // Synopsis: Approximate the length of a bezier path.
// plen = bezpath_length(path, [N], [max_deflect]);
// Topics: Bezier Paths // Topics: Bezier Paths
// See Also: bezier_points(), bezier_curve(), bezier_length() // See Also: bezier_points(), bezier_curve(), bezier_length()
// Usage:
// plen = bezpath_length(path, [N], [max_deflect]);
// Description: // Description:
// Approximates the length of the bezier path. // Approximates the length of the bezier path.
// Arguments: // Arguments:
@ -530,10 +543,11 @@ function bezpath_length(bezpath, N=3, max_deflect=0.001) =
// Function: path_to_bezpath() // Function: path_to_bezpath()
// Usage: // Synopsis: Generates a bezier path that passes through all points in a given linear path.
// bezpath = path_to_bezpath(path, [closed], [tangents], [uniform], [size=]|[relsize=]);
// Topics: Bezier Paths, Rounding // Topics: Bezier Paths, Rounding
// See Also: path_tangents() // See Also: path_tangents()
// Usage:
// bezpath = path_to_bezpath(path, [closed], [tangents], [uniform], [size=]|[relsize=]);
// Description: // Description:
// Given a 2d or 3d input path and optional list of tangent vectors, computes a cubic (degree 3) bezier // Given a 2d or 3d input path and optional list of tangent vectors, computes a cubic (degree 3) bezier
// path that passes through every point on the input path and matches the tangent vectors. If you do // path that passes through every point on the input path and matches the tangent vectors. If you do
@ -616,10 +630,11 @@ function path_to_bezpath(path, closed, tangents, uniform=false, size, relsize) =
// Function: bezpath_close_to_axis() // Function: bezpath_close_to_axis()
// Usage: // Synopsis: Closes a 2D bezier path to the specified axis.
// bezpath = bezpath_close_to_axis(bezpath, [axis], [N]);
// Topics: Bezier Paths // Topics: Bezier Paths
// See Also: bezpath_offset() // See Also: bezpath_offset()
// Usage:
// bezpath = bezpath_close_to_axis(bezpath, [axis], [N]);
// Description: // Description:
// Takes a 2D bezier path and closes it to the specified axis. // Takes a 2D bezier path and closes it to the specified axis.
// Arguments: // Arguments:
@ -659,10 +674,11 @@ function bezpath_close_to_axis(bezpath, axis="X", N=3) =
// Function: bezpath_offset() // Function: bezpath_offset()
// Usage: // Synopsis: Forms a closed bezier path loop with a translated and reversed copy of itself.
// bezpath = bezpath_offset(offset, bezier, [N]);
// Topics: Bezier Paths // Topics: Bezier Paths
// See Also: bezpath_close_to_axis() // See Also: bezpath_close_to_axis()
// Usage:
// bezpath = bezpath_offset(offset, bezier, [N]);
// Description: // Description:
// Takes a 2D bezier path and closes it with a matching reversed path that is offset by the given `offset` [X,Y] distance. // Takes a 2D bezier path and closes it with a matching reversed path that is offset by the given `offset` [X,Y] distance.
// Arguments: // Arguments:
@ -697,6 +713,7 @@ function bezpath_offset(offset, bezier, N=3) =
// Section: Cubic Bezier Path Construction // Section: Cubic Bezier Path Construction
// Function: bez_begin() // Function: bez_begin()
// Synopsis: Calculates starting bezier path control points.
// Topics: Bezier Paths // Topics: Bezier Paths
// See Also: bez_tang(), bez_joint(), bez_end() // See Also: bez_tang(), bez_joint(), bez_end()
// Usage: // Usage:
@ -767,6 +784,7 @@ function bez_begin(pt,a,r,p) =
// Function: bez_tang() // Function: bez_tang()
// Synopsis: Calculates control points for a smooth bezier path joint.
// Topics: Bezier Paths // Topics: Bezier Paths
// See Also: bez_begin(), bez_joint(), bez_end() // See Also: bez_begin(), bez_joint(), bez_end()
// Usage: // Usage:
@ -802,6 +820,7 @@ function bez_tang(pt,a,r1,r2,p) =
// Function: bez_joint() // Function: bez_joint()
// Synopsis: Calculates control points for a disjointed corner bezier path joint.
// Topics: Bezier Paths // Topics: Bezier Paths
// See Also: bez_begin(), bez_tang(), bez_end() // See Also: bez_begin(), bez_tang(), bez_end()
// Usage: // Usage:
@ -842,6 +861,7 @@ function bez_joint(pt,a1,a2,r1,r2,p1,p2) =
// Function: bez_end() // Function: bez_end()
// Synopsis: Calculates ending bezier path control points.
// Topics: Bezier Paths // Topics: Bezier Paths
// See Also: bez_tang(), bez_joint(), bez_end() // See Also: bez_tang(), bez_joint(), bez_end()
// Usage: // Usage:
@ -868,11 +888,12 @@ function bez_end(pt,a,r,p) =
// Function: is_bezier_patch() // Function: is_bezier_patch()
// Synopsis: Returns true if the given item is a bezier patch.
// Topics: Bezier Patches, Type Checking
// Usage: // Usage:
// bool = is_bezier_patch(x); // bool = is_bezier_patch(x);
// Topics: Bezier Patches, Type Checking
// Description: // Description:
// Returns true if the given item is a bezier patch. // Returns true if the given item is a bezier patch. (a 2D array of 3D points.)
// Arguments: // Arguments:
// x = The value to check the type of. // x = The value to check the type of.
function is_bezier_patch(x) = function is_bezier_patch(x) =
@ -880,10 +901,11 @@ function is_bezier_patch(x) =
// Function: bezier_patch_flat() // Function: bezier_patch_flat()
// Usage: // Synopsis: Creates a flat bezier patch.
// patch = bezier_patch_flat(size, [N=], [spin=], [orient=], [trans=]);
// Topics: Bezier Patches // Topics: Bezier Patches
// See Also: bezier_patch_points() // See Also: bezier_patch_points()
// Usage:
// patch = bezier_patch_flat(size, [N=], [spin=], [orient=], [trans=]);
// Description: // Description:
// Returns a flat rectangular bezier patch of degree `N`, centered on the XY plane. // Returns a flat rectangular bezier patch of degree `N`, centered on the XY plane.
// Arguments: // Arguments:
@ -913,10 +935,11 @@ function bezier_patch_flat(size, N=1, spin=0, orient=UP, trans=[0,0,0]) =
// Function: bezier_patch_reverse() // Function: bezier_patch_reverse()
// Usage: // Synopsis: Reverses the orientation of a bezier patch.
// rpatch = bezier_patch_reverse(patch);
// Topics: Bezier Patches // Topics: Bezier Patches
// See Also: bezier_patch_points(), bezier_patch_flat() // See Also: bezier_patch_points(), bezier_patch_flat()
// Usage:
// rpatch = bezier_patch_reverse(patch);
// Description: // Description:
// Reverses the patch, so that the faces generated from it are flipped back to front. // Reverses the patch, so that the faces generated from it are flipped back to front.
// Arguments: // Arguments:
@ -926,12 +949,13 @@ function bezier_patch_reverse(patch) =
// Function: bezier_patch_points() // Function: bezier_patch_points()
// Synopsis: Computes one or more specified points across a bezier surface patch.
// Topics: Bezier Patches
// See Also: bezier_patch_normals(), bezier_points(), bezier_curve(), bezpath_curve()
// Usage: // Usage:
// pt = bezier_patch_points(patch, u, v); // pt = bezier_patch_points(patch, u, v);
// ptgrid = bezier_patch_points(patch, LIST, LIST); // ptgrid = bezier_patch_points(patch, LIST, LIST);
// ptgrid = bezier_patch_points(patch, RANGE, RANGE); // ptgrid = bezier_patch_points(patch, RANGE, RANGE);
// Topics: Bezier Patches
// See Also: bezier_patch_normals(), bezier_points(), bezier_curve(), bezpath_curve()
// Description: // Description:
// Sample a bezier patch on a listed point set. The bezier patch must be a rectangular array of // Sample a bezier patch on a listed point set. The bezier patch must be a rectangular array of
// points, and it will be sampled at all the (u,v) pairs that you specify. If you give u and v // points, and it will be sampled at all the (u,v) pairs that you specify. If you give u and v
@ -987,10 +1011,11 @@ function _bezier_rectangle(patch, splinesteps=16, style="default") =
// Function: bezier_vnf() // Function: bezier_vnf()
// Usage: // Synopsis: Generates a (probably non-manifold) VNF for one or more bezier surface patches.
// vnf = bezier_vnf(patches, [splinesteps], [style]);
// Topics: Bezier Patches // Topics: Bezier Patches
// See Also: bezier_patch_points(), bezier_patch_flat() // See Also: bezier_patch_points(), bezier_patch_flat()
// Usage:
// vnf = bezier_vnf(patches, [splinesteps], [style]);
// Description: // Description:
// Convert a patch or list of patches into the corresponding Bezier surface, representing the // Convert a patch or list of patches into the corresponding Bezier surface, representing the
// result as a [VNF structure](vnf.scad). The `splinesteps` argument specifies the sampling grid of // result as a [VNF structure](vnf.scad). The `splinesteps` argument specifies the sampling grid of
@ -1113,6 +1138,9 @@ function bezier_vnf(patches=[], splinesteps=16, style="default") =
// Function: bezier_vnf_degenerate_patch() // Function: bezier_vnf_degenerate_patch()
// Synopsis: Generates a VNF for a degenerate bezier surface patch.
// Topics: Bezier Patches
// See Also: bezier_patch_points(), bezier_patch_flat(), bezier_vnf()
// Usage: // Usage:
// vnf = bezier_vnf_degenerate_patch(patch, [splinesteps], [reverse]); // vnf = bezier_vnf_degenerate_patch(patch, [splinesteps], [reverse]);
// vnf_edges = bezier_vnf_degenerate_patch(patch, [splinesteps], [reverse], return_edges=true); // vnf_edges = bezier_vnf_degenerate_patch(patch, [splinesteps], [reverse], return_edges=true);
@ -1297,12 +1325,13 @@ function bezier_vnf_degenerate_patch(patch, splinesteps=16, reverse=false, retur
// Function: bezier_patch_normals() // Function: bezier_patch_normals()
// Synopsis: Computes surface normals for one or more places on a bezier surface patch.
// Topics: Bezier Patches
// See Also: bezier_patch_points(), bezier_points(), bezier_curve(), bezpath_curve()
// Usage: // Usage:
// n = bezier_patch_normals(patch, u, v); // n = bezier_patch_normals(patch, u, v);
// ngrid = bezier_patch_normals(patch, LIST, LIST); // ngrid = bezier_patch_normals(patch, LIST, LIST);
// ngrid = bezier_patch_normals(patch, RANGE, RANGE); // ngrid = bezier_patch_normals(patch, RANGE, RANGE);
// Topics: Bezier Patches
// See Also: bezier_patch_points(), bezier_points(), bezier_curve(), bezpath_curve()
// Description: // Description:
// Compute the unit normal vector to a bezier patch at the listed point set. The bezier patch must be a rectangular array of // Compute the unit normal vector to a bezier patch at the listed point set. The bezier patch must be a rectangular array of
// points, and the normal will be computed at all the (u,v) pairs that you specify. If you give u and v // points, and the normal will be computed at all the (u,v) pairs that you specify. If you give u and v
@ -1409,10 +1438,11 @@ function bezier_patch_normals(patch, u, v) =
// Module: debug_bezier() // Module: debug_bezier()
// Usage: // Synopsis: Shows a bezier path and it's associated control points.
// debug_bezier(bez, [size], [N=]);
// Topics: Bezier Paths, Debugging // Topics: Bezier Paths, Debugging
// See Also: bezpath_curve() // See Also: bezpath_curve()
// Usage:
// debug_bezier(bez, [size], [N=]);
// Description: // Description:
// Renders 2D or 3D bezier paths and their associated control points. // Renders 2D or 3D bezier paths and their associated control points.
// Useful for debugging bezier paths. // Useful for debugging bezier paths.
@ -1462,10 +1492,11 @@ module debug_bezier(bezpath, width=1, N=3) {
// Module: debug_bezier_patches() // Module: debug_bezier_patches()
// Usage: // Synopsis: Shows a bezier surface patch and its associated control points.
// debug_bezier_patches(patches, [size=], [splinesteps=], [showcps=], [showdots=], [showpatch=], [convexity=], [style=]);
// Topics: Bezier Patches, Debugging // Topics: Bezier Patches, Debugging
// See Also: bezier_patch_points(), bezier_patch_flat(), bezier_vnf() // See Also: bezier_patch_points(), bezier_patch_flat(), bezier_vnf()
// Usage:
// debug_bezier_patches(patches, [size=], [splinesteps=], [showcps=], [showdots=], [showpatch=], [convexity=], [style=]);
// Description: // Description:
// Shows the surface, and optionally, control points of a list of bezier patches. // Shows the surface, and optionally, control points of a list of bezier patches.
// Arguments: // Arguments:

View file

@ -120,7 +120,7 @@ module pco1810_neck(wall=2, anchor="support-ring", spin=0, orient=UP)
thread_depth=thread_h+0.1, thread_depth=thread_h+0.1,
flank_angle=flank_angle, flank_angle=flank_angle,
turns=810/360, turns=810/360,
taper=-thread_h*2, lead_in=-thread_h*2,
anchor=TOP anchor=TOP
); );
zrot_copies(rots=[90,270]) { zrot_copies(rots=[90,270]) {
@ -196,7 +196,7 @@ module pco1810_cap(wall=2, texture="none", anchor=BOTTOM, spin=0, orient=UP)
} }
up(wall) cyl(d=cap_id, h=tamper_ring_h+wall, anchor=BOTTOM); up(wall) cyl(d=cap_id, h=tamper_ring_h+wall, anchor=BOTTOM);
} }
up(wall+2) thread_helix(d=thread_od-thread_depth*2, pitch=thread_pitch, thread_depth=thread_depth, flank_angle=flank_angle, turns=810/360, taper=-thread_depth, internal=true, anchor=BOTTOM); up(wall+2) thread_helix(d=thread_od-thread_depth*2, pitch=thread_pitch, thread_depth=thread_depth, flank_angle=flank_angle, turns=810/360, lead_in=-thread_depth, internal=true, anchor=BOTTOM);
} }
children(); children();
} }
@ -315,7 +315,7 @@ module pco1881_neck(wall=2, anchor="support-ring", spin=0, orient=UP)
thread_depth=thread_h+0.1, thread_depth=thread_h+0.1,
flank_angle=flank_angle, flank_angle=flank_angle,
turns=650/360, turns=650/360,
taper=-thread_h*2, lead_in=-thread_h*2,
anchor=TOP anchor=TOP
); );
zrot_copies(rots=[90,270]) { zrot_copies(rots=[90,270]) {
@ -383,7 +383,7 @@ module pco1881_cap(wall=2, texture="none", anchor=BOTTOM, spin=0, orient=UP)
} }
up(wall) cyl(d=28.58, h=11.2+wall, anchor=BOTTOM); up(wall) cyl(d=28.58, h=11.2+wall, anchor=BOTTOM);
} }
up(wall+2) thread_helix(d=25.5, pitch=2.7, thread_depth=1.6, flank_angle=15, turns=650/360, taper=-1.6, internal=true, anchor=BOTTOM); up(wall+2) thread_helix(d=25.5, pitch=2.7, thread_depth=1.6, flank_angle=15, turns=650/360, lead_in=-1.6, internal=true, anchor=BOTTOM);
} }
children(); children();
} }
@ -490,7 +490,7 @@ module generic_bottle_neck(
thread_depth = thread_h + 0.1 * diamMagMult, thread_depth = thread_h + 0.1 * diamMagMult,
flank_angle = flank_angle, flank_angle = flank_angle,
turns = (height - pitch - lip_roundover_r) * .6167 / pitch, turns = (height - pitch - lip_roundover_r) * .6167 / pitch,
taper = -thread_h * 2, lead_in = -thread_h * 2,
anchor = TOP anchor = TOP
); );
zrot_copies(rots = [90, 270]) { zrot_copies(rots = [90, 270]) {
@ -597,7 +597,7 @@ module generic_bottle_cap(
difference(){ difference(){
up(wall + pitch / 2) { up(wall + pitch / 2) {
thread_helix(d = neckOuterDTol, pitch = pitch, thread_depth = threadDepth, flank_angle = flank_angle, thread_helix(d = neckOuterDTol, pitch = pitch, thread_depth = threadDepth, flank_angle = flank_angle,
turns = ((height - pitch) / pitch), taper = -threadDepth, internal = true, anchor = BOTTOM); turns = ((height - pitch) / pitch), lead_in = -threadDepth, internal = true, anchor = BOTTOM);
} }
} }
} }
@ -984,8 +984,9 @@ function bottle_adapter_neck_to_neck(
// 400, 410 and 415. The 400 type neck has 360 degrees of thread, the 410 // 400, 410 and 415. The 400 type neck has 360 degrees of thread, the 410
// neck has 540 degrees of thread, and the 415 neck has 720 degrees of thread. // neck has 540 degrees of thread, and the 415 neck has 720 degrees of thread.
// You can also choose between the L style thread, which is symmetric and // You can also choose between the L style thread, which is symmetric and
// the M style thread, which is an asymmetric buttress thread. You can // the M style thread, which is an asymmetric buttress thread. The M style
// specify the wall thickness (measured from the base of the threads) or // may be good for 3d printing if printed with the flat face up.
// You can specify the wall thickness (measured from the base of the threads) or
// the inner diameter, and you can specify an optional bead at the base of the threads. // the inner diameter, and you can specify an optional bead at the base of the threads.
// Arguments: // Arguments:
// diam = nominal outer diameter of threads // diam = nominal outer diameter of threads
@ -1124,6 +1125,8 @@ module sp_neck(diam,type,wall,id,style="L",bead=false, anchor, spin, orient)
H = entry[2]; H = entry[2];
S = entry[3]; S = entry[3];
tpi = entry[4]; tpi = entry[4];
// a is the width of the thread
a = (style=="M" && tpi==12) ? 1.3 : struct_val(_sp_thread_width,tpi); a = (style=="M" && tpi==12) ? 1.3 : struct_val(_sp_thread_width,tpi);
twist = struct_val(_sp_twist, type); twist = struct_val(_sp_twist, type);
@ -1156,7 +1159,7 @@ module sp_neck(diam,type,wall,id,style="L",bead=false, anchor, spin, orient)
up((H+extra_bot)/2){ up((H+extra_bot)/2){
difference(){ difference(){
union(){ union(){
thread_helix(d=T-.01, profile=profile, pitch = INCH/tpi, turns=twist/360, taper=taperlen, anchor=TOP); thread_helix(d=T-.01, profile=profile, pitch = INCH/tpi, turns=twist/360, lead_in=taperlen, anchor=TOP);
cylinder(d=T-depth*2,h=H,anchor=TOP); cylinder(d=T-depth*2,h=H,anchor=TOP);
if (bead) if (bead)
down(bead_shift) down(bead_shift)
@ -1187,12 +1190,15 @@ module sp_neck(diam,type,wall,id,style="L",bead=false, anchor, spin, orient)
// the M style thread, which is an asymmetric buttress thread. Note that it // the M style thread, which is an asymmetric buttress thread. Note that it
// is OK to mix styles, so you can put an L-style cap onto an M-style neck. // is OK to mix styles, so you can put an L-style cap onto an M-style neck.
// . // .
// These caps often contain a cardboard or foam sealer disk, which can be as much as 1mm thick. // The 410 and 415 caps have very long unthreaded sections at the bottom.
// If you don't include this, your cap may bottom out on the bead on the neck instead of sealing // The bot_adj parameter specifies an amount to reduce that bottom extension, which might be
// against the top. If you set top_adj to 1 it will make the top space 1mm smaller so that the // necessary if the cap bottoms out on the bead. Be careful that you don't shrink past the threads,
// cap will not bottom out. The 410 and 415 caps have very long unthreaded sections at the bottom. // especially if making adjustments to 400 caps which have a very small bottom extension.
// The bot_adj parameter specifies an amount to reduce that bottom extension. Be careful that // These caps often contain a cardboard or foam sealer disk, which can be as much as 1mm thick, and
// you don't shrink past the threads. // would cause the cap to stop in a higher position.
// .
// You can also adjust the space between the top of the cap and the threads using top_adj. This
// will change how the threads engage when the cap is fully seated.
// . // .
// The inner diameter of the cap is set to allow 10% of the thread depth in clearance. The diameter // The inner diameter of the cap is set to allow 10% of the thread depth in clearance. The diameter
// is further increased by `2 * $slop` so you can increase clearance if necessary. // is further increased by `2 * $slop` so you can increase clearance if necessary.
@ -1215,6 +1221,7 @@ module sp_neck(diam,type,wall,id,style="L",bead=false, anchor, spin, orient)
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP` // orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
// Examples: // Examples:
// sp_cap(48,400,2); // sp_cap(48,400,2);
// sp_cap(22,400,2);
// sp_cap(22,410,2); // sp_cap(22,410,2);
// sp_cap(28,415,1.5,style="M"); // sp_cap(28,415,1.5,style="M");
module sp_cap(diam,type,wall,style="L",top_adj=0, bot_adj=0, texture="none", anchor, spin, orient) module sp_cap(diam,type,wall,style="L",top_adj=0, bot_adj=0, texture="none", anchor, spin, orient)
@ -1227,13 +1234,14 @@ module sp_cap(diam,type,wall,style="L",top_adj=0, bot_adj=0, texture="none", anc
T = entry[0]; T = entry[0];
I = entry[1]; I = entry[1];
H = entry[2]-1; H = entry[2]-0.5;
S = entry[3]; S = entry[3];
tpi = entry[4]; tpi = entry[4];
a = (style=="M" && tpi==12) ? 1.3 : struct_val(_sp_thread_width,tpi); a = (style=="M" && tpi==12) ? 1.3 : struct_val(_sp_thread_width,tpi);
twist = struct_val(_sp_twist, type); twist = struct_val(_sp_twist, type);
echo(top_adj=top_adj,bot_adj=bot_adj);
dum3=assert(top_adj<S+0.75*a, str("The top_adj value is too large so the thread won't fit. It must be smaller than ",S+0.75*a)); dum3=assert(top_adj<S+0.75*a, str("The top_adj value is too large so the thread won't fit. It must be smaller than ",S+0.75*a));
oprofile = _sp_thread_profile(tpi,a,S+0.75*a-top_adj,style,flip=true); oprofile = _sp_thread_profile(tpi,a,S+0.75*a-top_adj,style,flip=true);
bounds=pointlist_bounds(oprofile); bounds=pointlist_bounds(oprofile);
@ -1257,7 +1265,7 @@ module sp_cap(diam,type,wall,style="L",top_adj=0, bot_adj=0, texture="none", anc
} }
cyl(d=T+space, l=H-bot_adj+1, anchor=TOP); cyl(d=T+space, l=H-bot_adj+1, anchor=TOP);
} }
thread_helix(d=T+space-.01, profile=profile, pitch = INCH/tpi, turns=twist/360, taper=taperlen, anchor=TOP, internal=true); thread_helix(d=T+space-.01, profile=profile, pitch = INCH/tpi, turns=twist/360, lead_in=taperlen, anchor=TOP, internal=true);
} }
children(); children();
} }

View file

@ -16,81 +16,67 @@ $cubetruss_clip_thickness = 1.6;
// Section: Cube Trusses // Section: Cube Trusses
// Function: cubetruss_dist() // Module: cubetruss()
// Synopsis: Creates a multi-cube straight cubetruss shape.
// Topics: Trusses, CubeTruss, FDM Optimized, Parts
// See Also: cubetruss_segment(), cubetruss_support(), cubetruss(), cubetruss_corner()
// Usage: // Usage:
// cubetruss_dist(cubes, gaps, [size], [strut]); // cubetruss(extents, [clips=], [bracing=], [size=], [strut=], [clipthick=], ...) [ATTACHMENTS];
// Description: // Description:
// Function to calculate the length of a cubetruss truss. // Creates a cubetruss truss, assembled out of one or more cubical segments.
// Arguments: // Arguments:
// cubes = The number of cubes along the truss's length. // extents = The number of cubes in length to make the truss. If given as a [X,Y,Z] vector, specifies the number of cubes in each dimension.
// gaps = The number of extra strut widths to add in, corresponding to each time a truss butts up against another. // clips = List of vectors pointing towards the sides to add clips to.
// size = The length of each side of the cubetruss cubes. Default: `$cubetruss_size` (usually 30)
// strut = The width of the struts on the cubetruss cubes. Default: `$cubetruss_strut_size` (usually 3)
// Topics: Trusses
function cubetruss_dist(cubes=0, gaps=0, size, strut) =
let(
size = is_undef(size)? $cubetruss_size : size,
strut = is_undef(strut)? $cubetruss_strut_size : strut
) cubes*(size-strut)+gaps*strut;
// Module: cubetruss_segment()
// Usage:
// cubetruss_segment([size], [strut], [bracing]);
// Description:
// Creates a single cubetruss cube segment.
// Arguments:
// size = The length of each side of the cubetruss cubes. Default: `$cubetruss_size` (usually 30)
// strut = The width of the struts on the cubetruss cubes. Default: `$cubetruss_strut_size` (usually 3)
// bracing = If true, adds internal cross-braces. Default: `$cubetruss_bracing` (usually true) // bracing = If true, adds internal cross-braces. Default: `$cubetruss_bracing` (usually true)
// size = The length of each side of the cubetruss cubes. Default: `$cubetruss_size` (usually 30)
// strut = The width of the struts on the cubetruss cubes. Default: `$cubetruss_strut_size` (usually 3)
// clipthick = The thickness of the clips. Default: `$cubetruss_clip_thickness` (usually 1.6)
// --- // ---
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER` // anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
// spin = Rotate this many degrees around the Z axis. See [spin](attachments.scad#subsection-spin). Default: `0` // spin = Rotate this many degrees around the Z axis. See [spin](attachments.scad#subsection-spin). Default: `0`
// orient = Vector to rotate top towards. See [orient](attachments.scad#subsection-orient). Default: `UP` // orient = Vector to rotate top towards. See [orient](attachments.scad#subsection-orient). Default: `UP`
// Topics: Attachable, Trusses // Topics: Attachable, Trusses
// Examples: // Examples:
// cubetruss_segment(bracing=false); // cubetruss(extents=3);
// cubetruss_segment(bracing=true); // cubetruss(extents=3, clips=FRONT);
// cubetruss_segment(strut=4); // cubetruss(extents=3, clips=[FRONT,BACK]);
// cubetruss_segment(size=40); // cubetruss(extents=[2,3]);
module cubetruss_segment(size, strut, bracing, anchor=CENTER, spin=0, orient=UP) { // cubetruss(extents=[1,4,2]);
// cubetruss(extents=[1,4,2], bracing=false);
module cubetruss(extents=6, clips=[], bracing, size, strut, clipthick, anchor=CENTER, spin=0, orient=UP) {
clips = is_vector(clips)? [clips] : clips;
size = is_undef(size)? $cubetruss_size : size; size = is_undef(size)? $cubetruss_size : size;
strut = is_undef(strut)? $cubetruss_strut_size : strut; strut = is_undef(strut)? $cubetruss_strut_size : strut;
bracing = is_undef(bracing)? $cubetruss_bracing : bracing; bracing = is_undef(bracing)? $cubetruss_bracing : bracing;
h = size; clipthick = is_undef(clipthick)? $cubetruss_clip_thickness : clipthick;
crossthick = strut/sqrt(2); extents = is_vector(extents)? point3d(extents,fill=1) : [1,extents,1];
voffset = 0.333; w = extents[0];
attachable(anchor,spin,orient, size=[size,size,size]) { l = extents[1];
render(convexity=10) h = extents[2];
s = [cubetruss_dist(w,1), cubetruss_dist(l,1), cubetruss_dist(h,1)];
attachable(anchor,spin,orient, size=s) {
union() { union() {
difference() { for (zrow = [0:h-1]) {
// Start with a cube. up((zrow-(h-1)/2)*(size-strut)) {
cube([size, size, h], center=true); for (xcol = [0:w-1]) {
right((xcol-(w-1)/2)*(size-strut)) {
cube([size-strut*2, size-strut*2, h-strut*2], center=true); for (ycol = [0:l-1]) {
back((ycol-(l-1)/2)*(size-strut)) {
// Hollow out octogons in X and Y axes. cubetruss_segment(size=size, strut=strut, bracing=bracing);
zrot_copies([0,90]) { }
xrot(90) zrot(180/8) cylinder(h=max(h,size)+1, d=(min(h,size)-2*strut)/cos(180/8), center=true, $fn=8); }
}
}
} }
// Hollow out octogon vertically.
zrot(180/8) cylinder(h=max(h,size)+1, d=(min(h,size)-2*strut)/cos(180/8), center=true, $fn=8);
} }
if (clipthick > 0) {
// Interior cross-supports for (vec = clips) {
if (bracing) { exts = v_abs(rot(from=FWD, to=vec, p=extents));
for (i = [-1,1]) { rot(from=FWD,to=vec) {
zrot(i*45) { for (zrow = [0:1:exts.z-1]) {
difference() { up((zrow-(exts.z-1)/2)*(size-strut)) {
cube([crossthick, (size-strut)*sqrt(2), h], center=true); fwd((exts.y*(size-strut)+strut)/2) {
up(i*voffset) { cubetruss_clip(size=size, strut=strut, extents=exts.x, clipthick=clipthick);
yscale(1.3) {
yrot(90) {
zrot(180/6) {
cylinder(h=crossthick+1, d=(min(h,size)-2*strut)/cos(180/6)-2*voffset, center=true, $fn=6);
}
}
} }
} }
} }
@ -103,9 +89,88 @@ module cubetruss_segment(size, strut, bracing, anchor=CENTER, spin=0, orient=UP)
} }
// Module: cubetruss_support() // Module: cubetruss_corner()
// Synopsis: Creates a multi-cube corner cubetruss shape.
// Topics: Trusses, CubeTruss, FDM Optimized, Parts
// See Also: cubetruss_segment(), cubetruss_support(), cubetruss(), cubetruss_corner()
// Usage: // Usage:
// cubetruss_support([size], [strut], [extents], [anchor], [spin], [orient]) [ATTACHMENTS]; // cubetruss_corner(h, extents, [bracing=], [size=], [strut=], [clipthick=]);
// Description:
// Creates a corner cubetruss with extents jutting out in one or more directions.
// Arguments:
// h = The number of cubes high to make the base and horizontal extents.
// extents = The number of cubes to extend beyond the corner. If given as a vector of cube counts, gives the number of cubes to extend right, back, left, front, and up in order. If the vector is shorter than length 5 the extra cube counts are taken to be zero.
// bracing = If true, adds internal cross-braces. Default: `$cubetruss_bracing` (usually true)
// size = The length of each side of the cubetruss cubes. Default: `$cubetruss_size` (usually 30)
// strut = The width of the struts on the cubetruss cubes. Default: `$cubetruss_strut_size` (usually 3)
// clipthick = The thickness of the clips. Default: `$cubetruss_clip_thickness` (usually 1.6)
// ---
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
// spin = Rotate this many degrees around the Z axis. See [spin](attachments.scad#subsection-spin). Default: `0`
// orient = Vector to rotate top towards. See [orient](attachments.scad#subsection-orient). Default: `UP`
// Topics: Attachable, Trusses
// Examples:
// cubetruss_corner(extents=2);
// cubetruss_corner(extents=2, h=2);
// cubetruss_corner(extents=[3,3,0,0,2]);
// cubetruss_corner(extents=[3,0,3,0,2]);
// cubetruss_corner(extents=[3,3,3,3,2]);
module cubetruss_corner(h=1, extents=[1,1,0,0,1], bracing, size, strut, clipthick, anchor=CENTER, spin=0, orient=UP) {
size = is_undef(size)? $cubetruss_size : size;
strut = is_undef(strut)? $cubetruss_strut_size : strut;
bracing = is_undef(bracing)? $cubetruss_bracing : bracing;
clipthick = is_undef(clipthick)? $cubetruss_clip_thickness : clipthick;
exts = is_vector(extents)? list_pad(extents,5,fill=0) : [extents, extents, 0, 0, extents];
dummy = assert(len(exts)==5, "Input extents must be a scalar or vector with length 5 or less.");
s = [cubetruss_dist(exts[0]+1+exts[2],1), cubetruss_dist(exts[1]+1+exts[3],1), cubetruss_dist(h+exts[4],1)];
offset = [cubetruss_dist(exts[0]-exts[2],0), cubetruss_dist(exts[1]-exts[3],0), cubetruss_dist(h+exts[4]-1,0)]/2;
attachable(anchor,spin,orient, size=s, offset=offset) {
union() {
for (zcol = [0:h-1]) {
up((size-strut)*zcol) {
cubetruss_segment(size=size, strut=strut, bracing=bracing);
}
}
for (dir = [0:3]) {
if (exts[dir] != undef && exts[dir] > 0) {
zrot(dir*90) {
for (zcol = [0:h-1]) {
up((size-strut+0.01)*zcol) {
for (i = [1:exts[dir]]) {
right((size-strut+0.01)*i) cubetruss_segment(size=size, strut=strut, bracing=bracing);
}
if (clipthick > 0) {
right(exts[dir]*(size-strut)+size/2) {
zrot(90) cubetruss_clip(size=size, strut=strut, clipthick=clipthick);
}
}
}
}
}
}
}
if (exts[4] != undef && exts[4] > 0) {
for (i = [1:exts[4]]) {
up((size-strut+0.01)*(i+h-1)) cubetruss_segment(size=size, strut=strut, bracing=bracing);
}
if (clipthick > 0) {
up((exts[4]+h-1)*(size-strut)+size/2) {
xrot(-90) cubetruss_clip(size=size, strut=strut, clipthick=clipthick);
}
}
}
}
children();
}
}
// Module: cubetruss_support()
// Synopsis: Creates a cubetruss support structure shape.
// Topics: Trusses, CubeTruss, FDM Optimized, Parts
// See Also: cubetruss_segment(), cubetruss_support(), cubetruss(), cubetruss_corner()
// Usage:
// cubetruss_support([size=], [strut=], [extents=]) [ATTACHMENTS];
// Description: // Description:
// Creates a single cubetruss support. // Creates a single cubetruss support.
// Arguments: // Arguments:
@ -164,74 +229,15 @@ module cubetruss_support(size, strut, extents=1, anchor=CENTER, spin=0, orient=U
} }
// Module: cubetruss_clip()
// Usage:
// cubetruss_clip(extents, [size], [strut], [clipthick], [$slop=], [anchor=], [spin=], [orient=]) [ATTACHMENTS];
// Description:
// Creates a pair of clips to add onto the end of a truss.
// Arguments:
// extents = How many cubes to separate the clips by.
// size = The length of each side of the cubetruss cubes. Default: `$cubetruss_size` (usually 30)
// strut = The width of the struts on the cubetruss cubes. Default: `$cubetruss_strut_size` (usually 3)
// clipthick = The thickness of the clip. Default: `$cubetruss_clip_thickness` (usually 1.6)
// ---
// $slop = allowance for printer overextrusion
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
// spin = Rotate this many degrees around the Z axis. See [spin](attachments.scad#subsection-spin). Default: `0`
// orient = Vector to rotate top towards. See [orient](attachments.scad#subsection-orient). Default: `UP`
// Topics: Attachable, Trusses
// Examples:
// cubetruss_clip(extents=2);
// cubetruss_clip(extents=1);
// cubetruss_clip(clipthick=2.5);
module cubetruss_clip(extents=1, size, strut, clipthick, anchor=CENTER, spin=0, orient=UP) {
size = is_undef(size)? $cubetruss_size : size;
strut = is_undef(strut)? $cubetruss_strut_size : strut;
clipthick = is_undef(clipthick)? $cubetruss_clip_thickness : clipthick;
cliplen = strut * 2.6;
clipheight = min(size+strut, size/3+2*strut*2.6);
clipsize = 0.5;
s = [extents*(size-strut)+strut+2*clipthick, strut*2, clipheight-2*strut];
attachable(anchor,spin,orient, size=s) {
xflip_copy(offset=(extents*(size-strut)+strut)/2) {
difference() {
union() {
difference() {
right(clipthick/2-0.01) {
back(strut) {
difference() {
xrot(90) prismoid([clipthick, clipheight], [clipthick, clipheight-cliplen*2], h=cliplen);
right(clipthick/2) chamfer_edge_mask(l=clipheight+0.1, chamfer=clipthick);
}
}
}
fwd(strut*3/2) {
cube([get_slop(), strut*3, size], center=true);
}
}
right(get_slop()/2+0.01) {
fwd(strut*1.25+get_slop()) {
yrot(-90) prismoid([clipheight-cliplen*2, strut/2], [clipheight-cliplen*2-2*clipsize, strut/2], h=clipsize+0.01);
}
}
}
fwd(strut*1.6) {
left(clipsize) {
yscale(1.5) chamfer_edge_mask(l=size+1, chamfer=clipsize+clipthick/3);
}
}
zcopies(clipheight-strut) cube([clipthick*3, cliplen*2, strut], center=true);
zcopies(clipheight-2*strut) right(clipthick) chamfer_edge_mask(l=cliplen*2, chamfer=clipthick, orient=BACK);
}
}
children();
}
}
// Section: Cubetruss Support
// Module: cubetruss_foot() // Module: cubetruss_foot()
// Synopsis: Creates a foot that can connect two cubetrusses.
// Topics: Trusses, CubeTruss, FDM Optimized, Parts
// See Also: cubetruss_segment(), cubetruss_support(), cubetruss(), cubetruss_corner()
// Usage: // Usage:
// cubetruss_foot(w, [size], [strut], [clipthick], [$slop=], [anchor=], [spin=], [orient=]) [ATTACHMENTS]; // cubetruss_foot(w, [size=], [strut=], [clipthick=]) [ATTACHMENTS];
// Description: // Description:
// Creates a foot that can be clipped onto the bottom of a truss for support. // Creates a foot that can be clipped onto the bottom of a truss for support.
// Arguments: // Arguments:
@ -307,8 +313,11 @@ module cubetruss_foot(w=1, size, strut, clipthick, anchor=CENTER, spin=0, orient
// Module: cubetruss_joiner() // Module: cubetruss_joiner()
// Synopsis: Creates a joiner that can connect two cubetrusses end-to-end.
// Topics: Trusses, CubeTruss, FDM Optimized, Parts
// See Also: cubetruss_segment(), cubetruss_support(), cubetruss(), cubetruss_corner()
// Usage: // Usage:
// cubetruss_joiner([w], [vert], [size], [strut], [clipthick], [$slop=], [anchor=], [spin=], [orient=]) [ATTACHMENTS]; // cubetruss_joiner([w=], [vert=], [size=], [strut=], [clipthick=]) [ATTACHMENTS];
// Description: // Description:
// Creates a part to join two cubetruss trusses end-to-end. // Creates a part to join two cubetruss trusses end-to-end.
// Arguments: // Arguments:
@ -375,8 +384,11 @@ module cubetruss_joiner(w=1, vert=true, size, strut, clipthick, anchor=CENTER, s
// Module: cubetruss_uclip() // Module: cubetruss_uclip()
// Synopsis: Creates a joiner that can connect two cubetrusses end-to-end.
// Topics: Trusses, CubeTruss, FDM Optimized, Parts
// See Also: cubetruss_segment(), cubetruss_support(), cubetruss(), cubetruss_corner()
// Usage: // Usage:
// cubetruss_uclip(dual, [size], [strut], [clipthick], [$slop=], [anchor=], [spin=], [orient=]) [ATTACHMENTS]; // cubetruss_uclip(dual, [size=], [strut=], [clipthick=]) [ATTACHMENTS];
// Description: // Description:
// Creates a small clip that can snap around one or two adjacent struts. // Creates a small clip that can snap around one or two adjacent struts.
// Arguments: // Arguments:
@ -420,126 +432,68 @@ module cubetruss_uclip(dual=true, size, strut, clipthick, anchor=CENTER, spin=0,
} }
// Module: cubetruss()
// Section: Cubetruss Primitives
// Module: cubetruss_segment()
// Synopsis: Creates a single cubetruss cube.
// Topics: Trusses, CubeTruss, FDM Optimized, Parts
// See Also: cubetruss_segment(), cubetruss_support(), cubetruss(), cubetruss_corner()
// Usage: // Usage:
// cubetruss(extents, [clips], [bracing], [size], [strut], [clipthick]); // cubetruss_segment([size=], [strut=], [bracing=]);
// Description: // Description:
// Creates a cubetruss truss, assembled out of one or more cubical segments. // Creates a single cubetruss cube segment.
// Arguments: // Arguments:
// extents = The number of cubes in length to make the truss. If given as a [X,Y,Z] vector, specifies the number of cubes in each dimension.
// clips = List of vectors pointing towards the sides to add clips to.
// size = The length of each side of the cubetruss cubes. Default: `$cubetruss_size` (usually 30) // size = The length of each side of the cubetruss cubes. Default: `$cubetruss_size` (usually 30)
// strut = The width of the struts on the cubetruss cubes. Default: `$cubetruss_strut_size` (usually 3) // strut = The width of the struts on the cubetruss cubes. Default: `$cubetruss_strut_size` (usually 3)
// bracing = If true, adds internal cross-braces. Default: `$cubetruss_bracing` (usually true) // bracing = If true, adds internal cross-braces. Default: `$cubetruss_bracing` (usually true)
// clipthick = The thickness of the clips. Default: `$cubetruss_clip_thickness` (usually 1.6)
// --- // ---
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER` // anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
// spin = Rotate this many degrees around the Z axis. See [spin](attachments.scad#subsection-spin). Default: `0` // spin = Rotate this many degrees around the Z axis. See [spin](attachments.scad#subsection-spin). Default: `0`
// orient = Vector to rotate top towards. See [orient](attachments.scad#subsection-orient). Default: `UP` // orient = Vector to rotate top towards. See [orient](attachments.scad#subsection-orient). Default: `UP`
// Topics: Attachable, Trusses // Topics: Attachable, Trusses
// Examples: // Examples:
// cubetruss(extents=3); // cubetruss_segment(bracing=false);
// cubetruss(extents=3, clips=FRONT); // cubetruss_segment(bracing=true);
// cubetruss(extents=3, clips=[FRONT,BACK]); // cubetruss_segment(strut=4);
// cubetruss(extents=[2,3]); // cubetruss_segment(size=40);
// cubetruss(extents=[1,4,2]); module cubetruss_segment(size, strut, bracing, anchor=CENTER, spin=0, orient=UP) {
// cubetruss(extents=[1,4,2], bracing=false);
module cubetruss(extents=6, clips=[], bracing, size, strut, clipthick, anchor=CENTER, spin=0, orient=UP) {
clips = is_vector(clips)? [clips] : clips;
size = is_undef(size)? $cubetruss_size : size; size = is_undef(size)? $cubetruss_size : size;
strut = is_undef(strut)? $cubetruss_strut_size : strut; strut = is_undef(strut)? $cubetruss_strut_size : strut;
bracing = is_undef(bracing)? $cubetruss_bracing : bracing; bracing = is_undef(bracing)? $cubetruss_bracing : bracing;
clipthick = is_undef(clipthick)? $cubetruss_clip_thickness : clipthick; h = size;
extents = is_vector(extents)? point3d(extents,fill=1) : [1,extents,1]; crossthick = strut/sqrt(2);
w = extents[0]; voffset = 0.333;
l = extents[1]; attachable(anchor,spin,orient, size=[size,size,size]) {
h = extents[2]; render(convexity=10)
s = [cubetruss_dist(w,1), cubetruss_dist(l,1), cubetruss_dist(h,1)];
attachable(anchor,spin,orient, size=s) {
union() { union() {
for (zrow = [0:h-1]) { difference() {
up((zrow-(h-1)/2)*(size-strut)) { // Start with a cube.
for (xcol = [0:w-1]) { cube([size, size, h], center=true);
right((xcol-(w-1)/2)*(size-strut)) {
for (ycol = [0:l-1]) {
back((ycol-(l-1)/2)*(size-strut)) {
cubetruss_segment(size=size, strut=strut, bracing=bracing);
}
}
}
}
}
}
if (clipthick > 0) {
for (vec = clips) {
exts = v_abs(rot(from=FWD, to=vec, p=extents));
rot(from=FWD,to=vec) {
for (zrow = [0:1:exts.z-1]) {
up((zrow-(exts.z-1)/2)*(size-strut)) {
fwd((exts.y*(size-strut)+strut)/2) {
cubetruss_clip(size=size, strut=strut, extents=exts.x, clipthick=clipthick);
}
}
}
}
}
}
}
children();
}
}
cube([size-strut*2, size-strut*2, h-strut*2], center=true);
// Module: cubetruss_corner() // Hollow out octogons in X and Y axes.
// Usage: zrot_copies([0,90]) {
// cubetruss_corner(h, extents, [bracing], [size], [strut], [clipthick]); xrot(90) zrot(180/8) cylinder(h=max(h,size)+1, d=(min(h,size)-2*strut)/cos(180/8), center=true, $fn=8);
// Description:
// Creates a corner cubetruss with extents jutting out in one or more directions.
// Arguments:
// h = The number of cubes high to make the base and horizontal extents.
// extents = The number of cubes to extend beyond the corner. If given as a vector of cube counts, gives the number of cubes to extend right, back, left, front, and up in order. If the vector is shorter than length 5 the extra cube counts are taken to be zero.
// size = The length of each side of the cubetruss cubes. Default: `$cubetruss_size` (usually 30)
// strut = The width of the struts on the cubetruss cubes. Default: `$cubetruss_strut_size` (usually 3)
// bracing = If true, adds internal cross-braces. Default: `$cubetruss_bracing` (usually true)
// clipthick = The thickness of the clips. Default: `$cubetruss_clip_thickness` (usually 1.6)
// ---
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
// spin = Rotate this many degrees around the Z axis. See [spin](attachments.scad#subsection-spin). Default: `0`
// orient = Vector to rotate top towards. See [orient](attachments.scad#subsection-orient). Default: `UP`
// Topics: Attachable, Trusses
// Examples:
// cubetruss_corner(extents=2);
// cubetruss_corner(extents=2, h=2);
// cubetruss_corner(extents=[3,3,0,0,2]);
// cubetruss_corner(extents=[3,0,3,0,2]);
// cubetruss_corner(extents=[3,3,3,3,2]);
module cubetruss_corner(h=1, extents=[1,1,0,0,1], bracing, size, strut, clipthick, anchor=CENTER, spin=0, orient=UP) {
size = is_undef(size)? $cubetruss_size : size;
strut = is_undef(strut)? $cubetruss_strut_size : strut;
bracing = is_undef(bracing)? $cubetruss_bracing : bracing;
clipthick = is_undef(clipthick)? $cubetruss_clip_thickness : clipthick;
exts = is_vector(extents)? list_pad(extents,5,fill=0) : [extents, extents, 0, 0, extents];
dummy = assert(len(exts)==5, "Input extents must be a scalar or vector with length 5 or less.");
s = [cubetruss_dist(exts[0]+1+exts[2],1), cubetruss_dist(exts[1]+1+exts[3],1), cubetruss_dist(h+exts[4],1)];
offset = [cubetruss_dist(exts[0]-exts[2],0), cubetruss_dist(exts[1]-exts[3],0), cubetruss_dist(h+exts[4]-1,0)]/2;
attachable(anchor,spin,orient, size=s, offset=offset) {
union() {
for (zcol = [0:h-1]) {
up((size-strut)*zcol) {
cubetruss_segment(size=size, strut=strut, bracing=bracing);
} }
// Hollow out octogon vertically.
zrot(180/8) cylinder(h=max(h,size)+1, d=(min(h,size)-2*strut)/cos(180/8), center=true, $fn=8);
} }
for (dir = [0:3]) {
if (exts[dir] != undef && exts[dir] > 0) { // Interior cross-supports
zrot(dir*90) { if (bracing) {
for (zcol = [0:h-1]) { for (i = [-1,1]) {
up((size-strut+0.01)*zcol) { zrot(i*45) {
for (i = [1:exts[dir]]) { difference() {
right((size-strut+0.01)*i) cubetruss_segment(size=size, strut=strut, bracing=bracing); cube([crossthick, (size-strut)*sqrt(2), h], center=true);
} up(i*voffset) {
if (clipthick > 0) { yscale(1.3) {
right(exts[dir]*(size-strut)+size/2) { yrot(90) {
zrot(90) cubetruss_clip(size=size, strut=strut, clipthick=clipthick); zrot(180/6) {
cylinder(h=crossthick+1, d=(min(h,size)-2*strut)/cos(180/6)-2*voffset, center=true, $fn=6);
}
} }
} }
} }
@ -547,15 +501,73 @@ module cubetruss_corner(h=1, extents=[1,1,0,0,1], bracing, size, strut, clipthic
} }
} }
} }
if (exts[4] != undef && exts[4] > 0) { }
for (i = [1:exts[4]]) { children();
up((size-strut+0.01)*(i+h-1)) cubetruss_segment(size=size, strut=strut, bracing=bracing); }
} }
if (clipthick > 0) {
up((exts[4]+h-1)*(size-strut)+size/2) {
xrot(-90) cubetruss_clip(size=size, strut=strut, clipthick=clipthick); // Module: cubetruss_clip()
// Synopsis: Creates a clip for the end of a cubetruss to snap-lock it to another cubetruss.
// Topics: Trusses, CubeTruss, FDM Optimized, Parts
// See Also: cubetruss_segment(), cubetruss_support(), cubetruss(), cubetruss_corner()
// Usage:
// cubetruss_clip(extents, [size=], [strut=], [clipthick=]) [ATTACHMENTS];
// Description:
// Creates a pair of clips to add onto the end of a truss.
// Arguments:
// extents = How many cubes to separate the clips by.
// size = The length of each side of the cubetruss cubes. Default: `$cubetruss_size` (usually 30)
// strut = The width of the struts on the cubetruss cubes. Default: `$cubetruss_strut_size` (usually 3)
// clipthick = The thickness of the clip. Default: `$cubetruss_clip_thickness` (usually 1.6)
// ---
// $slop = allowance for printer overextrusion
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
// spin = Rotate this many degrees around the Z axis. See [spin](attachments.scad#subsection-spin). Default: `0`
// orient = Vector to rotate top towards. See [orient](attachments.scad#subsection-orient). Default: `UP`
// Topics: Attachable, Trusses
// Examples:
// cubetruss_clip(extents=2);
// cubetruss_clip(extents=1);
// cubetruss_clip(clipthick=2.5);
module cubetruss_clip(extents=1, size, strut, clipthick, anchor=CENTER, spin=0, orient=UP) {
size = is_undef(size)? $cubetruss_size : size;
strut = is_undef(strut)? $cubetruss_strut_size : strut;
clipthick = is_undef(clipthick)? $cubetruss_clip_thickness : clipthick;
cliplen = strut * 2.6;
clipheight = min(size+strut, size/3+2*strut*2.6);
clipsize = 0.5;
s = [extents*(size-strut)+strut+2*clipthick, strut*2, clipheight-2*strut];
attachable(anchor,spin,orient, size=s) {
xflip_copy(offset=(extents*(size-strut)+strut)/2) {
difference() {
union() {
difference() {
right(clipthick/2-0.01) {
back(strut) {
difference() {
xrot(90) prismoid([clipthick, clipheight], [clipthick, clipheight-cliplen*2], h=cliplen);
right(clipthick/2) chamfer_edge_mask(l=clipheight+0.1, chamfer=clipthick);
}
}
}
fwd(strut*3/2) {
cube([get_slop(), strut*3, size], center=true);
}
}
right(get_slop()/2+0.01) {
fwd(strut*1.25+get_slop()) {
yrot(-90) prismoid([clipheight-cliplen*2, strut/2], [clipheight-cliplen*2-2*clipsize, strut/2], h=clipsize+0.01);
}
} }
} }
fwd(strut*1.6) {
left(clipsize) {
yscale(1.5) chamfer_edge_mask(l=size+1, chamfer=clipsize+clipthick/3);
}
}
zcopies(clipheight-strut) cube([clipthick*3, cliplen*2, strut], center=true);
zcopies(clipheight-2*strut) right(clipthick) chamfer_edge_mask(l=cliplen*2, chamfer=clipthick, orient=BACK);
} }
} }
children(); children();
@ -563,5 +575,26 @@ module cubetruss_corner(h=1, extents=[1,1,0,0,1], bracing, size, strut, clipthic
} }
// Function: cubetruss_dist()
// Synopsis: Returns the length of a cubetruss truss.
// Topics: Trusses, CubeTruss, FDM Optimized, Parts
// See Also: cubetruss_segment(), cubetruss_support(), cubetruss(), cubetruss_corner()
// Usage:
// length = cubetruss_dist(cubes, [gaps], [size=], [strut=]);
// Description:
// Function to calculate the length of a cubetruss truss.
// Arguments:
// cubes = The number of cubes along the truss's length.
// gaps = The number of extra strut widths to add in, corresponding to each time a truss butts up against another.
// size = The length of each side of the cubetruss cubes. Default: `$cubetruss_size` (usually 30)
// strut = The width of the struts on the cubetruss cubes. Default: `$cubetruss_strut_size` (usually 3)
// Topics: Trusses
function cubetruss_dist(cubes=0, gaps=0, size, strut) =
let(
size = is_undef(size)? $cubetruss_size : size,
strut = is_undef(strut)? $cubetruss_strut_size : strut
) cubes*(size-strut)+gaps*strut;
// vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap // vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap

View file

@ -26,14 +26,15 @@
// Section: Gears // Section: Gears
// Function&Module: spur_gear() // Function&Module: spur_gear()
// Synopsis: Creates a spur gear shape.
// Topics: Gears, Parts
// See Also: rack(), spur_gear(), spur_gear2d(), bevel_gear()
// Usage: As a Module // Usage: As a Module
// spur_gear(pitch, teeth, thickness, [shaft_diam], [hide=], [pressure_angle=], [clearance=], [backlash=], [helical=], [slices=], [interior=]) [ATTACHMENTS]; // spur_gear(pitch, teeth, thickness, [shaft_diam], [hide=], [pressure_angle=], [clearance=], [backlash=], [helical=], [slices=], [interior=]) [ATTACHMENTS];
// spur_gear(mod=, teeth=, thickness=, [shaft_diam=], ...) [ATTACHMENTS]; // spur_gear(mod=, teeth=, thickness=, [shaft_diam=], ...) [ATTACHMENTS];
// Usage: As a Function // Usage: As a Function
// vnf = spur_gear(pitch, teeth, thickness, [shaft_diam], ...); // vnf = spur_gear(pitch, teeth, thickness, [shaft_diam=], ...);
// vnf = spur_gear(mod=, teeth=, thickness=, [shaft_diam], ...); // vnf = spur_gear(mod=, teeth=, thickness=, [shaft_diam=], ...);
// Topics: Gears
// See Also: rack()
// Description: // Description:
// Creates a (potentially helical) involute spur gear. The module `spur_gear()` gives an involute // Creates a (potentially helical) involute spur gear. The module `spur_gear()` gives an involute
// spur gear, with reasonable defaults for all the parameters. Normally, you should just choose the // spur gear, with reasonable defaults for all the parameters. Normally, you should just choose the
@ -191,14 +192,15 @@ module spur_gear(
// Function&Module: spur_gear2d() // Function&Module: spur_gear2d()
// Synopsis: Creates a 2D spur gear shape.
// Topics: Gears, Parts
// See Also: rack(), spur_gear(), spur_gear2d(), bevel_gear()
// Usage: As Module // Usage: As Module
// spur_gear2d(pitch, teeth, [hide=], [pressure_angle=], [clearance=], [backlash=], [interior=]) [ATTACHMENTS]; // spur_gear2d(pitch, teeth, [hide=], [pressure_angle=], [clearance=], [backlash=], [interior=]) [ATTACHMENTS];
// spur_gear2d(mod=, teeth=, [hide=], [pressure_angle=], [clearance=], [backlash=], [interior=]) [ATTACHMENTS]; // spur_gear2d(mod=, teeth=, [hide=], [pressure_angle=], [clearance=], [backlash=], [interior=]) [ATTACHMENTS];
// Usage: As Function // Usage: As Function
// poly = spur_gear2d(pitch, teeth, [hide=], [pressure_angle=], [clearance=], [backlash=], [interior=]); // poly = spur_gear2d(pitch, teeth, [hide=], [pressure_angle=], [clearance=], [backlash=], [interior=]);
// poly = spur_gear2d(mod=, teeth=, [hide=], [pressure_angle=], [clearance=], [backlash=], [interior=]); // poly = spur_gear2d(mod=, teeth=, [hide=], [pressure_angle=], [clearance=], [backlash=], [interior=]);
// Topics: Gears
// See Also: spur_gear()
// Description: // Description:
// When called as a module, creates a 2D involute spur gear. When called as a function, returns a // When called as a module, creates a 2D involute spur gear. When called as a function, returns a
// 2D path for the perimeter of a 2D involute spur gear. Normally, you should just specify the // 2D path for the perimeter of a 2D involute spur gear. Normally, you should just specify the
@ -291,14 +293,15 @@ module spur_gear2d(
// Function&Module: rack() // Function&Module: rack()
// Synopsis: Creates a gear rack shape.
// Topics: Gears, Parts
// See Also: rack2d(), spur_gear(), spur_gear2d(), bevel_gear()
// Usage: As a Module // Usage: As a Module
// rack(pitch, teeth, thickness, height, [pressure_angle=], [backlash=]) [ATTACHMENTS]; // rack(pitch, teeth, thickness, height, [pressure_angle=], [backlash=], [clearance=], [helical=]) [ATTACHMENTS];
// rack(mod=, teeth=, thickness=, height=, [pressure_angle=], [backlash]=) [ATTACHMENTS]; // rack(mod=, teeth=, thickness=, height=, [pressure_angle=], [backlash]=, [clearance=], [helical=]) [ATTACHMENTS];
// Usage: As a Function // Usage: As a Function
// vnf = rack(pitch, teeth, thickness, height, [pressure_angle=], [backlash=]); // vnf = rack(pitch, teeth, thickness, height, [pressure_angle=], [backlash=], [clearance=], [helical=]);
// vnf = rack(mod=, teeth=, thickness=, height=, [pressure_angle=], [backlash=]); // vnf = rack(mod=, teeth=, thickness=, height=, [pressure_angle=], [backlash=], [clearance=], [helical=]);
// Topics: Gears
// See Also: spur_gear()
// Description: // Description:
// This is used to create a 3D rack, which is a linear bar with teeth that a gear can roll along. // This is used to create a 3D rack, which is a linear bar with teeth that a gear can roll along.
// A rack can mesh with any gear that has the same `pitch` and `pressure_angle`. // A rack can mesh with any gear that has the same `pitch` and `pressure_angle`.
@ -439,14 +442,15 @@ function rack(
// Function&Module: rack2d() // Function&Module: rack2d()
// Synopsis: Creates a 2D gear rack shape.
// Topics: Gears, Parts
// See Also: rack(), spur_gear(), spur_gear2d(), bevel_gear()
// Usage: As a Module // Usage: As a Module
// path = rack2d(pitch, teeth, height, [pressure_angle=], [backlash=]) [ATTACHMENTS]; // rack2d(pitch, teeth, height, [pressure_angle=], [backlash=], [clearance=]) [ATTACHMENTS];
// path = rack2d(mod=, teeth=, height=, [pressure_angle=], [backlash=]) [ATTACHMENTS]; // rack2d(mod=, teeth=, height=, [pressure_angle=], [backlash=], [clearance=]) [ATTACHMENTS];
// Usage: As a Function // Usage: As a Function
// path = rack2d(pitch, teeth, height, [pressure_angle=], [backlash=]); // path = rack2d(pitch, teeth, height, [pressure_angle=], [backlash=], [clearance=]);
// path = rack2d(mod=, teeth=, height=, [pressure_angle=], [backlash=]); // path = rack2d(mod=, teeth=, height=, [pressure_angle=], [backlash=], [clearance=]);
// Topics: Gears
// See Also: spur_gear2d()
// Description: // Description:
// This is used to create a 2D rack, which is a linear bar with teeth that a gear can roll along. // This is used to create a 2D rack, which is a linear bar with teeth that a gear can roll along.
// A rack can mesh with any gear that has the same `pitch` and `pressure_angle`. // A rack can mesh with any gear that has the same `pitch` and `pressure_angle`.
@ -561,12 +565,15 @@ module rack2d(
// Function&Module: bevel_gear() // Function&Module: bevel_gear()
// Synopsis: Creates a possibly spiral beveled gear shape.
// Topics: Gears, Parts
// See Also: rack(), rack2d(), spur_gear(), spur_gear2d(), bevel_pitch_angle(), bevel_gear()
// Usage: As a Module // Usage: As a Module
// bevel_gear(pitch|mod, teeth, face_width, pitch_angle, [shaft_diam], [hide], [pressure_angle], [clearance], [backlash], [cutter_radius], [spiral_angle], [slices], [interior]); // bevel_gear(pitch, teeth, face_width, [pitch_angle=]|[mate_teeth=], [shaft_diam=], [hide=], [pressure_angle=], [clearance=], [backlash=], [cutter_radius=], [spiral_angle=], [left_handed=], [slices=], [interior=]);
// bevel_gear(mod=, teeth=, face_width=, [pitch_angle=]|[mate_teeth=], [shaft_diam=], [hide=], [pressure_angle=], [clearance=], [backlash=], [cutter_radius=], [spiral_angle=], [left_handed=], [slices=], [interior=]);
// Usage: As a Function // Usage: As a Function
// vnf = bevel_gear(pitch|mod, teeth, face_width, pitch_angle, [hide], [pressure_angle], [clearance], [backlash], [cutter_radius], [spiral_angle], [slices], [interior]); // vnf = bevel_gear(pitch, teeth, face_width, [pitch_angle=]|[mate_teeth=], [hide=], [pressure_angle=], [clearance=], [backlash=], [cutter_radius=], [spiral_angle=], [left_handed=], [slices=], [interior=]);
// Topics: Gears // vnf = bevel_gear(mod=, teeth=, face_width=, [pitch_angle=]|[mate_teeth=], [hide=], [pressure_angle=], [clearance=], [backlash=], [cutter_radius=], [spiral_angle=], [left_handed=], [slices=], [interior=]);
// See Also: bevel_pitch_angle()
// Description: // Description:
// Creates a (potentially spiral) bevel gear. The module `bevel_gear()` gives a bevel gear, with // Creates a (potentially spiral) bevel gear. The module `bevel_gear()` gives a bevel gear, with
// reasonable defaults for all the parameters. Normally, you should just choose the first 4 // reasonable defaults for all the parameters. Normally, you should just choose the first 4
@ -594,6 +601,7 @@ module rack2d(
// face_width = Width of the toothed surface in mm, from inside to outside. Default: 10 // face_width = Width of the toothed surface in mm, from inside to outside. Default: 10
// pitch_angle = Angle of beveled gear face. Default: 45 // pitch_angle = Angle of beveled gear face. Default: 45
// mate_teeth = The number of teeth in the gear that this gear will mate with. Overrides `pitch_angle` if given. // mate_teeth = The number of teeth in the gear that this gear will mate with. Overrides `pitch_angle` if given.
// ---
// shaft_diam = Diameter of the hole in the center, in mm. Module use only. Default: 0 (no shaft hole) // shaft_diam = Diameter of the hole in the center, in mm. Module use only. Default: 0 (no shaft hole)
// hide = Number of teeth to delete to make this only a fraction of a circle. Default: 0 // hide = Number of teeth to delete to make this only a fraction of a circle. Default: 0
// pressure_angle = Controls how straight or bulged the tooth sides are. In degrees. Default: 28 // pressure_angle = Controls how straight or bulged the tooth sides are. In degrees. Default: 28
@ -817,12 +825,15 @@ module bevel_gear(
// Function&Module: worm() // Function&Module: worm()
// Synopsis: Creates a worm shape that will mate with a worm gear.
// Topics: Gears, Parts
// See Also: worm(), worm_gear(), rack(), rack2d(), spur_gear(), spur_gear2d(), bevel_pitch_angle(), bevel_gear()
// Usage: As a Module // Usage: As a Module
// worm(pitch|mod, d, l, [starts], [left_handed], [pressure_angle], [backlash], [clearance]); // worm(pitch, d, l, [starts=], [left_handed=], [pressure_angle=], [backlash=], [clearance=]);
// worm(mod=, d=, l=, [starts=], [left_handed=], [pressure_angle=], [backlash=], [clearance=]);
// Usage: As a Function // Usage: As a Function
// vnf = worm(pitch|mod, d, l, [starts], [left_handed], [pressure_angle], [backlash], [clearance]); // vnf = worm(pitch, d, l, [starts=], [left_handed=], [pressure_angle=], [backlash=], [clearance=]);
// Topics: Gears // vnf = worm(mod=, d=, l=, [starts=], [left_handed=], [pressure_angle=], [backlash=], [clearance=]);
// See Also: worm_gear()
// Description: // Description:
// Creates a worm shape that can be matched to a worm gear. // Creates a worm shape that can be matched to a worm gear.
// Arguments: // Arguments:
@ -934,12 +945,15 @@ module worm(
// Function&Module: worm_gear() // Function&Module: worm_gear()
// Synopsis: Creates a worm gear shape that will mate with a worm.
// Topics: Gears, Parts
// See Also: worm(), worm_gear(), rack(), rack2d(), spur_gear(), spur_gear2d(), bevel_pitch_angle(), bevel_gear()
// Usage: As a Module // Usage: As a Module
// worm_gear(pitch|mod, teeth, worm_diam, [worm_starts], [crowning], [left_handed], [pressure_angle], [backlash], [slices], [clearance], [shaft_diam]); // worm_gear(pitch, teeth, worm_diam, [worm_starts=], [worm_arc=], [crowning=], [left_handed=], [pressure_angle=], [backlash=], [clearance=], [slices=], [shaft_diam=]) [ATTACHMENTS];
// worm_gear(mod=, teeth=, worm_diam=, [worm_starts=], [worm_arc=], [crowning=], [left_handed=], [pressure_angle=], [backlash=], [clearance=], [slices=], [shaft_diam=]) [ATTACHMENTS];
// Usage: As a Function // Usage: As a Function
// vnf = worm_gear(pitch|mod, teeth, worm_diam, [worm_starts], [crowning], [left_handed], [pressure_angle], [backlash], [slices], [clearance]); // vnf = worm_gear(pitch, teeth, worm_diam, [worm_starts=], [worm_arc=], [crowning=], [left_handed=], [pressure_angle=], [backlash=], [clearance=], [slices=]);
// Topics: Gears // vnf = worm_gear(mod=, teeth=, worm_diam=, [worm_starts=], [worm_arc=], [crowning=], [left_handed=], [pressure_angle=], [backlash=], [clearance=], [slices=]);
// See Also: worm()
// Description: // Description:
// Creates a worm gear to match with a worm. // Creates a worm gear to match with a worm.
// Arguments: // Arguments:
@ -1000,8 +1014,8 @@ function worm_gear(
pressure_angle = 20, pressure_angle = 20,
backlash = 0, backlash = 0,
clearance, clearance,
mod,
slices = 10, slices = 10,
mod,
anchor = CENTER, anchor = CENTER,
spin = 0, spin = 0,
orient = UP orient = UP
@ -1227,9 +1241,12 @@ module _gear_tooth_profile(
// Function: circular_pitch() // Function: circular_pitch()
// Synopsis: Returns tooth density expressed as "circular pitch".
// Topics: Gears, Parts
// See Also: spur_gear(), diametral_pitch(), circular_pitch(), pitch_value()
// Usage: // Usage:
// circp = circular_pitch(pitch|mod); // circp = circular_pitch(pitch);
// Topics: Gears // circp = circular_pitch(mod=);
// Description: // Description:
// Get tooth density expressed as "circular pitch". // Get tooth density expressed as "circular pitch".
// Arguments: // Arguments:
@ -1244,9 +1261,12 @@ function circular_pitch(pitch=5, mod) =
// Function: diametral_pitch() // Function: diametral_pitch()
// Synopsis: Returns tooth density expressed as "diametral pitch".
// Topics: Gears, Parts
// See Also: spur_gear(), diametral_pitch(), circular_pitch(), pitch_value()
// Usage: // Usage:
// dp = diametral_pitch(pitch|mod); // dp = diametral_pitch(pitch);
// Topics: Gears // dp = diametral_pitch(mod=);
// Description: // Description:
// Get tooth density expressed as "diametral pitch". // Get tooth density expressed as "diametral pitch".
// Arguments: // Arguments:
@ -1261,9 +1281,11 @@ function diametral_pitch(pitch=5, mod) =
// Function: pitch_value() // Function: pitch_value()
// Synopsis: Returns circular pitch in mm from module/modulus.
// Topics: Gears, Parts
// See Also: spur_gear(), diametral_pitch(), circular_pitch(), pitch_value(), module_value()
// Usage: // Usage:
// pitch = pitch_value(mod); // pitch = pitch_value(mod);
// Topics: Gears
// Description: // Description:
// Get circular pitch in mm from module/modulus. The circular pitch of a gear is the number of // Get circular pitch in mm from module/modulus. The circular pitch of a gear is the number of
// millimeters per tooth around the pitch radius circle. // millimeters per tooth around the pitch radius circle.
@ -1273,9 +1295,11 @@ function pitch_value(mod) = mod * PI;
// Function: module_value() // Function: module_value()
// Synopsis: Returns tooth density expressed as "module" or "modulus" in millimeters.
// Topics: Gears, Parts
// See Also: spur_gear(), diametral_pitch(), circular_pitch(), pitch_value(), module_value()
// Usage: // Usage:
// mod = module_value(pitch); // mod = module_value(pitch);
// Topics: Gears
// Description: // Description:
// Get tooth density expressed as "module" or "modulus" in millimeters. The module is the pitch // Get tooth density expressed as "module" or "modulus" in millimeters. The module is the pitch
// diameter of the gear divided by the number of teeth on it. For example, a gear with a pitch // diameter of the gear divided by the number of teeth on it. For example, a gear with a pitch
@ -1340,9 +1364,12 @@ function _dedendum(pitch=5, clearance, mod) =
// Function: pitch_radius() // Function: pitch_radius()
// Synopsis: Returns the pitch radius for a gear.
// Topics: Gears, Parts
// See Also: spur_gear(), diametral_pitch(), circular_pitch(), pitch_value(), module_value(), outer_radius()
// Usage: // Usage:
// pr = pitch_radius(pitch|mod, teeth); // pr = pitch_radius(pitch, teeth);
// Topics: Gears // pr = pitch_radius(mod=, teeth=);
// Description: // Description:
// Calculates the pitch radius for the gear. Two mated gears will have their centers spaced apart // Calculates the pitch radius for the gear. Two mated gears will have their centers spaced apart
// by the sum of the two gear's pitch radii. // by the sum of the two gear's pitch radii.
@ -1364,9 +1391,12 @@ function pitch_radius(pitch=5, teeth=11, mod) =
// Function: outer_radius() // Function: outer_radius()
// Synopsis: Returns the outer radius for a gear.
// Topics: Gears, Parts
// See Also: spur_gear(), diametral_pitch(), circular_pitch(), pitch_value(), module_value(), pitch_radius(), outer_radius()
// Usage: // Usage:
// or = outer_radius(pitch|mod, teeth, [clearance], [interior]); // or = outer_radius(pitch, teeth, [clearance=], [interior=]);
// Topics: Gears // or = outer_radius(mod=, teeth=, [clearance=], [interior=]);
// Description: // Description:
// Calculates the outer radius for the gear. The gear fits entirely within a cylinder of this radius. // Calculates the outer radius for the gear. The gear fits entirely within a cylinder of this radius.
// Arguments: // Arguments:
@ -1440,12 +1470,13 @@ function _base_radius(pitch=5, teeth=11, pressure_angle=28, mod) =
// Function: bevel_pitch_angle() // Function: bevel_pitch_angle()
// Synopsis: Returns the pitch cone angle for a bevel gear.
// Topics: Gears, Parts
// See Also: bevel_gear(), pitch_radius(), outer_radius()
// Usage: // Usage:
// ang = bevel_pitch_angle(teeth, mate_teeth, [drive_angle]); // ang = bevel_pitch_angle(teeth, mate_teeth, [drive_angle=]);
// Topics: Gears
// See Also: bevel_gear()
// Description: // Description:
// Returns the correct pitch angle for a bevel gear with a given number of tooth, that is // Returns the correct pitch cone angle for a bevel gear with a given number of teeth, that is
// matched to another bevel gear with a (possibly different) number of teeth. // matched to another bevel gear with a (possibly different) number of teeth.
// Arguments: // Arguments:
// teeth = Number of teeth that this gear has. // teeth = Number of teeth that this gear has.
@ -1471,10 +1502,12 @@ function bevel_pitch_angle(teeth, mate_teeth, drive_angle=90) =
// Function: worm_gear_thickness() // Function: worm_gear_thickness()
// Synopsis: Returns the thickness for a worm gear.
// Topics: Gears, Parts
// See Also: worm(), worm_gear(), pitch_radius(), outer_radius()
// Usage: // Usage:
// thick = worm_gear_thickness(pitch|mod, teeth, worm_diam, [worm_arc], [crowning], [clearance]); // thick = worm_gear_thickness(pitch, teeth, worm_diam, [worm_arc=], [crowning=], [clearance=]);
// Topics: Gears // thick = worm_gear_thickness(mod=, teeth=, worm_diam=, [worm_arc=], [crowning=], [clearance=]);
// See Also: worm(), worm_gear()
// Description: // Description:
// Calculate the thickness of the worm gear. // Calculate the thickness of the worm gear.
// Arguments: // Arguments:
@ -1482,7 +1515,7 @@ function bevel_pitch_angle(teeth, mate_teeth, drive_angle=90) =
// teeth = Total number of teeth along the rack. Default: 30 // teeth = Total number of teeth along the rack. Default: 30
// worm_diam = The pitch diameter of the worm gear to match to. Default: 30 // worm_diam = The pitch diameter of the worm gear to match to. Default: 30
// worm_arc = The arc of the worm to mate with, in degrees. Default: 60 degrees // worm_arc = The arc of the worm to mate with, in degrees. Default: 60 degrees
// crowning = The amount to oversize the virtual hobbing cutter used to make the teeth, to add a slight crowning to the teeth to make them fir the work easier. Default: 1 // crowning = The amount to oversize the virtual hobbing cutter used to make the teeth, to add a slight crowning to the teeth to make them fit the work easier. Default: 1
// clearance = Clearance gap at the bottom of the inter-tooth valleys. // clearance = Clearance gap at the bottom of the inter-tooth valleys.
// mod = The metric module/modulus of the gear. // mod = The metric module/modulus of the gear.
// Example: // Example:
@ -1521,5 +1554,4 @@ function _gear_q7(f,r,b,r2,t,s) = _gear_q6(b,s,t,(1-f)*max(b,r)+f*r2); //
// vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap // vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap

View file

@ -14,23 +14,32 @@ include <screws.scad>
// Section: Hinges // Section: Hinges
// Module: knuckle_hinge() // Module: knuckle_hinge()
// Synopsis: Creates a knuckle-hinge shape.
// Topics: Hinges, Parts
// See Also: living_hinge_mask(), snap_lock(), snap_socket()
// Usage: // Usage:
// knuckle_hinge(length, offset, segs, [inner], [arm_height=], [arm_angle=], [fill=], [clear_top=], [gap=], [round_top=], [round_bot=], [knuckle_diam=], [pin_diam=], [pin_fn=], [anchor=], [spin=], [orient=]) [ATTACHMENTS]; // knuckle_hinge(length, offset, segs, [inner], [arm_height=], [arm_angle=], [fill=], [clear_top=], [gap=], [round_top=], [round_bot=], [knuckle_diam=], [pin_diam=], [pin_fn=], [anchor=], [spin=], [orient=]) [ATTACHMENTS];
// Description: // Description:
// Construct standard knuckle hinge in two parts using a hinge pin that must be separately supplied. The default is configured to use a piece of 1.75 mm filament as the hinge pin, // Construct standard knuckle hinge in two parts using a hinge pin that must be separately supplied.
// but you can select any dimensions you like to use a screw or other available pin material. The BOTTOM of the hinge is its mount point, which is aligned with // The default is configured to use a piece of 1.75 mm filament as the hinge pin, but you can select
// the hinge pin centersurface, and the hinge pin hole is the CENTER of the hinge. // any dimensions you like to use a screw or other available pin material. The BOTTOM of the hinge
// The offset is the distance from a vertical mounting point to the center of the hinge pin. The hinge barrel is held by an angled support and // is its mount point, which is aligned with the hinge pin centersurface, and the hinge pin hole is
// vertical support. The length of the angled support is determined by its angle and the offset. You specify the length of the vertical support with the // the CENTER of the hinge. The offset is the distance from a vertical mounting point to the center
// arm_height parameter. // of the hinge pin. The hinge barrel is held by an angled support and vertical support. The
// // length of the angled support is determined by its angle and the offset. You specify the length
// of the vertical support with the arm_height parameter.
// . // .
// A hinge requires clearance so its parts don't interfere. If the hinge pin is exactly centered on the top of your part, then the hinge may not close all the way // A hinge requires clearance so its parts don't interfere. If the hinge pin is exactly centered on
// due to interference at the edge. A small clearance, specified with `clearance=`, raises the hinge up and can ease this interference. It should probably be equal to a layer thickness or two. // the top of your part, then the hinge may not close all the way due to interference at the edge.
// If the hinge knuckle is close to the hinged part then the mating part may interfere. You can create clearance to address this problem by increasing the offset // A small clearance, specified with `clearance=`, raises the hinge up and can ease this
// to move the hinge knuckles farther away. Another method is to cut out a curved recess on the parts to allow space for the other hinges. This is possible // interference. It should probably be equal to a layer thickness or two. If the hinge knuckle is
// using the `knuckle_clearance=` parameter, which specifies the extra space to cut away to leave room for the hinge knuckles. It must be positive for any space // close to the hinged part then the mating part may interfere. You can create clearance to address
// to be cut, and to use this option you must make the hinge a child of some object and specify {{diff()}} for the parent object of the hinge. // this problem by increasing the offset to move the hinge knuckles farther away. Another method is
// to cut out a curved recess on the parts to allow space for the other hinges. This is possible
// using the `knuckle_clearance=` parameter, which specifies the extra space to cut away to leave
// room for the hinge knuckles. It must be positive for any space to be cut, and to use this option
// you must make the hinge a child of some object and specify {{diff()}} for the parent object of
// the hinge.
// Figure(2D,Med,NoScales): The basic hinge form appears on the left. If fill is set to true the gap between the mount surface and hinge arm is filled as shown on the right. // Figure(2D,Med,NoScales): The basic hinge form appears on the left. If fill is set to true the gap between the mount surface and hinge arm is filled as shown on the right.
// _knuckle_hinge_profile(4, 5, $fn=32, fill=false); // _knuckle_hinge_profile(4, 5, $fn=32, fill=false);
// right(13)_knuckle_hinge_profile(4, 5, $fn=32, fill=true); // right(13)_knuckle_hinge_profile(4, 5, $fn=32, fill=true);
@ -336,6 +345,9 @@ module _knuckle_hinge_profile(offset, arm_height, arm_angle=45, knuckle_diam=4,
// Module: living_hinge_mask() // Module: living_hinge_mask()
// Synopsis: Creates a mask to make a folding "living" hinge.
// Topics: Hinges, Parts
// See Also: knuckle_hinge(), living_hinge_mask(), snap_lock(), snap_socket(), apply_folding_hinges_and_snaps()
// Usage: // Usage:
// living_hinge_mask(l, thick, [layerheight=], [foldangle=], [hingegap=], [$slop=], [anchor=], [spin=], [orient=]) [ATTACHMENTS]; // living_hinge_mask(l, thick, [layerheight=], [foldangle=], [hingegap=], [$slop=], [anchor=], [spin=], [orient=]) [ATTACHMENTS];
// Description: // Description:
@ -378,6 +390,9 @@ module folding_hinge_mask(l, thick, layerheight=0.2, foldangle=90, hingegap=unde
// Module: apply_folding_hinges_and_snaps() // Module: apply_folding_hinges_and_snaps()
// Synopsis: Adds snap shapes and removes living hinges from a child shape.
// Topics: Hinges, Parts
// See Also: knuckle_hinge(), living_hinge_mask(), snap_lock(), snap_socket()
// Usage: // Usage:
// apply_folding_hinges_and_snaps(thick, [foldangle=], [hinges=], [snaps=], [sockets=], [snaplen=], [snapdiam=], [hingegap=], [layerheight=], [$slop=]) CHILDREN; // apply_folding_hinges_and_snaps(thick, [foldangle=], [hinges=], [snaps=], [sockets=], [snaplen=], [snapdiam=], [hingegap=], [layerheight=], [$slop=]) CHILDREN;
// Description: // Description:
@ -460,6 +475,9 @@ module apply_folding_hinges_and_snaps(thick, foldangle=90, hinges=[], snaps=[],
// Module: snap_lock() // Module: snap_lock()
// Synopsis: Creates a snap-lock shape.
// Topics: Hinges, Parts
// See Also: knuckle_hinge(), living_hinge_mask(), snap_lock(), snap_socket()
// Usage: // Usage:
// snap_lock(thick, [snaplen=], [snapdiam=], [layerheight=], [foldangle=], [hingegap=], [$slop=], [anchor=], [spin=], [orient=]) [ATTACHMENTS]; // snap_lock(thick, [snaplen=], [snapdiam=], [layerheight=], [foldangle=], [hingegap=], [$slop=], [anchor=], [spin=], [orient=]) [ATTACHMENTS];
// Description: // Description:
@ -496,6 +514,9 @@ module snap_lock(thick, snaplen=5, snapdiam=5, layerheight=0.2, foldangle=90, hi
// Module: snap_socket() // Module: snap_socket()
// Synopsis: Creates a snap-lock socket shape.
// Topics: Hinges, Parts
// See Also: knuckle_hinge(), living_hinge_mask(), snap_lock(), snap_socket()
// Usage: // Usage:
// snap_socket(thick, [snaplen=], [snapdiam=], [layerheight=], [foldangle=], [hingegap=], [$slop=], [anchor=], [spin=], [orient=]) [ATTACHMENTS]; // snap_socket(thick, [snaplen=], [snapdiam=], [layerheight=], [foldangle=], [hingegap=], [$slop=], [anchor=], [spin=], [orient=]) [ATTACHMENTS];
// Description: // Description:
@ -533,3 +554,6 @@ module snap_socket(thick, snaplen=5, snapdiam=5, layerheight=0.2, foldangle=90,
} }
} }
// vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap

View file

@ -16,11 +16,13 @@ include <rounding.scad>
// Function&Module: half_joiner_clear() // Function&Module: half_joiner_clear()
// Synopsis: Creates a mask to clear space for a {{half_joiner()}}.
// Topics: Joiners, Parts
// See Also: half_joiner_clear(), half_joiner(), half_joiner2(), joiner_clear(), joiner(), snap_pin(), rabbit_clip(), dovetail()
// Usage: As Module // Usage: As Module
// half_joiner_clear(l, w, [ang=], [clearance=], [overlap=]) [ATTACHMENTS]; // half_joiner_clear(l, w, [ang=], [clearance=], [overlap=]) [ATTACHMENTS];
// Usage: As Function // Usage: As Function
// vnf = half_joiner_clear(l, w, [ang=], [clearance=], [overlap=]); // vnf = half_joiner_clear(l, w, [ang=], [clearance=], [overlap=]);
// Topics: Joiners, Parts
// Description: // Description:
// Creates a mask to clear an area so that a half_joiner can be placed there. // Creates a mask to clear an area so that a half_joiner can be placed there.
// Arguments: // Arguments:
@ -33,7 +35,6 @@ include <rounding.scad>
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER` // anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0` // spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP` // orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
// See Also: half_joiner_clear(), half_joiner(), half_joiner2(), joiner_clear(), joiner()
// Example: // Example:
// half_joiner_clear(); // half_joiner_clear();
function half_joiner_clear(l=20, w=10, ang=30, clearance=0, overlap=0.01, anchor=CENTER, spin=0, orient=UP) = function half_joiner_clear(l=20, w=10, ang=30, clearance=0, overlap=0.01, anchor=CENTER, spin=0, orient=UP) =
@ -60,11 +61,13 @@ module half_joiner_clear(l=20, w=10, ang=30, clearance=0, overlap=0.01, anchor=C
// Function&Module: half_joiner() // Function&Module: half_joiner()
// Synopsis: Creates a half-joiner shape to mate with a {{half_joiner2()}} shape..
// Topics: Joiners, Parts
// See Also: half_joiner_clear(), half_joiner(), half_joiner2(), joiner_clear(), joiner(), snap_pin(), rabbit_clip(), dovetail()
// Usage: As Module // Usage: As Module
// half_joiner(l, w, [base=], [ang=], [screwsize=], [$slop=]) [ATTACHMENTS]; // half_joiner(l, w, [base=], [ang=], [screwsize=], [$slop=]) [ATTACHMENTS];
// Usage: As Function // Usage: As Function
// vnf = half_joiner(l, w, [base=], [ang=], [screwsize=], [$slop=]); // vnf = half_joiner(l, w, [base=], [ang=], [screwsize=], [$slop=]);
// Topics: Joiners, Parts
// Description: // Description:
// Creates a half_joiner object that can be attached to a matching half_joiner2 object. // Creates a half_joiner object that can be attached to a matching half_joiner2 object.
// Arguments: // Arguments:
@ -78,7 +81,6 @@ module half_joiner_clear(l=20, w=10, ang=30, clearance=0, overlap=0.01, anchor=C
// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0` // spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP` // orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
// $slop = Printer specific slop value to make parts fit more closely. // $slop = Printer specific slop value to make parts fit more closely.
// See Also: half_joiner_clear(), half_joiner(), half_joiner2(), joiner_clear(), joiner()
// Examples(FlatSpin,VPD=75): // Examples(FlatSpin,VPD=75):
// half_joiner(screwsize=3); // half_joiner(screwsize=3);
// half_joiner(l=20,w=10,base=10); // half_joiner(l=20,w=10,base=10);
@ -241,11 +243,13 @@ module half_joiner(l=20, w=10, base=10, ang=30, screwsize, anchor=CENTER, spin=0
// Function&Module: half_joiner2() // Function&Module: half_joiner2()
// Synopsis: Creates a half_joiner2 shape to mate with a {{half_joiner()}} shape..
// Topics: Joiners, Parts
// See Also: half_joiner_clear(), half_joiner(), half_joiner2(), joiner_clear(), joiner(), snap_pin(), rabbit_clip(), dovetail()
// Usage: As Module // Usage: As Module
// half_joiner2(l, w, [base=], [ang=], [screwsize=]) // half_joiner2(l, w, [base=], [ang=], [screwsize=])
// Usage: As Function // Usage: As Function
// vnf = half_joiner2(l, w, [base=], [ang=], [screwsize=]) // vnf = half_joiner2(l, w, [base=], [ang=], [screwsize=])
// Topics: Joiners, Parts
// Description: // Description:
// Creates a half_joiner2 object that can be attached to half_joiner object. // Creates a half_joiner2 object that can be attached to half_joiner object.
// Arguments: // Arguments:
@ -258,7 +262,6 @@ module half_joiner(l=20, w=10, base=10, ang=30, screwsize, anchor=CENTER, spin=0
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER` // anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0` // spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP` // orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
// See Also: half_joiner_clear(), half_joiner(), half_joiner2(), joiner_clear(), joiner()
// Examples(FlatSpin,VPD=75): // Examples(FlatSpin,VPD=75):
// half_joiner2(screwsize=3); // half_joiner2(screwsize=3);
// half_joiner2(w=10,base=10,l=20); // half_joiner2(w=10,base=10,l=20);
@ -444,11 +447,13 @@ module half_joiner2(l=20, w=10, base=10, ang=30, screwsize, anchor=CENTER, spin=
// Module: joiner_clear() // Module: joiner_clear()
// Synopsis: Creates a mask to clear space for a {{joiner()}} shape.
// Topics: Joiners, Parts
// See Also: half_joiner_clear(), half_joiner(), half_joiner2(), joiner_clear(), joiner(), snap_pin(), rabbit_clip(), dovetail()
// Description: // Description:
// Creates a mask to clear an area so that a joiner can be placed there. // Creates a mask to clear an area so that a joiner can be placed there.
// Usage: // Usage:
// joiner_clear(l, w, [ang=], [clearance=], [overlap=]) [ATTACHMENTS]; // joiner_clear(l, w, [ang=], [clearance=], [overlap=]) [ATTACHMENTS];
// Topics: Joiners, Parts
// Arguments: // Arguments:
// l = Length of the joiner to clear space for. // l = Length of the joiner to clear space for.
// w = Width of the joiner to clear space for. // w = Width of the joiner to clear space for.
@ -459,7 +464,6 @@ module half_joiner2(l=20, w=10, base=10, ang=30, screwsize, anchor=CENTER, spin=
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER` // anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0` // spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP` // orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
// See Also: half_joiner_clear(), half_joiner(), half_joiner2(), joiner_clear(), joiner()
// Example: // Example:
// joiner_clear(); // joiner_clear();
function joiner_clear(l=40, w=10, ang=30, clearance=0, overlap=0.01, anchor=CENTER, spin=0, orient=UP) = no_function("joiner_clear"); function joiner_clear(l=40, w=10, ang=30, clearance=0, overlap=0.01, anchor=CENTER, spin=0, orient=UP) = no_function("joiner_clear");
@ -482,9 +486,11 @@ module joiner_clear(l=40, w=10, ang=30, clearance=0, overlap=0.01, anchor=CENTER
// Module: joiner() // Module: joiner()
// Synopsis: Creates a joiner shape that can mate with another rotated joiner shape.
// Topics: Joiners, Parts
// See Also: half_joiner_clear(), half_joiner(), half_joiner2(), joiner_clear(), joiner(), snap_pin(), rabbit_clip(), dovetail()
// Usage: // Usage:
// joiner(l, w, base, [ang=], [screwsize=], [$slop=]) [ATTACHMENTS]; // joiner(l, w, base, [ang=], [screwsize=], [$slop=]) [ATTACHMENTS];
// Topics: Joiners, Parts
// Description: // Description:
// Creates a joiner object that can be attached to another joiner object. // Creates a joiner object that can be attached to another joiner object.
// Arguments: // Arguments:
@ -498,7 +504,6 @@ module joiner_clear(l=40, w=10, ang=30, clearance=0, overlap=0.01, anchor=CENTER
// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0` // spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP` // orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
// $slop = Printer specific slop value to make parts fit more closely. // $slop = Printer specific slop value to make parts fit more closely.
// See Also: half_joiner_clear(), half_joiner(), half_joiner2(), joiner_clear(), joiner()
// Examples(FlatSpin,VPD=125): // Examples(FlatSpin,VPD=125):
// joiner(screwsize=3); // joiner(screwsize=3);
// joiner(l=40, w=10, base=10); // joiner(l=40, w=10, base=10);
@ -532,6 +537,9 @@ module joiner(l=40, w=10, base=10, ang=30, screwsize, anchor=CENTER, spin=0, ori
// Section: Dovetails // Section: Dovetails
// Module: dovetail() // Module: dovetail()
// Synopsis: Creates a possibly tapered dovetail shape.
// Topics: Joiners, Parts
// See Also: joiner(), snap_pin(), rabbit_clip()
// //
// Usage: // Usage:
// dovetail(gender, w=|width, h=|height, slide|thickness=, [slope=|angle=], [taper=|back_width=], [chamfer=], [r=|radius=], [round=], [extra=], [$slop=]) // dovetail(gender, w=|width, h=|height, slide|thickness=, [slope=|angle=], [taper=|back_width=], [chamfer=], [r=|radius=], [round=], [extra=], [$slop=])
@ -799,6 +807,9 @@ function _pin_size(size) =
// Module: snap_pin() // Module: snap_pin()
// Synopsis: Creates a snap-pin that can slot into a {{snap_pin_socket()}} to join two parts.
// Topics: Joiners, Parts
// See Also: snap_pin_socket(), joiner(), dovetail(), snap_pin(), rabbit_clip()
// Usage: // Usage:
// snap_pin(size, [pointed=], [anchor=], [spin=], [orient]=) [ATTACHMENTS]; // snap_pin(size, [pointed=], [anchor=], [spin=], [orient]=) [ATTACHMENTS];
// snap_pin(r=|radius=|d=|diameter=, l=|length=, nub_depth=, snap=, thickness=, [clearance=], [preload=], [pointed=]) [ATTACHMENTS]; // snap_pin(r=|radius=|d=|diameter=, l=|length=, nub_depth=, snap=, thickness=, [clearance=], [preload=], [pointed=]) [ATTACHMENTS];
@ -869,6 +880,9 @@ module snap_pin(size,r,radius,d,diameter, l,length, nub_depth, snap, thickness,
} }
// Module: snap_pin_socket() // Module: snap_pin_socket()
// Synopsis: Creates a snap-pin socket for a {{snap_pin()}} to slot into.
// Topics: Joiners, Parts
// See Also: snap_pin(), joiner(), dovetail(), snap_pin(), rabbit_clip()
// Usage: // Usage:
// snap_pin_socket(size, [fixed=], [fins=], [pointed=], [anchor=], [spin=], [orient=]) [ATTACHMENTS]; // snap_pin_socket(size, [fixed=], [fins=], [pointed=], [anchor=], [spin=], [orient=]) [ATTACHMENTS];
// snap_pin_socket(r=|radius=|d=|diameter=, l=|length=, nub_depth=, snap=, [fixed=], [pointed=], [fins=]) [ATTACHMENTS]; // snap_pin_socket(r=|radius=|d=|diameter=, l=|length=, nub_depth=, snap=, [fixed=], [pointed=], [fins=]) [ATTACHMENTS];
@ -939,6 +953,9 @@ module snap_pin_socket(size, r, radius, l,length, d,diameter,nub_depth, snap, fi
// Module: rabbit_clip() // Module: rabbit_clip()
// Synopsis: Creates a rabbit-eared clip that can snap into a slot.
// Topics: Joiners, Parts
// See Also: snap_pin(), joiner(), dovetail(), snap_pin(), rabbit_clip()
// Usage: // Usage:
// rabbit_clip(type, length, width, snap, thickness, depth, [compression=], [clearance=], [lock=], [lock_clearance=], [splineteps=], [anchor=], [orient=], [spin=]) [ATTACHMENTS]; // rabbit_clip(type, length, width, snap, thickness, depth, [compression=], [clearance=], [lock=], [lock_clearance=], [splineteps=], [anchor=], [orient=], [spin=]) [ATTACHMENTS];
// Description: // Description:

View file

@ -18,6 +18,8 @@ include <metric_screws.scad>
// Synopsis: Creates a generic linear bearing mount clamp. // Synopsis: Creates a generic linear bearing mount clamp.
// Topics: Parts, Bearings // Topics: Parts, Bearings
// See Also: linear_bearing(), lmXuu_info(), ball_bearing() // See Also: linear_bearing(), lmXuu_info(), ball_bearing()
// Usage:
// linear_bearing_housing(d, l, tab, gap, wall, tabwall, screwsize) [ATTACHMENTS];
// Description: // Description:
// Creates a model of a clamp to hold a generic linear bearing cartridge. // Creates a model of a clamp to hold a generic linear bearing cartridge.
// Arguments: // Arguments:
@ -28,6 +30,7 @@ include <metric_screws.scad>
// wall = Wall thickness of clamp housing. (Default: 3) // wall = Wall thickness of clamp housing. (Default: 3)
// gap = Gap in clamp. (Default: 5) // gap = Gap in clamp. (Default: 5)
// screwsize = Size of screw to use to tighten clamp. (Default: 3) // screwsize = Size of screw to use to tighten clamp. (Default: 3)
// ---
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER` // anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0` // spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP` // orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
@ -81,12 +84,15 @@ module linear_bearing_housing(d=15, l=24, tab=7, gap=5, wall=3, tabwall=5, screw
// Synopsis: Creates a generic linear bearing cartridge. // Synopsis: Creates a generic linear bearing cartridge.
// Topics: Parts, Bearings // Topics: Parts, Bearings
// See Also: linear_bearing_housing(), lmXuu_info(), ball_bearing() // See Also: linear_bearing_housing(), lmXuu_info(), ball_bearing()
// Usage:
// linear_bearing(l, od, id, length) [ATTACHMENTS];
// Description: // Description:
// Creates a rough model of a generic linear ball bearing cartridge. // Creates a rough model of a generic linear ball bearing cartridge.
// Arguments: // Arguments:
// l/length = The length of the linear bearing cartridge. // l/length = The length of the linear bearing cartridge.
// od = The outer diameter of the linear bearing cartridge. // od = The outer diameter of the linear bearing cartridge.
// id = The inner diameter of the linear bearing cartridge. // id = The inner diameter of the linear bearing cartridge.
// ---
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER` // anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0` // spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP` // orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
@ -112,6 +118,8 @@ module linear_bearing(l, od=15, id=8, length, anchor=CTR, spin=0, orient=UP) {
// Synopsis: Creates a standardized LM*UU linear bearing mount clamp. // Synopsis: Creates a standardized LM*UU linear bearing mount clamp.
// Topics: Parts, Bearings // Topics: Parts, Bearings
// See Also: linear_bearing(), linear_bearing_housing(), lmXuu_info(), lmXuu_bearing(), lmXuu_housing(), ball_bearing() // See Also: linear_bearing(), linear_bearing_housing(), lmXuu_info(), lmXuu_bearing(), lmXuu_housing(), ball_bearing()
// Usage:
// lmXuu_housing(size, tab, gap, wall, tabwall, screwsize) [ATTACHMENTS];
// Description: // Description:
// Creates a model of a clamp to hold a standard sized lmXuu linear bearing cartridge. // Creates a model of a clamp to hold a standard sized lmXuu linear bearing cartridge.
// Arguments: // Arguments:
@ -121,6 +129,7 @@ module linear_bearing(l, od=15, id=8, length, anchor=CTR, spin=0, orient=UP) {
// wall = Wall thickness of clamp housing. Default: 3 // wall = Wall thickness of clamp housing. Default: 3
// gap = Gap in clamp. Default: 5 // gap = Gap in clamp. Default: 5
// screwsize = Size of screw to use to tighten clamp. Default: 3 // screwsize = Size of screw to use to tighten clamp. Default: 3
// ---
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER` // anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0` // spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP` // orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
@ -139,10 +148,13 @@ module lmXuu_housing(size=8, tab=7, gap=5, wall=3, tabwall=5, screwsize=3, ancho
// Synopsis: Creates a standardized LM*UU linear bearing cartridge. // Synopsis: Creates a standardized LM*UU linear bearing cartridge.
// Topics: Parts, Bearings // Topics: Parts, Bearings
// See Also: linear_bearing(), linear_bearing_housing(), lmXuu_info(), lmXuu_bearing(), lmXuu_housing(), ball_bearing() // See Also: linear_bearing(), linear_bearing_housing(), lmXuu_info(), lmXuu_bearing(), lmXuu_housing(), ball_bearing()
// Usage:
// lmXuu_bearing(size) [ATTACHMENTS];
// Description: // Description:
// Creates a model of an lmXuu linear ball bearing cartridge. // Creates a model of an lmXuu linear ball bearing cartridge.
// Arguments: // Arguments:
// size = Standard lmXuu inner size. // size = Standard lmXuu inner size.
// ---
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER` // anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0` // spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP` // orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
@ -161,6 +173,8 @@ module lmXuu_bearing(size=8, anchor=CTR, spin=0, orient=UP) {
// Synopsis: Returns the sizes of a standard LM*UU linear bearing cartridge. // Synopsis: Returns the sizes of a standard LM*UU linear bearing cartridge.
// Topics: Parts, Bearings // Topics: Parts, Bearings
// See Also: linear_bearing(), linear_bearing_housing(), lmXuu_info(), lmXuu_bearing(), lmXuu_housing(), ball_bearing() // See Also: linear_bearing(), linear_bearing_housing(), lmXuu_info(), lmXuu_bearing(), lmXuu_housing(), ball_bearing()
// Usage:
// diam_len = lmXuu_info(size);
// Description: // Description:
// Get dimensional info for a standard metric lmXuu linear bearing cartridge. // Get dimensional info for a standard metric lmXuu linear bearing cartridge.
// Returns `[DIAM, LENGTH]` for the cylindrical cartridge. // Returns `[DIAM, LENGTH]` for the cylindrical cartridge.

View file

@ -54,7 +54,7 @@ function _same_type(a,b, depth) =
// Function: min_length() // Function: min_length()
// Synopsis: Returns the length of the shortest list. // Synopsis: Given a list of sublists, returns the length of the shortest sublist.
// Topics: List Handling // Topics: List Handling
// See Also: max_length() // See Also: max_length()
// Usage: // Usage:
@ -71,7 +71,7 @@ function min_length(list) =
// Function: max_length() // Function: max_length()
// Synopsis: Returns the length of the longest list. // Synopsis: Given a list of sublists, returns the length of the longest sublist.
// Topics: List Handling // Topics: List Handling
// See Also: min_length() // See Also: min_length()
// Usage: // Usage:
@ -233,7 +233,7 @@ function select(list, start, end) =
// Function: slice() // Function: slice()
// Synopsis: Returns part of a list, not including the last index. // Synopsis: Returns part of a list without wrapping.
// Topics: List Handling // Topics: List Handling
// See Also: select(), column(), last() // See Also: select(), column(), last()
// Usage: // Usage:
@ -286,7 +286,7 @@ function last(list) =
// Function: list_head() // Function: list_head()
// Synopsis: Returns the head of the given list. // Synopsis: Returns the elements at the beginning of a list.
// Topics: List Handling // Topics: List Handling
// See Also: select(), slice(), list_tail(), last() // See Also: select(), slice(), list_tail(), last()
// Usage: // Usage:
@ -315,7 +315,7 @@ function list_head(list, to=-2) =
// Function: list_tail() // Function: list_tail()
// Synopsis: Returns the tail of the given list. // Synopsis: Returns the elements at the end of a list.
// Topics: List Handling // Topics: List Handling
// See Also: select(), slice(), list_tail(), last() // See Also: select(), slice(), list_tail(), last()
// Usage: // Usage:
@ -346,7 +346,7 @@ function list_tail(list, from=1) =
// Function: bselect() // Function: bselect()
// Synopsis: Cherry-picks specific items from a list. // Synopsis: Select list items using boolean index list.
// Topics: List Handling // Topics: List Handling
// See Also: list_bset() // See Also: list_bset()
// Usage: // Usage:
@ -369,7 +369,7 @@ function bselect(list,index) =
// Function: repeat() // Function: repeat()
// Synopsis: Returns a list of N copies of a value. // Synopsis: Returns a list of repeated copies of a value.
// Topics: List Handling // Topics: List Handling
// See Also: count(), lerpn() // See Also: count(), lerpn()
// Usage: // Usage:
@ -395,7 +395,7 @@ function repeat(val, n, i=0) =
// Function: list_bset() // Function: list_bset()
// Synopsis: Returns a list where specific values are set from a list of values. // Synopsis: Returns a list where values are spread to locations indicated by a boolean index list.
// Topics: List Handling // Topics: List Handling
// See Also: bselect() // See Also: bselect()
// Usage: // Usage:
@ -473,7 +473,7 @@ function force_list(value, n=1, fill) =
// Section: List Modification // Section: List Modification
// Function: reverse() // Function: reverse()
// Synopsis: Reverses the ordering of a list. // Synopsis: Reverses the elements of a list.
// Topics: List Handling // Topics: List Handling
// See Also: select(), list_rotate() // See Also: select(), list_rotate()
// Usage: // Usage:
@ -529,7 +529,7 @@ function list_rotate(list,n=1) =
// Function: shuffle() // Function: shuffle()
// Synopsis: Randomizes the ordering of a list. // Synopsis: Randomizes the order of a list.
// Topics: List Handling // Topics: List Handling
// See Also: sort(), sortidx(), unique(), unique_count() // See Also: sort(), sortidx(), unique(), unique_count()
// Usage: // Usage:
@ -563,7 +563,7 @@ function shuffle(list,seed) =
// Function: repeat_entries() // Function: repeat_entries()
// Synopsis: Repeats items in a list to expand it to a given length. // Synopsis: Repeats list entries (as uniformly as possible) to make list of specified length.
// Topics: List Handling // Topics: List Handling
// See Also: repeat() // See Also: repeat()
// Usage: // Usage:
@ -605,7 +605,7 @@ function repeat_entries(list, N, exact=true) =
// Function: list_pad() // Function: list_pad()
// Synopsis: Adds items to the end of a list until it is a given length. // Synopsis: Extend list to specified length.
// Topics: List Handling // Topics: List Handling
// See Also: force_list(), scalar_vec3() // See Also: force_list(), scalar_vec3()
// Usage: // Usage:
@ -717,7 +717,7 @@ function list_insert(list, indices, values) =
// Function: list_remove() // Function: list_remove()
// Synopsis: Removes items from the middle of a list. // Synopsis: Removes items by index from a list.
// Topics: List Handling // Topics: List Handling
// See Also: list_set(), list_insert(), list_remove_values() // See Also: list_set(), list_insert(), list_remove_values()
// Usage: // Usage:
@ -760,7 +760,7 @@ function list_remove(list, ind) =
// Function: list_remove_values() // Function: list_remove_values()
// Synopsis: Removes specific values from a list. // Synopsis: Removes items by value from a list.
// Topics: List Handling // Topics: List Handling
// See Also: list_set(), list_insert(), list_remove() // See Also: list_set(), list_insert(), list_remove()
// Usage: // Usage:
@ -861,7 +861,7 @@ function idx(list, s=0, e=-1, step=1) =
// Function: pair() // Function: pair()
// Synopsis: Returns a list of consecutive pairs in a list. // Synopsis: Returns a list of overlapping consecutive pairs in a list.
// Topics: List Handling, Iteration // Topics: List Handling, Iteration
// See Also: idx(), triplet(), combinations(), permutations() // See Also: idx(), triplet(), combinations(), permutations()
// Usage: // Usage:
@ -895,7 +895,7 @@ function pair(list, wrap=false) =
// Function: triplet() // Function: triplet()
// Synopsis: Returns a list of consecutive triplets in a list. // Synopsis: Returns a list of overlapping consecutive triplets in a list.
// Topics: List Handling, Iteration // Topics: List Handling, Iteration
// See Also: idx(), pair(), combinations(), permutations() // See Also: idx(), pair(), combinations(), permutations()
// Usage: // Usage:
@ -935,7 +935,7 @@ function triplet(list, wrap=false) =
// Function: combinations() // Function: combinations()
// Synopsis: Returns a list of all item combinations in a list. // Synopsis: Returns a list of all combinations of the list entries.
// Topics: List Handling, Iteration // Topics: List Handling, Iteration
// See Also: idx(), pair(), triplet(), permutations() // See Also: idx(), pair(), triplet(), permutations()
// Usage: // Usage:
@ -962,7 +962,7 @@ function combinations(l,n=2,_s=0) =
// Function: permutations() // Function: permutations()
// Synopsis: Returns a list of all item permutations in a list. // Synopsis: Returns a list of all permutations of the list entries.
// Topics: List Handling, Iteration // Topics: List Handling, Iteration
// See Also: idx(), pair(), triplet(), combinations() // See Also: idx(), pair(), triplet(), combinations()
// Usage: // Usage:

View file

@ -192,7 +192,7 @@ Torx values: https://www.stanleyengineeredfastening.com/-/media/web/sef/resourc
// Topics: Threading, Screws // Topics: Threading, Screws
// See Also: screw_hole(), shoulder_screw() // See Also: screw_hole(), shoulder_screw()
// Usage: // Usage:
// screw([spec], [head], [drive], [thread=], [drive_size=], [length=|l=], [thread_len=], [undersize=], [shaft_undersize=], [head_undersize=], [tolerance=], [details=], [anchor=], [atype=], [orient=], [spin=]) [ATTACHMENTS]; // screw([spec], [head], [drive], [thread=], [drive_size=], [length=|l=], [thread_len=], [undersize=], [shaft_undersize=], [head_undersize=], [tolerance=], [blunt_start=], [details=], [anchor=], [atype=], [orient=], [spin=]) [ATTACHMENTS];
// Description: // Description:
// Create a screw. See [screw and nut parameters](#section-screw-and-nut-parameters) for details on // Create a screw. See [screw and nut parameters](#section-screw-and-nut-parameters) for details on
// the parameters that define a screw. The tolerance determines the dimensions of the screw based // the parameters that define a screw. The tolerance determines the dimensions of the screw based
@ -248,9 +248,11 @@ Torx values: https://www.stanleyengineeredfastening.com/-/media/web/sef/resourc
// shaft_undersize = amount to decrease diameter of the shaft of screw; replaces rather than adding to the shaft_oversize value in a screw specification. // shaft_undersize = amount to decrease diameter of the shaft of screw; replaces rather than adding to the shaft_oversize value in a screw specification.
// head_undersize = amount to decrease the head diameter of the screw; replaces rather than adding to the head_oversize value in a screw specification. // head_undersize = amount to decrease the head diameter of the screw; replaces rather than adding to the head_oversize value in a screw specification.
// bevel1 = bevel bottom end of screw. Default: true // bevel1 = bevel bottom end of screw. Default: true
// bevel2 = bevel top end of threaded section. Default: true for headless, false otherwise // bevel2 = bevel top end of threaded section. Default: true for fully threaded or unthreaded headless, false otherwise
// bevel = bevel both ends of the threaded section. // bevel = bevel both ends of the threaded section.
// higbee = if true create blunt start threads at both ends for headless screws, and bottom only for other screws. Default: false // blunt_start = if true and hole is threaded, create blunt start threads. Default: true
// blunt_start1 = if true and hole is threaded, create blunt start threads at bottom end.
// blunt_start2 = if true and hole is threaded, create blunt start threads top end.
// atype = anchor type, one of "screw", "head", "shaft", "threads", "shank" // atype = anchor type, one of "screw", "head", "shaft", "threads", "shank"
// anchor = Translate so anchor point on the shaft is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER` // anchor = Translate so anchor point on the shaft is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0` // spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
@ -426,7 +428,7 @@ Torx values: https://www.stanleyengineeredfastening.com/-/media/web/sef/resourc
// $fn=32; // $fn=32;
// projection(cut=true)xrot(-90){ // projection(cut=true)xrot(-90){
// screw("1/4-20,3/8", head="hex",orient=UP,anchor=BOTTOM,tolerance="1A"); // screw("1/4-20,3/8", head="hex",orient=UP,anchor=BOTTOM,tolerance="1A");
// down(INCH*1/20*1.395) nut("1/4-20", thickness=8, nutwidth=0.5*INCH, tolerance="1B"); // down(INCH*1/20*1.5) nut("1/4-20", thickness=8, nutwidth=0.5*INCH, tolerance="1B");
// } // }
// Example: Here is a screw with nonstandard threading and a weird head size, which we create by modifying the screw structure: // Example: Here is a screw with nonstandard threading and a weird head size, which we create by modifying the screw structure:
// spec = screw_info("M6x2,12",head="socket"); // spec = screw_info("M6x2,12",head="socket");
@ -517,19 +519,19 @@ function _nominal_diam(spec) = struct_val(spec,"diameter")+default(struct_val(sp
function screw(spec, head, drive, thread, drive_size, function screw(spec, head, drive, thread, drive_size,
length, l, thread_len, tolerance, details=true, length, l, thread_len, tolerance, details=true,
undersize, shaft_undersize, head_undersize, undersize, shaft_undersize, head_undersize,
atype="screw",anchor=BOTTOM, spin=0, orient=UP, atype="screw",anchor, spin=0, orient=UP,
_shoulder_diam=0, _shoulder_len=0, _shoulder_diam=0, _shoulder_len=0,
bevel,bevel1,bevel2,bevelsize, bevel,bevel1,bevel2,bevelsize,
higbee=false, blunt_start,blunt_start1, blunt_start2,
_internal=false, _counterbore, _teardrop) = no_function("screw"); _internal=false, _counterbore, _teardrop=false)
= no_function("screw");
module screw(spec, head, drive, thread, drive_size, module screw(spec, head, drive, thread, drive_size,
length, l, thread_len, tolerance, details=true, length, l, thread_len, tolerance, details=true,
undersize, shaft_undersize, head_undersize, undersize, shaft_undersize, head_undersize,
atype="screw",anchor, spin=0, orient=UP, atype="screw",anchor, spin=0, orient=UP,
_shoulder_diam=0, _shoulder_len=0, _shoulder_diam=0, _shoulder_len=0,
bevel,bevel1,bevel2,bevelsize, bevel,bevel1,bevel2,bevelsize,
higbee, blunt_start,blunt_start1, blunt_start2,
_internal=false, _counterbore, _teardrop=false) _internal=false, _counterbore, _teardrop=false)
{ {
tempspec = _get_spec(spec, "screw_info", _internal ? "screw_hole" : "screw", tempspec = _get_spec(spec, "screw_info", _internal ? "screw_hole" : "screw",
@ -587,6 +589,9 @@ module screw(spec, head, drive, thread, drive_size,
: (struct_val(spec,"head_size_sharp")+struct_val(spec,"head_oversize",0)-d_major)/2/tan(struct_val(spec,"head_angle")/2); : (struct_val(spec,"head_size_sharp")+struct_val(spec,"head_oversize",0)-d_major)/2/tan(struct_val(spec,"head_angle")/2);
flat_cbore_height = flathead && is_num(counterbore) ? counterbore : 0; flat_cbore_height = flathead && is_num(counterbore) ? counterbore : 0;
blunt_start1 = first_defined([blunt_start1,blunt_start,true]);
blunt_start2 = first_defined([blunt_start2,blunt_start,true]);
shoulder_adj = _shoulder_len>0 ? flat_height:0; // Adjustment because flathead height doesn't count toward shoulder length shoulder_adj = _shoulder_len>0 ? flat_height:0; // Adjustment because flathead height doesn't count toward shoulder length
shoulder_full = _shoulder_len==0 ? 0 : _shoulder_len + flat_height; shoulder_full = _shoulder_len==0 ? 0 : _shoulder_len + flat_height;
shank_len = is_def(user_thread_len) ? length - user_thread_len - (_shoulder_len==0?flat_height:0) : 0; shank_len = is_def(user_thread_len) ? length - user_thread_len - (_shoulder_len==0?flat_height:0) : 0;
@ -649,6 +654,8 @@ module screw(spec, head, drive, thread, drive_size,
: is_def(vnf) ? undef : is_def(vnf) ? undef
: head_height+flat_height+flat_cbore_height; : head_height+flat_height+flat_cbore_height;
bevelsize = default(bevelsize, d_major/12); bevelsize = default(bevelsize, d_major/12);
bevel1 = first_defined([bevel1,bevel,true]);
bevel2 = first_defined([bevel2,bevel,headless && _shoulder_len==0 && shank_len==0]);
attachable( attachable(
vnf = vnf, vnf = vnf,
d = u_add(u_mul(attach_d, rad_scale), islop), d = u_add(u_mul(attach_d, rad_scale), islop),
@ -673,8 +680,16 @@ module screw(spec, head, drive, thread, drive_size,
if (shank_len>0 || pitch==0){ if (shank_len>0 || pitch==0){
L = pitch==0 ? length - (_shoulder_len==0?flat_height:0) : shank_len; L = pitch==0 ? length - (_shoulder_len==0?flat_height:0) : shank_len;
bevsize = (_internal ? -1 : 1)*bevelsize; bevsize = (_internal ? -1 : 1)*bevelsize;
bev1 = details && pitch==0 && first_defined([bevel1,bevel,!_internal]) ? bevsize : 0; bev1 = pitch!=0 ? 0
bev2 = details && pitch==0 && first_defined([bevel2,bevel,headless && !_internal]) ? bevsize : 0; : bevel1==true ? bevsize
: bevel1==false ? 0
: bevel1=="reverse" ? -bevsize
: bevel1;
bev2 = pitch!=0 ? 0
: bevel2==true ? bevsize
: bevel2==false ? 0
: bevel2=="reverse" ? -bevsize
: bevel2;
down(_shoulder_len+flat_height-eps_shank) down(_shoulder_len+flat_height-eps_shank)
if (_teardrop) if (_teardrop)
teardrop(d=d_major*rad_scale+islop, h=L+eps_shank, anchor=FRONT, orient=BACK, $fn=sides, chamfer1=bev1, chamfer2=bev2); teardrop(d=d_major*rad_scale+islop, h=L+eps_shank, anchor=FRONT, orient=BACK, $fn=sides, chamfer1=bev1, chamfer2=bev2);
@ -682,18 +697,15 @@ module screw(spec, head, drive, thread, drive_size,
cyl(d=d_major*rad_scale+islop, h=L+eps_shank, anchor=TOP, $fn=sides, chamfer1=bev1, chamfer2=bev2); cyl(d=d_major*rad_scale+islop, h=L+eps_shank, anchor=TOP, $fn=sides, chamfer1=bev1, chamfer2=bev2);
} }
if (thread_len>0 && pitch>0){ if (thread_len>0 && pitch>0){
bev1 = details && first_defined([bevel1,bevel,!_internal]);
bev2 = details && first_defined([bevel2,bevel,!_internal && (flathead || _shoulder_len>0 || headless)]);
down(_shoulder_len+flat_height+shank_len-eps_thread) down(_shoulder_len+flat_height+shank_len-eps_thread)
threaded_rod([mean(struct_val(threadspec, "d_minor")), threaded_rod([mean(struct_val(threadspec, "d_minor")),
mean(struct_val(threadspec, "d_pitch")), mean(struct_val(threadspec, "d_pitch")),
d_major], d_major],
pitch = struct_val(threadspec, "pitch"), pitch = struct_val(threadspec, "pitch"),
l=thread_len+eps_thread, left_handed=false, internal=_internal, l=thread_len+eps_thread, left_handed=false, internal=_internal,
bevel1=bev1, bevel1=bevel1,
bevel2=bev2, bevel2=bevel2,
higbee1=higbee && !_internal, blunt_start=blunt_start, blunt_start1=blunt_start1, blunt_start2=blunt_start2,
higbee2=(!headless && !_internal) || is_undef(higbee) ? false : higbee,
$fn=sides, anchor=TOP); $fn=sides, anchor=TOP);
} }
@ -706,13 +718,12 @@ module screw(spec, head, drive, thread, drive_size,
// Module: screw_hole() // Module: screw_hole()
// Synopsis: Creates a screw hole. // Synopsis: Creates a screw hole.
// Topics: Threading, Screws // Topics: Threading, Screws
// See Also: screw() // See Also: screw()
// Usage: // Usage:
// screw_hole([spec], [head], [thread=], [length=|l=], [oversize=], [hole_oversize=], [teardrop=], [head_oversize], [tolerance=], [$slop=], [anchor=], [atype=], [orient=], [spin=]) [ATTACHMENTS]; // screw_hole([spec], [head], [thread=], [length=|l=], [oversize=], [hole_oversize=], [teardrop=], [head_oversize], [tolerance=], [$slop=], [blunt_start=], [anchor=], [atype=], [orient=], [spin=]) [ATTACHMENTS];
// Description: // Description:
// Create a screw hole mask. See [screw and nut parameters](#section-screw-and-nut-parameters) for details on the parameters that define a screw. // Create a screw hole mask. See [screw and nut parameters](#section-screw-and-nut-parameters) for details on the parameters that define a screw.
// The screw hole can be threaded to receive a screw or it can be an unthreaded clearance hole. // The screw hole can be threaded to receive a screw or it can be an unthreaded clearance hole.
@ -760,7 +771,9 @@ module screw(spec, head, drive, thread, drive_size,
// bevel = if true create bevel at both ends of hole. Default: see below // bevel = if true create bevel at both ends of hole. Default: see below
// bevel1 = if true create bevel at bottom end of hole. Default: false // bevel1 = if true create bevel at bottom end of hole. Default: false
// bevel2 = if true create bevel at top end of hole. Default: true when tolerance="self tap", false otherwise // bevel2 = if true create bevel at top end of hole. Default: true when tolerance="self tap", false otherwise
// higbee = if true and hole is threaded, create blunt start threads at the top of the hole. Default: false // blunt_start = if true and hole is threaded, create blunt start threads. Default: true
// blunt_start1 = if true and hole is threaded, create blunt start threads at bottom end.
// blunt_start2 = if true and hole is threaded, create blunt start threads top end.
// $slop = add extra gap to account for printer overextrusion. Default: 0 // $slop = add extra gap to account for printer overextrusion. Default: 0
// atype = anchor type, one of "screw", "head", "shaft", "threads", "shank" // atype = anchor type, one of "screw", "head", "shaft", "threads", "shank"
// anchor = Translate so anchor point on the shaft is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER` // anchor = Translate so anchor point on the shaft is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
@ -800,14 +813,20 @@ module screw(spec, head, drive, thread, drive_size,
// cuboid(20) // cuboid(20)
// attach(TOP) // attach(TOP)
// screw_hole("1/4-20,.5",head="flat",counterbore=0,anchor=TOP); // screw_hole("1/4-20,.5",head="flat",counterbore=0,anchor=TOP);
// Example: Threaded hole // Example: Threaded hole, with inward bevel at the base
// diff() // bottom_half()
// cuboid(20) // diff()
// attach(FRONT) // cuboid(20)
// screw_hole("M16,15",anchor=TOP,thread=true); // attach(FRONT)
// screw_hole("M16,15",anchor=TOP,thread=true,bevel1="reverse");
function screw_hole(spec, head, thread, oversize, hole_oversize, head_oversize,
length, l, thread_len, tolerance=undef, counterbore, teardrop=false,
bevel, bevel1, bevel2, blunt_start, blunt_start1, blunt_start2,
atype="screw",anchor=CENTER,spin=0, orient=UP)
= no_function("screw_hole");
module screw_hole(spec, head, thread, oversize, hole_oversize, head_oversize, module screw_hole(spec, head, thread, oversize, hole_oversize, head_oversize,
length, l, thread_len, tolerance=undef, counterbore, teardrop=false, length, l, thread_len, tolerance=undef, counterbore, teardrop=false,
bevel, bevel1, bevel2, higbee=false, bevel, bevel1, bevel2, blunt_start, blunt_start1, blunt_start2,
atype="screw",anchor=CENTER,spin=0, orient=UP) atype="screw",anchor=CENTER,spin=0, orient=UP)
{ {
screwspec = _get_spec(spec, "screw_info", "screw_hole", screwspec = _get_spec(spec, "screw_info", "screw_hole",
@ -826,9 +845,10 @@ module screw_hole(spec, head, thread, oversize, hole_oversize, head_oversize,
head_oversize = first_defined([head_oversize, oversize[1],struct_val(screwspec,"head_oversize")]); head_oversize = first_defined([head_oversize, oversize[1],struct_val(screwspec,"head_oversize")]);
if (threaded || is_def(hole_oversize) || tolerance==0 || tolerance=="none") { if (threaded || is_def(hole_oversize) || tolerance==0 || tolerance=="none") {
default_tag("remove") default_tag("remove")
screw(spec,head=head,thread=thread,shaft_undersize=u_mul(-1,hole_oversize), head_undersize=u_mul(-1,head_oversize), higbee=higbee, screw(spec,head=head,thread=thread,shaft_undersize=u_mul(-1,hole_oversize), head_undersize=u_mul(-1,head_oversize),
blunt_start=blunt_start, blunt_start1=blunt_start1, blunt_start2=blunt_start2,
length=length,l=l,thread_len=thread_len, tolerance=tolerance, _counterbore=counterbore, length=length,l=l,thread_len=thread_len, tolerance=tolerance, _counterbore=counterbore,
bevel=bevel, bevel1=bevel1, bevel2=bevel2, bevel1=bevel1, bevel2=bevel2,
atype=atype, anchor=anchor, spin=spin, orient=orient, _internal=true, _teardrop=teardrop) atype=atype, anchor=anchor, spin=spin, orient=orient, _internal=true, _teardrop=teardrop)
children(); children();
} }
@ -949,7 +969,7 @@ module screw_hole(spec, head, thread, oversize, hole_oversize, head_oversize,
default_tag("remove") default_tag("remove")
screw(spec,head=head,thread=0,shaft_undersize=-hole_oversize, head_undersize=-head_oversize, screw(spec,head=head,thread=0,shaft_undersize=-hole_oversize, head_undersize=-head_oversize,
length=length,l=l,thread_len=thread_len, _counterbore=counterbore, length=length,l=l,thread_len=thread_len, _counterbore=counterbore,
bevel=bevel, bevel1=bevel1, bevel2=bevel2, bevelsize=pitch>0?pitch:undef, higbee=higbee, bevel1=bevel1, bevel2=bevel2, bevelsize=pitch>0?pitch:undef,
atype=atype, anchor=anchor, spin=spin, orient=orient, _internal=true, _teardrop=teardrop) atype=atype, anchor=anchor, spin=spin, orient=orient, _internal=true, _teardrop=teardrop)
children(); children();
} }
@ -1033,8 +1053,13 @@ module screw_hole(spec, head, thread, oversize, hole_oversize, head_oversize,
// shoulder_screw("iso", 16, length=20, head="none"); // shoulder_screw("iso", 16, length=20, head="none");
// Example: Changing head height // Example: Changing head height
// shoulder_screw("iso", 16, length=20, head_size=[24,5]); // shoulder_screw("iso", 16, length=20, head_size=[24,5]);
function shoulder_screw(s,d,length,head, thread_len, tolerance, head_size, drive, drive_size, thread,
undersize, shaft_undersize, head_undersize, shoulder_undersize=0,
blunt_start, blunt_start1, blunt_start2,
atype="screw", anchor=BOT, orient,spin) = no_function("shoulder_screw");
module shoulder_screw(s,d,length,head, thread_len, tolerance, head_size, drive, drive_size, thread, module shoulder_screw(s,d,length,head, thread_len, tolerance, head_size, drive, drive_size, thread,
undersize, shaft_undersize, head_undersize, shoulder_undersize=0, undersize, shaft_undersize, head_undersize, shoulder_undersize=0,
blunt_start, blunt_start1, blunt_start2,
atype="screw", anchor=BOT, orient,spin) atype="screw", anchor=BOT, orient,spin)
{ {
d1= assert(is_num(d) && d>0, "Must specify shoulder diameter") d1= assert(is_num(d) && d>0, "Must specify shoulder diameter")
@ -1129,6 +1154,7 @@ module shoulder_screw(s,d,length,head, thread_len, tolerance, head_size, drive,
screw(struct_set(info, headfields), screw(struct_set(info, headfields),
_shoulder_len = length, _shoulder_diam = shoulder_diam-shoulder_tol, _shoulder_len = length, _shoulder_diam = shoulder_diam-shoulder_tol,
length=thread_len, tolerance=tolerance, shaft_undersize=shaft_undersize, head_undersize=head_undersize, length=thread_len, tolerance=tolerance, shaft_undersize=shaft_undersize, head_undersize=head_undersize,
blunt_start=blunt_start, blunt_start1=blunt_start1, blunt_start2=blunt_start2,
atype=atype, anchor=anchor, orient=orient, spin=spin) atype=atype, anchor=anchor, orient=orient, spin=spin)
children(); children();
} }
@ -1499,9 +1525,9 @@ module screw_head(screw_info,details=false, counterbore=0,flat_height,teardrop=f
// ibevel = if true, bevel the inside (the hole). Default: true // ibevel = if true, bevel the inside (the hole). Default: true
// ibevel1 = if true bevel the inside, bottom end. // ibevel1 = if true bevel the inside, bottom end.
// ibevel2 = if true bevel the inside, top end. // ibevel2 = if true bevel the inside, top end.
// higbee = If true apply higbee thread truncation at both ends, or set to an angle to adjust higbee cut point. Default: false // blunt_start = If true apply truncated blunt start threads at both ends. Default: true
// higbee1 = If true apply higbee thread truncation at bottom end, or set to an angle to adjust higbee cut point. // blunt_start1 = If true apply truncated blunt start threads bottom end.
// higbee2 = If true apply higbee thread truncation at top end, or set to an angle to adjust higbee cut point. // blunt_start2 = If true apply truncated blunt start threads top end.
// tolerance = nut tolerance. Determines actual nut thread geometry based on nominal sizing. See [tolerance](#subsection-tolerance). Default is "2B" for UTS and "6H" for ISO. // tolerance = nut tolerance. Determines actual nut thread geometry based on nominal sizing. See [tolerance](#subsection-tolerance). Default is "2B" for UTS and "6H" for ISO.
// $slop = extra space left to account for printing over-extrusion. Default: 0 // $slop = extra space left to account for printing over-extrusion. Default: 0
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER` // anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
@ -1550,7 +1576,7 @@ function nut(spec, shape, thickness, nutwidth, thread, tolerance, hole_oversize,
bevel,bevel1,bevel2,bevang=15,ibevel,ibevel1,ibevel2, higbee, higbee1, higbee2, anchor=BOTTOM, spin=0, orient=UP, oversize=0) bevel,bevel1,bevel2,bevang=15,ibevel,ibevel1,ibevel2, higbee, higbee1, higbee2, anchor=BOTTOM, spin=0, orient=UP, oversize=0)
= no_function("nut"); = no_function("nut");
module nut(spec, shape, thickness, nutwidth, thread, tolerance, hole_oversize, module nut(spec, shape, thickness, nutwidth, thread, tolerance, hole_oversize,
bevel,bevel1,bevel2,bevang=15,ibevel,ibevel1,ibevel2, higbee, higbee1, higbee2, anchor=BOTTOM, spin=0, orient=UP, oversize=0) bevel,bevel1,bevel2,bevang=15,ibevel,ibevel1,ibevel2,blunt_start, blunt_start1, blunt_start2, anchor=BOTTOM, spin=0, orient=UP, oversize=0)
{ {
dummyA = assert(is_undef(nutwidth) || (is_num(nutwidth) && nutwidth>0)); dummyA = assert(is_undef(nutwidth) || (is_num(nutwidth) && nutwidth>0));
@ -1578,11 +1604,15 @@ module nut(spec, shape, thickness, nutwidth, thread, tolerance, hole_oversize,
shape=shape, shape=shape,
bevel=bevel,bevel1=bevel1,bevel2=bevel2,bevang=bevang, bevel=bevel,bevel1=bevel1,bevel2=bevel2,bevang=bevang,
ibevel=ibevel,ibevel1=ibevel1,ibevel2=ibevel2, ibevel=ibevel,ibevel1=ibevel1,ibevel2=ibevel2,
higbee=higbee, higbee1=higbee1, higbee2=higbee2, blunt_start=blunt_start, blunt_start1=blunt_start1, blunt_start2=blunt_start2,
anchor=anchor,spin=spin,orient=orient) children(); anchor=anchor,spin=spin,orient=orient) children();
} }
// Module: nut_trap_side() // Module: nut_trap_side()
// Synopsis: Creates a side nut trap mask. // Synopsis: Creates a side nut trap mask.
// Topics: Threading, Screws // Topics: Threading, Screws

250
skin.scad
View file

@ -1053,132 +1053,140 @@ module rotate_sweep(
// Takes a closed 2D polygon path, centered on the XY plane, and sweeps/extrudes it along a 3D spiral path // Takes a closed 2D polygon path, centered on the XY plane, and sweeps/extrudes it along a 3D spiral path
// of a given radius, height and degrees of rotation. The origin in the profile traces out the helix of the specified radius. // of a given radius, height and degrees of rotation. The origin in the profile traces out the helix of the specified radius.
// If turns is positive the path will be right-handed; if turns is negative the path will be left-handed. // If turns is positive the path will be right-handed; if turns is negative the path will be left-handed.
// Such an extrusion can be used to make screw threads.
// . // .
// The taper options specify tapering at of the ends of the extrusion, and are given as the linear distance // The lead_in options specify a lead-in setiton where the ends of the spiral scale down to avoid a sharp cut face at the ends.
// over which to taper. If taper is positive the extrusion lengthened by the specified distance; if taper // You can specify the length of this scaling directly with the lead_in parameters or as an angle using the lead_in_ang parameters.
// is negative, the taper is included in the extrusion length specified by `turns`. // If you give a positive value, the extrusion is lengthenend by the specified distance or angle; if you give a negative
// value then the scaled end is included in the extrusion length specified by `turns`. If the value is zero then no scaled ends
// are produced. The shape of the scaled ends can be controlled with the lead_in_shape parameter. Supported options are "sqrt", "linear"
// "smooth" and "cut".
// .
// The inside argument changes how the extrusion lead-in sections are formed. If it is true then they scale
// towards the outside, like would be needed for internal threading. If internal is fale then the lead-in sections scale
// towards the inside, like would be appropriate for external threads.
// Arguments: // Arguments:
// poly = Array of points of a polygon path, to be extruded. // poly = Array of points of a polygon path, to be extruded.
// h = height of the spiral to extrude along. // h = height of the spiral extrusion path
// r = Radius of the spiral to extrude along. // r = Radius of the spiral extrusion path
// turns = number of revolutions to spiral up along the height. // turns = number of revolutions to include in the spiral
// --- // ---
// d = Diameter of the spiral to extrude along. // d = Diameter of the spiral extrusion path.
// d1/r1 = Bottom inside diameter or radius of spiral to extrude along. // d1/r1 = Bottom inside diameter or radius of spiral to extrude along.
// d2/r2 = Top inside diameter or radius of spiral to extrude along. // d2/r2 = Top inside diameter or radius of spiral to extrude along.
// taper = Length of tapers for thread ends. Positive to add taper to threads, negative to taper within specified length. Default: 0 // lead_in = Specify linear length of the lead-in scaled section of the spiral. Default: 0
// taper1 = Length of taper for bottom thread end // lead_in1 = Specify linear length of the lead-in scaled section of the spiral at the bottom
// taper2 = Length of taper for top thread end // lead_in2 = Specify linear length of the lead-in scaled section of the spiral at the top
// internal = if true make internal threads. The only effect this has is to change how the extrusion tapers if tapering is selected. When true, the extrusion tapers towards the outside; when false, it tapers towards the inside. Default: false // lead_in_ang = Specify angular length of the lead-in scaled section of the spiral
// lead_in_ang1 = Specify angular length of the lead-in scaled section of the spiral at the bottom
// lead_in_ang2 = Specify angular length of the lead-in scaled section of the spiral at the top
// lead_in_shape = Specify the shape of the thread lead in by giving a text string or function. Default: "sqrt"
// lead_in_shape1 = Specify the shape of the thread lead-in at the bottom by giving a text string or function.
// lead_in_shape2 = Specify the shape of the thread lead-in at the top by giving a text string or function.
// lead_in_sample = Factor to increase sample rate in the lead-in section. Default: 10
// internal = if true make internal threads. The only effect this has is to change how the extrusion lead-in section are formed. When true, the extrusion scales towards the outside; when false, it scales towards the inside. Default: false
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER` // anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0` // spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP` // orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
// center = If given, overrides `anchor`. A true value sets `anchor=CENTER`, false sets `anchor=BOTTOM`. // See Also: sweep(), linear_sweep(), rotate_sweep(), path_sweep(), thread_helix()
// See Also: sweep(), linear_sweep(), rotate_sweep(), path_sweep()
// Example: // Example:
// poly = [[-10,0], [-3,-5], [3,-5], [10,0], [0,-30]]; // poly = [[-10,0], [-3,-5], [3,-5], [10,0], [0,-30]];
// spiral_sweep(poly, h=200, r=50, turns=3, $fn=36); // spiral_sweep(poly, h=200, r=50, turns=3, $fn=36);
function _taperfunc_orig_1d(x,L) = _leadin_ogive=function (x,L)
x>1 ? 1 : x<0 ? 0: let( minscale = .05,
let(
higofs = pow(0.05,2) // Smallest hig scale is the square root of this value
)
sqrt((1-higofs)*x+higofs);
function _taperfunc_orig(x,L) =
let(s=_taperfunc_orig_1d(x))
x>1 ? [1,1]
: x<0 ? [0,0]
: [lerp(s,1,.25),s];
function _taperfunc_ellipse(x) =
sqrt(1-(1-x)^2);
function _taperfunc_linear(x) =
x>1 ? 1 : x<0 ? 0 : x;
function _taperfunc_ogive_width(x,L) =
let( minscale = .2,
r=(L^2+(1-minscale^2))/2/(1-minscale), r=(L^2+(1-minscale^2))/2/(1-minscale),
scale = sqrt(r^2-(L*(1-x))^2) -(r-1) scale = sqrt(r^2-(L*(1-x))^2) -(r-1)
) )
x>1 ? [1,1] x>1 ? [1,1]
: x<0 ? [0,0] : x<0 ? [lerp(minscale,1,.25),0]
: [scale,1]; : [lerp(scale,1,.25),scale];
function _taperfunc_ogive_width_circle(x,L,h) =
let( minscale = .2, _leadin_cut = function(x,L) x>0 ? [1,1] : [1,0];
r=(L^2+(1-minscale^2))/2/(1-minscale),
scale = sqrt(r^2-(L*(1-x))^2) -(r-1), _leadin_sqrt = function(x,L)
vscale = x*L>h ? h : sqrt(h^2-(x*L-h)^2) let(end=0.05) // Smallest scale at the end
)
x>1 ? [1,1] x>1 ? [1,1]
: x<0.02 ? [0,0] : x<0 ? [lerp(end,1,.25),0]
: [scale,vscale/h]; : let(
function _taperfunc_ogive_height(x,L) = s = sqrt(x + end^2 * (1-x))
let( minscale = .1,L=3*L,
r=(L^2+(1-minscale^2))/2/(1-minscale),
scale = sqrt(r^2-(L*(1-x))^2) -(r-1)
) )
[lerp(s,1,.25),s]; // thread width scale, thread height scale
_leadin_linear = function(x,L)
let(minscale=.1)
x>1 ? [1,1] x>1 ? [1,1]
: x<0 ? [0,0] //minscale,0] : x<0 ? [lerp(minscale,1,.25),0]
: [1,scale]; : let(scale = lerp(minscale,1,x))
function _taperfunc_ogive(x,L) = [lerp(scale,1,.25),scale];
let( minscale = .3,
r=(L^2+(1-minscale^2))/2/(1-minscale),
scale = sqrt(r^2-(L*(1-x))^2) -(r-1)
)
x>1 ? [1,1]
: x<0 ? [0,0]
: [scale,scale];
function _taperfunc_ogive_orig(x,L) =
let( minscale = .3,
r=(L^2+(1-minscale^2))/2/(1-minscale),
scale = sqrt(r^2-(L*(1-x))^2) -(r-1)
)
x>1 ? [1,1]
: x<0 ? [0,0]
: [lerp(_taperfunc_orig_1d(x),1,.25),scale];
function _taperfunc_cut(x,L) = x>1 ? [1,1] : [0,0];
function _taperfunc(x,L,h) = _taperfunc_ogive_width_circle(x,L,h);
//function _taperfunc(x,L,h) = _taperfunc_orig(x,L);
//function _taperfunc(x,L,h) = _taperfunc_ogive_width(x,L);
function _taperfunc(x,L,h) = _taperfunc_orig(x,L);
_lead_in_table = [
["default", _leadin_sqrt],
["sqrt", _leadin_sqrt],
["cut", _leadin_cut],
["smooth", _leadin_ogive],
["linear", _leadin_linear]
];
function _ss_polygon_r(N,theta) = function _ss_polygon_r(N,theta) =
let( alpha = 360/N ) let( alpha = 360/N )
cos(alpha/2)/(cos(posmod(theta,alpha)-alpha/2)); cos(alpha/2)/(cos(posmod(theta,alpha)-alpha/2));
function spiral_sweep(poly, h, r, turns=1, taper, center, r1, r2, d, d1, d2, taper1, taper2, internal=false, anchor=CENTER, spin=0, orient=UP) = function spiral_sweep(poly, h, r, turns=1, taper, r1, r2, d, d1, d2, internal=false,
lead_in_shape,lead_in_shape1, lead_in_shape2,
lead_in, lead_in1, lead_in2,
lead_in_ang, lead_in_ang1, lead_in_ang2,
height,l,length,
lead_in_sample = 10,
anchor=CENTER, spin=0, orient=UP) =
assert(is_num(turns) && turns != 0, "turns must be a nonzero number") assert(is_num(turns) && turns != 0, "turns must be a nonzero number")
assert(all_positive([h]), "Spiral height must be a positive number") assert(all_positive([h]), "Spiral height must be a positive number")
let( let(
tapersample = 10, // Oversample factor for higbee tapering
dir = sign(turns), dir = sign(turns),
r1 = get_radius(r1=r1, r=r, d1=d1, d=d, dflt=50), r1 = get_radius(r1=r1, r=r, d1=d1, d=d),
r2 = get_radius(r1=r2, r=r, d1=d2, d=d, dflt=50), r2 = get_radius(r1=r2, r=r, d1=d2, d=d),
bounds = pointlist_bounds(poly), bounds = pointlist_bounds(poly),
yctr = (bounds[0].y+bounds[1].y)/2, yctr = (bounds[0].y+bounds[1].y)/2,
xmin = bounds[0].x, xmin = bounds[0].x,
xmax = bounds[1].x, xmax = bounds[1].x,
poly = path3d(clockwise_polygon(poly)), poly = path3d(clockwise_polygon(poly)),
anchor = get_anchor(anchor,center,BOT,BOT),
sides = segs(max(r1,r2)), sides = segs(max(r1,r2)),
ang_step = 360/sides, ang_step = 360/sides,
turns = abs(turns), turns = abs(turns),
taper1 = first_defined([taper1, taper, 0]), lead_in1 = first_defined([lead_in1, lead_in]),
taper2 = first_defined([taper2, taper, 0]), lead_in2 = first_defined([lead_in1, lead_in]),
taperang1 = 360 * abs(taper1) / (2 * r1 * PI), lead_in_ang1 =
taperang2 = 360 * abs(taper2) / (2 * r2 * PI), let(
minang = taper1<=0 ? 0 : -taperang1, user_ang = first_defined([lead_in_ang1,lead_in_ang])
tapercut1 = taper1<=0 ? taperang1 : 0, )
maxang = taper2<=0 ? 360*turns : 360*turns+taperang2, assert(is_undef(user_ang) || is_undef(lead_in1), "Cannot define lead_in/lead_in1 by both length and angle")
tapercut2 = taper2<=0 ? 360*turns-taperang2 : 360*turns is_def(user_ang) ? user_ang : default(lead_in1,0)*360/(2*PI*r1),
lead_in_ang2 =
let(
user_ang = first_defined([lead_in_ang2,lead_in_ang])
)
assert(is_undef(user_ang) || is_undef(lead_in2), "Cannot define lead_in/lead_in2 by both length and angle")
is_def(user_ang) ? user_ang : default(lead_in2,0)*360/(2*PI*r2),
minang = -max(0,lead_in_ang1),
maxang = 360*turns + max(0,lead_in_ang2),
cut_ang1 = minang+abs(lead_in_ang1),
cut_ang2 = maxang-abs(lead_in_ang1),
lead_in_shape1 = first_defined([lead_in_shape1, lead_in_shape, "default"]),
lead_in_shape2 = first_defined([lead_in_shape2, lead_in_shape, "default"]),
lead_in_func1 = is_func(lead_in_shape1) ? lead_in_shape1
: assert(is_string(lead_in_shape1),"lead_in_shape/lead_in_shape1 must be a function or string")
let(ind = search([lead_in_shape1], _lead_in_table,0)[0])
assert(ind!=[],str("Unknown lead_in_shape, \"",lead_in_shape1,"\""))
_lead_in_table[ind[0]][1],
lead_in_func2 = is_func(lead_in_shape2) ? lead_in_shape2
: assert(is_string(lead_in_shape2),"lead_in_shape/lead_in_shape2 must be a function or string")
let(ind = search([lead_in_shape2], _lead_in_table,0)[0])
assert(ind!=[],str("Unknown lead_in_shape, \"",lead_in_shape2,"\""))
_lead_in_table[ind[0]][1]
) )
assert( tapercut1<tapercut2 && tapercut1<maxang, "Tapers are too long to fit") assert( cut_ang1<cut_ang2, "Tapers are too long to fit")
assert( all_positive([r1,r2]), "Diameter/radius must be positive") assert( all_positive([r1,r2]), "Diameter/radius must be positive")
let( let(
// This complicated sampling scheme is designed to ensure that faceting always starts at angle zero // This complicated sampling scheme is designed to ensure that faceting always starts at angle zero
// for alignment with cylinders, and there is always a facet boundary at the $fn specified locations, // for alignment with cylinders, and there is always a facet boundary at the $fn specified locations,
// regardless of what kind of subsampling occurs for tapers. // regardless of what kind of subsampling occurs for tapers.
@ -1189,17 +1197,17 @@ function spiral_sweep(poly, h, r, turns=1, taper, center, r1, r2, d, d1, d2, tap
maxang maxang
], ],
anglist = [ anglist = [
for(a=orig_anglist) if (a<tapercut1-EPSILON) a, for(a=orig_anglist) if (a<cut_ang1-EPSILON) a,
tapercut1, cut_ang1,
for(a=orig_anglist) if (a>tapercut1+EPSILON && a<tapercut2-EPSILON) a, for(a=orig_anglist) if (a>cut_ang1+EPSILON && a<cut_ang2-EPSILON) a,
tapercut2, cut_ang2,
for(a=orig_anglist) if (a>tapercut2+EPSILON) a for(a=orig_anglist) if (a>cut_ang2+EPSILON) a
], ],
interp_ang = [ interp_ang = [
for(i=idx(anglist,e=-2)) for(i=idx(anglist,e=-2))
each lerpn(anglist[i],anglist[i+1], each lerpn(anglist[i],anglist[i+1],
(taper1!=0 && anglist[i+1]<=tapercut1) || (taper2!=0 && anglist[i]>=tapercut2) (lead_in_ang1!=0 && anglist[i+1]<=cut_ang1) || (lead_in_ang2!=0 && anglist[i]>=cut_ang2)
? ceil((anglist[i+1]-anglist[i])/ang_step*tapersample) ? ceil((anglist[i+1]-anglist[i])/ang_step*lead_in_sample)
: 1, : 1,
endpoint=false), endpoint=false),
last(anglist) last(anglist)
@ -1207,8 +1215,8 @@ function spiral_sweep(poly, h, r, turns=1, taper, center, r1, r2, d, d1, d2, tap
skewmat = affine3d_skew_xz(xa=atan2(r2-r1,h)), skewmat = affine3d_skew_xz(xa=atan2(r2-r1,h)),
points = [ points = [
for (a = interp_ang) let ( for (a = interp_ang) let (
hsc = a<tapercut1 ? _taperfunc((a-minang)/taperang1,abs(taper1),xmax-xmin) hsc = a<cut_ang1 ? lead_in_func1((a-minang)/abs(lead_in_ang1),abs(lead_in_ang1)*2*PI*r1/360)
: a>tapercut2 ? _taperfunc((maxang-a)/taperang2,abs(taper2),xmax-xmin) : a>cut_ang2 ? lead_in_func2((maxang-a)/abs(lead_in_ang2),abs(lead_in_ang2)*2*PI*r2/360)
: [1,1], : [1,1],
u = a/(360*turns), u = a/(360*turns),
r = lerp(r1,r2,u), r = lerp(r1,r2,u),
@ -1230,15 +1238,30 @@ function spiral_sweep(poly, h, r, turns=1, taper, center, r1, r2, d, d1, d2, tap
module spiral_sweep(poly, h, r, turns=1, taper, center, r1, r2, d, d1, d2, taper1, taper2, internal=false, anchor=CENTER, spin=0, orient=UP) { module spiral_sweep(poly, h, r, turns=1, taper, r1, r2, d, d1, d2, internal=false,
vnf = spiral_sweep(poly, h, r, turns, taper, center, r1, r2, d, d1, d2, taper1, taper2, internal); lead_in_shape,lead_in_shape1, lead_in_shape2,
r1 = get_radius(r1=r1, r=r, d1=d1, d=d, dflt=50); lead_in, lead_in1, lead_in2,
r2 = get_radius(r1=r2, r=r, d1=d2, d=d, dflt=50); lead_in_ang, lead_in_ang1, lead_in_ang2,
taper1 = first_defined([taper1,taper,0]); height,l,length,
taper2 = first_defined([taper2,taper,0]); lead_in_sample=10,
extra = PI/2*(max(0,taper1/r1)+max(0,taper2/r2)); anchor=CENTER, spin=0, orient=UP)
{
vnf = spiral_sweep(poly=poly, h=h, r=r, turns=turns, r1=r1, r2=r2, d=d, d1=d1, d2=d2, internal=internal,
lead_in_shape=lead_in_shape,lead_in_shape1=lead_in_shape1, lead_in_shape2=lead_in_shape2,
lead_in=lead_in, lead_in1=lead_in1, lead_in2=lead_in2,
lead_in_ang=lead_in_ang, lead_in_ang1=lead_in_ang1, lead_in_ang2=lead_in_ang2,
height=height,l=length,length=length,
lead_in_sample=lead_in_sample);
h = one_defined([h,height,length,l],"h,height,length,l");
r1 = get_radius(r1=r1, r=r, d1=d1, d=d);
r2 = get_radius(r1=r2, r=r, d1=d2, d=d);
lead_in1 = u_mul(first_defined([lead_in1,lead_in]),1/(2*PI*r1));
lead_in2 = u_mul(first_defined([lead_in2,lead_in]),1/(2*PI*r2));
lead_in_ang1 = first_defined([lead_in_ang1,lead_in_ang]);
lead_in_ang2 = first_defined([lead_in_ang2,lead_in_ang]);
extra_turns = max(0,first_defined([lead_in1,lead_in_ang1,0]))+max(0,first_defined([lead_in2,lead_in_ang2,0]));
attachable(anchor,spin,orient, r1=r1, r2=r2, l=h) { attachable(anchor,spin,orient, r1=r1, r2=r2, l=h) {
vnf_polyhedron(vnf, convexity=ceil(2*(abs(turns)+extra))); vnf_polyhedron(vnf, convexity=ceil(2*(abs(turns)+extra_turns)));
children(); children();
} }
} }
@ -1796,7 +1819,22 @@ function path_sweep(shape, path, method="incremental", normal, closed, twist=0,
) )
assert(approx(ynormal*znormal,0),str("Supplied normal is parallel to the path tangent at point ",i)) assert(approx(ynormal*znormal,0),str("Supplied normal is parallel to the path tangent at point ",i))
translate(path[i%L])*rotation*zrot(-twist*tpathfrac[i]) translate(path[i%L])*rotation*zrot(-twist*tpathfrac[i])
] ]
: method=="cross"?
let(
crossnormal_mid = [for(i=[(closed?0:1):L-(closed?1:2)])
let(v= cross( select(path,i+1)-path[i], path[i]-select(path,i-1)),
f=assert(norm(v)>EPSILON)
)
v
],
crossnormal = closed ? crossnormal_mid : [crossnormal_mid[0], each crossnormal_mid, last(crossnormal_mid)]
)
[for(i=[0:L-(closed?0:1)]) let(
rotation = frame_map(x=crossnormal[i%L], z=tangents[i%L])
)
translate(path[i%L])*rotation*zrot(-twist*tpathfrac[i])
]
: method=="natural" ? // map x axis of shape to the path normal, which points in direction of curvature : method=="natural" ? // map x axis of shape to the path normal, which points in direction of curvature
let (pathnormal = path_normals(path, tangents, closed)) let (pathnormal = path_normals(path, tangents, closed))
assert(all_defined(pathnormal),"Natural normal vanishes on your curve, select a different method") assert(all_defined(pathnormal),"Natural normal vanishes on your curve, select a different method")

View file

@ -16,10 +16,10 @@
// Synopsis: Creates a V-groove slider. // Synopsis: Creates a V-groove slider.
// Topics: Parts, Sliders // Topics: Parts, Sliders
// See Also: rail() // See Also: rail()
// Description:
// Creates a slider to match a V-groove rail.
// Usage: // Usage:
// slider(l, w, h, [base=], [wall=], [ang=], [$slop=]) [ATTACHMENTS]; // slider(l, w, h, [base=], [wall=], [ang=], [$slop=]) [ATTACHMENTS];
// Description:
// Creates a slider to match a V-groove rail.
// Arguments: // Arguments:
// l = Length (long axis) of slider. // l = Length (long axis) of slider.
// w = Width of slider. // w = Width of slider.
@ -69,17 +69,17 @@ module slider(l=30, w=10, h=10, base=10, wall=5, ang=30, anchor=BOTTOM, spin=0,
// Synopsis: Creates a V-groove rail. // Synopsis: Creates a V-groove rail.
// Topics: Parts, Sliders // Topics: Parts, Sliders
// See Also: slider() // See Also: slider()
// Description:
// Creates a V-groove rail.
// Usage: // Usage:
// rail(l, w, h, [chamfer=], [ang=]) [ATTACHMENTS]; // rail(l, w, h, [chamfer=], [ang=]) [ATTACHMENTS];
// Description:
// Creates a V-groove rail.
// Arguments: // Arguments:
// l = Length (long axis) of slider. // l = Length (long axis) of slider.
// w = Width of slider. // w = Width of slider.
// h = Height of slider. // h = Height of slider.
// ---
// chamfer = Size of chamfer at end of rail. // chamfer = Size of chamfer at end of rail.
// ang = Overhang angle for slider, to facilitate supportless printig. // ang = Overhang angle for slider, to facilitate supportless printing.
// ---
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `BOTTOM` // anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `BOTTOM`
// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0` // spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP` // orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`

File diff suppressed because it is too large Load diff