Steven
Steven

Reputation: 700

How to implement MObject picker in Maya

I have a plugin running inside Maya that needs to perform an 'eye dropper' test against objects in the scene. My Plugin is running as a hosted WPF control, so I have a C# button event callback that wants to operate in a modal fashion until the hit is performed or escape is pressed. This was really easy to do in 3D Studio Max, but I cannot find out how to do this in Maya.

Any advice?

Upvotes: 0

Views: 471

Answers (1)

Green Cell
Green Cell

Reputation: 4777

I do miss that in 3dsMax, but as far as I know, no, there's no built-in functionality to do that.

Most tools in Maya work already having a selection before execution so then the tool can use cmds.ls(sl=True) to capture the selection and preform your validation.

What you can do is mimic an object picker by using a selection callback. There's cmds.scriptJob, but it's more efficient to use OpenMaya's callbacks. Here's an example that uses a class to store the callback's id and auto-manages it:

import maya.cmds as cmds
import maya.OpenMaya as OpenMaya


class ObjectPicker():

    _id = None  # Store callback's id here.

    def __init__(self):
        # When this class is created, add the callback.
        OpenMaya.MGlobal.displayWarning("Please pick an object")
        ObjectPicker.add_callback()

    @staticmethod
    def on_selection_changed(*args):
        # This gets triggered from the callback when the user changes the selection.
        # Auto-remove the callaback afterwards.
        print "Selection:", cmds.ls(sl=True)
        ObjectPicker.remove_callback()

    @staticmethod
    def add_callback():
        # First remove any existing callback, then store the id in this class.
        ObjectPicker.remove_callback()
        ObjectPicker._id = OpenMaya.MEventMessage.addEventCallback("SelectionChanged", ObjectPicker.on_selection_changed)

    @staticmethod
    def remove_callback():
        # Remove the callback so it stops triggering the function.
        if ObjectPicker._id is not None:
            OpenMaya.MEventMessage.removeCallback(ObjectPicker._id)
            ObjectPicker._id = None


# After calling this, pick a new object then it will print it in the Script Editor.
picker = ObjectPicker()

After creating an new instance of the class with picker = ObjectPicker(), a warning will pop-up to the user to pick an object. After the selection changes, it triggers the callback which prints the selection to the Script Editor then removes its own callback.

I think this might work, but Maya isn't 3dsMax, and at the end of the day it might be best to not force one software to work like another. So I'd consider to just stick with what everyone is already used to, and that is to work with the user's current selection.

Edit: Sorry just noticed c++ tag, but the same concept should apply.

Edit #2: I just learned about the command cmds.scriptCtx, so a picker does exist! I think it's an older command as it seems to only support MEL and the implementation doesn't feel that great. If you want to learn more then check out my answer to another question.

Upvotes: 2

Related Questions