Duplicate bones in python

Hello,

I try to duplicate bones in python but i dont succeed.
I want make equivalent of

‘Select armature’
‘Go in edit mode’
‘select a bone’
‘SHIFT-D’
‘ESC’

i try this script :

    bpy.ops.object.mode_set(mode='EDIT')
    bpy.ops.armature.select_all(action='DESELECT')
    arm = bpy.data.objects['rig']
    bone=arm.data.edit_bones['c_thigh_bend_01.r']
    bone.select=True
    arm.data.edit_bones.active = bone
    bpy.ops.armature.duplicate_move()

but the bone is not duplicated.

what is wrong in my script ?

Dealing with bones in Blender is not the simplest thing when you try writing the code to do it.
For that very reason, a long time ago I wrote a function to do it, and a few other functions besides.
I had it set up to pass in a class, because what I used the function for was multiple character types,
so I modified it slightly so you can pass in the bone name, and that means the armature name.
Usage example listed below the function.

def boneMirror(name, vector, mirror = False, fork=True, boneRoll=0):
    bpy.data.armatures[name].use_mirror_x = mirror
    x = vector[0]; y = vector[1]; z = vector[2]
    bpy.ops.object.mode_set(mode='EDIT')
    bpy.ops.armature.extrude_forked(ARMATURE_OT_extrude={"forked":fork}, TRANSFORM_OT_translate={"value":(x, y, z)})
    bone = bpy.context.object.data.bones.active
    currentBone = bpy.context.active_bone
    currentBone.roll = boneRoll
    return bone
    
name = 'Armature'
boneMirror(name, (1,0,-1))

You should be able to either use the function or view it as a guide for crafting your own. You can arrange or change the default values (the parameters with the equal signs, but they have to come
after the parameters without default values) After I did the modification of the function, I created an armature in Blender and tested the function to verify no mistakes, it is good.

1 Like

thank for your answer i ll check that

you can try something like this using matrix

arm = bpy.data.objects['rig']
bone = arm.data.edit_bones['c_thigh_bend_01.r']
copy_bone = arm.data.edit_bones.new(bone.name)
copy_bone.length = bone.length
copy_bone.matrix = bone.matrix.copy()
# move bone down
copy_bone.translate((0, 0, 1))
2 Likes

thanks anas , this solution do exactly what i need

arm = bpy.data.objects[‘rig’]
bone = arm.data.edit_bones[‘c_thigh_bend_01.r’]
copy_bone = arm.data.edit_bones.new(bone.name)
copy_bone.matrix = bone.matrix.copy()
copy_bone.length = bone.length

move bone down

copy_bone.translate((0, 0, 1))