DANIEL ARIAS // STARQUIXOTE

Extending ZBrush with Python: one plugin shipped, one experiment closed

// The question

ZBrush is where I spend my working day, and it has never had the one small thing I kept wanting: a persistent color swatch palette. ZBrush 2026 shipped a new Python SDK. Could an AI agent and I use it to build tools I'd actually keep — and while we were at it, find out where the SDK's real ceiling is?

// What I learned

The SDK is a UI automation layer, not an engine API — it can build palettes, buttons and sliders and press ZBrush's own controls, but it cannot create brushes, touch geometry, or read the canvas. Knowing exactly where that ceiling is turned out to be worth as much as the plugin itself: one idea shipped because it lived below the ceiling, the other closed because it lived above it.

// Why it stopped here

Zswatches shipped and stays: a swatch palette that survives restarts, captures colors without the keyboard, and rebuilds its own UI live. ZSelect Lab — synthetic strokes driving selection and slicing with custom shapes — worked, but the spline resolution of the slice brush made the cuts wobble, and I closed it with the findings written down rather than forcing it.

The itch

Sculptors live inside color and selection workflows all day, and ZBrush's interface is famously its own universe — extending it has historically meant ZScript, a scripting dialect from another era. ZBrush 2026 added a Python SDK. That reframes the question: my main tool suddenly speaks a language the AI is fluent in.

We tried ZScript first anyway. It failed silently at every turn — scripts that wouldn't compile, loads that produced no error and no result. The autopsy of why it failed became the map for the Python port, and that same afternoon the Python version was alive.

Zswatches: the one that shipped

A swatch palette under its own Zplugin menu: a grid of color swatches, an Edit switch that captures the current color with a click (no keyboard), sliders for swatch count and size, everything persisted to JSON so the palette survives restarts, and the whole panel rebuilt live when it changes — something the old ZScript world simply couldn't do.

It went through eight versions in a day, and the most useful moment was a rollback. I asked for a full color-mixing section — RGB sliders, copy/paste, a picker. We built it, and then established that ZBrush's native color picker is a core widget the SDK cannot fabricate: the SDK makes buttons, sliders and switches, and nothing else. A color panel without a picker is a worse version of the palette ZBrush already has. So v1.8 was archived and the shipping version is v1.5.1 — the feature set that earns its screen space, plus cleanup code so the abandoned era leaves no debris behind.

That decision — knowing what not to keep — is the part I'd show another sculptor.

ZSelect Lab: the one I closed

The second experiment asked something greedier: could scripted strokes give ZBrush selection and slicing with custom shapes — a star, a triangle — instead of freehand lasso? The mechanism worked, and getting there meant crawling under the SDK's floorboards: recording a real stroke, decoding its hex coordinate format, generating synthetic strokes of any shape, and injecting the modifier keys at the Windows level because the SDK's own key-press function is documented as broken.

With the slice brush active, a scripted star genuinely cut polygroups into the mesh. But the slice tool interprets strokes as splines: feed it a hundred dense points and the edge comes out wavering, not crisp. The workaround ideas exist and are written down — sparse anchor points at the corners, a masking route, importing shapes from Illustrator — but the honest reading was that I'd be fighting the tool's nature.

Closed, not failed. The findings file is the deliverable: the stroke format, the keyboard injection recipe, what the slice brush does to dense point runs. If Maxon ever opens the floor below the UI layer, the lab reopens in an afternoon.

The ceiling, stated plainly

For anyone considering the ZBrush 2026 Python SDK: it automates the interface, not the engine. No new brush types, no direct geometry edits, no mask buffers, no timers or events — and at least one advertised function that doesn't work. Below that ceiling you can build real, persistent, daily-use tools. Above it, you're synthesizing input events and negotiating with physics. Both of these projects were worth doing; only one of them was worth keeping.

← Back to log