Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MAYA-111834 - Crash when transforming multiple objects with duplicate stage #1554

Merged

Conversation

seando-adsk
Copy link
Collaborator

… stage

  • Replaced TF_AXIOM (which abort when fail) with TF_VERIFY to allow Add{Scale/Translate/Rotate} calls that already exist to return without crashing.

… stage

* Replaced TF_AXIOM (which abort when fail) with TF_VERIFY
  to allow Add{Scale/Translate/Rotate} calls that already exist
  to return without crashing.
Comment on lines 678 to 683
auto op = xformable.AddTranslateOp(OpPrecision<V>::precision, opSuffix);
TF_AXIOM(op);
if (!TF_VERIFY(
op,
"TranslateOp already exists for %s",
cmd.sceneItem()->path().string().c_str()))
return UsdGeomXformOp();
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You'll see on lines 631-633 it checks for the existence of the attribute and then creates a OpFunc (from lambda) for either using existing attribute op, or creating one first (this second lamdba) and then using the newly created one. The AddTranslateOp will output an error message if one already exists and return an empty UsdGeomXformOp. The previous test at line 661 would then abort because of the empty op. I changed it to a TF_VERIFY which just prints a message and then returns empty op. So crash is avoided.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will fall into this situation only on the first manipulation when ops are missing. Every consecutive manipulation will perform double edit.

We can make the behavior consistent and re-query the op when the addition failed. Why did you choose to issue a warning instead?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because I didn't know what the expected behavior is supposed to be. You are right about the consecutive manips will be double - I'm not sure this is expected either.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ppt-adsk What do you think?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kxl-adsk I am not sure I understand your comment. The core issue is the fact that two UFE paths refer to the same underlying USD object. If you create n UFE scene items for a Maya command that have this property, then you will get n edits (2 in the case of a duplicated stage). It is difficult for this mayaUsd code to identify this situation --- we would be violating separation of concerns, IMO. That is for the double edit part of the discussion.

For the add / don't add a transform op part of the discussion, I'm not sure what consistent behavior is. On command creation we determined there was no transform op, and on command execution a transform op appeared. For unique objects, this would be a bug caused by invalid operation of the software. In the current case, with multiple UFE scene items pointing to the same USD prim, we can indeed deal with the problem by assuming all is well and querying the op --- and the result will be a double edit. I believe users will find this unexpected.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After discussion with Krystian we will separate out the behavior from preventing the crash. To simplify debugging the behavior in the future, we'll make the create transform op failure code path simply try accessing the transform op, per Krystian's suggestion.

Comment on lines 479 to 485
// See comment in setVector3dCmd().
auto r = xformable.AddRotateXYZOp(UsdGeomXformOp::PrecisionFloat, opSuffix);
TF_AXIOM(r);
if (!TF_VERIFY(
r,
"RotateXYZOp already exists for %s",
usdSceneItem->path().string().c_str()))
return UsdGeomXformOp();
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my comment down below. Same change made for Scale/Rotate/Translate/Pivot.

@seando-adsk seando-adsk requested review from HamedSabri-adsk, kxl-adsk and ppt-adsk and removed request for HamedSabri-adsk July 7, 2021 19:45
… stage

* Reworked all transform op commands to:
** Check for no edit allowed first and return null command.
** Combine two lambda OpFunc into one which will use
   attribute if it exists, otherwise will create one.
… stage

* Factor out error checking into helper method.
Copy link
Collaborator Author

@seando-adsk seando-adsk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made the changes as discussed with Pierre.

Comment on lines 774 to 788
bool UsdTransform3dMayaXformStack::isAttributeEditAllowed(const PXR_NS::TfToken attrName, std::string& errMsg) const
{
UsdAttribute attr;
if (!attrName.IsEmpty())
attr = prim().GetAttribute(attrName);
if (attr && !MayaUsd::ufe::isAttributeEditAllowed(attr, &errMsg)) {
return false;
} else if (!attr) {
UsdGeomXformable xformable(prim());
if (!MayaUsd::ufe::isAttributeEditAllowed(xformable.GetXformOpOrderAttr(), &errMsg)) {
return false;
}
}
return true;
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Helper to factor out some common error checking code.

Comment on lines +455 to +479
auto f = OpFunc(
[attrName, opSuffix = getTRSOpSuffix(), setXformOpOrderFn = getXformOpOrderFn(), v](
const BaseUndoableCommand& cmd) {
auto usdSceneItem = std::dynamic_pointer_cast<UsdSceneItem>(cmd.sceneItem());
TF_AXIOM(usdSceneItem);
auto attr = usdSceneItem->prim().GetAttribute(attrName);
if (attr) {
return UsdGeomXformOp(attr);
} else {
// Use notification guard, otherwise will generate one notification
// for the xform op add, and another for the reorder.
InTransform3dChange guard(cmd.path());
auto usdSceneItem = std::dynamic_pointer_cast<UsdSceneItem>(cmd.sceneItem());
TF_AXIOM(usdSceneItem);
UsdGeomXformable xformable(usdSceneItem->prim());

auto r = xformable.AddRotateXYZOp(UsdGeomXformOp::PrecisionFloat, opSuffix);
TF_AXIOM(r);
r.Set(v);
auto result = setXformOpOrderFn(xformable);
TF_AXIOM(result);

return r;
}
});
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Combined two lambda OpFunc into one. First check if the prim already has the attribute. If yes, then use it to create UsdGeomXformOp. Otherwise first add the attribute and then use the newly added one. Same changes made in all the command methods.

Copy link
Collaborator

@ppt-adsk ppt-adsk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Much cleaner, thanks for doing this!

@seando-adsk seando-adsk added bug Something isn't working ufe-usd Related to UFE-USD plugin in Maya-Usd labels Jul 13, 2021
@seando-adsk seando-adsk added the ready-for-merge Development process is finished, PR is ready for merge label Jul 14, 2021
@kxl-adsk kxl-adsk merged commit 147efb6 into dev Jul 14, 2021
@kxl-adsk kxl-adsk deleted the donnels/MAYA-111834/crash_transforming_with_shared_stage branch July 14, 2021 13:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working ready-for-merge Development process is finished, PR is ready for merge ufe-usd Related to UFE-USD plugin in Maya-Usd
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants