PDA

View Full Version : MPXCommand


Tranimatronic
11-27-2008, 07:39 PM
Hi all,
Im having a problem with an MPXCommand I have created.
I am trying to send a list ie:-

list = ["one", "two", "three", "four"]
cmds.pythonCommand(sceneUpdates=list)

however when I try to get the input value all I can ever get is the first item of the list.
I have tried_

MArgList too;
argData.getFlagArgumentList("sceneUpdate", noOfArgs, too);
updatesQueue = too.asStringArray(noOfArgs, &status);

I DO get the correct number of items on the list by using-
unsigned int argumentNumber = argData.numberOfFlagUses("sceneUpdates");
I have tried looping though
argument = argData.flagArgumentString("sceneUpdate", loopThroughArgumentNumber, &status);

...but nothing is working. I only EVER get the first item on the list, and then an empty bunch of arrays
Anyone come across this before ?
I am using Python, but I wouldn't mind a MEL version if that is your thing.
Thanks for any help or pointers
T

Keilun
11-27-2008, 08:02 PM
Your issue is in your usage of the API. I'm not as good with the Python, so I'll illustrate how you would do this in C++.

MArgParser parser( argList );
int nFlagUses = parser.numberOfFlagUses( "sceneUpdate" );
for( int i = 0; i < noOfArgs; i++ )
{
MArgList too;
parser.getFlagArgumentList("sceneUpdate", i, too);

// Get string argument.
MString arg;
too.getFlagArgument( "sceneUpdate", 0, arg );
}


The difference here is that passing a string array via a single flag instance is not synonymous with passing N strings with N instances of a multi-use flag. When doing the latter, you cannot use .asStringArray(), since you'll only get the first element of that flag instance. Rather, you retrieve a secondary MArgList, to get a particular instance of the flag use, then process that argList for that instance's argument.

Tranimatronic
11-27-2008, 08:40 PM
I agree I have something confused along the way, I had tried the MArgParser previously, and could not get it to work. The code you posted does seem closer, however still is returning empty arrays.
Just to re-iterate I am trying to pass an array (list in python) to an MPXCommand as an argument of a flag.
Thanks for your help.
T

Tranimatronic
11-27-2008, 10:04 PM
After trying for a while I just cannot get it to work.
It seems you HAVE to make the flag multiuse otherwise it complains when you send an array to the flag

using the MPXCommand's doIt() method I am getting the MArgList& of all of the command's arguments.

MStatus CWPythonCommands::doIt( const MArgList& args )
{
MStatus status = MS::kSuccess;
cout << "Length of ArgList at beginning " << args.length() << endl;
//MArgDatabase extends MArgParser
MArgDatabase argData(syntax(), args);

//check that the sceneUpdate flag has been set and that it is exclusive
if ( argData.isFlagSet( cwSceneUpdateLong ) && (argData.numberOfFlagsUsed() == 1)) {
MStringArray updatesQueue;
MSelectionList list;

unsigned int nArguments = argData.numberOfFlagUses("sceneUpdate"); //argData inherits from MArgParser
cout << "Number of flag uses " << nArguments << endl;
unsigned int noOfArgs =0;

//MSelectionList list;
// argData.getFlagArgument("sceneUpdate", noOfArgs, list);
cout << "Length of sleection list " << list.length() << endl;

MArgList too;
argData.getFlagArgumentList("sceneUpdate", noOfArgs, too);
cout << "Length of argData argList " << too.length() << endl;

too.get(noOfArgs, updatesQueue);
cout << "Length of ArgList too " << too.length() << endl;

for (noOfArgs=0; noOfArgs<nArguments; noOfArgs++) {
MSelectionList list;
MString stringg;
argData.getFlagArgument("sceneUpdate", noOfArgs, list);
argData.getFlagArgument("sceneUpdate", noOfArgs, stringg);
cout <<" String from argData "<< stringg << endl;
list.getSelectionStrings(updatesQueue);
cout<< "selectionList " << updatesQueue << endl;
//MString result(argData.flagArgumentString("sceneUpdate", noOfArgs &status));
//cout << "ResultsA "<< result << endl;
}



Right from the get-go the argList's length is 0.
Number of flag uses 4
Length of sleection list 0
Length of argData argList 0
String from argData "one" **The first item in the list**
selectionList []
String from argData
selectionList []
String from argData
selectionList []
String from argData
selectionList []

Maya2008 Mac.
I THINK I have had this working before, but right now im wondering if this is a bug in Maya or just me having an off-day.
Thanks anyone for any pointers
T

Keilun
11-28-2008, 03:46 PM
Ah sorry. I was trying to freehand it in my previous post. This is how I do it in my own plug-in:


MArgParser parser( argList );
int nFlagUses = parser.numberOfFlagUses( "sceneUpdate" );
for( int i = 0; i < noOfArgs; i++ )
{
MArgList flagArgs;
parser.getFlagArgumentList("sceneUpdate", i, flagArgs);

// Get string argument. The argList returned is only the list of flag
// arguments for that instance, rather than flag + flag arguments.
//
MString str;
flagArgs.get( 0, str );
}


Multi-use is as the name indicates used when you want to be able to specify the flag multiple times. If you want to specify it all at once through a single flag, then you don't want multi-use.

The only restriction however is that for non-multi-use flags, when you specify that a given flag has 6 string arguments (max # of flag args is 6, I believe), then you must specify 6 flag arguments. No more, no less. Multi-use is more flexible, but it all really depends on what your flag is intended to do.

Tranimatronic
11-28-2008, 08:15 PM
Keilun (http://forums.cgsociety.org/member.php?u=188590), thanks for your help, but unfortunaltey for me, it still is only returning the first element of the array .
I am calling the command in MEL this time :-
string $abc[3] = {"one", "two", "three"};
cwPythonCommand -sceneUpdate $abc ;

Then using the slightly modified version of your code below. I am not using MArgParser because I am using an MArgDatabase for other flags to the same command, and MArgDatabase inherits from MArgParser, so AFAIK they are the same.

I removed the make flag mulit use as I am only calling the flag once using an array, and trying to get the MArgList sent to that one call (sceneUpdate @ 0). I am then going through the length of the ArgList and printing each string.
else { //flag is set and it is exclusive
//MArgParser parser( args );
//removed because an MArgDatabase (argData) is created earlier
MStringArray updatedObjects;
int nFlagUses = argData.numberOfFlagUses( "sceneUpdate" );
MArgList flagArgs;
argData.getFlagArgumentList("sceneUpdate", 0, flagArgs);
cout << "nFlagUses = " << nFlagUses << endl;
for( int i = 0; i < flagArgs.length(); i++ ){


// Get string argument. The argList returned is only the list of flag
// arguments for that instance, rather than flag + flag arguments.
//
MString str;
flagArgs.get( i, str );
cout << "Value = " << str << endl;
}

...and the result......
I am only getting the FIRST item in the array.
I tried it the way you wrote it and still only got the first item in the array returned.
It would be interesting to see if this exact code would work on a PC.
Again thanks for your help, as im getting to the point of wanting to drown myself.
T

Keilun
11-28-2008, 09:40 PM
Ah. So you're trying to pass a string array as a variable. I was under the impression that you were using it as a multi-use flag.

Multi-use flags mean:


string $abc[3] = {"one", "two", "three"};
cwPythonCommand -sceneUpdate $abc[0] -sceneUpdate $abc[1] -sceneUpdate $abc[2] ;


Which is not the same as trying to pass a string array. MEL commands don't have the ability to accept a string array as a single flag argument. You need to expand this yourself. If you take a look at MSyntax, you'll see the list of supported argument types.

So more or less you just need to wrap your python command with a loop that will append the "-sceneUpdate $abc[x]" string per element in the string array.

Tranimatronic
11-28-2008, 10:36 PM
okay - I get it now ;)
I THOUGHT there were python commands that would accept a list (array) as arguments to a flag, however it seems I was getting confused with command arguments, as right now I cannot fina one.
I also was led astray with the MArgDatabase.getFlagArgument that returns a selection list, thinking I could send a user-defiined list to a flag.
It does also seem confusing that MArgParser lets you retrieve an argumentLIST from a flag, however it seems that this will only ever return one item.

I got around the problem by saving out a seperate text file of updates and just notifiying Maya that the updates list exists. This way when a file is loaded locally it will know server updates are available immediatley.

Thanks again for your advice.
T

Keilun
12-01-2008, 03:50 PM
It does also seem confusing that MArgParser lets you retrieve an argumentLIST from a flag, however it seems that this will only ever return one item.

Yeah it can be confusing. The reason for it being able to return an argList from a flag is only for the multi-use flag.

Typically for a standard flag, you'd just use getFlagArgument and be done with it. However for a multi-use flag, you then need to tell Maya which instance of the flag you want to query. This is where getFlagArgumentList comes in. It might have been simpler to understand if you just had to pass a 2nd index indicating which flag instance to query, but unfortunately that's not the case.

Glad you got something working. :)

CGTalk Moderation
12-01-2008, 03:50 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.