DOGMA Adaptive Semantic Plan v24
Turning a VLM's four scene fixes into six SAM slots, in the right order
- plan_preview
- category_1
- sam_prompt_1
- sam_threshold_1
- category_2
- sam_prompt_2
- sam_threshold_2
- category_3
- sam_prompt_3
- sam_threshold_3
- category_4
- sam_prompt_4
- sam_threshold_4
- category_5
- sam_prompt_5
- sam_threshold_5
- category_6
- sam_prompt_6
- sam_threshold_6
The hard part of a semantic detailer isn't the sampling, it's deciding what to repair. DOGMAAdaptiveSemanticPlanV24 takes the free text a vision-language model wrote about a scene and turns it into a stable, fixed-width set of outputs a graph can be wired against: one plan_preview string plus six slots, each carrying category_N, sam_prompt_N and sam_threshold_N.
Why six slots when the VLM lists four things
Because a planner that returns a variable number of outputs can't be wired. The v24 logic reads the planner text line by line, normalises each line into a canonical category, keeps the first four distinct ones, and pads the rest with __none__. Then it builds the six slots deterministically:
- Slot 1 - conditional
road support, only inserted when one of the categories isroadway people. Reasoning: if the model says there are pedestrians in the roadway, the road under them is context you may need to repair too, and doing it in slot 1 means the coarse pass lands before the fine one. - Slots 2-5 - your four repair categories.
- Slot 6 -
signage, always present, always last.
That ordering is the design. Coarse and background-ish work goes early, delicate small things go late, so a later car or person pass can clean up any tiny spill a broad pass left behind. If you've ever had a facade detail pass nick a pedestrian's silhouette, this is the pack's answer.
What normalisation actually does
The _norm step is where this node earns its keep and where it will surprise you. It maps wording onto a fixed vocabulary: anything mentioning car/vehicle/van/motorcycle/bicycle becomes vehicles; person/pedestrian/crowd becomes people; window/door/balcony/facade becomes architectural details; railings and lamps become street furniture; faces, hands, animals, furniture, machinery and clothing get their own; products too.
Then it refuses two whole groups outright. Text and signage categories - sign, billboard, poster, lettering, logo, license plate - normalise to __none__ because generative passes rewrite glyphs, and rewritten lettering is a worse outcome than blurry lettering. And broad surfaces - road, sidewalk, grass, sky, water, wall, floor, background, haze - also become __none__, because a local crop is the wrong tool for a 40-megapixel field. Both are deliberate, opinionated refusals, and they're the difference between a planner you can trust and one that happily sets your render on fire.
Each surviving category gets a SAM prompt with per-concept caps and a threshold you can wire straight into a grounded segmenter: vehicles is car:220,automobile:220,bus:24,truck:24,van:24,motorcycle:16,bicycle:12 at threshold 0.13, people is person:180,pedestrian:180,human:180 at 0.14, faces 0.16, animals 0.16, and so on. Recall-biased numbers - the caps are per-concept detection limits, not confidence.
Wiring it
planner_text comes from your VLM node (Qwen3-VL-class; the later v31 audit node formalises this with explicit TARGET| and DEFECT| lines instead of prose). Take category_N, sam_prompt_N and sam_threshold_N per slot into one segmentation branch each, gate each with DOGMACategoryMaskGate so unused slots contribute a zero mask, and feed the crops downstream. plan_preview is a human-readable dump of the six slots - read it the first few times you run a new planner prompt, it's the fastest way to see that your VLM wrote a category you don't have a repair path for.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/axior/ComfyUI-DOGMA-Nodes
Or ComfyUI Manager → DOGMA Nodes, then restart. No pip dependencies (the pack declares none at all). You bring the models: a VLM to write the plan, a grounded segmenter for masks, FLUX.2 Klein for the local passes. The GitHub README doesn't cover this node.
Common issues
Everything normalises to __none__. Either the VLM wrote prose instead of category lines, or it wrote about roads and signage - which this node deliberately drops. If you genuinely need a road repaired, that's a macro/detail-injection path, not this one.
Slot order looks wrong in plan_preview. It's deterministic, not sorted by size or priority. If you want a different order, you want a different planner.
A category appears twice. Normalisation dedupes across the whole plan, so duplicates collapse. If you wanted two distinct passes on the same thing, plan them as different categories.
Thresholds that over-segment. 0.13-0.14 on a recall-biased prompt is deliberately grabby. Crowded scenes will pick up fragments; that's the trade the pack makes, and the crop stage's IoU dedupe is where it gets cleaned up.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| planner_text | STRING | — |
Outputs (19)
| Name | Type | Description |
|---|---|---|
| plan_preview | STRING | — |
| category_1 | STRING | — |
| sam_prompt_1 | STRING | — |
| sam_threshold_1 | FLOAT | — |
| category_2 | STRING | — |
| sam_prompt_2 | STRING | — |
| sam_threshold_2 | FLOAT | — |
| category_3 | STRING | — |
| sam_prompt_3 | STRING | — |
| sam_threshold_3 | FLOAT | — |
| category_4 | STRING | — |
| sam_prompt_4 | STRING | — |
| sam_threshold_4 | FLOAT | — |
| category_5 | STRING | — |
| sam_prompt_5 | STRING | — |
| sam_threshold_5 | FLOAT | — |
| category_6 | STRING | — |
| sam_prompt_6 | STRING | — |
| sam_threshold_6 | FLOAT | — |