def create_deform(self):
        org_bones = self.org_bones

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

        def_bones = []
        for o in org_bones:
            def_name = make_deformer_name(strip_org(o))
            def_name = copy_bone(self.obj, o, def_name)
            def_bones.append(def_name)

        bpy.ops.object.mode_set(mode='POSE')
        # Create bbone segments
        for bone in def_bones:
            self.obj.data.bones[bone].bbone_segments = self.bbones

        if not self.SINGLE_BONE:
            self.obj.data.bones[def_bones[0]].bbone_easein = 0.0
            self.obj.data.bones[def_bones[-1]].bbone_easeout = 0.0
        else:
            self.obj.data.bones[def_bones[0]].bbone_easein = 1.0
            self.obj.data.bones[def_bones[-1]].bbone_easeout = 1.0
        bpy.ops.object.mode_set(mode='EDIT')

        conv_def = ""
        if self.params.conv_bone and self.params.conv_def:
            b = org(self.params.conv_bone)
            conv_def = make_deformer_name(strip_org(b))
            conv_def = copy_bone(self.obj, b, conv_def)

        return def_bones, conv_def
Example #2
0
    def generate(self):
        """ Generate the rig.
            Do NOT modify any of the original bones, except for adding constraints.
            The main armature should be selected and active before this is called.

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

        # Make a control bone (copy of original).
        bone = copy_bone(self.obj, self.org_bone, self.org_name)

        # Make a deformation bone (copy of original, child of original).
        def_bone = copy_bone(self.obj, self.org_bone,
                             make_deformer_name(self.org_name))

        # Get edit bones
        eb = self.obj.data.edit_bones
        bone_e = eb[bone]
        def_bone_e = eb[def_bone]

        # Parent
        def_bone_e.use_connect = False
        def_bone_e.parent = eb[self.org_bone]

        bpy.ops.object.mode_set(mode='OBJECT')
        pb = self.obj.pose.bones

        # Constrain the original bone.
        con = pb[self.org_bone].constraints.new('COPY_TRANSFORMS')
        con.name = "copy_loc"
        con.target = self.obj
        con.subtarget = bone

        # Create control widget
        create_bone_widget(self.obj, bone)
    def generate(self):

        bpy.ops.object.mode_set(mode='EDIT')
        eb = self.obj.data.edit_bones

        bones = {}
        if eb[self.org_bones[0]].parent:
            def_name = make_deformer_name(
                strip_org(eb[self.org_bones[0]].parent.name))
            if self.params.def_parenting and def_name in eb.keys():
                bones['parent'] = def_name
            else:
                bones['parent'] = eb[self.org_bones[0]].parent.name

        # Clear parents for org bones
        for bone in self.org_bones[0:]:
            eb[bone].use_connect = False
            eb[bone].parent = None

        bones['def'], bones['conv_def'] = self.create_deform()
        if len(self.org_bones) > 2:
            bones['pivot'] = self.create_pivot()
        bones['chain'] = self.create_chain()

        self.parent_bones(bones)

        # ctrls snapping pass
        self.aggregate_ctrls(bones)

        self.constrain_bones(bones)
        self.stick_to_bendy_bones(bones)
        self.locks_and_widgets(bones)

        return
Example #4
0
    def make_def_chain(self):
        """
        Creates all DEFs in chain
        :return:
        :rtype:list
        """

        if not self.active:
            return []

        bpy.ops.object.mode_set(mode='EDIT')
        edit_bones = self.obj.data.edit_bones

        chain = self._bones['org']

        self._bones['def'] = []

        if self.chain_type == ChainType.TYPE_MCH_BASED:
            for chain_bone in chain:
                def_bone = make_deformer_name(strip_org(chain_bone))
                def_bone = copy_bone(self.obj,
                                     chain_bone,
                                     assign_name=def_bone)
                edit_bones[def_bone].parent = None
                edit_bones[def_bone].use_connect = False
                self._bones['def'].append(def_bone)

        return self._bones['def']
Example #5
0
    def gen_deform(self):
        """ Generate the deformation rig.

        """
        for name in self.org_bones:
            bpy.ops.object.mode_set(mode='EDIT')
            eb = self.obj.data.edit_bones

            # Create deform bone
            bone_e = eb[copy_bone(self.obj, name)]

            # Change its name
            bone_e.name = make_deformer_name(strip_org(name))
            bone_name = bone_e.name

            # Leave edit mode
            bpy.ops.object.mode_set(mode='OBJECT')

            # Get the pose bone
            bone = self.obj.pose.bones[bone_name]

            # Constrain to the original bone
            con = bone.constraints.new('COPY_TRANSFORMS')
            con.name = "copy_transforms"
            con.target = self.obj
            con.subtarget = name
Example #6
0
    def gen_deform(self):
        """ Generate the deformation rig.

        """
        for name in self.org_bones:
            bpy.ops.object.mode_set(mode='EDIT')
            eb = self.obj.data.edit_bones

            # Create deform bone
            bone_e = eb[copy_bone(self.obj, name)]

            # Change its name
            bone_e.name = make_deformer_name(strip_org(name))
            bone_name = bone_e.name

            # Leave edit mode
            bpy.ops.object.mode_set(mode='OBJECT')

            # Get the pose bone
            bone = self.obj.pose.bones[bone_name]

            # Constrain to the original bone
            con = bone.constraints.new('COPY_TRANSFORMS')
            con.name = "copy_transforms"
            con.target = self.obj
            con.subtarget = name
Example #7
0
    def generate(self):
        """ Generate the rig.
            Do NOT modify any of the original bones, except for adding constraints.
            The main armature should be selected and active before this is called.

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

        # Make a control bone (copy of original).
        bone = copy_bone(self.obj, self.org_bone, self.org_name)

        # Make a deformation bone (copy of original, child of original).
        def_bone = copy_bone(self.obj, self.org_bone, make_deformer_name(self.org_name))

        # Get edit bones
        eb = self.obj.data.edit_bones
        bone_e = eb[bone]
        def_bone_e = eb[def_bone]

        # Parent
        def_bone_e.use_connect = False
        def_bone_e.parent = eb[self.org_bone]

        bpy.ops.object.mode_set(mode='OBJECT')
        pb = self.obj.pose.bones

        # Constrain the original bone.
        con = pb[self.org_bone].constraints.new('COPY_TRANSFORMS')
        con.name = "copy_loc"
        con.target = self.obj
        con.subtarget = bone

        # Create control widget
        create_bone_widget(self.obj, bone)
Example #8
0
    def generate(self):
        bone_list = self.rubber_hose_limb.generate()

        # Set up toe
        bpy.ops.object.mode_set(mode='EDIT')
        toe = copy_bone(self.obj, self.org_bones[3],
                        make_deformer_name(strip_org(self.org_bones[3])))
        eb = self.obj.data.edit_bones
        eb[toe].use_connect = False
        eb[toe].parent = eb[self.org_bones[3]]

        return bone_list
    def create_def(self):

        bpy.ops.object.mode_set(mode='EDIT')
        edit_bones = self.obj.data.edit_bones

        self.bones['eye_def'] = dict()

        if self.params.make_deform:
            main_eye_def = make_deformer_name(strip_org(self.bones['org'][0]))
            main_eye_def = copy_bone(self.obj, self.bones['org'][0],
                                     main_eye_def)
            self.bones['eye_def']['eyeball_def'] = main_eye_def

        super().create_def()
    def create_def(self):
        """
        If add_glue_def is True adds a DEF
        :return:
        """

        if not self.params.add_glue_def:
            return

        bpy.ops.object.mode_set(mode='EDIT')
        edit_bones = self.obj.data.edit_bones

        def_bone = make_deformer_name(strip_org(self.base_bone))
        def_bone = copy_bone(self.obj, self.base_bone, def_bone)
        self.bones['glue_def'] = def_bone

        DEF_LAYER = [n == 29 for n in range(0, 32)]
        edit_bones[def_bone].layers = DEF_LAYER
        edit_bones[def_bone].use_deform = True
Example #11
0
    def deform(self):
        """ Generate the deformation rig.
            Just a copy of the original bones, except the first digit which is a twist bone.
        """
        bpy.ops.object.mode_set(mode="EDIT")

        # Create the bones
        # First bone is a twist bone
        if self.use_digit_twist:
            b1a = copy_bone(self.obj, self.org_bones[0], make_deformer_name(strip_org(self.org_bones[0] + ".01")))
            b1b = copy_bone(self.obj, self.org_bones[0], make_deformer_name(strip_org(self.org_bones[0] + ".02")))
            b1tip = copy_bone(self.obj, self.org_bones[0], make_mechanism_name(strip_org(self.org_bones[0] + ".tip")))
        else:
            b1 = copy_bone(self.obj, self.org_bones[0], make_deformer_name(strip_org(self.org_bones[0])))

        # The rest are normal
        bones = []
        for bone in self.org_bones[1:]:
            bones += [copy_bone(self.obj, bone, make_deformer_name(strip_org(bone)))]

        # Position bones
        eb = self.obj.data.edit_bones
        if self.use_digit_twist:
            b1a_e = eb[b1a]
            b1b_e = eb[b1b]
            b1tip_e = eb[b1tip]

            b1tip_e.use_connect = False
            b1tip_e.tail += Vector((0.1, 0, 0))
            b1tip_e.head = b1b_e.tail
            b1tip_e.length = b1a_e.length / 4

            center = (b1a_e.head + b1a_e.tail) / 2
            b1a_e.tail = center
            b1b_e.use_connect = False
            b1b_e.head = center

        # Parenting
        if self.use_digit_twist:
            b1b_e.parent = eb[self.org_bones[0]]
            b1tip_e.parent = eb[self.org_bones[0]]
        else:
            eb[b1].use_connect = False
            eb[b1].parent = eb[self.org_bones[0]]

        for (ba, bb) in zip(bones, self.org_bones[1:]):
            eb[ba].use_connect = False
            eb[ba].parent = eb[bb]

        # Constraints
        if self.use_digit_twist:
            bpy.ops.object.mode_set(mode="OBJECT")
            pb = self.obj.pose.bones

            b1a_p = pb[b1a]

            con = b1a_p.constraints.new("COPY_LOCATION")
            con.name = "copy_location"
            con.target = self.obj
            con.subtarget = self.org_bones[0]

            con = b1a_p.constraints.new("COPY_SCALE")
            con.name = "copy_scale"
            con.target = self.obj
            con.subtarget = self.org_bones[0]

            con = b1a_p.constraints.new("DAMPED_TRACK")
            con.name = "track_to"
            con.target = self.obj
            con.subtarget = b1tip
Example #12
0
    def generate(self):
        """ Generate the rig.
            Do NOT modify any of the original bones, except for adding constraints.
            The main armature should be selected and active before this is called.

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

        # Create upper arm bones
        if self.use_thigh_twist:
            thigh1 = copy_bone(
                self.obj, self.org_bones[0],
                make_deformer_name(strip_org(self.org_bones[0] + ".01")))
            thigh2 = copy_bone(
                self.obj, self.org_bones[0],
                make_deformer_name(strip_org(self.org_bones[0] + ".02")))
            utip = copy_bone(
                self.obj, self.org_bones[0],
                make_mechanism_name(strip_org(self.org_bones[0] + ".tip")))
        else:
            thigh = copy_bone(self.obj, self.org_bones[0],
                              make_deformer_name(strip_org(self.org_bones[0])))

        # Create forearm bones
        if self.use_shin_twist:
            shin1 = copy_bone(
                self.obj, self.org_bones[1],
                make_deformer_name(strip_org(self.org_bones[1] + ".01")))
            shin2 = copy_bone(
                self.obj, self.org_bones[1],
                make_deformer_name(strip_org(self.org_bones[1] + ".02")))
            stip = copy_bone(
                self.obj, self.org_bones[1],
                make_mechanism_name(strip_org(self.org_bones[1] + ".tip")))
        else:
            shin = copy_bone(self.obj, self.org_bones[1],
                             make_deformer_name(strip_org(self.org_bones[1])))

        # Create foot bone
        foot = copy_bone(self.obj, self.org_bones[2],
                         make_deformer_name(strip_org(self.org_bones[2])))

        # Create toe bone
        toe = copy_bone(self.obj, self.org_bones[3],
                        make_deformer_name(strip_org(self.org_bones[3])))

        # Get edit bones
        eb = self.obj.data.edit_bones

        org_thigh_e = eb[self.org_bones[0]]
        if self.use_thigh_twist:
            thigh1_e = eb[thigh1]
            thigh2_e = eb[thigh2]
            utip_e = eb[utip]
        else:
            thigh_e = eb[thigh]

        org_shin_e = eb[self.org_bones[1]]
        if self.use_shin_twist:
            shin1_e = eb[shin1]
            shin2_e = eb[shin2]
            stip_e = eb[stip]
        else:
            shin_e = eb[shin]

        org_foot_e = eb[self.org_bones[2]]
        foot_e = eb[foot]

        org_toe_e = eb[self.org_bones[3]]
        toe_e = eb[toe]

        # Parent and position thigh bones
        if self.use_thigh_twist:
            thigh1_e.use_connect = False
            thigh2_e.use_connect = False
            utip_e.use_connect = False

            thigh1_e.parent = org_thigh_e.parent
            thigh2_e.parent = org_thigh_e
            utip_e.parent = org_thigh_e

            center = Vector((org_thigh_e.head + org_thigh_e.tail) / 2)

            thigh1_e.tail = center
            thigh2_e.head = center
            put_bone(self.obj, utip, org_thigh_e.tail)
            utip_e.length = org_thigh_e.length / 8
        else:
            thigh_e.use_connect = False
            thigh_e.parent = org_thigh_e

        # Parent and position shin bones
        if self.use_shin_twist:
            shin1_e.use_connect = False
            shin2_e.use_connect = False
            stip_e.use_connect = False

            shin1_e.parent = org_shin_e
            shin2_e.parent = org_shin_e
            stip_e.parent = org_shin_e

            center = Vector((org_shin_e.head + org_shin_e.tail) / 2)

            shin1_e.tail = center
            shin2_e.head = center
            put_bone(self.obj, stip, org_shin_e.tail)
            stip_e.length = org_shin_e.length / 8

            # Align roll of shin2 with foot
            align_roll(self.obj, shin2, foot)
        else:
            shin_e.use_connect = False
            shin_e.parent = org_shin_e

        # Parent foot
        foot_e.use_connect = False
        foot_e.parent = org_foot_e

        # Parent toe
        toe_e.use_connect = False
        toe_e.parent = org_toe_e

        # Object mode, get pose bones
        bpy.ops.object.mode_set(mode='OBJECT')
        pb = self.obj.pose.bones

        if self.use_thigh_twist:
            thigh1_p = pb[thigh1]
        if self.use_shin_twist:
            shin2_p = pb[shin2]
        foot_p = pb[foot]

        # Thigh constraints
        if self.use_thigh_twist:
            con = thigh1_p.constraints.new('COPY_LOCATION')
            con.name = "copy_location"
            con.target = self.obj
            con.subtarget = self.org_bones[0]

            con = thigh1_p.constraints.new('COPY_SCALE')
            con.name = "copy_scale"
            con.target = self.obj
            con.subtarget = self.org_bones[0]

            con = thigh1_p.constraints.new('DAMPED_TRACK')
            con.name = "track_to"
            con.target = self.obj
            con.subtarget = utip

        # Shin constraints
        if self.use_shin_twist:
            con = shin2_p.constraints.new('COPY_ROTATION')
            con.name = "copy_rotation"
            con.target = self.obj
            con.subtarget = foot

            con = shin2_p.constraints.new('DAMPED_TRACK')
            con.name = "track_to"
            con.target = self.obj
            con.subtarget = stip
Example #13
0
    def deform(self):
        """ Generate the deformation rig.
            Just a copy of the original bones, except the first digit which is a twist bone.
        """
        bpy.ops.object.mode_set(mode='EDIT')

        # Create the bones
        # First bone is a twist bone
        if self.use_digit_twist:
            b1a = copy_bone(
                self.obj, self.org_bones[0],
                make_deformer_name(strip_org(self.org_bones[0] + ".01")))
            b1b = copy_bone(
                self.obj, self.org_bones[0],
                make_deformer_name(strip_org(self.org_bones[0] + ".02")))
            b1tip = copy_bone(
                self.obj, self.org_bones[0],
                make_mechanism_name(strip_org(self.org_bones[0] + ".tip")))
        else:
            b1 = copy_bone(self.obj, self.org_bones[0],
                           make_deformer_name(strip_org(self.org_bones[0])))

        # The rest are normal
        bones = []
        for bone in self.org_bones[1:]:
            bones += [
                copy_bone(self.obj, bone, make_deformer_name(strip_org(bone)))
            ]

        # Position bones
        eb = self.obj.data.edit_bones
        if self.use_digit_twist:
            b1a_e = eb[b1a]
            b1b_e = eb[b1b]
            b1tip_e = eb[b1tip]

            b1tip_e.use_connect = False
            b1tip_e.tail += Vector((0.1, 0, 0))
            b1tip_e.head = b1b_e.tail
            b1tip_e.length = b1a_e.length / 4

            center = (b1a_e.head + b1a_e.tail) / 2
            b1a_e.tail = center
            b1b_e.use_connect = False
            b1b_e.head = center

        # Parenting
        if self.use_digit_twist:
            b1b_e.parent = eb[self.org_bones[0]]
            b1tip_e.parent = eb[self.org_bones[0]]
        else:
            eb[b1].use_connect = False
            eb[b1].parent = eb[self.org_bones[0]]

        for (ba, bb) in zip(bones, self.org_bones[1:]):
            eb[ba].use_connect = False
            eb[ba].parent = eb[bb]

        # Constraints
        if self.use_digit_twist:
            bpy.ops.object.mode_set(mode='OBJECT')
            pb = self.obj.pose.bones

            b1a_p = pb[b1a]

            con = b1a_p.constraints.new('COPY_LOCATION')
            con.name = "copy_location"
            con.target = self.obj
            con.subtarget = self.org_bones[0]

            con = b1a_p.constraints.new('COPY_SCALE')
            con.name = "copy_scale"
            con.target = self.obj
            con.subtarget = self.org_bones[0]

            con = b1a_p.constraints.new('DAMPED_TRACK')
            con.name = "track_to"
            con.target = self.obj
            con.subtarget = b1tip
Example #14
0
    def generate(self):
        """ Generate the rig.
            Do NOT modify any of the original bones, except for adding constraints.
            The main armature should be selected and active before this is called.

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

        # Create upper arm bones
        if self.use_upper_arm_twist:
            uarm1 = copy_bone(
                self.obj, self.org_bones[0],
                make_deformer_name(strip_org(self.org_bones[0] + ".01")))
            uarm2 = copy_bone(
                self.obj, self.org_bones[0],
                make_deformer_name(strip_org(self.org_bones[0] + ".02")))
            utip = copy_bone(
                self.obj, self.org_bones[0],
                make_mechanism_name(strip_org(self.org_bones[0] + ".tip")))
        else:
            uarm = copy_bone(self.obj, self.org_bones[0],
                             make_deformer_name(strip_org(self.org_bones[0])))

        # Create forearm bones
        if self.use_forearm_twist:
            farm1 = copy_bone(
                self.obj, self.org_bones[1],
                make_deformer_name(strip_org(self.org_bones[1] + ".01")))
            farm2 = copy_bone(
                self.obj, self.org_bones[1],
                make_deformer_name(strip_org(self.org_bones[1] + ".02")))
            ftip = copy_bone(
                self.obj, self.org_bones[1],
                make_mechanism_name(strip_org(self.org_bones[1] + ".tip")))
        else:
            farm = copy_bone(self.obj, self.org_bones[1],
                             make_deformer_name(strip_org(self.org_bones[1])))

        # Create hand bone
        hand = copy_bone(self.obj, self.org_bones[2],
                         make_deformer_name(strip_org(self.org_bones[2])))

        # Get edit bones
        eb = self.obj.data.edit_bones

        org_uarm_e = eb[self.org_bones[0]]
        if self.use_upper_arm_twist:
            uarm1_e = eb[uarm1]
            uarm2_e = eb[uarm2]
            utip_e = eb[utip]
        else:
            uarm_e = eb[uarm]

        org_farm_e = eb[self.org_bones[1]]
        if self.use_forearm_twist:
            farm1_e = eb[farm1]
            farm2_e = eb[farm2]
            ftip_e = eb[ftip]
        else:
            farm_e = eb[farm]

        org_hand_e = eb[self.org_bones[2]]
        hand_e = eb[hand]

        # Parent and position upper arm bones
        if self.use_upper_arm_twist:
            uarm1_e.use_connect = False
            uarm2_e.use_connect = False
            utip_e.use_connect = False

            uarm1_e.parent = org_uarm_e.parent
            uarm2_e.parent = org_uarm_e
            utip_e.parent = org_uarm_e

            center = Vector((org_uarm_e.head + org_uarm_e.tail) / 2)

            uarm1_e.tail = center
            uarm2_e.head = center
            put_bone(self.obj, utip, org_uarm_e.tail)
            utip_e.length = org_uarm_e.length / 8
        else:
            uarm_e.use_connect = False
            uarm_e.parent = org_uarm_e

        # Parent and position forearm bones
        if self.use_forearm_twist:
            farm1_e.use_connect = False
            farm2_e.use_connect = False
            ftip_e.use_connect = False

            farm1_e.parent = org_farm_e
            farm2_e.parent = org_farm_e
            ftip_e.parent = org_farm_e

            center = Vector((org_farm_e.head + org_farm_e.tail) / 2)

            farm1_e.tail = center
            farm2_e.head = center
            put_bone(self.obj, ftip, org_farm_e.tail)
            ftip_e.length = org_farm_e.length / 8

            # Align roll of farm2 with hand
            align_roll(self.obj, farm2, hand)
        else:
            farm_e.use_connect = False
            farm_e.parent = org_farm_e

        # Parent hand
        hand_e.use_connect = False
        hand_e.parent = org_hand_e

        # Object mode, get pose bones
        bpy.ops.object.mode_set(mode='OBJECT')
        pb = self.obj.pose.bones

        if self.use_upper_arm_twist:
            uarm1_p = pb[uarm1]
        if self.use_forearm_twist:
            farm2_p = pb[farm2]
        # hand_p = pb[hand]  # UNUSED

        # Upper arm constraints
        if self.use_upper_arm_twist:
            con = uarm1_p.constraints.new('COPY_LOCATION')
            con.name = "copy_location"
            con.target = self.obj
            con.subtarget = self.org_bones[0]

            con = uarm1_p.constraints.new('COPY_SCALE')
            con.name = "copy_scale"
            con.target = self.obj
            con.subtarget = self.org_bones[0]

            con = uarm1_p.constraints.new('DAMPED_TRACK')
            con.name = "track_to"
            con.target = self.obj
            con.subtarget = utip

        # Forearm constraints
        if self.use_forearm_twist:
            con = farm2_p.constraints.new('COPY_ROTATION')
            con.name = "copy_rotation"
            con.target = self.obj
            con.subtarget = hand

            con = farm2_p.constraints.new('DAMPED_TRACK')
            con.name = "track_to"
            con.target = self.obj
            con.subtarget = ftip
Example #15
0
    def generate(self):
        """ Generate the rig.
            Do NOT modify any of the original bones, except for adding constraints.
            The main armature should be selected and active before this is called.

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

        # Create the deformation and control bone chains.
        # Just copies of the original chain.
        def_chain = []
        ctrl_chain = []
        for i in range(len(self.org_bones)):
            name = self.org_bones[i]

            # Control bone
            if self.make_controls:
                # Copy
                ctrl_bone = copy_bone(self.obj, name)
                eb = self.obj.data.edit_bones
                ctrl_bone_e = eb[ctrl_bone]
                # Name
                ctrl_bone_e.name = strip_org(name)
                # Parenting
                if i == 0:
                    # First bone
                    ctrl_bone_e.parent = eb[self.org_bones[0]].parent
                else:
                    # The rest
                    ctrl_bone_e.parent = eb[ctrl_chain[-1]]
                # Add to list
                ctrl_chain += [ctrl_bone_e.name]
            else:
                ctrl_chain += [None]

            # Deformation bone
            if self.make_deforms:
                # Copy
                def_bone = copy_bone(self.obj, name)
                eb = self.obj.data.edit_bones
                def_bone_e = eb[def_bone]
                # Name
                def_bone_e.name = make_deformer_name(strip_org(name))
                # Parenting
                if i == 0:
                    # First bone
                    def_bone_e.parent = eb[self.org_bones[0]].parent
                else:
                    # The rest
                    def_bone_e.parent = eb[def_chain[-1]]
                # Add to list
                def_chain += [def_bone_e.name]
            else:
                def_chain += [None]

        bpy.ops.object.mode_set(mode='OBJECT')
        pb = self.obj.pose.bones

        # Constraints for org and def
        for org, ctrl, defrm in zip(self.org_bones, ctrl_chain, def_chain):
            if self.make_controls:
                con = pb[org].constraints.new('COPY_TRANSFORMS')
                con.name = "copy_transforms"
                con.target = self.obj
                con.subtarget = ctrl

            if self.make_deforms:
                con = pb[defrm].constraints.new('COPY_TRANSFORMS')
                con.name = "copy_transforms"
                con.target = self.obj
                con.subtarget = org

        # Create control widgets
        if self.make_controls:
            for bone in ctrl_chain:
                create_bone_widget(self.obj, bone)
Example #16
0
    def generate(self):
        """ Generate the rig.
            Do NOT modify any of the original bones, except for adding constraints.
            The main armature should be selected and active before this is called.

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

        # Create upper arm bones
        if self.use_thigh_twist:
            thigh1 = copy_bone(self.obj, self.org_bones[0], make_deformer_name(strip_org(self.org_bones[0] + ".01")))
            thigh2 = copy_bone(self.obj, self.org_bones[0], make_deformer_name(strip_org(self.org_bones[0] + ".02")))
            utip = copy_bone(self.obj, self.org_bones[0], make_mechanism_name(strip_org(self.org_bones[0] + ".tip")))
        else:
            thigh = copy_bone(self.obj, self.org_bones[0], make_deformer_name(strip_org(self.org_bones[0])))

        # Create forearm bones
        if self.use_shin_twist:
            shin1 = copy_bone(self.obj, self.org_bones[1], make_deformer_name(strip_org(self.org_bones[1] + ".01")))
            shin2 = copy_bone(self.obj, self.org_bones[1], make_deformer_name(strip_org(self.org_bones[1] + ".02")))
            stip = copy_bone(self.obj, self.org_bones[1], make_mechanism_name(strip_org(self.org_bones[1] + ".tip")))
        else:
            shin = copy_bone(self.obj, self.org_bones[1], make_deformer_name(strip_org(self.org_bones[1])))

        # Create foot bone
        foot = copy_bone(self.obj, self.org_bones[2], make_deformer_name(strip_org(self.org_bones[2])))

        # Create toe bone
        toe = copy_bone(self.obj, self.org_bones[3], make_deformer_name(strip_org(self.org_bones[3])))

        # Get edit bones
        eb = self.obj.data.edit_bones

        org_thigh_e = eb[self.org_bones[0]]
        if self.use_thigh_twist:
            thigh1_e = eb[thigh1]
            thigh2_e = eb[thigh2]
            utip_e = eb[utip]
        else:
            thigh_e = eb[thigh]

        org_shin_e = eb[self.org_bones[1]]
        if self.use_shin_twist:
            shin1_e = eb[shin1]
            shin2_e = eb[shin2]
            stip_e = eb[stip]
        else:
            shin_e = eb[shin]

        org_foot_e = eb[self.org_bones[2]]
        foot_e = eb[foot]

        org_toe_e = eb[self.org_bones[3]]
        toe_e = eb[toe]

        # Parent and position thigh bones
        if self.use_thigh_twist:
            thigh1_e.use_connect = False
            thigh2_e.use_connect = False
            utip_e.use_connect = False

            thigh1_e.parent = org_thigh_e.parent
            thigh2_e.parent = org_thigh_e
            utip_e.parent = org_thigh_e

            center = Vector((org_thigh_e.head + org_thigh_e.tail) / 2)

            thigh1_e.tail = center
            thigh2_e.head = center
            put_bone(self.obj, utip, org_thigh_e.tail)
            utip_e.length = org_thigh_e.length / 8
        else:
            thigh_e.use_connect = False
            thigh_e.parent = org_thigh_e

        # Parent and position shin bones
        if self.use_shin_twist:
            shin1_e.use_connect = False
            shin2_e.use_connect = False
            stip_e.use_connect = False

            shin1_e.parent = org_shin_e
            shin2_e.parent = org_shin_e
            stip_e.parent = org_shin_e

            center = Vector((org_shin_e.head + org_shin_e.tail) / 2)

            shin1_e.tail = center
            shin2_e.head = center
            put_bone(self.obj, stip, org_shin_e.tail)
            stip_e.length = org_shin_e.length / 8

            # Align roll of shin2 with foot
            align_roll(self.obj, shin2, foot)
        else:
            shin_e.use_connect = False
            shin_e.parent = org_shin_e

        # Parent foot
        foot_e.use_connect = False
        foot_e.parent = org_foot_e

        # Parent toe
        toe_e.use_connect = False
        toe_e.parent = org_toe_e

        # Object mode, get pose bones
        bpy.ops.object.mode_set(mode='OBJECT')
        pb = self.obj.pose.bones

        if self.use_thigh_twist:
            thigh1_p = pb[thigh1]
        if self.use_shin_twist:
            shin2_p = pb[shin2]
        # foot_p = pb[foot]  # UNUSED

        # Thigh constraints
        if self.use_thigh_twist:
            con = thigh1_p.constraints.new('COPY_LOCATION')
            con.name = "copy_location"
            con.target = self.obj
            con.subtarget = self.org_bones[0]

            con = thigh1_p.constraints.new('COPY_SCALE')
            con.name = "copy_scale"
            con.target = self.obj
            con.subtarget = self.org_bones[0]

            con = thigh1_p.constraints.new('DAMPED_TRACK')
            con.name = "track_to"
            con.target = self.obj
            con.subtarget = utip

        # Shin constraints
        if self.use_shin_twist:
            con = shin2_p.constraints.new('COPY_ROTATION')
            con.name = "copy_rotation"
            con.target = self.obj
            con.subtarget = foot

            con = shin2_p.constraints.new('DAMPED_TRACK')
            con.name = "track_to"
            con.target = self.obj
            con.subtarget = stip
Example #17
0
    def generate(self):
        """ Generate the rig.
            Do NOT modify any of the original bones, except for adding constraints.
            The main armature should be selected and active before this is called.

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

        # Create the deformation and control bone chains.
        # Just copies of the original chain.
        def_chain = []
        ctrl_chain = []
        for i in range(len(self.org_bones)):
            name = self.org_bones[i]

            # Control bone
            if self.make_controls:
                # Copy
                ctrl_bone = copy_bone(self.obj, name)
                eb = self.obj.data.edit_bones
                ctrl_bone_e = eb[ctrl_bone]
                # Name
                ctrl_bone_e.name = strip_org(name)
                # Parenting
                if i == 0:
                    # First bone
                    ctrl_bone_e.parent = eb[self.org_bones[0]].parent
                else:
                    # The rest
                    ctrl_bone_e.parent = eb[ctrl_chain[-1]]
                # Add to list
                ctrl_chain += [ctrl_bone_e.name]
            else:
                ctrl_chain += [None]

            # Deformation bone
            if self.make_deforms:
                # Copy
                def_bone = copy_bone(self.obj, name)
                eb = self.obj.data.edit_bones
                def_bone_e = eb[def_bone]
                # Name
                def_bone_e.name = make_deformer_name(strip_org(name))
                # Parenting
                if i == 0:
                    # First bone
                    def_bone_e.parent = eb[self.org_bones[0]].parent
                else:
                    # The rest
                    def_bone_e.parent = eb[def_chain[-1]]
                # Add to list
                def_chain += [def_bone_e.name]
            else:
                def_chain += [None]

        bpy.ops.object.mode_set(mode='OBJECT')
        pb = self.obj.pose.bones

        # Constraints for org and def
        for org, ctrl, defrm in zip(self.org_bones, ctrl_chain, def_chain):
            if self.make_controls:
                con = pb[org].constraints.new('COPY_TRANSFORMS')
                con.name = "copy_transforms"
                con.target = self.obj
                con.subtarget = ctrl

            if self.make_deforms:
                con = pb[defrm].constraints.new('COPY_TRANSFORMS')
                con.name = "copy_transforms"
                con.target = self.obj
                con.subtarget = org

        # Create control widgets
        if self.make_controls:
            for bone in ctrl_chain:
                create_bone_widget(self.obj, bone)
Example #18
0
    def generate(self):
        def parent_ctrl(eb, child, parent_to=None):
            """This tries to parent the child to a .L/.R bone."""
            # Get parent if none supplied
            if parent_to is None and eb[child].parent is not None:
                parent_to = eb[child].parent.name
            print(parent_to)

            if parent_to + self.params.object_side in eb:
                eb[child].parent = (eb[parent_to + self.params.object_side])
            elif parent_to in eb:
                eb[child].parent = eb[parent_to]
            elif 'MCH-Flip' in eb:
                eb[child].parent = eb['MCH-Flip']
            else:
                raise Exception(
                    "RIGIFY ERROR: Bone %s does not have a %s side" %
                    (strip_org(eb[b].parent.name), side))

        if self.params.use_parent_Z_index and self.org_parent is not None:
            # Get parent's Z indices
            bpy.ops.object.mode_set(mode='OBJECT')
            pb = self.obj.pose.bones
            def_parent_name = make_deformer_name(strip_org(self.org_parent))
            if (self.params.object_side != ".C"
                    and def_parent_name[-2:] not in ['.L', '.R']):
                def_parent_name += self.params.object_side
            if not def_parent_name in pb:
                raise Exception(
                    "RIGIFY ERROR: Bone %s does not have a %s side" %
                    (strip_org(self.org_parent), self.params.object_side))
            parent_p = pb[def_parent_name]
            member_Z_index = parent_p['member_index']
            bone_Z_index = 0
            for b in pb:
                if b.bone.use_deform and b.name.startswith('DEF-'):
                    if not 'member_index' in b:
                        raise MetarigError(
                            "RIGIFY ERROR: One rig bone with should not be connected. "
                            "Check armature for connected bones.")
                    if (b['member_index'] == member_Z_index
                            and b['bone_index'] > bone_Z_index):
                        bone_Z_index = b['bone_index']
            bone_Z_index += 1

            bpy.ops.object.mode_set(mode='EDIT')
        else:
            member_Z_index = self.params.member_Z_index
            bone_Z_index = self.params.first_bone_Z_index

        eb = self.obj.data.edit_bones

        ctrl_chain = []
        mch_chain = []
        # def_chain = []

        # if self.params.duplicate_lr:
        #     sides = ['.L', '.R']
        # else:
        side = self.params.object_side
        if side == '.C':
            side = ''

        # IK control bone
        if self.params.chain_type == 'IK':
            last_bone = self.org_bones[-1]
            ctrl_bone = new_bone(self.obj, strip_org(last_bone) + ".ik" + side)
            ctrl_bone_e = eb[ctrl_bone]
            ctrl_bone_e.head = eb[last_bone].tail
            ctrl_bone_e.tail = eb[last_bone].tail + Vector((0.3, 0, 0))
            align_bone_z_axis(self.obj, ctrl_bone, Vector((0, 1, 0)))
            ctrl_chain.append(ctrl_bone)
            # ctrl_bone_e.layers = layers

        for i, b in enumerate(self.org_bones):
            # Control bones
            if self.params.chain_type in {'Normal', 'Curve', 'Dynamic'}:
                if side in b:
                    ctrl_bone_name = b
                else:
                    ctrl_bone_name = b + side
                ctrl_bone_name = strip_org(ctrl_bone_name)
                ctrl_bone = copy_bone(self.obj, b, ctrl_bone_name)
                ctrl_bone_e = eb[ctrl_bone]
                ctrl_chain.append(ctrl_bone)

                if self.params.chain_type == 'Curve':
                    ctrl_bone_e.use_connect = False
                    if self.params.curve_parent_to_first:
                        if i > 0:
                            parent_ctrl(eb, ctrl_bone, parent_to=ctrl_chain[0])
                        else:
                            parent_ctrl(eb,
                                        ctrl_bone,
                                        parent_to=self.org_parent)
                    else:
                        parent_ctrl(eb, ctrl_bone, parent_to=self.org_parent)
                    ctrl_bone_e.tail = (ctrl_bone_e.head + Vector(
                        (0, 0, 1)) * ctrl_bone_e.length)
                    align_bone_z_axis(self.obj, ctrl_bone, Vector((0, 1, 0)))

                elif self.params.chain_type == 'Dynamic':
                    # Create an empty object to use slow parent
                    # What follows is quite dirty.
                    # ctrl_bone_e.parent = eb[self.org_parent]
                    parent_ctrl(eb, ctrl_bone)

                    empty_name = self.obj.name + "_" + strip_org(b) + '.dyn'
                    if empty_name in bpy.data.objects:
                        empty_obj = bpy.data.objects[empty_name]
                    else:
                        empty_obj = bpy.data.objects.new(empty_name, None)
                    if not empty_name in bpy.context.scene.objects:
                        bpy.context.scene.objects.link(empty_obj)
                    empty_obj.empty_draw_type = 'SPHERE'
                    empty_obj.empty_draw_size = self.obj.data.bones[
                        b].length / 10
                    empty_obj.hide = True

                    empty_obj.parent = self.obj
                    empty_obj.parent_type = 'BONE'
                    empty_obj.parent_bone = ctrl_bone
                    empty_obj.matrix_local = Matrix()
                    empty_obj.use_slow_parent = True
                    empty_obj.slow_parent_offset = 1.0

            # Mechanism bones
            if self.params.chain_type == 'Curve':
                stretch_bone = copy_bone(
                    self.obj, b,
                    make_mechanism_name(strip_org(b)) + '.stretch' + side)
                stretch_bone_e = eb[stretch_bone]
                stretch_bone_e.use_connect = False
                stretch_bone_e.parent = eb[ctrl_bone]
                mch_chain.append(stretch_bone)

            elif self.params.chain_type == 'IK':
                ik_bone = copy_bone(
                    self.obj, b,
                    make_mechanism_name(strip_org(b)) + '.ik' + side)
                ik_bone_e = eb[ik_bone]
                ik_bone_e.parent = eb[mch_chain[-1] if i > 0 else self.
                                      org_parent]
                mch_chain.append(ik_bone)

            elif self.params.chain_type == 'Dynamic':
                dyn_bone = copy_bone(
                    self.obj, b,
                    make_mechanism_name(strip_org(b)) + '.dyn' + side)
                dyn_bone_e = eb[dyn_bone]
                dyn_bone_e.parent = eb[ctrl_bone]
                mch_chain.append(dyn_bone)

            # Parenting
            # if self.params.chain_type == 'Normal':
            if (i == 0 and self.params.chain_type in ('Normal', 'Dynamic')):
                parent_ctrl(eb, ctrl_bone)

            # Def bones
            def_bone = pantin_utils.create_deformation(self.obj, b,
                                                       member_Z_index,
                                                       bone_Z_index + i, 0.0,
                                                       b + side)

        if self.params.chain_type == 'Curve':
            # Curve end bone
            last_bone = self.org_bones[-1]
            ctrl_bone = new_bone(self.obj,
                                 strip_org(last_bone) + ".end" + side)
            ctrl_bone_e = eb[ctrl_bone]
            last_bone_e = eb[last_bone]

            ctrl_bone_e.use_connect = False
            if self.params.curve_parent_to_first:
                ctrl_bone_e.parent = eb[ctrl_chain[0]]
            else:
                parent_ctrl(eb, ctrl_bone, parent_to=self.org_parent)
            ctrl_bone_e.head = last_bone_e.tail
            ctrl_bone_e.tail = (ctrl_bone_e.head +
                                (last_bone_e.tail - last_bone_e.head))
            align_bone_z_axis(self.obj, ctrl_bone, Vector((0, 1, 0)))
            ctrl_chain.append(ctrl_bone)
            ctrl_bone_e.layers = last_bone_e.layers
            # ctrl_bone_e.layers = layers

        bpy.ops.object.mode_set(mode='OBJECT')
        pb = self.obj.pose.bones

        # Pose bone settings
        if self.params.chain_type in ('IK', 'Curve', 'Dynamic'):
            pbone = pb[ctrl_chain[-1]]
            pbone.rotation_mode = 'XZY'
            pbone.lock_location = (False, False, True)
            pbone.lock_rotation = (True, True, False)
            pbone.lock_rotation_w = False
            pbone.lock_scale = (False, False, False)

        if self.params.chain_type in ('IK', 'Curve', 'Dynamic'):
            # Widgets
            for ctrl_bone in ctrl_chain:
                global_scale = pb[ctrl_bone].length  # self.obj.dimensions[2]
                # member_factor = 0.06
                widget_size = global_scale * 0.3  # * member_factor
                pantin_utils.create_aligned_circle_widget(self.obj,
                                                          ctrl_bone,
                                                          radius=widget_size)

            # Constraints
            for org, mch in zip(self.org_bones, mch_chain):
                con = pb[org].constraints.new('COPY_TRANSFORMS')
                con.name = "copy_transforms"
                con.target = self.obj
                con.subtarget = mch
        else:
            # Widgets
            widget_size = 0.5
            for bone in ctrl_chain:
                pantin_utils.create_capsule_widget(self.obj,
                                                   bone,
                                                   length=widget_size,
                                                   width=widget_size * 0.1,
                                                   head_tail=0.5,
                                                   horizontal=False)

            # Constraints
            for org, ctrl in zip(self.org_bones, ctrl_chain):
                con = pb[org].constraints.new('COPY_TRANSFORMS')
                con.name = "copy_transforms"
                con.target = self.obj
                con.subtarget = ctrl

        ui_script = ""

        if self.params.chain_type == 'Curve':
            for ctrl, mch in zip(ctrl_chain[1:], mch_chain):
                con = pb[mch].constraints.new('STRETCH_TO')
                con.name = "stretch_to"
                con.target = self.obj
                con.subtarget = ctrl
                con.volume = 'NO_VOLUME'
                con.keep_axis = 'PLANE_Z'

        elif self.params.chain_type == 'IK':
            last_bone = mch_chain[-1]
            con = pb[last_bone].constraints.new('IK')
            con.target = self.obj
            con.subtarget = ctrl_bone
            con.chain_count = len(self.org_bones)

            # # Pelvis follow
            # if self.params.do_flip:
            #     pantin_utils.create_ik_child_of(
            #         self.obj, ctrl_bone, self.params.pelvis_name)

        elif self.params.chain_type == 'Dynamic':
            for ctrl, mch in zip(ctrl_chain, mch_chain):
                con = pb[mch].constraints.new('DAMPED_TRACK')
                con.name = "damped_track"
                con.target = empty_obj
                # con.volume = 'NO_VOLUME'
                # con.keep_axis = 'PLANE_Z'
                # con.rest_length = pb[ctrl].length

            ui_script = script % (ctrl, dyn_bone)  # % ctrl_bone, MCH-bone.dyn

        elif self.params.chain_type == 'Def':
            # Modify constraints to add side suffix
            if side in ('.L', '.R'):
                for b in self.org_bones:
                    for con in pb[b].constraints:
                        if (hasattr(con, 'subtarget')
                                and con.subtarget + side in pb):
                            con.subtarget += side

        return {
            'script': [ui_script],
            'imports': UI_IMPORTS,
            'utilities': PANTIN_UTILS,
            'register': PANTIN_REGISTER,
            'register_props': REGISTER_PANTIN_PROPS,
        }
Example #19
0
    def generate(self):
        if self.params.use_parent_Z_index and self.org_parent is not None:
            # Get parent's Z indices
            bpy.ops.object.mode_set(mode='OBJECT')
            pb = self.obj.pose.bones
            def_parent_name = make_deformer_name(strip_org(self.org_parent))
            if (self.params.object_side != ".C"
                    and def_parent_name[-2:] not in ['.L', '.R']):
                def_parent_name += self.params.object_side
            # print("DEF PARENT", def_parent_name)
            if not def_parent_name in pb:
                raise MetarigError(
                    "RIGIFY ERROR: Bone %s does not have a %s side" %
                    (strip_org(self.org_parent), self.params.object_side))
            parent_p = pb[def_parent_name]
            member_Z_index = parent_p['member_index']
            bone_Z_index = 0
            for b in pb:
                if b.bone.use_deform and b.name.startswith('DEF-'):
                    if (b['member_index'] == member_Z_index
                            and b['bone_index'] > bone_Z_index):
                        bone_Z_index = b['bone_index']
            bone_Z_index += 1

            bpy.ops.object.mode_set(mode='EDIT')
        else:
            member_Z_index = self.params.member_Z_index
            bone_Z_index = self.params.first_bone_Z_index

        eb = self.obj.data.edit_bones

        ctrl_chain = []
        # mch_chain = []

        # Control bones
        # Left
        left_ctrl = copy_bone(self.obj, self.org_bone,
                              strip_org(self.params.eye_name) + '.L')
        left_ctrl_e = eb[left_ctrl]
        left_ctrl_e.use_connect = False
        left_ctrl_e.tail = (left_ctrl_e.tail + Vector(
            (0, 0, 1)) * left_ctrl_e.length)
        left_ctrl_e.head = eb[self.org_bone].tail
        align_bone_z_axis(self.obj, left_ctrl, Vector((0, 1, 0)))
        ctrl_chain.append(left_ctrl)

        # Right
        right_ctrl = copy_bone(self.obj, self.org_bone,
                               strip_org(self.params.eye_name) + '.R')
        right_ctrl_e = eb[right_ctrl]
        right_ctrl_e.use_connect = False
        right_ctrl_e.tail = (right_ctrl_e.head + Vector(
            (0, 0, 1)) * right_ctrl_e.length)
        align_bone_z_axis(self.obj, right_ctrl, Vector((0, 1, 0)))
        ctrl_chain.append(right_ctrl)

        # Main
        main_ctrl = copy_bone(self.obj, self.org_bone,
                              strip_org(self.org_bone))
        main_ctrl_e = eb[main_ctrl]
        main_ctrl_e.head = (main_ctrl_e.head + main_ctrl_e.tail) / 2
        if self.org_parent is not None:
            main_ctrl_e.parent = eb[self.org_parent]
        ctrl_chain.append(main_ctrl)

        # Mechanism bones
        inter = copy_bone(
            self.obj, self.org_bone,
            make_mechanism_name(strip_org(self.org_bone) + '.intermediate'))
        eb[inter].parent = eb[main_ctrl]
        eb[left_ctrl].parent = eb[inter]
        eb[right_ctrl].parent = eb[inter]

        # # Def bones
        for i, b in enumerate([left_ctrl, right_ctrl]):
            def_bone = pantin_utils.create_deformation(self.obj, b,
                                                       member_Z_index,
                                                       bone_Z_index + i, 0.0,
                                                       b)

        bpy.ops.object.mode_set(mode='OBJECT')
        pb = self.obj.pose.bones

        # Widgets
        pantin_utils.create_capsule_widget(self.obj,
                                           main_ctrl,
                                           length=pb[self.org_bone].length,
                                           width=pb[self.org_bone].length *
                                           0.7,
                                           horizontal=False)
        for b in [left_ctrl, right_ctrl]:
            pantin_utils.create_aligned_circle_widget(self.obj,
                                                      b,
                                                      radius=pb[b].length / 4)
        # for ctrl_bone in ctrl_chain:
        #     global_scale = pb[ctrl_bone].length  # self.obj.dimensions[2]
        #     # member_factor = 0.06
        #     widget_size = global_scale * 0.5  # * member_factor
        #     pantin_utils.create_aligned_circle_widget(
        #         self.obj, ctrl_bone, radius=widget_size)

        # Constraints
        # for org, ctrl in zip(self.org_bones, mch_chain):
        con = pb[self.org_bone].constraints.new('COPY_TRANSFORMS')
        con.name = "copy_transforms"
        con.target = self.obj
        con.subtarget = inter

        # # Pelvis follow
        # if self.params.do_flip:
        #     pantin_utils.create_ik_child_of(
        #         self.obj, ctrl_bone, self.params.pelvis_name)

        return {
            'imports': UI_IMPORTS,
            'utilities': PANTIN_UTILS,
            'register': PANTIN_REGISTER,
            'register_props': REGISTER_PANTIN_PROPS,
        }
 def get_def_by_org(self, org_name):
     base_name = strip_org(org_name)
     return make_deformer_name(base_name)
Example #21
0
    def generate(self):
        """ Generate the rig.
            Do NOT modify any of the original bones, except for adding constraints.
            The main armature should be selected and active before this is called.

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

        # Create upper arm bones
        if self.use_upper_arm_twist:
            uarm1 = copy_bone(self.obj, self.org_bones[0], make_deformer_name(strip_org(self.org_bones[0] + ".01")))
            uarm2 = copy_bone(self.obj, self.org_bones[0], make_deformer_name(strip_org(self.org_bones[0] + ".02")))
            utip = copy_bone(self.obj, self.org_bones[0], make_mechanism_name(strip_org(self.org_bones[0] + ".tip")))
        else:
            uarm = copy_bone(self.obj, self.org_bones[0], make_deformer_name(strip_org(self.org_bones[0])))

        # Create forearm bones
        if self.use_forearm_twist:
            farm1 = copy_bone(self.obj, self.org_bones[1], make_deformer_name(strip_org(self.org_bones[1] + ".01")))
            farm2 = copy_bone(self.obj, self.org_bones[1], make_deformer_name(strip_org(self.org_bones[1] + ".02")))
            ftip = copy_bone(self.obj, self.org_bones[1], make_mechanism_name(strip_org(self.org_bones[1] + ".tip")))
        else:
            farm = copy_bone(self.obj, self.org_bones[1], make_deformer_name(strip_org(self.org_bones[1])))

        # Create hand bone
        hand = copy_bone(self.obj, self.org_bones[2], make_deformer_name(strip_org(self.org_bones[2])))

        # Get edit bones
        eb = self.obj.data.edit_bones

        org_uarm_e = eb[self.org_bones[0]]
        if self.use_upper_arm_twist:
            uarm1_e = eb[uarm1]
            uarm2_e = eb[uarm2]
            utip_e = eb[utip]
        else:
            uarm_e = eb[uarm]

        org_farm_e = eb[self.org_bones[1]]
        if self.use_forearm_twist:
            farm1_e = eb[farm1]
            farm2_e = eb[farm2]
            ftip_e = eb[ftip]
        else:
            farm_e = eb[farm]

        org_hand_e = eb[self.org_bones[2]]
        hand_e = eb[hand]

        # Parent and position upper arm bones
        if self.use_upper_arm_twist:
            uarm1_e.use_connect = False
            uarm2_e.use_connect = False
            utip_e.use_connect = False

            uarm1_e.parent = org_uarm_e.parent
            uarm2_e.parent = org_uarm_e
            utip_e.parent = org_uarm_e

            center = Vector((org_uarm_e.head + org_uarm_e.tail) / 2)

            uarm1_e.tail = center
            uarm2_e.head = center
            put_bone(self.obj, utip, org_uarm_e.tail)
            utip_e.length = org_uarm_e.length / 8
        else:
            uarm_e.use_connect = False
            uarm_e.parent = org_uarm_e

        # Parent and position forearm bones
        if self.use_forearm_twist:
            farm1_e.use_connect = False
            farm2_e.use_connect = False
            ftip_e.use_connect = False

            farm1_e.parent = org_farm_e
            farm2_e.parent = org_farm_e
            ftip_e.parent = org_farm_e

            center = Vector((org_farm_e.head + org_farm_e.tail) / 2)

            farm1_e.tail = center
            farm2_e.head = center
            put_bone(self.obj, ftip, org_farm_e.tail)
            ftip_e.length = org_farm_e.length / 8

            # Align roll of farm2 with hand
            align_roll(self.obj, farm2, hand)
        else:
            farm_e.use_connect = False
            farm_e.parent = org_farm_e

        # Parent hand
        hand_e.use_connect = False
        hand_e.parent = org_hand_e

        # Object mode, get pose bones
        bpy.ops.object.mode_set(mode='OBJECT')
        pb = self.obj.pose.bones

        if self.use_upper_arm_twist:
            uarm1_p = pb[uarm1]
        if self.use_forearm_twist:
            farm2_p = pb[farm2]
        # hand_p = pb[hand]  # UNUSED

        # Upper arm constraints
        if self.use_upper_arm_twist:
            con = uarm1_p.constraints.new('COPY_LOCATION')
            con.name = "copy_location"
            con.target = self.obj
            con.subtarget = self.org_bones[0]

            con = uarm1_p.constraints.new('COPY_SCALE')
            con.name = "copy_scale"
            con.target = self.obj
            con.subtarget = self.org_bones[0]

            con = uarm1_p.constraints.new('DAMPED_TRACK')
            con.name = "track_to"
            con.target = self.obj
            con.subtarget = utip

        # Forearm constraints
        if self.use_forearm_twist:
            con = farm2_p.constraints.new('COPY_ROTATION')
            con.name = "copy_rotation"
            con.target = self.obj
            con.subtarget = hand

            con = farm2_p.constraints.new('DAMPED_TRACK')
            con.name = "track_to"
            con.target = self.obj
            con.subtarget = ftip
def create_deformation(obj,
                       bone_name,
                       member_index=0,
                       bone_index=0,
                       extra_offset=0.0,
                       new_name=''):
    bpy.ops.object.mode_set(mode='EDIT')
    eb = obj.data.edit_bones

    org_bone_e = eb[bone_name]
    def_bone_e = eb.new(bone_name)

    #    bone = copy_bone(obj, bone_name, strip_org(bone_name))
    #    bone_e = eb[bone]

    if new_name == '':
        new_name = bone_name
    def_name = make_deformer_name(strip_org(new_name))
    def_bone_e.name = def_name
    #    def_bone_e.name = strip_org(bone_name)

    def_bone_e.parent = org_bone_e
    def_bone_e.use_connect = False

    def_bone_e.head = org_bone_e.head
    def_bone_e.tail = org_bone_e.tail
    align_bone_z_axis(obj, def_name, Vector((0, -1, 0)))
    # def_bone_e.tail.z += org_bone_e.length * 0.5

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

    def_bone_p = obj.pose.bones[def_name]
    def_bone_p['member_index'] = member_index
    def_bone_p['bone_index'] = bone_index
    def_bone_p['extra_offset'] = extra_offset

    # Driver
    driver = obj.driver_add('pose.bones["{}"].location'.format(def_name), 2)
    driver.driver.expression = (
        'member_index * 0.01 * -(flip*2-1) + bone_index * 0.001 * -(flip*2-1) - extra_offset * 0.01'
    )
    var_mi = driver.driver.variables.new()
    var_bi = driver.driver.variables.new()
    var_flip = driver.driver.variables.new()
    var_eo = driver.driver.variables.new()

    var_mi.type = 'SINGLE_PROP'
    var_mi.name = 'member_index'
    var_mi.targets[0].id_type = 'OBJECT'
    var_mi.targets[0].id = obj
    var_mi.targets[0].data_path = (
        'pose.bones["{}"]["member_index"]'.format(def_name))

    var_bi.type = 'SINGLE_PROP'
    var_bi.name = 'bone_index'
    var_bi.targets[0].id_type = 'OBJECT'
    var_bi.targets[0].id = obj
    var_bi.targets[0].data_path = (
        'pose.bones["{}"]["bone_index"]'.format(def_name))

    var_eo.type = 'SINGLE_PROP'
    var_eo.name = 'extra_offset'
    var_eo.targets[0].id_type = 'OBJECT'
    var_eo.targets[0].id = obj
    var_eo.targets[0].data_path = (
        'pose.bones["{}"]["extra_offset"]'.format(def_name))

    var_flip.type = 'SINGLE_PROP'
    var_flip.name = 'flip'
    var_flip.targets[0].id_type = 'OBJECT'
    var_flip.targets[0].id = obj
    var_flip.targets[0].data_path = 'pose.bones["root"]["flip"]'

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