vibe-openscad

tier-2-offset-handle-mug / gpt-6-astra

6 run / 累計 303.6s / 累計 $0.7789

openai gpt 6 astra bare

bare (provider default effort)

run detail →
render
bare render of tier-2-offset-handle-mug
loading STL…
success 20.3s · 273/1054t · $0.0554
SCAD (82 lines)
$fn = 180;

// 本体寸法(mm)
outer_diameter = 80;
inner_diameter = 70;
mug_height = 90;
bottom_thickness = 6;

// 取手寸法(mm)
handle_opening_height = 30;
handle_opening_width = 25;
handle_depth = 10;
handle_tip_thickness = 4;

outer_radius = outer_diameter / 2;
inner_radius = inner_diameter / 2;

// 本体外周へ 2 mm 食い込ませ、面接触ではなく体積で接続する。
handle_base_x = outer_radius - 2;
handle_opening_x = outer_radius + 1;
handle_center_z = mug_height / 2;

opening_offset = handle_opening_x - handle_base_x;
handle_outer_radius =
    opening_offset + handle_opening_width + handle_tip_thickness;

epsilon = 0.1;

// 直線辺が x=0、半円が +X 側にある D 字。
module half_disk(radius) {
    intersection() {
        circle(r = radius);
        translate([0, -radius])
            square([radius, 2 * radius]);
    }
}

module mug_body() {
    difference() {
        cylinder(h = mug_height, r = outer_radius);

        translate([0, 0, bottom_thickness])
            cylinder(
                h = mug_height - bottom_thickness + epsilon,
                r = inner_radius
            );
    }
}

module handle_profile() {
    difference() {
        // 外側は真円の半円、本体側は直線。
        half_disk(handle_outer_radius);

        // 内側の開口:X 方向 25 mm、高さ方向 30 mm。
        translate([opening_offset, 0])
            scale([
                handle_opening_width,
                handle_opening_height / 2
            ])
                half_disk(1);
    }
}

module handle() {
    // 2D の Y を高さ Z に写し、厚みを Y 方向へ付ける。
    // 取手全体を本体の +X 側だけに配置する。
    translate([handle_base_x, 0, handle_center_z])
        rotate([90, 0, 0])
            linear_extrude(
                height = handle_depth,
                center = true,
                convexity = 10
            )
                handle_profile();
}

render(convexity = 10)
    union() {
        mug_body();
        handle();
    }
パラメータ (9) —
スライダを動かすと openscad-wasm で再レンダリング

prompt

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

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

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

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

variant: effort

low success →
low
19.9s · 273/950t · $0.0502
SCAD (74 lines)
$fn = 180;

// 単位: mm
outer_diameter = 80;
inner_diameter = 70;
mug_height = 90;
bottom_thickness = 6;

handle_opening_height = 30;
handle_opening_width = 25;
handle_frame = 6;
handle_depth = 10;

outer_radius = outer_diameter / 2;
inner_radius = inner_diameter / 2;

handle_center_z = mug_height / 2;
handle_base_x = outer_radius - 3;
handle_outer_radius = handle_opening_width + 2 * handle_frame;
epsilon = 0.1;

// 外周は半円と直線からなる D 字。
// 開口は高さ 30 mm、幅 25 mm の半楕円。
module handle_profile() {
    difference() {
        intersection() {
            circle(r = handle_outer_radius);
            translate([0, -handle_outer_radius])
                square([
                    handle_outer_radius,
                    2 * handle_outer_radius
                ]);
        }

        translate([handle_frame, 0])
            intersection() {
                scale([
                    handle_opening_width,
                    handle_opening_height / 2
                ])
                    circle(r = 1);

                translate([0, -handle_opening_height / 2])
                    square([
                        handle_opening_width,
                        handle_opening_height
                    ]);
            }
    }
}

module handle() {
    // プロファイルを XZ 平面に配置し、Y 方向へ厚みを付ける。
    // 本体外周へ 3 mm 食い込ませ、面接触ではなく体積で接続。
    translate([handle_base_x, 0, handle_center_z])
        rotate([90, 0, 0])
            linear_extrude(height = handle_depth, center = true)
                handle_profile();
}

render(convexity = 10)
difference() {
    union() {
        cylinder(r = outer_radius, h = mug_height);
        handle();
    }

    // 上面を開放し、底に 6 mm 残す。
    translate([0, 0, bottom_thickness])
        cylinder(
            r = inner_radius,
            h = mug_height - bottom_thickness + epsilon
        );
}
medium (default) success →
medium
20.3s · 273/1054t · $0.0554
SCAD (82 lines)
$fn = 180;

// 本体寸法(mm)
outer_diameter = 80;
inner_diameter = 70;
mug_height = 90;
bottom_thickness = 6;

// 取手寸法(mm)
handle_opening_height = 30;
handle_opening_width = 25;
handle_depth = 10;
handle_tip_thickness = 4;

outer_radius = outer_diameter / 2;
inner_radius = inner_diameter / 2;

// 本体外周へ 2 mm 食い込ませ、面接触ではなく体積で接続する。
handle_base_x = outer_radius - 2;
handle_opening_x = outer_radius + 1;
handle_center_z = mug_height / 2;

opening_offset = handle_opening_x - handle_base_x;
handle_outer_radius =
    opening_offset + handle_opening_width + handle_tip_thickness;

epsilon = 0.1;

// 直線辺が x=0、半円が +X 側にある D 字。
module half_disk(radius) {
    intersection() {
        circle(r = radius);
        translate([0, -radius])
            square([radius, 2 * radius]);
    }
}

module mug_body() {
    difference() {
        cylinder(h = mug_height, r = outer_radius);

        translate([0, 0, bottom_thickness])
            cylinder(
                h = mug_height - bottom_thickness + epsilon,
                r = inner_radius
            );
    }
}

module handle_profile() {
    difference() {
        // 外側は真円の半円、本体側は直線。
        half_disk(handle_outer_radius);

        // 内側の開口:X 方向 25 mm、高さ方向 30 mm。
        translate([opening_offset, 0])
            scale([
                handle_opening_width,
                handle_opening_height / 2
            ])
                half_disk(1);
    }
}

module handle() {
    // 2D の Y を高さ Z に写し、厚みを Y 方向へ付ける。
    // 取手全体を本体の +X 側だけに配置する。
    translate([handle_base_x, 0, handle_center_z])
        rotate([90, 0, 0])
            linear_extrude(
                height = handle_depth,
                center = true,
                convexity = 10
            )
                handle_profile();
}

render(convexity = 10)
    union() {
        mug_body();
        handle();
    }
high success →
high
36.4s · 273/1934t · $0.0994
SCAD (82 lines)
$fn = 192;

outer_diameter = 80;
inner_diameter = 70;
mug_height = 90;
bottom_thickness = 6;

handle_inner_width = 25;
handle_inner_height = 30;
handle_depth = 10;
handle_back_thickness = 5;
handle_tip_thickness = 5;
handle_overlap = 3;

outer_radius = outer_diameter / 2;
handle_attach_x = outer_radius - handle_overlap;
handle_center_z = mug_height / 2;
handle_outer_radius =
    handle_back_thickness
    + handle_inner_width
    + handle_tip_thickness;

epsilon = 0.05;

// 左辺が直線、右辺が半楕円の閉じた2D形状。
// width == height / 2 の場合、右辺は正確な半円。
module half_ellipse_2d(width, height) {
    intersection() {
        scale([width, height / 2])
            circle(r = 1);

        translate([0, -height / 2])
            square([width + epsilon, height]);
    }
}

module mug_body() {
    difference() {
        cylinder(d = outer_diameter, h = mug_height);

        translate([0, 0, bottom_thickness])
            cylinder(
                d = inner_diameter,
                h = mug_height - bottom_thickness + epsilon
            );
    }
}

module handle_profile_2d() {
    difference() {
        // 外周:本体側が直線、外側が半円のD字。
        half_ellipse_2d(
            handle_outer_radius,
            2 * handle_outer_radius
        );

        // 開口部:幅25mm、高さ30mm。
        translate([handle_back_thickness, 0])
            half_ellipse_2d(
                handle_inner_width,
                handle_inner_height
            );
    }
}

module mug_handle() {
    // 2Dの横方向を+X、縦方向をZ、押出方向をYに配置。
    // 本体外壁へ3mm食い込ませ、体積を共有して接続する。
    translate([handle_attach_x, 0, handle_center_z])
        rotate([90, 0, 0])
            linear_extrude(
                height = handle_depth,
                center = true,
                convexity = 10
            )
                handle_profile_2d();
}

union() {
    mug_body();
    mug_handle();
}
max success →
max
124.1s · 273/6273t · $0.3164
SCAD (76 lines)
$fn = 192;

outer_diameter = 80;
inner_diameter = 70;
mug_height = 90;
bottom_thickness = 6;

opening_height = 30;
opening_width = 25;
handle_depth = 12;

handle_overlap = 3;
opening_clearance = 1;
handle_outer_wall = 6;

handle_x = outer_diameter / 2 - handle_overlap;
handle_spine = handle_overlap + opening_clearance;
handle_outer_radius = handle_spine + opening_width + handle_outer_wall;

eps = 0.1;

// 2D の +X 側半楕円。rx == ry の場合は半円。
module positive_x_half_ellipse(rx, ry) {
    intersection() {
        scale([rx, ry])
            circle(r = 1);

        translate([0, -ry - eps])
            square([rx + eps, 2 * ry + 2 * eps]);
    }
}

module mug_body() {
    difference() {
        cylinder(d = outer_diameter, h = mug_height);

        translate([0, 0, bottom_thickness])
            cylinder(
                d = inner_diameter,
                h = mug_height - bottom_thickness + eps
            );
    }
}

module d_handle() {
    // XZ 平面に配置し、Y 方向に厚みを持たせる。
    // 本体側の直線部分を外壁に 3 mm 食い込ませる。
    translate([handle_x, 0, mug_height / 2])
        rotate([90, 0, 0])
            linear_extrude(
                height = handle_depth,
                center = true,
                convexity = 10
            )
                difference() {
                    // 外周:+X 側が半円、本体側が直線。
                    positive_x_half_ellipse(
                        handle_outer_radius,
                        handle_outer_radius
                    );

                    // 開口:幅 25 mm × 高さ 30 mm。
                    // 全体を本体外周より外側に置き、空間を確保する。
                    translate([handle_spine, 0])
                        positive_x_half_ellipse(
                            opening_width,
                            opening_height / 2
                        );
                }
}

render(convexity = 10)
    union() {
        mug_body();
        d_handle();
    }
xhigh success →
xhigh
82.5s · 273/3985t · $0.2020
SCAD (63 lines)
$fn = 192;

outer_diameter = 80;
inner_diameter = 70;
mug_height     = 90;
bottom_thickness = 6;

handle_hole_height = 30;
handle_hole_width  = 25;
handle_depth       = 10; // Y方向の厚み
handle_rim         = 5;
attachment_overlap = 3; // 本体への食い込み量

handle_base_x = outer_diameter / 2 - attachment_overlap;
handle_center_z = mug_height / 2;

// 外周を真の半円にし、開口の前後に5mmの肉を確保
handle_outer_radius = handle_hole_width + 2 * handle_rim;

epsilon = 0.02;

// 2D:+X側の半円。本体側の境界は直線。
module right_semicircle(r) {
    intersection() {
        circle(r = r);
        translate([0, -r])
            square([r, 2 * r]);
    }
}

// 2D:外周が半円、内側開口が幅25mm×高さ30mmのD字形
module handle_profile() {
    difference() {
        right_semicircle(handle_outer_radius);

        translate([handle_rim, 0])
            scale([handle_hole_width, handle_hole_height / 2])
                right_semicircle(1);
    }
}

// 取手をXZ平面に配置し、Y方向へ厚みを付ける
module handle() {
    translate([handle_base_x, 0, handle_center_z])
        rotate([90, 0, 0])
            linear_extrude(height = handle_depth, center = true)
                handle_profile();
}

difference() {
    // 取手の直線側が本体に3mm入り込み、体積を持って接続
    union() {
        cylinder(d = outer_diameter, h = mug_height);
        handle();
    }

    // 上面を開放し、底面に6mmを残す
    translate([0, 0, bottom_thickness])
        cylinder(
            d = inner_diameter,
            h = mug_height - bottom_thickness + epsilon
        );
}