I'm trying to understand how selections and active objects work within a context. I thought I understood that a selection is part of a context. I read somewhere that you can create a copy of a context (context.copy()) in order to avoid changing the user's actual selections.

Some code I've seen fits this concept, such as..

  • context['selected_objects'] = list

  • context['active_object'] = object

But other code I've seen does not, such as..

  • object.select = False
  • bpy.ops.object.select_all(action='DESELECT')

Would anyone be able to help me understand what's happening behind the scenes? I can't imagine how object.select = False can be triggering any state changes inside of a context? Perhaps objects have their own selection states, but they can be overridden by a context? Or maybe the things I read were completely wrong?


Edit: It appears that part of my issue is that Blender keeps changing the syntax and setup of how selections work. It looks like they are now part of the view layer. But if I make a copy of the context, Blender reports that it doesn't even have a view layer. Does anyone know how to properly copy the context and select/activate objects with the copy?

  • 1
    $\begingroup$ In Blender 2.80 and after obj.select = Bool is replaced by obj.select_get() and obj.select_set(). Context should track all change inside it, I guess $\endgroup$ – HikariTW Sep 7 '19 at 0:52
  • $\begingroup$ Any idea how a copied context (I keep seeing it called an "override") can be used in this situation to avoid changing user selections? Blender's context has a view layer at bpy.context.view_layer. But if I copy the context with copy= bpy.context.copy(), my copy does not seem to have a view layer at copy.view_layer. Can anyone help me understand why? Or just how to use a context override correctly? $\endgroup$ – Robert Sep 7 '19 at 12:12
  • 1
    $\begingroup$ Don't. You only need to copy the context in case you want to override the actual context of an operator call like bpy.ops.object.delete({"selected_objects": objs}), good read: poll() failed, context incorrect?. Otherwise all operator methods already provide the current context (default argument): def execute(self, context): so don't worry about that too much. More about selection in 2.8 here: Python: Selecting object by name in 2.8 $\endgroup$ – brockmann Sep 7 '19 at 17:09
  • $\begingroup$ Ok, got it. Thanks. My only intention was to avoid changing the user's states like current selections and active object. Most of the add-ons that come shipped with Blender seem to be doing this manually, so I assume that is the best way? Just back them up, change them, execute functions, and restore them after? $\endgroup$ – Robert Sep 7 '19 at 17:37
  • $\begingroup$ Depends whether you have to call an operator which needs another context to be executed properly. Overriding is a good option to avoid changing for e.g. the viewport selection but sometimes you just have to do it so there is nothing like "the best way" (one reason why stackoverflow is so popular), it always depends. Show us your code @Robert and we'll see :) $\endgroup$ – brockmann Sep 7 '19 at 18:06

Your Answer

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

Browse other questions tagged or ask your own question.