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 + extra]); 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 front_depth = 6.5; 27 back_depth = 11.0; 28 29 /* Details. */ 30 31 front_label_width = 83.0; 32 front_label_height = 46.0; 33 front_label_depth = 1.0; 34 front_label_offset_from_bottom = 19.5; 35 36 top_label_width = front_label_width; 37 top_label_height = 11.5; 38 top_label_depth = front_label_depth; 39 top_label_offset_from_front = 2.5; 40 41 groove_width = 2.5; /* how much the groove cuts out of the back */ 42 groove_depth = 1.0; /* how deep the groove goes into each side */ 43 top_groove_width = 1.0; 44 top_groove_depth = 2.0; 45 inner_top_front_cutout_width = 87.0; 46 inner_top_front_cutout_depth = 1.0; 47 inner_top_front_cutout_offset = 2.0; 48 49 back_cavity_width = 68.0; 50 back_cavity_inner_width = 65.0; 51 back_cavity_offset_from_left = 10.5; 52 back_cavity_inner_offset_from_left = 12.0; 53 back_cavity_height = 13.5; 54 back_cavity_inner_height = 12.0; 55 back_cavity_depth = 1.5; 56 57 inner_back_cavity_offset = 1.0; 58 inner_back_cavity_offset_from_left = 2.0; 59 inner_back_slope_offset_from_left = 10.0; 60 inner_back_slope_width = 2.5; 61 inner_back_slope_depth = 2.5; 62 63 inner_back_edge_offset = 2.0; 64 inner_back_edge_width = 69.0; 65 inner_back_edge_height = 3.0; 66 inner_back_edge_depth = 1.5; 67 68 inner_front_edge_offset = 0.5; 69 inner_front_edge_width = 87.0; 70 inner_front_edge_height = 3.0; 71 inner_front_edge_depth = 1.5; 72 73 bottom_from_base = 13.5; 74 75 edge_connector_cutout_front_offset = 1.0; 76 edge_connector_cutout_front_depth = 1.0; 77 edge_connector_cutout_front_width = 15.0; 78 edge_connector_cutout_back_depth = 3.0; 79 edge_connector_cutout_back_width = 57.0; 80 81 /* Side thicknesses. */ 82 83 front = 2; 84 back = 3.5; 85 top = 3; 86 front_left = 1; 87 front_right = 1; 88 back_left = 2; 89 back_right = 2; 90 bottom = 2; 91 92 translate([0, -20, 0]) 93 difference() { 94 95 /* The cartridge surfaces. */ 96 97 union() { 98 99 /* Front portion. */ 100 101 translate([0, -front_depth + front / 2, 0]) 102 cube([width, front, height], center = true); 103 translate([-width / 2 + front_left / 2, -front_depth / 2, 0]) 104 cube([front_left, front_depth, height], center = true); 105 translate([width / 2 - front_right / 2, -front_depth / 2, 0]) 106 cube([front_right, front_depth, height], center = true); 107 translate([0, -front_depth / 2, height / 2 - top / 2]) 108 cube([width, front_depth, top], center = true); 109 difference() { 110 translate([0, -front_depth / 2, 111 -height / 2 + bottom / 2 + bottom_from_base]) 112 cube([width, front_depth, bottom], center = true); 113 translate([-width / 2 + edge_connector_cutout_front_offset + 114 edge_connector_cutout_front_width / 2, 115 -edge_connector_cutout_front_depth / 2, 116 -height / 2 + bottom / 2 + bottom_from_base]) 117 cube([edge_connector_cutout_front_width, 118 edge_connector_cutout_front_depth, 119 bottom + extra], center = true); 120 translate([width / 2 - edge_connector_cutout_front_offset - 121 edge_connector_cutout_front_width / 2, 122 -edge_connector_cutout_front_depth / 2, 123 -height / 2 + bottom / 2 + bottom_from_base]) 124 cube([edge_connector_cutout_front_width, 125 edge_connector_cutout_front_depth, 126 bottom + extra], center = true); 127 } 128 } 129 130 /* Label insets. */ 131 132 union() { 133 134 /* Front label. */ 135 136 translate([-front_label_width / 2, -front_depth, 137 front_label_offset_from_bottom - height / 2]) 138 cube([front_label_width, front_label_depth, 139 front_label_height]); 140 141 /* Top label. */ 142 143 translate([-top_label_width / 2, 144 -front_depth + top_label_offset_from_front, 145 height / 2 - top_label_depth]) 146 cube([top_label_width, top_label_height, 147 top_label_depth]); 148 } 149 150 /* Inner front edge cavity. */ 151 152 translate([inner_front_edge_width / 2, 153 -front_depth + inner_front_edge_offset, -height / 2]) 154 rotate([0, -90, 0]) 155 linear_extrude(height = inner_front_edge_width) 156 polygon([ 157 [-extra, 0], 158 [0, 0], 159 [inner_front_edge_height, inner_front_edge_depth], 160 [-extra, inner_front_edge_depth], 161 ]); 162 163 /* Inner top cutout for the top of the back portion. */ 164 165 translate([0, -inner_top_front_cutout_depth / 2, height / 2 - 166 inner_top_front_cutout_offset - 167 inner_top_front_cutout_depth / 2]) 168 cube([inner_top_front_cutout_width, 169 inner_top_front_cutout_depth, 170 inner_top_front_cutout_depth], center = true); 171 172 /* Fillets to round off the edges. */ 173 174 union() { 175 176 /* Top left and right rounding. */ 177 178 translate([-width / 2 + ro, -front_depth / 2, height / 2 - ro]) 179 rotate([0, 0, 180]) 180 rotate([90, 0, 0]) 181 fillet(rr, front_depth); 182 translate([width / 2 - ro, -front_depth / 2, height / 2 - ro]) 183 rotate([90, 0, 0]) 184 fillet(rr, front_depth); 185 186 /* Top front rounding. */ 187 188 translate([0, -front_depth + ro, height / 2 - ro]) 189 rotate([0, 0, 180]) 190 rotate([0, -90, 0]) 191 fillet(rr, width); 192 193 /* Edge rounding. */ 194 195 translate([-width / 2 + ro, -front_depth + ro, 0]) 196 rotate([0, 0, 180]) 197 fillet(rr, height); 198 translate([width / 2 - ro, -front_depth + ro, 0]) 199 rotate([0, 0, 270]) 200 fillet(rr, height); 201 } 202 } 203 204 difference() { 205 206 /* The cartridge surfaces. */ 207 208 union() { 209 210 /* Back portion. */ 211 212 translate([0, back_depth - back / 2, 0]) 213 cube([width, back, height], center = true); 214 translate([-width / 2 + back_left / 2, back_depth / 2, 0]) 215 cube([back_left, back_depth, height], center = true); 216 translate([width / 2 - back_right / 2, back_depth / 2, 0]) 217 cube([back_right, back_depth, height], center = true); 218 translate([0, back_depth / 2, height / 2 - top / 2]) 219 cube([width, back_depth, top], center = true); 220 difference() { 221 translate([0, back_depth / 2, 222 -height / 2 + bottom / 2 + bottom_from_base]) 223 cube([width, back_depth, bottom], center = true); 224 translate([0, edge_connector_cutout_back_depth / 2, 225 -height / 2 + bottom / 2 + bottom_from_base]) 226 cube([edge_connector_cutout_back_width, 227 edge_connector_cutout_back_depth, 228 bottom + extra], center = true); 229 } 230 } 231 232 /* Label insets. */ 233 234 union() { 235 236 /* Top label. */ 237 238 translate([-top_label_width / 2, 239 -front_depth + top_label_offset_from_front, 240 height / 2 - top_label_depth]) 241 cube([top_label_width, top_label_height, 242 top_label_depth]); 243 } 244 245 /* Top and side grooves, positioned in the back portion. */ 246 247 union() { 248 249 /* Left groove. */ 250 251 translate([-width / 2 + groove_depth / 2, groove_width / 2, 0]) 252 cube([groove_depth, groove_width, height], 253 center = true); 254 255 /* Right groove. */ 256 257 translate([width / 2 - groove_depth / 2, groove_width / 2, 0]) 258 cube([groove_depth, groove_width, height], 259 center = true); 260 261 /* Top grooves. */ 262 263 translate([0, groove_width / 2, height / 2 - groove_depth / 2]) 264 cube([width, groove_width, groove_depth], 265 center = true); 266 267 translate([0, top_groove_width / 2, 268 height / 2 - top_groove_depth / 2]) 269 cube([width, top_groove_width, top_groove_depth], 270 center = true); 271 } 272 273 /* Back cavity. */ 274 275 intersection() { 276 277 /* From the bottom upwards. */ 278 279 translate([0, back_depth, -height / 2]) 280 linear_extrude(height = back_cavity_height) 281 translate([-width / 2, 0, 0]) 282 polygon([ 283 [back_cavity_offset_from_left, 0], 284 [back_cavity_inner_offset_from_left, 285 -back_cavity_depth], 286 [back_cavity_inner_offset_from_left + 287 back_cavity_inner_width, 288 -back_cavity_depth], 289 [back_cavity_offset_from_left + 290 back_cavity_width, 0] 291 ]); 292 293 /* From left to right. */ 294 295 translate([back_cavity_width / 2, back_depth, -height / 2]) 296 rotate([0, -90, 0]) 297 linear_extrude(height = back_cavity_width) 298 polygon([ 299 [-extra, -back_cavity_depth], 300 [back_cavity_inner_height, 301 -back_cavity_depth], 302 [back_cavity_height, 0], 303 [-extra, 0] 304 ]); 305 } 306 307 /* Inner back cavities. */ 308 309 translate([0, back_depth - inner_back_cavity_offset, -height / 2]) 310 linear_extrude(height = bottom_from_base) 311 translate([-width / 2, 0, 0]) 312 polygon([ 313 [inner_back_cavity_offset_from_left, 0], 314 [inner_back_slope_offset_from_left, 0], 315 [inner_back_slope_offset_from_left + 316 inner_back_slope_width, 317 -inner_back_slope_depth], 318 [inner_back_cavity_offset_from_left, 319 -inner_back_slope_depth] 320 ]); 321 322 translate([0, back_depth - inner_back_cavity_offset, -height / 2]) 323 linear_extrude(height = bottom_from_base) 324 translate([-width / 2, 0, 0]) 325 polygon([ 326 [width - inner_back_slope_offset_from_left, 0], 327 [width - inner_back_cavity_offset_from_left, 0], 328 [width - inner_back_cavity_offset_from_left, 329 -inner_back_slope_depth], 330 [width - inner_back_slope_offset_from_left - 331 inner_back_slope_width, 332 -inner_back_slope_depth] 333 ]); 334 335 /* Inner back edge cavity. */ 336 337 translate([inner_back_edge_width / 2, 338 back_depth - inner_back_edge_offset, -height / 2]) 339 rotate([0, -90, 0]) 340 linear_extrude(height = inner_back_edge_width) 341 polygon([ 342 [-extra, -inner_back_edge_depth], 343 [inner_back_edge_height, -inner_back_edge_depth], 344 [0, 0], 345 [-extra, 0] 346 ]); 347 348 /* Fillets to round off the edges. */ 349 350 union() { 351 352 /* Top left and right rounding. */ 353 354 translate([-width / 2 + ro, back_depth / 2, height / 2 - ro]) 355 rotate([0, 0, 180]) 356 rotate([90, 0, 0]) 357 fillet(rr, back_depth); 358 translate([width / 2 - ro, back_depth / 2, height / 2 - ro]) 359 rotate([90, 0, 0]) 360 fillet(rr, back_depth); 361 362 /* Top back rounding. */ 363 364 translate([0, back_depth - ro, height / 2 - ro]) 365 rotate([0, -90, 0]) 366 fillet(rr, width); 367 368 /* Edge rounding. */ 369 370 translate([width / 2 - ro, back_depth - ro, 0]) 371 fillet(rr, height); 372 translate([-width / 2 + ro, back_depth - ro, 0]) 373 rotate([0, 0, 90]) 374 fillet(rr, height); 375 } 376 } 377 } 378 379 cartridge(); 380