Skip to content

Instantly share code, notes, and snippets.

@percentcer
Last active October 4, 2022 23:32
Show Gist options
  • Save percentcer/014421271f83b7bc43166768483ef808 to your computer and use it in GitHub Desktop.
Save percentcer/014421271f83b7bc43166768483ef808 to your computer and use it in GitHub Desktop.
A little script I wrote that helps with 2D puppet texturing (Blender)
# assumes you have a mesh selected
# assumes your image ref is on the XZ plane
# assumes your verts are also on the XZ plane
import bpy
import bmesh
# Get active mesh
ob = bpy.context.object
me = ob.data
if me.is_editmode:
bm = bmesh.from_edit_mesh(me)
else:
bm = bmesh.new()
bm.from_mesh(me)
# get the collection in which it resides (to get the image reference)
collection = ob.users_collection[0]
imgref = None
for obj in collection.objects:
if obj.type == "EMPTY":
imgref = obj
# determine world space dimensions of the image reference
(width, height) = imgref.data.size
if height > width:
(unitwidth, unitheight) = (imgref.empty_display_size * (width/height), imgref.empty_display_size)
else:
(unitwidth, unitheight) = (imgref.empty_display_size, imgref.empty_display_size * (height/width))
print('image: (%.3f, %.3f)' % (unitwidth, unitheight))
# loop through poly and find the verts + uvs
# do some math to get world space position of UV
# world space must be offset by half the image width and height to align world origin with UV origin
# then simply use (pos.x / unitwidth, pos.y / unitheight) for UV value
uv_lay = bm.loops.layers.uv.active
for face in bm.faces:
for loop in face.loops:
vert = loop.vert
vertWorld = ob.matrix_world @ vert.co
(wu, _, wv) = vertWorld
wu += unitwidth * 0.5
wv += unitheight * 0.5
wu = wu / unitwidth
wv = wv / unitheight
print('u: %.3f' % wu, ' v: %.3f' % wv)
loop[uv_lay].uv = (wu, wv)
if bm.is_wrapped:
bmesh.update_edit_mesh(me, False, False)
else:
bm.to_mesh(me)
me.update()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment