saliacoel commited on
Commit
b988c21
·
verified ·
1 Parent(s): a8b71cc

Upload wildcard_1.py

Browse files
Files changed (1) hide show
  1. wildcard_1.py +325 -0
wildcard_1.py ADDED
@@ -0,0 +1,325 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import random
2
+
3
+
4
+ class Wildcard_1:
5
+ @classmethod
6
+ def INPUT_TYPES(cls):
7
+ return {
8
+ "required": {
9
+ # Seed controls the whole combo (same seed -> same pair)
10
+ "seed": ("INT", {
11
+ "default": 0,
12
+ "min": 0,
13
+ "max": 0xffffffffffffffff,
14
+ "step": 1
15
+ }),
16
+ }
17
+ }
18
+
19
+ # Two text outputs: female + male
20
+ RETURN_TYPES = ("STRING", "STRING",)
21
+ RETURN_NAMES = ("female_prompt", "male_prompt",)
22
+ FUNCTION = "generate"
23
+ CATEGORY = "wildcards"
24
+
25
+ def generate(self, seed: int):
26
+ rnd = random.Random(int(seed))
27
+
28
+ # -------------------------
29
+ # Category 1: fixed gender token
30
+ # -------------------------
31
+ category1_f = "1girl"
32
+ category1_m = "1boy"
33
+
34
+ # -------------------------
35
+ # Category 2: POV of camera (8 directions, LEFTSIDE/RIGHTSIDE uppercase)
36
+ # -------------------------
37
+ pov_options = [
38
+ "straight-on, frontview",
39
+ "diagonal LEFTSIDE, three quarter view LEFTSIDE",
40
+ "sideview LEFTSIDE, from LEFTSIDE side",
41
+ "frontview POV",
42
+ "sideview RIGHTSIDE, from RIGHTSIDE side",
43
+ "diagonal RIGHTSIDE, three quarter view RIGHTSIDE",
44
+ "frontview, low angle POV, from below",
45
+ "straight-on, from below, low angle view",
46
+ ]
47
+ pov = rnd.choice(pov_options)
48
+
49
+ # -------------------------
50
+ # Category 3: woman / man / girl / boy / grandma / grandpa
51
+ # (chosen via female word, then mapped to male counterpart)
52
+ # -------------------------
53
+ female_roles = ["girl", "woman", "loli"]
54
+ role_f = rnd.choice(female_roles)
55
+ role_m = {
56
+ "girl": "boy",
57
+ "woman": "man",
58
+ "loli": "shota",
59
+ }[role_f]
60
+
61
+ # -------------------------
62
+ # Category 4: social + inner personality (two tokens)
63
+ # second word is the same and gender-correct
64
+ # e.g. "rich woman, sadistic woman"
65
+ # -------------------------
66
+ social_descriptors = [
67
+ "rich", "poor", "noble", "commoner",
68
+ "merchant", "warrior", "scholar", "artist",
69
+ "assassin", "guard", "leader", "servant",
70
+ "clumsy", "elegant", "streetwise", "aristocratic",
71
+ "rural", "city", "rebellious", "stoic",
72
+ ]
73
+ inner_descriptors = [
74
+ "sadistic", "kind", "gentle", "cold", "calculating",
75
+ "cheerful", "melancholic", "serious", "playful",
76
+ "paranoid", "confident", "insecure", "arrogant",
77
+ "humble", "curious", "apathetic", "obsessive",
78
+ "protective", "jealous", "ambitious",
79
+ ]
80
+ social = rnd.choice(social_descriptors)
81
+ inner = rnd.choice(inner_descriptors)
82
+
83
+ identity_f1 = f"{social} {role_f}"
84
+ identity_f2 = f"{inner} {role_f}"
85
+ identity_m1 = f"{social} {role_m}"
86
+ identity_m2 = f"{inner} {role_m}"
87
+
88
+ # -------------------------
89
+ # Skin tone (shared)
90
+ # -------------------------
91
+ skin_tones = [
92
+ "very pale skincolor",
93
+ "fair skincolor",
94
+ "light olive skincolor",
95
+ "olive skincolor",
96
+ "tan skincolor",
97
+ "dark-tan skincolor",
98
+ "brown skincolor",
99
+ "dark-brown skincolor",
100
+ ]
101
+ skin = rnd.choice(skin_tones)
102
+
103
+ # -------------------------
104
+ # Category 5: eyes = color + style + gaze direction
105
+ # (no eyewear)
106
+ # -------------------------
107
+ eye_colors = [
108
+ "blue eyes",
109
+ "green eyes",
110
+ "hazel eyes",
111
+ "amber eyes",
112
+ "grey eyes",
113
+ "dark-brown eyes",
114
+ "light-brown eyes",
115
+ "violet eyes",
116
+ ]
117
+ eye_styles = [
118
+ "sharp eyes",
119
+ "narrow eyes",
120
+ "gentle eyes",
121
+ "wide eyes",
122
+ "sleepy eyes",
123
+ "intense eyes",
124
+ "cold eyes",
125
+ "warm eyes",
126
+ "mischievous eyes",
127
+ "tired eyes",
128
+ ]
129
+ eye_directions = [
130
+ "",
131
+ ]
132
+ eye_color = rnd.choice(eye_colors)
133
+ eye_style = rnd.choice(eye_styles)
134
+ eye_direction = rnd.choice(eye_directions)
135
+ eyes = ", ".join([eye_color, eye_style, eye_direction])
136
+
137
+ # -------------------------
138
+ # Category 6: hair (color, length, hairstyle)
139
+ # Hair colors: avoid ambiguous "red hair", use "ginger" etc.
140
+ # -------------------------
141
+ hair_colors = [
142
+ "black hair",
143
+ "ginger hair",
144
+ "dark-brown hair",
145
+ "light-brown hair",
146
+ "chestnut-brown hair",
147
+ "platinum-blonde hair",
148
+ "ash-blonde hair",
149
+ "golden-blonde hair",
150
+ "silver hair",
151
+ "white hair",
152
+ "grey hair",
153
+ "blue-dyed hair",
154
+ "pink-dyed hair",
155
+ "purple-dyed hair",
156
+ ]
157
+ hair_lengths = [
158
+ "very short hair",
159
+ "short hair",
160
+ "medium-length hair",
161
+ "long hair",
162
+ "very long hair",
163
+ ]
164
+ hair_styles = [
165
+ "straight hair",
166
+ "wavy hair",
167
+ "curly hair",
168
+ "messy hair",
169
+ "neatly combed hair",
170
+ "braided hair",
171
+ "pony tail hair",
172
+ "twin braids hair",
173
+ "bun hair",
174
+ ]
175
+ hair = ", ".join([
176
+ rnd.choice(hair_colors),
177
+ rnd.choice(hair_lengths),
178
+ rnd.choice(hair_styles),
179
+ ])
180
+
181
+ # -------------------------
182
+ # Category 7: top garment
183
+ # color + topgarment, material + topgarment, adjective + topgarment
184
+ # e.g. "red shirt, linen shirt, torn shirt"
185
+ # -------------------------
186
+ top_colors = [
187
+ "red", "blue", "green", "yellow", "black",
188
+ "white", "grey", "brown", "purple", "pink", "beige",
189
+ ]
190
+ top_types = ["shirt", "blouse", "hoodie", "jacket", "sweater", "coat", "vest", "tank top"]
191
+ top_materials_by_type = {
192
+ "shirt": ["linen", "cotton", "silk"],
193
+ "blouse": ["linen", "cotton", "silk", "chiffon"],
194
+ "hoodie": ["cotton", "fleece", "synthetic"],
195
+ "jacket": ["leather", "denim", "canvas"],
196
+ "sweater": ["wool", "cotton", "cashmere"],
197
+ "coat": ["wool", "cotton"],
198
+ "vest": ["leather", "denim", "cotton"],
199
+ "tank top": ["cotton", "synthetic"],
200
+ }
201
+ top_adjectives = [
202
+ "torn", "elegant", "simple", "expensive",
203
+ "casual", "formal", "wrinkled", "clean",
204
+ "ornate", "plain", "striped", "checkered",
205
+ "logo-print", "oversized", "fitted", "loose",
206
+ ]
207
+
208
+ top_type = rnd.choice(top_types)
209
+ top_color = rnd.choice(top_colors)
210
+ top_material = rnd.choice(top_materials_by_type[top_type])
211
+ top_adj = rnd.choice(top_adjectives)
212
+
213
+ top = ", ".join([
214
+ f"{top_color} {top_type}",
215
+ f"{top_material} {top_type}",
216
+ f"{top_adj} {top_type}",
217
+ ])
218
+
219
+ # -------------------------
220
+ # Category 8: bottom garment (NO SKIRT)
221
+ # color + bottom, material + bottom, adjective + bottom
222
+ # -------------------------
223
+ bottom_colors = [
224
+ "black", "blue", "dark-blue", "grey",
225
+ "brown", "white", "khaki", "olive", "burgundy",
226
+ ]
227
+ bottom_types = ["pants", "jeans", "shorts", "cargo pants", "leggings"]
228
+ bottom_materials_by_type = {
229
+ "pants": ["wool", "cotton", "denim", "leather"],
230
+ "jeans": ["denim"],
231
+ "shorts": ["cotton", "denim"],
232
+ "cargo pants": ["cotton", "canvas"],
233
+ "leggings": ["cotton", "synthetic"],
234
+ }
235
+ bottom_adjectives = [
236
+ "slim", "baggy", "loose", "tight",
237
+ "high-waist", "low-waist", "ripped", "clean",
238
+ "casual", "formal", "wrinkled", "plain",
239
+ "patterned", "striped", "folded-hem",
240
+ ]
241
+
242
+ bottom_type = rnd.choice(bottom_types)
243
+ bottom_color = rnd.choice(bottom_colors)
244
+ bottom_material = rnd.choice(bottom_materials_by_type[bottom_type])
245
+ bottom_adj = rnd.choice(bottom_adjectives)
246
+
247
+ bottom = ", ".join([
248
+ f"{bottom_color} {bottom_type}",
249
+ f"{bottom_material} {bottom_type}",
250
+ f"{bottom_adj} {bottom_type}",
251
+ ])
252
+
253
+ # -------------------------
254
+ # Category 9: footwear
255
+ # color + footwear, adjective + footwear, adjective + footwear
256
+ # -------------------------
257
+ foot_colors = ["black", "brown", "grey", "white", "red", "blue", "tan"]
258
+ footwear_types = [
259
+ "boots", "sneakers", "shoes", "sandals",
260
+ "loafers", "ankle boots", "knee-high boots",
261
+ ]
262
+ footwear_adjectives = [
263
+ "leather", "worn", "polished", "dirty",
264
+ "sporty", "elegant", "heavy", "thick-soled",
265
+ "lace-up", "strapped", "high-heeled", "flat",
266
+ ]
267
+
268
+ footwear = rnd.choice(footwear_types)
269
+ foot_color = rnd.choice(foot_colors)
270
+ foot_adj1 = rnd.choice(footwear_adjectives)
271
+ remaining = [a for a in footwear_adjectives if a != foot_adj1]
272
+ foot_adj2 = rnd.choice(remaining) if remaining else foot_adj1
273
+
274
+ feet = ", ".join([
275
+ f"{foot_color} {footwear}",
276
+ f"{foot_adj1} {footwear}",
277
+ f"{foot_adj2} {footwear}",
278
+ ])
279
+
280
+
281
+ # -------------------------
282
+ # Assemble prompts
283
+ # -------------------------
284
+ parts_f = [
285
+ category1_f, # 1girl
286
+ pov, # POV string
287
+ role_f, # woman/girl/grandma
288
+ identity_f1, # social descriptor
289
+ identity_f2, # inner personality
290
+ skin, # skincolor
291
+ eyes, # eye color + style + direction
292
+ hair, # hair
293
+ top, # top garment
294
+ bottom, # bottom garment (no skirt)
295
+ feet, # footwear
296
+ ]
297
+
298
+ parts_m = [
299
+ category1_m, # 1boy
300
+ pov,
301
+ role_m, # man/boy/grandpa
302
+ identity_m1,
303
+ identity_m2,
304
+ skin,
305
+ eyes,
306
+ hair,
307
+ top,
308
+ bottom,
309
+ feet,
310
+ ]
311
+
312
+ female_prompt = ", ".join(parts_f) + "."
313
+ male_prompt = ", ".join(parts_m) + "."
314
+
315
+ return (female_prompt, male_prompt)
316
+
317
+
318
+ # ComfyUI requires these mappings at module level
319
+ NODE_CLASS_MAPPINGS = {
320
+ "Wildcard_1": Wildcard_1,
321
+ }
322
+
323
+ NODE_DISPLAY_NAME_MAPPINGS = {
324
+ "Wildcard_1": "Wildcard_1",
325
+ }