4
$\begingroup$

I'm wondering if there a way to get an object selection in order of selection. It' seams that Blender sort objects by keys, but the selection order is important for my tool.

Is there a way to do that ? I found many topic on other forum from 2015, I'm wondering if now we could do this ?

EDIT : A bit of Context :

  1. I have 4 Attributes on each objects ( marking front / back / right / left )
  2. I want to compare 2 objects together, see if the Right Attribute match the Left Attribute of the other Object
  3. I want my first selection to be the Object you compare too At the end I'm returning :
  4. Object 1 Front value == Object 2 Back Value
  5. Object 1 Back value == Object 2 Front Value
  6. Object 1 Right value == Object 2 Left Value
  7. Object 1 Left value == Object 2 Right Value

the result is the same if I compare the first to the second or the second to the first, it's just more user friendly to know My first selection is the base and the second is the one I compare to the first.

enter image description here

$\endgroup$
3
  • $\begingroup$ related: blender.stackexchange.com/questions/108725/… $\endgroup$
    – Chris
    Commented Feb 11, 2022 at 6:30
  • $\begingroup$ maybe it would be a better idea to tell us your "end goal". Often people just concentrate on one problem which might be solved in an easy other way so we might be able to help you with your "big" goal... $\endgroup$
    – Chris
    Commented Feb 11, 2022 at 6:36
  • $\begingroup$ You're right, i updated the main topic so you could understand what's i'm trying to achieve here :) $\endgroup$
    – Zhaie
    Commented Feb 11, 2022 at 17:23

1 Answer 1

5
$\begingroup$

Use get_ordered_selection_objects()

import bpy

def get_ordered_selection_objects():
    tagged_objects = []
    for o in bpy.data.objects:
        order_index = o.get("selection_order", -1)
        if order_index >= 0:
            tagged_objects.append((order_index, o))
    tagged_objects = sorted(tagged_objects, key=lambda item: item[0])
    return [o for i, o in tagged_objects]

def clear_order_flag(obj):
    try:
        del obj["selection_order"]
    except KeyError:
        pass

def update_selection_order():
    if not bpy.context.selected_objects:
        for o in bpy.data.objects:
            clear_order_flag(o)
        return
    selection_order = get_ordered_selection_objects()
    idx = 0
    for o in selection_order:
        if not o.select_get():
            selection_order.remove(o)
            clear_order_flag(o)
        else:
            o["selection_order"] = idx
            idx += 1
    for o in bpy.context.selected_objects:
        if o not in selection_order:
            o["selection_order"] = len(selection_order)
            selection_order.append(o)

def selection_change_handler(scene):
    if bpy.context.mode != "OBJECT":
        return
    is_selection_update = any(
        not u.is_updated_geometry
        and not u.is_updated_transform
        and not u.is_updated_shading
        for u in bpy.context.view_layer.depsgraph.updates
    )
    if is_selection_update:
        update_selection_order()

def register():
    bpy.app.handlers.depsgraph_update_post.append(selection_change_handler)

if __name__ == "__main__":    
    for f in bpy.app.handlers.depsgraph_update_post:
        if f.__name__ == "selection_change_handler":
            bpy.app.handlers.depsgraph_update_post.remove(f)
    register()
$\endgroup$
3
  • $\begingroup$ oh wow...Thank you so much i'm gonna try this :O $\endgroup$
    – Zhaie
    Commented Feb 11, 2022 at 17:49
  • $\begingroup$ It's not a perfect way but I hope it will help you $\endgroup$
    – Karan
    Commented Feb 11, 2022 at 18:00
  • $\begingroup$ I didn't have the chance to test it for now ! I will soon but thanks a lot ! even if you feel it's not perfect that so kind of you and i'm really thankful for your help :) $\endgroup$
    – Zhaie
    Commented Feb 14, 2022 at 17:46

You must log in to answer this question.

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