vibe-openscad

tier-3-butt-hinge / claude-sonnet-4-6

8 run / 累計 214.0s / 累計 $0.2457

claude sonnet 4.6 bare

bare (provider default effort)

run detail →
render
bare render of tier-3-butt-hinge
loading STL…
success 26.0s · 707/1627t · $0.0265
SCAD (136 lines)
// Butt Hinge - 180° open position
// Pin axis along Y, leaves extend in -X and +X directions

// Parameters
leaf_width  = 25;   // X direction (when open)
leaf_length = 30;   // Y direction (along pin)
leaf_thick  = 2;    // Z direction

pin_dia     = 4;
pin_r       = pin_dia / 2;
pin_length  = 32;   // 1mm overhang each end

knuckle_od  = 8;
knuckle_or  = knuckle_od / 2;
knuckle_id  = pin_dia + 0.3;  // 4.3mm  ← clearance bore
knuckle_ir  = knuckle_id / 2;
knuckle_h   = 6;    // each knuckle height

// Screw holes (M3 countersunk)
screw_cs_dia   = 6;
screw_cs_depth = 1;
screw_thru_dia = 3.2;
screw_count    = 3;
screw_pitch    = 8;   // Y spacing
// screw column is centred on leaf_length/2 in Y, spaced 8mm apart
// positions: -8, 0, +8  relative to leaf centre → 7, 15, 23 in Y

// Screw X position: middle of the leaf (away from knuckle side)
screw_x = -(leaf_width / 2);   // for left leaf  (negative side)

$fn = 48;

// ─────────────────────────────────────────────
// Helper: single countersunk hole (centred at origin, going -Z)
module cs_hole() {
    // countersink taper (cone, wider at top)
    cylinder(h = screw_cs_depth,
             r1 = screw_cs_dia / 2,
             r2 = screw_thru_dia / 2);
    // through hole
    translate([0, 0, -leaf_thick])
        cylinder(h = leaf_thick + screw_cs_depth + 0.01,
                 r = screw_thru_dia / 2);
}

// ─────────────────────────────────────────────
// Knuckle: a tube of height knuckle_h, centred at origin, axis = Z
module knuckle() {
    difference() {
        cylinder(h = knuckle_h, r = knuckle_or, center = true);
        cylinder(h = knuckle_h + 0.02, r = knuckle_ir, center = true);
    }
}

// ─────────────────────────────────────────────
// Left leaf  (x ≤ 0 side)
// Leaf flat face at z = 0, body goes to z = -leaf_thick
// Knuckles protrude above the flat face (z = 0 … knuckle_od/2 from axis)
// but we keep knuckle axis at x=0, z=0 and orient them along Y.
//
// Knuckle positions along Y (knuckle centres):
//   Left leaf  owns knuckles 1,3,5  → Y centres: 3, 15, 27  (0-indexed segments 0,2,4)
//   Right leaf owns knuckles 2,4    → Y centres: 9, 21       (segments 1,3)
//
// Knuckle axis is Y, so we rotate the tube 90° around X.

left_knuckle_y  = [3, 15, 27];   // centres in Y for left leaf
right_knuckle_y = [9, 21];       // centres in Y for right leaf

// The leaf starts at Y=0 and ends at Y=leaf_length (30).
// Knuckle outer radius sits on the x=0 line; leaf extends to x = -leaf_width.

module left_leaf() {
    difference() {
        union() {
            // flat plate
            translate([-leaf_width, 0, -leaf_thick])
                cube([leaf_width, leaf_length, leaf_thick]);

            // knuckles (rotated 90° so axis is Y)
            for (yc = left_knuckle_y) {
                translate([0, yc, 0])
                    rotate([90, 0, 0])
                        knuckle();
            }
        }

        // countersunk screw holes — placed on the leaf, away from knuckle side
        // X centre at -leaf_width/2, Y positions centred on leaf
        for (i = [0 : screw_count - 1]) {
            ypos = (leaf_length - (screw_count - 1) * screw_pitch) / 2
                   + i * screw_pitch;
            translate([-leaf_width / 2, ypos, 0])
                cs_hole();
        }
    }
}

module right_leaf() {
    difference() {
        union() {
            // flat plate
            translate([0, 0, -leaf_thick])
                cube([leaf_width, leaf_length, leaf_thick]);

            // knuckles
            for (yc = right_knuckle_y) {
                translate([0, yc, 0])
                    rotate([90, 0, 0])
                        knuckle();
            }
        }

        // countersunk screw holes
        for (i = [0 : screw_count - 1]) {
            ypos = (leaf_length - (screw_count - 1) * screw_pitch) / 2
                   + i * screw_pitch;
            translate([leaf_width / 2, ypos, 0])
                cs_hole();
        }
    }
}

// ─────────────────────────────────────────────
// Pin: along Y axis, centred so it overhangs 1mm at each end
module pin() {
    translate([0, -1, 0])          // shift so Y=-1 … Y=31
        rotate([-90, 0, 0])
            cylinder(h = pin_length, r = pin_r);
}

// ─────────────────────────────────────────────
// Assembly — 180° open: both leaves in the same Z=0 plane
color("silver", 0.9) left_leaf();
color("silver", 0.9) right_leaf();
color("gold",   1.0) pin();
パラメータ (12)
スライダを動かすと 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
21.7s · 707/1324t · $0.0220
SCAD (115 lines)
// Butt Hinge - 180° open state
// Pin axis along Y, leaves flat in XZ plane at z=0..2

// Parameters
leaf_w = 25;    // width (x direction)
leaf_h = 30;    // height (y direction)
leaf_t = 2;     // thickness (z direction)

pin_d = 4;
pin_r = pin_d / 2;
pin_len = 32;

knuckle_od = 8;
knuckle_or = knuckle_od / 2;
knuckle_id = 4.6;
knuckle_ir = knuckle_id / 2;
knuckle_h = 6;

// Screw holes
screw_d = 3.2;
cs_d = 6;
cs_depth = 1;
screw_count = 3;
screw_pitch = 8;
screw_x_offset = leaf_w / 2; // center of screw zone

// Left leaf: x from -leaf_w to 0, knuckles at x=0 side
// Right leaf: x from 0 to leaf_w, knuckles at x=0 side
// Both leaves lie in z = -leaf_t to 0 plane (top face at z=0)

module countersunk_hole(depth=leaf_t) {
    // Countersink: cone from diameter cs_d at top to screw_d, depth cs_depth
    // Then through hole screw_d for remaining depth
    union() {
        cylinder(d1=cs_d, d2=screw_d, h=cs_depth, $fn=32);
        translate([0,0,-depth+cs_depth])
            cylinder(d=screw_d, h=depth-cs_depth+0.01, $fn=32);
    }
}

module knuckle() {
    difference() {
        cylinder(d=knuckle_od, h=knuckle_h, $fn=32);
        translate([0,0,-0.1])
            cylinder(d=knuckle_id, h=knuckle_h+0.2, $fn=32);
    }
}

module left_leaf() {
    // Leaf body: x from -leaf_w to 0, y from -1 to 29 (pin offset by 1), z from -leaf_t to 0
    // Pin starts at y=-1, so leaf y from 0 to 30 mapped to pin y 0..30
    // Actually: leaf y from 0 to 30, knuckles centered on x=0 edge
    
    difference() {
        union() {
            // Main leaf plate
            translate([-leaf_w, 0, -leaf_t])
                cube([leaf_w, leaf_h, leaf_t]);
            
            // Left leaf knuckles: positions 0,2,4 (y=0,12,24) -> centers at y=3,15,27
            // knuckle 1: y=0..6, knuckle 3: y=12..18, knuckle 5: y=24..30
            for(i = [0, 2, 4]) {
                translate([0, i*knuckle_h, -knuckle_od/2])
                    rotate([-90, 0, 0])
                        // knuckle centered on x=0, extending in +x direction around pin
                        // Actually knuckle is a cylinder along y axis
                        translate([0, 0, 0])
                            knuckle();
            }
        }
        
        // Screw holes on leaf (top face z=0, going down)
        // Screws along y axis, x centered at -leaf_w/2
        for(i = [0:screw_count-1]) {
            translate([-leaf_w/2, 4 + i*screw_pitch, 0])
                rotate([180, 0, 0])
                    countersunk_hole(leaf_t);
        }
    }
}

module right_leaf() {
    difference() {
        union() {
            // Main leaf plate
            translate([0, 0, -leaf_t])
                cube([leaf_w, leaf_h, leaf_t]);
            
            // Right leaf knuckles: positions 1,3 (y=6..12, y=18..24)
            for(i = [1, 3]) {
                translate([0, i*knuckle_h, -knuckle_od/2])
                    rotate([-90, 0, 0])
                        knuckle();
            }
        }
        
        // Screw holes
        for(i = [0:screw_count-1]) {
            translate([leaf_w/2, 4 + i*screw_pitch, 0])
                rotate([180, 0, 0])
                    countersunk_hole(leaf_t);
        }
    }
}

module pin() {
    translate([0, -1, -knuckle_od/2])
        rotate([-90, 0, 0])
            cylinder(d=pin_d, h=pin_len, $fn=32);
}

// Render all parts
color("silver") left_leaf();
color("silver") right_leaf();
color("gold")   pin();
mediumnot run
high (default) success
high
22.5s · 707/1436t · $0.0237
SCAD (122 lines)
// Butt Hinge - 180° open state
// Units: mm

// Parameters
leaf_width  = 25;   // X direction (away from pin)
leaf_height = 30;   // Y direction (along pin axis)
leaf_thick  = 2;    // Z direction

pin_dia     = 4;
pin_r       = pin_dia / 2;
pin_len     = 32;   // 1mm overhang each end

knuckle_od  = 8;
knuckle_or  = knuckle_od / 2;
knuckle_id  = pin_dia + 0.3;  // 4.6mm
knuckle_ir  = knuckle_id / 2;
knuckle_h   = 6;    // each knuckle height (30/5)

// Countersink screw holes (M3)
cs_top_dia  = 6;
cs_depth    = 1;
cs_hole_dia = 3.2;
screw_x_offset = leaf_width / 2;  // center of screw in X on the leaf
// 3 screws per leaf, spaced 8mm apart in Y, centered on leaf_height
screw_y_positions = [
    leaf_height/2 - 8*1,  // 7
    leaf_height/2,         // 15
    leaf_height/2 + 8*1   // 23
];

// Left leaf knuckles: positions 0,2,4 (outer two + center)
// Y start positions: 0,6,12,18,24  -> knuckle centers at 3,9,15,21,27
// Left: segments 0,2,4 -> centers at 3, 15, 27
// Right: segments 1,3  -> centers at 9, 21

left_knuckle_centers  = [3, 15, 27];
right_knuckle_centers = [9, 21];

$fn = 64;

// ─── Modules ───────────────────────────────────────────────────

module knuckle(center_y) {
    translate([0, center_y - knuckle_h/2, -knuckle_or])
    rotate([-90, 0, 0])
    difference() {
        cylinder(h = knuckle_h, r = knuckle_or);
        cylinder(h = knuckle_h, r = knuckle_ir);
    }
}

// A leaf with knuckles and screw holes.
// leaf_side: -1 = left (extends in -X), +1 = right (extends in +X)
// knuckle_centers: list of Y centers for knuckles
module leaf(leaf_side, knuckle_centers) {
    // leaf body
    // The leaf flat face is at Z=0 (top surface).
    // Leaf thickness goes downward: Z from -leaf_thick to 0.
    // Knuckle center is at X=0; leaf extends in leaf_side * X direction.
    
    difference() {
        union() {
            // Flat leaf plate
            translate([leaf_side > 0 ? 0 : -leaf_width,
                       0,
                       -leaf_thick])
                cube([leaf_width, leaf_height, leaf_thick]);
            
            // Knuckles
            for (cy = knuckle_centers) {
                knuckle(cy);
            }
        }
        
        // Screw countersinks
        // Screws placed at X = leaf_side * (leaf_width * 0.5)
        sx = leaf_side * (leaf_width / 2);
        for (sy = screw_y_positions) {
            translate([sx, sy, 0]) {
                // Countersink taper: from dia 6 at Z=0 to dia 3.2 at Z=-cs_depth
                cylinder(h = cs_depth,
                         r1 = cs_top_dia / 2,
                         r2 = cs_hole_dia / 2);
                // Through hole
                translate([0, 0, -leaf_thick])
                    cylinder(h = leaf_thick, r = cs_hole_dia / 2);
            }
        }
        
        // Trim knuckle area flush with leaf (remove knuckle overlap below leaf)
        // Actually knuckles are centered at Z=0 so they protrude above.
        // We need to cut the flat leaf area where knuckles intersect.
        // The leaf is at Z -leaf_thick..0; knuckles protrude from Z -knuckle_or..+knuckle_or
        // so below the leaf (Z < -leaf_thick) knuckle material should be removed.
        // We'll cut below -leaf_thick in the leaf span.
        translate([leaf_side > 0 ? 0 : -leaf_width,
                   0,
                   -knuckle_or - 1])
            cube([leaf_width, leaf_height, knuckle_or - leaf_thick + 1 + 0.01]);
    }
}

module pin_axis() {
    // Pin along Y axis, centered at origin, length 32mm
    translate([0, -pin_len/2, 0])
    rotate([-90, 0, 0])
    cylinder(h = pin_len, r = pin_r);
}

// ─── Assembly ──────────────────────────────────────────────────

// Left leaf: extends in -X direction
color("silver")
leaf(-1, left_knuckle_centers);

// Right leaf: extends in +X direction
color("silver")
leaf(1, right_knuckle_centers);

// Pin axis
color("gold")
pin_axis();
maxnot run
xhighnot run

variant: thinking

off success
off
22.5s · 707/1436t · $0.0237
SCAD (122 lines)
// Butt Hinge - 180° open state
// Units: mm

// Parameters
leaf_width  = 25;   // X direction (away from pin)
leaf_height = 30;   // Y direction (along pin axis)
leaf_thick  = 2;    // Z direction

pin_dia     = 4;
pin_r       = pin_dia / 2;
pin_len     = 32;   // 1mm overhang each end

knuckle_od  = 8;
knuckle_or  = knuckle_od / 2;
knuckle_id  = pin_dia + 0.3;  // 4.6mm
knuckle_ir  = knuckle_id / 2;
knuckle_h   = 6;    // each knuckle height (30/5)

// Countersink screw holes (M3)
cs_top_dia  = 6;
cs_depth    = 1;
cs_hole_dia = 3.2;
screw_x_offset = leaf_width / 2;  // center of screw in X on the leaf
// 3 screws per leaf, spaced 8mm apart in Y, centered on leaf_height
screw_y_positions = [
    leaf_height/2 - 8*1,  // 7
    leaf_height/2,         // 15
    leaf_height/2 + 8*1   // 23
];

// Left leaf knuckles: positions 0,2,4 (outer two + center)
// Y start positions: 0,6,12,18,24  -> knuckle centers at 3,9,15,21,27
// Left: segments 0,2,4 -> centers at 3, 15, 27
// Right: segments 1,3  -> centers at 9, 21

left_knuckle_centers  = [3, 15, 27];
right_knuckle_centers = [9, 21];

$fn = 64;

// ─── Modules ───────────────────────────────────────────────────

module knuckle(center_y) {
    translate([0, center_y - knuckle_h/2, -knuckle_or])
    rotate([-90, 0, 0])
    difference() {
        cylinder(h = knuckle_h, r = knuckle_or);
        cylinder(h = knuckle_h, r = knuckle_ir);
    }
}

// A leaf with knuckles and screw holes.
// leaf_side: -1 = left (extends in -X), +1 = right (extends in +X)
// knuckle_centers: list of Y centers for knuckles
module leaf(leaf_side, knuckle_centers) {
    // leaf body
    // The leaf flat face is at Z=0 (top surface).
    // Leaf thickness goes downward: Z from -leaf_thick to 0.
    // Knuckle center is at X=0; leaf extends in leaf_side * X direction.
    
    difference() {
        union() {
            // Flat leaf plate
            translate([leaf_side > 0 ? 0 : -leaf_width,
                       0,
                       -leaf_thick])
                cube([leaf_width, leaf_height, leaf_thick]);
            
            // Knuckles
            for (cy = knuckle_centers) {
                knuckle(cy);
            }
        }
        
        // Screw countersinks
        // Screws placed at X = leaf_side * (leaf_width * 0.5)
        sx = leaf_side * (leaf_width / 2);
        for (sy = screw_y_positions) {
            translate([sx, sy, 0]) {
                // Countersink taper: from dia 6 at Z=0 to dia 3.2 at Z=-cs_depth
                cylinder(h = cs_depth,
                         r1 = cs_top_dia / 2,
                         r2 = cs_hole_dia / 2);
                // Through hole
                translate([0, 0, -leaf_thick])
                    cylinder(h = leaf_thick, r = cs_hole_dia / 2);
            }
        }
        
        // Trim knuckle area flush with leaf (remove knuckle overlap below leaf)
        // Actually knuckles are centered at Z=0 so they protrude above.
        // We need to cut the flat leaf area where knuckles intersect.
        // The leaf is at Z -leaf_thick..0; knuckles protrude from Z -knuckle_or..+knuckle_or
        // so below the leaf (Z < -leaf_thick) knuckle material should be removed.
        // We'll cut below -leaf_thick in the leaf span.
        translate([leaf_side > 0 ? 0 : -leaf_width,
                   0,
                   -knuckle_or - 1])
            cube([leaf_width, leaf_height, knuckle_or - leaf_thick + 1 + 0.01]);
    }
}

module pin_axis() {
    // Pin along Y axis, centered at origin, length 32mm
    translate([0, -pin_len/2, 0])
    rotate([-90, 0, 0])
    cylinder(h = pin_len, r = pin_r);
}

// ─── Assembly ──────────────────────────────────────────────────

// Left leaf: extends in -X direction
color("silver")
leaf(-1, left_knuckle_centers);

// Right leaf: extends in +X direction
color("silver")
leaf(1, right_knuckle_centers);

// Pin axis
color("gold")
pin_axis();
adaptive (default) success
adaptive
26.0s · 707/1627t · $0.0265
SCAD (136 lines)
// Butt Hinge - 180° open position
// Pin axis along Y, leaves extend in -X and +X directions

// Parameters
leaf_width  = 25;   // X direction (when open)
leaf_length = 30;   // Y direction (along pin)
leaf_thick  = 2;    // Z direction

pin_dia     = 4;
pin_r       = pin_dia / 2;
pin_length  = 32;   // 1mm overhang each end

knuckle_od  = 8;
knuckle_or  = knuckle_od / 2;
knuckle_id  = pin_dia + 0.3;  // 4.3mm  ← clearance bore
knuckle_ir  = knuckle_id / 2;
knuckle_h   = 6;    // each knuckle height

// Screw holes (M3 countersunk)
screw_cs_dia   = 6;
screw_cs_depth = 1;
screw_thru_dia = 3.2;
screw_count    = 3;
screw_pitch    = 8;   // Y spacing
// screw column is centred on leaf_length/2 in Y, spaced 8mm apart
// positions: -8, 0, +8  relative to leaf centre → 7, 15, 23 in Y

// Screw X position: middle of the leaf (away from knuckle side)
screw_x = -(leaf_width / 2);   // for left leaf  (negative side)

$fn = 48;

// ─────────────────────────────────────────────
// Helper: single countersunk hole (centred at origin, going -Z)
module cs_hole() {
    // countersink taper (cone, wider at top)
    cylinder(h = screw_cs_depth,
             r1 = screw_cs_dia / 2,
             r2 = screw_thru_dia / 2);
    // through hole
    translate([0, 0, -leaf_thick])
        cylinder(h = leaf_thick + screw_cs_depth + 0.01,
                 r = screw_thru_dia / 2);
}

// ─────────────────────────────────────────────
// Knuckle: a tube of height knuckle_h, centred at origin, axis = Z
module knuckle() {
    difference() {
        cylinder(h = knuckle_h, r = knuckle_or, center = true);
        cylinder(h = knuckle_h + 0.02, r = knuckle_ir, center = true);
    }
}

// ─────────────────────────────────────────────
// Left leaf  (x ≤ 0 side)
// Leaf flat face at z = 0, body goes to z = -leaf_thick
// Knuckles protrude above the flat face (z = 0 … knuckle_od/2 from axis)
// but we keep knuckle axis at x=0, z=0 and orient them along Y.
//
// Knuckle positions along Y (knuckle centres):
//   Left leaf  owns knuckles 1,3,5  → Y centres: 3, 15, 27  (0-indexed segments 0,2,4)
//   Right leaf owns knuckles 2,4    → Y centres: 9, 21       (segments 1,3)
//
// Knuckle axis is Y, so we rotate the tube 90° around X.

left_knuckle_y  = [3, 15, 27];   // centres in Y for left leaf
right_knuckle_y = [9, 21];       // centres in Y for right leaf

// The leaf starts at Y=0 and ends at Y=leaf_length (30).
// Knuckle outer radius sits on the x=0 line; leaf extends to x = -leaf_width.

module left_leaf() {
    difference() {
        union() {
            // flat plate
            translate([-leaf_width, 0, -leaf_thick])
                cube([leaf_width, leaf_length, leaf_thick]);

            // knuckles (rotated 90° so axis is Y)
            for (yc = left_knuckle_y) {
                translate([0, yc, 0])
                    rotate([90, 0, 0])
                        knuckle();
            }
        }

        // countersunk screw holes — placed on the leaf, away from knuckle side
        // X centre at -leaf_width/2, Y positions centred on leaf
        for (i = [0 : screw_count - 1]) {
            ypos = (leaf_length - (screw_count - 1) * screw_pitch) / 2
                   + i * screw_pitch;
            translate([-leaf_width / 2, ypos, 0])
                cs_hole();
        }
    }
}

module right_leaf() {
    difference() {
        union() {
            // flat plate
            translate([0, 0, -leaf_thick])
                cube([leaf_width, leaf_length, leaf_thick]);

            // knuckles
            for (yc = right_knuckle_y) {
                translate([0, yc, 0])
                    rotate([90, 0, 0])
                        knuckle();
            }
        }

        // countersunk screw holes
        for (i = [0 : screw_count - 1]) {
            ypos = (leaf_length - (screw_count - 1) * screw_pitch) / 2
                   + i * screw_pitch;
            translate([leaf_width / 2, ypos, 0])
                cs_hole();
        }
    }
}

// ─────────────────────────────────────────────
// Pin: along Y axis, centred so it overhangs 1mm at each end
module pin() {
    translate([0, -1, 0])          // shift so Y=-1 … Y=31
        rotate([-90, 0, 0])
            cylinder(h = pin_length, r = pin_r);
}

// ─────────────────────────────────────────────
// Assembly — 180° open: both leaves in the same Z=0 plane
color("silver", 0.9) left_leaf();
color("silver", 0.9) right_leaf();
color("gold",   1.0) pin();
dynamicnot run

iteration: iter-png

i1 success
iter 1
34.7s · 3090/2072t · $0.0403
diff vs bare: +72/-66
  // Butt Hinge - 180° open position
  // Pin axis along Y, leaves extend in -X and +X directions
  
+ $fn = 64;
+ 
  // Parameters
- leaf_width  = 25;   // X direction (when open)
+ leaf_width  = 25;   // X extent of flat plate portion
  leaf_length = 30;   // Y direction (along pin)
- leaf_thick  = 2;    // Z direction
+ leaf_thick  = 2;    // Z thickness
  
  pin_dia     = 4;
  pin_r       = pin_dia / 2;
- pin_length  = 32;   // 1mm overhang each end
+ pin_length  = 32;   // 1mm overhang each end (-1 to 31)
  
  knuckle_od  = 8;
- knuckle_or  = knuckle_od / 2;
- knuckle_id  = pin_dia + 0.3;  // 4.3mm  ← clearance bore
+ knuckle_or  = knuckle_od / 2;   // 4
+ knuckle_id  = pin_dia + 0.3;    // 4.3mm clearance bore
  knuckle_ir  = knuckle_id / 2;
- knuckle_h   = 6;    // each knuckle height
+ knuckle_h   = 6;                 // each knuckle segment height
  
  // Screw holes (M3 countersunk)
  screw_cs_dia   = 6;
  screw_cs_depth = 1;
  screw_thru_dia = 3.2;
  screw_count    = 3;
- screw_pitch    = 8;   // Y spacing
- // screw column is centred on leaf_length/2 in Y, spaced 8mm apart
- // positions: -8, 0, +8  relative to leaf centre → 7, 15, 23 in Y
+ screw_pitch    = 8;
  
- // Screw X position: middle of the leaf (away from knuckle side)
- screw_x = -(leaf_width / 2);   // for left leaf  (negative side)
+ // Knuckle Y centres:
+ //   Left leaf  (3 knuckles): segments 0,2,4 → Y centres 3, 15, 27
+ //   Right leaf (2 knuckles): segments 1,3   → Y centres 9, 21
+ left_knuckle_y  = [3, 15, 27];
+ right_knuckle_y = [9, 21];
  
- $fn = 48;
+ // The pin/knuckle axis is at X=0, Z=0.
+ // Leaf flat face is at Z=0 (top surface), body goes down to Z=-leaf_thick.
+ // Leaf plate extends from X=0 outward (left: -leaf_width, right: +leaf_width).
+ // Knuckle centre is at X=0, Z=0; lower half (Z<0) merges into plate edge.
  
  // ─────────────────────────────────────────────
- // Helper: single countersunk hole (centred at origin, going -Z)
- module cs_hole() {
-     // countersink taper (cone, wider at top)
-     cylinder(h = screw_cs_depth,
-              r1 = screw_cs_dia / 2,
-              r2 = screw_thru_dia / 2);
-     // through hole
-     translate([0, 0, -leaf_thick])
-         cylinder(h = leaf_thick + screw_cs_depth + 0.01,
-                  r = screw_thru_dia / 2);
+ // Knuckle tube, axis along Y, centred at origin
+ module knuckle_tube() {
+     rotate([90, 0, 0])
+         difference() {
+             cylinder(h = knuckle_h, r = knuckle_or, center = true);
+             cylinder(h = knuckle_h + 0.02, r = knuckle_ir, center = true);
+         }
  }
  
  // ─────────────────────────────────────────────
- // Knuckle: a tube of height knuckle_h, centred at origin, axis = Z
- module knuckle() {
-     difference() {
-         cylinder(h = knuckle_h, r = knuckle_or, center = true);
-         cylinder(h = knuckle_h + 0.02, r = knuckle_ir, center = true);
+ // Countersunk hole: top surface at Z=0, going downward through leaf_thick
+ // Wider at top (Z=0), narrows to thru-hole diameter
+ module cs_hole() {
+     union() {
+         // countersink cone: top z=0 dia=screw_cs_dia, bottom z=-screw_cs_depth dia=screw_thru_dia
+         translate([0, 0, -screw_cs_depth])
+             cylinder(h = screw_cs_depth + 0.01,
+                      r1 = screw_thru_dia / 2,
+                      r2 = screw_cs_dia / 2);
+         // through hole from countersink bottom to leaf bottom
+         translate([0, 0, -(leaf_thick + 0.01)])
+             cylinder(h = leaf_thick - screw_cs_depth + 0.02,
+                      r = screw_thru_dia / 2);
      }
  }
  
  // ─────────────────────────────────────────────
- // Left leaf  (x ≤ 0 side)
- // Leaf flat face at z = 0, body goes to z = -leaf_thick
- // Knuckles protrude above the flat face (z = 0 … knuckle_od/2 from axis)
- // but we keep knuckle axis at x=0, z=0 and orient them along Y.
- //
- // Knuckle positions along Y (knuckle centres):
- //   Left leaf  owns knuckles 1,3,5  → Y centres: 3, 15, 27  (0-indexed segments 0,2,4)
- //   Right leaf owns knuckles 2,4    → Y centres: 9, 21       (segments 1,3)
- //
- // Knuckle axis is Y, so we rotate the tube 90° around X.
+ // Screw hole Y positions (centred on leaf_length)
+ function screw_y(i) =
+     (leaf_length - (screw_count - 1) * screw_pitch) / 2 + i * screw_pitch;
  
- left_knuckle_y  = [3, 15, 27];   // centres in Y for left leaf
- right_knuckle_y = [9, 21];       // centres in Y for right leaf
- 
- // The leaf starts at Y=0 and ends at Y=leaf_length (30).
- // Knuckle outer radius sits on the x=0 line; leaf extends to x = -leaf_width.
- 
+ // ─────────────────────────────────────────────
+ // Left leaf: plate extends in -X direction, knuckles at X=0
  module left_leaf() {
      difference() {
          union() {
-             // flat plate
+             // Flat plate: from X=-leaf_width to X=0, Y=0 to Y=30, Z=-leaf_thick to Z=0
              translate([-leaf_width, 0, -leaf_thick])
                  cube([leaf_width, leaf_length, leaf_thick]);
  
-             // knuckles (rotated 90° so axis is Y)
+             // Knuckles at X=0 axis
              for (yc = left_knuckle_y) {
                  translate([0, yc, 0])
-                     rotate([90, 0, 0])
-                         knuckle();
+                     knuckle_tube();
              }
          }
  
-         // countersunk screw holes — placed on the leaf, away from knuckle side
-         // X centre at -leaf_width/2, Y positions centred on leaf
+         // Countersunk screw holes on flat part
+         // X centre at -leaf_width/2 (middle of plate away from hinge)
          for (i = [0 : screw_count - 1]) {
-             ypos = (leaf_length - (screw_count - 1) * screw_pitch) / 2
-                    + i * screw_pitch;
-             translate([-leaf_width / 2, ypos, 0])
+             translate([-leaf_width / 2, screw_y(i), 0])
                  cs_hole();
          }
+ 
+         // Remove pin bore through all knuckles
+         translate([0, -1, 0])
+             rotate([-90, 0, 0])
+                 cylinder(h = pin_length + 2, r = knuckle_ir);
      }
  }
  
+ // ─────────────────────────────────────────────
+ // Right leaf: plate extends in +X direction, knuckles at X=0
  module right_leaf() {
      difference() {
          union() {
-             // flat plate
+             // Flat plate: from X=0 to X=+leaf_width
              translate([0, 0, -leaf_thick])
                  cube([leaf_width, leaf_length, leaf_thick]);
  
-             // knuckles
+             // Knuckles at X=0 axis
              for (yc = right_knuckle_y) {
                  translate([0, yc, 0])
-                     rotate([90, 0, 0])
-                         knuckle();
+                     knuckle_tube();
              }
          }
  
-         // countersunk screw holes
+         // Countersunk screw holes
          for (i = [0 : screw_count - 1]) {
-             ypos = (leaf_length - (screw_count - 1) * screw_pitch) / 2
-                    + i * screw_pitch;
-             translate([leaf_width / 2, ypos, 0])
+             translate([leaf_width / 2, screw_y(i), 0])
                  cs_hole();
          }
+ 
+         // Remove pin bore through all knuckles
+         translate([0, -1, 0])
+             rotate([-90, 0, 0])
+                 cylinder(h = pin_length + 2, r = knuckle_ir);
      }
  }
  
  // ─────────────────────────────────────────────
- // Pin: along Y axis, centred so it overhangs 1mm at each end
+ // Pin: Y from -1 to +31 (1mm overhang each end)
  module pin() {
-     translate([0, -1, 0])          // shift so Y=-1 … Y=31
+     translate([0, -1, 0])
          rotate([-90, 0, 0])
              cylinder(h = pin_length, r = pin_r);
  }
  
  // ─────────────────────────────────────────────
- // Assembly — 180° open: both leaves in the same Z=0 plane
- color("silver", 0.9) left_leaf();
- color("silver", 0.9) right_leaf();
- color("gold",   1.0) pin();
+ // Assembly
+ color([0.75, 0.75, 0.78], 1.0) left_leaf();
+ color([0.75, 0.75, 0.78], 1.0) right_leaf();
+ color([0.85, 0.70, 0.20], 1.0) pin();
SCAD (142 lines)
// Butt Hinge - 180° open position
// Pin axis along Y, leaves extend in -X and +X directions

$fn = 64;

// Parameters
leaf_width  = 25;   // X extent of flat plate portion
leaf_length = 30;   // Y direction (along pin)
leaf_thick  = 2;    // Z thickness

pin_dia     = 4;
pin_r       = pin_dia / 2;
pin_length  = 32;   // 1mm overhang each end (-1 to 31)

knuckle_od  = 8;
knuckle_or  = knuckle_od / 2;   // 4
knuckle_id  = pin_dia + 0.3;    // 4.3mm clearance bore
knuckle_ir  = knuckle_id / 2;
knuckle_h   = 6;                 // each knuckle segment height

// Screw holes (M3 countersunk)
screw_cs_dia   = 6;
screw_cs_depth = 1;
screw_thru_dia = 3.2;
screw_count    = 3;
screw_pitch    = 8;

// Knuckle Y centres:
//   Left leaf  (3 knuckles): segments 0,2,4 → Y centres 3, 15, 27
//   Right leaf (2 knuckles): segments 1,3   → Y centres 9, 21
left_knuckle_y  = [3, 15, 27];
right_knuckle_y = [9, 21];

// The pin/knuckle axis is at X=0, Z=0.
// Leaf flat face is at Z=0 (top surface), body goes down to Z=-leaf_thick.
// Leaf plate extends from X=0 outward (left: -leaf_width, right: +leaf_width).
// Knuckle centre is at X=0, Z=0; lower half (Z<0) merges into plate edge.

// ─────────────────────────────────────────────
// Knuckle tube, axis along Y, centred at origin
module knuckle_tube() {
    rotate([90, 0, 0])
        difference() {
            cylinder(h = knuckle_h, r = knuckle_or, center = true);
            cylinder(h = knuckle_h + 0.02, r = knuckle_ir, center = true);
        }
}

// ─────────────────────────────────────────────
// Countersunk hole: top surface at Z=0, going downward through leaf_thick
// Wider at top (Z=0), narrows to thru-hole diameter
module cs_hole() {
    union() {
        // countersink cone: top z=0 dia=screw_cs_dia, bottom z=-screw_cs_depth dia=screw_thru_dia
        translate([0, 0, -screw_cs_depth])
            cylinder(h = screw_cs_depth + 0.01,
                     r1 = screw_thru_dia / 2,
                     r2 = screw_cs_dia / 2);
        // through hole from countersink bottom to leaf bottom
        translate([0, 0, -(leaf_thick + 0.01)])
            cylinder(h = leaf_thick - screw_cs_depth + 0.02,
                     r = screw_thru_dia / 2);
    }
}

// ─────────────────────────────────────────────
// Screw hole Y positions (centred on leaf_length)
function screw_y(i) =
    (leaf_length - (screw_count - 1) * screw_pitch) / 2 + i * screw_pitch;

// ─────────────────────────────────────────────
// Left leaf: plate extends in -X direction, knuckles at X=0
module left_leaf() {
    difference() {
        union() {
            // Flat plate: from X=-leaf_width to X=0, Y=0 to Y=30, Z=-leaf_thick to Z=0
            translate([-leaf_width, 0, -leaf_thick])
                cube([leaf_width, leaf_length, leaf_thick]);

            // Knuckles at X=0 axis
            for (yc = left_knuckle_y) {
                translate([0, yc, 0])
                    knuckle_tube();
            }
        }

        // Countersunk screw holes on flat part
        // X centre at -leaf_width/2 (middle of plate away from hinge)
        for (i = [0 : screw_count - 1]) {
            translate([-leaf_width / 2, screw_y(i), 0])
                cs_hole();
        }

        // Remove pin bore through all knuckles
        translate([0, -1, 0])
            rotate([-90, 0, 0])
                cylinder(h = pin_length + 2, r = knuckle_ir);
    }
}

// ─────────────────────────────────────────────
// Right leaf: plate extends in +X direction, knuckles at X=0
module right_leaf() {
    difference() {
        union() {
            // Flat plate: from X=0 to X=+leaf_width
            translate([0, 0, -leaf_thick])
                cube([leaf_width, leaf_length, leaf_thick]);

            // Knuckles at X=0 axis
            for (yc = right_knuckle_y) {
                translate([0, yc, 0])
                    knuckle_tube();
            }
        }

        // Countersunk screw holes
        for (i = [0 : screw_count - 1]) {
            translate([leaf_width / 2, screw_y(i), 0])
                cs_hole();
        }

        // Remove pin bore through all knuckles
        translate([0, -1, 0])
            rotate([-90, 0, 0])
                cylinder(h = pin_length + 2, r = knuckle_ir);
    }
}

// ─────────────────────────────────────────────
// Pin: Y from -1 to +31 (1mm overhang each end)
module pin() {
    translate([0, -1, 0])
        rotate([-90, 0, 0])
            cylinder(h = pin_length, r = pin_r);
}

// ─────────────────────────────────────────────
// Assembly
color([0.75, 0.75, 0.78], 1.0) left_leaf();
color([0.75, 0.75, 0.78], 1.0) right_leaf();
color([0.85, 0.70, 0.20], 1.0) pin();
i2 success
iter 2
31.2s · 3200/2294t · $0.0440
diff vs i1: +64/-47
  // Butt Hinge - 180° open position
  // Pin axis along Y, leaves extend in -X and +X directions
  
  $fn = 64;
  
  // Parameters
  leaf_width  = 25;   // X extent of flat plate portion
  leaf_length = 30;   // Y direction (along pin)
  leaf_thick  = 2;    // Z thickness
  
  pin_dia     = 4;
  pin_r       = pin_dia / 2;
- pin_length  = 32;   // 1mm overhang each end (-1 to 31)
+ pin_length  = 32;   // 1mm overhang each end
  
  knuckle_od  = 8;
- knuckle_or  = knuckle_od / 2;   // 4
+ knuckle_or  = knuckle_od / 2;   // 4mm
  knuckle_id  = pin_dia + 0.3;    // 4.3mm clearance bore
  knuckle_ir  = knuckle_id / 2;
- knuckle_h   = 6;                 // each knuckle segment height
+ knuckle_h   = 6;                 // each knuckle height
  
+ // Knuckle Y centres (each segment 6mm, centres at 3,9,15,21,27)
+ // Left leaf  (3 knuckles): segments 0,2,4 → Y centres 3, 15, 27
+ // Right leaf (2 knuckles): segments 1,3   → Y centres 9, 21
+ left_knuckle_y  = [3, 15, 27];
+ right_knuckle_y = [9, 21];
+ 
+ // Knuckle protrudes above the plate surface (Z=0).
+ // Knuckle axis (pin centre) is at Z = knuckle_or = 4mm above plate top face.
+ // So knuckle occupies Z = 0 to Z = knuckle_od = 8mm (diameter).
+ // The leaf plate sits at Z = -leaf_thick to Z = 0.
+ // A fillet block fills between plate top (Z=0) and knuckle bottom tangent line.
+ knuckle_z = knuckle_or;   // pin axis height above plate top face
+ 
  // Screw holes (M3 countersunk)
  screw_cs_dia   = 6;
  screw_cs_depth = 1;
  screw_thru_dia = 3.2;
  screw_count    = 3;
  screw_pitch    = 8;
  
- // Knuckle Y centres:
- //   Left leaf  (3 knuckles): segments 0,2,4 → Y centres 3, 15, 27
- //   Right leaf (2 knuckles): segments 1,3   → Y centres 9, 21
- left_knuckle_y  = [3, 15, 27];
- right_knuckle_y = [9, 21];
+ function screw_y(i) =
+     (leaf_length - (screw_count - 1) * screw_pitch) / 2 + i * screw_pitch;
  
- // The pin/knuckle axis is at X=0, Z=0.
- // Leaf flat face is at Z=0 (top surface), body goes down to Z=-leaf_thick.
- // Leaf plate extends from X=0 outward (left: -leaf_width, right: +leaf_width).
- // Knuckle centre is at X=0, Z=0; lower half (Z<0) merges into plate edge.
- 
  // ─────────────────────────────────────────────
- // Knuckle tube, axis along Y, centred at origin
- module knuckle_tube() {
-     rotate([90, 0, 0])
-         difference() {
-             cylinder(h = knuckle_h, r = knuckle_or, center = true);
-             cylinder(h = knuckle_h + 0.02, r = knuckle_ir, center = true);
-         }
+ // Single knuckle tube, axis along Y
+ // Placed so axis is at [0, yc, knuckle_z]
+ module knuckle_tube(yc) {
+     translate([0, yc, knuckle_z])
+         rotate([90, 0, 0])
+             difference() {
+                 cylinder(h = knuckle_h, r = knuckle_or, center = true);
+                 cylinder(h = knuckle_h + 0.02, r = knuckle_ir, center = true);
+             }
  }
  
+ // Fillet/web block connecting knuckle base to plate surface
+ // A square-ish block that fills the gap between the cylinder and the flat plate
+ module knuckle_base_fill(yc) {
+     translate([0, yc, 0])
+         rotate([90, 0, 0])
+             // Hull between a rectangle at Z=0 and the cylinder cross-section
+             linear_extrude(height = knuckle_h, center = true)
+                 hull() {
+                     // plate-level footprint (thin rectangle)
+                     translate([0, 0, 0])
+                         square([knuckle_od, 0.01], center = true);
+                     // knuckle circle at its axis height
+                     translate([0, knuckle_z, 0])
+                         circle(r = knuckle_or);
+                 }
+ }
+ 
  // ─────────────────────────────────────────────
- // Countersunk hole: top surface at Z=0, going downward through leaf_thick
- // Wider at top (Z=0), narrows to thru-hole diameter
+ // Countersunk hole: top surface at Z=0, going downward
  module cs_hole() {
      union() {
-         // countersink cone: top z=0 dia=screw_cs_dia, bottom z=-screw_cs_depth dia=screw_thru_dia
+         // countersink taper
          translate([0, 0, -screw_cs_depth])
              cylinder(h = screw_cs_depth + 0.01,
                       r1 = screw_thru_dia / 2,
                       r2 = screw_cs_dia / 2);
-         // through hole from countersink bottom to leaf bottom
+         // through hole
          translate([0, 0, -(leaf_thick + 0.01)])
              cylinder(h = leaf_thick - screw_cs_depth + 0.02,
                       r = screw_thru_dia / 2);
      }
  }
  
  // ─────────────────────────────────────────────
- // Screw hole Y positions (centred on leaf_length)
- function screw_y(i) =
-     (leaf_length - (screw_count - 1) * screw_pitch) / 2 + i * screw_pitch;
- 
- // ─────────────────────────────────────────────
- // Left leaf: plate extends in -X direction, knuckles at X=0
+ // Left leaf: plate extends in -X direction
  module left_leaf() {
      difference() {
          union() {
-             // Flat plate: from X=-leaf_width to X=0, Y=0 to Y=30, Z=-leaf_thick to Z=0
+             // Flat plate
              translate([-leaf_width, 0, -leaf_thick])
                  cube([leaf_width, leaf_length, leaf_thick]);
  
-             // Knuckles at X=0 axis
+             // Knuckles with base fills
              for (yc = left_knuckle_y) {
-                 translate([0, yc, 0])
-                     knuckle_tube();
+                 knuckle_tube(yc);
+                 knuckle_base_fill(yc);
              }
          }
  
-         // Countersunk screw holes on flat part
-         // X centre at -leaf_width/2 (middle of plate away from hinge)
+         // Countersunk screw holes
          for (i = [0 : screw_count - 1]) {
              translate([-leaf_width / 2, screw_y(i), 0])
                  cs_hole();
          }
  
-         // Remove pin bore through all knuckles
-         translate([0, -1, 0])
+         // Pin bore through all knuckle positions along Y
+         translate([0, -1, knuckle_z])
              rotate([-90, 0, 0])
                  cylinder(h = pin_length + 2, r = knuckle_ir);
      }
  }
  
  // ─────────────────────────────────────────────
- // Right leaf: plate extends in +X direction, knuckles at X=0
+ // Right leaf: plate extends in +X direction
  module right_leaf() {
      difference() {
          union() {
-             // Flat plate: from X=0 to X=+leaf_width
+             // Flat plate
              translate([0, 0, -leaf_thick])
                  cube([leaf_width, leaf_length, leaf_thick]);
  
-             // Knuckles at X=0 axis
+             // Knuckles with base fills
              for (yc = right_knuckle_y) {
-                 translate([0, yc, 0])
-                     knuckle_tube();
+                 knuckle_tube(yc);
+                 knuckle_base_fill(yc);
              }
          }
  
          // Countersunk screw holes
          for (i = [0 : screw_count - 1]) {
              translate([leaf_width / 2, screw_y(i), 0])
                  cs_hole();
          }
  
-         // Remove pin bore through all knuckles
-         translate([0, -1, 0])
+         // Pin bore
+         translate([0, -1, knuckle_z])
              rotate([-90, 0, 0])
                  cylinder(h = pin_length + 2, r = knuckle_ir);
      }
  }
  
  // ─────────────────────────────────────────────
- // Pin: Y from -1 to +31 (1mm overhang each end)
+ // Pin: Y from -1 to +31 (1mm overhang each end beyond 0..30)
  module pin() {
-     translate([0, -1, 0])
+     translate([0, -1, knuckle_z])
          rotate([-90, 0, 0])
              cylinder(h = pin_length, r = pin_r);
  }
  
  // ─────────────────────────────────────────────
  // Assembly
  color([0.75, 0.75, 0.78], 1.0) left_leaf();
  color([0.75, 0.75, 0.78], 1.0) right_leaf();
  color([0.85, 0.70, 0.20], 1.0) pin();
SCAD (159 lines)
// Butt Hinge - 180° open position
// Pin axis along Y, leaves extend in -X and +X directions

$fn = 64;

// Parameters
leaf_width  = 25;   // X extent of flat plate portion
leaf_length = 30;   // Y direction (along pin)
leaf_thick  = 2;    // Z thickness

pin_dia     = 4;
pin_r       = pin_dia / 2;
pin_length  = 32;   // 1mm overhang each end

knuckle_od  = 8;
knuckle_or  = knuckle_od / 2;   // 4mm
knuckle_id  = pin_dia + 0.3;    // 4.3mm clearance bore
knuckle_ir  = knuckle_id / 2;
knuckle_h   = 6;                 // each knuckle height

// Knuckle Y centres (each segment 6mm, centres at 3,9,15,21,27)
// Left leaf  (3 knuckles): segments 0,2,4 → Y centres 3, 15, 27
// Right leaf (2 knuckles): segments 1,3   → Y centres 9, 21
left_knuckle_y  = [3, 15, 27];
right_knuckle_y = [9, 21];

// Knuckle protrudes above the plate surface (Z=0).
// Knuckle axis (pin centre) is at Z = knuckle_or = 4mm above plate top face.
// So knuckle occupies Z = 0 to Z = knuckle_od = 8mm (diameter).
// The leaf plate sits at Z = -leaf_thick to Z = 0.
// A fillet block fills between plate top (Z=0) and knuckle bottom tangent line.
knuckle_z = knuckle_or;   // pin axis height above plate top face

// Screw holes (M3 countersunk)
screw_cs_dia   = 6;
screw_cs_depth = 1;
screw_thru_dia = 3.2;
screw_count    = 3;
screw_pitch    = 8;

function screw_y(i) =
    (leaf_length - (screw_count - 1) * screw_pitch) / 2 + i * screw_pitch;

// ─────────────────────────────────────────────
// Single knuckle tube, axis along Y
// Placed so axis is at [0, yc, knuckle_z]
module knuckle_tube(yc) {
    translate([0, yc, knuckle_z])
        rotate([90, 0, 0])
            difference() {
                cylinder(h = knuckle_h, r = knuckle_or, center = true);
                cylinder(h = knuckle_h + 0.02, r = knuckle_ir, center = true);
            }
}

// Fillet/web block connecting knuckle base to plate surface
// A square-ish block that fills the gap between the cylinder and the flat plate
module knuckle_base_fill(yc) {
    translate([0, yc, 0])
        rotate([90, 0, 0])
            // Hull between a rectangle at Z=0 and the cylinder cross-section
            linear_extrude(height = knuckle_h, center = true)
                hull() {
                    // plate-level footprint (thin rectangle)
                    translate([0, 0, 0])
                        square([knuckle_od, 0.01], center = true);
                    // knuckle circle at its axis height
                    translate([0, knuckle_z, 0])
                        circle(r = knuckle_or);
                }
}

// ─────────────────────────────────────────────
// Countersunk hole: top surface at Z=0, going downward
module cs_hole() {
    union() {
        // countersink taper
        translate([0, 0, -screw_cs_depth])
            cylinder(h = screw_cs_depth + 0.01,
                     r1 = screw_thru_dia / 2,
                     r2 = screw_cs_dia / 2);
        // through hole
        translate([0, 0, -(leaf_thick + 0.01)])
            cylinder(h = leaf_thick - screw_cs_depth + 0.02,
                     r = screw_thru_dia / 2);
    }
}

// ─────────────────────────────────────────────
// Left leaf: plate extends in -X direction
module left_leaf() {
    difference() {
        union() {
            // Flat plate
            translate([-leaf_width, 0, -leaf_thick])
                cube([leaf_width, leaf_length, leaf_thick]);

            // Knuckles with base fills
            for (yc = left_knuckle_y) {
                knuckle_tube(yc);
                knuckle_base_fill(yc);
            }
        }

        // Countersunk screw holes
        for (i = [0 : screw_count - 1]) {
            translate([-leaf_width / 2, screw_y(i), 0])
                cs_hole();
        }

        // Pin bore through all knuckle positions along Y
        translate([0, -1, knuckle_z])
            rotate([-90, 0, 0])
                cylinder(h = pin_length + 2, r = knuckle_ir);
    }
}

// ─────────────────────────────────────────────
// Right leaf: plate extends in +X direction
module right_leaf() {
    difference() {
        union() {
            // Flat plate
            translate([0, 0, -leaf_thick])
                cube([leaf_width, leaf_length, leaf_thick]);

            // Knuckles with base fills
            for (yc = right_knuckle_y) {
                knuckle_tube(yc);
                knuckle_base_fill(yc);
            }
        }

        // Countersunk screw holes
        for (i = [0 : screw_count - 1]) {
            translate([leaf_width / 2, screw_y(i), 0])
                cs_hole();
        }

        // Pin bore
        translate([0, -1, knuckle_z])
            rotate([-90, 0, 0])
                cylinder(h = pin_length + 2, r = knuckle_ir);
    }
}

// ─────────────────────────────────────────────
// Pin: Y from -1 to +31 (1mm overhang each end beyond 0..30)
module pin() {
    translate([0, -1, knuckle_z])
        rotate([-90, 0, 0])
            cylinder(h = pin_length, r = pin_r);
}

// ─────────────────────────────────────────────
// Assembly
color([0.75, 0.75, 0.78], 1.0) left_leaf();
color([0.75, 0.75, 0.78], 1.0) right_leaf();
color([0.85, 0.70, 0.20], 1.0) pin();
i3 success
iter 3
29.5s · 3320/1932t · $0.0389
diff vs i2: +68/-79
  // Butt Hinge - 180° open position
  // Pin axis along Y, leaves extend in -X and +X directions
  
  $fn = 64;
  
  // Parameters
- leaf_width  = 25;   // X extent of flat plate portion
- leaf_length = 30;   // Y direction (along pin)
- leaf_thick  = 2;    // Z thickness
+ leaf_width  = 25;
+ leaf_length = 30;
+ leaf_thick  = 2;
  
- pin_dia     = 4;
- pin_r       = pin_dia / 2;
- pin_length  = 32;   // 1mm overhang each end
+ pin_dia    = 4;
+ pin_r      = pin_dia / 2;
+ pin_length = 32;
  
- knuckle_od  = 8;
- knuckle_or  = knuckle_od / 2;   // 4mm
- knuckle_id  = pin_dia + 0.3;    // 4.3mm clearance bore
- knuckle_ir  = knuckle_id / 2;
- knuckle_h   = 6;                 // each knuckle height
+ knuckle_od = 8;
+ knuckle_or = knuckle_od / 2;
+ knuckle_id = pin_dia + 0.3;
+ knuckle_ir = knuckle_id / 2;
+ knuckle_h  = 6;
  
- // Knuckle Y centres (each segment 6mm, centres at 3,9,15,21,27)
- // Left leaf  (3 knuckles): segments 0,2,4 → Y centres 3, 15, 27
- // Right leaf (2 knuckles): segments 1,3   → Y centres 9, 21
- left_knuckle_y  = [3, 15, 27];
- right_knuckle_y = [9, 21];
+ // Knuckle Y start positions (each 6mm segment)
+ // Left leaf  (3 knuckles): segments 0,2,4 → Y start 0, 12, 24
+ // Right leaf (2 knuckles): segments 1,3   → Y start 6, 18
+ left_knuckle_y_starts  = [0, 12, 24];
+ right_knuckle_y_starts = [6, 18];
  
- // Knuckle protrudes above the plate surface (Z=0).
- // Knuckle axis (pin centre) is at Z = knuckle_or = 4mm above plate top face.
- // So knuckle occupies Z = 0 to Z = knuckle_od = 8mm (diameter).
- // The leaf plate sits at Z = -leaf_thick to Z = 0.
- // A fillet block fills between plate top (Z=0) and knuckle bottom tangent line.
- knuckle_z = knuckle_or;   // pin axis height above plate top face
+ // Pin axis is at Z = knuckle_or above plate top face (Z=0)
+ knuckle_z = knuckle_or;
  
  // Screw holes (M3 countersunk)
  screw_cs_dia   = 6;
  screw_cs_depth = 1;
  screw_thru_dia = 3.2;
  screw_count    = 3;
  screw_pitch    = 8;
  
  function screw_y(i) =
      (leaf_length - (screw_count - 1) * screw_pitch) / 2 + i * screw_pitch;
  
  // ─────────────────────────────────────────────
- // Single knuckle tube, axis along Y
- // Placed so axis is at [0, yc, knuckle_z]
- module knuckle_tube(yc) {
+ // Single knuckle: cylinder + web connecting it to the plate
+ // y0 = Y start of this 6mm segment
+ module single_knuckle(y0) {
+     yc = y0 + knuckle_h / 2;   // centre of knuckle in Y
+ 
+     // Knuckle tube
      translate([0, yc, knuckle_z])
          rotate([90, 0, 0])
              difference() {
                  cylinder(h = knuckle_h, r = knuckle_or, center = true);
-                 cylinder(h = knuckle_h + 0.02, r = knuckle_ir, center = true);
+                 cylinder(h = knuckle_h + 0.1, r = knuckle_ir, center = true);
              }
- }
  
- // Fillet/web block connecting knuckle base to plate surface
- // A square-ish block that fills the gap between the cylinder and the flat plate
- module knuckle_base_fill(yc) {
-     translate([0, yc, 0])
-         rotate([90, 0, 0])
-             // Hull between a rectangle at Z=0 and the cylinder cross-section
-             linear_extrude(height = knuckle_h, center = true)
-                 hull() {
-                     // plate-level footprint (thin rectangle)
-                     translate([0, 0, 0])
-                         square([knuckle_od, 0.01], center = true);
-                     // knuckle circle at its axis height
-                     translate([0, knuckle_z, 0])
-                         circle(r = knuckle_or);
-                 }
+     // Web / gusset: hull between flat plate rect and knuckle circle,
+     // extruded along Y for the length of this knuckle
+     translate([0, y0, 0])
+         linear_extrude(height = knuckle_h)
+             hull() {
+                 // footprint at plate top (Z=0): thin wide rect
+                 translate([0, 0])
+                     square([knuckle_od, 0.01], center = true);
+                 // knuckle cross-section at axis height
+                 translate([0, knuckle_z])
+                     circle(r = knuckle_or);
+             }
  }
  
  // ─────────────────────────────────────────────
- // Countersunk hole: top surface at Z=0, going downward
+ // Countersunk hole, opening at Z=0, going into -Z
  module cs_hole() {
-     union() {
-         // countersink taper
-         translate([0, 0, -screw_cs_depth])
-             cylinder(h = screw_cs_depth + 0.01,
-                      r1 = screw_thru_dia / 2,
-                      r2 = screw_cs_dia / 2);
-         // through hole
-         translate([0, 0, -(leaf_thick + 0.01)])
-             cylinder(h = leaf_thick - screw_cs_depth + 0.02,
-                      r = screw_thru_dia / 2);
-     }
+     // Countersink cone (wide at top, narrow at bottom)
+     translate([0, 0, 0.01])
+         cylinder(h = screw_cs_depth + 0.01,
+                  r1 = screw_cs_dia / 2,
+                  r2 = screw_thru_dia / 2,
+                  $fn = 32);
+     // Through shaft
+     translate([0, 0, -(leaf_thick + 0.01)])
+         cylinder(h = leaf_thick + screw_cs_depth + 0.02,
+                  r = screw_thru_dia / 2,
+                  $fn = 32);
  }
  
  // ─────────────────────────────────────────────
- // Left leaf: plate extends in -X direction
+ // Left leaf
  module left_leaf() {
      difference() {
          union() {
-             // Flat plate
+             // Flat plate (extends in -X)
              translate([-leaf_width, 0, -leaf_thick])
                  cube([leaf_width, leaf_length, leaf_thick]);
  
-             // Knuckles with base fills
-             for (yc = left_knuckle_y) {
-                 knuckle_tube(yc);
-                 knuckle_base_fill(yc);
-             }
+             // 3 knuckles
+             for (y0 = left_knuckle_y_starts)
+                 single_knuckle(y0);
          }
  
-         // Countersunk screw holes
-         for (i = [0 : screw_count - 1]) {
+         // Screw holes on the plate (centred in X over plate)
+         for (i = [0 : screw_count - 1])
              translate([-leaf_width / 2, screw_y(i), 0])
                  cs_hole();
-         }
  
-         // Pin bore through all knuckle positions along Y
+         // Pin bore along entire Y span
          translate([0, -1, knuckle_z])
              rotate([-90, 0, 0])
                  cylinder(h = pin_length + 2, r = knuckle_ir);
      }
  }
  
  // ─────────────────────────────────────────────
- // Right leaf: plate extends in +X direction
+ // Right leaf
  module right_leaf() {
      difference() {
          union() {
-             // Flat plate
+             // Flat plate (extends in +X)
              translate([0, 0, -leaf_thick])
                  cube([leaf_width, leaf_length, leaf_thick]);
  
-             // Knuckles with base fills
-             for (yc = right_knuckle_y) {
-                 knuckle_tube(yc);
-                 knuckle_base_fill(yc);
-             }
+             // 2 knuckles
+             for (y0 = right_knuckle_y_starts)
+                 single_knuckle(y0);
          }
  
-         // Countersunk screw holes
-         for (i = [0 : screw_count - 1]) {
+         // Screw holes
+         for (i = [0 : screw_count - 1])
              translate([leaf_width / 2, screw_y(i), 0])
                  cs_hole();
-         }
  
          // Pin bore
          translate([0, -1, knuckle_z])
              rotate([-90, 0, 0])
                  cylinder(h = pin_length + 2, r = knuckle_ir);
      }
  }
  
  // ─────────────────────────────────────────────
- // Pin: Y from -1 to +31 (1mm overhang each end beyond 0..30)
+ // Pin: Y from -1 to +31 (1mm overhang each end: 0..30 + margins)
  module pin() {
      translate([0, -1, knuckle_z])
          rotate([-90, 0, 0])
              cylinder(h = pin_length, r = pin_r);
  }
  
  // ─────────────────────────────────────────────
  // Assembly
- color([0.75, 0.75, 0.78], 1.0) left_leaf();
- color([0.75, 0.75, 0.78], 1.0) right_leaf();
- color([0.85, 0.70, 0.20], 1.0) pin();
+ color([0.75, 0.75, 0.78]) left_leaf();
+ color([0.75, 0.75, 0.78]) right_leaf();
+ color([0.85, 0.70, 0.20]) pin();
SCAD (148 lines)
// Butt Hinge - 180° open position
// Pin axis along Y, leaves extend in -X and +X directions

$fn = 64;

// Parameters
leaf_width  = 25;
leaf_length = 30;
leaf_thick  = 2;

pin_dia    = 4;
pin_r      = pin_dia / 2;
pin_length = 32;

knuckle_od = 8;
knuckle_or = knuckle_od / 2;
knuckle_id = pin_dia + 0.3;
knuckle_ir = knuckle_id / 2;
knuckle_h  = 6;

// Knuckle Y start positions (each 6mm segment)
// Left leaf  (3 knuckles): segments 0,2,4 → Y start 0, 12, 24
// Right leaf (2 knuckles): segments 1,3   → Y start 6, 18
left_knuckle_y_starts  = [0, 12, 24];
right_knuckle_y_starts = [6, 18];

// Pin axis is at Z = knuckle_or above plate top face (Z=0)
knuckle_z = knuckle_or;

// Screw holes (M3 countersunk)
screw_cs_dia   = 6;
screw_cs_depth = 1;
screw_thru_dia = 3.2;
screw_count    = 3;
screw_pitch    = 8;

function screw_y(i) =
    (leaf_length - (screw_count - 1) * screw_pitch) / 2 + i * screw_pitch;

// ─────────────────────────────────────────────
// Single knuckle: cylinder + web connecting it to the plate
// y0 = Y start of this 6mm segment
module single_knuckle(y0) {
    yc = y0 + knuckle_h / 2;   // centre of knuckle in Y

    // Knuckle tube
    translate([0, yc, knuckle_z])
        rotate([90, 0, 0])
            difference() {
                cylinder(h = knuckle_h, r = knuckle_or, center = true);
                cylinder(h = knuckle_h + 0.1, r = knuckle_ir, center = true);
            }

    // Web / gusset: hull between flat plate rect and knuckle circle,
    // extruded along Y for the length of this knuckle
    translate([0, y0, 0])
        linear_extrude(height = knuckle_h)
            hull() {
                // footprint at plate top (Z=0): thin wide rect
                translate([0, 0])
                    square([knuckle_od, 0.01], center = true);
                // knuckle cross-section at axis height
                translate([0, knuckle_z])
                    circle(r = knuckle_or);
            }
}

// ─────────────────────────────────────────────
// Countersunk hole, opening at Z=0, going into -Z
module cs_hole() {
    // Countersink cone (wide at top, narrow at bottom)
    translate([0, 0, 0.01])
        cylinder(h = screw_cs_depth + 0.01,
                 r1 = screw_cs_dia / 2,
                 r2 = screw_thru_dia / 2,
                 $fn = 32);
    // Through shaft
    translate([0, 0, -(leaf_thick + 0.01)])
        cylinder(h = leaf_thick + screw_cs_depth + 0.02,
                 r = screw_thru_dia / 2,
                 $fn = 32);
}

// ─────────────────────────────────────────────
// Left leaf
module left_leaf() {
    difference() {
        union() {
            // Flat plate (extends in -X)
            translate([-leaf_width, 0, -leaf_thick])
                cube([leaf_width, leaf_length, leaf_thick]);

            // 3 knuckles
            for (y0 = left_knuckle_y_starts)
                single_knuckle(y0);
        }

        // Screw holes on the plate (centred in X over plate)
        for (i = [0 : screw_count - 1])
            translate([-leaf_width / 2, screw_y(i), 0])
                cs_hole();

        // Pin bore along entire Y span
        translate([0, -1, knuckle_z])
            rotate([-90, 0, 0])
                cylinder(h = pin_length + 2, r = knuckle_ir);
    }
}

// ─────────────────────────────────────────────
// Right leaf
module right_leaf() {
    difference() {
        union() {
            // Flat plate (extends in +X)
            translate([0, 0, -leaf_thick])
                cube([leaf_width, leaf_length, leaf_thick]);

            // 2 knuckles
            for (y0 = right_knuckle_y_starts)
                single_knuckle(y0);
        }

        // Screw holes
        for (i = [0 : screw_count - 1])
            translate([leaf_width / 2, screw_y(i), 0])
                cs_hole();

        // Pin bore
        translate([0, -1, knuckle_z])
            rotate([-90, 0, 0])
                cylinder(h = pin_length + 2, r = knuckle_ir);
    }
}

// ─────────────────────────────────────────────
// Pin: Y from -1 to +31 (1mm overhang each end: 0..30 + margins)
module pin() {
    translate([0, -1, knuckle_z])
        rotate([-90, 0, 0])
            cylinder(h = pin_length, r = pin_r);
}

// ─────────────────────────────────────────────
// Assembly
color([0.75, 0.75, 0.78]) left_leaf();
color([0.75, 0.75, 0.78]) right_leaf();
color([0.85, 0.70, 0.20]) pin();