[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