From 89f56dc4df5ef641bd26f9fa4349c2f92c4a1b5a Mon Sep 17 00:00:00 2001
From: meta-androcto <meta.androcto1@gmail.com>
Date: Wed, 14 Jun 2017 12:26:11 +1000
Subject: [PATCH] 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 354fedc0e..b40d234ba 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]
-- 
GitLab