StupidGame's picture
Upload 1941 files
baa8e90
import traceback
import comfy
import nodes
import numpy as np
import torch
import torch.nn.functional as F
from . import prompt_support
class RegionalPromptSimple:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"basic_pipe": ("BASIC_PIPE",),
"mask": ("MASK",),
"cfg": ("FLOAT", {"default": 8.0, "min": 0.0, "max": 100.0}),
"sampler_name": (comfy.samplers.KSampler.SAMPLERS,),
"scheduler": (comfy.samplers.KSampler.SCHEDULERS,),
"wildcard_prompt": ("STRING", {"multiline": True, "dynamicPrompts": False, "placeholder": "wildcard prompt"}),
"controlnet_in_pipe": ("BOOLEAN", {"default": False, "label_on": "Keep", "label_off": "Override"}),
},
}
RETURN_TYPES = ("REGIONAL_PROMPTS", )
FUNCTION = "doit"
CATEGORY = "InspirePack/Regional"
def doit(self, basic_pipe, mask, cfg, sampler_name, scheduler, wildcard_prompt, controlnet_in_pipe=False):
if 'RegionalPrompt' not in nodes.NODE_CLASS_MAPPINGS:
raise Exception(f"[ERROR] To use RegionalPromptSimple, you need to install 'ComfyUI-Impact-Pack'")
model, clip, vae, positive, negative = basic_pipe
iwe = nodes.NODE_CLASS_MAPPINGS['ImpactWildcardEncode']()
kap = nodes.NODE_CLASS_MAPPINGS['KSamplerAdvancedProvider']()
rp = nodes.NODE_CLASS_MAPPINGS['RegionalPrompt']()
if wildcard_prompt != "":
model, clip, new_positive, _ = iwe.doit(model=model, clip=clip, populated_text=wildcard_prompt)
if controlnet_in_pipe:
prev_cnet = None
for t in positive:
if 'control' in t[1] and 'control_apply_to_uncond' in t[1]:
prev_cnet = t[1]['control'], t[1]['control_apply_to_uncond']
break
if prev_cnet is not None:
for t in new_positive:
t[1]['control'] = prev_cnet[0]
t[1]['control_apply_to_uncond'] = prev_cnet[1]
else:
new_positive = positive
basic_pipe = model, clip, vae, new_positive, negative
sampler = kap.doit(cfg, sampler_name, scheduler, basic_pipe)[0]
regional_prompts = rp.doit(mask, sampler)[0]
return (regional_prompts, )
def color_to_mask(color_mask, mask_color):
try:
if mask_color.startswith("#"):
selected = int(mask_color[1:], 16)
else:
selected = int(mask_color, 10)
except Exception:
raise Exception(f"[ERROR] Invalid mask_color value. mask_color should be a color value for RGB")
temp = (torch.clamp(color_mask, 0, 1.0) * 255.0).round().to(torch.int)
temp = torch.bitwise_left_shift(temp[:, :, :, 0], 16) + torch.bitwise_left_shift(temp[:, :, :, 1], 8) + temp[:, :, :, 2]
mask = torch.where(temp == selected, 1.0, 0.0)
return mask
class RegionalPromptColorMask:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"basic_pipe": ("BASIC_PIPE",),
"color_mask": ("IMAGE",),
"mask_color": ("STRING", {"multiline": False, "default": "#FFFFFF"}),
"cfg": ("FLOAT", {"default": 8.0, "min": 0.0, "max": 100.0}),
"sampler_name": (comfy.samplers.KSampler.SAMPLERS,),
"scheduler": (comfy.samplers.KSampler.SCHEDULERS,),
"wildcard_prompt": ("STRING", {"multiline": True, "dynamicPrompts": False, "placeholder": "wildcard prompt"}),
"controlnet_in_pipe": ("BOOLEAN", {"default": False, "label_on": "Keep", "label_off": "Override"}),
},
}
RETURN_TYPES = ("REGIONAL_PROMPTS", "MASK")
FUNCTION = "doit"
CATEGORY = "InspirePack/Regional"
def doit(self, basic_pipe, color_mask, mask_color, cfg, sampler_name, scheduler, wildcard_prompt, controlnet_in_pipe=False):
mask = color_to_mask(color_mask, mask_color)
rp = RegionalPromptSimple().doit(basic_pipe, mask, cfg, sampler_name, scheduler, wildcard_prompt, controlnet_in_pipe)[0]
return (rp, mask)
class RegionalConditioningSimple:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"clip": ("CLIP", ),
"mask": ("MASK",),
"strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.01}),
"set_cond_area": (["default", "mask bounds"],),
"prompt": ("STRING", {"multiline": True, "placeholder": "prompt"}),
},
}
RETURN_TYPES = ("CONDITIONING", )
FUNCTION = "doit"
CATEGORY = "InspirePack/Regional"
def doit(self, clip, mask, strength, set_cond_area, prompt):
conditioning = nodes.CLIPTextEncode().encode(clip, prompt)[0]
conditioning = nodes.ConditioningSetMask().append(conditioning, mask, set_cond_area, strength)[0]
return (conditioning, )
class RegionalConditioningColorMask:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"clip": ("CLIP", ),
"color_mask": ("IMAGE",),
"mask_color": ("STRING", {"multiline": False, "default": "#FFFFFF"}),
"strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.01}),
"set_cond_area": (["default", "mask bounds"],),
"prompt": ("STRING", {"multiline": True, "placeholder": "prompt"}),
},
}
RETURN_TYPES = ("CONDITIONING", "MASK")
FUNCTION = "doit"
CATEGORY = "InspirePack/Regional"
def doit(self, clip, color_mask, mask_color, strength, set_cond_area, prompt):
mask = color_to_mask(color_mask, mask_color)
conditioning = nodes.CLIPTextEncode().encode(clip, prompt)[0]
conditioning = nodes.ConditioningSetMask().append(conditioning, mask, set_cond_area, strength)[0]
return (conditioning, mask)
class ToIPAdapterPipe:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"ipadapter": ("IPADAPTER", ),
"clip_vision": ("CLIP_VISION",),
"model": ("MODEL", ),
}
}
RETURN_TYPES = ("IPADAPTER_PIPE",)
FUNCTION = "doit"
CATEGORY = "InspirePack/Util"
def doit(self, ipadapter, clip_vision, model):
pipe = ipadapter, clip_vision, model
return (pipe,)
class FromIPAdapterPipe:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"ipadapter_pipe": ("IPADAPTER_PIPE", ),
}
}
RETURN_TYPES = ("IPADAPTER", "CLIP_VISION", "MODEL")
FUNCTION = "doit"
CATEGORY = "InspirePack/Util"
def doit(self, ipadapter_pipe):
return ipadapter_pipe
class IPAdapterConditioning:
def __init__(self, mask, weight, weight_type, noise=None, image=None, embeds=None):
self.mask = mask
self.image = image
self.embeds = embeds
self.weight = weight
self.noise = noise
self.weight_type = weight_type
def doit(self, ipadapter, clip_vision, model):
if 'IPAdapterApply' not in nodes.NODE_CLASS_MAPPINGS:
raise Exception(f"[ERROR] To use Regional IPAdapter, you need to install 'ComfyUI_IPAdapter_plus'")
obj = nodes.NODE_CLASS_MAPPINGS['IPAdapterApply']
if self.image is None:
clip_vision = None
model = obj().apply_ipadapter(ipadapter, model, self.weight, clip_vision=clip_vision, image=self.image,
embeds=self.embeds, weight_type=self.weight_type, noise=self.noise,
attn_mask=self.mask)[0]
return model
class RegionalIPAdapterMask:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"mask": ("MASK",),
"image": ("IMAGE",),
"weight": ("FLOAT", {"default": 0.7, "min": -1, "max": 3, "step": 0.05}),
"noise": ("FLOAT", {"default": 0.5, "min": 0.0, "max": 1.0, "step": 0.01}),
"weight_type": (["original", "linear", "channel penalty"],),
},
}
RETURN_TYPES = ("REGIONAL_IPADAPTER", )
FUNCTION = "doit"
CATEGORY = "InspirePack/Regional"
def doit(self, mask, image, weight, noise, weight_type):
cond = IPAdapterConditioning(mask, weight, weight_type, noise=noise, image=image)
return (cond, )
class RegionalIPAdapterColorMask:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"color_mask": ("IMAGE",),
"mask_color": ("STRING", {"multiline": False, "default": "#FFFFFF"}),
"image": ("IMAGE",),
"weight": ("FLOAT", {"default": 0.7, "min": -1, "max": 3, "step": 0.05}),
"noise": ("FLOAT", {"default": 0.5, "min": 0.0, "max": 1.0, "step": 0.01}),
"weight_type": (["original", "linear", "channel penalty"], ),
},
}
RETURN_TYPES = ("REGIONAL_IPADAPTER", "MASK")
FUNCTION = "doit"
CATEGORY = "InspirePack/Regional"
def doit(self, color_mask, mask_color, image, weight, noise, weight_type):
mask = color_to_mask(color_mask, mask_color)
cond = IPAdapterConditioning(mask, weight, weight_type, noise=noise, image=image)
return (cond, mask)
class RegionalIPAdapterEncodedMask:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"mask": ("MASK",),
"embeds": ("embeds",),
"weight": ("FLOAT", {"default": 0.7, "min": -1, "max": 3, "step": 0.05}),
"weight_type": (["original", "linear", "channel penalty"],),
},
}
RETURN_TYPES = ("REGIONAL_IPADAPTER", )
FUNCTION = "doit"
CATEGORY = "InspirePack/Regional"
def doit(self, mask, embeds, weight, weight_type):
cond = IPAdapterConditioning(mask, weight, weight_type, embeds=embeds)
return (cond, )
class RegionalIPAdapterEncodedColorMask:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"color_mask": ("IMAGE",),
"mask_color": ("STRING", {"multiline": False, "default": "#FFFFFF"}),
"embeds": ("EMBEDS",),
"weight": ("FLOAT", {"default": 0.7, "min": -1, "max": 3, "step": 0.05}),
"weight_type": (["original", "linear", "channel penalty"],),
},
}
RETURN_TYPES = ("REGIONAL_IPADAPTER", "MASK")
FUNCTION = "doit"
CATEGORY = "InspirePack/Regional"
def doit(self, color_mask, mask_color, embeds, weight, weight_type):
mask = color_to_mask(color_mask, mask_color)
cond = IPAdapterConditioning(mask, weight, weight_type, embeds=embeds)
return (cond, mask)
class ApplyRegionalIPAdapters:
@classmethod
def INPUT_TYPES(s):
return {"required": {
"ipadapter_pipe": ("IPADAPTER_PIPE",),
"regional_ipadapter1": ("REGIONAL_IPADAPTER", ),
},
}
RETURN_TYPES = ("MODEL", )
FUNCTION = "doit"
CATEGORY = "InspirePack/Regional"
def doit(self, **kwargs):
ipadapter_pipe = kwargs['ipadapter_pipe']
ipadapter, clip_vision, model = ipadapter_pipe
del kwargs['ipadapter_pipe']
for k, v in kwargs.items():
model = v.doit(ipadapter, clip_vision, model)
return (model, )
class RegionalSeedExplorerMask:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"mask": ("MASK",),
"noise": ("NOISE",),
"seed_prompt": ("STRING", {"multiline": True, "dynamicPrompts": False, "pysssss.autocomplete": False}),
"enable_additional": ("BOOLEAN", {"default": True, "label_on": "true", "label_off": "false"}),
"additional_seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}),
"additional_strength": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.01}),
"noise_mode": (["GPU(=A1111)", "CPU"],),
},
}
RETURN_TYPES = ("NOISE",)
FUNCTION = "doit"
CATEGORY = "InspirePack/Regional"
def doit(self, mask, noise, seed_prompt, enable_additional, additional_seed, additional_strength, noise_mode):
device = comfy.model_management.get_torch_device()
noise_device = "cpu" if noise_mode == "CPU" else device
noise = noise.to(device)
mask = mask.to(device)
if len(mask.shape) == 2:
mask = mask.unsqueeze(0)
mask = torch.nn.functional.interpolate(mask.reshape((-1, 1, mask.shape[-2], mask.shape[-1])), size=(noise.shape[2], noise.shape[3]), mode="bilinear").squeeze(0)
try:
seed_prompt = seed_prompt.replace("\n", "")
items = seed_prompt.strip().split(",")
if items == ['']:
items = []
if enable_additional:
items.append((additional_seed, additional_strength))
noise = prompt_support.SeedExplorer.apply_variation(noise, items, noise_device, mask)
except Exception:
print(f"[ERROR] IGNORED: RegionalSeedExplorerColorMask is failed.")
traceback.print_exc()
noise = noise.cpu()
mask.cpu()
return (noise,)
class RegionalSeedExplorerColorMask:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"color_mask": ("IMAGE",),
"mask_color": ("STRING", {"multiline": False, "default": "#FFFFFF"}),
"noise": ("NOISE",),
"seed_prompt": ("STRING", {"multiline": True, "dynamicPrompts": False, "pysssss.autocomplete": False}),
"enable_additional": ("BOOLEAN", {"default": True, "label_on": "true", "label_off": "false"}),
"additional_seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}),
"additional_strength": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.01}),
"noise_mode": (["GPU(=A1111)", "CPU"],),
},
}
RETURN_TYPES = ("NOISE", "MASK")
FUNCTION = "doit"
CATEGORY = "InspirePack/Regional"
def doit(self, color_mask, mask_color, noise, seed_prompt, enable_additional, additional_seed, additional_strength, noise_mode):
device = comfy.model_management.get_torch_device()
noise_device = "cpu" if noise_mode == "CPU" else device
color_mask = color_mask.to(device)
noise = noise.to(device)
mask = color_to_mask(color_mask, mask_color)
original_mask = mask
mask = torch.nn.functional.interpolate(mask.reshape((-1, 1, mask.shape[-2], mask.shape[-1])), size=(noise.shape[2], noise.shape[3]), mode="bilinear").squeeze(0)
mask = mask.to(device)
try:
seed_prompt = seed_prompt.replace("\n", "")
items = seed_prompt.strip().split(",")
if items == ['']:
items = []
if enable_additional:
items.append((additional_seed, additional_strength))
noise = prompt_support.SeedExplorer.apply_variation(noise, items, noise_device, mask)
except Exception:
print(f"[ERROR] IGNORED: RegionalSeedExplorerColorMask is failed.")
traceback.print_exc()
color_mask.cpu()
noise = noise.cpu()
original_mask = original_mask.cpu()
return (noise, original_mask)
NODE_CLASS_MAPPINGS = {
"RegionalPromptSimple //Inspire": RegionalPromptSimple,
"RegionalPromptColorMask //Inspire": RegionalPromptColorMask,
"RegionalConditioningSimple //Inspire": RegionalConditioningSimple,
"RegionalConditioningColorMask //Inspire": RegionalConditioningColorMask,
"RegionalIPAdapterMask //Inspire": RegionalIPAdapterMask,
"RegionalIPAdapterColorMask //Inspire": RegionalIPAdapterColorMask,
"RegionalIPAdapterEncodedMask //Inspire": RegionalIPAdapterEncodedMask,
"RegionalIPAdapterEncodedColorMask //Inspire": RegionalIPAdapterEncodedColorMask,
"RegionalSeedExplorerMask //Inspire": RegionalSeedExplorerMask,
"RegionalSeedExplorerColorMask //Inspire": RegionalSeedExplorerColorMask,
"ToIPAdapterPipe //Inspire": ToIPAdapterPipe,
"FromIPAdapterPipe //Inspire": FromIPAdapterPipe,
"ApplyRegionalIPAdapters //Inspire": ApplyRegionalIPAdapters,
}
NODE_DISPLAY_NAME_MAPPINGS = {
"RegionalPromptSimple //Inspire": "Regional Prompt Simple (Inspire)",
"RegionalPromptColorMask //Inspire": "Regional Prompt By Color Mask (Inspire)",
"RegionalConditioningSimple //Inspire": "Regional Conditioning Simple (Inspire)",
"RegionalConditioningColorMask //Inspire": "Regional Conditioning By Color Mask (Inspire)",
"RegionalIPAdapterMask //Inspire": "Regional IPAdapter Mask (Inspire)",
"RegionalIPAdapterColorMask //Inspire": "Regional IPAdapter By Color Mask (Inspire)",
"RegionalIPAdapterEncodedMask //Inspire": "Regional IPAdapter Encoded Mask (Inspire)",
"RegionalIPAdapterEncodedColorMask //Inspire": "Regional IPAdapter Encoded By Color Mask (Inspire)",
"RegionalSeedExplorerMask //Inspire": "Regional Seed Explorer By Mask (Inspire)",
"RegionalSeedExplorerColorMask //Inspire": "Regional Seed Explorer By Color Mask (Inspire)",
"ToIPAdapterPipe //Inspire": "ToIPAdapterPipe (Inspire)",
"FromIPAdapterPipe //Inspire": "FromIPAdapterPipe (Inspire)",
"ApplyRegionalIPAdapters //Inspire": "Apply Regional IPAdapters (Inspire)"
}