Merge branch 'inpainting-rebase' of https://github.com/psychedelicious/stable-diffusion into inpainting-rebase

This commit is contained in:
Kyle Schouviller 2022-10-27 17:49:30 -07:00
commit a825210bd3
7 changed files with 77 additions and 26 deletions

View File

@ -1,3 +1,4 @@
import { Flex } from '@chakra-ui/react';
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import _ from 'lodash'; import _ from 'lodash';
import { ChangeEvent } from 'react'; import { ChangeEvent } from 'react';
@ -18,6 +19,7 @@ import { roundDownToMultiple } from '../../../../common/util/roundDownToMultiple
import { import {
InpaintingState, InpaintingState,
setBoundingBoxDimensions, setBoundingBoxDimensions,
setShouldLockBoundingBox,
setShouldShowBoundingBox, setShouldShowBoundingBox,
setShouldShowBoundingBoxFill, setShouldShowBoundingBoxFill,
} from '../../../tabs/Inpainting/inpaintingSlice'; } from '../../../tabs/Inpainting/inpaintingSlice';
@ -32,6 +34,7 @@ const boundingBoxDimensionsSelector = createSelector(
shouldShowBoundingBoxFill, shouldShowBoundingBoxFill,
pastLines, pastLines,
futureLines, futureLines,
shouldLockBoundingBox,
} = inpainting; } = inpainting;
return { return {
canvasDimensions, canvasDimensions,
@ -40,6 +43,7 @@ const boundingBoxDimensionsSelector = createSelector(
shouldShowBoundingBoxFill, shouldShowBoundingBoxFill,
pastLines, pastLines,
futureLines, futureLines,
shouldLockBoundingBox,
}; };
}, },
{ {
@ -56,6 +60,7 @@ const BoundingBoxSettings = () => {
boundingBoxDimensions, boundingBoxDimensions,
shouldShowBoundingBox, shouldShowBoundingBox,
shouldShowBoundingBoxFill, shouldShowBoundingBoxFill,
shouldLockBoundingBox,
} = useAppSelector(boundingBoxDimensionsSelector); } = useAppSelector(boundingBoxDimensionsSelector);
const handleChangeBoundingBoxWidth = (v: number) => { const handleChangeBoundingBoxWidth = (v: number) => {
@ -73,6 +78,10 @@ const BoundingBoxSettings = () => {
dispatch(setShouldShowBoundingBoxFill(!shouldShowBoundingBoxFill)); dispatch(setShouldShowBoundingBoxFill(!shouldShowBoundingBoxFill));
}; };
const handleChangeShouldLockBoundingBox = () => {
dispatch(setShouldLockBoundingBox(!shouldLockBoundingBox));
};
const handleResetWidth = () => { const handleResetWidth = () => {
dispatch( dispatch(
setBoundingBoxDimensions({ setBoundingBoxDimensions({
@ -169,13 +178,22 @@ const BoundingBoxSettings = () => {
} }
/> />
</div> </div>
<IAICheckbox <Flex alignItems={'center'} justifyContent={'space-between'}>
label="Darken Outside Box" <IAICheckbox
isChecked={shouldShowBoundingBoxFill} label="Darken Outside Box"
onChange={handleChangeShouldShowBoundingBoxFill} isChecked={shouldShowBoundingBoxFill}
styleClass="inpainting-bounding-box-darken" onChange={handleChangeShouldShowBoundingBoxFill}
isDisabled={!shouldShowBoundingBox} styleClass="inpainting-bounding-box-darken"
/> isDisabled={!shouldShowBoundingBox}
/>
<IAICheckbox
label="Lock Bounding Box"
isChecked={shouldLockBoundingBox}
onChange={handleChangeShouldLockBoundingBox}
styleClass="inpainting-bounding-box-darken"
isDisabled={!shouldShowBoundingBox}
/>
</Flex>
</div> </div>
</div> </div>
); );

View File

@ -60,7 +60,7 @@ const InpaintingCanvas = () => {
stageScale, stageScale,
shouldShowBoundingBoxFill, shouldShowBoundingBoxFill,
isDrawing, isDrawing,
isBoundingBoxTransforming, isTransformingBoundingBox,
shouldShowBoundingBox, shouldShowBoundingBox,
} = useAppSelector(inpaintingCanvasSelector); } = useAppSelector(inpaintingCanvasSelector);
@ -204,7 +204,7 @@ const InpaintingCanvas = () => {
!scaledCursorPosition || !scaledCursorPosition ||
!maskLayerRef.current || !maskLayerRef.current ||
isMovingBoundingBox || isMovingBoundingBox ||
isBoundingBoxTransforming isTransformingBoundingBox
) )
return; return;
@ -220,7 +220,7 @@ const InpaintingCanvas = () => {
); );
} }
}, },
[dispatch, brushSize, tool, isMovingBoundingBox, isBoundingBoxTransforming] [dispatch, brushSize, tool, isMovingBoundingBox, isTransformingBoundingBox]
); );
return ( return (

View File

@ -27,6 +27,12 @@ const Cacher = () => {
imageToInpaint, imageToInpaint,
shouldShowBrush, shouldShowBrush,
shouldShowBoundingBoxFill, shouldShowBoundingBoxFill,
shouldLockBoundingBox,
stageScale,
pastLines,
futureLines,
needsRepaint,
isDrawing,
} = useAppSelector((state: RootState) => state.inpainting); } = useAppSelector((state: RootState) => state.inpainting);
useLayoutEffect(() => { useLayoutEffect(() => {
@ -52,6 +58,12 @@ const Cacher = () => {
imageToInpaint, imageToInpaint,
shouldShowBrush, shouldShowBrush,
shouldShowBoundingBoxFill, shouldShowBoundingBoxFill,
shouldLockBoundingBox,
stageScale,
pastLines,
futureLines,
needsRepaint,
isDrawing,
]); ]);
return null; return null;

View File

@ -3,7 +3,7 @@ import Konva from 'konva';
import { KonvaEventObject } from 'konva/lib/Node'; import { KonvaEventObject } from 'konva/lib/Node';
import { Vector2d } from 'konva/lib/types'; import { Vector2d } from 'konva/lib/types';
import _ from 'lodash'; import _ from 'lodash';
import { useEffect, useRef } from 'react'; import { useEffect, useLayoutEffect, useRef } from 'react';
import { Group, Rect, Transformer } from 'react-konva'; import { Group, Rect, Transformer } from 'react-konva';
import { import {
RootState, RootState,
@ -15,7 +15,7 @@ import {
InpaintingState, InpaintingState,
setBoundingBoxCoordinate, setBoundingBoxCoordinate,
setBoundingBoxDimensions, setBoundingBoxDimensions,
setIsBoundingBoxTransforming, setIsTransformingBoundingBox,
setIsDrawing, setIsDrawing,
setShouldShowBrush, setShouldShowBrush,
} from '../inpaintingSlice'; } from '../inpaintingSlice';
@ -36,6 +36,7 @@ const boundingBoxPreviewSelector = createSelector(
stageScale, stageScale,
imageToInpaint, imageToInpaint,
isMovingBoundingBox, isMovingBoundingBox,
shouldLockBoundingBox,
} = inpainting; } = inpainting;
return { return {
boundingBoxCoordinate, boundingBoxCoordinate,
@ -47,6 +48,7 @@ const boundingBoxPreviewSelector = createSelector(
dash: DASH_WIDTH / stageScale, // scale dash lengths dash: DASH_WIDTH / stageScale, // scale dash lengths
strokeWidth: 1 / stageScale, // scale stroke thickness strokeWidth: 1 / stageScale, // scale stroke thickness
isMovingBoundingBox, isMovingBoundingBox,
shouldLockBoundingBox,
}; };
}, },
{ {
@ -157,6 +159,7 @@ const InpaintingBoundingBoxPreview = () => {
strokeWidth, strokeWidth,
stageScale, stageScale,
imageToInpaint, imageToInpaint,
shouldLockBoundingBox,
} = useAppSelector(boundingBoxPreviewSelector); } = useAppSelector(boundingBoxPreviewSelector);
const transformerRef = useRef<Konva.Transformer>(null); const transformerRef = useRef<Konva.Transformer>(null);
@ -166,10 +169,12 @@ const InpaintingBoundingBoxPreview = () => {
if (!transformerRef.current || !shapeRef.current) return; if (!transformerRef.current || !shapeRef.current) return;
transformerRef.current.nodes([shapeRef.current]); transformerRef.current.nodes([shapeRef.current]);
transformerRef.current.getLayer()?.batchDraw(); transformerRef.current.getLayer()?.batchDraw();
}, []); }, [shouldLockBoundingBox]);
const scaledStep = 64 * stageScale; const scaledStep = 64 * stageScale;
console.log(shouldLockBoundingBox);
return ( return (
<> <>
<Rect <Rect
@ -184,11 +189,11 @@ const InpaintingBoundingBoxPreview = () => {
onTransformStart={() => { onTransformStart={() => {
dispatch(setIsDrawing(false)); dispatch(setIsDrawing(false));
dispatch(setShouldShowBrush(false)); dispatch(setShouldShowBrush(false));
dispatch(setIsBoundingBoxTransforming(true)); dispatch(setIsTransformingBoundingBox(true));
}} }}
onTransformEnd={() => { onTransformEnd={() => {
dispatch(setShouldShowBrush(true)); dispatch(setShouldShowBrush(true));
dispatch(setIsBoundingBoxTransforming(false)); dispatch(setIsTransformingBoundingBox(false));
}} }}
onTransform={() => { onTransform={() => {
/** /**
@ -230,6 +235,7 @@ const InpaintingBoundingBoxPreview = () => {
}} }}
/> />
<Transformer <Transformer
enabledAnchors={shouldLockBoundingBox ? [] : undefined}
ref={transformerRef} ref={transformerRef}
rotateEnabled={false} rotateEnabled={false}
anchorSize={15} anchorSize={15}
@ -245,6 +251,9 @@ const InpaintingBoundingBoxPreview = () => {
onMouseDown={(e: KonvaEventObject<MouseEvent>) => { onMouseDown={(e: KonvaEventObject<MouseEvent>) => {
e.cancelBubble = true; e.cancelBubble = true;
}} }}
onMouseOver={(e: KonvaEventObject<MouseEvent>) => {
e.cancelBubble = true;
}}
anchorDragBoundFunc={( anchorDragBoundFunc={(
oldPos: Vector2d, // old absolute position of anchor point oldPos: Vector2d, // old absolute position of anchor point
newPos: Vector2d, // new absolute position (potentially) of anchor point newPos: Vector2d, // new absolute position (potentially) of anchor point

View File

@ -11,19 +11,24 @@ import { tabMap } from '../../InvokeTabs';
import { import {
InpaintingState, InpaintingState,
setIsMovingBoundingBox, setIsMovingBoundingBox,
toggleIsMovingBoundingBox,
toggleTool, toggleTool,
} from '../inpaintingSlice'; } from '../inpaintingSlice';
const keyboardEventManagerSelector = createSelector( const keyboardEventManagerSelector = createSelector(
[(state: RootState) => state.options, (state: RootState) => state.inpainting], [(state: RootState) => state.options, (state: RootState) => state.inpainting],
(options: OptionsState, inpainting: InpaintingState) => { (options: OptionsState, inpainting: InpaintingState) => {
const { shouldShowMask, cursorPosition, isMovingBoundingBox } = inpainting; const {
shouldShowMask,
cursorPosition,
isMovingBoundingBox,
shouldLockBoundingBox,
} = inpainting;
return { return {
activeTabName: tabMap[options.activeTab], activeTabName: tabMap[options.activeTab],
shouldShowMask, shouldShowMask,
isCursorOnCanvas: Boolean(cursorPosition), isCursorOnCanvas: Boolean(cursorPosition),
isMovingBoundingBox, isMovingBoundingBox,
shouldLockBoundingBox,
}; };
}, },
{ {
@ -40,9 +45,9 @@ const KeyboardEventManager = () => {
activeTabName, activeTabName,
isCursorOnCanvas, isCursorOnCanvas,
isMovingBoundingBox, isMovingBoundingBox,
shouldLockBoundingBox,
} = useAppSelector(keyboardEventManagerSelector); } = useAppSelector(keyboardEventManagerSelector);
const isFirstEvent = useRef<boolean>(true);
const wasLastEventOverCanvas = useRef<boolean>(false); const wasLastEventOverCanvas = useRef<boolean>(false);
const lastEvent = useRef<KeyboardEvent | null>(null); const lastEvent = useRef<KeyboardEvent | null>(null);
@ -52,7 +57,8 @@ const KeyboardEventManager = () => {
!['Alt', ' '].includes(e.key) || !['Alt', ' '].includes(e.key) ||
activeTabName !== 'inpainting' || activeTabName !== 'inpainting' ||
!shouldShowMask || !shouldShowMask ||
e.repeat e.repeat ||
shouldLockBoundingBox
) { ) {
return; return;
} }

View File

@ -40,7 +40,7 @@ export interface InpaintingState {
boundingBoxPreviewFill: RgbaColor; boundingBoxPreviewFill: RgbaColor;
shouldShowBoundingBox: boolean; shouldShowBoundingBox: boolean;
shouldShowBoundingBoxFill: boolean; shouldShowBoundingBoxFill: boolean;
isBoundingBoxTransforming: boolean; isTransformingBoundingBox: boolean;
lines: MaskLine[]; lines: MaskLine[];
pastLines: MaskLine[][]; pastLines: MaskLine[][];
futureLines: MaskLine[][]; futureLines: MaskLine[][];
@ -55,6 +55,7 @@ export interface InpaintingState {
isDrawing: boolean; isDrawing: boolean;
shouldUseInpaintReplace: boolean; shouldUseInpaintReplace: boolean;
inpaintReplace: number; inpaintReplace: number;
shouldLockBoundingBox: boolean;
} }
const initialInpaintingState: InpaintingState = { const initialInpaintingState: InpaintingState = {
@ -67,7 +68,7 @@ const initialInpaintingState: InpaintingState = {
boundingBoxPreviewFill: { r: 0, g: 0, b: 0, a: 0.7 }, boundingBoxPreviewFill: { r: 0, g: 0, b: 0, a: 0.7 },
shouldShowBoundingBox: false, shouldShowBoundingBox: false,
shouldShowBoundingBoxFill: false, shouldShowBoundingBoxFill: false,
isBoundingBoxTransforming: false, isTransformingBoundingBox: false,
cursorPosition: null, cursorPosition: null,
lines: [], lines: [],
pastLines: [], pastLines: [],
@ -83,6 +84,7 @@ const initialInpaintingState: InpaintingState = {
stageScale: 1, stageScale: 1,
shouldUseInpaintReplace: false, shouldUseInpaintReplace: false,
inpaintReplace: 1, inpaintReplace: 1,
shouldLockBoundingBox: true,
}; };
const initialState: InpaintingState = initialInpaintingState; const initialState: InpaintingState = initialInpaintingState;
@ -310,8 +312,8 @@ export const inpaintingSlice = createSlice({
setShouldShowBoundingBoxFill: (state, action: PayloadAction<boolean>) => { setShouldShowBoundingBoxFill: (state, action: PayloadAction<boolean>) => {
state.shouldShowBoundingBoxFill = action.payload; state.shouldShowBoundingBoxFill = action.payload;
}, },
setIsBoundingBoxTransforming: (state, action: PayloadAction<boolean>) => { setIsTransformingBoundingBox: (state, action: PayloadAction<boolean>) => {
state.isBoundingBoxTransforming = action.payload; state.isTransformingBoundingBox = action.payload;
}, },
setIsDrawing: (state, action: PayloadAction<boolean>) => { setIsDrawing: (state, action: PayloadAction<boolean>) => {
state.isDrawing = action.payload; state.isDrawing = action.payload;
@ -329,6 +331,9 @@ export const inpaintingSlice = createSlice({
setInpaintReplace: (state, action: PayloadAction<number>) => { setInpaintReplace: (state, action: PayloadAction<number>) => {
state.inpaintReplace = action.payload; state.inpaintReplace = action.payload;
}, },
setShouldLockBoundingBox: (state, action: PayloadAction<boolean>) => {
state.shouldLockBoundingBox = action.payload;
},
}, },
}); });
@ -357,13 +362,14 @@ export const {
toggleTool, toggleTool,
toggleIsMovingBoundingBox, toggleIsMovingBoundingBox,
setShouldShowBoundingBoxFill, setShouldShowBoundingBoxFill,
setIsBoundingBoxTransforming, setIsTransformingBoundingBox,
setIsDrawing, setIsDrawing,
setShouldShowBrush, setShouldShowBrush,
setShouldShowBoundingBox, setShouldShowBoundingBox,
setClearBrushHistory, setClearBrushHistory,
setShouldUseInpaintReplace, setShouldUseInpaintReplace,
setInpaintReplace, setInpaintReplace,
setShouldLockBoundingBox,
} = inpaintingSlice.actions; } = inpaintingSlice.actions;
export default inpaintingSlice.reducer; export default inpaintingSlice.reducer;

View File

@ -78,7 +78,7 @@ export const inpaintingCanvasSelector = createSelector(
stageScale, stageScale,
shouldShowBoundingBoxFill, shouldShowBoundingBoxFill,
isDrawing, isDrawing,
isBoundingBoxTransforming, isTransformingBoundingBox,
shouldShowBoundingBox, shouldShowBoundingBox,
} = inpainting; } = inpainting;
return { return {
@ -97,7 +97,7 @@ export const inpaintingCanvasSelector = createSelector(
stageScale, stageScale,
shouldShowBoundingBoxFill, shouldShowBoundingBoxFill,
isDrawing, isDrawing,
isBoundingBoxTransforming, isTransformingBoundingBox,
shouldShowBoundingBox, shouldShowBoundingBox,
}; };
}, },