Ejemplo n.º 1
0
    def __init__(self, obj, bone, params):
        self.obj = obj
        self.params = params

        # Get the chain of 2 connected bones
        leg_bones = [bone] + connected_children_names(self.obj, bone)[:2]

        if len(leg_bones) != 2:
            raise MetarigError(
                "RIGIFY ERROR: Bone '%s': incorrect bone configuration for rig type -- leg bones != 2"
                % (strip_org(bone)))

        # Get the foot and heel
        foot = None
        heel = None
        for b in self.obj.data.bones[leg_bones[1]].children:
            if b.use_connect is True:
                if len(b.children) >= 1 and has_connected_children(b):
                    foot = b.name
                else:
                    heel = b.name

        if foot is None:
            raise MetarigError(
                "RIGIFY ERROR: Bone '%s': incorrect bone configuration for rig type -- could not find foot bone (that is, a bone with >1 children connected) attached to bone '%s'"
                % (strip_org(bone), strip_org(leg_bones[1])))
        if heel is None:
            raise MetarigError(
                "RIGIFY ERROR: Bone '%s': incorrect bone configuration for rig type -- could not find heel bone (that is, a bone with no children connected) attached to bone '%s'"
                % (strip_org(bone), strip_org(leg_bones[1])))
        # Get the toe
        toe = None
        for b in self.obj.data.bones[foot].children:
            if b.use_connect is True:
                toe = b.name

        if toe is None:
            raise MetarigError(
                "RIGIFY ERROR: Bone '%s': incorrect bone configuration for rig type -- toe is None"
                % (strip_org(bone)))

        self.org_bones = leg_bones + [foot, toe, heel]

        # Get rig parameters
        if params.separate_hose_layers:
            layers = list(params.hose_layers)
        else:
            layers = None
        use_complex_rig = params.use_complex_leg
        knee_base_name = params.knee_base_name
        primary_rotation_axis = params.primary_rotation_axis_legacy

        # Based on common limb
        self.rubber_hose_limb = limb_common.RubberHoseLimb(
            obj, self.org_bones[0], self.org_bones[1], self.org_bones[2],
            use_complex_rig, knee_base_name, primary_rotation_axis, layers)
Ejemplo n.º 2
0
    def __init__(self, obj, bone, params, ikfk_switch=False):
        """ Gather and validate data about the rig.
            Store any data or references to data that will be needed later on.
            In particular, store references to bones that will be needed, and
            store names of bones that will be needed.
            Do NOT change any data in the scene.  This is a gathering phase only.
        """
        self.obj = obj
        self.params = params
        self.switch = ikfk_switch

        # Get the chain of 2 connected bones
        leg_bones = [bone] + connected_children_names(self.obj, bone)[:2]

        if len(leg_bones) != 2:
            raise MetarigError("RIGIFY ERROR: Bone '%s': incorrect bone configuration for rig type" % (strip_org(bone)))

        # Get the foot and heel
        foot = None
        heel = None
        rocker = None
        for b in self.obj.data.bones[leg_bones[1]].children:
            if b.use_connect == True:
                if len(b.children) >= 1 and has_connected_children(b):
                    foot = b.name
                else:
                    heel = b.name
                    if len(b.children) > 0:
                        rocker = b.children[0].name

        if foot is None or heel is None:
            print("blah")
            raise MetarigError("RIGIFY ERROR: Bone '%s': incorrect bone configuration for rig type" % (strip_org(bone)))

        # Get the toe
        toe = None
        for b in self.obj.data.bones[foot].children:
            if b.use_connect == True:
                toe = b.name

        # Get toe
        if toe is None:
            raise MetarigError("RIGIFY ERROR: Bone '%s': incorrect bone configuration for rig type" % (strip_org(bone)))

        self.org_bones = leg_bones + [foot, toe, heel, rocker]

        # Get rig parameters
        if params.separate_ik_layers:
            self.layers = list(params.ik_layers)
        else:
            self.layers = None

        self.bend_hint = params.bend_hint

        self.primary_rotation_axis = params.primary_rotation_axis
Ejemplo n.º 3
0
    def __init__(self, obj, bone, params):
        """ Gather and validate data about the rig.
            Store any data or references to data that will be needed later on.
            In particular, store references to bones that will be needed, and
            store names of bones that will be needed.
            Do NOT change any data in the scene.  This is a gathering phase only.

        """
        self.obj = obj
        self.params = params

        # Get the chain of 2 connected bones
        leg_bones = [bone] + connected_children_names(self.obj, bone)[:2]

        if len(leg_bones) != 2:
            raise MetarigError("RIGIFY ERROR: Bone '%s': incorrect bone configuration for rig type." % (strip_org(bone)))

        # Get the foot and heel
        foot = None
        heel = None
        for b in self.obj.data.bones[leg_bones[1]].children:
            if b.use_connect == True:
                if len(b.children) == 0:
                    heel = b.name
                else:
                    foot = b.name

        if foot == None or heel == None:
            raise MetarigError("RIGIFY ERROR: Bone '%s': incorrect bone configuration for rig type." % (strip_org(bone)))

        # Get the toe
        toe = None
        for b in self.obj.data.bones[foot].children:
            if b.use_connect == True:
                toe = b.name

        # Get the toe
        if toe == None:
            raise MetarigError("RIGIFY ERROR: Bone '%s': incorrect bone configuration for rig type." % (strip_org(bone)))

        self.org_bones = leg_bones + [foot, toe, heel]

        # Get (optional) parent
        if self.obj.data.bones[bone].parent == None:
            self.org_parent = None
        else:
            self.org_parent = self.obj.data.bones[bone].parent.name

        # Get rig parameters
        if "layers" in params:
            self.layers = get_layers(params["layers"])
        else:
            self.layers = None

        self.primary_rotation_axis = params.primary_rotation_axis
Ejemplo n.º 4
0
    def __init__(self, obj, bone, params):
        """ Gather and validate data about the rig.
            Store any data or references to data that will be needed later on.
            In particular, store references to bones that will be needed, and
            store names of bones that will be needed.
            Do NOT change any data in the scene.  This is a gathering phase only.

        """
        self.obj = obj
        self.params = params

        # Get the chain of 2 connected bones
        leg_bones = [bone] + connected_children_names(self.obj, bone)[:2]

        if len(leg_bones) != 2:
            raise MetarigError(
                "RIGIFY ERROR: Bone '%s': incorrect bone configuration for rig type"
                % (strip_org(bone)))

        # Get the foot and heel
        foot = None
        heel = None
        for b in self.obj.data.bones[leg_bones[1]].children:
            if b.use_connect == True:
                if len(b.children) >= 1 and has_connected_children(b):
                    foot = b.name
                else:
                    heel = b.name

        if foot is None or heel is None:
            raise MetarigError(
                "RIGIFY ERROR: Bone '%s': incorrect bone configuration for rig type"
                % (strip_org(bone)))

        # Get the toe
        toe = None
        for b in self.obj.data.bones[foot].children:
            if b.use_connect == True:
                toe = b.name

        if toe is None:
            raise MetarigError(
                "RIGIFY ERROR: Bone '%s': incorrect bone configuration for rig type"
                % (strip_org(bone)))

        self.org_bones = leg_bones + [foot, toe, heel]

        # Get rig parameters
        self.use_thigh_twist = params.use_thigh_twist
        self.use_shin_twist = params.use_shin_twist
Ejemplo n.º 5
0
    def get_mouth(self):
        """
        Returns the main bones of the mouth chain
        :return:
        """

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

        lip_bones = []
        for child in edit_bones[self.bones['org'][0]].children:
            if not child.use_connect:
                lip_bones.append(child.name)

        # Rule check
        if len(lip_bones) != 4:
            raise MetarigError(
                "Exactly 4 disconnected chains (lips) must be parented to main bone"
            )

        mouth_bones_dict = {'top': [], 'bottom': []}
        self.lip_len = len(self.get_chain_bones(lip_bones[0]))

        # Check all half-lips have same length
        for lip in lip_bones:
            if len(self.get_chain_bones(lip)) != self.lip_len:
                raise MetarigError("All lip chains must be the same length")

        m_b_head_positions = [edit_bones[name].head for name in lip_bones]
        head_sum = m_b_head_positions[0]
        for h in m_b_head_positions[1:]:
            head_sum = head_sum + h
        mouth_center = head_sum / 4

        chin_tail_position = edit_bones[self.main_mch].tail
        mouth_chin_distance = (mouth_center - chin_tail_position).magnitude
        for m_b in lip_bones:
            head = edit_bones[m_b].head
            if (head - chin_tail_position).magnitude < mouth_chin_distance:
                mouth_bones_dict['bottom'].append(m_b)
            elif (head - chin_tail_position).magnitude > mouth_chin_distance:
                mouth_bones_dict['top'].append(m_b)

        if not (len(mouth_bones_dict['top']) == len(mouth_bones_dict['bottom'])
                == 2):
            raise MetarigError("Badly drawn mouth")

        return mouth_bones_dict
Ejemplo n.º 6
0
    def __init__(self, obj, bone_name, params):
        """ Gather and validate data about the rig.

        """
        self.obj = obj
        self.org_bones = [bone_name] + connected_children_names(obj, bone_name)
        self.params = params

        # Collect control bone indices
        self.control_indices = [0, len(self.org_bones) - 1]
        temp = self.params.chain_bone_controls.split(",")
        for i in temp:
            try:
                j = int(i) - 1
            except ValueError:
                pass
            else:
                if (j > 0) and (j < len(
                        self.org_bones)) and (j not in self.control_indices):
                    self.control_indices += [j]
        self.control_indices.sort()

        self.pivot_rest = self.params.rest_pivot_slide
        self.pivot_rest = max(self.pivot_rest, 1.0 / len(self.org_bones))
        self.pivot_rest = min(self.pivot_rest,
                              1.0 - (1.0 / len(self.org_bones)))

        if len(self.org_bones) <= 1:
            raise MetarigError(
                "RIGIFY ERROR: Bone '%s': input to rig type must be a chain of 2 or more bones"
                % (strip_org(bone_name)))
Ejemplo n.º 7
0
    def __init__(self, obj, bone, params):
        """ Gather and validate data about the rig.
            Store any data or references to data that will be needed later on.
            In particular, store references to bones that will be needed, and
            store names of bones that will be needed.
            Do NOT change any data in the scene.  This is a gathering phase only.

        """
        self.obj = obj

        # Get the chain of 3 connected bones
        self.org_bones = [bone] + connected_children_names(self.obj, bone)[:2]

        if len(self.org_bones) != 3:
            raise MetarigError(
                "RIGIFY ERROR: Bone '%s': input to rig type must be a chain of at least 3 bones"
                % (strip_org(bone)))

        # Get params
        if "layers" in params:
            layers = get_layers(params["layers"])
        else:
            layers = None

        primary_rotation_axis = params.primary_rotation_axis_cessen

        # Arm is based on common limb
        self.fk_limb = limb_common.FKLimb(obj, self.org_bones[0],
                                          self.org_bones[1], self.org_bones[2],
                                          primary_rotation_axis, layers)
Ejemplo n.º 8
0
def get_bone_rigs(obj, bone_name, halt_on_missing=False):
    """ Fetch all the rigs specified on a bone.
    """
    rigs = []
    rig_type = obj.pose.bones[bone_name].rigify_type
    rig_type = rig_type.replace(" ", "")

    if rig_type == "":
        pass
    else:
        # Gather parameters
        try:
            params = obj.pose.bones[bone_name].rigify_parameters[0]
        except (KeyError, IndexError):
            params = None

        # Get the rig
        try:
            rig = get_rig_type(rig_type).Rig(obj, bone_name, params)
        except ImportError:
            message = "Rig Type Missing: python module for type '%s' not found (bone: %s)" % (
                rig_type, bone_name)
            if halt_on_missing:
                raise MetarigError(message)
            else:
                print(message)
                print('print_exc():')
                traceback.print_exc(file=sys.stdout)
        else:
            rigs += [rig]
    return rigs
Ejemplo n.º 9
0
    def __init__(self, obj, bone, params):
        """ Gather and validate data about the rig.
            Store any data or references to data that will be needed later on.
            In particular, store references to bones that will be needed, and
            store names of bones that will be needed.
            Do NOT change any data in the scene.  This is a gathering phase only.

        """
        self.obj = obj
        self.params = params

        # Get the chain of 3 connected bones
        self.org_bones = [bone] + connected_children_names(self.obj, bone)[:2]

        if len(self.org_bones) != 3:
            raise MetarigError(
                "RIGIFY ERROR: Bone '%s': input to rig type must be a chain of 3 bones"
                % (strip_org(bone)))

        # Get (optional) parent
        if self.obj.data.bones[bone].parent is None:
            self.org_parent = None
        else:
            self.org_parent = self.obj.data.bones[bone].parent.name

        # Get the rig parameters
        if "layers" in params:
            self.layers = get_layers(params["layers"])
        else:
            self.layers = None

        self.primary_rotation_axis = params.primary_rotation_axis
Ejemplo n.º 10
0
    def __init__(self, obj, bone, params, ikfk_switch=False):
        """ Gather and validate data about the rig.
            Store any data or references to data that will be needed later on.
            In particular, store references to bones that will be needed, and
            store names of bones that will be needed.
            Do NOT change any data in the scene.  This is a gathering phase only.

            ikfk_switch: if True, create an ik/fk switch slider
        """
        self.obj = obj
        self.params = params
        self.switch = ikfk_switch

        # Get the chain of 3 connected bones
        self.org_bones = [bone] + connected_children_names(self.obj, bone)[:2]

        if len(self.org_bones) != 3:
            raise MetarigError("RIGIFY ERROR: Bone '%s': input to rig type must be a chain of 3 bones" % (strip_org(bone)))

        # Get the rig parameters
        if params.separate_ik_layers:
            self.layers = list(params.ik_layers)
        else:
            self.layers = None

        self.bend_hint = params.bend_hint

        self.primary_rotation_axis = params.primary_rotation_axis
Ejemplo n.º 11
0
    def __init__(self, obj, bone, params, ikfk_switch=False):
        """ Gather and validate data about the rig.
            Store any data or references to data that will be needed later on.
            In particular, store references to bones that will be needed, and
            store names of bones that will be needed.
            Do NOT change any data in the scene.  This is a gathering phase only.

            ikfk_switch: if True, create an ik/fk switch slider
        """
        self.obj = obj
        self.params = params

        # Get the chain of 3 connected bones
        self.org_bones = [bone] + connected_children_names(self.obj, bone)[:2]
        if len(self.org_bones) != 3:
            raise MetarigError(
                "RIGIFY ERROR: Bone '%s': input to rig type must be a chain of 3 bones"
                % (strip_org(bone)))

        # Get the rig parameters
        if params.separate_ik_layers:
            layers = list(params.ik_layers)
        else:
            layers = None
        bend_hint = params.bend_hint
        primary_rotation_axis = params.primary_rotation_axis_cessen
        pole_target_base_name = self.params.elbow_base_name + "_target"

        # Arm is based on common limb
        self.ik_limb = limb_common.IKLimb(obj, self.org_bones[0],
                                          self.org_bones[1], self.org_bones[2],
                                          None, pole_target_base_name,
                                          primary_rotation_axis, bend_hint,
                                          layers, ikfk_switch)
Ejemplo n.º 12
0
    def __init__(self, obj, bone, params):
        self.obj = obj
        self.params = params

        # Get the chain of 3 connected bones
        self.org_bones = [bone] + connected_children_names(self.obj, bone)[:2]

        if len(self.org_bones) != 3:
            raise MetarigError(
                "RIGIFY ERROR: Bone '%s': input to rig type must be a chain of 3 bones"
                % (strip_org(bone)))

        # Get rig parameters
        if params.separate_hose_layers:
            layers = list(params.hose_layers)
        else:
            layers = None
        use_complex_rig = params.use_complex_arm
        elbow_base_name = params.elbow_base_name
        primary_rotation_axis = params.primary_rotation_axis_cessen

        # Based on common limb
        self.rubber_hose_limb = limb_common.RubberHoseLimb(
            obj, self.org_bones[0], self.org_bones[1], self.org_bones[2],
            use_complex_rig, elbow_base_name, primary_rotation_axis, layers)
Ejemplo n.º 13
0
    def __init__(self, obj, bone, params):
        """ Gather and validate data about the rig.
            Store any data or references to data that will be needed later on.
            In particular, store references to bones that will be needed.
            Do NOT change any data in the scene.  This is a gathering phase only.

        """
        bb = obj.data.bones

        if bb[bone].children is None:
            raise MetarigError("RIGIFY ERROR: bone '%s': rig type requires one child" % org_name(bone.name))
        if bb[bone].use_connect == True:
            raise MetarigError("RIGIFY ERROR: bone '%s': rig type cannot be connected to parent" % org_name(bone.name))

        self.obj = obj
        self.org_bones = {"delta": bone, "child": bb[bone].children[0].name}
        self.org_names = [org_name(bone), org_name(bb[bone].children[0].name)]
Ejemplo n.º 14
0
    def __init__(self, obj, bone_name, params):
        """ Gather and validate data about the rig.
        """
        self.obj = obj
        self.org_bones = [bone_name] + connected_children_names(obj, bone_name)
        self.params = params
        self.make_controls = params.make_controls
        self.make_deforms = params.make_deforms

        if len(self.org_bones) <= 1:
            raise MetarigError("RIGIFY ERROR: Bone '%s': input to rig type must be a chain of 2 or more bones" % (strip_org(bone_name)))
Ejemplo n.º 15
0
    def get_eyelids(self):
        """
        Returns the main bones of the lids chain
        :return:
        """

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

        lid_bones = []
        for child in edit_bones[self.bones['org'][0]].children:
            if not child.use_connect:
                lid_bones.append(child.name)

        # Rule check
        if len(lid_bones) != 2:
            raise MetarigError(
                "Exactly 2 disconnected chains (lids) must be parented to main bone"
            )

        eyelids_bones_dict = {'top': [], 'bottom': []}
        self.lid_len = len(self.get_chain_bones(lid_bones[0]))

        # Check both have same length
        for lid in lid_bones:
            if len(self.get_chain_bones(lid)) != self.lid_len:
                raise MetarigError("All lid chains must be the same length")

        if edit_bones[lid_bones[0]].tail.z < edit_bones[lid_bones[1]].tail.z:
            eyelids_bones_dict['top'].append(lid_bones[1])
            eyelids_bones_dict['bottom'].append(lid_bones[0])
        else:
            eyelids_bones_dict['top'].append(lid_bones[0])
            eyelids_bones_dict['bottom'].append(lid_bones[1])

        if not (len(eyelids_bones_dict['top']) == len(
                eyelids_bones_dict['bottom']) == 1):
            raise MetarigError("Badly drawn eyelids on %s" %
                               self.bones['org'][0])

        return eyelids_bones_dict
Ejemplo n.º 16
0
    def get_mouth(self):
        """
        Returns the mouth bones placeholders
        :return:
        """

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

        lip_bones = []
        for child in edit_bones[self.bones['org'][0]].children:
            if not child.use_connect:
                lip_bones.append(child.name)

        # Rule check
        if len(lip_bones) != 4:
            raise MetarigError("Exactly 4 disconnected placeholder bones (lip angles) must be parented to main bone")

        mouth_bones_dict = {'top': [], 'corners': [], 'bottom': []}

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

        for b in lip_bones:
            if pose_bones[b].rigify_parameters.bone_type == 'lip.T':
                mouth_bones_dict['top'].append(b)
            if pose_bones[b].rigify_parameters.bone_type == 'lip.B':
                mouth_bones_dict['bottom'].append(b)
            elif pose_bones[b].rigify_parameters.bone_type == 'lip.L' or\
                    pose_bones[b].rigify_parameters.bone_type == 'lip.R':
                mouth_bones_dict['corners'].append(b)

        if not len(mouth_bones_dict['top']) == 1 \
                or not len(mouth_bones_dict['bottom']) == 1\
                or not len(mouth_bones_dict['corners']) == 2:
            raise MetarigError("Exactly 4 bones w property rigify_parameters.bone_type = lip.X (T,B,L,R) must be parented to main bone")


        return mouth_bones_dict
Ejemplo n.º 17
0
    def __init__(self, obj, bone_name, params):
        """ Gather and validate data about the rig.

        """
        self.obj = obj
        self.org_bones = [bone_name] + connected_children_names(obj, bone_name)
        self.params = params

        if len(self.org_bones) <= 1:
            raise MetarigError("RIGIFY ERROR: Bone '%s': input to rig type must be a chain of 2 or more bones" % (strip_org(bone_name)))

        self.isolate = False
        if self.obj.data.bones[bone_name].parent:
            self.isolate = True
Ejemplo n.º 18
0
    def __init__(self, obj, bone_name, params):
        self.obj = obj
        self.params = params

        bones = self.obj.data.bones

        self.org_bone = bone_name
        if bones[bone_name].parent is not None:
            self.org_parent = bones[bone_name].parent.name
        else:
            self.org_parent = None
        if bones[bone_name].use_connect:
            raise MetarigError(
                "RIGIFY ERROR: Bone %s should not be connected. "
                "Check bone chain for multiple pantin.simple rigs" %
                (strip_org(self.org_parent)))
Ejemplo n.º 19
0
    def __init__(self, obj, bone_name, params):
        self.obj = obj
        self.params = params

        eb = self.obj.data.edit_bones

        self.org_bones = [bone_name] + connected_children_names(
            self.obj, bone_name)
        if eb[bone_name].parent is not None:
            self.org_parent = eb[bone_name].parent.name
        else:
            self.org_parent = None
        if eb[bone_name].use_connect:
            raise MetarigError(
                "RIGIFY ERROR: Bone %s should not be connected. "
                "Check bone chain for multiple pantin.simple rigs" %
                (strip_org(self.org_parent)))
        if self.params.chain_type == 'Dynamic' and len(self.org_bones) > 1:
            self.params.chain_type = "Curve"
Ejemplo n.º 20
0
    def __init__(self, obj, bone, params):
        """ Gather and validate data about the rig.
        """
        self.obj = obj
        self.org_bones = [bone] + connected_children_names(obj, bone)
        self.params = params

        if len(self.org_bones) <= 1:
            raise MetarigError("RIGIFY ERROR: Bone '%s': input to rig type must be a chain of 2 or more bones" % (strip_org(bone)))

        # Get user-specified layers, if they exist
        if params.separate_extra_layers:
            self.ex_layers = list(params.extra_layers)
        else:
            self.ex_layers = None

        # Get other rig parameters
        self.primary_rotation_axis = params.primary_rotation_axis
        self.use_digit_twist = params.use_digit_twist
Ejemplo n.º 21
0
    def __init__(self, obj, bone, params):
        """ Gather and validate data about the rig.
        """
        self.obj = obj
        self.params = params

        siblings = bone_siblings(obj, bone)

        if len(siblings) == 0:
            raise MetarigError("RIGIFY ERROR: Bone '%s': must have a parent and at least one sibling" % (strip_org(bone)))

        # Sort list by name and distance
        siblings.sort()
        siblings.sort(key=lambda b: bone_distance(obj, bone, b))

        self.org_bones = [bone] + siblings

        # Get rig parameters
        self.palm_rotation_axis = params.palm_rotation_axis
Ejemplo n.º 22
0
    def __init__(self, obj, bone, params):
        """ Gather and validate data about the rig.
            Store any data or references to data that will be needed later on.
            In particular, store references to bones that will be needed, and
            store names of bones that will be needed.
            Do NOT change any data in the scene.  This is a gathering phase only.

        """
        self.obj = obj
        self.params = params

        # Get the chain of 3 connected bones
        self.org_bones = [bone] + connected_children_names(self.obj, bone)[:2]

        if len(self.org_bones) != 3:
            raise MetarigError(
                "RIGIFY ERROR: Bone '%s': input to rig type must be a chain of 3 bones"
                % (strip_org(bone)))

        # Get rig parameters
        self.use_upper_arm_twist = params.use_upper_arm_twist
        self.use_forearm_twist = params.use_forearm_twist
Ejemplo n.º 23
0
    def get_subchains(self, name, exclude=None):
        """

        :param name:
        :type name: parent chain bone name
        :parameter exclude: list of subchains to exclude
        :return:
        """

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

        if exclude is None:
            exclude = []

        subchains = []

        chain = self.get_chain_object_by_name(name)

        for bone in edit_bones[name].children:
            if self.obj.pose.bones[
                    bone.
                    name].rigify_type == "" and not bone.use_connect and bone.name not in exclude:
                subchain = Chain(self.obj,
                                 bone.name,
                                 self.orientation_bone,
                                 chain_type=chain.chain_type,
                                 parent=chain)
                if subchain.length != chain.length:
                    raise MetarigError(
                        "Subchains of chain starting with %s are not the same length! assign a rig_type/"
                        "unconnected children of main bone of chain" % name)
                else:
                    subchains.append(bone.name)
                    self.chain_objects[subchain.base_name] = subchain

        return subchains
Ejemplo n.º 24
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,
        }
Ejemplo n.º 25
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,
        }