// -*- C -*-
+// Print one of each:
+// Main
+// TubeClampRight
+
+include <utils.scad>
+
tube_dia = 22.4;
hinge_around = 2.5;
-hinge_pin = 1.5; // xxx
+hinge_pin = 1.8 + 0.75;
main_th = 3;
minor_wall_min = 1;
screw = 5.0 + 0.75;
-screw_nut_across = 10; // xxx
-knob_behind_across = 15; // xxx
+screw_head = 8.7 + 1.2;
+screw_head_space_above = 10;
+screw_nut_across = 7.9 + 0.75;
+screw_nut_th = 3.9 + 0.75;
-clamp_width = 15;
+knob_behind_across = 12.2 + 0.75;
+behind_knob_th = 5;
+knob_standout_h = 2;
+
+clamp_min_width = 20;
clamp_gap = 2;
overlap_l = 0.1;
+bridge_slop = 1.2;
+
+hinge_lobe_per = 10;
+hinge_gap_z = 0.75;
+hinge_gap_xy = 0.75;
+
+$fs = 0.1;
+$fa = 5;
+
+bank_eps_bbox_x = [149, 598];
+bank_eps_bbox_y = [274, 1452];
+
+bank_y_sz = 102.25 + 0.50 + 3.2;
+bank_x_sz = (26.0 + 0.5);
+bank_recess_y = 5;
+
+strap_th = 3;
+strap_w = 5;
+strap_above = 2.5;
+
+strap_around_over = 1.0;
+strap_around_attach = 2.0;
+
+retainer_walls = [18, 30];
+
+bank_profile_scale_bodge = 1.0;
+
+bank_output_ctr = [ 12.5, 11.5 ]; // from nearest corner
+bank_output_sz = [ 11.0, 10.5 ];
+
+mounted_pos_y_offset_lim = -100;
+
+liner_th = 0.8;
+
+brace_r = 5;
+brace_len = 50;
+
+straps_y_adj = [ 3.5,
+ 0,
+ 0 ];
+
// calculated
-main_r = tube_dia/2 + main_th;
+straps_y = [ -bank_y_sz * 0.25, // these entries are special and used
+ +bank_y_sz * 0.25, // for the brace struts
+ 0 ];
-hinge_outer_r = hinge_around + hinge_pin/2
-hinge_y = tube_dia/2 + hinge_outer_r;
+screw_head_behind = main_th;
+endwall_th = main_th;
+
+bank_recess_dx = minor_wall_min;
+
+pspt_to_mm = 25.4 / 72;
+
+main_r = tube_dia/2 + main_th;
screw_max_y_lhs = -main_r -screw_nut_across/2;
screw_max_y_rhs = -main_r -knob_behind_across/2;
screw_y = min(screw_max_y_lhs,
screw_max_y_rhs);
-bot_y = -screw_y -max( screw_nut_across, knob_behind_across/2 )
+bot_y = screw_y -max( screw_nut_across/2, knob_behind_across/2 )
-minor_wall_min;
+holder_x_sz = bank_x_sz + bank_recess_dx*2;
+bank_bot_y = strap_above + strap_th;
+strap_r = strap_th;
+
+brace_total_len = brace_len + main_th;
+brace_ctrs_y_nom = [ straps_y[0] - (brace_r + strap_w/2),
+ straps_y[1] + (brace_r + strap_w/2) ];
+
+brace_ctrs_y = [ (straps_y + straps_y_adj)[0] + (brace_r + strap_w/2),
+ (straps_y + straps_y_adj)[1] + (brace_r + strap_w/2) ];
+
+clamp_width_actual = max(clamp_min_width, holder_x_sz);
+
+hinge_lobes = floor(clamp_width_actual / hinge_lobe_per);
+hinge_stride = (clamp_width_actual + hinge_gap_z) / hinge_lobes;
+
+hinge_outer_r = hinge_around + hinge_pin/2;
+hinge_y = tube_dia/2 + hinge_outer_r;
+
+top_cnr_r = min(endwall_th, main_th);
+
+mounted_pos_y_offset = max(mounted_pos_y_offset_lim,
+ bot_y - (-(bank_y_sz/2 + endwall_th)));
+
module TubePlan(){ circle(r = tube_dia/2); }
-module HingePlan(){ translate([0, hinge_y]) circle(r= hinge_pin/2); }
+module HingePinPlan(){ translate([0, hinge_y]) circle(r= hinge_pin/2); }
module HingeBodyPlan(){ translate([0, hinge_y]) circle(r= hinge_outer_r); }
module TubeClampLeftPlan(){
difference(){
union(){
- polygon([[ 0, hinge_y + hinge_outer_r ],
- [ -main_outer_r + overlap_l, hinge_y + hinge_outer_r ],
- [ -main_outer_r + overlap_l, bot_y ],
- [ -clamp_gap/2, bot_y ],
- [ -clamp_gap/2, 0, ],
- [ 0, 0, ],
+ polygon([[ 0, hinge_y + hinge_outer_r ],
+ [ -(main_r + overlap_l), hinge_y + hinge_outer_r ],
+ [ -(main_r + overlap_l), bot_y ],
+ [ -clamp_gap/2, bot_y ],
+ [ -clamp_gap/2, 0, ],
+ [ 0, 0, ],
]);
HingeBodyPlan();
}
}
module TubeClampLeft() { ////toplevel
- linextr(-clamp_width/2, clamp_width/2)
+ linextr(-clamp_width_actual/2, clamp_width_actual/2)
TubeClampLeftPlan();
}
-TubeClampLeft();
+module TubeClampRightPlan(){
+ difference(){
+ union(){
+ rectfromto([ clamp_gap/2, bot_y ],
+ [ clamp_gap/2 + behind_knob_th, 0 ]);
+ intersection(){
+ circle(r= main_r);
+ union(){
+ rectfromto([0,0],
+ main_r * [5,5]);
+ rectfromto([ clamp_gap/2, main_r*5 ],
+ main_r * [2,-5]);
+ }
+ }
+ HingeBodyPlan();
+ }
+ TubePlan();
+ HingePinPlan();
+ }
+}
+
+module Screws(){
+ linextr_x_yz(-main_r*5, main_r*5)
+ translate([screw_y, 0])
+ circle(r= screw/2);
+
+ translate([0, screw_y, 0]) {
+ linextr_x_yz(-(clamp_gap/2 + screw_nut_th), 0)
+ square([screw_nut_across,
+ screw_nut_across / cos(30) + bridge_slop*2],
+ center=true);
+
+ linextr_x_yz(-(main_r + bank_recess_y + screw_head_space_above),
+ -(clamp_gap/2 + screw_nut_th + screw_head_behind))
+ square([screw_head, screw_head + bridge_slop*2],
+ center=true);
+ }
+}
+
+module SomeClamp(hinge_alt=false){
+ difference(){
+ linextr(-clamp_width_actual/2, clamp_width_actual/2)
+ children(0);
+
+ Screws();
+
+ for (i=[0 : hinge_lobes-1]) {
+ translate([0,
+ hinge_y,
+ -clamp_width_actual/2 + i * hinge_stride
+ + (hinge_alt ? hinge_stride/2 : 0)
+ ])
+ linextr(-hinge_gap_z, hinge_stride/2)
+ square(hinge_outer_r*2 + hinge_gap_xy, center=true);
+ }
+ }
+}
+
+module PowerBankItselfSidePlan(){
+ translate([0, bank_bot_y]){
+ minkowski(){
+ circle($fn=8, r=liner_th);
+ scale( bank_profile_scale_bodge *
+ bank_x_sz / ( (
+ bank_eps_bbox_x[1] -
+ bank_eps_bbox_x[0]
+ ) * pspt_to_mm ))
+ translate(pspt_to_mm *
+ [-0.5 * (bank_eps_bbox_x[0] +
+ bank_eps_bbox_x[1]),
+ -bank_eps_bbox_y[0]])
+ import("powerbank-anker-10000.dxf", convexity=5);
+ }
+ }
+}
+
+module PowerBankItself(){ ////toplevel
+ rotate([0,90,0])
+ linextr_y_xz(-bank_y_sz/2,
+ +bank_y_sz/2)
+ PowerBankItselfSidePlan();
+}
+
+module PowerBankSidePlan(){ ////toplevel
+ render() difference(){
+ rectfromto([ -holder_x_sz/2, 0 ],
+ [ +holder_x_sz/2, bank_recess_y + bank_bot_y ]);
+
+ PowerBankItselfSidePlan();
+ }
+}
+
+module PowerBankStrapCut(){ ////toplevel
+ difference(){
+ rectfromto([ -holder_x_sz, -0.05 ],
+ [ +holder_x_sz, strap_th + strap_r ]);
+ hull(){
+ for (sx=[-1,+1]) {
+ translate([sx * (holder_x_sz/2 - strap_r + 0.1),
+ strap_th + strap_r])
+ circle(strap_r);
+ }
+ }
+ }
+}
+
+module PowerBankHolderTest(){ ////toplevel
+ difference(){
+ linextr(-1,5) PowerBankSidePlan();
+ linextr(0, strap_w) PowerBankStrapCut();
+ }
+}
+
+module EndRetainer(depth){ ////toplevel
+ translate([0, -bank_y_sz/2, 0]) {
+ linextr_y_xz(-endwall_th, 0)
+ rectfromto([ 0, -holder_x_sz/2 ],
+ [ -depth, +holder_x_sz/2 ]);
+
+ for (m=[0,1]) {
+ mirror([0,0,m]) {
+ linextr(-holder_x_sz/2, -bank_x_sz/2){
+ hull(){
+ rectfromto([ 0, -endwall_th ],
+ [ depth, 0 ]);
+ rectfromto([ 0, 0 ],
+ [ 0.1, depth-0.1 ]);
+ }
+ }
+ }
+ }
+ }
+}
+
+module BraceTubePlan(){
+ intersection(){
+ circle(r= brace_r);
+ rectfromto(brace_r * [-2, 0],
+ brace_r * [+2, +2]);
+ }
+}
+
+module PowerBankHolder(){ ////toplevel
+ difference(){
+ union(){
+ rotate([0,90,0])
+ linextr_y_xz(-(bank_y_sz/2 + 0.1),
+ +(bank_y_sz/2 + 0.1))
+ PowerBankSidePlan();
+
+ EndRetainer(retainer_walls[0]);
+ mirror([0,1,0]) EndRetainer(retainer_walls[1]);
+
+ translate([0,0, bank_x_sz/2]){
+ for (y = brace_ctrs_y) {
+ translate([0,y,0]) {
+ linextr_x_yz(0, brace_total_len)
+ BraceTubePlan();
+ }
+ }
+ translate([brace_total_len, 0,0])
+ linextr_y_xz(brace_ctrs_y_nom[0] - brace_r,
+ brace_ctrs_y_nom[1] + brace_r)
+ BraceTubePlan();
+ }
+
+ for (strap_y = straps_y + straps_y_adj) {
+ translate([0, strap_y, 0]) {
+ linextr(-holder_x_sz/2,
+ +holder_x_sz/2){
+ hull(){
+ for (dy = [-1,+1] *
+ (strap_w/2 + strap_around_attach - strap_around_over)) {
+ translate([0, dy, 0])
+ circle(r=strap_around_over);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ for (strap_y = straps_y + straps_y_adj)
+ translate([0, strap_y, 0])
+ rotate([0,0,-90])
+ rotate([0,90,0])
+ linextr(-strap_w/2,
+ +strap_w/2)
+ PowerBankStrapCut();
+
+ translate([ bank_bot_y, -bank_y_sz/2, -bank_x_sz/2 ])
+ linextr_y_xz(-50,50)
+ rotate([0,0,90])
+ translate(bank_output_ctr)
+ square(center=true, bank_output_sz);
+
+ translate([0, -(bank_y_sz/2 + endwall_th), 0] + 0.01 * [-1,-1]) {
+ linextr(-200,200){
+ difference(){
+ square(center=true, top_cnr_r*2);
+ translate(top_cnr_r * [1,1])
+ circle(r= top_cnr_r);
+ }
+ }
+ }
+ }
+}
+
+module TubeClampLeft() { ////toplevel
+ // We want this to print with the recess overhand to the right
+ // where the workpiece cooling fan is
+ rotate([0,0,180]){
+ difference(){
+ SomeClamp(true)
+ TubeClampLeftPlan();
+
+ Screws();
+ }
+ }
+}
+
+module PlacePowerBank(){
+ translate([main_r, -mounted_pos_y_offset, 0])
+ children(0);
+}
+
+module Main(){ ////toplevel
+ TubeClampLeft();
+ difference(){
+ PlacePowerBank()
+ PowerBankHolder();
+ rotate([0,0,180])
+ Screws();
+ }
+}
+
+module TubeClampRight() { ////toplevel
+ rotate([0,0,180]) {
+ rotate([180,0,0]) {
+ difference(){
+ union(){
+ SomeClamp()
+ TubeClampRightPlan();
+
+ translate([clamp_gap/2 + behind_knob_th, screw_y, 0]) {
+ hull(){
+ linextr_x_yz(-0.1, 0)
+ square(center=true,
+ [knob_behind_across,
+ knob_behind_across + knob_standout_h*2]);
+ linextr_x_yz(0, knob_standout_h)
+ square(center=true,
+ knob_behind_across);
+ }
+ }
+ }
+ Screws();
+ }
+ }
+ }
+}
+
+module TubeClampDemo() { ////toplevel
+ TubeClampLeft();
+ rotate([180,0,0])
+ TubeClampRight();
+}
+
+module Demo() { ////toplevel
+ Main();
+ rotate([180,0,0])
+ TubeClampRight();
+ PlacePowerBank()
+ %PowerBankItself();
+}