Ejemplo n.º 1
0
def set_parent(blender_object:bpy.types.Object,parent_info:ParentInfo)->None:
    assert isinstance(blender_object,bpy.types.Object)

    blender_object.parent = parent_info.parent
    blender_object.parent_type = parent_info.parent_type

    if parent_info.parent_type == _BONE:
        assert parent_info.parent.type == _ARMATURE and\
               parent_info.parent.data.bones.get(parent_info.parent_bone) is not None

        blender_object.parent_bone = parent_info.parent_bone
Ejemplo n.º 2
0
def build_pyramid_bones(armature_object: bpy.types.Object, pyramid_mesh_object: bpy.types.Object, target_bone_name: str, parent_bone_name: str):
    bone_names = PyramidBoneNames(target_bone_name)
    armature: bpy.types.Armature = armature_object.data

    if bone_names.base in armature.bones:
        # already built
        return

    print(f'build pyramid bones: {target_bone_name}')

    bpy.context.selected_objects.append(armature_object)
    bpy.context.view_layer.objects.active = armature_object

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

    pyramid_mesh: bpy.types.Mesh = pyramid_mesh_object.data
    vertices: List[Vector] = [v.co for v in pyramid_mesh.vertices]

    origin: Vector = pyramid_mesh_object.location - armature_object.location
    direction: Vector = vertices[PyramidVertex.APEX].normalized()

    bone_length = vertices[PyramidVertex.APEX].length / 7.5
    bone_vector = direction * bone_length

    # Move the apex vertex into the mesh
    pyramid_mesh.vertices[PyramidVertex.APEX].co -= bone_vector
    pyramid_mesh.update()

    def create_bones():
        base_bone = armature.edit_bones.new(bone_names.base)
        base_bone.head = origin
        base_bone.tail = origin + bone_vector
        base_bone.parent = armature.edit_bones[parent_bone_name]

        apex_bone = armature.edit_bones.new(bone_names.apex)
        apex_bone.parent = base_bone
        apex_bone.head = origin + vertices[PyramidVertex.APEX]
        apex_bone.tail = origin + vertices[PyramidVertex.APEX] + bone_vector

        base_a_bone = armature.edit_bones.new(bone_names.base_a)
        base_a_bone.parent = base_bone
        base_a_bone.head = origin + vertices[PyramidVertex.BASE_A]
        base_a_bone.tail = origin + vertices[PyramidVertex.BASE_A] + bone_vector

        base_b_bone = armature.edit_bones.new(bone_names.base_b)
        base_b_bone.parent = base_bone
        base_b_bone.head = origin + vertices[PyramidVertex.BASE_B]
        base_b_bone.tail = origin + vertices[PyramidVertex.BASE_B] + bone_vector

        base_c_bone = armature.edit_bones.new(bone_names.base_c)
        base_c_bone.parent = base_bone
        base_c_bone.head = origin + vertices[PyramidVertex.BASE_C]
        base_c_bone.tail = origin + vertices[PyramidVertex.BASE_C] + bone_vector

        base_d_bone = armature.edit_bones.new(bone_names.base_d)
        base_d_bone.parent = base_bone
        base_d_bone.head = origin + vertices[PyramidVertex.BASE_D]
        base_d_bone.tail = origin + vertices[PyramidVertex.BASE_D] + bone_vector

    create_bones()

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

    pyramid_mesh_object.parent = armature_object
    pyramid_mesh_object.parent_type = 'BONE'
    pyramid_mesh_object.parent_bone = bone_names.base
    pyramid_mesh_object.matrix_parent_inverse = armature.bones[bone_names.base].matrix_local.inverted() @ Matrix.Translation(-bone_vector)

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

    armature_editor = ArmatureEditor(armature_object)
    pose_bones = armature_editor.pose_bones
    armature_editor.add_copy_location_constraint(pose_bones[bone_names.apex], pyramid_mesh_object, 'apex', 'WORLD')
    armature_editor.add_copy_location_constraint(pose_bones[bone_names.base_a], pyramid_mesh_object, 'base_a', 'WORLD')
    armature_editor.add_copy_location_constraint(pose_bones[bone_names.base_b], pyramid_mesh_object, 'base_b', 'WORLD')
    armature_editor.add_copy_location_constraint(pose_bones[bone_names.base_c], pyramid_mesh_object, 'base_c', 'WORLD')
    armature_editor.add_copy_location_constraint(pose_bones[bone_names.base_d], pyramid_mesh_object, 'base_d', 'WORLD')

    bones = armature_editor.bones
    bones[bone_names.base].use_deform = False
    bones[target_bone_name].use_deform = False

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