[Bf-extensions-cvs] [e83541d4] master: animation_add_corrective_shape_key: return to release: T65258 38475602b2ef
meta-androcto
noreply at git.blender.org
Sun Jun 23 12:42:47 CEST 2019
Commit: e83541d42c71bfb689acf9a53a6eb66b0c190451
Author: meta-androcto
Date: Sun Jun 23 20:42:30 2019 +1000
Branches: master
https://developer.blender.org/rBACe83541d42c71bfb689acf9a53a6eb66b0c190451
animation_add_corrective_shape_key: return to release: T65258 38475602b2ef
===================================================================
D animation_add_corrective_shape_key.py
===================================================================
diff --git a/animation_add_corrective_shape_key.py b/animation_add_corrective_shape_key.py
deleted file mode 100644
index c0824168..00000000
--- a/animation_add_corrective_shape_key.py
+++ /dev/null
@@ -1,530 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-# <pep8-80 compliant>
-
-bl_info = {
- "name": "Corrective Shape Keys",
- "author": "Ivo Grigull (loolarge), Tal Trachtman", "Tokikake"
- "version": (1, 1, 0),
- "blender": (2, 80, 0),
- "location": "Object Data > Shape Keys (Search: corrective) ",
- "description": "Creates a corrective shape key for the current pose",
- "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
- "Scripts/Animation/Corrective_Shape_Key",
- "category": "Animation",
-}
-
-"""
-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
-- Converted to Blender 2.8 by Tokikake
-("fast" option was removed, add new "delta" option
-which count currently used shape key values of armature mesh when transfer)
-
-Limitations and new delta option for 2.8
-- Target mesh may not have any transformation at object level,
- it will be set to zero.
-
-- new "delta" option usage, when you hope to make new shape-key with keep currently visible other shape keys value.
- it can generate new shape key, with value as 1.00. then deform target shape as soruce shape with keep other shape key values relative.
-
-- If overwrite shape key,<select active shape key of target as non "base shape">
- current shape key value is ignored and turn as 1.00.
-
- then if active shape key was driven (bone rotation etc), you may get un-expected result. When transfer, I recommend, keep set active-shape key as base . so transfered shape key do not "overwrite". but generate new shape key.
- if active-shape key have no driver, you can overwrite it (but as 1.00 value )
-"""
-
-
-import bpy
-from mathutils import Vector, Matrix
-
-iterations = 20
-threshold = 1e-16
-
-def update_mesh(ob):
- depth = bpy.context.evaluated_depsgraph_get()
- depth.update()
- ob.update_tag()
- bpy.context.view_layer.update()
- ob.data.update()
-
-
-def reset_transform(ob):
- ob.matrix_local.identity()
-
-# this version is for shape_key data
-def extract_vert_coords(verts):
- return [v.co.copy() for v in verts]
-
-def extract_mapped_coords(ob, shape_verts):
- depth = bpy.context.evaluated_depsgraph_get()
- eobj = ob.evaluated_get(depth)
- mesh = bpy.data.meshes.new_from_object(eobj)
-
- # cheating, the original mapped verts happen
- # to be at the end of the vertex array
- verts = mesh.vertices
- #arr = [verts[i].co.copy() for i in range(len(verts) - totvert, len(verts))]
- arr = [verts[i].co.copy() for i in range(0, len(verts))]
- mesh.user_clear()
- bpy.data.meshes.remove(mesh)
- update_mesh(ob)
- return arr
-
-
-
-def apply_vert_coords(ob, mesh, x):
- for i, v in enumerate(mesh):
- v.co = x[i]
- update_mesh(ob)
-
-
-def func_add_corrective_pose_shape(source, target, flag):
-
- ob_1 = target
- mesh_1 = target.data
- ob_2 = source
- mesh_2 = source.data
-
- reset_transform(target)
-
- # If target object doesn't have Base shape key, create it.
- if not mesh_1.shape_keys:
- basis = ob_1.shape_key_add()
- basis.name = "Basis"
- update_mesh(ob_1)
- ob_1.active_shape_key_index = 0
- ob_1.show_only_shape_key = False
- key_index = ob_1.active_shape_key_index
- print(ob_1)
- print(ob_1.active_shape_key)
- active_key_name = ob_1.active_shape_key.name
-
- if (flag == True):
- # Make mix shape key from currently used shape keys
- if not key_index == 0:
- ob_1.active_shape_key.value = 0
- mix_shape = ob_1.shape_key_add(from_mix = True)
- mix_shape.name = "Mix_shape"
- update_mesh(ob_1)
- keys = ob_1.data.shape_keys.key_blocks.keys()
- ob_1.active_shape_key_index = keys.index(active_key_name)
-
- print("active_key_name: ", active_key_name)
-
- if key_index == 0:
- new_shapekey = ob_1.shape_key_add()
- new_shapekey.name = "Shape_" + ob_2.name
- update_mesh(ob_1)
- keys = ob_1.data.shape_keys.key_blocks.keys()
- ob_1.active_shape_key_index = keys.index(new_shapekey.name)
-
- # else, the active shape will be used (updated)
-
- ob_1.show_only_shape_key = True
-
- vgroup = 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 = ob_1.active_shape_key.data
-
- x = extract_vert_coords(mesh_1_key_verts)
-
- targetx = extract_vert_coords(mesh_2.vertices)
-
- for iteration in range(0, iterations):
- dx = [[], [], [], [], [], []]
-
- mapx = extract_mapped_coords(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 * 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[3] += [x[i] + 0.5 * epsilon * Vector((0, -1, 0))]
- dx[4] += [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):
- apply_vert_coords(ob_1, mesh_1_key_verts, dx[j])
- dx[j] = extract_mapped_coords(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 = Matrix((Gx, Gy, Gz))
- Delmorph = (targetx[i] - mapx[i])
- x[i] += G @ Delmorph
-
- apply_vert_coords(ob_1, mesh_1_key_verts, x)
-
- ob_1.show_only_shape_key = True
-
- if (flag == True):
- # remove delta of mix-shape key values from new shape key
- key_index = ob_1.active_shape_key_index
- active_key_name = ob_1.active_shape_key.name
- shape_data = ob_1.active_shape_key.data
- mix_data = mix_shape.data
- for i in range(0, len(mesh_1.vertices)):
- shape_data[i].co = mesh_1.vertices[i].co + shape_data[i].co - mix_data[i].co
- update_mesh(ob_1)
-
- ob_1.active_shape_key_index = ob_1.data.shape_keys.key_blocks.keys().index("Mix_shape")
- bpy.ops.object.shape_key_remove()
- ob_1.active_shape_key_index = ob_1.data.shape_keys.key_blocks.keys().index(active_key_name)
- ob_1.data.update()
- ob_1.show_only_shape_key = False
-
- 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
- update_mesh(ob_1)
-
-
-
-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"
-
- @classmethod
- def poll(cls, context):
- return context.active_object is not None
-
- def execute(self, context):
- selection = context.selected_objects
- if len(selection) != 2:
- self.report({'ERROR'}, "Select source and target objects")
- return {'CANCELLED'}
-
- target = context.active_object
- if context.active_object == selection[0]:
- source = selection[1]
- else:
- source = selection[0]
-
- delta_flag = False
-
- func_add_corrective_pose_shape(source, target, delta_flag)
-
- return {'FINISHED'}
-
-class add_corrective_pose_shape_delta (bpy.types.Operator):
- """Adds first object as shape to second object for the current pose """ \
- """while maintaining modifiers and currently used other shape keys""" \
- """with keep other shape key value, generate new shape key which deform to soruce shape """
-
- bl_idname = "object.add_corrective_pose_shape_delta"
- bl_label = "Add object as corrective pose shape delta"
-
- @classmethod
- def poll(cls, context):
- return context.active_object is not None
-
- def execute(self, context):
- selection = context.selected_objects
- if len(selection) != 2:
- self.report({'ERROR'}, "Select source and target objects")
- return {'CANCELLED'}
-
- target = conte
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-extensions-cvs
mailing list