Maya parsing command arguments sample code
Handling a list of parameter:
- Option1: -flag "elt0, elt1, elt2" having a flag with a single string and parsing the string for commas manually
- Option2: use MSyntax::makeFlagMultiUse() and MArgParser::getFlagArgumentList()
MStatus MPxCommand::doIt(const MArgList& args)
{
MString raw_command = MString("ComandName") + " " + to_str(args);
MGlobal::displayInfo(raw_command);
try {
MStatus status;
MSyntax syntax;
syntax.addFlag("-ato", "-accordingTo", MSyntax::kString );
syntax.addFlag("-sjt", "-sourceJoints", MSyntax::kString );
syntax.addFlag("-fmt", "-forceMapTo", MSyntax::kString, MSyntax::kString);
syntax.makeFlagMultiUse("-fmt");
MArgParser parser(syntax, args, &status);
if (!status) {
MGlobal::displayError("Incorrect command! Check flags / arguments are valid: ");
MGlobal::displayError(raw_command);
return MS::kFailure;
}
if (parser.isFlagSet("-accordingTo")) {
MString copy_options;
mayaCheck(parser.getFlagArgument("-accordingTo", 0, copy_options));
}
if (parser.isFlagSet("-sourceJoints")) {
MString joint_list;
mayaCheck(parser.getFlagArgument("-sourceJoints", 0, joint_list));
MStringArray joints = split(joint_list, ',');
std::vector<std::string> source_joints;
source_joints.resize(joints.length());
for (int i = 0; i < source_joints.size(); ++i)
source_joints[i] = to_str(joints[i]);
}
if (parser.isFlagSet("-copyWeights"))
{
MString src_skincluster_name;
MString dst_skincluster_name;
mayaCheck(parser.getFlagArgument("-copyWeights", 0, src_skincluster_name));
mayaCheck(parser.getFlagArgument("-copyWeights", 1, dst_skincluster_name));
MObject src_skin_cluster = get_MObject(src_skincluster_name);
MObject dst_skin_cluster = get_MObject(dst_skincluster_name);
// look up -forceMapTo flags
for(int i = 0; i < parser.numberOfFlagUses("-forceMapTo"); ++i)
{
MString src_joint_name, dst_joint_name;
MArgList arg_list;
mayaCheck( parser.getFlagArgumentList( "-forceMapTo", i, arg_list ) );
src_joint_name = arg_list.asString( 0, &status );
dst_joint_name = arg_list.asString( 1, &status );
mayaCheck( status );
}
}
return redoIt();
}
catch (std::exception& e) {
MGlobal::displayError("The command \"" + raw_command + "\" failed: ");
MGlobal::displayError(e.what());
MGlobal::displayError("Check input arguments or flags are valid.");
std::cerr << e.what();
return MS::kFailure;
}
return MS::kSuccess;
}
Raw parsing of the flags is what gives the most flexibility for the most work though:
char MpxCommand::_s_name[] = "MyCommandName";
// -----------------------------------------------------------------------------
MStatus MPxCommand::doIt(const MArgList& args)
{
MStatus status;
try
{
MString raw_command = MString(_s_name)+" "+to_str(args);
// detect repeated occurrences of -fixValues
// -fixValues double (min) double (max)
std::vector<tbx::Vec2> constraints = get_flag_fix_values( args );
// -nbIterations int
int nb_iters = get_flag_int(args, "-nbIterations", /*default value:*/0);
// detect presence of -myFlag flag and ignores arguments
bool has_my_flag = has_flag( args , "-myFlag");
// flag with list of values (array of ints and floats)
// -brushMask int (slot) int (length array) int[] (vert_ids) float[] (brush_values)
std::vector<Brush> mask = get_flag_brush_mask( args );
// -smoothCluster string
MString skin_cluster_name;
if( (skin_cluster_name = get_flag_string( args, "-smoothCluster")).length() > 0 )
MObject skin_cluster = get_MObject( skin_cluster_name );
status = redoIt();
}
catch (std::exception& e)
{
MGlobal::displayError( e.what() );
std::cerr << e.what();
status = MS::kFailure;
}
return status;
}
//------------------------------------------------------------------------------
static MString get_flag_string(const MArgList& args, const MString& str)
{
MStatus status;
unsigned len = args.length(&status);
mayaCheck(status);
MString name_arg;
for(unsigned i = 0; i < len; ++i)
{
MString val = args.asString(i, &status);
if( status == MS::kSuccess && str == val )
{
name_arg = args.asString(++i, &status);
mayaCheck( status );
break; // only one occurence is necessary.
}
}
return name_arg;
}
// -----------------------------------------------------------------------------
/// fetch the argument "-fixValues" double (min) double (max)
static std::vector<tbx::Vec2> get_flag_fix_values(const MArgList& args)
{
MStatus status;
std::vector<tbx::Vec2> constraints;
unsigned len = args.length(&status);
mayaCheck(status);
for(unsigned i = 0; i < len; ++i)
{
MString val = args.asString(i, &status);
if( status == MS::kSuccess && MString("-fixValues") == val )
{
float min = float(args.asDouble(++i, &status));
mayaCheck( status );
float max = float(args.asDouble(++i, &status));
mayaCheck( status );
constraints.push_back( Vec2(min, max) );
}
}
return constraints;
}
// -----------------------------------------------------------------------------
//
static int get_flag_int(const MArgList& args,
const MString& str,
int default_value)
{
MStatus status;
unsigned len = args.length(&status);
mayaCheck(status);
int value = default_value;
for(unsigned i = 0; i < len; ++i)
{
MString val = args.asString(i, &status);
if( status == MS::kSuccess && str == val )
{
value = args.asInt(++i, &status);
mayaCheck( status );
break; // only one occurence is necessary.
}
}
return value;
}
// -----------------------------------------------------------------------------
/// fetch the argument "-brushMask" int (slot) int (length array) int[] (vert_ids) float[] (brush_values)
/// @note the last two arguments are optional if length array is 0.
static std::vector<std::pair<int, float> > get_flag_brush_mask(const MArgList& args)
{
MStatus status;
std::vector<Brush> mask;
unsigned len = args.length(&status);
mayaCheck(status);
for(unsigned i = 0; i < len; ++i)
{
MString val = args.asString(i, &status);
if( status == MS::kSuccess && MString("-brushMask") == val )
{
// skip first int
int slot = args.asInt(++i, &status);
mayaCheck( status );
int len = args.asInt(++i, &status);
mayaCheck( status );
MIntArray ints;
MDoubleArray floats;
if( len > 0 )
{
ints = args.asIntArray(++i, &status);
mayaCheck( status );
floats = args.asDoubleArray(++i, &status);
mayaCheck( status );
}
mayaAssertMsg( ints.length() == floats.length(),
"Invalid command flag for -brushMask" );
for(unsigned j = 0; j < ints.length(); ++j)
mask.push_back( make_pair(ints[j], float(floats[j])) );
}
}
return mask;
}
// -----------------------------------------------------------------------------
static bool has_flag(const MArgList& args, const MString& flag_name)
{
MStatus status;
unsigned len = args.length(&status);
mayaCheck(status);
for(unsigned i = 0; i < len; ++i)
{
MString val = args.asString(i, &status);
if( status == MS::kSuccess && flag_name == val ) {
return true;
}
}
return false;
}
No comments