mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2024-12-29 00:09:41 +00:00
misc doc fixes, adjust scale to allow independent x and y scales
This commit is contained in:
parent
48292d9e8f
commit
30a7e40cf9
3 changed files with 48 additions and 19 deletions
|
@ -97,7 +97,8 @@ include <screw_drive.scad>
|
|||
// from the screw size, but by passing the `drive_size=` argument you can override the default, or
|
||||
// in cases where no default exists you can specify it. Flat head screws have variations such as 100 degree
|
||||
// angle for UTS, or undercut heads. You can also request a "sharp" screw which will set the screw diameter
|
||||
// the theoretical maximum and produce sharp corners instead of a flat edge on the head. The flat head options
|
||||
// the theoretical maximum and produce sharp corners instead of a flat edge on the head. For a flat head screw
|
||||
// the drive specification must start with "flat", but the flat head options
|
||||
// can be mixed in any order, for example, "flat sharp undercut" or "flat undercut sharp".
|
||||
// Subsection: Nuts
|
||||
// Nuts come in standard sizes and BOSL2 has tables to produce sizes for both Imperial and metric nuts.
|
||||
|
@ -2512,7 +2513,7 @@ function _screw_info_metric(diam, pitch, head, thread, drive) =
|
|||
[20, [10, undef, undef]],
|
||||
],
|
||||
entry = struct_val(metric_setscrew, diam),
|
||||
dummy=assert(is_def(entry), str("Screw size M",diam," unsupported for headless screws")),
|
||||
dummy=assert(drive=="none" || is_undef(drive) || is_def(entry), str("Screw size M",diam," unsupported for headless screws")),
|
||||
drive_dim = drive=="hex" ? [["drive_size", entry[0]], ["drive_depth", diam/2]]
|
||||
: drive=="torx" ? [["drive_size", entry[1]], ["drive_depth", entry[2]]]
|
||||
: drive=="slot" ? [["drive_size", entry[3]], ["drive_depth", entry[4]]]
|
||||
|
|
57
skin.scad
57
skin.scad
|
@ -1104,9 +1104,9 @@ module spiral_sweep(poly, h, r, turns=1, higbee, center, r1, r2, d, d1, d2, higb
|
|||
|
||||
// Function&Module: path_sweep()
|
||||
// Usage: As module
|
||||
// path_sweep(shape, path, [method], [normal=], [closed=], [twist=], [twist_by_length=], [symmetry=], [last_normal=], [tangent=], [uniform=], [relaxed=], [caps=], [style=], [convexity=], [anchor=], [cp=], [spin=], [orient=], [atype=]) [ATTACHMENTS];
|
||||
// path_sweep(shape, path, [method], [normal=], [closed=], [twist=], [twist_by_length=], [symmetry=], [scale=], [scale_by_length=], [last_normal=], [tangent=], [uniform=], [relaxed=], [caps=], [style=], [convexity=], [anchor=], [cp=], [spin=], [orient=], [atype=]) [ATTACHMENTS];
|
||||
// Usage: As function
|
||||
// vnf = path_sweep(shape, path, [method], [normal=], [closed=], [twist=], [twist_by_length=], [symmetry=], [last_normal=], [tangent=], [uniform=], [relaxed=], [caps=], [style=], [transforms=], [anchor=], [cp=], [spin=], [orient=], [atype=]);
|
||||
// vnf = path_sweep(shape, path, [method], [normal=], [closed=], [twist=], [twist_by_length=], [symmetry=], [scale=], [scale_by_length=], [last_normal=], [tangent=], [uniform=], [relaxed=], [caps=], [style=], [transforms=], [anchor=], [cp=], [spin=], [orient=], [atype=]);
|
||||
// Description:
|
||||
// Takes as input `shape`, a 2D polygon path (list of points), and `path`, a 2d or 3d path (also a list of points)
|
||||
// and constructs a polyhedron by sweeping the shape along the path. When run as a module returns the polyhedron geometry.
|
||||
|
@ -1223,6 +1223,11 @@ module spiral_sweep(poly, h, r, turns=1, higbee, center, r1, r2, d, d1, d2, higb
|
|||
// the cross section orientation. Specifying a list of normal vectors gives you complete control over the orientation of your
|
||||
// cross sections and can be useful if you want to position your model to be on the surface of some solid.
|
||||
// .
|
||||
// You can also apply scaling to the profile along the path. You can give a list of scalar scale factors or a list of 2-vector scale.
|
||||
// In the latter scale the x and y scales of the profile are scaled separately before the profile is placed onto the path. For non-closed
|
||||
// paths you can also give a single scale value or a 2-vector which is treated as the final scale. The intermediate sections
|
||||
// are then scaled by linear interpolation either relative to length (if scale_by_length is true) or by point count otherwise.
|
||||
// .
|
||||
// You can use set `transforms` to true to return a list of transformation matrices instead of the swept shape. In this case, you can
|
||||
// often omit shape entirely. The exception is when `closed=true` and you are using the "incremental" method. In this case, `path_sweep`
|
||||
// uses the shape to correct for twist when the shape closes on itself, so you must include a valid shape.
|
||||
|
@ -1234,8 +1239,10 @@ module spiral_sweep(poly, h, r, turns=1, higbee, center, r1, r2, d, d1, d2, higb
|
|||
// normal = normal vector for initializing the incremental method, or for setting normals with method="manual". Default: UP if the path makes an angle lower than 45 degrees to the xy plane, BACK otherwise.
|
||||
// closed = path is a closed loop. Default: false
|
||||
// twist = amount of twist to add in degrees. For closed sweeps must be a multiple of 360/symmetry. Default: 0
|
||||
// scale = Amount to scale the profiles. If you give a scalar the scale starts at 1 and ends at your specified value. You can also give a vector of values, one for each path point. Default: 1 (no scaling)
|
||||
// twist_by_length = if true then interpolate twist based on the path length of the path. If false interoplate based on point count. Default: true
|
||||
// symmetry = symmetry of the shape when closed=true. Allows the shape to join with a 360/symmetry rotation instead of a full 360 rotation. Default: 1
|
||||
// scale = Amount to scale the profiles. If you give a scalar the scale starts at 1 and ends at your specified value. The same is true for a 2-vector, but x and y are scaled separately. You can also give a vector of values, one for each path point, and you can give a list of 2-vectors that give the x and y scales of your profile for every point on the path (a Nx2 matrix for a path of length N. Default: 1 (no scaling)
|
||||
// scale_by_length = if true then interpolate scale based on the path length of the path. If false interoplate based on point count. Default: true
|
||||
// last_normal = normal to last point in the path for the "incremental" method. Constrains the orientation of the last cross section if you supply it.
|
||||
// uniform = if set to false then compute tangents using the uniform=false argument, which may give better results when your path is non-uniformly sampled. This argument is passed to {{path_tangents()}}. Default: true
|
||||
// tangent = a list of tangent vectors in case you need more accuracy (particularly at the end points of your curve)
|
||||
|
@ -1492,6 +1499,18 @@ module spiral_sweep(poly, h, r, turns=1, higbee, center, r1, r2, d, d1, d2, higb
|
|||
// outside = [for(i=[0:len(trans)-1]) trans[i]*scale(lerp(1,1.5,i/(len(trans)-1)))];
|
||||
// inside = [for(i=[len(trans)-1:-1:0]) trans[i]*scale(lerp(1.1,1.4,i/(len(trans)-1)))];
|
||||
// sweep(shape, concat(outside,inside),closed=true);
|
||||
// Example(NoScales): An easier way to scale your model is to use the scale parameter.
|
||||
// elliptic_arc = xscale(2, p=arc($fn=64,angle=[0,180], r=3));
|
||||
// path_sweep(pentagon(r=1), path3d(elliptic_arc), scale=2);
|
||||
// Example(NoScales): Scaling only in the y direction of the profile (z direction in the model in this case)
|
||||
// elliptic_arc = xscale(2, p=arc($fn=64,angle=[0,180], r=3));
|
||||
// path_sweep(rect(2), path3d(elliptic_arc), scale=[1,2]);
|
||||
// Example(NoScales): Specifying scale at every point for a closed path
|
||||
// N=64;
|
||||
// path = circle(r=5, $fn=64);
|
||||
// theta = lerpn(0,360,N,endpoint=false);
|
||||
// scale = [for(t=theta) sin(6*t)/5+1];
|
||||
// path_sweep(rect(2), path3d(path), closed=true, scale=scale);
|
||||
// Example(Med,NoScales): Using path_sweep on a region
|
||||
// rgn1 = [for (d=[10:10:60]) circle(d=d,$fn=8)];
|
||||
// rgn2 = [square(30,center=false)];
|
||||
|
@ -1518,17 +1537,17 @@ module spiral_sweep(poly, h, r, turns=1, higbee, center, r1, r2, d, d1, d2, higb
|
|||
// method="manual", normal=UP);
|
||||
// }
|
||||
|
||||
module path_sweep(shape, path, method="incremental", normal, closed, twist=0, twist_by_length=true, scale=1,
|
||||
module path_sweep(shape, path, method="incremental", normal, closed, twist=0, twist_by_length=true, scale=1, scale_by_length=true,
|
||||
symmetry=1, last_normal, tangent, uniform=true, relaxed=false, caps, style="min_edge", convexity=10,
|
||||
anchor="origin",cp="centroid",spin=0, orient=UP, atype="hull",profiles=false,width=1)
|
||||
{
|
||||
dummy = assert(is_region(shape) || is_path(shape,2), "shape must be a 2D path or region");
|
||||
vnf = path_sweep(shape, path, method, normal, closed, twist, twist_by_length, scale,
|
||||
vnf = path_sweep(shape, path, method, normal, closed, twist, twist_by_length, scale, scale_by_length,
|
||||
symmetry, last_normal, tangent, uniform, relaxed, caps, style);
|
||||
|
||||
if (profiles){
|
||||
assert(in_list(atype, _ANCHOR_TYPES), "Anchor type must be \"hull\" or \"intersect\"");
|
||||
tran = path_sweep(shape, path, method, normal, closed, twist, twist_by_length, scale,
|
||||
tran = path_sweep(shape, path, method, normal, closed, twist, twist_by_length, scale, scale_by_length,
|
||||
symmetry, last_normal, tangent, uniform, relaxed,transforms=true);
|
||||
rshape = is_path(shape) ? [path3d(shape)]
|
||||
: [for(s=shape) path3d(s)];
|
||||
|
@ -1543,11 +1562,11 @@ module path_sweep(shape, path, method="incremental", normal, closed, twist=0, tw
|
|||
}
|
||||
|
||||
|
||||
function path_sweep(shape, path, method="incremental", normal, closed, twist=0, twist_by_length=true, scale=1,
|
||||
function path_sweep(shape, path, method="incremental", normal, closed, twist=0, twist_by_length=true, scale=1, scale_by_length=true,
|
||||
symmetry=1, last_normal, tangent, uniform=true, relaxed=false, caps, style="min_edge", transforms=false,
|
||||
anchor="origin",cp="centroid",spin=0, orient=UP, atype="hull") =
|
||||
is_1region(path) ? path_sweep(shape=shape,path=path[0], method=method, normal=normal, closed=default(closed,true),
|
||||
twist=twist, scale=scale, twist_by_length=twist_by_length, symmetry=symmetry, last_normal=last_normal,
|
||||
twist=twist, scale=scale, scale_by_length=scale_by_length, twist_by_length=twist_by_length, symmetry=symmetry, last_normal=last_normal,
|
||||
tangent=tangent, uniform=uniform, relaxed=relaxed, caps=caps, style=style, transforms=transforms,
|
||||
anchor=anchor, cp=cp, spin=spin, orient=orient, atype=atype) :
|
||||
let(closed=default(closed,false))
|
||||
|
@ -1561,12 +1580,15 @@ function path_sweep(shape, path, method="incremental", normal, closed, twist=0,
|
|||
assert((is_region(shape) || is_path(shape,2)) || (transforms && !(closed && method=="incremental")),"shape must be a 2d path or region")
|
||||
let(
|
||||
path = path3d(path),
|
||||
f=echo(caps=caps),
|
||||
caps = is_def(caps) ? caps :
|
||||
closed ? false : true,
|
||||
capsOK = is_bool(caps) || is_bool_list(caps,2),
|
||||
fullcaps = is_bool(caps) ? [caps,caps] : caps,
|
||||
normalOK = is_undef(normal) || (method!="natural" && is_vector(normal,3))
|
||||
|| (method=="manual" && same_shape(normal,path))
|
||||
|| (method=="manual" && same_shape(normal,path)),
|
||||
scaleOK = scale==1 || ((is_num(scale) || is_vector(scale,2)) && !closed) || is_vector(scale,len(path)) || is_matrix(scale,len(path),2)
|
||||
|
||||
)
|
||||
assert(normalOK, method=="natural" ? "Cannot specify normal with the \"natural\" method"
|
||||
: method=="incremental" ? "Normal with \"incremental\" method must be a 3-vector"
|
||||
|
@ -1575,16 +1597,21 @@ function path_sweep(shape, path, method="incremental", normal, closed, twist=0,
|
|||
assert(!closed || !caps, "Cannot make closed shape with caps")
|
||||
assert(is_undef(normal) || (is_vector(normal) && len(normal)==3) || (is_path(normal) && len(normal)==len(path) && len(normal[0])==3), "Invalid normal specified")
|
||||
assert(is_undef(tangent) || (is_path(tangent) && len(tangent)==len(path) && len(tangent[0])==3), "Invalid tangent specified")
|
||||
assert(is_num(scale) || is_vector(scale,len(path)), str("Incompatible or invalid scale: must be a scalar or vector of length ",len(path)))
|
||||
assert(scaleOK,str("Incompatible or invalid scale",closed?" for closed path":"",": must be ", closed?"":"a scalar, a 2-vector, ",
|
||||
"a vector of length ",len(path)," or a ",len(path),"x2 matrix of scales"))
|
||||
let(
|
||||
scale = is_num(scale) ? lerpn(1,scale,len(path)) : scale,
|
||||
scale = !(is_num(scale) || is_vector(scale,2)) ? scale
|
||||
: let(s=is_num(scale) ? [scale,scale] : scale)
|
||||
!scale_by_length ? lerpn([1,1],s,len(path))
|
||||
: lerp([1,1],s, path_length_fractions(path,false)),
|
||||
scale_list = [for(s=scale) scale(s),if (closed) scale(scale[0])],
|
||||
tangents = is_undef(tangent) ? path_tangents(path,uniform=uniform,closed=closed) : [for(t=tangent) unit(t)],
|
||||
normal = is_path(normal) ? [for(n=normal) unit(n)] :
|
||||
is_def(normal) ? unit(normal) :
|
||||
method =="incremental" && abs(tangents[0].z) > 1/sqrt(2) ? BACK : UP,
|
||||
normals = is_path(normal) ? normal : repeat(normal,len(path)),
|
||||
pathfrac = twist_by_length ? path_length_fractions(path, closed) : [for(i=[0:1:len(path)]) i / (len(path)-(closed?0:1))],
|
||||
tpathfrac = twist_by_length ? path_length_fractions(path, closed) : [for(i=[0:1:len(path)]) i / (len(path)-(closed?0:1))],
|
||||
spathfrac = scale_by_length ? path_length_fractions(path, closed) : [for(i=[0:1:len(path)]) i / (len(path)-(closed?0:1))],
|
||||
L = len(path),
|
||||
unscaled_transform_list =
|
||||
method=="incremental" ?
|
||||
|
@ -1618,7 +1645,7 @@ function path_sweep(shape, path, method="incremental", normal, closed, twist=0,
|
|||
twistfix = correction_twist%(360/symmetry),
|
||||
adjusted_final = !closed ? undef :
|
||||
translate(path[0]) * rotations[0] * zrot(-correction_twist+correction_twist%(360/symmetry)-twist)
|
||||
) [for(i=idx(path)) translate(path[i]) * rotations[i] * zrot((twistfix-twist)*pathfrac[i]), if(closed) adjusted_final]
|
||||
) [for(i=idx(path)) translate(path[i]) * rotations[i] * zrot((twistfix-twist)*tpathfrac[i]), if(closed) adjusted_final]
|
||||
: method=="manual" ?
|
||||
[for(i=[0:L-(closed?0:1)]) let(
|
||||
ynormal = relaxed ? normals[i%L] : normals[i%L] - (normals[i%L] * tangents[i%L])*tangents[i%L],
|
||||
|
@ -1626,7 +1653,7 @@ function path_sweep(shape, path, method="incremental", normal, closed, twist=0,
|
|||
rotation = frame_map(y=ynormal, z=znormal)
|
||||
)
|
||||
assert(approx(ynormal*znormal,0),str("Supplied normal is parallel to the path tangent at point ",i))
|
||||
translate(path[i%L])*rotation*zrot(-twist*pathfrac[i])
|
||||
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
|
||||
let (pathnormal = path_normals(path, tangents, closed))
|
||||
|
@ -1638,7 +1665,7 @@ function path_sweep(shape, path, method="incremental", normal, closed, twist=0,
|
|||
[for(i=[0:L-(closed?0:1)]) let(
|
||||
rotation = frame_map(x=pathnormal[i%L], z=tangents[i%L])
|
||||
)
|
||||
translate(path[i%L])*rotation*zrot(-twist*pathfrac[i])
|
||||
translate(path[i%L])*rotation*zrot(-twist*tpathfrac[i])
|
||||
]
|
||||
: assert(false,"Unknown method or no method given"), // unknown method
|
||||
transform_list = v_mul(unscaled_transform_list, scale_list),
|
||||
|
|
|
@ -1381,7 +1381,8 @@ module generic_threaded_nut(
|
|||
// .
|
||||
// Unlike generic_threaded_rod, when internal=true this module generates the threads, not a thread mask.
|
||||
// The profile needs to be inverted to produce the proper thread form. If you use the built-in trapezoidal
|
||||
// thread you get the inverted thread, designed so that the inner diameter is d. With adequate clearance
|
||||
// thread you get the inverted thread, designed so that the inner diameter is d. If you supply a custom profile
|
||||
// you must invert it yourself to get internal threads. With adequate clearance
|
||||
// this thread will mate with the thread that uses the same parameters but has internal=false. Note that
|
||||
// unlike the threaded_rod modules, thread_helix does not adjust the diameter for faceting, nor does it
|
||||
// subtract any $slop for clearance.
|
||||
|
@ -1398,7 +1399,7 @@ module generic_threaded_nut(
|
|||
// profile = If an asymmetrical thread profile is needed, it can be specified here.
|
||||
// starts = The number of thread starts. Default: 1
|
||||
// left_handed = If true, thread has a left-handed winding.
|
||||
// internal = If true, invert threads for internal threading.
|
||||
// internal = If true, apply tapers for internal threading, and invert the default profile. Default: false
|
||||
// d1 = Bottom inside base diameter of threads.
|
||||
// d2 = Top inside base diameter of threads.
|
||||
// higbee = Length to taper thread ends over. Default: 0
|
||||
|
|
Loading…
Reference in a new issue