Soap dish v1
by Mach3 ·
Sports neat spherical cut out for a piece of soap, and bestagon ribs (of course!). Optional water collector tray.
Interactive Preview & Customizer
3D STL viewer with browser-based OpenSCAD rendering on parameter changes.
Loading preview...
Which part to preview or export
Vertical gap between tray and dish in assembly preview (mm)
step 0.5
Outer frame width (mm)
step 1
Outer frame height (mm)
step 1
Total frame thickness (mm)
step 0.5
Border wall thickness (mm)
step 0.1
Outer corner radius (mm)
step 0.5
Size of individual honeycomb cells (mm)
step 0.5
Thickness of honeycomb ribs (mm)
step 0.1
Radius for the spherical soap scoop (mm)
step 1
Depth of scoop into the frame (mm)
step 0.5
Clearance around dish footprint inside tray (mm)
step 0.1
Tray wall and floor thickness (mm)
step 0.1
Total tray height (mm)
step 0.5
Curve smoothness
step 1
WASM compiler loads on first parameter change.
Prompt
I want to turn this into soap holder.
1. make sure the hex structures are originating from the center of the shape;
2. I want to have a negative cut of huge sphere from the center of the shape
OpenSCAD Code
// Honeycomb Soap Dish + Optional Drip Tray
// Dimensions: 175mm x 175mm
/* [Output] */
// Which part to preview or export
part = "assembly"; // [dish,tray,assembly]
// Vertical gap between tray and dish in assembly preview (mm)
assembly_gap = 1.0; // [0:0.5:8]
/* [Frame] */
// Outer frame width (mm)
frame_width = 135; // [90:1:220]
// Outer frame height (mm)
frame_height = 135; // [90:1:220]
// Total frame thickness (mm)
frame_depth = 24; // [8:0.5:60]
// Border wall thickness (mm)
frame_border = 1.6; // [1:0.1:6]
// Outer corner radius (mm)
corner_radius = 35; // [8:0.5:70]
/* [Honeycomb] */
// Size of individual honeycomb cells (mm)
hex_radius = 20; // [6:0.5:40]
// Thickness of honeycomb ribs (mm)
hex_wall = 1.6; // [0.8:0.1:6]
/* [Bowl] */
// Radius for the spherical soap scoop (mm)
dish_radius = 220; // [120:1:420]
// Depth of scoop into the frame (mm)
dish_depth = 16; // [4:0.5:36]
/* [Tray] */
// Clearance around dish footprint inside tray (mm)
tray_tolerance = 1.0; // [0:0.1:3]
// Tray wall and floor thickness (mm)
tray_wall_thickness = 2.0; // [0.8:0.1:8]
// Total tray height (mm)
tray_height = 8; // [2:0.5:30]
/* [Quality] */
// Curve smoothness
$fn = 80; // [48:1:180]
// --- Render selection ---
if (part == "dish") {
soap_dish_body();
} else if (part == "tray") {
drip_tray();
} else if (part == "assembly") {
drip_tray();
translate([0, 0, tray_height + assembly_gap]) soap_dish_body();
}
// --- Modules ---
module soap_dish_body() {
// Position sphere so its bottom reaches the desired depth
sphere_z_offset = (frame_depth - dish_depth) + dish_radius;
difference() {
union() {
// 1. Outer border frame
difference() {
rounded_square(frame_width, frame_height, frame_depth, corner_radius);
// Interior cutout
translate([0, 0, -1])
rounded_square(
frame_width - frame_border * 2,
frame_height - frame_border * 2,
frame_depth + 2,
corner_radius - frame_border
);
}
// 2. Honeycomb fill
intersection() {
rounded_square(frame_width - frame_border, frame_height - frame_border, frame_depth, corner_radius - frame_border / 2);
// Pattern centered at 0,0
honeycomb_grid(frame_width, frame_height, frame_depth, hex_radius, hex_wall);
}
}
// 3. Concave soap bowl cut
translate([0, 0, sphere_z_offset])
sphere(r = dish_radius);
}
}
module drip_tray() {
// Fit tray to soap dish outer footprint
tray_inner_w = frame_width + (tray_tolerance * 2);
tray_inner_h = frame_height + (tray_tolerance * 2);
tray_inner_r = corner_radius + tray_tolerance;
tray_outer_w = tray_inner_w + (tray_wall_thickness * 2);
tray_outer_h = tray_inner_h + (tray_wall_thickness * 2);
tray_outer_r = tray_inner_r + tray_wall_thickness;
difference() {
// Outer tray body
rounded_square(tray_outer_w, tray_outer_h, tray_height, tray_outer_r);
// Inner cavity; shifted up to keep floor thickness
translate([0, 0, tray_wall_thickness])
rounded_square(tray_inner_w, tray_inner_h, tray_height, tray_inner_r);
}
}
module rounded_square(w, h, z, r) {
translate([-w / 2 + r, -h / 2 + r, 0])
hull() {
cylinder(h = z, r = r);
translate([w - 2 * r, 0, 0]) cylinder(h = z, r = r);
translate([0, h - 2 * r, 0]) cylinder(h = z, r = r);
translate([w - 2 * r, h - 2 * r, 0]) cylinder(h = z, r = r);
}
}
module honeycomb_grid(width, height, depth, r, wall) {
x_spacing = r * 1.5;
y_spacing = r * sqrt(3);
// Calculate number of cells needed to cover area
cols = ceil(width / x_spacing) + 1;
rows = ceil(height / y_spacing) + 1;
translate([0, 0, 0])
for (i = [-cols / 2 : cols / 2]) {
for (j = [-rows / 2 : rows / 2]) {
x_pos = i * x_spacing;
y_offset = (abs(i) % 2 == 1) ? y_spacing / 2 : 0;
y_pos = j * y_spacing + y_offset;
translate([x_pos, y_pos, 0])
difference() {
cylinder(h = depth, r = r, $fn = 6);
translate([0, 0, -0.5])
cylinder(h = depth + 1, r = r - wall, $fn = 6);
}
}
}
}