# Avoid selecting an object in the outliner using a callback

I am working on an extension for exporting particle systems in blender to glTF. As my engine doesn't support as much stuff as blender, I am creating a template which exposes the properties that I support and internally modified blender properties.

That template is made of two objects, a frontend one which will show the properties and an internal one (which later will probably be some more), which have the actual blender stuff.

I want to avoid the user selecting the Kuesa.Particles.Internal object, to avoid the user modifying the internal particle system properties or changing stuff, which may break the exporter.

Although the selection is disabled, this only works on the 3d viewport, but not on the outliner. Is there anyway to avoid the selection of something in the outliner? If not, I was thinking on using some kind of callback. When something is selected, check if it has a custom property type with value Kuesa.Particles.Internal and in that case, select the parent. How would I do something like that?

Using msgbus

Similarly to https://blender.stackexchange.com/a/163258/15543 which uses the message bus to capture when an object is made active

How to get an event when an object is selected?

By way of example the test is if the object trying to be made active has a name that starts with "Cube" The user could break this test by renaming, so choose something more rigorous, perhaps a collection of pointers to objects kept on the scene, or as mentioned a custom property, and hide the custom properties panel.

Also FWIW as mentioned prior am not a great advocate for an "exporter" that modifies the blend.

import bpy
from mathutils import Vector, Matrix

handle = object()

# Triggers when an object is made active
subscribe_to = bpy.types.LayerObjects, "active" #

def notify_test(context):
ob = context.object
#print(context.area) # always None
if (ob and ob.name.startswith("Cube")):
print("No select object:", ob.name)
ob.select_set(False)
context.view_layer.objects.active = ob.parent
if ob.parent:
ob.parent.select_set(True)

bpy.msgbus.subscribe_rna(
key=subscribe_to,
owner=handle,
args=(bpy.context,),
notify=notify_test,
)

bpy.msgbus.publish_rna(key=subscribe_to)

• Thanks for the detailed answer. Ill test ASAP. I would prefer to avoid modyfing the scene while exporting, but I can't find any other way of exporting my prefab as a custom glTF extension without exporting its internals which can be exported to standard glTF stuff (for example, the Kuesa.Particles.Internal node will be exported as a glTF node if I dont do something to it...). – jjcasmar Jul 6 '20 at 7:09
• you have answered a lot of my questions with a lot of detail. While trying to develop my addons, I usually feel like I am missing knowledge of how blender api works. Althought blender documentation is good, I think it fails to clearly explain how the api works and is structured and architected, which I feel is important to understand to really know what to do. Where can I find detailed information about the concepts behind the api? – jjcasmar Jul 6 '20 at 7:12
• If this solved your issue and you'd like to thank batFINGER, please learn how to accept and upvote the answer. How this site works: blender.stackexchange.com/tour @jjcasmar – brockmann Jul 8 '20 at 14:16