diff options
Diffstat (limited to 'rigify/utils.py')
-rw-r--r-- | rigify/utils.py | 1302 |
1 files changed, 0 insertions, 1302 deletions
diff --git a/rigify/utils.py b/rigify/utils.py deleted file mode 100644 index 73b64112..00000000 --- a/rigify/utils.py +++ /dev/null @@ -1,1302 +0,0 @@ -#====================== BEGIN GPL LICENSE BLOCK ====================== -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -#======================= END GPL LICENSE BLOCK ======================== - -# <pep8 compliant> - -import bpy -import imp -import importlib -import math -import random -import time -import re -import os -from mathutils import Vector, Matrix, Color -from rna_prop_ui import rna_idprop_ui_prop_get - -RIG_DIR = "rigs" # Name of the directory where rig types are kept -METARIG_DIR = "metarigs" # Name of the directory where metarigs are kept - -ORG_PREFIX = "ORG-" # Prefix of original bones. -MCH_PREFIX = "MCH-" # Prefix of mechanism bones. -DEF_PREFIX = "DEF-" # Prefix of deformation bones. -WGT_PREFIX = "WGT-" # Prefix for widget objects -ROOT_NAME = "root" # Name of the root bone. - -MODULE_NAME = "rigify" # Windows/Mac blender is weird, so __package__ doesn't work - -outdated_types = {"pitchipoy.limbs.super_limb": "limbs.super_limb", - "pitchipoy.limbs.super_arm": "limbs.super_limb", - "pitchipoy.limbs.super_leg": "limbs.super_limb", - "pitchipoy.limbs.super_front_paw": "limbs.super_limb", - "pitchipoy.limbs.super_rear_paw": "limbs.super_limb", - "pitchipoy.limbs.super_finger": "limbs.super_finger", - "pitchipoy.super_torso_turbo": "spines.super_spine", - "pitchipoy.simple_tentacle": "limbs.simple_tentacle", - "pitchipoy.super_face": "faces.super_face", - "pitchipoy.super_palm": "limbs.super_palm", - "pitchipoy.super_copy": "basic.super_copy", - "pitchipoy.tentacle": "", - "palm": "limbs.super_palm", - "basic.copy": "basic.super_copy", - "biped.arm": "", - "biped.leg": "", - "finger": "", - "neck_short": "", - "misc.delta": "", - "spine": "" - } - -#======================================================================= -# Error handling -#======================================================================= -class MetarigError(Exception): - """ Exception raised for errors. - """ - def __init__(self, message): - self.message = message - - def __str__(self): - return repr(self.message) - - -#======================================================================= -# Name manipulation -#======================================================================= - -def strip_trailing_number(s): - m = re.search(r'\.(\d{3})$', s) - return s[0:-4] if m else s - - -def unique_name(collection, base_name): - base_name = strip_trailing_number(base_name) - count = 1 - name = base_name - - while collection.get(name): - name = "%s.%03d" % (base_name, count) - count += 1 - return name - - -def org_name(name): - """ Returns the name with ORG_PREFIX stripped from it. - """ - if name.startswith(ORG_PREFIX): - return name[len(ORG_PREFIX):] - else: - return name - - -def strip_org(name): - """ Returns the name with ORG_PREFIX stripped from it. - """ - if name.startswith(ORG_PREFIX): - return name[len(ORG_PREFIX):] - else: - return name -org_name = strip_org - - -def strip_mch(name): - """ Returns the name with ORG_PREFIX stripped from it. - """ - if name.startswith(MCH_PREFIX): - return name[len(MCH_PREFIX):] - else: - return name - -def org(name): - """ Prepends the ORG_PREFIX to a name if it doesn't already have - it, and returns it. - """ - if name.startswith(ORG_PREFIX): - return name - else: - return ORG_PREFIX + name -make_original_name = org - - -def mch(name): - """ Prepends the MCH_PREFIX to a name if it doesn't already have - it, and returns it. - """ - if name.startswith(MCH_PREFIX): - return name - else: - return MCH_PREFIX + name -make_mechanism_name = mch - - -def deformer(name): - """ Prepends the DEF_PREFIX to a name if it doesn't already have - it, and returns it. - """ - if name.startswith(DEF_PREFIX): - return name - else: - return DEF_PREFIX + name -make_deformer_name = deformer - - -def insert_before_lr(name, text): - if name[-1] in ['l', 'L', 'r', 'R'] and name[-2] in ['.', '-', '_']: - return name[:-2] + text + name[-2:] - else: - return name + text - - -def upgradeMetarigTypes(metarig, revert=False): - """Replaces rigify_type properties from old versions with their current names - - :param revert: revert types to previous version (if old type available) - """ - - if revert: - vals = list(outdated_types.values()) - rig_defs = {v: k for k, v in outdated_types.items() if vals.count(v) == 1} - else: - rig_defs = outdated_types - - for bone in metarig.pose.bones: - rig_type = bone.rigify_type - if rig_type in rig_defs: - bone.rigify_type = rig_defs[rig_type] - if 'leg' in rig_type: - bone.rigfy_parameters.limb_type = 'leg' - if 'arm' in rig_type: - bone.rigfy_parameters.limb_type = 'arm' - if 'paw' in rig_type: - bone.rigfy_parameters.limb_type = 'paw' - if rig_type == "basic.copy": - bone.rigify_parameters.make_widget = False - - - -#======================= -# Bone manipulation -#======================= - -def new_bone(obj, bone_name): - """ Adds a new bone to the given armature object. - Returns the resulting bone's name. - """ - if obj == bpy.context.active_object and bpy.context.mode == 'EDIT_ARMATURE': - edit_bone = obj.data.edit_bones.new(bone_name) - name = edit_bone.name - edit_bone.head = (0, 0, 0) - edit_bone.tail = (0, 1, 0) - edit_bone.roll = 0 - bpy.ops.object.mode_set(mode='OBJECT') - bpy.ops.object.mode_set(mode='EDIT') - return name - else: - raise MetarigError("Can't add new bone '%s' outside of edit mode" % bone_name) - - -def copy_bone_simple(obj, bone_name, assign_name=''): - """ Makes a copy of the given bone in the given armature object. - but only copies head, tail positions and roll. Does not - address parenting either. - """ - #if bone_name not in obj.data.bones: - if bone_name not in obj.data.edit_bones: - raise MetarigError("copy_bone(): bone '%s' not found, cannot copy it" % bone_name) - - if obj == bpy.context.active_object and bpy.context.mode == 'EDIT_ARMATURE': - if assign_name == '': - assign_name = bone_name - # Copy the edit bone - edit_bone_1 = obj.data.edit_bones[bone_name] - edit_bone_2 = obj.data.edit_bones.new(assign_name) - bone_name_1 = bone_name - bone_name_2 = edit_bone_2.name - - # Copy edit bone attributes - edit_bone_2.layers = list(edit_bone_1.layers) - - edit_bone_2.head = Vector(edit_bone_1.head) - edit_bone_2.tail = Vector(edit_bone_1.tail) - edit_bone_2.roll = edit_bone_1.roll - - return bone_name_2 - else: - raise MetarigError("Cannot copy bones outside of edit mode") - - -def copy_bone(obj, bone_name, assign_name=''): - """ Makes a copy of the given bone in the given armature object. - Returns the resulting bone's name. - """ - #if bone_name not in obj.data.bones: - if bone_name not in obj.data.edit_bones: - raise MetarigError("copy_bone(): bone '%s' not found, cannot copy it" % bone_name) - - if obj == bpy.context.active_object and bpy.context.mode == 'EDIT_ARMATURE': - if assign_name == '': - assign_name = bone_name - # Copy the edit bone - edit_bone_1 = obj.data.edit_bones[bone_name] - edit_bone_2 = obj.data.edit_bones.new(assign_name) - bone_name_1 = bone_name - bone_name_2 = edit_bone_2.name - - edit_bone_2.parent = edit_bone_1.parent - edit_bone_2.use_connect = edit_bone_1.use_connect - - # Copy edit bone attributes - edit_bone_2.layers = list(edit_bone_1.layers) - - edit_bone_2.head = Vector(edit_bone_1.head) - edit_bone_2.tail = Vector(edit_bone_1.tail) - edit_bone_2.roll = edit_bone_1.roll - - edit_bone_2.use_inherit_rotation = edit_bone_1.use_inherit_rotation - edit_bone_2.use_inherit_scale = edit_bone_1.use_inherit_scale - edit_bone_2.use_local_location = edit_bone_1.use_local_location - - edit_bone_2.use_deform = edit_bone_1.use_deform - edit_bone_2.bbone_segments = edit_bone_1.bbone_segments - edit_bone_2.bbone_easein = edit_bone_1.bbone_easein - edit_bone_2.bbone_easeout = edit_bone_1.bbone_easeout - - bpy.ops.object.mode_set(mode='OBJECT') - - # Get the pose bones - pose_bone_1 = obj.pose.bones[bone_name_1] - pose_bone_2 = obj.pose.bones[bone_name_2] - - # Copy pose bone attributes - pose_bone_2.rotation_mode = pose_bone_1.rotation_mode - pose_bone_2.rotation_axis_angle = tuple(pose_bone_1.rotation_axis_angle) - pose_bone_2.rotation_euler = tuple(pose_bone_1.rotation_euler) - pose_bone_2.rotation_quaternion = tuple(pose_bone_1.rotation_quaternion) - - pose_bone_2.lock_location = tuple(pose_bone_1.lock_location) - pose_bone_2.lock_scale = tuple(pose_bone_1.lock_scale) - pose_bone_2.lock_rotation = tuple(pose_bone_1.lock_rotation) - pose_bone_2.lock_rotation_w = pose_bone_1.lock_rotation_w - pose_bone_2.lock_rotations_4d = pose_bone_1.lock_rotations_4d - - # Copy custom properties - for key in pose_bone_1.keys(): - if key != "_RNA_UI" \ - and key != "rigify_parameters" \ - and key != "rigify_type": - prop1 = rna_idprop_ui_prop_get(pose_bone_1, key, create=False) - prop2 = rna_idprop_ui_prop_get(pose_bone_2, key, create=True) - pose_bone_2[key] = pose_bone_1[key] - for key in prop1.keys(): - prop2[key] = prop1[key] - - bpy.ops.object.mode_set(mode='EDIT') - - return bone_name_2 - else: - raise MetarigError("Cannot copy bones outside of edit mode") - - -def flip_bone(obj, bone_name): - """ Flips an edit bone. - """ - if bone_name not in obj.data.bones: - raise MetarigError("flip_bone(): bone '%s' not found, cannot copy it" % bone_name) - - if obj == bpy.context.active_object and bpy.context.mode == 'EDIT_ARMATURE': - bone = obj.data.edit_bones[bone_name] - head = Vector(bone.head) - tail = Vector(bone.tail) - bone.tail = head + tail - bone.head = tail - bone.tail = head - else: - raise MetarigError("Cannot flip bones outside of edit mode") - - -def put_bone(obj, bone_name, pos): - """ Places a bone at the given position. - """ - if bone_name not in obj.data.bones: - raise MetarigError("put_bone(): bone '%s' not found, cannot move it" % bone_name) - - if obj == bpy.context.active_object and bpy.context.mode == 'EDIT_ARMATURE': - bone = obj.data.edit_bones[bone_name] - - delta = pos - bone.head - bone.translate(delta) - else: - raise MetarigError("Cannot 'put' bones outside of edit mode") - - -def make_nonscaling_child(obj, bone_name, location, child_name_postfix=""): - """ Takes the named bone and creates a non-scaling child of it at - the given location. The returned bone (returned by name) is not - a true child, but behaves like one sans inheriting scaling. - - It is intended as an intermediate construction to prevent rig types - from scaling with their parents. The named bone is assumed to be - an ORG bone. - """ - if bone_name not in obj.data.bones: - raise MetarigError("make_nonscaling_child(): bone '%s' not found, cannot copy it" % bone_name) - - if obj == bpy.context.active_object and bpy.context.mode == 'EDIT_ARMATURE': - # Create desired names for bones - name1 = make_mechanism_name(strip_org(insert_before_lr(bone_name, child_name_postfix + "_ns_ch"))) - name2 = make_mechanism_name(strip_org(insert_before_lr(bone_name, child_name_postfix + "_ns_intr"))) - - # Create bones - child = copy_bone(obj, bone_name, name1) - intermediate_parent = copy_bone(obj, bone_name, name2) - - # Get edit bones - eb = obj.data.edit_bones - child_e = eb[child] - intrpar_e = eb[intermediate_parent] - - # Parenting - child_e.use_connect = False - child_e.parent = None - - intrpar_e.use_connect = False - intrpar_e.parent = eb[bone_name] - - # Positioning - child_e.length *= 0.5 - intrpar_e.length *= 0.25 - - put_bone(obj, child, location) - put_bone(obj, intermediate_parent, location) - - # Object mode - bpy.ops.object.mode_set(mode='OBJECT') - pb = obj.pose.bones - - # Add constraints - con = pb[child].constraints.new('COPY_LOCATION') - con.name = "parent_loc" - con.target = obj - con.subtarget = intermediate_parent - - con = pb[child].constraints.new('COPY_ROTATION') - con.name = "parent_loc" - con.target = obj - con.subtarget = intermediate_parent - - bpy.ops.object.mode_set(mode='EDIT') - - return child - else: - raise MetarigError("Cannot make nonscaling child outside of edit mode") - - -#============================================= -# Widget creation -#============================================= - -def obj_to_bone(obj, rig, bone_name): - """ Places an object at the location/rotation/scale of the given bone. - """ - if bpy.context.mode == 'EDIT_ARMATURE': - raise MetarigError("obj_to_bone(): does not work while in edit mode") - - bone = rig.data.bones[bone_name] - - mat = rig.matrix_world @ bone.matrix_local - - obj.location = mat.to_translation() - - obj.rotation_mode = 'XYZ' - obj.rotation_euler = mat.to_euler() - - scl = mat.to_scale() - scl_avg = (scl[0] + scl[1] + scl[2]) / 3 - obj.scale = (bone.length * scl_avg), (bone.length * scl_avg), (bone.length * scl_avg) - - -def create_widget(rig, bone_name, bone_transform_name=None): - """ Creates an empty widget object for a bone, and returns the object. - """ - if bone_transform_name is None: - bone_transform_name = bone_name - - obj_name = WGT_PREFIX + rig.name + '_' + bone_name - scene = bpy.context.scene - collection = bpy.context.collection - id_store = bpy.context.window_manager - - # Check if it already exists in the scene - if obj_name in scene.objects: - # Move object to bone position, in case it changed - obj = scene.objects[obj_name] - obj_to_bone(obj, rig, bone_transform_name) - - return None - else: - # Delete object if it exists in blend data but not scene data. - # This is necessary so we can then create the object without - # name conflicts. - if obj_name in bpy.data.objects: - bpy.data.objects[obj_name].user_clear() - bpy.data.objects.remove(bpy.data.objects[obj_name]) - - # Create mesh object - mesh = bpy.data.meshes.new(obj_name) - obj = bpy.data.objects.new(obj_name, mesh) - collection.objects.link(obj) - - # Move object to bone position and set layers - obj_to_bone(obj, rig, bone_transform_name) - wgts_group_name = 'WGTS_' + rig.name - if wgts_group_name in bpy.data.objects.keys(): - obj.parent = bpy.data.objects[wgts_group_name] - - return obj - - -# Common Widgets - -def create_line_widget(rig, bone_name, bone_transform_name=None): - """ Creates a basic line widget, a line that spans the length of the bone. - """ - obj = create_widget(rig, bone_name, bone_transform_name) - if obj is not None: - mesh = obj.data - mesh.from_pydata([(0, 0, 0), (0, 1, 0)], [(0, 1)], []) - mesh.update() - - -def create_circle_widget(rig, bone_name, radius=1.0, head_tail=0.0, with_line=False, bone_transform_name=None): - """ Creates a basic circle widget, a circle around the y-axis. - radius: the radius of the circle - head_tail: where along the length of the bone the circle is (0.0=head, 1.0=tail) - """ - obj = create_widget(rig, bone_name, bone_transform_name) - if obj != None: - v = [(0.7071068286895752, 2.980232238769531e-07, -0.7071065306663513), (0.8314696550369263, 2.980232238769531e-07, -0.5555699467658997), (0.9238795042037964, 2.682209014892578e-07, -0.3826831877231598), (0.9807852506637573, 2.5331974029541016e-07, -0.19509011507034302), (1.0, 2.365559055306221e-07, 1.6105803979371558e-07), (0.9807853698730469, 2.2351741790771484e-07, 0.19509044289588928), (0.9238796234130859, 2.086162567138672e-07, 0.38268351554870605), (0.8314696550369263, 1.7881393432617188e-07, 0.5555704236030579), (0.7071068286895752, 1.7881393432617188e-07, 0.7071070075035095), (0.5555702447891235, 1.7881393432617188e-07, 0.8314698934555054), (0.38268327713012695, 1.7881393432617188e-07, 0.923879861831665), (0.19509008526802063, 1.7881393432617188e-07, 0.9807855486869812), (-3.2584136988589307e-07, 1.1920928955078125e-07, 1.000000238418579), (-0.19509072601795197, 1.7881393432617188e-07, 0.9807854294776917), (-0.3826838731765747, 1.7881393432617188e-07, 0.9238795638084412), (-0.5555707216262817, 1.7881393432617188e-07, 0.8314695358276367), (-0.7071071863174438, 1.7881393432617188e-07, 0.7071065902709961), (-0.8314700126647949, 1.7881393432617188e-07, 0.5555698871612549), (-0.923879861831665, 2.086162567138672e-07, 0.3826829195022583), (-0.9807853698730469, 2.2351741790771484e-07, 0.1950896978378296), (-1.0, 2.365559907957504e-07, -7.290432222362142e-07), (-0.9807850122451782, 2.5331974029541016e-07, -0.195091113448143), (-0.9238790273666382, 2.682209014892578e-07, -0.38268423080444336), (-0.831468939781189, 2.980232238769531e-07, -0.5555710196495056), (-0.7071058750152588, 2.980232238769531e-07, -0.707107424736023), (-0.555569052696228, 2.980232238769531e-07, -0.8314701318740845), (-0.38268208503723145, 2.980232238769531e-07, -0.923879861831665), (-0.19508881866931915, 2.980232238769531e-07, -0.9807853102684021), (1.6053570561780361e-06, 2.980232238769531e-07, -0.9999997615814209), (0.19509197771549225, 2.980232238769531e-07, -0.9807847142219543), (0.3826850652694702, 2.980232238769531e-07, -0.9238786101341248), (0.5555717945098877, 2.980232238769531e-07, -0.8314683437347412)] - verts = [(a[0] * radius, head_tail, a[2] * radius) for a in v] - if with_line: - edges = [(28, 12), (0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9), (9, 10), (10, 11), (11, 12), (12, 13), (13, 14), (14, 15), (15, 16), (16, 17), (17, 18), (18, 19), (19, 20), (20, 21), (21, 22), (22, 23), (23, 24), (24, 25), (25, 26), (26, 27), (27, 28), (28, 29), (29, 30), (30, 31), (0, 31)] - else: - edges = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9), (9, 10), (10, 11), (11, 12), (12, 13), (13, 14), (14, 15), (15, 16), (16, 17), (17, 18), (18, 19), (19, 20), (20, 21), (21, 22), (22, 23), (23, 24), (24, 25), (25, 26), (26, 27), (27, 28), (28, 29), (29, 30), (30, 31), (0, 31)] - mesh = obj.data - mesh.from_pydata(verts, edges, []) - mesh.update() - return obj - else: - return None - - -def create_cube_widget(rig, bone_name, radius=0.5, bone_transform_name=None): - """ Creates a basic cube widget. - """ - obj = create_widget(rig, bone_name, bone_transform_name) - if obj is not None: - r = radius - verts = [(r, r, r), (r, -r, r), (-r, -r, r), (-r, r, r), (r, r, -r), (r, -r, -r), (-r, -r, -r), (-r, r, -r)] - edges = [(0, 1), (1, 2), (2, 3), (3, 0), (4, 5), (5, 6), (6, 7), (7, 4), (0, 4), (1, 5), (2, 6), (3, 7)] - mesh = obj.data - mesh.from_pydata(verts, edges, []) - mesh.update() - - -def create_chain_widget(rig, bone_name, radius=0.5, invert=False, bone_transform_name=None): - """Creates a basic chain widget - """ - obj = create_widget(rig, bone_name, bone_transform_name) - if obj != None: - r = radius - rh = radius/2 - if invert: - verts = [(rh, rh, rh), (r, -r, r), (-r, -r, r), (-rh, rh, rh), (rh, rh, -rh), (r, -r, -r), (-r, -r, -r), (-rh, rh, -rh)] - else: - verts = [(r, r, r), (rh, -rh, rh), (-rh, -rh, rh), (-r, r, r), (r, r, -r), (rh, -rh, -rh), (-rh, -rh, -rh), (-r, r, -r)] - edges = [(0, 1), (1, 2), (2, 3), (3, 0), (4, 5), (5, 6), (6, 7), (7, 4), (0, 4), (1, 5), (2, 6), (3, 7)] - mesh = obj.data - mesh.from_pydata(verts, edges, []) - mesh.update() - - -def create_sphere_widget(rig, bone_name, bone_transform_name=None): - """ Creates a basic sphere widget, three pependicular overlapping circles. - """ - obj = create_widget(rig, bone_name, bone_transform_name) - if obj != None: - verts = [(0.3535533845424652, 0.3535533845424652, 0.0), (0.4619397521018982, 0.19134171307086945, 0.0), (0.5, -2.1855694143368964e-08, 0.0), (0.4619397521018982, -0.19134175777435303, 0.0), (0.3535533845424652, -0.3535533845424652, 0.0), (0.19134174287319183, -0.4619397521018982, 0.0), (7.549790126404332e-08, -0.5, 0.0), (-0.1913416087627411, -0.46193981170654297, 0.0), (-0.35355329513549805, -0.35355350375175476, 0.0), (-0.4619397521018982, -0.19134178757667542, 0.0), (-0.5, 5.962440319251527e-09, 0.0), (-0.4619397222995758, 0.1913418024778366, 0.0), (-0.35355326533317566, 0.35355350375175476, 0.0), (-0.19134148955345154, 0.46193987131118774, 0.0), (3.2584136988589307e-07, 0.5, 0.0), (0.1913420855998993, 0.46193960309028625, 0.0), (7.450580596923828e-08, 0.46193960309028625, 0.19134199619293213), (5.9254205098113744e-08, 0.5, 2.323586443253589e-07), (4.470348358154297e-08, 0.46193987131118774, -0.1913415789604187), (2.9802322387695312e-08, 0.35355350375175476, -0.3535533547401428), (2.9802322387695312e-08, 0.19134178757667542, -0.46193981170654297), (5.960464477539063e-08, -1.1151834122813398e-08, -0.5000000596046448), (5.960464477539063e-08, -0.1913418024778366, -0.46193984150886536), (5.960464477539063e-08, -0.35355350375175476, -0.3535533845424652), (7.450580596923828e-08, -0.46193981170654297, -0.19134166836738586), (9.348272556053416e-08, -0.5, 1.624372103492533e-08), (1.043081283569336e-07, -0.4619397521018982, 0.19134168326854706), (1.1920928955078125e-07, -0.3535533845424652, 0.35355329513549805), (1.1920928955078125e-07, -0.19134174287319183, 0.46193966269493103), (1.1920928955078125e-07, -4.7414250303745575e-09, 0.49999991059303284), (1.1920928955078125e-07, 0.19134172797203064, 0.46193966269493103), (8.940696716308594e-08, 0.3535533845424652, 0.35355329513549805), (0.3535534739494324, 0.0, 0.35355329513549805), (0.1913418173789978, -2.9802322387695312e-08, 0.46193966269493103), (8.303572940349113e-08, -5.005858838558197e-08, 0.49999991059303284), (-0.19134165346622467, -5.960464477539063e-08, 0.46193966269493103), (-0.35355329513549805, -8.940696716308594e-08, 0.35355329513549805), (-0.46193963289260864, -5.960464477539063e-08, 0.19134168326854706), (-0.49999991059303284, -5.960464477539063e-08, 1.624372103492533e-08), (-0.4619397521018982, -2.9802322387695312e-08, -0.19134166836738586), (-0.3535534143447876, -2.9802322387695312e-08, -0.3535533845424652), (-0.19134171307086945, 0.0, -0.46193984150886536), (7.662531942287387e-08, 9.546055501630235e-09, -0.5000000596046448), (0.19134187698364258, 5.960464477539063e-08, -0.46193981170654297), (0.3535535931587219, 5.960464477539063e-08, -0.3535533547401428), (0.4619399905204773, 5.960464477539063e-08, -0.1913415789604187), (0.5000000596046448, 5.960464477539063e-08, 2.323586443253589e-07), (0.4619396924972534, 2.9802322387695312e-08, 0.19134199619293213)] - edges = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9), (9, 10), (10, 11), (11, 12), (12, 13), (13, 14), (14, 15), (0, 15), (16, 31), (16, 17), (17, 18), (18, 19), (19, 20), (20, 21), (21, 22), (22, 23), (23, 24), (24, 25), (25, 26), (26, 27), (27, 28), (28, 29), (29, 30), (30, 31), (32, 33), (33, 34), (34, 35), (35, 36), (36, 37), (37, 38), (38, 39), (39, 40), (40, 41), (41, 42), (42, 43), (43, 44), (44, 45), (45, 46), (46, 47), (32, 47)] - mesh = obj.data - mesh.from_pydata(verts, edges, []) - mesh.update() - - -def create_limb_widget(rig, bone_name, bone_transform_name=None): - """ Creates a basic limb widget, a line that spans the length of the - bone, with a circle around the center. - """ - obj = create_widget(rig, bone_name, bone_transform_name) - if obj != None: - verts = [(-1.1920928955078125e-07, 1.7881393432617188e-07, 0.0), (3.5762786865234375e-07, 1.0000004768371582, 0.0), (0.1767769455909729, 0.5000001192092896, 0.17677664756774902), (0.20786768198013306, 0.5000001192092896, 0.1388925313949585), (0.23097014427185059, 0.5000001192092896, 0.09567084908485413), (0.24519658088684082, 0.5000001192092896, 0.048772573471069336), (0.2500002384185791, 0.5000001192092896, -2.545945676502015e-09), (0.24519658088684082, 0.5000001192092896, -0.048772573471069336), (0.23097014427185059, 0.5000001192092896, -0.09567084908485413), (0.20786768198013306, 0.5000001192092896, -0.13889259099960327), (0.1767769455909729, 0.5000001192092896, -0.1767767071723938), (0.13889282941818237, 0.5000001192092896, -0.20786744356155396), (0.09567105770111084, 0.5000001192092896, -0.23096990585327148), (0.04877278208732605, 0.5000001192092896, -0.24519634246826172), (1.7279069197684294e-07, 0.5000000596046448, -0.25), (-0.0487724244594574, 0.5000001192092896, -0.24519634246826172), (-0.09567070007324219, 0.5000001192092896, -0.2309698462486267), (-0.13889241218566895, 0.5000001192092896, -0.20786738395690918), (-0.17677652835845947, 0.5000001192092896, -0.17677664756774902), (-0.20786726474761963, 0.5000001192092896, -0.13889244198799133), (-0.23096972703933716, 0.5000001192092896, -0.09567070007324219), (-0.24519610404968262, 0.5000001192092896, -0.04877239465713501), (-0.2499997615814209, 0.5000001192092896, 2.1997936983098043e-07), (-0.24519598484039307, 0.5000001192092896, 0.04877282679080963), (-0.23096948862075806, 0.5000001192092896, 0.09567108750343323), (-0.20786696672439575, 0.5000001192092896, 0.1388927698135376), (-0.1767762303352356, 0.5000001192092896, 0.17677688598632812), (-0.13889199495315552, 0.5000001192092896, 0.2078675627708435), (-0.09567028284072876, 0.5000001192092896, 0.23097002506256104), (-0.048771947622299194, 0.5000001192092896, 0.24519634246826172), (6.555903269145347e-07, 0.5000001192092896, 0.25), (0.04877324402332306, 0.5000001192092896, 0.24519622325897217), (0.09567153453826904, 0.5000001192092896, 0.23096966743469238), (0.13889318704605103, 0.5000001192092896, 0.20786714553833008)] - edges = [(0, 1), (2, 3), (4, 3), (5, 4), (5, 6), (6, 7), (8, 7), (8, 9), (10, 9), (10, 11), (11, 12), (13, 12), (14, 13), (14, 15), (16, 15), (16, 17), (17, 18), (19, 18), (19, 20), (21, 20), (21, 22), (22, 23), (24, 23), (25, 24), (25, 26), (27, 26), (27, 28), (29, 28), (29, 30), (30, 31), (32, 31), (32, 33), (2, 33)] - mesh = obj.data - mesh.from_pydata(verts, edges, []) - mesh.update() - - -def create_bone_widget(rig, bone_name, bone_transform_name=None): - """ Creates a basic bone widget, a simple obolisk-esk shape. - """ - obj = create_widget(rig, bone_name, bone_transform_name) - if obj != None: - verts = [(0.04, 1.0, -0.04), (0.1, 0.0, -0.1), (-0.1, 0.0, -0.1), (-0.04, 1.0, -0.04), (0.04, 1.0, 0.04), (0.1, 0.0, 0.1), (-0.1, 0.0, 0.1), (-0.04, 1.0, 0.04)] - edges = [(1, 2), (0, 1), (0, 3), (2, 3), (4, 5), (5, 6), (6, 7), (4, 7), (1, 5), (0, 4), (2, 6), (3, 7)] - mesh = obj.data - mesh.from_pydata(verts, edges, []) - mesh.update() - - -def create_compass_widget(rig, bone_name, bone_transform_name=None): - """ Creates a compass-shaped widget. - """ - obj = create_widget(rig, bone_name, bone_transform_name) - if obj != None: - verts = [(0.0, 1.2000000476837158, 0.0), (0.19509032368659973, 0.9807852506637573, 0.0), (0.3826834559440613, 0.9238795042037964, 0.0), (0.5555702447891235, 0.8314695954322815, 0.0), (0.7071067690849304, 0.7071067690849304, 0.0), (0.8314696550369263, 0.5555701851844788, 0.0), (0.9238795042037964, 0.3826834261417389, 0.0), (0.9807852506637573, 0.19509035348892212, 0.0), (1.2000000476837158, 7.549790126404332e-08, 0.0), (0.9807853102684021, -0.19509020447731018, 0.0), (0.9238795638084412, -0.38268327713012695, 0.0), (0.8314696550369263, -0.5555701851844788, 0.0), (0.7071067690849304, -0.7071067690849304, 0.0), (0.5555701851844788, -0.8314696550369263, 0.0), (0.38268327713012695, -0.9238796234130859, 0.0), (0.19509008526802063, -0.9807853102684021, 0.0), (-3.2584136988589307e-07, -1.2999999523162842, 0.0), (-0.19509072601795197, -0.9807851910591125, 0.0), (-0.3826838731765747, -0.9238793253898621, 0.0), (-0.5555707216262817, -0.8314692974090576, 0.0), (-0.7071072459220886, -0.707106351852417, 0.0), (-0.8314700126647949, -0.5555696487426758, 0.0), (-0.923879861831665, -0.3826826810836792, 0.0), (-0.9807854294776917, -0.1950894594192505, 0.0), (-1.2000000476837158, 9.655991561885457e-07, 0.0), (-0.980785071849823, 0.1950913518667221, 0.0), (-0.923879086971283, 0.38268446922302246, 0.0), (-0.831468939781189, 0.5555712580680847, 0.0), (-0.7071058750152588, 0.707107663154602, 0.0), (-0.5555691123008728, 0.8314703702926636, 0.0), (-0.38268208503723145, 0.9238801002502441, 0.0), (-0.19508881866931915, 0.9807855486869812, 0.0)] - edges = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9), (9, 10), (10, 11), (11, 12), (12, 13), (13, 14), (14, 15), (15, 16), (16, 17), (17, 18), (18, 19), (19, 20), (20, 21), (21, 22), (22, 23), (23, 24), (24, 25), (25, 26), (26, 27), (27, 28), (28, 29), (29, 30), (30, 31), (0, 31)] - mesh = obj.data - mesh.from_pydata(verts, edges, []) - mesh.update() - - -def create_root_widget(rig, bone_name, bone_transform_name=None): - """ Creates a widget for the root bone. - """ - obj = create_widget(rig, bone_name, bone_transform_name) - if obj != None: - verts = [(0.7071067690849304, 0.7071067690849304, 0.0), (0.7071067690849304, -0.7071067690849304, 0.0), (-0.7071067690849304, 0.7071067690849304, 0.0), (-0.7071067690849304, -0.7071067690849304, 0.0), (0.8314696550369263, 0.5555701851844788, 0.0), (0.8314696550369263, -0.5555701851844788, 0.0), (-0.8314696550369263, 0.5555701851844788, 0.0), (-0.8314696550369263, -0.5555701851844788, 0.0), (0.9238795042037964, 0.3826834261417389, 0.0), (0.9238795042037964, -0.3826834261417389, 0.0), (-0.9238795042037964, 0.3826834261417389, 0.0), (-0.9238795042037964, -0.3826834261417389, 0.0), (0.9807852506637573, 0.19509035348892212, 0.0), (0.9807852506637573, -0.19509035348892212, 0.0), (-0.9807852506637573, 0.19509035348892212, 0.0), (-0.9807852506637573, -0.19509035348892212, 0.0), (0.19509197771549225, 0.9807849526405334, 0.0), (0.19509197771549225, -0.9807849526405334, 0.0), (-0.19509197771549225, 0.9807849526405334, 0.0), (-0.19509197771549225, -0.9807849526405334, 0.0), (0.3826850652694702, 0.9238788485527039, 0.0), (0.3826850652694702, -0.9238788485527039, 0.0), (-0.3826850652694702, 0.9238788485527039, 0.0), (-0.3826850652694702, -0.9238788485527039, 0.0), (0.5555717945098877, 0.8314685821533203, 0.0), (0.5555717945098877, -0.8314685821533203, 0.0), (-0.5555717945098877, 0.8314685821533203, 0.0), (-0.5555717945098877, -0.8314685821533203, 0.0), (0.19509197771549225, 1.2807848453521729, 0.0), (0.19509197771549225, -1.2807848453521729, 0.0), (-0.19509197771549225, 1.2807848453521729, 0.0), (-0.19509197771549225, -1.2807848453521729, 0.0), (1.280785322189331, 0.19509035348892212, 0.0), (1.280785322189331, -0.19509035348892212, 0.0), (-1.280785322189331, 0.19509035348892212, 0.0), (-1.280785322189331, -0.19509035348892212, 0.0), (0.3950919806957245, 1.2807848453521729, 0.0), (0.3950919806957245, -1.2807848453521729, 0.0), (-0.3950919806957245, 1.2807848453521729, 0.0), (-0.3950919806957245, -1.2807848453521729, 0.0), (1.280785322189331, 0.39509034156799316, 0.0), (1.280785322189331, -0.39509034156799316, 0.0), (-1.280785322189331, 0.39509034156799316, 0.0), (-1.280785322189331, -0.39509034156799316, 0.0), (0.0, 1.5807849168777466, 0.0), (0.0, -1.5807849168777466, 0.0), (1.5807852745056152, 0.0, 0.0), (-1.5807852745056152, 0.0, 0.0)] - edges = [(0, 4), (1, 5), (2, 6), (3, 7), (4, 8), (5, 9), (6, 10), (7, 11), (8, 12), (9, 13), (10, 14), (11, 15), (16, 20), (17, 21), (18, 22), (19, 23), (20, 24), (21, 25), (22, 26), (23, 27), (0, 24), (1, 25), (2, 26), (3, 27), (16, 28), (17, 29), (18, 30), (19, 31), (12, 32), (13, 33), (14, 34), (15, 35), (28, 36), (29, 37), (30, 38), (31, 39), (32, 40), (33, 41), (34, 42), (35, 43), (36, 44), (37, 45), (38, 44), (39, 45), (40, 46), (41, 46), (42, 47), (43, 47)] - mesh = obj.data - mesh.from_pydata(verts, edges, []) - mesh.update() - - -def create_neck_bend_widget(rig, bone_name, radius=1.0, head_tail=0.0, bone_transform_name=None): - obj = create_widget(rig, bone_name, bone_transform_name) - size = 2.0 - if obj != None: - v = [(-0.08855080604553223 * size, 0.7388765811920166 * size, -0.3940150737762451 * size), - (0.08855044841766357 * size, 0.7388765811920166 * size, -0.3940150737762451 * size), - (0.17710095643997192 * size, 0.5611097812652588 * size, -0.6478927135467529 * size), - (-4.0892032870942785e-07 * size, 0.4087378978729248 * size, -0.865501880645752 * size), - (-0.17710143327713013 * size, 0.5611097812652588 * size, -0.6478922367095947 * size), - (0.08855026960372925 * size, 0.5611097812652588 * size, -0.6478924751281738 * size), - (-0.08855092525482178 * size, 0.5611097812652588 * size, -0.6478927135467529 * size), - (-0.6478927135467529 * size, 0.5611097812652588 * size, 0.08855098485946655 * size), - (-0.6478927135467529 * size, 0.5611097812652588 * size, -0.08855020999908447 * size), - (-0.6478924751281738 * size, 0.5611097812652588 * size, 0.17710155248641968 * size), - (-0.865501880645752 * size, 0.4087378978729248 * size, 4.6876743908796925e-07 * size), - (-0.647892951965332 * size, 0.5611097812652588 * size, -0.17710083723068237 * size), - (-0.39401543140411377 * size, 0.7388765811920166 * size, -0.08855029940605164 * size), - (-0.39401543140411377 * size, 0.7388765811920166 * size, 0.08855095505714417 * size), - (0.6478927135467529 * size, 0.5611097812652588 * size, -0.08855059742927551 * size), - (0.6478927135467529 * size, 0.5611097812652588 * size, 0.08855065703392029 * size), - (0.6478924751281738 * size, 0.5611097812652588 * size, -0.17710113525390625 * size), - (0.865501880645752 * size, 0.4087378978729248 * size, -3.264514703005261e-08 * size), - (0.647892951965332 * size, 0.5611097812652588 * size, 0.1771012544631958 * size), - (0.08855065703392029 * size, 0.7388765811920166 * size, 0.3940155506134033 * size), - (-0.08855056762695312 * size, 0.7388765811920166 * size, 0.3940155506134033 * size), - (-0.17710107564926147 * size, 0.5611097812652588 * size, 0.647892951965332 * size), - (2.244429140318971e-07 * size, 0.4087378978729248 * size, 0.865502119064331 * size), - (0.17710131406784058 * size, 0.5611097812652588 * size, 0.6478927135467529 * size), - (-0.08855044841766357 * size, 0.5611097812652588 * size, 0.647892951965332 * size), - (0.08855074644088745 * size, 0.5611097812652588 * size, 0.647892951965332 * size), - (0.3940153121948242 * size, 0.7388765811920166 * size, 0.08855071663856506 * size), - (0.39401519298553467 * size, 0.7388765811920166 * size, -0.08855047821998596 * size), - (-8.416645869147032e-08 * size, 0.8255770206451416 * size, -0.2656517028808594 * size), - (-0.06875583529472351 * size, 0.8255770206451416 * size, -0.2565997838973999 * size), - (-0.13282597064971924 * size, 0.8255770206451416 * size, -0.2300611138343811 * size), - (-0.18784427642822266 * size, 0.8255770206451416 * size, -0.18784409761428833 * size), - (-0.2300613522529602 * size, 0.8255770206451416 * size, -0.1328257918357849 * size), - (-0.256600022315979 * size, 0.8255770206451416 * size, -0.06875564157962799 * size), - (-0.2656519412994385 * size, 0.8255770206451416 * size, 9.328307726264029e-08 * size), - (-0.25660014152526855 * size, 0.8255770206451416 * size, 0.06875583529472351 * size), - (-0.2300613522529602 * size, 0.8255770206451416 * size, 0.13282597064971924 * size), - (-0.18784433603286743 * size, 0.8255770206451416 * size, 0.18784421682357788 * size), - (-0.1328260898590088 * size, 0.8255770206451416 * size, 0.23006129264831543 * size), - (-0.06875592470169067 * size, 0.8255770206451416 * size, 0.256600022315979 * size), - (-1.8761508613351907e-07 * size, 0.8255770206451416 * size, 0.2656519412994385 * size), - (0.06875556707382202 * size, 0.8255770206451416 * size, 0.2566000819206238 * size), - (0.13282573223114014 * size, 0.8255770206451416 * size, 0.23006141185760498 * size), - (0.18784403800964355 * size, 0.8255770206451416 * size, 0.1878443956375122 * size), - (0.23006105422973633 * size, 0.8255770206451416 * size, 0.1328260898590088 * size), - (0.25659990310668945 * size, 0.8255770206451416 * size, 0.06875596940517426 * size), - (0.2656517028808594 * size, 0.8255770206451416 * size, 2.3684407324253698e-07 * size), - (0.25659990310668945 * size, 0.8255770206451416 * size, -0.06875550746917725 * size), - (0.23006117343902588 * size, 0.8255770206451416 * size, -0.13282567262649536 * size), - (0.18784427642822266 * size, 0.8255770206451416 * size, -0.18784397840499878 * size), - (0.13282597064971924 * size, 0.8255770206451416 * size, -0.23006099462509155 * size), - (0.0687558501958847 * size, 0.8255770206451416 * size, -0.2565997838973999 * size), ] - edges = [(1, 0), (3, 2), (5, 2), (4, 3), (6, 4), (1, 5), (0, 6), (13, 7), (12, 8), (7, 9), (9, 10), (8, 11), - (27, 14), (26, 15), (14, 16), (16, 17), (15, 18), (17, 18), (10, 11), (12, 13), (20, 19), (22, 21), - (24, 21), (23, 22), (29, 28), (30, 29), (31, 30), (32, 31), (33, 32), (34, 33), (35, 34), (36, 35), - (37, 36), (38, 37), (39, 38), (40, 39), (41, 40), (42, 41), (43, 42), (44, 43), (45, 44), (46, 45), - (47, 46), (48, 47), (49, 48), (50, 49), (51, 50), (28, 51), (26, 27), (25, 23), (20, 24), - (19, 25), ] - - verts = [(a[0] * radius, head_tail, a[2] * radius) for a in v] - mesh = obj.data - mesh.from_pydata(verts, edges, []) - mesh.update() - - -def create_neck_tweak_widget(rig, bone_name, size=1.0, bone_transform_name=None): - obj = create_widget(rig, bone_name, bone_transform_name) - - if obj != None: - verts = [(0.3535533845424652 * size, 0.3535533845424652 * size, 0.0 * size), - (0.4619397521018982 * size, 0.19134171307086945 * size, 0.0 * size), - (0.5 * size, -2.1855694143368964e-08 * size, 0.0 * size), - (0.4619397521018982 * size, -0.19134175777435303 * size, 0.0 * size), - (0.3535533845424652 * size, -0.3535533845424652 * size, 0.0 * size), - (0.19134174287319183 * size, -0.4619397521018982 * size, 0.0 * size), - (7.549790126404332e-08 * size, -0.5 * size, 0.0 * size), - (-0.1913416087627411 * size, -0.46193981170654297 * size, 0.0 * size), - (-0.35355329513549805 * size, -0.35355350375175476 * size, 0.0 * size), - (-0.4619397521018982 * size, -0.19134178757667542 * size, 0.0 * size), - (-0.5 * size, 5.962440319251527e-09 * size, 0.0 * size), - (-0.4619397222995758 * size, 0.1913418024778366 * size, 0.0 * size), - (-0.35355326533317566 * size, 0.35355350375175476 * size, 0.0 * size), - (-0.19134148955345154 * size, 0.46193987131118774 * size, 0.0 * size), - (3.2584136988589307e-07 * size, 0.5 * size, 0.0 * size), - (0.1913420855998993 * size, 0.46193960309028625 * size, 0.0 * size), - (7.450580596923828e-08 * size, 0.46193960309028625 * size, 0.19134199619293213 * size), - (5.9254205098113744e-08 * size, 0.5 * size, 2.323586443253589e-07 * size), - (4.470348358154297e-08 * size, 0.46193987131118774 * size, -0.1913415789604187 * size), - (2.9802322387695312e-08 * size, 0.35355350375175476 * size, -0.3535533547401428 * size), - (2.9802322387695312e-08 * size, 0.19134178757667542 * size, -0.46193981170654297 * size), - (5.960464477539063e-08 * size, -1.1151834122813398e-08 * size, -0.5000000596046448 * size), - (5.960464477539063e-08 * size, -0.1913418024778366 * size, -0.46193984150886536 * size), - (5.960464477539063e-08 * size, -0.35355350375175476 * size, -0.3535533845424652 * size), - (7.450580596923828e-08 * size, -0.46193981170654297 * size, -0.19134166836738586 * size), - (9.348272556053416e-08 * size, -0.5 * size, 1.624372103492533e-08 * size), - (1.043081283569336e-07 * size, -0.4619397521018982 * size, 0.19134168326854706 * size), - (1.1920928955078125e-07 * size, -0.3535533845424652 * size, 0.35355329513549805 * size), - (1.1920928955078125e-07 * size, -0.19134174287319183 * size, 0.46193966269493103 * size), - (1.1920928955078125e-07 * size, -4.7414250303745575e-09 * size, 0.49999991059303284 * size), - (1.1920928955078125e-07 * size, 0.19134172797203064 * size, 0.46193966269493103 * size), - (8.940696716308594e-08 * size, 0.3535533845424652 * size, 0.35355329513549805 * size), - (0.3535534739494324 * size, 0.0 * size, 0.35355329513549805 * size), - (0.1913418173789978 * size, -2.9802322387695312e-08 * size, 0.46193966269493103 * size), - (8.303572940349113e-08 * size, -5.005858838558197e-08 * size, 0.49999991059303284 * size), - (-0.19134165346622467 * size, -5.960464477539063e-08 * size, 0.46193966269493103 * size), - (-0.35355329513549805 * size, -8.940696716308594e-08 * size, 0.35355329513549805 * size), - (-0.46193963289260864 * size, -5.960464477539063e-08 * size, 0.19134168326854706 * size), - (-0.49999991059303284 * size, -5.960464477539063e-08 * size, 1.624372103492533e-08 * size), - (-0.4619397521018982 * size, -2.9802322387695312e-08 * size, -0.19134166836738586 * size), - (-0.3535534143447876 * size, -2.9802322387695312e-08 * size, -0.3535533845424652 * size), - (-0.19134171307086945 * size, 0.0 * size, -0.46193984150886536 * size), - (7.662531942287387e-08 * size, 9.546055501630235e-09 * size, -0.5000000596046448 * size), - (0.19134187698364258 * size, 5.960464477539063e-08 * size, -0.46193981170654297 * size), - (0.3535535931587219 * size, 5.960464477539063e-08 * size, -0.3535533547401428 * size), - (0.4619399905204773 * size, 5.960464477539063e-08 * size, -0.1913415789604187 * size), - (0.5000000596046448 * size, 5.960464477539063e-08 * size, 2.323586443253589e-07 * size), - (0.4619396924972534 * size, 2.9802322387695312e-08 * size, 0.19134199619293213 * size), - (1.563460111618042 * size, 2.778762819843905e-08 * size, 1.5634593963623047 * size), - (0.8461387157440186 * size, -1.0400220418205208e-07 * size, 2.0427582263946533 * size), - (7.321979467178608e-08 * size, -1.9357810288056498e-07 * size, 2.2110657691955566 * size), - (-0.8461385369300842 * size, -2.3579201524626114e-07 * size, 2.0427582263946533 * size), - (-1.5634597539901733 * size, -3.67581861837607e-07 * size, 1.5634593963623047 * size), - (-2.0427584648132324 * size, -2.3579204366797057e-07 * size, 0.8461383581161499 * size), - (-2.211066246032715 * size, -2.3579204366797057e-07 * size, 9.972505665700737e-08 * size), - (-2.0427589416503906 * size, -1.0400223260376151e-07 * size, -0.8461381196975708 * size), - (-1.5634604692459106 * size, -1.040022183929068e-07 * size, -1.563459873199463 * size), - (-0.8461387753486633 * size, 2.77876033294433e-08 * size, -2.042759418487549 * size), - (4.4872678017782164e-08 * size, 7.00015263532805e-08 * size, -2.211066484451294 * size), - (0.8461388349533081 * size, 2.913672290105751e-07 * size, -2.0427591800689697 * size), - (1.5634608268737793 * size, 2.9136725743228453e-07 * size, -1.563459873199463 * size), - (2.042759895324707 * size, 2.9136725743228453e-07 * size, -0.8461377024650574 * size), - (2.211066722869873 * size, 2.9136725743228453e-07 * size, 1.0554133496043505e-06 * size), - (2.0427587032318115 * size, 1.5957746768435754e-07 * size, 0.8461397886276245 * size), ] - edges = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9), (9, 10), (10, 11), - (11, 12), (12, 13), (13, 14), (14, 15), (0, 15), (16, 31), (16, 17), (17, 18), (18, 19), (19, 20), - (20, 21), (21, 22), (22, 23), (23, 24), (24, 25), (25, 26), (26, 27), (27, 28), (28, 29), (29, 30), - (30, 31), (32, 33), (33, 34), (34, 35), (35, 36), (36, 37), (37, 38), (38, 39), (39, 40), (40, 41), - (41, 42), (42, 43), (43, 44), (44, 45), (45, 46), (46, 47), (32, 47), (48, 49), (49, 50), (50, 51), - (51, 52), (52, 53), (53, 54), (54, 55), (55, 56), (56, 57), (57, 58), (58, 59), (59, 60), (60, 61), - (61, 62), (62, 63), (48, 63), (21, 58), (10, 54), (29, 50), (2, 62), ] - - mesh = obj.data - mesh.from_pydata(verts, edges, []) - mesh.update() - - -#============================================= -# Math -#============================================= - -def angle_on_plane(plane, vec1, vec2): - """ Return the angle between two vectors projected onto a plane. - """ - plane.normalize() - vec1 = vec1 - (plane * (vec1.dot(plane))) - vec2 = vec2 - (plane * (vec2.dot(plane))) - vec1.normalize() - vec2.normalize() - - # Determine the angle - angle = math.acos(max(-1.0, min(1.0, vec1.dot(vec2)))) - - if angle < 0.00001: # close enough to zero that sign doesn't matter - return angle - - # Determine the sign of the angle - vec3 = vec2.cross(vec1) - vec3.normalize() - sign = vec3.dot(plane) - if sign >= 0: - sign = 1 - else: - sign = -1 - - return angle * sign - - -def align_bone_roll(obj, bone1, bone2): - """ Aligns the roll of two bones. - """ - bone1_e = obj.data.edit_bones[bone1] - bone2_e = obj.data.edit_bones[bone2] - - bone1_e.roll = 0.0 - - # Get the directions the bones are pointing in, as vectors - y1 = bone1_e.y_axis - x1 = bone1_e.x_axis - y2 = bone2_e.y_axis - x2 = bone2_e.x_axis - - # Get the shortest axis to rotate bone1 on to point in the same direction as bone2 - axis = y1.cross(y2) - axis.normalize() - - # Angle to rotate on that shortest axis - angle = y1.angle(y2) - - # Create rotation matrix to make bone1 point in the same direction as bone2 - rot_mat = Matrix.Rotation(angle, 3, axis) - - # Roll factor - x3 = rot_mat @ x1 - dot = x2 @ x3 - if dot > 1.0: - dot = 1.0 - elif dot < -1.0: - dot = -1.0 - roll = math.acos(dot) - - # Set the roll - bone1_e.roll = roll - - # Check if we rolled in the right direction - x3 = rot_mat @ bone1_e.x_axis - check = x2 @ x3 - - # If not, reverse - if check < 0.9999: - bone1_e.roll = -roll - - -def align_bone_x_axis(obj, bone, vec): - """ Rolls the bone to align its x-axis as closely as possible to - the given vector. - Must be in edit mode. - """ - bone_e = obj.data.edit_bones[bone] - - vec = vec.cross(bone_e.y_axis) - vec.normalize() - - dot = max(-1.0, min(1.0, bone_e.z_axis.dot(vec))) - angle = math.acos(dot) - - bone_e.roll += angle - - dot1 = bone_e.z_axis.dot(vec) - - bone_e.roll -= angle * 2 - - dot2 = bone_e.z_axis.dot(vec) - - if dot1 > dot2: - bone_e.roll += angle * 2 - - -def align_bone_z_axis(obj, bone, vec): - """ Rolls the bone to align its z-axis as closely as possible to - the given vector. - Must be in edit mode. - """ - bone_e = obj.data.edit_bones[bone] - - vec = bone_e.y_axis.cross(vec) - vec.normalize() - - dot = max(-1.0, min(1.0, bone_e.x_axis.dot(vec))) - angle = math.acos(dot) - - bone_e.roll += angle - - dot1 = bone_e.x_axis.dot(vec) - - bone_e.roll -= angle * 2 - - dot2 = bone_e.x_axis.dot(vec) - - if dot1 > dot2: - bone_e.roll += angle * 2 - - -def align_bone_y_axis(obj, bone, vec): - """ Matches the bone y-axis to - the given vector. - Must be in edit mode. - """ - - bone_e = obj.data.edit_bones[bone] - vec.normalize() - vec = vec * bone_e.length - - bone_e.tail = bone_e.head + vec - - -#============================================= -# Misc -#============================================= - -def copy_attributes(a, b): - keys = dir(a) - for key in keys: - if not key.startswith("_") \ - and not key.startswith("error_") \ - and key != "group" \ - and key != "is_valid" \ - and key != "rna_type" \ - and key != "bl_rna": - try: - setattr(b, key, getattr(a, key)) - except AttributeError: - pass - - -def get_rig_type(rig_type): - """ Fetches a rig module by name, and returns it. - """ - name = ".%s.%s" % (RIG_DIR, rig_type) - submod = importlib.import_module(name, package=MODULE_NAME) - importlib.reload(submod) - return submod - - -def get_metarig_module(metarig_name, path=METARIG_DIR): - """ Fetches a rig module by name, and returns it. - """ - - name = ".%s.%s" % (path, metarig_name) - submod = importlib.import_module(name, package=MODULE_NAME) - importlib.reload(submod) - return submod - - -def connected_children_names(obj, bone_name): - """ 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. - If there is a connected branch, the list stops there. - """ - bone = obj.data.bones[bone_name] - names = [] - - while True: - connects = 0 - con_name = "" - - for child in bone.children: - if child.use_connect: - connects += 1 - con_name = child.name - - if connects == 1: - names += [con_name] - bone = obj.data.bones[con_name] - else: - break - - return names - - -def has_connected_children(bone): - """ Returns true/false whether a bone has connected children or not. - """ - t = False - for b in bone.children: - t = t or b.use_connect - return t - - -def get_layers(layers): - """ Does it's best to extract a set of layers from any data thrown at it. - """ - if type(layers) == int: - return [x == layers for x in range(0, 32)] - elif type(layers) == str: - s = layers.split(",") - l = [] - for i in s: - try: - l += [int(float(i))] - except ValueError: - pass - return [x in l for x in range(0, 32)] - elif type(layers) == tuple or type(layers) == list: - return [x in layers for x in range(0, 32)] - else: - try: - list(layers) - except TypeError: - pass - else: - return [x in layers for x in range(0, 32)] - - -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 - generating the real rig with rigify. - """ - code = [] - - code.append("import bpy\n\n") - code.append("from mathutils import Color\n\n") - - code.append("def %s(obj):" % func_name) - code.append(" # generated by rigify.utils.write_metarig") - bpy.ops.object.mode_set(mode='EDIT') - code.append(" bpy.ops.object.mode_set(mode='EDIT')") - code.append(" arm = obj.data") - - arm = obj.data - - # Rigify bone group colors info - if groups and len(arm.rigify_colors) > 0: - code.append("\n for i in range(" + str(len(arm.rigify_colors)) + "):") - code.append(" arm.rigify_colors.add()\n") - - for i in range(len(arm.rigify_colors)): - name = arm.rigify_colors[i].name - active = arm.rigify_colors[i].active - normal = arm.rigify_colors[i].normal - select = arm.rigify_colors[i].select - standard_colors_lock = arm.rigify_colors[i].standard_colors_lock - code.append(' arm.rigify_colors[' + str(i) + '].name = "' + name + '"') - code.append(' arm.rigify_colors[' + str(i) + '].active = Color(' + str(active[:]) + ')') - code.append(' arm.rigify_colors[' + str(i) + '].normal = Color(' + str(normal[:]) + ')') - code.append(' arm.rigify_colors[' + str(i) + '].select = Color(' + str(select[:]) + ')') - code.append(' arm.rigify_colors[' + str(i) + '].standard_colors_lock = ' + str(standard_colors_lock)) - - # Rigify layer layout info - if layers and len(arm.rigify_layers) > 0: - code.append("\n for i in range(" + str(len(arm.rigify_layers)) + "):") - code.append(" arm.rigify_layers.add()\n") - - for i in range(len(arm.rigify_layers)): - name = arm.rigify_layers[i].name - row = arm.rigify_layers[i].row - selset = arm.rigify_layers[i].selset - group = arm.rigify_layers[i].group - code.append(' arm.rigify_layers[' + str(i) + '].name = "' + name + '"') - code.append(' arm.rigify_layers[' + str(i) + '].row = ' + str(row)) - code.append(' arm.rigify_layers[' + str(i) + '].selset = ' + str(selset)) - code.append(' arm.rigify_layers[' + str(i) + '].group = ' + str(group)) - - # write parents first - bones = [(len(bone.parent_recursive), bone.name) for bone in arm.edit_bones] - bones.sort(key=lambda item: item[0]) - bones = [item[1] for item in bones] - - code.append("\n bones = {}\n") - - for bone_name in bones: - bone = arm.edit_bones[bone_name] - code.append(" bone = arm.edit_bones.new(%r)" % bone.name) - code.append(" bone.head[:] = %.4f, %.4f, %.4f" % bone.head.to_tuple(4)) - code.append(" bone.tail[:] = %.4f, %.4f, %.4f" % bone.tail.to_tuple(4)) - code.append(" bone.roll = %.4f" % bone.roll) - code.append(" bone.use_connect = %s" % str(bone.use_connect)) - if bone.parent: - code.append(" bone.parent = arm.edit_bones[bones[%r]]" % bone.parent.name) - code.append(" bones[%r] = bone.name" % bone.name) - - bpy.ops.object.mode_set(mode='OBJECT') - code.append("") - code.append(" bpy.ops.object.mode_set(mode='OBJECT')") - - # Rig type and other pose properties - for bone_name in bones: - pbone = obj.pose.bones[bone_name] - - code.append(" pbone = obj.pose.bones[bones[%r]]" % bone_name) - code.append(" pbone.rigify_type = %r" % pbone.rigify_type) - code.append(" pbone.lock_location = %s" % str(tuple(pbone.lock_location))) - code.append(" pbone.lock_rotation = %s" % str(tuple(pbone.lock_rotation))) - code.append(" pbone.lock_rotation_w = %s" % str(pbone.lock_rotation_w)) - code.append(" pbone.lock_scale = %s" % str(tuple(pbone.lock_scale))) - code.append(" pbone.rotation_mode = %r" % pbone.rotation_mode) - if layers: - code.append(" pbone.bone.layers = %s" % str(list(pbone.bone.layers))) - # Rig type parameters - for param_name in pbone.rigify_parameters.keys(): - param = getattr(pbone.rigify_parameters, param_name, '') - if str(type(param)) == "<class 'bpy_prop_array'>": - param = list(param) - if type(param) == str: - param = '"' + param + '"' - code.append(" try:") - code.append(" pbone.rigify_parameters.%s = %s" % (param_name, str(param))) - code.append(" except AttributeError:") - code.append(" pass") - - code.append("\n bpy.ops.object.mode_set(mode='EDIT')") - code.append(" for bone in arm.edit_bones:") - code.append(" bone.select = False") - code.append(" bone.select_head = False") - code.append(" bone.select_tail = False") - - code.append(" for b in bones:") - code.append(" bone = arm.edit_bones[bones[b]]") - code.append(" bone.select = True") - code.append(" bone.select_head = True") - code.append(" bone.select_tail = True") - code.append(" arm.edit_bones.active = bone") - - # Set appropriate layers visible - if layers: - # Find what layers have bones on them - active_layers = [] - for bone_name in bones: - bone = obj.data.bones[bone_name] - for i in range(len(bone.layers)): - if bone.layers[i]: - if i not in active_layers: - active_layers.append(i) - active_layers.sort() - - code.append("\n arm.layers = [(x in " + str(active_layers) + ") for x in range(" + str(len(arm.layers)) + ")]") - - code.append('\nif __name__ == "__main__":') - code.append(" " + func_name + "(bpy.context.active_object)") - - return "\n".join(code) - - -def write_widget(obj): - """ Write a mesh object as a python script for widget use. - """ - script = "" - script += "def create_thing_widget(rig, bone_name, size=1.0, bone_transform_name=None):\n" - script += " obj = create_widget(rig, bone_name, bone_transform_name)\n" - script += " if obj != None:\n" - - # Vertices - if len(obj.data.vertices) > 0: - script += " verts = [" - for v in obj.data.vertices: - script += "(" + str(v.co[0]) + "*size, " + str(v.co[1]) + "*size, " + str(v.co[2]) + "*size), " - script += "]\n" - - # Edges - if len(obj.data.edges) > 0: - script += " edges = [" - for e in obj.data.edges: - script += "(" + str(e.vertices[0]) + ", " + str(e.vertices[1]) + "), " - script += "]\n" - - # Faces - if len(obj.data.polygons) > 0: - script += " faces = [" - for f in obj.data.polygons: - script += "(" - for v in f.vertices: - script += str(v) + ", " - script += "), " - script += "]\n" - - # Build mesh - script += "\n mesh = obj.data\n" - script += " mesh.from_pydata(verts, edges, faces)\n" - script += " mesh.update()\n" - script += " mesh.update()\n" - script += " return obj\n" - script += " else:\n" - script += " return None\n" - - return script - - -def random_id(length=8): - """ Generates a random alphanumeric id string. - """ - tlength = int(length / 2) - rlength = int(length / 2) + int(length % 2) - - chars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'] - text = "" - for i in range(0, rlength): - text += random.choice(chars) - text += str(hex(int(time.time())))[2:][-tlength:].rjust(tlength, '0')[::-1] - return text - - -#============================================= -# Color correction functions -#============================================= - -def linsrgb_to_srgb (linsrgb): - """Convert physically linear RGB values into sRGB ones. The transform is - uniform in the components, so *linsrgb* can be of any shape. - - *linsrgb* values should range between 0 and 1, inclusively. - - """ - # From Wikipedia, but easy analogue to the above. - gamma = 1.055 * linsrgb**(1./2.4) - 0.055 - scale = linsrgb * 12.92 - # return np.where (linsrgb > 0.0031308, gamma, scale) - if linsrgb > 0.0031308: - return gamma - return scale - - -def gamma_correct(color): - - corrected_color = Color() - for i, component in enumerate(color): - corrected_color[i] = linsrgb_to_srgb(color[i]) - return corrected_color - - -#============================================= -# Keyframing functions -#============================================= - - -def get_keyed_frames(rig): - frames = [] - if rig.animation_data: - if rig.animation_data.action: - fcus = rig.animation_data.action.fcurves - for fc in fcus: - for kp in fc.keyframe_points: - if kp.co[0] not in frames: - frames.append(kp.co[0]) - - frames.sort() - - return frames - - -def bones_in_frame(f, rig, *args): - """ - True if one of the bones listed in args is animated at frame f - :param f: the frame - :param rig: the rig - :param args: bone names - :return: - """ - - if rig.animation_data and rig.animation_data.action: - fcus = rig.animation_data.action.fcurves - else: - return False - - for fc in fcus: - animated_frames = [kp.co[0] for kp in fc.keyframe_points] - for bone in args: - if bone in fc.data_path.split('"') and f in animated_frames: - return True - - return False - - -def overwrite_prop_animation(rig, bone, prop_name, value, frames): - act = rig.animation_data.action - if not act: - return - - bone_name = bone.name - curve = None - - for fcu in act.fcurves: - words = fcu.data_path.split('"') - if words[0] == "pose.bones[" and words[1] == bone_name and words[-2] == prop_name: - curve = fcu - break - - if not curve: - return - - for kp in curve.keyframe_points: - if kp.co[0] in frames: - kp.co[1] = value - - -def find_layer_collection_by_collection(layer_collection, collection): - if collection == layer_collection.collection: - return layer_collection - - # go recursive - for child in layer_collection.children: - layer_collection = find_layer_collection_by_collection(child, collection) - if layer_collection: - return layer_collection - - -def ensure_widget_collection(context): - wgts_collection_name = "Widgets" - - view_layer = context.view_layer - layer_collection = bpy.context.layer_collection - collection = layer_collection.collection - - widget_collection = bpy.data.collections.get(wgts_collection_name) - if not widget_collection: - # ------------------------------------------ - # Create the widget collection - widget_collection = bpy.data.collections.new(wgts_collection_name) - widget_collection.hide_viewport = True - widget_collection.hide_render = True - - widget_layer_collection = None - else: - widget_layer_collection = find_layer_collection_by_collection(view_layer.layer_collection, widget_collection) - - if not widget_layer_collection: - # Add the widget collection to the tree - collection.children.link(widget_collection) - widget_layer_collection = [c for c in layer_collection.children if c.collection == widget_collection][0] - - # Make the widget the active collection for the upcoming added (widget) objects - view_layer.active_layer_collection = widget_layer_collection - return widget_collection |