Nodes/ComfyUI-DAELab-Custom-Nodes-Library/Badge Local Mask Route V1
ComfyUI Node

Badge Local Mask Route V1

Colour pick or hand-drawn polygon? Pick one without running both

By TeutonicMepheles·Created 4 months ago·Updated 3 days ago· 0
Badge Local Mask Route V1
  • color_reference
  • color_mask
  • polygon_reference
  • polygon_mask
  • selection_reference
  • candidate_mask
  • selection_mode
  • status
◄selection_colortrue►
◄selection_polygonfalse►

What this is for

There are two honest ways to tell a machine which part of a badge you mean. You click a color and it finds every pixel like it, or you draw a polygon around the thing. The first is precise when the art is flat and useless when the render has gradients; the second always works and takes thirty seconds of your life. Most real badge work needs both, in the same graph, depending on the region.

Badge Local Mask Route V1 is the switch between them. It takes a reference image and a mask from each method, and hands forward the pair you selected - evaluating only that pair. Two booleans, four optional inputs, two useful outputs and two strings of bookkeeping.

The reason it's more than a switch is what it validates. A colour-derived mask and a polygon mask can both be the right shape and matched to different images by accident - one drawn on the flat art, one on the render. This node checks that the reference and the mask it's forwarding share a canvas, so the pairing error gets caught here instead of showing up as a mysteriously offset paid edit.

How it works

selection_color defaults true, selection_polygon defaults false, and exactly one must be set. Both or neither and execute raises Select exactly one badge local mask mode. - no silent default, no guessing.

check_lazy_status handles the branch pruning: it asks for the two inputs belonging to the chosen mode that are still unset, and nothing from the other mode. So a polygon workflow doesn't drag the colour-picking chain behind it, and vice versa. If you're not familiar with the pattern, the short version is that lazy inputs are how a node tells ComfyUI "I only need this side of the graph today", and it's the difference between a switch that's free and one that runs both branches anyway.

Then it does the pairing check. The selected reference must be a valid float image, the mask must be a valid mask, and their [batch, height, width] shapes must agree - otherwise The selected color reference and mask must share one canvas. If the branch is simply unwired you get The selected color mask branch is unavailable., which is the error I'd expect to see most often in a half-built graph.

Outputs: selection_reference (the image the colour picking or drawing happened on - this is what a mask preview should be drawn over), candidate_mask (the raw selection, not yet validated against the support mask), selection_mode (color or polygon, as a string), and status JSON with state: ready, the mode, a digest of the selected mask, and unselected_branch_resolved: false.

Note "candidate". This node doesn't decide whether a selection is legal - that's the guard's job. It resolves which selection you're talking about.

The inputs and outputs you touch

  • selection_color / selection_polygon - the XOR pair, and the only two widgets.
  • color_reference / color_mask - from the colour-picking side.
  • polygon_reference / polygon_mask - from the polygon/brush side.

Wire selection_reference and candidate_mask into your validation and preview, and selection_mode into anything that needs to know how the selection was made - the pack's own guard takes it as an input and reports it back.

Install

cd ComfyUI/custom_nodes
git clone https://github.com/TeutonicMepheles/ComfyUI-DAELab-Custom-Nodes-Library.git
# restart ComfyUI

V3 node, needs current comfy_api.latest. It shares a module with three sibling routers, so a failed import of that module means all four vanish at once - usually a missing cv2 or scipy, which the pack's requirements file doesn't declare but ComfyUI core normally provides:

ComfyUI/python_embeded/python.exe -m pip install opencv-python-headless scipy

Where people get burned

Exposing both booleans in an app. Same story as every XOR pair: users tick both. Here it's a hard error, which is better than a wrong-looking result but still not a nice experience. Give the app a single two-option selector.

Mismatched canvases. The node checks reference-against-mask, but it can't check that both branches agree with the downstream edit target. If you drew your polygon on a 1024 normalised image and your edit target is a raw 1536 render, this node passes and the guard downstream fails. Normalise once, early, and route the normalised image everywhere.

Treating candidate_mask as final. It's the selection as drawn, before any support/foreground clipping or minimum-size check. If a selection is 3 pixels you'll find out at the guard, not here - which is fine, just don't assume a clean route means a usable mask.

Skipping the status. unselected_branch_resolved: false is the node telling you the other side really wasn't evaluated. Useful when you're trying to work out why a graph is slow, or why a paid node upstream of the losing branch didn't fire.

CategoryDAELab/Badge/App

Inputs (6)

NameTypeDefaultDescription
selection_colorBOOLEANtrue—
selection_polygonBOOLEANfalse—
color_referenceoptIMAGE—
color_maskoptMASK—
polygon_referenceoptIMAGE—
polygon_maskoptMASK—

Outputs (4)

NameTypeDescription
selection_referenceIMAGE—
candidate_maskMASK—
selection_modeSTRING—
statusSTRING—