// -*- C -*- include include ply_th = 18; ply_hole_dia = 15; ply_edge_min = 10; ply_hole_dia_real = 12; tile_th = 3; post_dia = 8; post_shorter = 1; $screw_dia = 3.2; screw_big_dia = 3.6; screw_big_len = 4.0; round_edge_rad = 2.0; round_cnr_rad = 10; interlock_dia = 10; interlock_fine = 0.66; interlock_fine_slope = 1.0; interlock_fine_lenslop = 1.0; demo_slop = 0.1; leg_height = 53.75 - 0.95; leg_hole_dia = 5 + 0.75; leg_big_dia = 37; leg_bot_dia = 15; leg_top_flat_z = 2; leg_top_thick = 8; leg_midspc_dia = 20; leg_bot_thick = 8; leg_bot_mid_dia = 12; leg_fin_top_w = 3; leg_fin_bot_w = 5; leg_fin_bot_rad = 30; leg_fin_bot_flat_z = 5; leg_n_fins = 4; leg_n_tubules = 4; leg_tubule_dia = 4; // spacer spacer_ext_slop = 0.25; spacer_int_slop = 0.25; spacer_height = 10; // cutout machine_rear_to_front = 84 + 0.25 - 1.4; cutout_l_end_y_front_slop = 0.5; cutout_l_end_y_rear_slop = 0.5; cutout_l_end_x = 22; cutout_l_end_y = machine_rear_to_front; cutout_l_end_new_x_slop = 1.4 - 1.95; cutout_l_end_y_total = cutout_l_end_y + cutout_l_end_y_front_slop + cutout_l_end_y_rear_slop; tile02_tr = [-250, 0]; tile01_tr = [ 0, 0]; cutout_tile01_y = 170 - 147 + cutout_l_end_y_front_slop; cutout_tile11_y = cutout_l_end_y_total - cutout_tile01_y; // front and rear curves rearedge_len = 170 + 0.70; frontedge_len = 170; rearcurve_strt_len = 52; rearcurve_z_slop = -0.50; rearcurve_avoid_y = 35; rearcurve_double_inrad = 26.10 + 8.04; reartablet_z = 2.54; reartablet_x = 5 + 1; reartablet_y = 8; frontcurve_side_skew = 3.5 / 72; frontcurve_avoid_y = 70; frontcurve_z_slop = 0.75; frontcurve_strt_len = 50; frontcurve_dualcurve_angle = 30; teststrapslots_at = [ [ 110, 70 ], [ 110, -35 ], [ 180, 90 ], [ 190, -80 ], // do not change index of this one [ 0, 70 ], [ 0, -35 ], ]; teststrap = [ 3, 5 ]; teststrap_peg = [7.5, 3.5]; ply_edge_hole_dist_real = 14; // calculated TEST = false; JIG = false; ply_edge_hole_dist = ply_edge_min + ply_hole_dia/2; echo(str("HOLES IN PLY ctr dist from PLY edge = ", ply_edge_hole_dist)); hole_slop = (ply_hole_dia - post_dia)/2; tile_hard_edge_hole_dist = ply_edge_hole_dist + hole_slop; echo(str("HOLES IN PLY ctr dist from TILE HARD edge = ", tile_hard_edge_hole_dist)); echo(str("HOLES IN PLY ctr dist from TILE ROUND edge = ", tile_hard_edge_hole_dist + round_edge_rad)); thehd = [ tile_hard_edge_hole_dist, tile_hard_edge_hole_dist ]; thehd_tr = thehd; thehd_tl = [ -thehd_tr[0], thehd_tr[1] ]; thehd_bl = -thehd_tr; thehd_br = -thehd_tl; tablet_z_slop = 1.00; interlock_rad = interlock_dia/2; interlock_negative_rad = interlock_rad + 0.125; interlock_sq_adj = 0.2; // arbitrary leg_fin_top_rad = sqrt( pow(leg_big_dia/2,2) - pow(leg_fin_top_w/2,2) ); leg_tubule_pos_rad = leg_big_dia/2 * 0.6; m4_define(`POST_TCROSSSZ', `2*( tile_hard_edge_hole_dist - test_edge + 1 )') module Post(){ mirror([0,0,1]) { if (!JIG) { difference(){ cylinder(r= post_dia/2, h= tile_th + ply_th - post_shorter); translate([0,0, tile_th]) { cylinder(r= screw_big_dia/2, h= screw_big_len); cylinder(r= $screw_dia/2, h= ply_th, $fn=20); } } } if (TEST) { translate([0,0, tile_th/2]) { cube([post_dia, POST_TCROSSSZ, tile_th], center=true); cube([POST_TCROSSSZ, post_dia, tile_th], center=true); } } if (JIG) { translate([0,0, tile_th/2]) { cube([POST_TCROSSSZ, POST_TCROSSSZ, tile_th], center=true); } } } } module PostHole(){ if (JIG) { translate([0,0,-5]) cylinder(r= post_dia/2 + jig_post_hole_slop, h=10); translate([0,0, -jig_min_th]) cylinder(r= ply_hole_dia_real/2, h = 5); for (rot=[0:90:270]) rotate(rot) { translate([ ply_edge_hole_dist_real, 0, 0 ]) cube([ jig_pencil_rad*2, jig_pencil_slotlen, 20 ], center=true); } } } module Posts(posts) { for (p= posts) { translate(concat(p, [0])) Post(); } } module PostHoles(posts) { for (p= posts) { translate(concat(p, [0])) PostHole(); } } module TileBase(botleft, topright){ size = topright - botleft; botleft_post = botleft + thehd_tr; topright_post = topright + thehd_bl; difference(){ mirror([0,0,1]) translate(concat(botleft, [0])) cube(concat(size, [tile_th])); if (!(TEST || JIG)) { cidsz = topright_post-botleft_post + [-post_dia,-post_dia] + [0, thehd[1]]; cidszr = [ min(cidsz[0],50), min(cidsz[1],50) ]; echo("CID",cidsz,cidszr); translate( concat(botleft_post, [ -tile_th ]) + 0.5 * [ post_dia, post_dia, 0 ] + 0.5 * concat( cidsz - cidszr, [ 0 ]) ) Commitid_BestCount_M(cidszr); } if ((TEST || JIG)) { crossoff = tile_hard_edge_hole_dist + POST_TCROSSSZ/2; cidsz = [ thehd[0], size[1] - 2*crossoff ]; cidszr = [ cidsz[0], min(cidsz[1], 50) ]; if (TEST) translate( concat(botleft + [0, crossoff] + (cidsz-cidszr)/2, [0]) ) Commitid_BestCount(cidszr); difference(){ mirror([0,0,1]) { translate(concat(botleft + [test_edge,test_edge], [test_tile_th])) cube(concat(size - [test_edge,test_edge]*2, [tile_th*2])); translate(concat(botleft_post, [-1])) cube(concat(topright_post-botleft_post, [tile_th+2])); } shufflesz = max(test_edge, tile_hard_edge_hole_dist)*2; minkowski(){ MachineEnvelope(); cube(shufflesz, center=true); } if (JIG) { translate([0,0,-20]) linear_extrude(height=20) { for (diag=[[ +1, botleft ], [ -1, [topright[0], botleft[1]] ]]) { translate(diag[1]) rotate(atan2(size[1], diag[0] * size[0])) translate([0, -test_edge/2]) square([vectorlen2d(size), test_edge]); } } } } } } } m4_dnl R_EDGE(c,ix) m4_dnl c is from Rectangle_corners and m4_dnl ix is a corner number m4_dnl expands to two comma-separated corners: m4_dnl that denoted by ix, and the next one anticlockwise m4_define(`R_EDGE',`$1[$2], $1[(($2)+1)%4]') m4_dnl R_CNR(c,ix) m4_dnl c is from Rectangle_corners and m4_dnl ix is a corner number m4_dnl expands to an array of corners as for RoundCorner m4_define(`R_CNR',`[ $1[$2], $1[(($2)+1)%4], $1[(($2)+3)%4] ]') m4_dnl INREFFRAME(left_cnr, right_cnr, morevars) { body; } m4_define(`INREFFRAME',` length_vec = ($2) - ($1); length = dist2d([0,0], length_vec); length_uvec = length_vec / length; ortho_uvec = [ -length_uvec[1], length_uvec[0] ]; m = [ [ length_uvec[0], ortho_uvec[0], 0, ($1)[0], ], [ length_uvec[1], ortho_uvec[1], 0, ($1)[1], ], [ 0, 0, 1, 0, ], [ 0, 0, 0, 1, ] ]; $3 multmatrix(m) ') m4_dnl INREFFRAME(left_cnr, right_cnr, morevars) m4_dnl INREFFRAME_EDGE { body; } m4_define(`INREFFRAME_EDGE',` translate([0,0, -round_edge_rad]) ') module RoundEdge(left_cnr, right_cnr) { INREFFRAME(left_cnr, right_cnr) INREFFRAME_EDGE { difference(){ rotate([0,90,0]) cylinder(r= round_edge_rad, h= length, $fn=50); translate([-1, 0, -20]) cube([length+2, 20, 20]); } } } m4_define(`ROUNDCORNER_VARS',` this_cnr = ci[0]; right_cnr = ci[1]; left_cnr = ci[2]; bigr= round_cnr_rad - round_edge_rad; l_uvec = unitvector2d(left_cnr - this_cnr); r_uvec = unitvector2d(right_cnr - this_cnr); lp1 = left_cnr + clockwise2d(l_uvec) * bigr; lp2 = this_cnr + clockwise2d(l_uvec) * bigr; lp3 = this_cnr - clockwise2d(r_uvec) * bigr; lp4 = right_cnr - clockwise2d(r_uvec) * bigr; ctr = line_intersection_2d(lp1,lp2,lp3,lp4); ctr3 = concat(ctr,[0]) ') module RoundCorner_selector(ci, adj) { ROUNDCORNER_VARS; intersection(){ union(){ INREFFRAME(ctr3,concat(lp1,[4])){ translate([0,0,-bigr]) linear_extrude(height=bigr*2) { translate([-bigr*2 + adj, -bigr]) square([bigr*2, bigr*3]); } } } union(){ INREFFRAME(ctr3,concat(lp4,[0])){ translate([0,0,-bigr]) linear_extrude(height=bigr*2) { translate([-bigr*2, -bigr*2]) square([bigr*2 + adj, bigr*3]); } } } } } module RoundCornerCut(ci) { // ci should be [this_cnr, right_cnr, left_cnr] // where right_cnr is to the right (ie, anticlockwise) ROUNDCORNER_VARS; difference(){ RoundCorner_selector(ci, -0.1); translate(ctr3) cylinder(center=true, h=20, r= bigr); } } module RoundCornerAdd(ci) { ROUNDCORNER_VARS; intersection(){ RoundCorner_selector(ci, +0.1); INREFFRAME_EDGE { translate(ctr3){ rotate_extrude(convexity=10, $fn=50) translate([bigr, 0]) difference(){ circle(r= round_edge_rad, $fn=50); mirror([1,1]) square([20,20]); } } } } } module InterlockLobePlan(negative) { r = negative ? interlock_negative_rad : interlock_rad; ymir = negative ? 0 : 1; dx = sqrt(3) * r; $fn= 80; translate([thehd[0], 0]){ mirror([0,ymir]){ circle(r=r); difference(){ translate([-dx, -0.1]) square([ dx*2, r/2 + 0.1 ]); for (xi = [-1, 1]) { translate([ xi*dx, r ]) circle(r=r); } } } } } module InterlockEdgePlan(negative, nlobes, length, dosquare=true) { for (lobei = [ 0 : nlobes-1 ]) { lobex = (length - thehd[0]*2) * (lobei ? lobei / (nlobes-1) : 0); translate([lobex, 0, 0]) { InterlockLobePlan(negative); } } if (dosquare) { iadj = 0; slotshorter = negative ? -0.1 : interlock_fine_lenslop; mirror([0, negative]) translate([slotshorter, iadj]) square([length - slotshorter*2, interlock_fine + iadj*2]); } } module InterlockEdge(left_cnr, right_cnr, negative=0, nlobes=2) { plusth = negative * 1.0; protr = interlock_fine + interlock_sq_adj; z2 = -tile_th/2; z1 = -tile_th/2 - protr / interlock_fine_slope; z3 = -tile_th/2 + protr / interlock_fine_slope; negsign = negative ? -1 : +1; yprotr = negsign * protr; INREFFRAME(left_cnr, right_cnr) { for (vsect = [ // zs0 zs1 ys0, ys1 [ -tile_th-plusth, plusth, 0, 0], [ z1, z2, 0, yprotr], [ z2, z3, yprotr, 0], ]) { zs0 = vsect[0]; zs1 = vsect[1]; zsd = zs1-zs0; ys0 = vsect[2]; ys1 = vsect[3]; ysd = ys1-ys0; sl = ysd/zsd; m = [ [ 1,0, 0, 0 ], [ 0,1, -sl, -ys0 + negsign*interlock_sq_adj ], [ 0,0, 1, zs0 ], [ 0,0, 0, 1 ] ]; multmatrix(m) linear_extrude(height=zsd, convexity=10) InterlockEdgePlan(negative, nlobes, length, !!ysd); } } } function TestPiece_holes2corners(holes) = [ holes[0] + thehd_bl, holes[1] + thehd_br, holes[1] + thehd_tr, holes[0] + thehd_tl ]; module TestPiece1(){ ////toplevel holes = [ [-100, 0], [ 0, 0] ]; corners = TestPiece_holes2corners(holes); rcs = R_CNR(corners,0); difference(){ union(){ TileBase(corners[0], corners[2]); Posts(holes); RoundEdge(corners[0], corners[1]); RoundEdge(corners[3], corners[0]); } InterlockEdge(corners[1], corners[2], 1, nlobes=1); RoundCornerCut(rcs); PostHoles(holes); } RoundCornerAdd(rcs); } module TestPiece2(){ ////toplevel holes = [ [ 0, 0], [ 50, 0] ]; corners = TestPiece_holes2corners(holes); difference(){ union(){ TileBase(corners[0], corners[2]); Posts(holes); RoundEdge(corners[0], corners[1]); InterlockEdge(corners[3], corners[0], 0, nlobes=1); } PostHoles(holes); } } module TestDemo(){ ////toplevel translate([ -thehd[0], 0 ]) color("blue") TestPiece1(); translate([ +thehd[0] + demo_slop, 0 ]) TestPiece2(); } module PostTestPiece(){ ////toplevel hole_sizes = [2.8, 3.0, 3.1, 3.134, 3.168, 3.2, 3.3, 3.5]; nholes = len(hole_sizes)*2; nrows = 4; stride = post_dia*1.5; rect_sz = stride * [ nrows, ceil(nholes/nrows) ]; corners = Rectangle_corners(-stride * 0.5 * [1,1], rect_sz); difference(){ union(){ TileBase(corners[0], corners[2]); RoundEdge(corners[0], corners[1]); for (i= [ 0: nholes-1 ]) { $screw_dia = hole_sizes[ floor(i/2) ]; translate(stride * [ (nrows-1) - (i % nrows), floor(i / nrows), 0 ]) { Posts([[0,0]]); color("blue") mirror([0,0,1]) translate([post_dia/2, -post_dia/2, 1]) cube([1, post_dia * (i / nholes), tile_th]); } } } } } module Machine_NewRearProfile(){ // figures copied out of xfig edit boxes // best not to edit the posbox size if poss - just move it posbox = 10 * ([7.2333,-14.1267] - [-16.2289,40.0289]); // box, Green sideline = -10 * ([-6.2400,13.5600] - [-2.4467,28.2556]); // line, Blue scaleline = 10 * dist2d([-1.1911,-20.4800], [-11.2600,4.0578]); // Green2 scaleline_mm = 12+5+10+5+3; sh = -[abs(posbox[0]), abs(posbox[1])]; rot = atan2(-sideline[0], sideline[1]); sc = scaleline_mm / scaleline; //echo("SH",sh,rot,sc); scale(sc) rotate(rot) translate(sh){ import("sewing-table-rear-profile.dxf", convexity=10); // spline, Pink3 } } module Machine_NewFrontProfile(){ // figures copied out of xfig edit boxes // best not to edit the posbox size if poss - just move it posbox = 10 * ([11.8022,8.0600] - [4.2044,19.1867]); // box, Green refline = 10 * ([7.6778,16.7222] - [27.8689,17.6578]); // line, Blue refline_mm = (11-1)*10; sh = -[abs(posbox[0]), abs(posbox[1])]; rot = atan2(-refline[0], refline[1]); sc = refline_mm / vectorlen2d(refline); //echo("SH",sh,rot,sc); mirror([1,0]) scale(sc) rotate(rot+90) translate(sh){ import("sewing-table-front-profile.dxf", convexity=10); // spline, Pink3 } } module Machine_NewEndProfile(){ // figures copied out of xfig edit boxes // NB that y coords are reversed - xfig origin is at bottom left posboxs = 10 * [[4.0400,17.7956], [11.6622,32.5511]]; // box, Pink3 refline = 10 * ([8.4000,22.6000] - [50.3000,22.2000]); // line, Blue refline_mm = 10 * (11 - 2.5); sidelines = 10 * [[[9.0889,20.6178], [8.9644,14.6889]], [[50.3800,21.9578], [50.1933,14.4933]]]; // lines, Blue3 baseline = 10 * [[8.4000,18.0822], [50.3000,17.6822]]; // line, Green2 rot_adj = -0.38; posbox = [min(posboxs[0][0],posboxs[1][0]), max(posboxs[0][1],posboxs[1][1])]; m4_define(`MNEP_ELP', `line_intersection_2d(baseline[0],baseline[1], sidelines[$1][0],sidelines[$1][1])') endline = [MNEP_ELP(0),MNEP_ELP(1)]; rot = atan2(-refline[1], -refline[0]); sc = refline_mm / vectorlen2d(refline); sh = (0.5 * (endline[0] + endline[1])) - posbox; ellen = sc * dist2d(endline[0],endline[1]); scy = cutout_l_end_y_total / ellen; scale([scy,1]) scale(sc) rotate(rot + rot_adj) translate(-[sh[0],-sh[1]]){ mirror([0,1]){ //%translate(1 * (posboxs[0] - posbox)) square(50); //%translate(1 * (posboxs[1] - posbox)) square(50); // %translate(1 * (baseline[0] - posbox)) square([50,10]); // %translate(1 * (endline[0] - posbox)) square([50,10]); // %translate(1 * (endline[1] - posbox)) square([50,10]); // %translate(1 * (sidelines[0][0] - posbox)) square([10,50]); // %translate(1 * (sidelines[0][1] - posbox)) square([10,50]); // %translate(1 * (sidelines[1][0] - posbox)) square([10,50]); // %translate(1 * (sidelines[1][1] - posbox)) square([10,50]); } import("sewing-table-end-profile.dxf", convexity=10); // spline, Pink3 } } module Machine_NewEndProfileDemo(){ ////toplevel translate([0,5,0]) Machine_NewEndProfile(); translate([0,5,1]) color("blue") mirror([1,0]) Machine_NewEndProfile(); mirror([0,1,0]){ translate([0,5, 0]) Machine_NewEndProfile(); translate([0,5,-1]) color("blue") mirror([1,0]) Machine_NewEndProfile(); } } module Machine_NewArm(){ translate([0,0,-30]) linear_extrude(height=60) { translate(tile01_tr + [ -cutout_l_end_x - cutout_l_end_new_x_slop, (-cutout_tile01_y + cutout_tile11_y)/2 ]){ rotate(-90){ hull(){ for (d=[0,400]) translate([0,d]) Machine_NewEndProfile(); } } } } } module Machine_NewRearCurve(){ slant = atan2(4,210-10); //echo("SL",slant); translate([0,0, rearcurve_double_inrad]) rotate([slant,0,0]){ translate([ rearcurve_double_inrad, 0, -rearcurve_double_inrad + 10 ]){ rotate([180,0,0]) rotate([0,0,90]) linear_extrude(height=30){ hull(){ Machine_NewRearProfile(); translate([0,-100]) Machine_NewRearProfile(); } } } rotate([0,90,0]) rotate([90,0,0]) { intersection(){ rotate_extrude(convexity=10, $fn=64) rotate(90) translate([ 0, -rearcurve_double_inrad ]) Machine_NewRearProfile(); translate([0,0,-500]) cube([500,500,1000]); } } translate([1,0,-rearcurve_double_inrad]) rotate([0,-90,0]) rotate([0,0,-90]) linear_extrude(height= rearcurve_strt_len + 1) Machine_NewRearProfile(); } } module Machine_Curves(){ ////toplevel translate([ tile01_tr[0] - cutout_l_end_x + rearedge_len, cutout_tile11_y, 0 ]){ //%cube([20,20,20]); translate([ -reartablet_x, -1, -reartablet_z + tablet_z_slop]) mirror([0,0,1]) cube([ reartablet_x+1, reartablet_y+1, 20 ]); } translate([ tile01_tr[0] - cutout_l_end_x + frontedge_len, cutout_tile11_y, frontcurve_z_slop ]){ translate([0, -machine_rear_to_front, 0]) multmatrix([[1, -frontcurve_side_skew, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) mirror([1,0,0]) rotate([0,-90,0])rotate([0,0,-90]) linear_extrude(height= 200) Machine_NewFrontProfile(); } translate([ tile01_tr[0] - cutout_l_end_x + rearedge_len, cutout_tile11_y, frontcurve_z_slop ]){ translate([ rearcurve_strt_len, 0, rearcurve_z_slop ]){ Machine_NewRearCurve(); } } } module TestStrapSlots(){ pegwidth = teststrap_peg[0]; for (pos = teststrapslots_at) { echo("TSS",pos); translate(concat(pos,[0])) for (mx = [0,1]) mirror([mx,0,0]) { translate([ pegwidth/2, -teststrap[1]/2, -20 ]) cube(concat(teststrap,[40])); } } } module TestStrapPeg_any(l){ cube(concat([l],teststrap_peg)); } module TestStrapPeg_Short(){ ////toplevel TestStrapPeg_any(35); } module TestStrapPeg_Long(){ ////toplevel TestStrapPeg_any(60); } module PostSpacer(){ ////toplevel $fn = 50; difference(){ cylinder(r= ply_hole_dia_real/2 - spacer_ext_slop, h= spacer_height); translate([0,0,-1]) cylinder(r= post_dia/2 + spacer_int_slop, h= ply_th + 2); } } module Machine(){ ////toplevel Machine_NewArm(); Machine_Curves(); if (TEST) TestStrapSlots(); } module MachineEnvelope(){ // used for testing p_arm_bl = [-cutout_l_end_x, -cutout_tile01_y]; y_arm_t = cutout_tile11_y; p_crv_fl = p_arm_bl + [frontedge_len, -frontcurve_avoid_y]; y_crv_b = y_arm_t + rearcurve_avoid_y; translate([0,0,-50]) linear_extrude(height= 100){ translate(p_arm_bl) square([400, y_arm_t] - p_arm_bl); translate(p_crv_fl) square([400, y_crv_b] - p_crv_fl); } } module Leg(){ ////toplevel difference(){ union(){ hull(){ mirror([0,0,1]) cylinder(r= leg_big_dia/2, h=leg_top_flat_z, $fn=100); translate([0,0, -leg_top_thick]) cylinder(r= leg_bot_dia/2, height=1, $fn=100); } if (!TEST) translate([0,0,-leg_height]) cylinder(r= leg_bot_mid_dia/2, h=leg_bot_thick); for (rot=[0: 360/leg_n_fins : 359]) rotate(rot) { hull(){ mirror([0,0,1]) translate([0, -leg_fin_top_w/2, 0]) cube([ leg_fin_top_rad - 0.1, leg_fin_top_w, 1 ]) ; translate([0, -leg_fin_bot_w/2, -leg_height]) cube([ leg_fin_bot_rad, leg_fin_bot_w, leg_fin_bot_flat_z ]); } } } mirror([0,0,1]) translate([0,0,-1]) cylinder(r= leg_hole_dia/2, h= (!TEST ? leg_height+2 : leg_height/2), $fn=30); mirror([0,0,1]) translate([0,0,leg_top_thick - 0.1]) hull(){ cylinder(r= (!TEST ? leg_midspc_dia/2 : 0.1), h= leg_height - leg_top_thick - leg_bot_thick + 0.2, $fn=30); if (TEST) cylinder(r= leg_midspc_dia/2, h= leg_height - leg_top_thick - leg_bot_thick + (!TEST ? 0.2 : -leg_midspc_dia/2), $fn=30); } cid_shear = (leg_fin_bot_w - leg_fin_top_w)/2 / (leg_height -leg_fin_bot_flat_z); multmatrix([[ 1, 0, 0, leg_midspc_dia/2 ], [ 0, cid_shear, 1, -leg_fin_bot_w/2 ], [ 0, 1, 0, -leg_height + leg_fin_bot_flat_z ], [ 0, 0, 0, 1 ]]) Commitid_BestCount([ leg_big_dia/2 - leg_midspc_dia/2, leg_height - leg_fin_bot_flat_z - leg_top_thick ]); if (!TEST) for (rot=[45: 360/leg_n_tubules : 359]) rotate(rot) { mirror([0,0,1]) translate([ leg_tubule_pos_rad, 0, -1]) cylinder(r= leg_tubule_dia/2, h=leg_height+2, $fn=20); } } } function Rectangle_corners(c0, sz) = // returns the corners of a rectangle from c0 to c0+sz // if sz is positive, the corners are anticlockwise starting with c0 [ c0 + [ 0, 0 ], c0 + [ sz[0], 0 ], c0 + [ sz[0], sz[1] ], c0 + [ 0, sz[1] ] ]; function Rectangle_corners2posts(c) = [ c[0] + thehd_tr, c[1] + thehd_tl, c[2] + thehd_bl, c[3] + thehd_br ]; module Rectangle_TileBase(c) { TileBase(c[0], c[2]); } function Posts_interpolate_one(c0,c1) = [c0, (c0+c1)/2, c1]; module Tile02(){ ////toplevel sz = [100,170]; c0 = tile02_tr + -sz; c = Rectangle_corners(c0, sz); posts = Rectangle_corners2posts(c); rcs = R_CNR(c,0); difference(){ union(){ Rectangle_TileBase(c); Posts(posts); RoundEdge(R_EDGE(c,0)); RoundEdge(R_EDGE(c,3)); InterlockEdge(R_EDGE(c,2), 0); } InterlockEdge(R_EDGE(c,1), 1); RoundCornerCut(rcs); PostHoles(posts); } RoundCornerAdd(rcs); } module Tile12(){ ////toplevel sz = [100,250]; c0 = tile02_tr + [-sz[0], 0]; c = Rectangle_corners(c0, sz); posts = Rectangle_corners2posts(c); rcs = R_CNR(c,3); difference(){ union(){ Rectangle_TileBase(c); Posts(posts); RoundEdge(R_EDGE(c,2)); RoundEdge(R_EDGE(c,3)); } InterlockEdge(R_EDGE(c,0), 1); InterlockEdge(R_EDGE(c,1), 1); RoundCornerCut(rcs); PostHoles(posts); } RoundCornerAdd(rcs); } tile_01_11_cnr = tile01_tr + [-cutout_l_end_x, 0]; tile_11_10_cnr = tile01_tr + [0, cutout_tile11_y]; tile_01_00_cnr = tile01_tr - [0, cutout_tile01_y]; module Tile11(){ ////toplevel sz = [250,250]; c0 = tile01_tr + [-sz[0],0]; c = Rectangle_corners(c0, sz); cnr_posts = Rectangle_corners2posts(c); posts = concat( Posts_interpolate_one(cnr_posts[0], cnr_posts[1] - [cutout_l_end_x, 0]), [ cnr_posts[1] + [0, cutout_tile11_y], cnr_posts[2], cnr_posts[3] ]); difference(){ union(){ Rectangle_TileBase(c); Posts(posts); RoundEdge(R_EDGE(c,2)); InterlockEdge(R_EDGE(c,3)); } InterlockEdge(c[0], tile_01_11_cnr, 1); InterlockEdge(tile_11_10_cnr, c[2], 1); PostHoles(posts); Machine(); } } module Tile01(){ ////toplevel sz = [250,170]; c0 = tile01_tr + -sz; c = Rectangle_corners(c0, sz); cnr_posts = Rectangle_corners2posts(c); posts = concat( Posts_interpolate_one(R_EDGE(cnr_posts,0)), [ cnr_posts[2] + [0, -cutout_tile01_y] ], Posts_interpolate_one(cnr_posts[2] - [cutout_l_end_x, 0], cnr_posts[3]) ); difference(){ union(){ Rectangle_TileBase(c); Posts(posts); RoundEdge(R_EDGE(c,0)); InterlockEdge(tile_01_11_cnr, c[3]); InterlockEdge(R_EDGE(c,3)); } PostHoles(posts); InterlockEdge(c[1], tile_01_00_cnr, 1); Machine(); } } module Tile10(){ ////toplevel sz = [250,250]; c0 = tile01_tr + [0,0]; c = Rectangle_corners(c0, sz); cnr_posts = Rectangle_corners2posts(c); cty = cutout_tile11_y; rcy = cty + rearcurve_avoid_y; posts = [ cnr_posts[0] + [ 0, cty ], cnr_posts[1] + [ -sz[0] + rearedge_len - cutout_l_end_x, cty ], cnr_posts[1] + [ 0, rcy ], cnr_posts[2], cnr_posts[3] ]; rcs = R_CNR(c,2); difference(){ union(){ Rectangle_TileBase(c); Posts(posts); RoundEdge(R_EDGE(c,1)); RoundEdge(R_EDGE(c,2)); InterlockEdge(c[3], tile_11_10_cnr); } PostHoles(posts); RoundCornerCut(rcs); Machine(); } RoundCornerAdd(rcs); } module Tile00(){ ////toplevel sz = [250,170]; c0 = tile01_tr + [0,-sz[1]]; c = Rectangle_corners(c0, sz); // the edge c[1]..c[2] needs a diagonal chunk, from c1bis to c2bis c2bis = [ -cutout_l_end_x + frontedge_len + frontcurve_strt_len, c[2][1] ]; c1bis = [ c[1][0], c[2][1] - (c[2][0] - c2bis[0]) * tan(90 - frontcurve_dualcurve_angle) ]; cnr_posts = Rectangle_corners2posts(c); cty = cutout_tile01_y; rcy = cty + frontcurve_avoid_y; posts = [ cnr_posts[0], cnr_posts[1], 0.5 * (cnr_posts[0] + cnr_posts[1]), cnr_posts[2] + [ 0, -rcy ], cnr_posts[2] + [ -sz[0] + frontedge_len - cutout_l_end_x, -cty ], cnr_posts[3] + [ 0, -cty ] ]; rcs = R_CNR(c,1); rc2 = [c1bis,c2bis,c[1]]; difference(){ union(){ difference(){ union(){ Rectangle_TileBase(c); Posts(posts); RoundEdge(R_EDGE(c,0)); RoundEdge(c[1], c1bis); InterlockEdge(tile_01_00_cnr, c[0]); } RoundCornerCut(rcs); translate([0,0,-20]) linear_extrude(height=40) { polygon([ c1bis, c1bis + [50,0], c2bis + [50,0], c2bis ]); } } RoundEdge(c1bis, c2bis); } Machine(); PostHoles(posts); RoundCornerCut(rc2); } RoundCornerAdd(rcs); RoundCornerAdd(rc2); } module FitTest_general(c0,sz, dobrace=false, bracexx=0){ c = Rectangle_corners(c0, sz); brace = [7,7,9]; bsz = sz + [bracexx,0,0]; difference(){ union(){ Rectangle_TileBase(c); if (dobrace) { translate(concat(c0, [-brace[2] + 0.1])){ difference(){ cube(concat(bsz, [brace[2]]) - [5,0,0]); translate(brace + [0,0, -25]) cube(concat(bsz, [50]) - brace*2 + [10,0,0]); } } } RoundEdge(R_EDGE(c,1)); } Machine(); } } module FitTest_PairLink(cut=false){ ////toplevel cy0=-55; cy1=85; cx=132; bar = [10,10]; legrad = 12; footrad_min = 1; footrad_max = 4; footrad_depth = 5; strap = [3,5]; adj_neg_slop = 1.0; bar_z_slop = 1.75; // calculated straphole_x_max = legrad/sqrt(2) + footrad_max; dz = cut ? adj_neg_slop : 0; translate([cx - bar[0]/2, cy0, dz + bar_z_slop]) cube([bar[0], cy1-cy0, bar[1] - bar_z_slop]); for (endy=[cy0,cy1]) { $fn=32; translate([cx,endy,dz]){ // feet for (rot=[45:90:315]) rotate(rot) { translate([legrad,0,0]){ hull(){ cylinder(r= footrad_max, h=1); translate([0,0,-footrad_depth]) cylinder(r= footrad_min, h=1); } if (cut) translate([0,0,-10]) cylinder(r= footrad_min + adj_neg_slop * (footrad_max-footrad_min)/footrad_depth, h=20); } } // legs for (rot=[45,135]) rotate(rot) { hull(){ for (s=[-1,+1]){ translate([s*legrad,0,0]) cylinder(r= footrad_max, h=bar[1]); } } } // strap holes if (cut) { for (rot=[0,180]) rotate(rot) { translate([ straphole_x_max - strap[0]/2, 0,0 ]) cube(concat(strap,[20]), center=true); } } } } } module FitTest_RearCurve(){ ////toplevel difference(){ FitTest_general([100,0], [180,100]); FitTest_PairLink(true); TestStrapSlots(); } } module FitTest_FrontCurve(){ ////toplevel p0 = [100,-80]; sz = [180,80]; difference(){ intersection() { Tile00(); translate([0,0,-8]) linear_extrude(height=18) { translate(p0) square(sz); translate(teststrapslots_at[3]) scale(2* [ teststrap_peg[0], teststrap[1] ]) circle(r=1, $fn=20); } } FitTest_PairLink(true); TestStrapSlots(); } } module FitTest_Entire(){ ////toplevel p0 = [-33,-80]; szrear = [263,180]; szfront = [243,szrear[1]]; difference(){ FitTest_general(p0, szrear, dobrace=true, bracexx=0); FitTest_PairLink(true); translate(concat(p0,[0]) + [szfront[0],-10,-40]) cube([100, -p0[1], 80]); TestStrapSlots(); } intersection(){ FitTest_RearCurve(); translate(concat(p0,[-20])) cube(concat(szrear,[40])); } FitTest_FrontCurve(); } module FitTest_EntireDemo(){ ////toplevel FitTest_Entire(); //%Tile00(); } module FitTest_EndEnd(){ ////toplevel p0 = [-30,-32]; sz = [156,81] - p0; sz2 = [136,68] - p0; difference(){ FitTest_general(p0, sz); translate([ p0[0] -1, p0[1]+sz2[1], -10]) cube([ sz2[0] +1, 50, 20 ]); } } module FitTest_PairDemo(){ ////toplevel sh=[-90,-15,0]; translate(sh){ FitTest_PairLink(); %FitTest_FrontCurve(); %FitTest_RearCurve(); } rotate([0,0,180]){ translate(sh){ difference(){ union(){ FitTest_FrontCurve(); FitTest_RearCurve(); } #FitTest_PairLink(true); } } } } module RoundCornerDemo_plat(cnr){ mirror([0,0,1]) linear_extrude(height=1) polygon(cnr); } module RoundCornerDemo(){ ////toplevel cnr = [ [-2,-3], [13,-3], [-12,9] ]; translate([0,25,0]) RoundCornerDemo_plat(cnr); translate([25,0,0]) RoundCornerAdd(cnr); translate([-25,0,0]) RoundCornerCut(cnr); translate([0,-25,0]) RoundCorner_selector(cnr, 0); difference(){ RoundCornerDemo_plat(cnr); RoundCornerCut(cnr); } RoundCornerAdd(cnr); } module Demo(){ ////toplevel translate(demo_slop*[-2,1]) color("blue") Tile12(); translate(demo_slop*[-2,0]) color("red") Tile02(); translate(demo_slop*[-2,1]) color("orange") Tile11(); translate(demo_slop*[-2,0]) color("purple") Tile01(); translate(demo_slop*[-3,1]) color("blue") Tile10(); translate(demo_slop*[-3,0]) color("red") Tile00(); %Machine(); // Can also do this, to print reference sheet: // load this into openscad // select Ctrl-4 view, view all, scale appropriately // import sewing-table,Demo-flat.png // pngtopnm t.pnm // lpr t.pnm } //TestPiece1(); //TestPiece2(); //Demo(); //Machine_NewRearProfile(); //Machine_NewRearCurve(); //Machine_NewFrontProfile(); //Machine_NewEndProfile(); //Machine_NewEndProfileDemo(); //Machine_Curves(); //Machine(); //FitTest(); //MachineEnvelope();