DOGMA V50 Scene Plan
Your VLM writes the inventory, this node turns it into six SAM jobs
- preview
- category_1
- sam_prompt_1
- kind_1
- threshold_1
- local_prompt_1
- category_2
- sam_prompt_2
- kind_2
- threshold_2
- local_prompt_2
- category_3
- sam_prompt_3
- kind_3
- threshold_3
- local_prompt_3
- category_4
- sam_prompt_4
- kind_4
- threshold_4
- local_prompt_4
- category_5
- sam_prompt_5
- kind_5
- threshold_5
- local_prompt_5
- category_6
- sam_prompt_6
- kind_6
- threshold_6
- local_prompt_6
This node loads no model, renders no pixels, and has no settings worth a screenshot. It is a text parser with 31 outputs, and it's the hinge in one specific workflow: a VLM looks at your image, lists what it can see, and this node converts that list into six independent "find this and re-render it" jobs for a text-prompted segmenter plus an inpaint pass.
If you've ever wished a detailer would handle every car in the frame at once instead of a rectangle you drew by hand, that's the job. Category-level masking turns the normal detailing loop - detect, crop, re-render, paste back - from one region at a time into one class at a time.
What the loop looks like
You feed an image to a VLM. Not for a caption you'd paste into a prompt box, but for an inventory: a strict list of the semantic families present. Something like GROUP|cars|OBJECT|1970s Italian cars on a road. That text comes back through inventory_text, and this node hands you six slots of five outputs each:
category_1…category_6- the canonical family name the node resolved, e.g.cars,buildings,road.sam_prompt_1…sam_prompt_6- the phrase to give your promptable segmenter (SAM 3-class, or a Grounded SAM pair).kind_1…kind_6-OBJECT,STRUCTURE, orSURFACE.threshold_1…threshold_6- a per-category detection threshold for that segmenter.local_prompt_1…local_prompt_6- the prompt for the refine pass on that category's mask.
Plus preview, which is a human-readable dump of all six slots. Wire that into a Show Text node first. It's how you find out the VLM gave you something the node couldn't use before you spend minutes on SAM.
How it decides
inventory_text is scanned line by line; only lines starting with GROUP| count, split on the pipe. Field two gets canonicalized against a synonym table - automobile, sedan, hatchback all become cars; pedestrians and crowd become people. Duplicates are dropped after canonicalization, so the VLM repeating itself costs you nothing. Any prompt text over 16 words gets truncated.
Then a fixed lookup table supplies the rest. Cars and people land at a threshold of 0.18, buildings at 0.24 as STRUCTURE, road and vegetation at 0.22 as SURFACE, smaller object classes at 0.25. Anything that doesn't map - sky, windows, graffiti, whatever - becomes nonexistent_placeholder_object_xyz at a threshold of 0.35. That's not a bug: it's a deliberate dead end so an unusable category returns an empty mask instead of a mask of everything.
If a group line arrives without its own prompt, the node falls back to a canned one, and that fallback is where the author's demo shows through: a project context containing both "1970" and "ital" prefixes 1970s Italian, and nothing else does. So write prompts in your GROUP lines rather than relying on that.
Inputs you actually touch
Both inputs are forceInput strings, which means they're sockets, not boxes you type into. Feed each from a PrimitiveString or String node. inventory_text comes from your VLM (the pack's own DOGMAV50SceneInstruction node generates the prompt to give it). project_context is your one-line description of the scene - keep it to a line, because it's used as a style qualifier and a fallback, not as evidence.
Wire sam_prompt_i and threshold_i into your segmenter, kind_i into DOGMAV52MaskDeoverlap, and local_prompt_i into the refine pass. That's the graph.
Install
ComfyUI Manager → search DOGMA Nodes, or:
cd ComfyUI/custom_nodes
git clone https://github.com/axior/ComfyUI-DOGMA-Nodes
Restart ComfyUI. There are genuinely no dependencies - requirements.txt is a comment saying so, and pyproject.toml declares an empty list. comfy node install comfyui-dogma-nodes also works.
Where people get burned
The README doesn't document this node. It covers the WAN VACE pair and the DOGMA samplers, and that's it - the whole semantic-detailer family lives in dogma_semantic_v5641.py undocumented. Search the node menu for "scene plan" and you'll find it under category DOGMA/v50.
You get a blank preview. Either the VLM ignored the format rules (it needs to emit GROUP| lines and nothing else) or you wired prose into inventory_text. Don't hand-roll the prompt - use the pack's instruction node, which tells the model the exact format and forbids it from inventing objects from context.
A slot is empty and you assume the pack is broken. A placeholder sam_prompt plus threshold 0.35 means the node never recognized that category, and an empty mask is the correct outcome. Check the category_i output, not the mask.
You mix v50 and v52 without noticing. The v50 inventory prompt writes four fields per line including a prompt; the v52 one writes three and no prompt, because the v52 plan node ignores that field and generates its own. Either combination runs, but you'll wonder why your prompt text vanished.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| inventory_text | STRING | — | |
| project_context | STRING | — |
Outputs (31)
| Name | Type | Description |
|---|---|---|
| preview | STRING | — |
| category_1 | STRING | — |
| sam_prompt_1 | STRING | — |
| kind_1 | STRING | — |
| threshold_1 | FLOAT | — |
| local_prompt_1 | STRING | — |
| category_2 | STRING | — |
| sam_prompt_2 | STRING | — |
| kind_2 | STRING | — |
| threshold_2 | FLOAT | — |
| local_prompt_2 | STRING | — |
| category_3 | STRING | — |
| sam_prompt_3 | STRING | — |
| kind_3 | STRING | — |
| threshold_3 | FLOAT | — |
| local_prompt_3 | STRING | — |
| category_4 | STRING | — |
| sam_prompt_4 | STRING | — |
| kind_4 | STRING | — |
| threshold_4 | FLOAT | — |
| local_prompt_4 | STRING | — |
| category_5 | STRING | — |
| sam_prompt_5 | STRING | — |
| kind_5 | STRING | — |
| threshold_5 | FLOAT | — |
| local_prompt_5 | STRING | — |
| category_6 | STRING | — |
| sam_prompt_6 | STRING | — |
| kind_6 | STRING | — |
| threshold_6 | FLOAT | — |
| local_prompt_6 | STRING | — |