示例#1
0
    def add_bones_bone(self, context, rig):
        # Add bones then set their defaults
        root = self.get_root(rig)
        prev_bones = self.get_prev_bones(rig)
        bone = rig.data.edit_bones.new('Bone')
        bone.parent = root

        bone.translate(
            Vector(
                utils.multiply_list(
                    Get.cursor(context).location,
                    rig.matrix_world.inverted().to_scale(
                    ),  # Get the transforms for the unscaled rig
                )) - rig.matrix_world.to_translation())

        # Use the original bone size (unscaled by the rig)
        bone.tail = bone.head + Vector(
            utils.multiply_list(
                Vector((0, 0, 0.1)),
                rig.matrix_world.inverted().to_scale(),
            )) - rig.matrix_world.to_translation()

        bone = str(bone.name)

        # Switch back to Pose mode and setup pose bones
        Set.mode(context, 'POSE', rig)

        bone = rig.data.bones[bone]
        rig.data.bones.active = bone
        Set.select(bone)
示例#2
0
def returnToArmature(context, widget):
    bone = fromWidgetFindBone(widget)
    armature = bone.id_data

    # Unhide collection if it was hidden in a previous run
    if widget.users_collection:  # Try to use the widget's collection
        collection = widget.users_collection[0]
    else:  # otherwise use default
        collection = get_collection(context)
    Set.visible(context, collection)

    Set.mode(context, 'OBJECT', widget)

    # collection = get_collection(context)
    if [x for x in armature.users_collection if x != collection]:
        # Don't hide the active collection
        collection.hide_viewport = True
    "New version doesn't have this"
    # get_collection_view_layer(collection).hide_viewport = True

    if getattr(context.space_data, 'local_view', None):
        bpy.ops.view3d.localview()

    Set.active(context, armature)
    Set.select(armature, True)

    Set.mode(context, 'POSE', armature)
    # Set.select(bone, True)
    # Set.active(context, bone)
    armature.data.bones[bone.name].select = True
    armature.data.bones.active = armature.data.bones[bone.name]
示例#3
0
    def add_bones_root(self, context, rig):
        # Add bones then set their defaults
        root = self.get_root(rig)
        prev_bones = self.get_prev_bones(rig)
        new_root = not bool(root)
        if root is None:
            root = rig.data.edit_bones.new('root')
            root.tail = Vector((0, 1, 0))
            root.bbone_x = 0.5
            root.bbone_z = 0.01
            root.layers = self.layer(27)
        for eb in rig.data.edit_bones:
            if eb.parent is None:
                eb.use_connect = False
                eb.parent = root
        root = str(root.name)

        # Switch back to Pose mode and setup pose bones
        Set.mode(context, 'POSE', rig)

        root = rig.pose.bones[root]

        if new_root:
            self.widget(root, 'Blenrig - Root')
        rig.data.bones.active = root.bone
        rig.data.layers[27] = True
示例#4
0
def editWidget(context, active_bone):
    widget = active_bone.custom_shape

    armature = active_bone.id_data
    Set.mode(context, 'OBJECT', armature)
    Set.select(armature, False)
    '''  # 2.7
    if context.space_data.lock_camera_and_layers == False :
        visibleLayers = numpy.array(bpy.context.space_data.layers)+widget.layers-armature.layers
        bpy.context.space_data.layers = visibleLayers.tolist()

    else :
        visibleLayers = numpy.array(bpy.context.scene.layers)+widget.layers-armature.layers
        bpy.context.scene.layers = visibleLayers.tolist()
    '''

    "Commented because the new version only uses get_collection"
    if widget.users_collection:
        collection = widget.users_collection[0]
    else:
        collection = get_collection(context)
        collection.objects.link(widget)
    Set.in_scene(context, collection)
    Set.visible(context, collection)
    "Commented because new version uses operator"
    # get_collection_view_layer(collection).hide_viewport = False
    if getattr(context.space_data, 'local_view', None):
        bpy.ops.view3d.localview()

    # select object and make it active
    Set.select(widget, True)
    Set.active(context, widget)
    Set.mode(context, 'EDIT', widget)
示例#5
0
    def add_bones_ik(self, context, rig):
        # Add bones then set their defaults
        root = self.get_root(rig)
        prev_bones = self.get_prev_bones(rig)
        pose_bones = []

        for bone_name in prev_bones:
            prev = rig.data.edit_bones[bone_name]

            bone = rig.data.edit_bones.new(self.mirror_name(prev.name, 'IK'))
            pose_bones.append([bone.name, prev.name])
            self.reset(bone, prev)

            bone.parent = root
            bone.use_deform = False

        # Switch back to Pose mode and setup pose bones
        Set.mode(context, 'POSE', rig)

        for bone, prev in pose_bones:
            bone = rig.pose.bones[bone]
            prev = rig.pose.bones[prev]
            rig.data.bones.active = bone.bone
            bone.custom_shape_transform = prev
            self.widget(bone, 'Circle', slide=(0, 0.5, 1))

            bone['IK_FK'] = prev.name
            prev['IK_FK'] = prev.name

            bone['IK_IK'] = bone.name
            prev['IK_IK'] = bone.name

            bone.rotation_mode = 'QUATERNION'
            bone.matrix = prev.matrix

            # for ct in ['COPY_LOCATION', 'COPY_ROTATION', 'COPY_SCALE']:
            # con = deform.constraints.new(ct)
            # con.name = 'DEF-'+con.name
            # con.target = rig
            # con.subtarget = stretch.name
            # con.target_space = 'LOCAL'
            # con.owner_space = 'LOCAL'
            # con.use_offset = True
            # con.show_expanded = False
            # con				=	deform.constraints.new('STRETCH_TO')
            # con.name = 'DEF-'+con.name
            # con.target		=	rig
            # con.subtarget = tail.name
            # con.rest_length = deform.bone.length
            # con.head_tail = 0

            if prev.bone_group:
                bone.bone_group = self.bgroup(rig,
                                              'IK-' + prev.bone_group.name)
            else:
                bone.bone_group = self.bgroup(rig, 'IK')
                prev.bone_group = self.bgroup(rig, 'FK')
示例#6
0
    def execute(self, context):
        (rigs, __) = get_rig_bones(context)

        for (rig, bones) in rigs.items():
            for bone in bones:
                self.pose_func(context, rig.pose.bones[bone.name])

        for rig in rigs:
            Set.mode(context, 'EDIT', rig)

        # Reparent soon-to-be orphans
        for (pbone, rig) in self.bones.items():
            bone = rig.data.edit_bones[pbone.name]

            for parent in bone.parent_recursive:
                if (parent not in self.bones):
                    break
            else:
                parent = None

            for child in bone.children:
                if (child not in self.bones):
                    child.parent = parent

        # Remove the bbone constrollers
        for (pbone, rig) in self.bones.items():
            ebones = rig.data.edit_bones
            ebones.remove(ebones[pbone.name])

        for rig in rigs:
            Set.mode(context, 'POSE', rig)

            # remove unused groups
            groups = (rig.pose.bone_groups[bg]
                      for bg in ("BBone FK", "BBone Stretch", "BBone Curve",
                                 "BBone Stretch [Hidden]")
                      if rig.pose.bone_groups.get(bg))
            for bg in list(groups):
                for bone in rig.pose.bones:
                    if bone.bone_group == bg:
                        break
                else:
                    rig.pose.bone_groups.remove(bg)

        # Remove unused widgets
        for wgt in self.widgets:
            if (wgt.users < 2):  # 1) mesh  2+) objects
                wgt_col = list(wgt.users_collection)
                bpy.data.objects.remove(wgt)
                for col in wgt_col:
                    if not col.all_objects:
                        bpy.data.collections.remove(col)

        return {'FINISHED'}
示例#7
0
    def execute(self, context):
        rig = context.active_object
        active = None

        if context.mode == 'PAINT_WEIGHT':
            for obj in context.selected_objects:
                if obj.type == 'ARMATURE':
                    active = rig
                    rig = obj
                    Set.active(context, rig)

        # if rig.type =='ARMATURE' and context.mode != 'EDIT_ARMATURE':

        meshes = self.get_meshes(context, rig)

        bone1 = context.active_pose_bone
        # bone2 = context.selected_pose_bones[1]
        for bone2 in context.selected_pose_bones:
            if bone2 == bone1:
                continue
            found = None

            for mesh in meshes:
                utils.merge_vertex_groups(
                    mesh,
                    bone1.name,
                    bone2.name,
                    # If remove is False, and the bone stayed, it would be equivalent to transferring only partial weights
                    remove=(self.mode == 'remove'))
                found = True

            # if found:
            # if self.mode == 'hide':
            #     bone2.hide = True
            # elif self.mode == 'show':
            #     bone2.hide = False
            # elif self.mode == 'remove':
            if (found and self.mode == 'remove'):
                for ch in bone2.id_data.children:
                    if (ch.parent_type == 'BONE') and (ch.parent_bone
                                                       == bone2.name):
                        mat = Get.matrix(ch)
                        ch.parent_bone = bone1.name
                        Set.matrix(ch, mat)
                name2 = bone2.name
                Set.mode(context, mode='EDIT')
                bone2 = rig.data.edit_bones[name2]
                rig.data.edit_bones.remove(bone2)
                Set.mode(context, mode='POSE')

        if active:
            Set.active(context, active)

        return {'FINISHED'}
示例#8
0
    def add_bones_mch(self, context, rig, mch_parent=False):
        # Add bones then set their defaults
        root = self.get_root(rig)
        prev_bones = self.get_prev_bones(rig)
        pose_bones = []

        # Get MCH Prefix
        parent_name = context.scene.mch_bone
        if parent_name == "":
            parent_name = "MCH-parent_"

        for bone_name in prev_bones:
            prev = rig.data.edit_bones[bone_name]

            # Replace bone prefixes with MCH instead of inserting keeping both
            name = parent_name + (prev.name.replace("DEF-", "", 1)).replace(
                "CTRL-", "", 1)

            bone = rig.data.edit_bones.new(name)
            pose_bones.append([bone.name, prev.name])
            self.reset(bone, prev)

            bone.use_deform = False
            bone.use_connect = prev.use_connect
            bone.parent = prev.parent

            prev.use_connect = False
            prev.parent = bone
            # prev.select = False
            # prev.hide = True
            if not mch_parent:
                for c in prev.children:
                    c.parent = bone

            Set.select(bone, False)

        # Switch back to Pose mode and setup pose bones
        Set.mode(context, 'POSE', rig)

        for bone, prev in pose_bones:
            bone = rig.pose.bones[bone]
            prev = rig.pose.bones[prev]
            rig.data.bones.active = bone.bone
            # self.widget(bone, 'Box')
            ...

            # Retarget drivers
            if not mch_parent:
                for tar in self.mch_driver_targets:
                    if (tar.id is rig) and (tar.bone_target == prev.name):
                        tar.bone_target = bone.name
示例#9
0
    def add_bones_vis(self, context, rig):
        # Add bones then set their defaults
        root = self.get_root(rig)
        prev_bones = self.get_prev_bones(rig)
        pose_bones = []

        for bone_name in prev_bones:
            prev = rig.data.edit_bones[bone_name]

            bone = rig.data.edit_bones.new(self.mirror_name(prev.name, 'VIS'))
            pose_bones.append([bone.name, prev.name])
            self.reset(bone, prev)

            bone.use_deform = False

            bone.parent = prev

        # Switch back to Pose mode and setup pose bones
        Set.mode(context, 'POSE', rig)

        for bone, prev in pose_bones:
            bone = rig.pose.bones[bone]
            prev = rig.pose.bones[prev]
            # rig.data.bones.active = bone.bone
            bone.custom_shape = prev.custom_shape
            bone.custom_shape_transform = prev.custom_shape_transform

            bone.bone.show_wire = True
            prev.custom_shape = None

            bone.bone.hide_select = True

            bone.matrix = prev.matrix

            driver = bone.bone.driver_add('hide')
            var = driver.driver.variables.new()
            var.name = 'var'
            driver.driver.expression = 'not var'
            var.type = 'SINGLE_PROP'
            vt = var.targets[0]
            vt.id = rig

            # vt.bone_target = target.name
            # vt.transform_space = 'LOCAL_SPACE'
            # vt.transform_type = transform
            # # if transform == 'SINGLE_PROP':

            vt.data_path = prev.bone.path_from_id('select')
示例#10
0
    def execute(self, context):
        obj = context.object

        in_edit = (obj.mode == 'EDIT')
        if in_edit:
            Set.mode(context, 'OBJECT')

        active = obj.active_shape_key
        vg = active.vertex_group
        index = obj.active_shape_key_index
        pin = obj.show_only_shape_key

        obj.show_only_shape_key = True
        active.vertex_group = ''
        bpy.ops.object.shape_key_add(from_mix=True)
        while obj.active_shape_key_index > (index + 1):
            bpy.ops.object.shape_key_move(type='UP')
        active.vertex_group = vg

        shape = obj.active_shape_key

        if self.mirror:
            shape.name = utils.flip_name(active.name)
            shape.vertex_group = utils.flip_name(vg)
        else:
            shape.vertex_group = vg
            shape.name = active.name

        for var in ('interpolation', 'mute', 'relative_key', 'slider_max',
                    'slider_min', 'value'):
            setattr(shape, var, getattr(active, var))
            driver = Get.driver(active, var)
            if not driver:
                continue
            newdriver = utils.copy_driver(driver, shape, var)

            if self.mirror:
                for v in newdriver.driver.variables:
                    for t in v.targets:
                        t.bone_target = utils.flip_name(t.bone_target)

        # obj.active_shape_key_index = index
        obj.show_only_shape_key = pin

        if in_edit:
            Set.mode(context, 'EDIT')

        return {'FINISHED'}
示例#11
0
    def execute(self, context):
        (rigs, self.selected) = get_rig_bones(context)

        for rig in rigs:
            Set.mode(context, 'EDIT', rig)
            self.hide_bones[rig] = list()
            self.center_bones[rig] = list()
        for (rig, bones) in rigs.items():
            for bone in bones:
                self.edit_func(context, rig.data.edit_bones[bone.name])
        for (ebones, ebone, tbone) in self.delayed_parenting:
            ebones[ebone].parent = ebones[tbone]
        (do_mch, do_start_end, do_in_out) = self.do()
        if do_start_end:
            self.edit_mirror_center(context)

        if self.warning:
            self.report({'WARNING'}, self.warning)

        for rig in rigs:
            Set.mode(context, 'POSE', rig)
        for (rig, bones) in rigs.items():
            for bone in bones:
                self.pose_func(context, rig.pose.bones[bone.name])

        def widget(ctrl_type,
                   wgt='Sphere',
                   global_size=6,
                   scale=(1, 1, 1),
                   slide=None):
            from mathutils import Vector
            bpy.ops.bonewidget.create_widget(
                global_size=global_size,
                slide=Vector(slide) if slide else Vector(),
                scale=scale,
                bones='%r' % self.bone_widgets[ctrl_type],
                widget=wgt,
            )

        widget('mch', wgt='Box', global_size=1, scale=(0.75, 0.75, 1))
        # widget('start', slide=(0, -0.5, 0))
        widget('start', wgt='Blenrig - Box', global_size=3)
        # widget('end', slide=(0, 0.5, 0))
        widget('end', wgt='Blenrig - Box', global_size=3)
        widget('in_out', global_size=7.5, slide=(0, 0.5, 0))

        return {'FINISHED'}
示例#12
0
    def add_bones_dupli(self, context, rig):
        # Add bones then set their defaults
        root = self.get_root(rig)
        prev_bones = self.get_prev_bones(rig)
        pose_bones = []
        flip_bones = []

        def add_bone(bone_name):
            prev = rig.data.edit_bones[bone_name]

            bone = rig.data.edit_bones.new(prev.name)
            pose_bones.append([bone.name, prev.name])
            self.reset(bone, prev)

            bone.parent = prev.parent
            bone.use_deform = prev.use_deform

        for bone_name in prev_bones:
            add_bone(bone_name)

            if rig.pose.use_mirror_x:
                flip = utils.flip_name(bone_name)
                if (flip in rig.data.edit_bones) and (flip not in (
                        *prev_bones, *(p for (b, p) in pose_bones))):
                    # Mirrored bone exists but not selected
                    add_bone(flip)
                    flip_bones.append(flip)

        # Switch back to Pose mode and setup pose bones
        Set.mode(context, 'POSE', rig)

        for (bone, prev) in pose_bones:
            bone = rig.pose.bones[bone]
            prev = rig.pose.bones[prev]
            if (prev.name not in flip_bones):
                rig.data.bones.active = bone.bone
            bone.custom_shape = prev.custom_shape
            bone.custom_shape_transform = prev.custom_shape_transform
            bone.bone.show_wire = prev.bone.show_wire
            bone.matrix = prev.matrix
            bone.bone_group = prev.bone_group
            for lock in [
                    'location', 'rotations_4d', 'rotation_w', 'rotation',
                    'scale'
            ]:
                setattr(bone, 'lock_' + lock, getattr(prev, 'lock_' + lock))
示例#13
0
    def execute(self, context):
        obj = context.object

        in_edit = (obj.mode == 'EDIT')
        if in_edit:
            Set.mode(context, 'OBJECT')

        active = obj.active_shape_key
        index = obj.active_shape_key_index
        pin = obj.show_only_shape_key

        obj.show_only_shape_key = True
        bpy.ops.object.shape_key_add(from_mix=True)
        while obj.active_shape_key_index > (index + 1):
            bpy.ops.object.shape_key_move(type='UP')

        shape = obj.active_shape_key
        for var in ('interpolation', 'mute', 'relative_key', 'slider_max', 'slider_min', 'value'):
            setattr(shape, var, getattr(active, var))
        # if self.keep_vertex_group:
            # shape.vertex_group = active.vertex_group

        # Redirect drivers, so that they auto update after operation
        for var in ('slider_max', 'slider_min', 'value'):
            driver = Get.driver(active, var)
            if driver:
                driver.data_path = f'key_blocks["{shape.name}"].{var}'
                # driver.data_path = driver.data_path.replace(active.name, shape.name, 1)

        name = active.name
        active.name += ".masked"
        shape.name = name

        obj.active_shape_key_index = index
        bpy.ops.object.shape_key_remove(all=False)
        obj.active_shape_key_index = index
        obj.show_only_shape_key = pin

        if in_edit:
            Set.mode(context, 'EDIT')

        return {'FINISHED'}
示例#14
0
def add_placeholder_bones(rigify, obj, metarig):
    context = bpy.context

    rigify_mode = rigify.mode
    meta_mode = metarig.mode
    Set.mode(context, 'EDIT', metarig)
    Set.mode(context, 'EDIT', rigify)

    for rigify_bone in rigify.data.edit_bones.keys():
        if not rigify_bone.startswith('DEF-'):
            # Not a DEF group, so...
            continue

        meta_bone = rigify_bone[4:]
        if obj.vertex_groups.get(meta_bone):
            # Both DEF and regular name in vertex groups
            continue

        if (meta_bone in metarig.data.edit_bones):
            continue

        rbone = rigify.data.edit_bones[rigify_bone]
        mbone = metarig.data.edit_bones.new(meta_bone)
        for attr in (
            # 'bbone_curveinx', 'bbone_curveiny',
            # 'bbone_curveoutx', 'bbone_curveouty',
            # 'bbone_custom_handle_end', 'bbone_custom_handle_start',
            # 'bbone_easein', 'bbone_easeout',
            # 'bbone_handle_type_end', 'bbone_handle_type_start',
            # 'bbone_rollin', 'bbone_rollout',
            # 'bbone_scaleinx', 'bbone_scaleiny',
            # 'bbone_scaleoutx', 'bbone_scaleouty',
            # 'bbone_segments',
            'bbone_x', 'bbone_z',
            'envelope_distance', 'envelope_weight',
            'head', 'head_radius', 'tail', 'tail_radius',
            'roll',
            'inherit_scale', 'use_inherit_rotation', 'use_inherit_scale',
            'use_endroll_as_inroll',
            'use_envelope_multiply',
            'use_local_location',
            'use_relative_parent',
            ):
            setattr(mbone, attr, getattr(rbone, attr))
        if rbone.parent:
            mbone.parent = metarig.data.edit_bones.get(rbone.parent.name[4:])
            if mbone.parent:
                mbone.layers = mbone.parent.layers

    Set.mode(context, meta_mode, metarig)
    Set.mode(context, rigify_mode, rigify)
示例#15
0
    def add_bones_stretch_tail(self, context, rig):
        # Add bones then set their defaults
        root = self.get_root(rig)
        prev_bones = self.get_prev_bones(rig)
        pose_bones = []

        for bone_name in prev_bones:
            prev = rig.data.edit_bones[bone_name]

            bone = rig.data.edit_bones.new(self.mirror_name(prev.name, 'STRT'))
            pose_bones.append([bone.name, prev.name])
            self.reset(bone, prev)

            bone.parent = prev.parent
            bone.use_deform = False

        # Switch back to Pose mode and setup pose bones
        Set.mode(context, 'POSE', rig)

        for bone, prev in pose_bones:
            bone = rig.pose.bones[bone]
示例#16
0
文件: New.py 项目: Irmitya/zpy
def bone(context, armature, name="", edit=None, pose=None, overwrite=False):
    "Insert a bone into an armature object"

    if getattr(armature, 'type', None) != 'ARMATURE':
        return

    # active = Get.active(context)
    # Set.active(context, armature)
    # Set.select(armature, True)
    # Set.visible(context, armature, True)
    # mode = armature.mode.replace('EDIT_ARMATURE', 'EDIT')
    Set.in_scene(context, armature)
    is_visible = Is.visible(context, armature)
    Set.visible(context, armature, True)

    mode = armature.mode
    # mode = context.mode.replace('EDIT_ARMATURE', 'EDIT')

    # Go into Edit mode and create a new bone
    ebones = armature.data.edit_bones
    if armature.mode != 'EDIT':
        Set.mode(context, 'EDIT', armature)
    mirror = armature.data.use_mirror_x
    armature.data.use_mirror_x = False
    children = list()
    if overwrite and name in ebones:
        for child in ebones[name].children:
            children.append((child, child.use_connect))
            child.use_connect = False
        ebones.remove(ebones[name])
    bone = ebones.new(name)
    for child, child_connect in children:
        child.parent = bone
        child.use_connect = child_connect
    bone.tail = ((0, 0, 1))
    # If the bone's head AND tail stay at 0,
    # it gets deleted when leaving edit mode
    name = bone.name
    if edit:
        edit(bone)
    armature.data.use_mirror_x = mirror

    pbones = armature.pose.bones
    if pose:
        Set.mode(context, 'POSE', armature)
        bone = pbones[name]
        pose(bone)

    # Revert mode change
    if mode != armature.mode:
        # Set.active(active)
        Set.mode(context, mode, armature)
    Set.visible(context, armature, is_visible)

    if armature.mode == 'EDIT':
        bone = ebones[name]
    else:
        bone = pbones[name]

    return bone
    def fix_toe_roll():
        """
        The Toe controller bone may have a bad automated roll, so recalculate it
        """
        mode = Get.mode(rig)
        Set.mode(bpy.context, 'EDIT', rig)
        bones = rig.data.edit_bones

        ebones = bpy.context.selected_bones
        for ebone in ebones:
            ebone.select = False

        bone = tweak = None

        def get(name):
            nonlocal bone, tweak
            bone = bones.get(name)
            tweak = bones.get(name.replace('_master', ''))
            return (bone and tweak)

        def roll(name):
            if get(name):
                bone.select = True
                bones.active = tweak
                bpy.ops.armature.calculate_roll(type='ACTIVE')
                bone.select = False

        for lr in ('L', 'R'):
            for ind in range(1, 6):
                roll(f'toe{ind}.01_master.{lr}')
            roll(f'thumb.01_master.{lr}')
            roll(f'f_index.01_master.{lr}')
            roll(f'f_middle.01_master.{lr}')
            roll(f'f_ring.01_master.{lr}')
            roll(f'f_pinky.01_master.{lr}')

        for ebone in ebones:
            ebone.select = True

        Set.mode(bpy.context, mode, rig)
示例#18
0
def metafy_rigify(context, rig):
    """Isolate Org bones in rig, then mimic the likely original bone layers"""

    Set.mode(context, 'EDIT', rig)

    bones = rig.data.edit_bones
    for bone in bones.values():
        bone.inherit_scale = 'ALIGNED'
        if bone.name.startswith('ORG-'):
            bone.layers = utils.layer(0)
        else:
            bones.remove(bone)

    Set.mode(context, 'POSE', rig)

    for bone in rig.pose.bones:
        bone.lock_rotation_w = False
        for index in range(3):
            bone.lock_location[index] = False
            bone.lock_rotation[index] = False
            bone.lock_scale[index] = False

    rig.data.layers = utils.layer(0)
示例#19
0
    def execute(self, context):
        active = Get.active(context)
        mode = context.mode
        pose = list()

        for rig in context.selected_objects:
            (rig, meta) = self.poll_parse(context, rig)
            if None in (rig, meta):
                continue

            rigify_to_meta(rig, meta)
            pose.append((meta, rig))
        else:
            if mode == 'POSE':
                Set.mode(context, 'OBJECT')
            for (meta, rig) in pose:
                Set.select(rig, False)
                Set.select(meta, True)
                if rig == active:
                    Set.active(context, meta)
            if mode == 'POSE':
                Set.mode(context, 'POSE')

        return {'FINISHED'}
示例#20
0
    def execute(self, context):
        objects = [context.active_object] + \
                  [o for o in context.selected_editable_objects
                   if o != context.active_object]

        any_polled = False

        for rig in objects:
            if not Is.armature(rig) or not Set.mode(context, 'EDIT', rig):
                # object can't go into (armature) edit mode
                continue

            # Place driver search here to avoid scanning all datas, if nothing's being added
            if (not any_polled) and (self.type == 'MCH'):
                self.mch_driver_targets = list()
                # self.mch_driver_targets = self.get_drivers(objects)

            any_polled = True

            if self.type == 'BONE':
                self.add_bones_bone(context, rig)
                break  # Only add one bone, to the active rig or first applicable
            elif self.type == 'ROOT':
                self.add_bones_root(context, rig)
            elif self.type == 'DUPLI':
                self.add_bones_dupli(context, rig)
            elif self.type == 'VIS':
                self.add_bones_vis(context, rig)
            elif self.type == 'MCH':
                self.add_bones_mch(context, rig)
            elif self.type == 'MCH_PARENT':
                self.add_bones_mch(context, rig, mch_parent=True)
            elif self.type == 'IK':
                self.add_bones_ik(context, rig)
            elif self.type == 'STRETCH':
                self.add_bones_stretch(context, rig)
            elif self.type == 'STRETCH_TAIL':
                self.add_bones_stretch_tail(context, rig)

        if any_polled and (self.type == 'DUPLI'):
            bpy.ops.transform.translate('INVOKE_DEFAULT')

        return {'FINISHED'}
示例#21
0
    def execute(self, context):
        # TODO: Redo / Cleanup code
        class props:
            keep_matrix = True
            connect = False
            connect_child = False
            stretch = False

            if self.type == 'BONE':
                pass
            elif self.type == 'BONE_CONNECT':
                connect = True
            elif self.type == 'STRETCH':
                stretch = True
            elif self.type == 'STRETCH_CONNECT':
                stretch = True
                connect = True
            elif self.type == 'CHILD_CONNECT':
                connect_child = True

        ap = context.active_pose_bone
        bones = dict()
        matrices = {b: b.matrix.copy() for b in context.selected_pose_bones}

        for rig in context.selected_objects:
            if rig.mode != 'POSE':
                continue

            Set.mode(context, 'EDIT', rig)
            mirror = rig.data.use_mirror_x
            rig.data.use_mirror_x = False

            ab = context.active_bone
            edit_bones = Get.selected_edit_bones(context, rig)
            if ab and ab.parent in edit_bones:
                for eb in [*ab.parent_recursive, None]:
                    if eb in edit_bones:
                        # bones.append((rig, eb.name))
                        continue
                    ab.use_connect = False
                    ab.parent = eb
                    bones[ab.name] = rig
                    break
            for eb in edit_bones:
                if props.connect_child:
                    for bb in eb.children:
                        if bb in edit_bones:
                            eb.tail = bb.head
                            bb.use_connect = True
                else:
                    if eb == ab:  # or it'll delete itself
                        continue
                    eb.use_connect = False
                    if props.stretch:
                        eb.head = ab.tail
                    eb.parent = ab
                    bones[eb.name] = rig
                    if props.connect:
                        head = ab.tail - eb.head
                        tail = ab.tail - eb.tail
                        connects = []
                        for ebc in [*eb.children_recursive, eb]:
                            connects.append([ebc, ebc.use_connect])
                            ebc.use_connect = False
                        for ebc, c in connects:
                            ebc.translate(ab.tail - eb.head)
                        for ebc, c in connects:
                            ebc.use_connect = c
                        eb.use_connect = True

            rig.data.use_mirror_x = mirror
            Set.mode(context, 'POSE', rig)

        if props.keep_matrix:
            # ap.matrix = matrices[ap]
            # update()
            for b in bones:
                rig = bones[b]
                bone = rig.pose.bones.get(b)
                if bone is None:
                    print(f"{rig.name} can't find {b}",
                          *rig.pose.bones,
                          sep='\n\t')
                    continue
                if bone == ap:
                    # Skip changing the active bone
                    continue
                if bone not in matrices:
                    print("Skip matrix,", bone.name)
                    continue
                Set.matrix(bone, matrices[bone])
                utils.update(context)

        return {'FINISHED'}
示例#22
0
    def execute(self, context):
        # active = Get.active(context)

        for rig in context.selected_editable_objects:
            if not Is.armature(rig):
                continue

            mode = rig.mode

            if not Set.mode(context, 'EDIT', rig):
                Set.mode(context, mode, rig)
                continue
            mirror = rig.data.use_mirror_x
            rig.data.use_mirror_x = False

            # Set.active(context, rig)
            bones = Get.selected_edit_bones(context, rig)

            links = []  # empty list
            for bone in bones:
                if bone.parent and not Is.connected(
                        bone):  # prevent root-error
                    link = rig.data.edit_bones.new(
                        'COR-%s<>%s' % (bone.parent.name, bone.name))
                    link.tail = bone.head
                    link.head = bone.parent.tail

                    link.layers = bone.layers
                    # link.layers = utils.layer(30)

                    # # layer 28 = IK
                    # # Layer 32 = Gap<>fillers
                    # if (rig.data.rigify_layers):
                    # link.layers	=	[True if index in (31,) else False for index, layer in enumerate(range(32))]

                    link.use_deform = False
                    link.parent = bone.parent
                    bone.parent = link
                    connect(link)
                    connect(bone)
                    link.use_connect = True
                    bone.use_connect = True

                    # bpy.ops.object.mode_set(mode='POSE');bpy.ops.object.mode_set(mode='EDIT');
                    links.append(link.name)
                    # bone = rig.pose.bones[link.name]
                    # bone.lock_ik_x = True
                    # bone.lock_ik_y = True
                    # bone.lock_ik_z = True
                    '''def gap(bone):
                        #bpy.ops.object.mode_set(mode='POSE');
                        bone = C.active_object.pose.bones[bone]
                        bone.lock_ik_x=True;	bone.lock_ik_y=True;	bone.lock_ik_z=True;
                        #bpy.ops.object.mode_set(mode='EDIT');
                    try:
                        bone.lock_ik_x=True;	bone.lock_ik_y=True;	bone.lock_ik_z=True;
                        link = link.name
                    except: continue
                    '''
                elif Is.connected(bone):
                    bone.use_connect = True
                else:  # root-ctrl-bone
                    continue
                    "or this will create a parent for a 'root' bone"
                    link = rig.data.edit_bones.new('COR-%s<>%s' %
                                                   (bone.name, bone.name))
                    link.tail = bone.tail
                    link.head = bone.head

                    link.layers = utils.layer(30)

                    # link.layers = bone.layers
                    link.use_deform = False
                    link.show_wire = True
                    bone.parent = link

                    links.append(link.name)

            rig.data.use_mirror_x = mirror
            Set.mode(context, 'POSE', rig)

            for link in links:
                link = rig.pose.bones.get(link, None)
                if link is None:
                    # if bone's head+tail are the same, it'll cancel itself out
                    continue
                links = link.name.replace('COR-', '', 1).split('<>')
                # linked = rig.pose.bones.get(links[1], None)

                if self.lock_ik:
                    link.ik_stiffness_x = 1
                    link.ik_stiffness_y = 1
                    link.ik_stiffness_z = 1
                    if (links[0] != links[1]):  # Parent <x> Child
                        link.lock_ik_x = True
                        link.lock_ik_y = True
                        link.lock_ik_z = True
                        link.lock_location = [True, True, True]
                        link.lock_rotation_w = True
                        link.lock_rotation = [True, True, True]
                        link.lock_scale = [True, True, True]
                    else:  # Original bone was copied for a control bone
                        print("Original bone was copied for a control bone")
                        # try:
                        # linked.lock_ik_x=True;	linked.lock_ik_y=True;	linked.lock_ik_z=True;
                        # linked.ik_stiffness_x=1;	linked.ik_stiffness_y=1;	linked.ik_stiffness_z=1;
                        # if not 'WGT-hips' in bpy.data.objects:
                        # bpy.context.scene.quickrig.create_wgt = 'hips'
                        # bpy.ops.quickrig.create_widgets()
                        # widget = bpy.data.objects['WGT-hips']
                        # link.custom_shape = widget
                        # #have the bone follow the original	#link.custom_shape_transform = rig.pose.bones[links[1]]
                        # link.use_custom_shape_bone_size = False
                        # con = widget.constraints.new('COPY_TRANSFORMS')
                        # con.target = rig;	con.subtarget = link.name;
                        # widget.layers[9] = True;	layers = 0
                        # for layer in widget.layers:
                        # if layers != 9:	layer = False
                        # except:	pass
                        ...

                def bgroup(name):
                    bgroups = rig.pose.bone_groups
                    if name in bgroups:
                        group = bgroups[name]
                    else:
                        group = bgroups.new(name=name)
                        group.color_set = 'CUSTOM'
                        black = ((0.0, 0.0, 0.0))
                        select = ((0.1, 0.7, 0.9))
                        c = group.colors
                        c.active, c.normal, c.select = black, black, select
                    return group

                link.bone_group = bgroup('<>')

            Set.mode(context, mode, rig)
        # if active:
        # Set.active(context, active)
        return {'FINISHED'}
示例#23
0
    def execute(self, context):
        from zpy_constraints import Constraint
        wgt = utils.find_op('bonewidget.create_widget')
        # if wgt is None:
        #     def wgt(*nil, **null):
        #         return

        for bone in Get.selected_pose_bones(context):
            if not (bone.parent and bone.parent.parent):
                continue

            rig = bone.id_data
            bone_name = bone.name

            # Get and create bones for edit mode
            Set.mode(context, 'EDIT', rig)
            editbone = rig.data.edit_bones[bone_name]

            class fk:
                head = editbone.parent.parent
                tail = editbone.parent
                bone = editbone

            class ik:
                head = New.bone(context, rig, name="IK-" + fk.head.name)
                tail = New.bone(context, rig, name="IK-" + fk.tail.name)
                bone = New.bone(context, rig, name="IK-" + fk.bone.name)

            class stretch:
                head = New.bone(context,
                                rig,
                                name="IK-Stretch-" + fk.head.name)
                tail = New.bone(context,
                                rig,
                                name="IK-Stretch-" + fk.tail.name)
                bone = New.bone(context,
                                rig,
                                name="IK-Stretch-" + fk.bone.name)

            fk_names = [b.name for b in cls(fk)]
            ik_names = [b.name for b in cls(ik)]
            stretch_names = [b.name for b in cls(stretch)]

            # Set transforms for edit bones
            for k in (ik, stretch):
                for (b, f) in zip(cls(k), cls(fk)):
                    copy(b, f, 'bbone_x')
                    copy(b, f, 'bbone_z')
                    copy(b, f, 'matrix')
                    copy(b, f, 'tail')
            for b in cls(stretch):
                b.inherit_scale = 'NONE'
                b.length /= 3
            stretch.tail.head = fk.head.tail
            stretch.bone.head = fk.tail.tail
            ik.tail.tail = ik.bone.head

            # Set parenting
            ik.head.parent = fk.head.parent
            ik.tail.parent = ik.head
            # ik.bone.parent = fk.head.parent
            for (b, i) in zip(cls(stretch), cls(ik)):
                b.parent = i

            # Switch bones back to pose mode
            Set.mode(context, 'POSE', rig)
            bones = rig.pose.bones

            class fk:
                head = bones[fk_names[0]]
                tail = bones[fk_names[1]]
                bone = bones[fk_names[2]]

            class ik:
                head = bones[ik_names[0]]
                tail = bones[ik_names[1]]
                bone = bones[ik_names[2]]

            class stretch:
                head = bones[stretch_names[0]]
                tail = bones[stretch_names[1]]
                bone = bones[stretch_names[2]]

            # for k in ('fk', 'ik', 'stretch'):
            # for h in ('head', 'tail', 'bone'):
            #     exec(f"{k}.{h} = bones[{k}.{h}.name]")
            #     # fk.head = bones[fk.head.name]

            ik.head.ik_stretch = 0.10
            ik.tail.ik_stretch = 0.10

            # for (b, i) in zip(cls(ik), cls(fk)):
            # Set.matrix(b, Get.matrix(i))

            # Insert constraints
            cc = Constraint.new(context,
                                add_relations=False,
                                add_drivers=False)

            cc.type = 'IK'
            cc.add_constraint(context, ik.tail, ik.bone).chain_count = 2

            cc.type = 'COPY_TRANSFORMS'
            cc.add_constraint(context, fk.head, stretch.head)
            cc.add_constraint(context, fk.tail, stretch.tail)
            cc.add_constraint(context, fk.bone, stretch.bone)

            cc.type = 'STRETCH_TO'
            cc.add_constraint(context, fk.head, stretch.tail)
            cc.add_constraint(context, fk.tail, stretch.bone)

            fk.bone.bone.select = False
            ik.bone.bone.select = True
            if fk.bone.bone == rig.data.bones.active:
                rig.data.bones.active = ik.bone.bone

            # Hide bones
            fk.head.bone.hide = True
            ik.tail.bone.hide = True
            fk.tail.bone.hide = True
            fk.bone.bone.hide = True

            if not wgt:
                continue

            # wgt(cc, widget='Rigify - Arrows', slide=(0, 0, 0), rotate=(0, 0, 0), relative_size=True, global_size=1, scale=(1, 1, 1))
            cc = dict(selected_pose_bones=[ik.head])
            # wgt(cc, scale=(1.25, 1.50, 1), widget='Rigify - Arrows')
            wgt(cc, scale=(1, 1, 1), widget='Blenrig - IK Limb')

            cc = dict(selected_pose_bones=cls(stretch))
            wgt(cc, scale=(3, ) * 3, widget='Sphere')

            cc = dict(selected_pose_bones=[ik.bone])
            if 'hand' in ik.bone.name.lower():
                wgt(cc, scale=(1, 1, 1), widget='Blenrig - Hand')
            elif 'foot' in ik.bone.name.lower():
                wgt(cc, scale=(1, 1, 1), widget='Blenrig - Foot')
            else:
                wgt(cc, scale=(1, 1, 1), widget='Cube')

        return {'FINISHED'}
    def fix_poles():
        def op(**args):
            eval('bpy.ops.pose.rigify_limb_toggle_pole_' + rig.data["rig_id"])(
                dict(active_object=rig), 'INVOKE_DEFAULT', **args)

        poles = dict()

        def getmat(bone, active):
            """Helper function for visual transform copy,
            gets the active transform in bone space
            """
            obj_bone = bone.id_data
            obj_active = active.id_data
            data_bone = obj_bone.data.bones[bone.name]
            # all matrices are in armature space unless commented otherwise
            active_to_selected = obj_bone.matrix_world.inverted(
            ) @ obj_active.matrix_world
            active_matrix = active_to_selected @ active.matrix
            otherloc = active_matrix  # final 4x4 mat of target, location.
            bonemat_local = data_bone.matrix_local.copy()  # self rest matrix
            if data_bone.parent:
                parentposemat = obj_bone.pose.bones[
                    data_bone.parent.name].matrix.copy()
                parentbonemat = data_bone.parent.matrix_local.copy()
            else:
                parentposemat = parentbonemat = Matrix()
            if parentbonemat == parentposemat or not data_bone.use_inherit_rotation:
                newmat = bonemat_local.inverted() @ otherloc
            else:
                bonemat = parentbonemat.inverted() @ bonemat_local

                newmat = bonemat.inverted() @ parentposemat.inverted(
                ) @ otherloc
            return newmat

        def rotcopy(item, mat):
            """Copy rotation to item from matrix mat depending on item.rotation_mode"""
            if item.rotation_mode == 'QUATERNION':
                item.rotation_quaternion = mat.to_3x3().to_quaternion()
            elif item.rotation_mode == 'AXIS_ANGLE':
                rot = mat.to_3x3().to_quaternion().to_axis_angle(
                )  # returns (Vector((x, y, z)), w)
                axis_angle = rot[1], rot[0][0], rot[0][1], rot[0][
                    2]  # convert to w, x, y, z
                item.rotation_axis_angle = axis_angle
            else:
                item.rotation_euler = mat.to_3x3().to_euler(item.rotation_mode)

        def get_pole(pole, line):
            from math import radians
            from mathutils import Matrix

            bone["pole_vector"] = 0
            pole = get(pole)
            line = get(line)

            # lock rotation/scale, since bone only suppose to be moved
            pole.rotation_mode = 'XYZ'
            pole.lock_rotation_w = True
            pole.lock_rotation = (True, True, True)
            pole.lock_scale = (True, True, True)

            utils.update(bpy.context)
            mat = getmat(pole, line) @ Matrix.Rotation(radians(180), 4, 'X')
            rotcopy(pole, mat)
            utils.update(bpy.context)
            poles[pole.name] = Get.matrix(pole)
            rotcopy(pole, Matrix())

            pole.location = (0, 0, 0)

        if get('thigh_parent.L'):
            op(prop_bone="thigh_parent.L",
               ik_bones=
               "[\"thigh_ik.L\", \"MCH-shin_ik.L\", \"MCH-thigh_ik_target.L\"]",
               ctrl_bones=
               "[\"thigh_ik.L\", \"foot_ik.L\", \"thigh_ik_target.L\"]",
               extra_ctrls=
               "[\"foot_ik_pivot.L\", \"foot_heel_ik.L\", \"foot_spin_ik.L\"]")
            get_pole('thigh_ik_target.L', 'VIS_thigh_ik_pole.L')
        if get('thigh_parent.R'):
            op(prop_bone="thigh_parent.R",
               ik_bones=
               "[\"thigh_ik.R\", \"MCH-shin_ik.R\", \"MCH-thigh_ik_target.R\"]",
               ctrl_bones=
               "[\"thigh_ik.R\", \"foot_ik.R\", \"thigh_ik_target.R\"]",
               extra_ctrls=
               "[\"foot_ik_pivot.R\", \"foot_heel_ik.R\", \"foot_spin_ik.R\"]")
            get_pole('thigh_ik_target.R', 'VIS_thigh_ik_pole.R')
        if get('upper_arm_parent.L'):
            op(prop_bone="upper_arm_parent.L",
               ik_bones=
               "[\"upper_arm_ik.L\", \"MCH-forearm_ik.L\", \"MCH-upper_arm_ik_target.L\"]",
               ctrl_bones=
               "[\"upper_arm_ik.L\", \"hand_ik.L\", \"upper_arm_ik_target.L\"]",
               extra_ctrls="[\"hand_ik_pivot.L\", \"hand_ik_wrist.L\"]")
            get_pole('upper_arm_ik_target.L', 'VIS_upper_arm_ik_pole.L')
        if get('upper_arm_parent.R'):
            op(prop_bone="upper_arm_parent.R",
               ik_bones=
               "[\"upper_arm_ik.R\", \"MCH-forearm_ik.R\", \"MCH-upper_arm_ik_target.R\"]",
               ctrl_bones=
               "[\"upper_arm_ik.R\", \"hand_ik.R\", \"upper_arm_ik_target.R\"]",
               extra_ctrls="[\"hand_ik_pivot.R\", \"hand_ik_wrist.R\"]")
            get_pole('upper_arm_ik_target.R', 'VIS_upper_arm_ik_pole.R')
        if poles:
            utils.update(bpy.context)
            mode = Get.mode(rig)
            Set.mode(bpy.context, 'EDIT', rig)
            for (name, mat) in poles.items():
                edit_bone = rig.data.edit_bones[name]
                Set.matrix(edit_bone, mat)
            Set.mode(bpy.context, mode, rig)
示例#25
0
    def execute(self, context):
        (rig, meshes) = self.get_rig_meshes(context)
        if not (rig and meshes):
            return {'CANCELLED'}

        use_mask = bool((self.from_active or self.normalize_active))
        active = context.object
        active_bone = context.active_pose_bone.bone
        mode = active.mode
        pose = rig.data.pose_position
        scale = rig.scale.copy()

        if use_mask:
            active_bone.select = False

        Set.mode(context, 'OBJECT')
        rig.data.pose_position = 'REST'
        rig.scale *= 50

        for mesh in meshes:
            mscale = mesh.scale.copy()
            mp = mesh.parent
            while mp and mp != rig:
                # Sort through mesh parent hierarchy to find if the rig is a parent somewhere in there
                mp = mp.parent
            if mp != rig:
                # The rig/parent is already scaled, so don't scale mesh again
                mesh.scale *= 50
            Set.active(context, mesh)
            Set.mode(context, 'WEIGHT_PAINT')

            vg = mesh.vertex_groups
            bone_group = vg.get(active_bone.name)
            do_bone = bool((use_mask and bone_group))
            mindex = vg.active_index

            bpy.ops.paint.weight_from_bones(type='AUTOMATIC')

            if do_bone:
                vg.active_index = mindex
                bpy.ops.object.vertex_group_invert()
                for b in context.selected_pose_bones:
                    utils.subtract_vertex_groups(mesh, active_bone.name, b.name)
                bpy.ops.object.vertex_group_invert()
                if self.normalize_active:
                    for b in context.selected_pose_bones:
                        utils.subtract_vertex_groups(mesh, b.name, active_bone.name)

            if (mindex != -1):
                vg.active_index = mindex

            Set.mode(context, 'OBJECT')
            mesh.scale = mscale

        Set.active(context, active)
        rig.scale = scale
        rig.data.pose_position = pose
        Set.mode(context, mode)

        if use_mask:
            active_bone.select = True

        if len(meshes) > 1:
            self.report({'INFO'}, f"Assigned weights to {len(meshes)} meshes")
        else:
            self.report({'INFO'}, f"Assigned weights to {list(meshes)[0].name}")

        return {'FINISHED'}
示例#26
0
    def add_bones_stretch(self, context, rig):
        # Add bones then set their defaults
        root = self.get_root(rig)
        prev_bones = self.get_prev_bones(rig)
        pose_bones = []

        for bone_name in prev_bones:
            prev = rig.data.edit_bones[bone_name]

            bone = rig.data.edit_bones.new(self.mirror_name(prev.name, 'STR'))
            head = prev.parent.name if (prev.parent
                                        and prev.use_connect) else ''
            tail = [*[c.name for c in prev.children if c.use_connect], ''][0]

            pose_bones.append([bone.name, [prev.name, head, tail]])
            self.reset(bone, prev)

            bone.parent = prev.parent
            bone.use_deform = False

            # use_tip = True
            # child = None
            # if edit_bone.children:
            # for i in edit_bone.children:
            # if i.use_connect:
            # if child is not None:
            # child = False
            # break
            # child = i
            # if child in [None, False]:
            # for i in edit_bone.children:
            # if i.head == edit_bone.tail:
            # if child not in [None, False]:
            # child = False
            # break
            # child = i
            # if child:
            # tail = rig.data.edit_bones.get('STR-'+child.name)
            # if tail is None:
            # tail	=	rig.data.edit_bones.new('STR-'+child.name)
            # tail.parent		=	child
            # tail.use_deform	=	False
            # self.reset(tail, edit_bone=child)
            # else:
            # use_tip = False
            # else:  # create bone tip
            # tail			=	rig.data.edit_bones.new('STR_TAIL-'+bone.name)
            # tail.parent		=	edit_bone
            # tail.use_deform	=	False
            # self.reset(tail)
            # th = Vector(tail.tail-tail.head)
            # tail.tail += th
            # tail.head += th
            ...

        # Switch back to Pose mode and setup pose bones
        Set.mode(context, 'POSE', rig)

        for bone, prev in pose_bones:
            prev, head, tail = prev
            bone = rig.pose.bones[bone]
            prev = rig.pose.bones[prev]

            head = rig.pose.bones.get(head, None)
            if head:
                prev.bone.bbone_custom_handle_start = head.bone
            tail = rig.pose.bones.get(tail, None)
            if tail:
                prev.bone.bbone_custom_handle_end = tail.bone

            rig.data.bones.active = bone.bone
            bone.custom_shape_transform = prev
            self.widget(bone, 'Sphere', scale=(0, 1.5, 0))

            # bone['IK_FK'] = prev.name
            # prev['IK_IK'] = bone.name
            bone.rotation_mode = prev.rotation_mode
            bone.lock_rotation[0] = True
            bone.lock_rotation[2] = True
            # i['IK_Deform'] = deform.name
            # i['IK_Stretch'] = stretch.name
            # i['IK_Tail'] = tail.name
            bone.matrix = prev.matrix

            if prev.bone_group:
                bone.bone_group = self.bgroup(rig,
                                              'STR-' + prev.bone_group.name)
            else:
                bone.bone_group = self.bgroup(rig, 'STR')
                prev.bone_group = self.bgroup(rig, 'FK')