diff --git a/invokeai/frontend/web/src/features/canvas/util/createMaskStage.ts b/invokeai/frontend/web/src/features/canvas/util/createMaskStage.ts index 96ac592711..b417b3a786 100644 --- a/invokeai/frontend/web/src/features/canvas/util/createMaskStage.ts +++ b/invokeai/frontend/web/src/features/canvas/util/createMaskStage.ts @@ -9,7 +9,8 @@ import { IRect } from 'konva/lib/types'; */ const createMaskStage = async ( lines: CanvasMaskLine[], - boundingBox: IRect + boundingBox: IRect, + shouldInvertMask: boolean ): Promise => { // create an offscreen canvas and add the mask to it const { width, height } = boundingBox; @@ -29,7 +30,7 @@ const createMaskStage = async ( baseLayer.add( new Konva.Rect({ ...boundingBox, - fill: 'white', + fill: shouldInvertMask ? 'black' : 'white', }) ); @@ -37,7 +38,7 @@ const createMaskStage = async ( maskLayer.add( new Konva.Line({ points: line.points, - stroke: 'black', + stroke: shouldInvertMask ? 'white' : 'black', strokeWidth: line.strokeWidth * 2, tension: 0, lineCap: 'round', diff --git a/invokeai/frontend/web/src/features/canvas/util/getCanvasData.ts b/invokeai/frontend/web/src/features/canvas/util/getCanvasData.ts index 21a33aa349..d0190878e2 100644 --- a/invokeai/frontend/web/src/features/canvas/util/getCanvasData.ts +++ b/invokeai/frontend/web/src/features/canvas/util/getCanvasData.ts @@ -25,6 +25,7 @@ export const getCanvasData = async (state: RootState) => { boundingBoxCoordinates, boundingBoxDimensions, isMaskEnabled, + shouldPreserveMaskedArea, } = state.canvas; const boundingBox = { @@ -58,7 +59,8 @@ export const getCanvasData = async (state: RootState) => { // For the mask layer, use the normal boundingBox const maskStage = await createMaskStage( isMaskEnabled ? objects.filter(isCanvasMaskLine) : [], // only include mask lines, and only if mask is enabled - boundingBox + boundingBox, + shouldPreserveMaskedArea ); const maskBlob = await konvaNodeToBlob(maskStage, boundingBox); const maskImageData = await konvaNodeToImageData(maskStage, boundingBox); diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasGraph.ts index 2e741443cf..2d23b882ea 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasGraph.ts @@ -16,7 +16,7 @@ import { buildEdges } from '../edgeBuilders/buildEdges'; import { log } from 'app/logging/useLogger'; import { buildInpaintNode } from '../nodeBuilders/buildInpaintNode'; -const moduleLog = log.child({ namespace: 'buildCanvasGraph' }); +const moduleLog = log.child({ namespace: 'nodes' }); const buildBaseNode = ( nodeType: 'txt2img' | 'img2img' | 'inpaint' | 'outpaint', @@ -80,18 +80,23 @@ export const buildCanvasGraphComponents = async ( infillMethod, } = state.generation; - // generationParameters.invert_mask = shouldPreserveMaskedArea; - // if (boundingBoxScale !== 'none') { - // generationParameters.inpaint_width = scaledBoundingBoxDimensions.width; - // generationParameters.inpaint_height = scaledBoundingBoxDimensions.height; - // } + const { scaledBoundingBoxDimensions, boundingBoxScaleMethod } = + state.canvas; + + if (boundingBoxScaleMethod !== 'none') { + baseNode.inpaint_width = scaledBoundingBoxDimensions.width; + baseNode.inpaint_height = scaledBoundingBoxDimensions.height; + } + baseNode.seam_size = seamSize; baseNode.seam_blur = seamBlur; baseNode.seam_strength = seamStrength; baseNode.seam_steps = seamSteps; - baseNode.tile_size = tileSize; baseNode.infill_method = infillMethod as InpaintInvocation['infill_method']; - // baseNode.force_outpaint = false; + + if (infillMethod === 'tile') { + baseNode.tile_size = tileSize; + } } // We always range and iterate nodes, no matter the iteration count diff --git a/invokeai/frontend/web/src/features/nodes/util/nodeBuilders/buildInpaintNode.ts b/invokeai/frontend/web/src/features/nodes/util/nodeBuilders/buildInpaintNode.ts index 0556a499be..593658e536 100644 --- a/invokeai/frontend/web/src/features/nodes/util/nodeBuilders/buildInpaintNode.ts +++ b/invokeai/frontend/web/src/features/nodes/util/nodeBuilders/buildInpaintNode.ts @@ -2,15 +2,12 @@ import { v4 as uuidv4 } from 'uuid'; import { RootState } from 'app/store/store'; import { InpaintInvocation } from 'services/api'; import { O } from 'ts-toolbelt'; -import { activeTabNameSelector } from 'features/ui/store/uiSelectors'; export const buildInpaintNode = ( state: RootState, overrides: O.Partial = {} ): InpaintInvocation => { const nodeId = uuidv4(); - const { generation } = state; - const activeTabName = activeTabNameSelector(state); const { positivePrompt: prompt, @@ -25,8 +22,7 @@ export const buildInpaintNode = ( img2imgStrength: strength, shouldFitToWidthHeight: fit, shouldRandomizeSeed, - initialImage, - } = generation; + } = state.generation; const inpaintNode: InpaintInvocation = { id: nodeId, @@ -42,19 +38,6 @@ export const buildInpaintNode = ( fit, }; - // on Canvas tab, we do not manually specific init image - if (activeTabName !== 'unifiedCanvas') { - if (!initialImage) { - // TODO: handle this more better - throw 'no initial image'; - } - - inpaintNode.image = { - image_name: initialImage.name, - image_origin: initialImage.type, - }; - } - if (!shouldRandomizeSeed) { inpaintNode.seed = seed; }