Skip to content

Instantly share code, notes, and snippets.

@zeffii
Last active August 29, 2015 14:19
Show Gist options
  • Save zeffii/3b717a1717878f403e86 to your computer and use it in GitHub Desktop.
Save zeffii/3b717a1717878f403e86 to your computer and use it in GitHub Desktop.
triangulated delauny vertex colours from image
# Dealga McArdle 2015 April 22.
import bpy
import mathutils
from mathutils import Vector, Matrix
D = bpy.data
# access image, get pixels
img_name = 'Buzz_Aldrin_on_moon-thumb-590x499-82071.jpg'
img = D.images[img_name]
# flat r,g,b,a,r,g,b,a...
pxs = list(img.pixels)
# nested [[r,g,b,a],[r,g,b,a],...]
num_values = len(pxs)
nested_rgba_list = [pxs[i:i+4] for i in range(num_values)[::4]]
# px dims
px_wide = img.size[0] # 590
px_high = img.size[1] # 499
# mesh dimensions, match these with your target mesh.
# protip: use import image as planes addon
# match the size of your triangulated mesh to the rect
# generated by image as plane
x_wide = 1.18236
y_high = 1.0
# first how wide/tall is a pixel in this scene?
real_x = x_wide / px_wide
real_y = y_high / px_high
offs_x = real_x / 2
offs_y = real_y / 2
def idx_to_co(idx, width):
# the image starts bottom left
r = int(idx / width)
c = idx % width
return r, c
def generate_tree(vt):
size = len(vt)
kd = mathutils.kdtree.KDTree(size)
for i, vtx in enumerate(vt):
kd.insert(Vector(vtx), i)
kd.balance()
return kd
def get_pretend_pixels(indexed_pixels):
# let's pretend we get colour from the middle of the pixel
# this means offsetting the coordinates by half the real pixel sizes
pretend_pixels = []
add_pretend_px = pretend_pixels.append
for i, px in enumerate(indexed_pixels):
r, c = idx_to_co(i, px_wide)
x = offs_x + (c * real_x)
y = offs_y + (r * real_y)
add_pretend_px([x, y, 0])
return pretend_pixels
pretend_pixels = get_pretend_pixels(nested_rgba_list)
kdtree = generate_tree(pretend_pixels)
obj = bpy.data.objects['Sv_0.001']
mesh = obj.data
# for every vertex in delauny mesh,
# find its closest ordered px idx, (this gives us idx->color)
nearest_fake_vertex = []
add_fake = nearest_fake_vertex.append
for i, vtx in enumerate(mesh.vertices):
co, index, dist = kdtree.find(vtx.co)
add_fake(index)
color_layer = mesh.vertex_colors['Col']
# for every face in data.polygons
# for every indexed vertex of the face
# assign associated colour to colourmap index.
i = 0
for poly in mesh.polygons:
print(poly.loop_indices)
for idx in poly.loop_indices:
loop = mesh.loops[idx]
v = loop.vertex_index
f = nearest_fake_vertex[v]
color = nested_rgba_list[f]
color_layer.data[i].color = color[:3]
i +=1
@zeffii
Copy link
Author

zeffii commented Apr 23, 2015

note, this doesn't create the Vertex plane / Triangulation for you, that's a separate step you do before all this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment