1
$\begingroup$

I'm trying to parent an object to a specific bone. I need to assign 100% bone weights to all vertices, to be able to read this as a skeletal mesh in Unreal Engine. I'm using this code:

ob= bpy.data.objects['Cube']
arma = bpy.data.objects['Armature']

ob.parent = arma
ob.parent_bone = "Bone"
ob.parent_type = 'BONE'

... It works, but the object changes its transform. How can I parent it without changing transform of the object? Here is my simple test blend file: http://pasteall.org/blend/index.php?id=46227

Please click the 'Run Script' button to see the issue.

I would be grateful for some hints. I've tried the matrix multiplication (matrix_world.inverted()), but it doesn't work for bones.

For example, Ctrl + P in editor does it properly - it parents an object to a bone without moving it. Thanks!

Update: I've also thought about assigning all the object's vertices to a bone with 100% weight - but I can't find any info on this one, I'm afraid that it's not possible? :(

$\endgroup$

2 Answers 2

1
$\begingroup$

You can do this using bpy.ops.object.parent_set() and using the keep_transform parameter. I also allowed to choose which bone of your armature you want it to be the parent by setting parent_bone = 'BoneNameYouWantToBeParent'as shown below:

import bpy

ob= bpy.data.objects['Cube']
arma = bpy.data.objects['Armature']

bpy.ops.object.select_all(action='DESELECT')
arma.select = True
bpy.context.scene.objects.active = arma 

bpy.ops.object.mode_set(mode='EDIT')

parent_bone = 'Bone' # choose the bone name which you want to be the parent

arma.data.edit_bones.active = arma.data.edit_bones[parent_bone]

bpy.ops.object.mode_set(mode='OBJECT')

bpy.ops.object.select_all(action='DESELECT') #deselect all objects
ob.select = True
arma.select = True
bpy.context.scene.objects.active = arma    #the active object will be the parent of all selected object

bpy.ops.object.parent_set(type='BONE', keep_transform=True)

As shown below I modified your armature to have multiple bones so you can select which bone you want it to be the parent to your Cube. In the below screenshot I used Bone to be the parent:

enter image description here

In the screenshot below I chose Bone.001 to be the parent:

enter image description here

Updated .blend file can be found here:

$\endgroup$
1
  • $\begingroup$ Thank you! + To make this a skeletal mesh (recognizable in e.g. Unreal Engine), it's also necessary to assign vertex groups. In my case I did something like this: pastebin.com/XMfNYyC3 $\endgroup$ Commented Apr 11, 2017 at 11:00
0
$\begingroup$

For anyone stumbling upon this in the future, this code works, but you will need to update Taks code for Blender 3.0+:

arma.select_set(True) and bpy.context.view_layer.objects.active = arma

So updated script looks like:

import bpy

ob= bpy.data.objects['Cube']
arma = bpy.data.objects['Armature']

bpy.ops.object.select_all(action='DESELECT')

arma.select_set(True)
bpy.context.view_layer.objects.active = arma

bpy.ops.object.mode_set(mode='EDIT')


parent_bone = 'Bone'  # choose the bone name which you want to be the parent

arma.data.edit_bones.active = arma.data.edit_bones[parent_bone]

bpy.ops.object.mode_set(mode='OBJECT')

bpy.ops.object.select_all(action='DESELECT')  # deselect all objects
ob.select_set(True)
arma.select_set(True)
bpy.context.view_layer.objects.active = arma
# the active object will be the parent of all selected object

bpy.ops.object.parent_set(type='BONE', keep_transform=True)
$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .