diff --git a/README.md b/README.md index 3a1fa2dff..03d2978a6 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ [github-downloads-latest-shield]: https://img.shields.io/github/downloads/comfyanonymous/ComfyUI/latest/total?style=flat&label=downloads%40latest [github-downloads-link]: https://github.com/comfyanonymous/ComfyUI/releases -![ComfyUI Screenshot](comfyui_screenshot.png) +![ComfyUI Screenshot](https://github.com/user-attachments/assets/7ccaf2c1-9b72-41ae-9a89-5688c94b7abe) This ui will let you design and execute advanced stable diffusion pipelines using a graph/nodes/flowchart based interface. For some workflow examples and see what ComfyUI can do you can check out: diff --git a/api_server/services/terminal_service.py b/api_server/services/terminal_service.py index 284afab5a..ed788d9a4 100644 --- a/api_server/services/terminal_service.py +++ b/api_server/services/terminal_service.py @@ -1,5 +1,6 @@ from app.logger import on_flush import os +import shutil class TerminalService: @@ -10,15 +11,27 @@ class TerminalService: self.subscriptions = set() on_flush(self.send_messages) + def get_terminal_size(self): + try: + size = os.get_terminal_size() + return (size.columns, size.lines) + except OSError: + try: + size = shutil.get_terminal_size() + return (size.columns, size.lines) + except OSError: + return (80, 24) # fallback to 80x24 + def update_size(self): - sz = os.get_terminal_size() + columns, lines = self.get_terminal_size() changed = False - if sz.columns != self.cols: - self.cols = sz.columns + + if columns != self.cols: + self.cols = columns changed = True - if sz.lines != self.rows: - self.rows = sz.lines + if lines != self.rows: + self.rows = lines changed = True if changed: diff --git a/comfy/model_base.py b/comfy/model_base.py index f28331682..7e92ca107 100644 --- a/comfy/model_base.py +++ b/comfy/model_base.py @@ -153,8 +153,7 @@ class BaseModel(torch.nn.Module): def encode_adm(self, **kwargs): return None - def extra_conds(self, **kwargs): - out = {} + def concat_cond(self, **kwargs): if len(self.concat_keys) > 0: cond_concat = [] denoise_mask = kwargs.get("concat_mask", kwargs.get("denoise_mask", None)) @@ -193,7 +192,14 @@ class BaseModel(torch.nn.Module): elif ck == "masked_image": cond_concat.append(self.blank_inpaint_image_like(noise)) data = torch.cat(cond_concat, dim=1) - out['c_concat'] = comfy.conds.CONDNoiseShape(data) + return data + return None + + def extra_conds(self, **kwargs): + out = {} + concat_cond = self.concat_cond(**kwargs) + if concat_cond is not None: + out['c_concat'] = comfy.conds.CONDNoiseShape(concat_cond) adm = self.encode_adm(**kwargs) if adm is not None: @@ -523,9 +529,7 @@ class SD_X4Upscaler(BaseModel): return out class IP2P: - def extra_conds(self, **kwargs): - out = {} - + def concat_cond(self, **kwargs): image = kwargs.get("concat_latent_image", None) noise = kwargs.get("noise", None) device = kwargs["device"] @@ -537,18 +541,15 @@ class IP2P: image = utils.common_upscale(image.to(device), noise.shape[-1], noise.shape[-2], "bilinear", "center") image = utils.resize_to_batch_size(image, noise.shape[0]) + return self.process_ip2p_image_in(image) - out['c_concat'] = comfy.conds.CONDNoiseShape(self.process_ip2p_image_in(image)) - adm = self.encode_adm(**kwargs) - if adm is not None: - out['y'] = comfy.conds.CONDRegular(adm) - return out class SD15_instructpix2pix(IP2P, BaseModel): def __init__(self, model_config, model_type=ModelType.EPS, device=None): super().__init__(model_config, model_type, device=device) self.process_ip2p_image_in = lambda image: image + class SDXL_instructpix2pix(IP2P, SDXL): def __init__(self, model_config, model_type=ModelType.EPS, device=None): super().__init__(model_config, model_type, device=device) diff --git a/comfyui_screenshot.png b/comfyui_screenshot.png deleted file mode 100644 index 73272eae6..000000000 Binary files a/comfyui_screenshot.png and /dev/null differ diff --git a/nodes.py b/nodes.py index 1ac817a20..300cfcf17 100644 --- a/nodes.py +++ b/nodes.py @@ -382,6 +382,7 @@ class InpaintModelConditioning: "vae": ("VAE", ), "pixels": ("IMAGE", ), "mask": ("MASK", ), + "add_noise_mask": ("BOOLEAN", {"default": True, "tooltip": "Add a noise mask to the latent so sampling will only happen within the mask. Might improve results or completely break things depending on the model."}), }} RETURN_TYPES = ("CONDITIONING","CONDITIONING","LATENT") @@ -390,7 +391,7 @@ class InpaintModelConditioning: CATEGORY = "conditioning/inpaint" - def encode(self, positive, negative, pixels, vae, mask): + def encode(self, positive, negative, pixels, vae, mask, add_noise_mask): x = (pixels.shape[1] // 8) * 8 y = (pixels.shape[2] // 8) * 8 mask = torch.nn.functional.interpolate(mask.reshape((-1, 1, mask.shape[-2], mask.shape[-1])), size=(pixels.shape[1], pixels.shape[2]), mode="bilinear") @@ -414,7 +415,8 @@ class InpaintModelConditioning: out_latent = {} out_latent["samples"] = orig_latent - out_latent["noise_mask"] = mask + if add_noise_mask: + out_latent["noise_mask"] = mask out = [] for conditioning in [positive, negative]: