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

Assign to component tags #2963

Merged
merged 4 commits into from
Mar 24, 2023
Merged

Assign to component tags #2963

merged 4 commits into from
Mar 24, 2023

Conversation

JGamache-autodesk
Copy link
Collaborator

@JGamache-autodesk JGamache-autodesk commented Mar 22, 2023

Allows assigning materials to component tags
Will set family to "materialBind" if required
That is part 1 of 2. The second part requires being able to roundtrip these assignments thru import/export without gaining or losing any component tags.

- Automatically adjust the family name when assigning.
- Use a modern undo/redo framework to fix bugs.
@@ -735,7 +735,7 @@ static const std::vector<MayaUsd::ufe::SchemaTypeGroup> getConcretePrimTypes(boo
bool sceneItemSupportsShading(const Ufe::SceneItem::Ptr& sceneItem)
{
#if PXR_VERSION >= 2108
if (MayaUsd::ufe::BindMaterialUndoableCommand::CompatiblePrim(sceneItem).IsValid()) {
if (MayaUsd::ufe::BindMaterialUndoableCommand::CompatiblePrim(sceneItem)) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Some signatures were changed. This one now only returns a boolean.

@@ -1239,24 +1239,23 @@ Ufe::UndoableCommand::Ptr UsdContextOps::doOpCmd(const ItemPath& itemPath)
#endif
#if PXR_VERSION >= 2108
else if (itemPath[0] == BindMaterialUndoableCommand::commandName) {
return std::make_shared<BindMaterialUndoableCommand>(fItem->prim(), SdfPath(itemPath[1]));
return std::make_shared<BindMaterialUndoableCommand>(fItem->path(), SdfPath(itemPath[1]));
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

And the constructor now takes a Ufe path.

}

BindMaterialUndoableCommand::BindMaterialUndoableCommand(
const UsdPrim& prim,
Ufe::Path primPath,
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I was about to say that keeping a Ufe::Path was better than keeping a Stage/SdfPath for undo/redo, but then noticed that since I modernized to use a UsdUndoBlock, this is not relevant anymore.

}
bindingAPI.Bind(material);
if (auto subset = UsdGeomSubset(prim)) {
subset.GetFamilyNameAttr().Set(UsdShadeTokens->materialBind);
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That was the only required change to make assignment work and have the material display in the viewport.

Copy link
Collaborator

Choose a reason for hiding this comment

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

OK, but as I asked, IDk what are the implication of changing the family name on an existing subset.

@@ -312,7 +313,6 @@ def testAddNewPrim(self):
cmds.file(new=True, force=True)

# Create a proxy shape with empty stage to start with.
import mayaUsd_createStageWithNewLayer
proxyShape = mayaUsd_createStageWithNewLayer.createStageWithNewLayer()
Copy link
Collaborator

Choose a reason for hiding this comment

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

TY, it annoyed me too in past ;)

ufeCmd.execute(cmd)

self.assertEqual(topSubset.GetFamilyNameAttr().Get(), "materialBind")
self.assertTrue(topSubset.GetPrim().HasAPI(UsdShade.MaterialBindingAPI))
Copy link
Collaborator

Choose a reason for hiding this comment

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

I guess it was discussed internally, but i'm not sure what is better: change the name of the set or create a new set? The family name, according to USD, is used to group tags that are related, so changing it changes the group-of-subset composed of with members with the same family name.

In this case we're the one generating the componentTag, but it feels bad to now have 5 side with componentTag family name and one with the material binding one.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The end result of the discussions is that we try to keep the number of subsets to a minimum (hence the in-place family renaming), and a subsequent PR will also make sure that the number stays as stable as possible across import/export.

  • Maya: create poly sphere, select half the faces and apply material (no component tags on the mesh gets created)
  • Export to USD: creates a geom subset with same name as material and some extra roundtripping info
  • Import to Maya: the poly mesh does not get a new component tag but the face material assignment is preserved
  • Export again to USD: number of geom subsets stays stable.

or

  • Maya: create poly cube (automatically gets component tags)
  • Export to USD: tags exported as subsets. Extra info added to specify source.
  • In MayaUSD: assign material to one geom subset (this PR). Rename family and add material relationship.
  • Import from USD: We create both a mesh component tag (since we remember the origin) and a face-assigned material (since we want to see material in viewport). Need to add info to mark both as coming from the same geom subset.
  • Export again to USD: number of geom subsets stays stable because we recognize that the material subset is the same as the mesh subset (unless editing in Maya caused them to diverge).

This means the geom subset import/export will no longer be hardcoded to only support "componentTag" family name.

  1. All families are supported. Default if family is unknown is still "componentTag"
  2. There will be a way to assign a family name using USD dynamic tags on the Mesh (TBD). The import/export code will use that.

{
if (!_stage || _primPath.IsEmpty() || _materialPath.IsEmpty()) {
if (_primPath.empty() || _materialPath.IsEmpty()) {
return;
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

IDk if it warrants a warning or some other user feedback when the arguments are not valid?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

If the error handling scheme is still CTOR throws if command cannot execute then I agree this test should be moved to the constructor and throw accordingly. The execute() function should assume these are valid. Will fix that this afternoon.


auto prim = ufePathToPrim(_primPath);
if (!prim.IsValid()) {
return;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Same comment about all these early returns vs giving user feedback.

Copy link
Collaborator

@pierrebai-adsk pierrebai-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 would only want to know the rationale behind the decision to modify family names before approving.

Copy link
Collaborator

@stefanminning-autodesk stefanminning-autodesk left a comment

Choose a reason for hiding this comment

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

Nice improvements, LGTM.

@JGamache-autodesk
Copy link
Collaborator Author

I would only want to know the rationale behind the decision to modify family names before approving.

That is required by USD:

/// \note Material bindings authored on GeomSubsets are honored by renderers

/// only if their familyName is UsdShadeTokens->materialBind. This
/// allows robust interchange of subset bindings between multiple DCC apps.

There is a separate story logged as MAYA-128503 to reconcile the two known Maya geom subsets sources on import/export/rountrip.

@pierrebai-adsk
Copy link
Collaborator

My question was not about the name itself, but the decision to modify the subset family name instead of creating a new subset with a different family name.

pierrebai-adsk
pierrebai-adsk previously approved these changes Mar 23, 2023
if (!BindMaterialUndoableCommand::CompatiblePrim(parentItem)) {
const std::string error = TfStringPrintf(
"Assign new material: Skipping incompatible prim [%s] found in selection.",
Ufe::PathString::string(parentItem->path()).c_str());
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Found in the unit tests where the first new material ended up in the selection list for the second assign new material call.

@JGamache-autodesk JGamache-autodesk added the ready-for-merge Development process is finished, PR is ready for merge label Mar 24, 2023
@seando-adsk seando-adsk added ufe-usd Related to UFE-USD plugin in Maya-Usd and removed ufe Related to UFE component in Maya labels Mar 24, 2023
@seando-adsk seando-adsk merged commit 5863f62 into dev Mar 24, 2023
@seando-adsk seando-adsk deleted the gamaj/assign_to_component_tags branch March 24, 2023 13:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
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.

5 participants