diff --git a/invokeai/frontend/web/src/features/controlLayers/store/controlLayersSlice.ts b/invokeai/frontend/web/src/features/controlLayers/store/controlLayersSlice.ts index fb890f7d45..39186945c1 100644 --- a/invokeai/frontend/web/src/features/controlLayers/store/controlLayersSlice.ts +++ b/invokeai/frontend/web/src/features/controlLayers/store/controlLayersSlice.ts @@ -921,7 +921,7 @@ export const LAYER_BBOX_NAME = 'layer.bbox'; export const COMPOSITING_RECT_NAME = 'compositing-rect'; // Getters for non-singleton layer and object IDs -const getRGLayerId = (layerId: string) => `${RG_LAYER_NAME}_${layerId}`; +export const getRGLayerId = (layerId: string) => `${RG_LAYER_NAME}_${layerId}`; const getRGLayerLineId = (layerId: string, lineId: string) => `${layerId}.line_${lineId}`; const getRGLayerRectId = (layerId: string, lineId: string) => `${layerId}.rect_${lineId}`; export const getRGLayerObjectGroupId = (layerId: string, groupId: string) => `${layerId}.objectGroup_${groupId}`; diff --git a/invokeai/frontend/web/src/features/metadata/util/recallers.ts b/invokeai/frontend/web/src/features/metadata/util/recallers.ts index 673e2187f2..5a17fd4b5d 100644 --- a/invokeai/frontend/web/src/features/metadata/util/recallers.ts +++ b/invokeai/frontend/web/src/features/metadata/util/recallers.ts @@ -9,6 +9,9 @@ import { import { allLayersDeleted, caLayerRecalled, + getCALayerId, + getIPALayerId, + getRGLayerId, heightChanged, iiLayerRecalled, ipaLayerRecalled, @@ -72,6 +75,7 @@ import { setRefinerSteps, } from 'features/sdxl/store/sdxlSlice'; import { getImageDTO } from 'services/api/endpoints/images'; +import { v4 as uuidv4 } from 'uuid'; const recallPositivePrompt: MetadataRecallFunc = (positivePrompt) => { getStore().dispatch(positivePromptChanged(positivePrompt)); @@ -243,6 +247,7 @@ const recallIPAdapters: MetadataRecallFunc = (ipAdapt const recallLayer: MetadataRecallFunc = async (layer) => { const { dispatch } = getStore(); // We need to check for the existence of all images and models when recalling. If they do not exist, SMITE THEM! + // Also, we need fresh IDs for all objects when recalling, to prevent multiple layers with the same ID. if (layer.type === 'control_adapter_layer') { const clone = deepClone(layer); if (clone.controlAdapter.image) { @@ -264,6 +269,8 @@ const recallLayer: MetadataRecallFunc = async (layer) => { clone.controlAdapter.model = null; } } + clone.id = getCALayerId(uuidv4()); + clone.controlAdapter.id = uuidv4(); dispatch(caLayerRecalled(clone)); return; } @@ -282,6 +289,8 @@ const recallLayer: MetadataRecallFunc = async (layer) => { clone.ipAdapter.model = null; } } + clone.id = getIPALayerId(uuidv4()); + clone.ipAdapter.id = uuidv4(); dispatch(ipaLayerRecalled(clone)); return; } @@ -305,7 +314,9 @@ const recallLayer: MetadataRecallFunc = async (layer) => { ipAdapter.model = null; } } + ipAdapter.id = uuidv4(); } + clone.id = getRGLayerId(uuidv4()); dispatch(rgLayerRecalled(clone)); return; }