From 66f0d260c2b1bc4731bf59ddd334982db4419056 Mon Sep 17 00:00:00 2001 From: Adrian Mariano Date: Sat, 6 Jan 2024 22:07:45 -0500 Subject: [PATCH 01/13] inset->border in texture(), tex_style->style in cyl() --- shapes3d.scad | 27 ++++---- skin.scad | 182 ++++++++++++++++++++++++++------------------------ 2 files changed, 109 insertions(+), 100 deletions(-) diff --git a/shapes3d.scad b/shapes3d.scad index d0986b4..56c3354 100644 --- a/shapes3d.scad +++ b/shapes3d.scad @@ -1292,9 +1292,9 @@ function cylinder(h, r1, r2, center, r, d, d1, d2, anchor, spin=0, orient=UP) = // cyl(l|h|length|height, r|d, rounding1=, rounding2=, ...); // // Usage: Textured Cylinders -// cyl(l|h|length|height, r|d, texture=, [tex_size=]|[tex_counts=], [tex_scale=], [tex_rot=], [tex_samples=], [tex_style=], [tex_taper=], [tex_inset=], ...); -// cyl(l|h|length|height, r1=, r2=, texture=, [tex_size=]|[tex_counts=], [tex_scale=], [tex_rot=], [tex_samples=], [tex_style=], [tex_taper=], [tex_inset=], ...); -// cyl(l|h|length|height, d1=, d2=, texture=, [tex_size=]|[tex_counts=], [tex_scale=], [tex_rot=], [tex_samples=], [tex_style=], [tex_taper=], [tex_inset=], ...); +// cyl(l|h|length|height, r|d, texture=, [tex_size=]|[tex_counts=], [tex_scale=], [tex_rot=], [tex_samples=], [style=], [tex_taper=], [tex_inset=], ...); +// cyl(l|h|length|height, r1=, r2=, texture=, [tex_size=]|[tex_counts=], [tex_scale=], [tex_rot=], [tex_samples=], [style=], [tex_taper=], [tex_inset=], ...); +// cyl(l|h|length|height, d1=, d2=, texture=, [tex_size=]|[tex_counts=], [tex_scale=], [tex_rot=], [tex_samples=], [style=], [tex_taper=], [tex_inset=], ...); // // Usage: Caled as a function to get a VNF // vnf = cyl(...); @@ -1368,8 +1368,8 @@ function cylinder(h, r1, r2, center, r, d, d1, d2, anchor, spin=0, orient=UP) = // tex_rot = If true, rotates the texture 90º. // tex_scale = Scaling multiplier for the texture depth. // tex_samples = Minimum number of "bend points" to have in VNF texture tiles. Default: 8 -// tex_style = {{vnf_vertex_array()}} style used to triangulate heightfield textures. Default: "min_edge" // tex_taper = If given as a number, tapers the texture height to zero over the first and last given percentage of the path. If given as a lookup table with indices between 0 and 100, uses the percentage lookup table to ramp the texture heights. Default: `undef` (no taper) +// style = {{vnf_vertex_array()}} style used to triangulate heightfield textures. Default: "min_edge" // 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` // orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP` @@ -1434,12 +1434,12 @@ function cylinder(h, r1, r2, center, r, d, d1, d2, anchor, spin=0, orient=UP) = // Example: Texturing with heightfield pyramids // cyl(h=40, r1=20, r2=15, // texture="pyramids", tex_size=[5,5], -// tex_style="convex"); +// style="convex"); // // Example: Texturing with heightfield truncated pyramids // cyl(h=40, r1=20, r2=15, chamfer=5, // texture="trunc_pyramids", -// tex_size=[5,5], tex_style="convex"); +// tex_size=[5,5], style="convex"); // // Example: Texturing with VNF tile "dots" // cyl(h=40, r1=20, r2=15, rounding=9, @@ -1449,7 +1449,7 @@ function cylinder(h, r1, r2, center, r, d, d1, d2, anchor, spin=0, orient=UP) = // Example: Texturing with VNF tile "bricks_vnf" // cyl(h=50, r1=25, r2=20, shift=[0,10], rounding1=-10, // texture="bricks_vnf", tex_size=[10,10], -// tex_scale=0.5, tex_style="concave"); +// tex_scale=0.5, style="concave"); // // Example: No Texture Taper // cyl(d1=25, d2=20, h=30, rounding=5, @@ -1488,7 +1488,7 @@ function cylinder(h, r1, r2, center, r, d, d1, d2, anchor, spin=0, orient=UP) = // diff() // cyl(d=20*10/PI, h=10, chamfer=0, // texture=tex, tex_counts=[20,1], tex_scale=-1, -// tex_taper=undef, tex_style="concave") { +// tex_taper=undef, style="concave") { // attach([TOP,BOT]) { // cyl(d1=20*10/PI, d2=30, h=5, anchor=BOT) // attach(TOP) { @@ -1511,10 +1511,13 @@ function cyl( texture, tex_size=[5,5], tex_counts, tex_inset=false, tex_rot=false, tex_scale=1, tex_samples, length, height, - tex_taper, tex_style="min_edge", + tex_taper, style="min_edge", tex_style, anchor, spin=0, orient=UP ) = + assert(num_defined([style,tex_style])<2, "In cyl() the 'tex_style' parameters has been replaced by 'style'. You cannot give both.") let( + style = is_def(tex_style)? echo("In cyl the 'tex_style()' parameters is deprecated and has been replaced by 'style'")tex_style + : style, l = one_defined([l, h, length, height],"l,h,length,height",dflt=1), _r1 = get_radius(r1=r1, r=r, d1=d1, d=d, dflt=1), _r2 = get_radius(r1=r2, r=r, d1=d2, d=d, dflt=1), @@ -1620,7 +1623,7 @@ function cyl( texture=texture, tex_counts=tex_counts, tex_size=tex_size, tex_inset=tex_inset, tex_rot=tex_rot, tex_scale=tex_scale, tex_samples=tex_samples, - tex_taper=tex_taper, style=tex_style, closed=false + tex_taper=tex_taper, style=style, closed=false ), skmat = down(l/2) * skew(sxz=shift.x/l, syz=shift.y/l) * @@ -1663,7 +1666,7 @@ module cyl( texture, tex_size=[5,5], tex_counts, tex_inset=false, tex_rot=false, tex_scale=1, tex_samples, length, height, - tex_taper, tex_style="min_edge", + tex_taper, style="min_edge", tex_style, anchor, spin=0, orient=UP ) { l = one_defined([l, h, length, height],"l,h,length,height",dflt=1); @@ -1692,7 +1695,7 @@ module cyl( texture=texture, tex_size=tex_size, tex_counts=tex_counts, tex_scale=tex_scale, tex_inset=tex_inset, tex_rot=tex_rot, - tex_style=tex_style, tex_taper=tex_taper, + style=style, tex_style=tex_style, tex_taper=tex_taper, tex_samples=tex_samples ); vnf_polyhedron(vnf, convexity=texture!=undef? 2 : 10); diff --git a/skin.scad b/skin.scad index f44007b..9d4efba 100644 --- a/skin.scad +++ b/skin.scad @@ -2824,8 +2824,8 @@ function associate_vertices(polygons, split, curpoly=0) = // tex = The name of the texture to get. // --- // n = The general number of vertices to use to refine the resolution of the texture. -// inset = The amount to inset part of a VNF tile texture. Generally between 0 and 0.5. -// gap = The gap between logically distinct parts of a VNF tile. (ie: gap between bricks, gap between truncated ribs, etc.) +// border = The size of a border region on some VNF tile textures. Generally between 0 and 0.5. +// gap = The gap between logically distinct parts of some VNF tiles. (ie: gap between bricks, gap between truncated ribs, etc.) // roughness = The amount of roughness used on the surface of some heightfield textures. Generally between 0 and 0.5. // Example(3D): **"bricks"** (Heightfield) = A brick-wall pattern. Giving `n=` sets the number of heightfield samples to `n x n`. Default: 24. Giving `roughness=` adds a level of height randomization to add roughness to the texture. Default: 0.05. Use `style="convex"`. // tex = texture("bricks"); @@ -2833,31 +2833,31 @@ function associate_vertices(polygons, split, curpoly=0) = // rect(30), texture=tex, h=30, // tex_size=[10,10] // ); -// Example(3D): **"bricks_vnf"** (VNF) = VNF version of "bricks". Giving `gap=` sets the "mortar" gap between adjacent bricks, default 0.05. Giving `inset=` specifies that the top face of the brick is smaller than the bottom of the brick by `inset` on each of the four sides. If `gap` is zero then an `inset` value close to 0.5 will cause bricks to come to a sharp pointed edge, with just a tiny flat top surface. Note that `gap+inset` must be strictly smaller than 0.5. Default is `inset=0.05`. +// Example(3D): **"bricks_vnf"** (VNF) = VNF version of "bricks". Giving `gap=` sets the "mortar" gap between adjacent bricks, default 0.05. Giving `border=` specifies that the top face of the brick is smaller than the bottom of the brick by `border` on each of the four sides. If `gap` is zero then a `border` value close to 0.5 will cause bricks to come to a sharp pointed edge, with just a tiny flat top surface. Note that `gap+border` must be strictly smaller than 0.5. Default is `border=0.05`. // tex = texture("bricks_vnf"); // linear_sweep( // rect(30), texture=tex, h=30, // tex_size=[10,10] // ); -// Example(3D): "bricks_vnf" texture with large inset. -// tex = texture("bricks_vnf",inset=0.25); +// Example(3D): "bricks_vnf" texture with large border. +// tex = texture("bricks_vnf",border=0.25); // linear_sweep( // rect(30), texture=tex, h=30, // tex_size=[10,10] // ); -// Example(3D,VPR=[84.4,0,4.7],VPT=[2.44496,6.53317,14.6135],VPD = 126): **"checkers"** (VNF) = A pattern of alternating checkerboard squares. Giving `inset=` specifies that the top face of the checker surface is smaller than the bottom by `inset` on each of the four sides. As `inset` approaches 0.5 the tops come to sharp corners. You must set `inset` strictly between 0 and 0.5. Default: 0.05. +// Example(3D,VPR=[84.4,0,4.7],VPT=[2.44496,6.53317,14.6135],VPD = 126): **"checkers"** (VNF) = A pattern of alternating checkerboard squares. Giving `border=` specifies that the top face of the checker surface is smaller than the bottom by `border` on each of the four sides. As `border` approaches 0.5 the tops come to sharp corners. You must set `border` strictly between 0 and 0.5. Default: 0.05. // tex = texture("checkers"); // linear_sweep( // rect(30), texture=tex, h=30, // tex_size=[10,10] // ); -// Example(3D,VPR=[84.4,0,4.7],VPT=[2.44496,6.53317,14.6135],VPD = 126): "checkers" texture with large inset. -// tex = texture("checkers",inset=0.25); +// Example(3D,VPR=[84.4,0,4.7],VPT=[2.44496,6.53317,14.6135],VPD = 126): "checkers" texture with large border. +// tex = texture("checkers",border=0.25); // linear_sweep( // rect(30), texture=tex, h=30, // tex_size=[10,10] // ); -// Example(3D): **"cones"** (VNF) = Raised conical spikes. Giving `n=` sets `$fn` for the cone (will be rounded to a multiple of 4). Default: 16. Giving `inset=` specifies the horizontal inset of the base of the cone, relative to the tile edges. The `inset` value must be nonnegative and smaller than 0.5. Default: 0. +// Example(3D): **"cones"** (VNF) = Raised conical spikes. Giving `n=` sets `$fn` for the cone (will be rounded to a multiple of 4). Default: 16. Giving `border=` specifies the horizontal border width between the edge of the tile and the base of the cone. The `border` value must be nonnegative and smaller than 0.5. Default: 0. // tex = texture("cones"); // linear_sweep( // rect(30), texture=tex, h=30, tex_scale=3, @@ -2899,32 +2899,32 @@ function associate_vertices(polygons, split, curpoly=0) = // rect(30), texture=tex, h=30, // tex_size=[10,10] // ); -// Example(3D): **"dimples"** (VNF) = Round divots. Giving `n=` sets `$fn` for the curve (will be rounded to a multiple of 4). Default: 16. Giving `inset=` specifies the horizontal distance of the flat region around the dimple relative to the edge of the tile. Must be nonnegative and strictly less than 0.5. Default: 0.05. +// Example(3D): **"dimples"** (VNF) = Round divots. Giving `n=` sets `$fn` for the curve (will be rounded to a multiple of 4). Default: 16. Giving `border=` specifies the horizontal width of the flat border region between the tile edges and the edge of the dimple. Must be nonnegative and strictly less than 0.5. Default: 0.05. // tex = texture("dimples"); // linear_sweep( // rect(30), texture=tex, h=30, // tex_size=[10,10] // ); -// Example(3D): **"dots"** (VNF) = Raised round bumps. Giving `n=` sets `$fn` for the curve (will be rounded to a multiple of 4). Default: 16. Giving `inset=` specifies the horizontal inset of the dots, relative to the edge of the tile. Must be nonnegative and strictly less than 0.5. Default: 0.05. +// Example(3D): **"dots"** (VNF) = Raised round bumps. Giving `n=` sets `$fn` for the curve (will be rounded to a multiple of 4). Default: 16. Giving `border=` specifies the horizontal width of the flat border region between the tile edge and the edge of the dots. Must be nonnegative and strictly less than 0.5. Default: 0.05. // tex = texture("dots"); // linear_sweep( // rect(30), texture=tex, h=30, // tex_size=[10,10] // ); -// Example(3D): **"hex_grid"** (VNF) = A hexagonal grid defined by V-grove borders. Giving `inset=` specifies the horizontal inset of the left and right edges of the hexagonal tops, relative to their bottoms. This means the V-groove top width for grooves running parallel to the Y axis will be double the inset value. If the texture is scaled in the Y direction by sqrt(3) then the groove will be uniform on all six sides of the hexagon. Inset must be strictly between 0 and 0.5, default: 0.1. +// Example(3D): **"hex_grid"** (VNF) = A hexagonal grid defined by V-grove borders. Giving `border=` specifies that the top face of the hexagon is smaller than the bottom by `border` on the left and right sides. This means the V-groove top width for grooves running parallel to the Y axis will be double the border value. If the texture is scaled in the Y direction by sqrt(3) then the groove will be uniform on all six sides of the hexagon. Border must be strictly between 0 and 0.5, default: 0.1. // tex = texture("hex_grid"); // linear_sweep( // rect(30), texture=tex, h=30, // tex_size=[10,10] // ); -// Example(3D): "hex_grid" texture with large inset -// tex = texture("hex_grid", inset=0.4); +// Example(3D): "hex_grid" texture with large border +// tex = texture("hex_grid", border=0.4); // linear_sweep( // rect(30), texture=tex, h=30, // tex_size=[10,10] // ); // Example(3D): "hex_grid" scaled in Y by sqrt(3) so hexagons are regular and grooves are all the same width. Note height of cube is also scaled so tile fits without being automatically adjusted to fit, ruining our choice of scale. -// tex = texture("hex_grid",inset=.07); +// tex = texture("hex_grid",border=.07); // linear_sweep( // rect(30), texture=tex, h=quantup(30,10*sqrt(3)), // tex_size=[10,10*sqrt(3)], tex_scale=3 @@ -2971,20 +2971,20 @@ function associate_vertices(polygons, split, curpoly=0) = // rect(30), texture=tex, h=30, // tex_size=[10,10], style="min_edge" // ); -// Example(3D): **"tri_grid"** (VNF) = A triangular grid defined by V-groove borders Giving `inset=` specifies the horizontal inset of the triangular tops, relative to their bottoms, along the horizontal edges (parallel to the X axis) of the triangles. This means the V-groove top width of the grooves parallel to the X axis will be double the inset value. (The other grooves are wider.) If the tile is scaled in the Y direction by sqrt(3) then the groove will be uniform on the three sides of the triangle. The inset must be strictly between 0 and 1/6, default: 0.05. +// Example(3D): **"tri_grid"** (VNF) = A triangular grid defined by V-groove borders Giving `border=` specifies that the top face of the triangular surface is smaller than the bottom by `border` along the horizontal edges (parallel to the X axis). This means the V-groove top width of the grooves parallel to the X axis will be double the border value. (The other grooves are wider.) If the tile is scaled in the Y direction by sqrt(3) then the groove will be uniform on the three sides of the triangle. The border must be strictly between 0 and 1/6, default: 0.05. // tex = texture("tri_grid"); // linear_sweep( // rect(30), texture=tex, h=30, // tex_size=[10,10] // ); -// Example(3D): "tri_grid" texture with large inset. (Max inset for tri_grid is 1/6.) -// tex = texture("tri_grid",inset=.12); +// Example(3D): "tri_grid" texture with large border. (Max border for tri_grid is 1/6.) +// tex = texture("tri_grid",border=.12); // linear_sweep( // rect(30), texture=tex, h=30, // tex_size=[10,10] // ); // Example(3D): "tri_grid" texture scaled in Y by sqrt(3) so triangles are equilateral and grooves are all the same width. Note we have to ensure the height evenly fits the scaled texture tiles. -// tex = texture("tri_grid",inset=.04); +// tex = texture("tri_grid",border=.04); // linear_sweep( // rect(30), texture=tex, h=quantup(30,10*sqrt(3)), // tex_size=[10,10*sqrt(3)], tex_scale=3 @@ -2995,14 +2995,14 @@ function associate_vertices(polygons, split, curpoly=0) = // rect(30), texture=tex, h=34, // tex_size=[10,17] // ); -// Example(3D): **"trunc_diamonds"** (VNF) = Truncated diamonds, four-sided pyramids with the base corners aligned with the axes and the top cut off. Or you can interpret it as V-groove lines at 45º angles. Giving `inset=` specifies the horizontal inset of the square top face compared to the bottom face along all four edges. This means the V-groove top width will be double the inset value. The inset must be strictly between 0 and sqrt(2)/4, which is about 0.35. Default: 0.1. +// Example(3D): **"trunc_diamonds"** (VNF) = Truncated diamonds, four-sided pyramids with the base corners aligned with the axes and the top cut off. Or you can interpret it as V-groove lines at 45º angles. Giving `border=` specifies that the width and height of the top surface of the diamond are smaller by `border` at the left, right, top and bottom. The border is measured in the **horizontal** direction. This means the V-groove width will be sqrt(2) times the border value. The border must be strictly between 0 and sqrt(2)/4, which is about 0.35. Default: 0.1. // tex = texture("trunc_diamonds"); // linear_sweep( // rect(30), texture=tex, h=30, // tex_size=[10,10] // ); -// Example(3D): "trunc_diamonds" texture with large inset. -// tex = texture("trunc_diamonds",inset=.25); +// Example(3D): "trunc_diamonds" texture with large border. +// tex = texture("trunc_diamonds",border=.25); // linear_sweep( // rect(30), texture=tex, h=30, // tex_size=[10,10] @@ -3013,14 +3013,14 @@ function associate_vertices(polygons, split, curpoly=0) = // rect(30), texture=tex, h=30, // tex_size=[10,10], style="convex" // ); -// Example(3D): **"trunc_pyramids_vnf"** (VNF) = Truncated pyramids, four sided pyramids with the base edges aligned to the axes and the top cut off. You can also regard this as a grid of V-grooves. Giving `inset=` specifies the horizontal inset of the flat square tops on all four sides relative to their bottoms. This means the V-groove top width will be double the inset value. The inset must be strictly between 0 and 0.5. Default: 0.1. +// Example(3D): **"trunc_pyramids_vnf"** (VNF) = Truncated pyramids, four sided pyramids with the base edges aligned to the axes and the top cut off. You can also regard this as a grid of V-grooves. Giving `border=` specifies that the top face is smaller than the top by `border` on all four sides. This means the V-groove top width will be double the border value. The border must be strictly between 0 and 0.5. Default: 0.1. // tex = texture("trunc_pyramids_vnf"); // linear_sweep( // rect(30), texture=tex, h=30, // tex_size=[10,10] // ); -// Example(3D): "trunc_pyramids_vnf" texture with large inset -// tex = texture("trunc_pyramids_vnf", inset=.4); +// Example(3D): "trunc_pyramids_vnf" texture with large border +// tex = texture("trunc_pyramids_vnf", border=.4); // linear_sweep( // rect(30), texture=tex, h=30, // tex_size=[10,10] @@ -3032,8 +3032,8 @@ function associate_vertices(polygons, split, curpoly=0) = // tex_scale=3, tex_size=[10,10], // style="concave" // ); -// Example(3D): **"trunc_ribs_vnf"** (VNF) = Vertically aligned triangular ribs with the tops cut off. Giving `gap=` sets the bottom gap between ribs. Giving `inset=` specifies the horizontal inset of the rib top face, relative to the bottom on both sides. In order to fit, gap+2*inset must be less than 1. (This is because the gap is counted once but the inset counts on both sides.) Defaults: gap=1/4, inset=1/4. -// tex = texture("trunc_ribs_vnf", gap=0.25, inset=1/6); +// Example(3D): **"trunc_ribs_vnf"** (VNF) = Vertically aligned triangular ribs with the tops cut off. Giving `gap=` sets the bottom gap between ribs. Giving `border=` specifies that the top rib face is smaller than its base by `border` on both the left and right sides. The gap measures the flat part between ribs and the border the width of the sloping portion. In order to fit, gap+2*border must be less than 1. (This is because the gap is counted once but the border counts on both sides.) Defaults: gap=1/4, border=1/4. +// tex = texture("trunc_ribs_vnf", gap=0.25, border=1/6); // linear_sweep( // rect(30), h=30, texture=tex, // tex_scale=3, tex_size=[10,10] @@ -3045,13 +3045,19 @@ function associate_vertices(polygons, split, curpoly=0) = // tex_size=[10,10], tex_scale=3, style="concave" // ); -function texture(tex, n, inset, gap, roughness) = +function texture(tex, n, border, gap, roughness, inset) = + assert(num_defined([border,inset])<2, "In texture() the 'inset' parameter has been replaced by 'border'. You cannot give both parameters.") + let( + border = is_def(inset)?echo("In texture() the argument 'inset' has been deprecated and will be removed. Use 'border' instead") + inset + :border + ) assert(is_undef(n) || all_positive([n]), "n must be a positive value if given") - assert(is_undef(inset) || is_finite(inset), "inset must be a number if given") + assert(is_undef(border) || is_finite(border), "border must be a number if given") assert(is_undef(gap) || is_finite(gap), "gap must be a number if given") assert(is_undef(roughness) || all_nonnegative([roughness]), "roughness must be a nonnegative value if given") tex=="ribs"? - assert(num_defined([gap, inset, roughness])==0, "ribs texture does not accept gap, inset or roughness") + assert(num_defined([gap, border, roughness])==0, "ribs texture does not accept gap, border or roughness") let( n = quantup(default(n,2),2) @@ -3060,7 +3066,7 @@ function texture(tex, n, inset, gap, roughness) = each lerpn(0,1,n/2,endpoint=false), ]] : tex=="trunc_ribs"? - assert(num_defined([gap, inset, roughness])==0, "trunc_ribs texture does not accept gap, inset or roughness") + assert(num_defined([gap, border, roughness])==0, "trunc_ribs texture does not accept gap, border or roughness") let( n = quantup(default(n,4),4) ) [[ @@ -3072,25 +3078,25 @@ function texture(tex, n, inset, gap, roughness) = tex=="trunc_ribs_vnf"? assert(is_undef(n), "trunc_ribs_vnf texture does not accept n") let( - inset = default(inset,1/4)*2, + border = default(border,1/4)*2, gap = default(gap,1/4) ) - assert(all_nonnegative([inset,gap]), "trunc_ribs_vnf texture requires gap>=0 and inset>=0") - assert(gap+inset > 0, "trunc_ribs_vnf texture requires that gap+inset>0") - assert(gap+inset <= 1, "trunc_ribs_vnf texture requires that gap+2*inset<=1") + assert(all_nonnegative([border,gap]), "trunc_ribs_vnf texture requires gap>=0 and border>=0") + assert(gap+border > 0, "trunc_ribs_vnf texture requires that gap+border>0") + assert(gap+border <= 1, "trunc_ribs_vnf texture requires that gap+2*border<=1") [ [ each move([0.5,0.5], p=path3d(rect([1-gap,1]),0)), - each move([0.5,0.5], p=path3d(rect([1-gap-inset,1]),1)), + each move([0.5,0.5], p=path3d(rect([1-gap-border,1]),1)), each path3d(square(1)), ], [ [1,2,6], [1,6,5], [0,4,3], [3,4,7], - if (gap+inset < 1-EPSILON) each [[4,5,6], [4,6,7]], + if (gap+border < 1-EPSILON) each [[4,5,6], [4,6,7]], if (gap > EPSILON) each [[1,9,10], [1,10,2], [0,3,8], [3,11,8]], ] ] : tex=="wave_ribs"? - assert(num_defined([gap, inset, roughness])==0, "wave_ribs texture does not accept gap, inset or roughness") + assert(num_defined([gap, border, roughness])==0, "wave_ribs texture does not accept gap, border or roughness") let( n = max(6,default(n,8)) ) [[ @@ -3098,7 +3104,7 @@ function texture(tex, n, inset, gap, roughness) = (cos(a)+1)/2 ]] : tex=="diamonds"? - assert(num_defined([gap, inset, roughness])==0, "diamonds texture does not accept gap, inset or roughness") + assert(num_defined([gap, border, roughness])==0, "diamonds texture does not accept gap, border or roughness") let( n = quantup(default(n,2),2) ) [ @@ -3116,7 +3122,7 @@ function texture(tex, n, inset, gap, roughness) = ], ] : tex=="diamonds_vnf"? - assert(num_defined([n,gap, inset, roughness])==0, "diamonds_vnf texture does not accept n, gap, inset or roughness") + assert(num_defined([n,gap, border, roughness])==0, "diamonds_vnf texture does not accept n, gap, border or roughness") [ [ [0, 1, 1], [1/2, 1, 0], [1, 1, 1], @@ -3128,7 +3134,7 @@ function texture(tex, n, inset, gap, roughness) = ] ] : tex=="pyramids"? - assert(num_defined([gap, inset, roughness])==0, "pyramids texture does not accept gap, inset or roughness") + assert(num_defined([gap, border, roughness])==0, "pyramids texture does not accept gap, border or roughness") let( n = quantup(default(n,2),2) ) [ @@ -3138,13 +3144,13 @@ function texture(tex, n, inset, gap, roughness) = ] ] : tex=="pyramids_vnf"? - assert(num_defined([n,gap, inset, roughness])==0, "pyramids_Vnf texture does not accept n, gap, inset or roughness") + assert(num_defined([n,gap, border, roughness])==0, "pyramids_Vnf texture does not accept n, gap, border or roughness") [ [ [0,1,0], [1,1,0], [1/2,1/2,1], [0,0,0], [1,0,0] ], [ [2,0,1], [2,1,4], [2,4,3], [2,3,0] ] ] : tex=="trunc_pyramids"? - assert(num_defined([gap, inset, roughness])==0, "trunc_pyramids texture does not accept gap, inset or roughness") + assert(num_defined([gap, border, roughness])==0, "trunc_pyramids texture does not accept gap, border or roughness") let( n = quantup(default(n,6),3) ) [ @@ -3156,13 +3162,13 @@ function texture(tex, n, inset, gap, roughness) = tex=="trunc_pyramids_vnf"? assert(num_defined([gap, n, roughness])==0, "trunc_pyramids_vnf texture does not accept gap, n or roughness") let( - inset = default(inset,0.1) + border = default(border,0.1) ) - assert(inset>0 && inset<.5, "trunc_pyramids_vnf texture requires inset in (0,0.5)") + assert(border>0 && border<.5, "trunc_pyramids_vnf texture requires border in (0,0.5)") [ [ each path3d(square(1)), - each move([1/2,1/2,1], p=path3d(rect(1-2*inset))), + each move([1/2,1/2,1], p=path3d(rect(1-2*border))), ], [ for (i=[0:3]) each [ [i, (i+1)%4, i+4], @@ -3172,7 +3178,7 @@ function texture(tex, n, inset, gap, roughness) = ] ] : tex=="hills"? - assert(num_defined([gap, inset, roughness])==0, "hills texture does not accept gap, inset or roughness") + assert(num_defined([gap, border, roughness])==0, "hills texture does not accept gap, border or roughness") let( n = default(n,12) ) [ @@ -3182,7 +3188,7 @@ function texture(tex, n, inset, gap, roughness) = ] ] : tex=="bricks"? - assert(num_defined([gap,inset])==0, "bricks texture does not accept gap or inset") + assert(num_defined([gap,border])==0, "bricks texture does not accept gap or border") let( n = quantup(default(n,24),2), rough = default(roughness,0.05) @@ -3198,21 +3204,21 @@ function texture(tex, n, inset, gap, roughness) = tex=="bricks_vnf"? assert(num_defined([n,roughness])==0, "bricks_vnf texture does not accept n or roughness") let( - inset = default(inset,0.05), + border = default(border,0.05), gap = default(gap,0.05) ) - assert(inset>=0,"bricks_vnf texture requires nonnegative inset") + assert(border>=0,"bricks_vnf texture requires nonnegative border") assert(gap>0, "bricks_vnf requires gap greater than 0") - assert(gap+inset<0.5, "bricks_vnf requires gap+inset<0.5") + assert(gap+border<0.5, "bricks_vnf requires gap+border<0.5") [ [ each path3d(square(1)), each move([gap/2, gap/2, 0], p=path3d(square([1-gap, 0.5-gap]))), - each move([gap/2+inset/2, gap/2+inset/2, 1], p=path3d(square([1-gap-inset, 0.5-gap-inset]))), + each move([gap/2+border/2, gap/2+border/2, 1], p=path3d(square([1-gap-border, 0.5-gap-border]))), each move([0, 0.5+gap/2, 0], p=path3d(square([0.5-gap/2, 0.5-gap]))), - each move([0, 0.5+gap/2+inset/2, 1], p=path3d(square([0.5-gap/2-inset/2, 0.5-gap-inset]))), + each move([0, 0.5+gap/2+border/2, 1], p=path3d(square([0.5-gap/2-border/2, 0.5-gap-border]))), each move([0.5+gap/2, 0.5+gap/2, 0], p=path3d(square([0.5-gap/2, 0.5-gap]))), - each move([0.5+gap/2+inset/2, 0.5+gap/2+inset/2, 1], p=path3d(square([0.5-gap/2-inset/2, 0.5-gap-inset]))), + each move([0.5+gap/2+border/2, 0.5+gap/2+border/2, 1], p=path3d(square([0.5-gap/2-border/2, 0.5-gap-border]))), ], [ [ 8, 9,10], [ 8,10,11], [16,17,18], [16,18,19], [24,25,26], [24,26,27], [ 0, 1, 5], [ 0, 5, 4], [ 1,13, 6], [ 1, 6, 5], @@ -3228,19 +3234,19 @@ function texture(tex, n, inset, gap, roughness) = tex=="checkers"? assert(num_defined([gap, n, roughness])==0, "checkers texture does not accept gap, n or roughness") let( - inset = default(inset,0.05) + border = default(border,0.05) ) - assert(inset>0 && inset<.5, "checkers texture requires inset in (0,0.5)") + assert(border>0 && border<.5, "checkers texture requires border in (0,0.5)") [ [ - each move([0,0], p=path3d(square(0.5-inset),1)), - each move([0,0.5], p=path3d(square(0.5-inset))), - each move([0.5,0], p=path3d(square(0.5-inset))), - each move([0.5,0.5], p=path3d(square(0.5-inset),1)), - [1/2-inset/2,1/2-inset/2,1/2], [0,1,1], [1/2-inset,1,1], - [1/2,1,0], [1-inset,1,0], [1,0,1], [1,1/2-inset,1], - [1,1/2,0], [1,1-inset,0], [1,1,1], [1/2-inset/2,1-inset/2,1/2], - [1-inset/2,1-inset/2,1/2], [1-inset/2,1/2-inset/2,1/2], + each move([0,0], p=path3d(square(0.5-border),1)), + each move([0,0.5], p=path3d(square(0.5-border))), + each move([0.5,0], p=path3d(square(0.5-border))), + each move([0.5,0.5], p=path3d(square(0.5-border),1)), + [1/2-border/2,1/2-border/2,1/2], [0,1,1], [1/2-border,1,1], + [1/2,1,0], [1-border,1,0], [1,0,1], [1,1/2-border,1], + [1,1/2,0], [1,1-border,0], [1,1,1], [1/2-border/2,1-border/2,1/2], + [1-border/2,1-border/2,1/2], [1-border/2,1/2-border/2,1/2], ], [ for (i=[0:4:12]) each [[i,i+1,i+2], [i, i+2, i+3]], [10,13,11], [13,12,11], [2,5,4], [4,3,2], @@ -3257,22 +3263,22 @@ function texture(tex, n, inset, gap, roughness) = assert(num_defined([gap,roughness])==0, "cones texture does not accept gap or roughness") let( n = quant(default(n,16),4), - inset = default(inset,0) + border = default(border,0) ) - assert(inset>=0 && inset<0.5) + assert(border>=0 && border<0.5) [ [ - each move([1/2,1/2], p=path3d(circle(d=1-2*inset,$fn=n))), + each move([1/2,1/2], p=path3d(circle(d=1-2*border,$fn=n))), [1/2,1/2,1], each path3d(square(1)), ], [ for (i=[0:1:n-1]) [i, (i+1)%n, n], for (i=[0:1:3], j=[0:1:n/4-1]) [n+1+i, (i*n/4+j+1)%n, i*n/4+j], - if (inset > 0) for (i = [0:1:3]) [i+n+1, (i+1)%4+n+1, ((i+1)*n/4)%n], + if (border > 0) for (i = [0:1:3]) [i+n+1, (i+1)%4+n+1, ((i+1)*n/4)%n], ] ] : tex=="cubes"? - assert(num_defined([n, gap, inset, roughness])==0, "cubes texture does not accept n, gap, inset or roughness") + assert(num_defined([n, gap, border, roughness])==0, "cubes texture does not accept n, gap, border or roughness") [ [ [0,1,1/2], [1,1,1/2], [1/2,5/6,1], [0,4/6,0], [1,4/6,0], @@ -3287,14 +3293,14 @@ function texture(tex, n, inset, gap, roughness) = tex=="trunc_diamonds"? assert(num_defined([gap, n, roughness])==0, "trunc_diamonds texture does not accept gap, n or roughness") let( - inset = default(inset,0.1)/sqrt(2)*2 + border = default(border,0.1)/sqrt(2)*2 ) - assert(inset>0 && inset<0.5) + assert(border>0 && border<0.5) [ [ each move([1/2,1/2,0], p=path3d(circle(d=1,$fn=4))), - each move([1/2,1/2,1], p=path3d(circle(d=1-inset*2,$fn=4))), - for (a=[0:90:359]) each move([1/2,1/2], p=zrot(-a, p=[[1/2,inset,1], [inset,1/2,1], [1/2,1/2,1]])) + each move([1/2,1/2,1], p=path3d(circle(d=1-border*2,$fn=4))), + for (a=[0:90:359]) each move([1/2,1/2], p=zrot(-a, p=[[1/2,border,1], [border,1/2,1], [1/2,1/2,1]])) ], [ for (i=[0:3]) each let(j=i*3+8) [ [i,(i+1)%4,(i+1)%4+4], [i,(i+1)%4+4,i+4], @@ -3307,12 +3313,12 @@ function texture(tex, n, inset, gap, roughness) = assert(num_defined([gap,roughness])==0, str(tex," texture does not accept gap or roughness")) let( n = quant(default(n,16),4), - inset = default(inset,0.05) + border = default(border,0.05) ) - assert(inset>=0 && inset < 0.5) + assert(border>=0 && border < 0.5) let( rows=ceil(n/4), - r=adj_ang_to_hyp(1/2-inset,45), + r=adj_ang_to_hyp(1/2-border,45), dots = tex=="dots", cp = [1/2, 1/2, r*sin(45)*(dots?-1:1)], sc = 1 / (r - abs(cp.z)), @@ -3333,18 +3339,18 @@ function texture(tex, n, inset, gap, roughness) = [4+i*n+j, 4+i*n+(j+1)%n, 4+(i+1)*n+(j+1)%n], ], for (i=[0:1:n-1]) [4+(rows-1)*n+i, 4+(rows-1)*n+(i+1)%n, 4+rows*n], - if (inset>0) for (i=[0:3]) [i, (i+1)%4, 4+(i+1)%4*n/4] + if (border>0) for (i=[0:3]) [i, (i+1)%4, 4+(i+1)%4*n/4] ] ) [verts, faces] : tex=="tri_grid"? assert(num_defined([gap, n, roughness])==0, str(tex," texture does not accept gap, n or roughness")) let( - inset = default(inset,0.05)*sqrt(3) + border = default(border,0.05)*sqrt(3) ) - assert(inset>0 && inset0 && border0 && inset<0.5) + assert(border>0 && border<0.5) let( - diag=opp_ang_to_hyp(inset,60), + diag=opp_ang_to_hyp(border,60), side=adj_ang_to_opp(1,30), hyp=adj_ang_to_hyp(0.5,30), sc = 1/3/hyp, @@ -3389,15 +3395,15 @@ function texture(tex, n, inset, gap, roughness) = ) [ [ each hex, - each move([0.5,0.5], p=yscale(sc, p=path3d(ellipse(d=1-2*inset, circum=true, spin=-30,$fn=6),1))), + each move([0.5,0.5], p=yscale(sc, p=path3d(ellipse(d=1-2*border, circum=true, spin=-30,$fn=6),1))), hex[0]-[0,diag*sc,-1], for (ang=[270+60,270-60]) hex[1]+yscale(sc, p=cylindrical_to_xyz(diag,ang,1)), hex[2]-[0,diag*sc,-1], - [0,0,1], [0.5-inset,0,1], [0.5,0,0], [0.5+inset,0,1], [1,0,1], + [0,0,1], [0.5-border,0,1], [0.5,0,0], [0.5+border,0,1], [1,0,1], hex[3]+[0,diag*sc,1], for (ang=[90+60,90-60]) hex[4]+yscale(sc, p=cylindrical_to_xyz(diag,ang,1)), hex[5]+[0,diag*sc,1], - [0,1,1], [0.5-inset,1,1], [0.5,1,0], [0.5+inset,1,1], [1,1,1], + [0,1,1], [0.5-border,1,1], [0.5,1,0], [0.5+border,1,1], [1,1,1], ], [ for (i=[0:2:5]) let(b=6) [b+i, b+(i+1)%6, b+(i+2)%6], [6,8,10], for (i=[0:1:5]) each [ [i, (i+1)%6, (i+1)%6+6], [i, (i+1)%6+6, i+6] ], @@ -3410,7 +3416,7 @@ function texture(tex, n, inset, gap, roughness) = ] ] : tex=="rough"? - assert(num_defined([gap,inset])==0, str(tex," texture does not accept gap or inset")) + assert(num_defined([gap,border])==0, str(tex," texture does not accept gap or border")) let( n = default(n,32), rough = default(roughness, 0.2) From 8dfaa37ecc4fe798e0f065032776d4e4cb5cf201 Mon Sep 17 00:00:00 2001 From: adrianVmariano Date: Sun, 7 Jan 2024 03:08:24 +0000 Subject: [PATCH 02/13] Version Bump --- version.scad | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.scad b/version.scad index 9f046b9..274293a 100644 --- a/version.scad +++ b/version.scad @@ -9,7 +9,7 @@ ////////////////////////////////////////////////////////////////////// -BOSL_VERSION = [2,0,679]; +BOSL_VERSION = [2,0,680]; // Section: BOSL Library Version Functions From f9549f53a58817b0034e2146817ad0c880f1126a Mon Sep 17 00:00:00 2001 From: Adrian Mariano Date: Sat, 6 Jan 2024 23:36:39 -0500 Subject: [PATCH 03/13] bugfix --- shapes3d.scad | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/shapes3d.scad b/shapes3d.scad index 56c3354..d225746 100644 --- a/shapes3d.scad +++ b/shapes3d.scad @@ -1511,13 +1511,13 @@ function cyl( texture, tex_size=[5,5], tex_counts, tex_inset=false, tex_rot=false, tex_scale=1, tex_samples, length, height, - tex_taper, style="min_edge", tex_style, + tex_taper, style, tex_style, anchor, spin=0, orient=UP ) = assert(num_defined([style,tex_style])<2, "In cyl() the 'tex_style' parameters has been replaced by 'style'. You cannot give both.") let( style = is_def(tex_style)? echo("In cyl the 'tex_style()' parameters is deprecated and has been replaced by 'style'")tex_style - : style, + : default(style,"min_edge"), l = one_defined([l, h, length, height],"l,h,length,height",dflt=1), _r1 = get_radius(r1=r1, r=r, d1=d1, d=d, dflt=1), _r2 = get_radius(r1=r2, r=r, d1=d2, d=d, dflt=1), @@ -1666,9 +1666,11 @@ module cyl( texture, tex_size=[5,5], tex_counts, tex_inset=false, tex_rot=false, tex_scale=1, tex_samples, length, height, - tex_taper, style="min_edge", tex_style, + tex_taper, style, tex_style, anchor, spin=0, orient=UP ) { + style = is_def(tex_style)? echo("In cyl the 'tex_style()' parameters is deprecated and has been replaced by 'style'")tex_style + : default(style,"min_edge"); l = one_defined([l, h, length, height],"l,h,length,height",dflt=1); _r1 = get_radius(r1=r1, r=r, d1=d1, d=d, dflt=1); _r2 = get_radius(r1=r2, r=r, d1=d2, d=d, dflt=1); @@ -1695,7 +1697,7 @@ module cyl( texture=texture, tex_size=tex_size, tex_counts=tex_counts, tex_scale=tex_scale, tex_inset=tex_inset, tex_rot=tex_rot, - style=style, tex_style=tex_style, tex_taper=tex_taper, + style=style, tex_taper=tex_taper, tex_samples=tex_samples ); vnf_polyhedron(vnf, convexity=texture!=undef? 2 : 10); From ed98416726cb79afc771b21d76857404e97320fe Mon Sep 17 00:00:00 2001 From: adrianVmariano Date: Sun, 7 Jan 2024 04:37:47 +0000 Subject: [PATCH 04/13] Version Bump --- version.scad | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.scad b/version.scad index 274293a..9d58cfa 100644 --- a/version.scad +++ b/version.scad @@ -9,7 +9,7 @@ ////////////////////////////////////////////////////////////////////// -BOSL_VERSION = [2,0,680]; +BOSL_VERSION = [2,0,681]; // Section: BOSL Library Version Functions From f8436dacc01ba3e088e3b3e5cb571296b218f846 Mon Sep 17 00:00:00 2001 From: Adrian Mariano Date: Sun, 7 Jan 2024 20:38:53 -0500 Subject: [PATCH 05/13] change tex_counts to tex_reps --- screws.scad | 2 +- shapes3d.scad | 28 ++++++++++++++++++---------- skin.scad | 42 ++++++++++++++++++++++++++++-------------- 3 files changed, 47 insertions(+), 25 deletions(-) diff --git a/screws.scad b/screws.scad index 089eec5..0c2e317 100644 --- a/screws.scad +++ b/screws.scad @@ -1495,7 +1495,7 @@ module screw_head(screw_info,details=false, counterbore=0,flat_height,teardrop=f [20, .165]]; intersection() { cyl(h=head_height/4, d=head_size, anchor=BOT) - attach(TOP) cyl(l=head_height*3/4, d=head_size, anchor=BOT, texture="trunc_ribs", tex_counts=[31,1], tex_scale=-lookup(adj_diam,rib_size)); + attach(TOP) cyl(l=head_height*3/4, d=head_size, anchor=BOT, texture="trunc_ribs", tex_reps=[31,1], tex_scale=-lookup(adj_diam,rib_size)); cyl(h=head_height,d=head_size, chamfer2=adj_diam/10, anchor=BOT); } } diff --git a/shapes3d.scad b/shapes3d.scad index d225746..93cf8d8 100644 --- a/shapes3d.scad +++ b/shapes3d.scad @@ -1292,9 +1292,9 @@ function cylinder(h, r1, r2, center, r, d, d1, d2, anchor, spin=0, orient=UP) = // cyl(l|h|length|height, r|d, rounding1=, rounding2=, ...); // // Usage: Textured Cylinders -// cyl(l|h|length|height, r|d, texture=, [tex_size=]|[tex_counts=], [tex_scale=], [tex_rot=], [tex_samples=], [style=], [tex_taper=], [tex_inset=], ...); -// cyl(l|h|length|height, r1=, r2=, texture=, [tex_size=]|[tex_counts=], [tex_scale=], [tex_rot=], [tex_samples=], [style=], [tex_taper=], [tex_inset=], ...); -// cyl(l|h|length|height, d1=, d2=, texture=, [tex_size=]|[tex_counts=], [tex_scale=], [tex_rot=], [tex_samples=], [style=], [tex_taper=], [tex_inset=], ...); +// cyl(l|h|length|height, r|d, texture=, [tex_size=]|[tex_reps=], [tex_scale=], [tex_rot=], [tex_samples=], [style=], [tex_taper=], [tex_inset=], ...); +// cyl(l|h|length|height, r1=, r2=, texture=, [tex_size=]|[tex_reps=], [tex_scale=], [tex_rot=], [tex_samples=], [style=], [tex_taper=], [tex_inset=], ...); +// cyl(l|h|length|height, d1=, d2=, texture=, [tex_size=]|[tex_reps=], [tex_scale=], [tex_rot=], [tex_samples=], [style=], [tex_taper=], [tex_inset=], ...); // // Usage: Caled as a function to get a VNF // vnf = cyl(...); @@ -1363,7 +1363,7 @@ function cylinder(h, r1, r2, center, r, d, d1, d2, anchor, spin=0, orient=UP) = // teardrop = If given as a number, rounding around the bottom edge of the cylinder won't exceed this many degrees from vertical. If true, the limit angle is 45 degrees. Default: `false` // texture = A texture name string, or a rectangular array of scalar height values (0.0 to 1.0), or a VNF tile that defines the texture to apply to vertical surfaces. See {{texture()}} for what named textures are supported. // tex_size = An optional 2D target size for the textures. Actual texture sizes will be scaled somewhat to evenly fit the available surface. Default: `[5,5]` -// tex_counts = If given instead of tex_size, gives the tile repetition counts for textures over the surface length and height. +// tex_reps = If given instead of tex_size, gives the tile repetition counts for textures over the surface length and height. // tex_inset = If numeric, lowers the texture into the surface by that amount, before the tex_scale multiplier is applied. If `true`, insets by exactly `1`. Default: `false` // tex_rot = If true, rotates the texture 90º. // tex_scale = Scaling multiplier for the texture depth. @@ -1487,7 +1487,7 @@ function cylinder(h, r1, r2, center, r, d, d1, d2, anchor, spin=0, orient=UP) = // ]; // diff() // cyl(d=20*10/PI, h=10, chamfer=0, -// texture=tex, tex_counts=[20,1], tex_scale=-1, +// texture=tex, tex_reps=[20,1], tex_scale=-1, // tex_taper=undef, style="concave") { // attach([TOP,BOT]) { // cyl(d1=20*10/PI, d2=30, h=5, anchor=BOT) @@ -1508,16 +1508,19 @@ function cyl( circum=false, realign=false, shift=[0,0], teardrop=false, from_end, from_end1, from_end2, - texture, tex_size=[5,5], tex_counts, + texture, tex_size=[5,5], tex_reps, tex_counts, tex_inset=false, tex_rot=false, tex_scale=1, tex_samples, length, height, tex_taper, style, tex_style, anchor, spin=0, orient=UP ) = assert(num_defined([style,tex_style])<2, "In cyl() the 'tex_style' parameters has been replaced by 'style'. You cannot give both.") + assert(num_defined([tex_reps,tex_counts])<2, "In cyl() the 'tex_counts' parameters has been replaced by 'tex_reps'. You cannot give both.") let( - style = is_def(tex_style)? echo("In cyl the 'tex_style()' parameters is deprecated and has been replaced by 'style'")tex_style + style = is_def(tex_style)? echo("In cyl() the 'tex_style' parameter is deprecated and has been replaced by 'style'")tex_style : default(style,"min_edge"), + tex_reps = is_def(tex_counts)? echo("In cyl() the 'tex_counts' parameter is deprecated and has been replaced by 'tex_reps'")tex_counts + : tex_reps, l = one_defined([l, h, length, height],"l,h,length,height",dflt=1), _r1 = get_radius(r1=r1, r=r, d1=d1, d=d, dflt=1), _r2 = get_radius(r1=r2, r=r, d1=d2, d=d, dflt=1), @@ -1620,7 +1623,7 @@ function cyl( if (texture==undef) [0,l/2], ] ) rotate_sweep(path, - texture=texture, tex_counts=tex_counts, tex_size=tex_size, + texture=texture, tex_reps=tex_reps, tex_size=tex_size, tex_inset=tex_inset, tex_rot=tex_rot, tex_scale=tex_scale, tex_samples=tex_samples, tex_taper=tex_taper, style=style, closed=false @@ -1663,14 +1666,19 @@ module cyl( circum=false, realign=false, shift=[0,0], teardrop=false, from_end, from_end1, from_end2, - texture, tex_size=[5,5], tex_counts, + texture, tex_size=[5,5], tex_reps, tex_counts, tex_inset=false, tex_rot=false, tex_scale=1, tex_samples, length, height, tex_taper, style, tex_style, anchor, spin=0, orient=UP ) { + dummy= + assert(num_defined([style,tex_style])<2, "In cyl() the 'tex_style' parameters has been replaced by 'style'. You cannot give both.") + assert(num_defined([tex_reps,tex_counts])<2, "In cyl() the 'tex_counts' parameters has been replaced by 'tex_reps'. You cannot give both."); style = is_def(tex_style)? echo("In cyl the 'tex_style()' parameters is deprecated and has been replaced by 'style'")tex_style : default(style,"min_edge"); + tex_reps = is_def(tex_counts)? echo("In cyl() the 'tex_counts' parameter is deprecated and has been replaced by 'tex_reps'")tex_counts + : tex_reps; l = one_defined([l, h, length, height],"l,h,length,height",dflt=1); _r1 = get_radius(r1=r1, r=r, d1=d1, d=d, dflt=1); _r2 = get_radius(r1=r2, r=r, d1=d2, d=d, dflt=1); @@ -1695,7 +1703,7 @@ module cyl( from_end=from_end, from_end1=from_end1, from_end2=from_end2, teardrop=teardrop, texture=texture, tex_size=tex_size, - tex_counts=tex_counts, tex_scale=tex_scale, + tex_reps=tex_reps, tex_scale=tex_scale, tex_inset=tex_inset, tex_rot=tex_rot, style=style, tex_taper=tex_taper, tex_samples=tex_samples diff --git a/skin.scad b/skin.scad index 9d4efba..024f5f2 100644 --- a/skin.scad +++ b/skin.scad @@ -517,10 +517,10 @@ function skin(profiles, slices, refine=1, method="direct", sampling, caps, close // Usage: As Module // linear_sweep(region, [height], [center=], [slices=], [twist=], [scale=], [style=], [caps=], [convexity=]) [ATTACHMENTS]; // Usage: With Texturing -// linear_sweep(region, [height], [center=], texture=, [tex_size=]|[tex_counts=], [tex_scale=], [style=], [tex_samples=], ...) [ATTACHMENTS]; +// linear_sweep(region, [height], [center=], texture=, [tex_size=]|[tex_reps=], [tex_scale=], [style=], [tex_samples=], ...) [ATTACHMENTS]; // Usage: As Function // vnf = linear_sweep(region, [height], [center=], [slices=], [twist=], [scale=], [style=], [caps=]); -// vnf = linear_sweep(region, [height], [center=], texture=, [tex_size=]|[tex_counts=], [tex_scale=], [style=], [tex_samples=], ...); +// vnf = linear_sweep(region, [height], [center=], texture=, [tex_size=]|[tex_reps=], [tex_scale=], [style=], [tex_samples=], ...); // Description: // If called as a module, creates a polyhedron that is the linear extrusion of the given 2D region or polygon. // If called as a function, returns a VNF that can be used to generate a polyhedron of the linear extrusion @@ -545,7 +545,7 @@ function skin(profiles, slices, refine=1, method="direct", sampling, caps, close // maxseg = If given, then any long segments of the region will be subdivided to be shorter than this length. This can refine twisting flat faces a lot. Default: `undef` (no subsampling) // texture = A texture name string, or a rectangular array of scalar height values (0.0 to 1.0), or a VNF tile that defines the texture to apply to vertical surfaces. See {{texture()}} for what named textures are supported. // tex_size = An optional 2D target size for the textures. Actual texture sizes will be scaled somewhat to evenly fit the available surface. Default: `[5,5]` -// tex_counts = If given instead of tex_size, gives the tile repetition counts for textures over the surface length and height. +// tex_reps = If given instead of tex_size, gives the tile repetition counts for textures over the surface length and height. // tex_inset = If numeric, lowers the texture into the surface by that amount, before the tex_scale multiplier is applied. If `true`, insets by exactly `1`. Default: `false` // tex_rot = If true, rotates the texture 90º. // tex_scale = Scaling multiplier for the texture depth. @@ -707,7 +707,7 @@ module linear_sweep( region, height, center, twist=0, scale=1, shift=[0,0], slices, maxseg, style="default", convexity, caps=true, - texture, tex_size=[5,5], tex_counts, + texture, tex_size=[5,5], tex_reps, tex_counts, tex_inset=false, tex_rot=false, tex_scale=1, tex_samples, cp, atype="hull", h,l,length, @@ -724,6 +724,7 @@ module linear_sweep( twist=twist, scale=scale, shift=shift, texture=texture, tex_size=tex_size, + tex_reps=tex_reps, tex_counts=tex_counts, tex_inset=tex_inset, tex_rot=tex_rot, @@ -759,12 +760,17 @@ function linear_sweep( twist=0, scale=1, shift=[0,0], slices, maxseg, style="default", caps=true, cp, atype="hull", h, - texture, tex_size=[5,5], tex_counts, + texture, tex_size=[5,5], tex_reps, tex_counts, tex_inset=false, tex_rot=false, tex_scale=1, tex_samples, h, l, length, anchor, spin=0, orient=UP ) = - let( region = force_region(region) ) + assert(num_defined([tex_reps,tex_counts])<2, "In linear_sweep() the 'tex_counts' parameters has been replaced by 'tex_reps'. You cannot give both.") + let( + region = force_region(region), + tex_reps = is_def(tex_counts)? echo("In cyl() the 'tex_counts' parameter is deprecated and has been replaced by 'tex_reps'")tex_counts + : tex_reps + ) assert(is_region(region), "Input is not a region or polygon.") assert(is_num(scale) || is_vector(scale)) assert(is_vector(shift, 2), str(shift)) @@ -775,7 +781,7 @@ function linear_sweep( !is_undef(texture)? _textured_linear_sweep( region, h=h, caps=caps, texture=texture, tex_size=tex_size, - counts=tex_counts, inset=tex_inset, + counts=tex_reps, inset=tex_inset, rot=tex_rot, tex_scale=tex_scale, twist=twist, scale=scale, shift=shift, style=style, samples=tex_samples, @@ -851,7 +857,7 @@ function linear_sweep( // Usage: As Module // rotate_sweep(shape, [angle], ...) [ATTACHMENTS]; // Usage: With Texturing -// rotate_sweep(shape, texture=, [tex_size=]|[tex_counts=], [tex_scale=], [tex_samples=], [tex_rot=], [tex_inset=], ...) [ATTACHMENTS]; +// rotate_sweep(shape, texture=, [tex_size=]|[tex_reps=], [tex_scale=], [tex_samples=], [tex_rot=], [tex_inset=], ...) [ATTACHMENTS]; // Description: // Takes a polygon or [region](regions.scad) and sweeps it in a rotation around the Z axis, with optional texturing. // When called as a function, returns a [VNF](vnf.scad). @@ -862,7 +868,7 @@ function linear_sweep( // --- // texture = A texture name string, or a rectangular array of scalar height values (0.0 to 1.0), or a VNF tile that defines the texture to apply to vertical surfaces. See {{texture()}} for what named textures are supported. // tex_size = An optional 2D target size for the textures. Actual texture sizes will be scaled somewhat to evenly fit the available surface. Default: `[5,5]` -// tex_counts = If given instead of tex_size, gives the tile repetition counts for textures over the surface length and height. +// tex_reps = If given instead of tex_size, gives the tile repetition counts for textures over the surface length and height. // tex_inset = If numeric, lowers the texture into the surface by that amount, before the tex_scale multiplier is applied. If `true`, insets by exactly `1`. Default: `false` // tex_rot = If true, rotates the texture 90º. // tex_scale = Scaling multiplier for the texture depth. @@ -951,7 +957,7 @@ function linear_sweep( function rotate_sweep( shape, angle=360, - texture, tex_size=[5,5], tex_counts, + texture, tex_size=[5,5], tex_counts, tex_reps, tex_inset=false, tex_rot=false, tex_scale=1, tex_samples, tex_taper, shift=[0,0], closed=true, @@ -959,7 +965,11 @@ function rotate_sweep( atype="hull", anchor="origin", spin=0, orient=UP ) = - let( region = force_region(shape) ) + assert(num_defined([tex_reps,tex_counts])<2, "In rotate_sweep() the 'tex_counts' parameters has been replaced by 'tex_reps'. You cannot give both.") + let( region = force_region(shape), + tex_reps = is_def(tex_counts)? echo("In rotate_sweep() the 'tex_counts' parameter is deprecated and has been replaced by 'tex_reps'")tex_counts + : tex_reps + ) assert(is_region(region), "Input is not a region or polygon.") let( bounds = pointlist_bounds(flatten(region)), @@ -974,7 +984,7 @@ function rotate_sweep( shape, texture=texture, tex_size=tex_size, - counts=tex_counts, + counts=tex_reps, tex_scale=tex_scale, inset=tex_inset, rot=tex_rot, @@ -1005,7 +1015,7 @@ function rotate_sweep( module rotate_sweep( shape, angle=360, - texture, tex_size=[5,5], tex_counts, + texture, tex_size=[5,5], tex_counts, tex_reps, tex_inset=false, tex_rot=false, tex_scale=1, tex_samples, tex_taper, shift=[0,0], @@ -1018,6 +1028,10 @@ module rotate_sweep( spin=0, orient=UP ) { + dummy = + assert(num_defined([tex_reps,tex_counts])<2, "In rotate_sweep() the 'tex_counts' parameters has been replaced by 'tex_reps'. You cannot give both."); + tex_reps = is_def(tex_counts)? echo("In rotate_sweep() the 'tex_counts' parameter is deprecated and has been replaced by 'tex_reps'")tex_counts + : tex_reps; region = force_region(shape); check = assert(is_region(region), "Input is not a region or polygon."); bounds = pointlist_bounds(flatten(region)); @@ -1032,7 +1046,7 @@ module rotate_sweep( shape, texture=texture, tex_size=tex_size, - counts=tex_counts, + counts=tex_reps, tex_scale=tex_scale, inset=tex_inset, rot=tex_rot, From cb4169de2f7c9abe3742c911f4acf05a72b7e1b5 Mon Sep 17 00:00:00 2001 From: adrianVmariano Date: Mon, 8 Jan 2024 01:39:42 +0000 Subject: [PATCH 06/13] Version Bump --- version.scad | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.scad b/version.scad index 9d58cfa..c67907b 100644 --- a/version.scad +++ b/version.scad @@ -9,7 +9,7 @@ ////////////////////////////////////////////////////////////////////// -BOSL_VERSION = [2,0,681]; +BOSL_VERSION = [2,0,682]; // Section: BOSL Library Version Functions From b7cbbcf4c1b9d4d828ef9f1c64e2b693ff9835d3 Mon Sep 17 00:00:00 2001 From: Adrian Mariano Date: Mon, 8 Jan 2024 22:58:06 -0500 Subject: [PATCH 07/13] tex_scale->tex_depth, tex_count->tex_reps --- shapes3d.scad | 18 ++++-- skin.scad | 164 +++++++++++++++++++++++++++++++++----------------- 2 files changed, 120 insertions(+), 62 deletions(-) diff --git a/shapes3d.scad b/shapes3d.scad index 93cf8d8..7429028 100644 --- a/shapes3d.scad +++ b/shapes3d.scad @@ -1363,10 +1363,10 @@ function cylinder(h, r1, r2, center, r, d, d1, d2, anchor, spin=0, orient=UP) = // teardrop = If given as a number, rounding around the bottom edge of the cylinder won't exceed this many degrees from vertical. If true, the limit angle is 45 degrees. Default: `false` // texture = A texture name string, or a rectangular array of scalar height values (0.0 to 1.0), or a VNF tile that defines the texture to apply to vertical surfaces. See {{texture()}} for what named textures are supported. // tex_size = An optional 2D target size for the textures. Actual texture sizes will be scaled somewhat to evenly fit the available surface. Default: `[5,5]` -// tex_reps = If given instead of tex_size, gives the tile repetition counts for textures over the surface length and height. +// tex_reps = If given instead of tex_size, a 2-vector giving the number of texture tile repetitions in the horizontal and vertical directions. // tex_inset = If numeric, lowers the texture into the surface by that amount, before the tex_scale multiplier is applied. If `true`, insets by exactly `1`. Default: `false` -// tex_rot = If true, rotates the texture 90º. -// tex_scale = Scaling multiplier for the texture depth. +// tex_rot = Rotate texture by specified angle, which must be a multiple of 90 degrees. A value of true is equivalent to 90 deg, and false to 0. Default: 0 +// tex_depth = Specify texture depth; if negative, invert the texture. Default: 1. // tex_samples = Minimum number of "bend points" to have in VNF texture tiles. Default: 8 // tex_taper = If given as a number, tapers the texture height to zero over the first and last given percentage of the path. If given as a lookup table with indices between 0 and 100, uses the percentage lookup table to ramp the texture heights. Default: `undef` (no taper) // style = {{vnf_vertex_array()}} style used to triangulate heightfield textures. Default: "min_edge" @@ -1510,17 +1510,20 @@ function cyl( from_end, from_end1, from_end2, texture, tex_size=[5,5], tex_reps, tex_counts, tex_inset=false, tex_rot=false, - tex_scale=1, tex_samples, length, height, + tex_scale, tex_depth, tex_samples, length, height, tex_taper, style, tex_style, anchor, spin=0, orient=UP ) = assert(num_defined([style,tex_style])<2, "In cyl() the 'tex_style' parameters has been replaced by 'style'. You cannot give both.") assert(num_defined([tex_reps,tex_counts])<2, "In cyl() the 'tex_counts' parameters has been replaced by 'tex_reps'. You cannot give both.") + assert(num_defined([tex_scale,tex_depth])<2, "In linear_sweep() the 'tex_scale' parameter has been replaced by 'tex_depth'. You cannot give both.") let( style = is_def(tex_style)? echo("In cyl() the 'tex_style' parameter is deprecated and has been replaced by 'style'")tex_style : default(style,"min_edge"), tex_reps = is_def(tex_counts)? echo("In cyl() the 'tex_counts' parameter is deprecated and has been replaced by 'tex_reps'")tex_counts : tex_reps, + tex_depth = is_def(tex_scale)? echo("In rotate_sweep() the 'tex_scale' parameter is deprecated and has been replaced by 'tex_depth'")tex_scale + : default(tex_depth,1), l = one_defined([l, h, length, height],"l,h,length,height",dflt=1), _r1 = get_radius(r1=r1, r=r, d1=d1, d=d, dflt=1), _r2 = get_radius(r1=r2, r=r, d1=d2, d=d, dflt=1), @@ -1668,17 +1671,20 @@ module cyl( from_end, from_end1, from_end2, texture, tex_size=[5,5], tex_reps, tex_counts, tex_inset=false, tex_rot=false, - tex_scale=1, tex_samples, length, height, + tex_scale, tex_depth, tex_samples, length, height, tex_taper, style, tex_style, anchor, spin=0, orient=UP ) { dummy= assert(num_defined([style,tex_style])<2, "In cyl() the 'tex_style' parameters has been replaced by 'style'. You cannot give both.") - assert(num_defined([tex_reps,tex_counts])<2, "In cyl() the 'tex_counts' parameters has been replaced by 'tex_reps'. You cannot give both."); + assert(num_defined([tex_reps,tex_counts])<2, "In cyl() the 'tex_counts' parameters has been replaced by 'tex_reps'. You cannot give both.") + assert(num_defined([tex_scale,tex_depth])<2, "In cyl() the 'tex_scale' parameter has been replaced by 'tex_depth'. You cannot give both."); style = is_def(tex_style)? echo("In cyl the 'tex_style()' parameters is deprecated and has been replaced by 'style'")tex_style : default(style,"min_edge"); tex_reps = is_def(tex_counts)? echo("In cyl() the 'tex_counts' parameter is deprecated and has been replaced by 'tex_reps'")tex_counts : tex_reps; + tex_depth = is_def(tex_scale)? echo("In rotate_sweep() the 'tex_scale' parameter is deprecated and has been replaced by 'tex_depth'")tex_scale + : default(tex_depth,1); l = one_defined([l, h, length, height],"l,h,length,height",dflt=1); _r1 = get_radius(r1=r1, r=r, d1=d1, d=d, dflt=1); _r2 = get_radius(r1=r2, r=r, d1=d2, d=d, dflt=1); diff --git a/skin.scad b/skin.scad index 024f5f2..4e083c1 100644 --- a/skin.scad +++ b/skin.scad @@ -517,10 +517,10 @@ function skin(profiles, slices, refine=1, method="direct", sampling, caps, close // Usage: As Module // linear_sweep(region, [height], [center=], [slices=], [twist=], [scale=], [style=], [caps=], [convexity=]) [ATTACHMENTS]; // Usage: With Texturing -// linear_sweep(region, [height], [center=], texture=, [tex_size=]|[tex_reps=], [tex_scale=], [style=], [tex_samples=], ...) [ATTACHMENTS]; +// linear_sweep(region, [height], [center=], texture=, [tex_size=]|[tex_reps=], [tex_depth=], [style=], [tex_samples=], ...) [ATTACHMENTS]; // Usage: As Function // vnf = linear_sweep(region, [height], [center=], [slices=], [twist=], [scale=], [style=], [caps=]); -// vnf = linear_sweep(region, [height], [center=], texture=, [tex_size=]|[tex_reps=], [tex_scale=], [style=], [tex_samples=], ...); +// vnf = linear_sweep(region, [height], [center=], texture=, [tex_size=]|[tex_reps=], [tex_depth=], [style=], [tex_samples=], ...); // Description: // If called as a module, creates a polyhedron that is the linear extrusion of the given 2D region or polygon. // If called as a function, returns a VNF that can be used to generate a polyhedron of the linear extrusion @@ -545,10 +545,10 @@ function skin(profiles, slices, refine=1, method="direct", sampling, caps, close // maxseg = If given, then any long segments of the region will be subdivided to be shorter than this length. This can refine twisting flat faces a lot. Default: `undef` (no subsampling) // texture = A texture name string, or a rectangular array of scalar height values (0.0 to 1.0), or a VNF tile that defines the texture to apply to vertical surfaces. See {{texture()}} for what named textures are supported. // tex_size = An optional 2D target size for the textures. Actual texture sizes will be scaled somewhat to evenly fit the available surface. Default: `[5,5]` -// tex_reps = If given instead of tex_size, gives the tile repetition counts for textures over the surface length and height. -// tex_inset = If numeric, lowers the texture into the surface by that amount, before the tex_scale multiplier is applied. If `true`, insets by exactly `1`. Default: `false` -// tex_rot = If true, rotates the texture 90º. -// tex_scale = Scaling multiplier for the texture depth. +// tex_reps = If given instead of tex_size, a 2-vector giving the number of texture tile repetitions in the horizontal and vertical directions on the extrusion. +// tex_inset = If numeric, lowers the texture into the surface by that amount, before the tex_depth multiplier is applied. If `true`, insets by exactly `1`. Default: `false` +// tex_rot = Rotate texture by specified angle, which must be a multiple of 90 degrees. A value of true is equivalent to 90 deg, and false to 0. Default: 0 +// tex_depth = Specify texture depth; if negative, invert the texture. Default: 1. // tex_samples = Minimum number of "bend points" to have in VNF texture tiles. Default: 8 // style = The style to use when triangulating the surface of the object. Valid values are `"default"`, `"alt"`, or `"quincunx"`. // caps = If false do not create end caps. Can be a boolean vector. Default: true @@ -616,7 +616,7 @@ function skin(profiles, slices, refine=1, method="direct", sampling, caps, close // path = glued_circles(r=15, spread=40, tangent=45); // linear_sweep( // path, texture="bricks_vnf", tex_size=[10,10], -// tex_scale=0.25, h=40); +// tex_depth=0.25, h=40); // Example: User defined heightfield texture. // path = ellipse(r=[20,10]); // texture = [for (i=[0:9]) @@ -644,14 +644,14 @@ function skin(profiles, slices, refine=1, method="direct", sampling, caps, close // linear_sweep(path, texture=tex, tex_size=[5,5], h=40); // Example: Textured with twist and scale. // linear_sweep(regular_ngon(n=3, d=50), -// texture="rough", h=100, tex_scale=2, +// texture="rough", h=100, tex_depth=2, // tex_size=[20,20], style="min_edge", // convexity=10, scale=0.2, twist=120); // Example: As Function // path = glued_circles(r=15, spread=40, tangent=45); // vnf = linear_sweep( // path, h=40, texture="trunc_pyramids", tex_size=[5,5], -// tex_scale=1, style="convex"); +// tex_depth=1, style="convex"); // vnf_polyhedron(vnf, convexity=10); // Example: VNF tile that has no top/bottom edges and produces a disconnected result // shape = skin([rect(2/5), @@ -662,7 +662,7 @@ function skin(profiles, slices, refine=1, method="direct", sampling, caps, close // caps=false); // tile = move([0,1/2,2/3],yrot(90,shape)); // linear_sweep(circle(20), texture=tile, -// tex_size=[10,10],tex_scale=5, +// tex_size=[10,10],tex_depth=5, // h=40,convexity=4); // Example: The same tile from above, turned 90 degrees, creates problems at the ends, because the end cap is not a connected polygon. When the ends are disconnected you may find that some parts of the end cap are missing and spurious polygons included. // shape = skin([rect(2/5), @@ -673,7 +673,7 @@ function skin(profiles, slices, refine=1, method="direct", sampling, caps, close // caps=false); // tile = move([1/2,1,2/3],xrot(90,shape)); // linear_sweep(circle(20), texture=tile, -// tex_size=[30,20],tex_scale=15, +// tex_size=[30,20],tex_depth=15, // h=40,convexity=4); // Example: This example shows some endcap polygons missing and a spurious triangle // shape = skin([rect(2/5), @@ -685,7 +685,7 @@ function skin(profiles, slices, refine=1, method="direct", sampling, caps, close // tile = xscale(.5,move([1/2,1,2/3],xrot(90,shape))); // doubletile = vnf_join([tile, right(.5,tile)]); // linear_sweep(circle(20), texture=doubletile, -// tex_size=[45,45],tex_scale=15, h=40); +// tex_size=[45,45],tex_depth=15, h=40); // Example: You can fix ends for disconnected cases using {{top_half()}} and {{bottom_half()}} // shape = skin([rect(2/5), // rect(2/3), @@ -698,7 +698,7 @@ function skin(profiles, slices, refine=1, method="direct", sampling, caps, close // top_half( // bottom_half( // linear_sweep(circle(20), texture=tile, -// tex_size=[30,20],tex_scale=15, +// tex_size=[30,20],tex_depth=15, // h=40.2,caps=false), // z=20), // z=-20)); @@ -709,7 +709,7 @@ module linear_sweep( slices, maxseg, style="default", convexity, caps=true, texture, tex_size=[5,5], tex_reps, tex_counts, tex_inset=false, tex_rot=false, - tex_scale=1, tex_samples, + tex_depth, tex_scale, tex_samples, cp, atype="hull", h,l,length, anchor, spin=0, orient=UP ) { @@ -728,7 +728,7 @@ module linear_sweep( tex_counts=tex_counts, tex_inset=tex_inset, tex_rot=tex_rot, - tex_scale=tex_scale, + tex_scale=tex_depth, tex_samples=tex_samples, slices=slices, maxseg=maxseg, @@ -762,14 +762,17 @@ function linear_sweep( cp, atype="hull", h, texture, tex_size=[5,5], tex_reps, tex_counts, tex_inset=false, tex_rot=false, - tex_scale=1, tex_samples, h, l, length, + tex_scale, tex_depth, tex_samples, h, l, length, anchor, spin=0, orient=UP ) = - assert(num_defined([tex_reps,tex_counts])<2, "In linear_sweep() the 'tex_counts' parameters has been replaced by 'tex_reps'. You cannot give both.") + assert(num_defined([tex_reps,tex_counts])<2, "In linear_sweep() the 'tex_counts' parameter has been replaced by 'tex_reps'. You cannot give both.") + assert(num_defined([tex_scale,tex_depth])<2, "In linear_sweep() the 'tex_scale' parameter has been replaced by 'tex_depth'. You cannot give both.") let( region = force_region(region), - tex_reps = is_def(tex_counts)? echo("In cyl() the 'tex_counts' parameter is deprecated and has been replaced by 'tex_reps'")tex_counts - : tex_reps + tex_reps = is_def(tex_counts)? echo("In linear_sweep() the 'tex_counts' parameter is deprecated and has been replaced by 'tex_reps'")tex_counts + : tex_reps, + tex_depth = is_def(tex_scale)? echo("In linear_sweep() the 'tex_scale' parameter is deprecated and has been replaced by 'tex_depth'")tex_scale + : default(tex_depth,1) ) assert(is_region(region), "Input is not a region or polygon.") assert(is_num(scale) || is_vector(scale)) @@ -782,7 +785,7 @@ function linear_sweep( region, h=h, caps=caps, texture=texture, tex_size=tex_size, counts=tex_reps, inset=tex_inset, - rot=tex_rot, tex_scale=tex_scale, + rot=tex_rot, tex_scale=tex_depth, twist=twist, scale=scale, shift=shift, style=style, samples=tex_samples, anchor=anchor, spin=spin, orient=orient @@ -857,7 +860,7 @@ function linear_sweep( // Usage: As Module // rotate_sweep(shape, [angle], ...) [ATTACHMENTS]; // Usage: With Texturing -// rotate_sweep(shape, texture=, [tex_size=]|[tex_reps=], [tex_scale=], [tex_samples=], [tex_rot=], [tex_inset=], ...) [ATTACHMENTS]; +// rotate_sweep(shape, texture=, [tex_size=]|[tex_reps=], [tex_depth=], [tex_samples=], [tex_rot=], [tex_inset=], ...) [ATTACHMENTS]; // Description: // Takes a polygon or [region](regions.scad) and sweeps it in a rotation around the Z axis, with optional texturing. // When called as a function, returns a [VNF](vnf.scad). @@ -868,10 +871,10 @@ function linear_sweep( // --- // texture = A texture name string, or a rectangular array of scalar height values (0.0 to 1.0), or a VNF tile that defines the texture to apply to vertical surfaces. See {{texture()}} for what named textures are supported. // tex_size = An optional 2D target size for the textures. Actual texture sizes will be scaled somewhat to evenly fit the available surface. Default: `[5,5]` -// tex_reps = If given instead of tex_size, gives the tile repetition counts for textures over the surface length and height. -// tex_inset = If numeric, lowers the texture into the surface by that amount, before the tex_scale multiplier is applied. If `true`, insets by exactly `1`. Default: `false` -// tex_rot = If true, rotates the texture 90º. -// tex_scale = Scaling multiplier for the texture depth. +// tex_reps = If given instead of tex_size, a 2-vector giving the number of texture tile repetitions in the direction perpendicular to extrusion and in the direction parallel to extrusion. +// tex_inset = If numeric, lowers the texture into the surface by that amount, before the tex_depth multiplier is applied. If `true`, insets by exactly `1`. Default: `false` +// tex_rot = Rotate texture by specified angle, which must be a multiple of 90 degrees. A value of true is equivalent to 90 deg, and false to 0. Default: 0 +// tex_depth = Specify texture depth; if negative, invert the texture. Default: 1. // tex_samples = Minimum number of "bend points" to have in VNF texture tiles. Default: 8 // style = {{vnf_vertex_array()}} style. Default: "min_edge" // closed = If false, and shape is given as a path, then the revolved path will be sealed to the axis of rotation with untextured caps. Default: `true` @@ -899,7 +902,7 @@ function linear_sweep( // rotate_sweep(rgn); // Example: // path = right(50, p=circle(d=40)); -// rotate_sweep(path, texture="bricks_vnf", tex_size=[10,10], tex_scale=0.5, style="concave"); +// rotate_sweep(path, texture="bricks_vnf", tex_size=[10,10], tex_depth=0.5, style="concave"); // Example: // tex = [ // [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], @@ -919,7 +922,7 @@ function linear_sweep( // rotate_sweep( // path, closed=false, // texture=tex, tex_size=[20,20], -// tex_scale=1, style="concave"); +// tex_depth=1, style="concave"); // Example: // include // bezpath = [ @@ -932,7 +935,7 @@ function linear_sweep( // rotate_sweep( // path, closed=false, // texture="diamonds", tex_size=[10,10], -// tex_scale=1, style="concave"); +// tex_depth=1, style="concave"); // Example: // path = [ // [20, 30], [20, 20], @@ -942,7 +945,7 @@ function linear_sweep( // vnf = rotate_sweep( // path, closed=false, // texture="trunc_pyramids", -// tex_size=[5,5], tex_scale=1, +// tex_size=[5,5], tex_depth=1, // style="convex"); // vnf_polyhedron(vnf, convexity=10); // Example: @@ -952,23 +955,26 @@ function linear_sweep( // ]; // rotate_sweep( // rgn, texture="diamonds", -// tex_size=[10,10], tex_scale=1, +// tex_size=[10,10], tex_depth=1, // angle=240, style="concave"); function rotate_sweep( shape, angle=360, texture, tex_size=[5,5], tex_counts, tex_reps, tex_inset=false, tex_rot=false, - tex_scale=1, tex_samples, + tex_scale, tex_depth, tex_samples, tex_taper, shift=[0,0], closed=true, style="min_edge", cp="centroid", atype="hull", anchor="origin", spin=0, orient=UP ) = assert(num_defined([tex_reps,tex_counts])<2, "In rotate_sweep() the 'tex_counts' parameters has been replaced by 'tex_reps'. You cannot give both.") + assert(num_defined([tex_scale,tex_depth])<2, "In linear_sweep() the 'tex_scale' parameter has been replaced by 'tex_depth'. You cannot give both.") let( region = force_region(shape), tex_reps = is_def(tex_counts)? echo("In rotate_sweep() the 'tex_counts' parameter is deprecated and has been replaced by 'tex_reps'")tex_counts - : tex_reps + : tex_reps, + tex_depth = is_def(tex_scale)? echo("In rotate_sweep() the 'tex_scale' parameter is deprecated and has been replaced by 'tex_depth'")tex_scale + : default(tex_depth,1) ) assert(is_region(region), "Input is not a region or polygon.") let( @@ -985,7 +991,7 @@ function rotate_sweep( texture=texture, tex_size=tex_size, counts=tex_reps, - tex_scale=tex_scale, + tex_scale=tex_depth, inset=tex_inset, rot=tex_rot, samples=tex_samples, @@ -1017,7 +1023,7 @@ module rotate_sweep( shape, angle=360, texture, tex_size=[5,5], tex_counts, tex_reps, tex_inset=false, tex_rot=false, - tex_scale=1, tex_samples, + tex_scale, tex_depth, tex_samples, tex_taper, shift=[0,0], style="min_edge", closed=true, @@ -1029,9 +1035,12 @@ module rotate_sweep( orient=UP ) { dummy = - assert(num_defined([tex_reps,tex_counts])<2, "In rotate_sweep() the 'tex_counts' parameters has been replaced by 'tex_reps'. You cannot give both."); + assert(num_defined([tex_reps,tex_counts])<2, "In rotate_sweep() the 'tex_counts' parameters has been replaced by 'tex_reps'. You cannot give both.") + assert(num_defined([tex_scale,tex_depth])<2, "In rotate_sweep() the 'tex_scale' parameter has been replaced by 'tex_depth'. You cannot give both."); tex_reps = is_def(tex_counts)? echo("In rotate_sweep() the 'tex_counts' parameter is deprecated and has been replaced by 'tex_reps'")tex_counts : tex_reps; + tex_depth = is_def(tex_scale)? echo("In rotate_sweep() the 'tex_scale' parameter is deprecated and has been replaced by 'tex_depth'")tex_scale + : default(tex_depth,1); region = force_region(shape); check = assert(is_region(region), "Input is not a region or polygon."); bounds = pointlist_bounds(flatten(region)); @@ -1047,7 +1056,7 @@ module rotate_sweep( texture=texture, tex_size=tex_size, counts=tex_reps, - tex_scale=tex_scale, + tex_scale=tex_depth, inset=tex_inset, rot=tex_rot, samples=tex_samples, @@ -2727,7 +2736,7 @@ function associate_vertices(polygons, split, curpoly=0) = // height values which specify the height of the texture on a grid. // Values in the height field should range from 0 to 1. A zero height // in the height field corresponds to the height of the surface and 1 -// the heighest point in the texture. +// the highest point in the texture above the surface being textured. // Figure(2D,Big,NoScales): Here is a 2d texture described by a "grid" that just contains a single row. Such a texture can be used to create ribbing. The texture is `[[0, 1, 1, 0]]`, and the fixture shows three repetitions of the basic texture unit. // ftex1 = [0,1,1,0,0]; // stroke( transpose([count(5),ftex1]), dots=true, dots_width=3,width=.05); @@ -2738,8 +2747,43 @@ function associate_vertices(polygons, split, curpoly=0) = // Continues: // Line segments connect the dots within the texture and also the dots between adjacent texture tiles. // The size of the texture (specified with `tex_size`) includes the segment that connects the tile to the next one. -// Note that the grid is always uniformly spaced. If you want to keep the texture the same size but make the slope -// steeper you need to add more points. +// Note that the grid is always uniformly spaced. +// By default textures are created with unit depth, meaning that the top surface +// of the texture is 1 unit above the surface being textured, assuming that the texture +// is correctly designed to span the range from 0 to 1. The `tex_depth` parameter can adjust +// this dimension of a texture without changing anything else, and setting `tex_depth` negative +// will invert a texture. +// Figure(2D,Big,NoScales): +// ftex1 = [0,1,1,0,0]; +// left(0)color(.6*[1,1,1])rect([12,1],anchor=BACK+LEFT); +// stroke( transpose([count(5),ftex1]), dots=true, dots_width=3,width=.05); +// polygon( transpose([count(5),ftex1])); +// right(4){stroke( transpose([count(5),ftex1]), dots=true, width=.05,dots_width=3); +// polygon( transpose([count(5),ftex1])); +// } +// right(8){stroke( transpose([count(5),ftex1]), dots=true, dots_width=3,width=.05); +// polygon( transpose([count(5),ftex1])); +// } +// stroke([[12.25,0],[12.25,1]],width=.05,endcaps="arrow2",color="black"); +// move([12.35,.5])color("black")text("Depth=1", size=0.3,anchor=LEFT); +// fwd(4){ +// left(0)color(.6*[1,1,1])rect([12,1],anchor=BACK+LEFT); +// stroke( transpose([count(5),2*ftex1]), dots=true, dots_width=3,width=.05); +// polygon( transpose([count(5),2*ftex1])); +// right(4){stroke( transpose([count(5),2*ftex1]), dots=true, width=.05,dots_width=3); +// polygon( transpose([count(5),2*ftex1])); +// } +// right(8){stroke( transpose([count(5),2*ftex1]), dots=true, dots_width=3,width=.05); +// polygon( transpose([count(5),2*ftex1])); +// } +// stroke([[12.25,0],[12.25,2]],width=.05,endcaps="arrow2",color="black"); +// move([12.35,1])color("black")text("Depth=2", size=0.3,anchor=LEFT); +// } +// Continues: +// If you want to keep the texture the same size but make the slope +// steeper you need to add more points to make the uniform grid fine enough +// to represent the slope you want. This means that creating sharp edges +// can require a large number of points, resulting in longer run times. // Figure(2D,Big,NoScales): // ftex2 = xscale(4/11,transpose([count(12),[0,1,1,1,1,1,1,1,1,1,0,0]])); // stroke( ftex2, dots=true, dots_width=3,width=.05); @@ -2749,7 +2793,7 @@ function associate_vertices(polygons, split, curpoly=0) = // move([6,-.4])color("black")text("Texture Size", size=0.3,anchor=BACK); // Continues: // A more serious limitation of height field textures is that some shapes, such as hexagons or circles, cannot be accurately represented because -// their points don't fall on a grid. Trying to create such shapes is difficult and will require many points to approximate the +// their points don't fall on any grid. Trying to create such shapes is difficult and will require many points to approximate the // true point positions for the desired shape. This will make the texture slow to compute. // Another serious limitation is more subtle. In the 2D examples above, it is obvious how to connect the // dots together. But in 3D example we need to triangulate the points on a grid, and this triangulation is not unique. @@ -2874,7 +2918,7 @@ function associate_vertices(polygons, split, curpoly=0) = // Example(3D): **"cones"** (VNF) = Raised conical spikes. Giving `n=` sets `$fn` for the cone (will be rounded to a multiple of 4). Default: 16. Giving `border=` specifies the horizontal border width between the edge of the tile and the base of the cone. The `border` value must be nonnegative and smaller than 0.5. Default: 0. // tex = texture("cones"); // linear_sweep( -// rect(30), texture=tex, h=30, tex_scale=3, +// rect(30), texture=tex, h=30, tex_depth=3, // tex_size=[10,10] // ); // Example(3D): **"cubes"** (VNF) = Corner-cubes texture. This texture needs to be scaled in vertically by sqrt(3) to have its correct aspect @@ -2886,7 +2930,7 @@ function associate_vertices(polygons, split, curpoly=0) = // Example(3D): "cubes" texture at the correct scale. // tex = texture("cubes"); // linear_sweep( -// rect(30), texture=tex, h=20*sqrt(3), tex_scale=3, +// rect(30), texture=tex, h=20*sqrt(3), tex_depth=3, // tex_size=[10,10*sqrt(3)] // ); // Example(3D): **"diamonds"** (Heightfield) = Four-sided pyramid with the corners of the base aligned with the axes. Compare to "pyramids". Useful for knurling. Giving `n=` sets the number of heightfield samples to `n x n`. Default: 2. Use `style="concave"` for pointed bumps, or `style="default"` or `style="alt"` for a diagonal ribs. @@ -2941,7 +2985,7 @@ function associate_vertices(polygons, split, curpoly=0) = // tex = texture("hex_grid",border=.07); // linear_sweep( // rect(30), texture=tex, h=quantup(30,10*sqrt(3)), -// tex_size=[10,10*sqrt(3)], tex_scale=3 +// tex_size=[10,10*sqrt(3)], tex_depth=3 // ); // Example(3D): "hex_grid" texture, with approximate scaling because 17 is close to sqrt(3) times 10. // tex = texture("hex_grid"); @@ -2976,7 +3020,7 @@ function associate_vertices(polygons, split, curpoly=0) = // Example(3D): **"ribs"** (Heightfield) = Vertically aligned triangular ribs. Giving `n=` sets the number of heightfield samples to `n` by 1. Default: 2. The choice of style does not matter. // tex = texture("ribs"); // linear_sweep( -// rect(30), texture=tex, h=30, tex_scale=3, +// rect(30), texture=tex, h=30, tex_depth=3, // tex_size=[10,10], style="concave" // ); // Example(3D): **"rough"** (Heightfield) = A pseudo-randomized rough texture. Giving `n=` sets the number of heightfield samples to `n` by `n`. Default: 32. The `roughness=` parameter specifies the height of the random texture. Default: 0.2. @@ -3001,7 +3045,7 @@ function associate_vertices(polygons, split, curpoly=0) = // tex = texture("tri_grid",border=.04); // linear_sweep( // rect(30), texture=tex, h=quantup(30,10*sqrt(3)), -// tex_size=[10,10*sqrt(3)], tex_scale=3 +// tex_size=[10,10*sqrt(3)], tex_depth=3 // ); // Example(3D): "tri_grid" texture. Here scale makes Y approximately sqrt(3) larger than X so triangles are close to equilateral. // tex = texture("tri_grid"); @@ -3043,20 +3087,20 @@ function associate_vertices(polygons, split, curpoly=0) = // tex = texture("trunc_ribs"); // linear_sweep( // rect(30), h=30, texture=tex, -// tex_scale=3, tex_size=[10,10], +// tex_depth=3, tex_size=[10,10], // style="concave" // ); // Example(3D): **"trunc_ribs_vnf"** (VNF) = Vertically aligned triangular ribs with the tops cut off. Giving `gap=` sets the bottom gap between ribs. Giving `border=` specifies that the top rib face is smaller than its base by `border` on both the left and right sides. The gap measures the flat part between ribs and the border the width of the sloping portion. In order to fit, gap+2*border must be less than 1. (This is because the gap is counted once but the border counts on both sides.) Defaults: gap=1/4, border=1/4. // tex = texture("trunc_ribs_vnf", gap=0.25, border=1/6); // linear_sweep( // rect(30), h=30, texture=tex, -// tex_scale=3, tex_size=[10,10] +// tex_depth=3, tex_size=[10,10] // ); // Example(3D): **"wave_ribs"** (Heightfield) = Vertically aligned wavy ribs. Giving `n=` sets the number of heightfield samples to `n` by `1`. Default: 8. The style does not matter. // tex = texture("wave_ribs"); // linear_sweep( // rect(30), h=30, texture=tex, -// tex_size=[10,10], tex_scale=3, style="concave" +// tex_size=[10,10], tex_depth=3, style="concave" // ); function texture(tex, n, border, gap, roughness, inset) = @@ -3612,7 +3656,8 @@ function _textured_linear_sweep( for (vert = group) let( u = floor((j + vert.x) * samples), uu = ((j + vert.x) * samples) - u, - texh = (vert.z - inset) * tex_scale, + texh = tex_scale<0 ? -(1-vert.z - inset) * tex_scale + : (vert.z - inset) * tex_scale, base = lerp(bases[u], select(bases,u+1), uu), norm = unit(lerp(norms[u], select(norms,u+1), uu)), xy = base + norm * texh @@ -3652,7 +3697,8 @@ function _textured_linear_sweep( part = (j + (tj/texcnt.x)) * samples, u = floor(part), uu = part - u, - texh = (texture[ti][tj] - inset) * tex_scale, + texh = tex_scale<0 ? -(1-texture[ti][tj] - inset) * tex_scale + : (texture[ti][tj] - inset) * tex_scale, base = lerp(bases[u], select(bases,u+1), uu), norm = unit(lerp(norms[u], select(norms,u+1), uu)), xy = base + norm * texh @@ -3694,7 +3740,8 @@ function _textured_linear_sweep( part = (j + vert.x) * samples, u = floor(part), uu = part - u, - texh = (vert.y - inset) * tex_scale, + texh = tex_scale<0 ? -(1-vert.y - inset) * tex_scale + : (vert.y - inset) * tex_scale, base = lerp(bases[u], select(bases,u+1), uu), norm = unit(lerp(norms[u], select(norms,u+1), uu)), xy = base + norm * texh @@ -3900,7 +3947,8 @@ function _textured_revolution( base = lerp(select(bases,u), select(bases,u+1), uu), norm = unit(lerp(select(norms,u), select(norms,u+1), uu)), tex_scale = tex_scale * lookup(part/samples/counts_y, taper_lup), - texh = (vert.z - inset) * tex_scale * (base.x / maxx), + texh = tex_scale<0 ? -(1-vert.z - inset) * tex_scale * (base.x / maxx) + : (vert.z - inset) * tex_scale * (base.x / maxx), xyz = base - norm * texh ) zrot(vert.x*angle/counts_x, p=xyz) ] @@ -3926,7 +3974,8 @@ function _textured_revolution( base = lerp(bases[u], select(bases,u+1), uu), norm = unit(lerp(norms[u], select(norms,u+1), uu)), tex_scale = tex_scale * lookup(part/samples/counts_y, taper_lup), - texh = (texture[ti][tj] - inset) * tex_scale * (base.x / maxx), + texh = tex_scale<0 ? -(1-texture[ti][tj] - inset) * tex_scale * (base.x / maxx) + : (texture[ti][tj] - inset) * tex_scale * (base.x / maxx), xyz = base - norm * texh ) xyz ]) @@ -3963,7 +4012,8 @@ function _textured_revolution( base = lerp(select(bases,u), select(bases,u+1), uu), norm = unit(lerp(select(norms,u), select(norms,u+1), uu)), tex_scale = tex_scale * lookup(part/samples/counts_y, taper_lup), - texh = (vert.z - inset) * tex_scale * (base.x / maxx), + texh = tex_scale<0 ? -(1-vert.z - inset) * tex_scale * (base.x / maxx) + : (vert.z - inset) * tex_scale * (base.x / maxx), xyz = base - norm * texh ) xyz ] @@ -3979,7 +4029,8 @@ function _textured_revolution( base = lerp(bases[u], select(bases,u+1), uu), norm = unit(lerp(norms[u], select(norms,u+1), uu)), tex_scale = tex_scale * lookup(part/samples/counts_y, taper_lup), - texh = (texture[ti][0] - inset) * tex_scale * (base.x / maxx), + texh = tex_scale<0 ? -(1-texture[ti][0] - inset) * tex_scale * (base.x / maxx) + : (texture[ti][0] - inset) * tex_scale * (base.x / maxx), xyz = base - norm * texh ) xyz ], @@ -4012,7 +4063,8 @@ function _textured_revolution( for (vert = bpath) let( uang = vert.x / counts_x, tex_scale = tex_scale * lookup([0,1][j+1], taper_lup), - texh = (vert.y - inset) * tex_scale * (base.x / maxx), + texh = tex_scale<0 ? -(1-vert.y - inset) * tex_scale * (base.x / maxx) + : (vert.y - inset) * tex_scale * (base.x / maxx), xyz = base - norm * texh ) zrot(angle*uang, p=xyz) ], From 67cf7e9cb83f20919c5b8c41eb37d10ffc1fa385 Mon Sep 17 00:00:00 2001 From: adrianVmariano Date: Tue, 9 Jan 2024 03:58:40 +0000 Subject: [PATCH 08/13] Version Bump --- version.scad | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.scad b/version.scad index c67907b..4e44f8c 100644 --- a/version.scad +++ b/version.scad @@ -9,7 +9,7 @@ ////////////////////////////////////////////////////////////////////// -BOSL_VERSION = [2,0,682]; +BOSL_VERSION = [2,0,683]; // Section: BOSL Library Version Functions From 1b971dff82885f845b3621932eaa60d5963e332b Mon Sep 17 00:00:00 2001 From: Adrian Mariano Date: Mon, 8 Jan 2024 23:05:41 -0500 Subject: [PATCH 09/13] various fixes --- screws.scad | 3 ++- shapes3d.scad | 16 ++++++++-------- skin.scad | 6 +++--- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/screws.scad b/screws.scad index 0c2e317..8c92b0e 100644 --- a/screws.scad +++ b/screws.scad @@ -1495,7 +1495,8 @@ module screw_head(screw_info,details=false, counterbore=0,flat_height,teardrop=f [20, .165]]; intersection() { cyl(h=head_height/4, d=head_size, anchor=BOT) - attach(TOP) cyl(l=head_height*3/4, d=head_size, anchor=BOT, texture="trunc_ribs", tex_reps=[31,1], tex_scale=-lookup(adj_diam,rib_size)); + attach(TOP) cyl(l=head_height*3/4, d=head_size, anchor=BOT, texture="trunc_ribs", tex_reps=[31,1], + tex_inset=true, tex_depth=-lookup(adj_diam,rib_size)); cyl(h=head_height,d=head_size, chamfer2=adj_diam/10, anchor=BOT); } } diff --git a/shapes3d.scad b/shapes3d.scad index 7429028..bd4183b 100644 --- a/shapes3d.scad +++ b/shapes3d.scad @@ -1292,9 +1292,9 @@ function cylinder(h, r1, r2, center, r, d, d1, d2, anchor, spin=0, orient=UP) = // cyl(l|h|length|height, r|d, rounding1=, rounding2=, ...); // // Usage: Textured Cylinders -// cyl(l|h|length|height, r|d, texture=, [tex_size=]|[tex_reps=], [tex_scale=], [tex_rot=], [tex_samples=], [style=], [tex_taper=], [tex_inset=], ...); -// cyl(l|h|length|height, r1=, r2=, texture=, [tex_size=]|[tex_reps=], [tex_scale=], [tex_rot=], [tex_samples=], [style=], [tex_taper=], [tex_inset=], ...); -// cyl(l|h|length|height, d1=, d2=, texture=, [tex_size=]|[tex_reps=], [tex_scale=], [tex_rot=], [tex_samples=], [style=], [tex_taper=], [tex_inset=], ...); +// cyl(l|h|length|height, r|d, texture=, [tex_size=]|[tex_reps=], [tex_depth=], [tex_rot=], [tex_samples=], [style=], [tex_taper=], [tex_inset=], ...); +// cyl(l|h|length|height, r1=, r2=, texture=, [tex_size=]|[tex_reps=], [tex_depth=], [tex_rot=], [tex_samples=], [style=], [tex_taper=], [tex_inset=], ...); +// cyl(l|h|length|height, d1=, d2=, texture=, [tex_size=]|[tex_reps=], [tex_depth=], [tex_rot=], [tex_samples=], [style=], [tex_taper=], [tex_inset=], ...); // // Usage: Caled as a function to get a VNF // vnf = cyl(...); @@ -1364,7 +1364,7 @@ function cylinder(h, r1, r2, center, r, d, d1, d2, anchor, spin=0, orient=UP) = // texture = A texture name string, or a rectangular array of scalar height values (0.0 to 1.0), or a VNF tile that defines the texture to apply to vertical surfaces. See {{texture()}} for what named textures are supported. // tex_size = An optional 2D target size for the textures. Actual texture sizes will be scaled somewhat to evenly fit the available surface. Default: `[5,5]` // tex_reps = If given instead of tex_size, a 2-vector giving the number of texture tile repetitions in the horizontal and vertical directions. -// tex_inset = If numeric, lowers the texture into the surface by that amount, before the tex_scale multiplier is applied. If `true`, insets by exactly `1`. Default: `false` +// tex_inset = If numeric, lowers the texture into the surface by the specified proportion, e.g. 0.5 would lower it half way into the surface. If `true`, insets by exactly its full depth. Default: `false` // tex_rot = Rotate texture by specified angle, which must be a multiple of 90 degrees. A value of true is equivalent to 90 deg, and false to 0. Default: 0 // tex_depth = Specify texture depth; if negative, invert the texture. Default: 1. // tex_samples = Minimum number of "bend points" to have in VNF texture tiles. Default: 8 @@ -1449,7 +1449,7 @@ function cylinder(h, r1, r2, center, r, d, d1, d2, anchor, spin=0, orient=UP) = // Example: Texturing with VNF tile "bricks_vnf" // cyl(h=50, r1=25, r2=20, shift=[0,10], rounding1=-10, // texture="bricks_vnf", tex_size=[10,10], -// tex_scale=0.5, style="concave"); +// tex_depth=0.5, style="concave"); // // Example: No Texture Taper // cyl(d1=25, d2=20, h=30, rounding=5, @@ -1487,7 +1487,7 @@ function cylinder(h, r1, r2, center, r, d, d1, d2, anchor, spin=0, orient=UP) = // ]; // diff() // cyl(d=20*10/PI, h=10, chamfer=0, -// texture=tex, tex_reps=[20,1], tex_scale=-1, +// texture=tex, tex_reps=[20,1], tex_depth=-1, // tex_taper=undef, style="concave") { // attach([TOP,BOT]) { // cyl(d1=20*10/PI, d2=30, h=5, anchor=BOT) @@ -1628,7 +1628,7 @@ function cyl( ) rotate_sweep(path, texture=texture, tex_reps=tex_reps, tex_size=tex_size, tex_inset=tex_inset, tex_rot=tex_rot, - tex_scale=tex_scale, tex_samples=tex_samples, + tex_depth=tex_depth, tex_samples=tex_samples, tex_taper=tex_taper, style=style, closed=false ), skmat = down(l/2) * @@ -1709,7 +1709,7 @@ module cyl( from_end=from_end, from_end1=from_end1, from_end2=from_end2, teardrop=teardrop, texture=texture, tex_size=tex_size, - tex_reps=tex_reps, tex_scale=tex_scale, + tex_reps=tex_reps, tex_depth=tex_depth, tex_inset=tex_inset, tex_rot=tex_rot, style=style, tex_taper=tex_taper, tex_samples=tex_samples diff --git a/skin.scad b/skin.scad index 4e083c1..790f1c2 100644 --- a/skin.scad +++ b/skin.scad @@ -546,7 +546,7 @@ function skin(profiles, slices, refine=1, method="direct", sampling, caps, close // texture = A texture name string, or a rectangular array of scalar height values (0.0 to 1.0), or a VNF tile that defines the texture to apply to vertical surfaces. See {{texture()}} for what named textures are supported. // tex_size = An optional 2D target size for the textures. Actual texture sizes will be scaled somewhat to evenly fit the available surface. Default: `[5,5]` // tex_reps = If given instead of tex_size, a 2-vector giving the number of texture tile repetitions in the horizontal and vertical directions on the extrusion. -// tex_inset = If numeric, lowers the texture into the surface by that amount, before the tex_depth multiplier is applied. If `true`, insets by exactly `1`. Default: `false` +// tex_inset = If numeric, lowers the texture into the surface by the specified proportion, e.g. 0.5 would lower it half way into the surface. If `true`, insets by exactly its full depth. Default: `false` // tex_rot = Rotate texture by specified angle, which must be a multiple of 90 degrees. A value of true is equivalent to 90 deg, and false to 0. Default: 0 // tex_depth = Specify texture depth; if negative, invert the texture. Default: 1. // tex_samples = Minimum number of "bend points" to have in VNF texture tiles. Default: 8 @@ -872,7 +872,7 @@ function linear_sweep( // texture = A texture name string, or a rectangular array of scalar height values (0.0 to 1.0), or a VNF tile that defines the texture to apply to vertical surfaces. See {{texture()}} for what named textures are supported. // tex_size = An optional 2D target size for the textures. Actual texture sizes will be scaled somewhat to evenly fit the available surface. Default: `[5,5]` // tex_reps = If given instead of tex_size, a 2-vector giving the number of texture tile repetitions in the direction perpendicular to extrusion and in the direction parallel to extrusion. -// tex_inset = If numeric, lowers the texture into the surface by that amount, before the tex_depth multiplier is applied. If `true`, insets by exactly `1`. Default: `false` +// tex_inset = If numeric, lowers the texture into the surface by the specified proportion, e.g. 0.5 would lower it half way into the surface. If `true`, insets by exactly its full depth. Default: `false` // tex_rot = Rotate texture by specified angle, which must be a multiple of 90 degrees. A value of true is equivalent to 90 deg, and false to 0. Default: 0 // tex_depth = Specify texture depth; if negative, invert the texture. Default: 1. // tex_samples = Minimum number of "bend points" to have in VNF texture tiles. Default: 8 @@ -2778,7 +2778,7 @@ function associate_vertices(polygons, split, curpoly=0) = // } // stroke([[12.25,0],[12.25,2]],width=.05,endcaps="arrow2",color="black"); // move([12.35,1])color("black")text("Depth=2", size=0.3,anchor=LEFT); -// } +// } // Continues: // If you want to keep the texture the same size but make the slope // steeper you need to add more points to make the uniform grid fine enough From e9c08b4fbfa76c8aa23874f35ff21a9b1bb2a3c6 Mon Sep 17 00:00:00 2001 From: adrianVmariano Date: Tue, 9 Jan 2024 04:06:02 +0000 Subject: [PATCH 10/13] Version Bump --- version.scad | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.scad b/version.scad index 4e44f8c..14acdcb 100644 --- a/version.scad +++ b/version.scad @@ -9,7 +9,7 @@ ////////////////////////////////////////////////////////////////////// -BOSL_VERSION = [2,0,683]; +BOSL_VERSION = [2,0,684]; // Section: BOSL Library Version Functions From 8781fa1e9304315980939509827241dbf7cac386 Mon Sep 17 00:00:00 2001 From: Adrian Mariano Date: Wed, 10 Jan 2024 23:55:51 -0500 Subject: [PATCH 11/13] change n to $fn for round vnf textures; descriptive error message for abuse of n= or tex_samples --- shapes3d.scad | 2 +- skin.scad | 66 ++++++++++++++++++++++++++++++++------------------- utility.scad | 1 - 3 files changed, 43 insertions(+), 26 deletions(-) diff --git a/shapes3d.scad b/shapes3d.scad index bd4183b..d0eaf07 100644 --- a/shapes3d.scad +++ b/shapes3d.scad @@ -1365,7 +1365,7 @@ function cylinder(h, r1, r2, center, r, d, d1, d2, anchor, spin=0, orient=UP) = // tex_size = An optional 2D target size for the textures. Actual texture sizes will be scaled somewhat to evenly fit the available surface. Default: `[5,5]` // tex_reps = If given instead of tex_size, a 2-vector giving the number of texture tile repetitions in the horizontal and vertical directions. // tex_inset = If numeric, lowers the texture into the surface by the specified proportion, e.g. 0.5 would lower it half way into the surface. If `true`, insets by exactly its full depth. Default: `false` -// tex_rot = Rotate texture by specified angle, which must be a multiple of 90 degrees. A value of true is equivalent to 90 deg, and false to 0. Default: 0 +// tex_rot = Rotate texture by specified angle, which must be a multiple of 90 degrees. Default: 0 // tex_depth = Specify texture depth; if negative, invert the texture. Default: 1. // tex_samples = Minimum number of "bend points" to have in VNF texture tiles. Default: 8 // tex_taper = If given as a number, tapers the texture height to zero over the first and last given percentage of the path. If given as a lookup table with indices between 0 and 100, uses the percentage lookup table to ramp the texture heights. Default: `undef` (no taper) diff --git a/skin.scad b/skin.scad index 790f1c2..529ecd4 100644 --- a/skin.scad +++ b/skin.scad @@ -547,7 +547,7 @@ function skin(profiles, slices, refine=1, method="direct", sampling, caps, close // tex_size = An optional 2D target size for the textures. Actual texture sizes will be scaled somewhat to evenly fit the available surface. Default: `[5,5]` // tex_reps = If given instead of tex_size, a 2-vector giving the number of texture tile repetitions in the horizontal and vertical directions on the extrusion. // tex_inset = If numeric, lowers the texture into the surface by the specified proportion, e.g. 0.5 would lower it half way into the surface. If `true`, insets by exactly its full depth. Default: `false` -// tex_rot = Rotate texture by specified angle, which must be a multiple of 90 degrees. A value of true is equivalent to 90 deg, and false to 0. Default: 0 +// tex_rot = Rotate texture by specified angle, which must be a multiple of 90 degrees. Default: 0 // tex_depth = Specify texture depth; if negative, invert the texture. Default: 1. // tex_samples = Minimum number of "bend points" to have in VNF texture tiles. Default: 8 // style = The style to use when triangulating the surface of the object. Valid values are `"default"`, `"alt"`, or `"quincunx"`. @@ -873,7 +873,7 @@ function linear_sweep( // tex_size = An optional 2D target size for the textures. Actual texture sizes will be scaled somewhat to evenly fit the available surface. Default: `[5,5]` // tex_reps = If given instead of tex_size, a 2-vector giving the number of texture tile repetitions in the direction perpendicular to extrusion and in the direction parallel to extrusion. // tex_inset = If numeric, lowers the texture into the surface by the specified proportion, e.g. 0.5 would lower it half way into the surface. If `true`, insets by exactly its full depth. Default: `false` -// tex_rot = Rotate texture by specified angle, which must be a multiple of 90 degrees. A value of true is equivalent to 90 deg, and false to 0. Default: 0 +// tex_rot = Rotate texture by specified angle, which must be a multiple of 90 degrees. Default: 0 // tex_depth = Specify texture depth; if negative, invert the texture. Default: 1. // tex_samples = Minimum number of "bend points" to have in VNF texture tiles. Default: 8 // style = {{vnf_vertex_array()}} style. Default: "min_edge" @@ -2875,13 +2875,13 @@ function associate_vertices(polygons, split, curpoly=0) = // - VNF Tile textures, which are VNFs that cover the unit square [0,0] x [1,1]. These tend to be slower to render, but allow greater flexibility and precision for shapes that don't align with a grid. // . // In the descriptions below, imagine the textures positioned on the XY plane, so "horizontal" refers to the "sideways" dimensions of the texture and -// "up" and "down" refer to the depth dimension. If a texture is placed on a cylinder the "depth" will become the radial direction and the "horizontal" +// "up" and "down" refer to the depth dimension, perpendicular to the surface being textured. If a texture is placed on a cylinder the "depth" will become the radial direction and the "horizontal" // direction will be the vertical and tangential directions on the cylindrical surface. All horizontal dimensions for VNF textures are relative to the unit square -// on which the textures are defined, so a value of 0.25 for a gap or inset will refer to 1/4 of the texture's full length and/or width. All supported textures appear below in the examples. +// on which the textures are defined, so a value of 0.25 for a gap or border will refer to 1/4 of the texture's full length and/or width. All supported textures appear below in the examples. // Arguments: // tex = The name of the texture to get. // --- -// n = The general number of vertices to use to refine the resolution of the texture. +// n = The number of samples to use for defining a heightfield texture. Depending on the texture, result will be either n x n or 1 x n. Not allowed for VNF textures. See the `tex_samples` argument to {{cyl()}}, {{linear_sweep()}} and {{rotate_sweep()}} for controlling the sampling of VNF textures. // border = The size of a border region on some VNF tile textures. Generally between 0 and 0.5. // gap = The gap between logically distinct parts of some VNF tiles. (ie: gap between bricks, gap between truncated ribs, etc.) // roughness = The amount of roughness used on the surface of some heightfield textures. Generally between 0 and 0.5. @@ -2915,8 +2915,8 @@ function associate_vertices(polygons, split, curpoly=0) = // rect(30), texture=tex, h=30, // tex_size=[10,10] // ); -// Example(3D): **"cones"** (VNF) = Raised conical spikes. Giving `n=` sets `$fn` for the cone (will be rounded to a multiple of 4). Default: 16. Giving `border=` specifies the horizontal border width between the edge of the tile and the base of the cone. The `border` value must be nonnegative and smaller than 0.5. Default: 0. -// tex = texture("cones"); +// Example(3D): **"cones"** (VNF) = Raised conical spikes. Specify `$fn` to set the number of segments on the cone (will be rounded to a multiple of 4). If you use $fa and $fs then the number of segments is determined for the original VNF scale of 1x1. Giving `border=` specifies the horizontal border width between the edge of the tile and the base of the cone. The `border` value must be nonnegative and smaller than 0.5. Default: 0. +// tex = texture("cones", $fn=16); // linear_sweep( // rect(30), texture=tex, h=30, tex_depth=3, // tex_size=[10,10] @@ -2957,13 +2957,13 @@ function associate_vertices(polygons, split, curpoly=0) = // rect(30), texture=tex, h=30, // tex_size=[10,10] // ); -// Example(3D): **"dimples"** (VNF) = Round divots. Giving `n=` sets `$fn` for the curve (will be rounded to a multiple of 4). Default: 16. Giving `border=` specifies the horizontal width of the flat border region between the tile edges and the edge of the dimple. Must be nonnegative and strictly less than 0.5. Default: 0.05. +// Example(3D): **"dimples"** (VNF) = Round divots. Specify `$fn` to set the number of segments on the cone (will be rounded to a multiple of 4). If you use $fa and $fs then the number of segments is determined for the original VNF scale of 1x1. Giving `border=` specifies the horizontal width of the flat border region between the tile edges and the edge of the dimple. Must be nonnegative and strictly less than 0.5. Default: 0.05. // tex = texture("dimples"); // linear_sweep( // rect(30), texture=tex, h=30, // tex_size=[10,10] // ); -// Example(3D): **"dots"** (VNF) = Raised round bumps. Giving `n=` sets `$fn` for the curve (will be rounded to a multiple of 4). Default: 16. Giving `border=` specifies the horizontal width of the flat border region between the tile edge and the edge of the dots. Must be nonnegative and strictly less than 0.5. Default: 0.05. +// Example(3D): **"dots"** (VNF) = Raised round bumps. Specify `$fn` to set the number of segments on the cone (will be rounded to a multiple of 4). If you use $fa and $fs then the number of segments is determined for the original VNF scale of 1x1. Giving `border=` specifies the horizontal width of the flat border region between the tile edge and the edge of the dots. Must be nonnegative and strictly less than 0.5. Default: 0.05. // tex = texture("dots"); // linear_sweep( // rect(30), texture=tex, h=30, @@ -3103,6 +3103,9 @@ function associate_vertices(polygons, split, curpoly=0) = // tex_size=[10,10], tex_depth=3, style="concave" // ); + +__vnf_no_n_mesg=" texture is a VNF so it does not accept n. Set sample rate for VNF textures using the tex_samples parameter to cyl(), linear_sweep() or rotate_sweep()."; + function texture(tex, n, border, gap, roughness, inset) = assert(num_defined([border,inset])<2, "In texture() the 'inset' parameter has been replaced by 'border'. You cannot give both parameters.") let( @@ -3134,7 +3137,7 @@ function texture(tex, n, border, gap, roughness, inset) = each lerpn(1,0,n/4,endpoint=false), ]] : tex=="trunc_ribs_vnf"? - assert(is_undef(n), "trunc_ribs_vnf texture does not accept n") + assert(is_undef(n), str(tex,__vnf_no_n_mesg)) let( border = default(border,1/4)*2, gap = default(gap,1/4) @@ -3180,7 +3183,8 @@ function texture(tex, n, border, gap, roughness, inset) = ], ] : tex=="diamonds_vnf"? - assert(num_defined([n,gap, border, roughness])==0, "diamonds_vnf texture does not accept n, gap, border or roughness") + assert(is_undef(n), str(tex,__vnf_no_n_mesg)) + assert(num_defined([gap, border, roughness])==0, "diamonds_vnf texture does not accept gap, border or roughness") [ [ [0, 1, 1], [1/2, 1, 0], [1, 1, 1], @@ -3202,7 +3206,8 @@ function texture(tex, n, border, gap, roughness, inset) = ] ] : tex=="pyramids_vnf"? - assert(num_defined([n,gap, border, roughness])==0, "pyramids_Vnf texture does not accept n, gap, border or roughness") + assert(is_undef(n), str(tex,__vnf_no_n_mesg)) + assert(num_defined([gap, border, roughness])==0, "pyramids_vnf texture does not accept gap, border or roughness") [ [ [0,1,0], [1,1,0], [1/2,1/2,1], [0,0,0], [1,0,0] ], [ [2,0,1], [2,1,4], [2,4,3], [2,3,0] ] @@ -3218,7 +3223,8 @@ function texture(tex, n, border, gap, roughness, inset) = ] ] : tex=="trunc_pyramids_vnf"? - assert(num_defined([gap, n, roughness])==0, "trunc_pyramids_vnf texture does not accept gap, n or roughness") + assert(is_undef(n), str(tex,__vnf_no_n_mesg)) + assert(num_defined([gap, roughness])==0, "trunc_pyramids_vnf texture does not accept gap, or roughness") let( border = default(border,0.1) ) @@ -3260,7 +3266,8 @@ function texture(tex, n, border, gap, roughness, inset) = ] ] : tex=="bricks_vnf"? - assert(num_defined([n,roughness])==0, "bricks_vnf texture does not accept n or roughness") + assert(is_undef(n), str(tex,__vnf_no_n_mesg)) + assert(num_defined([roughness])==0, "bricks_vnf texture does not accept roughness") let( border = default(border,0.05), gap = default(gap,0.05) @@ -3290,7 +3297,8 @@ function texture(tex, n, border, gap, roughness, inset) = ] ] : tex=="checkers"? - assert(num_defined([gap, n, roughness])==0, "checkers texture does not accept gap, n or roughness") + assert(is_undef(n), str(tex,__vnf_no_n_mesg)) + assert(num_defined([gap, roughness])==0, "checkers texture does not accept gap, or roughness") let( border = default(border,0.05) ) @@ -3318,10 +3326,11 @@ function texture(tex, n, border, gap, roughness, inset) = ] ] : tex=="cones"? + assert(is_undef(n),str("To set number of segments on cones use $fn. ", tex,__vnf_no_n_mesg)) assert(num_defined([gap,roughness])==0, "cones texture does not accept gap or roughness") let( - n = quant(default(n,16),4), - border = default(border,0) + border = default(border,0), + n = quant(segs(1/2-border),4) ) assert(border>=0 && border<0.5) [ @@ -3336,7 +3345,8 @@ function texture(tex, n, border, gap, roughness, inset) = ] ] : tex=="cubes"? - assert(num_defined([n, gap, border, roughness])==0, "cubes texture does not accept n, gap, border or roughness") + assert(is_undef(n), str(tex,__vnf_no_n_mesg)) + assert(num_defined([gap, border, roughness])==0, "cubes texture does not accept gap, border or roughness") [ [ [0,1,1/2], [1,1,1/2], [1/2,5/6,1], [0,4/6,0], [1,4/6,0], @@ -3349,7 +3359,8 @@ function texture(tex, n, border, gap, roughness, inset) = ] ] : tex=="trunc_diamonds"? - assert(num_defined([gap, n, roughness])==0, "trunc_diamonds texture does not accept gap, n or roughness") + assert(is_undef(n), str(tex,__vnf_no_n_mesg)) + assert(num_defined([gap, roughness])==0, "trunc_diamonds texture does not accept gap or roughness") let( border = default(border,0.1)/sqrt(2)*2 ) @@ -3368,10 +3379,11 @@ function texture(tex, n, border, gap, roughness, inset) = ] ] : tex=="dimples" || tex=="dots" ? + assert(is_undef(n),str("To set number of segments on ",tex," use $fn. ", tex,__vnf_no_n_mesg)) assert(num_defined([gap,roughness])==0, str(tex," texture does not accept gap or roughness")) let( - n = quant(default(n,16),4), - border = default(border,0.05) + border = default(border,0.05), + n = quant(segs(1/2-border),4) ) assert(border>=0 && border < 0.5) let( @@ -3401,7 +3413,8 @@ function texture(tex, n, border, gap, roughness, inset) = ] ) [verts, faces] : tex=="tri_grid"? - assert(num_defined([gap, n, roughness])==0, str(tex," texture does not accept gap, n or roughness")) + assert(is_undef(n), str(tex,__vnf_no_n_mesg)) + assert(num_defined([gap, roughness])==0, str(tex," texture does not accept gap or roughness")) let( border = default(border,0.05)*sqrt(3) ) @@ -3439,7 +3452,8 @@ function texture(tex, n, border, gap, roughness, inset) = ] ] : tex=="hex_grid"? - assert(num_defined([gap, n, roughness])==0, str(tex," texture does not accept gap, n or roughness")) + assert(is_undef(n), str(tex,__vnf_no_n_mesg)) + assert(num_defined([gap, roughness])==0, str(tex," texture does not accept gap or roughness")) let( border=default(border,0.1) ) @@ -3574,7 +3588,7 @@ function _validate_texture(texture) = function _textured_linear_sweep( region, texture, tex_size=[5,5], - h, counts, inset=false, rot=false, + h, counts, inset=false, rot=0, tex_scale=1, twist, scale, shift, style="min_edge", l, caps=true, height, length, samples, @@ -3590,6 +3604,8 @@ function _textured_linear_sweep( caps = is_bool(caps) ? [caps,caps] : caps, regions = is_path(region,2)? [[region]] : region_parts(region), tex = is_string(texture)? texture(texture) : texture, + dummy = assert(is_undef(samples) || is_vnf(tex), "You gave the tex_samples argument with a heightfield texture, which is not permitted. Use the n= argument to texture() instead"), + dummy2=is_bool(rot)?echo("boolean value for tex_rot is deprecated. Use a numerical angle, one of 0, 90, 180, or 270.")0:0, texture = !rot? tex : is_vnf(tex)? zrot(is_num(rot)?rot:90, cp=[1/2,1/2], p=tex) : rot==180? reverse([for (row=tex) reverse(row)]) : @@ -3863,6 +3879,8 @@ function _textured_revolution( assert(closed || is_path(shape,2)) let( tex = is_string(texture)? texture(texture) : texture, + dummy = assert(is_undef(samples) || is_vnf(tex), "You gave the tex_samples argument with a heightfield texture, which is not permitted. Use the n= argument to texture() instead"), + dummy2=is_bool(rot)?echo("boolean value for tex_rot is deprecated. Use a numerical angle, one of 0, 90, 180, or 270.")0:0, texture = !rot? tex : is_vnf(tex)? zrot(is_num(rot)?rot:90, cp=[1/2,1/2], p=tex) : rot==180? reverse([for (row=tex) reverse(row)]) : diff --git a/utility.scad b/utility.scad index 1bf6283..2c544a7 100644 --- a/utility.scad +++ b/utility.scad @@ -766,7 +766,6 @@ function scalar_vec3(v, dflt) = is_list(v)? [for (i=[0:2]) default(v[i], default(dflt, 0))] : !is_undef(dflt)? [v,dflt,dflt] : [v,v,v]; - // Function: segs() // Synopsis: Returns the number of sides for a circle given `$fn`, `$fa`, and `$fs`. // Topics: Geometry From d4088bf2a59945f42faddcfabd1289dfa3c12617 Mon Sep 17 00:00:00 2001 From: adrianVmariano Date: Thu, 11 Jan 2024 04:56:33 +0000 Subject: [PATCH 12/13] Version Bump --- version.scad | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.scad b/version.scad index 14acdcb..f01ded2 100644 --- a/version.scad +++ b/version.scad @@ -9,7 +9,7 @@ ////////////////////////////////////////////////////////////////////// -BOSL_VERSION = [2,0,684]; +BOSL_VERSION = [2,0,685]; // Section: BOSL Library Version Functions From d7801edb4e884c634abd47ae1ed1ae0f6ae42e6f Mon Sep 17 00:00:00 2001 From: revarbat Date: Thu, 11 Jan 2024 05:17:23 +0000 Subject: [PATCH 13/13] Version Bump --- version.scad | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.scad b/version.scad index f01ded2..0307d82 100644 --- a/version.scad +++ b/version.scad @@ -9,7 +9,7 @@ ////////////////////////////////////////////////////////////////////// -BOSL_VERSION = [2,0,685]; +BOSL_VERSION = [2,0,686]; // Section: BOSL Library Version Functions