BD Parts Underpaint
What's under the jacket? BD Parts Underpaint reveals it
- parts
- model
- clip
- vae
- source_image
- parts
- base_image
- image_batch
- summary
Once you've torn a character into parts and rebuilt each one cleanly, you still need the background they sit on - but the original background has the character in it. Remove the jacket and what should show through is the shirt or skin underneath, and nobody generated that for you. BD Parts Underpaint is the node that fabricates it: it inpaints the source image where each part was removed, revealing whatever would naturally be underneath - skin under clothing, interior under panels, background behind an object.
It's the companion to BD Parts Batch Edit and they're designed to run together: Batch Edit produces the rebuilt part renders, Underpaint produces the clean base_image (source with all parts removed), and you wire that base into BD Parts Export's base_image so the rebuilt parts composite onto the clean surface. One node strips the character away, the other rebuilds the pieces - together they reassemble the whole scene.
The two modes
per_part_sequential(default) - one Qwen inpaint pass per part, inremove_order(outer layers first: jacket, then shirt, then pants). Each pass result feeds the next, so successive layers reveal beneath each other. Most detailed, but costs N × Qwen inference time.all_parts_combined- unions all part masks into one, single Qwen pass. Faster, and fine when parts don't overlap much, but large masked regions are harder for Qwen to fill coherently.
prompt_template (with {tag} interpolation) controls the language of the reveal - the defaults cover characters, vehicles, and products, and the tooltips give you ready swaps for each domain. prefill_mode (default color_spread) decides what Qwen sees before it starts: cv2 Telea inpaint fills from boundary colors, which gives the model a plausible gradient to refine; nearest-neighbor, neutral gray, and flat fills are the alternatives.
Backend choice: model_type
This is the input to read carefully, because it changes what you wire:
qwen_edit(default) - Qwen Image Edit. Uses VLM image tokens + reference latents; wire the same model/clip/vae stack as Batch Edit.kontext_dev- Flux Kontext Dev (flux1-kontext-dev.safetensors+ DualCLIPLoader + Flux VAE). Better real-scene coherence, per the pack.flux_fill- Flux Fill Dev or any plain Flux inpaint model.
Each maps to different wiring, and the full-image/edit-model guidance in the tooltips is worth heeding: full_image_pass should be ON for instruction-edit models (kontext_dev, qwen_edit) - they're designed to see the whole scene, and cropping to a part's bbox makes them hallucinate context. composite_mode=mask_region pastes only the masked region back, keeping pixels outside untouched - that's the default and the right call for inpaint models.
The other controls mirror Batch Edit (steps=4, cfg=1.0, euler, simple, shift=3, CFGNorm 0.85, tonemap 2 - all Lightning-LoRA defaults). mask_dilate_pixels (default 4, range up to 256) is the one you'll actually tune: raise it to 64–128 to eliminate edge halos when removing objects with visible outlines. remove_order and skip_tags control which parts get removed and in what sequence. Outputs: parts (passthrough), base_image, image_batch (per-step frames), and summary.
Install & expectations
In ComfyUI-BrainDead: Manager search "BrainDead", or clone + pip install -r requirements.txt. It runs a 20B edit model - budget VRAM accordingly, and keep ComfyUI on a current version (V3-API pack).
The honest caveat: sequential mode with full_image_pass on means a full-image generation per part, so a five-part character is five slow passes. That's the cost of coherence - if you're in a hurry and the parts don't overlap, all_parts_combined cuts it to one. And the quality ceiling is the edit model's: Qwen Image Edit is the 2026 default for this kind of work, but "what's under the jacket" is a genuinely hard question, so skim the per-step frames in image_batch before you trust the result in production.
Inputs (31)
| Name | Type | Default | Description |
|---|---|---|---|
| parts | PARTS_BUNDLE | — | |
| model | MODEL | — | |
| clip | CLIP | — | |
| vae | VAE | — | |
| source_image | IMAGE | Original full-resolution source image (before any parts were removed). Required — this is what gets inpainted. | |
| mode | COMBO | per_part_sequential | per_part_sequential — one Qwen inpaint call per part, processed in remove_order (outer layers first). Each pass feeds the next so successive layers reveal beneath each other. Gives the most detailed per-layer result but takes N × Qwen inference time. all_parts_combined — union all part masks into one, single Qwen call. Faster. Best when parts don't overlap much. May struggle to inpaint very large masked areas coherently. |
| prompt_template | STRING | Remove the {tag} from this image. Fill the region with whatever would naturally be visible underneath or behind the {tag} in this scene — skin, clothing, background surface, or interior. Preserve all surrounding pixels exactly. | Prompt for per_part_sequential mode. {tag} is replaced with the part's label. Adjust for your domain: Characters: 'Remove the {tag} and show the garment or bare skin underneath' Vehicles: 'Remove the {tag} and show the interior/chassis beneath' Products: 'Remove the {tag} and reveal the underlying surface' |
| prefill_mode | COMBO | color_spread | How to fill the masked region BEFORE Qwen sees it: color_spread (DEFAULT) — cv2 Telea inpaint: fills from surrounding boundary colors. Gives Qwen a plausible color gradient to refine, which typically produces the most natural 'underneath' texture. nearest_neighbor — Voronoi spread from nearest outside pixel. Sharper color boundaries. Good for geometric shapes. neutral_gray — 50% gray fill. Safe baseline. white / black — flat fills. Black required for Qwen Inpaint LoRA (prompt must start with 'Inpaint the black areas.'). none — pass the raw crop as-is (Qwen sees existing occluders). |
| latent_upscale_method | COMBO | nearest-exact | Interpolation for latent upscale. |
| target_pixels | COMBO | 1024x1024 | Working resolution for each Qwen inpaint pass. |
| seed | INT | 00–18446744073709550000 | — |
| steps | INT | 41–100 | 4 for Lightning LoRA, 8-20 for non-Lightning. |
| cfg | FLOAT | 1.00–20 | — |
| sampler_name | COMBO | euler | 44 options: euler, euler_cfg_pp, euler_ancestral, euler_ancestral_cfg_pp, heun, heunpp2, +38 |
| scheduler | COMBO | simple | 9 options: simple, sgm_uniform, karras, exponential, ddim_uniform, beta, +3 |
| denoise | FLOAT | 1.000–1 | — |
| model_typeopt | COMBO | qwen_edit | Which edit model is wired in: qwen_edit — Qwen Image Edit (default). Uses VLM image tokens + reference_latents. Requires the Qwen Edit model stack (UNETLoader → Lightning LoRA → Inpaint LoRA). kontext_dev — Flux Kontext Dev (flux1-kontext-dev). Uses plain CLIPTextEncode + image_cond_latents. Load flux1-kontext-dev.safetensors with UNETLoader and its matching dual CLIP. flux_fill — Flux Fill Dev or any plain Flux inpaint model. Uses CLIPTextEncode + noise_mask only. Load flux1-fill-dev.safetensors. |
| remove_orderopt | STRING | Comma or newline separated list of tags specifying which parts to remove and in what order (outer-to-inner). Missing = use bundle's dict order. Example for a clothed character: jacket, shirt, pants Tags not in this list that exist in the bundle are silently skipped ONLY if they aren't in the bundle. Unknown tags are ignored. Leave empty to process all parts in bundle order. | |
| all_parts_promptopt | STRING | Remove all the highlighted parts from this image and reveal the complete underlying surface — bare skin, undergarments, interior, or background — as it would naturally appear with all parts absent. | Prompt used in all_parts_combined mode (single inpaint call, all masks unioned). {tag} and {tags} are replaced with the comma-joined list of removed part labels. |
| context_extend_factoropt | FLOAT | 1.51–3 | How much surrounding context to give Qwen around each part's bbox. 1.0 = crop exactly to part bbox. 1.5 = 50% larger crop so Qwen sees more neighboring skin/surface for better extrapolation. 2.0 = double. Higher = better context but smaller part gets larger canvas proportion. |
| skip_tagsopt | STRING | Tags to skip entirely (csv or newline). Parts not in this list are still processed. Useful to skip hair, background, or accessory parts that shouldn't be removed before the underpaint. | |
| mask_dilate_pixelsopt | INT | 40–256 | Expand the inpaint region N pixels beyond the exact part boundary. Also controls the compositing zone — blending back uses the dilated mask so original object edges/halos never leak through. 4-8 for slight seam smoothing; 64-128 for aggressive background removal where outlines are still visible. |
| mask_blend_pixelsopt | INT | 40–32 | Soft-edge feather when pasting the Qwen result back into the source. Prevents hard seams at the part boundary. 4-8 recommended. |
| latent_upscale_factoropt | FLOAT | 1.251–2 | Upscale the encoded latent by this factor before KSampler (high-res-fix). 1.25 is a good default with the Lightning LoRA stack. 1.0 = no upscale. |
| model_sampling_shiftopt | FLOAT | 3.00–20 | ModelSamplingAuraFlow shift. Required for Lightning LoRA + latent upscale. 3.0 from the standard recipe. 0.0 = disabled. |
| cfg_norm_strengthopt | FLOAT | 0.850–2 | CFGNorm post-cfg function. 0.85 from recipe. 0.0 = disabled. |
| tonemap_reinhard_multiplieropt | FLOAT | 2.00–10 | Reinhard tonemap on KSampler output before VAE decode. 2.0 from recipe. 0.0 = off. |
| target_pixels_customopt | INT | 104857665536–4194304 | Custom pixel budget (used when target_pixels='custom'). |
| negative_promptopt | STRING | Negative prompt (no effect at cfg=1.0). | |
| composite_modeopt | COMBO | mask_region | How the edited crop is merged back into the scene: mask_region (DEFAULT) — paste only the masked region back onto the original; pixels outside the mask stay untouched. Correct for inpaint models (qwen_edit / flux_fill) whose noise_mask already kept the surround identical. full_crop — paste the model's ENTIRE edited crop (feathered only at the crop border). Use for full-image edit models (kontext_dev): removes objects cleanly with no leftover pixels outside the mask, and avoids the masked-patch misalignment/ghosting (doubling) you get when compositing a regenerated patch back onto the un-regenerated original. Rule of thumb: kontext_dev → mask_region (with full_image_pass on), qwen_edit/flux_fill → mask_region. |
| full_image_passopt | BOOLEAN | false | Feed the WHOLE image to the model each pass instead of a per-part crop. Instruction edit models (kontext_dev, qwen_edit) are designed to see the entire scene. Cropping to a part's bbox strips global context and makes them hallucinate fill that doesn't match the scene (e.g. a floating beach in the middle). Turn this ON for edit models. When ON, context_extend_factor is ignored. Combine with composite_mode=mask_region for clean object removal with zero drift outside the mask. Leave OFF only for a true masked inpaint model (flux_fill) where a focused crop is cheaper and correct. Note: per_part_sequential + full_image_pass runs a full-image generation per part (slower). all_parts_combined does it in a single pass. |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| parts | PARTS_BUNDLE | Passthrough — unchanged PARTS_BUNDLE. |
| base_image | IMAGE | Source image with all processed parts inpainted away. Wire into BD_PartsExport[base_image] so rebuilt part renders composite onto this clean surface. |
| image_batch | IMAGE | (N, H, W, 3) batch of per-step intermediate frames for sequential mode. Frame 0 = after removing first tag, frame N-1 = base_image. Single frame for all_parts_combined. |
| summary | STRING | — |