3
$\begingroup$

I wanted to apply an object operator (shade_smooth/flat) to linked/dupli objects, but can't find a way to pass the object to this operator.

import bpy

# flat or smooth
flat = False

for ob in context.scene.objects:
    if ob.dupli_group and ob.dupli_group.objects:
        for dob in ob.dupli_group.objects:
            if flat:
                bpy.ops.object.shade_flat()
            else:
                bpy.ops.object.shade_smooth()

Of course this doesn't work, because it applies on selected objects only. Was surprised to see this even works from the python terminal, without the need to override context.

Any clues?

$\endgroup$

2 Answers 2

3
$\begingroup$

This uses selected_editable_objects, You can find out which attributes are used by passing in a Python context, and then check the terminal for where each requested attribute is printed.

(Yes, we know this isnt an ideal way to design the API, however this is internal C code which defines which context variables are used).

import bpy
from bpy import context

# flat or smooth
flat = True

# use a 'set' to avoid duplicates, can convert into a list after.
selected_editable_objects = set()

for obj in context.scene.objects:
    if obj.dupli_type == 'GROUP':
        group = obj.dupli_group
        if group:
            for dob in obj.dupli_group.objects:
                selected_editable_objects.add(dob)

context_py = context.copy()

context_py["selected_editable_objects"] = list(selected_editable_objects)


if flat:
    bpy.ops.object.shade_flat(context_py)
else:
    bpy.ops.object.shade_smooth(context_py)

Note: this would be more efficient to de-duplicate based on the object data, since its possible many objects reference the same data. But for the example above, its simpler to just take unique objects.

$\endgroup$
2
  • $\begingroup$ It works! On local objects, I was wondering about it working on linked meshes. An animator asked me if they could switch smooth/flat shading on linked characters, to better check deformations. Is this possible? I get a "Warning: Can't edit linked mesh or curve data" when running this. $\endgroup$ Commented Apr 29, 2014 at 13:07
  • 1
    $\begingroup$ @Pablo Vazquez - for linked data the operator intentionally disallows this. so. no quick solution. Theres nothing stopping you going over every mesh and setting all faces, but this is a bit of a hassle from a Python script. (though with foreach_set it could be fast enough). $\endgroup$
    – ideasman42
    Commented Apr 29, 2014 at 16:30
1
$\begingroup$

bpy.ops.object.shade_flat() and bpy.ops.object.shade_smooth() set the shading on all selected objects. The active object doesn't matter - if it's not selected, it won't be affected.

# Deselect
for ob in context.scene.objects:
    ob.select = False

# Select
for ob in context.scene.objects:
    if ob.dupli_group and ob.dupli_group.objects:
        for dob in ob.dupli_group.objects:
            dob.select = True

# Set shading on all selected objects
if flat:
    bpy.ops.object.shade_flat()
else:
    bpy.ops.object.shade_smooth()
$\endgroup$

You must log in to answer this question.

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