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