Ejemplo n.º 1
0
    def execute(self, context):
        if (context.mode == 'POSE'):
            if self.selected:
                bones = context.selected_pose_bones
            else:
                bones = [context.active_pose_bone]
        else:
            if self.selected:
                bones = context.selected_bones
            else:
                bones = [context.active_bone]

        for _bone in bones:
            (bone, child) = self.get_bone_child(_bone)
            self.set_bbone(bone, child)

            if Is.posebone(_bone):
                mirror_x = (_bone.id_data.pose.use_mirror_x
                            or bone.id_data.use_mirror_x)
            else:
                mirror_x = bone.id_data.use_mirror_x

            if mirror_x:
                m_bone = Get.mirror_bone(_bone)
                if m_bone and (m_bone not in bones):
                    (mbone, mchild) = self.get_bone_child(m_bone)
                    self.set_bbone(mbone, mchild)

        return {'FINISHED'}
Ejemplo n.º 2
0
def get_rig_bones(context):
    rigs = dict()  # rig object with a list of selected and mirrored bones
    selected = list()  # remember selected and non-selected mirror bones

    for bone in context.selected_pose_bones:
        rig = bone.id_data
        if Is.linked(rig):
            continue
        if rig not in rigs:
            rigs[rig] = list()

        if (bone not in rigs[rig]):
            rigs[rig].append(bone)
            selected.append((bone, rig))
            if (rig.pose.use_mirror_x or rig.data.use_mirror_x):
                mirror = Get.mirror_bone(bone)
                if mirror and (mirror not in rigs[rig]):
                    rigs[rig].append(mirror)
                    selected.append((mirror, rig))

    return (rigs, selected)
Ejemplo n.º 3
0
    def pose_func(self, context, bone):
        rig = bone.id_data
        bones = rig.pose.bones
        bbones = ('bbone', 'bbone_start', 'bbone_end', 'bbone_head',
                  'bbone_in', 'bbone_out')

        def parse(bbone):
            self.bones[bbone] = rig

            # Prep the widget for removal
            wgt = bbone.custom_shape
            if wgt:
                self.widgets.add(wgt)

            # Remove stretch constraints
            for con in list(bone.constraints):
                if (getattr(con, 'target', None) == rig) and (con.subtarget
                                                              == bbone.name):
                    bone.constraints.remove(con)

            # Remove Custom Handle
            if bone.bbone_custom_handle_start == bbone:
                bone.bone.bbone_custom_handle_start = None
                bone.bone.bbone_handle_type_start = 'AUTO'
            if bone.bbone_custom_handle_end == bbone:
                bone.bone.bbone_custom_handle_end = None
                bone.bone.bbone_handle_type_end = 'AUTO'

        for bbone_name in bbones:
            bbone = bones.get(get_name(bone, bbone_name))
            if not bbone:
                continue

            parse(bbone)

            if bbone_name in ('bbone_start',
                              'bbone_end') and Get.mirror_bone(bbone):
                (prefix, replace, suffix,
                 number) = utils.flip_name(bone.name, only_split=True)
                center_name = prefix + suffix + number
                center = bones.get(center_name)
                if center:
                    parse(center)

            # Remove BBone drivers
            if bbone_name in ('bbone_in', 'bbone_out'):
                in_out = bbone_name.split('_')[1]
                in_outs = (
                    f'bbone_curve{in_out}x',
                    f'bbone_curve{in_out}y',
                    f'bbone_roll{in_out}',
                    f'bbone_scale{in_out}x',
                    f'bbone_scale{in_out}y',
                    f'bbone_ease{in_out}',
                )
                for bbone_in_out in in_outs:
                    Driver = Get.driver(bone, bbone_in_out)
                    try:
                        target = Driver.driver.variables[0].targets[0]
                    except:
                        continue
                    if (target.bone_target == bbone.name) and (target.id
                                                               == rig):
                        bone.driver_remove(bbone_in_out)
Ejemplo n.º 4
0
 def get_bones(rig, bbone):
     ebones = rig.data.edit_bones
     ebone = ebones.get(get_name(bone, bbone))
     mebone = Get.mirror_bone(ebone)
     return (ebone, mebone)
Ejemplo n.º 5
0
    def edit_mirror_center(self, context):
        def get_bones(rig, bbone):
            ebones = rig.data.edit_bones
            ebone = ebones.get(get_name(bone, bbone))
            mebone = Get.mirror_bone(ebone)
            return (ebone, mebone)

        found = []
        for (bone, rig) in self.selected:
            if not (rig.pose.use_mirror_x or rig.data.use_mirror_x):
                continue
            mbone = Get.mirror_bone(bone)
            if mbone in found:
                continue
            else:
                found.append(bone)

            (ebone, mebone) = get_bones(rig, 'bbone_start')
            if not (ebone and mebone):
                continue

            if (ebone.parent == mebone.parent):
                # Connect heads
                if Is.connected(bone):
                    # The parent will already handle the symmetry
                    continue
                parent = ebone.parent
            else:
                (ebone, mebone) = get_bones(rig, 'bbone_end')
                if not (ebone and mebone):
                    continue

                # Find a mutual parent between the two bones
                parent = [
                    *(x for x in ebone.parent_recursive
                      if x in mebone.parent_recursive), None
                ][0]

            distance = abs(sum(ebone.head) - sum(mebone.head)) / 2
            margin = utils.lerp(bone.bone.length, mbone.bone.length,
                                0.5) / bone.bone.bbone_segments
            if distance >= margin:
                # Bones too far apart
                continue

            (prefix, replace, suffix,
             number) = utils.flip_name(bone.name, only_split=True)
            center_name = prefix + suffix + number
            center = New.bone(context, rig, name=center_name, overwrite=True)

            attributes = [
                'head',
                'head_radius',
                'tail',
                'tail_radius',
                'roll',
                'matrix',
                'layers',
                'bbone_x',
                'bbone_z',
            ]
            for atr in attributes:
                if hasattr(center, atr):
                    setattr(
                        center, atr,
                        utils.lerp(getattr(ebone, atr), getattr(mebone, atr),
                                   0.5))
            center.use_deform = False
            center.inherit_scale = 'NONE'
            center.parent = parent
            center.hide = True

            ebone.parent = mebone.parent = center
            self.hide_bones[rig].extend((ebone.name, mebone.name))
            self.center_bones[rig].append(center.name)