1
$\begingroup$

After selected several bones in Edit mode, Let's say 3 bones in order of name "A", "B", "C". When I check the selected_bones array index from 0 - 2, the order of the array is not selected order but something different(BCA or CBA something doesn't much to actual selected order). It seems the order is an order that I can see on the outliner window. But I would like to know the selected order of bones for script that I made for renaming bones. Is there a way to get that data? Thank you.

$\endgroup$
2
$\begingroup$

You can use a modal operator to handle your own selection order:

enter image description here

The script below is based on one of the scripts templates available in Blender (the one called 'operator modal draw', but 'operator modal' can be enough if you don't want to draw anything).

The needed parts are commented below (but please comment if you need more information):

import bpy
import bgl
import blf


def draw_callback_px(self, context):
    font_id = 0 
    blf.position(font_id, 15, 30, 0)
    blf.size(font_id, 20, 72)
    blf.draw(font_id, " / ".join([b.name for b in self.bones]))

class ModalDrawOperator(bpy.types.Operator):
    """Draw a line with the mouse"""
    bl_idname = "view3d.modal_operator"
    bl_label = "Simple Modal View3D Operator"

    def modal(self, context, event):
        context.area.tag_redraw()

        #Escape here allows to stop, but you can also do it from any other property from your addon
        if event.type in {'ESC'}:
            bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
            return {'CANCELLED'}

        #Last selected is first in this way of coding
        self.bones = [b for b in context.selected_bones if b not in self.bones] + [b for b in self.bones if b in context.selected_bones]

        #Return PASS_THROUGH in order to allow Blender interpret the events
        return {'PASS_THROUGH'}

    def invoke(self, context, event):
        #Check the context for 'EDIT_ARMATURE'
        if context.area.type == 'VIEW_3D' and context.mode == 'EDIT_ARMATURE':
            args = (self, context)
            self._handle = bpy.types.SpaceView3D.draw_handler_add(draw_callback_px, args, 'WINDOW', 'POST_PIXEL')

            #Empty bones at the beginning
            self.bones = []
            #Or allready selected
            #self.bones = context.selected_bones[:]
            #Or from your data
            #self.bones = your previous selection

            context.window_manager.modal_handler_add(self)
            return {'RUNNING_MODAL'}
        else:
            self.report({'WARNING'}, "View3D not found, cannot run operator")
            return {'CANCELLED'}


def register():
    bpy.utils.register_class(ModalDrawOperator)


def unregister():
    bpy.utils.unregister_class(ModalDrawOperator)

if __name__ == "__main__":
    register()
$\endgroup$
1
  • $\begingroup$ Wow. Thank you very much for detailed answer ! I was writing small scripts for modeling but I've never tried modal type add on but it seems it is the one I can use for that purpose. I'm gonna start studying interactive add-on too like this. Thank you! $\endgroup$
    – Miumiu
    Mar 28 '17 at 18:13

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.