diff --git a/affine.scad b/affine.scad index f829112..2b319ee 100644 --- a/affine.scad +++ b/affine.scad @@ -1,5 +1,5 @@ ////////////////////////////////////////////////////////////////////// -// LibFile: matrices.scad +// LibFile: affine.scad // Matrix math and affine transformation matrices. // To use, add the following lines to the beginning of your file: // ``` diff --git a/attachments.scad b/attachments.scad index 438b899..d7a82eb 100644 --- a/attachments.scad +++ b/attachments.scad @@ -155,7 +155,8 @@ function _str_char_split(s,delim,n=0,acc=[],word="") = // // Example: // #cylinder(d=5, h=10); -// orient_and_anchor([5,5,10], orient=ORIENT_Y, anchor=BACK, orig_anchor=UP) cylinder(d=5, h=10); +// orient_and_anchor([5,5,10], orient=ORIENT_Y, anchor=BACK, orig_anchor=BOTTOM) +// cylinder(d=5, h=10); module orient_and_anchor( size=undef, orient=ORIENT_Z, anchor=CENTER, center=undef, noncentered=BOTTOM, @@ -194,14 +195,21 @@ module orient_and_anchor( ] ) ) : concat( - (anchor==CENTER)? [] : [ - let(anch = find_anchor(anchor, size.z, size, size2=size2, shift=shift, extra_anchors=anchors, geometry=geometry, two_d=two_d)) - affine3d_translate(-anch[1]) - ], (orient==ORIENT_Z)? [] : [ affine3d_xrot(orient.x), affine3d_yrot(orient.y), affine3d_zrot(orient.z) + ], + (anchor==CENTER)? [] : [ + let( + anchr = is_vector(anchor)? rotate_points3d([anchor], orient, reverse=true)[0] : anchor, + anch = find_anchor( + anchr, size.z, size, size2=size2, + shift=shift, extra_anchors=anchors, + geometry=geometry, two_d=two_d + ) + ) + affine3d_translate(rotate_points3d([-anch[1]],orient)[0]) ] ) )); @@ -436,8 +444,8 @@ module intersect(a, b=undef, keep=undef) // Example: // hulling("body") // sphere(d=100, $tags="body") { -// attach(CENTER) cube([40,100,100], anchor=CENTER, $tags="body"); -// attach(CENTER) xcyl(d=40, h=100); +// attach(CENTER) cube([40,90,90], anchor=CENTER, $tags="body"); +// attach(CENTER) xcyl(d=40, h=120, $tags="other"); // } module hulling(a) { diff --git a/debug.scad b/debug.scad index c3a2567..d0b7341 100644 --- a/debug.scad +++ b/debug.scad @@ -66,7 +66,7 @@ module debug_vertices(vertices, size=1, disabled=false) { // faces = Array of faces by vertex numbers. // size = The size of the text used to label the faces and vertices. // disabled = If true, don't draw numbers, and draw children without transparency. Default = false. -// Example: +// Example(EdgesMed): // verts = [for (z=[-10,10], y=[-10,10], x=[-10,10]) [x,y,z]]; // faces = [[0,1,2], [1,3,2], [0,4,5], [0,5,1], [1,5,7], [1,7,3], [3,7,6], [3,6,2], [2,6,4], [2,4,0], [4,6,7], [4,7,5]]; // debug_faces(vertices=verts, faces=faces, size=2) { @@ -130,7 +130,7 @@ module debug_faces(vertices, faces, size=1, disabled=false) { // faces = Array of faces by vertex numbers. // txtsize = The size of the text used to label the faces and vertices. // disabled = If true, act exactly like `polyhedron()`. Default = false. -// Example: +// Example(EdgesMed): // verts = [for (z=[-10,10], a=[0:120:359.9]) [10*cos(a),10*sin(a),z]]; // faces = [[0,1,2], [5,4,3], [0,3,4], [0,4,1], [1,4,5], [1,5,2], [2,5,3], [2,3,0]]; // debug_polyhedron(points=verts, faces=faces, txtsize=1); diff --git a/examples/attachments.scad b/examples/attachments.scad index f208b20..dce1262 100644 --- a/examples/attachments.scad +++ b/examples/attachments.scad @@ -2,7 +2,7 @@ include $fn=32; -cuboid([60,40,40], rounding=5, edges=EDGES_Z_ALL, anchor=BOTTOM) { +cuboid([60,40,40], rounding=5, edges=edges("Z"), anchor=BOTTOM) { attach(TOP, BOTTOM) rounded_prismoid([60,40],[20,20], h=50, r1=5, r2=10) { attach(TOP) cylinder(d=20, h=30) { attach(TOP) cylinder(d1=50, d2=30, h=12); diff --git a/involute_gears.scad b/involute_gears.scad index 6184a88..28b1040 100644 --- a/involute_gears.scad +++ b/involute_gears.scad @@ -144,12 +144,12 @@ function base_radius(mm_per_tooth=5, number_of_teeth=11, pressure_angle=28) // Example(2D): // gear_tooth_profile(mm_per_tooth=5, number_of_teeth=20, pressure_angle=20); module gear_tooth_profile( - mm_per_tooth = 3, //this is the "circular pitch", the circumference of the pitch circle divided by the number of teeth - number_of_teeth = 11, //total number of teeth around the entire perimeter - pressure_angle = 28, //Controls how straight or bulged the tooth sides are. In degrees. - backlash = 0.0, //gap between two meshing teeth, in the direction along the circumference of the pitch circle - bevelang = 0.0, //Gear face angle for bevelled gears. - clearance = undef, //gap between top of a tooth on one gear and bottom of valley on a meshing gear (in millimeters) + mm_per_tooth = 3, + number_of_teeth = 11, + pressure_angle = 28, + backlash = 0.0, + bevelang = 0.0, + clearance = undef, interior = false ) { function polar(r,theta) = r*[sin(theta), cos(theta)]; //convert polar to cartesian coordinates @@ -202,12 +202,12 @@ module gear_tooth_profile( // Example(2D): Partial Gear // gear2d(mm_per_tooth=5, number_of_teeth=20, teeth_to_hide=15, pressure_angle=20); module gear2d( - mm_per_tooth = 3, //this is the "circular pitch", the circumference of the pitch circle divided by the number of teeth - number_of_teeth = 11, //total number of teeth around the entire perimeter - teeth_to_hide = 0, //number of teeth to delete to make this only a fraction of a circle - pressure_angle = 28, //Controls how straight or bulged the tooth sides are. In degrees. - clearance = undef, //gap between top of a tooth on one gear and bottom of valley on a meshing gear (in millimeters) - backlash = 0.0, //gap between two meshing teeth, in the direction along the circumference of the pitch circle + mm_per_tooth = 3, + number_of_teeth = 11, + teeth_to_hide = 0, + pressure_angle = 28, + clearance = undef, + backlash = 0.0, bevelang = 0.0, interior = false ) { @@ -291,17 +291,17 @@ module gear2d( // Example: Beveled Gear // gear(mm_per_tooth=5, number_of_teeth=20, thickness=10*cos(45), hole_diameter=5, twist=-30, bevelang=45, slices=12, $fa=1, $fs=1); module gear( - mm_per_tooth = 3, //this is the "circular pitch", the circumference of the pitch circle divided by the number of teeth - number_of_teeth = 11, //total number of teeth around the entire perimeter - thickness = 6, //thickness of gear in mm - hole_diameter = 3, //diameter of the hole in the center, in mm - teeth_to_hide = 0, //number of teeth to delete to make this only a fraction of a circle - pressure_angle = 28, //Controls how straight or bulged the tooth sides are. In degrees. - clearance = undef, //gap between top of a tooth on one gear and bottom of valley on a meshing gear (in millimeters) - backlash = 0.0, //gap between two meshing teeth, in the direction along the circumference of the pitch circle - bevelang = 0.0, //angle of bevelled gear face. - twist = undef, //teeth rotate this many degrees from bottom of gear to top. 360 makes the gear a screw with each thread going around once - slices = undef, //Number of slices to divide gear into. Useful for refining gears with `twist`. + mm_per_tooth = 3, + number_of_teeth = 11, + thickness = 6, + hole_diameter = 3, + teeth_to_hide = 0, + pressure_angle = 28, + clearance = undef, + backlash = 0.0, + bevelang = 0.0, + twist = undef, + slices = undef, interior = false, orient = ORIENT_Z, anchor = CENTER @@ -310,7 +310,7 @@ module gear( c = outer_radius(mm_per_tooth, number_of_teeth, clearance, interior); r = root_radius(mm_per_tooth, number_of_teeth, clearance, interior); p2 = p - (thickness*tan(bevelang)); - orient_and_anchor([p, p, thickness], orient, anchor, chain=true) { + orient_and_anchor([p, p, thickness], orient, anchor, geometry="cylinder", chain=true) { difference() { linear_extrude(height=thickness, center=true, convexity=10, twist=twist, scale=p2/p, slices=slices) { gear2d( @@ -356,24 +356,48 @@ module gear( // backlash = Gap between two meshing teeth, in the direction along the circumference of the pitch circle // orient = Orientation of the rack. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_X`. // anchor = Alignment of the rack. Use the constants from `constants.scad`. Default: `RIGHT`. +// Anchors: +// "adendum" = At the tips of the teeth, at the center of rack. +// "adendum-left" = At the tips of the teeth, at the left end of the rack. +// "adendum-right" = At the tips of the teeth, at the right end of the rack. +// "adendum-top" = At the tips of the teeth, at the top of the rack. +// "adendum-bottom" = At the tips of the teeth, at the bottom of the rack. +// "dedendum" = At the base of the teeth, at the center of rack. +// "dedendum-left" = At the base of the teeth, at the left end of the rack. +// "dedendum-right" = At the base of the teeth, at the right end of the rack. +// "dedendum-top" = At the base of the teeth, at the top of the rack. +// "dedendum-bottom" = At the base of the teeth, at the bottom of the rack. // Example: // rack(mm_per_tooth=5, number_of_teeth=10, thickness=5, height=5, pressure_angle=20); module rack( - mm_per_tooth = 5, //this is the "circular pitch", the circumference of the pitch circle divided by the number of teeth - number_of_teeth = 20, //total number of teeth along the rack - thickness = 5, //thickness of rack in mm (affects each tooth) - height = 10, //height of rack in mm, from tooth top to back of rack. - pressure_angle = 28, //Controls how straight or bulged the tooth sides are. In degrees. - backlash = 0.0, //gap between two meshing teeth, in the direction along the circumference of the pitch circle + mm_per_tooth = 5, + number_of_teeth = 20, + thickness = 5, + height = 10, + pressure_angle = 28, + backlash = 0.0, clearance = undef, - orient = ORIENT_X, - anchor = RIGHT + orient = ORIENT_Z, + anchor = CENTER ) { a = adendum(mm_per_tooth); d = dedendum(mm_per_tooth, clearance); xa = a * sin(pressure_angle); xd = d * sin(pressure_angle); - orient_and_anchor([(number_of_teeth-1)*mm_per_tooth, height, thickness], orient, anchor, orig_orient=ORIENT_X, chain=true) { + l = number_of_teeth * mm_per_tooth; + anchors = [ + anchorpt("adendum", [0,a,0], BACK), + anchorpt("adendum-left", [-l/2,a,0], LEFT), + anchorpt("adendum-right", [l/2,a,0], RIGHT), + anchorpt("adendum-top", [0,a,thickness/2], UP), + anchorpt("adendum-bottom", [0,a,-thickness/2], DOWN), + anchorpt("dedendum", [0,-d,0], BACK), + anchorpt("dedendum-left", [-l/2,-d,0], LEFT), + anchorpt("dedendum-right", [l/2,-d,0], RIGHT), + anchorpt("dedendum-top", [0,-d,thickness/2], UP), + anchorpt("dedendum-bottom", [0,-d,-thickness/2], DOWN), + ]; + orient_and_anchor([l, 2*abs(a-height), thickness], orient, anchor, anchors=anchors, chain=true) { left((number_of_teeth-1)*mm_per_tooth/2) { linear_extrude(height = thickness, center = true, convexity = 10) { for (i = [0:number_of_teeth-1] ) { diff --git a/joiners.scad b/joiners.scad index 915d671..98da13b 100644 --- a/joiners.scad +++ b/joiners.scad @@ -34,7 +34,7 @@ module half_joiner_clear(h=20, w=10, a=30, clearance=0, overlap=0.01, orient=ORI guide_size = w/3; guide_width = 2*(dmnd_height/2-guide_size)*tan(a); - orient_and_anchor([w, guide_width, h], orient, anchor, orig_orient=ORIENT_Y, chain=true) { + orient_and_anchor([w, guide_width, h], orient, anchor, orig_orient=ORIENT_Y) { union() { yspread(overlap, n=overlap>0? 2 : 1) { difference() { @@ -50,7 +50,6 @@ module half_joiner_clear(h=20, w=10, a=30, clearance=0, overlap=0.01, orient=ORI } if (overlap>0) cube([w+clearance, overlap+0.001, h], center=true); } - children(); } } @@ -87,7 +86,7 @@ module half_joiner(h=20, w=10, l=10, a=30, screwsize=undef, guides=true, slop=PR } } render(convexity=12) - orient_and_anchor([w, 2*l, h], orient, anchor, orig_orient=ORIENT_Y, chain=true) { + orient_and_anchor([w, 2*l, h], orient, anchor, orig_orient=ORIENT_Y) { difference() { union() { // Make base. @@ -133,7 +132,6 @@ module half_joiner(h=20, w=10, l=10, a=30, screwsize=undef, guides=true, slop=PR yrot(90) cylinder(r=screwsize*1.1/2, h=w+1, center=true, $fn=12); } } - children(); } } //half_joiner(screwsize=3, orient=ORIENT_Z, anchor=UP); @@ -171,7 +169,7 @@ module half_joiner2(h=20, w=10, l=10, a=30, screwsize=undef, guides=true, orient } render(convexity=12) - orient_and_anchor([w, 2*l, h], orient, anchor, orig_orient=ORIENT_Y, chain=true) { + orient_and_anchor([w, 2*l, h], orient, anchor, orig_orient=ORIENT_Y) { difference() { union () { fwd(l/2) cube(size=[w, l, h], center=true); @@ -186,7 +184,6 @@ module half_joiner2(h=20, w=10, l=10, a=30, screwsize=undef, guides=true, orient xcyl(r=screwsize*1.1/2, l=w+1, $fn=12); } } - children(); } } @@ -217,12 +214,11 @@ module joiner_clear(h=40, w=10, a=30, clearance=0, overlap=0.01, orient=ORIENT_Y guide_size = w/3; guide_width = 2*(dmnd_height/2-guide_size)*tan(a); - orient_and_anchor([w, guide_width, h], orient, anchor, orig_orient=ORIENT_Y, chain=true) { + orient_and_anchor([w, guide_width, h], orient, anchor, orig_orient=ORIENT_Y) { union() { up(h/4) half_joiner_clear(h=h/2.0-0.01, w=w, a=a, overlap=overlap, clearance=clearance); down(h/4) half_joiner_clear(h=h/2.0-0.01, w=w, a=a, overlap=overlap, clearance=-0.01); } - children(); } } @@ -245,7 +241,7 @@ module joiner_clear(h=40, w=10, a=30, clearance=0, overlap=0.01, orient=ORIENT_Y // anchor = Alignment of the shape by the axis-negative (size1) end. Use the constants from `constants.scad`. Default: `CENTER`. // Examples: // joiner(screwsize=3, orient=ORIENT_X); -// joiner(w=10, l=10, h=40, orient=ORIENT_X) cuboid([10, 10*2, 40], anchor=LEFT); +// joiner(w=10, l=10, h=40, orient=ORIENT_X) cuboid([10, 10*2, 40], anchor=RIGHT); module joiner(h=40, w=10, l=10, a=30, screwsize=undef, guides=true, slop=PRINTER_SLOP, orient=ORIENT_Y, anchor=CENTER) { if ($children > 0) { @@ -254,12 +250,11 @@ module joiner(h=40, w=10, l=10, a=30, screwsize=undef, guides=true, slop=PRINTER joiner_clear(h=h, w=w, a=a, clearance=0.1, orient=orient, anchor=anchor); } } - orient_and_anchor([w, 2*l, h], orient, anchor, orig_orient=ORIENT_Y, chain=true) { + orient_and_anchor([w, 2*l, h], orient, anchor, orig_orient=ORIENT_Y) { union() { up(h/4) half_joiner(h=h/2, w=w, l=l, a=a, screwsize=screwsize, guides=guides, slop=slop); down(h/4) half_joiner2(h=h/2, w=w, l=l, a=a, screwsize=screwsize, guides=guides); } - children(); } } @@ -293,11 +288,10 @@ module joiner_pair_clear(spacing=100, h=40, w=10, a=30, n=2, clearance=0, overla guide_size = w/3; guide_width = 2*(dmnd_height/2-guide_size)*tan(a); - orient_and_anchor([spacing+w, guide_width, h], orient, anchor, orig_orient=ORIENT_Y, chain=true) { + orient_and_anchor([spacing+w, guide_width, h], orient, anchor, orig_orient=ORIENT_Y) { xspread(spacing, n=n) { joiner_clear(h=h, w=w, a=a, clearance=clearance, overlap=overlap); } - children(); } } @@ -322,7 +316,7 @@ module joiner_pair_clear(spacing=100, h=40, w=10, a=30, n=2, clearance=0, overla // orient = Orientation of the shape. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Y`. // anchor = Alignment of the shape by the axis-negative (size1) end. Use the constants from `constants.scad`. Default: `CENTER`. // Examples: -// joiner_pair(spacing=50, l=10, orient=ORIENT_X) cuboid([10, 50+10-0.1, 40], anchor=LEFT); +// joiner_pair(spacing=50, l=10, orient=ORIENT_X) cuboid([10, 50+10-0.1, 40], anchor=RIGHT); // joiner_pair(spacing=50, l=10, n=2, orient=ORIENT_X); // joiner_pair(spacing=50, l=10, n=3, alternate=false, orient=ORIENT_X); // joiner_pair(spacing=50, l=10, n=3, alternate=true, orient=ORIENT_X); @@ -335,7 +329,7 @@ module joiner_pair(spacing=100, h=40, w=10, l=10, a=30, n=2, alternate=true, scr joiner_pair_clear(spacing=spacing, h=h, w=w, a=a, clearance=0.1, orient=orient, anchor=anchor); } } - orient_and_anchor([spacing+w, 2*l, h], orient, anchor, orig_orient=ORIENT_Y, chain=true) { + orient_and_anchor([spacing+w, 2*l, h], orient, anchor, orig_orient=ORIENT_Y) { left((n-1)*spacing/2) { for (i=[0:n-1]) { right(i*spacing) { @@ -345,7 +339,6 @@ module joiner_pair(spacing=100, h=40, w=10, l=10, a=30, n=2, alternate=true, scr } } } - children(); } } @@ -377,13 +370,12 @@ module joiner_quad_clear(xspacing=undef, yspacing=undef, spacing1=undef, spacing { spacing1 = first_defined([spacing1, xspacing, 100]); spacing2 = first_defined([spacing2, yspacing, 50]); - orient_and_anchor([w+spacing1, spacing2, h], orient, anchor, orig_orient=ORIENT_Y, chain=true) { + orient_and_anchor([w+spacing1, spacing2, h], orient, anchor, orig_orient=ORIENT_Y) { zrot_copies(n=2) { back(spacing2/2) { joiner_pair_clear(spacing=spacing1, n=n, h=h, w=w, a=a, clearance=clearance, overlap=overlap); } } - children(); } } @@ -423,13 +415,12 @@ module joiner_quad(spacing1=undef, spacing2=undef, xspacing=undef, yspacing=unde joiner_quad_clear(spacing1=spacing1, spacing2=spacing2, h=h, w=w, a=a, clearance=0.1, orient=orient, anchor=anchor); } } - orient_and_anchor([w+spacing1, spacing2, h], orient, anchor, orig_orient=ORIENT_Y, chain=true) { + orient_and_anchor([w+spacing1, spacing2, h], orient, anchor, orig_orient=ORIENT_Y) { zrot_copies(n=2) { back(spacing2/2) { joiner_pair(spacing=spacing1, n=n, h=h, w=w, l=l, a=a, screwsize=screwsize, guides=guides, slop=slop); } } - children(); } } diff --git a/linear_bearings.scad b/linear_bearings.scad index 72852ca..e4909b5 100644 --- a/linear_bearings.scad +++ b/linear_bearings.scad @@ -80,26 +80,43 @@ function get_lmXuu_bearing_length(size) = lookup(size, [ // anchor = Alignment of the housing by the axis-negative (size1) end. Use the constants from `constants.scad`. Default: `UP` // Example: // linear_bearing_housing(d=19, l=29, wall=2, tab=6, screwsize=2.5); -module linear_bearing_housing(d=15, l=24, tab=7, gap=5, wall=3, tabwall=5, screwsize=3, orient=ORIENT_X, anchor=UP) +module linear_bearing_housing(d=15, l=24, tab=7, gap=5, wall=3, tabwall=5, screwsize=3, orient=ORIENT_X, anchor=BOTTOM) { od = d+2*wall; ogap = gap+2*tabwall; tabh = tab/2+od/2*sqrt(2)-ogap/2; - orient_and_anchor([l, od, od], orient, anchor, orig_orient=ORIENT_X, chain=true) { + h = od+tab/2; + anchors = [ + anchorpt("axis", [0,0,-tab/2/2]), + anchorpt("screw", [0,2-ogap/2,tabh-tab/2/2],FWD), + anchorpt("nut", [0,ogap/2-2,tabh-tab/2/2],FWD) + ]; + orient_and_anchor([l, od, h], orient, anchor, anchors=anchors, orig_orient=ORIENT_X, chain=true) { + down(tab/2/2) difference() { union() { + // Housing zrot(90) teardrop(r=od/2,h=l); - up(tabh) cube(size=[l,ogap,tab+0.05], center=true); - down(od/4) cube(size=[l,od,od/2], center=true); + + // Base + cube([l,od,od/2], anchor=TOP); + + // Tabs + cube([l,ogap,od/2+tab/2], anchor=BOTTOM); } + + // Clear bearing space zrot(90) teardrop(r=d/2,h=l+0.05); - up((d*sqrt(2)+tab)/2) - cube(size=[l+0.05,gap,d+tab], center=true); + + // Clear gap + cube([l+0.05,gap,od], anchor=BOTTOM); + up(tabh) { - fwd(ogap/2-2+0.01) - xrot(90) screw(screwsize=screwsize*1.06, screwlen=ogap, headsize=screwsize*2, headlen=10); - back(ogap/2+0.01) - xrot(90) metric_nut(size=screwsize, hole=false); + // Screwhole + fwd(ogap/2-2+0.01) xrot(90) screw(screwsize=screwsize*1.06, screwlen=ogap, headsize=screwsize*2, headlen=10); + + // Nut holder + back(ogap/2-2+0.01) xrot(90) metric_nut(size=screwsize, hole=false); } } children(); @@ -121,7 +138,7 @@ module linear_bearing_housing(d=15, l=24, tab=7, gap=5, wall=3, tabwall=5, screw // anchor = Alignment of the housing by the axis-negative (size1) end. Use the constants from `constants.scad`. Default: `UP` // Example: // lmXuu_housing(size=10, wall=2, tab=6, screwsize=2.5); -module lmXuu_housing(size=8, tab=7, gap=5, wall=3, tabwall=5, screwsize=3, orient=ORIENT_X, anchor=UP) +module lmXuu_housing(size=8, tab=7, gap=5, wall=3, tabwall=5, screwsize=3, orient=ORIENT_X, anchor=BOTTOM) { d = get_lmXuu_bearing_diam(size); l = get_lmXuu_bearing_length(size); diff --git a/masks.scad b/masks.scad index 76383da..4168eff 100644 --- a/masks.scad +++ b/masks.scad @@ -164,8 +164,8 @@ module cylinder_mask( // anchor = Alignment of the mask. Use the constants from `constants.h`. Default: centered. // Example: // difference() { -// cube(50); -// #chamfer_mask(l=50, chamfer=10, orient=ORIENT_X, anchor=BOTTOM); +// cube(50, anchor=BOTTOM+FRONT); +// #chamfer_mask(l=50, chamfer=10, orient=ORIENT_X); // } module chamfer_mask(l=1, chamfer=1, orient=ORIENT_Z, anchor=CENTER) { orient_and_anchor([chamfer*2, chamfer*2, l], orient, anchor, chain=true) { @@ -188,8 +188,8 @@ module chamfer_mask(l=1, chamfer=1, orient=ORIENT_Z, anchor=CENTER) { // anchor = Alignment of the cylinder. Use the constants from constants.h. Default: centered. // Example: // difference() { -// left(40) cube(80); -// #chamfer_mask_x(l=80, chamfer=20); +// cube(50, anchor=BOTTOM+FRONT); +// #chamfer_mask_x(l=50, chamfer=10); // } module chamfer_mask_x(l=1.0, chamfer=1.0, anchor=CENTER) { chamfer_mask(l=l, chamfer=chamfer, orient=ORIENT_X, anchor=anchor) children(); @@ -209,8 +209,8 @@ module chamfer_mask_x(l=1.0, chamfer=1.0, anchor=CENTER) { // anchor = Alignment of the cylinder. Use the constants from constants.h. Default: centered. // Example: // difference() { -// fwd(40) cube(80); -// right(80) #chamfer_mask_y(l=80, chamfer=20); +// cube(50, anchor=BOTTOM+RIGHT); +// #chamfer_mask_y(l=50, chamfer=10); // } module chamfer_mask_y(l=1.0, chamfer=1.0, anchor=CENTER) { chamfer_mask(l=l, chamfer=chamfer, orient=ORIENT_Y, anchor=anchor) children(); @@ -230,8 +230,8 @@ module chamfer_mask_y(l=1.0, chamfer=1.0, anchor=CENTER) { // anchor = Alignment of the cylinder. Use the constants from constants.h. Default: centered. // Example: // difference() { -// down(40) cube(80); -// #chamfer_mask_z(l=80, chamfer=20); +// cube(50, anchor=FRONT+RIGHT); +// #chamfer_mask_z(l=50, chamfer=10); // } module chamfer_mask_z(l=1.0, chamfer=1.0, anchor=CENTER) { chamfer_mask(l=l, chamfer=chamfer, orient=ORIENT_Z, anchor=anchor) children(); @@ -295,6 +295,11 @@ module chamfer(chamfer=1, size=[1,1,1], edges=EDGES_ALL) // cylinder(r=50, h=100, center=true); // up(50) #chamfer_cylinder_mask(r=50, chamfer=10); // } +// Example: +// difference() { +// cylinder(r=50, h=100, center=true); +// up(50) chamfer_cylinder_mask(r=50, chamfer=10); +// } module chamfer_cylinder_mask(r=undef, d=undef, chamfer=0.25, ang=45, from_end=false, orient=ORIENT_Z) { r = get_radius(r=r, d=d, dflt=1); @@ -325,6 +330,12 @@ module chamfer_cylinder_mask(r=undef, d=undef, chamfer=0.25, ang=45, from_end=fa // up(50) #chamfer_hole_mask(d=50, chamfer=10); // } // Example: +// difference() { +// cube(100, center=true); +// cylinder(d=50, h=100.1, center=true); +// up(50) chamfer_hole_mask(d=50, chamfer=10); +// } +// Example: // chamfer_hole_mask(d=100, chamfer=25, ang=30, overage=10); module chamfer_hole_mask(r=undef, d=undef, chamfer=0.25, ang=45, from_end=false, overage=0.1, orient=ORIENT_Z, anchor=CENTER) { @@ -659,6 +670,12 @@ module rounding_cylinder_mask(r=1.0, rounding=0.25) // cylinder(r=50, h=100.1, center=true); // up(50) #rounding_hole_mask(r=50, rounding=10); // } +// Example(Med): +// difference() { +// cube([150,150,100], center=true); +// cylinder(r=50, h=100.1, center=true); +// up(50) rounding_hole_mask(r=50, rounding=10); +// } // Example: // rounding_hole_mask(r=40, rounding=20, $fa=2, $fs=2); module rounding_hole_mask(r=undef, d=undef, rounding=0.25, overage=0.1, orient=ORIENT_Z, anchor=CENTER) diff --git a/metric_screws.scad b/metric_screws.scad index fe5ba1b..f4d007d 100644 --- a/metric_screws.scad +++ b/metric_screws.scad @@ -393,12 +393,12 @@ module screw( anchor="base" ) { sides = max(12, segs(screwsize/2)); - algn = countersunk? DOWN : anchor; + algn = countersunk? TOP : anchor; anchors = [ anchorpt("base", [0,0,-headlen/2+screwlen/2]), anchorpt("sunken", [0,0,(headlen+screwlen)/2-0.01]) ]; - orient_and_anchor([headsize, headsize, headlen+screwlen], orient, algn, anchors=anchors, chain=true) { + orient_and_anchor([screwsize, screwsize, headlen+screwlen], orient, algn, anchors=anchors, geometry="cylinder", chain=true) { down(headlen/2-screwlen/2) { down(screwlen/2) { if (pitch == undef) { diff --git a/nema_steppers.scad b/nema_steppers.scad index afdc0a5..4273d5b 100644 --- a/nema_steppers.scad +++ b/nema_steppers.scad @@ -100,7 +100,7 @@ function nema_motor_screw_depth(size) = lookup(size, [ // shaft = Shaft diameter. Default: 5mm // shaft_len = Length of shaft protruding out the top of the stepper motor. Default: 20mm // orient = Orientation of the stepper. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Z`. -// anchor = Alignment of the stepper. Use the constants from `constants.scad`. Default: `DOWN`. +// anchor = Alignment of the stepper. Use the constants from `constants.scad`. Default: `TOP`. // Extra Anchors: // "shaft-top" = The top of the shaft. // "shaft-middle" = The middle of the shaft. @@ -112,7 +112,7 @@ function nema_motor_screw_depth(size) = lookup(size, [ // "screw4" = The screw-hole in the X+Y- quadrant. // Example: // nema11_stepper(); -module nema11_stepper(h=24, shaft=5, shaft_len=20, orient=ORIENT_Z, anchor=DOWN) +module nema11_stepper(h=24, shaft=5, shaft_len=20, orient=ORIENT_Z, anchor=TOP) { size = 11; motor_width = nema_motor_width(size); @@ -163,7 +163,7 @@ module nema11_stepper(h=24, shaft=5, shaft_len=20, orient=ORIENT_Z, anchor=DOWN) // shaft = Shaft diameter. Default: 5mm // shaft_len = Length of shaft protruding out the top of the stepper motor. Default: 24mm // orient = Orientation of the stepper. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Z`. -// anchor = Alignment of the stepper. Use the constants from `constants.scad`. Default: `DOWN`. +// anchor = Alignment of the stepper. Use the constants from `constants.scad`. Default: `TOP`. // Extra Anchors: // "shaft-top" = The top of the shaft. // "shaft-middle" = The middle of the shaft. @@ -175,7 +175,7 @@ module nema11_stepper(h=24, shaft=5, shaft_len=20, orient=ORIENT_Z, anchor=DOWN) // "screw4" = The screw-hole in the X+Y- quadrant. // Example: // nema14_stepper(); -module nema14_stepper(h=24, shaft=5, shaft_len=24, orient=ORIENT_Z, anchor=DOWN) +module nema14_stepper(h=24, shaft=5, shaft_len=24, orient=ORIENT_Z, anchor=TOP) { size = 14; motor_width = nema_motor_width(size); @@ -226,7 +226,7 @@ module nema14_stepper(h=24, shaft=5, shaft_len=24, orient=ORIENT_Z, anchor=DOWN) // shaft = Shaft diameter. Default: 5mm // shaft_len = Length of shaft protruding out the top of the stepper motor. Default: 20mm // orient = Orientation of the stepper. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Z`. -// anchor = Alignment of the stepper. Use the constants from `constants.scad`. Default: `DOWN`. +// anchor = Alignment of the stepper. Use the constants from `constants.scad`. Default: `TOP`. // Extra Anchors: // "shaft-top" = The top of the shaft. // "shaft-middle" = The middle of the shaft. @@ -308,7 +308,7 @@ module nema17_stepper(h=34, shaft=5, shaft_len=20, orient=ORIENT_Z, anchor=TOP) // shaft = Shaft diameter. Default: 6.35mm // shaft_len = Length of shaft protruding out the top of the stepper motor. Default: 25mm // orient = Orientation of the stepper. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Z`. -// anchor = Alignment of the stepper. Use the constants from `constants.scad`. Default: `DOWN`. +// anchor = Alignment of the stepper. Use the constants from `constants.scad`. Default: `TOP`. // Extra Anchors: // "shaft-top" = The top of the shaft. // "shaft-middle" = The middle of the shaft. @@ -373,7 +373,7 @@ module nema23_stepper(h=50, shaft=6.35, shaft_len=25, orient=ORIENT_Z, anchor=TO // shaft = Shaft diameter. Default: 12.7mm // shaft_len = Length of shaft protruding out the top of the stepper motor. Default: 32mm // orient = Orientation of the stepper. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Z`. -// anchor = Alignment of the stepper. Use the constants from `constants.scad`. Default: `DOWN`. +// anchor = Alignment of the stepper. Use the constants from `constants.scad`. Default: `TOP`. // Extra Anchors: // "shaft-top" = The top of the shaft. // "shaft-middle" = The middle of the shaft. diff --git a/paths.scad b/paths.scad index e103407..189531f 100644 --- a/paths.scad +++ b/paths.scad @@ -207,16 +207,13 @@ module extrude_from_to(pt1, pt2, convexity=undef, twist=undef, scale=undef, slic // circle(r=40, $fn=6); module extrude_2d_hollow(wall=2, height=50, twist=90, slices=60, center=undef, orient=ORIENT_Z, anchor=BOTTOM) { - orient_and_anchor([0,0,height], orient, anchor, center, chain=true) { - linear_extrude(height=height, twist=twist, slices=slices, center=true) { - difference() { + linear_extrude(height=height, twist=twist, slices=slices, center=true) { + difference() { + children(); + offset(r=-wall) { children(); - offset(r=-wall) { - children(); - } } } - children(); } } @@ -427,7 +424,7 @@ module trace_polyline(pline, N=1, showpts=false, size=1, color="yellow") { // points = The array of 2D polygon vertices. // paths = The path connections between the vertices. // convexity = The max number of walls a ray can pass through the given polygon paths. -// Example(2D): +// Example(Big2D): // debug_polygon( // points=concat( // path2d_regular_ngon(r=10, n=8), diff --git a/scripts/docs_gen.py b/scripts/docs_gen.py index c534789..758399a 100755 --- a/scripts/docs_gen.py +++ b/scripts/docs_gen.py @@ -145,11 +145,14 @@ class ImageProcessing(object): "--imgsize={}".format(imgsizes[0]), "--hardwarnings", "--projection=o", - "--view=axes,scales", "--autocenter", "--viewall", "--camera", eye+",0,0,0" ] + if "Edges" in extype: # Force render + scadcmd.extend(["--view=axes,scales,edges"]) + else: + scadcmd.extend(["--view=axes,scales"]) if "FR" in extype: # Force render scadcmd.extend(["--render", ""]) scadcmd.append(scriptfile) @@ -174,12 +177,15 @@ class ImageProcessing(object): "--imgsize={}".format(imgsizes[0]), "--hardwarnings", "--projection=o", - "--view=axes,scales", "--autocenter", "--viewall" ] if "2D" in extype: # 2D viewpoint scadcmd.extend(["--camera", "0,0,0,0,0,0,500"]) + if "Edges" in extype: # Force render + scadcmd.extend(["--view=axes,scales,edges"]) + else: + scadcmd.extend(["--view=axes,scales"]) if "FR" in extype: # Force render scadcmd.extend(["--render", ""]) scadcmd.append(scriptfile) diff --git a/shapes.scad b/shapes.scad index c61efe1..76d3a4c 100644 --- a/shapes.scad +++ b/shapes.scad @@ -779,7 +779,7 @@ module tube( od=undef, od1=undef, od2=undef, ir=undef, id=undef, ir1=undef, ir2=undef, id1=undef, id2=undef, - center=undef, orient=ORIENT_Z, anchor=UP, + center=undef, orient=ORIENT_Z, anchor=BOTTOM, realign=false ) { r1 = first_defined([or1, od1/2, r1, d1/2, or, od/2, r, d/2, ir1+wall, id1/2+wall, ir+wall, id/2+wall]); @@ -1128,7 +1128,7 @@ module pie_slice( ang=30, l=undef, r=10, r1=undef, r2=undef, d=undef, d1=undef, d2=undef, - orient=ORIENT_Z, anchor=UP, + orient=ORIENT_Z, anchor=BOTTOM, center=undef, h=undef ) { l = first_defined([l, h, 1]); @@ -1263,9 +1263,9 @@ module slot( // center = If given and true, centers vertically. If given and false, drops flush with XY plane. Overrides `anchor`. // $fn2 = The `$fn` value to use on the small round endcaps. The major arcs are still based on `$fn`. Default: `$fn` // -// Example: Typical Arced Slot +// Example(Med): Typical Arced Slot // arced_slot(d=60, h=5, sd=10, sa=60, ea=280); -// Example: Conical Arced Slot +// Example(Med): Conical Arced Slot // arced_slot(r=60, h=5, sd1=10, sd2=15, sa=45, ea=180); module arced_slot( r=undef, d=undef, h=1.0, diff --git a/sliders.scad b/sliders.scad index 667555a..f7f706e 100644 --- a/sliders.scad +++ b/sliders.scad @@ -29,7 +29,7 @@ // anchor = Alignment of the slider. Use the constants from `constants.scad`. Default: `UP`. // Example: // slider(l=30, base=10, wall=4, slop=0.2, orient=ORIENT_Y); -module slider(l=30, w=10, h=10, base=10, wall=5, ang=30, slop=PRINTER_SLOP, orient=ORIENT_Y, anchor=UP) +module slider(l=30, w=10, h=10, base=10, wall=5, ang=30, slop=PRINTER_SLOP, orient=ORIENT_Y, anchor=BOTTOM) { full_width = w + 2*wall; full_height = h + base; @@ -37,18 +37,18 @@ module slider(l=30, w=10, h=10, base=10, wall=5, ang=30, slop=PRINTER_SLOP, orie orient_and_anchor([full_width, l, h+2*base], orient, anchor, orig_orient=ORIENT_Y, chain=true) { down(base+h/2) { // Base - cuboid([full_width, l, base-slop], chamfer=2, edges=edges([FRONT,BACK], except=BOT), anchor=UP); + cuboid([full_width, l, base-slop], chamfer=2, edges=edges([FRONT,BACK], except=BOT), anchor=BOTTOM); // Wall xflip_copy(offset=w/2+slop) { - cuboid([wall, l, full_height], chamfer=2, edges=edges(RIGHT, except=BOT), anchor=UP+RIGHT); + cuboid([wall, l, full_height], chamfer=2, edges=edges(RIGHT, except=BOT), anchor=BOTTOM+LEFT); } // Sliders up(base+h/2) { xflip_copy(offset=w/2+slop+0.02) { bev_h = h/2*tan(ang); - prismoid([l, h], [l-w, 0], h=bev_h+0.01, orient=ORIENT_XNEG, anchor=LEFT); + prismoid([l, h], [l-w, 0], h=bev_h+0.01, orient=ORIENT_XNEG, anchor=RIGHT); } } } @@ -73,7 +73,7 @@ module slider(l=30, w=10, h=10, base=10, wall=5, ang=30, slop=PRINTER_SLOP, orie // anchor = Alignment of the rail. Use the constants from `constants.scad`. Default: `UP`. // Example: // rail(l=100, w=10, h=10); -module rail(l=30, w=10, h=10, chamfer=1.0, ang=30, orient=ORIENT_Y, anchor=UP) +module rail(l=30, w=10, h=10, chamfer=1.0, ang=30, orient=ORIENT_Y, anchor=BOTTOM) { attack_ang = 30; attack_len = 2; @@ -99,7 +99,7 @@ module rail(l=30, w=10, h=10, chamfer=1.0, ang=30, orient=ORIENT_Y, anchor=UP) y1 = l/2; y2 = y1 - attack_len * cos(attack_ang); - orient_and_anchor([w, l, h], orient, anchor, orig_orient=ORIENT_Y, chain=true) { + orient_and_anchor([w, h, l], orient, anchor, orig_orient=ORIENT_Y, chain=true) { polyhedron( convexity=4, points=[ diff --git a/threading.scad b/threading.scad index 50a003a..47b0e18 100644 --- a/threading.scad +++ b/threading.scad @@ -97,7 +97,7 @@ module thread_helix(base_d, pitch, thread_depth=undef, thread_angle=15, twist=72 // trapezoidal_threaded_rod(d=10, l=40, pitch=3, thread_angle=15, left_handed=true, starts=3, $fn=36); // trapezoidal_threaded_rod(d=25, l=40, pitch=10, thread_depth=8/3, thread_angle=50, starts=4, center=false, $fa=2, $fs=2); // trapezoidal_threaded_rod(d=50, l=35, pitch=8, thread_angle=30, starts=3, bevel=true); -// trapezoidal_threaded_rod(l=25, d=10, pitch=2, thread_angle=15, starts=3, $fa=1, $fs=1, orient=ORIENT_X, anchor=UP); +// trapezoidal_threaded_rod(l=25, d=10, pitch=2, thread_angle=15, starts=3, $fa=1, $fs=1, orient=ORIENT_X, anchor=BOTTOM); module trapezoidal_threaded_rod( d=10, l=100, @@ -872,7 +872,7 @@ module pco1881_neck(wall=2, orient=ORIENT_Z, anchor="support-ring") // "inside-top" = Centered on the inside top of the cap. // Example: // pco1881_cap(); -module pco1881_cap(wall=2, orient=ORIENT_Z, anchor=TOP) +module pco1881_cap(wall=2, orient=ORIENT_ZNEG, anchor=BOTTOM) { $fn = segs(33/2); w = 28.58 + 2*wall; diff --git a/walls.scad b/walls.scad index 3e6cb38..27b0c52 100644 --- a/walls.scad +++ b/walls.scad @@ -33,7 +33,7 @@ // // Example: // narrowing_strut(w=10, l=100, wall=5, ang=30); -module narrowing_strut(w=10, l=100, wall=5, ang=30, orient=ORIENT_Y, anchor=FRONT) +module narrowing_strut(w=10, l=100, wall=5, ang=30, orient=ORIENT_Y, anchor=BOTTOM) { h = wall + w/2/tan(ang); size = [w, h, l];