How to create new shapekey with scripting

Hello, I am trying to do some viseme work for DAZ model into ones for VRChat and a couple of other ones I want. I am wondering how do I either duplicate a shape key or create new from mix and then take the very last one in the shape key array and rename it to whatever I want to name the new one.

Updated
I managed to figure out how to duplicate shapekeys but I have no idea how to reorder them.
Update 2
I managed to rename materials, but I don’t know how to make it active a specific material for deletion. Also, I don’t know how to re-orde them nor shapekeys. For the shapekeys I want stuff like Ah, then Ah2 and go down a predetermined list.

import bpy

#Get the selected object
selected_object = bpy.context.object

#Get object's Shapekeys
shape_keys = selected_object.data.shape_keys.key_blocks

#Loops through shapekeys and replace the names
for key in shape_keys:
    key.name = key.name.replace("Genesis8Male__PHMTeethGap","vrc.v_sil")
    key.name = key.name.replace("head__eCTRLvW","vrc.v_pp")
    key.name = key.name.replace("head__eCTRLvF","vrc.v_ff")
    key.name = key.name.replace("head__eCTRLvTH","vrc.v_th")
    key.name = key.name.replace("head__eCTRLvT","vrc.v_dd")
    key.name = key.name.replace("head__eCTRLvK","vrc.v_kk")
    key.name = key.name.replace("head__eCTRLvSH","vrc.v_ch")
    key.name = key.name.replace("head__eCTRLvS","vrc.v_ss")
    key.name = key.name.replace("head__eCTRLvM","vrc.v_nn")
    key.name = key.name.replace("head__eCTRLvER","vrc.v_rr")
    key.name = key.name.replace("head__eCTRLvAA","vrc.v_aa")
    key.name = key.name.replace("head__eCTRLvEE","vrc.v_e")
    key.name = key.name.replace("head__eCTRLvIH","vrc.v_ih")
    key.name = key.name.replace("head__eCTRLvOW","vrc.v_oh")
    key.name = key.name.replace("head__eCTRLvUW","vrc.v_ou")
    key.name = key.name.replace("head__eCTRLSmileOpenFullFace_HD","Smile")
    key.name = key.name.replace("head__eCTRLAngry_HD","Anger")
    key.name = key.name.replace("head__eCTRLShock_HD","Hachu Eye")
    key.name = key.name.replace("head__eCTRLEyesClosedR","Wink Right")
    key.name = key.name.replace("head__eCTRLEyesClosedL","Wink")
    key.name = key.name.replace("Genesis8Male__HFS_Head_17_Cat","CatHead_Head")
    key.name = key.name.replace("Genesis8MaleEyelashes__HFS_Head_17_Cat","CatHead_Lashes")
    key.name = key.name.replace("head__eCTRLEyesClosed","Blink")
    key.name = key.name.replace("Genesis8Male__HFS_Legs_05_Pawed","Paws")
    key.name = key.name.replace("Genesis8Male__PHMEyesPupilsSlit","SlitEyes")
    
ob=selected_object
sk = ob.data.shape_keys

#Materials
for material in bpy.data.materials:
    material.name = material.name.replace("EyeSocket","Face")
    material.name = material.name.replace("EyeMoisture","Delete1")
    material.name = material.name.replace("Toenails","Legs")
    material.name = material.name.replace("Fingernails","Arms")
    material.name = material.name.replace("Sclera","Eyes")
    material.name = material.name.replace("Cornea","Delete2")

#for material in bpy.data.materials:
#    if(material.name=='Delete1'):
#        bpy.ops.object.editmode_toggle()
#        bpy.ops.object.material_slot_select()
#        bpy.ops.mesh.delete(type='VERT')
#        bpy.ops.object.editmode_toggle()
#    if(material.name=='Delete2'):
#        bpy.ops.object.editmode_toggle()
#        bpy.ops.object.material_slot_select()
#        bpy.ops.mesh.delete(type='VERT')
#        bpy.ops.object.editmode_toggle()
#    bpy.ops.object.material_slot_remove_unused()


#ShapeKeys   
kingKey=bpy.context.object.data.shape_keys.key_blocks     
for shape in ob.data.shape_keys.key_blocks:
    if (shape.name=='vrc.v_aa'):
        shape.value=1.0
        selected_object.shape_key_add(from_mix=True)
        shape.value=0.0
        for key in shape_keys:
             key.name = key.name.replace("Key","Aah")
    if (shape.name=='Aah'):
        shape.value=1.0
        kingKey["vrc.v_aa"].value = 1
        selected_object.shape_key_add(from_mix=True)
        kingKey["vrc.v_aa"].value = 0
        shape.value=0.0
        for key in shape_keys:
             key.name = key.name.replace("Key","Aah 2")
    if (shape.name=='vrc.v_ch'):
        shape.value=1.0
        selected_object.shape_key_add(from_mix=True)
        shape.value=0.0
        for key in shape_keys:
             key.name = key.name.replace("Key","Ch")
    if (shape.name=='vrc.v_ou'):
        shape.value=1.0
        selected_object.shape_key_add(from_mix=True)
        shape.value=0.0
        for key in shape_keys:
             key.name = key.name.replace("Key","U")
    if (shape.name=='vrc.v_e'):
        shape.value=1.0
        selected_object.shape_key_add(from_mix=True)
        shape.value=0.0
        for key in shape_keys:
             key.name = key.name.replace("Key","E")
    if (shape.name=='vrc.v_oh'):
        shape.value=1.0
        selected_object.shape_key_add(from_mix=True)
        shape.value=0.0
        for key in shape_keys:
             key.name = key.name.replace("Key","Oh")
    if (shape.name=='vrc.v_nn'):
        shape.value=1.0
        selected_object.shape_key_add(from_mix=True)
        shape.value=0.0
        for key in shape_keys:
             key.name = key.name.replace("Key","Hmm")
    if (shape.name=='vrc.v_pp'):
        shape.value=1.0
        selected_object.shape_key_add(from_mix=True)
        shape.value=0.0
        for key in shape_keys:
             key.name = key.name.replace("Key","Wa")
    if (shape.name=='CatHead_Head'):
        shape.value=1.0
        kingKey["CatHead_Lashes"].value = 1
        selected_object.shape_key_add(from_mix=True)
        kingKey["CatHead_Lashes"].value = 0
        shape.value=0.0
        for key in shape_keys:
             key.name = key.name.replace("Key","CatHead")
    if (shape.name=='Genesis8Male__PHMEyesPupilsDilate'):
        shape.value=0.15
        kingKey["Genesis8Male__CTRLEyesIrisSize"].slider_min = -1.0
        kingKey["Genesis8Male__CTRLEyesIrisSize"].value = -1.0
        selected_object.shape_key_add(from_mix=True)
        kingKey["Genesis8Male__CTRLEyesIrisSize"].value = 0.0
        shape.value=0.0
        for key in shape_keys:
             key.name = key.name.replace("Key","HorrorChild!")
    if (shape.name=='CatHead'):
        shape.value=1.0
        kingKey["Paws"].value=0.5
        selected_object.shape_key_add(from_mix=True)
        kingKey["Paws"].value=0.0
        shape.value=0.0
        for key in shape_keys:
            key.name = key.name.replace("Key","Full_Cat")

sk = ob.data.shape_keys.key_blocks

sk_names = ("Aah", "Aah 2", "Ch", "U", "E", "Oh", "Hmm", "Wa", "Smile", "Anger",
         "HorrorChild!",  "Hachu Eyes", "CatHead", "Paws", "SlitEyes","Full_Cat")

for name in reversed(sk_names):
    idx = sk.find(name)
    if idx != -1:
        ob.active_shape_key_index = idx
        bpy.ops.object.shape_key_move(type='TOP')

You would have to get the index of a key, make it active (so it’s selected) and use bpy.ops.object.shape_key_move() to move it in a direction. Example:

sk = ob.data.shape_keys

# Getting the index of last key
last_sk = sk.key_blocks[-1]
idx = sk.key_blocks.find(last_sk.name)

# Setting the key active
ob.active_shape_key_index = idx

# Moving the key (one of 'TOP', 'BOTTOM', 'UP', 'DOWN')
bpy.ops.object.shape_key_move(type='TOP')

I am not familiar with python, would it be possible to inject this into a part of my code above so I would be able to see what you mean?

It would depend on where in the execution chain you want to move the last key, but assuming it’s the last thing you wanted to do, just have it placed at the end of the script:

import bpy

#Get the selected object
selected_object = bpy.context.object

#Get object's Shapekeys
shape_keys = selected_object.data.shape_keys.key_blocks

#Loops through shapekeys and replace the names
for key in shape_keys:
    key.name = key.name.replace("Genesis8Male__PHMTeethGap","vrc.v_sil")
    key.name = key.name.replace("head__eCTRLvW","vrc.v_pp")
    key.name = key.name.replace("head__eCTRLvF","vrc.v_ff")
    key.name = key.name.replace("head__eCTRLvTH","vrc.v_th")
    key.name = key.name.replace("head__eCTRLvT","vrc.v_dd")
    key.name = key.name.replace("head__eCTRLvK","vrc.v_kk")
    key.name = key.name.replace("head__eCTRLvSH","vrc.v_ch")
    key.name = key.name.replace("head__eCTRLvS","vrc.v_ss")
    key.name = key.name.replace("head__eCTRLvM","vrc.v_nn")
    key.name = key.name.replace("head__eCTRLvER","vrc.v_rr")
    key.name = key.name.replace("head__eCTRLvAA","vrc.v_aa")
    key.name = key.name.replace("head__eCTRLvEE","vrc.v_e")
    key.name = key.name.replace("head__eCTRLvIH","vrc.v_ih")
    key.name = key.name.replace("head__eCTRLvOW","vrc.v_oh")
    key.name = key.name.replace("head__eCTRLvUW","vrc.v_ou")
    key.name = key.name.replace("head__eCTRLSmileOpenFullFace_HD","Smile")
    key.name = key.name.replace("head__eCTRLAngry_HD","Anger")
    key.name = key.name.replace("head__eCTRLShock_HD","Hachu Eye")
    key.name = key.name.replace("head__eCTRLEyesClosedR","Wink Right")
    key.name = key.name.replace("head__eCTRLEyesClosedL","Wink")
    key.name = key.name.replace("Genesis8Male__HFS_Head_17_Cat","CatHead_Head")
    key.name = key.name.replace("Genesis8MaleEyelashes__HFS_Head_17_Cat","CatHead_Lashes")
    key.name = key.name.replace("head__eCTRLEyesClosed","Blink")
    key.name = key.name.replace("Genesis8Male__HFS_Legs_05_Pawed","Paws")
    key.name = key.name.replace("Genesis8Male__PHMEyesPupilsSlit","SlitEyes")
    
ob=selected_object
sk = ob.data.shape_keys

#Materials
for material in bpy.data.materials:
    material.name = material.name.replace("EyeSocket","Face")
    material.name = material.name.replace("Face.001","Face")
    material.name = material.name.replace("EyeMoisture","Delete1")
    material.name = material.name.replace("Toenails","Legs")
    material.name = material.name.replace("Fingernails","Arms")
    material.name = material.name.replace("Legs.001","Legs")
    material.name = material.name.replace("Sclera","Eyes")
    material.name = material.name.replace("Cornea","Delete2")

for material in bpy.data.materials:
    if(material.name=='Delete1'):
        bpy.ops.object.editmode_toggle()
        bpy.ops.object.material_slot_select()
        bpy.ops.mesh.delete(type='VERT')
        bpy.ops.object.editmode_toggle()
    if(material.name=='Delete2'):
        bpy.ops.object.editmode_toggle()
        bpy.ops.object.material_slot_select()
        bpy.ops.mesh.delete(type='VERT')
        bpy.ops.object.editmode_toggle()
    bpy.ops.object.material_slot_remove_unused()


#ShapeKeys   
kingKey=bpy.data.shape_keys["Key.001"].key_blocks           
for shape in ob.data.shape_keys.key_blocks:
    if (shape.name=='vrc.v_aa'):
        shape.value=1.0
        selected_object.shape_key_add(from_mix=True)
        shape.value=0.0
        for key in shape_keys:
             key.name = key.name.replace("Key","Aah")
    if (shape.name=='Aah'):
        shape.value=1.0
        kingKey["vrc.v_aa"].value = 1
        selected_object.shape_key_add(from_mix=True)
        kingKey["vrc.v_aa"].value = 0
        shape.value=0.0
        for key in shape_keys:
             key.name = key.name.replace("Key","Aah 2")
    if (shape.name=='vrc.v_ch'):
        shape.value=1.0
        selected_object.shape_key_add(from_mix=True)
        shape.value=0.0
        for key in shape_keys:
             key.name = key.name.replace("Key","Ch")
    if (shape.name=='vrc.v_ou'):
        shape.value=1.0
        selected_object.shape_key_add(from_mix=True)
        shape.value=0.0
        for key in shape_keys:
             key.name = key.name.replace("Key","U")
    if (shape.name=='vrc.v_e'):
        shape.value=1.0
        selected_object.shape_key_add(from_mix=True)
        shape.value=0.0
        for key in shape_keys:
             key.name = key.name.replace("Key","E")
    if (shape.name=='vrc.v_oh'):
        shape.value=1.0
        selected_object.shape_key_add(from_mix=True)
        shape.value=0.0
        for key in shape_keys:
             key.name = key.name.replace("Key","Oh")
    if (shape.name=='vrc.v_nn'):
        shape.value=1.0
        selected_object.shape_key_add(from_mix=True)
        shape.value=0.0
        for key in shape_keys:
             key.name = key.name.replace("Key","Hmm")
    if (shape.name=='vrc.v_pp'):
        shape.value=1.0
        selected_object.shape_key_add(from_mix=True)
        shape.value=0.0
        for key in shape_keys:
             key.name = key.name.replace("Key","Wa")
    if (shape.name=='CatHead_Head'):
        shape.value=1.0
        kingKey["CatHead_Lashes"].value = 1
        selected_object.shape_key_add(from_mix=True)
        kingKey["CatHead_Lashes"].value = 0
        shape.value=0.0
        for key in shape_keys:
             key.name = key.name.replace("Key","CatHead")
    if (shape.name=='Genesis8Male__PHMEyesPupilsDilate'):
        shape.value=0.15
        kingKey["Genesis8Male__CTRLEyesIrisSize"].slider_min = -1.0
        kingKey["Genesis8Male__CTRLEyesIrisSize"].value = -1.0
        selected_object.shape_key_add(from_mix=True)
        kingKey["Genesis8Male__CTRLEyesIrisSize"].value = 0.0
        shape.value=0.0
        for key in shape_keys:
             key.name = key.name.replace("Key","HorrorChild!")
    if (shape.name=='CatHead'):
        shape.value=1.0
        kingKey["Paws"].value=0.5
        selected_object.shape_key_add(from_mix=True)
        kingKey["Paws"].value=0.0
        shape.value=0.0
        for key in shape_keys:
            key.name = key.name.replace("Key","Full_Cat")


sk = ob.data.shape_keys

# Getting the index of last key
last_sk = sk.key_blocks[-1]
idx = sk.key_blocks.find(last_sk.name)

# Setting the key active
ob.active_shape_key_index = idx

# Moving the key (one of 'TOP', 'BOTTOM', 'UP', 'DOWN')
bpy.ops.object.shape_key_move(type='TOP')

Its almost what I want. I’m wanting it to be like
Aah
Aah 2
Ch
U
E
Oh
Hmm
Wa
Smile
Anger
HorrorChild!
Hachu Eyes
CatHead
Paws
SlitEyes

Like I have a specific order I want things to be in, I don’t know how to make them in that specific order.

To get that order you start from the other end of the list and move each key to the top.

sk_names = ("Aah", "Aah 2", "Ch", "U", "E", "Oh", "Hmm", "Wa", "Smile", "Anger",
         "HorrorChild!",  "Hachu Eyes", "CatHead", "Paws", "SlitEyes")

for name in reversed(sk_names):
    idx = sk.find(name)
    if idx != -1:
        ob.active_shape_key_index = idx
        bpy.ops.object.shape_key_move(type='TOP')

Incorporated in the full script it would be something like this:

import bpy

#Get the selected object
selected_object = bpy.context.object

#Get object's Shapekeys
shape_keys = selected_object.data.shape_keys.key_blocks

#Loops through shapekeys and replace the names
for key in shape_keys:
    key.name = key.name.replace("Genesis8Male__PHMTeethGap","vrc.v_sil")
    key.name = key.name.replace("head__eCTRLvW","vrc.v_pp")
    key.name = key.name.replace("head__eCTRLvF","vrc.v_ff")
    key.name = key.name.replace("head__eCTRLvTH","vrc.v_th")
    key.name = key.name.replace("head__eCTRLvT","vrc.v_dd")
    key.name = key.name.replace("head__eCTRLvK","vrc.v_kk")
    key.name = key.name.replace("head__eCTRLvSH","vrc.v_ch")
    key.name = key.name.replace("head__eCTRLvS","vrc.v_ss")
    key.name = key.name.replace("head__eCTRLvM","vrc.v_nn")
    key.name = key.name.replace("head__eCTRLvER","vrc.v_rr")
    key.name = key.name.replace("head__eCTRLvAA","vrc.v_aa")
    key.name = key.name.replace("head__eCTRLvEE","vrc.v_e")
    key.name = key.name.replace("head__eCTRLvIH","vrc.v_ih")
    key.name = key.name.replace("head__eCTRLvOW","vrc.v_oh")
    key.name = key.name.replace("head__eCTRLvUW","vrc.v_ou")
    key.name = key.name.replace("head__eCTRLSmileOpenFullFace_HD","Smile")
    key.name = key.name.replace("head__eCTRLAngry_HD","Anger")
    key.name = key.name.replace("head__eCTRLShock_HD","Hachu Eye")
    key.name = key.name.replace("head__eCTRLEyesClosedR","Wink Right")
    key.name = key.name.replace("head__eCTRLEyesClosedL","Wink")
    key.name = key.name.replace("Genesis8Male__HFS_Head_17_Cat","CatHead_Head")
    key.name = key.name.replace("Genesis8MaleEyelashes__HFS_Head_17_Cat","CatHead_Lashes")
    key.name = key.name.replace("head__eCTRLEyesClosed","Blink")
    key.name = key.name.replace("Genesis8Male__HFS_Legs_05_Pawed","Paws")
    key.name = key.name.replace("Genesis8Male__PHMEyesPupilsSlit","SlitEyes")
    
ob=selected_object
sk = ob.data.shape_keys

#Materials
for material in bpy.data.materials:
    material.name = material.name.replace("EyeSocket","Face")
    material.name = material.name.replace("Face.001","Face")
    material.name = material.name.replace("EyeMoisture","Delete1")
    material.name = material.name.replace("Toenails","Legs")
    material.name = material.name.replace("Fingernails","Arms")
    material.name = material.name.replace("Legs.001","Legs")
    material.name = material.name.replace("Sclera","Eyes")
    material.name = material.name.replace("Cornea","Delete2")

for material in bpy.data.materials:
    if(material.name=='Delete1'):
        bpy.ops.object.editmode_toggle()
        bpy.ops.object.material_slot_select()
        bpy.ops.mesh.delete(type='VERT')
        bpy.ops.object.editmode_toggle()
    if(material.name=='Delete2'):
        bpy.ops.object.editmode_toggle()
        bpy.ops.object.material_slot_select()
        bpy.ops.mesh.delete(type='VERT')
        bpy.ops.object.editmode_toggle()
    bpy.ops.object.material_slot_remove_unused()


#ShapeKeys   
kingKey=bpy.data.shape_keys["Key.001"].key_blocks           
for shape in ob.data.shape_keys.key_blocks:
    if (shape.name=='vrc.v_aa'):
        shape.value=1.0
        selected_object.shape_key_add(from_mix=True)
        shape.value=0.0
        for key in shape_keys:
             key.name = key.name.replace("Key","Aah")
    if (shape.name=='Aah'):
        shape.value=1.0
        kingKey["vrc.v_aa"].value = 1
        selected_object.shape_key_add(from_mix=True)
        kingKey["vrc.v_aa"].value = 0
        shape.value=0.0
        for key in shape_keys:
             key.name = key.name.replace("Key","Aah 2")
    if (shape.name=='vrc.v_ch'):
        shape.value=1.0
        selected_object.shape_key_add(from_mix=True)
        shape.value=0.0
        for key in shape_keys:
             key.name = key.name.replace("Key","Ch")
    if (shape.name=='vrc.v_ou'):
        shape.value=1.0
        selected_object.shape_key_add(from_mix=True)
        shape.value=0.0
        for key in shape_keys:
             key.name = key.name.replace("Key","U")
    if (shape.name=='vrc.v_e'):
        shape.value=1.0
        selected_object.shape_key_add(from_mix=True)
        shape.value=0.0
        for key in shape_keys:
             key.name = key.name.replace("Key","E")
    if (shape.name=='vrc.v_oh'):
        shape.value=1.0
        selected_object.shape_key_add(from_mix=True)
        shape.value=0.0
        for key in shape_keys:
             key.name = key.name.replace("Key","Oh")
    if (shape.name=='vrc.v_nn'):
        shape.value=1.0
        selected_object.shape_key_add(from_mix=True)
        shape.value=0.0
        for key in shape_keys:
             key.name = key.name.replace("Key","Hmm")
    if (shape.name=='vrc.v_pp'):
        shape.value=1.0
        selected_object.shape_key_add(from_mix=True)
        shape.value=0.0
        for key in shape_keys:
             key.name = key.name.replace("Key","Wa")
    if (shape.name=='CatHead_Head'):
        shape.value=1.0
        kingKey["CatHead_Lashes"].value = 1
        selected_object.shape_key_add(from_mix=True)
        kingKey["CatHead_Lashes"].value = 0
        shape.value=0.0
        for key in shape_keys:
             key.name = key.name.replace("Key","CatHead")
    if (shape.name=='Genesis8Male__PHMEyesPupilsDilate'):
        shape.value=0.15
        kingKey["Genesis8Male__CTRLEyesIrisSize"].slider_min = -1.0
        kingKey["Genesis8Male__CTRLEyesIrisSize"].value = -1.0
        selected_object.shape_key_add(from_mix=True)
        kingKey["Genesis8Male__CTRLEyesIrisSize"].value = 0.0
        shape.value=0.0
        for key in shape_keys:
             key.name = key.name.replace("Key","HorrorChild!")
    if (shape.name=='CatHead'):
        shape.value=1.0
        kingKey["Paws"].value=0.5
        selected_object.shape_key_add(from_mix=True)
        kingKey["Paws"].value=0.0
        shape.value=0.0
        for key in shape_keys:
            key.name = key.name.replace("Key","Full_Cat")


sk = ob.data.shape_keys.key_blocks

sk_names = ("Aah", "Aah 2", "Ch", "U", "E", "Oh", "Hmm", "Wa", "Smile", "Anger",
         "HorrorChild!",  "Hachu Eyes", "CatHead", "Paws", "SlitEyes")

for name in reversed(sk_names):
    idx = sk.find(name)
    if idx != -1:
        ob.active_shape_key_index = idx
        bpy.ops.object.shape_key_move(type='TOP')

When I run it, it fails at idx = sk.find(name)

I’ve made a small change. Try again.

If it doesn’t work, can you paste the traceback?

That fixed it. Umm, so, how would I tell it a specific shapekey block? If you look at the top of the shapekey section I have a kingKey. I want it to take selected and I don’t know how to make it take selected object.

Not sure what you mean by “take selected”.

Do you want kingKey to refer to the key blocks of the selected object?

kingKey = bpy.context.object.data.shape_keys.key_blocks

Thats exactly what I mean. I have hopefully only 2 more needed questions before I can finish or work more on this project. This one is specifically materials. I have two specific materials I want it to remove. I have them renamed to Delete1 and Delete2. However when I run them as it is in the current code it doesn’t actually work, it just removes slot 1. I want it to remove those specific materials

My second question because I just thought about it for visemes. I tried implementing this before and it crashed blender. Basically if it sees something exist such as Aah I don’t want it to try and make another one where it than makes Aah.001

To remove those specific materials:

ob = bpy.context.object
remove_mats = ("Delete1", "Delete2")

for mat_name in remove_mats:
    idx = ob.material_slots.find(mat_name)
    if idx != -1:
        ob.data.materials.pop(index=idx)

You’d have to either break out of the loop after replacing the name, or hide it under a conditional. As it stands now, the script keeps trying to replace shape key names over and over. I’d rewrite some parts for you, but I can’t test the code.

So for the materials I want it to remove specific verts assigned to those materials than have it remove them. (Its extra verts I don’t want to deal with but all the models I work with have).

So in java (because thats what I’m learning in school) I would write somthing similar to this but doing this crashed it

if(shape.name=='Aah')
    continue
else
    <the big bunch of code to make it>

or atleast something like this

Materials aren’t assigned to vertices, only to faces. You want to remove the faces with those materials assigned?

import bmesh
remove_mats = ("Delete1", "Delete2")

if bpy.context.mode != 'EDIT_MESH':
    bpy.ops.object.editmode_toggle()
bm = bmesh.from_edit_mesh(ob.data)

for mat_name in remove_mats:
    idx = ob.material_slots.find(mat_name)
    if idx != -1:
        faces = [f for f in bm.faces if f.material_index == idx]
        bmesh.ops.delete(bm, geom=faces, context='FACES')

bmesh.update_edit_mesh(ob.data)
bpy.ops.object.mode_set(mode='OBJECT')

The material one worked as intended, the last part isn’t necessary but its something I would like to have in the event that I would need to use it more than once. However, in my current run workflow its only needed once.

Oh, I never said thank you! I really appreciate you giving me some time in creating this script.

I don’t have a blend file to work with so I’ve no idea if this works or if it’s the outcome you’re after, but it should help you get an idea.

Duplicating/copying shape keys is moved into a function.

import bpy
import bmesh

def run():
    #Get the selected object
    ob = bpy.context.object

    #Get object's Shapekeys
    shape_keys = ob.data.shape_keys.key_blocks

    replace_keys = {
        "Genesis8Male__PHMTeethGap": "vrc.v_sil",
        "head__eCTRLvW": "vrc.v_pp",
        "head__eCTRLvF": "vrc.v_ff",
        "head__eCTRLvTH": "vrc.v_th",
        "head__eCTRLvT": "vrc.v_dd",
        "head__eCTRLvK": "vrc.v_kk",
        "head__eCTRLvSH": "vrc.v_ch",
        "head__eCTRLvS": "vrc.v_ss",
        "head__eCTRLvM": "vrc.v_nn",
        "head__eCTRLvER": "vrc.v_rr",
        "head__eCTRLvAA": "vrc.v_aa",
        "head__eCTRLvEE": "vrc.v_e",
        "head__eCTRLvIH": "vrc.v_ih",
        "head__eCTRLvOW": "vrc.v_oh",
        "head__eCTRLvUW": "vrc.v_ou",
        "head__eCTRLSmileOpenFullFace_HD": "Smile",
        "head__eCTRLAngry_HD": "Anger",
        "head__eCTRLShock_HD": "Hachu Eye",
        "head__eCTRLEyesClosedR": "Wink Right",
        "head__eCTRLEyesClosedL": "Wink",
        "Genesis8Male__HFS_Head_17_Cat": "CatHead_Head",
        "Genesis8MaleEyelashes__HFS_Head_17_Cat": "CatHead_Lashes",
        "head__eCTRLEyesClosed": "Blink",
        "Genesis8Male__HFS_Legs_05_Pawed": "Paws",
        "Genesis8Male__PHMEyesPupilsSlit": "SlitEyes"
    }
    #Loops through shapekeys and replaces the names
    for key_old, key_new in replace_keys.items():
        key = shape_keys.get(key_old)
        if key:
            key.name = key_new

    # Replace material names
    replace_mats = {
        "EyeSocket": "Face",
        "EyeMoisture": "Delete1",
        "Toenails": "Legs",
        "Fingernails": "Arms",
        "Sclera": "Eyes",
        "Cornea": "Delete2"
    }
    for old_mat, new_mat in replace_mats.items():
        mat = bpy.data.materials.get(old_mat)
        if mat:
            mat.name = new_mat

    # Remove geometry assigned to "Delete1", "Delete2"
    if bpy.context.mode != 'EDIT_MESH':
        bpy.ops.object.editmode_toggle()
    bm = bmesh.from_edit_mesh(ob.data)

    for mat_name in ("Delete1", "Delete2"):
        idx = ob.material_slots.find(mat_name)
        if idx != -1:
            faces = [f for f in bm.faces if f.material_index == idx]
            bmesh.ops.delete(bm, geom=faces, context='FACES')

    bmesh.update_edit_mesh(ob.data)
    bpy.ops.object.mode_set(mode='OBJECT')

    # Duplicate key function
    sk = ob.data.shape_keys.key_blocks
    def duplicate_key(ob, idx, new_name, start_val=1.0):
        sk[idx].value = start_val
        ob.active_shape_key_index = idx
        ob.shape_key_add(from_mix=True)
        ob.data.shape_keys.key_blocks[-1].name = new_name
        sk[idx].value = 0.0

    #ShapeKeys   
    kingKey = ob.data.shape_keys.key_blocks
    for idx, shape in enumerate(ob.data.shape_keys.key_blocks):
        if (shape.name=='vrc.v_aa'):
            duplicate_key(ob, idx, "Aah")
        elif (shape.name=='Aah'):
            duplicate_key(ob, idx, "Aah 2")
        elif (shape.name=='vrc.v_ch'):
            duplicate_key(ob, idx, "Ch")
        elif (shape.name=='vrc.v_ou'):
            duplicate_key(ob, idx, "U")
        elif (shape.name=='vrc.v_e'):
            duplicate_key(ob, idx, "E")
        elif (shape.name=='vrc.v_oh'):
            duplicate_key(ob, idx, "Oh")
        elif (shape.name=='vrc.v_nn'):
            duplicate_key(ob, idx, "Hmm")
        elif (shape.name=='vrc.v_pp'):
            duplicate_key(ob, idx, "Wa")
        elif (shape.name=='CatHead_Head'):
            duplicate_key(ob, idx, "CatHead")
        elif (shape.name=='Genesis8Male__PHMEyesPupilsDilate'):
            kingKey["Genesis8Male__CTRLEyesIrisSize"].slider_min = -1.0
            kingKey["Genesis8Male__CTRLEyesIrisSize"].value = -1.0
            duplicate_key(ob, idx, "HorrorChild!", start_val=0.15)
            kingKey["Genesis8Male__CTRLEyesIrisSize"].value = 0.0
        elif (shape.name=='CatHead'):
            duplicate_key(ob, idx, "Full_Cat", start_val=0.5)

    sk_names = ("Aah", "Aah 2", "Ch", "U", "E", "Oh", "Hmm", "Wa", "Smile", "Anger",
             "HorrorChild!",  "Hachu Eyes", "CatHead", "Paws", "SlitEyes","Full_Cat")

    for name in reversed(sk_names):
        idx = sk.find(name)
        if idx != -1:
            ob.active_shape_key_index = idx
            bpy.ops.object.shape_key_move(type='TOP')

if __name__ == "__main__":
    run()

Ok, I’ll have to give it a try tomorrow and let you know if it works. That looks so much cleaner than my current file.

It worked without issue. And it looks so clean compared to my code T.T