- 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.
35 lines
1.9 KiB
TypeScript
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;
|
|
}
|