Skip to content

Commit

Permalink
feat(ui): use revised filters
Browse files Browse the repository at this point in the history
- Add backcompat for cnet model default settings
- Default filter selection based on model type
- Updated UI components to use new filter nodes
- Added handling for failed filter executions, preventing filter from getting stuck in case it failed for some reason
- New translations for all filters & fields
  • Loading branch information
psychedelicious committed Sep 11, 2024
1 parent 80dc44e commit 7b8cc8b
Show file tree
Hide file tree
Showing 26 changed files with 829 additions and 870 deletions.
78 changes: 73 additions & 5 deletions invokeai/frontend/web/public/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1809,13 +1809,81 @@
"process": "Process",
"apply": "Apply",
"cancel": "Cancel",
"spandrel": {
"spandrel_filter": {
"label": "Image-to-Image Model",
"description": "Run an image-to-image model on the selected layer.",
"paramModel": "Model",
"paramAutoScale": "Auto Scale",
"paramAutoScaleDesc": "The selected model will be run until the target scale is reached.",
"paramScale": "Target Scale"
"model": "Model",
"autoScale": "Auto Scale",
"autoScaleDesc": "The selected model will be run until the target scale is reached.",
"scale": "Target Scale"
},
"canny_edge_detection": {
"label": "Canny Edge Detection",
"description": "Generates an edge map from the selected layer using the Canny edge detection algorithm.",
"low_threshold": "Low Threshold",
"high_threshold": "Hight Threshold"
},
"color_map": {
"label": "Color Map",
"description": "Create a color map from the selected layer.",
"tile_size": "Tile Size"
},
"content_shuffle": {
"label": "Content Shuffle",
"description": "Shuffles the content of the selected layer, similar to a 'liquify' effect.",
"scale_factor": "Scale Factor"
},
"depth_anything_depth_estimation": {
"label": "Depth Anything",
"description": "Generates a depth map from the selected layer using a Depth Anything model.",
"model_size": "Model Size",
"model_size_small": "Small",
"model_size_small_v2": "Small v2",
"model_size_base": "Base",
"model_size_large": "Large"
},
"dw_openpose_detection": {
"label": "DW Openpose Detection",
"description": "Detects human poses in the selected layer using the DW Openpose model.",
"draw_hands": "Draw Hands",
"draw_face": "Draw Face",
"draw_body": "Draw Body"
},
"hed_edge_detection": {
"label": "HED Edge Detection",
"description": "Generates an edge map from the selected layer using the HED edge detection model.",
"scribble": "Scribble"
},
"lineart_anime_edge_detection": {
"label": "Lineart Anime Edge Detection",
"description": "Generates an edge map from the selected layer using the Lineart Anime edge detection model."
},
"lineart_edge_detection": {
"label": "Lineart Edge Detection",
"description": "Generates an edge map from the selected layer using the Lineart edge detection model.",
"coarse": "Coarse"
},
"mediapipe_face_detection": {
"label": "MediaPipe Face Detection",
"description": "Detects faces in the selected layer using the MediaPipe face detection model.",
"max_faces": "Max Faces",
"min_confidence": "Min Confidence"
},
"mlsd_detection": {
"label": "Line Segment Detection",
"description": "Generates a line segment map from the selected layer using the MLSD line segment detection model.",
"score_threshold": "Score Threshold",
"distance_threshold": "Distance Threshold"
},
"normal_map": {
"label": "Normal Map",
"description": "Generates a normal map from the selected layer."
},
"pidi_edge_detection": {
"label": "PiDiNet Edge Detection",
"description": "Generates an edge map from the selected layer using the PiDiNet edge detection model.",
"scribble": "Scribble",
"quantize_edges": "Quantize Edges"
}
},
"transform": {
Expand Down
2 changes: 1 addition & 1 deletion invokeai/frontend/web/src/app/types/invokeai.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { FilterType } from 'features/controlLayers/store/types';
import type { FilterType } from 'features/controlLayers/store/filters';
import type { ParameterPrecision, ParameterScheduler } from 'features/parameters/types/parameterSchemas';
import type { TabName } from 'features/ui/store/uiTypes';
import type { O } from 'ts-toolbelt';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import {
selectAutoProcessFilter,
settingsAutoProcessFilterToggled,
} from 'features/controlLayers/store/canvasSettingsSlice';
import { type FilterConfig, IMAGE_FILTERS } from 'features/controlLayers/store/types';
import type { FilterConfig } from 'features/controlLayers/store/filters';
import { IMAGE_FILTERS } from 'features/controlLayers/store/filters';
import { memo, useCallback, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { PiArrowsCounterClockwiseBold, PiCheckBold, PiShootingStarBold, PiXBold } from 'react-icons/pi';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library';
import type { CannyProcessorConfig } from 'features/controlLayers/store/types';
import { IMAGE_FILTERS } from 'features/controlLayers/store/types';
import type { CannyEdgeDetectionFilterConfig } from 'features/controlLayers/store/filters';
import { IMAGE_FILTERS } from 'features/controlLayers/store/filters';
import { useCallback } from 'react';
import { useTranslation } from 'react-i18next';

import type { FilterComponentProps } from './types';

type Props = FilterComponentProps<CannyProcessorConfig>;
const DEFAULTS = IMAGE_FILTERS['canny_image_processor'].buildDefaults();
type Props = FilterComponentProps<CannyEdgeDetectionFilterConfig>;
const DEFAULTS = IMAGE_FILTERS.canny_edge_detection.buildDefaults();

export const FilterCanny = ({ onChange, config }: Props) => {
export const FilterCannyEdgeDetection = ({ onChange, config }: Props) => {
const { t } = useTranslation();
const handleLowThresholdChanged = useCallback(
(v: number) => {
Expand All @@ -27,7 +27,7 @@ export const FilterCanny = ({ onChange, config }: Props) => {
return (
<>
<FormControl>
<FormLabel m={0}>{t('controlnet.lowThreshold')}</FormLabel>
<FormLabel m={0}>{t('controlLayers.filter.canny_edge_detection.low_threshold')}</FormLabel>
<CompositeSlider
value={config.low_threshold}
onChange={handleLowThresholdChanged}
Expand All @@ -44,7 +44,7 @@ export const FilterCanny = ({ onChange, config }: Props) => {
/>
</FormControl>
<FormControl>
<FormLabel m={0}>{t('controlnet.highThreshold')}</FormLabel>
<FormLabel m={0}>{t('controlLayers.filter.canny_edge_detection.high_threshold')}</FormLabel>
<CompositeSlider
value={config.high_threshold}
onChange={handleHighThresholdChanged}
Expand All @@ -64,4 +64,4 @@ export const FilterCanny = ({ onChange, config }: Props) => {
);
};

FilterCanny.displayName = 'FilterCanny';
FilterCannyEdgeDetection.displayName = 'FilterCannyEdgeDetection';
Original file line number Diff line number Diff line change
@@ -1,39 +1,38 @@
import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library';
import type { ColorMapProcessorConfig } from 'features/controlLayers/store/types';
import { IMAGE_FILTERS } from 'features/controlLayers/store/types';
import { type ColorMapFilterConfig, IMAGE_FILTERS } from 'features/controlLayers/store/filters';
import { memo, useCallback } from 'react';
import { useTranslation } from 'react-i18next';

import type { FilterComponentProps } from './types';

type Props = FilterComponentProps<ColorMapProcessorConfig>;
const DEFAULTS = IMAGE_FILTERS['color_map_image_processor'].buildDefaults();
type Props = FilterComponentProps<ColorMapFilterConfig>;
const DEFAULTS = IMAGE_FILTERS.color_map.buildDefaults();

export const FilterColorMap = memo(({ onChange, config }: Props) => {
const { t } = useTranslation();
const handleColorMapTileSizeChanged = useCallback(
(v: number) => {
onChange({ ...config, color_map_tile_size: v });
onChange({ ...config, tile_size: v });
},
[config, onChange]
);

return (
<>
<FormControl>
<FormLabel m={0}>{t('controlnet.colorMapTileSize')}</FormLabel>
<FormLabel m={0}>{t('controlLayers.filter.color_map.tile_size')}</FormLabel>
<CompositeSlider
value={config.color_map_tile_size}
defaultValue={DEFAULTS.color_map_tile_size}
value={config.tile_size}
defaultValue={DEFAULTS.tile_size}
onChange={handleColorMapTileSizeChanged}
min={1}
max={256}
step={1}
marks
/>
<CompositeNumberInput
value={config.color_map_tile_size}
defaultValue={DEFAULTS.color_map_tile_size}
value={config.tile_size}
defaultValue={DEFAULTS.tile_size}
onChange={handleColorMapTileSizeChanged}
min={1}
max={4096}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,75 +1,43 @@
import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library';
import type { ContentShuffleProcessorConfig } from 'features/controlLayers/store/types';
import { IMAGE_FILTERS } from 'features/controlLayers/store/types';
import type { ContentShuffleFilterConfig } from 'features/controlLayers/store/filters';
import { IMAGE_FILTERS } from 'features/controlLayers/store/filters';
import { memo, useCallback } from 'react';
import { useTranslation } from 'react-i18next';

import type { FilterComponentProps } from './types';

type Props = FilterComponentProps<ContentShuffleProcessorConfig>;
const DEFAULTS = IMAGE_FILTERS['content_shuffle_image_processor'].buildDefaults();
type Props = FilterComponentProps<ContentShuffleFilterConfig>;
const DEFAULTS = IMAGE_FILTERS.content_shuffle.buildDefaults();

export const FilterContentShuffle = memo(({ onChange, config }: Props) => {
const { t } = useTranslation();

const handleWChanged = useCallback(
const handleScaleFactorChanged = useCallback(
(v: number) => {
onChange({ ...config, w: v });
},
[config, onChange]
);

const handleHChanged = useCallback(
(v: number) => {
onChange({ ...config, h: v });
},
[config, onChange]
);

const handleFChanged = useCallback(
(v: number) => {
onChange({ ...config, f: v });
onChange({ ...config, scale_factor: v });
},
[config, onChange]
);

return (
<>
<FormControl>
<FormLabel m={0}>{t('controlnet.w')}</FormLabel>
<FormLabel m={0}>{t('controlLayers.filter.content_shuffle.scale_factor')}</FormLabel>
<CompositeSlider
value={config.w}
defaultValue={DEFAULTS.w}
onChange={handleWChanged}
value={config.scale_factor}
defaultValue={DEFAULTS.scale_factor}
onChange={handleScaleFactorChanged}
min={0}
max={4096}
marks
/>
<CompositeNumberInput value={config.w} defaultValue={DEFAULTS.w} onChange={handleWChanged} min={0} max={4096} />
</FormControl>
<FormControl>
<FormLabel m={0}>{t('controlnet.h')}</FormLabel>
<CompositeSlider
value={config.h}
defaultValue={DEFAULTS.h}
onChange={handleHChanged}
min={0}
max={4096}
marks
/>
<CompositeNumberInput value={config.h} defaultValue={DEFAULTS.h} onChange={handleHChanged} min={0} max={4096} />
</FormControl>
<FormControl>
<FormLabel m={0}>{t('controlnet.f')}</FormLabel>
<CompositeSlider
value={config.f}
defaultValue={DEFAULTS.f}
onChange={handleFChanged}
<CompositeNumberInput
value={config.scale_factor}
defaultValue={DEFAULTS.scale_factor}
onChange={handleScaleFactorChanged}
min={0}
max={4096}
marks
/>
<CompositeNumberInput value={config.f} defaultValue={DEFAULTS.f} onChange={handleFChanged} min={0} max={4096} />
</FormControl>
</>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import { Flex, FormControl, FormLabel, Switch } from '@invoke-ai/ui-library';
import type { DWOpenposeProcessorConfig } from 'features/controlLayers/store/types';
import { IMAGE_FILTERS } from 'features/controlLayers/store/types';
import { type DWOpenposeDetectionFilterConfig, IMAGE_FILTERS } from 'features/controlLayers/store/filters';
import type { ChangeEvent } from 'react';
import { memo, useCallback } from 'react';
import { useTranslation } from 'react-i18next';

import type { FilterComponentProps } from './types';

type Props = FilterComponentProps<DWOpenposeProcessorConfig>;
const DEFAULTS = IMAGE_FILTERS['dw_openpose_image_processor'].buildDefaults();
type Props = FilterComponentProps<DWOpenposeDetectionFilterConfig>;
const DEFAULTS = IMAGE_FILTERS['dw_openpose_detection'].buildDefaults();

export const FilterDWOpenpose = memo(({ onChange, config }: Props) => {
export const FilterDWOpenposeDetection = memo(({ onChange, config }: Props) => {
const { t } = useTranslation();

const handleDrawBodyChanged = useCallback(
Expand Down Expand Up @@ -38,15 +37,15 @@ export const FilterDWOpenpose = memo(({ onChange, config }: Props) => {
<>
<Flex sx={{ flexDir: 'row', gap: 6 }}>
<FormControl w="max-content">
<FormLabel m={0}>{t('controlnet.body')}</FormLabel>
<FormLabel m={0}>{t('controlLayers.filter.dw_openpose_detection.draw_body')}</FormLabel>
<Switch defaultChecked={DEFAULTS.draw_body} isChecked={config.draw_body} onChange={handleDrawBodyChanged} />
</FormControl>
<FormControl w="max-content">
<FormLabel m={0}>{t('controlnet.face')}</FormLabel>
<FormLabel m={0}>{t('controlLayers.filter.dw_openpose_detection.draw_face')}</FormLabel>
<Switch defaultChecked={DEFAULTS.draw_face} isChecked={config.draw_face} onChange={handleDrawFaceChanged} />
</FormControl>
<FormControl w="max-content">
<FormLabel m={0}>{t('controlnet.hands')}</FormLabel>
<FormLabel m={0}>{t('controlLayers.filter.dw_openpose_detection.draw_hands')}</FormLabel>
<Switch
defaultChecked={DEFAULTS.draw_hands}
isChecked={config.draw_hands}
Expand All @@ -58,4 +57,4 @@ export const FilterDWOpenpose = memo(({ onChange, config }: Props) => {
);
});

FilterDWOpenpose.displayName = 'FilterDWOpenpose';
FilterDWOpenposeDetection.displayName = 'FilterDWOpenposeDetection';
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import type { ComboboxOnChange } from '@invoke-ai/ui-library';
import { Combobox, FormControl, FormLabel } from '@invoke-ai/ui-library';
import type { DepthAnythingModelSize, DepthAnythingProcessorConfig } from 'features/controlLayers/store/types';
import { isDepthAnythingModelSize } from 'features/controlLayers/store/types';
import type { DepthAnythingFilterConfig, DepthAnythingModelSize } from 'features/controlLayers/store/filters';
import { isDepthAnythingModelSize } from 'features/controlLayers/store/filters';
import { memo, useCallback, useMemo } from 'react';
import { useTranslation } from 'react-i18next';

import type { FilterComponentProps } from './types';

type Props = FilterComponentProps<DepthAnythingProcessorConfig>;
type Props = FilterComponentProps<DepthAnythingFilterConfig>;

export const FilterDepthAnything = memo(({ onChange, config }: Props) => {
export const FilterDepthAnythingDepthEstimation = memo(({ onChange, config }: Props) => {
const { t } = useTranslation();
const handleModelSizeChange = useCallback<ComboboxOnChange>(
(v) => {
Expand All @@ -23,10 +23,10 @@ export const FilterDepthAnything = memo(({ onChange, config }: Props) => {

const options: { label: string; value: DepthAnythingModelSize }[] = useMemo(
() => [
{ label: t('controlnet.depthAnythingSmallV2'), value: 'small_v2' },
{ label: t('controlnet.small'), value: 'small' },
{ label: t('controlnet.base'), value: 'base' },
{ label: t('controlnet.large'), value: 'large' },
{ label: t('controlLayers.filter.depth_anything_depth_estimation.model_size_small_v2'), value: 'small_v2' },
{ label: t('controlLayers.filter.depth_anything_depth_estimation.model_size_small'), value: 'small' },
{ label: t('controlLayers.filter.depth_anything_depth_estimation.model_size_base'), value: 'base' },
{ label: t('controlLayers.filter.depth_anything_depth_estimation.model_size_large'), value: 'large' },
],
[t]
);
Expand All @@ -36,11 +36,11 @@ export const FilterDepthAnything = memo(({ onChange, config }: Props) => {
return (
<>
<FormControl>
<FormLabel m={0}>{t('controlnet.modelSize')}</FormLabel>
<FormLabel m={0}>{t('controlLayers.filter.depth_anything_depth_estimation.model_size')}</FormLabel>
<Combobox value={value} options={options} onChange={handleModelSizeChange} isSearchable={false} />
</FormControl>
</>
);
});

FilterDepthAnything.displayName = 'FilterDepthAnything';
FilterDepthAnythingDepthEstimation.displayName = 'FilterDepthAnythingDepthEstimation';
Loading

0 comments on commit 7b8cc8b

Please sign in to comment.