mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2026-02-10 13:32:36 +08:00
Merge branch 'master' of https://github.com/comfyanonymous/ComfyUI into ci-quality-workflows
This commit is contained in:
commit
26c8e8bcdb
@ -390,11 +390,20 @@ def get_mask_aabb(masks):
|
|||||||
|
|
||||||
return bounding_boxes, is_empty
|
return bounding_boxes, is_empty
|
||||||
|
|
||||||
def resolve_cond_masks(conditions, h, w, device):
|
def resolve_areas_and_cond_masks(conditions, h, w, device):
|
||||||
# We need to decide on an area outside the sampling loop in order to properly generate opposite areas of equal sizes.
|
# We need to decide on an area outside the sampling loop in order to properly generate opposite areas of equal sizes.
|
||||||
# While we're doing this, we can also resolve the mask device and scaling for performance reasons
|
# While we're doing this, we can also resolve the mask device and scaling for performance reasons
|
||||||
for i in range(len(conditions)):
|
for i in range(len(conditions)):
|
||||||
c = conditions[i]
|
c = conditions[i]
|
||||||
|
if 'area' in c[1]:
|
||||||
|
area = c[1]['area']
|
||||||
|
if area[0] == "percentage":
|
||||||
|
modified = c[1].copy()
|
||||||
|
area = (max(1, round(area[1] * h)), max(1, round(area[2] * w)), round(area[3] * h), round(area[4] * w))
|
||||||
|
modified['area'] = area
|
||||||
|
c = [c[0], modified]
|
||||||
|
conditions[i] = c
|
||||||
|
|
||||||
if 'mask' in c[1]:
|
if 'mask' in c[1]:
|
||||||
mask = c[1]['mask']
|
mask = c[1]['mask']
|
||||||
mask = mask.to(device=device)
|
mask = mask.to(device=device)
|
||||||
@ -622,8 +631,8 @@ class KSampler:
|
|||||||
positive = positive[:]
|
positive = positive[:]
|
||||||
negative = negative[:]
|
negative = negative[:]
|
||||||
|
|
||||||
resolve_cond_masks(positive, noise.shape[2], noise.shape[3], self.device)
|
resolve_areas_and_cond_masks(positive, noise.shape[2], noise.shape[3], self.device)
|
||||||
resolve_cond_masks(negative, noise.shape[2], noise.shape[3], self.device)
|
resolve_areas_and_cond_masks(negative, noise.shape[2], noise.shape[3], self.device)
|
||||||
|
|
||||||
calculate_start_end_timesteps(self.model_wrap, negative)
|
calculate_start_end_timesteps(self.model_wrap, negative)
|
||||||
calculate_start_end_timesteps(self.model_wrap, positive)
|
calculate_start_end_timesteps(self.model_wrap, positive)
|
||||||
|
|||||||
@ -121,17 +121,22 @@ def add_model_folder_path(folder_name, full_folder_path):
|
|||||||
def get_folder_paths(folder_name):
|
def get_folder_paths(folder_name):
|
||||||
return folder_names_and_paths[folder_name][0][:]
|
return folder_names_and_paths[folder_name][0][:]
|
||||||
|
|
||||||
def recursive_search(directory):
|
def recursive_search(directory, excluded_dir_names=None):
|
||||||
if not os.path.isdir(directory):
|
if not os.path.isdir(directory):
|
||||||
return [], {}
|
return [], {}
|
||||||
|
|
||||||
|
if excluded_dir_names is None:
|
||||||
|
excluded_dir_names = []
|
||||||
|
|
||||||
result = []
|
result = []
|
||||||
dirs = {directory: os.path.getmtime(directory)}
|
dirs = {directory: os.path.getmtime(directory)}
|
||||||
for root, subdir, file in os.walk(directory, followlinks=True):
|
for dirpath, subdirs, filenames in os.walk(directory, followlinks=True, topdown=True):
|
||||||
for filepath in file:
|
subdirs[:] = [d for d in subdirs if d not in excluded_dir_names]
|
||||||
#we os.path,join directory with a blank string to generate a path separator at the end.
|
for file_name in filenames:
|
||||||
result.append(os.path.join(root, filepath).replace(os.path.join(directory,''),''))
|
relative_path = os.path.relpath(os.path.join(dirpath, file_name), directory)
|
||||||
for d in subdir:
|
result.append(relative_path)
|
||||||
path = os.path.join(root, d)
|
for d in subdirs:
|
||||||
|
path = os.path.join(dirpath, d)
|
||||||
dirs[path] = os.path.getmtime(path)
|
dirs[path] = os.path.getmtime(path)
|
||||||
return result, dirs
|
return result, dirs
|
||||||
|
|
||||||
@ -159,7 +164,7 @@ def get_filename_list_(folder_name):
|
|||||||
folders = folder_names_and_paths[folder_name]
|
folders = folder_names_and_paths[folder_name]
|
||||||
output_folders = {}
|
output_folders = {}
|
||||||
for x in folders[0]:
|
for x in folders[0]:
|
||||||
files, folders_all = recursive_search(x)
|
files, folders_all = recursive_search(x, excluded_dir_names=[".git"])
|
||||||
output_list.update(filter_files_extensions(files, folders[1]))
|
output_list.update(filter_files_extensions(files, folders[1]))
|
||||||
output_folders = {**output_folders, **folders_all}
|
output_folders = {**output_folders, **folders_all}
|
||||||
|
|
||||||
|
|||||||
27
nodes.py
27
nodes.py
@ -159,6 +159,31 @@ class ConditioningSetArea:
|
|||||||
c.append(n)
|
c.append(n)
|
||||||
return (c, )
|
return (c, )
|
||||||
|
|
||||||
|
class ConditioningSetAreaPercentage:
|
||||||
|
@classmethod
|
||||||
|
def INPUT_TYPES(s):
|
||||||
|
return {"required": {"conditioning": ("CONDITIONING", ),
|
||||||
|
"width": ("FLOAT", {"default": 1.0, "min": 0, "max": 1.0, "step": 0.01}),
|
||||||
|
"height": ("FLOAT", {"default": 1.0, "min": 0, "max": 1.0, "step": 0.01}),
|
||||||
|
"x": ("FLOAT", {"default": 0, "min": 0, "max": 1.0, "step": 0.01}),
|
||||||
|
"y": ("FLOAT", {"default": 0, "min": 0, "max": 1.0, "step": 0.01}),
|
||||||
|
"strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.01}),
|
||||||
|
}}
|
||||||
|
RETURN_TYPES = ("CONDITIONING",)
|
||||||
|
FUNCTION = "append"
|
||||||
|
|
||||||
|
CATEGORY = "conditioning"
|
||||||
|
|
||||||
|
def append(self, conditioning, width, height, x, y, strength):
|
||||||
|
c = []
|
||||||
|
for t in conditioning:
|
||||||
|
n = [t[0], t[1].copy()]
|
||||||
|
n[1]['area'] = ("percentage", height, width, y, x)
|
||||||
|
n[1]['strength'] = strength
|
||||||
|
n[1]['set_area_to_bounds'] = False
|
||||||
|
c.append(n)
|
||||||
|
return (c, )
|
||||||
|
|
||||||
class ConditioningSetMask:
|
class ConditioningSetMask:
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def INPUT_TYPES(s):
|
||||||
@ -1583,6 +1608,7 @@ NODE_CLASS_MAPPINGS = {
|
|||||||
"ConditioningCombine": ConditioningCombine,
|
"ConditioningCombine": ConditioningCombine,
|
||||||
"ConditioningConcat": ConditioningConcat,
|
"ConditioningConcat": ConditioningConcat,
|
||||||
"ConditioningSetArea": ConditioningSetArea,
|
"ConditioningSetArea": ConditioningSetArea,
|
||||||
|
"ConditioningSetAreaPercentage": ConditioningSetAreaPercentage,
|
||||||
"ConditioningSetMask": ConditioningSetMask,
|
"ConditioningSetMask": ConditioningSetMask,
|
||||||
"KSamplerAdvanced": KSamplerAdvanced,
|
"KSamplerAdvanced": KSamplerAdvanced,
|
||||||
"SetLatentNoiseMask": SetLatentNoiseMask,
|
"SetLatentNoiseMask": SetLatentNoiseMask,
|
||||||
@ -1644,6 +1670,7 @@ NODE_DISPLAY_NAME_MAPPINGS = {
|
|||||||
"ConditioningAverage ": "Conditioning (Average)",
|
"ConditioningAverage ": "Conditioning (Average)",
|
||||||
"ConditioningConcat": "Conditioning (Concat)",
|
"ConditioningConcat": "Conditioning (Concat)",
|
||||||
"ConditioningSetArea": "Conditioning (Set Area)",
|
"ConditioningSetArea": "Conditioning (Set Area)",
|
||||||
|
"ConditioningSetAreaPercentage": "Conditioning (Set Area with Percentage)",
|
||||||
"ConditioningSetMask": "Conditioning (Set Mask)",
|
"ConditioningSetMask": "Conditioning (Set Mask)",
|
||||||
"ControlNetApply": "Apply ControlNet",
|
"ControlNetApply": "Apply ControlNet",
|
||||||
"ControlNetApplyAdvanced": "Apply ControlNet (Advanced)",
|
"ControlNetApplyAdvanced": "Apply ControlNet (Advanced)",
|
||||||
|
|||||||
@ -11529,7 +11529,7 @@ LGraphNode.prototype.executeAction = function(action)
|
|||||||
if (timeout) {
|
if (timeout) {
|
||||||
clearInterval(timeout);
|
clearInterval(timeout);
|
||||||
}
|
}
|
||||||
timeout = setTimeout(refreshHelper, 250);
|
timeout = setTimeout(refreshHelper, 10);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|||||||
@ -717,6 +717,10 @@ export class ComfyApp {
|
|||||||
this.loadGraphData(workflow);
|
this.loadGraphData(workflow);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
if (e.target.type === "text" || e.target.type === "textarea") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Litegraph default paste
|
// Litegraph default paste
|
||||||
this.canvas.pasteFromClipboard();
|
this.canvas.pasteFromClipboard();
|
||||||
}
|
}
|
||||||
@ -1224,6 +1228,7 @@ export class ComfyApp {
|
|||||||
const inputData = inputs[inputName];
|
const inputData = inputs[inputName];
|
||||||
const type = inputData[0];
|
const type = inputData[0];
|
||||||
|
|
||||||
|
let widgetCreated = true;
|
||||||
if (Array.isArray(type)) {
|
if (Array.isArray(type)) {
|
||||||
// Enums
|
// Enums
|
||||||
Object.assign(config, widgets.COMBO(this, inputName, inputData, app) || {});
|
Object.assign(config, widgets.COMBO(this, inputName, inputData, app) || {});
|
||||||
@ -1236,8 +1241,10 @@ export class ComfyApp {
|
|||||||
} else {
|
} else {
|
||||||
// Node connection inputs
|
// Node connection inputs
|
||||||
this.addInput(inputName, type);
|
this.addInput(inputName, type);
|
||||||
|
widgetCreated = false;
|
||||||
}
|
}
|
||||||
if(inputData[1]?.forceInput && config?.widget) {
|
|
||||||
|
if(widgetCreated && inputData[1]?.forceInput && config?.widget) {
|
||||||
if (!config.widget.options) config.widget.options = {};
|
if (!config.widget.options) config.widget.options = {};
|
||||||
config.widget.options.forceInput = inputData[1].forceInput;
|
config.widget.options.forceInput = inputData[1].forceInput;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user