MPxTransform::validateAndSetValue() is not called.

MPxTransform::validateAndSetValue() is not called.

hayashiL7MJP
Participant Participant
891 Views
12 Replies
Message 1 of 13

MPxTransform::validateAndSetValue() is not called.

hayashiL7MJP
Participant
Participant

I am creating a CustomTransformNode by inheriting MPxTransform.
When customTransformNode is moved by manipulator in Maya2023
MPxTransform::validateAndSetValue() is not called.
It is called if enter a value directly in the attribute.
Is this a bug in the API?

Until Maya2022, it is always called in all cases.

thank you.

0 Likes
Accepted solutions (3)
892 Views
12 Replies
Replies (12)
Message 2 of 13

brentmc
Autodesk
Autodesk
Accepted solution

Hi,

 

There was some changes to the internals of MPxTransform to fix some bugs and streamline the code so it does not duplicate functionality in the Maya transform.

I do not believe this is a bug. If you disagree please provide details of what you are trying to accomplish and I can figure out if there is another way to accomplish the same thing.

For example, you might be able to use the apply limits/locks methods? e.g. applyTranslationLimits?

 

Thanks.

Brent McPherson
Principle Engineer
0 Likes
Message 3 of 13

hayashiL7MJP
Participant
Participant

Thank you for your reply.

 

My node has a custom transform attribute and a bool attribute (enable custom transform).
If enable is on, the value of custom transform attribute will be valid.
If off, the value of the default transform attribute is valid.

 

When each custom attribute and default transform attribute are input, enable on/off is checked and transformation is applied in validateAndSetValue().
The apparent transformation can be controlled with MPxTransformationMatrix::asMatrix().
And when enable is off, there is no problem.
When enable is on, if the node is moved by the manipulator, validateAndSetValue() is not called, so there is a problem that only the value of plug changes.

 

----------------
[API Reference] validateAndSetValue()
When a plug's value is set, and the plug is on a default transform attribute, or has been flagged by the mustCallValidateAndSet() method, then this method will be called.
----------------

 

The target plug is the default transform attribute.
The problem is that it is not called only when it is moved by the manipulator.

 

PS
I'm not good at English.
I'm sorry if it's hard to understand.

0 Likes
Message 4 of 13

brentmc
Autodesk
Autodesk
Accepted solution

Hi,

 

I am going to open a new issue for this.

Thanks for reporting this.

Brent McPherson
Principle Engineer
0 Likes
Message 5 of 13

hayashiL7MJP
Participant
Participant

It wasn't just manipulator.
ValidateAndSetValu() is not called even if the transformation is changed by animCurve etc.

 

and,

I tried to use applyTranslationLimits() and so on.
This method is always called.
I was able to solve the problem of my node for now.
Thank you.

 

I noticed a new problem while working,
The return values of applyTranslationLimits() and applyRotationLimits() and so on are not limited value.

The problem of validateAndSetValue() may not be a bug, but this is a bug, isn't it?

0 Likes
Message 6 of 13

brentmc
Autodesk
Autodesk

Hi,

 

We are treating the validateAndSetValue change as a bug/regression for now.

So, are you saying that if you change the value in applyTranslationLimits it is not being applied?

I tried modifying the rockingTransform example in the SDK to clamp the Z translation to zero and it is working for me?

MVector rockingTransformNode::applyTranslationLimits(const MVector &unclampedT, MDataBlock &block, MStatus *ReturnStatus)
{
	return MVector(unclampedT.x, unclampedT.y, 0.0);
}

 

Thanks.

Brent McPherson
Principle Engineer
0 Likes
Message 7 of 13

hayashiL7MJP
Participant
Participant

The function to clamp the value is normal.
The return value of the method is wrong.

 

For example, I checked the return value like this.

MVector rockingTransformNode::applyTranslationLimits(const MVector &unclampedT, MDataBlock &block, MStatus* ReturnStatus) {

    MVector limitedT = ParentClass::applyTranslationLimits(unclampedT, block);
    MString infoX, infoY, infoZ;
    infoX.set(limitedT.x);
    infoY.set(limitedT.y);
    infoZ.set(limitedT.z);
    MGlobal::displayInfo("return value : " + infoX + ", " + infoY + ", " + infoZ);

    return limitedT;
}

 

Enable limit translation of node.
Input a value that out of limit to attribute and check the return value.

img_tf01.jpg

 

In this case, I expect the return value will be (1, 0, 0). but,
In Maya2023, (10, 0, 0) is returned.
In Maya2022, (1, 0, 0) is returned.

 

Thank you.

0 Likes
Message 8 of 13

brentmc
Autodesk
Autodesk

Hi,

 

To provide some background on the MPxTransform changes. Previously there was a lot of code duplication internally in the custom transform implementation which led to bugs and inconsistencies. Therefore, the code was cleaned up to eliminate the duplication. (and the bugs that resulted from the duplication)

This is what led to the changes you are seeing and in this instance we give the custom transform a chance to modify the unclamped values. Any limits will be applied after than which is why the input parameter to applyTranslationLimits is called "unclampedT".

If you need the limits you can retreive them using the passed in data block.

Brent McPherson
Principle Engineer
0 Likes
Message 9 of 13

hayashiL7MJP
Participant
Participant

Passing any vector to ParentClass::applyTranslationLimits() will return the same vector.
So there is no point in doing this in Maya2023.

 

Is my understanding correct?

 

Is there no choice but to check by myself using the data block?

MVector myNode::applyTranslationLimits(const MVector &unclampedT, MDataBlock &block, MStatus* ReturnStatus) {
    MVector minTLimit = block.inputValue(minTransLimit).asVector();
    MVector maxTLimit = block.inputValue(maxTransLimit).asVector();
    bool minTEnable[3] = { block.inputValue(minTransXLimitEnable).asBool(),
                            block.inputValue(minTransYLimitEnable).asBool(),
                            block.inputValue(minTransZLimitEnable).asBool() };
    bool maxTEnable[3] = { block.inputValue(maxTransXLimitEnable).asBool(),
                            block.inputValue(maxTransYLimitEnable).asBool(),
                            block.inputValue(maxTransZLimitEnable).asBool() };
    MVector limitedT = unclampedT;
    for (int i = 0; i < 3; ++i) {
        if (limitedT[i] < minTLimit[i]) {
            if (minTEnable[i]) {
                limitedT[i] = minTLimit[i];
            }
        } else if (limitedT[i] > maxTLimit[i]) {
            if (maxTEnable[i]) {
                limitedT[i] = maxTLimit[i];
            }
        }
    }
    return limitedT;
}

 

Thank you.

0 Likes
Message 10 of 13

brentmc
Autodesk
Autodesk
Accepted solution

Based on the API docs I think calling ParentClass::applyTranslationLimits should apply any active transformation limits so we are treating this as a bug/regression too.

 

Thanks.

Brent McPherson
Principle Engineer
0 Likes
Message 11 of 13

hayashiL7MJP
Participant
Participant

Noted.
I'll be waiting for the update.

 

Thanks for your help.

0 Likes
Message 12 of 13

brentmc
Autodesk
Autodesk

Hi,

 

Check out Maya 2023.2 as it has a number of custom transform bug fixes.

Brent McPherson
Principle Engineer
Message 13 of 13

hayashiL7MJP
Participant
Participant

I was able to check out the update.


Thank you very much.

0 Likes