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
    $\begingroup$ What exactly you'd like to do? Please provide a bit more context. $\endgroup$ – brockmann Dec 17 '19 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 Dec 18 '19 at 12:41
  • $\begingroup$ Yes - how to select all objects with same object color obj.color as context object? $\endgroup$ – guest Dec 19 '19 at 4:00
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) 
| improve this answer | |
$\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

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.