From 89f56dc4df5ef641bd26f9fa4349c2f92c4a1b5a Mon Sep 17 00:00:00 2001 From: meta-androcto Date: Wed, 14 Jun 2017 12:26:11 +1000 Subject: Skinify: Update to new rigify types by karab44: T51036 --- object_skinify.py | 195 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 152 insertions(+), 43 deletions(-) diff --git a/object_skinify.py b/object_skinify.py index 354fedc0..b40d234b 100644 --- a/object_skinify.py +++ b/object_skinify.py @@ -19,7 +19,7 @@ bl_info = { "name": "Skinify Rig", "author": "Albert Makac (karab44)", - "version": (0, 8, 1), + "version": (0, 8, 7), "blender": (2, 7, 8), "location": "Properties > Bone > Skinify Rig (visible on pose mode only)", "description": "Creates a mesh object from selected bones", @@ -44,7 +44,37 @@ from mathutils import ( Euler, ) from bpy.app.handlers import persistent - +from enum import Enum + +#can the armature data properties group_prop and row be fetched directly from the rigify script? +horse_data = (1 , 5 ) ,( 2 , 4 ) ,( 3 , 0 ) ,( 4 , 3 ) ,( 5 , 4 ) ,( 1 , 0 ) ,( 1 , 0 ) ,( 7 , 2 ) ,( 8 , 5 ) ,( 9 , 4 ) ,( 7 , 2 ) ,( 8 , 5 ) ,( 9 , 4 ) ,( 10 , 2 ) ,( 11 , 5 ) ,( 12 , 4 ) ,( 10 , 2 ) ,( 11 , 5 ) ,( 12 , 4 ) ,( 13 , 6 ) ,( 1 , 4 ) ,( 14 , 6 ) ,( 1 , 0 ) ,( 1 , 0 ) ,( 1 , 0 ) ,( 1 , 0 ) ,( 1 , 0 ) ,( 1 , 0 ) ,( 14 , 1 ) , +shark_data = ( 1 , 5 ), ( 2 , 4 ), ( 1 , 0 ), ( 3 , 3 ), ( 4 , 4 ), ( 5 , 6 ), ( 6 , 5 ), ( 7 , 4 ), ( 6 , 5 ), ( 7 , 4 ), ( 8 , 3 ), ( 9 , 4 ), ( 1 , 0 ), ( 1 , 6 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 14 , 1 ) , +bird_data = ( 1 , 6 ), ( 2 , 4 ), ( 1 , 0 ), ( 3 , 3 ), ( 4 , 4 ), ( 1 , 0 ), ( 1 , 0 ), ( 6 , 5 ), ( 8 , 0 ), ( 7 , 4 ), ( 6 , 5 ), ( 8 , 0 ), ( 7 , 4 ), ( 10 , 2 ), ( 11 , 5 ), ( 12 , 4 ), ( 10 , 2 ), ( 11 , 5 ), ( 12 , 4 ), ( 1 , 0 ), ( 1 , 0 ), ( 13 , 6 ), ( 14 , 4 ), ( 1 , 0 ), ( 8 , 6 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 14 , 1 ), +cat_data = ( 1 , 5 ), ( 2 , 2 ), ( 2 , 3 ), ( 3 , 3 ), ( 4 , 4 ), ( 5 , 6 ), ( 6 , 4 ), ( 7 , 2 ), ( 8 , 5 ), ( 9 , 4 ), ( 7 , 2 ), ( 8 , 5 ), ( 9 , 4 ), ( 10 , 2 ), ( 11 , 5 ), ( 12 , 4 ), ( 10 , 2 ), ( 11 , 5 ), ( 12 , 4 ), ( 13 , 3 ), ( 14 , 4 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 16 , 1 ), +biped_data = ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 3 , 3 ), ( 4 , 4 ), ( 1 , 0 ), ( 1 , 0 ), ( 7 , 2 ), ( 8 , 5 ), ( 9 , 4 ), ( 7 , 2 ), ( 8 , 5 ), ( 9 , 4 ), ( 10 , 2 ), ( 11 , 5 ), ( 12 , 4 ), ( 10 , 2 ), ( 11 , 5 ), ( 12 , 4 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 14 , 1 ), +human_data = ( 1 , 5 ), ( 2 , 2 ), ( 2 , 3 ), ( 3 , 3 ), ( 4 , 4 ), ( 5 , 6 ), ( 6 , 4 ), ( 7 , 2 ), ( 8 , 5 ), ( 9 , 4 ), ( 7 , 2 ), ( 8 , 5 ), ( 9 , 4 ), ( 10 , 2 ), ( 11 , 5 ), ( 12 , 4 ), ( 10 , 2 ), ( 11 , 5 ), ( 12 , 4 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 14 , 1 ), +wolf_data = ( 1 , 5 ), ( 2 , 2 ), ( 2 , 3 ), ( 3 , 3 ), ( 4 , 4 ), ( 5 , 6 ), ( 6 , 4 ), ( 7 , 2 ), ( 8 , 5 ), ( 9 , 4 ), ( 7 , 2 ), ( 8 , 5 ), ( 9 , 4 ), ( 10 , 2 ), ( 11 , 5 ), ( 12 , 4 ), ( 10 , 2 ), ( 11 , 5 ), ( 12 , 4 ), ( 13 , 6 ), ( 1 , 0 ), ( 13 , 0 ), ( 13 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 14 , 1 ), +quadruped_data = ( 1 , 0 ), ( 2 , 0 ), ( 2 , 0 ), ( 3 , 3 ), ( 4 , 4 ), ( 5 , 0 ), ( 6 , 0 ), ( 7 , 2 ), ( 8 , 5 ), ( 9 , 4 ), ( 7 , 2 ), ( 8 , 5 ), ( 9 , 4 ), ( 10 , 2 ), ( 11 , 5 ), ( 12 , 4 ), ( 10 , 2 ), ( 11 , 5 ), ( 12 , 4 ), ( 13 , 6 ), ( 1 , 0 ), ( 13 , 0 ), ( 13 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 14 , 1 ), + +human_legacy_data = ( 1, None ), ( 1, None ), ( 2, None ), ( 1, None ), ( 3, None ), ( 3, None ), ( 4, None ), ( 5, None ), ( 6, None ), ( 4, None ), ( 5, None ), ( 6, None ), ( 7, None ), ( 8, None ), ( 9, None ), ( 7, None ), ( 8, None ), ( 9, None ), ( 1, None ), ( 1, None ), ( 1, None ), ( 1, None ), ( 1, None ), ( 1, None ), ( 1, None ), ( 1, None ), ( 1, None ), ( 1, None ), +pitchipoy_data = ( 1, None ), ( 2, None), ( 2, None ), ( 3, None ), ( 4, None ), ( 5, None ), ( 6, None ), ( 7, None ), ( 8, None ), ( 9, None ), ( 7, None ), ( 8, None ), ( 9, None ), ( 10, None ), ( 11, None ), ( 12, None ), ( 10, None ), ( 11, None ), ( 12, None ), ( 1, None ), ( 1, None ), ( 1, None ), ( 1, None ), ( 1, None ), ( 1, None ), ( 1, None ), ( 1, None ), ( 1, None ), + +rigify_data = horse_data, shark_data, bird_data, cat_data, biped_data, human_data, wolf_data, quadruped_data, human_legacy_data, pitchipoy_data + +class Rig_type(Enum): + HORSE = 0 + SHARK = 1 + BIRD = 2 + CAT = 3 + BIPED= 4 + HUMAN = 5 + WOLF = 6 + QUAD = 7 + LEGACY = 8 + PITCHIPOY = 9 + OTHER = 10 + +rig_type = Rig_type.OTHER # initialize properties def init_props(): @@ -79,6 +109,109 @@ def select_vertices(mesh_obj, idx): bpy.ops.object.mode_set(mode=mode) return selectedVerts + +def identify_rig(): + if 'rigify_layers' not in bpy.context.object.data: + return Rig_type.OTHER #non recognized + + LEGACY_LAYERS_SIZE = 28 + layers = bpy.context.object.data['rigify_layers'] + + + for type, rig in enumerate(rigify_data): + index = 0 + + + for props in layers: + if len(layers) == LEGACY_LAYERS_SIZE and 'group_prop' not in props: + + if props['row'] != rig[index][0] or rig[index][1] != None: + break + + elif (props['row'] != rig[index][0]) or (props['group_prop'] != rig[index][1]): + break + + #SUCCESS if reach the end + if index == len(layers) -1: + return Rig_type(type) + + index = index + 1 + + return Rig_type.OTHER + +def prepare_ignore_list(rig_type, bones): + # detect the head, face, hands, breast, heels or other exceptionary bones to exclusion or customization + common_ignore_list = ['eye', 'heel', 'breast', 'root'] + + #edit these lists to suits your taste + + + horse_ignore_list = ['chest', 'belly', 'pelvis', 'jaw', 'nose', 'skull', 'ear.' ] + + shark_ignore_list = ['jaw'] + + bird_ignore_list = ['face', 'pelvis', 'nose', 'lip', 'jaw', 'chin', 'ear.', 'brow', + 'lid', 'forehead', 'temple', 'cheek', 'teeth', 'tongue', 'beak'] + + cat_ignore_list = ['face', 'belly' 'pelvis.C', 'nose', 'lip', 'jaw', 'chin', 'ear.', 'brow', + 'lid', 'forehead', 'temple', 'cheek', 'teeth', 'tongue'] + + biped_ignore_list = ['pelvis'] + + human_ignore_list = ['face', 'pelvis', 'nose', 'lip', 'jaw', 'chin', 'ear.', 'brow', + 'lid', 'forehead', 'temple', 'cheek', 'teeth', 'tongue'] + + wolf_ignore_list = ['face', 'pelvis', 'nose', 'lip', 'jaw', 'chin', 'ear.', 'brow', + 'lid', 'forehead', 'temple', 'cheek', 'teeth', 'tongue'] + + quad_ignore_list = ['face', 'pelvis', 'nose', 'lip', 'jaw', 'chin', 'ear.', 'brow', + 'lid', 'forehead', 'temple', 'cheek', 'teeth', 'tongue'] + + rigify_legacy_ignore_list = [] + + pitchipoy_ignore_list = ['face', 'pelvis', 'nose', 'lip', 'jaw', 'chin', 'ear.', 'brow', + 'lid', 'forehead', 'temple', 'cheek', 'teeth', 'tongue'] + + other_ignore_list = [] + + ignore_list = common_ignore_list + + if rig_type == Rig_type.HORSE: + ignore_list = ignore_list + horse_ignore_list + print("RIDER OF THE APOCALYPSE") + elif rig_type == Rig_type.SHARK: + ignore_list = ignore_list + shark_ignore_list + print("DEADLY JAWS") + elif rig_type == Rig_type.BIRD: + ignore_list = ignore_list + bird_ignore_list + print("WINGS OF LIBERTY") + elif rig_type == Rig_type.CAT: + ignore_list = ignore_list + cat_ignore_list + print("MEOW") + elif rig_type == Rig_type.BIPED: + ignore_list = ignore_list + biped_ignore_list + print("HUMANOID") + elif rig_type == Rig_type.HUMAN: + ignore_list = ignore_list + human_ignore_list + print("JUST A HUMAN AFTER ALL") + elif rig_type == Rig_type.WOLF: + ignore_list = ignore_list + wolf_ignore_list + print("WHITE FANG") + elif rig_type == Rig_type.QUAD: + ignore_list = ignore_list + quad_ignore_list + print("MYSTERIOUS CREATURE") + elif rig_type == Rig_type.LEGACY: + ignore_list = ignore_list + rigify_legacy_ignore_list + print("LEGACY RIGIFY") + elif rig_type == Rig_type.PITCHIPOY: + ignore_list = ignore_list + pitchipoy_ignore_list + print("PITCHIPOY") + elif rig_type == Rig_type.OTHER: + ignore_list = ignore_list + other_ignore_list + print("rig non recognized...") + + + return ignore_list # generates edges from vertices used by skin modifier def generate_edges(mesh, shape_object, bones, scale, connect_mesh=False, connect_parents=False, @@ -87,42 +220,18 @@ def generate_edges(mesh, shape_object, bones, scale, connect_mesh=False, connect This function adds vertices for all heads and tails """ # scene preferences - # scn = bpy.context.scene - - # detect the head, face, hands, breast, heels or other exceptionary bones to exclusion or customization - common_ignore_list = ['eye', 'heel', 'breast', 'root'] - - # bvh_ignore_list = [] - rigify_ignore_list = [] - pitchipoy_ignore_list = ['face', 'breast', 'pelvis', 'nose', 'lip', 'jaw', 'chin', 'ear.', 'brow', - 'lid', 'forehead', 'temple', 'cheek', 'teeth', 'tongue'] - rigify_new_ignore_list = ['face', 'breast', 'pelvis', 'nose', 'lip', 'jaw', 'chin', 'ear.', 'brow', - 'lid', 'forehead', 'temple', 'cheek', 'teeth', 'tongue'] alternate_scale_list = [] - # rig_type rigify = 1, pitchipoy = 2, rigify_new = 3 - rig_type = 0 + me = mesh verts = [] edges = [] idx = 0 alternate_scale_idx_list = list() - ignore_list = common_ignore_list - # detect rig type - for b in bones: - if b.name == 'hips' and b.rigify_type == 'spine': - ignore_list = ignore_list + rigify_ignore_list - rig_type = 1 - break - if b.name == 'spine' and b.rigify_type == 'pitchipoy.super_torso_turbo': - ignore_list = ignore_list + pitchipoy_ignore_list - rig_type = 2 - break - if b.name == 'spine' and b.rigify_type == 'spines.super_spine': - ignore_list = ignore_list + rigify_new_ignore_list - rig_type = 3 - break + rig_type = identify_rig() + ignore_list = prepare_ignore_list(rig_type, bones) + # edge generator loop for b in bones: @@ -150,10 +259,10 @@ def generate_edges(mesh, shape_object, bones, scale, connect_mesh=False, connect if head_ornaments is False: if b.parent is not None: - if 'head' in b.parent.name.lower() and not rig_type == 3: + if 'head' in b.parent.name.lower() and not rig_type == Rig_type.HUMAN: continue - if 'face' in b.parent.name.lower() and rig_type == 3: + if 'face' in b.parent.name.lower() and rig_type == Rig_type.HUMAN: continue if connect_parents: @@ -185,8 +294,8 @@ def generate_edges(mesh, shape_object, bones, scale, connect_mesh=False, connect idx = idx + 2 # for bvh free floating hips and hips correction for rigify and pitchipoy if ((generate_all is False and 'hip' in b.name.lower()) or - (generate_all is False and (b.name == 'hips' and rig_type == 1) or - (b.name == 'spine' and rig_type == 2) or (b.name == 'spine' and rig_type == 3))): + (generate_all is False and (b.name == 'hips' and rig_type == Rig_type.LEGACY) or + (b.name == 'spine' and rig_type == Rig_type.PITCHIPOY) or (b.name == 'spine' and rig_type == Rig_type.HUMAN) or (b.name == 'spine' and rig_type == Rig_type.BIPED))): continue vert1 = b.head @@ -275,14 +384,14 @@ def generate_mesh(shape_object, size, thickness=0.8, finger_thickness=0.25, sub_ bpy.ops.mesh.remove_doubles() # fix rigify and pitchipoy hands topology - if connect_mesh and connect_parents and generate_all is False and rig_type > 0: + if connect_mesh and connect_parents and generate_all is False and (rig_type == Rig_type.LEGACY or rig_type == Rig_type.PITCHIPOY or rig_type == Rig_type.HUMAN): # thickness will set palm vertex for both hands look pretty corrective_thickness = 2.5 # left hand verts merge_idx = [] - if rig_type == 1: + if rig_type == Rig_type.LEGACY: merge_idx = [7, 8, 13, 17, 22, 27] - else: + elif rig_type == Rig_type.PITCHIPOY or rig_type == Rig_type.HUMAN: merge_idx = [9, 14, 18, 23, 24, 29] select_vertices(shape_object, merge_idx) bpy.ops.mesh.merge(type='CENTER') @@ -295,9 +404,9 @@ def generate_mesh(shape_object, size, thickness=0.8, finger_thickness=0.25, sub_ bpy.ops.mesh.select_all(action='DESELECT') # right hand verts - if rig_type == 1: + if rig_type == Rig_type.LEGACY: merge_idx = [30, 35, 39, 44, 45, 50] - else: + elif rig_type == Rig_type.PITCHIPOY or rig_type == Rig_type.HUMAN: merge_idx = [32, 37, 41, 46, 51, 52] select_vertices(shape_object, merge_idx) @@ -312,10 +421,10 @@ def generate_mesh(shape_object, size, thickness=0.8, finger_thickness=0.25, sub_ # making hands even more pretty bpy.ops.mesh.select_all(action='DESELECT') hands_idx = [] # left and right hand vertices - if rig_type == 1: + if rig_type == Rig_type.LEGACY: # hands_idx = [8, 33] # L and R hands_idx = [6, 29] - else: + elif rig_type == Rig_type.PITCHIPOY or rig_type == Rig_type.HUMAN: # hands_idx = [10, 35] # L and R hands_idx = [8, 31] select_vertices(shape_object, hands_idx) @@ -331,9 +440,9 @@ def generate_mesh(shape_object, size, thickness=0.8, finger_thickness=0.25, sub_ # todo optionally take root from rig's hip tail or head depending on scenario root_idx = [] - if rig_type == 1: + if rig_type == Rig_type.LEGACY: root_idx = [59] - elif rig_type == 2: + elif rig_type == Rig_type.PITCHIPOY or rig_type == Rig_type.HUMAN: root_idx = [56] else: root_idx = [0] -- cgit v1.2.3