multi-use flags and python

581 views
Skip to first unread message

viktoras

unread,
Jan 22, 2010, 1:28:36 PM1/22/10
to python_in...@googlegroups.com
heya,
got a problem with multiuse arguments and python. google only leads to
other posts similar
to mine none of which got an answer.

i'm writting a custom command in C++, but intending to call that from
maya in python.
i need to define a multiuse argument for it (array of strings).
i've got command up and running, but the problem is... MEL call works
fine, while Python
won't. my code is really based just on whatever is posted as a correct
example of reading
multi-use arguments (including the example in maya's API)

software: maya 2008, visual studio 2008.

i call command as:

MEL: ngTestCmd -s "persp" -s "top" (outputs "persp" and "top" correctly)
Python: cmds.ngTestCmd(s=["persp","top"]) (fails trying to print first
element)


i define command syntax as:

MSyntax syntax;
syntax.addFlag(TEST_FLAG,"strings",MSyntax::kString);
syntax.makeFlagMultiUse(TEST_FLAG);
syntax.enableQuery( false );
syntax.enableEdit( false );
return syntax;

i read args like this (CHECK_STATUS macro fires statusException if
status is not "success"):
try {
MStatus status;
MArgDatabase argDb(this->syntax(),args,&status);
CHECK_STATUS("failed to create arg db");

uint numUses = argDb.numberOfFlagUses(TEST_FLAG);
for (uint i=0;i<numUses;i++){
MArgList selList;
status = argDb.getFlagArgumentList(TEST_FLAG,i,selList);
CHECK_STATUS("failed to get sel list");

// asString fails when command call is made from python
MGlobal::displayInfo(selList.asString(0,&status));
CHECK_STATUS("failed to get string from sel list");

}
}
catch (StatusException e){
MGlobal::displayError(e.getStatus().errorString());
return e.getStatus();
}

in both python and MEL calls numberOfFlagUses return 2, which is
correct. however,
python calls always result in status check failure after selList.asString()

help! :)

--
viktoras
www.neglostyti.com

Chris G

unread,
Jan 22, 2010, 2:43:18 PM1/22/10
to python_in...@googlegroups.com
Yes, this is unfortunately a known bug. You can use mel.eval to hack around it.

- Chris

> --
> http://groups.google.com/group/python_inside_maya

viktoras

unread,
Jan 22, 2010, 2:52:25 PM1/22/10
to python_in...@googlegroups.com

> Yes, this is unfortunately a known bug. You can use mel.eval to hack around it.
>
thanks!

it's not very good news after spending half a day trying to find out
what i was doing wrong.
is this a bug in maya 2008, or is it unresolved in 2010 as well?

mel.eval doesn't look like a best option. i guess i'll go with another
hacky solution and
allow passing parameter list in two ways:

python: cmds.myCommand(allParams="param1;param2;param3")
mel: myCommand -param "param1" -param "param2" -param "param3"

and split "allParams" into multiple ones if "param" is not present.


--
viktoras
www.neglostyti.com


Adam Mechtley

unread,
Jan 22, 2010, 3:23:09 PM1/22/10
to python_in...@googlegroups.com
It obviously depends what you are doing in your final command (i.e. if you are not already using an object list or selection), but another option could be to use objects if your arguments are objects in the DG anyway. Using objects allows your command to accept either an individual object or an object list. For instance:

syntax.setObjectType(MSyntax::kSelectionList) // You can also optionally specify a min and max

If you need multiple objects for this particular case but also need to operate on a single specified node, you could set syntax.useSelectionAsDefault(false) and then do one of the following approaches:
  • Get your selection inside the command using MGlobal::getActiveSelectionList()
  • Get your selection inside the command using another flag
In either of these cases, you would call the command with the object names passed as your object list and then have the option of specifying the node on which you need to operate with these items either assuming it is the current selection or by passing it as an argument:
  • MEL:
    • ngTestCmd persp top // Using getActiveSelectionList() to specify a node
    • ngTestCmd -node nodeName persp top // Using another flag to specify a node
  • Python:
    • cmds.ngTestCmd(["persp","top"]) # Using getActiveSelectionList() to specify a node
    • cmds.ngTestCmd(["persp","top"], node="nodeName")# Using another flag to specify a node
You could even combine both approaches if you wanted. Again though, this assumes that you a) need to operate on an object and b) it is only a single object and not several.


viktoras

unread,
Jan 23, 2010, 6:18:14 AM1/23/10
to python_in...@googlegroups.com
Adam Mechtley wrote:
> It obviously depends what you are doing in your final command (i.e. if
> you are not already using an object list or selection), but another
> option could be to use objects if your arguments are objects in the DG
> anyway. Using objects allows your command to accept either an
> individual object or an object list. For instance:
I use object list/selection already. the thing is, i need multiple
object/component selections to be passed to command.
object list or selection defines what command should be modifying;
few optional flags, defined by other component selections,
restrict/change command behavior.

i was also considering supplying those optional flags as maya's
selection sets, this would only require one identifier per flag.

--
viktoras
www.neglostyti.com


Reply all
Reply to author
Forward
0 new messages