一半君的总结纸

听话只听一半君

#83 How do I devise a setup whereby when I select one object, Maya automatically selects another object?

The only method with which Maya communicates a change in selection is via a scriptJob. There is no attribute on an object to indicate whether it is part of the active selection list, and nothing in the DG becomes “dirty” when you simply click something with the mouse.

Now here’s the kicker: The event doesn’t tell you what was just selected (or unselected), only that the selection has changed. You’ll have to figure out for yourself what’s moved in or out of the queue.

Now, here’s the real kicker: Whenever you perform a selection as a response to a SelectionChanged event, you add the selection to the undo queue. Attempting to undo the selection puts you back into the callback for the SelectionChanged event, which undoes your undo by restoring the selection just the way it was. Result: You can’t undo.

So, what you have to do within the SelectionChanged event is to ‘undo’ the selection, modify the array of items to select if necessary, and ‘redo’ the selection. This tip from the Highend3D Maya Mailing List courtesy Roger Klado.

I also found that the “Click Drag Select” mode would trigger a SelectionChanged event which, upon obediently performing its undo, made the Click Drag ineffectual. So I had to wrap the works with a query to the Undo queue to assert it was triggered by a selection event and not a move event.

In the following example “ObjectB” will be selected whenever “ObjectA” is selected.

<br />// Set up the scriptJob<br />scriptJob -event "SelectionChanged" reactToSelection;<br /><br />// Callback for "SelectionChanged" scriptJob event.<br />global proc reactToSelection()<br />{<br />  string $whyAmIHere = `undoInfo -q -undoName`;<br /><br />  // Wrapper to prevent unwanted Undo during 'Click Drag Select' mode.<br />  if ( `gmatch $whyAmIHere "select*"` )<br />  {<br />    string $select[] = `ls -sl`;<br /><br />    // Undo the user selection.<br />    undo;<br /><br />    int $hasObjectA = stringArrayCount( "ObjectA", $select );<br /><br />    if ( $hasObjectA )<br />    {<br />      $select = stringArrayCatenate( { "ObjectB" }, $select );<br />    }<br />    else<br />    // Don't allow ObjectB to be selected alone.<br />    {<br />      $select = stringArrayRemove( { "ObjectB" }, $select );<br />    }<br /><br />    // Redo with modified selection.<br />    select $select;<br />  }<br />}<br /><br />

There’s bound to be some issues with this that I haven’t foreseen. If it breaks, please let me know.

Acknowledgements

Highend3D.com

Roger Klado, Man’O’War

09 February 2002

Advertisements

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s

%d 博主赞过: