From b313cf8afd015df94c943298f90f989007fb9715 Mon Sep 17 00:00:00 2001 From: blessedcoolant <54517381+blessedcoolant@users.noreply.github.com> Date: Tue, 21 Feb 2023 02:27:55 +1300 Subject: [PATCH] Add Symmetry Settings --- invokeai/frontend/public/locales/en.json | 2 + .../src/common/util/parameterTranslation.ts | 16 ++++++ .../Output/ImageToImageOutputSettings.tsx | 2 + .../Output/OutputSettings.tsx | 2 + .../Output/SymmetrySettings.tsx | 57 +++++++++++++++++++ .../parameters/store/generationSlice.ts | 18 ++++++ .../UnifiedCanvasOtherSettings.tsx | 5 ++ .../UnifiedCanvas/UnifiedCanvasPanel.tsx | 5 ++ 8 files changed, 107 insertions(+) create mode 100644 invokeai/frontend/src/features/parameters/components/AdvancedParameters/Output/SymmetrySettings.tsx create mode 100644 invokeai/frontend/src/features/ui/components/UnifiedCanvas/UnifiedCanvasOtherSettings.tsx diff --git a/invokeai/frontend/public/locales/en.json b/invokeai/frontend/public/locales/en.json index 9ae8dc869d..9ba4f5ba83 100644 --- a/invokeai/frontend/public/locales/en.json +++ b/invokeai/frontend/public/locales/en.json @@ -441,6 +441,8 @@ "infillScalingHeader": "Infill and Scaling", "img2imgStrength": "Image To Image Strength", "toggleLoopback": "Toggle Loopback", + "hSymmetryStep": "H Symmetry Step", + "vSymmetryStep": "V Symmetry Step", "invoke": "Invoke", "cancel": { "immediate": "Cancel immediately", diff --git a/invokeai/frontend/src/common/util/parameterTranslation.ts b/invokeai/frontend/src/common/util/parameterTranslation.ts index 21dd6484cb..26ed125ae8 100644 --- a/invokeai/frontend/src/common/util/parameterTranslation.ts +++ b/invokeai/frontend/src/common/util/parameterTranslation.ts @@ -65,6 +65,8 @@ export type BackendGenerationParameters = { with_variations?: Array>; variation_amount?: number; enable_image_debugging?: boolean; + h_symmetry_time_pct: number; + v_symmetry_time_pct: number; }; export type BackendEsrGanParameters = { @@ -141,6 +143,8 @@ export const frontendToBackendParameters = ( tileSize, variationAmount, width, + horizontalSymmetryTimePercentage, + verticalSymmetryTimePercentage, } = generationState; const { @@ -165,6 +169,8 @@ export const frontendToBackendParameters = ( save_intermediates: saveIntermediatesInterval, generation_mode: generationMode, init_mask: '', + h_symmetry_time_pct: horizontalSymmetryTimePercentage, + v_symmetry_time_pct: verticalSymmetryTimePercentage, }; let esrganParameters: false | BackendEsrGanParameters = false; @@ -173,6 +179,16 @@ export const frontendToBackendParameters = ( // Multiplying it by 10000 so the Slider can have values between 0 and 1 which makes more sense generationParameters.threshold = threshold * 1000; + generationParameters.h_symmetry_time_pct = Math.max( + 0, + Math.min(1, horizontalSymmetryTimePercentage / steps) + ); + + generationParameters.v_symmetry_time_pct = Math.max( + 0, + Math.min(1, verticalSymmetryTimePercentage / steps) + ); + if (negativePrompt !== '') { generationParameters.prompt = `${prompt} [${negativePrompt}]`; } diff --git a/invokeai/frontend/src/features/parameters/components/AdvancedParameters/Output/ImageToImageOutputSettings.tsx b/invokeai/frontend/src/features/parameters/components/AdvancedParameters/Output/ImageToImageOutputSettings.tsx index f037e79523..1d9e935a8d 100644 --- a/invokeai/frontend/src/features/parameters/components/AdvancedParameters/Output/ImageToImageOutputSettings.tsx +++ b/invokeai/frontend/src/features/parameters/components/AdvancedParameters/Output/ImageToImageOutputSettings.tsx @@ -1,10 +1,12 @@ import { Flex } from '@chakra-ui/react'; import SeamlessSettings from './SeamlessSettings'; +import SymmetrySettings from './SymmetrySettings'; const ImageToImageOutputSettings = () => { return ( + ); }; diff --git a/invokeai/frontend/src/features/parameters/components/AdvancedParameters/Output/OutputSettings.tsx b/invokeai/frontend/src/features/parameters/components/AdvancedParameters/Output/OutputSettings.tsx index 1eaba1eaae..e2a60c2f37 100644 --- a/invokeai/frontend/src/features/parameters/components/AdvancedParameters/Output/OutputSettings.tsx +++ b/invokeai/frontend/src/features/parameters/components/AdvancedParameters/Output/OutputSettings.tsx @@ -1,12 +1,14 @@ import { Flex } from '@chakra-ui/react'; import HiresSettings from './HiresSettings'; import SeamlessSettings from './SeamlessSettings'; +import SymmetrySettings from './SymmetrySettings'; const OutputSettings = () => { return ( + ); }; diff --git a/invokeai/frontend/src/features/parameters/components/AdvancedParameters/Output/SymmetrySettings.tsx b/invokeai/frontend/src/features/parameters/components/AdvancedParameters/Output/SymmetrySettings.tsx new file mode 100644 index 0000000000..2214594190 --- /dev/null +++ b/invokeai/frontend/src/features/parameters/components/AdvancedParameters/Output/SymmetrySettings.tsx @@ -0,0 +1,57 @@ +import { RootState } from 'app/store'; +import { useAppDispatch, useAppSelector } from 'app/storeHooks'; +import IAISlider from 'common/components/IAISlider'; +import { + setHorizontalSymmetryTimePercentage, + setVerticalSymmetryTimePercentage, +} from 'features/parameters/store/generationSlice'; +import { useTranslation } from 'react-i18next'; + +export default function SymmetrySettings() { + const horizontalSymmetryTimePercentage = useAppSelector( + (state: RootState) => state.generation.horizontalSymmetryTimePercentage + ); + + const verticalSymmetryTimePercentage = useAppSelector( + (state: RootState) => state.generation.verticalSymmetryTimePercentage + ); + + const steps = useAppSelector((state: RootState) => state.generation.steps); + + const dispatch = useAppDispatch(); + + const { t } = useTranslation(); + + return ( + <> + dispatch(setHorizontalSymmetryTimePercentage(v))} + min={0} + max={steps} + step={1} + withInput + inputWidth="6.5rem" + withSliderMarks + withReset + handleReset={() => dispatch(setHorizontalSymmetryTimePercentage(0))} + sliderMarkRightOffset={-6} + > + dispatch(setVerticalSymmetryTimePercentage(v))} + min={0} + max={steps} + step={1} + withInput + inputWidth="6.5rem" + withSliderMarks + withReset + handleReset={() => dispatch(setVerticalSymmetryTimePercentage(0))} + sliderMarkRightOffset={-6} + > + + ); +} diff --git a/invokeai/frontend/src/features/parameters/store/generationSlice.ts b/invokeai/frontend/src/features/parameters/store/generationSlice.ts index 6bd90b1842..f057f56ba3 100644 --- a/invokeai/frontend/src/features/parameters/store/generationSlice.ts +++ b/invokeai/frontend/src/features/parameters/store/generationSlice.ts @@ -32,6 +32,8 @@ export interface GenerationState { tileSize: number; variationAmount: number; width: number; + horizontalSymmetryTimePercentage: number; + verticalSymmetryTimePercentage: number; } const initialGenerationState: GenerationState = { @@ -60,6 +62,8 @@ const initialGenerationState: GenerationState = { tileSize: 32, variationAmount: 0.1, width: 512, + horizontalSymmetryTimePercentage: 0, + verticalSymmetryTimePercentage: 0, }; const initialState: GenerationState = initialGenerationState; @@ -325,6 +329,18 @@ export const generationSlice = createSlice({ setInfillMethod: (state, action: PayloadAction) => { state.infillMethod = action.payload; }, + setHorizontalSymmetryTimePercentage: ( + state, + action: PayloadAction + ) => { + state.horizontalSymmetryTimePercentage = action.payload; + }, + setVerticalSymmetryTimePercentage: ( + state, + action: PayloadAction + ) => { + state.verticalSymmetryTimePercentage = action.payload; + }, }, }); @@ -362,6 +378,8 @@ export const { setTileSize, setVariationAmount, setWidth, + setHorizontalSymmetryTimePercentage, + setVerticalSymmetryTimePercentage, } = generationSlice.actions; export default generationSlice.reducer; diff --git a/invokeai/frontend/src/features/ui/components/UnifiedCanvas/UnifiedCanvasOtherSettings.tsx b/invokeai/frontend/src/features/ui/components/UnifiedCanvas/UnifiedCanvasOtherSettings.tsx new file mode 100644 index 0000000000..3c1698ecd8 --- /dev/null +++ b/invokeai/frontend/src/features/ui/components/UnifiedCanvas/UnifiedCanvasOtherSettings.tsx @@ -0,0 +1,5 @@ +import SymmetrySettings from 'features/parameters/components/AdvancedParameters/Output/SymmetrySettings'; + +export default function UnifiedCanvasOtherSettings() { + return ; +} diff --git a/invokeai/frontend/src/features/ui/components/UnifiedCanvas/UnifiedCanvasPanel.tsx b/invokeai/frontend/src/features/ui/components/UnifiedCanvas/UnifiedCanvasPanel.tsx index 15071898d1..680faf9357 100644 --- a/invokeai/frontend/src/features/ui/components/UnifiedCanvas/UnifiedCanvasPanel.tsx +++ b/invokeai/frontend/src/features/ui/components/UnifiedCanvas/UnifiedCanvasPanel.tsx @@ -15,6 +15,7 @@ import NegativePromptInput from 'features/parameters/components/PromptInput/Nega import PromptInput from 'features/parameters/components/PromptInput/PromptInput'; import InvokeOptionsPanel from 'features/ui/components/InvokeParametersPanel'; import { useTranslation } from 'react-i18next'; +import UnifiedCanvasOtherSettings from './UnifiedCanvasOtherSettings'; export default function UnifiedCanvasPanel() { const { t } = useTranslation(); @@ -46,6 +47,10 @@ export default function UnifiedCanvasPanel() { content: , additionalHeaderComponents: , }, + output: { + header: `${t('parameters.otherOptions')}`, + content: , + }, }; const unifiedCanvasImg2ImgAccordion = {