Maya - How to read plugs from an array attribute of compound attributes?

I’m currently using C#, and this is my first time using Array attributes and Compound attributes within an MPxNode. Essentially I have this node setup:

public static void initialize() {
	MFnCompoundAttribute cAttr = new MFnCompoundAttribute();
	MFnMessageAttribute mAttr = new MFnMessageAttribute();
	MFnTypedAttribute tAttr = new MFnTypedAttribute();
	MFnMatrixAttribute matrixAttr = new MFnMatrixAttribute();

	spacesAttr = cAttr.create( "spaces", "sp" );
	cAttr.isArray = true;
	cAttr.addChild( mAttr.create( "inTransform", "it" ) );
	cAttr.addChild( tAttr.create( "name", "nm", MFnData.Type.kString ) );
	cAttr.isStorable = true;
	cAttr.usesArrayDataBuilder = true;
	addAttribute( spacesAttr );

	outMatrix = matrixAttr.create( "outMatrix", "om" );
	matrixAttr.isStorable = false;
	addAttribute( outMatrix );

	outName = tAttr.create( "outName", "on", MFnData.Type.kString );
	tAttr.isStorable = false;
	addAttribute( outName );

	// Attribute Affects
	attributeAffects( spacesAttr, outMatrix );
	attributeAffects( spacesAttr, outName );


What I’m trying to do is - During the compute function, I want to iterate on all inTransform plugs and grab the nodes that are connected. I’m a little stumped on how to deal with Array Compound attributes with the datablock.

This is what I have so far, but I’m not sure if its correct or not. I’ve tried different ways to try and get at the array compound plugs but so far no luck. Any help would be much appreciated!

public override bool compute( MPlug plug, MDataBlock dataBlock ) {
	MMatrix final_matrix = new MMatrix();
	string final_name = "";

	if( plug.attribute.equalEqual( outMatrix ) ) {
		MArrayDataHandle array_handle = dataBlock.inputArrayValue( spacesAttr );
		uint num_elements = array_handle.elementCount();
		for( uint i=0; i<num_elements; i++ ){
			array_handle.jumpToElement( i );
			MDataHandle element_handle = array_handle.inputValue();

			// ???
			// ???
			// ???

		MDataHandle outMatrixHandle = dataBlock.outputValue( outMatrix );
		outMatrixHandle.asMatrix = final_matrix;

		MDataHandle outNameHandle = dataBlock.outputValue( outName );
		outNameHandle.asString = final_name;

	// Set output data
	dataBlock.setClean( plug );

	return true;

Please don’t do that. Seriously.
While it’s technically possible to do using the api, it’s a bad idea.

A node should only know what values it’s getting from its inputs, and how to set values on its outputs. Anything more than that, and you start breaking the base assumptions of what a dependency graph is at its core. And you start introducing some REALLY strange bugs.

From the names I’m reading, it looks like you’re trying to make a space-switcher?
Then your inTransform plugs should probably be matrixAttrs.

What other data you’re trying to get from the connected nodes?

From the names I’m reading, it looks like you’re trying to make a space-switcher?

Yep! So in the meantime as a hacky workaround I converted the message plugs ( inTransform ) to matrix plugs ( and renamed them to inMatrix ) and changed the way I’m grabbing the data.

I’m currently using the supplied MPlug to the compute function, using plug.node to find the MFnDependencyNode and using that to findPlug to the inputs I need. Its gross and definitely not the way to do it, but it does work as a prototype.

Ideally I would like to just use the data in the datablock. From my example code above, I can get a handle ( element_handle ) to the compound plug but I am unsure how to get the child plugs below it so I can grab the MMatrix values from it.

tfox_TD - could you point me in the right direction on the correct way to set that up? I would very much appreciate it!

Could you help me to configure visual studio to start seeing those libraries or program something too? I would appreciate any link you can share with me.

Pablo - do you need help setting up Visual Studio to compile Maya plugins in C#? If so I can help you set that up

First off, up in the initialize method, you’re creating, then immediately adding as a child.
Attr.addChild( mAttr.create( "inTransform", "it" ) );
You’re not storing the inTransform attribute on any variable.
That needs to be 2 separate lines, and the variable has to be one of the static members (or whatever the c++ equivalent is in c#) like all the other attributes.

Then it should just be this, assuming you call your variable inTransformAttr

		for( uint i=0; i<num_elements; i++ ){
			array_handle.jumpToElement( i );
			MDataHandle transformHandle = array_handle.child(inTransformAttr);

tfox_TD - ah alrighty I’ll give that a shot, thanks!