← Back to Models
Desktop Organizer with Drawer

Desktop Organizer with Drawer

by Mach3 ·

Interactive Preview & Customizer

3D preview with OpenSCAD rendering on parameter changes.

Loading previewLoading 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.
Download

Screenshots

Model screenshot

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();
}

Download Model

Choose the model version and file format.

Model version