Maya MPxCommand - passing matrix as a flag

Hi - I’m looking for an example of a command that will accept an array of 16 floats as a flag. Anyone has anything like it working for both MEL and maya.cmds?

Cheers.

Ok - the only way I’ve found (and works) is to parse arguments differently if the command has been called from Python and from MEL.

If it’s called from MEL then the MArgList provided to MPxCommand.doIt(const MArgList& argList) will have length (for python it returns 0).
As you can see below when called from python I collect the matrix from multi use flag (because maya.cmds treats list passed to a flag as multiple uses of this flag).
When called from MEL I treat it with my small custom args parser.
That way I can call this function like this:

machinaPoseApply -ps “[{“name”:“somePose”}]” -ns “namespace” -pm {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 12.23, 0.135, 0.0, 1.0};

So - what do you think?


MStatus poseApply::doIt(const MArgList& args)
{
	MStatus status;
	if(args.length() > 0)
	{
		status = parseArgsMel(args);
	} else {
		status = parseArgsPython(args);
	}
	return status;
}

MStatus poseApply::parseArgsMel(const MArgList& argList)
{
	unsigned int index = 0;
	MStatus status;
	unsigned int argsNum = argList.length();
	while (index < argList.length())
	{
		MString argValue = argList.asString(index, &status);
		CHECK_MSTATUS_AND_RETURN_IT(status);
		
		// --- Compare the argValue with all the flags names. If arg matches the flag name
		// --- parsedFlag will be set to true. If parsed flag will remain false it could mean that
		// --- we're done with flag parsing and we need to start collecting objects.
		// --- This prevents mixing flags and objects and forces the objects to be provided at the end
		// --- of the command.
		bool parsedFlag = false;
		bool doneParsingFlags = false;

		if(!doneParsingFlags){
			// --- Collect namespace
			if (argValue == MString("-ns"))
			{
				index++;
				mNamespace = argList.asString(index, &status);
				CHECK_MSTATUS_AND_RETURN_IT(status);
				parsedFlag = true;
			}

			// --- Collect pose string
			if (argValue == MString("-ps"))
			{
				index++;
				mNamespace = argList.asString(index, &status);
				CHECK_MSTATUS_AND_RETURN_IT(status);
				parsedFlag = true;
			}

			// --- Collect pose string
			if (argValue == MString("-pm"))
			{
				index++;
				//mPoseString = argList.asString(index, &status);
				MDoubleArray matrixNumbers = argList.asDoubleArray(index, &status);
				CHECK_MSTATUS_AND_RETURN_IT(status);
				if (matrixNumbers.length() != 16)
				{
					MGlobal::displayError("Invalid format of poseMatrix flag!");
					return MStatus::kFailure;
				}
				
				for (unsigned int u = 0; u < 4; u++)
				{
					for (unsigned int v = 0; v < 4; v++)
					{
						mPoseMatrix[u][v] = matrixNumbers[(u * 4) + v];
					}
				}
				parsedFlag = true;
			}
			
			// --- Check if maybe there are some wrong flags?
			if(!parsedFlag && argValue.length() > 0)
			{
				if(argValue.substring(0, 0) == MString("-"))
				{
					MGlobal::displayError(MString("Invalid flag ") + argValue);
					return MStatus::kFailure;
				}
			}

			if (!parsedFlag)
			{
				doneParsingFlags = true;
			}
		}

		// --- Done parsing flags, getting objects
		if(doneParsingFlags && !parsedFlag)
		{
			status = mObjects.add(argValue);
			if (status != MStatus::kSuccess)
			{
				MGlobal::displayError(MString("Invalid object ") + argValue);
				return status;
			}
		}

		index++;
	}

	// --- If no objects provided use selection
	if(mObjects.length() == 0)
	{
		MGlobal::getActiveSelectionList(mObjects);
	}
	
	return MStatus::kSuccess;
}


MStatus poseApply::parseArgsPython(const MArgList& argList)
{
	MArgDatabase argData(syntax(), argList);
	MStatus status;
	// --- Get the pose string.
	if (argData.isFlagSet("-ps"))
	{
		argData.getFlagArgument("-ps", 0, mPoseString);
	} else {
		MGlobal::displayError("Pose string not set!");
		return MStatus::kFailure;
	}

	// --- Get all objects to save in the pose.
	mObjects.clear();
	status = argData.getObjects(mObjects);
	if (MS::kSuccess != status) {
		MGlobal::displayError("Error getting objects");
		return status;
	}

	// --- Get the namespace name to remove from the string.
	if (argData.isFlagSet("-ns"))
	{
		argData.getFlagArgument("-ns", 0, mNamespace);
	}

	// --- Get the pose matrix.
	if (argData.isFlagSet("-pm"))
	{
		MArgList poseMatrixArgsList;

		for (unsigned int u = 0; u < 4; u++)
		{
			for (unsigned int v = 0; v < 4; v++)
			{
				MArgList poseMatrixArgsList;
				MStatus stat = argData.getFlagArgumentList("-pm", (u * 4) + v, poseMatrixArgsList);
				if (stat == MStatus::kFailure)
				{
					mPoseMatrix = MMatrix();
					MGlobal::displayError("Invalid format of poseMatrix flag!");
					return MStatus::kFailure;
				}
				mPoseMatrix[u][v] = poseMatrixArgsList.asDouble(0);
			}
		}
	}
	return MStatus::kSuccess;
}