Working well

Performance

Rhea is fast because its core never loops over geometry in Python. Here is what that buys you in numbers, and what to do when you ask for more than it can give.

The targets

These are acceptance criteria the toolkit is tested against, measured on a mid-range CPU, single-threaded, with nothing installed beyond Blender.

Tessellate — 10k faces, ~1M verts out
≤ 2.0 s
Tessellate preview quality
≤ 150 ms
Conway dkD on 5,000 faces
≤ 1.0 s
Curvature field, 100,000 verts
≤ 400 ms
AO field, 64 samples, 50k verts
≤ 3.0 s
Animated rebuild, 5,000 faces
≤ 100 ms
Add-on registration, cold start
≤ 120 ms

The animated rebuild figure is the one that matters most in practice: it is what makes timeline scrubbing possible rather than a render-only trick.

Why it holds

  • No Python loops over geometry. Nothing in a compute path iterates vertices or faces. Loops are over operators or iterations only.
  • One read, one write. Mesh data moves in and out as flat preallocated arrays, never element by element.
  • Preallocated, never appended. No array is grown inside a loop.
  • Cached spatial structures. BVH and KD-trees are keyed by source hash and rebuilt only when the hash changes.
  • Lazy imports. Heavy modules load inside operators, not at registration, so Blender starts fast.

The practical consequence is that Rhea does not degrade gracefully as counts rise — it stays fast until it runs out of memory. That is usually what you want, but it means the failure mode is abrupt rather than gradual.

The vertex budget

Every operation projects its output size before running. Above the budget — four million vertices by default — it refuses with a message naming the number rather than attempting it.

  base faces  ×  component verts  =  output verts

     10,000  ×      100           =    1,000,000   fine
     10,000  ×    1,000           =   10,000,000   refused
    100,000  ×      100           =   10,000,000   refused

This is a guard rail, not a limit on ambition. Raise it in preferences if you have the RAM and know what you are asking for. But read the multiplication first: the number that surprises people is almost always the component vertex count, not the base face count.

Iteration is geometric

Tessellate iterations feed each pass into the next. Two passes of a forty-vertex component on three hundred faces is six hundred thousand vertices; three passes is twenty-four million. Start from a face count that looks almost too sparse.

What costs what

Roughly, cheapest first

Instant
Cavity field, gradient, slope, noise, formula, dual mesh, rotate faces and edges, fan subdivide.
Fast
Curvature, live effects, Conway chains on small seeds, Lloyd relaxation, tris to quads.
Noticeable
Tessellation at real densities, adaptive subdivide, Voronoi, geodesic distance, proximity.
Slow, and worth it
Ambient occlusion at high sample counts, thickness, reaction-diffusion, differential growth, form finding, long Conway chains.

When you exceed it

Work coarse, finish fine

Develop everything at a low face count. Pattern scale relative to the surface is roughly preserved, so what you tune transfers when you raise the density. This single habit is worth more than every other optimisation here combined.

Simplify the component

Component vertex count multiplies. A component at four hundred vertices that could be a hundred is four times the output for no visible gain at the scale it will be seen. Decimate it, or model it more carefully.

Cover less, not smaller

Lowering Coverage reduces the copy count directly. Raising density and shrinking the component gives you the same visual density at several times the cost.

Cheap field, then expensive field

Use Cavity while iterating and switch to Ambient occlusion once the look is settled. They read similarly and one is instant. Similarly, lower the AO sample count while working — thirty-two is fine to judge by, sixty-four for the final.

Apply what you have finished deciding

A live stack re-evaluates. Once a layer is settled, apply it and continue on plain geometry. Duplicate first if you might want the recipe back.

Use symmetry

A mirrored half evaluates one field, one pattern, one solve, then duplicates. For a symmetric design that is close to half the cost.

Viewport, not compute

Sometimes the slowness is display rather than calculation. Check these before optimising the wrong thing:

  • Overlays. They are budgeted and culled, but not free on a multi-million-vertex mesh. Turn them off, or switch away from the Rhea tab, which stops them drawing entirely.
  • Wireframe and statistics overlays. Blender's own, and expensive at high counts.
  • Subdivision preview levels. Set viewport levels below render levels.
  • Component objects still visible. Use Hide sources after tessellating.

Anything over roughly two hundred milliseconds runs modally: a percentage in the status bar, a progress cursor, and Esc to cancel. Cancelling restores the pre-run state rather than leaving you halfway through something.

Blender itself stays responsive throughout — no step blocks the UI for more than about a tenth of a second. If Blender genuinely freezes during a Rhea operation, that is a bug worth reporting, not expected behaviour.

Memory

Four million vertices with positions, normals, UVs and attributes is on the order of a gigabyte before Blender's own overhead. If you are working near the budget:

  • Close other .blend files — Blender shares one process and one heap.
  • Purge orphaned data (File → Clean Up → Recursive Unused Datablocks). Rhea does not leave orphans, but an exploratory session accumulates them from everything else.
  • Save and reopen. Blender's memory does not always return after a large operation, and a restart is faster than fighting it.