$fn = 64; // --- Parametric Dimensions (in mm) --- trellis_width = 140; // Overall width of the trellis trellis_height = 160; // Height of the rectangular section (arch adds to this) grid_spacing = 28; // Distance between grid lines bar_thickness = 4; // Z-height/thickness (ideal for fast flat printing) bar_width = 6; // Width of the individual structural bars stake_length = 80; // Length of the ground/pot insertion stakes // --- Main Assembly --- union() { outer_frame(); // Inner grid constrained exactly to the trellis boundary intersection() { grid(); trellis_boundary(); } stakes(); } // --- Modules --- // Solid shape representing the entire boundary of the trellis (used for intersection) module trellis_boundary() { union() { translate([-trellis_width/2, 0, 0]) cube([trellis_width, trellis_height, bar_thickness]); translate([0, trellis_height, 0]) cylinder(h=bar_thickness, d=trellis_width); } } // The thick outer border of the trellis module outer_frame() { union() { // Left vertical side translate([-trellis_width/2, 0, 0]) cube([bar_width, trellis_height, bar_thickness]); // Right vertical side translate([trellis_width/2 - bar_width, 0, 0]) cube([bar_width, trellis_height, bar_thickness]); // Bottom horizontal base translate([-trellis_width/2, 0, 0]) cube([trellis_width, bar_width, bar_thickness]); // Top Arch translate([0, trellis_height, 0]) difference() { cylinder(h=bar_thickness, d=trellis_width); // Hollow out the center of the arch translate([0, 0, -1]) cylinder(h=bar_thickness + 2, d=trellis_width - 2*bar_width); // Remove the bottom half of the arch to make it a semi-circle translate([-trellis_width/2 - 1, -trellis_width/2 - 1, -1]) cube([trellis_width + 2, trellis_width/2 + 1, bar_thickness + 2]); } } } // The internal intersecting lattice module grid() { union() { // Vertical bars for(x = [-trellis_width/2 + grid_spacing : grid_spacing : trellis_width/2 - 1]) { translate([x - bar_width/2, 0, 0]) cube([bar_width, trellis_height + trellis_width/2, bar_thickness]); } // Horizontal bars for(y = [grid_spacing : grid_spacing : trellis_height + trellis_width/2 - 1]) { translate([-trellis_width/2, y - bar_width/2, 0]) cube([trellis_width, bar_width, bar_thickness]); } } } // Ground insertion stakes at the bottom module stakes() { union() { // Left stake body translate([-trellis_width/2, -stake_length, 0]) cube([bar_width, stake_length, bar_thickness]); // Left stake tip translate([-trellis_width/2, -stake_length - bar_width*1.5, 0]) linear_extrude(height=bar_thickness) polygon([[0, bar_width*1.5], [bar_width, bar_width*1.5], [bar_width/2, 0]]); // Right stake body translate([trellis_width/2 - bar_width, -stake_length, 0]) cube([bar_width, stake_length, bar_thickness]); // Right stake tip translate([trellis_width/2 - bar_width, -stake_length - bar_width*1.5, 0]) linear_extrude(height=bar_thickness) polygon([[0, bar_width*1.5], [bar_width, bar_width*1.5], [bar_width/2, 0]]); } }