This is a Blender add-on to transfer ShapeKeys between objects using compatible UV maps for vertex matching.
With respect to the integrated Blender method, based on triangle search in the proximity, this method offers advantages and disadvantages:
- (GOOD) This method doesn't require the geometries to be of a similar shape or perfectly overlapped.
- (GOOD) If the UVs are well-made, it might work better in problematic concave areas like nose and ears.
- (BAD) UV editing is a pain!
- Download a zip release (
sktransfer-x.y.zip
) - Install the zip through the Menu
Edit -> Preferences ...
and theAdd-ons
tab.
A short video tutorial can be found here: https://www.youtube.com/watch?v=DAWjtayuwE0
Transferring a ShapeKey from a Source to a Destination object works if both have active UV layers able to show the same texture correctly.
In Object mode:
- Select (
click
) the Source object - Select (
click
) the ShapeKey to transfer - Add to selection (
shift+Click
) the Destination object - Search (
F3
)Transfer ShapeKey via UV
- or, from the Python console:
bpy.ops.object.transfer_shapekey_via_uv()
- or, from the Python console:
Done. The Destination object should have a new ShapeKey with the same name of the source one.
Actually, during transfer, a texture is not really needed. It is just for the user to check if the UVs are comparable.
Parameters:
buffer_size
(int) is the size of the intermediate buffer used to store ShapeKey deltas. By default it is set at 256. Increase it if you have a very dense topology and you notice bad transfer in areas with many close pixels.relative_to_normals
(bool) if True, the ShapyKey offsets will be computed and applied relatively to the normals. Otherwise, by default, vertices offset is simply copied in mesh coordinate space.save_debug_images
(bool) if True activates the creation of PNG images for visual debug (see later section).
A short video showing the addon in action: https://www.youtube.com/watch?v=IZ5r9AO-G30
First example transferring SHapeKeys between UV spheres created with different segments and rings. The ShapeKeys are displacing segments outward the sphere centers.
Source | Destination | |
---|---|---|
Basis | ||
UVs | ||
ShapeKey: NorthPole | ||
ShapeKey: WaterUp |
The Source is the default Suzanne. The destination is a Suzanne after some scalings and a subdivision, all of them applied to the geometry.
Source | Destination | |
---|---|---|
Basis | ||
UVs | ||
ShapeKey: BigEars | ||
ShapeKey: BrowsUp |
The source object is actually a FLAME model, automatically generated and textured. The destination is again Suzanne.
For this case, I edited the UV of the monkey and tried to match the texture returned by FLAME. Given the strong difference in the two models, I couldn't get anything useful on the upper part of the face, but I focussed on the mouth and the addon was able to transfer a smile.
Source | Destination | |
---|---|---|
Basis | ||
UVs | It's a mess! I focused mainly on the mouth. | |
ShapeKey: Smile |
The source object is actually a FLAME model, automatically generated and textured. The destination is a FLAME model (but without ShapeKeys) generated via the EMOCA framework (3D mesh is automatically generated from video analysis).
For this case, the UV maps are already perfectly compatible.
Source | Destination | |
---|---|---|
Basis | ||
UVs | ||
ShapeKey: Exp1 |
-
[0.2] - 2024-01-23
- Optionally, ShapeKey deltas are computed relatively to vertex normals.
-
[0.1] - 2024-01-13
- First public release
- Fill corners of the transfer buffer
- Panel and buttons
- A scaling parameter to modulate delta transfer
- Move the visual debug as addon option rather than operator parameter
Option 1:
- Clone this repository
- Open a Terminal
- Set env variable:
export BLENDER_USER_SCRIPTS="path/to/Transfer-ShapeKeys-Via-UV-Blender-Addon/BlenderScripts"
- Run Blender:
path/to/blender.app/Contents/MacOS/blender
Option 2:
- Clone this repository
- Menu
Edit -> Preferences ...
- Tab
File Paths
- Panel
Script Directories
- Add directory
Transfer-ShapeKeys-Via-UV-Blender-Addon/BlenderScripts
cd BlenderScripts/addons
zip -r sktransfer-x.y.zip sktransfer -x "**/.DS_Store" "**/__pycache__/*"
WARNING: if you use the save_debug_images
option, the PIL module (pip install pillow
) must be installed in the Blender internal Python interpreter.
E.g., on a Mac, from a Terminal:
> /Applications/blender-3.6.7/Blender.app/Contents/Resources/3.6/python/bin/python3.10 -m pip install pillow
If the operator parameter save_debug_images
is set to True, three images will be saved on disk in the current working directory:
{SourceObjectName}-sk{number}-uv{number}-{buffer_size}x{buffer_size}-counts.png
- Every pixel is colored grey if a vertex delta was saved. The brighter, more deltas were accumulated and averaged.
{SourceObjectName}-sk{number}-uv{number}-{buffer_size}x{buffer_size}-deltas.png
- The accumulated XYZ ShapeKey delta values visualized as RGB colors.
{SourceObjectName}-sk{number}-uv{number}-{buffer_size}x{buffer_size}-filled.png
- The delta buffer after triangulation and interpolated triangle filling.
-
The project has been developed at the Affective Computing group of the German Research Center for Artificial Intelligence (DFKI)
-
The development was funded by the following research projects:
- SocialWear (BMBF, cost action 22132)
- BIGEKO (BMBF, grant number 16SV9093)
-
The
delaunay
module for triangularization is distributed under the MIT license (seeLICENSE-delaunay.txt
) and was originally retreieved from https://github.com/mkirc/delaunay. Many thanks to mkirc for the bug fixes! -
Triangle filling routines were inspired by this page: http://www.sunshine2k.de/coding/java/TriangleRasterization/TriangleRasterization.html
- My version includes vertex value interpolation