feat: Image Pool accepts optional POOL_PROFILE (profile or pool_id)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+15
-8
@@ -26,6 +26,11 @@ class GridImagePool:
|
|||||||
"index": ("INT", {"default": -1, "min": -1, "max": 9999}),
|
"index": ("INT", {"default": -1, "min": -1, "max": 9999}),
|
||||||
"pool_id": ("STRING", {"default": "default"}),
|
"pool_id": ("STRING", {"default": "default"}),
|
||||||
},
|
},
|
||||||
|
# optional companion input: a Pool Profile node feeds the profile id
|
||||||
|
# here; when connected it overrides pool_id (see `effective` below).
|
||||||
|
"optional": {
|
||||||
|
"profile": ("POOL_PROFILE",),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@@ -35,13 +40,14 @@ class GridImagePool:
|
|||||||
idx = pool.resolve_slot(m, index)
|
idx = pool.resolve_slot(m, index)
|
||||||
return base, m, idx
|
return base, m, idx
|
||||||
|
|
||||||
def run(self, index, pool_id="default"):
|
def run(self, index, pool_id="default", profile=None):
|
||||||
base, m, idx = self._resolve(index, pool_id)
|
effective = profile or pool_id
|
||||||
|
base, m, idx = self._resolve(index, effective)
|
||||||
if idx < 0:
|
if idx < 0:
|
||||||
img, mask = imaging.empty_outputs()
|
img, mask = imaging.empty_outputs()
|
||||||
return (img, mask, 0, 0, "")
|
return (img, mask, 0, 0, "")
|
||||||
slot = m["slots"][idx]
|
slot = m["slots"][idx]
|
||||||
d = pool.pool_dir(base, pool_id)
|
d = pool.pool_dir(base, effective)
|
||||||
img = imaging.load_image_tensor(str(d / slot["image"]))
|
img = imaging.load_image_tensor(str(d / slot["image"]))
|
||||||
h, w = int(img.shape[1]), int(img.shape[2])
|
h, w = int(img.shape[1]), int(img.shape[2])
|
||||||
mask_name = slot.get("mask")
|
mask_name = slot.get("mask")
|
||||||
@@ -49,19 +55,20 @@ class GridImagePool:
|
|||||||
return (img, mask, idx, len(m["slots"]), slot.get("label", ""))
|
return (img, mask, idx, len(m["slots"]), slot.get("label", ""))
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def IS_CHANGED(cls, index, pool_id="default", **kwargs):
|
def IS_CHANGED(cls, index, pool_id="default", profile=None, **kwargs):
|
||||||
base, m, idx = cls._resolve(index, pool_id)
|
effective = profile or pool_id
|
||||||
|
base, m, idx = cls._resolve(index, effective)
|
||||||
if idx < 0:
|
if idx < 0:
|
||||||
return imaging.change_hash(pool_id, -1, [])
|
return imaging.change_hash(effective, -1, [])
|
||||||
slot = m["slots"][idx]
|
slot = m["slots"][idx]
|
||||||
d = pool.pool_dir(base, pool_id)
|
d = pool.pool_dir(base, effective)
|
||||||
mtimes = []
|
mtimes = []
|
||||||
for key in ("image", "mask"):
|
for key in ("image", "mask"):
|
||||||
name = slot.get(key)
|
name = slot.get(key)
|
||||||
p = d / name if name else None
|
p = d / name if name else None
|
||||||
mtimes.append(os.path.getmtime(p) if p and p.exists() else 0.0)
|
mtimes.append(os.path.getmtime(p) if p and p.exists() else 0.0)
|
||||||
# include active so manual selection changes invalidate cache
|
# include active so manual selection changes invalidate cache
|
||||||
return imaging.change_hash(pool_id, f"{idx}:{m.get('active')}", mtimes)
|
return imaging.change_hash(effective, f"{idx}:{m.get('active')}", mtimes)
|
||||||
|
|
||||||
|
|
||||||
NODE_CLASS_MAPPINGS = {"GridImagePool": GridImagePool}
|
NODE_CLASS_MAPPINGS = {"GridImagePool": GridImagePool}
|
||||||
|
|||||||
@@ -54,3 +54,17 @@ def test_is_changed_differs_after_active_change(tmp_path, monkeypatch):
|
|||||||
pool.set_active(base, "p1", 1)
|
pool.set_active(base, "p1", 1)
|
||||||
h2 = node.GridImagePool.IS_CHANGED(index=-1, pool_id="p1")
|
h2 = node.GridImagePool.IS_CHANGED(index=-1, pool_id="p1")
|
||||||
assert h1 != h2
|
assert h1 != h2
|
||||||
|
|
||||||
|
|
||||||
|
def test_profile_input_overrides_pool_id(tmp_path, monkeypatch):
|
||||||
|
base = str(tmp_path / "grid_pool")
|
||||||
|
monkeypatch.setattr(node, "_grid_pool_base", lambda: base)
|
||||||
|
import io
|
||||||
|
from PIL import Image
|
||||||
|
from gates import pool
|
||||||
|
buf = io.BytesIO(); Image.new("RGB", (4, 6), (255, 0, 0)).save(buf, "PNG")
|
||||||
|
pool.add_image(base, "prof1", buf.getvalue(), ts=1) # images under the PROFILE id
|
||||||
|
n = node.GridImagePool()
|
||||||
|
# pool_id is "default" (empty) but profile points at prof1
|
||||||
|
img, mask, idx, count, label = n.run(index=-1, pool_id="default", profile="prof1")
|
||||||
|
assert count == 1 and idx == 0
|
||||||
|
|||||||
Reference in New Issue
Block a user