Skip to content
Snippets Groups Projects
Commit cb5a35b7 authored by Campbell Barton's avatar Campbell Barton
Browse files

make pep8 compliant

parent bd994c66
Branches
Tags
No related merge requests found
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
# #
# ##### END GPL LICENSE BLOCK ##### # ##### END GPL LICENSE BLOCK #####
# <pep8-80 compliant>
bl_info = { bl_info = {
'name': 'Corrective shape keys', 'name': 'Corrective shape keys',
'author': 'Ivo Grigull (loolarge), Tal Trachtman', 'author': 'Ivo Grigull (loolarge), Tal Trachtman',
...@@ -57,9 +59,9 @@ from mathutils import Vector, Matrix ...@@ -57,9 +59,9 @@ from mathutils import Vector, Matrix
iterations = 20 iterations = 20
threshold = 1e-16 threshold = 1e-16
def reset_transform(ob): def reset_transform(ob):
m = Matrix() ob.matrix_local.identity()
ob.matrix_local = m
# this version is for shape_key data # this version is for shape_key data
...@@ -78,25 +80,26 @@ def extract_mapped_coords(ob, shape_verts): ...@@ -78,25 +80,26 @@ def extract_mapped_coords(ob, shape_verts):
arr = [verts[i].co.copy() for i in range(len(verts) - totvert, len(verts))] arr = [verts[i].co.copy() for i in range(len(verts) - totvert, len(verts))]
mesh.user_clear() mesh.user_clear()
bpy.data.meshes.remove(mesh) bpy.data.meshes.remove(mesh)
return arr return arr
def apply_vert_coords(ob, mesh, x ):
def apply_vert_coords(ob, mesh, x):
for i, v in enumerate(mesh): for i, v in enumerate(mesh):
v.co = x[i] v.co = x[i]
ob.data.update() ob.data.update()
def func_add_corrective_pose_shape( source, target): def func_add_corrective_pose_shape(source, target):
ob_1 = target ob_1 = target
mesh_1 = target.data mesh_1 = target.data
ob_2 = source ob_2 = source
mesh_2 = source.data mesh_2 = source.data
reset_transform(target) reset_transform(target)
# If target object doesn't have Basis shape key, create it. # If target object doesn't have Basis shape key, create it.
if not mesh_1.shape_keys: if not mesh_1.shape_keys:
basis = ob_1.shape_key_add() basis = ob_1.shape_key_add()
...@@ -108,75 +111,73 @@ def func_add_corrective_pose_shape( source, target): ...@@ -108,75 +111,73 @@ def func_add_corrective_pose_shape( source, target):
if key_index == 0: if key_index == 0:
new_shapekey = ob_1.shape_key_add() new_shapekey = ob_1.shape_key_add()
new_shapekey.name = "Shape_" + ob_2.name new_shapekey.name = "Shape_" + ob_2.name
key_index = len(mesh_1.shape_keys.key_blocks)-1 key_index = len(mesh_1.shape_keys.key_blocks) - 1
ob_1.active_shape_key_index = key_index ob_1.active_shape_key_index = key_index
# else, the active shape will be used (updated) # else, the active shape will be used (updated)
ob_1.show_only_shape_key = True ob_1.show_only_shape_key = True
vgroup = ob_1.active_shape_key.vertex_group vgroup = ob_1.active_shape_key.vertex_group
ob_1.active_shape_key.vertex_group = "" ob_1.active_shape_key.vertex_group = ""
mesh_1_key_verts = mesh_1.shape_keys.key_blocks[ key_index ].data mesh_1_key_verts = mesh_1.shape_keys.key_blocks[key_index].data
x = extract_vert_coords(ob_1, mesh_1_key_verts) x = extract_vert_coords(ob_1, mesh_1_key_verts)
targetx = extract_vert_coords(ob_2, mesh_2.vertices) targetx = extract_vert_coords(ob_2, mesh_2.vertices)
for iteration in range(0, iterations): for iteration in range(0, iterations):
dx = [[], [], [], [], [], []] dx = [[], [], [], [], [], []]
mapx = extract_mapped_coords(ob_1, mesh_1_key_verts) mapx = extract_mapped_coords(ob_1, mesh_1_key_verts)
# finite differencing in X/Y/Z to get approximate gradient # finite differencing in X/Y/Z to get approximate gradient
for i in range(0, len(mesh_1.vertices)): for i in range(0, len(mesh_1.vertices)):
epsilon = (targetx[i] - mapx[i]).length epsilon = (targetx[i] - mapx[i]).length
if epsilon < threshold: if epsilon < threshold:
epsilon = 0.0 epsilon = 0.0
dx[0] += [x[i] + 0.5 * epsilon * Vector((1, 0, 0))] dx[0] += [x[i] + 0.5 * epsilon * Vector((1, 0, 0))]
dx[1] += [x[i] + 0.5 * epsilon * Vector((-1, 0, 0))] dx[1] += [x[i] + 0.5 * epsilon * Vector((-1, 0, 0))]
dx[2] += [x[i] + 0.5 * epsilon * Vector((0, 1, 0))] dx[2] += [x[i] + 0.5 * epsilon * Vector((0, 1, 0))]
dx[3] += [x[i] + 0.5 * epsilon * Vector((0, -1, 0))] dx[3] += [x[i] + 0.5 * epsilon * Vector((0, -1, 0))]
dx[4] += [x[i] + 0.5 * epsilon * Vector((0, 0, 1))] dx[4] += [x[i] + 0.5 * epsilon * Vector((0, 0, 1))]
dx[5] += [x[i] + 0.5 * epsilon * Vector((0, 0, -1))] dx[5] += [x[i] + 0.5 * epsilon * Vector((0, 0, -1))]
for j in range(0, 6): for j in range(0, 6):
apply_vert_coords(ob_1, mesh_1_key_verts, dx[j]) apply_vert_coords(ob_1, mesh_1_key_verts, dx[j])
dx[j] = extract_mapped_coords(ob_1, mesh_1_key_verts) dx[j] = extract_mapped_coords(ob_1, mesh_1_key_verts)
# take a step in the direction of the gradient # take a step in the direction of the gradient
for i in range(0, len(mesh_1.vertices)): for i in range(0, len(mesh_1.vertices)):
epsilon = (targetx[i] - mapx[i]).length epsilon = (targetx[i] - mapx[i]).length
if epsilon >= threshold: if epsilon >= threshold:
Gx = list((dx[0][i] - dx[1][i]) / epsilon) Gx = list((dx[0][i] - dx[1][i]) / epsilon)
Gy = list((dx[2][i] - dx[3][i]) / epsilon) Gy = list((dx[2][i] - dx[3][i]) / epsilon)
Gz = list((dx[4][i] - dx[5][i]) / epsilon) Gz = list((dx[4][i] - dx[5][i]) / epsilon)
G = Matrix((Gx, Gy, Gz)) G = Matrix((Gx, Gy, Gz))
x[i] += G * (targetx[i] - mapx[i]) x[i] += G * (targetx[i] - mapx[i])
apply_vert_coords(ob_1, mesh_1_key_verts, x ) apply_vert_coords(ob_1, mesh_1_key_verts, x)
ob_1.active_shape_key.vertex_group = vgroup ob_1.active_shape_key.vertex_group = vgroup
# set the new shape key value to 1.0, so we see the result instantly # set the new shape key value to 1.0, so we see the result instantly
ob_1.active_shape_key.value = 1.0 ob_1.active_shape_key.value = 1.0
#mesh_1.update() #mesh_1.update()
ob_1.show_only_shape_key = False ob_1.show_only_shape_key = False
class add_corrective_pose_shape(bpy.types.Operator):
class add_corrective_pose_shape(bpy.types.Operator):
"""Adds first object as shape to second object for the current pose """ \ """Adds first object as shape to second object for the current pose """ \
"""while maintaining modifiers """ \ """while maintaining modifiers """ \
"""(i.e. anisculpt, avoiding crazy space) Beware of slowness!""" """(i.e. anisculpt, avoiding crazy space) Beware of slowness!"""
bl_idname = "object.add_corrective_pose_shape" bl_idname = "object.add_corrective_pose_shape"
bl_label = "Add object as corrective pose shape" bl_label = "Add object as corrective pose shape"
...@@ -196,22 +197,23 @@ class add_corrective_pose_shape(bpy.types.Operator): ...@@ -196,22 +197,23 @@ class add_corrective_pose_shape(bpy.types.Operator):
else: else:
source = selection[0] source = selection[0]
func_add_corrective_pose_shape( source, target) func_add_corrective_pose_shape(source, target)
return {'FINISHED'} return {'FINISHED'}
def func_object_duplicate_flatten_modifiers(ob, scene): def func_object_duplicate_flatten_modifiers(scene, obj):
mesh = ob.to_mesh( bpy.context.scene, True, 'PREVIEW' ) mesh = obj.to_mesh(scene, True, 'PREVIEW')
name = ob.name + "_clean" name = obj.name + "_clean"
new_object = bpy.data.objects.new( name, mesh) new_object = bpy.data.objects.new(name, mesh)
new_object.data = mesh new_object.data = mesh
scene.objects.link(new_object) scene.objects.link(new_object)
return new_object return new_object
class object_duplicate_flatten_modifiers(bpy.types.Operator):
class object_duplicate_flatten_modifiers(bpy.types.Operator):
'''Duplicates the selected object with modifiers applied''' '''Duplicates the selected object with modifiers applied'''
bl_idname = "object.object_duplicate_flatten_modifiers" bl_idname = "object.object_duplicate_flatten_modifiers"
bl_label = "Duplicate and apply all" bl_label = "Duplicate and apply all"
...@@ -222,8 +224,9 @@ class object_duplicate_flatten_modifiers(bpy.types.Operator): ...@@ -222,8 +224,9 @@ class object_duplicate_flatten_modifiers(bpy.types.Operator):
def execute(self, context): def execute(self, context):
scene = context.scene scene = context.scene
obj_act = context.active_object obj_act = context.active_object
new_object = func_object_duplicate_flatten_modifiers(obj_act, context.scene)
new_object = func_object_duplicate_flatten_modifiers(obj_act, scene)
# setup the context # setup the context
bpy.ops.object.select_all(action='DESELECT') bpy.ops.object.select_all(action='DESELECT')
...@@ -232,30 +235,29 @@ class object_duplicate_flatten_modifiers(bpy.types.Operator): ...@@ -232,30 +235,29 @@ class object_duplicate_flatten_modifiers(bpy.types.Operator):
return {'FINISHED'} return {'FINISHED'}
def unposeMesh(meshObToUnpose, meshObToUnposeWeightSrc, armatureOb): def unposeMesh(meshObToUnpose, meshObToUnposeWeightSrc, armatureOb):
psdMeshData = meshObToUnpose psdMeshData = meshObToUnpose
psdMesh = psdMeshData psdMesh = psdMeshData
I = Matrix() #identity matrix I = Matrix() # identity matrix
meshData = meshObToUnposeWeightSrc.data meshData = meshObToUnposeWeightSrc.data
mesh = meshData mesh = meshData
armData = armatureOb.data armData = armatureOb.data
pose = armatureOb.pose pose = armatureOb.pose
pbones = pose.bones pbones = pose.bones
for index, v in enumerate(mesh.vertices): for index, v in enumerate(mesh.vertices):
# above is python shortcut for:index goes up from 0 to tot num of # above is python shortcut for:index goes up from 0 to tot num of
# verts in mesh, with index incrementing by 1 each iteration # verts in mesh, with index incrementing by 1 each iteration
psdMeshVert = psdMesh[index] psdMeshVert = psdMesh[index]
listOfBoneNameWeightPairs = [] listOfBoneNameWeightPairs = []
for n in mesh.vertices[index].groups: for n in mesh.vertices[index].groups:
try: try:
name = meshObToUnposeWeightSrc.vertex_groups[n.group].name name = meshObToUnposeWeightSrc.vertex_groups[n.group].name
weight = n.weight weight = n.weight
...@@ -266,7 +268,7 @@ def unposeMesh(meshObToUnpose, meshObToUnposeWeightSrc, armatureOb): ...@@ -266,7 +268,7 @@ def unposeMesh(meshObToUnpose, meshObToUnposeWeightSrc, armatureOb):
break break
# ignore non-bone vertex groups # ignore non-bone vertex groups
if is_bone: if is_bone:
listOfBoneNameWeightPairs.append( [name, weight] ) listOfBoneNameWeightPairs.append([name, weight])
except: except:
print('error') print('error')
pass pass
...@@ -277,8 +279,8 @@ def unposeMesh(meshObToUnpose, meshObToUnposeWeightSrc, armatureOb): ...@@ -277,8 +279,8 @@ def unposeMesh(meshObToUnpose, meshObToUnposeWeightSrc, armatureOb):
totalWeight += pair[1] totalWeight += pair[1]
for pair in listOfBoneNameWeightPairs: for pair in listOfBoneNameWeightPairs:
if (totalWeight>0): #avoid divide by zero! if totalWeight > 0: # avoid divide by zero!
weightedAverageDictionary[pair[0]] = pair[1]/totalWeight weightedAverageDictionary[pair[0]] = pair[1] / totalWeight
else: else:
weightedAverageDictionary[pair[0]] = 0 weightedAverageDictionary[pair[0]] = 0
...@@ -298,7 +300,7 @@ def unposeMesh(meshObToUnpose, meshObToUnposeWeightSrc, armatureOb): ...@@ -298,7 +300,7 @@ def unposeMesh(meshObToUnpose, meshObToUnposeWeightSrc, armatureOb):
m = pbone.matrix_channel.copy() m = pbone.matrix_channel.copy()
#m.transpose() #m.transpose()
sigma += (m - I) * vertexWeight sigma += (m - I) * vertexWeight
else: else:
pass pass
#~ print("no key for bone " + pbone.name) #~ print("no key for bone " + pbone.name)
...@@ -308,45 +310,42 @@ def unposeMesh(meshObToUnpose, meshObToUnposeWeightSrc, armatureOb): ...@@ -308,45 +310,42 @@ def unposeMesh(meshObToUnpose, meshObToUnposeWeightSrc, armatureOb):
psdMeshVert.co = psdMeshVert.co * sigma psdMeshVert.co = psdMeshVert.co * sigma
def func_add_corrective_pose_shape_fast(source, target): def func_add_corrective_pose_shape_fast(source, target):
reset_transform(target) reset_transform(target)
# If target object doesn't have Basis shape key, create it. # If target object doesn't have Basis shape key, create it.
if not target.data.shape_keys: if not target.data.shape_keys:
basis = target.shape_key_add() basis = target.shape_key_add()
basis.name = "Basis" basis.name = "Basis"
target.data.update() target.data.update()
key_index = target.active_shape_key_index key_index = target.active_shape_key_index
if key_index == 0: if key_index == 0:
# Insert new shape key # Insert new shape key
new_shapekey = target.shape_key_add() new_shapekey = target.shape_key_add()
new_shapekey.name = "Shape_" + source.name new_shapekey.name = "Shape_" + source.name
key_index = len(target.data.shape_keys.key_blocks)-1 key_index = len(target.data.shape_keys.key_blocks) - 1
target.active_shape_key_index = key_index target.active_shape_key_index = key_index
# else, the active shape will be used (updated) # else, the active shape will be used (updated)
target.show_only_shape_key = True target.show_only_shape_key = True
shape_key_verts = target.data.shape_keys.key_blocks[ key_index ].data shape_key_verts = target.data.shape_keys.key_blocks[key_index].data
try: try:
vgroup = target.active_shape_key.vertex_group vgroup = target.active_shape_key.vertex_group
target.active_shape_key.vertex_group = '' target.active_shape_key.vertex_group = ''
except: except:
print("blub")
pass pass
# copy the local vertex positions to the new shape # copy the local vertex positions to the new shape
verts = source.data.vertices verts = source.data.vertices
for n in range( len(verts)): for n in range(len(verts)):
shape_key_verts[n].co = verts[n].co shape_key_verts[n].co = verts[n].co
# go to all armature modifies and unpose the shape # go to all armature modifies and unpose the shape
...@@ -357,29 +356,28 @@ def func_add_corrective_pose_shape_fast(source, target): ...@@ -357,29 +356,28 @@ def func_add_corrective_pose_shape_fast(source, target):
n.use_deform_preserve_volume = False n.use_deform_preserve_volume = False
n.use_vertex_groups = True n.use_vertex_groups = True
armature = n.object armature = n.object
unposeMesh( shape_key_verts, target, armature) unposeMesh(shape_key_verts, target, armature)
break break
# set the new shape key value to 1.0, so we see the result instantly # set the new shape key value to 1.0, so we see the result instantly
target.data.shape_keys.key_blocks[target.active_shape_key_index].value = 1.0 target.active_shape_key.value = 1.0
try: try:
target.active_shape_key.vertex_group = vgroup target.active_shape_key.vertex_group = vgroup
except: except:
#~ print("bluba")
pass pass
target.show_only_shape_key = False target.show_only_shape_key = False
target.data.update() target.data.update()
class add_corrective_pose_shape_fast(bpy.types.Operator): class add_corrective_pose_shape_fast(bpy.types.Operator):
'''Adds 1st object as shape to 2nd object as pose shape (only 1 armature)''' """Adds 1st object as shape to 2nd object as pose shape
(only 1 armature)"""
bl_idname = "object.add_corrective_pose_shape_fast" bl_idname = "object.add_corrective_pose_shape_fast"
bl_label = "Add object as corrective shape faster" bl_label = "Add object as corrective shape faster"
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
return context.active_object != None return context.active_object != None
...@@ -396,25 +394,26 @@ class add_corrective_pose_shape_fast(bpy.types.Operator): ...@@ -396,25 +394,26 @@ class add_corrective_pose_shape_fast(bpy.types.Operator):
else: else:
source = selection[0] source = selection[0]
func_add_corrective_pose_shape_fast( source, target) func_add_corrective_pose_shape_fast(source, target)
return {'FINISHED'} return {'FINISHED'}
# -----------------------------------------------------------------------------
# GUI
## GUI
def vgroups_draw(self, context): def vgroups_draw(self, context):
layout = self.layout layout = self.layout
layout.operator("object.object_duplicate_flatten_modifiers", layout.operator("object.object_duplicate_flatten_modifiers",
text='Create duplicate for editing' ) text='Create duplicate for editing')
layout.operator("object.add_corrective_pose_shape_fast", layout.operator("object.add_corrective_pose_shape_fast",
text='Add as corrective pose-shape (fast, armatures only)', text='Add as corrective pose-shape (fast, armatures only)',
icon='COPY_ID') # icon is not ideal icon='COPY_ID') # icon is not ideal
layout.operator("object.add_corrective_pose_shape", layout.operator("object.add_corrective_pose_shape",
text='Add as corrective pose-shape (slow, all modifiers)', text='Add as corrective pose-shape (slow, all modifiers)',
icon='COPY_ID') # icon is not ideal icon='COPY_ID') # icon is not ideal
def modifiers_draw(self, context): def modifiers_draw(self, context):
pass pass
...@@ -423,8 +422,9 @@ def modifiers_draw(self, context): ...@@ -423,8 +422,9 @@ def modifiers_draw(self, context):
def register(): def register():
bpy.utils.register_module(__name__) bpy.utils.register_module(__name__)
bpy.types.MESH_MT_shape_key_specials.append( vgroups_draw ) bpy.types.MESH_MT_shape_key_specials.append(vgroups_draw)
bpy.types.DATA_PT_modifiers.append( modifiers_draw ) bpy.types.DATA_PT_modifiers.append(modifiers_draw)
def unregister(): def unregister():
bpy.utils.unregister_module(__name__) bpy.utils.unregister_module(__name__)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment