// CyberDeck case — RUGGED MODULAR // Ammo-can-inspired sealed box with a gasket lip and four separate // snap-in module bays (compute, radio, display, keyboard) so any one // component can be swapped without opening the whole enclosure — the // odd one out of the four: not a laptop/slab/typewriter shape at all, // built for field use (dust, drops) over desk aesthetics. // Fits: Raspberry Pi 4/5, Meshtastic-class LoRa board, 5-7" DSI/HDMI display, // BB Q10/Q20-class keyboard. See ../bom.json for source hardware. // // Print settings: 0.28mm layer height, 40% infill (structural — this case // is meant to survive drops), supports OFF (designed support-free), ASA or // PETG for outdoor UV/heat tolerance, print the lid gasket lip flat-down // for max layer strength across the seal line. // // Compile: openscad -o rugged-modular.stl rugged-modular.scad pi_w = 85; pi_d = 56; pi_h = 17; lora_w = 51; lora_d = 26; lora_h = 14; disp_w = 194; disp_d = 110; disp_h = 20; kb_w = 116; kb_d = 43; kb_h = 10; wall = 4; // thick, rugged gasket = 2; lid_h = 14; box_w = disp_w + 2*(wall+6); box_d = disp_d + kb_d + 3*(wall+6); box_h = pi_h + lora_h + wall*3 + 10; module rounded_box3(w,d,h,r) { hull(){ for (x=[r,w-r]) for (y=[r,d-r]) translate([x,y,0]) cylinder(r=r,h=h,$fn=32); } } module base_box() { difference(){ rounded_box3(box_w, box_d, box_h, 6); translate([wall,wall,wall]) rounded_box3(box_w-2*wall, box_d-2*wall, box_h, 5); // gasket channel around the top rim translate([0,0,box_h-gasket-1]) difference(){ rounded_box3(box_w, box_d, gasket+2, 6); translate([wall-gasket, wall-gasket, -1]) rounded_box3(box_w-2*(wall-gasket), box_d-2*(wall-gasket), gasket+4, 4); } } // four internal module bay dividers divider_y = wall + disp_d + 6; translate([wall, divider_y, wall]) cube([box_w-2*wall, wall, box_h-wall*2]); translate([box_w/2, wall, wall]) cube([wall, disp_d, box_h-wall*2]); // corner reinforcement gussets (rugged detail) for (c=[[wall,wall],[box_w-wall*3,wall],[wall,box_d-wall*3],[box_w-wall*3,box_d-wall*3]]) translate([c[0],c[1],wall]) cube([wall*2, wall*2, 12]); // engraved wordmark on the front exterior face, recessed panel translate([box_w/2, -0.1, box_h*0.6]) rotate([90,0,0]) linear_extrude(height=0.6) text("PERFECT WORLD PROJECT", size=5.5, halign="center", valign="center", font="Liberation Mono:style=Bold"); translate([box_w/2, -0.1, box_h*0.6-9]) rotate([90,0,0]) linear_extrude(height=0.6) text("CYBERDECK — RUGGED MODULAR", size=3.2, halign="center", valign="center", font="Liberation Mono"); } module lid() { difference(){ rounded_box3(box_w, box_d, lid_h, 6); translate([wall, wall, gasket]) rounded_box3(box_w-2*wall, box_d-2*wall, lid_h, 4); // display window translate([wall+6, wall+6, -1]) cube([disp_w, disp_d, lid_h+2]); // keyboard window translate([(box_w-kb_w)/2, box_d-wall-6-kb_d, -1]) cube([kb_w, kb_d, lid_h+2]); } // gasket tongue matching base channel translate([wall-gasket, wall-gasket, -gasket]) difference(){ rounded_box3(box_w-2*(wall-gasket), box_d-2*(wall-gasket), gasket, 4); translate([gasket,gasket,-1]) rounded_box3(box_w-2*wall, box_d-2*wall, gasket+2, 3); } // four corner latch tabs (printed cantilever snaps, field-serviceable // without tools — the point of the "modular" name) for (c=[[10,0],[box_w-10-8,0],[10,box_d-4],[box_w-10-8,box_d-4]]) translate([c[0],c[1],-6]) cube([8,4,6]); } translate([0,0,0]) base_box(); translate([box_w+20,0,0]) lid();