This will give you a dictionary of colors attached to each vertex:
in the form {vertex_index : [ color(s) ] ,... }
.
import bpy
mesh = bpy.context.active_object.data
color_layer = mesh.vertex_colors['Col']
tk = {}
i = 0
for poly in mesh.polygons:
for idx in poly.loop_indices:
loop = mesh.loops[idx]
v = loop.vertex_index
linked = tk.get(v, [])
linked.append(color_layer.data[i].color)
tk[v] = linked
i += 1
print(tk)
There are nicer ways to write this, using collections.defaultdict
. In this example I also import pprint
to nicely display the vertex<-->colors dict (tk
).
import bpy
from collections import defaultdict
tk = defaultdict(list)
mesh = bpy.context.active_object.data
color_layer = mesh.vertex_colors['Col']
i = 0
for poly in mesh.polygons:
for idx in poly.loop_indices:
loop = mesh.loops[idx]
color = color_layer.data[i].color
tk[loop.vertex_index].append(color)
i += 1
# you must cast this as a dict manually like tk = dict(tk) ,
# if you need it as a dict, but defaultdict will behave mostly the same
import pprint
pprint.pprint(tk)
This will get you as far as being able to average the colors. The output for this Col
(for sake of simplicity i use a 9 vertex planar surface)

is
{0: [Color((0.800000011920929, 0.4313725531101227, 0.04313725605607033))],
1: [Color((0.11372549086809158, 0.800000011920929, 0.0))],
2: [Color((0.27450981736183167, 0.27843138575553894, 0.27843138575553894))],
3: [Color((0.7882353067398071, 0.7921568751335144, 0.800000011920929))],
4: [Color((0.800000011920929, 0.4313725531101227, 0.04313725605607033)),
Color((0.27450981736183167, 0.27843138575553894, 0.27843138575553894))],
5: [Color((0.11372549086809158, 0.800000011920929, 0.0)),
Color((0.7882353067398071, 0.7921568751335144, 0.800000011920929))],
6: [Color((0.7882353067398071, 0.7921568751335144, 0.800000011920929)),
Color((0.27450981736183167, 0.27843138575553894, 0.27843138575553894))],
7: [Color((0.800000011920929, 0.4313725531101227, 0.04313725605607033)),
Color((0.11372549086809158, 0.800000011920929, 0.0))],
8: [Color((0.800000011920929, 0.4313725531101227, 0.04313725605607033)),
Color((0.11372549086809158, 0.800000011920929, 0.0)),
Color((0.7882353067398071, 0.7921568751335144, 0.800000011920929)),
Color((0.27450981736183167, 0.27843138575553894, 0.27843138575553894))]}
To complete this, here's an example of how to average a list of colors (naturally, for greyscale colors you only have to concentrate on 1 component as R,G and B should all be the same.
import pprint
from mathutils import Color
cols = tk[8] # unadulterated color list for that vertex
pprint.pprint(cols)
def avg_col(cols):
avg_col = Color((0.0, 0.0, 0.0))
for col in cols:
avg_col += col/len(cols)
return avg_col
print('average')
col = avg_col(cols)
print(col)
Now using the defaultdict
that represents the vertices and their occurrence in vertex_colors
you can average them, or do whatever calculations and create a new dict with a dict comprehension.
import pprint
import bpy
vcol_averages = {k: avg_col(v) for k, v in tk.items()}
pprint.pprint(vcol_averages)
''' outputs, nicely the averages.
{0: Color((0.800000011920929, 0.4313725531101227, 0.04313725605607033)),
1: Color((0.11372549086809158, 0.800000011920929, 0.0)),
2: Color((0.27450981736183167, 0.27843138575553894, 0.27843138575553894)),
3: Color((0.7882353067398071, 0.7921568751335144, 0.800000011920929)),
4: Color((0.5372549295425415, 0.3549019694328308, 0.16078431904315948)),
5: Color((0.45098039507865906, 0.7960784435272217, 0.4000000059604645)),
6: Color((0.5313725471496582, 0.5352941155433655, 0.5392156839370728)),
7: Color((0.45686274766921997, 0.615686297416687, 0.021568628028035164)),
8: Color((0.4941176474094391, 0.5754902362823486, 0.2803921699523926))}
'''
From this you might create a list of vertex indices following a threshold test.
vertices_of_interest = [k for k, v in vcol_averages.items() if v.r < 0.5]
pprint.pprint(vertices_of_interest)
# [1, 2, 5, 7, 8]
Selecting vertices, is easy once you get to this point.
if bpy.context.object.data.vertex_colors.active.data[0].color[1] < .1:
$\endgroup$ – CharlesL Aug 6 '13 at 14:49