Polygon Mask V1 (DAELab)
Draw the mask, get a real tensor out of it
- image
- color
- masked_image
- raw_mask
- text
Every "draw your mask" node in ComfyUI is really two products stapled together: a JavaScript editor and a Python rasteriser. Most of them fail at the staple. You draw something, queue, and get a mask from three edits ago - or the editor forgets your work when you reload the workflow.
Polygon Mask V1 (DAELab) is the pack's take, re-registered under the DAELAB.* namespace so it boots through the newer schema path. It takes an external IMAGE socket, gives you a canvas with multiple closed polygons on top, and hands back a composited image, a black-and-white mask at the input resolution, and a text passthrough.
The mechanism
The Python half is straightforward. polygon_data carries the editor's state - polygons in normalised coordinates, selection, undo state, and a cleared flag. On execute, the node parses that state, draws each closed polygon into an all-zero mask at the input image's exact width and height, and outputs:
masked_image- your input image with all the polygons drawn over it, atfill_opacityandoutline_widthincolor. Preview-grade, and genuinely useful for confirming what you selected.raw_mask- the binary mask: white where any polygon covers, black elsewhere. Same width and height as the input. This is the one you wire onward.text- a multiline string from the node's own panel, passed through untouched. Handy for smuggling a per-selection prompt through the graph without an extra node.
The state sync is the part that was engineered. The polygon_data widget pushes the live canvas state both on beforeQueued and on serialise, so dragging a vertex and immediately hitting queue uses the vertices you just placed. And there's a fixed restoration order - the widget value, then a properties fallback, then a legacy properties key from older versions - so workflows saved by previous releases still open with their polygons intact.
The one workflow-specific nicety: reading Load Image directly
If image is connected to a plain ComfyUI Load Image, clicking the node's Load Image button reads that upstream loader's currently selected file immediately, without queueing anything. That's a small thing that removes real friction: you flip through artwork files, click once, and the canvas updates.
Other IMAGE sources (a generated image, a resize node, anything whose value only exists after execution) behave differently. They stage the most recent run's image as a preview. That preview deliberately does not touch polygon_data, properties, undo history or the persisted image identity - you press Apply Preview when you actually want it to become the editing base. Neither button queues the prompt.
That design matters because it stops the "copied workflow" bug where two instances share a node ID and one graph's executed image leaks into the other's editor.
Changing the image
Replacing the image doesn't nuke your work. Same dimensions - absolute coordinates are kept as-is. Different dimensions - every vertex is scaled by width and height ratio. Unknown old dimensions - coordinates are clamped into the new bounds. If you previously hit Clear, the node respects that and keeps returning an empty mask rather than helpfully adding a default triangle back.
Reset is how you ask for a rebuild, and it reconstructs the selected polygon with the current vertex_count while keeping the centre. vertex_count is clamped to 3–50; that limit is enforced on every path.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/TeutonicMepheles/ComfyUI-DAELab-Custom-Nodes-Library.git
Restart ComfyUI and refresh the browser tab. The editor is a set of web/ modules; a stale tab gives you a node with a dead canvas. In ComfyUI Manager, search the pack title "ComfyUI-DAELab-Custom-Nodes-Library".
Note that the original Polygon Mask (un-namespaced PolygonMask) still exists in the pack. Install one copy of the repo, not two - and if you're migrating a workflow, expect the node IDs to be different, so you'll be re-adding this node rather than swapping a widget.
Gotchas
The polygon_data input is marked as internal state by the author and it means it. Typing coordinates into it by hand is possible and almost never worth debugging; the editor writes it.
If a mask comes out with the right shape but the wrong colours, check fill_opacity - but remember it only affects masked_image. raw_mask is binary regardless, so a "too transparent" mask is never a fill_opacity problem.
App Mode compatibility is handled by a shared bypass script for this pack's nodes; if the canvas disappears when you bypass the node in a built app, that's the front-end state, not your polygons. Toggle back to Active and the panel returns, per the pack's documented behaviour.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| vertex_count | INT | 33–50 | — |
| color | COLOR | #FF0000 | — |
| fill_opacity | INT | 350–100 | — |
| outline_width | INT | 30–20 | — |
| polygon_data | STRING | Internal polygon state managed by the Polygon Mask editor. | |
| text | STRING | Multiline text passed through to the text output. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| masked_image | IMAGE | — |
| raw_mask | MASK | — |
| text | STRING | — |