From 703fcb21d9e023550c608cbadec7317ed4f6855f Mon Sep 17 00:00:00 2001 From: Sam Hadow Date: Sun, 25 Oct 2026 00:39:33 +0200 Subject: [PATCH] weave planter: reach top and bottom --- flower_pot/weave_planter.scad | 63 +++++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 21 deletions(-) diff --git a/flower_pot/weave_planter.scad b/flower_pot/weave_planter.scad index 5163e21..a1ca099 100644 --- a/flower_pot/weave_planter.scad +++ b/flower_pot/weave_planter.scad @@ -4,6 +4,8 @@ // Reverse-engineered from "Planter - 100mm" and "Drip Tray - 100mm" STLs (https://www.printables.com/model/1507840-weave-planter). // // Outside: diagonal basket weave (two strip directions crossing over/under, 45 deg chamfered strip edges, dark diamond gaps between strips). +// The weave runs right up into the planter's rim bead and right down onto the tray's foot bead (no smooth neck +// in between); the ends that meet at the planter/tray joint keep their 45 deg run-out. // Lock: 4 lugs on the tray rim pass between 4 stops on the underside of the planter. Push the planter down onto the tray with the lugs in the gaps, then twist ~45 deg so every lug sits over a stop. // // Both parts print as modelled (flat side down, no supports): @@ -83,8 +85,15 @@ blk_z = lug_z0 + (R_rim_i - blk_r) - lock_c; // stop vertical land before the pocket_h = rim_h + 0.3; // slot ceiling inside the planter z_s = tray_h - rim_h; // tray shoulder height fe_p = max(floor_edge, pocket_h + 1.2); -planter_skin_z1 = planter_h - bead_h - neck_h; -tray_skin_z0 = bead_h + neck_h; +planter_skin_z1 = planter_h - bead_h - neck_h; // old end of the weave (only used when texture = false) +tray_skin_z0 = bead_h + neck_h; // old start of the weave; also the phase reference of the pattern + +// The weave runs right up into the ridges instead of stopping short of them: +// planter: ends inside the rim bead (the bead hides the cut) +// tray : starts inside the foot bead (the bead hides the cut) +foot_r = 0.7; // radius of the rounded foot bead +planter_weave_z1 = planter_h - bead_r; // bead is at full radius here +tray_weave_z0 = bead_h / 2; // foot bead is at full radius here assert(lug_tf >= 0.1, "rim_h too small for the lug: raise rim_h or lower lug_z0"); assert(blk_z + (blk_r - plug_r) < pocket_h - 0.5, "slot too shallow for the stops: raise rim_h"); @@ -145,27 +154,30 @@ function g_faces(a, dl, P, off) = g_q(a, dl + 1, P) ? [] : [[p01, p11, i11], [p01, i11, i01]], g_q(a - 1, dl + 1, P) ? [] : [[p00, p01, i01], [p00, i01, i00]]); -// Ring-shaped skin whose outer surface is the weave between z0 and z1, with the 45 deg run-out at both ends (trimmed by the envelope below). -module weave_skin(z0, z1) { +// Ring-shaped skin whose outer surface is the weave between z0 and z1. +// zref_in: height the weave pattern is anchored to (keeps the pattern phase when z0 moves); undef = anchor at z0 taper_lo/hi: true = 45 deg run-out at that end (free end, trimmed by the envelope below) false = weave is cut square; the end must be buried inside a ridge (bead) +module weave_skin(z0, z1, zref_in = undef, taper_lo = true, taper_hi = true) { + zref = is_undef(zref_in) ? z0 : zref_in; // (a default value cannot refer to another parameter) L = z1 - z0; M = nl * N; - ylo = -0.6 * cellx; - yhi = L + 0.6 * cellx; + ylo = z0 - zref - 0.6 * cellx; // mesh coverage, relative to zref + yhi = z1 - zref + 0.6 * cellx; dlo = floor((weave_zphase - yhi) * 2 * nl / cellx) - 3; dhi = ceil((weave_zphase - ylo) * 2 * nl / cellx) + 3; Dn = dhi - dlo + 1; P = [M, Dn, dlo, dhi, ylo, yhi]; off = M * Dn; - pts = concat([for (a = [0 : M - 1], dl = [dlo : dhi]) g_pt(a, dl, z0, false)], - [for (a = [0 : M - 1], dl = [dlo : dhi]) g_pt(a, dl, z0, true)]); + pts = concat([for (a = [0 : M - 1], dl = [dlo : dhi]) g_pt(a, dl, zref, false)], + [for (a = [0 : M - 1], dl = [dlo : dhi]) g_pt(a, dl, zref, true)]); fcs = [for (a = [0 : M - 1], dl = [dlo : dhi]) if (g_q(a, dl, P)) each g_faces(a, dl, P, off)]; Rbig = R_t + 0.6; k = Rbig - Rc; // 45 deg run-out - assert(L > 2 * k + 1, "weave zone too short"); + assert(L > (taper_lo ? k : 0) + (taper_hi ? k : 0) + 1, "weave zone too short"); + env = concat(taper_lo ? [[Rc - 1, 0], [Rc, 0], [Rbig, k]] : [[Rc - 1, 0], [Rbig, 0]], + taper_hi ? [[Rbig, L - k], [Rc, L], [Rc - 1, L]] : [[Rbig, L], [Rc - 1, L]]); intersection() { rotate([0, 0, weave_rot]) polyhedron(points = pts, faces = fcs, convexity = 10); - translate([0, 0, z0]) rotate_extrude($fn = fn_core) - polygon([[Rc - 1, 0], [Rc, 0], [Rbig, k], [Rbig, L - k], [Rc, L], [Rc - 1, L]]); + translate([0, 0, z0]) rotate_extrude($fn = fn_core) polygon(env); } } @@ -173,9 +185,14 @@ module weave_skin(z0, z1) { module planter_profile() { difference() { union() { - polygon([[0, 0], [wall_r, 0], [wall_r, planter_skin_z1 - 0.2], - [neck_r, planter_skin_z1 - 0.2], [neck_r, planter_h], - [R_in, planter_h], [R_in, fe_p], [0, floor_center]]); + // textured: the core wall continues straight up under the bead (no smooth neck), + // the weave skin covers it and runs into the bead + polygon(texture + ? [[0, 0], [wall_r, 0], [wall_r, planter_h], + [R_in, planter_h], [R_in, fe_p], [0, floor_center]] + : [[0, 0], [wall_r, 0], [wall_r, planter_skin_z1 - 0.2], + [neck_r, planter_skin_z1 - 0.2], [neck_r, planter_h], + [R_in, planter_h], [R_in, fe_p], [0, floor_center]]); // rim bead: round on top, 45 deg underneath (printable) cx = R - bead_r; cz = planter_h - bead_r; @@ -220,19 +237,23 @@ module planter() { } drain_holes(); } - if (texture) weave_skin(0, planter_skin_z1); + if (texture) weave_skin(0, planter_weave_z1, 0, true, false); // free end at the bottom, rim bead at the top } } // -------------------------------------------------------------------- tray --- module tray_profile() { union() { - polygon([[0, 0], [neck_r, 0], [neck_r, tray_skin_z0 + 0.2], - [wall_r, tray_skin_z0 + 0.2], [wall_r, z_s], - [R_rim_o, z_s], [R_rim_o, z_s + rim_h], [R_rim_i, z_s + rim_h], - [R_rim_i, tray_floor_edge], [0, tray_floor_center]]); + polygon(texture + ? [[0, 0], [wall_r, 0], [wall_r, z_s], // core wall runs straight down into the foot bead + [R_rim_o, z_s], [R_rim_o, z_s + rim_h], [R_rim_i, z_s + rim_h], + [R_rim_i, tray_floor_edge], [0, tray_floor_center]] + : [[0, 0], [neck_r, 0], [neck_r, tray_skin_z0 + 0.2], + [wall_r, tray_skin_z0 + 0.2], [wall_r, z_s], + [R_rim_o, z_s], [R_rim_o, z_s + rim_h], [R_rim_i, z_s + rim_h], + [R_rim_i, tray_floor_edge], [0, tray_floor_center]]); // rounded foot bead - r = 0.7; + r = foot_r; hull() { translate([R - r, r]) circle(r = r, $fn = 32); translate([R - r, bead_h - r]) circle(r = r, $fn = 32); @@ -257,7 +278,7 @@ module tray() { union() { rotate_extrude($fn = fn_core) tray_profile(); lock_lugs(); - if (texture) weave_skin(tray_skin_z0, z_s); + if (texture) weave_skin(tray_weave_z0, z_s, tray_skin_z0, false, true); // foot bead at the bottom, free end at the top } }