Organic shapes are where CAD gets painful. A brain coral, a staghorn branch and a starfish all grown into one piece would take hours of sculpting. With signed distance functions it is about 70 lines of numpy, and every part blends into its neighbours automatically.
This is the generator behind my coral reef desk organizer: a brain-coral dome, three organ-pipe tubes for pens, staghorn branches for clips and rings, and a starfish.
1. Two helpers
Everything is built from a smooth minimum and a tapered capsule (a line segment with a radius that changes along it):
def smin(a, b, k):
h = np.clip(0.5 + 0.5*(b - a)/k, 0, 1)
return b*(1 - h) + a*h - k*h*(1 - h)
def cap(X, Y, Z, a, b, ra, rb):
a = np.array(a, float); b = np.array(b, float); ba = b - a
px, py, pz = X - a[0], Y - a[1], Z - a[2]
h = np.clip((px*ba[0] + py*ba[1] + pz*ba[2]) / (ba @ ba), 0, 1)
return np.sqrt((px - ba[0]*h)**2 + (py - ba[1]*h)**2 + (pz - ba[2]*h)**2) - (ra + (rb - ra)*h)
smin with a larger k gives a fatter fillet. That one number is how the tubes look grown out of the dome instead of stuck on.
2. Brain coral: domain-warped sine valleys
The dome is a squashed ellipsoid. The maze pattern on top is two sine waves, each with its input bent by another sine (domain warping). Where their sum is near zero, a gaussian pushes the surface in, which carves a valley:
d = (np.sqrt((X/52)**2 + (Y/42)**2 + (Z/30)**2) - 1)*30
v = np.sin(0.62*X + 2.4*np.sin(0.15*Y + 0.11*Z)) \
+ np.sin(0.62*Y + 2.4*np.sin(0.16*X - 0.1*Z))
d += 1.7*np.exp(-(v/0.5)**2)*np.clip(Z/6, 0, 1)
Without the inner sines you get a regular grid of bumps. With them, the zero line wanders and splits, and it reads as the meanders of a real brain coral. The clip(Z/6) fades the valleys out near the base so the footprint stays flat.
3. Organ-pipe tubes
Each pen cup is a capsule from the floor up, with a slight taper and a sine ripple on its radius for growth rings. The ripple starts above 12 mm so it does not fight the blend into the dome:
t = cap(X, Y, Z, (x, y, 0), (x, y, h - r*0.3), r, r*0.92) \
+ 0.45*np.sin(Z*1.1)*np.clip((Z - 12)/6, 0, 1)
d = smin(d, t, 6)
Real organ-pipe coral has horizontal plates tying the tubes together, so every pair of tubes also gets a thin capsule "web" between them at about half height. Those webs also make the cups much stiffer.
4. Staghorn: a recursive branch list
The staghorn is not an SDF at first. It is a list of capsules made by a small recursive grower. Each branch splits into two, turned left and right around an axis perpendicular to the branch, a bit shorter and thinner each time:
def grow(p, d, r, depth):
q = p + d*rng.uniform(9, 14)*(0.85**(3 - depth))
out.append((p.copy(), q.copy(), r, r*0.8))
if depth == 0: return
for s in (-1, 1):
ax = np.cross(d, [0, 0, 1]); ax /= np.linalg.norm(ax)
ang = s*rng.uniform(0.35, 0.6)
nd = d*math.cos(ang) + np.cross(ax, d)*math.sin(ang)
nd[2] = max(nd[2], 0.35); nd /= np.linalg.norm(nd)
grow(q, nd, r*0.8, depth - 1)
The nd[2] = max(nd[2], 0.35) line keeps every branch pointing upward at a printable angle, so the whole organizer prints with no supports. Three roots, three levels deep, give 45 capsules, all smin-ed in with a small k.
5. Starfish on a slope
The starfish sits on the curved dome, so its arms are built in a local frame: the dome's surface normal at that point, plus two tangent vectors. Five tapered capsules in that frame, with the normal axis squashed to make them flat, and a checker of small bumps on top for the skin.
6. Mesh it
The whole field is meshed on a 0.55 mm grid. Then plain manifold booleans do the precise parts: cut flat at z = 0 and drill clean 13 mm bores down each tube.
m = grid_level_set(lambda X, Y, Z: -reef(X, Y, Z), bounds, 0.55)
for x, y, h, r in TUBES:
m = m - Mf.cylinder(h, BORE, BORE, 48).translate([x, y, 5])
Mixing the two is the trick: SDFs for anything organic, exact solids for anything that has to fit something (a pen, the print bed).
Result
One piece, about 120 mm wide and 92 mm tall, no supports. Pens go in the tubes, paper clips and rings hang on the staghorn.
The STL is on Cults3D: Coral Reef Desk Organizer.
Other designs and early access: patreon.com/123black

Top comments (0)