Nodes/aioli-nodes/✂️ Mask Split Regions (manual multi)
ComfyUI Node

✂️ Mask Split Regions (manual multi)

Just paint, and let it split

By aiolicollective·Created 6 months ago·Updated 2 months ago· 0
✂️ Mask Split Regions (manual multi)
  • mask
  • masks
  • count
threshold0.50
min_area64
sort_by

SAM3 multi-region editing is genuinely powerful: a segmentation model finds each object, and every region gets its own prompt and its own inpaint pass. The catch is it needs the SAM3 model, its keywords, and a chunk of VRAM. If you just want the same "different prompt per area" workflow with none of that, paint your regions by hand - then let this node sort them out.

MaskSplitRegions takes one hand-drawn mask and splits it into N separate masks, one per disconnected blob, using connected-component labelling. Paint a few blobs over the objects you want to edit, this turns each blob into its own full-size mask, and from there it drops into the same per-region machinery the SAM3 path uses - each region gets its own bbox, crop and prompt. No segmentation model, no keywords. For a single blob it just returns one mask, identical to a normal single-region inpaint, so there's no harm in always running it.

How it works

The painted mask is binarised at threshold (default 0.5), then scipy.ndimage finds connected components - that's all it is under the hood. Each connected blob becomes one output mask, positioned on the full canvas, black everywhere else. Two internals are fixed in the code rather than exposed as widgets: connectivity = 8 (diagonal neighbours count as connected, correct for virtually all hand-drawn masks) and merge_distance = 0 (strokes are never merged). Both are one-line edits in mask_split_regions.py if you ever need to change them.

The output is a list, which is the whole point: it feeds MaskBoundingBox+ and the rest of the multi-region pipeline directly, where each mask gets its own crop and coordinates.

Inputs and outputs

Only three widgets, and they're the three you'd actually fiddle with:

  • threshold - binarisation cutoff for the drawn mask, default 0.5.
  • min_area - ignore blobs smaller than this many pixels. Default 64, and this is your anti-stray-dot dial: a tiny fleck of brush opacity becomes a "region" that gets its own crop and prompt otherwise.
  • sort_by - output order: area_desc (largest first, the default), area_asc, top_to_bottom, left_to_right. The order you get here is the layering order downstream, so it's worth setting deliberately.

Outputs: masks (the list) and count, so you can see how many regions you actually got.

Installing it

Ships in the Aioli Nodes pack. ComfyUI Manager → search "Aioli Nodes", or:

cd ComfyUI/custom_nodes
git clone https://github.com/aiolicollective/aioli-nodes

Restart ComfyUI; it shows up under Aioli Nodes. Its one real dependency, scipy, is already bundled with ComfyUI - no install step, no requirements.txt.

Where people get tripped up

The classic moment: you paint two blobs that were supposed to be separate regions, but they touch at a corner, and with 8-connectivity that's one region. If you hit it, the fix is editing connectivity = 4 in the source so only side-by-side pixels merge. The more common annoyance is stray specks becoming full "regions" - raise min_area and they vanish. And remember the output list's order is your layer hierarchy downstream, so if the big background-ish blob comes out first it'll sit on top of the objects; sort_by exists precisely so you can control that. It's a young pack from a small studio, so the GitHub issues page is where real problems actually get answered.

CategoryAioli Nodes

Inputs (4)

NameTypeDefaultDescription
maskMASK
thresholdoptFLOAT0.500–1
min_areaoptINT640–16777216
sort_byoptCOMBO4 options: area_desc, area_asc, top_to_bottom, left_to_right

Outputs (2)

NameTypeDescription
masksMASK
countINT