Changeset View
Changeset View
Standalone View
Standalone View
rigify/utils/rig.py
| Show First 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | outdated_types = {"pitchipoy.limbs.super_limb": "limbs.super_limb", | ||||
| "biped.arm": "", | "biped.arm": "", | ||||
| "biped.leg": "", | "biped.leg": "", | ||||
| "finger": "", | "finger": "", | ||||
| "neck_short": "", | "neck_short": "", | ||||
| "misc.delta": "", | "misc.delta": "", | ||||
| "spine": "" | "spine": "" | ||||
| } | } | ||||
| def get_rigify_type(pose_bone): | |||||
| return pose_bone.rigify_type.replace(" ", "") | |||||
| def is_rig_base_bone(obj, name): | |||||
| return bool(get_rigify_type(obj.pose.bones[name])) | |||||
| def upgradeMetarigTypes(metarig, revert=False): | def upgradeMetarigTypes(metarig, revert=False): | ||||
| """Replaces rigify_type properties from old versions with their current names | """Replaces rigify_type properties from old versions with their current names | ||||
| :param revert: revert types to previous version (if old type available) | :param revert: revert types to previous version (if old type available) | ||||
| """ | """ | ||||
| if revert: | if revert: | ||||
| vals = list(outdated_types.values()) | vals = list(outdated_types.values()) | ||||
| Show All 23 Lines | def get_resource(resource_name): | ||||
| """ Fetches a rig module by name, and returns it. | """ Fetches a rig module by name, and returns it. | ||||
| """ | """ | ||||
| module = importlib.import_module(resource_name) | module = importlib.import_module(resource_name) | ||||
| importlib.reload(module) | importlib.reload(module) | ||||
| return module | return module | ||||
| def attach_persistent_script(obj, script): | |||||
| """Make sure the ui script always follows the rig around""" | |||||
| skip = False | |||||
| driver = None | |||||
| if not obj.animation_data: | |||||
| obj.animation_data_create() | |||||
| for fcurve in obj.animation_data.drivers: | |||||
| if fcurve.data_path == 'pass_index': | |||||
| driver = fcurve.driver | |||||
| for variable in driver.variables: | |||||
| if variable.name == script.name: | |||||
| skip = True | |||||
| break | |||||
| break | |||||
| if not skip: | |||||
| if not driver: | |||||
| fcurve = obj.driver_add("pass_index") | |||||
| driver = fcurve.driver | |||||
| variable = driver.variables.new() | |||||
| variable.name = script.name | |||||
| variable.targets[0].id_type = 'TEXT' | |||||
| variable.targets[0].id = script | |||||
| def connected_children_names(obj, bone_name): | def connected_children_names(obj, bone_name): | ||||
| """ Returns a list of bone names (in order) of the bones that form a single | """ Returns a list of bone names (in order) of the bones that form a single | ||||
| connected chain starting with the given bone as a parent. | connected chain starting with the given bone as a parent. | ||||
| If there is a connected branch, the list stops there. | If there is a connected branch, the list stops there. | ||||
| """ | """ | ||||
| bone = obj.data.bones[bone_name] | bone = obj.data.bones[bone_name] | ||||
| names = [] | names = [] | ||||
| Show All 19 Lines | def has_connected_children(bone): | ||||
| """ Returns true/false whether a bone has connected children or not. | """ Returns true/false whether a bone has connected children or not. | ||||
| """ | """ | ||||
| t = False | t = False | ||||
| for b in bone.children: | for b in bone.children: | ||||
| t = t or b.use_connect | t = t or b.use_connect | ||||
| return t | return t | ||||
| def _list_bone_names_depth_first_sorted_rec(result_list, bone): | |||||
| result_list.append(bone.name) | |||||
| for child in sorted(list(bone.children), key=lambda b: b.name): | |||||
| _list_bone_names_depth_first_sorted_rec(result_list, child) | |||||
| def list_bone_names_depth_first_sorted(obj): | |||||
| """Returns a list of bone names in depth first name sorted order.""" | |||||
| result_list = [] | |||||
| for bone in sorted(list(obj.data.bones), key=lambda b: b.name): | |||||
| if bone.parent is None: | |||||
| _list_bone_names_depth_first_sorted_rec(result_list, bone) | |||||
| return result_list | |||||
| def write_metarig(obj, layers=False, func_name="create", groups=False): | def write_metarig(obj, layers=False, func_name="create", groups=False): | ||||
| """ | """ | ||||
| Write a metarig as a python script, this rig is to have all info needed for | Write a metarig as a python script, this rig is to have all info needed for | ||||
| generating the real rig with rigify. | generating the real rig with rigify. | ||||
| """ | """ | ||||
| code = [] | code = [] | ||||
| code.append("import bpy\n\n") | code.append("import bpy\n\n") | ||||
| ▲ Show 20 Lines • Show All 108 Lines • ▼ Show 20 Lines | if layers: | ||||
| for i in range(len(bone.layers)): | for i in range(len(bone.layers)): | ||||
| if bone.layers[i]: | if bone.layers[i]: | ||||
| if i not in active_layers: | if i not in active_layers: | ||||
| active_layers.append(i) | active_layers.append(i) | ||||
| active_layers.sort() | active_layers.sort() | ||||
| code.append("\n arm.layers = [(x in " + str(active_layers) + ") for x in range(" + str(len(arm.layers)) + ")]") | code.append("\n arm.layers = [(x in " + str(active_layers) + ") for x in range(" + str(len(arm.layers)) + ")]") | ||||
| code.append("\n return bones") | |||||
| code.append('\nif __name__ == "__main__":') | code.append('\nif __name__ == "__main__":') | ||||
| code.append(" " + func_name + "(bpy.context.active_object)\n") | code.append(" " + func_name + "(bpy.context.active_object)\n") | ||||
| return "\n".join(code) | return "\n".join(code) | ||||