Interactive Preview & Customizer
3D preview with OpenSCAD rendering on parameter changes.
Loading preview...
step 1
step 1
step 1
step 1
step 0.5
step 0.1
step 0.2
step 0.2
step 1
step 1
step 0.1
step 0.05
step 0.05
step 1
step 0.05
step 0.1
step 1
step 1
step 1
step 0.5
WASM compiler loads on first parameter change.
Screenshots
Prompt
create parametric desktop organizer with drawer and tray.
OpenSCAD Code
// Parametric Desktop Organizer
// Overall: 178mm width x 155mm depth x 125mm height
// Smart Zero-Bridge Design: Drop-in upper tray on self-supporting 50° angled ledges with flat top and snug fit
/* [Overall Dimensions] */
total_width = 178; // [120:1:250]
total_depth = 155; // [100:1:220]
height_back = 125; // [80:1:180]
height_front = 38; // [25:1:60]
corner_chamfer = 4; // [1:0.5:10]
base_chamfer = 1; // [0.4:0.1:2.0]
wall_th = 1.2; // [0.8:0.2:2.4]
floor_th = 1.2; // [0.8:0.2:2.4]
/* [Compartment Layout] */
back_slot_depth = 34; // [20:1:60]
drawer_height = 36; // [25:1:60]
drawer_clearance = 0.5; // [0.2:0.1:1.0]
tray_clearance = 0.25; // [0.05:0.05:0.6] Snug drop-in fit clearance
split_ratio_x = 0.5; // [0.3:0.05:0.7]
front_bin_depth = 52; // [30:1:80]
curve_power = 0.55; // [0.3:0.05:1.2]
/* [Shelf Ledge Settings] */
ledge_width = 3; // [1.5:0.1:4.0]
ledge_angle = 50; // [40:1:60]
/* [Print / Display Mode] */
part = "assembly"; // [assembly:Full Assembly, body:Organizer Body Only, drawer:Drawer Only, upper_tray:Upper Drop-in Tray Only, print_plate:Print Layout]
drawer_pull_out = 21; // [0:1:80]
tray_exploded_z = 0; // [0:1:80]
$fn = 40;
// Calculated internal dimensions
inner_w_total = total_width - 2 * wall_th;
usable_w = inner_w_total - wall_th;
left_w = usable_w * split_ratio_x;
right_w = usable_w * (1 - split_ratio_x);
front_area_d = total_depth - 2 * wall_th - back_slot_depth - wall_th;
mid_depth = front_area_d - front_bin_depth - wall_th;
// Exact inner chamfer coordinate offset for rear corners
c_inner = corner_chamfer + wall_th * (sqrt(2) - 1);
// Ledge vertical height derived from width and overhang angle (50° from horizontal)
ledge_h = ledge_width * tan(ledge_angle);
// Ledge starts cleanly above drawer space
shelf_bottom_z = floor_th + drawer_height;
shelf_top_z = shelf_bottom_z + ledge_h;
// 2D Outer footprint: chamfered only at the back corners, clean square front
module organizer_footprint_2d(w, d, c) {
polygon([
[0, 0],
[w, 0],
[w, d - c],
[w - c, d],
[c, d],
[0, d - c]
]);
}
// Side height curve: flat over the rear document slot, then smooth convex curve down to front
function get_side_height(y) =
let(
curve_start_y = total_depth - wall_th - back_slot_depth,
yn = max(0, min(1, y / curve_start_y)),
t = pow(yn, curve_power)
)
(y >= curve_start_y) ? height_back : height_front + (height_back - height_front) * t;
// 3D side profile cutting mask
module top_cut_mask() {
steps = 60;
dy = total_depth / steps;
poly_pts = concat(
[[ -5, height_back + 30 ], [ total_depth + 5, height_back + 30 ]],
[for (i = [steps:-1:0])
let(y = i * dy, h = get_side_height(y))
[y, h]
],
[[ -5, height_front ]]
);
translate([-10, 0, 0])
rotate([90, 0, 90])
linear_extrude(height = total_width + 20)
polygon(poly_pts);
}
// Bottom perimeter chamfer cutting tool
module base_chamfer_cut(w, d, c, bc) {
if (bc > 0) {
difference() {
translate([-5, -5, -2])
cube([w + 10, d + 10, bc + 2]);
hull() {
translate([0, 0, -1])
linear_extrude(height = 1.01)
offset(delta = -bc)
organizer_footprint_2d(w, d, c);
translate([0, 0, bc])
linear_extrude(height = 0.01)
organizer_footprint_2d(w, d, c);
}
}
}
}
// Finger notch cutout (for drawer pull)
module finger_notch(w=28, d=15, th=10) {
rotate([-90, 0, 0])
hull() {
translate([-w/2 + 6, 0, -th/2]) cylinder(r=6, h=th);
translate([w/2 - 6, 0, -th/2]) cylinder(r=6, h=th);
translate([0, -d, -th/2]) cylinder(r=4, h=th);
}
}
// Support-free 50-degree wedge prism (flat top, 50° slope underneath)
module shelf_wedge(w, h, len) {
translate([0, len, 0])
rotate([90, 0, 0])
linear_extrude(height = len)
polygon([
[0, 0],
[0, h],
[w, h]
]);
}
// Solid 3D self-supporting shelf ledges inside left tunnel:
// 50° bottom slope for support-free 3D printing, flat top shelf for drop-in tray
module solid_shelf_ledges() {
ov = 0.4; // Wall overlap to ensure robust manifold union
y_start = wall_th;
y_end = wall_th + front_area_d;
// Left ledge: attached to outer left wall (slopes up-inward towards +X)
translate([wall_th - ov, y_start, shelf_bottom_z])
shelf_wedge(ledge_width + ov, ledge_h, front_area_d);
// Right ledge: attached to middle divider wall (slopes up-inward towards -X)
translate([wall_th + left_w + ov, y_start, shelf_bottom_z])
mirror([1, 0, 0])
shelf_wedge(ledge_width + ov, ledge_h, front_area_d);
// Back ledge: attached to rear divider wall (slopes up-inward towards -Y)
translate([wall_th, y_end + ov, shelf_bottom_z])
rotate([0, 0, -90])
shelf_wedge(ledge_width + ov, ledge_h, left_w);
}
// Main Organizer Body
module organizer_body() {
union() {
difference() {
// Outer solid footprint extruded to back height
linear_extrude(height = height_back)
organizer_footprint_2d(total_width, total_depth, corner_chamfer);
// Base 45-degree chamfer
base_chamfer_cut(total_width, total_depth, corner_chamfer, base_chamfer);
// Top slope convex curve cut
top_cut_mask();
// 1. REAR DOCUMENT / MAIL SLOT
translate([0, 0, floor_th])
linear_extrude(height = height_back + 10)
polygon([
[wall_th, total_depth - wall_th - back_slot_depth],
[total_width - wall_th, total_depth - wall_th - back_slot_depth],
[total_width - wall_th, total_depth - c_inner],
[total_width - c_inner, total_depth - wall_th],
[c_inner, total_depth - wall_th],
[wall_th, total_depth - c_inner]
]);
// 2. LEFT SIDE: FULL OPEN TUNNEL
translate([wall_th, -2, floor_th])
cube([left_w, front_area_d + wall_th + 2, height_back + 10]);
// 3. RIGHT SIDE: FRONT NOTEPAD BIN
translate([wall_th + left_w + wall_th, wall_th, floor_th])
cube([right_w, front_bin_depth, height_back + 10]);
// 4. RIGHT SIDE: REAR PEN CUPS (2 side-by-side cups)
pen_w = (right_w - wall_th) / 2;
translate([wall_th + left_w + wall_th, wall_th + front_bin_depth + wall_th, floor_th])
cube([pen_w, mid_depth, height_back + 10]);
translate([wall_th + left_w + wall_th + pen_w + wall_th, wall_th + front_bin_depth + wall_th, floor_th])
cube([pen_w, mid_depth, height_back + 10]);
}
// Fused self-supporting 50° shelf ledges
solid_shelf_ledges();
}
}
// Pull-out Drawer
module drawer() {
dr_w = left_w - 2 * drawer_clearance;
dr_d = front_area_d + wall_th - drawer_clearance;
dr_h = drawer_height - drawer_clearance;
dr_bc = min(base_chamfer, 0.8);
difference() {
cube([dr_w, dr_d, dr_h]);
if (dr_bc > 0) {
difference() {
translate([-2, -2, -1])
cube([dr_w + 4, dr_d + 4, dr_bc + 1]);
hull() {
translate([dr_bc, dr_bc, -1.01])
cube([dr_w - 2 * dr_bc, dr_d - 2 * dr_bc, 0.01]);
translate([0, 0, dr_bc])
cube([dr_w, dr_d, 0.01]);
}
}
}
translate([wall_th, wall_th, floor_th])
cube([dr_w - 2 * wall_th, dr_d - 2 * wall_th, dr_h + 1]);
translate([dr_w / 2, 0, dr_h])
finger_notch(w=28, d=15, th=wall_th * 6);
}
}
// Drop-in Upper Tray (rests neatly on the internal 50° ledges with a snug fit)
module upper_tray() {
tray_w = left_w - 2 * tray_clearance;
tray_d = front_area_d - tray_clearance;
tray_max_h = height_back - shelf_top_z;
difference() {
// Outer solid block
cube([tray_w, tray_d, tray_max_h]);
// Match the top curved cut
translate([-wall_th, -wall_th, -shelf_top_z])
top_cut_mask();
// Front compartment
translate([wall_th, wall_th, floor_th])
cube([tray_w - 2 * wall_th, front_bin_depth - wall_th, height_back]);
// Rear compartment
translate([wall_th, front_bin_depth + wall_th, floor_th])
cube([tray_w - 2 * wall_th, mid_depth - wall_th, height_back]);
}
}
// Assemble / Render
if (part == "assembly") {
organizer_body();
// Position drawer
translate([wall_th + drawer_clearance, -drawer_pull_out, floor_th])
drawer();
// Position upper tray with snug alignment
translate([wall_th + tray_clearance, wall_th + tray_clearance/2, shelf_top_z + tray_exploded_z])
upper_tray();
} else if (part == "body") {
organizer_body();
} else if (part == "drawer") {
drawer();
} else if (part == "upper_tray") {
upper_tray();
} else if (part == "print_plate") {
// Print layout: all 3 parts oriented for support-free printing
organizer_body();
translate([total_width + 10, 0, 0])
drawer();
translate([total_width + 10, front_area_d + 15, 0])
upper_tray();
}


