Lately a lot of questions on other forums have been posted centered around
creating custom popUpMenu’s in mel that reflect objects/components under cursor.
The solution for some has been to manually edit maya’s internal files :eek:
Namely dagMenuProc.mel.
This seems pretty drastic. I wonder if anyone here does as much?
( acceptable practice?? )
I have tried to come up with some alternative solutions that “may”
perhaps be useful to some.
I hope u guys don’t mind if I compile them here?
Also, looking for feedback ( similar solutions? logic errors on my part? )
Begin:
you will not find “dagObjectHit” in the mel command documentation however you can find all the flags for it in quick help.
additionally
ls -preSelectHilite
is helpful for contextual component cursor query
a template fer both:
// cly_contextualCursorHit_template.mel
{
if( `popupMenu -exists cly_contextualTrash` ) {
deleteUI cly_contextualTrash;
}
popupMenu
-alt 1
-button 3
-mm 1
-p viewPanes
-pmc ( "string $bob[] = `ls -preSelectHilite`;"+ // ls return of pre-select hilite under cursor
"if (`popupMenu -e -exists cly_contextualTrash`) {"+
"popupMenu -e -deleteAllItems cly_contextualTrash;"+
" setParent -menu cly_contextualTrash;"+
"if ( `dagObjectHit`)"+ // dag object Hit returns int if cursor is over an object
"menuItem -label \"object under cursor\";"+
"else"+
" menuItem -label \"no object under cursor\";"+
"if ( size( $bob ) ) "+
" for ( $b in $bob ) "+
"menuItem"+
"-label $b; }" )
cly_contextualTrash;
}
// end
after executing the above code:
alt + rightclick on object and components
builds dynamic popUp that reflects object and component status under cursor
result
More pop-up menu Fun…
different methods are needed to return “object under the cursor” depending on the panel.
First in the model panels:
How is the $object argument passed to dagMenuProc.mel ?!
This is a bit tricky!
The only procedure that uses dagMenuProc is buildObjectMenuItemsNow.mel.
And it only “seems” to execute it in only one place in the code…
if NOT! dagObjectHit -mn “theMenuNameHere” then the last object currently
selected is $object. So dagmenuProc ( in “theMenuNameHere”, with $object represented )
This works as expected ( if no cursor is over an object but at least 1 object is selected…
Then the last selected object is represented in the dagMenu pop up )
Where then, is dagMenuProc executed for cursor over unselected object?
ENTER, the enigmatic dark shadowy command known as dagObjectHit to save the day (sorta) once again…
Although dagObjectHit only returns int. When used with the -menu flag
It executes dagMenuProc and passes as arguments both the menu string provided in the flag and the object under the cursor as well!
for instance:
// with our cursor over polyMesh1...
dagObjectHit -mn "cly_contextualTrash", ;
// results in:
// dagMenuProc("cly_contextualTrash", "polyMesh1");
dagObjectHit is only used once in all internal Maya scripts…
( our buildObjectMenuItemsNow.mel example above)
if (!`dagObjectHit -mn $parentName`)
despite the logical !not operator this dagObjectHit query is what actually
executes cursor/object represented popUp menu builds.
Why this isn’t a fully documented command that returns object query as a string is beyond me? May be some danger lurking here?
Let’s not start celebrating jes yet tho…
For our uses, this code:
dagObjectHit -mn "ourCustomMenu"
will simply use the dagMenuProc menu builder to build “our” menu!
( the dagMenuBuild is appended to our menu so far )
Which is fine, if that is what we want… ( to extend Maya’s default model Menu Pop Ups )
However if we want unadultered popUpMenu’s, yet keep the dagObjectHit’s passed $object
We will have to do a little hacking:
Don’t rewrite an internal mel file…
pillage dagMenuProc results instead, then -deleteAllItems to restore yer menu:
/*
cly_objectHitMenuTemplate.mel v0.2
Roger Klado was here
because no one else will do it fer me
April 15, 2009 ( should be dom war-ing instead )
RogerKlado@gmail.com ( Klado/Claydough/cly_ )
A template for setting up object aware view pane pop-up menus
*/
global proc cly_objectHitMenuTemplate()
{
if( `popupMenu -exists cly_contextualTrash` ) {
deleteUI cly_contextualTrash;
}
popupMenu
-alt 1
-button 3
-mm 1
-p viewPanes
-pmc ( "string $bob[] = `ls -preSelectHilite`;"+ // ls return of pre-select hilite under cursor
"if (`popupMenu -e -exists cly_contextualTrash`) {"+
"popupMenu -e -deleteAllItems cly_contextualTrash;"+
" setParent -menu cly_contextualTrash;"+
"if ( `dagObjectHit`)"+ // dag object Hit returns int if cursor is over an object
"menuItem -label `cly_dagMenuRape`;"+
"else"+
" menuItem -label \"no object under cursor\";"+
"if ( size( $bob ) ) "+
" for ( $b in $bob ) "+
"menuItem"+
"-label $b; }" )
cly_contextualTrash;
}
//________________________________________________________________________________________
// end
global proc string cly_dagMenuRape()
{
dagObjectHit -mn "cly_contextualTrash";
string $popsChildren[] = `popupMenu -q -itemArray cly_contextualTrash`;
string $objectMenuItem = `menuItem -q -l $popsChildren[0]`;
string $dotFreeObject[];
tokenize $objectMenuItem "." $dotFreeObject;
// we have had our way with dagMenuProc. call her a cab...
popupMenu -e -deleteAllItems cly_contextualTrash;
return $dotFreeObject[0];
}
// end: insert applause here...
result
The above code werks for all objects ( joints etc… ) in the model panels.
We have to use different logic for the hypergraph however.
Thankfully this is a lot easier.
The hypergraph command can query object nodes under the cursor with the -feedbackNode flag.
fer instance hyperGraphPanel1:
/*
cly_objectHitHyperGraphMenuTemplate.mel v0.1
Roger Klado was here
because no one else will do it fer me
April 15, 2009 ( should be dom war-ing instead )
RogerKlado@gmail.com ( Klado/Claydough/cly_ )
A template for setting up object aware view pane pop-up menus
*/
global proc cly_objectHitHyperGraphMenuTemplate()
{
if( `popupMenu -exists cly_contextualTrash2` ) {
deleteUI cly_contextualTrash2;
}
popupMenu
-alt 1
-button 3
-mm 1
-p "hyperGraphPanel1HyperGraphEd"
-pmc "cly_hyperFeedBack"
cly_contextualTrash2;
}
global proc cly_hyperFeedBack()
{
if (`popupMenu -e -exists cly_contextualTrash2`) {
popupMenu -e -deleteAllItems cly_contextualTrash2;
string $feedBackNode = `hyperGraph -query -feedbackNode "hyperGraphPanel1HyperGraphEd"`;
// optionally tokenize
string $tokenizedFeedBackNode[]; // *this line for short names
tokenize $feedBackNode "|" $tokenizedFeedBackNode; // "
setParent -menu cly_contextualTrash2;
//menuItem -label $feedBackNode; // *uncomment this line for long names
// *this line for short names
menuItem -label $tokenizedFeedBackNode[size($tokenizedFeedBackNode) - 1];
}
}
// end
The objects are returned with short names here. Use the long name method included to solve for naming clashes.
result
have I missed anything?
// end