Delete xyz_grid.py
Browse files- xyz_grid.py +0 -285
xyz_grid.py
DELETED
|
@@ -1,285 +0,0 @@
|
|
| 1 |
-
"""
|
| 2 |
-
lib_mega_freeu/global_state.py
|
| 3 |
-
Runtime state, data structures, presets for ⚡ Mega FreeU.
|
| 4 |
-
|
| 5 |
-
Sources:
|
| 6 |
-
sd-webui-freeu/lib_free_u/global_state.py -- StageInfo layout, State, preset JSON, XYZ
|
| 7 |
-
WAS FreeU_Advanced/nodes.py -- BLEND_MODE_NAMES, MSCALES
|
| 8 |
-
ComfyUI_FreeU_V2_Advanced/FreeU_B1B2.py -- b_start/b_end, channel_threshold
|
| 9 |
-
ComfyUI_FreeU_V2_Advanced/FreeU_S1S2.py -- s_start/s_end, adaptive cap
|
| 10 |
-
nrs_kohaku_enhanced_v3_5.py -- hf_boost, gaussian standalone
|
| 11 |
-
"""
|
| 12 |
-
import dataclasses
|
| 13 |
-
import json
|
| 14 |
-
import math
|
| 15 |
-
import pathlib
|
| 16 |
-
import re
|
| 17 |
-
import sys
|
| 18 |
-
from typing import Any, Dict, List, Optional, Union
|
| 19 |
-
|
| 20 |
-
# ─── Blending modes (WAS FreeU_Advanced/nodes.py blending_modes keys) ─────────
|
| 21 |
-
BLEND_MODE_NAMES: List[str] = [
|
| 22 |
-
"lerp", "inject", "bislerp", "colorize",
|
| 23 |
-
"cosine interp", "cuberp", "hslerp", "stable_slerp", "linear dodge",
|
| 24 |
-
]
|
| 25 |
-
|
| 26 |
-
# ─── Multi-scale presets (WAS nodes.py mscales dict -- exact) ─────────────────
|
| 27 |
-
MSCALES: Dict[str, Optional[list]] = {
|
| 28 |
-
"Default": None,
|
| 29 |
-
"Low-Pass": [(10, 1.0)],
|
| 30 |
-
"Pass-Through": [(10, 1.0)],
|
| 31 |
-
"Gaussian-Blur": [(10, 0.5)],
|
| 32 |
-
"Edge-Enhancement": [(10, 2.0)],
|
| 33 |
-
"Sharpen": [(10, 1.5)],
|
| 34 |
-
"Multi-Bandpass": [[(5, 0.0), (15, 1.0), (25, 0.0)]],
|
| 35 |
-
"Multi-Low-Pass": [[(5, 1.0), (10, 0.5), (15, 0.2)]],
|
| 36 |
-
"Multi-High-Pass": [[(5, 0.0), (10, 0.5), (15, 0.8)]],
|
| 37 |
-
"Multi-Pass-Through": [[(5, 1.0), (10, 1.0), (15, 1.0)]],
|
| 38 |
-
"Multi-Gaussian-Blur": [[(5, 0.5), (10, 0.8), (15, 0.2)]],
|
| 39 |
-
"Multi-Edge-Enhancement": [[(5, 1.2), (10, 1.5), (15, 2.0)]],
|
| 40 |
-
"Multi-Sharpen": [[(5, 1.5), (10, 2.0), (15, 2.5)]],
|
| 41 |
-
}
|
| 42 |
-
|
| 43 |
-
ALL_VERSIONS: Dict[str, str] = {"Version 1": "1", "Version 2": "2"}
|
| 44 |
-
REVERSED_VERSIONS: Dict[str, str] = {v: k for k, v in ALL_VERSIONS.items()}
|
| 45 |
-
FFT_TYPES: List[str] = ["gaussian", "box"]
|
| 46 |
-
STAGES_COUNT: int = 3
|
| 47 |
-
|
| 48 |
-
_shorthand_re = re.compile(r"^([a-z]{1,3})(\d+)$")
|
| 49 |
-
|
| 50 |
-
# ─── StageInfo ─────────────────────────────────────────────────────────────────
|
| 51 |
-
@dataclasses.dataclass
|
| 52 |
-
class StageInfo:
|
| 53 |
-
"""
|
| 54 |
-
All per-stage parameters.
|
| 55 |
-
Fields 1-6: same order as sd-webui-freeu for PNG backwards compat.
|
| 56 |
-
New fields appended at end.
|
| 57 |
-
"""
|
| 58 |
-
# sd-webui-freeu compat (DO NOT REORDER first 6)
|
| 59 |
-
backbone_factor: float = 1.0
|
| 60 |
-
skip_factor: float = 1.0
|
| 61 |
-
backbone_offset: float = 0.0
|
| 62 |
-
backbone_width: float = 0.5
|
| 63 |
-
skip_cutoff: float = 0.0
|
| 64 |
-
skip_high_end_factor: float = 1.0
|
| 65 |
-
# WAS blending
|
| 66 |
-
backbone_blend_mode: str = "lerp"
|
| 67 |
-
backbone_blend: float = 1.0
|
| 68 |
-
# ComfyUI V2 independent timestep ranges
|
| 69 |
-
b_start_ratio: float = 0.0
|
| 70 |
-
b_end_ratio: float = 1.0
|
| 71 |
-
s_start_ratio: float = 0.0
|
| 72 |
-
s_end_ratio: float = 1.0
|
| 73 |
-
# FFT
|
| 74 |
-
fft_type: str = "box"
|
| 75 |
-
fft_radius_ratio: float = 0.07
|
| 76 |
-
hf_boost: float = 1.0
|
| 77 |
-
# Adaptive Cap (FreeU_S1S2)
|
| 78 |
-
enable_adaptive_cap: bool = False
|
| 79 |
-
cap_threshold: float = 0.35
|
| 80 |
-
cap_factor: float = 0.6
|
| 81 |
-
adaptive_cap_mode: str = "adaptive"
|
| 82 |
-
|
| 83 |
-
def to_dict(self, include_default=False):
|
| 84 |
-
default = StageInfo()
|
| 85 |
-
d = dataclasses.asdict(self)
|
| 86 |
-
if not include_default:
|
| 87 |
-
d = {k: v for k, v in d.items() if v != getattr(default, k)}
|
| 88 |
-
return d
|
| 89 |
-
|
| 90 |
-
def copy(self):
|
| 91 |
-
return StageInfo(**dataclasses.asdict(self))
|
| 92 |
-
|
| 93 |
-
STAGE_FIELD_NAMES = [f.name for f in dataclasses.fields(StageInfo)]
|
| 94 |
-
STAGE_FIELD_COUNT = len(STAGE_FIELD_NAMES)
|
| 95 |
-
|
| 96 |
-
# ─── State ─────────────────────────────────────────────────────────────────────
|
| 97 |
-
@dataclasses.dataclass
|
| 98 |
-
class State:
|
| 99 |
-
enable: bool = True
|
| 100 |
-
start_ratio: Any = 0.0
|
| 101 |
-
stop_ratio: Any = 1.0
|
| 102 |
-
transition_smoothness: float = 0.0
|
| 103 |
-
version: str = "1"
|
| 104 |
-
multiscale_mode: str = "Default"
|
| 105 |
-
multiscale_strength: float = 1.0
|
| 106 |
-
override_scales: str = ""
|
| 107 |
-
channel_threshold: int = 96
|
| 108 |
-
stage_infos: List[Any] = dataclasses.field(
|
| 109 |
-
default_factory=lambda: [StageInfo() for _ in range(STAGES_COUNT)]
|
| 110 |
-
)
|
| 111 |
-
# Post-CFG Shift (WAS_PostCFGShift) — stored in presets & PNG
|
| 112 |
-
pcfg_enabled: bool = False
|
| 113 |
-
pcfg_steps: int = 20
|
| 114 |
-
pcfg_mode: str = "inject"
|
| 115 |
-
pcfg_blend: float = 1.0
|
| 116 |
-
pcfg_b: float = 1.1
|
| 117 |
-
pcfg_fourier: bool = False
|
| 118 |
-
pcfg_ms_mode: str = "Default"
|
| 119 |
-
pcfg_ms_str: float = 1.0
|
| 120 |
-
pcfg_threshold: int = 1
|
| 121 |
-
pcfg_s: float = 0.5
|
| 122 |
-
pcfg_gain: float = 1.0
|
| 123 |
-
verbose: bool = False
|
| 124 |
-
|
| 125 |
-
def __post_init__(self):
|
| 126 |
-
self.stage_infos = self._coerce_stages()
|
| 127 |
-
self.version = ALL_VERSIONS.get(self.version, self.version)
|
| 128 |
-
|
| 129 |
-
def _coerce_stages(self):
|
| 130 |
-
result, raw = [], list(self.stage_infos)
|
| 131 |
-
i = 0
|
| 132 |
-
while i < len(raw) and len(result) < STAGES_COUNT:
|
| 133 |
-
item = raw[i]
|
| 134 |
-
if isinstance(item, StageInfo):
|
| 135 |
-
result.append(item); i += 1
|
| 136 |
-
elif isinstance(item, dict):
|
| 137 |
-
known = {k: v for k, v in item.items() if k in STAGE_FIELD_NAMES}
|
| 138 |
-
result.append(StageInfo(**known)); i += 1
|
| 139 |
-
else:
|
| 140 |
-
chunk = raw[i:i+STAGE_FIELD_COUNT]
|
| 141 |
-
result.append(StageInfo(*chunk))
|
| 142 |
-
i += STAGE_FIELD_COUNT
|
| 143 |
-
while len(result) < STAGES_COUNT:
|
| 144 |
-
result.append(StageInfo())
|
| 145 |
-
return result
|
| 146 |
-
|
| 147 |
-
def to_dict(self):
|
| 148 |
-
d = dataclasses.asdict(self)
|
| 149 |
-
d["stage_infos"] = [si.to_dict() for si in self.stage_infos]
|
| 150 |
-
del d["enable"]
|
| 151 |
-
return d
|
| 152 |
-
|
| 153 |
-
def copy(self):
|
| 154 |
-
d = dataclasses.asdict(self)
|
| 155 |
-
d["stage_infos"] = [StageInfo(**s) for s in d["stage_infos"]]
|
| 156 |
-
return State(**d)
|
| 157 |
-
|
| 158 |
-
def update_attr(self, key, value):
|
| 159 |
-
if m := _shorthand_re.match(key):
|
| 160 |
-
char, idx = m.group(1), int(m.group(2))
|
| 161 |
-
if 0 <= idx < STAGES_COUNT:
|
| 162 |
-
si = self.stage_infos[idx]
|
| 163 |
-
_MAP = {
|
| 164 |
-
"b":"backbone_factor","s":"skip_factor","o":"backbone_offset",
|
| 165 |
-
"w":"backbone_width","t":"skip_cutoff","h":"skip_high_end_factor",
|
| 166 |
-
"bm":"backbone_blend_mode","bb":"backbone_blend",
|
| 167 |
-
"bs":"b_start_ratio","be":"b_end_ratio",
|
| 168 |
-
"ss":"s_start_ratio","se":"s_end_ratio",
|
| 169 |
-
"ft":"fft_type","fr":"fft_radius_ratio","hfb":"hf_boost",
|
| 170 |
-
"cap":"enable_adaptive_cap","ct":"cap_threshold","cf":"cap_factor","acm":"adaptive_cap_mode",
|
| 171 |
-
}
|
| 172 |
-
if char in _MAP:
|
| 173 |
-
setattr(si, _MAP[char], value); return
|
| 174 |
-
if hasattr(self, key):
|
| 175 |
-
setattr(self, key, value)
|
| 176 |
-
|
| 177 |
-
# ─── Singletons ────────────────────────────────────────────────────────────────
|
| 178 |
-
instance: State = State()
|
| 179 |
-
xyz_attrs: Dict[str, Any] = {}
|
| 180 |
-
current_sampling_step: int = 0
|
| 181 |
-
|
| 182 |
-
# ─── Preset builders ───────────────────────────────────────────────────────────
|
| 183 |
-
def _v1(*pairs):
|
| 184 |
-
infos = [StageInfo(backbone_factor=b, skip_factor=s) for b,s in pairs]
|
| 185 |
-
while len(infos) < STAGES_COUNT: infos.append(StageInfo())
|
| 186 |
-
return State(version="1", stage_infos=infos)
|
| 187 |
-
|
| 188 |
-
def _v2g(pairs):
|
| 189 |
-
infos = []
|
| 190 |
-
for b, s, r, hfb, bs, be, ss, se in pairs:
|
| 191 |
-
infos.append(StageInfo(
|
| 192 |
-
backbone_factor=b, skip_factor=s,
|
| 193 |
-
fft_type="gaussian", fft_radius_ratio=r, hf_boost=hfb,
|
| 194 |
-
b_start_ratio=bs, b_end_ratio=be,
|
| 195 |
-
s_start_ratio=ss, s_end_ratio=se,
|
| 196 |
-
))
|
| 197 |
-
while len(infos) < STAGES_COUNT: infos.append(StageInfo())
|
| 198 |
-
return State(version="2", stage_infos=infos)
|
| 199 |
-
|
| 200 |
-
default_presets: Dict[str, State] = {
|
| 201 |
-
"SD1.4 Recommendations": _v1((1.2,0.9),(1.4,0.2),(1.0,1.0)),
|
| 202 |
-
"SD2.1 Recommendations": _v1((1.1,0.9),(1.2,0.2),(1.0,1.0)),
|
| 203 |
-
"SDXL Recommendations": _v1((1.1,0.6),(1.2,0.4),(1.0,1.0)),
|
| 204 |
-
"SD1.5 V2 Gaussian": _v2g([
|
| 205 |
-
(1.2,0.9,0.07,1.0, 0.0,0.35, 0.35,1.0),
|
| 206 |
-
(1.4,0.2,0.07,1.0, 0.0,0.35, 0.35,1.0),
|
| 207 |
-
]),
|
| 208 |
-
"SD1.5 V2 High Detail": _v2g([
|
| 209 |
-
(1.4,0.8,0.08,1.2, 0.0,0.35, 0.35,1.0),
|
| 210 |
-
(1.6,0.1,0.06,1.0, 0.0,0.35, 0.35,1.0),
|
| 211 |
-
]),
|
| 212 |
-
"SDXL V2 Gaussian": _v2g([
|
| 213 |
-
(1.1,0.6,0.05,1.1, 0.0,0.35, 0.35,1.0),
|
| 214 |
-
(1.2,0.4,0.05,1.1, 0.0,0.35, 0.35,1.0),
|
| 215 |
-
]),
|
| 216 |
-
"SD1.5 Adaptive Cap": State(version="2", stage_infos=[
|
| 217 |
-
StageInfo(backbone_factor=1.3,skip_factor=0.9,
|
| 218 |
-
fft_type="gaussian",fft_radius_ratio=0.08,hf_boost=1.2,
|
| 219 |
-
b_start_ratio=0.0,b_end_ratio=0.35,
|
| 220 |
-
s_start_ratio=0.35,s_end_ratio=1.0,
|
| 221 |
-
enable_adaptive_cap=True,cap_threshold=0.35,
|
| 222 |
-
cap_factor=0.6,adaptive_cap_mode="adaptive"),
|
| 223 |
-
StageInfo(backbone_factor=1.4,skip_factor=0.2,
|
| 224 |
-
fft_type="gaussian",fft_radius_ratio=0.06,hf_boost=1.0,
|
| 225 |
-
b_start_ratio=0.0,b_end_ratio=0.35,
|
| 226 |
-
s_start_ratio=0.35,s_end_ratio=1.0,
|
| 227 |
-
enable_adaptive_cap=True,cap_threshold=0.70,
|
| 228 |
-
cap_factor=0.6,adaptive_cap_mode="adaptive"),
|
| 229 |
-
StageInfo(),
|
| 230 |
-
]),
|
| 231 |
-
"Independent B/S (SD1.5)": _v2g([
|
| 232 |
-
(1.2,0.9,0.07,1.0, 0.0,0.35, 0.35,1.0),
|
| 233 |
-
(1.4,0.2,0.06,1.0, 0.0,0.35, 0.35,1.0),
|
| 234 |
-
]),
|
| 235 |
-
}
|
| 236 |
-
|
| 237 |
-
all_presets: Dict[str, State] = {}
|
| 238 |
-
PRESETS_PATH = pathlib.Path(__file__).parent.parent / "presets.json"
|
| 239 |
-
|
| 240 |
-
def reload_presets():
|
| 241 |
-
all_presets.clear()
|
| 242 |
-
all_presets.update(default_presets)
|
| 243 |
-
all_presets.update(_load_user_presets())
|
| 244 |
-
|
| 245 |
-
def _load_user_presets():
|
| 246 |
-
if not PRESETS_PATH.exists(): return {}
|
| 247 |
-
try:
|
| 248 |
-
with open(PRESETS_PATH, encoding="utf-8") as f:
|
| 249 |
-
raw = json.load(f)
|
| 250 |
-
except Exception as e:
|
| 251 |
-
print(f"[MegaFreeU] preset load error: {e}", file=sys.stderr)
|
| 252 |
-
return {}
|
| 253 |
-
result = {}
|
| 254 |
-
_state_fields = {f.name for f in dataclasses.fields(State)}
|
| 255 |
-
for k, v in raw.items():
|
| 256 |
-
try:
|
| 257 |
-
# Filter unknown keys so future/old fields don't crash State(**v)
|
| 258 |
-
known = {fk: fv for fk, fv in v.items() if fk in _state_fields}
|
| 259 |
-
result[k] = State(**known)
|
| 260 |
-
except Exception as e:
|
| 261 |
-
print(f"[MegaFreeU] skipping preset {k!r}: {e}", file=sys.stderr)
|
| 262 |
-
return result
|
| 263 |
-
|
| 264 |
-
def save_presets(custom=None):
|
| 265 |
-
if custom is None: custom = get_user_presets()
|
| 266 |
-
try:
|
| 267 |
-
PRESETS_PATH.parent.mkdir(parents=True, exist_ok=True)
|
| 268 |
-
with open(PRESETS_PATH, "w", encoding="utf-8") as f:
|
| 269 |
-
json.dump({k: v.to_dict() for k,v in custom.items()}, f, indent=4)
|
| 270 |
-
except Exception as e:
|
| 271 |
-
print(f"[MegaFreeU] preset save error: {e}", file=sys.stderr)
|
| 272 |
-
|
| 273 |
-
def get_user_presets():
|
| 274 |
-
return {k: v for k,v in all_presets.items() if k not in default_presets}
|
| 275 |
-
|
| 276 |
-
def apply_xyz():
|
| 277 |
-
global instance
|
| 278 |
-
if pk := xyz_attrs.get("preset"):
|
| 279 |
-
if p := all_presets.get(pk):
|
| 280 |
-
instance = p.copy()
|
| 281 |
-
elif pk != "UI Settings":
|
| 282 |
-
print(f"[MegaFreeU] XYZ preset '{pk}' not found", file=sys.stderr)
|
| 283 |
-
for k, v in xyz_attrs.items():
|
| 284 |
-
if k != "preset":
|
| 285 |
-
instance.update_attr(k, v)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|