vibe-openscad

tier-3-butt-hinge / gpt-5.4-mini-2026-03-17

7 run / 累計 228.5s / 累計 $0.1079

openai gpt 5.4 mini 2026-03-17 bare

bare (provider default effort)

run detail →
render
bare render of tier-3-butt-hinge
loading STL…
success 6.6s · 592/789t · $0.0026
SCAD (100 lines)
$fn = 96;

// Parameters
leaf_len = 30;
leaf_w   = 25;
leaf_th  = 2;

pin_d = 4;
pin_len = 32;

knuckle_od = 8;
knuckle_id  = 4.6;
knuckle_len = 6;

clear_x = 0.05;   // tiny assembly clearance
clear_z = 0.02;

m3_through_d = 3.2;
m3_csk_top_d = 6;
m3_csk_depth = 1;

leaf_hole_y = [-8, 0, 8];   // 8 mm pitch, 3 holes

// Derived positions
y_min = -leaf_len/2;
y_max =  leaf_len/2;

module leaf_base(side=1) {
    // side: -1 left, +1 right
    translate([side*(pin_len/2 + leaf_w/2 - clear_x), 0, 0])
        cube([leaf_w, leaf_len, leaf_th], center=true);
}

module knuckle_segment(yc) {
    translate([0, yc, 0])
    difference() {
        cylinder(d=knuckle_od, h=knuckle_len, center=true);
        cylinder(d=knuckle_id, h=knuckle_len + 2, center=true);
    }
}

module pin_axis() {
    translate([0, 0, 0])
        cylinder(d=pin_d, h=pin_len, center=true);
}

module countersunk_holes(side=1) {
    // side: -1 left leaf, +1 right leaf
    // holes are on the side far from knuckles
    x_hole = side*(pin_len/2 + leaf_w - 6);  // near outer edge, inside plate
    for (yy = leaf_hole_y) {
        translate([x_hole, yy, 0]) {
            // through hole
            translate([0, 0, -leaf_th/2 - 0.1])
                cylinder(d=m3_through_d, h=leaf_th + 0.2, center=false);
            // countersink from outer surface
            translate([0, 0, leaf_th/2 - m3_csk_depth])
                cylinder(d1=m3_csk_top_d, d2=m3_through_d, h=m3_csk_depth, center=false);
        }
    }
}

module leaf_with_knuckles(side=1) {
    // side: -1 left leaf, +1 right leaf
    difference() {
        union() {
            // plate
            leaf_base(side);

            // knuckles: left leaf gets 3 segments, right leaf gets 2 segments
            if (side < 0) {
                // outer, middle, outer
                knuckle_segment(-9);
                knuckle_segment(0);
                knuckle_segment(9);
            } else {
                // two middle segments
                knuckle_segment(-4.5);
                knuckle_segment(4.5);
            }
        }
        countersunk_holes(side);
    }
}

// Assemble opened state (180°): both leaf flats on same plane
// Pin axis is along Y and centered at X=0, Z=0.
union() {
    // Left leaf extends to -X
    translate([-(pin_len/2 + leaf_w/2), 0, 0])
        rotate([0, 180, 0])
            leaf_with_knuckles(-1);

    // Right leaf extends to +X
    translate([ (pin_len/2 + leaf_w/2), 0, 0])
        leaf_with_knuckles(+1);

    // Pin axis
    pin_axis();
}
パラメータ (13)
スライダを動かすと openscad-wasm で再レンダリング

prompt

OpenSCAD で、家具用の小型バット蝶番(butt hinge)を作ってください。
3 つのパーツ(左板、右板、ピン軸)が組み合わさって動作する完成品を、
「開いた状態(180°)」で 1 つの SCAD ファイルに配置して出力します。

寸法と配置:
- 板(leaf)2 枚: 30mm × 25mm × 厚さ 2mm の鉄板形状
  - 縦 30mm の辺がピン軸に沿う(ヒンジ軸方向)
  - 横 25mm の辺が回転で開く方向に伸びる
- ピン軸: 直径 4mm の円柱、長さ 32mm(両端 1mm ずつ knuckle から飛び出す)
- knuckle(筒部): 縦 30mm を 5 等分(各 6mm)に区切り、左板に 3 個・右板に 2 個を
  互い違いに配置(左板は外側 2 個 + 中央 1 個、右板は中間 2 個)
- knuckle 外径 8mm、内径はピン軸 + 0.3mm クリアランス(= 4.6mm 穴)
- 左板と右板はピン軸を共有して回転可能。180° 開いた状態で、両板の
  平らな面が同一平面に来るように配置する
- 各板の knuckle から離れた側に、M3 用の皿穴を 3 個ずつ
  (穴ピッチは板の縦方向に 8mm 間隔、皿穴は表面から見て直径 6mm × 深さ 1mm
  のテーパ + 直径 3.2mm の貫通穴)

座標系:
- ピン軸の中心線を Y 軸に重ねる(ピン軸は +Y 方向)
- 板の平らな面は Z 軸に直交し、左板が x<0 側、右板が x>0 側に伸びる(180° 開)
- knuckle は X=0 を中心とし、Y 方向に 6mm ずつ並ぶ

完成したコード全体を ```openscad ... ``` のフェンスで囲んで出力してください。
コードのみで、追加の説明は不要です。

variant: effort

low success
low
18.3s · 592/2297t · $0.0071
SCAD (91 lines)
$fn = 64;

// Dimensions
leaf_len = 30;          // along Y
leaf_w   = 25;          // along X
leaf_t   = 2;           // along Z

pin_d    = 4;
pin_r    = pin_d/2;
pin_len  = 32;          // 1mm protrusion each side beyond 30mm knuckle span

knuckle_od = 8;
knuckle_r  = knuckle_od/2;
knuckle_id  = 4.6;
knuckle_ir  = knuckle_id/2;
knuckle_seg = 6;        // 30 / 5

// Countersunk holes (M3)
hole_d   = 3.2;
hole_r   = hole_d/2;
cs_d     = 6;
cs_r     = cs_d/2;
cs_depth = 1;

// Helpers
module pin() {
    translate([0,-1,1])
        cylinder(h=pin_len, r=pin_r, center=false);
}

module knuckle_barrel(yc) {
    translate([0, yc, 1])
        difference() {
            cylinder(h=knuckle_seg, r=knuckle_r, center=true);
            cylinder(h=knuckle_seg + 0.4, r=knuckle_ir, center=true);
        }
}

module leaf_body_left() {
    // Plate spans x = -25..0, y = 0..30, z = 0..2
    difference() {
        union() {
            translate([-leaf_w, 0, 0])
                cube([leaf_w, leaf_len, leaf_t], center=false);

            // Left leaf knuckles: segments 1,3,5
            knuckle_barrel(3);
            knuckle_barrel(15);
            knuckle_barrel(27);
        }

        // M3 countersunk holes, 3 pcs, 8mm pitch along Y
        for (yy = [6, 14, 22]) {
            translate([-leaf_w/2, yy, leaf_t - cs_depth]) {
                cylinder(h=cs_depth + 0.02, r1=cs_r, r2=hole_r, center=false);
                translate([0,0,-0.05])
                    cylinder(h=leaf_t + 0.10, r=hole_r, center=false);
            }
        }
    }
}

module leaf_body_right() {
    // Plate spans x = 0..25, y = 0..30, z = 0..2
    difference() {
        union() {
            translate([0, 0, 0])
                cube([leaf_w, leaf_len, leaf_t], center=false);

            // Right leaf knuckles: segments 2,4
            knuckle_barrel(9);
            knuckle_barrel(21);
        }

        // M3 countersunk holes, 3 pcs, 8mm pitch along Y
        for (yy = [6, 14, 22]) {
            translate([leaf_w/2, yy, leaf_t - cs_depth]) {
                cylinder(h=cs_depth + 0.02, r1=cs_r, r2=hole_r, center=false);
                translate([0,0,-0.05])
                    cylinder(h=leaf_t + 0.10, r=hole_r, center=false);
            }
        }
    }
}

// Assemble open state (180°): both leaves coplanar
union() {
    leaf_body_left();
    leaf_body_right();
    pin();
}
medium (default) success
medium
6.6s · 592/789t · $0.0026
SCAD (100 lines)
$fn = 96;

// Parameters
leaf_len = 30;
leaf_w   = 25;
leaf_th  = 2;

pin_d = 4;
pin_len = 32;

knuckle_od = 8;
knuckle_id  = 4.6;
knuckle_len = 6;

clear_x = 0.05;   // tiny assembly clearance
clear_z = 0.02;

m3_through_d = 3.2;
m3_csk_top_d = 6;
m3_csk_depth = 1;

leaf_hole_y = [-8, 0, 8];   // 8 mm pitch, 3 holes

// Derived positions
y_min = -leaf_len/2;
y_max =  leaf_len/2;

module leaf_base(side=1) {
    // side: -1 left, +1 right
    translate([side*(pin_len/2 + leaf_w/2 - clear_x), 0, 0])
        cube([leaf_w, leaf_len, leaf_th], center=true);
}

module knuckle_segment(yc) {
    translate([0, yc, 0])
    difference() {
        cylinder(d=knuckle_od, h=knuckle_len, center=true);
        cylinder(d=knuckle_id, h=knuckle_len + 2, center=true);
    }
}

module pin_axis() {
    translate([0, 0, 0])
        cylinder(d=pin_d, h=pin_len, center=true);
}

module countersunk_holes(side=1) {
    // side: -1 left leaf, +1 right leaf
    // holes are on the side far from knuckles
    x_hole = side*(pin_len/2 + leaf_w - 6);  // near outer edge, inside plate
    for (yy = leaf_hole_y) {
        translate([x_hole, yy, 0]) {
            // through hole
            translate([0, 0, -leaf_th/2 - 0.1])
                cylinder(d=m3_through_d, h=leaf_th + 0.2, center=false);
            // countersink from outer surface
            translate([0, 0, leaf_th/2 - m3_csk_depth])
                cylinder(d1=m3_csk_top_d, d2=m3_through_d, h=m3_csk_depth, center=false);
        }
    }
}

module leaf_with_knuckles(side=1) {
    // side: -1 left leaf, +1 right leaf
    difference() {
        union() {
            // plate
            leaf_base(side);

            // knuckles: left leaf gets 3 segments, right leaf gets 2 segments
            if (side < 0) {
                // outer, middle, outer
                knuckle_segment(-9);
                knuckle_segment(0);
                knuckle_segment(9);
            } else {
                // two middle segments
                knuckle_segment(-4.5);
                knuckle_segment(4.5);
            }
        }
        countersunk_holes(side);
    }
}

// Assemble opened state (180°): both leaf flats on same plane
// Pin axis is along Y and centered at X=0, Z=0.
union() {
    // Left leaf extends to -X
    translate([-(pin_len/2 + leaf_w/2), 0, 0])
        rotate([0, 180, 0])
            leaf_with_knuckles(-1);

    // Right leaf extends to +X
    translate([ (pin_len/2 + leaf_w/2), 0, 0])
        leaf_with_knuckles(+1);

    // Pin axis
    pin_axis();
}
high success
high
180.6s · 592/28439t · $0.0856
SCAD (58 lines)
$fn = 64;
eps = 0.05;

plate_w = 25;
plate_l = 30;
plate_t = 2;

knuckle_od = 8;
knuckle_id = 4.6;
knuckle_len = 6;

pin_d = 4;
pin_len = 32;

screw_d = 3.2;
sink_d = 6;
sink_depth = 1;
hole_x = plate_w - 7;
hole_ys = [7, 15, 23];

module countersunk_hole(x, y) {
    translate([x, y, plate_t - sink_depth])
        cylinder(h = sink_depth + eps, d1 = sink_d, d2 = screw_d);
    translate([x, y, -eps])
        cylinder(h = plate_t + 2 * eps, d = screw_d);
}

module knuckle(yc) {
    translate([0, yc, plate_t / 2])
        rotate([90, 0, 0])
            difference() {
                cylinder(h = knuckle_len, d = knuckle_od, center = true);
                cylinder(h = knuckle_len + 2 * eps, d = knuckle_id, center = true);
            }
}

module leaf(side, knuckles) {
    difference() {
        union() {
            translate([side < 0 ? -plate_w : 0, 0, 0])
                cube([plate_w, plate_l, plate_t]);
            for (yc = knuckles)
                knuckle(yc);
        }
        for (yy = hole_ys)
            countersunk_hole(side > 0 ? hole_x : -hole_x, yy);
    }
}

color([0.72, 0.72, 0.75]) {
    leaf(-1, [3, 15, 27]);
    leaf(1, [9, 21]);
}

color([0.9, 0.9, 0.95])
translate([0, plate_l / 2, plate_t / 2])
    rotate([90, 0, 0])
    cylinder(h = pin_len, d = pin_d, center = true);
maxnot run
xhighnot run

iteration: iter-png

i1 success
iter 1
5.1s · 2046/757t · $0.0031
diff vs bare: +39/-45
  $fn = 96;
  
  // Parameters
  leaf_len = 30;
  leaf_w   = 25;
  leaf_th  = 2;
  
  pin_d = 4;
  pin_len = 32;
  
  knuckle_od = 8;
- knuckle_id  = 4.6;
+ knuckle_id = 4.6;
  knuckle_len = 6;
  
- clear_x = 0.05;   // tiny assembly clearance
- clear_z = 0.02;
+ leaf_hole_y = [-8, 0, 8];   // 8 mm pitch
  
- m3_through_d = 3.2;
- m3_csk_top_d = 6;
- m3_csk_depth = 1;
+ // Layout
+ // Opened state (180°): both leaf flats lie on the same plane.
+ // Left leaf extends toward -X, right leaf toward +X.
+ // Pin axis is aligned with +Y at X=0.
+ left_leaf_center_x  = -(leaf_w/2 + pin_len/2);
+ right_leaf_center_x =  (leaf_w/2 + pin_len/2);
  
- leaf_hole_y = [-8, 0, 8];   // 8 mm pitch, 3 holes
+ // Knuckle centers along Y: 5 equal sections over 30mm => 6mm each.
+ // Interleaving pattern: left leaf = 3 knuckles, right leaf = 2 knuckles.
+ left_knuckle_y  = [-9, 0, 9];
+ right_knuckle_y = [-4.5, 4.5];
  
- // Derived positions
- y_min = -leaf_len/2;
- y_max =  leaf_len/2;
- 
- module leaf_base(side=1) {
+ module leaf_plate(side=1) {
      // side: -1 left, +1 right
-     translate([side*(pin_len/2 + leaf_w/2 - clear_x), 0, 0])
+     translate([side * (leaf_w/2 + pin_len/2), 0, 0])
          cube([leaf_w, leaf_len, leaf_th], center=true);
  }
  
  module knuckle_segment(yc) {
      translate([0, yc, 0])
      difference() {
          cylinder(d=knuckle_od, h=knuckle_len, center=true);
          cylinder(d=knuckle_id, h=knuckle_len + 2, center=true);
      }
  }
  
  module pin_axis() {
-     translate([0, 0, 0])
-         cylinder(d=pin_d, h=pin_len, center=true);
+     // 1mm protrusion at both ends of the 30mm knuckle span => 32mm total
+     cylinder(d=pin_d, h=pin_len, center=true);
  }
  
- module countersunk_holes(side=1) {
-     // side: -1 left leaf, +1 right leaf
-     // holes are on the side far from knuckles
-     x_hole = side*(pin_len/2 + leaf_w - 6);  // near outer edge, inside plate
+ module leaf_holes(side=1) {
+     // Holes are on the side away from knuckles:
+     // left leaf outer side = negative X, right leaf outer side = positive X
+     x_hole = side * (pin_len/2 + leaf_w - 6);
+ 
      for (yy = leaf_hole_y) {
          translate([x_hole, yy, 0]) {
-             // through hole
-             translate([0, 0, -leaf_th/2 - 0.1])
-                 cylinder(d=m3_through_d, h=leaf_th + 0.2, center=false);
-             // countersink from outer surface
+             // Through hole
+             translate([0, 0, -leaf_th/2 - 0.2])
+                 cylinder(d=m3_through_d, h=leaf_th + 0.4);
+ 
+             // Countersink from the outer surface:
+             // top diameter 6mm, depth 1mm, taper to 3.2mm hole
              translate([0, 0, leaf_th/2 - m3_csk_depth])
-                 cylinder(d1=m3_csk_top_d, d2=m3_through_d, h=m3_csk_depth, center=false);
+                 cylinder(d1=m3_csk_top_d, d2=m3_through_d, h=m3_csk_depth);
          }
      }
  }
  
  module leaf_with_knuckles(side=1) {
      // side: -1 left leaf, +1 right leaf
      difference() {
          union() {
-             // plate
-             leaf_base(side);
+             leaf_plate(side);
  
-             // knuckles: left leaf gets 3 segments, right leaf gets 2 segments
              if (side < 0) {
-                 // outer, middle, outer
-                 knuckle_segment(-9);
-                 knuckle_segment(0);
-                 knuckle_segment(9);
+                 for (yy = left_knuckle_y)
+                     knuckle_segment(yy);
              } else {
-                 // two middle segments
-                 knuckle_segment(-4.5);
-                 knuckle_segment(4.5);
+                 for (yy = right_knuckle_y)
+                     knuckle_segment(yy);
              }
          }
-         countersunk_holes(side);
+         leaf_holes(side);
      }
  }
  
- // Assemble opened state (180°): both leaf flats on same plane
- // Pin axis is along Y and centered at X=0, Z=0.
  union() {
-     // Left leaf extends to -X
-     translate([-(pin_len/2 + leaf_w/2), 0, 0])
-         rotate([0, 180, 0])
-             leaf_with_knuckles(-1);
+     // Left leaf
+     leaf_with_knuckles(-1);
  
-     // Right leaf extends to +X
-     translate([ (pin_len/2 + leaf_w/2), 0, 0])
-         leaf_with_knuckles(+1);
+     // Right leaf
+     leaf_with_knuckles(+1);
  
-     // Pin axis
+     // Pin axis centered on the hinge line
      pin_axis();
  }
SCAD (94 lines)
$fn = 96;

// Parameters
leaf_len = 30;
leaf_w   = 25;
leaf_th  = 2;

pin_d = 4;
pin_len = 32;

knuckle_od = 8;
knuckle_id = 4.6;
knuckle_len = 6;

leaf_hole_y = [-8, 0, 8];   // 8 mm pitch

// Layout
// Opened state (180°): both leaf flats lie on the same plane.
// Left leaf extends toward -X, right leaf toward +X.
// Pin axis is aligned with +Y at X=0.
left_leaf_center_x  = -(leaf_w/2 + pin_len/2);
right_leaf_center_x =  (leaf_w/2 + pin_len/2);

// Knuckle centers along Y: 5 equal sections over 30mm => 6mm each.
// Interleaving pattern: left leaf = 3 knuckles, right leaf = 2 knuckles.
left_knuckle_y  = [-9, 0, 9];
right_knuckle_y = [-4.5, 4.5];

module leaf_plate(side=1) {
    // side: -1 left, +1 right
    translate([side * (leaf_w/2 + pin_len/2), 0, 0])
        cube([leaf_w, leaf_len, leaf_th], center=true);
}

module knuckle_segment(yc) {
    translate([0, yc, 0])
    difference() {
        cylinder(d=knuckle_od, h=knuckle_len, center=true);
        cylinder(d=knuckle_id, h=knuckle_len + 2, center=true);
    }
}

module pin_axis() {
    // 1mm protrusion at both ends of the 30mm knuckle span => 32mm total
    cylinder(d=pin_d, h=pin_len, center=true);
}

module leaf_holes(side=1) {
    // Holes are on the side away from knuckles:
    // left leaf outer side = negative X, right leaf outer side = positive X
    x_hole = side * (pin_len/2 + leaf_w - 6);

    for (yy = leaf_hole_y) {
        translate([x_hole, yy, 0]) {
            // Through hole
            translate([0, 0, -leaf_th/2 - 0.2])
                cylinder(d=m3_through_d, h=leaf_th + 0.4);

            // Countersink from the outer surface:
            // top diameter 6mm, depth 1mm, taper to 3.2mm hole
            translate([0, 0, leaf_th/2 - m3_csk_depth])
                cylinder(d1=m3_csk_top_d, d2=m3_through_d, h=m3_csk_depth);
        }
    }
}

module leaf_with_knuckles(side=1) {
    // side: -1 left leaf, +1 right leaf
    difference() {
        union() {
            leaf_plate(side);

            if (side < 0) {
                for (yy = left_knuckle_y)
                    knuckle_segment(yy);
            } else {
                for (yy = right_knuckle_y)
                    knuckle_segment(yy);
            }
        }
        leaf_holes(side);
    }
}

union() {
    // Left leaf
    leaf_with_knuckles(-1);

    // Right leaf
    leaf_with_knuckles(+1);

    // Pin axis centered on the hinge line
    pin_axis();
}
i2 success
iter 2
6.3s · 2014/979t · $0.0037
diff vs i1: +59/-43
  $fn = 96;
  
- // Parameters
- leaf_len = 30;
- leaf_w   = 25;
- leaf_th  = 2;
+ // Dimensions
+ leaf_len = 30;          // Y direction
+ leaf_w   = 25;          // X direction
+ leaf_th  = 2;           // Z thickness
  
- pin_d = 4;
- pin_len = 32;
+ pin_d    = 4;
+ pin_len  = 32;
  
  knuckle_od = 8;
  knuckle_id = 4.6;
  knuckle_len = 6;
  
- leaf_hole_y = [-8, 0, 8];   // 8 mm pitch
+ m3_through_d = 3.2;
+ m3_csk_top_d  = 6;
+ m3_csk_depth  = 1;
  
- // Layout
- // Opened state (180°): both leaf flats lie on the same plane.
- // Left leaf extends toward -X, right leaf toward +X.
- // Pin axis is aligned with +Y at X=0.
- left_leaf_center_x  = -(leaf_w/2 + pin_len/2);
- right_leaf_center_x =  (leaf_w/2 + pin_len/2);
+ // Geometry positions
+ // Open 180°: both leaves lie in the same plane, with leaves extending
+ // to opposite sides of the hinge axis along X.
+ left_leaf_x  = -(pin_len/2 + leaf_w/2);
+ right_leaf_x =  (pin_len/2 + leaf_w/2);
  
- // Knuckle centers along Y: 5 equal sections over 30mm => 6mm each.
- // Interleaving pattern: left leaf = 3 knuckles, right leaf = 2 knuckles.
- left_knuckle_y  = [-9, 0, 9];
- right_knuckle_y = [-4.5, 4.5];
+ // Knuckles distributed over 30mm in 5 sections of 6mm each.
+ // Each knuckle is centered in its section.
+ // Left leaf: outer 2 + center 1 => sections 1,3,5 => y = -12, 0, 12
+ // Right leaf: middle 2 => sections 2,4 => y = -6, 6
+ left_knuckle_y  = [-12, 0, 12];
+ right_knuckle_y = [-6, 6];
  
+ // M3 holes: 3 per leaf, along Y at 8mm pitch, placed on the side
+ // away from the knuckles.
+ hole_y = [-8, 0, 8];
+ 
  module leaf_plate(side=1) {
      // side: -1 left, +1 right
-     translate([side * (leaf_w/2 + pin_len/2), 0, 0])
+     translate([side * (pin_len/2 + leaf_w/2), 0, 0])
          cube([leaf_w, leaf_len, leaf_th], center=true);
  }
  
  module knuckle_segment(yc) {
      translate([0, yc, 0])
      difference() {
          cylinder(d=knuckle_od, h=knuckle_len, center=true);
          cylinder(d=knuckle_id, h=knuckle_len + 2, center=true);
      }
  }
  
  module pin_axis() {
-     // 1mm protrusion at both ends of the 30mm knuckle span => 32mm total
-     cylinder(d=pin_d, h=pin_len, center=true);
+     // Pin axis is centered on X=0, Z=0 and runs along Y
+     rotate([90,0,0])
+         cylinder(d=pin_d, h=pin_len, center=true);
  }
  
- module leaf_holes(side=1) {
-     // Holes are on the side away from knuckles:
-     // left leaf outer side = negative X, right leaf outer side = positive X
-     x_hole = side * (pin_len/2 + leaf_w - 6);
+ module countersunk_hole_at(x, y) {
+     // Through-hole
+     translate([x, y, 0])
+         cylinder(d=m3_through_d, h=leaf_th + 0.4, center=true);
  
-     for (yy = leaf_hole_y) {
-         translate([x_hole, yy, 0]) {
-             // Through hole
-             translate([0, 0, -leaf_th/2 - 0.2])
-                 cylinder(d=m3_through_d, h=leaf_th + 0.4);
- 
-             // Countersink from the outer surface:
-             // top diameter 6mm, depth 1mm, taper to 3.2mm hole
-             translate([0, 0, leaf_th/2 - m3_csk_depth])
-                 cylinder(d1=m3_csk_top_d, d2=m3_through_d, h=m3_csk_depth);
-         }
-     }
+     // Countersink from the outer face of the leaf
+     // Left leaf outer face is x = left_leaf_x - leaf_w/2
+     // Right leaf outer face is x = right_leaf_x + leaf_w/2
  }
  
  module leaf_with_knuckles(side=1) {
      // side: -1 left leaf, +1 right leaf
+     holes_x = side < 0 ? (left_leaf_x - leaf_w/2 + 0.8) : (right_leaf_x + leaf_w/2 - 0.8);
+     csk_dir = side < 0 ? -1 : 1;
+ 
      difference() {
          union() {
-             leaf_plate(side);
+             // Leaf plate
+             translate([side * (pin_len/2 + leaf_w/2), 0, 0])
+                 cube([leaf_w, leaf_len, leaf_th], center=true);
  
+             // Knuckles
              if (side < 0) {
                  for (yy = left_knuckle_y)
                      knuckle_segment(yy);
              } else {
                  for (yy = right_knuckle_y)
                      knuckle_segment(yy);
              }
          }
-         leaf_holes(side);
+ 
+         // M3 through holes + countersinks
+         for (yy = hole_y) {
+             translate([holes_x, yy, 0]) {
+                 // through
+                 cube([0,0,0]); // no-op to keep scope simple
+ 
+                 // Drill through along X
+                 rotate([0,90,0])
+                     cylinder(d=m3_through_d, h=leaf_w + 2, center=true);
+ 
+                 // Countersink from outer face
+                 translate([csk_dir * (leaf_w/2 - 0.01), 0, 0])
+                     rotate([0,90,0])
+                         cylinder(d1=m3_csk_top_d, d2=m3_through_d, h=m3_csk_depth, center=false);
+             }
+         }
      }
  }
  
  union() {
-     // Left leaf
      leaf_with_knuckles(-1);
- 
-     // Right leaf
      leaf_with_knuckles(+1);
- 
-     // Pin axis centered on the hinge line
      pin_axis();
  }
SCAD (110 lines)
$fn = 96;

// Dimensions
leaf_len = 30;          // Y direction
leaf_w   = 25;          // X direction
leaf_th  = 2;           // Z thickness

pin_d    = 4;
pin_len  = 32;

knuckle_od = 8;
knuckle_id = 4.6;
knuckle_len = 6;

m3_through_d = 3.2;
m3_csk_top_d  = 6;
m3_csk_depth  = 1;

// Geometry positions
// Open 180°: both leaves lie in the same plane, with leaves extending
// to opposite sides of the hinge axis along X.
left_leaf_x  = -(pin_len/2 + leaf_w/2);
right_leaf_x =  (pin_len/2 + leaf_w/2);

// Knuckles distributed over 30mm in 5 sections of 6mm each.
// Each knuckle is centered in its section.
// Left leaf: outer 2 + center 1 => sections 1,3,5 => y = -12, 0, 12
// Right leaf: middle 2 => sections 2,4 => y = -6, 6
left_knuckle_y  = [-12, 0, 12];
right_knuckle_y = [-6, 6];

// M3 holes: 3 per leaf, along Y at 8mm pitch, placed on the side
// away from the knuckles.
hole_y = [-8, 0, 8];

module leaf_plate(side=1) {
    // side: -1 left, +1 right
    translate([side * (pin_len/2 + leaf_w/2), 0, 0])
        cube([leaf_w, leaf_len, leaf_th], center=true);
}

module knuckle_segment(yc) {
    translate([0, yc, 0])
    difference() {
        cylinder(d=knuckle_od, h=knuckle_len, center=true);
        cylinder(d=knuckle_id, h=knuckle_len + 2, center=true);
    }
}

module pin_axis() {
    // Pin axis is centered on X=0, Z=0 and runs along Y
    rotate([90,0,0])
        cylinder(d=pin_d, h=pin_len, center=true);
}

module countersunk_hole_at(x, y) {
    // Through-hole
    translate([x, y, 0])
        cylinder(d=m3_through_d, h=leaf_th + 0.4, center=true);

    // Countersink from the outer face of the leaf
    // Left leaf outer face is x = left_leaf_x - leaf_w/2
    // Right leaf outer face is x = right_leaf_x + leaf_w/2
}

module leaf_with_knuckles(side=1) {
    // side: -1 left leaf, +1 right leaf
    holes_x = side < 0 ? (left_leaf_x - leaf_w/2 + 0.8) : (right_leaf_x + leaf_w/2 - 0.8);
    csk_dir = side < 0 ? -1 : 1;

    difference() {
        union() {
            // Leaf plate
            translate([side * (pin_len/2 + leaf_w/2), 0, 0])
                cube([leaf_w, leaf_len, leaf_th], center=true);

            // Knuckles
            if (side < 0) {
                for (yy = left_knuckle_y)
                    knuckle_segment(yy);
            } else {
                for (yy = right_knuckle_y)
                    knuckle_segment(yy);
            }
        }

        // M3 through holes + countersinks
        for (yy = hole_y) {
            translate([holes_x, yy, 0]) {
                // through
                cube([0,0,0]); // no-op to keep scope simple

                // Drill through along X
                rotate([0,90,0])
                    cylinder(d=m3_through_d, h=leaf_w + 2, center=true);

                // Countersink from outer face
                translate([csk_dir * (leaf_w/2 - 0.01), 0, 0])
                    rotate([0,90,0])
                        cylinder(d1=m3_csk_top_d, d2=m3_through_d, h=m3_csk_depth, center=false);
            }
        }
    }
}

union() {
    leaf_with_knuckles(-1);
    leaf_with_knuckles(+1);
    pin_axis();
}
i3 success
iter 3
5.0s · 2230/759t · $0.0032
diff vs i2: +33/-61
  $fn = 96;
  
- // Dimensions
- leaf_len = 30;          // Y direction
- leaf_w   = 25;          // X direction
- leaf_th  = 2;           // Z thickness
+ // Base dimensions
+ leaf_len = 30;          // along Y
+ leaf_w   = 25;          // along X
+ leaf_th  = 2;           // along Z
  
  pin_d    = 4;
- pin_len  = 32;
+ pin_len  = 32;          // extends 1mm beyond knuckles at both ends
  
  knuckle_od = 8;
  knuckle_id = 4.6;
- knuckle_len = 6;
+ knuckle_len = 6;        // 30mm / 5
  
  m3_through_d = 3.2;
- m3_csk_top_d  = 6;
- m3_csk_depth  = 1;
+ m3_csk_top_d = 6;
+ m3_csk_depth = 1;
  
- // Geometry positions
- // Open 180°: both leaves lie in the same plane, with leaves extending
- // to opposite sides of the hinge axis along X.
- left_leaf_x  = -(pin_len/2 + leaf_w/2);
- right_leaf_x =  (pin_len/2 + leaf_w/2);
+ // Open 180° layout:
+ // leaves are coplanar in Z, and separated on X so their free edges point away
+ // from the hinge axis. Hinge axis is along Y at X=0.
+ left_leaf_center_x  = -(pin_len/2 + leaf_w/2);
+ right_leaf_center_x =  (pin_len/2 + leaf_w/2);
  
- // Knuckles distributed over 30mm in 5 sections of 6mm each.
- // Each knuckle is centered in its section.
- // Left leaf: outer 2 + center 1 => sections 1,3,5 => y = -12, 0, 12
- // Right leaf: middle 2 => sections 2,4 => y = -6, 6
- left_knuckle_y  = [-12, 0, 12];
- right_knuckle_y = [-6, 6];
+ left_knuckle_y  = [-12, 0, 12];   // 3 segments: 1,3,5
+ right_knuckle_y = [-6, 6];        // 2 segments: 2,4
  
- // M3 holes: 3 per leaf, along Y at 8mm pitch, placed on the side
- // away from the knuckles.
+ // M3 holes: 3 per leaf, spaced 8mm along Y, on the side away from knuckles.
  hole_y = [-8, 0, 8];
  
- module leaf_plate(side=1) {
-     // side: -1 left, +1 right
+ module leaf_plate(side = -1) {
      translate([side * (pin_len/2 + leaf_w/2), 0, 0])
          cube([leaf_w, leaf_len, leaf_th], center=true);
  }
  
  module knuckle_segment(yc) {
      translate([0, yc, 0])
      difference() {
          cylinder(d=knuckle_od, h=knuckle_len, center=true);
          cylinder(d=knuckle_id, h=knuckle_len + 2, center=true);
      }
  }
  
  module pin_axis() {
-     // Pin axis is centered on X=0, Z=0 and runs along Y
-     rotate([90,0,0])
+     rotate([90, 0, 0])
          cylinder(d=pin_d, h=pin_len, center=true);
  }
  
- module countersunk_hole_at(x, y) {
-     // Through-hole
-     translate([x, y, 0])
-         cylinder(d=m3_through_d, h=leaf_th + 0.4, center=true);
+ module leaf_with_knuckles(side = -1) {
+     leaf_x = side < 0 ? left_leaf_center_x : right_leaf_center_x;
+     knuckles = side < 0 ? left_knuckle_y : right_knuckle_y;
+     hole_x = side < 0 ? (leaf_x + leaf_w/2 - 0.8) : (leaf_x - leaf_w/2 + 0.8);
+     csk_dir = side < 0 ? 1 : -1;
  
-     // Countersink from the outer face of the leaf
-     // Left leaf outer face is x = left_leaf_x - leaf_w/2
-     // Right leaf outer face is x = right_leaf_x + leaf_w/2
- }
- 
- module leaf_with_knuckles(side=1) {
-     // side: -1 left leaf, +1 right leaf
-     holes_x = side < 0 ? (left_leaf_x - leaf_w/2 + 0.8) : (right_leaf_x + leaf_w/2 - 0.8);
-     csk_dir = side < 0 ? -1 : 1;
- 
      difference() {
          union() {
-             // Leaf plate
-             translate([side * (pin_len/2 + leaf_w/2), 0, 0])
+             translate([leaf_x, 0, 0])
                  cube([leaf_w, leaf_len, leaf_th], center=true);
  
-             // Knuckles
-             if (side < 0) {
-                 for (yy = left_knuckle_y)
-                     knuckle_segment(yy);
-             } else {
-                 for (yy = right_knuckle_y)
-                     knuckle_segment(yy);
-             }
+             for (yy = knuckles)
+                 knuckle_segment(yy);
          }
  
-         // M3 through holes + countersinks
+         // Through holes
          for (yy = hole_y) {
-             translate([holes_x, yy, 0]) {
-                 // through
-                 cube([0,0,0]); // no-op to keep scope simple
- 
-                 // Drill through along X
-                 rotate([0,90,0])
+             translate([hole_x, yy, 0])
+                 rotate([0, 90, 0])
                      cylinder(d=m3_through_d, h=leaf_w + 2, center=true);
  
-                 // Countersink from outer face
-                 translate([csk_dir * (leaf_w/2 - 0.01), 0, 0])
-                     rotate([0,90,0])
-                         cylinder(d1=m3_csk_top_d, d2=m3_through_d, h=m3_csk_depth, center=false);
-             }
+             // Countersink from the outer face of the leaf
+             translate([leaf_x + csk_dir * leaf_w/2, yy, 0])
+                 rotate([0, 90, 0])
+                     cylinder(d1=m3_csk_top_d, d2=m3_through_d, h=m3_csk_depth, center=false);
          }
      }
  }
  
  union() {
      leaf_with_knuckles(-1);
      leaf_with_knuckles(+1);
      pin_axis();
  }
SCAD (82 lines)
$fn = 96;

// Base dimensions
leaf_len = 30;          // along Y
leaf_w   = 25;          // along X
leaf_th  = 2;           // along Z

pin_d    = 4;
pin_len  = 32;          // extends 1mm beyond knuckles at both ends

knuckle_od = 8;
knuckle_id = 4.6;
knuckle_len = 6;        // 30mm / 5

m3_through_d = 3.2;
m3_csk_top_d = 6;
m3_csk_depth = 1;

// Open 180° layout:
// leaves are coplanar in Z, and separated on X so their free edges point away
// from the hinge axis. Hinge axis is along Y at X=0.
left_leaf_center_x  = -(pin_len/2 + leaf_w/2);
right_leaf_center_x =  (pin_len/2 + leaf_w/2);

left_knuckle_y  = [-12, 0, 12];   // 3 segments: 1,3,5
right_knuckle_y = [-6, 6];        // 2 segments: 2,4

// M3 holes: 3 per leaf, spaced 8mm along Y, on the side away from knuckles.
hole_y = [-8, 0, 8];

module leaf_plate(side = -1) {
    translate([side * (pin_len/2 + leaf_w/2), 0, 0])
        cube([leaf_w, leaf_len, leaf_th], center=true);
}

module knuckle_segment(yc) {
    translate([0, yc, 0])
    difference() {
        cylinder(d=knuckle_od, h=knuckle_len, center=true);
        cylinder(d=knuckle_id, h=knuckle_len + 2, center=true);
    }
}

module pin_axis() {
    rotate([90, 0, 0])
        cylinder(d=pin_d, h=pin_len, center=true);
}

module leaf_with_knuckles(side = -1) {
    leaf_x = side < 0 ? left_leaf_center_x : right_leaf_center_x;
    knuckles = side < 0 ? left_knuckle_y : right_knuckle_y;
    hole_x = side < 0 ? (leaf_x + leaf_w/2 - 0.8) : (leaf_x - leaf_w/2 + 0.8);
    csk_dir = side < 0 ? 1 : -1;

    difference() {
        union() {
            translate([leaf_x, 0, 0])
                cube([leaf_w, leaf_len, leaf_th], center=true);

            for (yy = knuckles)
                knuckle_segment(yy);
        }

        // Through holes
        for (yy = hole_y) {
            translate([hole_x, yy, 0])
                rotate([0, 90, 0])
                    cylinder(d=m3_through_d, h=leaf_w + 2, center=true);

            // Countersink from the outer face of the leaf
            translate([leaf_x + csk_dir * leaf_w/2, yy, 0])
                rotate([0, 90, 0])
                    cylinder(d1=m3_csk_top_d, d2=m3_through_d, h=m3_csk_depth, center=false);
        }
    }
}

union() {
    leaf_with_knuckles(-1);
    leaf_with_knuckles(+1);
    pin_axis();
}