vibe-openscad

tier-2-offset-handle-mug / claude-opus-4-8

10 run / 累計 178.9s / 累計 $0.3658

claude opus 4.8 bare

bare (provider default effort)

run detail →
render
bare render of tier-2-offset-handle-mug
loading STL…
success 11.5s · 343/853t · $0.0230
SCAD (67 lines)
// マグカップ(取手は +X 方向のみ)

// パラメータ
outer_d   = 80;   // 外径
inner_d   = 70;   // 内径
wall      = (outer_d - inner_d) / 2; // 肉厚 5mm
height    = 90;   // 全体高さ
bottom_th = 6;    // 底厚

outer_r = outer_d / 2; // 40
inner_r = inner_d / 2; // 35

// 取手パラメータ
hole_h   = 30;    // 取手内側の高さ
hole_w   = 25;    // 取手内側の幅
h_thick  = 8;     // 取手の太さ(断面)
handle_z = height / 2; // 取手を高さ中央に

$fn = 96;

// ===== 本体 =====
module body() {
    difference() {
        cylinder(h = height, r = outer_r);
        translate([0, 0, bottom_th])
            cylinder(h = height - bottom_th + 1, r = inner_r);
    }
}

// ===== 取手 =====
// D字形状: 外側半円 + 直線(本体側)
// 押し出し方向は Y、形状は XZ 平面で定義
module handle() {
    // 取手の外形 - 内側の穴
    handle_outer_w = hole_w + 2 * h_thick; // 全体幅
    handle_outer_h = hole_h + 2 * h_thick; // 全体高さ

    // 取手は +X 側に張り出す。
    // 本体表面 (x=outer_r) から外側へ伸びる D 字。
    translate([outer_r - h_thick, 0, handle_z])
    rotate([90, 0, 0]) // XZ断面をY方向に押し出すため
    linear_extrude(height = h_thick, center = true)
    difference() {
        // 外形 D字
        hull() {
            // 本体側(直線部)
            translate([0, -handle_outer_h/2])
                square([1, handle_outer_h]);
            // 外側半円部
            translate([handle_outer_w - handle_outer_h/2, 0])
                circle(d = handle_outer_h);
        }
        // 内側の穴 D字
        hull() {
            translate([h_thick, -hole_h/2])
                square([1, hole_h]);
            translate([h_thick + hole_w - hole_h/2, 0])
                circle(d = hole_h);
        }
    }
}

// ===== 結合 =====
union() {
    body();
    handle();
}
パラメータ (7)
スライダを動かすと openscad-wasm で再レンダリング

prompt

OpenSCAD で、向きが指定されたマグカップを作ってください。

本体:
- 外径 80mm、内径 70mm(肉厚 5mm)、高さ 90mm の円筒形マグ
- 底面の厚みは 6mm
- 内側は飲み物を入れられるよう中空

取手(handle):
- マグの **+X 軸方向の側面のみ** に付ける(他の方向には付けない)
- 取手は D 字形状(外側が半円、本体側が直線)で、本体外周にしっかり接続する
- 取手の内側の空間は高さ 30mm × 幅 25mm(指 3 本ぐらい入る)
- 取手はマグの高さ方向の中央付近に付ける
- 本体と取手は確実に union され、マニフォールド(隙間や宙吊りなし)を保つ

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

variant: effort

low success
low
12.8s · 343/974t · $0.0261
SCAD (73 lines)
// マグカップ(取手は +X 方向のみ)

$fn = 100;

// ===== パラメータ =====
outer_d   = 80;   // 外径
inner_d   = 70;   // 内径
height    = 90;   // 全体高さ
bottom_th = 6;    // 底厚

outer_r = outer_d / 2;
inner_r = inner_d / 2;

// 取手パラメータ
handle_hole_h = 30;   // 内側空間の高さ
handle_hole_w = 25;   // 内側空間の幅
handle_th     = 8;    // 取手の太さ(断面)
handle_z      = height / 2;  // 取手の高さ中心

// ===== 本体 =====
module body() {
    difference() {
        cylinder(h = height, r = outer_r);
        // 内側中空
        translate([0, 0, bottom_th])
            cylinder(h = height - bottom_th + 1, r = inner_r);
    }
}

// ===== 取手(D字形状)=====
module handle() {
    // 外側半径と内側半径
    inner_handle_r = handle_hole_h / 2;          // D字の内側半円半径(高さ方向)
    outer_handle_r = inner_handle_r + handle_th; // 外側半径

    // 取手を rotate_extrude で D 字状リングとして作り、
    // 半分(外側半円側)だけを使う方式ではなく、
    // ここでは平面 D 字形を押し出して構成する。

    translate([0, 0, handle_z])
    rotate([90, 0, 0])   // XZ平面の形を Y 方向に厚みを持たせる
    linear_extrude(height = handle_th, center = true)
        difference() {
            // 外形 D 字(外側半円 + 本体側直線)
            hull() {
                // 本体側の上下端(直線部)
                translate([0, -handle_hole_h/2 - handle_th/2])
                    square([handle_th, handle_th], center = true);
                translate([0,  handle_hole_h/2 + handle_th/2])
                    square([handle_th, handle_th], center = true);
                // 外側半円
                translate([handle_hole_w, 0])
                    circle(r = outer_handle_r);
            }
            // 内側の穴
            hull() {
                translate([0, -handle_hole_h/2])
                    square([0.1, handle_th], center = true);
                translate([0,  handle_hole_h/2])
                    square([0.1, handle_th], center = true);
                translate([handle_hole_w, 0])
                    circle(r = inner_handle_r);
            }
        }
}

// ===== 組み立て =====
union() {
    body();
    // 取手を本体外周に接続(少し本体側へめり込ませて確実に union)
    translate([outer_r - 2, 0, 0])
        handle();
}
mediumnot run
high (default) success
high
21.4s · 343/1325t · $0.0348
SCAD (108 lines)
// マグカップ(取手は +X 方向のみ)

// ===== パラメータ =====
outer_d   = 80;   // 本体外径
inner_d   = 70;   // 本体内径
wall      = (outer_d - inner_d) / 2; // 肉厚 5mm
height    = 90;   // 全体高さ
bottom_th = 6;    // 底厚

// 取手パラメータ
handle_inner_h = 30;  // 取手内側の高さ
handle_inner_w = 25;  // 取手内側の幅(本体外周からの突き出し方向)
handle_th      = 8;   // 取手の太さ(断面直径)
handle_z       = height / 2; // 取手中心の高さ

$fn = 100;

// ===== 本体 =====
module body() {
    difference() {
        // 外形
        cylinder(d = outer_d, h = height);
        // 内側中空
        translate([0, 0, bottom_th])
            cylinder(d = inner_d, h = height - bottom_th + 1);
    }
}

// ===== 取手 =====
module handle() {
    // 取手の D 字外形:本体外周から +X 方向へ伸びる
    // 内側の空間を確保するため、外側の輪郭を rounded で作り、
    // 内側をくり抜く

    // 取手中心軸の X 位置
    x_outer = outer_d / 2;             // 本体外面 X
    // D字の外側半円中心
    inner_top_z    = handle_z + handle_inner_h / 2;
    inner_bottom_z = handle_z - handle_inner_h / 2;

    // 取手リングの中心線が描く矩形+半円の経路を太らせる
    // 簡易的に rotate_extrude 風ではなく hull で構成

    translate([0, 0, 0]) {
        // 上下の接続部(本体側 → 外側)を太い棒で作り、外側は半円
        difference() {
            // 取手の外側ソリッド形状
            hull_handle_outer();
            // 内側の空間をくり抜く
            hull_handle_inner();
        }
    }

    module hull_handle_outer() {
        // 外側の D 形状を太さ handle_th で作る
        // 経路上の点に球を配置して hull
        // 経路:本体側(x_outer)から外側(x_outer + handle_inner_w)へ
        x_far = x_outer + handle_inner_w;

        // 上側コーナー
        a_top    = [x_outer, 0, inner_top_z];
        b_top    = [x_far,   0, inner_top_z];
        // 下側コーナー
        a_bot    = [x_outer, 0, inner_bottom_z];
        b_bot    = [x_far,   0, inner_bottom_z];

        // 上辺
        hull() {
            place_sphere(a_top);
            place_sphere(b_top);
        }
        // 下辺
        hull() {
            place_sphere(a_bot);
            place_sphere(b_bot);
        }
        // 外側辺
        hull() {
            place_sphere(b_top);
            place_sphere(b_bot);
        }
        // 本体接続部(上)を本体内部まで食い込ませる
        hull() {
            place_sphere([x_outer - wall, 0, inner_top_z]);
            place_sphere(a_top);
        }
        // 本体接続部(下)
        hull() {
            place_sphere([x_outer - wall, 0, inner_bottom_z]);
            place_sphere(a_bot);
        }
    }

    module place_sphere(p) {
        translate(p) sphere(d = handle_th);
    }

    module hull_handle_inner() {
        // 何もくり抜かない(経路太らせ方式なので穴は自然にできる)
        // ダミー
    }
}

// ===== 組み立て =====
union() {
    body();
    handle();
}
max success
max
49.2s · 341/3620t · $0.0922
SCAD (66 lines)
$fn = 96;

// ===== パラメータ =====
mug_outer_d   = 80;   // 本体外径
mug_inner_d   = 70;   // 本体内径 (肉厚5mm)
mug_height    = 90;   // 本体高さ
bottom_thick  = 6;    // 底の厚み

handle_grip_d = 12;   // 取手の太さ(断面の直径)
handle_open_h = 30;   // 取手内側の空間の高さ
handle_open_w = 25;   // 取手内側の空間の幅(本体外周からの張り出し方向)
handle_z      = mug_height / 2;  // 取手を付ける高さ(中央)

mug_outer_r = mug_outer_d / 2;
mug_inner_r = mug_inner_d / 2;

// ===== 本体 =====
module mug_body() {
    difference() {
        // 外形
        cylinder(h = mug_height, r = mug_outer_r);
        // 内側のくぼみ(中空)
        translate([0, 0, bottom_thick])
            cylinder(h = mug_height, r = mug_inner_r);
    }
}

// ===== 取手 (+X 側のみ, D字形状) =====
// D字の中心線(パス)に沿って円形断面をスイープする
module handle() {
    // 取手中心線が描く D 字輪郭の寸法
    // 内側の空間: 高さ handle_open_h, 幅 handle_open_w
    path_h = handle_open_h + handle_grip_d; // 中心線の高さ方向スパン
    path_w = handle_open_w;                 // 中心線の張り出し幅

    // 取手の付け根 X 位置(本体外周に少し食い込ませて確実に union)
    base_x = mug_outer_r - 2;

    translate([base_x, 0, handle_z])
    rotate([90, 0, 0])  // 取手の平面を XZ→作図しやすい向きへ
    linear_extrude(height = handle_grip_d, center = true)
        difference() {
            d_shape(path_w, path_h);
            offset(r = -handle_grip_d)
                d_shape(path_w, path_h);
        }
}

// D字の外形(2D): 左側が直線(本体側)、右側が半円
module d_shape(w, h) {
    hull() {
        // 直線側(本体に接する辺):上下2点
        translate([0,  h/2 - w/2]) circle(r = 0.01);
        translate([0, -h/2 + w/2]) circle(r = 0.01);
        // 半円側
        translate([0,  h/2 - w/2]) translate([w - w/2,0]) circle(r = 0.01);
        translate([0, -h/2 + w/2]) translate([w - w/2,0]) circle(r = 0.01);
    }
    // 上記hullだと角丸の矩形になるため、よりD字に近い形を別途構成
}

// ===== 組み立て =====
union() {
    mug_body();
    handle();
}
xhigh success
xhigh
14.7s · 343/984t · $0.0263
SCAD (72 lines)
// マグカップ(取手は +X 方向のみ)

$fn = 100;

// ===== パラメータ =====
outer_d   = 80;   // 本体外径
inner_d   = 70;   // 本体内径
wall      = (outer_d - inner_d) / 2; // 肉厚 5mm
height    = 90;   // 全体高さ
bottom_th = 6;    // 底面厚み

// 取手パラメータ
handle_inner_h = 30;  // 取手内側の高さ
handle_inner_w = 25;  // 取手内側の幅(本体側面からの張り出し)
handle_th      = 10;  // 取手の太さ(断面)
handle_z       = height / 2; // 取手中心の高さ(中央付近)

// ===== 本体 =====
module body() {
    difference() {
        // 外形
        cylinder(d = outer_d, h = height);
        // 内側の中空(底厚を残す)
        translate([0, 0, bottom_th])
            cylinder(d = inner_d, h = height - bottom_th + 1);
    }
}

// ===== 取手(D 字形状)=====
// 本体側が直線、外側が半円の D 字。
// rotate_extrude で D 字断面のリングを作り、半分(外側半円)+ 直線部で構成する。
module handle() {
    // 取手中心線が描く D 字パスの寸法
    // 内側空間: 高さ handle_inner_h, 幅 handle_inner_w
    inner_h = handle_inner_h;
    inner_w = handle_inner_w;
    t       = handle_th; // 取手の太さ

    // 本体外周に接続する基準 X 位置
    x_base = outer_d / 2 - 1; // わずかに本体へ食い込ませて確実に union

    // D 字を構成する 3 つの円柱(上の直線・下の直線・外側半円)
    // 中心線の半径
    r_mid = t / 2;

    // 上下の水平直線部(本体から外側へ伸びる)
    // 半円部の中心 X
    half_x = x_base + inner_w;

    union() {
        // 上の水平バー
        translate([x_base, 0, handle_z + inner_h/2])
            rotate([0, 90, 0])
                cylinder(d = t, h = inner_w);
        // 下の水平バー
        translate([x_base, 0, handle_z - inner_h/2])
            rotate([0, 90, 0])
                cylinder(d = t, h = inner_w);
        // 外側の半円(縦の円弧)
        translate([half_x, 0, handle_z])
            rotate([90, 0, 0])
                rotate_extrude(angle = 180)
                    translate([inner_h/2, 0, 0])
                        circle(d = t);
    }
}

// ===== 結合 =====
union() {
    body();
    handle();
}

variant: thinking

off success
off
21.4s · 343/1325t · $0.0348
SCAD (108 lines)
// マグカップ(取手は +X 方向のみ)

// ===== パラメータ =====
outer_d   = 80;   // 本体外径
inner_d   = 70;   // 本体内径
wall      = (outer_d - inner_d) / 2; // 肉厚 5mm
height    = 90;   // 全体高さ
bottom_th = 6;    // 底厚

// 取手パラメータ
handle_inner_h = 30;  // 取手内側の高さ
handle_inner_w = 25;  // 取手内側の幅(本体外周からの突き出し方向)
handle_th      = 8;   // 取手の太さ(断面直径)
handle_z       = height / 2; // 取手中心の高さ

$fn = 100;

// ===== 本体 =====
module body() {
    difference() {
        // 外形
        cylinder(d = outer_d, h = height);
        // 内側中空
        translate([0, 0, bottom_th])
            cylinder(d = inner_d, h = height - bottom_th + 1);
    }
}

// ===== 取手 =====
module handle() {
    // 取手の D 字外形:本体外周から +X 方向へ伸びる
    // 内側の空間を確保するため、外側の輪郭を rounded で作り、
    // 内側をくり抜く

    // 取手中心軸の X 位置
    x_outer = outer_d / 2;             // 本体外面 X
    // D字の外側半円中心
    inner_top_z    = handle_z + handle_inner_h / 2;
    inner_bottom_z = handle_z - handle_inner_h / 2;

    // 取手リングの中心線が描く矩形+半円の経路を太らせる
    // 簡易的に rotate_extrude 風ではなく hull で構成

    translate([0, 0, 0]) {
        // 上下の接続部(本体側 → 外側)を太い棒で作り、外側は半円
        difference() {
            // 取手の外側ソリッド形状
            hull_handle_outer();
            // 内側の空間をくり抜く
            hull_handle_inner();
        }
    }

    module hull_handle_outer() {
        // 外側の D 形状を太さ handle_th で作る
        // 経路上の点に球を配置して hull
        // 経路:本体側(x_outer)から外側(x_outer + handle_inner_w)へ
        x_far = x_outer + handle_inner_w;

        // 上側コーナー
        a_top    = [x_outer, 0, inner_top_z];
        b_top    = [x_far,   0, inner_top_z];
        // 下側コーナー
        a_bot    = [x_outer, 0, inner_bottom_z];
        b_bot    = [x_far,   0, inner_bottom_z];

        // 上辺
        hull() {
            place_sphere(a_top);
            place_sphere(b_top);
        }
        // 下辺
        hull() {
            place_sphere(a_bot);
            place_sphere(b_bot);
        }
        // 外側辺
        hull() {
            place_sphere(b_top);
            place_sphere(b_bot);
        }
        // 本体接続部(上)を本体内部まで食い込ませる
        hull() {
            place_sphere([x_outer - wall, 0, inner_top_z]);
            place_sphere(a_top);
        }
        // 本体接続部(下)
        hull() {
            place_sphere([x_outer - wall, 0, inner_bottom_z]);
            place_sphere(a_bot);
        }
    }

    module place_sphere(p) {
        translate(p) sphere(d = handle_th);
    }

    module hull_handle_inner() {
        // 何もくり抜かない(経路太らせ方式なので穴は自然にできる)
        // ダミー
    }
}

// ===== 組み立て =====
union() {
    body();
    handle();
}
adaptive (default) success
adaptive
14.7s · 343/984t · $0.0263
SCAD (72 lines)
// マグカップ(取手は +X 方向のみ)

$fn = 100;

// ===== パラメータ =====
outer_d   = 80;   // 本体外径
inner_d   = 70;   // 本体内径
wall      = (outer_d - inner_d) / 2; // 肉厚 5mm
height    = 90;   // 全体高さ
bottom_th = 6;    // 底面厚み

// 取手パラメータ
handle_inner_h = 30;  // 取手内側の高さ
handle_inner_w = 25;  // 取手内側の幅(本体側面からの張り出し)
handle_th      = 10;  // 取手の太さ(断面)
handle_z       = height / 2; // 取手中心の高さ(中央付近)

// ===== 本体 =====
module body() {
    difference() {
        // 外形
        cylinder(d = outer_d, h = height);
        // 内側の中空(底厚を残す)
        translate([0, 0, bottom_th])
            cylinder(d = inner_d, h = height - bottom_th + 1);
    }
}

// ===== 取手(D 字形状)=====
// 本体側が直線、外側が半円の D 字。
// rotate_extrude で D 字断面のリングを作り、半分(外側半円)+ 直線部で構成する。
module handle() {
    // 取手中心線が描く D 字パスの寸法
    // 内側空間: 高さ handle_inner_h, 幅 handle_inner_w
    inner_h = handle_inner_h;
    inner_w = handle_inner_w;
    t       = handle_th; // 取手の太さ

    // 本体外周に接続する基準 X 位置
    x_base = outer_d / 2 - 1; // わずかに本体へ食い込ませて確実に union

    // D 字を構成する 3 つの円柱(上の直線・下の直線・外側半円)
    // 中心線の半径
    r_mid = t / 2;

    // 上下の水平直線部(本体から外側へ伸びる)
    // 半円部の中心 X
    half_x = x_base + inner_w;

    union() {
        // 上の水平バー
        translate([x_base, 0, handle_z + inner_h/2])
            rotate([0, 90, 0])
                cylinder(d = t, h = inner_w);
        // 下の水平バー
        translate([x_base, 0, handle_z - inner_h/2])
            rotate([0, 90, 0])
                cylinder(d = t, h = inner_w);
        // 外側の半円(縦の円弧)
        translate([half_x, 0, handle_z])
            rotate([90, 0, 0])
                rotate_extrude(angle = 180)
                    translate([inner_h/2, 0, 0])
                        circle(d = t);
    }
}

// ===== 結合 =====
union() {
    body();
    handle();
}
dynamicnot run

iteration: iter-png

i1 success
iter 1
11.7s · 1957/975t · $0.0342
diff vs bare: +9/-12
  // マグカップ(取手は +X 方向のみ)
  
  // パラメータ
  outer_d   = 80;   // 外径
  inner_d   = 70;   // 内径
  wall      = (outer_d - inner_d) / 2; // 肉厚 5mm
  height    = 90;   // 全体高さ
  bottom_th = 6;    // 底厚
  
  outer_r = outer_d / 2; // 40
  inner_r = inner_d / 2; // 35
  
  // 取手パラメータ
  hole_h   = 30;    // 取手内側の高さ
  hole_w   = 25;    // 取手内側の幅
- h_thick  = 8;     // 取手の太さ(断面)
+ h_thick  = 10;    // 取手の太さ(断面・押し出し方向)
+ embed    = 3;     // 本体への食い込み量(接続強化)
  handle_z = height / 2; // 取手を高さ中央に
  
  $fn = 96;
  
  // ===== 本体 =====
  module body() {
      difference() {
          cylinder(h = height, r = outer_r);
          translate([0, 0, bottom_th])
              cylinder(h = height - bottom_th + 1, r = inner_r);
      }
  }
  
  // ===== 取手 =====
  // D字形状: 外側半円 + 直線(本体側)
- // 押し出し方向は Y、形状は XZ 平面で定義
+ // XZ平面で形状を定義し、Y方向へ押し出す
  module handle() {
-     // 取手の外形 - 内側の穴
-     handle_outer_w = hole_w + 2 * h_thick; // 全体幅
      handle_outer_h = hole_h + 2 * h_thick; // 全体高さ
+     handle_outer_w = hole_w + 2 * h_thick; // 全体幅
  
-     // 取手は +X 側に張り出す。
-     // 本体表面 (x=outer_r) から外側へ伸びる D 字。
-     translate([outer_r - h_thick, 0, handle_z])
-     rotate([90, 0, 0]) // XZ断面をY方向に押し出すため
+     // 本体表面より少し内側(embed)から張り出して接続を確実にする
+     translate([outer_r - h_thick - embed, 0, handle_z])
+     rotate([90, 0, 0])
      linear_extrude(height = h_thick, center = true)
      difference() {
          // 外形 D字
          hull() {
-             // 本体側(直線部)
              translate([0, -handle_outer_h/2])
                  square([1, handle_outer_h]);
-             // 外側半円部
              translate([handle_outer_w - handle_outer_h/2, 0])
                  circle(d = handle_outer_h);
          }
          // 内側の穴 D字
          hull() {
-             translate([h_thick, -hole_h/2])
+             translate([h_thick + embed, -hole_h/2])
                  square([1, hole_h]);
-             translate([h_thick + hole_w - hole_h/2, 0])
+             translate([h_thick + embed + hole_w - hole_h/2, 0])
                  circle(d = hole_h);
          }
      }
  }
  
  // ===== 結合 =====
  union() {
      body();
      handle();
  }
SCAD (64 lines)
// マグカップ(取手は +X 方向のみ)

// パラメータ
outer_d   = 80;   // 外径
inner_d   = 70;   // 内径
wall      = (outer_d - inner_d) / 2; // 肉厚 5mm
height    = 90;   // 全体高さ
bottom_th = 6;    // 底厚

outer_r = outer_d / 2; // 40
inner_r = inner_d / 2; // 35

// 取手パラメータ
hole_h   = 30;    // 取手内側の高さ
hole_w   = 25;    // 取手内側の幅
h_thick  = 10;    // 取手の太さ(断面・押し出し方向)
embed    = 3;     // 本体への食い込み量(接続強化)
handle_z = height / 2; // 取手を高さ中央に

$fn = 96;

// ===== 本体 =====
module body() {
    difference() {
        cylinder(h = height, r = outer_r);
        translate([0, 0, bottom_th])
            cylinder(h = height - bottom_th + 1, r = inner_r);
    }
}

// ===== 取手 =====
// D字形状: 外側半円 + 直線(本体側)
// XZ平面で形状を定義し、Y方向へ押し出す
module handle() {
    handle_outer_h = hole_h + 2 * h_thick; // 全体高さ
    handle_outer_w = hole_w + 2 * h_thick; // 全体幅

    // 本体表面より少し内側(embed)から張り出して接続を確実にする
    translate([outer_r - h_thick - embed, 0, handle_z])
    rotate([90, 0, 0])
    linear_extrude(height = h_thick, center = true)
    difference() {
        // 外形 D字
        hull() {
            translate([0, -handle_outer_h/2])
                square([1, handle_outer_h]);
            translate([handle_outer_w - handle_outer_h/2, 0])
                circle(d = handle_outer_h);
        }
        // 内側の穴 D字
        hull() {
            translate([h_thick + embed, -hole_h/2])
                square([1, hole_h]);
            translate([h_thick + embed + hole_w - hole_h/2, 0])
                circle(d = hole_h);
        }
    }
}

// ===== 結合 =====
union() {
    body();
    handle();
}
i2 success
iter 2
11.9s · 1925/1051t · $0.0359
diff vs i1: +0/-0
  // マグカップ(取手は +X 方向のみ)
  
  // パラメータ
  outer_d   = 80;   // 外径
  inner_d   = 70;   // 内径
  wall      = (outer_d - inner_d) / 2; // 肉厚 5mm
  height    = 90;   // 全体高さ
  bottom_th = 6;    // 底厚
  
  outer_r = outer_d / 2; // 40
  inner_r = inner_d / 2; // 35
  
  // 取手パラメータ
  hole_h   = 30;    // 取手内側の高さ
  hole_w   = 25;    // 取手内側の幅
  h_thick  = 10;    // 取手の太さ(断面・押し出し方向)
  embed    = 3;     // 本体への食い込み量(接続強化)
  handle_z = height / 2; // 取手を高さ中央に
  
  $fn = 96;
  
  // ===== 本体 =====
  module body() {
      difference() {
          cylinder(h = height, r = outer_r);
          translate([0, 0, bottom_th])
              cylinder(h = height - bottom_th + 1, r = inner_r);
      }
  }
  
  // ===== 取手 =====
  // D字形状: 外側半円 + 直線(本体側)
  // XZ平面で形状を定義し、Y方向へ押し出す
  module handle() {
      handle_outer_h = hole_h + 2 * h_thick; // 全体高さ
      handle_outer_w = hole_w + 2 * h_thick; // 全体幅
  
      // 本体表面より少し内側(embed)から張り出して接続を確実にする
      translate([outer_r - h_thick - embed, 0, handle_z])
      rotate([90, 0, 0])
      linear_extrude(height = h_thick, center = true)
      difference() {
          // 外形 D字
          hull() {
              translate([0, -handle_outer_h/2])
                  square([1, handle_outer_h]);
              translate([handle_outer_w - handle_outer_h/2, 0])
                  circle(d = handle_outer_h);
          }
          // 内側の穴 D字
          hull() {
              translate([h_thick + embed, -hole_h/2])
                  square([1, hole_h]);
              translate([h_thick + embed + hole_w - hole_h/2, 0])
                  circle(d = hole_h);
          }
      }
  }
  
  // ===== 結合 =====
  union() {
      body();
      handle();
  }
SCAD (64 lines)
// マグカップ(取手は +X 方向のみ)

// パラメータ
outer_d   = 80;   // 外径
inner_d   = 70;   // 内径
wall      = (outer_d - inner_d) / 2; // 肉厚 5mm
height    = 90;   // 全体高さ
bottom_th = 6;    // 底厚

outer_r = outer_d / 2; // 40
inner_r = inner_d / 2; // 35

// 取手パラメータ
hole_h   = 30;    // 取手内側の高さ
hole_w   = 25;    // 取手内側の幅
h_thick  = 10;    // 取手の太さ(断面・押し出し方向)
embed    = 3;     // 本体への食い込み量(接続強化)
handle_z = height / 2; // 取手を高さ中央に

$fn = 96;

// ===== 本体 =====
module body() {
    difference() {
        cylinder(h = height, r = outer_r);
        translate([0, 0, bottom_th])
            cylinder(h = height - bottom_th + 1, r = inner_r);
    }
}

// ===== 取手 =====
// D字形状: 外側半円 + 直線(本体側)
// XZ平面で形状を定義し、Y方向へ押し出す
module handle() {
    handle_outer_h = hole_h + 2 * h_thick; // 全体高さ
    handle_outer_w = hole_w + 2 * h_thick; // 全体幅

    // 本体表面より少し内側(embed)から張り出して接続を確実にする
    translate([outer_r - h_thick - embed, 0, handle_z])
    rotate([90, 0, 0])
    linear_extrude(height = h_thick, center = true)
    difference() {
        // 外形 D字
        hull() {
            translate([0, -handle_outer_h/2])
                square([1, handle_outer_h]);
            translate([handle_outer_w - handle_outer_h/2, 0])
                circle(d = handle_outer_h);
        }
        // 内側の穴 D字
        hull() {
            translate([h_thick + embed, -hole_h/2])
                square([1, hole_h]);
            translate([h_thick + embed + hole_w - hole_h/2, 0])
                circle(d = hole_h);
        }
    }
}

// ===== 結合 =====
union() {
    body();
    handle();
}
i3 success
iter 3
9.7s · 1925/900t · $0.0321
diff vs i2: +0/-0
  // マグカップ(取手は +X 方向のみ)
  
  // パラメータ
  outer_d   = 80;   // 外径
  inner_d   = 70;   // 内径
  wall      = (outer_d - inner_d) / 2; // 肉厚 5mm
  height    = 90;   // 全体高さ
  bottom_th = 6;    // 底厚
  
  outer_r = outer_d / 2; // 40
  inner_r = inner_d / 2; // 35
  
  // 取手パラメータ
  hole_h   = 30;    // 取手内側の高さ
  hole_w   = 25;    // 取手内側の幅
  h_thick  = 10;    // 取手の太さ(断面・押し出し方向)
  embed    = 3;     // 本体への食い込み量(接続強化)
  handle_z = height / 2; // 取手を高さ中央に
  
  $fn = 96;
  
  // ===== 本体 =====
  module body() {
      difference() {
          cylinder(h = height, r = outer_r);
          translate([0, 0, bottom_th])
              cylinder(h = height - bottom_th + 1, r = inner_r);
      }
  }
  
  // ===== 取手 =====
  // D字形状: 外側半円 + 直線(本体側)
  // XZ平面で形状を定義し、Y方向へ押し出す
  module handle() {
      handle_outer_h = hole_h + 2 * h_thick; // 全体高さ
      handle_outer_w = hole_w + 2 * h_thick; // 全体幅
  
      // 本体表面より少し内側(embed)から張り出して接続を確実にする
      translate([outer_r - h_thick - embed, 0, handle_z])
      rotate([90, 0, 0])
      linear_extrude(height = h_thick, center = true)
      difference() {
          // 外形 D字
          hull() {
              translate([0, -handle_outer_h/2])
                  square([1, handle_outer_h]);
              translate([handle_outer_w - handle_outer_h/2, 0])
                  circle(d = handle_outer_h);
          }
          // 内側の穴 D字
          hull() {
              translate([h_thick + embed, -hole_h/2])
                  square([1, hole_h]);
              translate([h_thick + embed + hole_w - hole_h/2, 0])
                  circle(d = hole_h);
          }
      }
  }
  
  // ===== 結合 =====
  union() {
      body();
      handle();
  }
SCAD (64 lines)
// マグカップ(取手は +X 方向のみ)

// パラメータ
outer_d   = 80;   // 外径
inner_d   = 70;   // 内径
wall      = (outer_d - inner_d) / 2; // 肉厚 5mm
height    = 90;   // 全体高さ
bottom_th = 6;    // 底厚

outer_r = outer_d / 2; // 40
inner_r = inner_d / 2; // 35

// 取手パラメータ
hole_h   = 30;    // 取手内側の高さ
hole_w   = 25;    // 取手内側の幅
h_thick  = 10;    // 取手の太さ(断面・押し出し方向)
embed    = 3;     // 本体への食い込み量(接続強化)
handle_z = height / 2; // 取手を高さ中央に

$fn = 96;

// ===== 本体 =====
module body() {
    difference() {
        cylinder(h = height, r = outer_r);
        translate([0, 0, bottom_th])
            cylinder(h = height - bottom_th + 1, r = inner_r);
    }
}

// ===== 取手 =====
// D字形状: 外側半円 + 直線(本体側)
// XZ平面で形状を定義し、Y方向へ押し出す
module handle() {
    handle_outer_h = hole_h + 2 * h_thick; // 全体高さ
    handle_outer_w = hole_w + 2 * h_thick; // 全体幅

    // 本体表面より少し内側(embed)から張り出して接続を確実にする
    translate([outer_r - h_thick - embed, 0, handle_z])
    rotate([90, 0, 0])
    linear_extrude(height = h_thick, center = true)
    difference() {
        // 外形 D字
        hull() {
            translate([0, -handle_outer_h/2])
                square([1, handle_outer_h]);
            translate([handle_outer_w - handle_outer_h/2, 0])
                circle(d = handle_outer_h);
        }
        // 内側の穴 D字
        hull() {
            translate([h_thick + embed, -hole_h/2])
                square([1, hole_h]);
            translate([h_thick + embed + hole_w - hole_h/2, 0])
                circle(d = hole_h);
        }
    }
}

// ===== 結合 =====
union() {
    body();
    handle();
}