| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- // -----------------------------------------------------------------------
- // Modular 6-Part Enclosure for 10mm Pitch LED Matrix WITH DOVETAILS
- // -----------------------------------------------------------------------
- // NATIVE LANDSCAPE LAYOUT (3 columns x 2 rows)
- // Select which tile to generate:
- // 1 = Top Left | 2 = Top Mid | 3 = Top Right
- // 4 = Bottom Left | 5 = Bottom Mid | 6 = Bottom Right
- part = 1; // [1:6]
- // --- Core Math ---
- cellsX = 16;
- cellsY = 16;
- pitch = 10;
- gridWidth = cellsX * pitch;
- gridHeight = cellsY * pitch;
- borderWidth = 10;
- // Internal depth is 51mm (clearing the 49mm box height)
- depth = 55;
- wall = 4;
- // Logic for 3x2 Landscape Grid
- hasLeft = (part == 1 || part == 4) ? 1 : 0;
- hasRight = (part == 3 || part == 6) ? 1 : 0;
- hasTop = (part == 1 || part == 2 || part == 3) ? 1 : 0;
- hasBottom = (part == 4 || part == 5 || part == 6) ? 1 : 0;
- leftOffset = hasLeft * borderWidth;
- bottomOffset = hasBottom * borderWidth;
- totalWidth = gridWidth + (hasLeft * borderWidth) + (hasRight * borderWidth);
- totalHeight = gridHeight + (hasTop * borderWidth) + (hasBottom * borderWidth);
- $fn = 24;
- // --- Dovetail Joint Geometry ---
- module dovetail(clearance=0) {
- linear_extrude(wall)
- polygon([
- [-0.1, -6 - clearance],
- [8, -10 - clearance],
- [8, 10 + clearance],
- [-0.1, 6 + clearance]
- ]);
- }
- module posts() {
- holeRad = 1.4; // Sized for M3 self-tapping screws
- postRad = 4;
-
- // Left Border
- if (hasLeft) {
- for (i = [1 : 3]) {
- translate([borderWidth / 2, bottomOffset + (i * gridHeight/4), 0])
- difference() {
- cylinder(h=depth, r=postRad);
- translate([0, 0, wall]) cylinder(h=depth, r=holeRad);
- }
- }
- }
- // Right Border
- if (hasRight) {
- for (i = [1 : 3]) {
- translate([totalWidth - (borderWidth / 2), bottomOffset + (i * gridHeight/4), 0])
- difference() {
- cylinder(h=depth, r=postRad);
- translate([0, 0, wall]) cylinder(h=depth, r=holeRad);
- }
- }
- }
- // Top Border
- if (hasTop) {
- for (i = [1 : 3]) {
- translate([leftOffset + (i * gridWidth/4), totalHeight - (borderWidth / 2), 0])
- difference() {
- cylinder(h=depth, r=postRad);
- translate([0, 0, wall]) cylinder(h=depth, r=holeRad);
- }
- }
- }
- // Bottom Border
- if (hasBottom) {
- for (i = [1 : 3]) {
- translate([leftOffset + (i * gridWidth/4), borderWidth / 2, 0])
- difference() {
- cylinder(h=depth, r=postRad);
- translate([0, 0, wall]) cylinder(h=depth, r=holeRad);
- }
- }
- }
- }
- module keyhole() {
- cylinder(r=4, h=wall+2, center=true);
- translate([0, 6, 0]) cylinder(r=2.2, h=wall+2, center=true);
- translate([0, 3, 0]) cube([4.4, 6, wall+2], center=true);
- }
- difference() {
- union() {
- // Main block
- cube([totalWidth, totalHeight, depth]);
-
- // Add Male Dovetail Tabs on internal edges
- if (!hasRight) {
- for(i=[1:3]) translate([totalWidth, totalHeight * 0.25 * i, 0]) dovetail(0);
- }
- if (!hasBottom) {
- for(i=[1:3]) translate([totalWidth * 0.25 * i, 0, 0]) rotate([0, 0, -90]) dovetail(0);
- }
- }
-
- // Cavity cutout
- cutX = hasLeft ? wall : -1;
- cutY = hasBottom ? wall : -1;
- cutW = totalWidth - (hasLeft ? wall : -1) - (hasRight ? wall : -1);
- cutH = totalHeight - (hasBottom ? wall : -1) - (hasTop ? wall : -1);
-
- translate([cutX, cutY, wall])
- cube([cutW, cutH, depth]);
-
- // Subtract Female Dovetail Cuts on internal edges
- if (!hasLeft) {
- for(i=[1:3]) translate([0, totalHeight * 0.25 * i, 0]) dovetail(0.3);
- }
- if (!hasTop) {
- for(i=[1:3]) translate([totalWidth * 0.25 * i, totalHeight, 0]) rotate([0, 0, -90]) dovetail(0.3);
- }
-
- // Power Jack (9mm hole) straight through the right wall
- if (part == 6) {
- // Y = 17.5 (slot start) + 12.5 (center of 25mm controller) = 30
- // Z = 4 (floor) + 19 = 23
- translate([totalWidth + 1, 30, 23])
- rotate([0, -90, 0])
- cylinder(h=wall + 20, r=4.5);
- }
-
- // Wall mount keyholes on top parts
- if (hasTop && hasLeft) {
- translate([totalWidth/2, totalHeight/2, wall/2])
- keyhole();
- }
- if (hasTop && hasRight) {
- translate([totalWidth/2, totalHeight/2, wall/2])
- keyhole();
- }
- }
- // Add mounting posts back into the cavity
- posts();
- // =================================================================
- // PERPENDICULAR CONTROLLER SLOT
- // Exclusively generated on Part 6.
- // Mounts the 25x49 face dead flush against the internal right wall.
- // Controller extends 90mm inward along the X-axis.
- // =================================================================
- if (part == 6) {
- // Left retaining wall (X-axis inner stop at 90mm length)
- translate([73, 15.5, wall])
- cube([2, 30, 20]);
-
- // Top retaining wall (Y-axis upper stop)
- translate([73, 43.5, wall])
- cube([93, 2, 20]);
-
- // Bottom retaining wall (Y-axis lower stop)
- translate([73, 15.5, wall])
- cube([93, 2, 20]);
- }
|