A snail shell is one of the few shapes in nature you can write down exactly: a tube that sweeps around a centre while growing by the same factor every turn. That is a logarithmic spiral, and it makes a lovely planter, because the last whorl is big enough to hold a small succulent.
The tricky part is not the spiral. It is getting a signed distance function for it, so it can be blended smoothly into a snail body and hollowed out. Here is how I did it in numpy.
1. The spiral
Pick how much the shell grows per turn (G = 1.9 here, so each whorl is 1.9x the one inside it). The radius of the tube's centre line is then R(θ) = A·e^(Bθ) with B = ln(G)/2π, and the tube's own radius is a fixed fraction of that:
G = 1.9; B = math.log(G)/(2*math.pi)
TMAX = 6*math.pi; RE = 40.0 # three turns, 40 mm at the opening
A = RE/math.exp(B*TMAX)
RT = 0.62 # tube radius / centre radius
2. Distance to a spiral tube
For a point in the shell's plane we know its angle phi around the centre. But that angle hits the spiral once per turn, so there are several candidate whorls the point could belong to. The fix is to just try each turn and keep the closest:
rho = np.hypot(x, z); phi = np.arctan2(z, x)
base = np.mod(PHI_END - phi, 2*math.pi)
out = np.full(X.shape, 1e9)
for k in range(4):
psi = base + 2*math.pi*k # angle back from the opening, turn k
th = TMAX - psi
R = A*np.exp(B*th); r = RT*R
dc = np.sqrt((rho - R)**2 + Y**2) # distance to that whorl's centre line
out = np.where(th > 0.8, np.minimum(out, dc - r), out)
It is not an exact distance (the tube's centre line curves), but it is close enough for meshing on a 0.6 mm grid, and every operation is vectorised.
3. Growth lines for free
Since psi already tells us how far along the shell we are, growth lines across the whorls are a one-liner. Add a small ridge to the distance, scaled down on the tiny inner whorls:
ridge = 0.35*np.sin(psi*26)*np.clip(r/12, 0, 1)
out = np.minimum(out, dc - r + ridge)
4. Hollow only the last whorl
For the soil pocket, the same loop computes a second, thinner tube (r - WALL), but only for the final turn. Subtracting it hollows the last whorl and leaves the inner coils solid, which keeps the print strong and saves soil:
inner = (psi > 0.35) & (psi < 2*math.pi + 0.6)
hol = np.where(inner & ok, np.minimum(hol, dc - (r - WALL)), hol)
5. The snail
The body is a handful of tapered capsules joined with a smooth minimum (smin): a wide flat foot, a raised head, eye stalks with eyes, lower feelers, and a small mouth slit cut in. A low sine pattern on the head gives wrinkled skin. The shell is smin-ed onto the foot with a 5 mm blend so it looks grown together, not glued on.
d = smin(shell_dist, body_dist, 5)
d = np.maximum(d, -hollow)
The final mesh is cut flat at z = 0, and a round opening is cut into the top of the last whorl for the plant.
Result
One piece, prints upright on the foot without supports on most printers. It fits a small succulent, air plant or cactus cutting.
The STL is on Cults3D: Snail Shell Succulent Planter.
Other designs and early access: patreon.com/123black

Top comments (2)
Hollowing only the last whorl is a neat constraint, because it keeps the inner coils solid while still giving the plant room. Did you choose the wall thickness mainly for print strength, or to leave enough soil depth for a succulent?
Mostly print strength. 3 mm walls stay solid without extra perimeters, and the last whorl still leaves plenty of soil room for a small succulent. There's no drain hole, so water lightly or use it as a cachepot.