Files
image-studio/operations/masks/semantic-select.ts
syntaxbullet ff762b8f17 feat: add inpaint region functionality and related tools
- Enhanced cursor behavior for new tools: semantic select, mask lasso, and mask rectangle.
- Updated mask edit state to include mask asset ID and kind.
- Implemented inpaint region commands for adding, applying, and removing inpaint regions.
- Introduced new operations for lasso and semantic selection tools.
- Created UI components for candidate review and inpaint region management.
- Added tests for inpaint region commands to ensure functionality.
- Updated various components to support new inpaint features and improve user experience.
2026-07-11 16:41:22 +02:00

35 lines
1.9 KiB
TypeScript

import { commandIds } from "@commands/ids";
import type { Vec2D } from "@core/geometry";
import type { AppStore } from "@editor/store";
import { mergeMaskSources } from "@platform/browser/maskRaster";
import { requestSemanticSelection } from "@platform/comfy/generationClient";
import { runGenerationJob } from "@operations/generation/generationJob";
import { documentPointToAssetPoint, resolveMaskSelectionTarget } from "./magic-wand";
export async function applySemanticSelectionAt(store: AppStore, point: Vec2D, mode: "replace" | "add" | "subtract") {
const state = store.getState();
if (state.editor.tools.activeTool !== "semanticSelect") return false;
const target = resolveMaskSelectionTarget(state.document, state.editor);
if (!target?.inpaintRegion || !target.maskAsset) return true;
const region = target.inpaintRegion;
const maskAsset = target.maskAsset;
const assetPoint = documentPointToAssetPoint(point, target.layer, target.asset.intrinsicSize);
if (assetPoint.x < 0 || assetPoint.y < 0 || assetPoint.x >= target.asset.intrinsicSize.w || assetPoint.y >= target.asset.intrinsicSize.h) return true;
const controller = new AbortController();
await runGenerationJob({
kind: "mask",
label: "Selecting object",
dispatch: store.dispatch,
signal: controller.signal,
task: async (signal, report) => {
report(0.1, "Sending point to SAM3");
const result = await requestSemanticSelection({ inputImage: target.asset.source, x: assetPoint.x, y: assetPoint.y }, signal);
report(0.85, "Merging object mask");
const source = await mergeMaskSources(maskAsset.source, result.source, Math.round(target.asset.intrinsicSize.w), Math.round(target.asset.intrinsicSize.h), mode);
store.dispatch(commandIds.documentApplyInpaintRegionMaskOperation, { regionId: region.id, source, mimeType: "image/png", operation: { type: "magicWand" } });
report(1, "Object selected");
},
});
return true;
}