1
$\begingroup$

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?
$\endgroup$
3
  • 3
    $\begingroup$ What exactly you'd like to do? Please provide a bit more context. $\endgroup$
    – brockmann
    Commented Dec 17, 2019 at 13:44
  • 1
    $\begingroup$ Given obj is obj.material_slots.data is the question: how to select all objects with same object color obj.color as context object? $\endgroup$
    – batFINGER
    Commented Dec 18, 2019 at 12:41
  • $\begingroup$ Yes - how to select all objects with same object color obj.color as context object? $\endgroup$
    – guest
    Commented Dec 19, 2019 at 4:00

2 Answers 2

2
$\begingroup$

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) 
$\endgroup$
2
$\begingroup$

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

$\endgroup$
3
  • 1
    $\begingroup$ or C.object.color[:] $\endgroup$
    – batFINGER
    Commented Dec 21, 2019 at 17:05
  • $\begingroup$ Appreciated @batFINGER, but tbh I dont get why...? $\endgroup$
    – brockmann
    Commented Dec 21, 2019 at 23:18
  • $\begingroup$ IMO preferable to its equivalent [c for c in obj.color] or similarly with bm.verts[:] etc $\endgroup$
    – batFINGER
    Commented Dec 21, 2019 at 23:52

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .