diff --git a/invokeai/frontend/web/src/features/controlLayers/components/ControlLayer/ControlLayerBadges.tsx b/invokeai/frontend/web/src/features/controlLayers/components/ControlLayer/ControlLayerBadges.tsx index 5ca8601ecc..28224876ff 100644 --- a/invokeai/frontend/web/src/features/controlLayers/components/ControlLayer/ControlLayerBadges.tsx +++ b/invokeai/frontend/web/src/features/controlLayers/components/ControlLayer/ControlLayerBadges.tsx @@ -1,7 +1,7 @@ import { Badge } from '@invoke-ai/ui-library'; import { useAppSelector } from 'app/store/storeHooks'; import { useEntityIdentifierContext } from 'features/controlLayers/contexts/EntityIdentifierContext'; -import { selectControlLayerOrThrow } from 'features/controlLayers/store/controlLayersReducers'; +import { selectControlLayerEntityOrThrow } from 'features/controlLayers/store/controlLayersReducers'; import { memo } from 'react'; import { useTranslation } from 'react-i18next'; @@ -9,7 +9,7 @@ export const ControlLayerBadges = memo(() => { const { id } = useEntityIdentifierContext(); const { t } = useTranslation(); const withTransparencyEffect = useAppSelector( - (s) => selectControlLayerOrThrow(s.canvasV2, id).withTransparencyEffect + (s) => selectControlLayerEntityOrThrow(s.canvasV2, id).withTransparencyEffect ); return ( diff --git a/invokeai/frontend/web/src/features/controlLayers/components/ControlLayer/ControlLayerMenuItemsTransparencyEffect.tsx b/invokeai/frontend/web/src/features/controlLayers/components/ControlLayer/ControlLayerMenuItemsTransparencyEffect.tsx index 3fdb2947b7..fe53a785fd 100644 --- a/invokeai/frontend/web/src/features/controlLayers/components/ControlLayer/ControlLayerMenuItemsTransparencyEffect.tsx +++ b/invokeai/frontend/web/src/features/controlLayers/components/ControlLayer/ControlLayerMenuItemsTransparencyEffect.tsx @@ -6,7 +6,7 @@ import { controlLayerWithTransparencyEffectToggled, selectCanvasV2Slice, } from 'features/controlLayers/store/canvasV2Slice'; -import { selectControlLayerOrThrow } from 'features/controlLayers/store/controlLayersReducers'; +import { selectControlLayerEntityOrThrow } from 'features/controlLayers/store/controlLayersReducers'; import { memo, useCallback, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { PiDropHalfBold } from 'react-icons/pi'; @@ -18,7 +18,7 @@ export const ControlLayerMenuItemsTransparencyEffect = memo(() => { const selectWithTransparencyEffect = useMemo( () => createSelector(selectCanvasV2Slice, (canvasV2) => { - const entity = selectControlLayerOrThrow(canvasV2, entityIdentifier.id); + const entity = selectControlLayerEntityOrThrow(canvasV2, entityIdentifier.id); return entity.withTransparencyEffect; }), [entityIdentifier.id] diff --git a/invokeai/frontend/web/src/features/controlLayers/components/ControlLayersEditor.tsx b/invokeai/frontend/web/src/features/controlLayers/components/ControlLayersEditor.tsx index 9a300a9a10..8c4cd6aa6b 100644 --- a/invokeai/frontend/web/src/features/controlLayers/components/ControlLayersEditor.tsx +++ b/invokeai/frontend/web/src/features/controlLayers/components/ControlLayersEditor.tsx @@ -5,6 +5,7 @@ import { CanvasDropArea } from 'features/controlLayers/components/CanvasDropArea import { ControlLayersToolbar } from 'features/controlLayers/components/ControlLayersToolbar'; import { Filter } from 'features/controlLayers/components/Filters/Filter'; import { StageComponent } from 'features/controlLayers/components/StageComponent'; +import { StagingAreaIsStagingGate } from 'features/controlLayers/components/StagingArea/StagingAreaIsStagingGate'; import { StagingAreaToolbar } from 'features/controlLayers/components/StagingArea/StagingAreaToolbar'; import { Transform } from 'features/controlLayers/components/Transform'; import { CanvasManagerProviderGate } from 'features/controlLayers/contexts/CanvasManagerProviderGate'; @@ -32,7 +33,9 @@ export const CanvasEditor = memo(() => { - + + + diff --git a/invokeai/frontend/web/src/features/controlLayers/components/StagingArea/StagingAreaIsStagingGate.tsx b/invokeai/frontend/web/src/features/controlLayers/components/StagingArea/StagingAreaIsStagingGate.tsx new file mode 100644 index 0000000000..51fc64c96f --- /dev/null +++ b/invokeai/frontend/web/src/features/controlLayers/components/StagingArea/StagingAreaIsStagingGate.tsx @@ -0,0 +1,15 @@ +import { useAppSelector } from 'app/store/storeHooks'; +import type { PropsWithChildren } from 'react'; +import { memo } from 'react'; + +export const StagingAreaIsStagingGate = memo((props: PropsWithChildren) => { + const isStaging = useAppSelector((s) => s.canvasV2.session.isStaging); + + if (!isStaging) { + return null; + } + + return props.children; +}); + +StagingAreaIsStagingGate.displayName = 'StagingAreaIsStagingGate'; diff --git a/invokeai/frontend/web/src/features/controlLayers/components/StagingArea/StagingAreaToolbar.tsx b/invokeai/frontend/web/src/features/controlLayers/components/StagingArea/StagingAreaToolbar.tsx index ce34e2c914..c0cac8214f 100644 --- a/invokeai/frontend/web/src/features/controlLayers/components/StagingArea/StagingAreaToolbar.tsx +++ b/invokeai/frontend/web/src/features/controlLayers/components/StagingArea/StagingAreaToolbar.tsx @@ -25,18 +25,6 @@ import { } from 'react-icons/pi'; export const StagingAreaToolbar = memo(() => { - const isStaging = useAppSelector((s) => s.canvasV2.session.isStaging); - - if (!isStaging) { - return null; - } - - return ; -}); - -StagingAreaToolbar.displayName = 'StagingAreaToolbar'; - -export const StagingAreaToolbarContent = memo(() => { const dispatch = useAppDispatch(); const session = useAppSelector((s) => s.canvasV2.session); const shouldShowStagedImage = useStore($shouldShowStagedImage); @@ -204,4 +192,4 @@ export const StagingAreaToolbarContent = memo(() => { ); }); -StagingAreaToolbarContent.displayName = 'StagingAreaToolbarContent'; +StagingAreaToolbar.displayName = 'StagingAreaToolbar'; diff --git a/invokeai/frontend/web/src/features/controlLayers/hooks/useLayerControlAdapter.ts b/invokeai/frontend/web/src/features/controlLayers/hooks/useLayerControlAdapter.ts index 5f7aca0237..7a4bff4f46 100644 --- a/invokeai/frontend/web/src/features/controlLayers/hooks/useLayerControlAdapter.ts +++ b/invokeai/frontend/web/src/features/controlLayers/hooks/useLayerControlAdapter.ts @@ -2,14 +2,14 @@ import { createMemoizedAppSelector } from 'app/store/createMemoizedSelector'; import { useAppSelector } from 'app/store/storeHooks'; import { deepClone } from 'common/util/deepClone'; import { selectCanvasV2Slice } from 'features/controlLayers/store/canvasV2Slice'; -import { selectControlLayerOrThrow } from 'features/controlLayers/store/controlLayersReducers'; +import { selectControlLayerEntityOrThrow } from 'features/controlLayers/store/controlLayersReducers'; import type { CanvasEntityIdentifier, ControlNetConfig, IPAdapterConfig, T2IAdapterConfig, } from 'features/controlLayers/store/types'; -import { initialControlNetV2, initialIPAdapterV2, initialT2IAdapterV2 } from 'features/controlLayers/store/types'; +import { initialControlNet, initialIPAdapter, initialT2IAdapter } from 'features/controlLayers/store/types'; import { zModelIdentifierField } from 'features/nodes/types/common'; import { useMemo } from 'react'; import { useControlNetAndT2IAdapterModels, useIPAdapterModels } from 'services/api/hooks/modelsByType'; @@ -18,7 +18,7 @@ export const useControlLayerControlAdapter = (entityIdentifier: CanvasEntityIden const selectControlAdapter = useMemo( () => createMemoizedAppSelector(selectCanvasV2Slice, (canvasV2) => { - const layer = selectControlLayerOrThrow(canvasV2, entityIdentifier.id); + const layer = selectControlLayerEntityOrThrow(canvasV2, entityIdentifier.id); return layer.controlAdapter; }), [entityIdentifier] @@ -36,7 +36,7 @@ export const useDefaultControlAdapter = (): ControlNetConfig | T2IAdapterConfig const compatibleModels = modelConfigs.filter((m) => (baseModel ? m.base === baseModel : true)); const model = compatibleModels[0] ?? modelConfigs[0] ?? null; const controlAdapter = - model?.type === 't2i_adapter' ? deepClone(initialT2IAdapterV2) : deepClone(initialControlNetV2); + model?.type === 't2i_adapter' ? deepClone(initialT2IAdapter) : deepClone(initialControlNet); if (model) { controlAdapter.model = zModelIdentifierField.parse(model); @@ -56,7 +56,7 @@ export const useDefaultIPAdapter = (): IPAdapterConfig => { const defaultControlAdapter = useMemo(() => { const compatibleModels = modelConfigs.filter((m) => (baseModel ? m.base === baseModel : true)); const model = compatibleModels[0] ?? modelConfigs[0] ?? null; - const ipAdapter = deepClone(initialIPAdapterV2); + const ipAdapter = deepClone(initialIPAdapter); if (model) { ipAdapter.model = zModelIdentifierField.parse(model); diff --git a/invokeai/frontend/web/src/features/controlLayers/store/controlLayersReducers.ts b/invokeai/frontend/web/src/features/controlLayers/store/controlLayersReducers.ts index 6900c8135b..01bc97e166 100644 --- a/invokeai/frontend/web/src/features/controlLayers/store/controlLayersReducers.ts +++ b/invokeai/frontend/web/src/features/controlLayers/store/controlLayersReducers.ts @@ -14,12 +14,12 @@ import type { ControlNetConfig, T2IAdapterConfig, } from './types'; -import { initialControlNetV2 } from './types'; +import { initialControlNet } from './types'; -export const selectControlLayer = (state: CanvasV2State, id: string) => - state.controlLayers.entities.find((layer) => layer.id === id); -export const selectControlLayerOrThrow = (state: CanvasV2State, id: string) => { - const layer = selectControlLayer(state, id); +const selectControlLayerEntity = (state: CanvasV2State, id: string) => + state.controlLayers.entities.find((entity) => entity.id === id); +export const selectControlLayerEntityOrThrow = (state: CanvasV2State, id: string) => { + const layer = selectControlLayerEntity(state, id); assert(layer, `Layer with id ${id} not found`); return layer; }; @@ -40,7 +40,7 @@ export const controlLayersReducers = { objects: [], opacity: 1, position: { x: 0, y: 0 }, - controlAdapter: deepClone(initialControlNetV2), + controlAdapter: deepClone(initialControlNet), }; merge(layer, overrides); state.controlLayers.entities.push(layer); @@ -63,7 +63,7 @@ export const controlLayersReducers = { controlLayerConvertedToRasterLayer: { reducer: (state, action: PayloadAction<{ id: string; newId: string }>) => { const { id, newId } = action.payload; - const layer = selectControlLayer(state, id); + const layer = selectControlLayerEntity(state, id); if (!layer) { return; } @@ -95,7 +95,7 @@ export const controlLayersReducers = { }> ) => { const { id, modelConfig } = action.payload; - const layer = selectControlLayer(state, id); + const layer = selectControlLayerEntity(state, id); if (!layer || !layer.controlAdapter) { return; } @@ -123,7 +123,7 @@ export const controlLayersReducers = { }, controlLayerControlModeChanged: (state, action: PayloadAction<{ id: string; controlMode: ControlModeV2 }>) => { const { id, controlMode } = action.payload; - const layer = selectControlLayer(state, id); + const layer = selectControlLayerEntity(state, id); if (!layer || !layer.controlAdapter || layer.controlAdapter.type !== 'controlnet') { return; } @@ -131,7 +131,7 @@ export const controlLayersReducers = { }, controlLayerWeightChanged: (state, action: PayloadAction<{ id: string; weight: number }>) => { const { id, weight } = action.payload; - const layer = selectControlLayer(state, id); + const layer = selectControlLayerEntity(state, id); if (!layer || !layer.controlAdapter) { return; } @@ -142,7 +142,7 @@ export const controlLayersReducers = { action: PayloadAction<{ id: string; beginEndStepPct: [number, number] }> ) => { const { id, beginEndStepPct } = action.payload; - const layer = selectControlLayer(state, id); + const layer = selectControlLayerEntity(state, id); if (!layer || !layer.controlAdapter) { return; } @@ -150,7 +150,7 @@ export const controlLayersReducers = { }, controlLayerWithTransparencyEffectToggled: (state, action: PayloadAction<{ id: string }>) => { const { id } = action.payload; - const layer = selectControlLayer(state, id); + const layer = selectControlLayerEntity(state, id); if (!layer) { return; } diff --git a/invokeai/frontend/web/src/features/controlLayers/store/rasterLayersReducers.ts b/invokeai/frontend/web/src/features/controlLayers/store/rasterLayersReducers.ts index 6c1d4fb171..aad77777a5 100644 --- a/invokeai/frontend/web/src/features/controlLayers/store/rasterLayersReducers.ts +++ b/invokeai/frontend/web/src/features/controlLayers/store/rasterLayersReducers.ts @@ -5,7 +5,7 @@ import { merge } from 'lodash-es'; import { assert } from 'tsafe'; import type { CanvasControlLayerState, CanvasRasterLayerState, CanvasV2State } from './types'; -import { initialControlNetV2 } from './types'; +import { initialControlNet } from './types'; export const selectRasterLayer = (state: CanvasV2State, id: string) => state.rasterLayers.entities.find((layer) => layer.id === id); @@ -62,7 +62,7 @@ export const rasterLayersReducers = { ...deepClone(layer), id: newId, type: 'control_layer', - controlAdapter: deepClone(initialControlNetV2), + controlAdapter: deepClone(initialControlNet), withTransparencyEffect: true, }; diff --git a/invokeai/frontend/web/src/features/controlLayers/store/types.ts b/invokeai/frontend/web/src/features/controlLayers/store/types.ts index 0878d155bc..30e943b8de 100644 --- a/invokeai/frontend/web/src/features/controlLayers/store/types.ts +++ b/invokeai/frontend/web/src/features/controlLayers/store/types.ts @@ -1,6 +1,3 @@ -import type { CanvasControlAdapter } from 'features/controlLayers/konva/CanvasControlAdapter'; -import { CanvasLayerAdapter } from 'features/controlLayers/konva/CanvasLayerAdapter'; -import { CanvasMaskAdapter } from 'features/controlLayers/konva/CanvasMaskAdapter'; import { getPrefixedId } from 'features/controlLayers/konva/util'; import { zModelIdentifierField } from 'features/nodes/types/common'; import type { AspectRatioState } from 'features/parameters/components/DocumentSize/types'; @@ -25,45 +22,35 @@ import type { ParameterVAEModel, ParameterWidth, } from 'features/parameters/types/parameterSchemas'; -import { - zParameterNegativePrompt, - zParameterPositivePrompt, -} from 'features/parameters/types/parameterSchemas'; -import type { - AnyInvocation, - BaseModelType, - ControlNetModelConfig, - ImageDTO, - S, - T2IAdapterModelConfig, -} from 'services/api/types'; +import { zParameterNegativePrompt, zParameterPositivePrompt } from 'features/parameters/types/parameterSchemas'; +import type { AnyInvocation, BaseModelType, ImageDTO, S } from 'services/api/types'; import { z } from 'zod'; -export const zId = z.string().min(1); -export const zName = z.string().min(1).nullable(); +const zId = z.string().min(1); +const zName = z.string().min(1).nullable(); -export const zImageWithDims = z.object({ +const zImageWithDims = z.object({ image_name: z.string(), width: z.number().int().positive(), height: z.number().int().positive(), }); export type ImageWithDims = z.infer; -export const zBeginEndStepPct = z +const zBeginEndStepPct = z .tuple([z.number().gte(0).lte(1), z.number().gte(0).lte(1)]) .refine(([begin, end]) => begin < end, { message: 'Begin must be less than end', }); -export const zControlModeV2 = z.enum(['balanced', 'more_prompt', 'more_control', 'unbalanced']); +const zControlModeV2 = z.enum(['balanced', 'more_prompt', 'more_control', 'unbalanced']); export type ControlModeV2 = z.infer; export const isControlModeV2 = (v: unknown): v is ControlModeV2 => zControlModeV2.safeParse(v).success; -export const zCLIPVisionModelV2 = z.enum(['ViT-H', 'ViT-G']); +const zCLIPVisionModelV2 = z.enum(['ViT-H', 'ViT-G']); export type CLIPVisionModelV2 = z.infer; export const isCLIPVisionModelV2 = (v: unknown): v is CLIPVisionModelV2 => zCLIPVisionModelV2.safeParse(v).success; -export const zIPMethodV2 = z.enum(['full', 'style', 'composition']); +const zIPMethodV2 = z.enum(['full', 'style', 'composition']); export type IPMethodV2 = z.infer; export const isIPMethodV2 = (v: unknown): v is IPMethodV2 => zIPMethodV2.safeParse(v).success; @@ -175,7 +162,7 @@ const zZoeDepthProcessorConfig = z.object({ }); export type ZoeDepthProcessorConfig = z.infer; -export const zFilterConfig = z.discriminatedUnion('type', [ +const zFilterConfig = z.discriminatedUnion('type', [ zCannyProcessorConfig, zColorMapProcessorConfig, zContentShuffleProcessorConfig, @@ -471,31 +458,10 @@ export const IMAGE_FILTERS: { [key in FilterConfig['type']]: ImageFilterData; -export function isDrawingTool(tool: Tool): tool is 'brush' | 'eraser' | 'rect' { - return tool === 'brush' || tool === 'eraser' || tool === 'rect'; -} - -const zDrawingTool = zTool.extract(['brush', 'eraser']); const zPoints = z.array(z.number()).refine((points) => points.length % 2 === 0, { message: 'Must have an even number of points', }); -const zOLD_VectorMaskLine = z.object({ - id: zId, - type: z.literal('vector_mask_line'), - tool: zDrawingTool, - strokeWidth: z.number().min(1), - points: zPoints, -}); - -const zOLD_VectorMaskRect = z.object({ - id: zId, - type: z.literal('vector_mask_rect'), - x: z.number(), - y: z.number(), - width: z.number().min(1), - height: z.number().min(1), -}); const zRgbColor = z.object({ r: z.number().int().min(0).max(255), @@ -507,9 +473,7 @@ const zRgbaColor = zRgbColor.extend({ a: z.number().min(0).max(1), }); export type RgbaColor = z.infer; -export const RGBA_RED: RgbaColor = { r: 255, g: 0, b: 0, a: 1 }; export const RGBA_BLACK: RgbaColor = { r: 0, g: 0, b: 0, a: 1 }; -export const RGBA_WHITE: RgbaColor = { r: 255, g: 255, b: 255, a: 1 }; const zOpacity = z.number().gte(0).lte(1); @@ -577,9 +541,6 @@ const zCanvasObjectState = z.discriminatedUnion('type', [ zCanvasRectState, ]); export type CanvasObjectState = z.infer; -export function isCanvasBrushLineState(obj: CanvasObjectState): obj is CanvasBrushLineState { - return obj.type === 'brush_line'; -} const zIPAdapterConfig = z.object({ image: zImageWithDims.nullable(), @@ -591,7 +552,7 @@ const zIPAdapterConfig = z.object({ }); export type IPAdapterConfig = z.infer; -export const zCanvasIPAdapterState = z.object({ +const zCanvasIPAdapterState = z.object({ id: zId, name: zName, type: z.literal('ip_adapter'), @@ -600,47 +561,6 @@ export const zCanvasIPAdapterState = z.object({ }); export type CanvasIPAdapterState = z.infer; -const zMaskObject = z - .discriminatedUnion('type', [ - zOLD_VectorMaskLine, - zOLD_VectorMaskRect, - zCanvasBrushLineState, - zCanvasEraserLineState, - zCanvasRectState, - ]) - .transform((val) => { - // Migrate old vector mask objects to new format - if (val.type === 'vector_mask_line') { - const { tool, ...rest } = val; - if (tool === 'brush') { - const asBrushline: CanvasBrushLineState = { - ...rest, - type: 'brush_line', - color: { r: 255, g: 255, b: 255, a: 1 }, - clip: null, - }; - return asBrushline; - } else if (tool === 'eraser') { - const asEraserLine: CanvasEraserLineState = { - ...rest, - type: 'eraser_line', - clip: null, - }; - return asEraserLine; - } - } else if (val.type === 'vector_mask_rect') { - const asRectShape: CanvasRectState = { - ...val, - type: 'rect', - color: { r: 255, g: 255, b: 255, a: 1 }, - }; - return asRectShape; - } else { - return val; - } - }) - .pipe(z.discriminatedUnion('type', [zCanvasBrushLineState, zCanvasEraserLineState, zCanvasRectState])); - const zFillStyle = z.enum(['solid', 'grid', 'crosshatch', 'diagonal', 'horizontal', 'vertical']); export type FillStyle = z.infer; export const isFillStyle = (v: unknown): v is FillStyle => zFillStyle.safeParse(v).success; @@ -658,7 +578,7 @@ const zRegionalGuidanceIPAdapterConfig = z.object({ }); export type RegionalGuidanceIPAdapterConfig = z.infer; -export const zCanvasRegionalGuidanceState = z.object({ +const zCanvasRegionalGuidanceState = z.object({ id: zId, name: zName, type: z.literal('regional_guidance'), @@ -686,37 +606,6 @@ const zCanvasInpaintMaskState = z.object({ }); export type CanvasInpaintMaskState = z.infer; -const zCanvasControlAdapterStateBase = z.object({ - id: zId, - type: z.literal('control_adapter'), - isEnabled: z.boolean(), - position: zCoordinate, - opacity: zOpacity, - filters: z.array(zLayerEffect), - weight: z.number().gte(-1).lte(2), - imageObject: zCanvasImageState.nullable(), - processedImageObject: zCanvasImageState.nullable(), - processorConfig: zFilterConfig.nullable(), - processorPendingBatchId: z.string().nullable().default(null), - beginEndStepPct: zBeginEndStepPct, - model: zModelIdentifierField.nullable(), -}); -const zCanvasControlNetState = zCanvasControlAdapterStateBase.extend({ - adapterType: z.literal('controlnet'), - controlMode: zControlModeV2, -}); -export type CanvasControlNetState = z.infer; -const zCanvasT2IAdapteState = zCanvasControlAdapterStateBase.extend({ - adapterType: z.literal('t2i_adapter'), -}); -export type CanvasT2IAdapterState = z.infer; - -export const zCanvasControlAdapterState = z.discriminatedUnion('adapterType', [ - zCanvasControlNetState, - zCanvasT2IAdapteState, -]); -export type CanvasControlAdapterState = z.infer; - const zControlNetConfig = z.object({ type: z.literal('controlnet'), model: zModelIdentifierField.nullable(), @@ -745,14 +634,14 @@ export const zCanvasRasterLayerState = z.object({ }); export type CanvasRasterLayerState = z.infer; -export const zCanvasControlLayerState = zCanvasRasterLayerState.extend({ +const zCanvasControlLayerState = zCanvasRasterLayerState.extend({ type: z.literal('control_layer'), withTransparencyEffect: z.boolean(), controlAdapter: z.discriminatedUnion('type', [zControlNetConfig, zT2IAdapterConfig]), }); export type CanvasControlLayerState = z.infer; -export const initialControlNetV2: ControlNetConfig = { +export const initialControlNet: ControlNetConfig = { type: 'controlnet', model: null, weight: 1, @@ -760,14 +649,14 @@ export const initialControlNetV2: ControlNetConfig = { controlMode: 'balanced', }; -export const initialT2IAdapterV2: T2IAdapterConfig = { +export const initialT2IAdapter: T2IAdapterConfig = { type: 't2i_adapter', model: null, weight: 1, beginEndStepPct: [0, 1], }; -export const initialIPAdapterV2: IPAdapterConfig = { +export const initialIPAdapter: IPAdapterConfig = { image: null, model: null, beginEndStepPct: [0, 1], @@ -776,17 +665,6 @@ export const initialIPAdapterV2: IPAdapterConfig = { weight: 1, }; -export const buildControlAdapterProcessorV2 = ( - modelConfig: ControlNetModelConfig | T2IAdapterModelConfig -): FilterConfig | null => { - const defaultPreprocessor = modelConfig.default_settings?.preprocessor; - if (!isFilterType(defaultPreprocessor)) { - return null; - } - const processorConfig = IMAGE_FILTERS[defaultPreprocessor].buildDefaults(modelConfig.base); - return processorConfig; -}; - export const imageDTOToImageWithDims = ({ image_name, width, height }: ImageDTO): ImageWithDims => ({ image_name, width, @@ -960,11 +838,6 @@ export type EntityRasterizedPayload = EntityIdentifierPayload<{ }>; export type ImageObjectAddedArg = { id: string; imageDTO: ImageDTO; position?: Coordinate }; -//#region Type guards -export const isLine = (obj: CanvasObjectState): obj is CanvasBrushLineState | CanvasEraserLineState => { - return obj.type === 'brush_line' || obj.type === 'eraser_line'; -}; - /** * A helper type to remove `[index: string]: any;` from a type. * This is useful for some Konva types that include `[index: string]: any;` in addition to statically named @@ -993,12 +866,6 @@ export function isDrawableEntity( return isDrawableEntityType(entity.type); } -export function isDrawableEntityAdapter( - adapter: CanvasLayerAdapter | CanvasControlAdapter | CanvasMaskAdapter -): adapter is CanvasLayerAdapter | CanvasMaskAdapter { - return adapter instanceof CanvasLayerAdapter || adapter instanceof CanvasMaskAdapter; -} - export const getEntityIdentifier = (entity: CanvasEntityState): CanvasEntityIdentifier => { return { id: entity.id, type: entity.type }; }; diff --git a/invokeai/frontend/web/src/features/controlLayers/util/simplify.ts b/invokeai/frontend/web/src/features/controlLayers/util/simplify.ts index d416e2870c..d2543ac5d3 100644 --- a/invokeai/frontend/web/src/features/controlLayers/util/simplify.ts +++ b/invokeai/frontend/web/src/features/controlLayers/util/simplify.ts @@ -131,7 +131,7 @@ type SimplifyOptions = { }; // both algorithms combined for awesome performance -export function simplifyCoords(points: Coordinate[], options?: SimplifyOptions): Coordinate[] { +function simplifyCoords(points: Coordinate[], options?: SimplifyOptions): Coordinate[] { const { tolerance, highestQuality } = { ...options, tolerance: 1, highestQuality: false }; if (points.length <= 2) { @@ -146,11 +146,11 @@ export function simplifyCoords(points: Coordinate[], options?: SimplifyOptions): return secondPassPoints; } -export function coordsToFlatNumbersArray(coords: Coordinate[]): number[] { +function coordsToFlatNumbersArray(coords: Coordinate[]): number[] { return coords.flatMap((coord) => [coord.x, coord.y]); } -export function flatNumbersArrayToCoords(array: number[]): Coordinate[] { +function flatNumbersArrayToCoords(array: number[]): Coordinate[] { assert(array.length % 2 === 0, 'Array length must be even'); const coords: Coordinate[] = []; for (let i = 0; i < array.length; i += 2) { diff --git a/invokeai/frontend/web/src/features/metadata/util/parsers.ts b/invokeai/frontend/web/src/features/metadata/util/parsers.ts index e28399809c..479add2e99 100644 --- a/invokeai/frontend/web/src/features/metadata/util/parsers.ts +++ b/invokeai/frontend/web/src/features/metadata/util/parsers.ts @@ -4,9 +4,9 @@ import type { CanvasControlAdapterState, CanvasIPAdapterState, CanvasRasterLayer import { IMAGE_FILTERS, imageDTOToImageWithDims, - initialControlNetV2, - initialIPAdapterV2, - initialT2IAdapterV2, + initialControlNet, + initialIPAdapter, + initialT2IAdapter, isFilterType, zCanvasRasterLayerState, } from 'features/controlLayers/store/types'; @@ -563,8 +563,8 @@ const parseControlNetToControlAdapterLayer: MetadataParseFunc = .parse(await getProperty(metadataItem, 'end_step_percent')); const beginEndStepPct: [number, number] = [ - begin_step_percent ?? initialIPAdapterV2.beginEndStepPct[0], - end_step_percent ?? initialIPAdapterV2.beginEndStepPct[1], + begin_step_percent ?? initialIPAdapter.beginEndStepPct[0], + end_step_percent ?? initialIPAdapter.beginEndStepPct[1], ]; const imageDTO = image ? await getImageDTO(image.image_name) : null; @@ -690,11 +690,11 @@ const parseIPAdapterToIPAdapterLayer: MetadataParseFunc = type: 'ip_adapter', isEnabled: true, model: zModelIdentifierField.parse(ipAdapterModel), - weight: typeof weight === 'number' ? weight : initialIPAdapterV2.weight, + weight: typeof weight === 'number' ? weight : initialIPAdapter.weight, beginEndStepPct, imageObject: imageDTO ? imageDTOToImageWithDims(imageDTO) : null, - clipVisionModel: initialIPAdapterV2.clipVisionModel, // TODO: This needs to be added to the zIPAdapterField... - method: method ?? initialIPAdapterV2.method, + clipVisionModel: initialIPAdapter.clipVisionModel, // TODO: This needs to be added to the zIPAdapterField... + method: method ?? initialIPAdapter.method, }; return layer; diff --git a/invokeai/frontend/web/src/features/nodes/store/actions.ts b/invokeai/frontend/web/src/features/nodes/store/actions.ts index 080acb4d95..14b7cfa95c 100644 --- a/invokeai/frontend/web/src/features/nodes/store/actions.ts +++ b/invokeai/frontend/web/src/features/nodes/store/actions.ts @@ -4,7 +4,7 @@ import type { Graph, GraphAndWorkflowResponse } from 'services/api/types'; const textToImageGraphBuilt = createAction('nodes/textToImageGraphBuilt'); const imageToImageGraphBuilt = createAction('nodes/imageToImageGraphBuilt'); -export const canvasGraphBuilt = createAction('nodes/canvasGraphBuilt'); +const canvasGraphBuilt = createAction('nodes/canvasGraphBuilt'); const nodesGraphBuilt = createAction('nodes/nodesGraphBuilt'); export const isAnyGraphBuilt = isAnyOf( diff --git a/invokeai/frontend/web/src/features/nodes/util/graph/generation/addRegions.ts b/invokeai/frontend/web/src/features/nodes/util/graph/generation/addRegions.ts index 2c42d2c077..3542356a34 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graph/generation/addRegions.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graph/generation/addRegions.ts @@ -18,6 +18,13 @@ type AddedRegionResult = { addedIPAdapters: number; }; +const isValidRegion = (rg: CanvasRegionalGuidanceState, base: BaseModelType) => { + const isEnabled = rg.isEnabled; + const hasTextPrompt = Boolean(rg.positivePrompt || rg.negativePrompt); + const hasIPAdapter = rg.ipAdapters.filter((ipa) => isValidIPAdapter(ipa, base)).length > 0; + return isEnabled && (hasTextPrompt || hasIPAdapter); +}; + /** * Adds regional guidance to the graph * @param regions Array of regions to add @@ -227,10 +234,3 @@ export const addRegions = async ( return results; }; - -export const isValidRegion = (rg: CanvasRegionalGuidanceState, base: BaseModelType) => { - const isEnabled = rg.isEnabled; - const hasTextPrompt = Boolean(rg.positivePrompt || rg.negativePrompt); - const hasIPAdapter = rg.ipAdapters.filter((ipa) => isValidIPAdapter(ipa, base)).length > 0; - return isEnabled && (hasTextPrompt || hasIPAdapter); -}; diff --git a/invokeai/frontend/web/src/features/nodes/util/graph/graphBuilderUtils.ts b/invokeai/frontend/web/src/features/nodes/util/graph/graphBuilderUtils.ts index 9818357fc0..5b4748cb2e 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graph/graphBuilderUtils.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graph/graphBuilderUtils.ts @@ -3,7 +3,6 @@ import type { CanvasV2State } from 'features/controlLayers/store/types'; import type { BoardField } from 'features/nodes/types/common'; import type { Graph } from 'features/nodes/util/graph/generation/Graph'; import { buildPresetModifiedPrompt } from 'features/stylePresets/hooks/usePresetModifiedPrompts'; -import { activeTabNameSelector } from 'features/ui/store/uiSelectors'; import { pick } from 'lodash-es'; import { stylePresetsApi } from 'services/api/endpoints/stylePresets'; import type { Invocation } from 'services/api/types'; @@ -63,17 +62,6 @@ export const getPresetModifiedPrompts = ( }; }; -/** - * Gets the is_intermediate field, based on the active tab and shouldAutoSave setting. - */ -export const getIsIntermediate = (state: RootState) => { - const activeTabName = activeTabNameSelector(state); - if (activeTabName === 'canvas') { - return !state.canvas.shouldAutoSave; - } - return false; -}; - export const getSizes = (bboxState: CanvasV2State['bbox']) => { const originalSize = pick(bboxState.rect, 'width', 'height'); const scaledSize = ['auto', 'manual'].includes(bboxState.scaleMethod) ? bboxState.scaledSize : originalSize; diff --git a/invokeai/frontend/web/src/features/parameters/components/DocumentSize/constants.ts b/invokeai/frontend/web/src/features/parameters/components/DocumentSize/constants.ts index 0e435e795e..8ecdf2bc1b 100644 --- a/invokeai/frontend/web/src/features/parameters/components/DocumentSize/constants.ts +++ b/invokeai/frontend/web/src/features/parameters/components/DocumentSize/constants.ts @@ -1,29 +1,7 @@ import type { ComboboxOption } from '@invoke-ai/ui-library'; import type { AspectRatioID, AspectRatioState } from './types'; -// When the aspect ratio is between these two values, we show the icon (experimentally determined) -export const ICON_LOW_CUTOFF = 0.23; -export const ICON_HIGH_CUTOFF = 1 / ICON_LOW_CUTOFF; -const ICON_SIZE_PX = 64; -const ICON_PADDING_PX = 16; -export const BOX_SIZE_CSS_CALC = `min(${ICON_SIZE_PX}px, calc(100% - ${ICON_PADDING_PX}px))`; -export const MOTION_ICON_INITIAL = { - opacity: 0, -}; -export const MOTION_ICON_ANIMATE = { - opacity: 1, - transition: { duration: 0.1 }, -}; -export const MOTION_ICON_EXIT = { - opacity: 0, - transition: { duration: 0.1 }, -}; -export const ICON_CONTAINER_STYLES = { - width: '100%', - height: '100%', - alignItems: 'center', - justifyContent: 'center', -}; + export const ASPECT_RATIO_OPTIONS: ComboboxOption[] = [ { label: 'Free' as const, value: 'Free' }, { label: '16:9' as const, value: '16:9' }, diff --git a/invokeai/frontend/web/src/features/parameters/types/parameterSchemas.ts b/invokeai/frontend/web/src/features/parameters/types/parameterSchemas.ts index 82620e488e..01d28ee63f 100644 --- a/invokeai/frontend/web/src/features/parameters/types/parameterSchemas.ts +++ b/invokeai/frontend/web/src/features/parameters/types/parameterSchemas.ts @@ -132,7 +132,7 @@ export type ParameterSpandrelImageToImageModel = z.infer; export const isParameterStrength = (val: unknown): val is ParameterStrength => zParameterStrength.safeParse(val).success; @@ -201,8 +201,3 @@ const zLoRAWeight = z.number(); type ParameterLoRAWeight = z.infer; export const isParameterLoRAWeight = (val: unknown): val is ParameterLoRAWeight => zLoRAWeight.safeParse(val).success; // #endregion - -// #region Regional Prompts AutoNegative -export const zAutoNegative = z.enum(['off', 'invert']); -export type ParameterAutoNegative = z.infer; -// #endregion