scriptCtx issues with selection sets

Hey all,

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 :slight_smile:


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 )

cly_scriptCtx_Template;
select -r pSphere1 pSphere2 ;
{ string $Selection1[]; $Selection1[0] = “pSphereShape1”; $Selection1[1] = “pSphereShape2”;
cly_scriptCtxTemplateCmd $cly_scriptCtx_count $Selection1; };
! In Selection A:
pSphereShape1
pSphereShape2

select -r pSphere3 pSphere4 ;
{ string $Selection1[]; $Selection1[0] = “pSphereShape3”; $Selection1[1] = “pSphereShape4”;
cly_scriptCtxTemplateCmd $cly_scriptCtx_count $Selection1; };
! In Selection B:
pSphereShape3
pSphereShape4

hope that helps

edit: forgot to declare the global variable…

	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;