0
$\begingroup$

My most recent code is like this:

bpy.ops.object.mode_set(mode='EDIT')
bone_obj = armature_obj.data.bones[bone_name]
bone_obj.select = True
armature_obj.data.bones.active = bone_obj
# Parent the mesh directly to the bone 
bpy.ops.object.mode_set(mode='OBJECT')
bpy.context.view_layer.objects.active = meshobj 
meshobj.select_set(True)
meshobj.parent = armature_obj
meshobj.parent_bone = bone_name
meshobj.parent_type = 'BONE'
                                                                                                                                            

What happens is that there's a cloud of orange points (spheres?) that surround and animate around the bones, but the actual meshes don't animate.

Edit, following the code below, I'm now getting the following, which I was getting before, and we gave up on bones.

Failed to add relation "Bone Parent"
Could not find op_from: ComponentKey(OBhanim_l_hip, BONE, 'hanim_l_hip')

Trace:

Depth    Type                     Name
-----    ----                     ----
1        Object                   HAnimJointLandmark_Box.144
2        Object                   USE_l_hip_JointShape
3        Object                   hanim_l_thigh

Basically, I'm getting this for each bone with the ComponentKey error. I will try to post more. I will probably have to construct a small example.

$\endgroup$

1 Answer 1

0
$\begingroup$

There are many ways to attach an object to a bone. The simplest is bone parenting. The script below should do it.

import bpy

# Get the armature object using its object name.
arm = bpy.data.objects['Rig']
# Get the active bone. I assume the weapon needs to be attached to this bone. If the name of the bone is known, this step can be skipped.
bone = arm.data.bones.active
# Get the active object. I assume the active object is the weapon.
obj = bpy.context.active_object

# Modify the parenting parameters to achieve bone parenting.
obj.parent = arm # Armature object
obj.parent_bone = bone.name # Bone name
obj.parent_type = 'BONE'

This will place the weapon at the tip of the bone and orient it to match the bone orientation. If this is not the desired position and orientation, you will have to modify the weapon transforms.

If you already prepared a setup where the weapon just needs to be parented to a proxy object (for example, an Empty), you can use object parenting which is simpler as shown below.

import bpy

empty = bpy.data.objects['Empty']
obj = bpy.context.active_object

obj.parent = empty

Edit: I would like to point out a few issues with the revised code in the question. I leave them as comments below.

# I assume you have "import bpy" somewhere before this snippet and you
# assigned the variables: bone_name, armature_obj, meshobj.

# 1. There is no need to switch to edit mode. We're dealing with object
# relations which is done on the object level.
# 2. This is an operator, which means it depends on the context. You
# need to make sure that the object of interest is active before
# running this.
bpy.ops.object.mode_set(mode='EDIT')

# Looking below, it doesn't seem you're using the bone at all. You're
# also not depending on the bone to be selected nor active. Also, bones
# are not objects. Bones to an armature object are like vertices to a
# mesh object.
bone_obj = armature_obj.data.bones[bone_name]
bone_obj.select = True
armature_obj.data.bones.active = bone_obj

# Since the switch to object mode was unnecessary, the switch back to
# object mode is unnecessary too.
bpy.ops.object.mode_set(mode='OBJECT')

# Making the object active and selecting it are both only needed if
# you're running an operator that requires the context to make sense.
bpy.context.view_layer.objects.active = meshobj 
meshobj.select_set(True)

# If you already have a handle on the meshobj and the armature_obj, and
# know the bone_name, these three lines are all you need.
meshobj.parent = armature_obj
meshobj.parent_bone = bone_name
meshobj.parent_type = 'BONE'

Edit: This is how the script would change if one wants to parent the mesh_obj to an empty_obj and parent the empty_obj to a bone named bone_name under armature_obj?

# I assume bpy was imported and the variables were already assigned. Something like the following lines will do:
import bpy
mesh_obj = bpy.data.objects["Cube"]
armature_obj = bpy.data.objects["Armature"]
empty_obj = bpy.data.objects["Empty"]
bone_name = "Bone"

# This is where the actual parenting happens.
mesh_obj.parent = empty_obj

empty_obj.parent = armature_obj
empty_obj.parent_bone = bone_name
empty_obj.parent_type = 'BONE'
$\endgroup$
5
  • $\begingroup$ I couldn’t get your first example to work, like I don’t have a top level bone or something. I’m not sure how to ger a top-level bone under armature yet. $\endgroup$ Commented May 12 at 18:26
  • $\begingroup$ I am not exactly sure what you mean by a top-level bone. The first example assumes that: the name of the armature object is known (Rig in the example), the bone that will act as the parent is active in edit-mode of the armature, and the child object, the weapon, is the active object. You don't really need the bone to be active. What you need is the bone name. I simply get the active bone to use its name later. $\endgroup$
    – Mr A
    Commented May 13 at 10:31
  • $\begingroup$ Okay, I’m going to proceed with attaching an empty to the bone, if there’s a complete script to parent to empty to bone and parent “axe” to empty, that would be cool. I discovered some other things related to matrix multiplication that I’m working on with simple examples. $\endgroup$ Commented Jun 6 at 21:38
  • $\begingroup$ @JohnCarlson, I edited my answer. I added a section with comments on your current code and a section answering your last question in the comments. $\endgroup$
    – Mr A
    Commented Jun 7 at 11:45
  • $\begingroup$ I’ll get back to this eventually. Right now, I’m using empties instead of bones, and the animation has been off. So there’s more fundamental things going on. I hope to provide both a bone solution and a non-bone solution. $\endgroup$ Commented Jun 7 at 15:24

You must log in to answer this question.

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