[Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [1189] contrib/py/scripts/addons/ add_corrective_shape_key.py: working version contrib/py/scripts/addons/ add_corrective_shape_key.py

Brendon Murphy meta.androcto1 at gmail.com
Tue Nov 23 10:09:25 CET 2010


Revision: 1189
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-extensions&revision=1189
Author:   meta-androcto
Date:     2010-11-23 10:09:25 +0100 (Tue, 23 Nov 2010)

Log Message:
-----------
working version contrib/py/scripts/addons/add_corrective_shape_key.py

Modified Paths:
--------------
    contrib/py/scripts/addons/add_corrective_shape_key.py

Modified: contrib/py/scripts/addons/add_corrective_shape_key.py
===================================================================
--- contrib/py/scripts/addons/add_corrective_shape_key.py	2010-11-22 22:56:11 UTC (rev 1188)
+++ contrib/py/scripts/addons/add_corrective_shape_key.py	2010-11-23 09:09:25 UTC (rev 1189)
@@ -16,445 +16,480 @@
 #
 # ##### END GPL LICENSE BLOCK #####
 
+# This script transfer the shape from an object (base mesh without
+# modifiers) to another object with modifiers (i.e. posed Armature).
+# Only two objects must be selected.
+# The first selected object will be added to the second selected
+# object as a new shape key.
+#
+# Original 2.4x script by ? (brecht?)
+# Unpose-function reused from a script by Tal Trachtman in 2007 http://www.apexbow.com/randd.html
+# Converted to Blender 2.5 by Ivo Grigull
+#
+# Limitations:
+#	  Target mesh may not have any transformation at object level, it will be set to zero.
+#     Fast/Armature method does not work with Bone envelopes or dual quaternions, both settings will be disabled in the modifier
+
+
 bl_addon_info = {
     'name': 'Corrective shape keys',
     'author': 'Ivo Grigull, Tal Trachtman',
-    'version': (1,0),
-    'blender': (2, 5, 3),
-    'api': 31667,
-    'location': 'Object Data > Shape Keys (Search: corrective)',
-    'description': 'Transfer shape from object w/out modifier to object with modifier',
-    'wiki_url': 'http://wiki.blender.org/index.php/Extensions:2.5/Py/' \
-        'Scripts/Animation/Corrective_Shape_Key',
-    'tracker_url': 'https://projects.blender.org/tracker/index.php?'\
-        'func=detail&aid=22129&group_id=153&atid=468',
-    'category': 'Animation'}
+    'version': '1.0',
+    'blender': (2, 5, 5),
+    'location': '',
+    'description': 'Creates a corrective shape key for the current pose',
+    'url': '',
+    'category': 'Shape'}
 
-"""
-This script transfer the shape from an object (base mesh without
-modifiers) to another object with modifiers (i.e. posed Armature).
-Only two objects must be selected.
-The first selected object will be added to the second selected
-object as a new shape key.
-
-Original 2.4x script by ? (brecht?)
-Unpose-function reused from a script by Tal Trachtman in 2007 http://www.apexbow.com/randd.html
-Converted to Blender 2.5 by Ivo Grigull
-"""
-
 import bpy
 import mathutils
 
 
 iterations = 20
-threshold = 1e-6
+threshold = 1e-16
 
+def reset_transform(ob):
+	m = mathutils.Matrix()
+	ob.matrix_local = m	
 
-
 # flips rotation matrix
 def flip_matrix_direction(m):
-    mat = mathutils.Matrix()
-    
-    mat[0][0] = m[0][0]
-    mat[0][1] = m[1][0]
-    mat[0][2] = m[2][0]
-    
-    mat[1][0] = m[0][1]
-    mat[1][1] = m[1][1]
-    mat[1][2] = m[2][1]
-    
-    mat[2][0] = m[0][2]
-    mat[2][1] = m[1][2]
-    mat[2][2] = m[2][2]
-    
-    return mat 
+	mat = mathutils.Matrix()
+	
+	mat[0][0] = m[0][0]
+	mat[0][1] = m[1][0]
+	mat[0][2] = m[2][0]
+	
+	mat[1][0] = m[0][1]
+	mat[1][1] = m[1][1]
+	mat[1][2] = m[2][1]
+	
+	mat[2][0] = m[0][2]
+	mat[2][1] = m[1][2]
+	mat[2][2] = m[2][2]
+	
+	return mat 
 
 # this version is for shape_key data
 def extractX(ob, mesh):
-    x = []
-    
-    for i in range(0, len(mesh)):
-        v = mesh[i]
-        x += [mathutils.Vector(v.co)]
-    
-    return x
+	x = []
+	
+	for i in range(0, len(mesh)):
+		v = mesh[i]
+		x += [mathutils.Vector(v.co)]
+	
+	return x
 
 # this version is for mesh data
 def extractX_2(ob, mesh):
-    x = []
-    
-    for i in range(0, len(mesh.verts)):
-        v = mesh.verts[i]
-        x += [mathutils.Vector(v.co)]
-    
-    return x
+	x = []
+	
+	for i in range(0, len(mesh.vertices)):
+		v = mesh.vertices[i]
+		x += [mathutils.Vector(v.co)]
+	
+	return x
 
 def extractMappedX(ob, mesh):
-    totvert = len(mesh)
-    
-    mesh = ob.create_mesh( bpy.context.scene, True, 'PREVIEW' )
+	totvert = len(mesh)
+	
+	mesh = ob.create_mesh( bpy.context.scene, True, 'PREVIEW' )
 
-    x = []
+	x = []
 
-    # cheating, the original mapped verts happen
-    # to be at the end of the vertex array
-    for i in range(len(mesh.verts)-totvert, len(mesh.verts)):
-        v = mesh.verts[i]
-        x += [mathutils.Vector(v.co)]
+	# cheating, the original mapped verts happen
+	# to be at the end of the vertex array
+	for i in range(len(mesh.vertices)-totvert, len(mesh.vertices)):
+		v = mesh.vertices[i]
+		x += [mathutils.Vector(v.co)]
 
-    mesh.user_clear()
-    bpy.data.meshes.remove(mesh)    
-    
-    return x
+	mesh.user_clear()
+	bpy.data.meshes.remove(mesh)    
+	
+	return x
 
 def applyX(ob, mesh, x ):
-    for i in range(0, len(mesh)):
-        v = mesh[i]
-        v.co = x[i]
-    
-    ob.data.update()
-    
-    return x
+	for i in range(0, len(mesh)):
+		v = mesh[i]
+		v.co = x[i]
+	
+	ob.data.update()
+	
+	return x
 
 
 def func_add_corrective_pose_shape( source, target):
-    
-    ob_1   = target
-    mesh_1 = target.data
-    ob_2   = source
-    mesh_2 = source.data
+	
+	ob_1   = target
+	mesh_1 = target.data
+	ob_2   = source
+	mesh_2 = source.data
 
-    # If target object doesn't have Basis shape key, create it.
-    try:
-        num_keys = len( mesh_1.shape_keys.keys )
-    except:
-        basis = ob_1.add_shape_key()
-        basis.name = "Basis"
-        ob_1.data.update()
-        
-    
-    key_index = ob_1.active_shape_key_index
-    # Insert new shape key
-    if key_index == 0:
-        new_shapekey = ob_1.add_shape_key()
-        new_shapekey.name = "Shape_" + ob_2.name
-        new_shapekey_name = new_shapekey.name
-        
-        key_index = len(mesh_1.shape_keys.keys)-1
-        ob_1.active_shape_key_index = key_index
-        
-    # else, the active shape will be used (updated)
-                
-    ob_1.shape_key_lock = True
-    
-    mesh_1_key_verts = mesh_1.shape_keys.keys[ key_index ].data
-    
-    
-    x = extractX(ob_1, mesh_1_key_verts)
-    
-    targetx = extractX_2(ob_2, mesh_2)
-    
-    for iteration in range(0, iterations):
-        dx = [[], [], [], [], [], []]
-    
-        mapx = extractMappedX(ob_1, mesh_1_key_verts)
-        
-        # finite differencing in X/Y/Z to get approximate gradient
-        for i in range(0, len(mesh_1.verts)):
-            epsilon = (targetx[i] - mapx[i]).length
-            
-            if epsilon < threshold:
-                epsilon = 0.0
-            
-            dx[0] += [x[i] + 0.5*epsilon*mathutils.Vector([1, 0, 0])]
-            dx[1] += [x[i] + 0.5*epsilon*mathutils.Vector([-1, 0, 0])]
-            dx[2] += [x[i] + 0.5*epsilon*mathutils.Vector([0, 1, 0])]
-            dx[3] += [x[i] + 0.5*epsilon*mathutils.Vector([0, -1, 0])]
-            dx[4] += [x[i] + 0.5*epsilon*mathutils.Vector([0, 0, 1])]
-            dx[5] += [x[i] + 0.5*epsilon*mathutils.Vector([0, 0, -1])]
-    
-        for j in range(0, 6):
-            applyX(ob_1, mesh_1_key_verts, dx[j] )
-            dx[j] = extractMappedX(ob_1, mesh_1_key_verts)
-    
-        # take a step in the direction of the gradient
-        for i in range(0, len(mesh_1.verts)):
-            epsilon = (targetx[i] - mapx[i]).length
-            
-            if epsilon >= threshold:
-                Gx = list((dx[0][i] - dx[1][i])/epsilon)
-                Gy = list((dx[2][i] - dx[3][i])/epsilon)
-                Gz = list((dx[4][i] - dx[5][i])/epsilon)
-                G = mathutils.Matrix(Gx, Gy, Gz)
-                G = flip_matrix_direction(G)
-    
-                x[i] += G*(targetx[i] - mapx[i])
-        
-        applyX(ob_1, mesh_1_key_verts, x )
-    
-    
-    # set the new shape key value to 1.0, so we see the result instantly
-    mesh_1.shape_keys.keys[ob_1.active_shape_key_index].value = 1.0
-    
-    #mesh_1.update()
-    ob_1.shape_key_lock = False
-    
+	reset_transform(target)
+	
+	# If target object doesn't have Basis shape key, create it.
+	try:
+		num_keys = len( mesh_1.shape_keys.keys )
+	except:
+		basis = ob_1.add_shape_key()
+		basis.name = "Basis"
+		ob_1.data.update()
+		
+	
+	key_index = ob_1.active_shape_key_index
+	# Insert new shape key
+	if key_index == 0:
+		new_shapekey = ob_1.add_shape_key()
+		new_shapekey.name = "Shape_" + ob_2.name
+		new_shapekey_name = new_shapekey.name
+		
+		key_index = len(mesh_1.shape_keys.keys)-1
+		ob_1.active_shape_key_index = key_index
+		
+	# else, the active shape will be used (updated)
+				
+	ob_1.show_only_shape_key = True
 
-class add_corrective_pose_shape(bpy.types.Operator):    
-    '''Adds first object as shape to second object for the current pose while maintaining modifiers (i.e. anisculpt, avoiding crazy space) Beware of slowness!!!'''
-    
-    bl_idname = "object.add_corrective_pose_shape"
-    bl_label = "Add object as corrective pose shape"
+	vgroup = ob_1.active_shape_key.vertex_group
+	ob_1.active_shape_key.vertex_group = ""
+		
+	mesh_1_key_verts = mesh_1.shape_keys.keys[ key_index ].data
+	
+	
+	x = extractX(ob_1, mesh_1_key_verts)
+	
+	targetx = extractX_2(ob_2, mesh_2)
+	
+	for iteration in range(0, iterations):
+		dx = [[], [], [], [], [], []]
+	
+		mapx = extractMappedX(ob_1, mesh_1_key_verts)
+		
+		# finite differencing in X/Y/Z to get approximate gradient
+		for i in range(0, len(mesh_1.vertices)):
+			epsilon = (targetx[i] - mapx[i]).length
+			
+			if epsilon < threshold:
+				epsilon = 0.0
+			
+			dx[0] += [x[i] + 0.5*epsilon*mathutils.Vector([1, 0, 0])]
+			dx[1] += [x[i] + 0.5*epsilon*mathutils.Vector([-1, 0, 0])]
+			dx[2] += [x[i] + 0.5*epsilon*mathutils.Vector([0, 1, 0])]
+			dx[3] += [x[i] + 0.5*epsilon*mathutils.Vector([0, -1, 0])]
+			dx[4] += [x[i] + 0.5*epsilon*mathutils.Vector([0, 0, 1])]
+			dx[5] += [x[i] + 0.5*epsilon*mathutils.Vector([0, 0, -1])]
+	
+		for j in range(0, 6):
+			applyX(ob_1, mesh_1_key_verts, dx[j] )
+			dx[j] = extractMappedX(ob_1, mesh_1_key_verts)
+	
+		# take a step in the direction of the gradient
+		for i in range(0, len(mesh_1.vertices)):
+			epsilon = (targetx[i] - mapx[i]).length
+			
+			if epsilon >= threshold:
+				Gx = list((dx[0][i] - dx[1][i])/epsilon)
+				Gy = list((dx[2][i] - dx[3][i])/epsilon)
+				Gz = list((dx[4][i] - dx[5][i])/epsilon)
+				G = mathutils.Matrix(Gx, Gy, Gz)
+				G = flip_matrix_direction(G)
+	
+				x[i] += (targetx[i] - mapx[i]) * G
+		
+		applyX(ob_1, mesh_1_key_verts, x )
+	
 
-    @classmethod
-    def poll(cls, context):
-        return context.active_object != None
+	ob_1.active_shape_key.vertex_group = vgroup
+	
+	# set the new shape key value to 1.0, so we see the result instantly
+	ob_1.active_shape_key.value = 1.0
+	
+	#mesh_1.update()
+	ob_1.show_only_shape_key = False
+	
 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-extensions-cvs mailing list