0

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?

Thanks!

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?

Robert
  • 1,265
  • 1
  • 13
  • 29
  • 1
    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 – HikariTW Sep 07 '19 at 00:52
  • 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? – Robert Sep 07 '19 at 12:12
  • 1
    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 – brockmann Sep 07 '19 at 17:09
  • 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? – Robert Sep 07 '19 at 17:37
  • 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 :) – brockmann Sep 07 '19 at 18:06
  • The code only exists in my head at the moment. I'm trying to map it out before I begin. I'm worried about complex situations where I'm duplicating objects in one function to merge them in another function, each one needing to change the active object and selected objects. And while all of this is going on, the root function driving everything will have to keep its own selection list running that will be sent to the FBX exporter. I should probably make a secondary temporary list for the root function, then select them after everything is finished. Oh well, I think I'm getting close. – Robert Sep 07 '19 at 22:16

0 Answers0