Add accumulator preview and batch save node
This commit is contained in:
+46
-2
@@ -117,6 +117,15 @@ COMMON_INPUT_TOOLTIPS = {
|
||||
"image": "Image to store in the accumulator.",
|
||||
"entry_id": "Stable ID used for replace_by_entry_id or grouping variants.",
|
||||
"entry_tag": "Optional suffix added to entry_id.",
|
||||
"preview_limit": "Maximum number of accumulator images to show in the preview panel.",
|
||||
"delete_action": "Optional execution-time delete operation. JS buttons can delete interactively without setting this.",
|
||||
"delete_entry_id": "Entry id to delete when delete_action is delete_entry_id.",
|
||||
"delete_index": "1-based entry index to delete when delete_action is delete_index. 0 disables it.",
|
||||
"save_batch": "When enabled, save all current accumulator images once finished is true.",
|
||||
"finished": "Gate for saving. Outside a loop, leave true; inside a loop, wire a final-iteration signal.",
|
||||
"save_path": "Folder to save the accumulator batch. Relative paths are inside ComfyUI output; absolute paths are used directly.",
|
||||
"filename_prefix": "Filename prefix for saved accumulator images.",
|
||||
"clear_after_save": "Clear the accumulator store after a successful batch save.",
|
||||
"clothing": "Built-in clothing density for legacy direct generation. Category/profile nodes can override this.",
|
||||
"poses": "Built-in pose pool for legacy direct generation.",
|
||||
"backside_bias": "Legacy bias toward rear/backside poses where that category supports it.",
|
||||
@@ -317,7 +326,13 @@ def _install_input_tooltips(node_classes: dict[str, type]) -> None:
|
||||
node_class._sxcp_tooltips_installed = True
|
||||
|
||||
try:
|
||||
from .loop_nodes import ANY_TYPE, LOOP_NODE_CLASS_MAPPINGS, LOOP_NODE_DISPLAY_NAME_MAPPINGS
|
||||
from .loop_nodes import (
|
||||
ANY_TYPE,
|
||||
LOOP_NODE_CLASS_MAPPINGS,
|
||||
LOOP_NODE_DISPLAY_NAME_MAPPINGS,
|
||||
accumulator_delete_entries,
|
||||
accumulator_list_entries,
|
||||
)
|
||||
from .prompt_builder import (
|
||||
build_camera_config_json,
|
||||
build_camera_orbit_config_json,
|
||||
@@ -386,7 +401,13 @@ try:
|
||||
from .caption_naturalizer import naturalize_caption
|
||||
from .krea_formatter import format_krea2_prompt
|
||||
except ImportError:
|
||||
from loop_nodes import ANY_TYPE, LOOP_NODE_CLASS_MAPPINGS, LOOP_NODE_DISPLAY_NAME_MAPPINGS
|
||||
from loop_nodes import (
|
||||
ANY_TYPE,
|
||||
LOOP_NODE_CLASS_MAPPINGS,
|
||||
LOOP_NODE_DISPLAY_NAME_MAPPINGS,
|
||||
accumulator_delete_entries,
|
||||
accumulator_list_entries,
|
||||
)
|
||||
from prompt_builder import (
|
||||
build_camera_config_json,
|
||||
build_camera_orbit_config_json,
|
||||
@@ -469,6 +490,29 @@ if PromptServer is not None and web is not None:
|
||||
except Exception as exc:
|
||||
return web.json_response({"error": str(exc)}, status=400)
|
||||
|
||||
@PromptServer.instance.routes.post("/sxcp/accumulator/list")
|
||||
async def sxcp_accumulator_list(request):
|
||||
try:
|
||||
payload = await request.json()
|
||||
result = accumulator_list_entries(str(payload.get("store_key") or ""))
|
||||
return web.json_response(result)
|
||||
except Exception as exc:
|
||||
return web.json_response({"error": str(exc)}, status=400)
|
||||
|
||||
@PromptServer.instance.routes.post("/sxcp/accumulator/delete")
|
||||
async def sxcp_accumulator_delete(request):
|
||||
try:
|
||||
payload = await request.json()
|
||||
result = accumulator_delete_entries(
|
||||
store_key=str(payload.get("store_key") or ""),
|
||||
entry_id=str(payload.get("entry_id") or ""),
|
||||
index=int(payload.get("index") or 0),
|
||||
clear=bool(payload.get("clear")),
|
||||
)
|
||||
return web.json_response(result)
|
||||
except Exception as exc:
|
||||
return web.json_response({"error": str(exc)}, status=400)
|
||||
|
||||
|
||||
class SxCPPromptBuilder:
|
||||
@classmethod
|
||||
|
||||
Reference in New Issue
Block a user