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 inner_back_cavity_offset = 1.0; 50 inner_back_cavity_offset_from_left = 2.0; 51 inner_back_slope_offset_from_left = 10.0; 52 inner_back_slope_width = 2.5; 53 inner_back_slope_depth = 2.5; 54 55 inner_back_edge_offset = 2.0; 56 inner_back_edge_width = 69.0; 57 inner_back_edge_height = 3.0; 58 inner_back_edge_depth = 1.5; 59 60 inner_front_edge_offset = 0.5; 61 inner_front_edge_width = 87.0; 62 inner_front_edge_height = 3.0; 63 inner_front_edge_depth = 1.5; 64 65 bottom_from_base = 13.5; 66 67 /* Side thicknesses. */ 68 69 front = 2; 70 back = 3.5; 71 top = 3; 72 left = 2; 73 right = 2; 74 bottom = 2; 75 76 difference() { 77 78 /* The cartridge surfaces. */ 79 80 union() { 81 translate([0, -depth / 2 + front / 2, 0]) 82 cube([width, front, height], center = true); 83 translate([0, depth / 2 - back / 2, 0]) 84 cube([width, back, height], center = true); 85 translate([-width / 2 + left / 2, 0, 0]) 86 cube([left, depth, height], center = true); 87 translate([width / 2 - right / 2, 0, 0]) 88 cube([right, depth, height], center = true); 89 translate([0, 0, height / 2 - top / 2]) 90 cube([width, depth, top], center = true); 91 translate([0, 0, -height / 2 + bottom / 2 + bottom_from_base]) 92 cube([width, depth, top], center = true); 93 } 94 95 /* Label insets. */ 96 97 union() { 98 99 /* Front label. */ 100 101 translate([-front_label_width / 2, -depth / 2, 102 front_label_offset_from_bottom - height / 2]) 103 cube([front_label_width, front_label_depth, 104 front_label_height]); 105 106 /* Top label. */ 107 108 translate([-top_label_width / 2, 109 -depth / 2 + top_label_offset_from_front, 110 height / 2 - top_label_depth]) 111 cube([top_label_width, top_label_height, 112 top_label_depth]); 113 } 114 115 /* Top and side grooves. */ 116 117 union() { 118 119 /* Left groove. */ 120 121 translate([-width / 2 + groove_depth / 2, 0, 0]) 122 cube([groove_depth, groove_depth, height], 123 center = true); 124 125 /* Right groove. */ 126 127 translate([width / 2 - groove_depth / 2, 0, 0]) 128 cube([groove_depth, groove_depth, height], 129 center = true); 130 131 /* Top groove. */ 132 133 translate([0, 0, height / 2 - groove_depth / 2]) 134 cube([width, groove_depth, groove_depth], 135 center = true); 136 } 137 138 /* Back cavity. */ 139 140 intersection() { 141 142 /* From the bottom upwards. */ 143 144 translate([0, depth / 2, -height / 2]) 145 linear_extrude(height = back_cavity_height) 146 translate([-width / 2, 0, 0]) 147 polygon([ 148 [back_cavity_offset_from_left, 0], 149 [back_cavity_inner_offset_from_left, 150 -back_cavity_depth], 151 [back_cavity_inner_offset_from_left + 152 back_cavity_inner_width, 153 -back_cavity_depth], 154 [back_cavity_offset_from_left + 155 back_cavity_width, 0] 156 ]); 157 158 /* From left to right. */ 159 160 translate([back_cavity_width / 2, depth / 2, -height / 2]) 161 rotate([0, -90, 0]) 162 linear_extrude(height = back_cavity_width) 163 polygon([ 164 [-extra, -back_cavity_depth], 165 [back_cavity_inner_height, 166 -back_cavity_depth], 167 [back_cavity_height, 0], 168 [-extra, 0] 169 ]); 170 } 171 172 /* Inner back cavities. */ 173 174 translate([0, depth / 2 - inner_back_cavity_offset, -height / 2]) 175 linear_extrude(height = bottom_from_base) 176 translate([-width / 2, 0, 0]) 177 polygon([ 178 [inner_back_cavity_offset_from_left, 0], 179 [inner_back_slope_offset_from_left, 0], 180 [inner_back_slope_offset_from_left + 181 inner_back_slope_width, 182 -inner_back_slope_depth], 183 [inner_back_cavity_offset_from_left, 184 -inner_back_slope_depth] 185 ]); 186 187 translate([0, depth / 2 - inner_back_cavity_offset, -height / 2]) 188 linear_extrude(height = bottom_from_base) 189 translate([-width / 2, 0, 0]) 190 polygon([ 191 [width - inner_back_slope_offset_from_left, 0], 192 [width - inner_back_cavity_offset_from_left, 0], 193 [width - inner_back_cavity_offset_from_left, 194 -inner_back_slope_depth], 195 [width - inner_back_slope_offset_from_left - 196 inner_back_slope_width, 197 -inner_back_slope_depth] 198 ]); 199 200 /* Inner back edge cavity. */ 201 202 translate([inner_back_edge_width / 2, 203 depth / 2 - inner_back_edge_offset, -height / 2]) 204 rotate([0, -90, 0]) 205 linear_extrude(height = inner_back_edge_width) 206 polygon([ 207 [-extra, -inner_back_edge_depth], 208 [inner_back_edge_height, -inner_back_edge_depth], 209 [0, 0], 210 [-extra, 0] 211 ]); 212 213 /* Inner front edge cavity. */ 214 215 translate([inner_front_edge_width / 2, 216 -depth / 2 + inner_front_edge_offset, -height / 2]) 217 rotate([0, -90, 0]) 218 linear_extrude(height = inner_front_edge_width) 219 polygon([ 220 [-extra, 0], 221 [0, 0], 222 [inner_front_edge_height, inner_front_edge_depth], 223 [-extra, inner_front_edge_depth], 224 ]); 225 226 /* Fillets to round off the edges. */ 227 228 union() { 229 230 /* Top left and right rounding. */ 231 232 translate([-width / 2 + ro, 0, height / 2 - ro]) 233 rotate([0, 0, 180]) 234 rotate([90, 0, 0]) 235 fillet(rr, depth); 236 translate([width / 2 - ro, 0, height / 2 - ro]) 237 rotate([90, 0, 0]) 238 fillet(rr, depth); 239 240 /* Top back and front rounding. */ 241 242 translate([0, depth / 2 - ro, height / 2 - ro]) 243 rotate([0, -90, 0]) 244 fillet(rr, width); 245 translate([0, -depth / 2 + ro, height / 2 - ro]) 246 rotate([0, 0, 180]) 247 rotate([0, -90, 0]) 248 fillet(rr, width); 249 250 /* Edge rounding. */ 251 252 translate([width / 2 - ro, depth / 2 - ro, 0]) 253 fillet(rr, height); 254 translate([-width / 2 + ro, depth / 2 - ro, 0]) 255 rotate([0, 0, 90]) 256 fillet(rr, height); 257 translate([-width / 2 + ro, -depth / 2 + ro, 0]) 258 rotate([0, 0, 180]) 259 fillet(rr, height); 260 translate([width / 2 - ro, -depth / 2 + ro, 0]) 261 rotate([0, 0, 270]) 262 fillet(rr, height); 263 } 264 } 265 } 266 267 cartridge(); 268