Skinify Rig: Cleanup

Bumped version to 0.9.1
Pep8 cleanup
Strip trailing empty spaces
No other functional changes
This commit is contained in:
Vuk Gardašević 2017-07-12 22:23:43 +02:00
parent 1fd6f67b33
commit be06758806
1 changed files with 98 additions and 95 deletions

View File

@ -19,7 +19,7 @@
bl_info = {
"name": "Skinify Rig",
"author": "Albert Makac (karab44)",
"version": (0, 9, 0),
"version": (0, 9, 1),
"blender": (2, 7, 9),
"location": "Properties > Bone > Skinify Rig (visible on pose mode only)",
"description": "Creates a mesh object from selected bones",
@ -104,11 +104,13 @@ pitchipoy_data = \
rigify_data = horse_data, shark_data, bird_data, cat_data, biped_data, human_data, \
wolf_data, quadruped_data, human_legacy_data, pitchipoy_data
#Skin.rig_type.ENUM
#Skin.junction_dict['bname'].data[0] idx, data[1] idx +1, data[2] thicnkess
#NOTE each fragment contains section information about adequate bone junctions idx and idx + 1 and these vertices' ids share common thickness
# Skin.rig_type.ENUM
# Skin.junction_dict['bname'].data[0] idx, data[1] idx + 1, data[2] thickness
# NOTE each fragment contains section information about adequate bone
# junctions idx and idx + 1 and these vertices' ids share common thickness
class Skin(object):
class Rig_type(Enum):
HORSE = 0
SHARK = 1
@ -121,31 +123,31 @@ class Skin(object):
LEGACY = 8
PITCHIPOY = 9
OTHER = 10
def __init__(self, rig_type):
self.rig_type = rig_type
self.junctions_dict = dict()
def fragment_create(self, bname, idx = None, thickness = 0.0):
def fragment_create(self, bname, idx=None, thickness=0.0):
data = []
data.insert(0, idx)
if idx != None:
if idx is not None:
data.insert(1, idx + 1)
else:
data.insert(1, None)
data.insert(1, None)
self.junctions_dict[bname] = data
self.junctions_dict[bname].append(thickness)
#for the sake of code clarity
def fragment_update(self, bname, idx = None, thickness = 0.0):
# for the sake of code clarity
def fragment_update(self, bname, idx=None, thickness=0.0):
self.fragment_create(bname, idx, thickness)
rig_type = Skin.Rig_type.OTHER
# initialize properties
def init_props():
# additional check - this should be a rare case if the handler
@ -190,11 +192,11 @@ def identify_rig():
return Skin.Rig_type.OTHER
#prepares customizable ignore and thickness lists
# prepares customizable ignore and thickness lists
# edit these lists to suits your taste
def prepare_lists(rig_type, finger_thickness):
# EXAMPLE IGNORE LIST
# detect the head, face, hands, breast, heels or other exceptionary bones for exclusion or customization
common_ignore_list = ['eye', 'heel', 'breast', 'root']
@ -227,28 +229,28 @@ def prepare_lists(rig_type, finger_thickness):
'lid', 'forehead', 'temple', 'cheek', 'teeth', 'tongue'
]
other_ignore_list = []
# EXAMPLE THICKNESS
# feel free to modify and customize the list by adding elements followed by comma common_thickness_dict = {"hand": common_finger_thickness, "head": common_head_thickness}
common_finger_thickness = finger_thickness
common_thickness_dict = {"hand": common_finger_thickness}
# feel free to modify and customize the list by adding elements followed by comma
# common_thickness_dict = {"hand": common_finger_thickness, "head": common_head_thickness}
common_finger_thickness = finger_thickness
common_thickness_dict = {"hand": common_finger_thickness}
horse_thickness_dict = {}
shark_thickness_dict = {}
bird_thickness_dict = {}
cat_thickness_dict = {}
face_thickness = 0.20
biped_thickness_dict = {}
human_thickness_dict = {"face": face_thickness}
face_thickness = 0.20
biped_thickness_dict = {}
human_thickness_dict = {"face": face_thickness}
wolf_thickness_dict = {}
quad_thickness_dict = {}
rigify_legacy_thickness_dict = {}
quad_thickness_dict = {}
rigify_legacy_thickness_dict = {}
pitchipoy_thickness_dict = {"face": face_thickness}
other_thickness_dict = {}
#combine lists depending on rig type
# combine lists depending on rig type
ignore_list = common_ignore_list
thickness_dict = common_thickness_dict
thickness_dict = common_thickness_dict
if rig_type == Skin.Rig_type.HORSE:
ignore_list = ignore_list + horse_ignore_list
thickness_dict.update(horse_thickness_dict)
@ -266,12 +268,12 @@ def prepare_lists(rig_type, finger_thickness):
thickness_dict.update(cat_thickness_dict)
print("MEOW")
elif rig_type == Skin.Rig_type.BIPED:
ignore_list = ignore_list + biped_ignore_list
thickness_dict.update(biped_thickness_dict)
ignore_list = ignore_list + biped_ignore_list
thickness_dict.update(biped_thickness_dict)
print("HUMANOID")
elif rig_type == Skin.Rig_type.HUMAN:
ignore_list = ignore_list + human_ignore_list
thickness_dict.update(human_thickness_dict)
thickness_dict.update(human_thickness_dict)
print("JUST A HUMAN AFTER ALL")
elif rig_type == Skin.Rig_type.WOLF:
ignore_list = ignore_list + wolf_ignore_list
@ -293,44 +295,44 @@ def prepare_lists(rig_type, finger_thickness):
ignore_list = ignore_list + other_ignore_list
thickness_dict.update(other_thickness_dict)
print("rig non recognized...")
return ignore_list, thickness_dict
# generates edges from vertices used by skin modifier
def generate_edges(mesh, shape_object, bones, scale, connect_mesh=False, connect_parents=False,
head_ornaments=False, generate_all=False, thickness = 0.0, finger_thickness = 0.0):
head_ornaments=False, generate_all=False, thickness=0.0, finger_thickness=0.0):
"""
This function adds vertices for all bones' heads and tails
"""
me = mesh
verts = []
edges = []
idx = 0
rig_type = identify_rig()
skin = Skin(rig_type)
# prepare the list
# prepare the list
ignore_list, thickness_dict = prepare_lists(skin.rig_type, finger_thickness)
#create default junctions for all bones
for b in bones:
# create default junctions for all bones
for b in bones:
# set default thickness to all new junctions
skin.fragment_create(bname = b.name, idx = None, thickness = thickness)
skin.fragment_create(bname=b.name, idx=None, thickness=thickness)
# edge generator loop
for b in bones:
for b in bones:
# look for rig's specific bones and their childs and set individual thickness
for bname, thick in thickness_dict.items():
if bname.lower() in b.name.lower():
skin.fragment_update(bname = b.name, idx = None, thickness = thick)
if bname.lower() in b.name.lower():
skin.fragment_update(bname=b.name, idx=None, thickness=thick)
for c in b.children_recursive:
#update junctions with specific thickness
skin.fragment_update(bname = c.name, idx = None, thickness = thick)
# update junctions with specific thickness
skin.fragment_update(bname=c.name, idx=None, thickness=thick)
found = False
for i in ignore_list:
@ -374,14 +376,14 @@ def generate_edges(mesh, shape_object, bones, scale, connect_mesh=False, connect
verts.append(vert1)
verts.append(vert2)
edges.append([idx, idx + 1])
# also make list of edges made of gaps between the bones
# also make list of edges made of gaps between the bones
for bname, data in skin.junctions_dict.items():
if b.name == bname:
if b.name == bname:
skin.fragment_update(b.name, idx, data[2])
break
# create new segment for new connections
break
# create new segment for new connections
skin.fragment_create(b.name + b.parent.name, idx, data[2])
idx = idx + 2
@ -397,19 +399,19 @@ def generate_edges(mesh, shape_object, bones, scale, connect_mesh=False, connect
verts.append(vert1)
verts.append(vert2)
edges.append([idx, idx + 1])
edges.append([idx, idx + 1])
# insert idx to junctions and update
for bname, data in skin.junctions_dict.items():
if b.name == bname:
skin.fragment_update(b.name, idx, data[2])
#insert idx to junctions and update
for bname, data in skin.junctions_dict.items():
if b.name == bname:
skin.fragment_update(b.name, idx, data[2])
idx = idx + 2
# Create mesh from given verts, faces
me.from_pydata(verts, edges, [])
# Update mesh with new data
me.update()
me.update()
# set object scale exact as armature's scale
shape_object.scale = scale
@ -433,13 +435,14 @@ def select_vertices(mesh_obj, idx):
return selectedVerts
def generate_mesh(shape_object, size, sub_level=1, connect_mesh=False, connect_parents=False, generate_all=False, apply_mod=True, skin = None, bones=[]):
def generate_mesh(shape_object, size, sub_level=1, connect_mesh=False, connect_parents=False,
generate_all=False, apply_mod=True, skin=None, bones=[]):
"""
This function adds modifiers for generated edges
"""
total_bones_num = len(bpy.context.object.pose.bones.keys())
selected_bones_num = len(bones)
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='DESELECT')
@ -463,24 +466,24 @@ def generate_mesh(shape_object, size, sub_level=1, connect_mesh=False, connect_p
# calculate optimal, normalized thickness for each segment
bpy.ops.object.skin_root_mark(override)
# select finger vertices and calculate optimal thickness for fingers to fix proportions
# by default set fingers thickness to 25 percent of body thickness
# make loose hands only for better topology
if len(skin.junctions_dict.keys()) > 0:
# make loose hands only for better topology
if len(skin.junctions_dict.keys()) > 0:
for bname, data in skin.junctions_dict.items():
if data[0] != None:
if data[0] is not None:
fragment_idx = list()
fragment_idx.append(data[0])
fragment_idx.append(data[1])
thickness = data[2]
thickness = data[2]
select_vertices(shape_object, fragment_idx)
bpy.ops.transform.skin_resize(override,
value=(1 * thickness * (size / 10), 1 * thickness * (size / 10), 1 * thickness * (size / 10)),
constraint_axis=(False, False, False), constraint_orientation='GLOBAL',
mirror=False, proportional='DISABLED', proportional_edit_falloff='SMOOTH',
proportional_size=1
value=(1 * thickness * (size / 10), 1 * thickness * (size / 10),
1 * thickness * (size / 10)), constraint_axis=(False, False, False),
constraint_orientation='GLOBAL', mirror=False, proportional='DISABLED',
proportional_edit_falloff='SMOOTH', proportional_size=1
)
shape_object.modifiers["Skin"].use_smooth_shade = True
shape_object.modifiers["Skin"].use_x_symmetry = True
@ -492,24 +495,23 @@ def generate_mesh(shape_object, size, sub_level=1, connect_mesh=False, connect_p
bpy.ops.mesh.select_all(action='DESELECT')
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.remove_doubles()
# fix rigify and pitchipoy hands topology
# fix rigify and pitchipoy hands topology
if connect_mesh and connect_parents and generate_all is False and \
(skin.rig_type == Skin.Rig_type.LEGACY or skin.rig_type == Skin.Rig_type.PITCHIPOY or skin.rig_type == Skin.Rig_type.HUMAN) and \
selected_bones_num == total_bones_num:
(skin.rig_type == Skin.Rig_type.LEGACY or skin.rig_type == Skin.Rig_type.PITCHIPOY or
skin.rig_type == Skin.Rig_type.HUMAN) and selected_bones_num == total_bones_num:
# thickness will set palm vertex for both hands look pretty
corrective_thickness = 2.5
# left hand verts
merge_idx = []
if skin.rig_type == Skin.Rig_type.LEGACY:
merge_idx = [8, 9, 14, 18, 23, 28]
elif skin.rig_type == Skin.Rig_type.PITCHIPOY or skin.rig_type == Skin.Rig_type.HUMAN:
merge_idx = [10, 11, 16, 20, 25, 30]
select_vertices(shape_object, merge_idx)
bpy.ops.mesh.merge(type='CENTER')
bpy.ops.transform.skin_resize(override,
@ -520,13 +522,13 @@ def generate_mesh(shape_object, size, sub_level=1, connect_mesh=False, connect_p
)
bpy.ops.mesh.select_all(action='DESELECT')
# right hand verts
# right hand verts
if skin.rig_type == Skin.Rig_type.LEGACY:
merge_idx = [31, 32, 37, 41, 46, 51]
elif skin.rig_type == Skin.Rig_type.PITCHIPOY or skin.rig_type == Skin.Rig_type.HUMAN:
merge_idx = [33, 34, 39, 43, 48, 53]
select_vertices(shape_object, merge_idx)
bpy.ops.mesh.merge(type='CENTER')
bpy.ops.transform.skin_resize(override,
@ -542,11 +544,11 @@ def generate_mesh(shape_object, size, sub_level=1, connect_mesh=False, connect_p
if skin.rig_type == Skin.Rig_type.LEGACY:
# hands_idx = [8, 33] # L and R
hands_idx = [7, 30]
elif skin.rig_type == Skin.Rig_type.PITCHIPOY or skin.rig_type == Skin.Rig_type.HUMAN:
# hands_idx = [10, 35] # L and R
hands_idx = [9, 32]
select_vertices(shape_object, hands_idx)
# change the thickness to make hands look less blocky and more sexy
corrective_thickness = 0.7
@ -563,7 +565,8 @@ def generate_mesh(shape_object, size, sub_level=1, connect_mesh=False, connect_p
root_idx = []
if skin.rig_type == Skin.Rig_type.LEGACY and selected_bones_num == total_bones_num:
root_idx = [59]
elif (skin.rig_type == Skin.Rig_type.PITCHIPOY or skin.rig_type == Skin.Rig_type.HUMAN) and selected_bones_num == total_bones_num:
elif (skin.rig_type == Skin.Rig_type.PITCHIPOY or skin.rig_type == Skin.Rig_type.HUMAN) and \
selected_bones_num == total_bones_num:
root_idx = [56]
elif selected_bones_num == total_bones_num:
root_idx = [0]
@ -647,7 +650,7 @@ def main(context):
sknfy.connect_parents, sknfy.head_ornaments,
sknfy.generate_all, sknfy.thickness, sknfy.finger_thickness
)
generate_mesh(ob, size, sknfy.sub_level,
sknfy.connect_mesh, sknfy.connect_parents, sknfy.generate_all,
sknfy.apply_mod, skin, bone_selection)