123 lines
3.8 KiB
OpenSCAD
123 lines
3.8 KiB
OpenSCAD
// ========================================================
|
|
// PARAMETRIC SEEDLING TRAY & PUSHABLE PLATES
|
|
// ========================================================
|
|
|
|
/* [Grid Configuration] */
|
|
cols = 3; // Number of columns
|
|
rows = 2; // Number of rows
|
|
cell_size = 35; // Inner width/length of each square cell (mm)
|
|
tray_height = 50; // Total height of the tray (mm)
|
|
|
|
/* [Wall & Ledge Dimensions] */
|
|
wall_thickness = 1.6; // Thickness of the walls (mm)
|
|
bottom_lip = 4.0; // Width of the bottom ledge holding the plate (mm)
|
|
floor_thickness = 2.0; // Thickness of the bottom lip (mm)
|
|
|
|
/* [Pusher Plate Settings] */
|
|
plate_thickness = 2.0; // Thickness of the pushable plate (mm)
|
|
clearance = 0.4; // Gap between cell walls and plate for easy sliding (mm)
|
|
drain_hole_dia = 4.5; // Diameter of drainage holes in the pushable plate (mm)
|
|
|
|
/* [Render Mode] */
|
|
// ["both_layout", "assembled", "tray_only", "plates_only"]
|
|
render_mode = "both_layout";
|
|
|
|
|
|
|
|
// --- DERIVED CALCULATIONS ---
|
|
pitch = cell_size + wall_thickness;
|
|
total_width = cols * pitch + wall_thickness;
|
|
total_length = rows * pitch + wall_thickness;
|
|
|
|
|
|
// --- MAIN DISPLAY ---
|
|
if (render_mode == "tray_only") {
|
|
seedling_tray();
|
|
} else if (render_mode == "plates_only") {
|
|
plate_grid();
|
|
} else if (render_mode == "both_layout") {
|
|
seedling_tray();
|
|
translate([0, total_length + 10, 0])
|
|
plate_grid();
|
|
} else if (render_mode == "assembled") {
|
|
// Visual preview
|
|
seedling_tray();
|
|
for (r = [0 : rows - 1]) {
|
|
for (c = [0 : cols - 1]) {
|
|
translate([
|
|
wall_thickness + c * pitch + clearance/2,
|
|
wall_thickness + r * pitch + clearance/2,
|
|
floor_thickness
|
|
])
|
|
pusher_plate();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// ========================================================
|
|
// MODULES
|
|
// ========================================================
|
|
|
|
// Main seedling tray body
|
|
module seedling_tray() {
|
|
difference() {
|
|
// Outer solid volume
|
|
cube([total_width, total_length, tray_height]);
|
|
|
|
// Cut out each cell pocket and bottom push hole
|
|
for (r = [0 : rows - 1]) {
|
|
for (c = [0 : cols - 1]) {
|
|
x_pos = wall_thickness + c * pitch;
|
|
y_pos = wall_thickness + r * pitch;
|
|
|
|
// 1. Main cell compartment
|
|
translate([x_pos, y_pos, floor_thickness])
|
|
cube([cell_size, cell_size, tray_height]);
|
|
|
|
// 2. Bottom push-through opening
|
|
translate([x_pos + bottom_lip, y_pos + bottom_lip, -1])
|
|
cube([
|
|
cell_size - (2 * bottom_lip),
|
|
cell_size - (2 * bottom_lip),
|
|
floor_thickness + 2
|
|
]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Single pushable bottom plate
|
|
module pusher_plate() {
|
|
p_size = cell_size - clearance;
|
|
offset_margin = p_size / 3.5;
|
|
|
|
difference() {
|
|
// Plate body
|
|
cube([p_size, p_size, plate_thickness]);
|
|
|
|
// 5-points drainage hole pattern
|
|
translate([p_size / 2, p_size / 2, -1])
|
|
cylinder(h = plate_thickness + 2, d = drain_hole_dia, $fn = 20);
|
|
|
|
for (dx = [offset_margin, p_size - offset_margin]) {
|
|
for (dy = [offset_margin, p_size - offset_margin]) {
|
|
translate([dx, dy, -1])
|
|
cylinder(h = plate_thickness + 2, d = drain_hole_dia, $fn = 20);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Plate grid
|
|
module plate_grid() {
|
|
p_size = cell_size - clearance;
|
|
spacing = 2;
|
|
|
|
for (r = [0 : rows - 1]) {
|
|
for (c = [0 : cols - 1]) {
|
|
translate([c * (p_size + spacing), r * (p_size + spacing), 0])
|
|
pusher_plate();
|
|
}
|
|
}
|
|
} |