1 module cartridge() 2 { 3 $fn = 50; 4 5 /* Rounding/fillet radius and additional margin of subtracted 6 material. The additional margin helps avoid geometry 7 problems. */ 8 9 rr = 1; 10 ro = rr; 11 extra = 0.1; 12 13 module fillet(r, h) { 14 translate([0, 0, -h/2]) 15 difference() { 16 cube([r + extra, r + extra, h]); 17 cylinder(r = r, h = h); 18 } 19 } 20 21 /* Cartridge dimensions. */ 22 23 width = 89.0; 24 height = 68.5; 25 depth = 16.5; 26 27 /* Details. */ 28 29 front_label_width = 83.0; 30 front_label_height = 46.0; 31 front_label_depth = 1.0; 32 front_label_offset_from_bottom = 19.5; 33 34 top_label_width = front_label_width; 35 top_label_height = 11.5; 36 top_label_depth = front_label_depth; 37 top_label_offset_from_front = 2.5; 38 39 groove_depth = 1.0; 40 41 back_cavity_width = 68.0; 42 back_cavity_inner_width = 65.0; 43 back_cavity_offset_from_left = 10.5; 44 back_cavity_inner_offset_from_left = 12.0; 45 back_cavity_height = 13.5; 46 back_cavity_inner_height = 12.0; 47 back_cavity_depth = 1.5; 48 49 /* Side thicknesses. */ 50 51 front = 2; 52 back = 3.5; 53 top = 3; 54 left = 2; 55 right = 2; 56 57 difference() { 58 59 /* The cartridge surfaces. */ 60 61 union() { 62 translate([0, -depth / 2 + front / 2, 0]) 63 cube([width, front, height], center = true); 64 translate([0, depth / 2 - back / 2, 0]) 65 cube([width, back, height], center = true); 66 translate([-width / 2 + left / 2, 0, 0]) 67 cube([left, depth, height], center = true); 68 translate([width / 2 - right / 2, 0, 0]) 69 cube([right, depth, height], center = true); 70 translate([0, 0, height / 2 - top / 2]) 71 cube([width, depth, top], center = true); 72 } 73 74 /* Label insets. */ 75 76 union() { 77 78 /* Front label. */ 79 80 translate([-front_label_width / 2, -depth / 2, 81 front_label_offset_from_bottom - height / 2]) 82 cube([front_label_width, front_label_depth, 83 front_label_height]); 84 85 /* Top label. */ 86 87 translate([-top_label_width / 2, 88 -depth / 2 + top_label_offset_from_front, 89 height / 2 - top_label_depth]) 90 cube([top_label_width, top_label_height, 91 top_label_depth]); 92 } 93 94 /* Top and side grooves. */ 95 96 union() { 97 98 /* Left groove. */ 99 100 translate([-width / 2 + groove_depth / 2, 0, 0]) 101 cube([groove_depth, groove_depth, height], 102 center = true); 103 104 /* Right groove. */ 105 106 translate([width / 2 - groove_depth / 2, 0, 0]) 107 cube([groove_depth, groove_depth, height], 108 center = true); 109 110 /* Top groove. */ 111 112 translate([0, 0, height / 2 - groove_depth / 2]) 113 cube([width, groove_depth, groove_depth], 114 center = true); 115 } 116 117 /* Back cavity. */ 118 119 intersection() { 120 121 /* From the bottom upwards. */ 122 123 translate([0, depth / 2, -height / 2]) 124 linear_extrude(height = back_cavity_height) 125 translate([-width / 2, 0, 0]) 126 polygon([ 127 [back_cavity_offset_from_left, 0], 128 [back_cavity_inner_offset_from_left, 129 -back_cavity_depth], 130 [back_cavity_inner_offset_from_left + 131 back_cavity_inner_width, 132 -back_cavity_depth], 133 [back_cavity_offset_from_left + 134 back_cavity_width, 0] 135 ]); 136 137 /* From left to right. */ 138 139 translate([back_cavity_width / 2, depth / 2, -height / 2]) 140 rotate([0, -90, 0]) 141 linear_extrude(height = back_cavity_width) 142 polygon([ 143 [-extra, -back_cavity_depth], 144 [back_cavity_inner_height, 145 -back_cavity_depth], 146 [back_cavity_height, 0], 147 [-extra, 0] 148 ]); 149 } 150 151 /* Fillets to round off the edges. */ 152 153 union() { 154 155 /* Top left and right rounding. */ 156 157 translate([-width / 2 + ro, 0, height / 2 - ro]) 158 rotate([0, 0, 180]) 159 rotate([90, 0, 0]) 160 fillet(rr, depth); 161 translate([width / 2 - ro, 0, height / 2 - ro]) 162 rotate([90, 0, 0]) 163 fillet(rr, depth); 164 165 /* Top back and front rounding. */ 166 167 translate([0, depth / 2 - ro, height / 2 - ro]) 168 rotate([0, -90, 0]) 169 fillet(rr, width); 170 translate([0, -depth / 2 + ro, height / 2 - ro]) 171 rotate([0, 0, 180]) 172 rotate([0, -90, 0]) 173 fillet(rr, width); 174 175 /* Edge rounding. */ 176 177 translate([width / 2 - ro, depth / 2 - ro, 0]) 178 fillet(rr, height); 179 translate([-width / 2 + ro, depth / 2 - ro, 0]) 180 rotate([0, 0, 90]) 181 fillet(rr, height); 182 translate([-width / 2 + ro, -depth / 2 + ro, 0]) 183 rotate([0, 0, 180]) 184 fillet(rr, height); 185 translate([width / 2 - ro, -depth / 2 + ro, 0]) 186 rotate([0, 0, 270]) 187 fillet(rr, height); 188 } 189 } 190 } 191 192 cartridge(); 193