I'm working with a 3D mesh (non-convex) and would like to achieve a similar effect as shown in the following video:


From: https://youtu.be/Z0Qiq22PRWQ?t=1544

In other words, if I'm starting with a mesh that looks like this: enter image description here

I would like to flatten/unwrap/morph/project its vertices to a flat plane mesh like this: enter image description here

I'm looking for a general process of how this could be done. An example, e.g with Suzanne, would be helpful.

I recognize that this is somewhat similar to UV-unwrapping. However, it's not clear to me how one would go about creating flat 3D mesh vertices from the UV map data.

This could also be done by moving each mesh vertex to the desired position on a plane, but I wonder if there is a more efficient method.

  • 2
    $\begingroup$ I think this is the answer you are looking for: blender.stackexchange.com/questions/40157/… $\endgroup$
    – cgslav
    Aug 26 '19 at 20:24
  • $\begingroup$ @cgslav Thank you for the link. That looks very close to what I'm looking for. I will give it a try $\endgroup$
    – Justas
    Aug 26 '19 at 20:51

This script can help you to prepare the animation:

enter image description here

The script should be run in object mode.

The script will report UV map coordinates into a shape key, so that you can animate the shape key.

You need to prepare the mesh: mark seams and make your UV map (you may need to move rotate, scale the uv isles as you wish). If you modify the UV map, run the script again so that the shape key will be updated.

The seams are important because the script will use them to split the original mesh (so your mesh will be modified by the script).

These splits are done because we want each vertex to have only one correspondent uv vertex in the uv map.

It is commented, below, but if some more details are needed, please ask:

import bpy
import bmesh
from mathutils import Vector

print( "------------" )

shape_key_name = "test"
object_name = "Suzanne"
uv_map_name = "UVMap"

obj = bpy.data.objects[object_name]

# Prepare the shape keys

if not obj.data.shape_keys:
    obj.shape_key_add( name = "Basis" )

shape_key = obj.data.shape_keys.key_blocks.get( shape_key_name )

if shape_key:
    obj.shape_key_remove( shape_key )

shape_key = obj.shape_key_add( name = shape_key_name )

# Cut the mesh

# Get a bmesh from the object mesh
bm = bmesh.new()
bm.from_mesh( obj.data )

# Prepare the mesh

# Split edges that have seam and link to 2 faces
edges = [e for e in bm.edges if e.seam and len(e.link_faces) == 2]
bmesh.ops.split_edges( bm, edges = edges )

# Give the new geometry back to the object
bm.to_mesh( obj.data )

# Get the uv map
uv_map = obj.data.uv_layers[uv_map_name]

# Assign the coordinates to the shape key
for loop, uv_data in zip( obj.data.loops, uv_map.data ):
    uv = uv_data.uv
    vertex_index = loop.vertex_index
    shape_key.data[vertex_index].co = Vector( (uv.x, 0, uv.y) )

  • $\begingroup$ Wow. This is really cool. You basically made a UV map -> 2D mesh converter $\endgroup$
    – Justas
    Aug 27 '19 at 19:24
  • 1
    $\begingroup$ @Justas FYI there is an API to convert a UV map to mesh. But we can't use it here as we need vertex order coherency for shape keys. $\endgroup$
    – lemon
    Aug 28 '19 at 5:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.