diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 459074c..f1a13a4 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -13,7 +13,7 @@ body: label: Full console logs description: | The full console log of your terminal. - From `Python 3.10.*, Version: v1.*, Commit hash: *` to the end. + From `Python 3.*, Version: ..., Commit hash: ...` to the end. render: Shell validations: required: true diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index bbcbbe7..0000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for this project -title: '' -labels: '' -assignees: '' - ---- - -**Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] - -**Describe the solution you'd like** -A clear and concise description of what you want to happen. - -**Describe alternatives you've considered** -A clear and concise description of any alternative solutions or features you've considered. - -**Additional context** -Add any other context or screenshots about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.yaml b/.github/ISSUE_TEMPLATE/feature_request.yaml new file mode 100644 index 0000000..c496137 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yaml @@ -0,0 +1,24 @@ +name: Feature request +description: Suggest an idea for this project +title: "[Feature Request]: " + +body: + - type: textarea + attributes: + label: Is your feature request related to a problem? Please describe. + description: A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + + - type: textarea + attributes: + label: Describe the solution you'd like + description: A clear and concise description of what you want to happen. + + - type: textarea + attributes: + label: Describe alternatives you've considered + description: A clear and concise description of any alternative solutions or features you've considered. + + - type: textarea + attributes: + label: Additional context + description: Add any other context or screenshots about the feature request here. diff --git a/CHANGELOG.md b/CHANGELOG.md index 1cd0dc9..ea080f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 2023-06-05 + +- v23.6.2 +- xyz_grid에서 ADetailer를 사용할 수 있게함. + - 8가지 옵션만 1st 탭에 적용되도록 함. + ## 2023-06-01 - v23.6.1 diff --git a/adetailer/__version__.py b/adetailer/__version__.py index b5bbe5b..54cb9a0 100644 --- a/adetailer/__version__.py +++ b/adetailer/__version__.py @@ -1 +1 @@ -__version__ = "23.6.1.post0" +__version__ = "23.6.2" diff --git a/adetailer/ui.py b/adetailer/ui.py index d31921c..a0439a1 100644 --- a/adetailer/ui.py +++ b/adetailer/ui.py @@ -287,7 +287,7 @@ def inpainting(w: Widgets, n: int, is_img2img: bool): label="Inpaint only masked" + suffix(n), value=True, visible=True, - elem_id=eid("ad_inpaint_full_res"), + elem_id=eid("ad_inpaint_only_masked"), ) w.ad_inpaint_only_masked_padding = gr.Slider( label="Inpaint only masked padding, pixels" + suffix(n), @@ -296,7 +296,7 @@ def inpainting(w: Widgets, n: int, is_img2img: bool): step=4, value=32, visible=True, - elem_id=eid("ad_inpaint_full_res_padding"), + elem_id=eid("ad_inpaint_only_masked_padding"), ) w.ad_inpaint_only_masked.change( diff --git a/scripts/!adetailer.py b/scripts/!adetailer.py index 5b62fb3..07ed494 100644 --- a/scripts/!adetailer.py +++ b/scripts/!adetailer.py @@ -7,6 +7,7 @@ import sys import traceback from contextlib import contextmanager, suppress from copy import copy, deepcopy +from functools import partial from pathlib import Path from textwrap import dedent from typing import Any @@ -26,7 +27,7 @@ from adetailer.args import ALL_ARGS, BBOX_SORTBY, ADetailerArgs, EnableChecker from adetailer.common import PredictOutput from adetailer.mask import filter_by_ratio, mask_preprocess, sort_bboxes from adetailer.ui import adui, ordinal, suffix -from controlnet_ext import ControlNetExt, controlnet_exists +from controlnet_ext import ControlNetExt, controlnet_exists, get_cn_models from controlnet_ext.restore import ( CNHijackRestore, cn_allow_script_control, @@ -157,7 +158,7 @@ class AfterDetailerScript(scripts.Script): checker = EnableChecker(a0=a0, a1=a1) return checker.is_enabled() - def get_args(self, *args_) -> list[ADetailerArgs]: + def get_args(self, p, *args_) -> list[ADetailerArgs]: """ `args_` is at least 1 in length by `is_ad_enabled` immediately above """ @@ -167,6 +168,9 @@ class AfterDetailerScript(scripts.Script): message = f"[-] ADetailer: Invalid arguments passed to ADetailer: {args_!r}" raise ValueError(message) + if hasattr(p, "adetailer_xyz"): + args[0].update(p.adetailer_xyz) + all_inputs = [] for n, arg_dict in enumerate(args, 1): @@ -448,7 +452,7 @@ class AfterDetailerScript(scripts.Script): return if self.is_ad_enabled(*args_): - arg_list = self.get_args(*args_) + arg_list = self.get_args(p, *args_) extra_params = self.extra_params(arg_list) p.extra_generation_params.update(extra_params) @@ -538,7 +542,7 @@ class AfterDetailerScript(scripts.Script): p._idx = getattr(p, "_idx", -1) + 1 init_image = copy(pp.image) - arg_list = self.get_args(*args_) + arg_list = self.get_args(p, *args_) is_processed = False with CNHijackRestore(), pause_total_tqdm(), cn_allow_script_control(): @@ -630,5 +634,87 @@ def on_ui_settings(): ) +# xyz_grid + + +def make_axis_on_xyz_grid(): + xyz_grid = None + for script in scripts.scripts_data: + if script.script_class.__module__ == "xyz_grid.py": + xyz_grid = script.module + break + + if xyz_grid is None: + return + + model_list = ["None"] + list(model_mapping.keys()) + + def set_value(p, x, xs, *, field: str): + if not hasattr(p, "adetailer_xyz"): + p.adetailer_xyz = {} + p.adetailer_xyz[field] = x + + axis = [ + xyz_grid.AxisOption( + "[ADetailer] ADetailer model 1st", + str, + partial(set_value, field="ad_model"), + choices=lambda: model_list, + ), + xyz_grid.AxisOption( + "[ADetailer] ADetailer prompt 1st", + str, + partial(set_value, field="ad_prompt"), + ), + xyz_grid.AxisOption( + "[ADetailer] ADetailer negative prompt 1st", + str, + partial(set_value, field="ad_negative_prompt"), + ), + xyz_grid.AxisOption( + "[ADetailer] Mask erosion / dilation 1st", + int, + partial(set_value, field="ad_dilate_erode"), + ), + xyz_grid.AxisOption( + "[ADetailer] Inpaint denoising strength 1st", + float, + partial(set_value, field="ad_denoising_strength"), + ), + xyz_grid.AxisOption( + "[ADetailer] Inpaint only masked 1st", + str, + partial(set_value, field="ad_inpaint_only_masked"), + choices=lambda: ["True", "False"], + ), + xyz_grid.AxisOption( + "[ADetailer] Inpaint only masked padding 1st", + int, + partial(set_value, field="ad_inpaint_only_masked_padding"), + ), + xyz_grid.AxisOption( + "[ADetailer] ControlNet model 1st", + str, + partial(set_value, field="ad_controlnet_model"), + choices=lambda: ["None"] + get_cn_models(), + ), + ] + + if not any(x.label.startswith("[ADetailer]") for x in xyz_grid.axis_options): + xyz_grid.axis_options.extend(axis) + + +def on_before_ui(): + try: + make_axis_on_xyz_grid() + except Exception: + error = traceback.format_exc() + print( + f"[-] ADetailer: xyz_grid error:\n{error}", + file=sys.stderr, + ) + + script_callbacks.on_ui_settings(on_ui_settings) script_callbacks.on_after_component(on_after_component) +script_callbacks.on_before_ui(on_before_ui) diff --git a/sd_webui/script_callbacks.py b/sd_webui/script_callbacks.py index 5183e47..06f99fa 100644 --- a/sd_webui/script_callbacks.py +++ b/sd_webui/script_callbacks.py @@ -11,5 +11,12 @@ if TYPE_CHECKING: def on_after_component(callback: Callable): pass + def on_before_ui(callback: Callable): + pass + else: - from modules.script_callbacks import on_after_component, on_ui_settings + from modules.script_callbacks import ( + on_after_component, + on_before_ui, + on_ui_settings, + ) diff --git a/sd_webui/scripts.py b/sd_webui/scripts.py index a161a8b..e515bbb 100644 --- a/sd_webui/scripts.py +++ b/sd_webui/scripts.py @@ -4,6 +4,7 @@ from typing import TYPE_CHECKING if TYPE_CHECKING: from abc import ABC, abstractmethod + from collections import namedtuple from dataclasses import dataclass from typing import Any @@ -79,5 +80,15 @@ if TYPE_CHECKING: def elem_id(self, item_id: Any) -> str: pass + ScriptClassData = namedtuple( + "ScriptClassData", ["script_class", "path", "basedir", "module"] + ) + scripts_data: list[ScriptClassData] = [] + else: - from modules.scripts import AlwaysVisible, PostprocessImageArgs, Script + from modules.scripts import ( + AlwaysVisible, + PostprocessImageArgs, + Script, + scripts_data, + )