vibe-openscad

tier-2-offset-handle-mug / claude-opus-4-5-20251101

7 run / 累計 74.2s / 累計 $0.1658

claude opus 4.5 2025-11-01 bare

bare (provider default effort)

run detail →
render
bare render of tier-2-offset-handle-mug
loading STL…
success 11.4s · 330/709t · $0.0194
SCAD (73 lines)
// Mug parameters
outer_diameter = 80;
inner_diameter = 70;
mug_height = 90;
bottom_thickness = 6;
wall_thickness = 5;

// Handle parameters
handle_inner_height = 30;
handle_inner_width = 25;
handle_thickness = 8;

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

// Handle position (centered vertically)
handle_center_z = mug_height / 2;

module mug_body() {
    difference() {
        // Outer cylinder
        cylinder(h = mug_height, r = outer_radius, $fn = 100);
        
        // Inner cavity (hollow part for liquid)
        translate([0, 0, bottom_thickness])
            cylinder(h = mug_height - bottom_thickness + 1, r = inner_radius, $fn = 100);
    }
}

module handle() {
    // Handle dimensions
    handle_outer_height = handle_inner_height + 2 * handle_thickness;
    handle_outer_width = handle_inner_width + handle_thickness;
    
    // Position handle on +X side
    handle_x_offset = outer_radius - 2; // Overlap with mug body for solid union
    
    translate([handle_x_offset, 0, handle_center_z - handle_outer_height / 2]) {
        rotate([90, 0, 0]) {
            linear_extrude(height = handle_thickness, center = true) {
                difference() {
                    // Outer D-shape
                    union() {
                        // Rectangular part connecting to mug
                        translate([0, handle_outer_height / 2])
                            square([handle_thickness + 2, handle_outer_height], center = true);
                        
                        // Semi-circular outer part
                        translate([handle_thickness / 2, handle_outer_height / 2])
                            resize([handle_outer_width * 2, handle_outer_height])
                                circle(d = handle_outer_height, $fn = 60);
                    }
                    
                    // Inner cutout (D-shape hole)
                    translate([handle_thickness / 2, handle_outer_height / 2])
                        resize([handle_inner_width * 2, handle_inner_height])
                            circle(d = handle_inner_height, $fn = 60);
                    
                    // Cut off the left side to make D-shape
                    translate([-handle_outer_width - 5, 0])
                        square([handle_outer_width + 5, handle_outer_height + 10]);
                }
            }
        }
    }
}

// Final mug assembly
union() {
    mug_body();
    handle();
}
パラメータ (8)
スライダを動かすと openscad-wasm で再レンダリング

prompt

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

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

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

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

variant: effort

low success
low
7.9s · 431/554t · $0.0160
SCAD (50 lines)
// マグカップ - 取手は+X方向
$fn = 64;

// 本体パラメータ
outer_d = 80;
inner_d = 70;
height = 90;
bottom_thick = 6;

// 取手パラメータ
handle_inner_h = 30;
handle_inner_w = 25;
handle_thick = 5;

// 本体
difference() {
    cylinder(d=outer_d, h=height);
    translate([0, 0, bottom_thick])
        cylinder(d=inner_d, h=height);
}

// 取手(+X方向)
handle_outer_w = handle_inner_w + handle_thick * 2;
handle_outer_h = handle_inner_h + handle_thick * 2;
handle_center_z = height / 2;

translate([outer_d/2, 0, handle_center_z])
rotate([90, 0, 0])
rotate([0, 90, 0])
difference() {
    // 外側形状
    hull() {
        translate([0, -handle_inner_h/2 - handle_thick/2, 0])
            cylinder(d=handle_thick, h=handle_outer_w);
        translate([0, handle_inner_h/2 + handle_thick/2, 0])
            cylinder(d=handle_thick, h=handle_outer_w);
        translate([handle_inner_w/2 + handle_thick/2, 0, 0])
            cylinder(d=handle_thick, h=handle_outer_w);
    }
    // 内側くり抜き
    translate([0, 0, handle_thick])
    hull() {
        translate([0, -handle_inner_h/2, 0])
            cylinder(d=0.1, h=handle_inner_w);
        translate([0, handle_inner_h/2, 0])
            cylinder(d=0.1, h=handle_inner_w);
        translate([handle_inner_w/2, 0, 0])
            cylinder(d=0.1, h=handle_inner_w);
    }
}
mediumnot run
high (default) success
high
11.4s · 330/709t · $0.0194
SCAD (73 lines)
// Mug parameters
outer_diameter = 80;
inner_diameter = 70;
mug_height = 90;
bottom_thickness = 6;
wall_thickness = 5;

// Handle parameters
handle_inner_height = 30;
handle_inner_width = 25;
handle_thickness = 8;

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

// Handle position (centered vertically)
handle_center_z = mug_height / 2;

module mug_body() {
    difference() {
        // Outer cylinder
        cylinder(h = mug_height, r = outer_radius, $fn = 100);
        
        // Inner cavity (hollow part for liquid)
        translate([0, 0, bottom_thickness])
            cylinder(h = mug_height - bottom_thickness + 1, r = inner_radius, $fn = 100);
    }
}

module handle() {
    // Handle dimensions
    handle_outer_height = handle_inner_height + 2 * handle_thickness;
    handle_outer_width = handle_inner_width + handle_thickness;
    
    // Position handle on +X side
    handle_x_offset = outer_radius - 2; // Overlap with mug body for solid union
    
    translate([handle_x_offset, 0, handle_center_z - handle_outer_height / 2]) {
        rotate([90, 0, 0]) {
            linear_extrude(height = handle_thickness, center = true) {
                difference() {
                    // Outer D-shape
                    union() {
                        // Rectangular part connecting to mug
                        translate([0, handle_outer_height / 2])
                            square([handle_thickness + 2, handle_outer_height], center = true);
                        
                        // Semi-circular outer part
                        translate([handle_thickness / 2, handle_outer_height / 2])
                            resize([handle_outer_width * 2, handle_outer_height])
                                circle(d = handle_outer_height, $fn = 60);
                    }
                    
                    // Inner cutout (D-shape hole)
                    translate([handle_thickness / 2, handle_outer_height / 2])
                        resize([handle_inner_width * 2, handle_inner_height])
                            circle(d = handle_inner_height, $fn = 60);
                    
                    // Cut off the left side to make D-shape
                    translate([-handle_outer_width - 5, 0])
                        square([handle_outer_width + 5, handle_outer_height + 10]);
                }
            }
        }
    }
}

// Final mug assembly
union() {
    mug_body();
    handle();
}
maxnot run
xhighnot run

variant: thinking

off (default) success
off
7.9s · 431/554t · $0.0160
SCAD (50 lines)
// マグカップ - 取手は+X方向
$fn = 64;

// 本体パラメータ
outer_d = 80;
inner_d = 70;
height = 90;
bottom_thick = 6;

// 取手パラメータ
handle_inner_h = 30;
handle_inner_w = 25;
handle_thick = 5;

// 本体
difference() {
    cylinder(d=outer_d, h=height);
    translate([0, 0, bottom_thick])
        cylinder(d=inner_d, h=height);
}

// 取手(+X方向)
handle_outer_w = handle_inner_w + handle_thick * 2;
handle_outer_h = handle_inner_h + handle_thick * 2;
handle_center_z = height / 2;

translate([outer_d/2, 0, handle_center_z])
rotate([90, 0, 0])
rotate([0, 90, 0])
difference() {
    // 外側形状
    hull() {
        translate([0, -handle_inner_h/2 - handle_thick/2, 0])
            cylinder(d=handle_thick, h=handle_outer_w);
        translate([0, handle_inner_h/2 + handle_thick/2, 0])
            cylinder(d=handle_thick, h=handle_outer_w);
        translate([handle_inner_w/2 + handle_thick/2, 0, 0])
            cylinder(d=handle_thick, h=handle_outer_w);
    }
    // 内側くり抜き
    translate([0, 0, handle_thick])
    hull() {
        translate([0, -handle_inner_h/2, 0])
            cylinder(d=0.1, h=handle_inner_w);
        translate([0, handle_inner_h/2, 0])
            cylinder(d=0.1, h=handle_inner_w);
        translate([handle_inner_w/2, 0, 0])
            cylinder(d=0.1, h=handle_inner_w);
    }
}
adaptivenot run
dynamicnot run

iteration: iter-png

i1 success
iter 1
13.3s · 1795/825t · $0.0296
diff vs bare: +33/-33
  // Mug parameters
  outer_diameter = 80;
  inner_diameter = 70;
  mug_height = 90;
  bottom_thickness = 6;
  wall_thickness = 5;
  
  // Handle parameters
  handle_inner_height = 30;
  handle_inner_width = 25;
- handle_thickness = 8;
+ handle_thickness = 10;
  
  // Derived values
  outer_radius = outer_diameter / 2;
  inner_radius = inner_diameter / 2;
  
  // Handle position (centered vertically)
  handle_center_z = mug_height / 2;
  
  module mug_body() {
      difference() {
          // Outer cylinder
          cylinder(h = mug_height, r = outer_radius, $fn = 100);
          
          // Inner cavity (hollow part for liquid)
          translate([0, 0, bottom_thickness])
              cylinder(h = mug_height - bottom_thickness + 1, r = inner_radius, $fn = 100);
      }
  }
  
  module handle() {
-     // Handle dimensions
-     handle_outer_height = handle_inner_height + 2 * handle_thickness;
-     handle_outer_width = handle_inner_width + handle_thickness;
+     // Handle creates a D-shape with specified inner dimensions
+     // Inner space: 30mm height x 25mm width
      
-     // Position handle on +X side
-     handle_x_offset = outer_radius - 2; // Overlap with mug body for solid union
+     handle_width = handle_inner_width + handle_thickness; // Total width from mug surface
+     handle_total_height = handle_inner_height + 2 * handle_thickness;
      
-     translate([handle_x_offset, 0, handle_center_z - handle_outer_height / 2]) {
-         rotate([90, 0, 0]) {
-             linear_extrude(height = handle_thickness, center = true) {
-                 difference() {
-                     // Outer D-shape
-                     union() {
-                         // Rectangular part connecting to mug
-                         translate([0, handle_outer_height / 2])
-                             square([handle_thickness + 2, handle_outer_height], center = true);
-                         
-                         // Semi-circular outer part
-                         translate([handle_thickness / 2, handle_outer_height / 2])
-                             resize([handle_outer_width * 2, handle_outer_height])
-                                 circle(d = handle_outer_height, $fn = 60);
-                     }
-                     
-                     // Inner cutout (D-shape hole)
-                     translate([handle_thickness / 2, handle_outer_height / 2])
-                         resize([handle_inner_width * 2, handle_inner_height])
-                             circle(d = handle_inner_height, $fn = 60);
-                     
-                     // Cut off the left side to make D-shape
-                     translate([-handle_outer_width - 5, 0])
-                         square([handle_outer_width + 5, handle_outer_height + 10]);
-                 }
-             }
-         }
+     // Create handle using rotate_extrude with a partial arc and connection bars
+     translate([outer_radius, 0, handle_center_z]) {
+         // Top connection bar
+         translate([0, 0, handle_inner_height/2 + handle_thickness/2])
+             rotate([0, 90, 0])
+                 cylinder(h = handle_inner_width, r = handle_thickness/2, $fn = 30);
+         
+         // Bottom connection bar
+         translate([0, 0, -handle_inner_height/2 - handle_thickness/2])
+             rotate([0, 90, 0])
+                 cylinder(h = handle_inner_width, r = handle_thickness/2, $fn = 30);
+         
+         // Outer curved part (semi-circle)
+         translate([handle_inner_width, 0, 0])
+             rotate([0, 0, -90])
+                 rotate_extrude(angle = 180, $fn = 60)
+                     translate([handle_inner_height/2 + handle_thickness/2, 0, 0])
+                         circle(r = handle_thickness/2, $fn = 30);
+         
+         // Fill connection spheres for smooth joints
+         translate([0, 0, handle_inner_height/2 + handle_thickness/2])
+             sphere(r = handle_thickness/2, $fn = 30);
+         translate([0, 0, -handle_inner_height/2 - handle_thickness/2])
+             sphere(r = handle_thickness/2, $fn = 30);
+         translate([handle_inner_width, 0, handle_inner_height/2 + handle_thickness/2])
+             sphere(r = handle_thickness/2, $fn = 30);
+         translate([handle_inner_width, 0, -handle_inner_height/2 - handle_thickness/2])
+             sphere(r = handle_thickness/2, $fn = 30);
      }
  }
  
  // Final mug assembly
  union() {
      mug_body();
      handle();
  }
SCAD (73 lines)
// Mug parameters
outer_diameter = 80;
inner_diameter = 70;
mug_height = 90;
bottom_thickness = 6;
wall_thickness = 5;

// Handle parameters
handle_inner_height = 30;
handle_inner_width = 25;
handle_thickness = 10;

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

// Handle position (centered vertically)
handle_center_z = mug_height / 2;

module mug_body() {
    difference() {
        // Outer cylinder
        cylinder(h = mug_height, r = outer_radius, $fn = 100);
        
        // Inner cavity (hollow part for liquid)
        translate([0, 0, bottom_thickness])
            cylinder(h = mug_height - bottom_thickness + 1, r = inner_radius, $fn = 100);
    }
}

module handle() {
    // Handle creates a D-shape with specified inner dimensions
    // Inner space: 30mm height x 25mm width
    
    handle_width = handle_inner_width + handle_thickness; // Total width from mug surface
    handle_total_height = handle_inner_height + 2 * handle_thickness;
    
    // Create handle using rotate_extrude with a partial arc and connection bars
    translate([outer_radius, 0, handle_center_z]) {
        // Top connection bar
        translate([0, 0, handle_inner_height/2 + handle_thickness/2])
            rotate([0, 90, 0])
                cylinder(h = handle_inner_width, r = handle_thickness/2, $fn = 30);
        
        // Bottom connection bar
        translate([0, 0, -handle_inner_height/2 - handle_thickness/2])
            rotate([0, 90, 0])
                cylinder(h = handle_inner_width, r = handle_thickness/2, $fn = 30);
        
        // Outer curved part (semi-circle)
        translate([handle_inner_width, 0, 0])
            rotate([0, 0, -90])
                rotate_extrude(angle = 180, $fn = 60)
                    translate([handle_inner_height/2 + handle_thickness/2, 0, 0])
                        circle(r = handle_thickness/2, $fn = 30);
        
        // Fill connection spheres for smooth joints
        translate([0, 0, handle_inner_height/2 + handle_thickness/2])
            sphere(r = handle_thickness/2, $fn = 30);
        translate([0, 0, -handle_inner_height/2 - handle_thickness/2])
            sphere(r = handle_thickness/2, $fn = 30);
        translate([handle_inner_width, 0, handle_inner_height/2 + handle_thickness/2])
            sphere(r = handle_thickness/2, $fn = 30);
        translate([handle_inner_width, 0, -handle_inner_height/2 - handle_thickness/2])
            sphere(r = handle_thickness/2, $fn = 30);
    }
}

// Final mug assembly
union() {
    mug_body();
    handle();
}
i2 success
iter 2
10.6s · 1911/902t · $0.0321
diff vs i1: +19/-18
  // Mug parameters
  outer_diameter = 80;
  inner_diameter = 70;
  mug_height = 90;
  bottom_thickness = 6;
  wall_thickness = 5;
  
  // Handle parameters
  handle_inner_height = 30;
  handle_inner_width = 25;
- handle_thickness = 10;
+ handle_thickness = 12;
  
  // Derived values
  outer_radius = outer_diameter / 2;
  inner_radius = inner_diameter / 2;
  
  // Handle position (centered vertically)
  handle_center_z = mug_height / 2;
  
  module mug_body() {
      difference() {
          // Outer cylinder
          cylinder(h = mug_height, r = outer_radius, $fn = 100);
          
          // Inner cavity (hollow part for liquid)
          translate([0, 0, bottom_thickness])
              cylinder(h = mug_height - bottom_thickness + 1, r = inner_radius, $fn = 100);
      }
  }
  
  module handle() {
      // Handle creates a D-shape with specified inner dimensions
      // Inner space: 30mm height x 25mm width
      
-     handle_width = handle_inner_width + handle_thickness; // Total width from mug surface
-     handle_total_height = handle_inner_height + 2 * handle_thickness;
+     // Start position slightly inside the mug wall for solid connection
+     start_x = outer_radius - 3;
      
-     // Create handle using rotate_extrude with a partial arc and connection bars
-     translate([outer_radius, 0, handle_center_z]) {
-         // Top connection bar
+     translate([start_x, 0, handle_center_z]) {
+         // Top horizontal bar
          translate([0, 0, handle_inner_height/2 + handle_thickness/2])
              rotate([0, 90, 0])
-                 cylinder(h = handle_inner_width, r = handle_thickness/2, $fn = 30);
+                 cylinder(h = handle_inner_width + 3, r = handle_thickness/2, $fn = 30);
          
-         // Bottom connection bar
+         // Bottom horizontal bar
          translate([0, 0, -handle_inner_height/2 - handle_thickness/2])
              rotate([0, 90, 0])
-                 cylinder(h = handle_inner_width, r = handle_thickness/2, $fn = 30);
+                 cylinder(h = handle_inner_width + 3, r = handle_thickness/2, $fn = 30);
          
-         // Outer curved part (semi-circle)
-         translate([handle_inner_width, 0, 0])
+         // Outer curved part (semi-circle connecting top and bottom)
+         translate([handle_inner_width + 3, 0, 0])
              rotate([0, 0, -90])
                  rotate_extrude(angle = 180, $fn = 60)
                      translate([handle_inner_height/2 + handle_thickness/2, 0, 0])
                          circle(r = handle_thickness/2, $fn = 30);
          
-         // Fill connection spheres for smooth joints
-         translate([0, 0, handle_inner_height/2 + handle_thickness/2])
+         // Smooth joint spheres at corners
+         translate([handle_inner_width + 3, 0, handle_inner_height/2 + handle_thickness/2])
              sphere(r = handle_thickness/2, $fn = 30);
-         translate([0, 0, -handle_inner_height/2 - handle_thickness/2])
+         translate([handle_inner_width + 3, 0, -handle_inner_height/2 - handle_thickness/2])
              sphere(r = handle_thickness/2, $fn = 30);
-         translate([handle_inner_width, 0, handle_inner_height/2 + handle_thickness/2])
-             sphere(r = handle_thickness/2, $fn = 30);
-         translate([handle_inner_width, 0, -handle_inner_height/2 - handle_thickness/2])
-             sphere(r = handle_thickness/2, $fn = 30);
      }
+     
+     // Additional connection blocks to ensure solid attachment to mug body
+     translate([outer_radius - 5, -handle_thickness/2, handle_center_z - handle_inner_height/2 - handle_thickness])
+         cube([8, handle_thickness, handle_thickness]);
+     translate([outer_radius - 5, -handle_thickness/2, handle_center_z + handle_inner_height/2])
+         cube([8, handle_thickness, handle_thickness]);
  }
  
  // Final mug assembly
  union() {
      mug_body();
      handle();
  }
SCAD (74 lines)
// Mug parameters
outer_diameter = 80;
inner_diameter = 70;
mug_height = 90;
bottom_thickness = 6;
wall_thickness = 5;

// Handle parameters
handle_inner_height = 30;
handle_inner_width = 25;
handle_thickness = 12;

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

// Handle position (centered vertically)
handle_center_z = mug_height / 2;

module mug_body() {
    difference() {
        // Outer cylinder
        cylinder(h = mug_height, r = outer_radius, $fn = 100);
        
        // Inner cavity (hollow part for liquid)
        translate([0, 0, bottom_thickness])
            cylinder(h = mug_height - bottom_thickness + 1, r = inner_radius, $fn = 100);
    }
}

module handle() {
    // Handle creates a D-shape with specified inner dimensions
    // Inner space: 30mm height x 25mm width
    
    // Start position slightly inside the mug wall for solid connection
    start_x = outer_radius - 3;
    
    translate([start_x, 0, handle_center_z]) {
        // Top horizontal bar
        translate([0, 0, handle_inner_height/2 + handle_thickness/2])
            rotate([0, 90, 0])
                cylinder(h = handle_inner_width + 3, r = handle_thickness/2, $fn = 30);
        
        // Bottom horizontal bar
        translate([0, 0, -handle_inner_height/2 - handle_thickness/2])
            rotate([0, 90, 0])
                cylinder(h = handle_inner_width + 3, r = handle_thickness/2, $fn = 30);
        
        // Outer curved part (semi-circle connecting top and bottom)
        translate([handle_inner_width + 3, 0, 0])
            rotate([0, 0, -90])
                rotate_extrude(angle = 180, $fn = 60)
                    translate([handle_inner_height/2 + handle_thickness/2, 0, 0])
                        circle(r = handle_thickness/2, $fn = 30);
        
        // Smooth joint spheres at corners
        translate([handle_inner_width + 3, 0, handle_inner_height/2 + handle_thickness/2])
            sphere(r = handle_thickness/2, $fn = 30);
        translate([handle_inner_width + 3, 0, -handle_inner_height/2 - handle_thickness/2])
            sphere(r = handle_thickness/2, $fn = 30);
    }
    
    // Additional connection blocks to ensure solid attachment to mug body
    translate([outer_radius - 5, -handle_thickness/2, handle_center_z - handle_inner_height/2 - handle_thickness])
        cube([8, handle_thickness, handle_thickness]);
    translate([outer_radius - 5, -handle_thickness/2, handle_center_z + handle_inner_height/2])
        cube([8, handle_thickness, handle_thickness]);
}

// Final mug assembly
union() {
    mug_body();
    handle();
}
i3 success
iter 3
11.7s · 1922/948t · $0.0333
diff vs i2: +40/-31
  // Mug parameters
  outer_diameter = 80;
  inner_diameter = 70;
  mug_height = 90;
  bottom_thickness = 6;
  wall_thickness = 5;
  
  // Handle parameters
  handle_inner_height = 30;
  handle_inner_width = 25;
  handle_thickness = 12;
  
  // Derived values
  outer_radius = outer_diameter / 2;
  inner_radius = inner_diameter / 2;
  
  // Handle position (centered vertically)
  handle_center_z = mug_height / 2;
  
  module mug_body() {
      difference() {
          // Outer cylinder
          cylinder(h = mug_height, r = outer_radius, $fn = 100);
          
          // Inner cavity (hollow part for liquid)
          translate([0, 0, bottom_thickness])
              cylinder(h = mug_height - bottom_thickness + 1, r = inner_radius, $fn = 100);
      }
  }
  
  module handle() {
-     // Handle creates a D-shape with specified inner dimensions
+     // Handle creates a D-shape attached to +X side of mug
      // Inner space: 30mm height x 25mm width
      
-     // Start position slightly inside the mug wall for solid connection
-     start_x = outer_radius - 3;
+     handle_tube_r = handle_thickness / 2;
      
-     translate([start_x, 0, handle_center_z]) {
-         // Top horizontal bar
-         translate([0, 0, handle_inner_height/2 + handle_thickness/2])
-             rotate([0, 90, 0])
-                 cylinder(h = handle_inner_width + 3, r = handle_thickness/2, $fn = 30);
-         
-         // Bottom horizontal bar
-         translate([0, 0, -handle_inner_height/2 - handle_thickness/2])
-             rotate([0, 90, 0])
-                 cylinder(h = handle_inner_width + 3, r = handle_thickness/2, $fn = 30);
-         
-         // Outer curved part (semi-circle connecting top and bottom)
-         translate([handle_inner_width + 3, 0, 0])
-             rotate([0, 0, -90])
-                 rotate_extrude(angle = 180, $fn = 60)
-                     translate([handle_inner_height/2 + handle_thickness/2, 0, 0])
-                         circle(r = handle_thickness/2, $fn = 30);
-         
-         // Smooth joint spheres at corners
-         translate([handle_inner_width + 3, 0, handle_inner_height/2 + handle_thickness/2])
-             sphere(r = handle_thickness/2, $fn = 30);
-         translate([handle_inner_width + 3, 0, -handle_inner_height/2 - handle_thickness/2])
-             sphere(r = handle_thickness/2, $fn = 30);
+     // Vertical positions for top and bottom of handle inner space
+     top_z = handle_center_z + handle_inner_height / 2;
+     bottom_z = handle_center_z - handle_inner_height / 2;
+     
+     // Horizontal extension from mug surface
+     extend_x = handle_inner_width;
+     
+     hull() {
+         // Top connection point - embedded in mug wall
+         translate([outer_radius - handle_tube_r, 0, top_z])
+             sphere(r = handle_tube_r, $fn = 40);
+         // Top outer point
+         translate([outer_radius + extend_x, 0, top_z])
+             sphere(r = handle_tube_r, $fn = 40);
      }
      
-     // Additional connection blocks to ensure solid attachment to mug body
-     translate([outer_radius - 5, -handle_thickness/2, handle_center_z - handle_inner_height/2 - handle_thickness])
-         cube([8, handle_thickness, handle_thickness]);
-     translate([outer_radius - 5, -handle_thickness/2, handle_center_z + handle_inner_height/2])
-         cube([8, handle_thickness, handle_thickness]);
+     hull() {
+         // Bottom connection point - embedded in mug wall
+         translate([outer_radius - handle_tube_r, 0, bottom_z])
+             sphere(r = handle_tube_r, $fn = 40);
+         // Bottom outer point
+         translate([outer_radius + extend_x, 0, bottom_z])
+             sphere(r = handle_tube_r, $fn = 40);
+     }
+     
+     // Outer vertical curved section (semicircle in XZ plane)
+     translate([outer_radius + extend_x, 0, handle_center_z])
+         rotate([90, 0, 0])
+             rotate_extrude(angle = 180, convexity = 10, $fn = 60)
+                 translate([handle_inner_height / 2, 0, 0])
+                     circle(r = handle_tube_r, $fn = 40);
+     
+     // Connection reinforcement blocks to ensure solid union with mug body
+     // Top connection block
+     translate([outer_radius - wall_thickness, -handle_tube_r, top_z - handle_tube_r])
+         cube([wall_thickness + 2, handle_tube_r * 2, handle_tube_r * 2]);
+     
+     // Bottom connection block
+     translate([outer_radius - wall_thickness, -handle_tube_r, bottom_z - handle_tube_r])
+         cube([wall_thickness + 2, handle_tube_r * 2, handle_tube_r * 2]);
  }
  
  // Final mug assembly
  union() {
      mug_body();
      handle();
  }
SCAD (83 lines)
// Mug parameters
outer_diameter = 80;
inner_diameter = 70;
mug_height = 90;
bottom_thickness = 6;
wall_thickness = 5;

// Handle parameters
handle_inner_height = 30;
handle_inner_width = 25;
handle_thickness = 12;

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

// Handle position (centered vertically)
handle_center_z = mug_height / 2;

module mug_body() {
    difference() {
        // Outer cylinder
        cylinder(h = mug_height, r = outer_radius, $fn = 100);
        
        // Inner cavity (hollow part for liquid)
        translate([0, 0, bottom_thickness])
            cylinder(h = mug_height - bottom_thickness + 1, r = inner_radius, $fn = 100);
    }
}

module handle() {
    // Handle creates a D-shape attached to +X side of mug
    // Inner space: 30mm height x 25mm width
    
    handle_tube_r = handle_thickness / 2;
    
    // Vertical positions for top and bottom of handle inner space
    top_z = handle_center_z + handle_inner_height / 2;
    bottom_z = handle_center_z - handle_inner_height / 2;
    
    // Horizontal extension from mug surface
    extend_x = handle_inner_width;
    
    hull() {
        // Top connection point - embedded in mug wall
        translate([outer_radius - handle_tube_r, 0, top_z])
            sphere(r = handle_tube_r, $fn = 40);
        // Top outer point
        translate([outer_radius + extend_x, 0, top_z])
            sphere(r = handle_tube_r, $fn = 40);
    }
    
    hull() {
        // Bottom connection point - embedded in mug wall
        translate([outer_radius - handle_tube_r, 0, bottom_z])
            sphere(r = handle_tube_r, $fn = 40);
        // Bottom outer point
        translate([outer_radius + extend_x, 0, bottom_z])
            sphere(r = handle_tube_r, $fn = 40);
    }
    
    // Outer vertical curved section (semicircle in XZ plane)
    translate([outer_radius + extend_x, 0, handle_center_z])
        rotate([90, 0, 0])
            rotate_extrude(angle = 180, convexity = 10, $fn = 60)
                translate([handle_inner_height / 2, 0, 0])
                    circle(r = handle_tube_r, $fn = 40);
    
    // Connection reinforcement blocks to ensure solid union with mug body
    // Top connection block
    translate([outer_radius - wall_thickness, -handle_tube_r, top_z - handle_tube_r])
        cube([wall_thickness + 2, handle_tube_r * 2, handle_tube_r * 2]);
    
    // Bottom connection block
    translate([outer_radius - wall_thickness, -handle_tube_r, bottom_z - handle_tube_r])
        cube([wall_thickness + 2, handle_tube_r * 2, handle_tube_r * 2]);
}

// Final mug assembly
union() {
    mug_body();
    handle();
}