ImageGen-NoobAI / chain_injectors /ipadapter_injector.py
RioShiina's picture
Upload folder using huggingface_hub
1875ee2 verified
def inject(assembler, chain_definition, chain_items):
if not chain_items:
return
final_settings = {}
if chain_items and isinstance(chain_items[-1], dict) and chain_items[-1].get('is_final_settings'):
final_settings = chain_items.pop()
if not chain_items:
return
end_node_name = chain_definition.get('end')
if not end_node_name or end_node_name not in assembler.node_map:
print(f"Warning: Target node '{end_node_name}' for IPAdapter chain not found. Skipping chain injection.")
return
end_node_id = assembler.node_map[end_node_name]
if 'model' not in assembler.workflow[end_node_id]['inputs']:
print(f"Warning: Target node '{end_node_name}' is missing 'model' input. Skipping IPAdapter chain.")
return
current_model_connection = assembler.workflow[end_node_id]['inputs']['model']
model_type = final_settings.get('model_type', 'sdxl')
megapixels = 1.05 if model_type == 'sdxl' else 0.39
pos_embed_outputs = []
neg_embed_outputs = []
for i, item_data in enumerate(chain_items):
loader_type = 'FaceID' if 'FACEID' in item_data.get('preset', '') else 'Unified'
loader_template_name = "IPAdapterUnifiedLoader"
if loader_type == 'FaceID':
loader_template_name = "IPAdapterUnifiedLoaderFaceID"
image_loader_id = assembler._get_unique_id()
image_loader_node = assembler._get_node_template("LoadImage")
image_loader_node['inputs']['image'] = item_data['image']
assembler.workflow[image_loader_id] = image_loader_node
image_scaler_id = assembler._get_unique_id()
image_scaler_node = assembler._get_node_template("ImageScaleToTotalPixels")
image_scaler_node['inputs']['image'] = [image_loader_id, 0]
image_scaler_node['inputs']['megapixels'] = megapixels
image_scaler_node['inputs']['upscale_method'] = "lanczos"
assembler.workflow[image_scaler_id] = image_scaler_node
ipadapter_loader_id = assembler._get_unique_id()
ipadapter_loader_node = assembler._get_node_template(loader_template_name)
ipadapter_loader_node['inputs']['model'] = current_model_connection
ipadapter_loader_node['inputs']['preset'] = item_data['preset']
if loader_type == 'FaceID':
ipadapter_loader_node['inputs']['lora_strength'] = item_data.get('lora_strength', 0.6)
assembler.workflow[ipadapter_loader_id] = ipadapter_loader_node
encoder_id = assembler._get_unique_id()
encoder_node = assembler._get_node_template("IPAdapterEncoder")
encoder_node['inputs']['weight'] = item_data['weight']
encoder_node['inputs']['ipadapter'] = [ipadapter_loader_id, 1]
encoder_node['inputs']['image'] = [image_scaler_id, 0]
assembler.workflow[encoder_id] = encoder_node
pos_embed_outputs.append([encoder_id, 0])
neg_embed_outputs.append([encoder_id, 1])
pos_combiner_id = assembler._get_unique_id()
pos_combiner_node = assembler._get_node_template("IPAdapterCombineEmbeds")
pos_combiner_node['inputs']['method'] = final_settings.get('final_combine_method', 'concat')
for i, conn in enumerate(pos_embed_outputs):
pos_combiner_node['inputs'][f'embed{i+1}'] = conn
assembler.workflow[pos_combiner_id] = pos_combiner_node
neg_combiner_id = assembler._get_unique_id()
neg_combiner_node = assembler._get_node_template("IPAdapterCombineEmbeds")
neg_combiner_node['inputs']['method'] = final_settings.get('final_combine_method', 'concat')
for i, conn in enumerate(neg_embed_outputs):
neg_combiner_node['inputs'][f'embed{i+1}'] = conn
assembler.workflow[neg_combiner_id] = neg_combiner_node
final_loader_type = 'FaceID' if 'FACEID' in final_settings.get('final_preset', '') else 'Unified'
final_loader_template_name = "IPAdapterUnifiedLoader"
if final_loader_type == 'FaceID':
final_loader_template_name = "IPAdapterUnifiedLoaderFaceID"
final_loader_id = assembler._get_unique_id()
final_loader_node = assembler._get_node_template(final_loader_template_name)
final_loader_node['inputs']['model'] = current_model_connection
final_loader_node['inputs']['preset'] = final_settings.get('final_preset', 'STANDARD (medium strength)')
if final_loader_type == 'FaceID':
final_loader_node['inputs']['lora_strength'] = final_settings.get('final_lora_strength', 0.6)
assembler.workflow[final_loader_id] = final_loader_node
apply_embeds_id = assembler._get_unique_id()
apply_embeds_node = assembler._get_node_template("IPAdapterEmbeds")
apply_embeds_node['inputs']['weight'] = final_settings.get('final_weight', 1.0)
apply_embeds_node['inputs']['embeds_scaling'] = final_settings.get('final_embeds_scaling', 'V only')
apply_embeds_node['inputs']['model'] = [final_loader_id, 0]
apply_embeds_node['inputs']['ipadapter'] = [final_loader_id, 1]
apply_embeds_node['inputs']['pos_embed'] = [pos_combiner_id, 0]
apply_embeds_node['inputs']['neg_embed'] = [neg_combiner_id, 0]
assembler.workflow[apply_embeds_id] = apply_embeds_node
assembler.workflow[end_node_id]['inputs']['model'] = [apply_embeds_id, 0]
print(f"IPAdapter injector applied. Redirected '{end_node_name}' model input through {len(chain_items)} reference images.")