Nodes/ComfyUI-Texturaizer/Switch Smart (Texturaizer)
ComfyUI Node

Switch Smart (Texturaizer)

Route a branch by matching text, not by remembering an index

By LatentSpaceDirective·Created 2 years ago·Updated 10 months ago· 22
Switch Smart (Texturaizer)
  • key
  • input1
  • input2
  • input3
  • input4
  • input5
  • input6
  • input7
  • input8
  • input9
  • input10
  • selected
  • index
◄trigger1►
◄trigger2►
◄trigger3►
◄trigger4►
◄trigger5►
◄trigger6►
◄trigger7►
◄trigger8►
◄trigger9►
◄trigger10►

Index-based switches are fine until the index has to mean something. Switch Smart (Texturaizer) is the one that understands meaning: you give it a key (any value), define up to ten inputs, and give each input a trigger string - then it matches the key against the triggers and selects the matching branch. And because it's lazy, only that branch ever gets computed.

Context: Texturaizer is a paid Blender addon by Luke Kratsios (LatentSpaceDirective); these nodes are its free ComfyUI companion pack. This is a genuinely useful utility - the pack's most interesting switch.

The trigger language

Each triggerN input is a string of match tokens, comma- or pipe-separated (the author's tooltip spells it out):

  • dog - exact match
  • ^AYS - starts-with prefix
  • AYS* - also starts-with (the * wildcard form)
  • re:^GITS\[coeff= - a full regex, after the re: prefix

A blank trigger acts as ELSE - the first blank trigger among the ten is the fallback branch. Triggers are checked in order, so put your catch-all last.

The key input is wildcard-typed and converted to a string before matching, so you can throw a model name, a sampler name, a path, whatever at it.

Inputs and outputs

  • key (*) - required; the selector, converted to string.
  • input1–input10 (*) - the branches, all lazy.
  • trigger1–trigger10 (STRING) - the match rules, blank = ELSE.
  • Outputs: selected (*) and index (INT).

How it works

Mechanically it's Switch Lazy with a matcher bolted on: check_lazy_status() resolves which trigger set matches the key, then tells the executor to evaluate only that input. _token_matches() implements the four token forms (with a try/except around the regex so a bad pattern just doesn't match rather than crashing). The matching is first-hit-wins: the first trigger whose any token matches selects that branch; if nothing matches, the first blank (ELSE) trigger wins; if there's no ELSE either, input 1.

The pattern that makes it valuable

The classic Texturaizer use: route on a value that comes out of the data. Say a scene property carries the checkpoint or scheduler name - wire it into key, set trigger1 to euler, trigger2 to ^dpm, trigger3 to re:.*ancestral, and a blank on trigger4 as ELSE. The graph then routes itself based on what Blender exported, no manual re-plumbing per object. That "match the data, not the graph" move is the whole philosophy of this pack.

Install

Pack-level:

cd ComfyUI/custom_nodes
git clone https://github.com/LatentSpaceDirective/ComfyUI-Texturaizer

or ComfyUI Manager → search "Texturaizer" → Install → restart. Stock dependencies, no models.

Where people get tripped up

Regex without the re: prefix is treated as literal text - that's the #1 "why doesn't it match" mistake. Second, matching is prefix-position-sensitive: ^AYS matches "AYS SDXL" but not "SD AYS". And remember triggers and inputs are matched positionally (trigger1 ↔ input1), not by content. If the key input is an integer, it's stringified first, so 42 matches trigger 42 but not ^4... actually ^4 would match "42" as a prefix - which is a great example of why you should read the tokens as strings, because that's exactly what they are.

CategoryTexturaizer

Inputs (21)

NameTypeDefaultDescription
key*Selector (any type). Converted to string and matched against triggers.
input1opt*—
input2opt*—
input3opt*—
input4opt*—
input5opt*—
input6opt*—
input7opt*—
input8opt*—
input9opt*—
input10opt*—
trigger1optSTRINGTokens: exact, ^prefix, prefix*, or re:<regex>. Comma or | separated. Blank = ELSE.
trigger2optSTRINGTokens: exact, ^prefix, prefix*, or re:<regex>. Comma or | separated. Blank = ELSE.
trigger3optSTRINGTokens: exact, ^prefix, prefix*, or re:<regex>. Comma or | separated. Blank = ELSE.
trigger4optSTRINGTokens: exact, ^prefix, prefix*, or re:<regex>. Comma or | separated. Blank = ELSE.
trigger5optSTRINGTokens: exact, ^prefix, prefix*, or re:<regex>. Comma or | separated. Blank = ELSE.
trigger6optSTRINGTokens: exact, ^prefix, prefix*, or re:<regex>. Comma or | separated. Blank = ELSE.
trigger7optSTRINGTokens: exact, ^prefix, prefix*, or re:<regex>. Comma or | separated. Blank = ELSE.
trigger8optSTRINGTokens: exact, ^prefix, prefix*, or re:<regex>. Comma or | separated. Blank = ELSE.
trigger9optSTRINGTokens: exact, ^prefix, prefix*, or re:<regex>. Comma or | separated. Blank = ELSE.
trigger10optSTRINGTokens: exact, ^prefix, prefix*, or re:<regex>. Comma or | separated. Blank = ELSE.

Outputs (2)

NameTypeDescription
selected*—
indexINT—