Nodes/DOGMA Nodes/DOGMA DualMask v56.6
ComfyUI Node

DOGMA DualMask v56.6

DOGMA DualMask v56.6 and the 12-pixel difference that matters

By axior·Created 4 months ago·Updated 3 days ago· 1
DOGMA DualMask v56.6
  • mask
  • inpaint_mask
  • blend_mask
  • inpaint_preview
  • blend_preview
  • info
kind

You have one approved mask and you need two. Not because the pack is being fussy - because sampling and compositing want genuinely different things, and using the same mask for both is how you get a ring of noise around every repaired object.

The idea

Standard inpainting practice, per the KB's inpainting doc: mask blur and padding exist because a masked pass with a razor-thin boundary has no context. The model gets told "these pixels are unknown, those pixels are gospel", right at the mask edge, and it resolves that tension badly - visible seams, a dark or soft rim.

The DOGMA pipeline had a related injury, and the author's own account of it is on Reddit: running hundreds of VACE inpaintings for a broadcast spot, mask edges were the part that needed hand work frame by frame. DualMask is the two-mask discipline that came out of that. Give the sampler a slightly fatter mask so the generated pixels have support and don't have to make up a boundary. Give the compositor the exact approved mask, so nothing you didn't verify ever gets pasted over your source.

How it works

The threshold and the dilation, both in about ten lines:

seed = (mask.float() >= .5).float()[:, None]
radius = min(32, max(8, round(min(mask.shape[-2:]) * .012)))
size = 2 * radius + 1
wide = F.max_pool2d(seed, (1, size), 1, (0, radius))
wide = F.max_pool2d(wide, (size, 1), 1, (radius, 0))

Two separable max-pools, horizontally then vertically, which is a square dilation of radius pixels. On a 1024-wide crop that's 12px; the radius scales with the crop, clamped between 8 and 32, and there's no widget for it. inpaint_mask is the dilated mask, blend_mask is the exact one.

The info string says the rest out loud: "Exact approved ownership: no closing, hole filling or blend growth. Noise support +12px only." Note what it deliberately does not do - no morphological closing, no filling interior holes. Holes in your approved mask are treated as information (a window in a facade, the gap between two pedestrians), not as errors to patch over.

Inputs and outputs

  • mask - the approved, ownership-resolved mask. In practice from DOGMAMaskOwnershipV567 or DOGMAFinalMasksV567.
  • kind - STRUCTURE/SURFACE/OBJECT, normally from DOGMADenoiseCategoryV566. It's a required wire, but the shipped v56.6 code doesn't branch on it; the two masks are built the same way regardless.

Outputs: inpaint_mask and blend_mask (both MASK), plus inpaint_preview and blend_preview (IMAGE) so you can eyeball what you're about to sample with, and info.

Wiring, and this trips people up:

  • inpaint_maskgeneration_masks on DOGMASoftStitchV566 andmask on DOGMAMaskedDenoiseLatentV566. It's the support mask.
  • blend_maskblend_masks on the stitch node. That's the alpha seed.
  • In the stitch node the final seed is blend AND generation, so the dilation can never widen what gets composited. Two masks in, one ownership rule out.

Install

comfy node install comfyui-dogma-nodes
# or
cd ComfyUI/custom_nodes
git clone https://github.com/axior/ComfyUI-DOGMA-Nodes
pip install -r ComfyUI-DOGMA-Nodes/requirements.txt

The README says the pack is PyTorch-only; requirements.txt disagrees (scipy>=1.10), and while this node only needs torch, the module it lives in imports scipy.ndimage at the top. So install via Manager or run the pip line - hand-copying the folder without it fails at import, not at this node. No models to download for DualMask itself.

Gotchas

Check your mask range. The node assumes 0..1 probabilities. A mask that arrives scaled 0..255 reads as "everything is >= 0.5" and you'll silently get a full-frame dilation - the previews exist so you catch that in five seconds rather than after a 40-minute render. Same rule as the SAM guards upstream, which reject masks whose values fall outside 0..1.

The radius isn't a dial. If you need 24px of support on a 512px crop, either resize, dilate upstream, or accept the 8px you're getting. It scales with the crop rather than the object, so a small vehicle in a big crop gets proportionally more support than the same vehicle cropped tight.

Don't use inpaint_mask as your composite mask. It's the single most likely mis-wire in the graph, and it looks fine until you notice the fringe.

CategoryDOGMA/v56.6

Inputs (2)

NameTypeDefaultDescription
maskMASK
kindSTRING

Outputs (5)

NameTypeDescription
inpaint_maskMASK
blend_maskMASK
inpaint_previewIMAGE
blend_previewIMAGE
infoSTRING