feat: enhance ControlNet integration with Xinsir-compatible pose rendering and update model handling

This commit is contained in:
syntaxbullet
2026-07-11 19:46:02 +02:00
parent ff762b8f17
commit 95043dfbdd
2 changed files with 37 additions and 8 deletions

View File

@@ -95,8 +95,8 @@ export async function listGenerationOptions() {
...(info["MiDaS-DepthMapPreprocessor"] && info.ControlNetApplyAdvanced && info.ControlNetLoader ? ["depth"] : []),
...(info.OpenposePreprocessor && info.ControlNetApplyAdvanced && info.ControlNetLoader ? ["pose"] : []),
],
semanticSelection: Boolean(info.SAM3_Detect && info.MaskToImage && diffusionModels.some((model) => /sam.?3/i.test(model))),
sam3Models: diffusionModels.filter((model) => /sam.?3/i.test(model)),
semanticSelection: Boolean(info.SAM3_Detect && info.MaskToImage && checkpointModels.some((model) => /sam.?3/i.test(model))),
sam3Models: checkpointModels.filter((model) => /sam.?3/i.test(model)),
architectures: [
{
value: "sdxl",
@@ -134,7 +134,7 @@ export async function segment(request: ComfySegmentRequest, signal?: AbortSignal
if (!request.inputImage) throw new Error("Semantic selection requires an image");
if (!Number.isFinite(request.x) || !Number.isFinite(request.y)) throw new Error("Semantic selection requires a valid point");
const info = await fetchObjectInfo();
const models = info.UNETLoader?.input?.required?.unet_name?.[0] ?? [];
const models = info.CheckpointLoaderSimple?.input?.required?.ckpt_name?.[0] ?? [];
const model = request.model && request.model !== "auto" ? request.model : models.find((candidate) => /sam.?3/i.test(candidate));
if (!info.SAM3_Detect || !info.MaskToImage || !model || !models.includes(model)) throw new Error("SAM3 semantic selection is not installed in ComfyUI. Install a SAM3 model and enable the native SAM3 nodes.");
const uploaded = await uploadDataUrl(request.inputImage, `image-studio-segment-${crypto.randomUUID()}.png`, signal);
@@ -158,7 +158,7 @@ export async function segment(request: ComfySegmentRequest, signal?: AbortSignal
export function buildSemanticSelectionWorkflow(request: ComfySegmentRequest & { model: string }): Workflow {
return {
"1": { class_type: "UNETLoader", inputs: { unet_name: request.model, weight_dtype: "default" } },
"1": { class_type: "CheckpointLoaderSimple", inputs: { ckpt_name: request.model } },
"2": { class_type: "LoadImage", inputs: { image: request.inputImage } },
"3": { class_type: "SAM3_Detect", inputs: { model: ["1", 0], image: ["2", 0], positive_coords: JSON.stringify([{ x: Math.round(request.x), y: Math.round(request.y) }]), threshold: 0.5, refine_iterations: 2, individual_masks: false } },
"4": { class_type: "MaskToImage", inputs: { mask: ["3", 0] } },
@@ -379,7 +379,7 @@ function finalizeSdxlWorkflow(workflow: Workflow, samplerInputs: Record<string,
} else if (control === "depth") {
workflow["21"] = { class_type: "MiDaS-DepthMapPreprocessor", inputs: { image: ["4", 0], a: 6.283, bg_threshold: 0.1, resolution: Math.max(request.width ?? 512, request.height ?? 512) } };
} else {
workflow["21"] = { class_type: "OpenposePreprocessor", inputs: { image: ["4", 0], detect_hand: "enable", detect_body: "enable", detect_face: "enable", resolution: Math.max(request.width ?? 512, request.height ?? 512) } };
workflow["21"] = { class_type: "OpenposePreprocessor", inputs: { image: ["4", 0], detect_hand: "enable", detect_body: "enable", detect_face: "enable", scale_stick_for_xinsr_cn: "enable", resolution: Math.max(request.width ?? 512, request.height ?? 512) } };
}
workflow["22"] = {
class_type: "ControlNetApplyAdvanced",