Преглед изворни кода

Cut cable channel through hinge drum; full-width Y+ lid flange

- align drum axis with epd_case pivot (LID_T+LIP)
- channel hulled between flat-plate FPC slot mouth and epd_case
  backplate slot exit; cable now routes fully inside the drum
- Y+ locking flange/rib now a single piece across the face (FPC notch
  obsolete), also prevents cable pinch during assembly
- add _section.scad customizer-driven cross-section viewer; wrap
  combined.scad parts in assembly() module for it
ZiB пре 3 месеци
родитељ
комит
734a2a747a
4 измењених фајлова са 67 додато и 121 уклоњено
  1. 0 92
      _rim_compare.scad
  2. 23 0
      _section.scad
  3. 16 12
      combined.scad
  4. 28 17
      lid.scad

+ 0 - 92
_rim_compare.scad

@@ -1,92 +0,0 @@
-include <params.scad>
-
-module old_rim() {
-  color("#2C3863") {
-    hull() {
-      translate([WALL + FLANGE_W - SLIDE_CLEAR - 0.01, 0, 0])
-        cube([0.01, LID_Y_LEN - FLANGE_W + SLIDE_CLEAR, FLANGE_H - SLIDE_CLEAR]);
-      translate([WALL + SLIDE_CLEAR, 0, -0.005])
-        cube([0.01, LID_Y_LEN - FLANGE_W + SLIDE_CLEAR, 0.01]);
-    }
-    hull() {
-      translate([OUT_L - WALL - FLANGE_W + SLIDE_CLEAR, 0, 0])
-        cube([0.01, LID_Y_LEN - FLANGE_W + SLIDE_CLEAR, FLANGE_H - SLIDE_CLEAR]);
-      translate([OUT_L - WALL - SLIDE_CLEAR - 0.01, 0, -0.005])
-        cube([0.01, LID_Y_LEN - FLANGE_W + SLIDE_CLEAR, 0.01]);
-    }
-    translate([WALL + FLANGE_W - SLIDE_CLEAR, 0, 0])
-      cube([2.0, LID_Y_LEN - FLANGE_W + SLIDE_CLEAR, FLANGE_H]);
-    translate([OUT_L - WALL - FLANGE_W + SLIDE_CLEAR - 2.0, 0, 0])
-      cube([2.0, LID_Y_LEN - FLANGE_W + SLIDE_CLEAR, FLANGE_H]);
-
-    hull() {
-      translate([FLANGE_W - SLIDE_CLEAR + 2.0, LID_Y_LEN - FLANGE_W + SLIDE_CLEAR - 0.01, 0])
-        cube([OUT_L - 2*(FLANGE_W - SLIDE_CLEAR + 2.0), 0.01, FLANGE_H - SLIDE_CLEAR]);
-      translate([FLANGE_W - SLIDE_CLEAR + 2.0, LID_Y_LEN - SLIDE_CLEAR - 0.01, -0.005])
-        cube([OUT_L - 2*(FLANGE_W - SLIDE_CLEAR + 2.0), 0.01, 0.01]);
-    }
-    translate([FLANGE_W - SLIDE_CLEAR + 2.0, LID_Y_LEN - FLANGE_W + SLIDE_CLEAR - 2.0, 0])
-      cube([OUT_L - 2*(FLANGE_W - SLIDE_CLEAR + 2.0), 2.0, FLANGE_H]);
-
-    intersection() {
-      hull() {
-        translate([WALL + FLANGE_W - SLIDE_CLEAR - 0.01, LID_Y_LEN - FLANGE_W + SLIDE_CLEAR, 0])
-          cube([0.01, FLANGE_W - 2*SLIDE_CLEAR, FLANGE_H - SLIDE_CLEAR]);
-        translate([WALL + SLIDE_CLEAR, LID_Y_LEN - FLANGE_W + SLIDE_CLEAR, -0.005])
-          cube([0.01, FLANGE_W - 2*SLIDE_CLEAR, 0.01]);
-      }
-      hull() {
-        translate([WALL + SLIDE_CLEAR, LID_Y_LEN - FLANGE_W + SLIDE_CLEAR, 0])
-          cube([FLANGE_W - 2*SLIDE_CLEAR, 0.01, FLANGE_H - SLIDE_CLEAR]);
-        translate([WALL + SLIDE_CLEAR, LID_Y_LEN - SLIDE_CLEAR - 0.01, -0.005])
-          cube([FLANGE_W - 2*SLIDE_CLEAR, 0.01, 0.01]);
-      }
-    }
-    intersection() {
-      hull() {
-        translate([OUT_L - WALL - FLANGE_W + SLIDE_CLEAR, LID_Y_LEN - FLANGE_W + SLIDE_CLEAR, 0])
-          cube([0.01, FLANGE_W - 2*SLIDE_CLEAR, FLANGE_H - SLIDE_CLEAR]);
-        translate([OUT_L - WALL - SLIDE_CLEAR - 0.01, LID_Y_LEN - FLANGE_W + SLIDE_CLEAR, -0.005])
-          cube([0.01, FLANGE_W - 2*SLIDE_CLEAR, 0.01]);
-      }
-      hull() {
-        translate([OUT_L - WALL - FLANGE_W + SLIDE_CLEAR, LID_Y_LEN - FLANGE_W + SLIDE_CLEAR, 0])
-          cube([FLANGE_W - 2*SLIDE_CLEAR, 0.01, FLANGE_H - SLIDE_CLEAR]);
-        translate([OUT_L - WALL - FLANGE_W + SLIDE_CLEAR, LID_Y_LEN - SLIDE_CLEAR - 0.01, -0.005])
-          cube([FLANGE_W - 2*SLIDE_CLEAR, 0.01, 0.01]);
-      }
-    }
-  }
-}
-
-RIB = 2.0;
-
-module ring(x0, x1, y1, h, run) {
-  translate([x0, 0, 0])
-    diff()
-    cuboid([x1 - x0, y1, h], anchor=BOTTOM+FRONT+LEFT) {
-      if (run > 0)
-        edge_profile_asym([TOP+LEFT, TOP+RIGHT, TOP+BACK], corner_type="chamfer")
-          mask2d_chamfer(x=run, y=h);
-      tag("remove")
-        position(BOTTOM+FRONT+LEFT)
-          translate([run, -0.1, -0.1])
-            cuboid([(x1 - x0) - 2*run, y1 - run + 0.1, h + 0.2], anchor=BOTTOM+FRONT+LEFT);
-    }
-}
-
-module new_rim() {
-  color("#2C3863") {
-    ring(WALL + SLIDE_CLEAR, OUT_L - WALL - SLIDE_CLEAR, LID_Y_LEN,
-         FLANGE_H - SLIDE_CLEAR, FLANGE_W);
-    ring(WALL + SLIDE_CLEAR + FLANGE_W, OUT_L - WALL - SLIDE_CLEAR - FLANGE_W, LID_Y_LEN,
-         FLANGE_H, RIB);
-  }
-}
-
-
-// ============================================================
-// RENDER — old (hand-rolled) vs new (BOSL2 cuboid+chamfer)
-// ============================================================
-old_rim();
-translate([0, LID_Y_LEN + 15, 0]) new_rim();

+ 23 - 0
_section.scad

@@ -0,0 +1,23 @@
+// Cross-section viewer — open in the OpenSCAD GUI and drive from the Customizer
+// (Window > Customizer). Slices PART with a plane normal to AXIS at POS, keeping
+// the positive side (FLIP keeps the other half). Not a printable part.
+include <params.scad>
+use <combined.scad>
+use <cpu_case.scad>
+use <lid.scad>
+use <epd_case.scad>
+
+/* [Section] */
+PART = "lid";  // [lid, base, epd_case, assembly]
+AXIS = "X";    // [X, Y, Z]
+POS  = 66.0;   // [-10:0.5:200]
+FLIP = false;
+
+_v = AXIS == "X" ? [1, 0, 0] : AXIS == "Y" ? [0, 1, 0] : [0, 0, 1];
+
+half_of(v = FLIP ? -_v : _v, cp = POS * _v, s = 600) {
+  if      (PART == "lid")      lid();
+  else if (PART == "base")     base();
+  else if (PART == "epd_case") epd_case();
+  else                         assembly();
+}

+ 16 - 12
combined.scad

@@ -16,19 +16,23 @@ SHOW_BATTERY  = true;
 SHOW_DISP     = true;
 EXPLODE       = $t*75;   // mm to pull lid out in Y- for inspection (try 40)
 
-if (SHOW_BASE)  base();
+module assembly() {
+  if (SHOW_BASE)  base();
 
-if ($preview && SHOW_BATTERY) battery();
+  if ($preview && SHOW_BATTERY) battery();
 
-if (SHOW_LID)
-  translate([0,
-             WALL - EXPLODE,
-             BASE_H - FLANGE_H])
-    lid();
+  if (SHOW_LID)
+    translate([0,
+               WALL - EXPLODE,
+               BASE_H - FLANGE_H])
+      lid();
 
-if ($preview && SHOW_BOARD) stl_board();
+  if ($preview && SHOW_BOARD) stl_board();
 
-if (SHOW_PLUNGERS)
-  for (bcx = BTN_CX)
-    translate([PCB_OX + bcx, OUT_W - WALL, PCB_Z + BTN_CZ])
-      plunger();
+  if (SHOW_PLUNGERS)
+    for (bcx = BTN_CX)
+      translate([PCB_OX + bcx, OUT_W - WALL, PCB_Z + BTN_CZ])
+        plunger();
+}
+
+assembly();

+ 28 - 17
lid.scad

@@ -43,23 +43,20 @@ module lid() {
     translate([OUT_L - WALL - FLANGE_W + SLIDE_CLEAR - 2.0, 0, 0])
       cube([2.0, LID_Y_LEN - FLANGE_W + SLIDE_CLEAR, FLANGE_H]);
 
-    // Y+ locking flanges — angled wedge matching side-flange profile; split around FPC notch
-    for (seg = [
-      [FLANGE_W - SLIDE_CLEAR + 2.0,
-       2+PCB_OX + FPC_CX - FPC_NOTCH_W/2 - (WALL + FLANGE_W - SLIDE_CLEAR + 2.0)],
-      [PCB_OX + FPC_CX + FPC_NOTCH_W/2,
-       OUT_L - FLANGE_W + SLIDE_CLEAR - 2.0 - (PCB_OX + FPC_CX + FPC_NOTCH_W/2)]
-    ]) {
-      hull() {
-        translate([seg[0], LID_Y_LEN - FLANGE_W + SLIDE_CLEAR - 0.01, 0])
-          cube([seg[1], 0.01, FLANGE_H - SLIDE_CLEAR]);
-        translate([seg[0], LID_Y_LEN - SLIDE_CLEAR - 0.01, -0.005])
-          cube([seg[1], 0.01, 0.01]);
-      }
-      // Backing rib — 2 mm deep on cavity face of flange, matches side-rib style
-      translate([seg[0], LID_Y_LEN - FLANGE_W + SLIDE_CLEAR - 2.0, 0])
-        cube([seg[1], 2.0, FLANGE_H]);
+    // Y+ locking flange — single angled wedge matching side-flange profile.
+    // Spans the whole face (the old FPC notch split is no longer needed thanks
+    // to the Y- clearance) and shields the cable from pinching during assembly.
+    _ypf_x0 = FLANGE_W - SLIDE_CLEAR + 2.0;
+    _ypf_w  = OUT_L - FLANGE_W + SLIDE_CLEAR - 2.0 - _ypf_x0;
+    hull() {
+      translate([_ypf_x0, LID_Y_LEN - FLANGE_W + SLIDE_CLEAR - 0.01, 0])
+        cube([_ypf_w, 0.01, FLANGE_H - SLIDE_CLEAR]);
+      translate([_ypf_x0, LID_Y_LEN - SLIDE_CLEAR - 0.01, -0.005])
+        cube([_ypf_w, 0.01, 0.01]);
     }
+    // Backing rib — 2 mm deep on cavity face of flange, matches side-rib style
+    translate([_ypf_x0, LID_Y_LEN - FLANGE_W + SLIDE_CLEAR - 2.0, 0])
+      cube([_ypf_w, 2.0, FLANGE_H]);
 
     // Y+ corners — intersection of the X-prism and Y-prism in the corner region.
     // Equivalent to: cube with the X-flange relief cut AND the Y-flange relief cut applied.
@@ -113,7 +110,7 @@ module lid() {
         // Inset CORNER_R from each end so it stays clear of the corner rounding.
         if (EPD_ANGLE > 0)
           color("#004B49")
-          translate([OUT_L/2 - epd_case_w/2 + CORNER_R, OUT_W - WALL, LID_T + WALL])
+          translate([OUT_L/2 - epd_case_w/2 + CORNER_R, OUT_W - WALL, LID_T + LIP])
             rotate([0, 90, 0])
               pie_slice(ang=EPD_ANGLE, l=epd_case_w - 2*CORNER_R, r=HINGE_R,
                         spin=270 - EPD_ANGLE, anchor=BOT, $fn=96);
@@ -135,6 +132,20 @@ module lid() {
                FPC_SLOT_Y0,
                FLANGE_H - 0.1])
       cube([FPC_NOTCH_W, FPC_SLOT_W, LID_T + 0.2]);
+
+    // Cable channel through hinge drum — straight tapered passage hulled between
+    // the flat-plate slot mouth and the epd_case backplate slot exit on the tilted
+    // face. Both mouths share the same X extent; the hull stays >1.9 mm inside the
+    // drum's curved surface.
+    if (EPD_IS_LID && EPD_ANGLE > 0)
+      hull() {
+        translate([PCB_OX + FPC_CX - FPC_NOTCH_W/2, FPC_SLOT_Y0, FLANGE_H + LID_T - 0.1])
+          cube([FPC_NOTCH_W, FPC_SLOT_W, 0.2]);
+        translate([OUT_L/2 - epd_case_w/2, OUT_W - WALL, LID_T + LIP])
+          rotate([-EPD_ANGLE, 0, 0])
+            translate([_fpc_x1, BEZEL_Y + DISP_D + DISP_Y_EXTRA - epd_case_d, -0.1])
+              cube([_fpc_xw, FPC_SLOT_W, 0.2]);
+      }
   }
 }