I’m having some issues with the scriptCtx command in MEL. I’m trying to make a tool that chains together some functions that perform some operations on a list of objects. My selection sets don’t seem to be working at all.
At the end of the scriptCtx, it does call the functions I have listed, but the contents of the selections are wrong. In addition, the second set will not accept a single object alone, I press enter and nothing happens until I select 2 or 3. Then, testProcB prints the wrong set of objects, to boot!:curses:
So clearly I’m doing something crazy wrong here
This is what I’d like to accomplish:
Press a button in a UI
User selects a set of objects and presses Enter
Objects are added $Selection1
User selects another set of objects presses Enter
Objects are added to $Selection2
$Selection1 is passed to testProcA
do some things to objects in $Selection1
$Selection1 is passed to testProcB
do some things to objects in $Selection2
and so on until the end of the chain (set to 2, currently)…
Here’s my code and thanks for reading. This site has really helped me grow as a tech artist
proc testProcA(string $a[]) {
for ($object in $a) {
print("In Selection A: "+$object +"
");
}
}
proc testProcB(string $a[]) {
for ($object in $a) {
print("In Selection B: "+$object +"
");
}
}
if (`contextInfo -exists chainTest`)
deleteUI chainTest;
window;
columnLayout;
button -c "setToolTo chainTest" chainTest;
showWindow;
scriptCtx
-title "chainTest"
-totalSelectionSets 2
-finalCommandScript "testProcA($Selection1); testProcB($Selection2);"
-setNoSelectionPrompt ("1: Select objects")
-setSelectionPrompt ("1: Select more and hit ENTER")
-setAutoToggleSelection false
-setAutoComplete false
-setSelectionCount 0
-setNoSelectionPrompt ("2: Select objects")
-setSelectionPrompt ("2: Select more and hit ENTER")
-setAutoToggleSelection false
-setAutoComplete false
-setSelectionCount 0
chainTest;
I had some rough times trying to get the scriptCtx to work, I think you can do a lot of the same stuff with a selectionCtx (and there might be other Ctx you can use as well)
I usually will not get a predictable result unless I specify a select type.
And even then I have found that building my own selection sets one at a time was the only way to get predictable behavior.
The following is trimmed down template of as much. ( usually I would add scriptJobs instead as well as more error checking )
// Ham fisted Cro Magnon Solution cly_scriptCtx_Template.mel
// ( Roger Klado was here... cuz no one else would do it fer me )
// select 2 selections sets do something to each ( two ) resulting selection sets
global proc cly_scriptCtx_Template()
{
global int $cly_scriptCtx_count = 0; // bulletproof the global variable or bypass it with a selection event/condition scriptJob?
cly_buildScrptCtx;
}
global proc cly_buildScrptCtx()
{
global int $cly_scriptCtx_count;
if ( `contextInfo -ex cly_scriptCtxToolTemplate` )
deleteUI cly_scriptCtxToolTemplate;
scriptCtx
-title "cly_scriptCtxTool1Template"
-tct "question"
-totalSelectionSets 1
-cls 0
-expandSelectionList 1
-fcs "cly_scriptCtxTemplateCmd $cly_scriptCtx_count $Selection1"
-setSelectionPrompt "Make a selection"
-setAutoComplete 0
-setSelectionCount 0
-polymesh 1 -nurbsSurface 1 // selectType command's doc has selection types listed
cly_scriptCtxToolTemplate;
setToolTo cly_scriptCtxToolTemplate;
}
global proc cly_scriptCtxTemplateCmd( int $whichSelection, string $cly_selSet[] )
{
global int $cly_scriptCtx_count;
if ( $whichSelection ) {
print ( "! In Selection B:
");
print $cly_selSet;
print "
";
$cly_scriptCtx_count = 0;
}
else {
print ( "! In Selection A:
");
print $cly_selSet;
print "
";
$cly_scriptCtx_count = 1;
evalDeferred cly_buildScrptCtx;
}
}
// end ( insert applause )
executing
cly_scriptCtx_Template
with the expected result: ( select a: prints a, select b: prints b, end )
global int $cly_scriptCtx_count; // bulletproof the global variable or bypass it with a selection event/condition scriptJob?
$cly_scriptCtx_count = 0;
If instead of initializing the global variable I declare it ( even if it comes before any possible scope ) before assigning zero it seems to be pretty bullet proof.
( unless some joker rips of yer cly_prefix. )
In which case mebbe I don’t have to use scriptJobs for cleanUp myself?
Guess it depends on what make u more nervous… scriptJobs or global variables. ( I love both ).
Can’t think of how I could break the following: ( the global counter will always be rebuilt predictably? )
// Ham fisted Cro Magnon Solution cly_scriptCtx_Template.mel
// ( Roger Klado was here... cuz no one else would do it fer me )
// select 2 selections sets do something to each ( two ) resulting selection sets
global proc cly_scriptCtx_Template()
{
global int $cly_scriptCtx_count; // bulletproof the global variable or bypass it with a selection event/condition scriptJob?
$cly_scriptCtx_count = 0;
cly_buildScrptCtx;
}
global proc cly_buildScrptCtx()
{
global int $cly_scriptCtx_count;
if ( `contextInfo -ex cly_scriptCtxToolTemplate` )
deleteUI cly_scriptCtxToolTemplate;
scriptCtx
-title "cly_scriptCtxTool1Template"
-tct "question"
-totalSelectionSets 1
-cls 0
-expandSelectionList 1
-fcs "cly_scriptCtxTemplateCmd $cly_scriptCtx_count $Selection1"
-setSelectionPrompt "Make a selection"
-setAutoComplete 0
-setSelectionCount 0
-polymesh 1 -nurbsSurface 1 // selectType command's doc has selection types listed
cly_scriptCtxToolTemplate;
setToolTo cly_scriptCtxToolTemplate;
}
global proc cly_scriptCtxTemplateCmd( int $whichSelection, string $cly_selSet[] )
{
global int $cly_scriptCtx_count;
if ( $whichSelection ) {
print ( "! In Selection B:
");
print $cly_selSet;
print "
";
$cly_scriptCtx_count = 0;
}
else {
print ( "! In Selection A:
");
print $cly_selSet;
print "
";
$cly_scriptCtx_count = 1;
evalDeferred cly_buildScrptCtx;
}
}
// end ( insert applause )
Interesting solution, Roger, thanks! I ended up going about it a different way, which was to use two scriptCtx calls instead of one and call scriptCtx:B from the function executed by scriptCtx:A
I found it was important to use evalDeferred(“setToolTo yourScriptCtx;”) when calling scriptCtx from inside a function like this, or you may get bad results. In my case, it caused Maya to crash :eek:
I wanted to post this solution in case anyone runs into a problem like this. Maybe somebody will find it useful. I don’t know if this is the best way, but it worked for me.
proc testProcA(string $a[]) {
for ($object in $a) {
print("In Selection A: "+$object +"
");
evalDeferred("setToolTo chainTestB;");
select -cl;
}
}
proc testProcB(string $a[]) {
for ($object in $a) {
print("In Selection B: "+$object +"
");
select -cl;
}
}
if (`contextInfo -exists chainTestA`)
deleteUI chainTestA;
if (`contextInfo -exists chainTestB`)
deleteUI chainTestB;
window;
columnLayout;
button -c "setToolTo chainTestA" chainTestA;
showWindow;
scriptCtx
-title "chainTestA"
-totalSelectionSets 1
-finalCommandScript "testProcA($Selection1)"
-setNoSelectionPrompt ("1: Select objects")
-setSelectionPrompt ("1: Select more and hit ENTER")
-setAutoToggleSelection false
-setAutoComplete false
-setSelectionCount 0
chainTestA;
scriptCtx
-title "chainTestB"
-totalSelectionSets 1
-finalCommandScript "testProcB($Selection1)"
-setNoSelectionPrompt ("2: Select objects")
-setSelectionPrompt ("2: Select more and hit ENTER")
-setAutoToggleSelection false
-setAutoComplete false
-setSelectionCount 0
chainTestB;