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$ 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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.