Announcements

Between mid-October and November, the content on AREA will be relocated to the Autodesk Community M&E Hub and the Autodesk Community Gallery. Learn more HERE.

validateAndSetValue not being called for attributes that are part of a double3

validateAndSetValue not being called for attributes that are part of a double3

jmreinhart
Advisor Advisor
670 Views
2 Replies
Message 1 of 3

validateAndSetValue not being called for attributes that are part of a double3

jmreinhart
Advisor
Advisor

I have a custom transform node and validateAndSet is not being called when I have a connection into one of the individual attributes. It's only being called when I have a connection into the compound attribute. Below is some code from the initialize method to show what I mean.

	aOffsetRotateX = uAttr.create("offsetRotateX", "offrX", MFnUnitAttribute::kAngle, 0.0);
	uAttr.setAffectsWorldSpace(true);

	aOffsetRotateY = uAttr.create("offsetRotateY", "offrY", MFnUnitAttribute::kAngle, 0.0);
	uAttr.setAffectsWorldSpace(true);

	aOffsetRotateZ = uAttr.create("offsetRotateZ", "offrZ", MFnUnitAttribute::kAngle, 0.0);
	uAttr.setAffectsWorldSpace(true);

	aOffsetRotate = nAttr.create("offsetRotate", "offr", aOffsetRotateX, aOffsetRotateY, aOffsetRotateZ);
	uAttr.setAffectsWorldSpace(true);
	mustCallValidateAndSet(aOffsetRotate);
	mustCallValidateAndSet(aOffsetRotateX);
	mustCallValidateAndSet(aOffsetRotateY);
	mustCallValidateAndSet(aOffsetRotateZ);

 

0 Likes
Accepted solutions (1)
671 Views
2 Replies
Replies (2)
Message 2 of 3

jmreinhart
Advisor
Advisor

setting the parent attribute to not "mustCallValidateAndSet" allows the children attributes to be call "validateAndSet", but then the parent attribute of course doesn't call it. Marking only the parent attribute as "mustCallValidateAndSet" does not make the children get called. This is in Maya 2018 btw.

0 Likes
Message 3 of 3

jmreinhart
Advisor
Advisor
Accepted solution

Apologies for the sort of vague question. I'll do my best to explain the problem I had/have and explain the solution that I found.

 

So my custom transform node has added offset attributes that affect the matrix and have output attributes that add the offset to the standard transform attribute.

 

Problem 1:

When I make a connection to the parent plug of offsetTranslate everything works as intended. The validateAndSet method gets called for offsetTranslate and the normalTransform visually updates in the viewport. jonahrnhrt_10-1602782168170.png

When I connect to a child plug it calls the compute method for the parent plug (which is bizarre). I was never able to figure out why this happens, but the solution to problem 2 solved this issue as well, so if you're running into this same problem read on.

jonahrnhrt_9-1602781847689.png

 

Problem 2:

jonahrnhrt_7-1602781806236.png

When you have outputs being computed using the inputs into the normalTransform node, when those inputs update validateAndSetValue does not get called. So what you need to do is when you get the input data out of the dataBlock to compute the output plug you need to also pass that data to the MPxTransformationMatrix, here's an example:

	//outputTranslateX
	if (plug == aOutputTranslateX)
	{
		double offsetTranslateX_val = block.inputValue(aOffsetTranslateX, &status).asDouble();
		double translateX_val = block.inputValue(translateX, &status).asDouble();

		block.outputValue(aOutputTranslateX, &status).setDouble(offsetTranslateX_val + translateX_val);
		block.setClean(plug);
		ltm->setOffsetTranslateX(offsetTranslateX_val);
	}

ltm is a pointer to the MPxTransformationMatrix

 

We can use this same method of passing data to the MPxTransformationMatrix during compute to handle those unexplained compute calls for input plugs.

	//aOffsetTranslate
	if (plug == aOffsetTranslate)
	{
		if (ltm)
		{
			ltm->setOffsetTranslateX(plug.child(0).asDouble());
			ltm->setOffsetTranslateY(plug.child(1).asDouble());
			ltm->setOffsetTranslateZ(plug.child(2).asDouble());
		}
		else
		{
			MGlobal::displayError("Failed to get normal transform matrix");
		}
		block.setClean(plug);
		return MS::kSuccess;
	}

So now my node is working the way it needs to, so I'll mark this as a solution but if anyone has a deeper insight into why those comput input plug calls were happening. That would be great.