LED_LENS.scad 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. // -----------------------------------------------------------------------
  2. // Modular LED Matrix Prismatic Lens Array (Short Pegs / Manifold Fix)
  3. // -----------------------------------------------------------------------
  4. // NATIVE LANDSCAPE LAYOUT (3 columns x 2 rows)
  5. // Select which tile to generate:
  6. // 1 = Top Left | 2 = Top Mid | 3 = Top Right
  7. // 4 = Bottom Left | 5 = Bottom Mid | 6 = Bottom Right
  8. part = 1; // [1:6]
  9. // --- Matrix Parameters ---
  10. cellsX = 16;
  11. cellsY = 16;
  12. pitch = 10;
  13. meshSolid = 2;
  14. meshSpace = pitch - meshSolid; // 8mm hole space from the Front Grid
  15. borderWidth = 10;
  16. // --- Lens Array Parameters ---
  17. baseThickness = 0.4; // 2 layers at 0.2mm for an ultra-thin sandwich film
  18. clearance = 0.3; // Friction fit tolerance
  19. plugSize = meshSpace - clearance; // ~7.7mm peg
  20. plugHeight = 1.5; // SHORTENED: Snaps into hole but leaves an air gap above the LED
  21. prismSize = 1.5; // Size of the light-scattering pyramids on top
  22. prismHeight = 0.8; // Height of the pyramids
  23. // --- Logic ---
  24. hasLeft = (part == 1 || part == 4) ? 1 : 0;
  25. hasRight = (part == 3 || part == 6) ? 1 : 0;
  26. hasTop = (part == 1 || part == 2 || part == 3) ? 1 : 0;
  27. hasBottom = (part == 4 || part == 5 || part == 6) ? 1 : 0;
  28. gridWidth = cellsX * pitch;
  29. gridHeight = cellsY * pitch;
  30. leftOffset = hasLeft * borderWidth;
  31. bottomOffset = hasBottom * borderWidth;
  32. totalWidth = gridWidth + (hasLeft * borderWidth) + (hasRight * borderWidth);
  33. totalHeight = gridHeight + (hasTop * borderWidth) + (hasBottom * borderWidth);
  34. holeRad = 2; // Clearance for M3 screws
  35. // --- Procedural Prismatic Refractor (Manifold Safe) ---
  36. module pyramid(size, h) {
  37. // A 4-sided cylinder rotated 45 degrees makes a perfect, render-safe square pyramid
  38. translate([size/2, size/2, 0])
  39. rotate([0, 0, 45])
  40. cylinder(h=h, r1=size/sqrt(2), r2=0, $fn=4);
  41. }
  42. module refractor_top(size, h, step) {
  43. count = floor(size / step);
  44. offset = (size - (count * step)) / 2;
  45. translate([offset, offset, 0])
  46. for(x=[0:count-1]) {
  47. for(y=[0:count-1]) {
  48. translate([x*step, y*step, 0])
  49. pyramid(step, h);
  50. }
  51. }
  52. }
  53. // --- Main Build ---
  54. difference() {
  55. union() {
  56. // 1. The Ultra-Thin Sandwich Film Base
  57. cube([totalWidth, totalHeight, baseThickness]);
  58. // 2. The Extruded Diffuser Pegs
  59. for (x = [0 : cellsX - 1]) {
  60. for (y = [0 : cellsY - 1]) {
  61. // Calculate position to exactly match the Front Grid holes
  62. px = leftOffset + (meshSolid/2) + (x * pitch) + (clearance/2);
  63. py = bottomOffset + (meshSolid/2) + (y * pitch) + (clearance/2);
  64. translate([px, py, baseThickness]) {
  65. // Solid Light Pipe
  66. cube([plugSize, plugSize, plugHeight]);
  67. // Prismatic Scatter Top
  68. translate([0, 0, plugHeight])
  69. refractor_top(plugSize, prismHeight, prismSize);
  70. }
  71. }
  72. }
  73. }
  74. // 3. Punch alignment holes perfectly matched to the outer frame
  75. if (hasLeft) {
  76. for (i = [1 : 3]) {
  77. translate([borderWidth / 2, bottomOffset + (i * gridHeight/4), -0.1])
  78. cylinder(h=baseThickness + plugHeight + prismHeight + 1, r=holeRad, $fn=32);
  79. }
  80. }
  81. if (hasRight) {
  82. for (i = [1 : 3]) {
  83. translate([totalWidth - (borderWidth / 2), bottomOffset + (i * gridHeight/4), -0.1])
  84. cylinder(h=baseThickness + plugHeight + prismHeight + 1, r=holeRad, $fn=32);
  85. }
  86. }
  87. if (hasTop) {
  88. for (i = [1 : 3]) {
  89. translate([leftOffset + (i * gridWidth/4), totalHeight - (borderWidth / 2), -0.1])
  90. cylinder(h=baseThickness + plugHeight + prismHeight + 1, r=holeRad, $fn=32);
  91. }
  92. }
  93. if (hasBottom) {
  94. for (i = [1 : 3]) {
  95. translate([leftOffset + (i * gridWidth/4), borderWidth / 2, -0.1])
  96. cylinder(h=baseThickness + plugHeight + prismHeight + 1, r=holeRad, $fn=32);
  97. }
  98. }
  99. }