1

I would like to select all the objects in the scene that have the same object color Object.color as the active object.

import bpy
active = bpy.context.view_layer.objects.active
color=active.material_slots.data.color
for obj in bpy.data.objects.keys():
    colorSelect = obj.material_slots.data.color
    if colorSelect == color:
        #How do I select this object?
batFINGER
  • 84,216
  • 10
  • 108
  • 233
guest
  • 11
  • 3

2 Answers2

2

Based on your comment, I guess you want to compare against the viewport display color property:

enter image description here

I think one easy way to compare color values is appending the components to a new list and compare the resulting lists using the == operator.

>>> [c for c in C.object.color]
>>> [1.0, 1.0, 1.0, 1.0]
>>>
>>> [c for c in C.object.color] == [1.0, 1.0, 1.0, 1.0]
>>> True

If you don't like lists for any reason, you can also convert the color to a tuple using the slice operator [:], which is even shorter -> thanks to @batFINGER:

>>> C.object.color[:] == (1.0, 1.0, 1.0, 1.0)
True

Full script iterating through Scene.objects, comparing the color values (r,g,b,a) of each object against the values of Context.object and selecting the matches:

import bpy

ctx = bpy.context
obj = ctx.object

# Object color as list
obj_clr = [c for c in obj.color]

for o in ctx.scene.objects:
    if o != obj and o.type not in ('LIGHT', 'CAMERA', 'EMPTY'):
        # Compare both lists
        if [c for c in o.color] == obj_clr:
            o.select_set(True)

obj.select_set(False)

Be aware that there are might be issues with floating point precision when comparing the values. One way around that is using isclose(a, b, *, rel_tol=1e-09, abs_tol=0.0) provided by the math module, which can be wrapped into a little helper function to test all 4 floats at once:

def compare_color(a, b, t=0.001):
    from math import isclose
    comp = {isclose(i, j, abs_tol=t) for i, j in zip(list(a),list(b))}
    return True if (len(comp) == 1 and next(iter(comp)) == True) else False

Another example comparing against Material.diffuse_color using the helper function:

import bpy

def compare_color(a, b, t=0.001):
    from math import isclose
    comp = {isclose(i, j, abs_tol=t) for i, j in zip(list(a),list(b))}
    return True if (len(comp) == 1 and next(iter(comp)) == True) else False

ctx = bpy.context
obj = ctx.object

# Object color as list
obj_clr = obj.active_material.diffuse_color

for o in ctx.scene.objects:
    if o != obj and o.type not in ('LIGHT', 'CAMERA', 'EMPTY'):
        # Compare both lists
        if compare_color(obj_clr, o.active_material.diffuse_color):
            o.select_set(True)

Further Reading: Select an object by name in 2.8 and Set active object in 2.8

brockmann
  • 12,613
  • 4
  • 50
  • 93
2

Similarly with Vectors

@brockmann has absolutely nailed it.

Here is another example using the length of Vector difference of the colors

import bpy
from mathutils import Vector

context = bpy.context
ob = context.object
col = Vector(ob.color)

for o in context.scene.objects:
    o.select_set((Vector(o.color) - col).length < 1e-4) 

To compare only the rgb and not a (alpha) parts, use one of

col = Vector(ob.color).to_3d()
col = Vector(ob.color).xyz
col = Vector(ob.color[3:])

to make the vector 3d (r, g, b)

To select only mesh objects with same rgb color as active

o.select_set(o.type == 'MESH' and (Vector(o.color).xyz - col.xyz).length < 1e-4) 
batFINGER
  • 84,216
  • 10
  • 108
  • 233